From 2f189c65e83a7c4042944211215702990186dd18 Mon Sep 17 00:00:00 2001 From: Ivan Paden Date: Tue, 9 May 2023 11:24:47 +0200 Subject: [PATCH 01/42] Bump dev version --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index b7d8bb7..e30a71f 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,7 +31,7 @@ #include -std::string CITY4CFD_VERSION = "0.4.0"; +std::string CITY4CFD_VERSION = "0.4.0+dev"; void printWelcome() { auto logo{ From 89d0185999bfaac9586b1516b403f01ea970392a Mon Sep 17 00:00:00 2001 From: Ivan Paden Date: Mon, 5 Jun 2023 15:10:51 +0200 Subject: [PATCH 02/42] Bump dev version --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index a9c8d40..072afd0 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,7 +31,7 @@ #include -std::string CITY4CFD_VERSION = "0.4.1"; +std::string CITY4CFD_VERSION = "0.4.1+dev"; void printWelcome() { auto logo{ From ea129965f8415302021cb15066c7c864d13ffb8b Mon Sep 17 00:00:00 2001 From: Ivan Paden Date: Fri, 25 Aug 2023 11:43:39 +0200 Subject: [PATCH 03/42] Bump dev version --- src/main.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main.cpp b/src/main.cpp index c27d64d..b34fe36 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,7 +31,7 @@ #include -std::string CITY4CFD_VERSION = "0.4.3"; +std::string CITY4CFD_VERSION = "0.4.3+dev"; void printWelcome() { auto logo{ From c3f1bee9df5e1d0c98089d61df5f90e57b599c7b Mon Sep 17 00:00:00 2001 From: Ivan Paden Date: Fri, 25 Aug 2023 14:28:40 +0200 Subject: [PATCH 04/42] Update CMake version --- thirdparty/LAStools/CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/thirdparty/LAStools/CMakeLists.txt b/thirdparty/LAStools/CMakeLists.txt index e6a66be..ea62b23 100644 --- a/thirdparty/LAStools/CMakeLists.txt +++ b/thirdparty/LAStools/CMakeLists.txt @@ -1,4 +1,4 @@ -cmake_minimum_required(VERSION 3.1) +cmake_minimum_required(VERSION 3.9) set(CMAKE_SUPPRESS_REGENERATION true) project("LAStools") From 5e98b3ebd5e24c89fad82ee46d4cf52fa863745b Mon Sep 17 00:00:00 2001 From: Ivan Paden Date: Sat, 9 Sep 2023 22:33:16 +0200 Subject: [PATCH 05/42] Add lod as a required property in json schema --- src/configSchema.inc | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/configSchema.inc b/src/configSchema.inc index 4f9cf23..6866772 100644 --- a/src/configSchema.inc +++ b/src/configSchema.inc @@ -406,7 +406,7 @@ namespace jsonschema { ], "required": [ "point_of_interest", "influence_region", "domain_bnd", "building_percentile", "edge_max_len", "output_file_name", "output_format", - "output_separately" ] + "output_separately", "lod"] } )"_json; } From 80ca0463036c398a3d5fa6201c729f8a4a6ba7b8 Mon Sep 17 00:00:00 2001 From: Ivan Paden Date: Wed, 25 Oct 2023 01:17:46 +0200 Subject: [PATCH 06/42] Improve polygon flattening when adjacent to a building --- src/CGALTypes.h | 21 ++++++-- src/ImportedBuilding.cpp | 2 +- src/Map3d.cpp | 32 +++++++++-- src/PointCloud.cpp | 10 ++-- src/PointCloud.h | 3 +- src/PolyFeature.cpp | 113 +++++++++++++++++++++++++++++++++++---- src/PolyFeature.h | 5 +- src/Terrain.cpp | 6 ++- src/geomutils.cpp | 21 ++++++++ src/geomutils.h | 1 + 10 files changed, 185 insertions(+), 29 deletions(-) diff --git a/src/CGALTypes.h b/src/CGALTypes.h index df5d350..77e99c8 100644 --- a/src/CGALTypes.h +++ b/src/CGALTypes.h @@ -62,6 +62,13 @@ typedef CGAL::Polygon_2 Polygon_3; //- CGAL's Polygon_with_holes container expanded struct Polygon_with_holes_2 { + Polygon_with_holes_2() = default; + + Polygon_with_holes_2(const CGAL::Polygon_with_holes_2& cgalPoly) { + _rings.push_back(cgalPoly.outer_boundary()); + for (auto& hole : cgalPoly.holes()) _rings.push_back(hole); + } + std::vector _rings; std::vector& rings() {return _rings;} @@ -92,12 +99,20 @@ struct Polygon_with_holes_2 { } return cgalPoly; } - const CGAL::Polygon_with_holes_2 get_exact() const { + + const CGAL::Polygon_2 get_exact_outer_boundary() const { Converter to_exact; - CGAL::Polygon_with_holes_2 cgalPoly; + CGAL::Polygon_2 cgalOuterPoly; for (auto& pt : _rings.front()) { - cgalPoly.outer_boundary().push_back(to_exact(pt)); + cgalOuterPoly.push_back(to_exact(pt)); } + return cgalOuterPoly; + } + + const CGAL::Polygon_with_holes_2 get_exact() const { + Converter to_exact; + CGAL::Polygon_with_holes_2 cgalPoly; + cgalPoly.outer_boundary() = get_exact_outer_boundary(); for (auto hole = holes_begin(); hole != holes_end(); ++hole) { CGAL::Polygon_2 holePoly; for (auto& pt : *hole) { diff --git a/src/ImportedBuilding.cpp b/src/ImportedBuilding.cpp index 6a4190e..4dc371a 100644 --- a/src/ImportedBuilding.cpp +++ b/src/ImportedBuilding.cpp @@ -432,7 +432,7 @@ void ImportedBuilding::check_simplicity(Polygon_2& ring) { void ImportedBuilding::polyset_to_polygon(const CGAL::Polygon_set_2& polySet) { // polySet.remove_redundant_edges(); - std::list> res; + std::vector> res; polySet.polygons_with_holes(std::back_inserter(res)); Converter to_inexact; diff --git a/src/Map3d.cpp b/src/Map3d.cpp index 20267ad..3eac0ed 100644 --- a/src/Map3d.cpp +++ b/src/Map3d.cpp @@ -316,8 +316,20 @@ void Map3d::reconstruct_terrain() { if (_terrainPtr->get_cdt().number_of_vertices() == 0) { std::cout << "\nReconstructing terrain" << std::endl; _terrainPtr->prep_constraints(_allFeaturesPtr, _pointCloud.get_terrain()); - if (!Config::get().flattenSurfaces.empty()) - _pointCloud.flatten_polygon_pts(_allFeaturesPtr, _terrainPtr->get_extra_constrained_edges()); + // Handle flattening + if (!Config::get().flattenSurfaces.empty()) { + std::vector> additionalPolys; + _pointCloud.flatten_polygon_pts(_allFeaturesPtr, _terrainPtr->get_extra_constrained_edges(), additionalPolys); + if (!additionalPolys.empty()) { + for (auto& polyToAdd : additionalPolys) { + Polygon_with_attr newPolyToAdd; + newPolyToAdd.polygon = polyToAdd.first; + auto surfacePoly = std::make_shared(newPolyToAdd, polyToAdd.second); + _surfaceLayersPtr.push_back(surfacePoly); + _allFeaturesPtr.push_back(surfacePoly); + } + } + } _terrainPtr->set_cdt(_pointCloud.get_terrain()); _terrainPtr->constrain_features(); } @@ -413,8 +425,20 @@ void Map3d::clip_buildings() { //-- Prepare terrain with subset std::cout << "\nReconstructing terrain" << std::endl; _terrainPtr->prep_constraints(_allFeaturesPtr, _pointCloud.get_terrain()); - if (!Config::get().flattenSurfaces.empty()) - _pointCloud.flatten_polygon_pts(_allFeaturesPtr, _terrainPtr->get_extra_constrained_edges()); + // Handle flattening + if (!Config::get().flattenSurfaces.empty()) { + std::vector> additionalPolys; + _pointCloud.flatten_polygon_pts(_allFeaturesPtr, _terrainPtr->get_extra_constrained_edges(), additionalPolys); + if (!additionalPolys.empty()) { + for (auto& polyToAdd : additionalPolys) { + Polygon_with_attr newPolyToAdd; + newPolyToAdd.polygon = polyToAdd.first; + auto surfacePoly = std::make_shared(newPolyToAdd, polyToAdd.second); + _surfaceLayersPtr.push_back(surfacePoly); + _allFeaturesPtr.push_back(surfacePoly); + } + } + } _terrainPtr->set_cdt(_pointCloud.get_terrain()); _terrainPtr->constrain_features(); _terrainPtr->prepare_subset(); diff --git a/src/PointCloud.cpp b/src/PointCloud.cpp index 1005cd9..718025b 100644 --- a/src/PointCloud.cpp +++ b/src/PointCloud.cpp @@ -110,7 +110,6 @@ void PointCloud::smooth_terrain() { for (auto& pt : mesh.points()) { _pointCloudTerrain.insert(pt); } - _pointCloudTerrain.add_property_map ("is_building_point", false); } void PointCloud::remove_points_in_polygon(const BuildingsPtr& features) { @@ -155,7 +154,6 @@ void PointCloud::create_flat_terrain(const PolyFeaturesPtr& lsFeatures) { _pointCloudTerrain.insert(Point_3(pt.x(), pt.y(), 0.0)); } } - _pointCloudTerrain.add_property_map ("is_building_point", false); } void PointCloud::set_flat_terrain() { @@ -164,11 +162,11 @@ void PointCloud::set_flat_terrain() { flatPC.insert(Point_3(pt.x(), pt.y(), 0.)); } _pointCloudTerrain = flatPC; - _pointCloudTerrain.add_property_map ("is_building_point", false); } void PointCloud::flatten_polygon_pts(const PolyFeaturesPtr& lsFeatures, - std::vector& constrainedEdges) { + std::vector& constrainedEdges, + std::vector>& newPolys) { std::cout << "\n Flattening surfaces" << std::endl; std::map flattenedPts; @@ -199,7 +197,8 @@ void PointCloud::flatten_polygon_pts(const PolyFeaturesPtr& lsFeatures, auto ita = Config::get().flattenSurfaces.find(f->get_output_layer_id()); if (ita != Config::get().flattenSurfaces.end()) { // flatten points - if(f->flatten_polygon_inner_points(_pointCloudTerrain, flattenedPts, searchTree, pointCloudConnectivity)) { + if(f->flatten_polygon_inner_points(_pointCloudTerrain, flattenedPts, searchTree, pointCloudConnectivity, + constrainedEdges, newPolys)) { // add to list if constructing vertical borders if (std::find(Config::get().flattenVertBorder.begin(), Config::get().flattenVertBorder.end(), f->get_output_layer_id()) != Config::get().flattenVertBorder.end()) { @@ -331,7 +330,6 @@ void PointCloud::read_point_clouds() { if (!Config::get().ground_xyz.empty()) { std::cout << "Reading ground points" << std::endl; IO::read_point_cloud(Config::get().ground_xyz, _pointCloudTerrain); - _pointCloudTerrain.add_property_map("is_building_point", false); std::cout << " Points read: " << _pointCloudTerrain.size() << std::endl; } else { diff --git a/src/PointCloud.h b/src/PointCloud.h index d50a518..2631435 100644 --- a/src/PointCloud.h +++ b/src/PointCloud.h @@ -44,7 +44,8 @@ class PointCloud { void set_flat_terrain(); void smooth_terrain(); void remove_points_in_polygon(const BuildingsPtr& features); - void flatten_polygon_pts(const PolyFeaturesPtr& lsFeatures, std::vector& constrainedEdges); + void flatten_polygon_pts(const PolyFeaturesPtr& lsFeatures, std::vector& constrainedEdges, + std::vector>& newPolys); void buffer_flat_edges(const PolyFeaturesPtr& avgFeatures, std::vector& constrainedEdges); void read_point_clouds(); diff --git a/src/PolyFeature.cpp b/src/PolyFeature.cpp index ba3c09f..295b211 100644 --- a/src/PolyFeature.cpp +++ b/src/PolyFeature.cpp @@ -25,13 +25,23 @@ Delft University of Technology */ +#ifdef CITY4CFD_VERBOSE + #define CITY4CFD_POLYFEATURE_VERBOSE +#endif + #include "PolyFeature.h" #include "geomutils.h" +#include "Building.h" #include #include #include +#include +#include +#include +#include + #ifndef NDEBUG #include #endif @@ -222,10 +232,17 @@ double PolyFeature::ground_elevation() { bool PolyFeature::flatten_polygon_inner_points(const Point_set_3& pointCloud, std::map& flattenedPts, const SearchTree& searchTree, - const std::unordered_map& pointCloudConnectivity) const { + const std::unordered_map& pointCloudConnectivity, + std::vector& constrainedEdges, + std::vector>& newPolys) { + + typedef CGAL::Straight_skeleton_2 Ss; + typedef boost::shared_ptr> PolygonPtrWH; + typedef std::vector PolygonPtrVectorWH; + std::vector indices; std::vector originalHeights; - auto is_building_pt = pointCloud.property_map("is_building_point").first; + auto building_pt = pointCloud.property_map>("building_point").first; //-- Take tree subset bounded by the polygon std::vector subsetPts; Polygon_2 bbox = geomutils::calc_bbox_poly(_poly.rings().front()); @@ -234,23 +251,88 @@ bool PolyFeature::flatten_polygon_inner_points(const Point_set_3& pointCloud, Fuzzy_iso_box pts_range(bbox1, bbox2); searchTree.search(std::back_inserter(subsetPts), pts_range); - //-- Collect points that have not been already flattened + //-- Check if the polygon is overlapping with a building + std::map> overlappingBuildings; //id-building map for (auto& pt3 : subsetPts) { Point_2 pt(pt3.x(), pt3.y()); if (CGAL::bounded_side_2(_poly._rings.front().begin(), _poly._rings.front().end(), pt) != CGAL::ON_UNBOUNDED_SIDE) { auto itIdx = pointCloudConnectivity.find(pt3); - auto pointSetIt = pointCloud.begin(); std::advance(pointSetIt, itIdx->second); - if (is_building_pt[*pointSetIt]) - return false; //todo temp solution when having adjacent buildings - auto it = flattenedPts.find(itIdx->second); - if (it == flattenedPts.end()) { - indices.push_back(itIdx->second); - originalHeights.push_back(pointCloud.point(itIdx->second).z()); + auto currBuilding = building_pt[*pointSetIt]; + if (currBuilding != nullptr) { + int buildingId = currBuilding->get_internal_id(); + auto it = overlappingBuildings.find(buildingId); + if (it == overlappingBuildings.end()) { + overlappingBuildings[buildingId] = currBuilding; + } + } + } + } + //-- If next intersecting a building, clip poly with building + std::vector flattenCandidatePolys; + if (!overlappingBuildings.empty()) { + // Add clipping polys to set + CGAL::Polygon_set_2 polySet; + Converter to_exact; + for (auto& intersectBuilding : overlappingBuildings) { + polySet.insert(intersectBuilding.second->get_poly().get_exact_outer_boundary()); + } + // Clip with this polygon + polySet.complement(); + polySet.intersection(this->get_poly().get_exact()); + // Store this as the new polygon + std::vector> resPolys; + polySet.polygons_with_holes(std::back_inserter(resPolys)); +#ifdef CITY4CFD_POLYFEATURE_VERBOSE + std::cout << "After flatten polygon clipping, total new polygons: " << resPolys.size() << std::endl; +#endif + for (auto& flattenBndPoly : resPolys) { + flattenCandidatePolys.emplace_back(geomutils::exact_poly_to_poly(flattenBndPoly)); + } + } + std::vector flattenBndPolys; + if (!flattenCandidatePolys.empty()) { + bool isFirst = true; + for (auto& poly : flattenCandidatePolys) { + const double offsetVal = 0.1; // offset value hardcoded + PolygonPtrVectorWH offset_poly = + CGAL::create_interior_skeleton_and_offset_polygons_with_holes_2(offsetVal, + poly.get_cgal_type()); + if (offset_poly.size() == 1) { // make a check whether the offset is successfully created or not + flattenBndPolys.push_back(offset_poly.front()->outer_boundary()); + } else { + std::cout << "Skeleton construction failed!" << std::endl; + return false; + } + if (isFirst) { + _poly = Polygon_with_holes_2(*(offset_poly.front())); + isFirst = false; + } else { + // Some polys are cut -- save the new resulting polys and add them as new features in Map3D + newPolys.emplace_back(Polygon_with_holes_2(*(offset_poly.front())), _outputLayerID); + } + } + } else { + flattenBndPolys.push_back(_poly.outer_boundary()); + } + //-- Collect points that have not been already flattened + for (auto& pt3 : subsetPts) { + for (auto& flattenBndPoly : flattenBndPolys) { + Point_2 pt(pt3.x(), pt3.y()); + if (CGAL::bounded_side_2(flattenBndPoly.begin(), + flattenBndPoly.end(), + pt) != CGAL::ON_UNBOUNDED_SIDE) { + auto itIdx = pointCloudConnectivity.find(pt3); + + auto it = flattenedPts.find(itIdx->second); + if (it == flattenedPts.end()) { + indices.push_back(itIdx->second); + originalHeights.push_back(pointCloud.point(itIdx->second).z()); + } } } } @@ -265,6 +347,17 @@ bool PolyFeature::flatten_polygon_inner_points(const Point_set_3& pointCloud, for (auto& i : indices) { flattenedPts[i] = Point_3(pointCloud.point(i).x(), pointCloud.point(i).y(), avgHeight); } + //-- Add additional new segments to constrain + if (!flattenBndPolys.empty()) { + for (auto& flattenBndPoly : flattenBndPolys) { + for (const auto& newEdge: flattenBndPoly.edges()) { + ePoint_3 pt1(newEdge.point(0).x(), newEdge.point(0).y(), avgHeight); + ePoint_3 pt2(newEdge.point(1).x(), newEdge.point(1).y(), avgHeight); + constrainedEdges.emplace_back(pt1, pt2); + } + } + } + return true; } diff --git a/src/PolyFeature.h b/src/PolyFeature.h index e6ec815..416e692 100644 --- a/src/PolyFeature.h +++ b/src/PolyFeature.h @@ -54,8 +54,9 @@ class PolyFeature : public TopoFeature { double ground_elevation(); // double slope_height(); bool flatten_polygon_inner_points(const Point_set_3& pointCloud, std::map& flattenedPts, - const SearchTree& searchTree, const std::unordered_map& pointCloudConnectivity) const; + const SearchTree& searchTree, const std::unordered_map& pointCloudConnectivity, + std::vector& constrainedEdges, + std::vector>& newPolys); void set_zero_borders(); void calc_min_bbox(); void clear_feature(); diff --git a/src/Terrain.cpp b/src/Terrain.cpp index cfb0e64..6ab96d0 100644 --- a/src/Terrain.cpp +++ b/src/Terrain.cpp @@ -30,6 +30,7 @@ #include "geomutils.h" #include "io.h" #include "SurfaceLayer.h" +#include "Building.h" Terrain::Terrain() : TopoFeature(0), _cdt(), _surfaceLayersTerrain(), @@ -64,7 +65,8 @@ void Terrain::set_cdt(const Point_set_3& pointCloud) { void Terrain::prep_constraints(const PolyFeaturesPtr& features, Point_set_3& pointCloud) { std::cout << " Lifting polygon edges to terrain elevation" << std::endl; int countFeatures = 0; - auto is_building_pt = pointCloud.property_map("is_building_point").first; +// auto is_building_pt = pointCloud.add_property_map("is_building_point", false).first; + auto building_pt = pointCloud.add_property_map>("building_point", nullptr).first; for (auto& f : features) { if (!f->is_active()) continue; bool is_building = false; @@ -78,7 +80,7 @@ void Terrain::prep_constraints(const PolyFeaturesPtr& features, Point_set_3& poi for (auto& polyVertex : ring) { pts.push_back(ePoint_3(polyVertex.x(), polyVertex.y(), elevations[polyCount][i])); auto it = pointCloud.insert(Point_3(polyVertex.x(), polyVertex.y(), elevations[polyCount][i++])); - if (is_building) is_building_pt[*it] = true; + if (is_building) building_pt[*it] = std::static_pointer_cast(f); } _constrainedPolys.push_back(pts); ++polyCount; diff --git a/src/geomutils.cpp b/src/geomutils.cpp index 7491e2f..b49eeb6 100644 --- a/src/geomutils.cpp +++ b/src/geomutils.cpp @@ -234,6 +234,27 @@ bool geomutils::polygons_in_contact(const Polygon_with_holes_2& firstPoly, const return false; } +Polygon_with_holes_2 geomutils::exact_poly_to_poly(const CGAL::Polygon_with_holes_2& exactPoly) { + Converter to_inexact; + Polygon_with_holes_2 convertedPoly; + Polygon_2 transferKernelPoly; + for (auto& outerPt : exactPoly.outer_boundary()) { + Point_2 polyPt = to_inexact(outerPt); + transferKernelPoly.push_back(polyPt); + } + convertedPoly.rings().push_back(transferKernelPoly); + + for (auto& hole : exactPoly.holes()) { + transferKernelPoly.clear(); + for (auto& pt : hole) { + Point_2 polyPt = to_inexact(pt); + transferKernelPoly.push_back(polyPt); + } + convertedPoly.rings().push_back(transferKernelPoly); + } + return convertedPoly; +} + //-- Templated functions //-- Check if the point is inside a polygon on a 2D projection template diff --git a/src/geomutils.h b/src/geomutils.h index 04eddb9..94f14c9 100644 --- a/src/geomutils.h +++ b/src/geomutils.h @@ -44,6 +44,7 @@ namespace geomutils { Point_3 rotate_pt_xy(const Point_3& pt, const double angle, Point_2 centerPt = Point_2(0, 0)); void interpolate_poly_from_pc(const Polygon_2& poly, std::vector& elevations, const Point_set_3& pointCloud); bool polygons_in_contact(const Polygon_with_holes_2& firstPoly, const Polygon_with_holes_2& secondPoly); + Polygon_with_holes_2 exact_poly_to_poly(const CGAL::Polygon_with_holes_2& exactPoly); void remove_self_intersections(Mesh& mesh); //-- Templated functions From 364aee2807d12ba815d34b632498f363be108181 Mon Sep 17 00:00:00 2001 From: Ivan Paden Date: Wed, 25 Oct 2023 03:37:56 +0200 Subject: [PATCH 07/42] Handle vertical borders next to building when flattening --- src/Map3d.cpp | 3 ++- src/PointCloud.cpp | 5 +++-- src/PolyFeature.cpp | 4 +++- src/PolyFeature.h | 3 ++- src/Terrain.cpp | 1 - 5 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/Map3d.cpp b/src/Map3d.cpp index 3eac0ed..7430de3 100644 --- a/src/Map3d.cpp +++ b/src/Map3d.cpp @@ -324,7 +324,8 @@ void Map3d::reconstruct_terrain() { for (auto& polyToAdd : additionalPolys) { Polygon_with_attr newPolyToAdd; newPolyToAdd.polygon = polyToAdd.first; - auto surfacePoly = std::make_shared(newPolyToAdd, polyToAdd.second); + auto surfacePoly + = std::make_shared(newPolyToAdd, polyToAdd.second); _surfaceLayersPtr.push_back(surfacePoly); _allFeaturesPtr.push_back(surfacePoly); } diff --git a/src/PointCloud.cpp b/src/PointCloud.cpp index 718025b..9d31ad7 100644 --- a/src/PointCloud.cpp +++ b/src/PointCloud.cpp @@ -197,11 +197,12 @@ void PointCloud::flatten_polygon_pts(const PolyFeaturesPtr& lsFeatures, auto ita = Config::get().flattenSurfaces.find(f->get_output_layer_id()); if (ita != Config::get().flattenSurfaces.end()) { // flatten points + bool isNextToBuilding = false; if(f->flatten_polygon_inner_points(_pointCloudTerrain, flattenedPts, searchTree, pointCloudConnectivity, - constrainedEdges, newPolys)) { + constrainedEdges, newPolys, isNextToBuilding)) { // add to list if constructing vertical borders if (std::find(Config::get().flattenVertBorder.begin(), Config::get().flattenVertBorder.end(), - f->get_output_layer_id()) != Config::get().flattenVertBorder.end()) { + f->get_output_layer_id()) != Config::get().flattenVertBorder.end() && !isNextToBuilding) { vertBorders.push_back(f); } } diff --git a/src/PolyFeature.cpp b/src/PolyFeature.cpp index 295b211..c34cc85 100644 --- a/src/PolyFeature.cpp +++ b/src/PolyFeature.cpp @@ -234,7 +234,8 @@ bool PolyFeature::flatten_polygon_inner_points(const Point_set_3& pointCloud, const SearchTree& searchTree, const std::unordered_map& pointCloudConnectivity, std::vector& constrainedEdges, - std::vector>& newPolys) { + std::vector>& newPolys, + bool& isNextToBuilding) { typedef CGAL::Straight_skeleton_2 Ss; typedef boost::shared_ptr> PolygonPtrWH; @@ -272,6 +273,7 @@ bool PolyFeature::flatten_polygon_inner_points(const Point_set_3& pointCloud, } } } + if (!overlappingBuildings.empty()) isNextToBuilding = true; //-- If next intersecting a building, clip poly with building std::vector flattenCandidatePolys; if (!overlappingBuildings.empty()) { diff --git a/src/PolyFeature.h b/src/PolyFeature.h index 416e692..9bf11f6 100644 --- a/src/PolyFeature.h +++ b/src/PolyFeature.h @@ -56,7 +56,8 @@ class PolyFeature : public TopoFeature { bool flatten_polygon_inner_points(const Point_set_3& pointCloud, std::map& flattenedPts, const SearchTree& searchTree, const std::unordered_map& pointCloudConnectivity, std::vector& constrainedEdges, - std::vector>& newPolys); + std::vector>& newPolys, + bool& isNextToBuilding); void set_zero_borders(); void calc_min_bbox(); void clear_feature(); diff --git a/src/Terrain.cpp b/src/Terrain.cpp index 6ab96d0..404a109 100644 --- a/src/Terrain.cpp +++ b/src/Terrain.cpp @@ -65,7 +65,6 @@ void Terrain::set_cdt(const Point_set_3& pointCloud) { void Terrain::prep_constraints(const PolyFeaturesPtr& features, Point_set_3& pointCloud) { std::cout << " Lifting polygon edges to terrain elevation" << std::endl; int countFeatures = 0; -// auto is_building_pt = pointCloud.add_property_map("is_building_point", false).first; auto building_pt = pointCloud.add_property_map>("building_point", nullptr).first; for (auto& f : features) { if (!f->is_active()) continue; From d33ceb92f0f432b725150521c8efd5f135f91a02 Mon Sep 17 00:00:00 2001 From: Ivan Paden Date: Fri, 27 Oct 2023 05:15:04 +0200 Subject: [PATCH 08/42] Add fallback for failing reconstruction of imported buildings --- src/Building.cpp | 4 +++ src/Building.h | 1 + src/ImportedBuilding.cpp | 8 ++++++ src/Map3d.cpp | 46 ++++++++++++++++++++++++++--------- src/Map3d.h | 1 + src/PolyFeature.cpp | 6 +++++ src/PolyFeature.h | 1 + src/ReconstructedBuilding.cpp | 9 +++++++ src/ReconstructedBuilding.h | 1 + 9 files changed, 66 insertions(+), 11 deletions(-) diff --git a/src/Building.cpp b/src/Building.cpp index f2dd75f..b5060ce 100644 --- a/src/Building.cpp +++ b/src/Building.cpp @@ -275,6 +275,10 @@ double Building::sq_max_dim() { return *(std::max_element(dims.begin(), dims.end())); } +PointSet3Ptr Building::get_points() const { + return _ptsPtr; +} + void Building::get_cityjson_info(nlohmann::json& b) const { b["type"] = "Building"; // b["attributes"]; diff --git a/src/Building.h b/src/Building.h index d0a1b1c..70db150 100644 --- a/src/Building.h +++ b/src/Building.h @@ -59,6 +59,7 @@ class Building : public PolyFeature { bool has_self_intersections() const; void set_to_zero_terrain(); double sq_max_dim(); + PointSet3Ptr get_points() const; virtual void get_cityjson_info(nlohmann::json& b) const override; virtual void get_cityjson_semantics(nlohmann::json& g) const override; diff --git a/src/ImportedBuilding.cpp b/src/ImportedBuilding.cpp index 6a4190e..75e9d6b 100644 --- a/src/ImportedBuilding.cpp +++ b/src/ImportedBuilding.cpp @@ -339,6 +339,14 @@ void ImportedBuilding::reconstruct() { PMP::polygon_soup_to_polygon_mesh(points, polygons, _mesh); PMP::triangulate_faces(_mesh); + if (this->get_height() < Config::get().minHeight) { + this->deactivate(); + // Store points to ptsPtr so that it might be used for LoD1 reconstruction + for (auto& pt : _ptMap) _ptsPtr->insert(pt.second); + throw std::runtime_error("Importing failed. It could be that the height is lower than minimum, or the " + "mesh connectivity is broken. Trying to reconstruct LoD1 from building points"); + } + /* Mesh wrap; const double relative_alpha = 300.; diff --git a/src/Map3d.cpp b/src/Map3d.cpp index 20267ad..b2d28da 100644 --- a/src/Map3d.cpp +++ b/src/Map3d.cpp @@ -333,10 +333,23 @@ void Map3d::reconstruct_buildings() { << ". If I cannot find a geometry with that LoD, I will reconstruct in the highest LoD available" << std::endl; } + std::cout << "Total number of _buildingsPtr: " << _buildingsPtr.size() << std::endl; + this->reconstruct_buildings(_buildingsPtr); + std::cout << "Total number of _buildingsPtr: " << _buildingsPtr.size() << std::endl; + // Gather failed reconstructions int failed = 0; + for (auto& b : _buildingsPtr) if (b->has_failed_to_reconstruct()) ++failed; + std::cout << " Number of successfully reconstructed buildings: " << _buildingsPtr.size() - failed << std::endl; + Config::get().logSummary << "Building reconstruction summary: successfully reconstructed buildings: " + << _buildingsPtr.size() - failed << std::endl; + Config::get().logSummary << " num of failed reconstructions: " + << failed << std::endl; +} + +void Map3d::reconstruct_buildings(BuildingsPtr& buildings) { + BuildingsPtr newBuildingsToReconstruct; #pragma omp parallel for - for (auto& f : _buildingsPtr) { - if (!f->is_active()) continue; + for (auto& f : buildings) { try { f->reconstruct(); //-- In case of hybrid boolean/constraining reconstruction @@ -345,20 +358,31 @@ void Map3d::reconstruct_buildings() { f->reconstruct(); } } catch (std::exception& e) { - #pragma omp atomic - ++failed; + if (f->is_imported()) { + // try to recover by reconstructing LoD1 from geometry pts + auto importToReconstructBuild = + std::make_shared(std::static_pointer_cast(f)); + _reconstructedBuildingsPtr.push_back(importToReconstructBuild); + _allFeaturesPtr.push_back(importToReconstructBuild); + _buildingsPtr.push_back(importToReconstructBuild); + newBuildingsToReconstruct.push_back(importToReconstructBuild); + } else { + // mark for geojson output + f->mark_as_failed(); + } // add information to log file Config::write_to_log("Building ID: " + f->get_id() + " Failed to reconstruct. Reason: " + e.what()); - // mark for geojson output - f->mark_as_failed(); } } this->clear_inactives(); - std::cout << " Number of successfully reconstructed buildings: " << _buildingsPtr.size() << std::endl; - Config::get().logSummary << "Building reconstruction summary: successfully reconstructed buildings: " - << _buildingsPtr.size() - failed << std::endl; - Config::get().logSummary << " num of failed reconstructions: " - << failed << std::endl; + /* + for (auto& b : newBuildingsToReconstruct) { + _reconstructedBuildingsPtr.push_back(std::static_pointer_cast(b)); + _allFeaturesPtr.push_back(b); + _buildingsPtr.push_back(b); + } + */ + if (!newBuildingsToReconstruct.empty()) this->reconstruct_buildings(newBuildingsToReconstruct); } void Map3d::reconstruct_boundaries() { diff --git a/src/Map3d.h b/src/Map3d.h index 17c4828..8309d71 100644 --- a/src/Map3d.h +++ b/src/Map3d.h @@ -80,6 +80,7 @@ class Map3d { void remove_extra_terrain_pts(); void reconstruct_terrain(); void reconstruct_buildings(); + void reconstruct_buildings(BuildingsPtr& buildings); void reconstruct_boundaries(); void reconstruct_with_flat_terrain(); void solve_building_conflicts(); diff --git a/src/PolyFeature.cpp b/src/PolyFeature.cpp index ba3c09f..fa341e6 100644 --- a/src/PolyFeature.cpp +++ b/src/PolyFeature.cpp @@ -309,6 +309,12 @@ const Polygon_with_holes_2& PolyFeature::get_poly() const { return _poly; } +Polygon_with_attr PolyFeature::get_poly_w_attr() const { + Polygon_with_attr poly; + poly.polygon = _poly; + return poly; +} + const std::vector>& PolyFeature::get_ground_elevations() const { return _groundElevations; } diff --git a/src/PolyFeature.h b/src/PolyFeature.h index e6ec815..5b85abd 100644 --- a/src/PolyFeature.h +++ b/src/PolyFeature.h @@ -68,6 +68,7 @@ class PolyFeature : public TopoFeature { Polygon_with_holes_2& get_poly(); const Polygon_with_holes_2& get_poly() const; + Polygon_with_attr get_poly_w_attr() const; const std::vector>& get_ground_elevations() const; const int get_internal_id() const; MinBbox& get_min_bbox(); diff --git a/src/ReconstructedBuilding.cpp b/src/ReconstructedBuilding.cpp index 3b92047..5f3260e 100644 --- a/src/ReconstructedBuilding.cpp +++ b/src/ReconstructedBuilding.cpp @@ -29,6 +29,7 @@ #include "geomutils.h" #include "LoD12.h" +#include "ImportedBuilding.h" ReconstructedBuilding::ReconstructedBuilding() : Building(), _attributeHeight(-global::largnum), @@ -109,6 +110,14 @@ ReconstructedBuilding::ReconstructedBuilding(const Polygon_with_attr& poly, cons } } +ReconstructedBuilding::ReconstructedBuilding(const std::shared_ptr& importedBuilding) + : Building(importedBuilding->get_poly_w_attr(), importedBuilding->get_internal_id()), + _attributeHeight(-global::largnum), _attributeHeightAdvantage(Config::get().buildingHeightAttrAdv) { + _ptsPtr = importedBuilding->get_points(); + _groundElevations = importedBuilding->get_ground_elevations(); + _id = importedBuilding->get_id(); +} + ReconstructedBuilding::~ReconstructedBuilding() = default; /* diff --git a/src/ReconstructedBuilding.h b/src/ReconstructedBuilding.h index 3536186..4707989 100644 --- a/src/ReconstructedBuilding.h +++ b/src/ReconstructedBuilding.h @@ -38,6 +38,7 @@ class ReconstructedBuilding : public Building { // ReconstructedBuilding(const nlohmann::json& poly); ReconstructedBuilding(const nlohmann::json& poly, const int internalID); ReconstructedBuilding(const Polygon_with_attr& poly, const int internalID); + ReconstructedBuilding(const std::shared_ptr& importedBuilding); ~ReconstructedBuilding(); virtual double get_elevation() override; From c44015cc87d3ebf439a3ca5608cf570b3d2aa202 Mon Sep 17 00:00:00 2001 From: Ivan Paden Date: Fri, 27 Oct 2023 05:26:16 +0200 Subject: [PATCH 09/42] Remove extra --- src/Map3d.cpp | 9 --------- 1 file changed, 9 deletions(-) diff --git a/src/Map3d.cpp b/src/Map3d.cpp index b2d28da..9fd8a07 100644 --- a/src/Map3d.cpp +++ b/src/Map3d.cpp @@ -333,9 +333,7 @@ void Map3d::reconstruct_buildings() { << ". If I cannot find a geometry with that LoD, I will reconstruct in the highest LoD available" << std::endl; } - std::cout << "Total number of _buildingsPtr: " << _buildingsPtr.size() << std::endl; this->reconstruct_buildings(_buildingsPtr); - std::cout << "Total number of _buildingsPtr: " << _buildingsPtr.size() << std::endl; // Gather failed reconstructions int failed = 0; for (auto& b : _buildingsPtr) if (b->has_failed_to_reconstruct()) ++failed; @@ -375,13 +373,6 @@ void Map3d::reconstruct_buildings(BuildingsPtr& buildings) { } } this->clear_inactives(); - /* - for (auto& b : newBuildingsToReconstruct) { - _reconstructedBuildingsPtr.push_back(std::static_pointer_cast(b)); - _allFeaturesPtr.push_back(b); - _buildingsPtr.push_back(b); - } - */ if (!newBuildingsToReconstruct.empty()) this->reconstruct_buildings(newBuildingsToReconstruct); } From b6712203379e9a8d509f48c4f83d1c5c160d98a4 Mon Sep 17 00:00:00 2001 From: Ivan Paden Date: Fri, 27 Oct 2023 06:46:10 +0200 Subject: [PATCH 10/42] Sort out PolyFeature ID situation --- src/Building.cpp | 14 ------------ src/Building.h | 3 --- src/ImportedBuilding.cpp | 32 +++++++++++++--------------- src/ImportedBuilding.h | 6 ++---- src/Map3d.cpp | 17 ++++++--------- src/PolyFeature.cpp | 40 +++++++++-------------------------- src/PolyFeature.h | 8 +++---- src/ReconstructedBuilding.cpp | 18 ++++++---------- src/ReconstructedBuilding.h | 5 ++--- 9 files changed, 46 insertions(+), 97 deletions(-) diff --git a/src/Building.cpp b/src/Building.cpp index b5060ce..5f1e21b 100644 --- a/src/Building.cpp +++ b/src/Building.cpp @@ -42,30 +42,16 @@ Building::Building() : PolyFeature(1), _elevation(-global::largnum), _height(-global::largnum), _ptsPtr(std::make_shared()), _hasFailed(false) {} -Building::Building(const int internalID) - : PolyFeature(1, internalID), _elevation(-global::largnum), _height(-global::largnum), - _ptsPtr(std::make_shared()), _hasFailed(false) {} - Building::Building(const nlohmann::json& poly) : PolyFeature(poly, true, 1), _elevation(-global::largnum), _height(-global::largnum), _ptsPtr(std::make_shared()), _hasFailed(false) {} // 'true' here to check for polygon simplicity -Building::Building(const nlohmann::json& poly, const int internalID) - : PolyFeature(poly, true, 1, internalID), _elevation(-global::largnum), _height(-global::largnum), - _ptsPtr(std::make_shared()), _hasFailed(false) {} - // 'true' here to check for polygon simplicity - Building::Building(const Polygon_with_attr& poly) : PolyFeature(poly, true, 1), _elevation(-global::largnum), _height(-global::largnum), _ptsPtr(std::make_shared()), _hasFailed(false) {} // 'true' here to check for polygon simplicity -Building::Building(const Polygon_with_attr& poly, const int internalID) - : PolyFeature(poly, true, 1, internalID), _elevation(-global::largnum), _height(-global::largnum), - _ptsPtr(std::make_shared()), _hasFailed(false) {} - // 'true' here to check for polygon simplicity - Building::~Building() = default; void Building::insert_point(const Point_3& pt) { diff --git a/src/Building.h b/src/Building.h index 70db150..58fcb1b 100644 --- a/src/Building.h +++ b/src/Building.h @@ -34,11 +34,8 @@ class Building : public PolyFeature { public: Building(); - Building(const int internalID); Building(const nlohmann::json& poly); - Building(const nlohmann::json& poly, const int internalID); Building(const Polygon_with_attr& poly); - Building(const Polygon_with_attr& poly, const int internalID); ~Building(); static void alpha_wrap(const BuildingsPtr& buildings, Mesh& newMesh); diff --git a/src/ImportedBuilding.cpp b/src/ImportedBuilding.cpp index 75e9d6b..4e7a8ce 100644 --- a/src/ImportedBuilding.cpp +++ b/src/ImportedBuilding.cpp @@ -40,14 +40,14 @@ int ImportedBuilding::noBottom = 0; -ImportedBuilding::ImportedBuilding(std::unique_ptr& buildingJson, PointSet3Ptr& importedBuildingPts, const int internalID) - : Building(internalID), _buildingJson(std::move(buildingJson)), - _footprintIdxList(), _parentBuildingID(), _ptMap(), - _appendToBuilding(false), _lodIdx(-1), _footprintPtsIdxList(), _trueHeight(Config::get().importTrueHeight) { +ImportedBuilding::ImportedBuilding(std::unique_ptr& buildingJson, PointSet3Ptr& importedBuildingPts) + : Building(), _buildingJson(std::move(buildingJson)), + _footprintIdxList(), _ptMap(), _appendToBuilding(false), + _lodIdx(-1), _footprintPtsIdxList(), _trueHeight(Config::get().importTrueHeight) { _f_imported = true; // the flag is here to avoid shorten polygons later. todo to fix - //-- Get parent building ID - _parentBuildingID = (*_buildingJson)["parents"].front(); + //-- ID is the partent building ID + _id = (*_buildingJson)["parents"].front(); //-- Define LoD std::map lodGeomLst; @@ -124,7 +124,7 @@ ImportedBuilding::ImportedBuilding(std::unique_ptr& buildingJson pointConnectivity[IO::gen_key_bucket(Point_2(_ptMap.at(ptIdx).x(), _ptMap.at(ptIdx).y()))] = ptIdx; } if (!facePoly.is_simple()) { - Config::write_to_log("Failed to import building: " + this->get_parent_building_id() + Config::write_to_log("Failed to import building: " + this->get_id() + " Reason: Footprint polygon is not simple."); this->deactivate(); return; @@ -141,12 +141,13 @@ ImportedBuilding::ImportedBuilding(std::unique_ptr& buildingJson this->set_footprint_mesh_connectivity(pointConnectivity); } -ImportedBuilding::ImportedBuilding(Mesh& mesh, const int internalID) - : Building(internalID), _buildingJson(std::make_unique()), - _footprintIdxList(), _parentBuildingID(), _appendToBuilding(false), _ptMap(), +ImportedBuilding::ImportedBuilding(Mesh& mesh) + : Building(), _buildingJson(std::make_unique()), + _footprintIdxList(), _appendToBuilding(false), _ptMap(), _lodIdx(-1), _footprintPtsIdxList(), _trueHeight(Config::get().importTrueHeight) { _f_imported = true; // the flag is here to avoid shorten polygons later. todo to fix + _id = std::to_string(_polyInternalID); //-- Get the polygon from the building bottom // group faces pointing down CGAL::Vector_3 downVector(0, 0, -1); @@ -343,8 +344,9 @@ void ImportedBuilding::reconstruct() { this->deactivate(); // Store points to ptsPtr so that it might be used for LoD1 reconstruction for (auto& pt : _ptMap) _ptsPtr->insert(pt.second); - throw std::runtime_error("Importing failed. It could be that the height is lower than minimum, or the " - "mesh connectivity is broken. Trying to reconstruct LoD1 from building points"); + throw std::runtime_error("Importing failed. It could be that the height is" + "\n lower than minimum, or the mesh connectivity is broken." + "\n Trying to reconstruct LoD1.2 from building points"); } /* @@ -417,10 +419,6 @@ const nlohmann::json& ImportedBuilding::get_building_json() const { return *_buildingJson; } -const std::string& ImportedBuilding::get_parent_building_id() const { - return _parentBuildingID; -} - const int ImportedBuilding::get_lod_idx() const { return _lodIdx; } @@ -431,7 +429,7 @@ const bool ImportedBuilding::is_appending() const { void ImportedBuilding::check_simplicity(Polygon_2& ring) { if (!ring.is_simple()) { - Config::write_to_log("Failed to import building: " + this->get_parent_building_id() + Config::write_to_log("Failed to import building: " + this->get_id() + " Reason: Footprint polygon is not simple."); this->deactivate(); return; diff --git a/src/ImportedBuilding.h b/src/ImportedBuilding.h index c30ee3b..bfbce2e 100644 --- a/src/ImportedBuilding.h +++ b/src/ImportedBuilding.h @@ -38,8 +38,8 @@ class ImportedBuilding : public Building { ImportedBuilding() = delete; ImportedBuilding(std::unique_ptr& buildingJson, - PointSet3Ptr& importedBuildingPts, const int internalID); - ImportedBuilding(Mesh& mesh, const int internalID); + PointSet3Ptr& importedBuildingPts); + ImportedBuilding(Mesh& mesh); ~ImportedBuilding(); virtual double get_elevation() override; @@ -49,7 +49,6 @@ class ImportedBuilding : public Building { void append_nonground_part(const std::shared_ptr& other); const nlohmann::json& get_building_json() const; - const std::string& get_parent_building_id() const; const int get_lod_idx() const; const bool is_appending() const; @@ -61,7 +60,6 @@ class ImportedBuilding : public Building { std::unique_ptr _buildingJson; std::vector _footprintIdxList; std::vector> _footprintPtsIdxList; - std::string _parentBuildingID; bool _appendToBuilding; bool _trueHeight; int _lodIdx; diff --git a/src/Map3d.cpp b/src/Map3d.cpp index 9fd8a07..17ee023 100644 --- a/src/Map3d.cpp +++ b/src/Map3d.cpp @@ -106,9 +106,8 @@ void Map3d::set_features() { //-- Add features - order in _allFeaturesPtr defines the advantage in marking terrain polygons //- Buildings - int internalID = 0; for (auto& poly : _polygonsBuildings) { - auto building = std::make_shared(*poly, internalID++); + auto building = std::make_shared(*poly); _reconstructedBuildingsPtr.push_back(building); _buildingsPtr.push_back(building); _allFeaturesPtr.push_back(building); @@ -119,10 +118,8 @@ void Map3d::set_features() { std::cout << "Importing CityJSON geometries" << std::endl; std::vector> appendingBuildings; - internalID = 0; for (auto& importedBuilding: _importedBuildingsJSON) { - auto explicitCityJSONGeom = std::make_shared(importedBuilding, _importedBuildingsPts, - internalID++); + auto explicitCityJSONGeom = std::make_shared(importedBuilding, _importedBuildingsPts); if (!explicitCityJSONGeom->is_appending()) { _importedBuildingsPtr.push_back(explicitCityJSONGeom); _buildingsPtr.push_back(explicitCityJSONGeom); @@ -134,7 +131,7 @@ void Map3d::set_features() { //- Check for building parts that do not have footprint and append to another instance of the same building for (auto& b: appendingBuildings) { for (auto& importedBuilding: _importedBuildingsPtr) { - if (b->get_parent_building_id() == importedBuilding->get_parent_building_id()) { + if (b->get_id() == importedBuilding->get_id()) { importedBuilding->append_nonground_part(b); break; } @@ -145,7 +142,7 @@ void Map3d::set_features() { } else if (!_importedBuildingsOther.empty()) { std::cout << "Importing geometries" << std::endl; for (auto& mesh : _importedBuildingsOther) { - auto explicitOBJGeom = std::make_shared(mesh, internalID++); + auto explicitOBJGeom = std::make_shared(mesh); _importedBuildingsPtr.push_back(explicitOBJGeom); _buildingsPtr.push_back(explicitOBJGeom); _allFeaturesPtr.push_back(explicitOBJGeom); @@ -563,14 +560,14 @@ void Map3d::clear_inactives() { for (auto& importedBuilding: _importedBuildingsPtr) { if (!importedBuilding->is_active()) { auto it = std::find(inactiveBuildingIdxs.begin(), inactiveBuildingIdxs.end(), - importedBuilding->get_parent_building_id()); + importedBuilding->get_id()); if (it == inactiveBuildingIdxs.end()) - inactiveBuildingIdxs.push_back(importedBuilding->get_parent_building_id()); + inactiveBuildingIdxs.push_back(importedBuilding->get_id()); } } for (unsigned long i = 0; i < _importedBuildingsPtr.size();) { auto it = std::find(inactiveBuildingIdxs.begin(), inactiveBuildingIdxs.end(), - _importedBuildingsPtr[i]->get_parent_building_id()); + _importedBuildingsPtr[i]->get_id()); if (it == inactiveBuildingIdxs.end()) ++i; else { _importedBuildingsPtr[i]->deactivate(); diff --git a/src/PolyFeature.cpp b/src/PolyFeature.cpp index fa341e6..bc55623 100644 --- a/src/PolyFeature.cpp +++ b/src/PolyFeature.cpp @@ -37,19 +37,15 @@ #endif PolyFeature::PolyFeature() - : TopoFeature(), _poly(), _groundElevations(), _polyInternalID(), + : TopoFeature(), _poly(), _groundElevations(), _polyInternalID(new_internal_id()), _groundElevation(-global::largnum), _minBbox() {} PolyFeature::PolyFeature(const int outputLayerID) - : TopoFeature(outputLayerID), _poly(), _groundElevations(), _polyInternalID(), + : TopoFeature(outputLayerID), _poly(), _groundElevations(), _polyInternalID(new_internal_id()), _groundElevation(-global::largnum), _minBbox() {} -PolyFeature::PolyFeature(const int outputLayerID, const int internalID) - : TopoFeature(outputLayerID), _groundElevations(), _polyInternalID(internalID), - _groundElevation(-global::largnum), _minBbox() {} - PolyFeature::PolyFeature(const nlohmann::json& poly, const bool checkSimplicity) - : TopoFeature(), _groundElevations(), _polyInternalID(), + : TopoFeature(), _groundElevations(), _polyInternalID(new_internal_id()), _groundElevation(-global::largnum), _minBbox() { this->parse_json_poly(poly, checkSimplicity); } @@ -63,19 +59,8 @@ PolyFeature::PolyFeature(const nlohmann::json& poly, const bool checkSimplicity, PolyFeature::PolyFeature(const nlohmann::json& poly, const int outputLayerID) : PolyFeature(poly, false, outputLayerID) {} -PolyFeature::PolyFeature(const nlohmann::json& poly, const bool checkSimplicity, - const int outputLayerID, const int internalID) - : PolyFeature(poly, checkSimplicity) { - _polyInternalID = internalID; - _outputLayerID = outputLayerID; - if (_outputLayerID >= _numOfOutputLayers) _numOfOutputLayers = _outputLayerID + 1; -} - -PolyFeature::PolyFeature(const nlohmann::json& poly, const int outputLayerID, const int internalID) - : PolyFeature(poly, false, outputLayerID, internalID) {} - PolyFeature::PolyFeature(const Polygon_with_attr& poly, const bool checkSimplicity) - : TopoFeature(), _groundElevations(), _polyInternalID(), + : TopoFeature(), _groundElevations(), _polyInternalID(new_internal_id()), _groundElevation(-global::largnum), _minBbox() { bool isOuterRing = true; for (auto& ring : poly.polygon.rings()) { @@ -122,19 +107,10 @@ PolyFeature::PolyFeature(const Polygon_with_attr& poly, const bool checkSimplici PolyFeature::PolyFeature(const Polygon_with_attr& poly, const int outputLayerID) : PolyFeature(poly, false, outputLayerID) {} -PolyFeature::PolyFeature(const Polygon_with_attr& poly, const bool checkSimplicity, - const int outputLayerID, const int internalID) - : PolyFeature(poly, checkSimplicity) { - _polyInternalID = internalID; - _outputLayerID = outputLayerID; - if (_outputLayerID >= _numOfOutputLayers) _numOfOutputLayers = _outputLayerID + 1; -} - -PolyFeature::PolyFeature(const Polygon_with_attr& poly, const int outputLayerID, const int internalID) - : PolyFeature(poly, false, outputLayerID, internalID) {} - PolyFeature::~PolyFeature() = default; +int PolyFeature::_numOfPolyFeatures = 0; + void PolyFeature::calc_footprint_elevation_nni(const DT& dt) { typedef std::vector> Point_coordinate_vector; DT::Face_handle fh = nullptr; @@ -301,6 +277,10 @@ void PolyFeature::clear_feature() { _mesh.clear(); } +int PolyFeature::new_internal_id() { + return ++_numOfPolyFeatures; +} + Polygon_with_holes_2& PolyFeature::get_poly() { return _poly; } diff --git a/src/PolyFeature.h b/src/PolyFeature.h index 5b85abd..fa2ecc3 100644 --- a/src/PolyFeature.h +++ b/src/PolyFeature.h @@ -34,17 +34,12 @@ class PolyFeature : public TopoFeature { public: PolyFeature(); PolyFeature(const int outputLayerID); - PolyFeature(const int outputLayerID, const int internalID); PolyFeature(const nlohmann::json& poly, const bool checkSimplicity = false); PolyFeature(const nlohmann::json& poly, const bool checkSimplicity, const int outputLayerID); - PolyFeature(const nlohmann::json& poly, const bool checkSimplicity, const int outputLayerID, const int internalID); PolyFeature(const nlohmann::json& poly, const int outputLayerID); - PolyFeature(const nlohmann::json& poly, const int outputLayerID, const int internalID); PolyFeature(const Polygon_with_attr& poly, const bool checkSimplicity = false); PolyFeature(const Polygon_with_attr& poly, const bool checkSimplicity, const int outputLayerID); - PolyFeature(const Polygon_with_attr& poly, const bool checkSimplicity, const int outputLayerID, const int internalID); PolyFeature(const Polygon_with_attr& poly, const int outputLayerID); - PolyFeature(const Polygon_with_attr& poly, const int outputLayerID, const int internalID); virtual ~PolyFeature(); void calc_footprint_elevation_nni(const DT& dt); @@ -74,12 +69,15 @@ class PolyFeature : public TopoFeature { MinBbox& get_min_bbox(); protected: + static int _numOfPolyFeatures; + int _polyInternalID; Polygon_with_holes_2 _poly; std::vector> _groundElevations; double _groundElevation; MinBbox _minBbox; + int new_internal_id(); void parse_json_poly(const nlohmann::json& poly, const bool checkSimplicity); }; diff --git a/src/ReconstructedBuilding.cpp b/src/ReconstructedBuilding.cpp index 5f3260e..9fa71cc 100644 --- a/src/ReconstructedBuilding.cpp +++ b/src/ReconstructedBuilding.cpp @@ -35,10 +35,6 @@ ReconstructedBuilding::ReconstructedBuilding() : Building(), _attributeHeight(-global::largnum), _attributeHeightAdvantage(Config::get().buildingHeightAttrAdv) {} -ReconstructedBuilding::ReconstructedBuilding(const int internalID) - : Building(internalID), _attributeHeight(-global::largnum), - _attributeHeightAdvantage(Config::get().buildingHeightAttrAdv) {} - ReconstructedBuilding::ReconstructedBuilding(const Mesh& mesh) : ReconstructedBuilding() { _mesh = mesh; @@ -61,13 +57,13 @@ ReconstructedBuilding::ReconstructedBuilding(const nlohmann::json& poly) } */ -ReconstructedBuilding::ReconstructedBuilding(const nlohmann::json& poly, const int internalID) - : Building(poly, internalID), _attributeHeight(-global::largnum), +ReconstructedBuilding::ReconstructedBuilding(const nlohmann::json& poly) + : Building(poly), _attributeHeight(-global::largnum), _attributeHeightAdvantage(Config::get().buildingHeightAttrAdv) { if (!Config::get().buildingUniqueId.empty() && poly["properties"].contains(Config::get().buildingUniqueId)) { _id = poly["properties"][Config::get().buildingUniqueId].dump(); } else { - _id = std::to_string(internalID); + _id = std::to_string(_polyInternalID); } if (poly["properties"].contains(Config::get().buildingHeightAttribute)) { if (poly["properties"][Config::get().buildingHeightAttribute].is_number()) { @@ -85,15 +81,15 @@ ReconstructedBuilding::ReconstructedBuilding(const nlohmann::json& poly, const i } } -ReconstructedBuilding::ReconstructedBuilding(const Polygon_with_attr& poly, const int internalID) - : Building(poly, internalID), _attributeHeight(-global::largnum), +ReconstructedBuilding::ReconstructedBuilding(const Polygon_with_attr& poly) + : Building(poly), _attributeHeight(-global::largnum), _attributeHeightAdvantage(Config::get().buildingHeightAttrAdv) { // Check for the polygon ID attribute auto idIt = poly.attributes.find(Config::get().buildingUniqueId); if (idIt != poly.attributes.end()) { _id = idIt->second; } else { - _id = std::to_string(internalID); + _id = std::to_string(_polyInternalID); } // Check for the building height attribute auto buildingHeightAttrIt = poly.attributes.find(Config::get().buildingHeightAttribute); @@ -111,7 +107,7 @@ ReconstructedBuilding::ReconstructedBuilding(const Polygon_with_attr& poly, cons } ReconstructedBuilding::ReconstructedBuilding(const std::shared_ptr& importedBuilding) - : Building(importedBuilding->get_poly_w_attr(), importedBuilding->get_internal_id()), + : Building(importedBuilding->get_poly_w_attr()), _attributeHeight(-global::largnum), _attributeHeightAdvantage(Config::get().buildingHeightAttrAdv) { _ptsPtr = importedBuilding->get_points(); _groundElevations = importedBuilding->get_ground_elevations(); diff --git a/src/ReconstructedBuilding.h b/src/ReconstructedBuilding.h index 4707989..a7db236 100644 --- a/src/ReconstructedBuilding.h +++ b/src/ReconstructedBuilding.h @@ -33,11 +33,10 @@ class ReconstructedBuilding : public Building { public: ReconstructedBuilding(); - ReconstructedBuilding(const int internalID); ReconstructedBuilding(const Mesh& mesh); // ReconstructedBuilding(const nlohmann::json& poly); - ReconstructedBuilding(const nlohmann::json& poly, const int internalID); - ReconstructedBuilding(const Polygon_with_attr& poly, const int internalID); + ReconstructedBuilding(const nlohmann::json& poly); + ReconstructedBuilding(const Polygon_with_attr& poly); ReconstructedBuilding(const std::shared_ptr& importedBuilding); ~ReconstructedBuilding(); From 40f7e94f3769aa31804dad5a7596eb634b8e44ac Mon Sep 17 00:00:00 2001 From: Ivan Paden Date: Fri, 27 Oct 2023 17:50:37 +0200 Subject: [PATCH 11/42] Refactor fallback --- src/ImportedBuilding.cpp | 1 - src/Map3d.cpp | 57 ++++++++++++++++++++-------------------- src/Map3d.h | 2 +- 3 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/ImportedBuilding.cpp b/src/ImportedBuilding.cpp index 4e7a8ce..e6d5342 100644 --- a/src/ImportedBuilding.cpp +++ b/src/ImportedBuilding.cpp @@ -341,7 +341,6 @@ void ImportedBuilding::reconstruct() { PMP::triangulate_faces(_mesh); if (this->get_height() < Config::get().minHeight) { - this->deactivate(); // Store points to ptsPtr so that it might be used for LoD1 reconstruction for (auto& pt : _ptMap) _ptsPtr->insert(pt.second); throw std::runtime_error("Importing failed. It could be that the height is" diff --git a/src/Map3d.cpp b/src/Map3d.cpp index 17ee023..d568112 100644 --- a/src/Map3d.cpp +++ b/src/Map3d.cpp @@ -330,7 +330,9 @@ void Map3d::reconstruct_buildings() { << ". If I cannot find a geometry with that LoD, I will reconstruct in the highest LoD available" << std::endl; } - this->reconstruct_buildings(_buildingsPtr); + # pragma omp parallel for + for (auto& b : _buildingsPtr) this->reconstruct_one_building(b); + this->clear_inactives(); // Gather failed reconstructions int failed = 0; for (auto& b : _buildingsPtr) if (b->has_failed_to_reconstruct()) ++failed; @@ -341,36 +343,33 @@ void Map3d::reconstruct_buildings() { << failed << std::endl; } -void Map3d::reconstruct_buildings(BuildingsPtr& buildings) { - BuildingsPtr newBuildingsToReconstruct; - #pragma omp parallel for - for (auto& f : buildings) { - try { - f->reconstruct(); - //-- In case of hybrid boolean/constraining reconstruction - if (Config::get().clip && !Config::get().handleSelfIntersect && f->has_self_intersections()) { - f->set_clip_flag(false); - f->reconstruct(); - } - } catch (std::exception& e) { - if (f->is_imported()) { - // try to recover by reconstructing LoD1 from geometry pts - auto importToReconstructBuild = - std::make_shared(std::static_pointer_cast(f)); - _reconstructedBuildingsPtr.push_back(importToReconstructBuild); - _allFeaturesPtr.push_back(importToReconstructBuild); - _buildingsPtr.push_back(importToReconstructBuild); - newBuildingsToReconstruct.push_back(importToReconstructBuild); - } else { - // mark for geojson output - f->mark_as_failed(); - } - // add information to log file - Config::write_to_log("Building ID: " + f->get_id() + " Failed to reconstruct. Reason: " + e.what()); +void Map3d::reconstruct_one_building(std::shared_ptr& building) { + try { + building->reconstruct(); + //-- In case of hybrid boolean/constraining reconstruction + if (Config::get().clip && !Config::get().handleSelfIntersect && building->has_self_intersections()) { + building->set_clip_flag(false); + building->reconstruct(); + } + } catch (std::exception& e) { + // add information to log file + Config::write_to_log("Building ID: " + building->get_id() + " Failed to reconstruct. Reason: " + e.what()); + // fallback for failed reconstruction of imported buildings + if (building->is_imported()) { + building->deactivate(); // deactivate this and use reconstructed instead + // try to recover by reconstructing LoD1.2 from geometry pts + auto importToReconstructBuild = + std::make_shared(std::static_pointer_cast(building)); + _reconstructedBuildingsPtr.push_back(importToReconstructBuild); + _allFeaturesPtr.push_back(importToReconstructBuild); + _buildingsPtr.push_back(importToReconstructBuild); + std::shared_ptr buildToReconstruct = importToReconstructBuild; + this->reconstruct_one_building(buildToReconstruct); + } else { + // mark for geojson output + building->mark_as_failed(); } } - this->clear_inactives(); - if (!newBuildingsToReconstruct.empty()) this->reconstruct_buildings(newBuildingsToReconstruct); } void Map3d::reconstruct_boundaries() { diff --git a/src/Map3d.h b/src/Map3d.h index 8309d71..71dd4d8 100644 --- a/src/Map3d.h +++ b/src/Map3d.h @@ -80,7 +80,7 @@ class Map3d { void remove_extra_terrain_pts(); void reconstruct_terrain(); void reconstruct_buildings(); - void reconstruct_buildings(BuildingsPtr& buildings); + void reconstruct_one_building(std::shared_ptr& building); void reconstruct_boundaries(); void reconstruct_with_flat_terrain(); void solve_building_conflicts(); From 6e79408da86a17315826f6a26b4f5c30af89528d Mon Sep 17 00:00:00 2001 From: Ivan Paden Date: Fri, 27 Oct 2023 23:09:51 +0200 Subject: [PATCH 12/42] Make sure inactive buildings are not reconstructed --- src/Map3d.cpp | 6 ++++-- src/PolyFeature.cpp | 4 ++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/src/Map3d.cpp b/src/Map3d.cpp index d568112..bc14f8a 100644 --- a/src/Map3d.cpp +++ b/src/Map3d.cpp @@ -331,8 +331,10 @@ void Map3d::reconstruct_buildings() { << std::endl; } # pragma omp parallel for - for (auto& b : _buildingsPtr) this->reconstruct_one_building(b); - this->clear_inactives(); + for (auto& b : _buildingsPtr) { + if (b->is_active()) this->reconstruct_one_building(b); + } + this->clear_inactives(); // in case of imported-reconstructed fallback // Gather failed reconstructions int failed = 0; for (auto& b : _buildingsPtr) if (b->has_failed_to_reconstruct()) ++failed; diff --git a/src/PolyFeature.cpp b/src/PolyFeature.cpp index bc55623..4872e35 100644 --- a/src/PolyFeature.cpp +++ b/src/PolyFeature.cpp @@ -177,8 +177,8 @@ void PolyFeature::calc_footprint_elevation_linear(const DT& dt) { double PolyFeature::ground_elevation() { if (_groundElevation < -global::largnum + global::smallnum) { - if (_groundElevations.empty())throw std::runtime_error("Polygon elevations missing!" - " Cannot calculate average"); + if (_groundElevations.empty()) throw std::runtime_error("Polygon elevations missing!" + " Cannot calculate average"); // calculating base elevation as 95 percentile of outer ring _groundElevation = geomutils::percentile(_groundElevations.front(), 0.95); } From 2f2252886f6e39b2f1a209c95d91a36ff4d6a320 Mon Sep 17 00:00:00 2001 From: Ivan Paden Date: Fri, 27 Oct 2023 23:17:09 +0200 Subject: [PATCH 13/42] Update changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cc5769..f261183 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## [Unreleased] +### Changed +- Improved fallbacks in case building import fails in late stages +### Fixed +- Minor bugfixes + ## [0.4.3] - 2023-08-25 ### Fixed - Issue with GDAL on Ubuntu 20.04 From 98cf4f7a65d08eec9cb00a19cadd7475b4021e56 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Mon, 30 Oct 2023 17:18:58 -0600 Subject: [PATCH 14/42] Attempt to compile win64 --- .github/workflows/win_build.yml | 37 ++++++++++++++++++++++++ CMakeLists.txt | 22 +++++++++++--- src/Map3d.cpp | 6 ++-- src/PointCloud.cpp | 7 +++-- src/types.h | 10 ++++++- tools/prepare_point_cloud/CMakeLists.txt | 2 +- vcpkg.json | 15 ++++++++++ 7 files changed, 88 insertions(+), 11 deletions(-) create mode 100644 .github/workflows/win_build.yml create mode 100644 vcpkg.json diff --git a/.github/workflows/win_build.yml b/.github/workflows/win_build.yml new file mode 100644 index 0000000..838848b --- /dev/null +++ b/.github/workflows/win_build.yml @@ -0,0 +1,37 @@ +# This is a basic workflow to help you get started with Actions + +name: windows build test + +# Controls when the action will run. Triggers the workflow on push or pull request +# events but only for the master branch +on: + push: + branches: [ master, development, win ] + +# A workflow run is made up of one or more jobs that can run sequentially or in parallel +jobs: + Windows-build: + name: Build Windows + runs-on: windows-latest + env: + VCPKG_DEFAULT_TRIPLET: x64-windows + VCPKG_INSTALLATION_ROOT: C:\vcpkg + VCPKG_FEATURE_FLAGS: manifests + steps: + - uses: actions/checkout@v2 + - name: Build + run: | + vcpkg install + mkdir Release + cd Release + cmake .. -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows -DCMAKE_INSTALL_PREFIX=C:\Software -DCMAKE_PREFIX_PATH=Release\vcpkg_installed\x64-windows\share\lastools + cmake --build . --parallel 4 --config Release + - name: Package binary files + run: | + cd Release + 7z a city4cfd-win64.zip .\Release\* + - name: Upload binary files as artifact + uses: actions/upload-artifact@master + with: + name: city4cfd-win64 + path: Release/3dfier-win64.zip diff --git a/CMakeLists.txt b/CMakeLists.txt index 525242e..2a5ac86 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -4,15 +4,29 @@ project(city4cfd) #set( CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS true ) -set(CMAKE_CXX_FLAGS "-O3") +set(CMAKE_CXX_FLAGS "-O2") set(CMAKE_BUILD_TYPE "Release") -#if (COMMAND cmake_policy) -# cmake_policy(SET CMP0003 NEW) -#endif() +if (COMMAND cmake_policy) + cmake_policy(SET CMP0003 NEW) +endif() + +if (MSVC) + add_definitions(-DNOMINMAX) + add_definitions("/EHsc") +endif (MSVC) # BOOST find_package(Boost 1.66 REQUIRED COMPONENTS filesystem locale) +if (WIN32) + FIND_PACKAGE(Boost) + if (Boost_FOUND) + INCLUDE_DIRECTORIES(${Boost_INCLUDE_DIR}) + ADD_DEFINITIONS( "-DHAS_BOOST" ) + set(Boost_USE_STATIC_LIBS ON) + set(Boost_ARCHITECTURE "-x64") + endif() +endif (WIN32) # CGAL find_package(CGAL REQUIRED QUIET COMPONENTS) diff --git a/src/Map3d.cpp b/src/Map3d.cpp index 20267ad..187bfde 100644 --- a/src/Map3d.cpp +++ b/src/Map3d.cpp @@ -335,7 +335,9 @@ void Map3d::reconstruct_buildings() { } int failed = 0; #pragma omp parallel for - for (auto& f : _buildingsPtr) { + for (int i = 0; i < _buildingsPtr.size(); ++i) { + //for (auto& f : _buildingsPtr) { // MSVC doesn't like range loops with OMP + auto& f = _buildingsPtr[i]; if (!f->is_active()) continue; try { f->reconstruct(); @@ -627,4 +629,4 @@ void Map3d::set_footprint_elevation(T& features) { //- Explicit template instantiation template void Map3d::set_footprint_elevation (BuildingsPtr& feature); template void Map3d::set_footprint_elevation(SurfaceLayersPtr& feature); -template void Map3d::set_footprint_elevation (PolyFeaturesPtr& feature); \ No newline at end of file +template void Map3d::set_footprint_elevation (PolyFeaturesPtr& feature); diff --git a/src/PointCloud.cpp b/src/PointCloud.cpp index 1005cd9..6b2d5dd 100644 --- a/src/PointCloud.cpp +++ b/src/PointCloud.cpp @@ -243,8 +243,9 @@ void PointCloud::buffer_flat_edges(const PolyFeaturesPtr& avgFeatures, std::vector offsets{0.001}; std::vector polyList; #pragma omp parallel for - for (auto& f: avgFeatures) { - auto& poly = f->get_poly().outer_boundary(); + for (int i = 0; i < avgFeatures.size(); ++i) { + //for (auto& f: avgFeatures) { // MSVC doesn't like range loop with OMP + auto& poly = avgFeatures[i]->get_poly().outer_boundary(); // set the frame boost::optional margin = CGAL::compute_outer_frame_margin(poly.begin(), poly.end(), offsets.back()); CGAL::Bbox_2 bbox = CGAL::bbox_2(poly.begin(), poly.end()); @@ -364,4 +365,4 @@ const Point_set_3& PointCloud::get_terrain() const { const Point_set_3& PointCloud::get_buildings() const { return _pointCloudBuildings; -} \ No newline at end of file +} diff --git a/src/types.h b/src/types.h index 5262876..92c7eae 100644 --- a/src/types.h +++ b/src/types.h @@ -30,6 +30,14 @@ #include "nlohmann/json.hpp" +#ifndef M_PI +#define M_PI 3.14159265358979323846264338327950288 +#endif + +#ifndef M_PI_2 +#define M_PI_2 1.57079632679489661923132169163975144 +#endif + //-- Typedefs for smart pointers class Building; class Boundary; class TopoFeature; class PolyFeature; class Terrain; class SurfaceLayer; @@ -73,4 +81,4 @@ namespace global { const double smallnum = 1e-7; } -#endif //CITY4CFD_TYPES_H \ No newline at end of file +#endif //CITY4CFD_TYPES_H diff --git a/tools/prepare_point_cloud/CMakeLists.txt b/tools/prepare_point_cloud/CMakeLists.txt index 18da6b6..f901acb 100644 --- a/tools/prepare_point_cloud/CMakeLists.txt +++ b/tools/prepare_point_cloud/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.9) project(city4cfd_pcprep) -set(CMAKE_CXX_FLAGS "-O3") +set(CMAKE_CXX_FLAGS "-O2") set(CMAKE_BUILD_TYPE "Release") #if (COMMAND cmake_policy) diff --git a/vcpkg.json b/vcpkg.json new file mode 100644 index 0000000..d967cc8 --- /dev/null +++ b/vcpkg.json @@ -0,0 +1,15 @@ +{ + "name": "city4cfd", + "version-string": "0.4.3", + "dependencies": [ + "boost-program-options", + "boost-geometry", + "boost-locale", + "boost-chrono", + "boost-system", + "boost-filesystem", + "eigen3", + "cgal", + "gdal" + ] +} From 6f1aa518a144f9fd47710a24ca6fd2edf5aeb31d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Mon, 30 Oct 2023 22:09:27 -0600 Subject: [PATCH 15/42] Fix compile error --- thirdparty/CGAL/include/CGAL/IO/read_las_points.h | 2 +- thirdparty/CGAL/include/CGAL/IO/write_las_points.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/thirdparty/CGAL/include/CGAL/IO/read_las_points.h b/thirdparty/CGAL/include/CGAL/IO/read_las_points.h index a2701b9..01f8cd8 100644 --- a/thirdparty/CGAL/include/CGAL/IO/read_las_points.h +++ b/thirdparty/CGAL/include/CGAL/IO/read_las_points.h @@ -44,7 +44,7 @@ # pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif -#define USE_AS_DLL +#define USE_AS_DLL 1 #include #undef USE_AS_DLL diff --git a/thirdparty/CGAL/include/CGAL/IO/write_las_points.h b/thirdparty/CGAL/include/CGAL/IO/write_las_points.h index 0a67f57..620e203 100644 --- a/thirdparty/CGAL/include/CGAL/IO/write_las_points.h +++ b/thirdparty/CGAL/include/CGAL/IO/write_las_points.h @@ -38,7 +38,7 @@ # pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif -#define USE_AS_DLL +#define USE_AS_DLL 1 #include #include #include From dc7e82011f2f4ec801ff273d063efe6f3ead73c9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Tue, 31 Oct 2023 00:32:19 -0600 Subject: [PATCH 16/42] Try to fix compilation error --- thirdparty/CGAL/include/CGAL/IO/read_las_points.h | 2 +- thirdparty/CGAL/include/CGAL/IO/write_las_points.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/thirdparty/CGAL/include/CGAL/IO/read_las_points.h b/thirdparty/CGAL/include/CGAL/IO/read_las_points.h index 01f8cd8..9613d6f 100644 --- a/thirdparty/CGAL/include/CGAL/IO/read_las_points.h +++ b/thirdparty/CGAL/include/CGAL/IO/read_las_points.h @@ -46,7 +46,7 @@ #define USE_AS_DLL 1 #include -#undef USE_AS_DLL +//#undef USE_AS_DLL #ifdef __GNUC__ # pragma GCC diagnostic pop diff --git a/thirdparty/CGAL/include/CGAL/IO/write_las_points.h b/thirdparty/CGAL/include/CGAL/IO/write_las_points.h index 620e203..f4afa3a 100644 --- a/thirdparty/CGAL/include/CGAL/IO/write_las_points.h +++ b/thirdparty/CGAL/include/CGAL/IO/write_las_points.h @@ -42,7 +42,7 @@ #include #include #include -#undef USE_AS_DLL +//#undef USE_AS_DLL #ifdef __GNUC__ # pragma GCC diagnostic pop From 1ef7ee97691de85c5022f404e3f4ec7aad87631a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Tue, 31 Oct 2023 13:17:29 -0600 Subject: [PATCH 17/42] Try to fix compile error --- thirdparty/CGAL/include/CGAL/IO/read_las_points.h | 4 ++-- thirdparty/CGAL/include/CGAL/IO/write_las_points.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/thirdparty/CGAL/include/CGAL/IO/read_las_points.h b/thirdparty/CGAL/include/CGAL/IO/read_las_points.h index 9613d6f..aab96cb 100644 --- a/thirdparty/CGAL/include/CGAL/IO/read_las_points.h +++ b/thirdparty/CGAL/include/CGAL/IO/read_las_points.h @@ -44,9 +44,9 @@ # pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif -#define USE_AS_DLL 1 +#define COMPILE_AS_DLL 1 #include -//#undef USE_AS_DLL +#undef COMPILE_AS_DLL #ifdef __GNUC__ # pragma GCC diagnostic pop diff --git a/thirdparty/CGAL/include/CGAL/IO/write_las_points.h b/thirdparty/CGAL/include/CGAL/IO/write_las_points.h index f4afa3a..2795d7a 100644 --- a/thirdparty/CGAL/include/CGAL/IO/write_las_points.h +++ b/thirdparty/CGAL/include/CGAL/IO/write_las_points.h @@ -38,11 +38,11 @@ # pragma GCC diagnostic ignored "-Wstrict-aliasing" #endif -#define USE_AS_DLL 1 +#define COMPILE_AS_DLL 1 #include #include #include -//#undef USE_AS_DLL +#undef COMPILE_AS_DLL #ifdef __GNUC__ # pragma GCC diagnostic pop From 1711dce9ebf78f1e2081665cb7d5e573776e9982 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Tue, 31 Oct 2023 13:23:02 -0600 Subject: [PATCH 18/42] Further changes --- thirdparty/LAStools/CMakeLists.txt | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/thirdparty/LAStools/CMakeLists.txt b/thirdparty/LAStools/CMakeLists.txt index ea62b23..112eac5 100644 --- a/thirdparty/LAStools/CMakeLists.txt +++ b/thirdparty/LAStools/CMakeLists.txt @@ -6,12 +6,11 @@ add_definitions(-w) if (!MSVC) add_compile_options(-O3 -Wall -Wno-strict-aliasing) + option(BUILD_SHARED_LIBS "Build LASlib as DLL" OFF) else() - add_definitions(-D_CRT_SECURE_NO_WARNINGS) + add_definitions(-DCOMPILE_AS_DLL -D_CRT_SECURE_NO_WARNINGS) endif() -option(BUILD_SHARED_LIBS "Build LASlib as DLL" OFF) - if (BUILD_SHARED_LIBS AND UNIX AND NOT APPLE) set(CMAKE_INSTALL_RPATH "${CMAKE_INSTALL_PREFIX}/lib/LASlib") endif() From 08d9140ca2c78579c192e2e17e26b9abe3c460ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Tue, 31 Oct 2023 16:16:32 -0600 Subject: [PATCH 19/42] Add changes to cmakelists --- thirdparty/CSF/CMakeLists.txt | 2 +- thirdparty/CSF/src/CMakeLists.txt | 6 +++++- thirdparty/LAStools/CMakeLists.txt | 1 + 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/thirdparty/CSF/CMakeLists.txt b/thirdparty/CSF/CMakeLists.txt index e0563d5..2300e32 100644 --- a/thirdparty/CSF/CMakeLists.txt +++ b/thirdparty/CSF/CMakeLists.txt @@ -3,4 +3,4 @@ project(CSF LANGUAGES CXX) add_subdirectory(src) -set(BUILD_SHARED_LIBS "Build as shared library" OFF) \ No newline at end of file +set(BUILD_SHARED_LIBS "Build as shared library" OFF) diff --git a/thirdparty/CSF/src/CMakeLists.txt b/thirdparty/CSF/src/CMakeLists.txt index 45429ad..d502515 100644 --- a/thirdparty/CSF/src/CMakeLists.txt +++ b/thirdparty/CSF/src/CMakeLists.txt @@ -22,7 +22,11 @@ set(CSF_HEADERS ) add_library(CSF ${CSF_SOURCES} ${CSF_HEADERS}) -target_compile_options(CSF PRIVATE -Werror -Wall -Wextra -Wno-unused-private-field) +if (!MSVC) + target_compile_options(CSF PRIVATE -Werror -Wall -Wextra -Wno-unused-private-field) +else() + target_compile_options(CSF PRIVATE -Wall) +endif() if (OpenMP_CXX_FOUND) target_link_libraries(CSF PUBLIC OpenMP::OpenMP_CXX) diff --git a/thirdparty/LAStools/CMakeLists.txt b/thirdparty/LAStools/CMakeLists.txt index 112eac5..67ffe79 100644 --- a/thirdparty/LAStools/CMakeLists.txt +++ b/thirdparty/LAStools/CMakeLists.txt @@ -8,6 +8,7 @@ if (!MSVC) add_compile_options(-O3 -Wall -Wno-strict-aliasing) option(BUILD_SHARED_LIBS "Build LASlib as DLL" OFF) else() + add_compile_options(-O2) add_definitions(-DCOMPILE_AS_DLL -D_CRT_SECURE_NO_WARNINGS) endif() From 4b02a5bc18c57e00a152d0649a15fed3c3f78546 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Tue, 31 Oct 2023 19:26:57 -0600 Subject: [PATCH 20/42] Modify the win64 action --- .github/workflows/build.yml | 16 ++++++++++++++++ .../{win_build.yml => release-win64.yml} | 9 ++++----- thirdparty/CSF/src/CMakeLists.txt | 2 -- 3 files changed, 20 insertions(+), 7 deletions(-) rename .github/workflows/{win_build.yml => release-win64.yml} (88%) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c1e63ab..af1a46d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -48,6 +48,22 @@ jobs: mkdir build && cd build cmake .. && make -j4 + build_win64: + runs-on: windows-latest + env: + VCPKG_DEFAULT_TRIPLET: x64-windows + VCPKG_INSTALLATION_ROOT: C:\vcpkg + VCPKG_FEATURE_FLAGS: manifests + steps: + - uses: actions/checkout@v2 + - name: Build + run: | + vcpkg install + mkdir Release + cd Release + cmake .. -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows -DCMAKE_INSTALL_PREFIX=C:\Software -DCMAKE_PREFIX_PATH=Release\vcpkg_installed\x64-windows\share\lastools + cmake --build . --parallel 4 --config Release + build_docker: runs-on: ubuntu-latest steps: diff --git a/.github/workflows/win_build.yml b/.github/workflows/release-win64.yml similarity index 88% rename from .github/workflows/win_build.yml rename to .github/workflows/release-win64.yml index 838848b..74274e6 100644 --- a/.github/workflows/win_build.yml +++ b/.github/workflows/release-win64.yml @@ -1,17 +1,16 @@ # This is a basic workflow to help you get started with Actions -name: windows build test +name: Release Windows executable # Controls when the action will run. Triggers the workflow on push or pull request # events but only for the master branch on: push: - branches: [ master, development, win ] + branches: [ master, development, win64 ] # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: - Windows-build: - name: Build Windows + release_win64: runs-on: windows-latest env: VCPKG_DEFAULT_TRIPLET: x64-windows @@ -34,4 +33,4 @@ jobs: uses: actions/upload-artifact@master with: name: city4cfd-win64 - path: Release/3dfier-win64.zip + path: Release/city4cfd-win64.zip diff --git a/thirdparty/CSF/src/CMakeLists.txt b/thirdparty/CSF/src/CMakeLists.txt index d502515..ea3f840 100644 --- a/thirdparty/CSF/src/CMakeLists.txt +++ b/thirdparty/CSF/src/CMakeLists.txt @@ -24,8 +24,6 @@ set(CSF_HEADERS add_library(CSF ${CSF_SOURCES} ${CSF_HEADERS}) if (!MSVC) target_compile_options(CSF PRIVATE -Werror -Wall -Wextra -Wno-unused-private-field) -else() - target_compile_options(CSF PRIVATE -Wall) endif() if (OpenMP_CXX_FOUND) From 2b750579325e0d62e4cc9de60259ed421480c31d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Tue, 31 Oct 2023 19:38:12 -0600 Subject: [PATCH 21/42] Prepare win64 release workflow --- .../{release-win64.yml => release-win64-exe.yml} | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) rename .github/workflows/{release-win64.yml => release-win64-exe.yml} (81%) diff --git a/.github/workflows/release-win64.yml b/.github/workflows/release-win64-exe.yml similarity index 81% rename from .github/workflows/release-win64.yml rename to .github/workflows/release-win64-exe.yml index 74274e6..e0b8c81 100644 --- a/.github/workflows/release-win64.yml +++ b/.github/workflows/release-win64-exe.yml @@ -1,12 +1,14 @@ # This is a basic workflow to help you get started with Actions -name: Release Windows executable +name: Release Windows Executable # Controls when the action will run. Triggers the workflow on push or pull request # events but only for the master branch on: - push: - branches: [ master, development, win64 ] + release: + types: [created] + pull_request: + workflow_dispatch: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: @@ -34,3 +36,9 @@ jobs: with: name: city4cfd-win64 path: Release/city4cfd-win64.zip + - name: Add binaries as an asset to the release + uses: softprops/action-gh-release@v1 + with: + files: | + Release/city4cfd-win64.zip + From a246a58c7116aa9c68272dcd267a350f34c30834 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Tue, 31 Oct 2023 19:55:35 -0600 Subject: [PATCH 22/42] Remove duplicate workflow --- .github/workflows/build.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index af1a46d..c1f63d7 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,7 +2,6 @@ name: CI on: push: - pull_request: workflow_dispatch: schedule: - cron: '0 6 1 * *' # Run on the first day of every month at 06:00 UTC From 07caed1ffe55a5558a26e291b32b95c022f64b2b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Tue, 31 Oct 2023 20:05:15 -0600 Subject: [PATCH 23/42] Update readme and changelog --- CHANGELOG.md | 4 ++++ README.md | 7 +++++-- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4cc5769..6681fd1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## [Unreleased] +### Added +- Precompiled Windows executable + ## [0.4.3] - 2023-08-25 ### Fixed - Issue with GDAL on Ubuntu 20.04 diff --git a/README.md b/README.md index f5c6420..28fe053 100644 --- a/README.md +++ b/README.md @@ -7,7 +7,7 @@ ![welcome_figure](https://github.com/tudelft3d/City4CFD/blob/main/docs/images/workflow.png) -City4CFD--*City for CFD*--is a tool that aims to automatically reconstruct 3D city geometries tailored for microscale urban flow simulations. +City4CFD--*City for CFD*--is a cross-platform tool that aims to automatically reconstruct 3D city geometries tailored for microscale urban flow simulations. It can create automatically a terrain from a point cloud and imprint different surfaces (e.g. green areas, water, roads). @@ -34,7 +34,7 @@ City4CFD is developed by the [3D Geoinformation Research Group](https://3d.bk.tu **Output** is in the following formats: OBJ, STL, and CityJSON. The ID of each polygon is preserved, and there is a 1-to-1 mapping between the input and the output. ## Installation -You can directly compile City4CFD on your system using cmake, run it through a Docker container, or install using Homebrew in the case of macOS. +You can directly compile City4CFD on your system using cmake, run it through a Docker container, install using Homebrew in the case of macOS, or use a precompiled binary on Windows. ### Build from source The following libraries are required to build the project: @@ -77,6 +77,9 @@ Mac users can install City4CFD through Homebrew: brew install tudelft3d/software/city4cfd ``` +### Windows +Windows users can use a precompiled binary in [Releases](https://github.com/tudelft3d/City4CFD/releases). + ## Getting started The folder *examples* contains example datasets you can run for your first reconstruction. You can run your first reconstruction from the `/examples/TUD_Campus` folder by typing: From 33df8d80f340f2b0a61879ac3666e9cae4bcf918 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Wed, 1 Nov 2023 00:11:41 -0600 Subject: [PATCH 24/42] Bump checkuot ver and update actions --- .github/workflows/build.yml | 4 ++-- .github/workflows/release-win64-exe.yml | 9 ++++----- 2 files changed, 6 insertions(+), 7 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index c1f63d7..3d079ae 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -54,13 +54,13 @@ jobs: VCPKG_INSTALLATION_ROOT: C:\vcpkg VCPKG_FEATURE_FLAGS: manifests steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build run: | vcpkg install mkdir Release cd Release - cmake .. -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows -DCMAKE_INSTALL_PREFIX=C:\Software -DCMAKE_PREFIX_PATH=Release\vcpkg_installed\x64-windows\share\lastools + cmake .. -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows-static -DCMAKE_INSTALL_PREFIX=C:\Software -DCMAKE_PREFIX_PATH=Release\vcpkg_installed\x64-windows\share\lastools cmake --build . --parallel 4 --config Release build_docker: diff --git a/.github/workflows/release-win64-exe.yml b/.github/workflows/release-win64-exe.yml index e0b8c81..7beceb6 100644 --- a/.github/workflows/release-win64-exe.yml +++ b/.github/workflows/release-win64-exe.yml @@ -19,26 +19,25 @@ jobs: VCPKG_INSTALLATION_ROOT: C:\vcpkg VCPKG_FEATURE_FLAGS: manifests steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3 - name: Build run: | vcpkg install mkdir Release cd Release - cmake .. -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows -DCMAKE_INSTALL_PREFIX=C:\Software -DCMAKE_PREFIX_PATH=Release\vcpkg_installed\x64-windows\share\lastools + cmake .. -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows-static -DCMAKE_INSTALL_PREFIX=C:\Software -DCMAKE_PREFIX_PATH=Release\vcpkg_installed\x64-windows\share\lastools cmake --build . --parallel 4 --config Release - name: Package binary files run: | - cd Release 7z a city4cfd-win64.zip .\Release\* - name: Upload binary files as artifact uses: actions/upload-artifact@master with: name: city4cfd-win64 - path: Release/city4cfd-win64.zip + path: city4cfd-win64.zip - name: Add binaries as an asset to the release uses: softprops/action-gh-release@v1 with: files: | - Release/city4cfd-win64.zip + city4cfd-win64.zip From ca00a2c35f052b969d4d3635ca44797f24e42366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Wed, 1 Nov 2023 09:10:25 -0600 Subject: [PATCH 25/42] Fix library linking --- .github/workflows/build.yml | 2 +- .github/workflows/release-win64-exe.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3d079ae..de3e2c0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -60,7 +60,7 @@ jobs: vcpkg install mkdir Release cd Release - cmake .. -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows-static -DCMAKE_INSTALL_PREFIX=C:\Software -DCMAKE_PREFIX_PATH=Release\vcpkg_installed\x64-windows\share\lastools + cmake .. -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows -DCMAKE_INSTALL_PREFIX=C:\Software -DCMAKE_PREFIX_PATH=Release\vcpkg_installed\x64-windows\share\lastools cmake --build . --parallel 4 --config Release build_docker: diff --git a/.github/workflows/release-win64-exe.yml b/.github/workflows/release-win64-exe.yml index 7beceb6..7aa51fd 100644 --- a/.github/workflows/release-win64-exe.yml +++ b/.github/workflows/release-win64-exe.yml @@ -25,7 +25,7 @@ jobs: vcpkg install mkdir Release cd Release - cmake .. -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows-static -DCMAKE_INSTALL_PREFIX=C:\Software -DCMAKE_PREFIX_PATH=Release\vcpkg_installed\x64-windows\share\lastools + cmake .. -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows -DCMAKE_INSTALL_PREFIX=C:\Software -DCMAKE_PREFIX_PATH=Release\vcpkg_installed\x64-windows\share\lastools cmake --build . --parallel 4 --config Release - name: Package binary files run: | From fb98b8acfe36640c2db409774018a568b9536366 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Wed, 1 Nov 2023 11:01:32 -0600 Subject: [PATCH 26/42] Cache vcpkg for faster runs --- .github/workflows/build.yml | 28 +++++++------ .github/workflows/release-win64-exe.yml | 55 +++++++++++++------------ 2 files changed, 45 insertions(+), 38 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index de3e2c0..d31fc76 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -49,19 +49,23 @@ jobs: build_win64: runs-on: windows-latest - env: - VCPKG_DEFAULT_TRIPLET: x64-windows - VCPKG_INSTALLATION_ROOT: C:\vcpkg - VCPKG_FEATURE_FLAGS: manifests steps: - - uses: actions/checkout@v3 - - name: Build - run: | - vcpkg install - mkdir Release - cd Release - cmake .. -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows -DCMAKE_INSTALL_PREFIX=C:\Software -DCMAKE_PREFIX_PATH=Release\vcpkg_installed\x64-windows\share\lastools - cmake --build . --parallel 4 --config Release + - uses: actions/checkout@v3 + - name: vcpkg build + uses: johnwason/vcpkg-action@v5 + id: vcpkg + with: + pkgs: | + boost-program-options boost-geometry boost-locale boost-chrono boost-system boost-filesystem + eigen3 cgal gdal + triplet: x64-windows-release + token: ${{ github.token }} + - name: Build + run: | + mkdir Release + cd Release + cmake .. ${{ steps.vcpkg.outputs.vcpkg-cmake-config }} + cmake --build . --parallel 4 --config Release build_docker: runs-on: ubuntu-latest diff --git a/.github/workflows/release-win64-exe.yml b/.github/workflows/release-win64-exe.yml index 7aa51fd..b843ca7 100644 --- a/.github/workflows/release-win64-exe.yml +++ b/.github/workflows/release-win64-exe.yml @@ -14,30 +14,33 @@ on: jobs: release_win64: runs-on: windows-latest - env: - VCPKG_DEFAULT_TRIPLET: x64-windows - VCPKG_INSTALLATION_ROOT: C:\vcpkg - VCPKG_FEATURE_FLAGS: manifests steps: - - uses: actions/checkout@v3 - - name: Build - run: | - vcpkg install - mkdir Release - cd Release - cmake .. -DCMAKE_TOOLCHAIN_FILE="$env:VCPKG_INSTALLATION_ROOT\scripts\buildsystems\vcpkg.cmake" -DVCPKG_TARGET_TRIPLET=x64-windows -DCMAKE_INSTALL_PREFIX=C:\Software -DCMAKE_PREFIX_PATH=Release\vcpkg_installed\x64-windows\share\lastools - cmake --build . --parallel 4 --config Release - - name: Package binary files - run: | - 7z a city4cfd-win64.zip .\Release\* - - name: Upload binary files as artifact - uses: actions/upload-artifact@master - with: - name: city4cfd-win64 - path: city4cfd-win64.zip - - name: Add binaries as an asset to the release - uses: softprops/action-gh-release@v1 - with: - files: | - city4cfd-win64.zip - + - uses: actions/checkout@v3 + - name: vcpkg build + uses: johnwason/vcpkg-action@v5 + id: vcpkg + with: + pkgs: | + boost-program-options boost-geometry boost-locale boost-chrono boost-system boost-filesystem + eigen3 cgal gdal + triplet: x64-windows-release + token: ${{ github.token }} + - name: Build + run: | + mkdir Release + cd Release + cmake .. ${{ steps.vcpkg.outputs.vcpkg-cmake-config }} + cmake --build . --parallel 4 --config Release + - name: Package binary files + run: | + 7z a city4cfd-win64.zip .\Release\* + - name: Upload binary files as artifact + uses: actions/upload-artifact@master + with: + name: city4cfd-win64 + path: city4cfd-win64.zip + - name: Add binaries as an asset to the release + uses: softprops/action-gh-release@v1 + with: + files: | + city4cfd-win64.zip From a5200f201a7761be2f4178f39a18ca146d996c26 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Wed, 1 Nov 2023 11:56:50 -0600 Subject: [PATCH 27/42] Test --- .github/workflows/build.yml | 1 + .github/workflows/release-win64-exe.yml | 1 + 2 files changed, 2 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index d31fc76..7a793af 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -60,6 +60,7 @@ jobs: eigen3 cgal gdal triplet: x64-windows-release token: ${{ github.token }} + extra-args: --clean-after-build - name: Build run: | mkdir Release diff --git a/.github/workflows/release-win64-exe.yml b/.github/workflows/release-win64-exe.yml index b843ca7..5583524 100644 --- a/.github/workflows/release-win64-exe.yml +++ b/.github/workflows/release-win64-exe.yml @@ -25,6 +25,7 @@ jobs: eigen3 cgal gdal triplet: x64-windows-release token: ${{ github.token }} + extra-args: --clean-after-build - name: Build run: | mkdir Release From c452abb6e1190367466e870a58239a7d48b8cd82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Wed, 1 Nov 2023 13:27:39 -0600 Subject: [PATCH 28/42] Fix issues with vcpkg action --- .github/workflows/build.yml | 4 +--- .github/workflows/release-win64-exe.yml | 9 ++++----- 2 files changed, 5 insertions(+), 8 deletions(-) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 7a793af..4fd19e3 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -55,9 +55,7 @@ jobs: uses: johnwason/vcpkg-action@v5 id: vcpkg with: - pkgs: | - boost-program-options boost-geometry boost-locale boost-chrono boost-system boost-filesystem - eigen3 cgal gdal + pkgs: boost-program-options boost-geometry boost-locale boost-chrono boost-system boost-filesystem eigen3 cgal gdal triplet: x64-windows-release token: ${{ github.token }} extra-args: --clean-after-build diff --git a/.github/workflows/release-win64-exe.yml b/.github/workflows/release-win64-exe.yml index 5583524..007d5d5 100644 --- a/.github/workflows/release-win64-exe.yml +++ b/.github/workflows/release-win64-exe.yml @@ -20,9 +20,7 @@ jobs: uses: johnwason/vcpkg-action@v5 id: vcpkg with: - pkgs: | - boost-program-options boost-geometry boost-locale boost-chrono boost-system boost-filesystem - eigen3 cgal gdal + pkgs: boost-program-options boost-geometry boost-locale boost-chrono boost-system boost-filesystem eigen3 cgal gdal triplet: x64-windows-release token: ${{ github.token }} extra-args: --clean-after-build @@ -34,12 +32,13 @@ jobs: cmake --build . --parallel 4 --config Release - name: Package binary files run: | - 7z a city4cfd-win64.zip .\Release\* + cd Release + 7z a city4cfd-win64.zip .\Release\* ..\tools\LASTools\Release\* ..\tools\prepare_point_cloud\Release\* - name: Upload binary files as artifact uses: actions/upload-artifact@master with: name: city4cfd-win64 - path: city4cfd-win64.zip + path: Release/city4cfd-win64.zip - name: Add binaries as an asset to the release uses: softprops/action-gh-release@v1 with: From 9c11726035c16c6ab0f6cc766784c11337971eae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Wed, 1 Nov 2023 13:36:54 -0600 Subject: [PATCH 29/42] Remove vcpkg manifest --- vcpkg.json | 15 --------------- 1 file changed, 15 deletions(-) delete mode 100644 vcpkg.json diff --git a/vcpkg.json b/vcpkg.json deleted file mode 100644 index d967cc8..0000000 --- a/vcpkg.json +++ /dev/null @@ -1,15 +0,0 @@ -{ - "name": "city4cfd", - "version-string": "0.4.3", - "dependencies": [ - "boost-program-options", - "boost-geometry", - "boost-locale", - "boost-chrono", - "boost-system", - "boost-filesystem", - "eigen3", - "cgal", - "gdal" - ] -} From 885ed842259848017806dfabcbf814162162fbdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Wed, 1 Nov 2023 15:51:34 -0600 Subject: [PATCH 30/42] Update gh actions --- .github/workflows/release-win64-exe.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release-win64-exe.yml b/.github/workflows/release-win64-exe.yml index 007d5d5..e7911b1 100644 --- a/.github/workflows/release-win64-exe.yml +++ b/.github/workflows/release-win64-exe.yml @@ -33,7 +33,7 @@ jobs: - name: Package binary files run: | cd Release - 7z a city4cfd-win64.zip .\Release\* ..\tools\LASTools\Release\* ..\tools\prepare_point_cloud\Release\* + 7z a city4cfd-win64.zip .\Release\* .\tools\LASTools\Release\* .\tools\prepare_point_cloud\Release\* - name: Upload binary files as artifact uses: actions/upload-artifact@master with: @@ -41,6 +41,7 @@ jobs: path: Release/city4cfd-win64.zip - name: Add binaries as an asset to the release uses: softprops/action-gh-release@v1 + if: startsWith(github.ref, 'refs/tags/') with: files: | city4cfd-win64.zip From 132a7e778fe211d31c055daef3d545d07245ed3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Wed, 1 Nov 2023 17:20:01 -0600 Subject: [PATCH 31/42] Change release packaging --- .github/workflows/release-win64-exe.yml | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/.github/workflows/release-win64-exe.yml b/.github/workflows/release-win64-exe.yml index e7911b1..20e89fc 100644 --- a/.github/workflows/release-win64-exe.yml +++ b/.github/workflows/release-win64-exe.yml @@ -32,13 +32,18 @@ jobs: cmake --build . --parallel 4 --config Release - name: Package binary files run: | - cd Release - 7z a city4cfd-win64.zip .\Release\* .\tools\LASTools\Release\* .\tools\prepare_point_cloud\Release\* + mkdir ReleaseArchive + xcopy Release\Release\* ReleaseArchive\ + mkdir ReleaseArchive\tools\city4cfd_las2las + xcopy Release\tools\LASTools\Release\* ReleaseArchive\tools\city4cfd_las2las + mkdir ReleaseArchive\tools\prepare_point_cloud + xcopy Release\tools\prepare_point_cloud\Release\* ReleaseArchive\tools\prepare_point_cloud\ + tar -zcvf city4cfd-win64.zip ReleaseArchive\* - name: Upload binary files as artifact uses: actions/upload-artifact@master with: name: city4cfd-win64 - path: Release/city4cfd-win64.zip + path: city4cfd-win64.zip - name: Add binaries as an asset to the release uses: softprops/action-gh-release@v1 if: startsWith(github.ref, 'refs/tags/') From a29dafeebd9a40043012923327c62753122f5a63 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Wed, 1 Nov 2023 19:15:03 -0600 Subject: [PATCH 32/42] Rename folder --- .github/workflows/release-win64-exe.yml | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/.github/workflows/release-win64-exe.yml b/.github/workflows/release-win64-exe.yml index 20e89fc..c8de22e 100644 --- a/.github/workflows/release-win64-exe.yml +++ b/.github/workflows/release-win64-exe.yml @@ -32,13 +32,13 @@ jobs: cmake --build . --parallel 4 --config Release - name: Package binary files run: | - mkdir ReleaseArchive - xcopy Release\Release\* ReleaseArchive\ - mkdir ReleaseArchive\tools\city4cfd_las2las - xcopy Release\tools\LASTools\Release\* ReleaseArchive\tools\city4cfd_las2las - mkdir ReleaseArchive\tools\prepare_point_cloud - xcopy Release\tools\prepare_point_cloud\Release\* ReleaseArchive\tools\prepare_point_cloud\ - tar -zcvf city4cfd-win64.zip ReleaseArchive\* + mkdir city4cfd-win64 + xcopy Release\Release\* city4cfd-win64\ + mkdir city4cfd-win64\tools\city4cfd_las2las + xcopy Release\tools\LASTools\Release\* city4cfd-win64\tools\city4cfd_las2las + mkdir city4cfd-win64\tools\prepare_point_cloud + xcopy Release\tools\prepare_point_cloud\Release\* city4cfd-win64\tools\prepare_point_cloud\ + tar -zcvf city4cfd-win64.zip city4cfd-win64\* - name: Upload binary files as artifact uses: actions/upload-artifact@master with: From 455a8b961a685d3261b470e7ee5044cfde6bf701 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Wed, 1 Nov 2023 19:46:38 -0600 Subject: [PATCH 33/42] Add proj db to win64 release package --- .github/workflows/release-win64-exe.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release-win64-exe.yml b/.github/workflows/release-win64-exe.yml index c8de22e..7344312 100644 --- a/.github/workflows/release-win64-exe.yml +++ b/.github/workflows/release-win64-exe.yml @@ -38,6 +38,7 @@ jobs: xcopy Release\tools\LASTools\Release\* city4cfd-win64\tools\city4cfd_las2las mkdir city4cfd-win64\tools\prepare_point_cloud xcopy Release\tools\prepare_point_cloud\Release\* city4cfd-win64\tools\prepare_point_cloud\ + xcopy vcpkg\installed\x64-windows-release\share\proj\proj.db city4cfd-win64\ tar -zcvf city4cfd-win64.zip city4cfd-win64\* - name: Upload binary files as artifact uses: actions/upload-artifact@master From d974418831758847af0577af2fe2b14b7d5def82 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Thu, 2 Nov 2023 08:51:48 -0600 Subject: [PATCH 34/42] Add PR back to gh workflow --- .github/workflows/build.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 4fd19e3..5d7dc9d 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -2,6 +2,7 @@ name: CI on: push: + pull_request: workflow_dispatch: schedule: - cron: '0 6 1 * *' # Run on the first day of every month at 06:00 UTC From fde2c96cb2d2452d527b5b3bdd10ccb6ff0a81e3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Thu, 2 Nov 2023 09:06:40 -0600 Subject: [PATCH 35/42] Move docker build to its own action --- .github/workflows/build-docker.yml | 15 +++++++++++++++ .github/workflows/build.yml | 11 +---------- 2 files changed, 16 insertions(+), 10 deletions(-) create mode 100644 .github/workflows/build-docker.yml diff --git a/.github/workflows/build-docker.yml b/.github/workflows/build-docker.yml new file mode 100644 index 0000000..a0faa97 --- /dev/null +++ b/.github/workflows/build-docker.yml @@ -0,0 +1,15 @@ +name: Build Docker + +on: + push: + workflow_dispatch: + +jobs: + build_docker: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v3 + - name: Docker registry login + run: echo "${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}" | docker login -u "${{ secrets.DOCKER_HUB_USERNAME }}" --password-stdin + - name: Build the Docker image + run: docker build --build-arg JOBS=2 . --file docker/city4cfd.dockerfile --tag tudelft3d/city4cfd:latest diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 5d7dc9d..c82d660 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -1,4 +1,4 @@ -name: CI +name: build on: push: @@ -66,12 +66,3 @@ jobs: cd Release cmake .. ${{ steps.vcpkg.outputs.vcpkg-cmake-config }} cmake --build . --parallel 4 --config Release - - build_docker: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - name: Docker registry login - run: echo "${{ secrets.DOCKER_HUB_ACCESS_TOKEN }}" | docker login -u "${{ secrets.DOCKER_HUB_USERNAME }}" --password-stdin - - name: Build the Docker image - run: docker build --build-arg JOBS=2 . --file docker/city4cfd.dockerfile --tag tudelft3d/city4cfd:latest From ee0595337e9a71697cab56bb9a6f933cb1cb84d1 Mon Sep 17 00:00:00 2001 From: Ivan Paden Date: Thu, 2 Nov 2023 17:57:01 +0100 Subject: [PATCH 36/42] Fix import-reconstruct issues --- src/ImportedBuilding.cpp | 42 +++++++++++++++++++++++++--------------- src/Map3d.cpp | 13 ++++++++----- src/PolyFeature.cpp | 2 +- 3 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/ImportedBuilding.cpp b/src/ImportedBuilding.cpp index e6d5342..b6d65d2 100644 --- a/src/ImportedBuilding.cpp +++ b/src/ImportedBuilding.cpp @@ -116,23 +116,33 @@ ImportedBuilding::ImportedBuilding(std::unique_ptr& buildingJson // int polyNo = 0; for (int& footprintIdx : _footprintIdxList) { //-- Construct footprint polygon from ground surface - nlohmann::json coordBnd = geometry["boundaries"].front()[footprintIdx].front(); - CGAL::Polygon_2 facePoly; - for (const int& ptIdx: coordBnd) { - facePoly.push_back(ePoint_2(_ptMap.at(ptIdx).x(), _ptMap.at(ptIdx).y())); - footprintElevations.push_back(_ptMap.at(ptIdx).z()); - pointConnectivity[IO::gen_key_bucket(Point_2(_ptMap.at(ptIdx).x(), _ptMap.at(ptIdx).y()))] = ptIdx; - } - if (!facePoly.is_simple()) { - Config::write_to_log("Failed to import building: " + this->get_id() - + " Reason: Footprint polygon is not simple."); - this->deactivate(); - return; + CGAL::Polygon_with_holes_2 facePolyWH; + bool first = true; + for (auto& coordBnd : geometry["boundaries"].front()[footprintIdx]) { + CGAL::Polygon_2 facePoly; + for (const int& ptIdx: coordBnd) { + facePoly.push_back(ePoint_2(_ptMap.at(ptIdx).x(), _ptMap.at(ptIdx).y())); + footprintElevations.push_back(_ptMap.at(ptIdx).z()); + pointConnectivity[IO::gen_key_bucket(Point_2(_ptMap.at(ptIdx).x(), _ptMap.at(ptIdx).y()))] = ptIdx; + } + if (!facePoly.is_simple()) { + Config::write_to_log("Failed to import building: " + this->get_id() + + " Reason: Footprint polygon is not simple."); + this->deactivate(); + return; + } + geomutils::pop_back_if_equal_to_front(facePoly); + + if (first) { + if (facePoly.is_clockwise_oriented()) facePoly.reverse_orientation(); + first = false; + facePolyWH.outer_boundary() = facePoly; + } else { + if (facePoly.is_counterclockwise_oriented()) facePoly.reverse_orientation(); + facePolyWH.add_hole(facePoly); + } } - geomutils::pop_back_if_equal_to_front(facePoly); - if (facePoly.is_clockwise_oriented()) facePoly.reverse_orientation(); - - polySet.join(facePoly); + polySet.join(facePolyWH); } //-- Polyset to polygon data structure this->polyset_to_polygon(polySet); diff --git a/src/Map3d.cpp b/src/Map3d.cpp index bc14f8a..a3a1f82 100644 --- a/src/Map3d.cpp +++ b/src/Map3d.cpp @@ -360,11 +360,14 @@ void Map3d::reconstruct_one_building(std::shared_ptr& building) { if (building->is_imported()) { building->deactivate(); // deactivate this and use reconstructed instead // try to recover by reconstructing LoD1.2 from geometry pts - auto importToReconstructBuild = - std::make_shared(std::static_pointer_cast(building)); - _reconstructedBuildingsPtr.push_back(importToReconstructBuild); - _allFeaturesPtr.push_back(importToReconstructBuild); - _buildingsPtr.push_back(importToReconstructBuild); + auto importToReconstructBuild = + std::make_shared(std::static_pointer_cast(building)); + #pragma omp critical + { + _reconstructedBuildingsPtr.push_back(importToReconstructBuild); + _allFeaturesPtr.push_back(importToReconstructBuild); + _buildingsPtr.push_back(importToReconstructBuild); + } std::shared_ptr buildToReconstruct = importToReconstructBuild; this->reconstruct_one_building(buildToReconstruct); } else { diff --git a/src/PolyFeature.cpp b/src/PolyFeature.cpp index 4872e35..813211a 100644 --- a/src/PolyFeature.cpp +++ b/src/PolyFeature.cpp @@ -41,7 +41,7 @@ PolyFeature::PolyFeature() _groundElevation(-global::largnum), _minBbox() {} PolyFeature::PolyFeature(const int outputLayerID) - : TopoFeature(outputLayerID), _poly(), _groundElevations(), _polyInternalID(new_internal_id()), + : TopoFeature(outputLayerID), _poly(), _groundElevations(), _polyInternalID(new_internal_id()), _groundElevation(-global::largnum), _minBbox() {} PolyFeature::PolyFeature(const nlohmann::json& poly, const bool checkSimplicity) From 21350b483177fffef9f321f3f1696a03dea9f690 Mon Sep 17 00:00:00 2001 From: Ivan Paden Date: Tue, 9 Jan 2024 15:12:34 +0100 Subject: [PATCH 37/42] Fix segfault when empty poly gets imported --- src/PolyFeature.cpp | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/PolyFeature.cpp b/src/PolyFeature.cpp index dd2ff6a..b94774b 100644 --- a/src/PolyFeature.cpp +++ b/src/PolyFeature.cpp @@ -75,7 +75,7 @@ PolyFeature::PolyFeature(const Polygon_with_attr& poly, const bool checkSimplici bool isOuterRing = true; for (auto& ring : poly.polygon.rings()) { Polygon_2 tempPoly; - const double minDist = 0.0001; + const double minDist = 0.0001; // hardcoded Point_2 prev(global::largnum, global::largnum); for (auto& pt: ring.vertices()) { if (CGAL::squared_distance(pt, prev) > minDist) { @@ -84,6 +84,11 @@ PolyFeature::PolyFeature(const Polygon_with_attr& poly, const bool checkSimplici } } geomutils::pop_back_if_equal_to_front(tempPoly); + if (tempPoly.size() < 3) { // Sanity check if it is even a polygon + std::cout << "WARNING: Skipping import of a zero-area polygon" << std::endl; + this->deactivate(); + return; + } if (isOuterRing) { if (tempPoly.is_clockwise_oriented()) tempPoly.reverse_orientation(); isOuterRing = false; From 25cfae83f00ced80975b7669fea541435eed55bd Mon Sep 17 00:00:00 2001 From: Ivan Paden Date: Tue, 9 Jan 2024 15:18:19 +0100 Subject: [PATCH 38/42] Update changelog --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 9f41a9c..3f40e99 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,7 @@ - Precompiled Windows executable ### Changed - Improved fallbacks in case building import fails in late stages +- Improved polygon flattening when buildings are adjacent ### Fixed - Minor bugfixes From b554461e5ae382b01d3687cd2d2945281cdd7771 Mon Sep 17 00:00:00 2001 From: Ivan Paden Date: Tue, 9 Jan 2024 16:15:18 +0100 Subject: [PATCH 39/42] Happy new year --- src/Boundary.cpp | 2 +- src/BoundingRegion.cpp | 2 +- src/BoundingRegion.h | 2 +- src/Building.cpp | 2 +- src/Building.h | 2 +- src/CGALTypes.h | 2 +- src/Config.cpp | 2 +- src/Config.h | 2 +- src/ImportedBuilding.cpp | 2 +- src/ImportedBuilding.h | 2 +- src/LoD12.cpp | 2 +- src/LoD12.h | 2 +- src/Map3d.cpp | 2 +- src/Map3d.h | 2 +- src/PointCloud.cpp | 2 +- src/PointCloud.h | 2 +- src/PolyFeature.cpp | 2 +- src/PolyFeature.h | 2 +- src/ReconstructedBuilding.cpp | 2 +- src/ReconstructedBuilding.h | 2 +- src/Sides.cpp | 2 +- src/Sides.h | 2 +- src/SurfaceLayer.cpp | 2 +- src/SurfaceLayer.h | 2 +- src/Terrain.cpp | 2 +- src/Terrain.h | 2 +- src/Top.cpp | 2 +- src/Top.h | 2 +- src/TopoFeature.cpp | 2 +- src/TopoFeature.h | 2 +- src/configSchema.inc | 2 +- src/geomutils.cpp | 2 +- src/geomutils.h | 2 +- src/io.cpp | 2 +- src/io.h | 2 +- src/main.cpp | 4 ++-- src/types.h | 2 +- tools/prepare_point_cloud/src/PCconfigSchema.inc | 2 +- tools/prepare_point_cloud/src/city4cfd_pcprep.cpp | 4 ++-- 39 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/Boundary.cpp b/src/Boundary.cpp index 8bcd580..bf55948 100644 --- a/src/Boundary.cpp +++ b/src/Boundary.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/BoundingRegion.cpp b/src/BoundingRegion.cpp index 9eaafd3..3ecff69 100644 --- a/src/BoundingRegion.cpp +++ b/src/BoundingRegion.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/BoundingRegion.h b/src/BoundingRegion.h index 3326487..64e64fe 100644 --- a/src/BoundingRegion.h +++ b/src/BoundingRegion.h @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/Building.cpp b/src/Building.cpp index 5f1e21b..fa6903d 100644 --- a/src/Building.cpp +++ b/src/Building.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/Building.h b/src/Building.h index 58fcb1b..4ce3596 100644 --- a/src/Building.h +++ b/src/Building.h @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/CGALTypes.h b/src/CGALTypes.h index 77e99c8..c395fbd 100644 --- a/src/CGALTypes.h +++ b/src/CGALTypes.h @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/Config.cpp b/src/Config.cpp index b6d07c9..e9ae1a4 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/Config.h b/src/Config.h index 90bc65f..463ac43 100644 --- a/src/Config.h +++ b/src/Config.h @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/ImportedBuilding.cpp b/src/ImportedBuilding.cpp index d3e718f..2450f26 100644 --- a/src/ImportedBuilding.cpp +++ b/src/ImportedBuilding.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/ImportedBuilding.h b/src/ImportedBuilding.h index bfbce2e..ce2f1e6 100644 --- a/src/ImportedBuilding.h +++ b/src/ImportedBuilding.h @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/LoD12.cpp b/src/LoD12.cpp index 2b6316b..3210359 100644 --- a/src/LoD12.cpp +++ b/src/LoD12.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/LoD12.h b/src/LoD12.h index ede982f..8f25e16 100644 --- a/src/LoD12.h +++ b/src/LoD12.h @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/Map3d.cpp b/src/Map3d.cpp index f654ba6..5f4280d 100644 --- a/src/Map3d.cpp +++ b/src/Map3d.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/Map3d.h b/src/Map3d.h index 71dd4d8..607a7e1 100644 --- a/src/Map3d.h +++ b/src/Map3d.h @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/PointCloud.cpp b/src/PointCloud.cpp index 2732b59..c772882 100644 --- a/src/PointCloud.cpp +++ b/src/PointCloud.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/PointCloud.h b/src/PointCloud.h index 2631435..5954ece 100644 --- a/src/PointCloud.h +++ b/src/PointCloud.h @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/PolyFeature.cpp b/src/PolyFeature.cpp index dd2ff6a..e459307 100644 --- a/src/PolyFeature.cpp +++ b/src/PolyFeature.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/PolyFeature.h b/src/PolyFeature.h index 2473f9b..2a1d7cc 100644 --- a/src/PolyFeature.h +++ b/src/PolyFeature.h @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/ReconstructedBuilding.cpp b/src/ReconstructedBuilding.cpp index 9fa71cc..1c87faf 100644 --- a/src/ReconstructedBuilding.cpp +++ b/src/ReconstructedBuilding.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/ReconstructedBuilding.h b/src/ReconstructedBuilding.h index a7db236..79fb713 100644 --- a/src/ReconstructedBuilding.h +++ b/src/ReconstructedBuilding.h @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/Sides.cpp b/src/Sides.cpp index 5fe4d81..6377851 100644 --- a/src/Sides.cpp +++ b/src/Sides.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/Sides.h b/src/Sides.h index 47ad608..a469114 100644 --- a/src/Sides.h +++ b/src/Sides.h @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/SurfaceLayer.cpp b/src/SurfaceLayer.cpp index 7a3f23c..10b0067 100644 --- a/src/SurfaceLayer.cpp +++ b/src/SurfaceLayer.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/SurfaceLayer.h b/src/SurfaceLayer.h index 2bd5386..a05d4af 100644 --- a/src/SurfaceLayer.h +++ b/src/SurfaceLayer.h @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/Terrain.cpp b/src/Terrain.cpp index 404a109..acbf22e 100644 --- a/src/Terrain.cpp +++ b/src/Terrain.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/Terrain.h b/src/Terrain.h index 4fa309c..6cfc92a 100644 --- a/src/Terrain.h +++ b/src/Terrain.h @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/Top.cpp b/src/Top.cpp index 77329be..c7c30db 100644 --- a/src/Top.cpp +++ b/src/Top.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/Top.h b/src/Top.h index 35cf93a..42cccab 100644 --- a/src/Top.h +++ b/src/Top.h @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/TopoFeature.cpp b/src/TopoFeature.cpp index 3d7751a..5d5470c 100644 --- a/src/TopoFeature.cpp +++ b/src/TopoFeature.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/TopoFeature.h b/src/TopoFeature.h index a5a5def..5b45066 100644 --- a/src/TopoFeature.h +++ b/src/TopoFeature.h @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/configSchema.inc b/src/configSchema.inc index 6866772..aff0a59 100644 --- a/src/configSchema.inc +++ b/src/configSchema.inc @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/geomutils.cpp b/src/geomutils.cpp index b49eeb6..03e75fe 100644 --- a/src/geomutils.cpp +++ b/src/geomutils.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/geomutils.h b/src/geomutils.h index 94f14c9..29f6bc3 100644 --- a/src/geomutils.h +++ b/src/geomutils.h @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/io.cpp b/src/io.cpp index a11279c..b938fb5 100644 --- a/src/io.cpp +++ b/src/io.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/io.h b/src/io.h index 4020d0d..ac2df9e 100644 --- a/src/io.h +++ b/src/io.h @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/src/main.cpp b/src/main.cpp index b34fe36..3d40c0b 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. @@ -57,7 +57,7 @@ void printWelcome() { }; std::cout << logo; - std::cout << "City4CFD Copyright (C) 2021-2023 3D Geoinformation Research Group, TU Delft\n" << std::endl; + std::cout << "City4CFD Copyright (C) 2021-2024 3D Geoinformation Research Group, TU Delft\n" << std::endl; } void printHelp() { diff --git a/src/types.h b/src/types.h index 92c7eae..69a0330 100644 --- a/src/types.h +++ b/src/types.h @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/tools/prepare_point_cloud/src/PCconfigSchema.inc b/tools/prepare_point_cloud/src/PCconfigSchema.inc index fa8f588..406c929 100644 --- a/tools/prepare_point_cloud/src/PCconfigSchema.inc +++ b/tools/prepare_point_cloud/src/PCconfigSchema.inc @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. diff --git a/tools/prepare_point_cloud/src/city4cfd_pcprep.cpp b/tools/prepare_point_cloud/src/city4cfd_pcprep.cpp index 586abd7..e9218ac 100644 --- a/tools/prepare_point_cloud/src/city4cfd_pcprep.cpp +++ b/tools/prepare_point_cloud/src/city4cfd_pcprep.cpp @@ -1,7 +1,7 @@ /* City4CFD - Copyright (c) 2021-2023, 3D Geoinformation Research Group, TU Delft + Copyright (c) 2021-2024, 3D Geoinformation Research Group, TU Delft This file is part of City4CFD. @@ -81,7 +81,7 @@ void printWelcome() { )" }; std::cout << logo; - std::cout << "City4CFD Copyright (C) 2021-2023 3D Geoinformation Research Group, TU Delft\n" << std::endl; + std::cout << "City4CFD Copyright (C) 2021-2024 3D Geoinformation Research Group, TU Delft\n" << std::endl; std::cout << info; } From 6fc3d30dd690e85458e47d3f4249207e42b8b60d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Tue, 9 Jan 2024 16:24:09 +0100 Subject: [PATCH 40/42] Update README.md --- README.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 28fe053..065ba92 100644 --- a/README.md +++ b/README.md @@ -1,10 +1,10 @@ -[![docs](https://img.shields.io/badge/docs-Wiki-brightgreen?style=flat-square)](https://github.com/tudelft3d/City4CFD/wiki) +# City4CFD + +[![build](https://img.shields.io/github/actions/workflow/status/tudelft3d/City4CFD/build.yml?branch=main&style=flat-square)](https://github.com/tudelft3d/City4CFD/actions/workflows/build.yml) +[![docs](https://img.shields.io/badge/docs-Wiki-yellow?style=flat-square)](https://github.com/tudelft3d/City4CFD/wiki) [![GitHub license](https://img.shields.io/github/license/tudelft3d/City4CFD?style=flat-square)](https://github.com/tudelft3d/City4CFD/blob/master/LICENSE) [![DOI:10.3389/fbuil.2022.899332](http://img.shields.io/badge/DOI-10.3389/fbuil.2022.899332-B62030.svg?style=flat-square)](https://doi.org/10.3389/fbuil.2022.899332) - -# City4CFD - ![welcome_figure](https://github.com/tudelft3d/City4CFD/blob/main/docs/images/workflow.png) City4CFD--*City for CFD*--is a cross-platform tool that aims to automatically reconstruct 3D city geometries tailored for microscale urban flow simulations. From 5abd64767e107c641ef8d3592baca103d05e6a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Sat, 13 Jan 2024 09:30:01 +0100 Subject: [PATCH 41/42] Revert win64 release for now --- .github/workflows/release-win64-exe.yml | 1 + CHANGELOG.md | 2 -- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/release-win64-exe.yml b/.github/workflows/release-win64-exe.yml index 7344312..901fb24 100644 --- a/.github/workflows/release-win64-exe.yml +++ b/.github/workflows/release-win64-exe.yml @@ -13,6 +13,7 @@ on: # A workflow run is made up of one or more jobs that can run sequentially or in parallel jobs: release_win64: + if: false runs-on: windows-latest steps: - uses: actions/checkout@v3 diff --git a/CHANGELOG.md b/CHANGELOG.md index 3f40e99..08f7595 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,8 +1,6 @@ # Changelog ## [Unreleased] -### Added -- Precompiled Windows executable ### Changed - Improved fallbacks in case building import fails in late stages - Improved polygon flattening when buildings are adjacent From 6ef47bb263cb9ecd6e6b912f48127ba63ca6697c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ivan=20Pa=C4=91en?= <49401914+ipadjen@users.noreply.github.com> Date: Sat, 13 Jan 2024 10:53:23 +0100 Subject: [PATCH 42/42] Bump version to 0.4.4 --- CHANGELOG.md | 2 +- src/main.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 08f7595..5955fc7 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## [Unreleased] +## [0.4.4] - 2024-01-13 ### Changed - Improved fallbacks in case building import fails in late stages - Improved polygon flattening when buildings are adjacent diff --git a/src/main.cpp b/src/main.cpp index 3d40c0b..3b5ac23 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -31,7 +31,7 @@ #include -std::string CITY4CFD_VERSION = "0.4.3+dev"; +std::string CITY4CFD_VERSION = "0.4.4"; void printWelcome() { auto logo{