diff --git a/apps/roofer-app/crop_tile.hpp b/apps/roofer-app/crop_tile.hpp index 6bc44458..ec32ab3b 100644 --- a/apps/roofer-app/crop_tile.hpp +++ b/apps/roofer-app/crop_tile.hpp @@ -137,7 +137,8 @@ bool crop_tile(const roofer::TBox& tile, roofer::arr2f nodata_c; for (unsigned i = 0; i < N_fp; ++i) { roofer::misc::RasterisePointcloud(ipc.building_clouds[i], footprints[i], - ipc.building_rasters[i], cfg.cellsize); + ipc.building_rasters[i], cfg.cellsize, + ipc.grnd_class, ipc.bld_class); ipc.nodata_fractions[i] = roofer::misc::computeNoDataFraction(ipc.building_rasters[i]); ipc.pt_densities[i] = @@ -331,8 +332,17 @@ bool crop_tile(const roofer::TBox& tile, building.attribute_index = i; building.z_offset = (*pj->data_offset)[2]; - building.pointcloud = - input_pointclouds[selected->index].building_clouds[i]; + auto& points = input_pointclouds[selected->index].building_clouds[i]; + auto classification = points.attributes.get_if("classification"); + for (size_t i = 0; i < points.size(); ++i) { + if (input_pointclouds[selected->index].grnd_class == + (*classification)[i]) { + building.pointcloud_ground.push_back(points[i]); + } else if (input_pointclouds[selected->index].bld_class == + (*classification)[i]) { + building.pointcloud_building.push_back(points[i]); + } + } building.footprint = footprints[i]; building.h_ground = input_pointclouds[selected->index].ground_elevations[i]; diff --git a/apps/roofer-app/reconstruct_building.hpp b/apps/roofer-app/reconstruct_building.hpp index 0f766ece..7c47c098 100644 --- a/apps/roofer-app/reconstruct_building.hpp +++ b/apps/roofer-app/reconstruct_building.hpp @@ -136,16 +136,7 @@ void reconstruct_building(BuildingObject& building, RooferConfig* rfcfg) { auto* cfg = &(rfcfg->rec); auto& logger = roofer::logger::Logger::get_logger(); // split into ground and roof points - roofer::PointCollection points, points_ground, points_roof; - auto classification = - building.pointcloud.attributes.get_if("classification"); - for (size_t i = 0; i < building.pointcloud.size(); ++i) { - if (2 == (*classification)[i]) { - points_ground.push_back(building.pointcloud[i]); - } else if (6 == (*classification)[i]) { - points_roof.push_back(building.pointcloud[i]); - } - } + // logger.debug("{} ground points and {} roof points", points_ground.size(), // points_roof.size()); @@ -158,24 +149,26 @@ void reconstruct_building(BuildingObject& building, RooferConfig* rfcfg) { rec.set_global(); #endif -#ifdef RF_USE_RERUN - rec.log("world/raw_points", - rerun::Collection{rerun::components::AnnotationContext{ - rerun::datatypes::AnnotationInfo( - 6, "BUILDING", rerun::datatypes::Rgba32(255, 0, 0)), - rerun::datatypes::AnnotationInfo(2, "GROUND"), - rerun::datatypes::AnnotationInfo(1, "UNCLASSIFIED"), - }}); - rec.log("world/raw_points", - rerun::Points3D(points).with_class_ids(classification)); -#endif + // #ifdef RF_USE_RERUN + // auto classification = + // building.pointcloud.attributes.get_if("classification"); + // rec.log("world/raw_points", + // rerun::Collection{rerun::components::AnnotationContext{ + // rerun::datatypes::AnnotationInfo( + // 6, "BUILDING", rerun::datatypes::Rgba32(255, 0, 0)), + // rerun::datatypes::AnnotationInfo(2, "GROUND"), + // rerun::datatypes::AnnotationInfo(1, "UNCLASSIFIED"), + // }}); + // rec.log("world/raw_points", + // rerun::Points3D(points).with_class_ids(classification)); + // #endif std::unordered_map> timings; auto t0 = std::chrono::high_resolution_clock::now(); auto PlaneDetector = roofer::reconstruction::createPlaneDetector(); PlaneDetector->detect( - points_roof, + building.pointcloud_building, { .metrics_plane_k = cfg->plane_detect_k, .metrics_plane_min_points = cfg->plane_detect_min_points, @@ -205,7 +198,7 @@ void reconstruct_building(BuildingObject& building, RooferConfig* rfcfg) { t0 = std::chrono::high_resolution_clock::now(); auto PlaneDetector_ground = roofer::reconstruction::createPlaneDetector(); - PlaneDetector_ground->detect(points_ground); + PlaneDetector_ground->detect(building.pointcloud_ground); timings["PlaneDetector_ground"] = std::chrono::high_resolution_clock::now() - t0; // logger.debug("Completed PlaneDetector (ground), found {} groundplanes", @@ -306,7 +299,8 @@ void reconstruct_building(BuildingObject& building, RooferConfig* rfcfg) { auto SegmentRasteriser = roofer::reconstruction::createSegmentRasteriser(); SegmentRasteriser->compute( AlphaShaper->alpha_triangles, AlphaShaper_ground->alpha_triangles, - {.use_ground = !points_ground.empty() && cfg->clip_ground}); + {.use_ground = + !building.pointcloud_ground.empty() && cfg->clip_ground}); timings["SegmentRasteriser"] = std::chrono::high_resolution_clock::now() - t0; // logger.debug("Completed SegmentRasteriser"); @@ -346,7 +340,8 @@ void reconstruct_building(BuildingObject& building, RooferConfig* rfcfg) { { .data_multiplier = cfg->complexity_factor, .smoothness_multiplier = float(1. - cfg->complexity_factor), - .use_ground = !points_ground.empty() && cfg->clip_ground, + .use_ground = + !building.pointcloud_ground.empty() && cfg->clip_ground, }); timings["ArrangementOptimiser"] = std::chrono::high_resolution_clock::now() - t0; diff --git a/apps/roofer-app/roofer-app.cpp b/apps/roofer-app/roofer-app.cpp index 8c003df5..e05d94cf 100644 --- a/apps/roofer-app/roofer-app.cpp +++ b/apps/roofer-app/roofer-app.cpp @@ -92,7 +92,8 @@ namespace fs = std::filesystem; * some attributes that are set during the reconstruction. */ struct BuildingObject { - roofer::PointCollection pointcloud; + roofer::PointCollection pointcloud_ground; + roofer::PointCollection pointcloud_building; roofer::LinearRing footprint; float z_offset = 0; diff --git a/include/roofer/misc/PointcloudRasteriser.hpp b/include/roofer/misc/PointcloudRasteriser.hpp index 5f1eaf16..3340520e 100644 --- a/include/roofer/misc/PointcloudRasteriser.hpp +++ b/include/roofer/misc/PointcloudRasteriser.hpp @@ -31,7 +31,8 @@ namespace roofer::misc { void RasterisePointcloud(PointCollection& pointcloud, LinearRing& footprint, ImageMap& image_bundle, // Raster& heightfield, - float cellsize = 0.5); + float cellsize = 0.5, int ground_class = 2, + int building_class = 6); void gridthinPointcloud(PointCollection& pointcloud, const Image& cnt_image, float max_density = 20); diff --git a/src/extra/misc/PointcloudRasteriser.cpp b/src/extra/misc/PointcloudRasteriser.cpp index 8176111d..3f403013 100644 --- a/src/extra/misc/PointcloudRasteriser.cpp +++ b/src/extra/misc/PointcloudRasteriser.cpp @@ -35,7 +35,8 @@ namespace roofer::misc { void RasterisePointcloud(PointCollection& pointcloud, LinearRing& footprint, ImageMap& image_bundle, // RasterTools::Raster& heightfield, - float cellsize) { + float cellsize, int ground_class, + int building_class) { // TODO: this is always true? bool use_footprint = true; Box box; @@ -81,9 +82,9 @@ namespace roofer::misc { auto& p = pointcloud[pi]; auto& c = (*classification)[pi]; if (r_max.check_point(p[0], p[1])) { - if (c == 2) { + if (c == ground_class) { r_ground_points.add_value(p[0], p[1], 1); - } else if (c == 6) { + } else if (c == building_class) { r_non_ground_points.add_value(p[0], p[1], 1); }