Merge pull request #14 from kenohori/cgal

Bugfixes + some validation code when creating New polyhedra
This commit is contained in:
Ken Arroyo Ohori
2017-03-30 19:16:48 -06:00
committed by GitHub
5 changed files with 59 additions and 25 deletions
@@ -5,21 +5,13 @@ bool IfcGeom::CgalKernel::convert_wire_to_face(const cgal_wire_t& wire, cgal_fac
return true;
}
void IfcGeom::CgalKernel::remove_duplicate_points_from_loop(cgal_wire_t& polygon, bool closed, double tol) {
if (tol <= 0.) tol = getValue(GV_PRECISION);
tol *= tol;
void IfcGeom::CgalKernel::remove_duplicate_points_from_loop(cgal_wire_t& polygon) {
std::set<cgal_point_t> points;
for (int i = 0; i < polygon.size(); ++i) {
for (int j = i+1; j < polygon.size(); ++j) {
if (CGAL::squared_distance(polygon[i], polygon[j]) < tol) {
polygon.erase(polygon.begin()+j);
--j;
}
} if (closed) {
if (CGAL::squared_distance(polygon.front(), polygon.back()) < tol) {
polygon.erase(polygon.begin()+polygon.size()-1);
}
}
if (points.count(polygon[i])) {
polygon.erase(polygon.begin()+i);
--i;
} else points.insert(polygon[i]);
}
}
@@ -51,8 +43,28 @@ CGAL::Polyhedron_3<Kernel> IfcGeom::CgalKernel::create_polyhedron(std::list<cgal
return polyhedron;
}
CGAL::Polyhedron_3<Kernel> IfcGeom::CgalKernel::create_polyhedron(CGAL::Nef_polyhedron_3<Kernel> &nef_polyhedron) {
if (nef_polyhedron.is_simple()) {
CGAL::Polyhedron_3<Kernel> polyhedron;
nef_polyhedron.convert_to_polyhedron(polyhedron);
return polyhedron;
} else {
std::cout << "Nef polyhedron not simple: cannot create polyhedron!" << std::endl;
return CGAL::Polyhedron_3<Kernel>();
}
}
CGAL::Nef_polyhedron_3<Kernel> IfcGeom::CgalKernel::create_nef_polyhedron(std::list<cgal_face_t> &face_list) {
CGAL::Polyhedron_3<Kernel> polyhedron = create_polyhedron(face_list);
return CGAL::Nef_polyhedron_3<Kernel>(polyhedron);
}
CGAL::Nef_polyhedron_3<Kernel> IfcGeom::CgalKernel::create_nef_polyhedron(CGAL::Polyhedron_3<Kernel> &polyhedron) {
if (polyhedron.is_valid()) {
CGAL::Polygon_mesh_processing::triangulate_faces(polyhedron);
return CGAL::Nef_polyhedron_3<Kernel>(polyhedron);
} else {
std::cout << "Polyhedron not valid: cannot create Nef polyhedron!" << std::endl;
return CGAL::Nef_polyhedron_3<Kernel>();
}
}
@@ -86,6 +86,14 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcAxis2Placement2D* l, cgal_
if ( hasRef ) IfcGeom::CgalKernel::convert(l->RefDirection(),refDirection);
cgal_direction_t y = Kernel::Vector_3(-refDirection.y(), refDirection.x(), 0.0);
const double tolerance = 0.01;
if (refDirection.squared_length() < 1.0-tolerance || refDirection.squared_length() > 1.0+tolerance ||
y.squared_length() < 1.0-tolerance || y.squared_length() > 1.0+tolerance) {
std::cout << "Ref direction (x): " << refDirection << " squared length: " << refDirection.squared_length() << std::endl;
std::cout << "y: " << y << " squared length: " << y.squared_length() << std::endl;
std::cout << "Origin: " << o << std::endl;
}
// TODO: Should be checked.
trsf = Kernel::Aff_transformation_3(refDirection.cartesian(0), y.cartesian(0), 0.0, o.cartesian(0),
refDirection.cartesian(1), y.cartesian(1), 0.0, o.cartesian(1),
@@ -107,9 +115,16 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcAxis2Placement3D* l, cgal_
Kernel::Vector_3 y = CGAL::cross_product(axis, refDirection);
Kernel::Vector_3 x = CGAL::cross_product(y, axis);
// std::cout << "Ref direction: " << refDirection << std::endl;
// std::cout << "Axis: " << axis << std::endl;
// std::cout << "Origin: " << o << std::endl;
const double tolerance = 0.01;
if (x.squared_length() < 1.0-tolerance || x.squared_length() > 1.0+tolerance ||
y.squared_length() < 1.0-tolerance || y.squared_length() > 1.0+tolerance ||
axis.squared_length() < 1.0-tolerance || axis.squared_length() > 1.0+tolerance) {
std::cout << "Ref direction: " << refDirection << " squared length: " << refDirection.squared_length() << std::endl;
std::cout << "Axis (z): " << axis << " squared length: " << axis.squared_length() << std::endl;
std::cout << "y: " << y << " squared length: " << y.squared_length() << std::endl;
std::cout << "x: " << x << " squared length: " << x.squared_length() << std::endl;
std::cout << "Origin: " << o << std::endl;
}
// TODO: Should be checked.
trsf = Kernel::Aff_transformation_3(x.cartesian(0), y.cartesian(0), axis.cartesian(0), o.cartesian(0),
@@ -133,6 +148,12 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcAxis1Placement* l, cgal_pl
IfcGeom::CgalKernel::convert(l->Location(),o);
if ( l->hasAxis() ) IfcGeom::CgalKernel::convert(l->Axis(), axis);
const double tolerance = 0.01;
if (axis.squared_length() < 1.0-tolerance || axis.squared_length() > 1.0+tolerance) {
std::cout << "Axis (z): " << axis << " squared length: " << axis.squared_length() << std::endl;
std::cout << "Origin: " << o << std::endl;
}
// TODO: Should be checked.
ax = Kernel::Aff_transformation_3(1.0, 0.0, axis.cartesian(0), o.cartesian(0),
0.0, 1.0, axis.cartesian(1), o.cartesian(1),
@@ -63,9 +63,9 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcShellBasedSurfaceModel* l,
bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcManifoldSolidBrep* l, ConversionResults& shape) {
cgal_shape_t s;
CGAL::Nef_polyhedron_3<Kernel> nef_s(s);
const SurfaceStyle* collective_style = get_style(l);
if (convert_shape(l->Outer(),s) ) {
CGAL::Nef_polyhedron_3<Kernel> nef_s = create_nef_polyhedron(s);
const SurfaceStyle* indiv_style = get_style(l->Outer());
IfcSchema::IfcClosedShell::list::ptr voids(new IfcSchema::IfcClosedShell::list);
@@ -80,16 +80,15 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcManifoldSolidBrep* l, Conv
for (IfcSchema::IfcClosedShell::list::it it = voids->begin(); it != voids->end(); ++it) {
cgal_shape_t s2;
CGAL::Nef_polyhedron_3<Kernel> nef_s2(s2);
// TODO: This looks weird. Aren't we removing the outer shell again and again?
// Maybe it should be
// if (convert_shape(*it, s2)) {
if (convert_shape(l->Outer(), s2)) {
nef_s -= nef_s2;
nef_s -= CGAL::Nef_polyhedron_3<Kernel>(s2);
}
}
nef_s.convert_to_polyhedron(s);
s = create_polyhedron(nef_s);
shape.push_back(ConversionResult(new CgalShape(s), indiv_style ? indiv_style : collective_style));
return true;
}
@@ -19,7 +19,7 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcPolyLoop* l, cgal_wire_t&
}
// Remove points that are too close to one another
remove_duplicate_points_from_loop(polygon, true);
remove_duplicate_points_from_loop(polygon);
std::size_t count = polygon.size();
if (original_count - count != 0) {
@@ -54,7 +54,7 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcPolyline* l, cgal_wire_t&
}
// Remove points that are too close to one another
remove_duplicate_points_from_loop(polygon, false);
remove_duplicate_points_from_loop(polygon);
result = polygon;
return true;
@@ -198,7 +198,7 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcCompositeCurve* l, cgal_wi
}
}
remove_duplicate_points_from_loop(w, false);
remove_duplicate_points_from_loop(w);
wire = w;
return true;
+3 -1
View File
@@ -136,12 +136,14 @@ namespace IfcGeom {
bool convert_wire_to_face(const cgal_wire_t& wire, cgal_face_t& face);
void remove_duplicate_points_from_loop(cgal_wire_t& polygon, bool closed, double tol = -1.);
void remove_duplicate_points_from_loop(cgal_wire_t& polygon);
bool convert_openings(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings, const ConversionResults& entity_shapes, const cgal_placement_t& entity_trsf, ConversionResults& cut_shapes);
CGAL::Polyhedron_3<Kernel> create_polyhedron(std::list<cgal_face_t> &face_list);
CGAL::Polyhedron_3<Kernel> create_polyhedron(CGAL::Nef_polyhedron_3<Kernel> &nef_polyhedron);
CGAL::Nef_polyhedron_3<Kernel> create_nef_polyhedron(std::list<cgal_face_t> &face_list);
CGAL::Nef_polyhedron_3<Kernel> create_nef_polyhedron(CGAL::Polyhedron_3<Kernel> &polyhedron);
void purge_cache() {
// Rather hack-ish, but a stopgap solution to keep memory under control