From 4f5ecee81e59d6eb567c521d453905c0f78e7462 Mon Sep 17 00:00:00 2001 From: Ken Arroyo Ohori Date: Mon, 6 Mar 2017 16:03:29 -0600 Subject: [PATCH] Removing duplicate points, IfcCartesianTransformationOperator3D with problems --- .../kernels/cgal/CgalConversionFunctions.cpp | 41 +++++++++++++++++++ src/ifcgeom/kernels/cgal/CgalEntityMapping.h | 1 + .../kernels/cgal/CgalIfcGeomShapes.cpp | 23 ++++++++++- src/ifcgeom/kernels/cgal/CgalIfcGeomWires.cpp | 8 ++-- src/ifcgeom/kernels/cgal/CgalKernel.h | 2 + 5 files changed, 69 insertions(+), 6 deletions(-) diff --git a/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp b/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp index d0d6be43bc..6866dea9e9 100644 --- a/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp +++ b/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp @@ -152,3 +152,44 @@ bool IfcGeom::CgalKernel::convert_wire_to_face(const cgal_wire_t& wire, cgal_fac face.outer = wire; return true; } + +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcCartesianTransformationOperator3D* l, cgal_placement_t& trsf) { +// IN_CACHE(IfcCartesianTransformationOperator3D,l,gp_Trsf,trsf) + cgal_point_t origin; + IfcGeom::CgalKernel::convert(l->LocalOrigin(),origin); + cgal_direction_t axis1 (1.,0.,0.); + cgal_direction_t axis2 (0.,1.,0.); + cgal_direction_t axis3 (0.,0.,1.); + if ( l->hasAxis1() ) IfcGeom::CgalKernel::convert(l->Axis1(),axis1); + if ( l->hasAxis2() ) IfcGeom::CgalKernel::convert(l->Axis2(),axis2); + if ( l->hasAxis3() ) IfcGeom::CgalKernel::convert(l->Axis3(),axis3); + double scale = 1.0; + if (l->hasScale()) { + scale = l->Scale(); + } + + trsf = Kernel::Aff_transformation_3(scale*axis1.cartesian(0), axis2.cartesian(0), axis3.cartesian(0), origin.cartesian(0), + axis1.cartesian(1), scale*axis2.cartesian(1), axis3.cartesian(1), origin.cartesian(1), + axis1.cartesian(2), axis2.cartesian(2), scale*axis3.cartesian(2), origin.cartesian(2)); + +// CACHE(IfcCartesianTransformationOperator3D,l,trsf) + 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; + + 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); + } + } + } +} diff --git a/src/ifcgeom/kernels/cgal/CgalEntityMapping.h b/src/ifcgeom/kernels/cgal/CgalEntityMapping.h index 072594ce65..78ab93c02e 100644 --- a/src/ifcgeom/kernels/cgal/CgalEntityMapping.h +++ b/src/ifcgeom/kernels/cgal/CgalEntityMapping.h @@ -64,3 +64,4 @@ CLASS(IfcDirection,cgal_direction_t); CLASS(IfcAxis2Placement2D,cgal_placement_t); CLASS(IfcAxis2Placement3D,cgal_placement_t); CLASS(IfcObjectPlacement,cgal_placement_t); +CLASS(IfcCartesianTransformationOperator3D,cgal_placement_t); diff --git a/src/ifcgeom/kernels/cgal/CgalIfcGeomShapes.cpp b/src/ifcgeom/kernels/cgal/CgalIfcGeomShapes.cpp index 10f7bde015..0bdd75128f 100644 --- a/src/ifcgeom/kernels/cgal/CgalIfcGeomShapes.cpp +++ b/src/ifcgeom/kernels/cgal/CgalIfcGeomShapes.cpp @@ -43,8 +43,7 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcMappedItem* l, ConversionR return false; } else if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator3D) ) { cgal_placement_t trsf; - Logger::Message(Logger::LOG_ERROR, "Unsupported MappingTarget:", transform->entity); -// IfcGeom::CgalKernel::convert((IfcSchema::IfcCartesianTransformationOperator3D*)transform,trsf); + IfcGeom::CgalKernel::convert((IfcSchema::IfcCartesianTransformationOperator3D*)transform,trsf); gtrsf = trsf; } else if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator2D) ) { cgal_placement_t trsf_2d; @@ -108,6 +107,7 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcExtrudedAreaSolid *l, cgal cgal_face_t face; if ( !convert_face(l->SweptArea(),face) ) return false; +// std::cout << "Face vertices: " << face.outer.size() << std::endl; cgal_placement_t trsf; bool has_position = true; @@ -125,6 +125,17 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcExtrudedAreaSolid *l, cgal std::list face_list; face_list.push_back(face); +// if (true) { +// cgal_shape_t polyhedron = CGAL::Polyhedron_3(); +// PolyhedronBuilder builder(&face_list); +// polyhedron.delegate(builder); +// +// std::ofstream fresult; +// fresult.open("/Users/ken/Desktop/profile.off"); +// fresult << polyhedron << std::endl; +// fresult.close(); +// } + for (std::vector::const_iterator current_vertex = face.outer.begin(); current_vertex != face.outer.end(); ++current_vertex) { @@ -155,6 +166,14 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcExtrudedAreaSolid *l, cgal // Stitch edges // std::cout << "Before: " << polyhedron.size_of_vertices() << " vertices and " << polyhedron.size_of_facets() << " facets" << std::endl; CGAL::Polygon_mesh_processing::stitch_borders(polyhedron); + if (!polyhedron.is_valid()) { + std::cout << "Invalid polyhedron!" << std::endl; + std::ofstream fresult; + fresult.open("/Users/ken/Desktop/invalid.off"); + fresult << polyhedron << std::endl; + fresult.close(); + } + if (!CGAL::Polygon_mesh_processing::is_outward_oriented(polyhedron)) { CGAL::Polygon_mesh_processing::reverse_face_orientations(polyhedron); } CGAL_postcondition(polyhedron.is_valid() && polyhedron.is_closed()); diff --git a/src/ifcgeom/kernels/cgal/CgalIfcGeomWires.cpp b/src/ifcgeom/kernels/cgal/CgalIfcGeomWires.cpp index c6d8820c65..b605eac93a 100644 --- a/src/ifcgeom/kernels/cgal/CgalIfcGeomWires.cpp +++ b/src/ifcgeom/kernels/cgal/CgalIfcGeomWires.cpp @@ -18,8 +18,8 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcPolyLoop* l, cgal_wire_t& return false; } - // TODO: Remove repeated points and points that are too close to one another - // remove_duplicate_points_from_loop(polygon, true); + // Remove points that are too close to one another + remove_duplicate_points_from_loop(polygon, true); std::size_t count = polygon.size(); if (original_count - count != 0) { @@ -53,8 +53,8 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcPolyline* l, cgal_wire_t& polygon.push_back(pnt); } - // TODO: Remove points that are too close to one another - // remove_duplicate_points_from_loop(polygon, false); + // Remove points that are too close to one another + remove_duplicate_points_from_loop(polygon, false); result = polygon; return true; diff --git a/src/ifcgeom/kernels/cgal/CgalKernel.h b/src/ifcgeom/kernels/cgal/CgalKernel.h index 748fd4fbb3..30d0a33792 100644 --- a/src/ifcgeom/kernels/cgal/CgalKernel.h +++ b/src/ifcgeom/kernels/cgal/CgalKernel.h @@ -133,6 +133,8 @@ namespace IfcGeom { bool convert_face(const IfcUtil::IfcBaseClass* L, cgal_face_t& result); 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.); // bool convert_openings(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings, const ConversionResults& entity_shapes, const gp_Trsf& entity_trsf, ConversionResults& cut_shapes);