mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-14 03:14:23 +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) {
|
||||
|
||||
+22
-9
@@ -24,6 +24,7 @@
|
||||
#include "../ifcmax/IfcMax.h"
|
||||
#include "../ifcmax/MaxMaterials.h"
|
||||
#include "../ifcgeom/IfcGeomObjects.h"
|
||||
|
||||
int controlsInit = false;
|
||||
|
||||
BOOL WINAPI DllMain(HINSTANCE hinstDLL,ULONG fdwReason,LPVOID lpvReserved) {
|
||||
@@ -106,10 +107,11 @@ int IFCImp::DoImport(const TCHAR *name, ImpInterface *impitfc, Interface *itfc,
|
||||
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::USE_WORLD_COORDS,false);
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::WELD_VERTICES,true);
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::SEW_SHELLS,true);
|
||||
|
||||
if ( ! IfcGeomObjects::Init((char*)name,0,0) ) return false;
|
||||
|
||||
std::map<int, TriObject*> dict;
|
||||
//std::map<int, TriObject*> dict;
|
||||
MtlBaseLib* mats = itfc->GetSceneMtls();
|
||||
int slot = mats->Count();
|
||||
|
||||
@@ -129,10 +131,14 @@ int IFCImp::DoImport(const TCHAR *name, ImpInterface *impitfc, Interface *itfc,
|
||||
m = static_cast<Mtl*>((*mats)[matIndex]);
|
||||
}
|
||||
|
||||
std::map<int, TriObject*>::const_iterator it = dict.find(o->mesh->id);
|
||||
// This mapping is useless for now, because this even in case
|
||||
// meshes entities in IFC share the same representation elements
|
||||
// they will never be given the same id.
|
||||
// TODO: Fix this!
|
||||
// std::map<int, TriObject*>::const_iterator it = dict.find(o->mesh->id);
|
||||
|
||||
TriObject* tri;
|
||||
if ( it == dict.end() ) {
|
||||
// if ( it == dict.end() ) {
|
||||
tri = CreateNewTriObject();
|
||||
const int numVerts = o->mesh->verts.size()/3;
|
||||
tri->mesh.setNumVerts(numVerts);
|
||||
@@ -145,14 +151,21 @@ int IFCImp::DoImport(const TCHAR *name, ImpInterface *impitfc, Interface *itfc,
|
||||
tri->mesh.faces[i].setVerts(o->mesh->faces[3*i+0],o->mesh->faces[3*i+1],o->mesh->faces[3*i+2]);
|
||||
tri->mesh.faces[i].setEdgeVisFlags(o->mesh->edges[3*i+0],o->mesh->edges[3*i+1],o->mesh->edges[3*i+2]);
|
||||
}
|
||||
tri->mesh.InvalidateTopologyCache();
|
||||
tri->mesh.InvalidateGeomCache();
|
||||
|
||||
tri->mesh.buildNormals();
|
||||
// Either use this or undefine the FACESETS_AS_COMPOUND option in IfcGeom.h to have
|
||||
// properly oriented normals. Using only the line below will result in a consistent
|
||||
// orientation of normals accross shells, but not always oriented towards the
|
||||
// outside.
|
||||
// tri->mesh.UnifyNormals(false);
|
||||
tri->mesh.BuildStripsAndEdges();
|
||||
dict[o->mesh->id] = tri;
|
||||
} else {
|
||||
tri = (*it).second;
|
||||
}
|
||||
tri->mesh.InvalidateTopologyCache();
|
||||
tri->mesh.InvalidateGeomCache();
|
||||
|
||||
// dict[o->mesh->id] = tri;
|
||||
// } else {
|
||||
// tri = (*it).second;
|
||||
// }
|
||||
|
||||
ImpNode* node = impitfc->CreateNode();
|
||||
node->Reference(tri);
|
||||
|
||||
@@ -49,6 +49,7 @@ int main ( int argc, char** argv ) {
|
||||
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::USE_WORLD_COORDS,true);
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::WELD_VERTICES,false);
|
||||
IfcGeomObjects::Settings(IfcGeomObjects::SEW_SHELLS,true);
|
||||
|
||||
// Stream for log messages, we don't want to interupt our new progress bar...
|
||||
std::stringstream ss;
|
||||
|
||||
@@ -822,6 +822,7 @@ Tokens* Ifc::tokens = 0;
|
||||
double Ifc::LengthUnit = 1.0f;
|
||||
double Ifc::PlaneAngleUnit = 1.0f;
|
||||
bool Ifc::hasPlaneAngleUnit = false;
|
||||
bool Ifc::SewShells = false;
|
||||
int Ifc::CircleSegments = 32;
|
||||
MapEntitiesByType Ifc::bytype;
|
||||
MapEntityById Ifc::byid;
|
||||
|
||||
@@ -268,6 +268,7 @@ public:
|
||||
static std::string GetLog();
|
||||
static void Dispose();
|
||||
static bool hasPlaneAngleUnit;
|
||||
static bool SewShells;
|
||||
static double LengthUnit;
|
||||
static double PlaneAngleUnit;
|
||||
static int CircleSegments;
|
||||
|
||||
@@ -23,6 +23,7 @@ namespace IfcGeomObjects {
|
||||
const int USE_WORLD_COORDS = 2;
|
||||
const int CONVERT_BACK_UNITS = 3;
|
||||
const int USE_BREP_DATA = 4;
|
||||
const int SEW_SHELLS = 5;
|
||||
|
||||
class IfcMesh {
|
||||
public:
|
||||
|
||||
Reference in New Issue
Block a user