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:
Thomas Krijnen
2012-03-23 17:38:44 +00:00
parent df2bcecf96
commit a9bba39b9d
9 changed files with 96 additions and 51 deletions
+3 -1
View File
@@ -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);
+3 -1
View File
@@ -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() {
+29 -7
View File
@@ -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;
+35 -33
View File
@@ -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
View File
@@ -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);
+1
View File
@@ -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;
+1
View File
@@ -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;
+1
View File
@@ -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;
+1
View File
@@ -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: