Merge pull request #13 from kenohori/cgal

Move shapes back to Polyhedron_3, more IFC entities supported, bugfixes
This commit is contained in:
Ken Arroyo Ohori
2017-03-23 20:33:52 -06:00
committed by GitHub
10 changed files with 196 additions and 119 deletions
@@ -23,10 +23,10 @@ void IfcGeom::CgalKernel::remove_duplicate_points_from_loop(cgal_wire_t& polygon
}
}
CGAL::Nef_polyhedron_3<Kernel> IfcGeom::CgalKernel::create_nef_polyhedron(std::list<cgal_face_t> &face_list) {
CGAL::Polyhedron_3<Kernel> IfcGeom::CgalKernel::create_polyhedron(std::list<cgal_face_t> &face_list) {
// Naive creation
CGAL::Polyhedron_3<Kernel> polyhedron = CGAL::Polyhedron_3<Kernel>();
CGAL::Polyhedron_3<Kernel> polyhedron;
PolyhedronBuilder builder(&face_list);
polyhedron.delegate(builder);
@@ -34,35 +34,25 @@ CGAL::Nef_polyhedron_3<Kernel> IfcGeom::CgalKernel::create_nef_polyhedron(std::l
// 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 << "create_nef_polyhedron: Polyhedron not valid!" << std::endl;
// std::ofstream fresult;
// fresult.open("/Users/ken/Desktop/invalid.off");
// fresult << polyhedron << std::endl;
// fresult.close();
return CGAL::Nef_polyhedron_3<Kernel>();
} if (!polyhedron.is_closed()) {
// std::ofstream fresult;
// fresult.open("/Users/ken/Desktop/open.off");
// fresult << polyhedron << std::endl;
// fresult.close();
CGAL::Nef_polyhedron_3<Kernel> mesh;
unsigned int current_face = 0;
for (auto &face: faces(polyhedron)) {
++current_face;
// if (current_face%10 == 0) std::cout << current_face << "/" << polyhedron.size_of_facets() << std::endl;
std::list<Kernel::Point_3> points_in_face;
CGAL::Polyhedron_3<Kernel>::Halfedge_around_facet_const_circulator current_halfedge = face->facet_begin();
do {
points_in_face.push_back(current_halfedge->vertex()->point());
++current_halfedge;
} while (current_halfedge != face->facet_begin());
mesh += CGAL::Nef_polyhedron_3<Kernel>(points_in_face.begin(), points_in_face.end());
} return mesh;
}
if (!CGAL::Polygon_mesh_processing::is_outward_oriented(polyhedron)) {
CGAL::Polygon_mesh_processing::reverse_face_orientations(polyhedron);
std::cout << "create_polyhedron: Polyhedron not valid!" << std::endl;
// std::ofstream fresult;
// fresult.open("/Users/ken/Desktop/invalid.off");
// fresult << polyhedron << std::endl;
// fresult.close();
return CGAL::Polyhedron_3<Kernel>();
} if (polyhedron.is_closed()) {
if (!CGAL::Polygon_mesh_processing::is_outward_oriented(polyhedron)) {
CGAL::Polygon_mesh_processing::reverse_face_orientations(polyhedron);
}
}
// std::cout << "After: " << polyhedron.size_of_vertices() << " vertices and " << polyhedron.size_of_facets() << " facets" << std::endl;
return polyhedron;
}
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);
}
@@ -5,41 +5,8 @@ void IfcGeom::CgalShape::Triangulate(const IfcGeom::IteratorSettings & settings,
cgal_shape_t s = shape_;
const cgal_placement_t& trsf = dynamic_cast<const CgalPlacement*>(place)->trsf();
std::cout << "Nef Model: " << s.number_of_facets() << " facets and " << s.number_of_vertices() << " vertices" << std::endl;
std::cout << "Simple: " << s.is_simple() << std::endl;
CGAL::Polyhedron_3<Kernel> polyhedron;
if (s.is_simple()) s.convert_to_polyhedron(polyhedron);
else {
std::list<cgal_face_t> face_list;
face_list.push_back(cgal_face_t());
std::set<CGAL::Nef_polyhedron_3<Kernel>::Halffacet_const_handle> visited_halffacets;
for (CGAL::Nef_polyhedron_3<Kernel>::Halffacet_const_iterator current_halffacet = s.halffacets_begin();
current_halffacet != s.halffacets_end();
++current_halffacet) {
if (visited_halffacets.count(current_halffacet->twin())) continue;
for (CGAL::Nef_polyhedron_3<Kernel>::Halffacet_cycle_const_iterator current_halffacet_cycle = current_halffacet->facet_cycles_begin();
current_halffacet_cycle != current_halffacet->facet_cycles_end();
++current_halffacet_cycle) {
if (current_halffacet_cycle.is_shalfloop()) continue;
CGAL::Nef_polyhedron_3<Kernel>::SHalfedge_const_handle first_shalfedge = current_halffacet_cycle;
CGAL::Nef_polyhedron_3<Kernel>::SHalfedge_const_handle current_shalfedge = first_shalfedge;
if (!face_list.back().outer.empty()) face_list.push_back(cgal_face_t());
do {
face_list.back().outer.push_back(current_shalfedge->source()->center_vertex()->point());
current_shalfedge = current_shalfedge->next();
} while (current_shalfedge != first_shalfedge);
}
} if (face_list.back().outer.empty()) face_list.pop_back();
PolyhedronBuilder builder(&face_list);
polyhedron.delegate(builder);
}
std::cout << "Polyhedron Model: " << polyhedron.size_of_facets() << " facets and " << polyhedron.size_of_vertices() << " vertices" << std::endl;
std::cout << "Valid: " << polyhedron.is_valid() << std::endl;
// Apply transformation
if (place != NULL) for (auto &vertex: vertices(polyhedron)) {
if (place != NULL) for (auto &vertex: vertices(s)) {
vertex->point() = vertex->point().transform(trsf);
}
@@ -53,7 +20,7 @@ void IfcGeom::CgalShape::Triangulate(const IfcGeom::IteratorSettings & settings,
boost::associative_property_map<std::map<cgal_vertex_descriptor_t, Kernel::Vector_3>> vertex_normals_map(vertex_normals);
std::map<cgal_face_descriptor_t, Kernel::Vector_3> face_normals;
boost::associative_property_map<std::map<cgal_face_descriptor_t, Kernel::Vector_3>> face_normals_map(face_normals);
if (CGAL::Polygon_mesh_processing::triangulate_faces(polyhedron)) {
if (CGAL::Polygon_mesh_processing::triangulate_faces(s)) {
// std::cout << "Triangulated model: " << s.size_of_facets() << " facets and " << s.size_of_vertices() << " vertices" << std::endl;
} else {
Logger::Message(Logger::LOG_ERROR, "Failed to triangulate shape");
@@ -65,9 +32,9 @@ void IfcGeom::CgalShape::Triangulate(const IfcGeom::IteratorSettings & settings,
// fafter << s << std::endl;
// fafter.close();
CGAL::Polygon_mesh_processing::compute_normals(polyhedron, vertex_normals_map, face_normals_map);
CGAL::Polygon_mesh_processing::compute_normals(s, vertex_normals_map, face_normals_map);
for (auto &face: faces(polyhedron)) {
for (auto &face: faces(s)) {
if (!face->is_triangle()) {
std::cout << "Warning: non-triangular face!" << std::endl;
continue;
+46 -17
View File
@@ -39,55 +39,84 @@ SHAPES(IfcMappedItem);
SHAPES(IfcManifoldSolidBrep);
SHAPES(IfcGeometricSet);
#ifdef USE_IFC4
//SHAPE(IfcCylindricalSurface);
//SHAPE(IfcAdvancedBrep);
//SHAPE(IfcBSplineSurfaceWithKnots);
SHAPE(IfcTriangulatedFaceSet);
//SHAPE(IfcExtrudedAreaSolidTapered);
#endif
//SHAPE(IfcPlane);
SHAPE(IfcExtrudedAreaSolid);
//SHAPE(IfcRevolvedAreaSolid);
SHAPE(IfcConnectedFaceSet);
SHAPE(IfcCsgSolid);
SHAPE(IfcBlock);
SHAPE(IfcBooleanResult);
SHAPE(IfcSphere);
//SHAPE(IfcPolygonalBoundedHalfSpace);
SHAPE(IfcHalfSpaceSolid);
//SHAPE(IfcSurfaceOfLinearExtrusion);
//SHAPE(IfcSurfaceOfRevolution);
SHAPE(IfcBlock);
SHAPE(IfcRectangularPyramid);
SHAPE(IfcRightCircularCylinder);
SHAPE(IfcRightCircularCone);
#ifdef USE_IFC4
SHAPE(IfcTriangulatedFaceSet);
#endif
SHAPE(IfcHalfSpaceSolid);
SHAPE(IfcSphere);
SHAPE(IfcCsgSolid);
//SHAPE(IfcCurveBoundedPlane);
//SHAPE(IfcRectangularTrimmedSurface);
//SHAPE(IfcSurfaceCurveSweptAreaSolid);
//SHAPE(IfcSweptDiskSolid);
FACE(IfcArbitraryProfileDefWithVoids);
FACE(IfcArbitraryClosedProfileDef);
FACE(IfcCircleHollowProfileDef);
FACE(IfcCircleProfileDef);
FACE(IfcFace);
FACE(IfcRoundedRectangleProfileDef);
FACE(IfcRectangleHollowProfileDef);
FACE(IfcRectangleProfileDef);
FACE(IfcTrapeziumProfileDef);
FACE(IfcEllipseProfileDef);
FACE(IfcTrapeziumProfileDef)
FACE(IfcCShapeProfileDef);
// IfcAsymmetricIShapeProfileDef included
FACE(IfcIShapeProfileDef);
FACE(IfcLShapeProfileDef);
FACE(IfcTShapeProfileDef);
FACE(IfcUShapeProfileDef);
FACE(IfcZShapeProfileDef);
FACE(IfcCircleHollowProfileDef);
FACE(IfcCircleProfileDef);
FACE(IfcEllipseProfileDef);
//FACE(IfcCenterLineProfileDef);
//FACE(IfcCompositeProfileDef);
FACE(IfcDerivedProfileDef);
// IfcFaceSurface included
// IfcAdvancedFace included in case of IFC4
FACE(IfcFace);
WIRE(IfcEdgeLoop);
//WIRE(IfcEdgeCurve);
//WIRE(IfcSubedge);
WIRE(IfcOrientedEdge);
WIRE(IfcPolyLoop);
WIRE(IfcEdge);
WIRE(IfcEdgeLoop);
WIRE(IfcPolyline);
WIRE(IfcPolyLoop);
WIRE(IfcCompositeCurve);
WIRE(IfcTrimmedCurve);
//WIRE(IfcArbitraryOpenProfileDef);
CURVE(IfcCircle);
CURVE(IfcEllipse);
CURVE(IfcLine);
#ifdef USE_IFC4
// IfcRationalBSplineCurveWithKnots included
//CURVE(IfcBSplineCurveWithKnots);
#endif
CLASS(IfcCartesianPoint,cgal_point_t);
CLASS(IfcDirection,cgal_direction_t);
CLASS(IfcVector,cgal_vector_t);
CLASS(IfcPlane,cgal_plane_t);
CLASS(IfcAxis2Placement2D,cgal_placement_t);
CLASS(IfcAxis2Placement3D,cgal_placement_t);
CLASS(IfcObjectPlacement,cgal_placement_t);
CLASS(IfcAxis1Placement,cgal_placement_t);
CLASS(IfcCartesianTransformationOperator2DnonUniform,cgal_placement_t);
CLASS(IfcCartesianTransformationOperator3DnonUniform,cgal_placement_t);
CLASS(IfcCartesianTransformationOperator2D,cgal_placement_t);
CLASS(IfcCartesianTransformationOperator3D,cgal_placement_t);
CLASS(IfcObjectPlacement,cgal_placement_t);
CLASS(IfcVector,cgal_vector_t);
CLASS(IfcPlane,cgal_plane_t);
@@ -10,6 +10,21 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcArbitraryClosedProfileDef*
return success;
}
bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcArbitraryProfileDefWithVoids* l, cgal_face_t& face) {
cgal_wire_t profile;
if ( ! convert_wire(l->OuterCurve(),profile) ) return false;
cgal_face_t mf;
mf.outer = profile;
IfcSchema::IfcCurve::list::ptr voids = l->InnerCurves();
for( IfcSchema::IfcCurve::list::it it = voids->begin(); it != voids->end(); ++ it ) {
cgal_wire_t hole;
if ( convert_wire(*it,hole) ) {
mf.inner.push_back(hole);
}
} face = mf;
return true;
}
bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcRectangleProfileDef* l, cgal_face_t& face) {
const double x = l->XDim() / 2.0f * getValue(GV_LENGTH_UNIT);
const double y = l->YDim() / 2.0f * getValue(GV_LENGTH_UNIT);
@@ -956,3 +971,18 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcZShapeProfileDef* l, cgal_
return true;
}
bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcDerivedProfileDef* l, cgal_face_t& face) {
cgal_face_t f;
cgal_placement_t trsf2d;
if (convert_face(l->ParentProfile(), f) && IfcGeom::CgalKernel::convert(l->Operator(), trsf2d)) {
cgal_placement_t trsf = trsf2d;
for (auto &vertex: f.outer) vertex = vertex.transform(trsf);
for (auto &ring: f.inner) {
for (auto &vertex: ring) vertex = vertex.transform(trsf);
} face = f;
return true;
} else {
return false;
}
}
@@ -126,8 +126,23 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcAxis2Placement3D* l, cgal_
return true;
}
bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcAxis1Placement* l, cgal_placement_t& ax) {
// IN_CACHE(IfcAxis1Placement,l,gp_Ax1,ax)
cgal_point_t o;
cgal_direction_t axis = Kernel::Vector_3(0,0,1);
IfcGeom::CgalKernel::convert(l->Location(),o);
if ( l->hasAxis() ) IfcGeom::CgalKernel::convert(l->Axis(), axis);
// 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),
0.0, 0.0, axis.cartesian(2), o.cartesian(2));
// CACHE(IfcAxis1Placement,l,ax)
return true;
}
bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcObjectPlacement* l, cgal_placement_t& trsf) {
// TODO: These macros don't work for the CGAL types. Need to check why.
// IN_CACHE(IfcObjectPlacement,l,cgal_placement_t,trsf)
if ( ! l->is(IfcSchema::Type::IfcLocalPlacement) ) {
Logger::Message(Logger::LOG_ERROR, "Unsupported IfcObjectPlacement:", l->entity);
+41 -30
View File
@@ -50,7 +50,13 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcExtrudedAreaSolid *l, cgal
top_face.outer.push_back(*vertex+height*dir);
} face_list.push_back(top_face);
shape = create_nef_polyhedron(face_list);
if (bottom_face.inner.empty()) {
shape = create_polyhedron(face_list);
for (auto &vertex: vertices(shape)) vertex->point() = vertex->point().transform(trsf);
return true;
}
CGAL::Nef_polyhedron_3<Kernel> nef_shape = create_nef_polyhedron(face_list);
// Inner
// TODO: Would be faster to triangulate top/bottom face template rather than use Nef polyhedra for subtraction
@@ -84,10 +90,11 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcExtrudedAreaSolid *l, cgal
hole_top_face.outer.push_back(*vertex+height*dir);
} face_list.push_back(hole_top_face);
shape -= create_nef_polyhedron(face_list);
nef_shape -= create_nef_polyhedron(face_list);
}
shape.transform(trsf);
nef_shape.transform(trsf);
nef_shape.convert_to_polyhedron(shape);
return true;
}
@@ -116,7 +123,7 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcConnectedFaceSet* l, cgal_
face_list.push_back(face);
}
shape = create_nef_polyhedron(face_list);
shape = create_polyhedron(face_list);
return true;
}
@@ -176,9 +183,8 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcBlock* l, cgal_shape_t& sh
cgal_placement_t trsf;
IfcGeom::CgalKernel::convert(l->Position(),trsf);
shape = create_nef_polyhedron(face_list);
shape.transform(trsf);
shape = create_polyhedron(face_list);
for (auto &vertex: vertices(shape)) vertex->point() = vertex->point().transform(trsf);
return true;
}
@@ -233,8 +239,8 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcBooleanResult* l, cgal_sha
const IfcSchema::IfcBooleanOperator::IfcBooleanOperator op = l->Operator();
if (!s1.is_simple()) {
Logger::Message(Logger::LOG_ERROR, "s1: Not simple Nef?", operand1->entity);
if (!s1.is_valid()) {
Logger::Message(Logger::LOG_ERROR, "s1: Not valid?", operand1->entity);
return false;
} else {
// std::ofstream f1;
@@ -247,8 +253,8 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcBooleanResult* l, cgal_sha
bool is_plane = false;
cgal_plane_t plane;
if (!s2.is_simple()) {
Logger::Message(Logger::LOG_ERROR, "s2: Not simple Nef?", operand2->entity);
if (!s2.is_valid()) {
Logger::Message(Logger::LOG_ERROR, "s2: Not valid?", operand2->entity);
return false;
} else if (is_halfspace) {
// std::cout << "s2: halfspace" << std::endl;
@@ -285,11 +291,11 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcBooleanResult* l, cgal_sha
if (op == IfcSchema::IfcBooleanOperator::IfcBooleanOperator_DIFFERENCE) {
// std::cout << "Difference" << std::endl;
CGAL::Nef_polyhedron_3<Kernel> nef_result = s1;
CGAL::Nef_polyhedron_3<Kernel> nef_result(s1);
if (is_halfspace) {
if (is_plane) nef_result = nef_result.intersection(plane, CGAL::Nef_polyhedron_3<Kernel>::Intersection_mode::CLOSED_HALFSPACE);
} else {
nef_result -= s2;
nef_result -= CGAL::Nef_polyhedron_3<Kernel>(s2);
}
if (!nef_result.is_simple()) {
std::cout << "Not simple: " << nef_result.number_of_volumes() << " volumes" << std::endl;
@@ -301,13 +307,13 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcBooleanResult* l, cgal_sha
// fresult.open("/Users/ken/Desktop/result.off");
// fresult << result << std::endl;
// fresult.close();
} shape = nef_result;
} nef_result.convert_to_polyhedron(shape);
return true;
} else if (op == IfcSchema::IfcBooleanOperator::IfcBooleanOperator_UNION) {
// std::cout << "Union" << std::endl;
CGAL::Nef_polyhedron_3<Kernel> nef_result = s1+s2;
CGAL::Nef_polyhedron_3<Kernel> nef_result = CGAL::Nef_polyhedron_3<Kernel>(s1)+CGAL::Nef_polyhedron_3<Kernel>(s2);
if (!nef_result.is_simple()) {
std::cout << "Not simple: " << nef_result.number_of_volumes() << " volumes" << std::endl;
return false;
@@ -318,13 +324,13 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcBooleanResult* l, cgal_sha
// fresult.open("/Users/ken/Desktop/result.off");
// fresult << result << std::endl;
// fresult.close();
} shape = nef_result;
} nef_result.convert_to_polyhedron(shape);
return true;
} else if (op == IfcSchema::IfcBooleanOperator::IfcBooleanOperator_INTERSECTION) {
// std::cout << "Intersection" << std::endl;
CGAL::Nef_polyhedron_3<Kernel> nef_result = s1*s2;
CGAL::Nef_polyhedron_3<Kernel> nef_result = CGAL::Nef_polyhedron_3<Kernel>(s1)*CGAL::Nef_polyhedron_3<Kernel>(s2);
if (!nef_result.is_simple()) {
std::cout << "Not simple: " << nef_result.number_of_volumes() << " volumes" << std::endl;
return false;
@@ -335,7 +341,7 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcBooleanResult* l, cgal_sha
// fresult.open("/Users/ken/Desktop/result.off");
// fresult << result << std::endl;
// fresult.close();
} shape = nef_result;
} nef_result.convert_to_polyhedron(shape);
return true;
} return false;
}
@@ -512,8 +518,13 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcSphere* l, cgal_shape_t& s
cgal_placement_t trsf;
IfcGeom::CgalKernel::convert(l->Position(),trsf);
shape = create_nef_polyhedron(face_list);
shape.transform(trsf);
shape = create_polyhedron(face_list);
for (auto &vertex: vertices(shape)) {
vertex->point() = Kernel::Point_3(r*vertex->point().x(),
r*vertex->point().y(),
r*vertex->point().z());
vertex->point() = vertex->point().transform(trsf);
}
return true;
}
@@ -555,8 +566,8 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcRectangularPyramid* l, cga
cgal_placement_t trsf;
IfcGeom::CgalKernel::convert(l->Position(),trsf);
shape = create_nef_polyhedron(face_list);
shape.transform(trsf);
shape = create_polyhedron(face_list);
for (auto &vertex: vertices(shape)) vertex->point() = vertex->point().transform(trsf);
return true;
}
@@ -597,8 +608,8 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcRightCircularCylinder* l,
cgal_placement_t trsf;
IfcGeom::CgalKernel::convert(l->Position(),trsf);
shape = create_nef_polyhedron(face_list);
shape.transform(trsf);
shape = create_polyhedron(face_list);
for (auto &vertex: vertices(shape)) vertex->point() = vertex->point().transform(trsf);
return true;
}
@@ -631,8 +642,8 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcRightCircularCone* l, cgal
cgal_placement_t trsf;
IfcGeom::CgalKernel::convert(l->Position(),trsf);
shape = create_nef_polyhedron(face_list);
shape.transform(trsf);
shape = create_polyhedron(face_list);
for (auto &vertex: vertices(shape)) vertex->point() = vertex->point().transform(trsf);
return true;
}
@@ -682,7 +693,7 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcTriangulatedFaceSet* l, cg
face_list.back().outer.push_back(c);
}
shape = create_nef_polyhedron(face_list);
shape = create_polyhedron(face_list);
return true;
}
#endif
@@ -701,8 +712,8 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcHalfSpaceSolid* l, cgal_sh
// const gp_Pnt pnt = pln.Location().Translated( l->AgreementFlag() ? -pln.Axis().Direction() : pln.Axis().Direction());
// shape = BRepPrimAPI_MakeHalfSpace(BRepBuilderAPI_MakeFace(pln),pnt).Solid();
shape = CGAL::Nef_polyhedron_3<Kernel>();
// TODO: We return an empty Nef polyhedron for now and handle halfspace differences in IfcBooleanResult. The other option would be to switch to an extended kernel.
// shape = CGAL::Nef_polyhedron_3<Kernel>(pln);
// TODO: For now we do nothing and process halfspaces in IfcBooleanResult, which likely doesn't capture all cases.
// Find a better solution later (with an abstract shape class?)
shape = CGAL::Polyhedron_3<Kernel>();
return true;
}
@@ -63,6 +63,7 @@ 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) ) {
const SurfaceStyle* indiv_style = get_style(l->Outer());
@@ -79,14 +80,16 @@ 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)) {
s -= s2;
nef_s -= nef_s2;
}
}
nef_s.convert_to_polyhedron(s);
shape.push_back(ConversionResult(new CgalShape(s), indiv_style ? indiv_style : collective_style));
return true;
}
@@ -86,6 +86,34 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcOrientedEdge* l, cgal_wire
}
}
bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcEdge* l, cgal_wire_t& result) {
if (!l->EdgeStart()->is(IfcSchema::Type::IfcVertexPoint) || !l->EdgeEnd()->is(IfcSchema::Type::IfcVertexPoint)) {
Logger::Message(Logger::LOG_ERROR, "Only IfcVertexPoints are supported for EdgeStart and -End", l->entity);
return false;
}
IfcSchema::IfcPoint* pnt1 = ((IfcSchema::IfcVertexPoint*) l->EdgeStart())->VertexGeometry();
IfcSchema::IfcPoint* pnt2 = ((IfcSchema::IfcVertexPoint*) l->EdgeEnd())->VertexGeometry();
if (!pnt1->is(IfcSchema::Type::IfcCartesianPoint) || !pnt2->is(IfcSchema::Type::IfcCartesianPoint)) {
Logger::Message(Logger::LOG_ERROR, "Only IfcCartesianPoints are supported for VertexGeometry", l->entity);
return false;
}
cgal_point_t p1, p2;
if (!convert(((IfcSchema::IfcCartesianPoint*)pnt1), p1) ||
!convert(((IfcSchema::IfcCartesianPoint*)pnt2), p2))
{
return false;
}
cgal_wire_t mw;
mw.push_back(p1);
mw.push_back(p2);
result = mw;
return true;
}
bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcCompositeCurve* l, cgal_wire_t& wire) {
if ( getValue(GV_PLANEANGLE_UNIT)<0 ) {
Logger::Message(Logger::LOG_WARNING,"Creating a composite curve without unit information:",l->entity);
+6 -3
View File
@@ -250,7 +250,7 @@ bool IfcGeom::CgalKernel::convert_openings(const IfcSchema::IfcProduct* entity,
}
gtrsf = gtrsf * opening_trsf;
cgal_shape_t opening_shape(((CgalShape*)opening_shapes[i].Shape())->shape());
opening_shape.transform(gtrsf);
for (auto &vertex: vertices(opening_shape)) vertex->point() = vertex->point().transform(gtrsf);
opening_shapelist.push_back(opening_shape);
// std::cout << "gtrsf" << std::endl;
@@ -270,10 +270,11 @@ bool IfcGeom::CgalKernel::convert_openings(const IfcSchema::IfcProduct* entity,
cgal_shape_t entity_shape(entity_shape_unlocated);
if (it3->Placement()) {
const cgal_placement_t& entity_shape_gtrsf = *(CgalPlacement*)it3->Placement();
entity_shape.transform(entity_shape_gtrsf);
for (auto &vertex: vertices(entity_shape)) vertex->point() = vertex->point().transform(entity_shape_gtrsf);
}
cgal_shape_t brep_cut_result(entity_shape);
CGAL::Nef_polyhedron_3<Kernel> nef_brep_cut_result(brep_cut_result);
for (auto &opening: opening_shapelist) {
@@ -289,7 +290,8 @@ bool IfcGeom::CgalKernel::convert_openings(const IfcSchema::IfcProduct* entity,
// fresult << polyhedron << std::endl;
// fresult.close();
brep_cut_result -= opening;
CGAL::Nef_polyhedron_3<Kernel> nef_opening(opening);
nef_brep_cut_result -= nef_opening;
// brep_cut_result.convert_to_polyhedron(polyhedron);
// fresult.open("/Users/ken/Desktop/after.off");
@@ -298,6 +300,7 @@ bool IfcGeom::CgalKernel::convert_openings(const IfcSchema::IfcProduct* entity,
}
if (brep_cut_result.is_valid()) {
nef_brep_cut_result.convert_to_Polyhedron(brep_cut_result);
cut_shapes.push_back(IfcGeom::ConversionResult(new CgalShape(brep_cut_result), &it3->Style()));
} else {
// Apparently processing the boolean operation failed or resulted in an invalid result
+2 -1
View File
@@ -64,7 +64,7 @@ struct cgal_face_t {
std::vector<cgal_wire_t> inner;
};
typedef CGAL::Nef_polyhedron_3<Kernel> cgal_shape_t;
typedef CGAL::Polyhedron_3<Kernel> cgal_shape_t;
typedef boost::graph_traits<CGAL::Polyhedron_3<Kernel>>::vertex_descriptor cgal_vertex_descriptor_t;
typedef boost::graph_traits<CGAL::Polyhedron_3<Kernel>>::face_descriptor cgal_face_descriptor_t;
@@ -140,6 +140,7 @@ namespace IfcGeom {
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::Nef_polyhedron_3<Kernel> create_nef_polyhedron(std::list<cgal_face_t> &face_list);
void purge_cache() {