mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-11 22:31:55 +00:00
Add support for IFC4.IfcTriangulatedFaceSet
This commit is contained in:
@@ -320,7 +320,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcArbitraryProfileDefWithVoids*
|
|||||||
|
|
||||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcRectangleProfileDef* l, TopoDS_Shape& face) {
|
bool IfcGeom::Kernel::convert(const IfcSchema::IfcRectangleProfileDef* l, TopoDS_Shape& face) {
|
||||||
const double x = l->XDim() / 2.0f * getValue(GV_LENGTH_UNIT);
|
const double x = l->XDim() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||||
const double y = l->YDim() / 2.0f * getValue(GV_LENGTH_UNIT);
|
const double y = l->YDim() / 2.0f * getValue(GV_LENGTH_UNIT);
|
||||||
|
|
||||||
if ( x < ALMOST_ZERO || y < ALMOST_ZERO ) {
|
if ( x < ALMOST_ZERO || y < ALMOST_ZERO ) {
|
||||||
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
|
||||||
|
|||||||
@@ -74,6 +74,7 @@
|
|||||||
#include <BRepPrimAPI_MakeCylinder.hxx>
|
#include <BRepPrimAPI_MakeCylinder.hxx>
|
||||||
#include <BRepPrimAPI_MakeSphere.hxx>
|
#include <BRepPrimAPI_MakeSphere.hxx>
|
||||||
#include <BRepPrimAPI_MakeWedge.hxx>
|
#include <BRepPrimAPI_MakeWedge.hxx>
|
||||||
|
#include <BRepBuilderAPI_MakePolygon.hxx>
|
||||||
|
|
||||||
#include <BRepBuilderAPI_Transform.hxx>
|
#include <BRepBuilderAPI_Transform.hxx>
|
||||||
#include <BRepBuilderAPI_MakeShell.hxx>
|
#include <BRepBuilderAPI_MakeShell.hxx>
|
||||||
@@ -824,4 +825,112 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcAdvancedBrep* l, TopoDS_Shape&
|
|||||||
return convert(l->Outer(), shape);
|
return convert(l->Outer(), shape);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IfcGeom::Kernel::convert(const IfcSchema::IfcTriangulatedFaceSet* l, TopoDS_Shape& shape) {
|
||||||
|
IfcSchema::IfcCartesianPointList3D* point_list = l->Coordinates();
|
||||||
|
const std::vector< std::vector<double> > coordinates = point_list->CoordList();
|
||||||
|
std::vector<gp_Pnt> points;
|
||||||
|
points.reserve(coordinates.size());
|
||||||
|
for (std::vector< std::vector<double> >::const_iterator it = coordinates.begin(); it != coordinates.end(); ++it) {
|
||||||
|
const std::vector<double>& coords = *it;
|
||||||
|
if (coords.size() != 3) {
|
||||||
|
Logger::Message(Logger::LOG_ERROR, "Invalid dimensions encountered on Coordinates", l->entity);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
points.push_back(gp_Pnt(coords[0] * getValue(GV_LENGTH_UNIT),
|
||||||
|
coords[1] * getValue(GV_LENGTH_UNIT),
|
||||||
|
coords[2] * getValue(GV_LENGTH_UNIT)));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector< std::vector<int> > indices = l->CoordIndex();
|
||||||
|
|
||||||
|
std::vector<TopoDS_Face> faces;
|
||||||
|
faces.reserve(indices.size());
|
||||||
|
|
||||||
|
for(std::vector< std::vector<int> >::const_iterator it = indices.begin(); it != indices.end(); ++ it) {
|
||||||
|
const std::vector<int>& tri = *it;
|
||||||
|
if (tri.size() != 3) {
|
||||||
|
Logger::Message(Logger::LOG_ERROR, "Invalid dimensions encountered on CoordIndex", l->entity);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const int min_index = *std::min_element(tri.begin(), tri.end());
|
||||||
|
const int max_index = *std::max_element(tri.begin(), tri.end());
|
||||||
|
|
||||||
|
if (min_index < 1 || max_index > points.size()) {
|
||||||
|
Logger::Message(Logger::LOG_ERROR, "Contents of CoordIndex out of bounds", l->entity);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
const gp_Pnt& a = points[tri[0] - 1]; // account for zero- vs
|
||||||
|
const gp_Pnt& b = points[tri[1] - 1]; // one-based indices in
|
||||||
|
const gp_Pnt& c = points[tri[2] - 1]; // c++ and express
|
||||||
|
|
||||||
|
TopoDS_Wire wire = BRepBuilderAPI_MakePolygon(a, b, c, true).Wire();
|
||||||
|
TopoDS_Face face = BRepBuilderAPI_MakeFace(wire).Face();
|
||||||
|
|
||||||
|
TopoDS_Iterator face_it(face, false);
|
||||||
|
const TopoDS_Wire& w = TopoDS::Wire(face_it.Value());
|
||||||
|
const bool reversed = w.Orientation() == TopAbs_REVERSED;
|
||||||
|
if (reversed) {
|
||||||
|
face.Reverse();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (face_area(face) > getValue(GV_MINIMAL_FACE_AREA)) {
|
||||||
|
faces.push_back(face);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (faces.empty()) return false;
|
||||||
|
|
||||||
|
const unsigned int num_faces = indices.size();
|
||||||
|
bool valid_shell = false;
|
||||||
|
|
||||||
|
if (faces.size() < getValue(GV_MAX_FACES_TO_SEW)) {
|
||||||
|
BRepOffsetAPI_Sewing builder;
|
||||||
|
builder.SetTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||||
|
builder.SetMaxTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||||
|
builder.SetMinTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||||
|
|
||||||
|
for (std::vector<TopoDS_Face>::const_iterator it = faces.begin(); it != faces.end(); ++it) {
|
||||||
|
builder.Add(*it);
|
||||||
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
builder.Perform();
|
||||||
|
shape = builder.SewedShape();
|
||||||
|
valid_shell = BRepCheck_Analyzer(shape).IsValid();
|
||||||
|
} catch(...) {}
|
||||||
|
|
||||||
|
if (valid_shell) {
|
||||||
|
try {
|
||||||
|
ShapeFix_Solid solid;
|
||||||
|
solid.LimitTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||||
|
TopoDS_Solid solid_shape = solid.SolidFromShell(TopoDS::Shell(shape));
|
||||||
|
if (!solid_shape.IsNull()) {
|
||||||
|
try {
|
||||||
|
BRepClass3d_SolidClassifier classifier(solid_shape);
|
||||||
|
shape = solid_shape;
|
||||||
|
} catch (...) {}
|
||||||
|
}
|
||||||
|
} catch(...) {}
|
||||||
|
} else {
|
||||||
|
Logger::Message(Logger::LOG_WARNING, "Failed to sew faceset:", l->entity);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!valid_shell) {
|
||||||
|
TopoDS_Compound compound;
|
||||||
|
BRep_Builder builder;
|
||||||
|
builder.MakeCompound(compound);
|
||||||
|
|
||||||
|
for (std::vector<TopoDS_Face>::const_iterator it = faces.begin(); it != faces.end(); ++it) {
|
||||||
|
builder.Add(compound, *it);
|
||||||
|
}
|
||||||
|
|
||||||
|
shape = compound;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -54,6 +54,7 @@ SHAPE(IfcAdvancedBrep);
|
|||||||
// FIXME: Surfaces should have a shape type of their own
|
// FIXME: Surfaces should have a shape type of their own
|
||||||
SHAPE(IfcBSplineSurfaceWithKnots);
|
SHAPE(IfcBSplineSurfaceWithKnots);
|
||||||
SHAPE(IfcPlane);
|
SHAPE(IfcPlane);
|
||||||
|
SHAPE(IfcTriangulatedFaceSet);
|
||||||
#endif
|
#endif
|
||||||
SHAPE(IfcExtrudedAreaSolid);
|
SHAPE(IfcExtrudedAreaSolid);
|
||||||
SHAPE(IfcRevolvedAreaSolid);
|
SHAPE(IfcRevolvedAreaSolid);
|
||||||
|
|||||||
Reference in New Issue
Block a user