Skip to content

Commit

Permalink
Merge pull request #22 from tudelft3d/cgal-6
Browse files Browse the repository at this point in the history
CGAL6
  • Loading branch information
ipadjen authored Oct 16, 2024
2 parents ebc27a1 + e256091 commit 275c279
Show file tree
Hide file tree
Showing 20 changed files with 84 additions and 53 deletions.
20 changes: 10 additions & 10 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,33 +16,33 @@ jobs:
run: |
sudo apt-get update
sudo apt-get install libgmp-dev libmpfr-dev libboost-all-dev libeigen3-dev libomp-dev libgdal-dev
- name: Download CGAL
- name: Download CGAL 6.0
run: |
wget https://github.com/CGAL/cgal/releases/download/v5.6.1/CGAL-5.6.1-library.tar.xz -P ${{ github.workspace }}
wget https://github.com/CGAL/cgal/releases/download/v6.0/CGAL-6.0-library.tar.xz -P ${{ github.workspace }}
cd ${{ github.workspace }}
tar -xvf CGAL-5.6.1-library.tar.xz
tar -xvf CGAL-6.0-library.tar.xz
- name: Build
run: |
mkdir build && cd build
cmake .. -DCGAL_DIR=${{ github.workspace }}/CGAL-5.6.1 && make -j4
cmake .. -DCGAL_DIR=${{ github.workspace }}/CGAL-6.0 && make -j4
build_linux_2004:
runs-on: ubuntu-20.04
build_linux_2204:
runs-on: ubuntu-22.04
steps:
- uses: actions/checkout@v3
- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install libgmp-dev libmpfr-dev libboost-all-dev libeigen3-dev libomp-dev libgdal-dev
- name: Download CGAL
- name: Download CGAL 6.0
run: |
wget https://github.com/CGAL/cgal/releases/download/v5.6.1/CGAL-5.6.1-library.tar.xz -P ${{ github.workspace }}
wget https://github.com/CGAL/cgal/releases/download/v6.0/CGAL-6.0-library.tar.xz -P ${{ github.workspace }}
cd ${{ github.workspace }}
tar -xvf CGAL-5.6.1-library.tar.xz
tar -xvf CGAL-6.0-library.tar.xz
- name: Build
run: |
mkdir build && cd build
cmake .. -DCGAL_DIR=${{ github.workspace }}/CGAL-5.6.1 && make -j4
cmake .. -DCGAL_DIR=${{ github.workspace }}/CGAL-6.0 && make -j4
build_macos:
runs-on: macos-latest
Expand Down
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
# Changelog

## [Unreleased]
### Changed
- Updated to CGAL 6

## [0.5.0] - 2024-07-29 - breaking changes
### Added
- LoD2.2 and LoD1.3 reconstruction
Expand Down
4 changes: 4 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ set(CMAKE_BUILD_TYPE "Release")
# cmake_policy(SET CMP0003 NEW)
#endif()

if(POLICY CMP0167)
cmake_policy(SET CMP0167 NEW)
endif()

if (MSVC)
add_definitions(-DNOMINMAX)
add_definitions("/EHsc")
Expand Down
19 changes: 17 additions & 2 deletions docker/city4cfd-build-base.dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,26 @@ LABEL org.opencontainers.image.description="Base image for building City4CFD"
LABEL org.opencontainers.image.licenses="AGPL-3.0"
LABEL org.opencontainers.image.url="https://github.com/tudelft3d/city4cfd"

# Install required packages and clean up
RUN apt-get update && apt-get install -y --no-install-recommends \
build-essential \
cmake \
libboost-all-dev \
libcgal-dev \
libgmp-dev \
libmpfr-dev \
libeigen3-dev \
libomp-dev \
libgdal-dev
libgdal-dev \
wget \
ca-certificates \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/* \
&& rm -rf /tmp/*

# Download and extract CGAL
RUN wget https://github.com/CGAL/cgal/releases/download/v6.0/CGAL-6.0-library.tar.xz \
&& tar -xf CGAL-6.0-library.tar.xz -C /opt \
&& rm CGAL-6.0-library.tar.xz

# Set environment variable for CGAL
ENV CGAL_DIR=/opt/CGAL-6.0
8 changes: 4 additions & 4 deletions src/Building.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,10 +296,10 @@ void Building::get_cityjson_info(nlohmann::json& b) const {

void Building::get_cityjson_semantics(nlohmann::json& g) const { // Temp for checking CGAL mesh properties
Face_property semantics;
bool foundProperty;
boost::tie(semantics, foundProperty) = m_mesh.property_map<face_descriptor, std::string>("f:semantics");
// auto semantics = m_mesh.property_map<face_descriptor, std::string>("f:semantics");
if (!foundProperty) throw city4cfd_error("Semantic property map not found!");
auto semanticsMap = m_mesh.property_map<face_descriptor, std::string>("f:semantics");
if (semanticsMap.has_value()) {
semantics = semanticsMap.value();
} else throw city4cfd_error("Semantic property map not found!");

std::unordered_map<std::string, int> surfaceId;
surfaceId["RoofSurface"] = 0; g["semantics"]["surfaces"][0]["type"] = "RoofSurface";
Expand Down
10 changes: 5 additions & 5 deletions src/Config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ void Config::set_config(nlohmann::json& j) {
//- Domain boundaries
Config::get().set_region(domainBndConfig, "domain_bnd", j);
// Define domain type if using BPG
if (domainBndConfig.type() == typeid(bool)) {
if (std::holds_alternative<bool>(domainBndConfig)) {
if (j.contains("flow_direction"))
flowDirection = Vector_2(j["flow_direction"][0], j["flow_direction"][1]);

Expand All @@ -165,13 +165,13 @@ void Config::set_config(nlohmann::json& j) {
}

// Set domain side and top
if (domainBndConfig.type() == typeid(Polygon_2)) {
Polygon_2 poly = boost::get<Polygon_2>(domainBndConfig);
if (std::holds_alternative<Polygon_2>(domainBndConfig)) {
Polygon_2 poly = std::get<Polygon_2>(domainBndConfig);
numSides = poly.size();
for (int i = 0; i < poly.size(); ++i) {
outputSurfaces.emplace_back("Side_" + std::to_string(i % poly.size()));
}
} else if (domainBndConfig.type() == typeid(double) || bpgDomainType != RECTANGLE) {
} else if (std::holds_alternative<double>(domainBndConfig) || bpgDomainType != RECTANGLE) {
outputSurfaces.emplace_back("Sides");
} else if (bpgDomainType == RECTANGLE) { // Expand output surfaces with front and back
numSides = 4;
Expand Down Expand Up @@ -327,7 +327,7 @@ void Config::set_config(nlohmann::json& j) {
}

//-- influRegion and domainBndConfig flow control
void Config::set_region(boost::variant<bool, double, Polygon_2>& regionType,
void Config::set_region(std::variant<bool, double, Polygon_2>& regionType,
const std::string regionName,
nlohmann::json& j) {
if (j[regionName].is_string()) { // Search for GeoJSON polygon
Expand Down
6 changes: 3 additions & 3 deletions src/Config.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class Config {
public:
void validate(nlohmann::json& j);
void set_config(nlohmann::json& j);
void set_region(boost::variant<bool, double, Polygon_2>& regionType,
void set_region(std::variant<bool, double, Polygon_2>& regionType,
const std::string regionName,
nlohmann::json& j);
static void write_to_log(const std::string& msg);
Expand All @@ -65,7 +65,7 @@ class Config {
//-- Domain setup
Point_2 pointOfInterest;
double topHeight = 0.;
boost::variant<bool, double, Polygon_2> domainBndConfig;
std::variant<bool, double, Polygon_2> domainBndConfig;
DomainType bpgDomainType;
bool bpgBlockageRatioFlag = false;
double bpgBlockageRatio = 0.03;
Expand Down Expand Up @@ -134,7 +134,7 @@ class Config {

//-- Struct for reconstruction regions (part of Buildings)
struct ReconRegion{
boost::variant<bool, double, Polygon_2> influRegionConfig;
std::variant<bool, double, Polygon_2> influRegionConfig;
std::string lod;
double bpgInfluExtra = 0.;
bool importAdvantage = true;
Expand Down
8 changes: 4 additions & 4 deletions src/Map3d.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -198,7 +198,7 @@ void Map3d::set_features() {
for (auto& reconRegion : Config::get().reconRegions) {
m_reconRegions.emplace_back(reconRegion);
}
if (Config::get().domainBndConfig.type() == typeid(bool)) m_bndBPG = true;
if (std::holds_alternative<bool>(Config::get().domainBndConfig)) m_bndBPG = true;

//-- Apply area filtering
if (Config::get().minArea > 0.) {
Expand Down Expand Up @@ -256,15 +256,15 @@ void Map3d::set_influ_region() {
//-- Set the reconstruction (influence) regions --//
double maxDim = -1.; // this works if there's one point of interest
for (int i = 0; i < m_reconRegions.size(); ++i) {
if (m_reconRegions[i].m_reconSettings->influRegionConfig.type() == typeid(bool)) {// bool defines BPG request
if (std::holds_alternative<bool>(m_reconRegions[i].m_reconSettings->influRegionConfig)) {// bool defines BPG request
std::cout << "INFO: Reconstruction region "<< i << " not defined in config. "
<< "Calculating with BPG." << std::endl;
if (maxDim < 0.)
maxDim = m_reconRegions[i].calc_influ_region_bpg(m_dt, m_buildingsPtr);
else
m_reconRegions[i].calc_influ_region_bpg(maxDim);
} else
boost::apply_visitor(m_reconRegions[i], Config::get().reconRegions[i]->influRegionConfig);
std::visit(m_reconRegions[i], Config::get().reconRegions[i]->influRegionConfig);
}
// Check if regions get larger with increasing index
for (int i = 0; i < m_reconRegions.size(); ++i) {
Expand Down Expand Up @@ -303,7 +303,7 @@ void Map3d::set_bnd() {
m_domainBnd.calc_bnd_bpg(m_reconRegions.back().get_bounding_region(), m_buildingsPtr);
} else {
//-- Define boundary region with values set in config
boost::apply_visitor(m_domainBnd, Config::get().domainBndConfig);
std::visit(m_domainBnd, Config::get().domainBndConfig);
}
this->bnd_sanity_check(); // Check if outer bnd is larger than the influ region

Expand Down
7 changes: 3 additions & 4 deletions src/PointCloud.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,6 @@
#include "Building.h"
#include "Quadtree/Quadtree.h"

#include <boost/locale.hpp>
#include <CGAL/Polygon_mesh_processing/remesh.h>
#include <CGAL/Polygon_mesh_processing/smooth_shape.h>
#include <CGAL/wlop_simplify_and_regularize_point_set.h>
Expand Down Expand Up @@ -241,7 +240,7 @@ void PointCloud::buffer_flat_edges(const PolyFeaturesPtr& avgFeatures,
typedef CGAL::Polygon_offset_builder_traits_2<EPICK> OffsetBuilderTraits;
typedef CGAL::Polygon_offset_builder_2<Ss, OffsetBuilderTraits, Polygon_2> OffsetBuilder;

typedef boost::shared_ptr<Polygon_2> ContourPtr;
typedef std::shared_ptr<Polygon_2> ContourPtr;
typedef std::vector<ContourPtr> ContourSequence;
// get info using the original point cloud
// std::vector<double> offsets{0.001, 0.2};
Expand All @@ -252,7 +251,7 @@ void PointCloud::buffer_flat_edges(const PolyFeaturesPtr& avgFeatures,
//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<double> margin = CGAL::compute_outer_frame_margin(poly.begin(), poly.end(), offsets.back());
auto margin = CGAL::compute_outer_frame_margin(poly.begin(), poly.end(), offsets.back());
CGAL::Bbox_2 bbox = CGAL::bbox_2(poly.begin(), poly.end());
// Compute the boundaries of the frame
double fxmin = bbox.xmin() - *margin;
Expand All @@ -271,7 +270,7 @@ void PointCloud::buffer_flat_edges(const PolyFeaturesPtr& avgFeatures,
poly.reverse_orientation();
ssb.enter_contour(poly.begin(), poly.end());
// Construct the skeleton
boost::shared_ptr<Ss> ss = ssb.construct_skeleton();
auto ss = ssb.construct_skeleton();
// Proceed only if the skeleton was correctly constructed.
if (ss) {
for (auto& offset: offsets) {
Expand Down
4 changes: 2 additions & 2 deletions src/PolyFeature.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ bool PolyFeature::flatten_polygon_inner_points(const Point_set_3& pointCloud,
bool& isNextToBuilding) {

typedef CGAL::Straight_skeleton_2<EPICK> Ss;
typedef boost::shared_ptr<CGAL::Polygon_with_holes_2<EPICK>> PolygonPtrWH;
typedef std::shared_ptr<CGAL::Polygon_with_holes_2<EPICK>> PolygonPtrWH;
typedef std::vector<PolygonPtrWH> PolygonPtrVectorWH;

#ifdef CITY4CFD_POLYFEATURE_VERBOSE
Expand All @@ -234,7 +234,7 @@ bool PolyFeature::flatten_polygon_inner_points(const Point_set_3& pointCloud,

std::vector<int> indices;
std::vector<double> originalHeights;
auto buildingPt = pointCloud.property_map<std::shared_ptr<Building>>("building_point").first;
auto buildingPt = pointCloud.property_map<std::shared_ptr<Building>>("building_point").value();
//-- Take tree subset bounded by the polygon
std::vector<Point_3> subsetPts;
Polygon_2 bbox = geomutils::calc_bbox_poly(m_poly.rings().front());
Expand Down
8 changes: 4 additions & 4 deletions src/ReconstructedBuilding.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -339,10 +339,10 @@ void ReconstructedBuilding::get_cityjson_info(nlohmann::json& b) const {

void ReconstructedBuilding::get_cityjson_semantics(nlohmann::json& g) const { // Temp for checking CGAL mesh properties
Face_property semantics;
bool foundProperty;
boost::tie(semantics, foundProperty) = m_mesh.property_map<face_descriptor, std::string>("f:semantics");
// auto semantics = m_mesh.property_map<face_descriptor, std::string>("f:semantics");
if (!foundProperty) throw city4cfd_error("Semantic property map not found!");
auto semanticsMap = m_mesh.property_map<face_descriptor, std::string>("f:semantics");
if (semanticsMap.has_value()) {
semantics = semanticsMap.value();
} else throw city4cfd_error("Semantic property map not found!");

std::unordered_map<std::string, int> surfaceId;
surfaceId["RoofSurface"] = 0; g["semantics"]["surfaces"][0]["type"] = "RoofSurface";
Expand Down
4 changes: 2 additions & 2 deletions src/Terrain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -35,12 +35,12 @@
Terrain::Terrain()
: TopoFeature(0), m_cdt(), m_surfaceLayersTerrain(),
m_constrainedPolys(), m_vertexFaceMap(), m_extraConstrainedEdges(),
m_searchTree(Config::get().searchtree_bucket_size) {}
m_searchTree() {}

Terrain::Terrain(int pid)
: TopoFeature(pid), m_cdt(), m_surfaceLayersTerrain(),
m_constrainedPolys(), m_vertexFaceMap(), m_extraConstrainedEdges(),
m_searchTree(Config::get().searchtree_bucket_size) {}
m_searchTree() {}

Terrain::~Terrain() = default;

Expand Down
1 change: 1 addition & 0 deletions src/io.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ bool IO::read_point_cloud(std::string& file, Point_set_3& pc) {
for (auto it = pc.points().begin(); it != pc.points().end(); ++it) {
transformPC.insert(it->transform(translate));
}
transformPC.add_normal_map(); //todo temp workaround due to CGAL bug
pc = transformPC;
return true;
}
Expand Down
10 changes: 8 additions & 2 deletions thirdparty/roofer/src/reconstruction/ArrangementBase.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,10 @@ class Face_index_observer : public CGAL::Arr_observer<Arrangement_2>
n_faces (0), in_footprint(is_footprint), plane_id(pid), elevation(elevation), plane(plane)
{
CGAL_precondition (arr.is_empty());
arr.unbounded_face()->data().is_finite=false;
for (auto uf = arr.unbounded_faces_begin();
uf != arr.unbounded_faces_end(); ++uf) {
uf->data().is_finite = false;
}
n_faces++;
};
virtual void after_split_face (Face_handle old_face,
Expand All @@ -122,7 +125,10 @@ class Face_split_observer : public CGAL::Arr_observer<Arrangement_2>
n_faces (0)
{
CGAL_precondition (arr.is_empty());
arr.unbounded_face()->data().in_footprint=false;
for (auto uf = arr.unbounded_faces_begin();
uf != arr.unbounded_faces_end(); ++uf) {
uf->data().is_finite = false;
}
n_faces++;
}
virtual void after_split_face (Face_handle old_face,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ namespace roofer::detection {
// arr_common_face(edge->source(), edge->target(), common_face);
auto result = CGAL::intersection(Segment_2(e_source, e_target), segment);
if (result) {
if (auto p = boost::get<Point_2>(&*result)) {
if (auto p = std::get_if<Point_2>(&*result)) {
// std::cout << "\tp " << *p << std::endl;
// std::cout << "\tp (geo) " << CGAL::to_double(p->x())+CGAL::to_double(geo_p.x()) << ", " << CGAL::to_double(p->y())+CGAL::to_double(geo_p.y()) << std::endl;
// check if point of intersection is practically at the same coordinates of one of the edge's end points
Expand Down
4 changes: 2 additions & 2 deletions thirdparty/roofer/src/reconstruction/ArrangementExtruder.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -296,7 +296,7 @@ namespace roofer::detection {
auto l_a = EPECK::Line_3(EPECK::Point_3(p1.x(), p1.y(), h1a), EPECK::Point_3(p2.x(), p2.y(), h2a));
auto l_b = EPECK::Line_3(EPECK::Point_3(p1.x(), p1.y(), h1b), EPECK::Point_3(p2.x(), p2.y(), h2b));
auto result = CGAL::intersection(l_a, l_b);
auto px = boost::get<typename EPECK::Point_3>(&*result);
auto px = std::get_if<typename EPECK::Point_3>(&*result);

// TODO: check if distance from px to p1 and p2 is longer than snap_tolerance?

Expand Down Expand Up @@ -334,7 +334,7 @@ namespace roofer::detection {
auto l_a = EPECK::Line_3(EPECK::Point_3(p1.x(), p1.y(), h1a), EPECK::Point_3(p2.x(), p2.y(), h2a));
auto l_b = EPECK::Line_3(EPECK::Point_3(p1.x(), p1.y(), h1b), EPECK::Point_3(p2.x(), p2.y(), h2b));
auto result = CGAL::intersection(l_a, l_b);
auto px = boost::get<typename EPECK::Point_3>(&*result);
auto px = std::get_if<typename EPECK::Point_3>(&*result);

// TODO: check if distance from px to p1 and p2 is longer than snap_tolerance?

Expand Down
4 changes: 2 additions & 2 deletions thirdparty/roofer/src/reconstruction/ArrangementSnapper.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -210,7 +210,7 @@ namespace arragementsnapper {
auto obj = walk_pl.locate( Walk_pl::Arrangement_2::Point_2(p.x(), p.y()) );

// std::cout << "The point (" << p << ") is located ";
if (auto f = boost::get<Face_const_handle>(&obj)) { // located inside a face
if (auto f = std::get_if<Face_const_handle>(&obj)) { // located inside a face
// std::cout << "inside "
// << (((*f)->is_unbounded()) ? "the unbounded" : "a bounded")
// << " face." << std::endl;
Expand Down Expand Up @@ -476,7 +476,7 @@ namespace arragementsnapper {

auto obj = walk_pl.locate( Walk_pl::Arrangement_2::Point_2(p.x(), p.y()) );

if (auto f = boost::get<Face_const_handle>(&obj)) { // located inside a face
if (auto f = std::get_if<Face_const_handle>(&obj)) { // located inside a face
// arrFace->data() = (*f)->data();
canidate_faces[arr.non_const_handle(*f)] += cdt.triangle(fit).area();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -233,7 +233,7 @@ namespace linereg {
Segment_2 s(a_2d.target(), b_2d.source());
auto result = CGAL::intersection(l_a, l_b);
if (result) {
if (auto p = boost::get<Point_2>(&*result)) {
if (auto p = std::get_if<Point_2>(&*result)) {
if (CGAL::squared_distance(*p, s) < snap_threshold) {
double z = -plane.a()/plane.c() * p->x() - plane.b()/plane.c()*p->y() - plane.d()/plane.c();
ring_pts.push_back( Point_3(p->x(), p->y(), z) );
Expand Down
3 changes: 2 additions & 1 deletion thirdparty/roofer/src/reconstruction/PlaneIntersector.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
#include "PlaneIntersector.hpp"

#include <map>
#include <optional>

namespace roofer::detection {

Expand Down Expand Up @@ -72,7 +73,7 @@ namespace roofer::detection {
auto result = CGAL::intersection(plane_hi, plane_lo);
if (result) {
// bound the line to extend of one plane's inliers
if (auto l = boost::get<typename EPICK::Line_3>(&*result)) {
if (auto l = std::get_if<typename EPICK::Line_3>(&*result)) {
Point pmin_lo, pmax_lo;
Point pmin_hi, pmax_hi;
double dmin_lo, dmax_lo;
Expand Down
Loading

0 comments on commit 275c279

Please sign in to comment.