Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update repository #1

Draft
wants to merge 47 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
47 commits
Select commit Hold shift + click to select a range
c98027f
add option for RANSAC plane detection, improve polygon triangulator m…
Ylannl May 14, 2023
6cd53ec
add Regularise planes node
Ylannl May 25, 2023
1bb9ed0
finish regularise planes node
Ylannl May 30, 2023
0a94023
detect when a triangulated CGAL SurfaceMesh face somehow seems to hav…
Ylannl May 30, 2023
c4310cf
Merge commit '0a94023a6d83e501b5c415de917b651d9d554e91' into develop
Ylannl May 30, 2023
e002265
formatting
Ylannl May 30, 2023
c752fb7
implement triangle based volume calculation
Ylannl Jun 5, 2023
0f31515
add volume calculation to triangulation node
Ylannl Jun 6, 2023
ba9fb11
add option to output one mtc for each mesh input in triangulator node
Ylannl Jun 7, 2023
c5a05da
add RoofPartition3DBAGRasteriseNode
Ylannl Jun 12, 2023
1e05ba3
fix potential inf loop in surface mesh simplification node
Ylannl Jun 16, 2023
a9e5058
Merge branch 'develop'
balazsdukai Jun 19, 2023
a258df3
Bump version to 0.3.3
balazsdukai Jun 19, 2023
189f49a
remove inline keyword
Ylannl Jul 17, 2023
7820f31
bump version
Ylannl Jul 17, 2023
708dbc1
integrate plane regularisation code into plane detection node
Ylannl Jul 27, 2023
80ffe8c
correct for z offset in RoofPartition3DBAGRasteriseNode
Ylannl Aug 7, 2023
32c6488
bump version number
Ylannl Aug 14, 2023
b063ac8
more robust mesh repair for CGAL Surface mesh to fix infinite loop in…
Ylannl Aug 16, 2023
629a26b
bump version
Ylannl Aug 16, 2023
062fe5f
always write mtc in PolygonTriangulatorNode
Ylannl Oct 5, 2023
a666475
option for smooth normals in MeshClipperNode
Ylannl Dec 14, 2023
9f5d9c1
add MeshSimplify2DNode
Ylannl Jan 19, 2024
0c7298e
Merge branch 'master' into develop
Ylannl Jan 19, 2024
55f5cdb
fix handling of vertical faces in MeshSimplify2D Node
Ylannl Jan 26, 2024
30b2913
implement slope/azimuth calculation for roofparts
Ylannl Feb 12, 2024
2b4f4f3
MeshSimplify2DNode: add minpts parameter
Ylannl Feb 21, 2024
8a8b2f6
MeshSimplify2DNode: further improvements minpts feature
Ylannl Feb 21, 2024
b4d40f1
update region-grower code
Ylannl Feb 22, 2024
4b6d2b5
debug slope/azimuth code
Ylannl Feb 23, 2024
fbe70ed
fix degree conversion for azimuth
Ylannl Feb 23, 2024
d16ea6c
bump version
Ylannl Feb 23, 2024
dd11302
attempt to fix duplicate rings in polygon triangulator
Ylannl Feb 28, 2024
ddc11cf
bump version
Ylannl Feb 28, 2024
a64aa9c
fix windows build
Ylannl Mar 8, 2024
1e9de98
bump version
Ylannl Mar 8, 2024
61bbb6c
windows build fixes
Ylannl Mar 8, 2024
2cc58f4
fix potential crash with height calculation
Ylannl Apr 14, 2024
afee286
fix potential crash due to invalid normal
Ylannl Apr 14, 2024
c20d971
bump version
Ylannl Apr 20, 2024
3d0f5d6
Merge branch 'master' into develop
Ylannl Apr 20, 2024
363deda
bump version
Ylannl Apr 20, 2024
19f8c9c
set ptinpoly c_standard to 90
Ylannl Jul 24, 2024
8f3284d
prevent crash due to CGAL uncertain_conversion_exception
Ylannl Aug 8, 2024
f03b0d0
bump version
Ylannl Aug 9, 2024
b3ea57d
fix azimuth/slope calculation
Ylannl Dec 3, 2024
7eeee94
bump version
Ylannl Dec 3, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 4 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.21)
project (building-reconstruction VERSION 0.3.2)
project (building-reconstruction VERSION 0.4.5)

option(GFP_WITH_PDAL "Build parts dependent on PDAL" OFF)

Expand All @@ -17,7 +17,7 @@ endif(GFP_WITH_PDAL)
add_library(ptinpoly STATIC thirdparty/ptinpoly/ptinpoly.c)
set_target_properties(
ptinpoly PROPERTIES
C_STANDARD 11
C_STANDARD 90
POSITION_INDEPENDENT_CODE ON
)

Expand Down Expand Up @@ -81,6 +81,7 @@ geoflow_create_plugin(
src/MeshSimplify.cpp
src/MeshGridSimplify.cpp
src/Mesh2TriangleCollectionNode.cpp
src/tinsimp.cpp
)

target_include_directories(gfp_buildingreconstruction PRIVATE
Expand Down Expand Up @@ -109,4 +110,4 @@ if (MSVC)
FILES_MATCHING
PATTERN "*.dll"
PATTERN "gfp*" EXCLUDE)
endif()
endif()
3 changes: 3 additions & 0 deletions register.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,8 +78,11 @@ void register_nodes(geoflow::NodeRegister& node_register) {
node_register.register_node<MaxInscribedCircleNode>("MaxInscribedCircle");
node_register.register_node<MeshSimplifyFastQuadNode>("MeshSimplifyFastQuad");
node_register.register_node<MeshSimplifyNode>("MeshSimplify");
node_register.register_node<SurfaceMesh2OFFNode>("SurfaceMesh2OFF");
node_register.register_node<MeshGridSimplifyNode>("MeshGridSimplify");
node_register.register_node<MeshClipperNode>("MeshClipper");
node_register.register_node<Mesh2TriangleCollectionNode>("Mesh2TriangleCollection");
node_register.register_node<Mesh2CGALSurfaceMeshNode>("Mesh2CGALSurfaceMesh");
node_register.register_node<RoofPartition3DBAGRasteriseNode>("RoofPartition3DBAGRasterise");
node_register.register_node<MeshSimplify2DNode>("MeshSimplify2D");
}
43 changes: 36 additions & 7 deletions src/Mesh2TriangleCollectionNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

#include <CGAL/Polygon_mesh_processing/compute_normal.h>
#include <CGAL/Polygon_mesh_processing/triangulate_faces.h>
#include <cstddef>

#include <CGAL/Polygon_mesh_processing/manifoldness.h>
#include <CGAL/Polygon_mesh_processing/repair.h>
#include <CGAL/Polygon_mesh_processing/repair_polygon_soup.h>
#include <CGAL/Polygon_mesh_processing/orient_polygon_soup_extension.h>

namespace geoflow::nodes::stepedge {

Expand Down Expand Up @@ -30,7 +36,7 @@ namespace geoflow::nodes::stepedge {

TriangleCollection triangleCollection;
vec3f normals;
for (auto& f : smesh.faces()) {
for (auto f : smesh.faces()) {
Triangle t;
unsigned i = 0;

Expand Down Expand Up @@ -61,31 +67,54 @@ namespace geoflow::nodes::stepedge {

SurfaceMesh smesh;
{
std::map<arr3f, VertexIndex> vertex_map;
std::map<arr3f, std::size_t> vertex_map;
std::set<arr3f> vertex_set;
std::vector<K::Point_3> points;
for (const auto &ring : gfmesh.get_polygons())
{
for (auto &v : ring)
{
auto [it, did_insert] = vertex_set.insert(v);
if (did_insert)
{
vertex_map[v] = smesh.add_vertex(K::Point_3(v[0],v[1],v[2]));;
vertex_map[v] = points.size();
points.push_back(K::Point_3(v[0],v[1],v[2]));
}
}
}


// First build a polygon soup
std::vector<std::vector<std::size_t> > polygons;
for (auto& ring : gfmesh.get_polygons()) {
std::vector<VertexIndex> rindices;
std::vector<std::size_t> rindices;
rindices.reserve(ring.size());
for(auto& p : ring) {
rindices.push_back(vertex_map[p]);
}
smesh.add_face(rindices);
polygons.push_back(rindices);
}

// Do CGAL mesh repair magic, see https://github.com/CGAL/cgal/issues/7529

// remove all kinds of typical issues in a polygon soup (degenerate polygons, isolated points, etc.)
CGAL::Polygon_mesh_processing::repair_polygon_soup(points, polygons);

// duplicate non-manifold edges (but does not re-orient faces)
CGAL::Polygon_mesh_processing::duplicate_non_manifold_edges_in_polygon_soup(points, polygons);

CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(points, polygons, smesh);

if(!CGAL::is_triangle_mesh(smesh)) PMP::triangulate_faces(smesh);

// this prevents potentially getting stuck in infinite loop (see https://github.com/CGAL/cgal/issues/7529)
CGAL::Polygon_mesh_processing::duplicate_non_manifold_vertices( smesh );

// this is not needed since PMP::repair_polygon_soup() will perform this repair
// CGAL::Polygon_mesh_processing::remove_isolated_vertices( smesh );

}

if(!CGAL::is_triangle_mesh(smesh)) PMP::triangulate_faces(smesh);


output("cgal_surface_mesh").set(smesh);
}
Expand Down
150 changes: 89 additions & 61 deletions src/MeshClipperNode.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,43 @@ namespace geoflow::nodes::stepedge {
return t;
}

struct MeshBuilder {
std::map<K::Point_3, std::size_t> vertex_map;
std::set<K::Point_3> vertex_set;
std::vector<K::Point_3> points;

std::vector<std::vector<std::size_t> > polygons;

void add_point(const K::Point_3& p) {
auto [it, did_insert] = vertex_set.insert(p);
if (did_insert)
{
vertex_map[p] = points.size();
points.push_back(p);
}
}

void add_triangle(const K::Point_3& p0, const K::Point_3& p1, const K::Point_3& p2) {
add_point(p0);
add_point(p1);
add_point(p2);

// First build a polygon soup
std::vector<std::size_t> rindices;
rindices.reserve(3);
rindices.push_back(vertex_map[p0]);
rindices.push_back(vertex_map[p1]);
rindices.push_back(vertex_map[p2]);
polygons.push_back(rindices);
}

void get_mesh(SurfaceMesh& smesh) {
smesh.clear();
CGAL::Polygon_mesh_processing::polygon_soup_to_polygon_mesh(points, polygons, smesh);
}

};

void MeshClipperNode::process() {

typedef SurfaceMesh::Vertex_index VertexIndex;
Expand All @@ -38,32 +75,6 @@ namespace geoflow::nodes::stepedge {
namespace PMP = CGAL::Polygon_mesh_processing;

auto smesh = input("mesh").get<SurfaceMesh>();

// SurfaceMesh smesh;
// {
// std::map<arr3f, VertexIndex> vertex_map;
// std::set<arr3f> vertex_set;
// for (const auto &ring : gfmesh.get_polygons())
// {
// for (auto &v : ring)
// {
// auto [it, did_insert] = vertex_set.insert(v);
// if (did_insert)
// {
// vertex_map[v] = smesh.add_vertex(Point_3(v[0],v[1],v[2]));;
// }
// }
// }

// for (auto& ring : gfmesh.get_polygons()) {
// std::vector<VertexIndex> rindices;
// rindices.reserve(ring.size());
// for(auto& p : ring) {
// rindices.push_back(vertex_map[p]);
// }
// smesh.add_face(rindices);
// }
// }

// clip
if(!CGAL::is_triangle_mesh(smesh)) PMP::triangulate_faces(smesh);
Expand All @@ -76,12 +87,6 @@ namespace geoflow::nodes::stepedge {
Point_3(pmax[0], pmax[1], pmax[2])
);

TriangleCollection triangleCollection;
vec3f normals;

auto fnormals = smesh.add_property_map<FaceIndex, K::Vector_3>("f:normals", CGAL::NULL_VECTOR).first;
PMP::compute_face_normals(smesh, fnormals);

if (!skip_clip_) {
if (cgal_clip_) { // use cgal mesh_processing
if (!PMP::does_self_intersect(smesh)) {
Expand All @@ -91,8 +96,9 @@ namespace geoflow::nodes::stepedge {
);
}
} else {
MeshBuilder mb;
CGAL::Vertex_around_face_iterator<SurfaceMesh> vit, vend;
for (auto& f : smesh.faces()) {
for (auto f : smesh.faces()) {
boost::tie(vit, vend) = CGAL::vertices_around_face(smesh.halfedge(f), smesh);
auto end = vit;
K::Point_3 p1 = smesh.point(*vit); vit++;
Expand All @@ -106,61 +112,83 @@ namespace geoflow::nodes::stepedge {

const auto result = CGAL::intersection(triangle, cuboid);
if (result) {
auto& n = fnormals[f];
// auto& n = fnormals[f];
if (const Triangle_3* tri = boost::get<Triangle_3>(&*result)) {
triangleCollection.push_back(create_gf_triangle(
mb.add_triangle(
tri->vertex(0),
tri->vertex(1),
tri->vertex(2)
));
normals.push_back(arr3f{ float(n.x()), float(n.y()), float(n.z()) });
normals.push_back(arr3f{ float(n.x()), float(n.y()), float(n.z()) });
normals.push_back(arr3f{ float(n.x()), float(n.y()), float(n.z()) });
);
} else if (const Poly_3* poly = boost::get<Poly_3 >(&*result)) {
// std::cout << "polygon! [" << poly->size() << std::endl;

for(unsigned i=0; i<poly->size()-2; ++i) {
// std::cout << i << " ";
triangleCollection.push_back(create_gf_triangle(
mb.add_triangle(
(*poly)[0],
(*poly)[i+1],
(*poly)[i+2]
));
normals.push_back(arr3f{ float(n.x()), float(n.y()), float(n.z()) });
normals.push_back(arr3f{ float(n.x()), float(n.y()), float(n.z()) });
normals.push_back(arr3f{ float(n.x()), float(n.y()), float(n.z()) });
);
}

}
}
}
mb.get_mesh(smesh);
}
}

if (skip_clip_ || cgal_clip_) {
for (auto& f : smesh.faces()) {
Triangle t;
unsigned i = 0;

for(VertexIndex vi : vertices_around_face(smesh.halfedge(f), smesh)) {
auto& p = smesh.point(vi);
t[i++] = arr3f{
auto fnormals = smesh.add_property_map<FaceIndex, K::Vector_3>("f:normals", CGAL::NULL_VECTOR).first;
auto vnormals = smesh.add_property_map<VertexIndex, K::Vector_3>("v:normals", CGAL::NULL_VECTOR).first;

if (smooth_normals_) {
PMP::compute_vertex_normals(smesh, vnormals);
} else {
PMP::compute_face_normals(smesh, fnormals);
}

// convert to triangleCollection
TriangleCollection triangleCollection;
vec3f normals;
for (auto f : smesh.faces()) {
Triangle t;

unsigned i = 0;
for(VertexIndex vi : vertices_around_face(smesh.halfedge(f), smesh)) {
if(i==3) {
std::cout << "WARNING: skipping triangulated SurfaceMesh face with more than 3 vertices\n";
continue;
}
auto& p = smesh.point(vi);
t[i++] = arr3f{
(float) p.x(),
(float) p.y(),
(float) p.z()
};
};
// if (!smesh.is_border(vi)) {
if (smooth_normals_) {
normals.push_back(arr3f{
float(vnormals[vi].x()),
float(vnormals[vi].y()),
float(vnormals[vi].z()) });
} else {
normals.push_back(arr3f{
float(fnormals[f].x()),
float(fnormals[f].y()),
float(fnormals[f].z()) });
}
auto& n = fnormals[f];
normals.push_back(arr3f{ float(n.x()), float(n.y()), float(n.z()) });
normals.push_back(arr3f{ float(n.x()), float(n.y()), float(n.z()) });
normals.push_back(arr3f{ float(n.x()), float(n.y()), float(n.z()) });
triangleCollection.push_back(t);
}
}
// if (!smooth_normals_) {


// normals.push_back(arr3f{ float(n.x()), float(n.y()), float(n.z()) });
// normals.push_back(arr3f{ float(n.x()), float(n.y()), float(n.z()) });
// }
triangleCollection.push_back(t);
}

output("triangles").set(triangleCollection);
output("normals").set(normals);
// output("cgal_surface_mesh").set(smesh);
}

}
}
6 changes: 3 additions & 3 deletions src/MeshGridSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ namespace geoflow::nodes::stepedge {
// merge vertices in each grid cell, and create a mapping (old vertex indices -> new vertex indices, std::map<unsigned, unsigned>)
Grid2D G(box, cell_size_xy_, cell_size_z_);
std::unordered_map<unsigned, unsigned> vertex_map;
for (auto& vi : smesh.vertices()) {
for (auto vi : smesh.vertices()) {
unsigned c = G.getCellCoordinate( smesh.point(vi) );
vertex_map[vi] = c;
}
Expand All @@ -161,15 +161,15 @@ namespace geoflow::nodes::stepedge {
// Cluster(float x, float y) : x(x), y(y) {};
// };
std::unordered_map<unsigned, arr3f> new_vertices;
for (auto& f : smesh.faces()) {
for (auto f : smesh.faces()) {
for(VertexIndex vi : vertices_around_face(smesh.halfedge(f), smesh)) {
auto p = G.getCellCenterPoint(vertex_map[vi]);
new_mesh_vertices[vertex_map[vi]] = smesh_new.add_vertex(K::Point_3(p[0], p[1], p[2]));
}
}
}
{
for (auto& f : smesh.faces()) {
for (auto f : smesh.faces()) {
std::set<unsigned> face_set;
for(VertexIndex vi : vertices_around_face(smesh.halfedge(f), smesh)) {
face_set.insert(vertex_map[vi]);
Expand Down
Loading