Thomas Krijnen
2012-06-25 15:08:58 +00:00
parent 9a54a64311
commit 4975de6d74
5 changed files with 80 additions and 34 deletions
+19 -14
View File
@@ -42,21 +42,23 @@
#include "../ifcgeom/IfcShapeList.h"
// Tolerances for various geometrical operations:
// Specifies the deflection of the mesher
#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.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.
#define MAX_FACES_TO_SEW 1000
namespace IfcGeom {
// Tolerances and settings for various geometrical operations:
enum GeomValue {
// Specifies the deflection of the mesher
GV_DEFLECTION_TOLERANCE,
// Specifies the tolerance of the wire builder, most notably for trimmed curves
GV_WIRE_CREATION_TOLERANCE,
// Specifies the minimal area of a face to be included in an IfcConnectedFaceset
GV_MINIMAL_FACE_AREA,
// Specifies the treshold distance under which cartesian points are deemed equal
GV_POINT_EQUALITY_TOLERANCE,
// Specifies maximum number of faces for a shell to be sewed. Sewing shells
// that consist of many faces is really detrimental for the performance.
GV_MAX_FACES_TO_SEW
};
bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face);
bool convert_shapes(const IfcUtil::IfcBaseClass* L, ShapeList& result);
bool is_shape_collection(const IfcUtil::IfcBaseClass* L);
@@ -76,6 +78,9 @@ namespace IfcGeom {
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);
void SetValue(GeomValue var, double value);
double GetValue(GeomValue var);
namespace Cache {
void Purge();
void PurgeShapeCache();
+49 -8
View File
@@ -23,6 +23,8 @@
* *
********************************************************************************/
#include <cassert>
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
#include <gp_Dir.hxx>
@@ -88,9 +90,9 @@
bool IfcGeom::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape) {
BRepOffsetAPI_Sewing builder;
builder.SetTolerance(POINT_EQUALITY_TOLERANCE);
builder.SetMaxTolerance(POINT_EQUALITY_TOLERANCE);
builder.SetMinTolerance(POINT_EQUALITY_TOLERANCE);
builder.SetTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
builder.SetMaxTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
builder.SetMinTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
TopExp_Explorer exp(compound,TopAbs_FACE);
if ( ! exp.More() ) return false;
for ( ; exp.More(); exp.Next() ) {
@@ -101,7 +103,7 @@ bool IfcGeom::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Sh
shape = builder.SewedShape();
try {
ShapeFix_Solid sf_solid;
sf_solid.LimitTolerance(POINT_EQUALITY_TOLERANCE);
sf_solid.LimitTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
shape = sf_solid.SolidFromShell(TopoDS::Shell(shape));
} catch(...) {}
return true;
@@ -369,8 +371,8 @@ bool IfcGeom::is_convex(const TopoDS_Wire& wire) {
edge_points.push_back(P2);
}
if ( edge_points.size() != 2 ) continue;
if ( edge_points[0].IsEqual(P1,POINT_EQUALITY_TOLERANCE)) neighbors.push_back(edge_points[1]);
else if ( edge_points[1].IsEqual(P1,POINT_EQUALITY_TOLERANCE)) neighbors.push_back(edge_points[0]);
if ( edge_points[0].IsEqual(P1,GetValue(GV_POINT_EQUALITY_TOLERANCE))) neighbors.push_back(edge_points[1]);
else if ( edge_points[1].IsEqual(P1, GetValue(GV_POINT_EQUALITY_TOLERANCE))) neighbors.push_back(edge_points[0]);
}
// There should be two of these
if ( neighbors.size() != 2 ) return false;
@@ -379,10 +381,10 @@ bool IfcGeom::is_convex(const TopoDS_Wire& wire) {
for ( TopExp_Explorer exp2(wire,TopAbs_VERTEX); exp2.More(); exp2.Next() ) {
TopoDS_Vertex V2 = TopoDS::Vertex(exp2.Current());
gp_Pnt P2 = BRep_Tool::Pnt(V2);
if ( P1.IsEqual(P2,POINT_EQUALITY_TOLERANCE) ) continue;
if ( P1.IsEqual(P2,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) continue;
bool found = false;
for( std::vector<gp_Pnt>::const_iterator it = neighbors.begin(); it != neighbors.end(); ++ it ) {
if ( (*it).IsEqual(P2,POINT_EQUALITY_TOLERANCE) ) { found = true; break; }
if ( (*it).IsEqual(P2,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) { found = true; break; }
}
if ( ! found ) non_neighbors.push_back(P2);
}
@@ -421,4 +423,43 @@ gp_Pnt IfcGeom::point_above_plane(const gp_Pln& pln, bool agree) {
} else {
return pln.Location().Translated(-pln.Axis().Direction());
}
}
static double deflection_tolerance = 0.001;
static double wire_creation_tolerance = 0.0001;
static double minimal_face_area = 0.000001;
static double point_equality_tolerance = 0.00001;
static double max_faces_to_sew = 1000;
void IfcGeom::SetValue(GeomValue var, double value) {
switch (var) {
case GV_DEFLECTION_TOLERANCE:
deflection_tolerance = value;
case GV_WIRE_CREATION_TOLERANCE:
wire_creation_tolerance = value;
case GV_MINIMAL_FACE_AREA:
minimal_face_area = value;
case GV_POINT_EQUALITY_TOLERANCE:
point_equality_tolerance = value;
case GV_MAX_FACES_TO_SEW:
max_faces_to_sew = value;
}
assert(!"never reach here");
}
double IfcGeom::GetValue(GeomValue var) {
switch (var) {
case GV_DEFLECTION_TOLERANCE:
return deflection_tolerance;
case GV_WIRE_CREATION_TOLERANCE:
return wire_creation_tolerance;
case GV_MINIMAL_FACE_AREA:
return minimal_face_area;
case GV_POINT_EQUALITY_TOLERANCE:
return point_equality_tolerance;
case GV_MAX_FACES_TO_SEW:
return max_faces_to_sew;
}
assert(!"never reach here");
return 0;
}
+1 -1
View File
@@ -103,7 +103,7 @@ IfcGeomObjects::IfcMesh::IfcMesh(int i, const IfcGeom::ShapeList& shapes) {
// Triangulate the shape
try {
//BRepTools::Clean(s);
BRepMesh::Mesh(s,DEFLECTION_TOLERANCE);
BRepMesh::Mesh(s, IfcGeom::GetValue(IfcGeom::GV_DEFLECTION_TOLERANCE));
} catch(...) {
Ifc::LogMessage("Error","Failed to triangulate mesh:",Ifc::EntityById(i)->entity);
continue;
+7 -7
View File
@@ -294,14 +294,14 @@ bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr l, TopoDS_Shape& sh
Ifc2x3::IfcFace::list faces = l->CfsFaces();
bool facesAdded = false;
const unsigned int num_faces = faces->Size();
if ( Ifc::SewShells && num_faces < MAX_FACES_TO_SEW ) {
if ( Ifc::SewShells && num_faces < GetValue(GV_MAX_FACES_TO_SEW) ) {
BRepOffsetAPI_Sewing builder;
builder.SetTolerance(POINT_EQUALITY_TOLERANCE);
builder.SetMaxTolerance(POINT_EQUALITY_TOLERANCE);
builder.SetMinTolerance(POINT_EQUALITY_TOLERANCE);
builder.SetTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
builder.SetMaxTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
builder.SetMinTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
for( Ifc2x3::IfcFace::it it = faces->begin(); it != faces->end(); ++ it ) {
TopoDS_Face face;
if ( IfcGeom::convert_face(*it,face) && face_area(face) > MINIMAL_FACE_AREA ) {
if ( IfcGeom::convert_face(*it,face) && face_area(face) > GetValue(GV_MINIMAL_FACE_AREA) ) {
builder.Add(face);
facesAdded = true;
} else {
@@ -313,7 +313,7 @@ bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr l, TopoDS_Shape& sh
shape = builder.SewedShape();
try {
ShapeFix_Solid solid;
solid.LimitTolerance(POINT_EQUALITY_TOLERANCE);
solid.LimitTolerance(GetValue(GV_POINT_EQUALITY_TOLERANCE));
shape = solid.SolidFromShell(TopoDS::Shell(shape));
} catch(...) {}
} else {
@@ -322,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) && face_area(face) > MINIMAL_FACE_AREA ) {
if ( IfcGeom::convert_face(*it,face) && face_area(face) > GetValue(GV_MINIMAL_FACE_AREA) ) {
builder.Add(compound,face);
facesAdded = true;
} else {
+4 -4
View File
@@ -117,7 +117,7 @@ bool IfcGeom::convert(const Ifc2x3::IfcCompositeCurve::ptr l, TopoDS_Wire& wire)
}
if ( ! (*it)->SameSense() ) wire2.Reverse();
ShapeFix_ShapeTolerance FTol;
FTol.SetTolerance(wire2, WIRE_CREATION_TOLERANCE, TopAbs_WIRE);
FTol.SetTolerance(wire2, GetValue(GV_WIRE_CREATION_TOLERANCE), TopAbs_WIRE);
/*if ( it != segments->begin() ) {
TopExp_Explorer exp (wire2,TopAbs_VERTEX);
const TopoDS_Vertex& first_vertex = TopoDS::Vertex(exp.Current());
@@ -204,7 +204,7 @@ bool IfcGeom::convert(const Ifc2x3::IfcPolyline::ptr l, TopoDS_Wire& result) {
gp_Pnt P1;gp_Pnt P2;
for( Ifc2x3::IfcCartesianPoint::it it = points->begin(); it != points->end(); ++ it ) {
IfcGeom::convert(*it,P2);
if ( it != points->begin() && ( !P1.IsEqual(P2,POINT_EQUALITY_TOLERANCE) ) )
if ( it != points->begin() && ( !P1.IsEqual(P2,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) )
w.Add(BRepBuilderAPI_MakeEdge(P1,P2));
P1 = P2;
}
@@ -220,13 +220,13 @@ bool IfcGeom::convert(const Ifc2x3::IfcPolyLoop::ptr l, TopoDS_Wire& result) {
int count = 0;
for( Ifc2x3::IfcCartesianPoint::it it = points->begin(); it != points->end(); ++ it ) {
IfcGeom::convert(*it,P2);
if ( it != points->begin() && ( !P1.IsEqual(P2,POINT_EQUALITY_TOLERANCE) ) ) {
if ( it != points->begin() && ( !P1.IsEqual(P2,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) ) {
w.Add(BRepBuilderAPI_MakeEdge(P1,P2));
count ++;
} else if ( ! count ) F = P2;
P1 = P2;
}
if ( !P1.IsEqual(F,POINT_EQUALITY_TOLERANCE) ) {
if ( !P1.IsEqual(F,GetValue(GV_POINT_EQUALITY_TOLERANCE)) ) {
w.Add(BRepBuilderAPI_MakeEdge(P1,F));
count ++;
}