diff --git a/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp b/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp index 30e441be04..f290b24061 100644 --- a/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp +++ b/src/ifcgeom/kernels/cgal/CgalConversionFunctions.cpp @@ -49,6 +49,15 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcDirection* l, cgal_directi return true; } +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcVector* l, cgal_vector_t& v) { +// IN_CACHE(IfcVector,l,cgal_vector_t,v) + cgal_direction_t d; + IfcGeom::CgalKernel::convert(l->Orientation(),d); + v = l->Magnitude() * getValue(GV_LENGTH_UNIT) * d; +// CACHE(IfcVector,l,v) + return true; +} + bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcPlane* pln, cgal_plane_t& plane) { // IN_CACHE(IfcPlane,pln,gp_Pln,plane) IfcSchema::IfcAxis2Placement3D* l = pln->Position(); diff --git a/src/ifcgeom/kernels/cgal/CgalEntityMapping.h b/src/ifcgeom/kernels/cgal/CgalEntityMapping.h index c2f0825b72..21dbc8cbb6 100644 --- a/src/ifcgeom/kernels/cgal/CgalEntityMapping.h +++ b/src/ifcgeom/kernels/cgal/CgalEntityMapping.h @@ -73,8 +73,13 @@ WIRE(IfcPolyLoop); WIRE(IfcPolyline); WIRE(IfcCompositeCurve); +CURVE(IfcCircle); +CURVE(IfcEllipse); +CURVE(IfcLine); + 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); diff --git a/src/ifcgeom/kernels/cgal/CgalIfcGeomCurves.cpp b/src/ifcgeom/kernels/cgal/CgalIfcGeomCurves.cpp new file mode 100644 index 0000000000..536bc74b66 --- /dev/null +++ b/src/ifcgeom/kernels/cgal/CgalIfcGeomCurves.cpp @@ -0,0 +1,75 @@ +#include "CgalKernel.h" + +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcCircle* l, cgal_curve_t& curve) { + const double r = l->Radius() * getValue(GV_LENGTH_UNIT); + if ( r < ALMOST_ZERO ) { + Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", l->entity); + return false; + } + cgal_placement_t trsf; + IfcSchema::IfcAxis2Placement* placement = l->Position(); + if (placement->is(IfcSchema::Type::IfcAxis2Placement3D)) { + IfcGeom::CgalKernel::convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf); + } else { + cgal_placement_t trsf2d; + IfcGeom::CgalKernel::convert((IfcSchema::IfcAxis2Placement2D*)placement,trsf2d); + trsf = trsf2d; + } + + const int segments = 12; + + curve = cgal_curve_t(); + for (int current_segment = 0; current_segment < segments; ++current_segment) { + double current_angle = current_segment*2.0*3.141592653589793/((double)segments); + curve.push_back(Kernel::Point_3(r*cos(current_angle), r*sin(current_angle), 0)); + } + + for (auto &vertex: curve) { + vertex = vertex.transform(trsf); + } + + return true; +} + +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcEllipse* l, cgal_curve_t& curve) { + double x = l->SemiAxis1() * getValue(GV_LENGTH_UNIT); + double y = l->SemiAxis2() * getValue(GV_LENGTH_UNIT); + if (x < ALMOST_ZERO || y < ALMOST_ZERO) { + Logger::Message(Logger::LOG_ERROR, "Radius not greater than zero for:", l->entity); + return false; + } + cgal_placement_t trsf; + IfcSchema::IfcAxis2Placement* placement = l->Position(); + if (placement->is(IfcSchema::Type::IfcAxis2Placement3D)) { + convert((IfcSchema::IfcAxis2Placement3D*)placement,trsf); + } else { + cgal_placement_t trsf2d; + convert((IfcSchema::IfcAxis2Placement2D*)placement,trsf2d); + trsf = trsf2d; + } + + const int segments = 12; + + curve = cgal_curve_t(); + for (int current_segment = 0; current_segment < segments; ++current_segment) { + double current_angle = current_segment*2.0*3.141592653589793/((double)segments); + curve.push_back(Kernel::Point_3(x*cos(current_angle), y*sin(current_angle), 0)); + } + + for (auto &vertex: curve) { + vertex = vertex.transform(trsf); + } + + return true; +} + +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcLine* l, cgal_curve_t& curve) { + cgal_point_t pnt; + cgal_direction_t vec; + convert(l->Pnt(),pnt); + convert(l->Dir(),vec); + curve = cgal_curve_t(); + curve.push_back(pnt); + curve.push_back(pnt+vec); + return true; +} diff --git a/src/ifcgeom/kernels/cgal/CgalKernel.h b/src/ifcgeom/kernels/cgal/CgalKernel.h index e6658f547f..f63404d129 100644 --- a/src/ifcgeom/kernels/cgal/CgalKernel.h +++ b/src/ifcgeom/kernels/cgal/CgalKernel.h @@ -54,6 +54,7 @@ typedef CGAL::Exact_predicates_exact_constructions_kernel Kernel; typedef Kernel::Aff_transformation_3 cgal_placement_t; typedef Kernel::Point_3 cgal_point_t; typedef Kernel::Vector_3 cgal_direction_t; +typedef Kernel::Vector_3 cgal_vector_t; typedef Kernel::Plane_3 cgal_plane_t; typedef std::vector cgal_curve_t; typedef std::vector cgal_wire_t;