diff --git a/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp b/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp index 38f9e0d457..b096b3408e 100644 --- a/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp +++ b/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp @@ -144,3 +144,8 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcObjectPlacement* l, cgal_p // CACHE(IfcObjectPlacement,l,trsf) return true; } + +bool IfcGeom::CgalKernel::convert_wire_to_face(const cgal_wire_t& wire, cgal_face_t& face) { + face.outer = wire; + return true; +} diff --git a/src/ifcgeom/kernels/cgal/CgalEntityMapping.h b/src/ifcgeom/kernels/cgal/CgalEntityMapping.h index 520c21dfd4..54efeb04ba 100644 --- a/src/ifcgeom/kernels/cgal/CgalEntityMapping.h +++ b/src/ifcgeom/kernels/cgal/CgalEntityMapping.h @@ -34,16 +34,19 @@ SHAPES(IfcRepresentation); // IfcFacetedBrepWithVoids included // IfcAdvancedBrepWithVoids included SHAPES(IfcManifoldSolidBrep); +SHAPES(IfcMappedItem); SHAPE(IfcExtrudedAreaSolid); SHAPE(IfcConnectedFaceSet); SHAPE(IfcCsgSolid); SHAPE(IfcBlock); +FACE(IfcArbitraryClosedProfileDef); FACE(IfcFace); FACE(IfcRectangleProfileDef); WIRE(IfcPolyLoop); +WIRE(IfcPolyline); CLASS(IfcCartesianPoint,cgal_point_t); CLASS(IfcDirection,cgal_direction_t); diff --git a/src/ifcgeom/kernels/cgal/CgalIfcGeomFaces.cpp b/src/ifcgeom/kernels/cgal/CgalIfcGeomFaces.cpp index 6cd88a434b..7c4e64337f 100644 --- a/src/ifcgeom/kernels/cgal/CgalIfcGeomFaces.cpp +++ b/src/ifcgeom/kernels/cgal/CgalIfcGeomFaces.cpp @@ -1,5 +1,15 @@ #include "CgalKernel.h" +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcArbitraryClosedProfileDef* l, cgal_face_t& face) { + cgal_wire_t wire; + if ( ! convert_wire(l->OuterCurve(),wire) ) return false; + + cgal_face_t f; + bool success = convert_wire_to_face(wire, f); + if (success) face = f; + return success; +} + 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); diff --git a/src/ifcgeom/kernels/cgal/CgalIfcGeomShapes.cpp b/src/ifcgeom/kernels/cgal/CgalIfcGeomShapes.cpp index 78b9b33c80..37c344e483 100644 --- a/src/ifcgeom/kernels/cgal/CgalIfcGeomShapes.cpp +++ b/src/ifcgeom/kernels/cgal/CgalIfcGeomShapes.cpp @@ -32,6 +32,58 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcManifoldSolidBrep* l, Conv return false; } +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcMappedItem* l, ConversionResults& shapes) { + cgal_placement_t gtrsf; + IfcSchema::IfcCartesianTransformationOperator* transform = l->MappingTarget(); + if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator3DnonUniform) ) { + Logger::Message(Logger::LOG_ERROR, "Unsupported MappingTarget:", transform->entity); +// IfcGeom::CgalKernel::convert((IfcSchema::IfcCartesianTransformationOperator3DnonUniform*)transform,gtrsf); + } else if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator2DnonUniform) ) { + Logger::Message(Logger::LOG_ERROR, "Unsupported MappingTarget:", transform->entity); + 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); + gtrsf = trsf; + } else if ( transform->is(IfcSchema::Type::IfcCartesianTransformationOperator2D) ) { + cgal_placement_t trsf_2d; + Logger::Message(Logger::LOG_ERROR, "Unsupported MappingTarget:", transform->entity); +// IfcGeom::CgalKernel::convert((IfcSchema::IfcCartesianTransformationOperator2D*)transform,trsf_2d); + gtrsf = (cgal_placement_t) trsf_2d; + } + IfcSchema::IfcRepresentationMap* map = l->MappingSource(); + IfcSchema::IfcAxis2Placement* placement = map->MappingOrigin(); + cgal_placement_t trsf; + if (placement->is(IfcSchema::Type::IfcAxis2Placement3D)) { + IfcGeom::CgalKernel::convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf); + } else { + cgal_placement_t trsf_2d; + IfcGeom::CgalKernel::convert((IfcSchema::IfcAxis2Placement2D*)placement,trsf_2d); + trsf = trsf_2d; + } + // TODO: Check + gtrsf = trsf * gtrsf; + + const IfcGeom::SurfaceStyle* mapped_item_style = get_style(l); + + const size_t previous_size = shapes.size(); + bool b = convert_shapes(map->MappedRepresentation(), shapes); + + for (size_t i = previous_size; i < shapes.size(); ++ i ) { + IfcGeom::CgalPlacement place(gtrsf); + shapes[i].prepend(&place); + + // Apply styles assigned to the mapped item only if on + // a more granular level no styles have been applied + if (!shapes[i].hasStyle()) { + shapes[i].setStyle(mapped_item_style); + } + } + + return b; +} + bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcExtrudedAreaSolid *l, cgal_shape_t &shape) { const double height = l->Depth() * getValue(GV_LENGTH_UNIT); if (height < getValue(GV_PRECISION)) { diff --git a/src/ifcgeom/kernels/cgal/CgalIfcGeomWires.cpp b/src/ifcgeom/kernels/cgal/CgalIfcGeomWires.cpp index 56e43432c3..c6d8820c65 100644 --- a/src/ifcgeom/kernels/cgal/CgalIfcGeomWires.cpp +++ b/src/ifcgeom/kernels/cgal/CgalIfcGeomWires.cpp @@ -18,7 +18,7 @@ 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?) + // TODO: Remove repeated points and points that are too close to one another // remove_duplicate_points_from_loop(polygon, true); std::size_t count = polygon.size(); @@ -41,3 +41,21 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcPolyLoop* l, cgal_wire_t& return true; } + +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcPolyline* l, cgal_wire_t& result) { + IfcSchema::IfcCartesianPoint::list::ptr points = l->Points(); + + // Parse and store the points in a sequence + cgal_wire_t polygon = std::vector(); + for(IfcSchema::IfcCartesianPoint::list::it it = points->begin(); it != points->end(); ++ it) { + cgal_point_t pnt; + IfcGeom::CgalKernel::convert(*it, pnt); + polygon.push_back(pnt); + } + + // TODO: 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 4e82272375..94021ae750 100644 --- a/src/ifcgeom/kernels/cgal/CgalKernel.h +++ b/src/ifcgeom/kernels/cgal/CgalKernel.h @@ -130,6 +130,8 @@ namespace IfcGeom { bool convert_wire(const IfcUtil::IfcBaseClass* L, cgal_wire_t& result); bool convert_curve(const IfcUtil::IfcBaseClass* L, cgal_curve_t& result); 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); // 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);