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
// Specifies the tolerance of the wire builder, most notably for trimmed curves
#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
#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
// 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);
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 face_area(const TopoDS_Face& f);
namespace Cache {
void Purge();
void PurgeShapeCache();
+23 -20
View File
@@ -73,8 +73,6 @@
#include <ShapeFix_ShapeTolerance.hxx>
#include <ShapeFix_Solid.hxx>
#include <BRepFilletAPI_MakeFillet2d.hxx>
#include <TopLoc_Location.hxx>
#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 ( bounds->Size() == 1 ) {
face = mf.Face();
return true;
}
for( ++it; it != bounds->end(); ++ it) {
Ifc2x3::IfcLoop::ptr loop = (*it)->Bound();
TopoDS_Wire wire;
if ( ! IfcGeom::convert_wire(loop,wire) ) return false;
mf.Add(wire);
}
if ( mf.IsDone() ) {
ShapeFix_Shape sfs(mf.Face());
sfs.Perform();
TopoDS_Shape sfs_shape = sfs.Shape();
bool is_face = sfs_shape.ShapeType() == TopAbs_FACE;
if ( is_face ) {
face = TopoDS::Face(sfs_shape);
return true;
} else {
for( ++it; it != bounds->end(); ++ it) {
Ifc2x3::IfcLoop::ptr loop = (*it)->Bound();
TopoDS_Wire wire;
if ( ! IfcGeom::convert_wire(loop,wire) ) return false;
mf.Add(wire);
}
if ( mf.IsDone() ) {
ShapeFix_Shape sfs(mf.Face());
sfs.Perform();
TopoDS_Shape sfs_shape = sfs.Shape();
bool is_face = sfs_shape.ShapeType() == TopAbs_FACE;
if ( is_face ) {
face = TopoDS::Face(sfs_shape);
} else {
return false;
}
} else {
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) {
TopoDS_Wire wire;
+12 -5
View File
@@ -88,7 +88,9 @@
bool IfcGeom::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape) {
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);
if ( ! exp.More() ) return false;
for ( ; exp.More(); exp.Next() ) {
@@ -99,7 +101,7 @@ bool IfcGeom::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Sh
shape = builder.SewedShape();
try {
ShapeFix_Solid sf_solid;
sf_solid.LimitTolerance(0.01);
sf_solid.LimitTolerance(POINT_EQUALITY_TOLERANCE);
shape = sf_solid.SolidFromShell(TopoDS::Shell(shape));
} catch(...) {}
return true;
@@ -259,9 +261,14 @@ bool IfcGeom::profile_helper(int numVerts, double* verts, int numFillets, int* f
return true;
}
double IfcGeom::shape_volume(const TopoDS_Shape& s) {
GProp_GProps System;
BRepGProp::VolumeProperties(s, System);
return (double) System.Mass();
GProp_GProps prop;
BRepGProp::VolumeProperties(s, prop);
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) {
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();
if ( Ifc::SewShells && num_faces < MAX_FACES_TO_SEW ) {
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 ) {
TopoDS_Face face;
if ( IfcGeom::convert_face(*it,face) ) {
if ( IfcGeom::convert_face(*it,face) && face_area(face) > MINIMAL_FACE_AREA ) {
builder.Add(face);
facesAdded = true;
} else {
@@ -311,7 +313,7 @@ bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr l, TopoDS_Shape& sh
shape = builder.SewedShape();
try {
ShapeFix_Solid solid;
solid.LimitTolerance(0.01);
solid.LimitTolerance(POINT_EQUALITY_TOLERANCE);
shape = solid.SolidFromShell(TopoDS::Shell(shape));
} catch(...) {}
} else {
@@ -320,7 +322,7 @@ bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr l, TopoDS_Shape& sh
builder.MakeCompound(compound);
for( Ifc2x3::IfcFace::it it = faces->begin(); it != faces->end(); ++ it ) {
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);
facesAdded = true;
} else {