mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 14:41:25 +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
|
#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();
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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() ) {
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
Reference in New Issue
Block a user