From 0fbadc2985f2409762131d79fc41ef251a0cdadc Mon Sep 17 00:00:00 2001 From: Ken Arroyo Ohori Date: Thu, 9 Mar 2017 16:29:14 -0600 Subject: [PATCH] T profiles --- src/ifcgeom/kernels/cgal/CgalEntityMapping.h | 1 + src/ifcgeom/kernels/cgal/CgalIfcGeomFaces.cpp | 139 ++++++++++++++++++ 2 files changed, 140 insertions(+) diff --git a/src/ifcgeom/kernels/cgal/CgalEntityMapping.h b/src/ifcgeom/kernels/cgal/CgalEntityMapping.h index 371a2b7769..99387cec0d 100644 --- a/src/ifcgeom/kernels/cgal/CgalEntityMapping.h +++ b/src/ifcgeom/kernels/cgal/CgalEntityMapping.h @@ -63,6 +63,7 @@ FACE(IfcEllipseProfileDef); FACE(IfcCShapeProfileDef); FACE(IfcIShapeProfileDef); FACE(IfcLShapeProfileDef); +FACE(IfcTShapeProfileDef); WIRE(IfcEdgeLoop); WIRE(IfcOrientedEdge); diff --git a/src/ifcgeom/kernels/cgal/CgalIfcGeomFaces.cpp b/src/ifcgeom/kernels/cgal/CgalIfcGeomFaces.cpp index 69e50cde35..5d50e810da 100644 --- a/src/ifcgeom/kernels/cgal/CgalIfcGeomFaces.cpp +++ b/src/ifcgeom/kernels/cgal/CgalIfcGeomFaces.cpp @@ -655,3 +655,142 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcIShapeProfileDef* l, cgal_ return true; } + +bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcTShapeProfileDef* l, cgal_face_t& face) { + const bool doFlangeEdgeFillet = l->hasFlangeEdgeRadius(); + const bool doWebEdgeFillet = l->hasWebEdgeRadius(); + const bool doFillet = l->hasFilletRadius(); + const bool hasFlangeSlope = l->hasFlangeSlope(); + const bool hasWebSlope = l->hasWebSlope(); + + const double y = l->Depth() / 2.0f * getValue(GV_LENGTH_UNIT); + const double x = l->FlangeWidth() / 2.0f * getValue(GV_LENGTH_UNIT); + const double d1 = l->WebThickness() * getValue(GV_LENGTH_UNIT); + const double d2 = l->FlangeThickness() * getValue(GV_LENGTH_UNIT); + const double flangeSlope = hasFlangeSlope ? (l->FlangeSlope() * getValue(GV_PLANEANGLE_UNIT)) : 0.; + const double webSlope = hasWebSlope ? (l->WebSlope() * getValue(GV_PLANEANGLE_UNIT)) : 0.; + + if ( x < ALMOST_ZERO || y < ALMOST_ZERO || d1 < ALMOST_ZERO || d2 < ALMOST_ZERO ) { + Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity); + return false; + } + + double dy1 = 0.0f; + double dy2 = 0.0f; + double dx1 = 0.0f; + double dx2 = 0.0f; + double f1 = 0.0f; + double f2 = 0.0f; + double f3 = 0.0f; + + if (doFillet) { + f1 = l->FilletRadius() * getValue(GV_LENGTH_UNIT); + } + if (doWebEdgeFillet) { + f2 = l->WebEdgeRadius() * getValue(GV_LENGTH_UNIT); + } + if (doFlangeEdgeFillet) { + f3 = l->FlangeEdgeRadius() * getValue(GV_LENGTH_UNIT); + } + + double xx, xy; + if (hasFlangeSlope) { + dy1 = (x / 2. - d1) * tan(flangeSlope); + dy2 = x / 2. * tan(flangeSlope); + } + if (hasWebSlope) { + dx1 = (y - d2) * tan(webSlope); + dx2 = y * tan(webSlope); + } + if (hasWebSlope || hasFlangeSlope) { + const double x1s = d1/2. - dx2; const double y1s = -y; + const double x1e = d1/2. + dx1; const double y1e = y - d2; + const double x2s = x; const double y2s = y - d2 + dy2; + const double x2e = d1/2.; const double y2e = y - d2 - dy1; + + const double a1 = y1e - y1s; + const double b1 = x1s - x1e; + const double c1 = a1*x1s + b1*y1s; + + const double a2 = y2e - y2s; + const double b2 = x2s - x2e; + const double c2 = a2*x2s + b2*y2s; + + const double det = a1*b2 - a2*b1; + + if (ALMOST_THE_SAME(det, 0.)) { + Logger::Message(Logger::LOG_NOTICE, "Web and flange do not intersect for:",l->entity); + return false; + } + + xx = (b2*c1 - b1*c2) / det; + xy = (a1*c2 - a2*c1) / det; + } else { + xx = d1 / 2; + xy = y - d2; + } + + cgal_placement_t trsf2d; + bool has_position = true; +#ifdef USE_IFC4 + has_position = l->hasPosition(); +#endif + + const int segments = 3; + + face = cgal_face_t(); + if (f2 == 0.0) { + face.outer.push_back(Kernel::Point_3(d1/2.-dx2, -y, 0.0)); + } else { + for (int current_segment = 0; current_segment <= segments; ++current_segment) { + double current_angle = 1.5*3.141592653589793+current_segment*0.5*3.141592653589793/((double)segments); + face.outer.push_back(Kernel::Point_3(d1/2.-dx2-f2+f2*cos(current_angle), -y+f2+f2*sin(current_angle), 0)); + } + } if (f1 == 0.0) { + face.outer.push_back(Kernel::Point_3(xx, xy, 0.0)); + } else { + for (int current_segment = segments; current_segment >= 0; --current_segment) { + double current_angle = 0.5*3.141592653589793+current_segment*0.5*3.141592653589793/((double)segments); + face.outer.push_back(Kernel::Point_3(xx+f1+f1*cos(current_angle), xy-f1+f1*sin(current_angle), 0)); + } + } if (f3 == 0.0) { + face.outer.push_back(Kernel::Point_3(x, y-d2+dy2, 0.0)); + } else { + for (int current_segment = 0; current_segment <= segments; ++current_segment) { + double current_angle = 1.5*3.141592653589793+current_segment*0.5*3.141592653589793/((double)segments); + face.outer.push_back(Kernel::Point_3(x-f3+f3*cos(current_angle), y-d2+dy2+f3+f3*sin(current_angle), 0)); + } + } face.outer.push_back(Kernel::Point_3(x, y, 0.0)); + face.outer.push_back(Kernel::Point_3(-x, y, 0.0)); + if (f3 == 0.0) { + face.outer.push_back(Kernel::Point_3(-x, y-d2+dy2, 0.0)); + } else { + for (int current_segment = 0; current_segment <= segments; ++current_segment) { + double current_angle = 1.0*3.141592653589793+current_segment*0.5*3.141592653589793/((double)segments); + face.outer.push_back(Kernel::Point_3(-x+f3+f3*cos(current_angle), y-d2+dy2+f3+f3*sin(current_angle), 0)); + } + } if (f1 == 0.0) { + face.outer.push_back(Kernel::Point_3(-xx, xy, 0.0)); + } else { + for (int current_segment = segments; current_segment >= 0; --current_segment) { + double current_angle = current_segment*0.5*3.141592653589793/((double)segments); + face.outer.push_back(Kernel::Point_3(-xx-f1+f1*cos(current_angle), xy-f1+f1*sin(current_angle), 0)); + } + } if (f2 == 0.0) { + face.outer.push_back(Kernel::Point_3(-d1/2.+dx2, -y, 0.0)); + } else { + for (int current_segment = 0; current_segment <= segments; ++current_segment) { + double current_angle = 1.0*3.141592653589793+current_segment*0.5*3.141592653589793/((double)segments); + face.outer.push_back(Kernel::Point_3(-d1/2.+dx2+f2+f2*cos(current_angle), -y+f2+f2*sin(current_angle), 0)); + } + } + + if (has_position) { + IfcGeom::CgalKernel::convert(l->Position(), trsf2d); + for (auto &vertex: face.outer) { + vertex = vertex.transform(trsf2d); + } + } + + return true; +}