mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-16 21:42:19 +00:00
Merge pull request #8 from kenohori/cgal
More profiles (T, U, Z) and support for openings
This commit is contained in:
@@ -54,9 +54,15 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcPlane* pln, cgal_plane_t&
|
|||||||
IfcSchema::IfcAxis2Placement3D* l = pln->Position();
|
IfcSchema::IfcAxis2Placement3D* l = pln->Position();
|
||||||
cgal_point_t o;
|
cgal_point_t o;
|
||||||
cgal_direction_t axis = Kernel::Vector_3(0,0,1);
|
cgal_direction_t axis = Kernel::Vector_3(0,0,1);
|
||||||
|
cgal_direction_t refDirection;
|
||||||
IfcGeom::CgalKernel::convert(l->Location(),o);
|
IfcGeom::CgalKernel::convert(l->Location(),o);
|
||||||
|
bool hasRef = l->hasRefDirection();
|
||||||
if ( l->hasAxis() ) IfcGeom::CgalKernel::convert(l->Axis(),axis);
|
if ( l->hasAxis() ) IfcGeom::CgalKernel::convert(l->Axis(),axis);
|
||||||
plane = Kernel::Plane_3(o, axis);
|
if ( hasRef ) IfcGeom::CgalKernel::convert(l->RefDirection(),refDirection);
|
||||||
|
cgal_plane_t ax3;
|
||||||
|
if ( hasRef ) ax3 = Kernel::Plane_3(o,o+axis,o+refDirection);
|
||||||
|
else ax3 = Kernel::Plane_3(o,axis);
|
||||||
|
plane = ax3;
|
||||||
// CACHE(IfcPlane,pln,plane)
|
// CACHE(IfcPlane,pln,plane)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -63,6 +63,9 @@ FACE(IfcEllipseProfileDef);
|
|||||||
FACE(IfcCShapeProfileDef);
|
FACE(IfcCShapeProfileDef);
|
||||||
FACE(IfcIShapeProfileDef);
|
FACE(IfcIShapeProfileDef);
|
||||||
FACE(IfcLShapeProfileDef);
|
FACE(IfcLShapeProfileDef);
|
||||||
|
FACE(IfcTShapeProfileDef);
|
||||||
|
FACE(IfcUShapeProfileDef);
|
||||||
|
FACE(IfcZShapeProfileDef);
|
||||||
|
|
||||||
WIRE(IfcEdgeLoop);
|
WIRE(IfcEdgeLoop);
|
||||||
WIRE(IfcOrientedEdge);
|
WIRE(IfcOrientedEdge);
|
||||||
|
|||||||
@@ -655,3 +655,304 @@ bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcIShapeProfileDef* l, cgal_
|
|||||||
|
|
||||||
return true;
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcUShapeProfileDef* l, cgal_face_t& face) {
|
||||||
|
const bool doEdgeFillet = l->hasEdgeRadius();
|
||||||
|
const bool doFillet = l->hasFilletRadius();
|
||||||
|
const bool hasSlope = l->hasFlangeSlope();
|
||||||
|
|
||||||
|
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 slope = hasSlope ? (l->FlangeSlope() * getValue(GV_PLANEANGLE_UNIT)) : 0.;
|
||||||
|
|
||||||
|
double dy1 = 0.0f;
|
||||||
|
double dy2 = 0.0f;
|
||||||
|
double f1 = 0.0f;
|
||||||
|
double f2 = 0.0f;
|
||||||
|
|
||||||
|
if (doFillet) {
|
||||||
|
f1 = l->FilletRadius() * getValue(GV_LENGTH_UNIT);
|
||||||
|
}
|
||||||
|
if (doEdgeFillet) {
|
||||||
|
f2 = l->EdgeRadius() * getValue(GV_LENGTH_UNIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (hasSlope) {
|
||||||
|
dy1 = (x - d1) * tan(slope);
|
||||||
|
dy2 = x * tan(slope);
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
cgal_placement_t trsf2d;
|
||||||
|
bool has_position = true;
|
||||||
|
#ifdef USE_IFC4
|
||||||
|
has_position = l->hasPosition();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const int segments = 3;
|
||||||
|
|
||||||
|
face = cgal_face_t();
|
||||||
|
face.outer.push_back(Kernel::Point_3(-x, -y, 0.0));
|
||||||
|
face.outer.push_back(Kernel::Point_3(x, -y, 0.0));
|
||||||
|
if (f2 == 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 = current_segment*0.5*3.141592653589793/((double)segments);
|
||||||
|
face.outer.push_back(Kernel::Point_3(x-f2+f2*cos(current_angle), -y+d2-dy2-f2+f2*sin(current_angle), 0));
|
||||||
|
}
|
||||||
|
} if (f1 == 0.0) {
|
||||||
|
face.outer.push_back(Kernel::Point_3(-x+d1, -y+d2+dy1, 0.0));
|
||||||
|
} else {
|
||||||
|
for (int current_segment = segments; current_segment >= 0; --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+d1+f1+f1*cos(current_angle), -y+d2+dy1+f1+f1*sin(current_angle), 0));
|
||||||
|
}
|
||||||
|
} if (f1 == 0.0) {
|
||||||
|
face.outer.push_back(Kernel::Point_3(-x+d1, y-d2-dy1, 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(-x+d1+f1+f1*cos(current_angle), y-d2-dy1-f1+f1*sin(current_angle), 0));
|
||||||
|
}
|
||||||
|
} if (f2 == 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-f2+f2*cos(current_angle), y-d2+dy2+f2+f2*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 (has_position) {
|
||||||
|
IfcGeom::CgalKernel::convert(l->Position(), trsf2d);
|
||||||
|
for (auto &vertex: face.outer) {
|
||||||
|
vertex = vertex.transform(trsf2d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IfcGeom::CgalKernel::convert(const IfcSchema::IfcZShapeProfileDef* l, cgal_face_t& face) {
|
||||||
|
const double x = l->FlangeWidth() * getValue(GV_LENGTH_UNIT);
|
||||||
|
const double y = l->Depth() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||||
|
const double dx = l->WebThickness() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||||
|
const double dy = l->FlangeThickness() * getValue(GV_LENGTH_UNIT);
|
||||||
|
|
||||||
|
bool doFillet = l->hasFilletRadius();
|
||||||
|
bool doEdgeFillet = l->hasEdgeRadius();
|
||||||
|
|
||||||
|
double f1 = 0.;
|
||||||
|
double f2 = 0.;
|
||||||
|
|
||||||
|
if ( doFillet ) {
|
||||||
|
f1 = l->FilletRadius() * getValue(GV_LENGTH_UNIT);
|
||||||
|
}
|
||||||
|
if ( doEdgeFillet ) {
|
||||||
|
f2 = l->EdgeRadius() * getValue(GV_LENGTH_UNIT);
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( x == 0.0f || y == 0.0f || dx == 0.0f || dy == 0.0f ) {
|
||||||
|
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
cgal_placement_t trsf2d;
|
||||||
|
bool has_position = true;
|
||||||
|
#ifdef USE_IFC4
|
||||||
|
has_position = l->hasPosition();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const int segments = 3;
|
||||||
|
|
||||||
|
face = cgal_face_t();
|
||||||
|
face.outer.push_back(Kernel::Point_3(-dx, -y, 0.0));
|
||||||
|
face.outer.push_back(Kernel::Point_3(x, -y, 0.0));
|
||||||
|
if (f2 == 0.0) {
|
||||||
|
face.outer.push_back(Kernel::Point_3(x, -y+dy, 0.0));
|
||||||
|
} else {
|
||||||
|
for (int current_segment = 0; current_segment <= segments; ++current_segment) {
|
||||||
|
double current_angle = current_segment*0.5*3.141592653589793/((double)segments);
|
||||||
|
face.outer.push_back(Kernel::Point_3(x-f2+f2*cos(current_angle), -y+dy-f2+f2*sin(current_angle), 0));
|
||||||
|
}
|
||||||
|
} if (f1 == 0.0) {
|
||||||
|
face.outer.push_back(Kernel::Point_3(dx, -y+dy, 0.0));
|
||||||
|
} else {
|
||||||
|
for (int current_segment = segments; current_segment >= 0; --current_segment) {
|
||||||
|
double current_angle = 1.0*3.141592653589793+current_segment*0.5*3.141592653589793/((double)segments);
|
||||||
|
face.outer.push_back(Kernel::Point_3(dx+f1+f1*cos(current_angle), -y+dy+f1+f1*sin(current_angle), 0));
|
||||||
|
}
|
||||||
|
} face.outer.push_back(Kernel::Point_3(dx, y, 0.0));
|
||||||
|
face.outer.push_back(Kernel::Point_3(-x, y, 0.0));
|
||||||
|
if (f2 == 0.0) {
|
||||||
|
face.outer.push_back(Kernel::Point_3(-x, y-dy, 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+f2+f2*cos(current_angle), y-dy+f2+f2*sin(current_angle), 0));
|
||||||
|
}
|
||||||
|
} if (f1 == 0.0) {
|
||||||
|
face.outer.push_back(Kernel::Point_3(-dx, y-dy, 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(-dx-f1+f1*cos(current_angle), y-dy-f1+f1*sin(current_angle), 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (has_position) {
|
||||||
|
IfcGeom::CgalKernel::convert(l->Position(), trsf2d);
|
||||||
|
for (auto &vertex: face.outer) {
|
||||||
|
vertex = vertex.transform(trsf2d);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -111,25 +111,24 @@ IfcGeom::NativeElement<double>* IfcGeom::CgalKernel::create_brep_for_representat
|
|||||||
const std::string product_type = IfcSchema::Type::ToString(product->type());
|
const std::string product_type = IfcSchema::Type::ToString(product->type());
|
||||||
ElementSettings element_settings(settings, getValue(GV_LENGTH_UNIT), product_type);
|
ElementSettings element_settings(settings, getValue(GV_LENGTH_UNIT), product_type);
|
||||||
|
|
||||||
if (!settings.get(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS) && openings && openings->size()) {
|
if (!settings.get(IfcGeom::IteratorSettings::DISABLE_OPENING_SUBTRACTIONS) && openings && openings->size()) {
|
||||||
Logger::Message(Logger::LOG_ERROR, "Not implemented opening subtractions");
|
IfcGeom::ConversionResults opened_shapes;
|
||||||
}
|
convert_openings(product,openings,shapes,trsf,opened_shapes);
|
||||||
|
if (settings.get(IteratorSettings::USE_WORLD_COORDS)) {
|
||||||
if (settings.get(IteratorSettings::USE_WORLD_COORDS)) {
|
for ( IfcGeom::ConversionResults::iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++ it ) {
|
||||||
// TODO: OpenCascade code uses opened_shapes. Check why.
|
it->prepend(new CgalPlacement(trsf));
|
||||||
|
}
|
||||||
|
trsf = cgal_placement_t();
|
||||||
|
}
|
||||||
|
shape = new IfcGeom::Representation::Native(element_settings, representation->entity->id(), opened_shapes);
|
||||||
|
} else if (settings.get(IteratorSettings::USE_WORLD_COORDS)) {
|
||||||
for ( IfcGeom::ConversionResults::iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
for ( IfcGeom::ConversionResults::iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
||||||
it->prepend(new CgalPlacement(trsf));
|
it->prepend(new CgalPlacement(trsf));
|
||||||
}
|
}
|
||||||
trsf = Kernel::Aff_transformation_3();
|
trsf = cgal_placement_t();
|
||||||
shape = new IfcGeom::Representation::Native(element_settings, representation->entity->id(), shapes);
|
shape = new IfcGeom::Representation::Native(element_settings, representation->entity->id(), shapes);
|
||||||
} else if (settings.get(IteratorSettings::USE_WORLD_COORDS)) {
|
|
||||||
for ( IfcGeom::ConversionResults::iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
|
|
||||||
it->prepend(new CgalPlacement(trsf));
|
|
||||||
}
|
|
||||||
trsf = Kernel::Aff_transformation_3();
|
|
||||||
shape = new IfcGeom::Representation::Native(element_settings, representation->entity->id(), shapes);
|
|
||||||
} else {
|
} else {
|
||||||
shape = new IfcGeom::Representation::Native(element_settings, representation->entity->id(), shapes);
|
shape = new IfcGeom::Representation::Native(element_settings, representation->entity->id(), shapes);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string context_string = "";
|
std::string context_string = "";
|
||||||
@@ -191,3 +190,75 @@ IfcGeom::NativeElement<double>* IfcGeom::CgalKernel::create_brep_for_processed_r
|
|||||||
brep->geometry_pointer()
|
brep->geometry_pointer()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IfcGeom::CgalKernel::convert_openings(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings,
|
||||||
|
const IfcGeom::ConversionResults& entity_shapes, const cgal_placement_t& entity_trsf, IfcGeom::ConversionResults& cut_shapes) {
|
||||||
|
|
||||||
|
std::list<cgal_shape_t> opening_shapelist;
|
||||||
|
|
||||||
|
for ( IfcSchema::IfcRelVoidsElement::list::it it = openings->begin(); it != openings->end(); ++ it ) {
|
||||||
|
IfcSchema::IfcRelVoidsElement* v = *it;
|
||||||
|
IfcSchema::IfcFeatureElementSubtraction* fes = v->RelatedOpeningElement();
|
||||||
|
if ( fes->is(IfcSchema::Type::IfcOpeningElement) ) {
|
||||||
|
if (!fes->hasRepresentation()) continue;
|
||||||
|
|
||||||
|
// Convert the IfcRepresentation of the IfcOpeningElement
|
||||||
|
cgal_placement_t opening_trsf;
|
||||||
|
if (fes->hasObjectPlacement()) {
|
||||||
|
try {
|
||||||
|
convert(fes->ObjectPlacement(),opening_trsf);
|
||||||
|
} catch (...) {}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move the opening into the coordinate system of the IfcProduct
|
||||||
|
opening_trsf = opening_trsf * entity_trsf.inverse();
|
||||||
|
|
||||||
|
IfcSchema::IfcProductRepresentation* prodrep = fes->Representation();
|
||||||
|
IfcSchema::IfcRepresentation::list::ptr reps = prodrep->Representations();
|
||||||
|
|
||||||
|
IfcGeom::ConversionResults opening_shapes;
|
||||||
|
|
||||||
|
for ( IfcSchema::IfcRepresentation::list::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) {
|
||||||
|
convert_shapes(*it2,opening_shapes);
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( unsigned int i = 0; i < opening_shapes.size(); ++ i ) {
|
||||||
|
cgal_shape_t opening_shape(((CgalShape*)opening_shapes[i].Shape())->shape());
|
||||||
|
if (opening_shapes[i].Placement()) {
|
||||||
|
cgal_placement_t gtrsf = *(CgalPlacement*)opening_shapes[i].Placement();
|
||||||
|
gtrsf = gtrsf * opening_trsf;
|
||||||
|
opening_shape.transform(gtrsf);
|
||||||
|
} opening_shapelist.push_back(opening_shape);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Iterate over the shapes of the IfcProduct
|
||||||
|
for ( IfcGeom::ConversionResults::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
|
||||||
|
const cgal_shape_t& entity_shape_unlocated(((CgalShape*)it3->Shape())->shape());
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
cgal_shape_t brep_cut_result(entity_shape);
|
||||||
|
|
||||||
|
for (auto &opening: opening_shapelist) {
|
||||||
|
brep_cut_result -= opening;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (brep_cut_result.is_valid()) {
|
||||||
|
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
|
||||||
|
// in which case the original shape without the subtractions is returned instead
|
||||||
|
// we try convert the openings in the original way, one by one.
|
||||||
|
Logger::Message(Logger::LOG_WARNING, "Subtracting combined openings compound failed:", entity->entity);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|||||||
@@ -137,7 +137,7 @@ namespace IfcGeom {
|
|||||||
|
|
||||||
void remove_duplicate_points_from_loop(cgal_wire_t& polygon, bool closed, double tol = -1.);
|
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);
|
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);
|
||||||
|
|
||||||
void purge_cache() {
|
void purge_cache() {
|
||||||
// Rather hack-ish, but a stopgap solution to keep memory under control
|
// Rather hack-ish, but a stopgap solution to keep memory under control
|
||||||
|
|||||||
Reference in New Issue
Block a user