mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-21 14:23:53 +00:00
Applied Patch #3509752 by mv2ax
Made the sewing of TopoDS_Shells into a IfcGeomObjects::Setting Limit the maximum number of faces a shell to be sewed
This commit is contained in:
@@ -50,7 +50,9 @@
|
||||
// Specifies the treshold distance under which cartesian points are deemed equal
|
||||
#define POINT_EQUALITY_TOLERANCE 0.000001
|
||||
|
||||
#define FACESET_AS_COMPOUND 1
|
||||
// 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 100
|
||||
|
||||
namespace IfcGeom {
|
||||
bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face);
|
||||
|
||||
@@ -25,7 +25,6 @@
|
||||
#include <gp_GTrsf2d.hxx>
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <gp_Trsf2d.hxx>
|
||||
#include <gp_Quaternion.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
@@ -522,6 +521,9 @@ void IfcGeomObjects::Settings(int setting, bool value) {
|
||||
case USE_BREP_DATA:
|
||||
use_brep_data = value;
|
||||
break;
|
||||
case SEW_SHELLS:
|
||||
Ifc::SewShells = value;
|
||||
break;
|
||||
}
|
||||
}
|
||||
int IfcGeomObjects::Progress() {
|
||||
|
||||
@@ -38,9 +38,7 @@
|
||||
* IfcGeomObject.matrix is a 4x3 matrix that defines the orientation and *
|
||||
* translation of the mesh in relation to the world origin *
|
||||
* *
|
||||
* Init(char* fn, bool world_coords) parses the IFC file in fn, returns true *
|
||||
* on succes, world_coords = true will result in all IfcGeomObject.matrix *
|
||||
* being an identity matrix and IfcMesh.verts containing global positions *
|
||||
* Init(char* fn) parses the IFC file in fn, returns true on succes. *
|
||||
* *
|
||||
* Get() returns a pointer to the current IfcGeomObject *
|
||||
* *
|
||||
@@ -69,13 +67,37 @@
|
||||
|
||||
namespace IfcGeomObjects {
|
||||
|
||||
const int WELD_VERTICES = 1;
|
||||
const int USE_WORLD_COORDS = 2;
|
||||
const int CONVERT_BACK_UNITS = 3;
|
||||
const int USE_BREP_DATA = 4;
|
||||
// Enumeration of setting identifiers. These settings define the
|
||||
// behaviour of various aspects of IfcOpenShell.
|
||||
|
||||
// Specifies whether vertices are welded, meaning that the coordinates
|
||||
// vector will only contain unique xyz-triplets. This results in a
|
||||
// manifold mesh which is useful for modelling applications, but might
|
||||
// result in unwanted shading artifacts in rendering applications.
|
||||
const int WELD_VERTICES = 1;
|
||||
// Specifies whether to apply the local placements of building elements
|
||||
// directly to the coordinates of the representation mesh rather than
|
||||
// to represent the local placement in the 4x3 matrix, which will in that
|
||||
// case be the identity matrix.
|
||||
const int USE_WORLD_COORDS = 2;
|
||||
// Internally IfcOpenShell measures everything in meters. This settings
|
||||
// specifies whether to convert IfcGeomObjects back to the units in which
|
||||
// the geometry in the IFC file is specified.
|
||||
const int CONVERT_BACK_UNITS = 3;
|
||||
// Specifies whether to use the Open Cascade BREP format for representation
|
||||
// items rather than to create triangle meshes. This is useful is IfcOpenShell
|
||||
// is used as a library in an application that is also built on Open Cascade.
|
||||
const int USE_BREP_DATA = 4;
|
||||
// Specifies whether to sew IfcConnectedFaceSets (open and closed shells) to
|
||||
// TopoDS_Shells or whether to keep them as a loose collection of faces.
|
||||
const int SEW_SHELLS = 5;
|
||||
|
||||
// End of settings enumeration.
|
||||
|
||||
// Some typedefs for convenience
|
||||
typedef std::vector<int>::const_iterator IntIt;
|
||||
typedef std::vector<double>::const_iterator FltIt;
|
||||
// A nested pair of doubles to be able to store an XYZ coordinate in a map.
|
||||
typedef std::pair< double,std::pair<double,double> > VertKey;
|
||||
typedef std::map<VertKey,int> VertKeyMap;
|
||||
typedef std::pair<int,int> Edge;
|
||||
|
||||
@@ -71,8 +71,6 @@
|
||||
#include <ShapeFix_ShapeTolerance.hxx>
|
||||
#include <ShapeFix_Solid.hxx>
|
||||
|
||||
#include <BRepFilletAPI_MakeFillet2d.hxx>
|
||||
|
||||
#include <TopLoc_Location.hxx>
|
||||
|
||||
#include <BRepCheck_Analyzer.hxx>
|
||||
@@ -293,41 +291,45 @@ bool IfcGeom::convert(const Ifc2x3::IfcBooleanClippingResult::ptr l, TopoDS_Shap
|
||||
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr l, TopoDS_Shape& shape) {
|
||||
#ifdef FACESET_AS_COMPOUND
|
||||
TopoDS_Compound compound;
|
||||
BRep_Builder builder;
|
||||
builder.MakeCompound(compound);
|
||||
#else
|
||||
BRepOffsetAPI_Sewing builder;
|
||||
builder.SetTolerance(0.01);
|
||||
#endif
|
||||
Ifc2x3::IfcFace::list faces = l->CfsFaces();
|
||||
bool facesAdded = false;
|
||||
for( Ifc2x3::IfcFace::it it = faces->begin(); it != faces->end(); ++ it ) {
|
||||
TopoDS_Face face;
|
||||
if ( IfcGeom::convert_face(*it,face) ) {
|
||||
#ifdef FACESET_AS_COMPOUND
|
||||
builder.Add(compound,face);
|
||||
#else
|
||||
builder.Add(face);
|
||||
#endif
|
||||
facesAdded = true;
|
||||
} else {
|
||||
Ifc::LogMessage("Warning","Invalid face:",(*it)->entity);
|
||||
const unsigned int num_faces = faces->Size();
|
||||
if ( Ifc::SewShells && num_faces < MAX_FACES_TO_SEW ) {
|
||||
BRepOffsetAPI_Sewing builder;
|
||||
builder.SetTolerance(0.01);
|
||||
for( Ifc2x3::IfcFace::it it = faces->begin(); it != faces->end(); ++ it ) {
|
||||
TopoDS_Face face;
|
||||
if ( IfcGeom::convert_face(*it,face) ) {
|
||||
builder.Add(face);
|
||||
facesAdded = true;
|
||||
} else {
|
||||
Ifc::LogMessage("Warning","Invalid face:",(*it)->entity);
|
||||
}
|
||||
}
|
||||
if ( ! facesAdded ) return false;
|
||||
builder.Perform();
|
||||
shape = builder.SewedShape();
|
||||
try {
|
||||
ShapeFix_Solid solid;
|
||||
solid.LimitTolerance(0.01);
|
||||
shape = solid.SolidFromShell(TopoDS::Shell(shape));
|
||||
} catch(...) {}
|
||||
} else {
|
||||
TopoDS_Compound compound;
|
||||
BRep_Builder builder;
|
||||
builder.MakeCompound(compound);
|
||||
for( Ifc2x3::IfcFace::it it = faces->begin(); it != faces->end(); ++ it ) {
|
||||
TopoDS_Face face;
|
||||
if ( IfcGeom::convert_face(*it,face) ) {
|
||||
builder.Add(compound,face);
|
||||
facesAdded = true;
|
||||
} else {
|
||||
Ifc::LogMessage("Warning","Invalid face:",(*it)->entity);
|
||||
}
|
||||
}
|
||||
if ( ! facesAdded ) return false;
|
||||
shape = compound;
|
||||
}
|
||||
if ( ! facesAdded ) return false;
|
||||
#ifdef FACESET_AS_COMPOUND
|
||||
shape = compound;
|
||||
#else
|
||||
builder.Perform();
|
||||
shape = builder.SewedShape();
|
||||
try {
|
||||
ShapeFix_Solid solid;
|
||||
solid.LimitTolerance(0.01);
|
||||
shape = solid.SolidFromShell(TopoDS::Shell(shape));
|
||||
} catch(...) {}
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcMappedItem::ptr l, ShapeList& shapes) {
|
||||
|
||||
Reference in New Issue
Block a user