Add support for IFC4.IfcTriangulatedFaceSet

This commit is contained in:
Thomas Krijnen
2015-06-16 12:58:51 +00:00
parent 4f60c7d48c
commit 28863f90b9
3 changed files with 111 additions and 1 deletions
+1 -1
View File
@@ -320,7 +320,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcArbitraryProfileDefWithVoids*
bool IfcGeom::Kernel::convert(const IfcSchema::IfcRectangleProfileDef* l, TopoDS_Shape& face) {
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 ) {
Logger::Message(Logger::LOG_NOTICE,"Skipping zero sized profile:",l->entity);
+109
View File
@@ -74,6 +74,7 @@
#include <BRepPrimAPI_MakeCylinder.hxx>
#include <BRepPrimAPI_MakeSphere.hxx>
#include <BRepPrimAPI_MakeWedge.hxx>
#include <BRepBuilderAPI_MakePolygon.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include <BRepBuilderAPI_MakeShell.hxx>
@@ -824,4 +825,112 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcAdvancedBrep* l, TopoDS_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
+1
View File
@@ -54,6 +54,7 @@ SHAPE(IfcAdvancedBrep);
// FIXME: Surfaces should have a shape type of their own
SHAPE(IfcBSplineSurfaceWithKnots);
SHAPE(IfcPlane);
SHAPE(IfcTriangulatedFaceSet);
#endif
SHAPE(IfcExtrudedAreaSolid);
SHAPE(IfcRevolvedAreaSolid);