Only add faces to shells that have a surface area larger than some threshold value

This commit is contained in:
Thomas Krijnen
2012-04-07 14:34:44 +00:00
parent aa7a290ea1
commit b2b51e343f
4 changed files with 45 additions and 30 deletions
+4 -1
View File
@@ -47,8 +47,10 @@
#define DEFLECTION_TOLERANCE 0.001 #define DEFLECTION_TOLERANCE 0.001
// Specifies the tolerance of the wire builder, most notably for trimmed curves // Specifies the tolerance of the wire builder, most notably for trimmed curves
#define WIRE_CREATION_TOLERANCE 0.0001 #define WIRE_CREATION_TOLERANCE 0.0001
// Specifies the minimal area of a face to be included in an IfcConnectedFaceset
#define MINIMAL_FACE_AREA 0.000001
// Specifies the treshold distance under which cartesian points are deemed equal // Specifies the treshold distance under which cartesian points are deemed equal
#define POINT_EQUALITY_TOLERANCE 0.0000001 #define POINT_EQUALITY_TOLERANCE 0.00001
// Specifies maximum number of faces for a shell to be sewed. Sewing shells // Specifies maximum number of faces for a shell to be sewed. Sewing shells
// that consist of many faces is really detrimental for the performance. // that consist of many faces is really detrimental for the performance.
@@ -72,6 +74,7 @@ namespace IfcGeom {
const TopoDS_Shape& ensure_fit_for_subtraction(const TopoDS_Shape& shape, TopoDS_Shape& solid); const TopoDS_Shape& ensure_fit_for_subtraction(const TopoDS_Shape& shape, TopoDS_Shape& solid);
bool profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Face& face); bool profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Face& face);
double shape_volume(const TopoDS_Shape& s); double shape_volume(const TopoDS_Shape& s);
double face_area(const TopoDS_Face& f);
namespace Cache { namespace Cache {
void Purge(); void Purge();
void PurgeShapeCache(); void PurgeShapeCache();
+23 -20
View File
@@ -73,8 +73,6 @@
#include <ShapeFix_ShapeTolerance.hxx> #include <ShapeFix_ShapeTolerance.hxx>
#include <ShapeFix_Solid.hxx> #include <ShapeFix_Solid.hxx>
#include <BRepFilletAPI_MakeFillet2d.hxx>
#include <TopLoc_Location.hxx> #include <TopLoc_Location.hxx>
#include "../ifcgeom/IfcGeom.h" #include "../ifcgeom/IfcGeom.h"
@@ -97,28 +95,33 @@ bool IfcGeom::convert(const Ifc2x3::IfcFace::ptr l, TopoDS_Face& face) {
if ( er != BRepBuilderAPI_FaceDone ) return false; if ( er != BRepBuilderAPI_FaceDone ) return false;
if ( bounds->Size() == 1 ) { if ( bounds->Size() == 1 ) {
face = mf.Face(); face = mf.Face();
return true; } else {
} for( ++it; it != bounds->end(); ++ it) {
for( ++it; it != bounds->end(); ++ it) { Ifc2x3::IfcLoop::ptr loop = (*it)->Bound();
Ifc2x3::IfcLoop::ptr loop = (*it)->Bound(); TopoDS_Wire wire;
TopoDS_Wire wire; if ( ! IfcGeom::convert_wire(loop,wire) ) return false;
if ( ! IfcGeom::convert_wire(loop,wire) ) return false; mf.Add(wire);
mf.Add(wire); }
} if ( mf.IsDone() ) {
if ( mf.IsDone() ) { ShapeFix_Shape sfs(mf.Face());
ShapeFix_Shape sfs(mf.Face()); sfs.Perform();
sfs.Perform(); TopoDS_Shape sfs_shape = sfs.Shape();
TopoDS_Shape sfs_shape = sfs.Shape(); bool is_face = sfs_shape.ShapeType() == TopAbs_FACE;
bool is_face = sfs_shape.ShapeType() == TopAbs_FACE; if ( is_face ) {
if ( is_face ) { face = TopoDS::Face(sfs_shape);
face = TopoDS::Face(sfs_shape); } else {
return true; return false;
}
} else { } else {
return false; return false;
} }
} else {
return false;
} }
// It might be a good idea to globally discard faces
// smaller than a certain treshold value. But for now
// only when processing IfcConnectedFacesets the small
// faces are skipped.
// return face_area(face) > 0.0001;
return true;
} }
bool IfcGeom::convert(const Ifc2x3::IfcArbitraryClosedProfileDef::ptr l, TopoDS_Face& face) { bool IfcGeom::convert(const Ifc2x3::IfcArbitraryClosedProfileDef::ptr l, TopoDS_Face& face) {
TopoDS_Wire wire; TopoDS_Wire wire;
+12 -5
View File
@@ -88,7 +88,9 @@
bool IfcGeom::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape) { bool IfcGeom::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape) {
BRepOffsetAPI_Sewing builder; BRepOffsetAPI_Sewing builder;
builder.SetTolerance(0.01); builder.SetTolerance(POINT_EQUALITY_TOLERANCE);
builder.SetMaxTolerance(POINT_EQUALITY_TOLERANCE);
builder.SetMinTolerance(POINT_EQUALITY_TOLERANCE);
TopExp_Explorer exp(compound,TopAbs_FACE); TopExp_Explorer exp(compound,TopAbs_FACE);
if ( ! exp.More() ) return false; if ( ! exp.More() ) return false;
for ( ; exp.More(); exp.Next() ) { for ( ; exp.More(); exp.Next() ) {
@@ -99,7 +101,7 @@ bool IfcGeom::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Sh
shape = builder.SewedShape(); shape = builder.SewedShape();
try { try {
ShapeFix_Solid sf_solid; ShapeFix_Solid sf_solid;
sf_solid.LimitTolerance(0.01); sf_solid.LimitTolerance(POINT_EQUALITY_TOLERANCE);
shape = sf_solid.SolidFromShell(TopoDS::Shell(shape)); shape = sf_solid.SolidFromShell(TopoDS::Shell(shape));
} catch(...) {} } catch(...) {}
return true; return true;
@@ -259,9 +261,14 @@ bool IfcGeom::profile_helper(int numVerts, double* verts, int numFillets, int* f
return true; return true;
} }
double IfcGeom::shape_volume(const TopoDS_Shape& s) { double IfcGeom::shape_volume(const TopoDS_Shape& s) {
GProp_GProps System; GProp_GProps prop;
BRepGProp::VolumeProperties(s, System); BRepGProp::VolumeProperties(s, prop);
return (double) System.Mass(); return prop.Mass();
}
double IfcGeom::face_area(const TopoDS_Face& f) {
GProp_GProps prop;
BRepGProp::SurfaceProperties(f,prop);
return prop.Mass();
} }
bool IfcGeom::is_convex(const TopoDS_Wire& wire) { bool IfcGeom::is_convex(const TopoDS_Wire& wire) {
for ( TopExp_Explorer exp1(wire,TopAbs_VERTEX); exp1.More(); exp1.Next() ) { for ( TopExp_Explorer exp1(wire,TopAbs_VERTEX); exp1.More(); exp1.Next() ) {
+6 -4
View File
@@ -296,10 +296,12 @@ bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr l, TopoDS_Shape& sh
const unsigned int num_faces = faces->Size(); const unsigned int num_faces = faces->Size();
if ( Ifc::SewShells && num_faces < MAX_FACES_TO_SEW ) { if ( Ifc::SewShells && num_faces < MAX_FACES_TO_SEW ) {
BRepOffsetAPI_Sewing builder; BRepOffsetAPI_Sewing builder;
builder.SetTolerance(0.01); builder.SetTolerance(POINT_EQUALITY_TOLERANCE);
builder.SetMaxTolerance(POINT_EQUALITY_TOLERANCE);
builder.SetMinTolerance(POINT_EQUALITY_TOLERANCE);
for( Ifc2x3::IfcFace::it it = faces->begin(); it != faces->end(); ++ it ) { for( Ifc2x3::IfcFace::it it = faces->begin(); it != faces->end(); ++ it ) {
TopoDS_Face face; TopoDS_Face face;
if ( IfcGeom::convert_face(*it,face) ) { if ( IfcGeom::convert_face(*it,face) && face_area(face) > MINIMAL_FACE_AREA ) {
builder.Add(face); builder.Add(face);
facesAdded = true; facesAdded = true;
} else { } else {
@@ -311,7 +313,7 @@ bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr l, TopoDS_Shape& sh
shape = builder.SewedShape(); shape = builder.SewedShape();
try { try {
ShapeFix_Solid solid; ShapeFix_Solid solid;
solid.LimitTolerance(0.01); solid.LimitTolerance(POINT_EQUALITY_TOLERANCE);
shape = solid.SolidFromShell(TopoDS::Shell(shape)); shape = solid.SolidFromShell(TopoDS::Shell(shape));
} catch(...) {} } catch(...) {}
} else { } else {
@@ -320,7 +322,7 @@ bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr l, TopoDS_Shape& sh
builder.MakeCompound(compound); builder.MakeCompound(compound);
for( Ifc2x3::IfcFace::it it = faces->begin(); it != faces->end(); ++ it ) { for( Ifc2x3::IfcFace::it it = faces->begin(); it != faces->end(); ++ it ) {
TopoDS_Face face; TopoDS_Face face;
if ( IfcGeom::convert_face(*it,face) ) { if ( IfcGeom::convert_face(*it,face) && face_area(face) > MINIMAL_FACE_AREA ) {
builder.Add(compound,face); builder.Add(compound,face);
facesAdded = true; facesAdded = true;
} else { } else {