mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Only add faces to shells that have a surface area larger than some threshold value
This commit is contained in:
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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() ) {
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user