Skip to content

Commit b2b51e3

Browse files
committed
Only add faces to shells that have a surface area larger than some threshold value
1 parent aa7a290 commit b2b51e3

4 files changed

Lines changed: 45 additions & 30 deletions

File tree

src/ifcgeom/IfcGeom.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,8 +47,10 @@
4747
#define DEFLECTION_TOLERANCE 0.001
4848
// Specifies the tolerance of the wire builder, most notably for trimmed curves
4949
#define WIRE_CREATION_TOLERANCE 0.0001
50+
// Specifies the minimal area of a face to be included in an IfcConnectedFaceset
51+
#define MINIMAL_FACE_AREA 0.000001
5052
// Specifies the treshold distance under which cartesian points are deemed equal
51-
#define POINT_EQUALITY_TOLERANCE 0.0000001
53+
#define POINT_EQUALITY_TOLERANCE 0.00001
5254

5355
// Specifies maximum number of faces for a shell to be sewed. Sewing shells
5456
// that consist of many faces is really detrimental for the performance.
@@ -72,6 +74,7 @@ namespace IfcGeom {
7274
const TopoDS_Shape& ensure_fit_for_subtraction(const TopoDS_Shape& shape, TopoDS_Shape& solid);
7375
bool profile_helper(int numVerts, double* verts, int numFillets, int* filletIndices, double* filletRadii, gp_Trsf2d trsf, TopoDS_Face& face);
7476
double shape_volume(const TopoDS_Shape& s);
77+
double face_area(const TopoDS_Face& f);
7578
namespace Cache {
7679
void Purge();
7780
void PurgeShapeCache();

src/ifcgeom/IfcGeomFaces.cpp

Lines changed: 23 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -73,8 +73,6 @@
7373
#include <ShapeFix_ShapeTolerance.hxx>
7474
#include <ShapeFix_Solid.hxx>
7575

76-
#include <BRepFilletAPI_MakeFillet2d.hxx>
77-
7876
#include <TopLoc_Location.hxx>
7977

8078
#include "../ifcgeom/IfcGeom.h"
@@ -97,28 +95,33 @@ bool IfcGeom::convert(const Ifc2x3::IfcFace::ptr l, TopoDS_Face& face) {
9795
if ( er != BRepBuilderAPI_FaceDone ) return false;
9896
if ( bounds->Size() == 1 ) {
9997
face = mf.Face();
100-
return true;
101-
}
102-
for( ++it; it != bounds->end(); ++ it) {
103-
Ifc2x3::IfcLoop::ptr loop = (*it)->Bound();
104-
TopoDS_Wire wire;
105-
if ( ! IfcGeom::convert_wire(loop,wire) ) return false;
106-
mf.Add(wire);
107-
}
108-
if ( mf.IsDone() ) {
109-
ShapeFix_Shape sfs(mf.Face());
110-
sfs.Perform();
111-
TopoDS_Shape sfs_shape = sfs.Shape();
112-
bool is_face = sfs_shape.ShapeType() == TopAbs_FACE;
113-
if ( is_face ) {
114-
face = TopoDS::Face(sfs_shape);
115-
return true;
98+
} else {
99+
for( ++it; it != bounds->end(); ++ it) {
100+
Ifc2x3::IfcLoop::ptr loop = (*it)->Bound();
101+
TopoDS_Wire wire;
102+
if ( ! IfcGeom::convert_wire(loop,wire) ) return false;
103+
mf.Add(wire);
104+
}
105+
if ( mf.IsDone() ) {
106+
ShapeFix_Shape sfs(mf.Face());
107+
sfs.Perform();
108+
TopoDS_Shape sfs_shape = sfs.Shape();
109+
bool is_face = sfs_shape.ShapeType() == TopAbs_FACE;
110+
if ( is_face ) {
111+
face = TopoDS::Face(sfs_shape);
112+
} else {
113+
return false;
114+
}
116115
} else {
117116
return false;
118117
}
119-
} else {
120-
return false;
121118
}
119+
// It might be a good idea to globally discard faces
120+
// smaller than a certain treshold value. But for now
121+
// only when processing IfcConnectedFacesets the small
122+
// faces are skipped.
123+
// return face_area(face) > 0.0001;
124+
return true;
122125
}
123126
bool IfcGeom::convert(const Ifc2x3::IfcArbitraryClosedProfileDef::ptr l, TopoDS_Face& face) {
124127
TopoDS_Wire wire;

src/ifcgeom/IfcGeomFunctions.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@
8888

8989
bool IfcGeom::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape) {
9090
BRepOffsetAPI_Sewing builder;
91-
builder.SetTolerance(0.01);
91+
builder.SetTolerance(POINT_EQUALITY_TOLERANCE);
92+
builder.SetMaxTolerance(POINT_EQUALITY_TOLERANCE);
93+
builder.SetMinTolerance(POINT_EQUALITY_TOLERANCE);
9294
TopExp_Explorer exp(compound,TopAbs_FACE);
9395
if ( ! exp.More() ) return false;
9496
for ( ; exp.More(); exp.Next() ) {
@@ -99,7 +101,7 @@ bool IfcGeom::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Sh
99101
shape = builder.SewedShape();
100102
try {
101103
ShapeFix_Solid sf_solid;
102-
sf_solid.LimitTolerance(0.01);
104+
sf_solid.LimitTolerance(POINT_EQUALITY_TOLERANCE);
103105
shape = sf_solid.SolidFromShell(TopoDS::Shell(shape));
104106
} catch(...) {}
105107
return true;
@@ -259,9 +261,14 @@ bool IfcGeom::profile_helper(int numVerts, double* verts, int numFillets, int* f
259261
return true;
260262
}
261263
double IfcGeom::shape_volume(const TopoDS_Shape& s) {
262-
GProp_GProps System;
263-
BRepGProp::VolumeProperties(s, System);
264-
return (double) System.Mass();
264+
GProp_GProps prop;
265+
BRepGProp::VolumeProperties(s, prop);
266+
return prop.Mass();
267+
}
268+
double IfcGeom::face_area(const TopoDS_Face& f) {
269+
GProp_GProps prop;
270+
BRepGProp::SurfaceProperties(f,prop);
271+
return prop.Mass();
265272
}
266273
bool IfcGeom::is_convex(const TopoDS_Wire& wire) {
267274
for ( TopExp_Explorer exp1(wire,TopAbs_VERTEX); exp1.More(); exp1.Next() ) {

src/ifcgeom/IfcGeomShapes.cpp

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -296,10 +296,12 @@ bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr l, TopoDS_Shape& sh
296296
const unsigned int num_faces = faces->Size();
297297
if ( Ifc::SewShells && num_faces < MAX_FACES_TO_SEW ) {
298298
BRepOffsetAPI_Sewing builder;
299-
builder.SetTolerance(0.01);
299+
builder.SetTolerance(POINT_EQUALITY_TOLERANCE);
300+
builder.SetMaxTolerance(POINT_EQUALITY_TOLERANCE);
301+
builder.SetMinTolerance(POINT_EQUALITY_TOLERANCE);
300302
for( Ifc2x3::IfcFace::it it = faces->begin(); it != faces->end(); ++ it ) {
301303
TopoDS_Face face;
302-
if ( IfcGeom::convert_face(*it,face) ) {
304+
if ( IfcGeom::convert_face(*it,face) && face_area(face) > MINIMAL_FACE_AREA ) {
303305
builder.Add(face);
304306
facesAdded = true;
305307
} else {
@@ -311,7 +313,7 @@ bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr l, TopoDS_Shape& sh
311313
shape = builder.SewedShape();
312314
try {
313315
ShapeFix_Solid solid;
314-
solid.LimitTolerance(0.01);
316+
solid.LimitTolerance(POINT_EQUALITY_TOLERANCE);
315317
shape = solid.SolidFromShell(TopoDS::Shell(shape));
316318
} catch(...) {}
317319
} else {
@@ -320,7 +322,7 @@ bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr l, TopoDS_Shape& sh
320322
builder.MakeCompound(compound);
321323
for( Ifc2x3::IfcFace::it it = faces->begin(); it != faces->end(); ++ it ) {
322324
TopoDS_Face face;
323-
if ( IfcGeom::convert_face(*it,face) ) {
325+
if ( IfcGeom::convert_face(*it,face) && face_area(face) > MINIMAL_FACE_AREA ) {
324326
builder.Add(compound,face);
325327
facesAdded = true;
326328
} else {

0 commit comments

Comments
 (0)