- Make distinction between single shape and list of shapes

- Store shapes in std::vectors rather than TopoDS_Compounds
- Apply transformation only on triangulated meshes or when processing openings
- Store transformations in a gp_GTrsf to allow arbitrary transformations
- Support IfcCartesianTransformationOperator3DnonUniform
- TODO: Create proper class for ShapeList
- TODO: Carefully check for null pointers returned from IfcGeom::convert_shape()
This commit is contained in:
Thomas Krijnen
2011-10-23 17:11:06 +00:00
parent 8bcb9ffa3e
commit bd79df2be7
17 changed files with 360 additions and 174 deletions
+11 -2
View File
@@ -25,6 +25,10 @@
#include <gp_Pnt.hxx>
#include <gp_Vec.hxx>
#include <gp_Mat.hxx>
#include <gp_Mat2d.hxx>
#include <gp_GTrsf.hxx>
#include <gp_GTrsf2d.hxx>
#include <gp_Trsf.hxx>
#include <gp_Trsf2d.hxx>
#include <TopoDS.hxx>
@@ -37,12 +41,17 @@
#include "../ifcparse/IfcUtil.h"
namespace IfcGeom {
typedef std::pair<gp_GTrsf*,const TopoDS_Shape*> LocationShape;
typedef std::vector<LocationShape> ShapeList;
bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face);
bool convert_shape(const IfcUtil::IfcBaseClass* L, TopoDS_Shape& result);
bool convert_shapes(const IfcUtil::IfcBaseClass* L, ShapeList& result);
bool is_shape_collection(const IfcUtil::IfcBaseClass* L);
const TopoDS_Shape* convert_shape(const IfcUtil::IfcBaseClass* L, TopoDS_Shape& result);
bool convert_wire(const IfcUtil::IfcBaseClass* L, TopoDS_Wire& result);
bool convert_curve(const IfcUtil::IfcBaseClass* L, Handle(Geom_Curve)& result);
bool convert_face(const IfcUtil::IfcBaseClass* L, TopoDS_Face& result);
bool convert_openings(const Ifc2x3::IfcProduct::ptr L, const Ifc2x3::IfcRelVoidsElement::list& openings, TopoDS_Shape& result, const gp_Trsf& trsf);
bool convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings, const ShapeList& entity_shapes, const gp_Trsf& entity_trsf, ShapeList& cut_shapes);
bool profile_helper(int numVerts, float* verts, int numFillets, int* filletIndices, float* filletRadii, gp_Trsf2d trsf, TopoDS_Face& face);
float shape_volume(const TopoDS_Shape& s);
namespace Cache {
+4 -1
View File
@@ -29,9 +29,12 @@
#include <gp_Pnt2d.hxx>
#include <gp_Vec2d.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Mat.hxx>
#include <gp_Mat2d.hxx>
#include <gp_GTrsf.hxx>
#include <gp_GTrsf2d.hxx>
#include <gp_Trsf.hxx>
#include <gp_Trsf2d.hxx>
#include <gp_Mat.hxx>
#include <gp_Ax3.hxx>
#include <gp_Ax2d.hxx>
#include <gp_Pln.hxx>
+4 -1
View File
@@ -31,9 +31,12 @@
#include <gp_Pnt2d.hxx>
#include <gp_Vec2d.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Mat.hxx>
#include <gp_Mat2d.hxx>
#include <gp_GTrsf.hxx>
#include <gp_GTrsf2d.hxx>
#include <gp_Trsf.hxx>
#include <gp_Trsf2d.hxx>
#include <gp_Mat.hxx>
#include <gp_Ax3.hxx>
#include <gp_Ax2d.hxx>
#include <gp_Pln.hxx>
+74 -22
View File
@@ -29,9 +29,12 @@
#include <gp_Pnt2d.hxx>
#include <gp_Vec2d.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Mat.hxx>
#include <gp_Mat2d.hxx>
#include <gp_GTrsf.hxx>
#include <gp_GTrsf2d.hxx>
#include <gp_Trsf.hxx>
#include <gp_Trsf2d.hxx>
#include <gp_Mat.hxx>
#include <gp_Ax3.hxx>
#include <gp_Ax2d.hxx>
#include <gp_Pln.hxx>
@@ -75,37 +78,86 @@
#include <GProp_GProps.hxx>
#include <BRepGProp.hxx>
#include <BRepBuilderAPI_GTransform.hxx>
#include "../ifcgeom/IfcGeom.h"
bool IfcGeom::convert_openings(const Ifc2x3::IfcProduct::ptr entity,
const Ifc2x3::IfcRelVoidsElement::list& openings, TopoDS_Shape& result, const gp_Trsf& trsf2) {
bool IfcGeom::convert_openings(const Ifc2x3::IfcProduct::ptr entity, const Ifc2x3::IfcRelVoidsElement::list& openings,
const ShapeList& entity_shapes, const gp_Trsf& entity_trsf, ShapeList& cut_shapes) {
// Iterate over IfcOpeningElements
IfcGeom::ShapeList opening_shapes;
unsigned int last_size = 0;
for ( Ifc2x3::IfcRelVoidsElement::it it = openings->begin(); it != openings->end(); ++ it ) {
Ifc2x3::IfcRelVoidsElement::ptr v = *it;
Ifc2x3::IfcFeatureElementSubtraction::ptr fes = v->RelatedOpeningElement();
if ( fes->is(Ifc2x3::Type::IfcOpeningElement) ) {
gp_Trsf trsf;
IfcGeom::convert(fes->ObjectPlacement(),trsf);
trsf.PreMultiply(trsf2.Inverted());
// Convert the IfcRepresentation of the IfcOpeningElement
gp_Trsf opening_trsf;
IfcGeom::convert(fes->ObjectPlacement(),opening_trsf);
// Move the opening into the coordinate system of the IfcProduct
opening_trsf.PreMultiply(entity_trsf.Inverted());
Ifc2x3::IfcProductRepresentation::ptr prodrep = fes->Representation();
if ( prodrep->is(Ifc2x3::Type::IfcProductDefinitionShape) ) {
Ifc2x3::IfcProductDefinitionShape::ptr pds = reinterpret_pointer_cast<Ifc2x3::IfcProductRepresentation,Ifc2x3::IfcProductDefinitionShape>(prodrep);
Ifc2x3::IfcRepresentation::list reps = pds->Representations();
for ( Ifc2x3::IfcRepresentation::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) {
TopoDS_Shape s;
IfcGeom::convert_shape(*it2,s);
s.Move(trsf);
const float opening_volume = shape_volume(s);
if ( opening_volume <= ALMOST_ZERO )
Ifc::LogMessage("warning","Empty solid for:",fes->entity);
const float original_shape_volume = shape_volume(result);
result = BRepAlgoAPI_Cut(result,s);
const float volume_after_subtraction = shape_volume(result);
if ( ALMOST_THE_SAME(original_shape_volume,volume_after_subtraction) )
Ifc::LogMessage("warning","Warning subtraction yields unchanged volume:",entity->entity);
}
Ifc2x3::IfcRepresentation::list reps = prodrep->Representations();
for ( Ifc2x3::IfcRepresentation::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) {
IfcGeom::convert_shapes(*it2,opening_shapes);
}
const unsigned int current_size = (const unsigned int) opening_shapes.size();
for ( unsigned int i = last_size; i < current_size; ++ i ) {
opening_shapes[i].first->PreMultiply(opening_trsf);
}
last_size = current_size;
}
}
// Iterate over the shapes of the IfcProduct
for ( IfcGeom::ShapeList::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
const TopoDS_Shape& entity_shape_unlocated = *(it3->second);
const gp_GTrsf& entity_shape_gtrsf = *(it3->first);
TopoDS_Shape entity_shape;
if ( entity_shape_gtrsf.Form() == gp_Other ) {
Ifc::LogMessage("warning","Applying non uniform transformation to:",entity->entity);
entity_shape = BRepBuilderAPI_GTransform(entity_shape_unlocated,entity_shape_gtrsf,true).Shape();
} else {
entity_shape = entity_shape_unlocated.Moved(entity_shape_gtrsf.Trsf());
}
// Iterate over the shapes of the IfcOpeningElements
for ( IfcGeom::ShapeList::const_iterator it4 = opening_shapes.begin(); it4 != opening_shapes.end(); ++ it4 ) {
const TopoDS_Shape& opening_shape_unlocated = *(it4->second);
const gp_GTrsf& opening_shape_gtrsf = *(it4->first);
if ( opening_shape_gtrsf.Form() == gp_Other ) {
Ifc::LogMessage("warning","Applying non uniform transformation to opening of:",entity->entity);
}
const TopoDS_Shape& opening_shape = opening_shape_gtrsf.Form() == gp_Other
? BRepBuilderAPI_GTransform(opening_shape_unlocated,opening_shape_gtrsf,true).Shape()
: opening_shape_unlocated.Moved(opening_shape_gtrsf.Trsf());
const float opening_volume = shape_volume(opening_shape);
if ( opening_volume <= ALMOST_ZERO )
Ifc::LogMessage("warning","Empty opening for:",entity->entity);
const float original_shape_volume = shape_volume(entity_shape);
entity_shape = BRepAlgoAPI_Cut(entity_shape,opening_shape);
const float volume_after_subtraction = shape_volume(entity_shape);
if ( ALMOST_THE_SAME(original_shape_volume,volume_after_subtraction) )
Ifc::LogMessage("warning","Warning subtraction yields unchanged volume:",entity->entity);
}
cut_shapes.push_back(IfcGeom::LocationShape(new gp_GTrsf(),new TopoDS_Shape(entity_shape)));
}
// Delete references to opening transformations, but keep shapes in the cache
for ( IfcGeom::ShapeList::const_iterator it5 = opening_shapes.begin(); it5 != opening_shapes.end(); ++ it5 ) {
delete it5->first;
}
return true;
}
bool IfcGeom::convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face) {
+50 -1
View File
@@ -29,9 +29,12 @@
#include <gp_Pnt2d.hxx>
#include <gp_Vec2d.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Mat.hxx>
#include <gp_Mat2d.hxx>
#include <gp_GTrsf.hxx>
#include <gp_GTrsf2d.hxx>
#include <gp_Trsf.hxx>
#include <gp_Trsf2d.hxx>
#include <gp_Mat.hxx>
#include <gp_Ax3.hxx>
#include <gp_Ax2d.hxx>
#include <gp_Pln.hxx>
@@ -160,6 +163,52 @@ bool IfcGeom::convert(const Ifc2x3::IfcCartesianTransformationOperator2D::ptr l,
CACHE(IfcCartesianTransformationOperator2D,l,trsf)
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcCartesianTransformationOperator3DnonUniform::ptr l, gp_GTrsf& gtrsf) {
IN_CACHE(IfcCartesianTransformationOperator3DnonUniform,l,gp_GTrsf,gtrsf)
gp_Trsf trsf;
gp_Pnt origin;
IfcGeom::convert(l->LocalOrigin(),origin);
gp_Dir axis1 (1.,0.,0.);
gp_Dir axis2 (0.,1.,0.);
gp_Dir axis3;
if ( l->hasAxis1() ) IfcGeom::convert(l->Axis1(),axis1);
if ( l->hasAxis2() ) IfcGeom::convert(l->Axis2(),axis2);
if ( l->hasAxis3() ) IfcGeom::convert(l->Axis3(),axis3);
else axis3 = axis1.Crossed(axis2);
gp_Ax3 ax3 (origin,axis3,axis1);
if ( axis2.Dot(ax3.YDirection()) < 0 ) ax3.YReverse();
trsf.SetTransformation(ax3);
trsf.Invert();
const float scale1 = l->hasScale() ? l->Scale() : 1.0f;
const float scale2 = l->hasScale2() ? l->Scale2() : scale1;
const float scale3 = l->hasScale3() ? l->Scale3() : scale1;
gtrsf = gp_GTrsf();
gtrsf.SetValue(1,1,scale1);
gtrsf.SetValue(2,2,scale2);
gtrsf.SetValue(3,3,scale3);
gtrsf.Multiply(trsf);
CACHE(IfcCartesianTransformationOperator3DnonUniform,l,gtrsf)
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcCartesianTransformationOperator2DnonUniform::ptr l, gp_GTrsf2d& gtrsf) {
IN_CACHE(IfcCartesianTransformationOperator2DnonUniform,l,gp_GTrsf2d,gtrsf)
gp_Trsf2d trsf;
gp_Pnt origin;
IfcGeom::convert(l->LocalOrigin(),origin);
gp_Dir axis1 (1.,0.,0.);
if ( l->hasAxis1() ) IfcGeom::convert(l->Axis1(),axis1);
const gp_Ax2d ax2d (gp_Pnt2d(origin.X(),origin.Y()),gp_Dir2d(axis1.X(),axis1.Y()));
trsf.SetTransformation(ax2d);
trsf.Invert();
const float scale1 = l->hasScale() ? l->Scale() : 1.0f;
const float scale2 = l->hasScale2() ? l->Scale2() : scale1;
gtrsf = gp_GTrsf2d();
gtrsf.SetValue(1,1,scale1);
gtrsf.SetValue(2,2,scale2);
gtrsf.Multiply(trsf);
CACHE(IfcCartesianTransformationOperator2DnonUniform,l,gtrsf)
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcPlane::ptr pln, gp_Pln& plane) {
IN_CACHE(IfcPlane,pln,gp_Pln,plane)
Ifc2x3::IfcAxis2Placement3D::ptr l = pln->Position();
+101 -82
View File
@@ -19,7 +19,12 @@
#include <map>
#include <gp_Mat.hxx>
#include <gp_Mat2d.hxx>
#include <gp_GTrsf.hxx>
#include <gp_GTrsf2d.hxx>
#include <gp_Trsf.hxx>
#include <gp_Trsf2d.hxx>
#include <TopoDS_Compound.hxx>
#include <BRep_Builder.hxx>
#include <BRepTools.hxx>
@@ -38,7 +43,7 @@
#include "../ifcgeom/IfcGeom.h"
// Welds vertices that belong to different faces
int IfcGeomObjects::IfcMesh::addvert(gp_Pnt p) {
int IfcGeomObjects::IfcMesh::addvert(const gp_XYZ& p) {
const float X = (float)p.X();const float Y = (float)p.Y();const float Z = (float)p.Z();
const VertKey key = VertKey(X,std::pair<float,float>(Y,Z));
VertKeyMap::const_iterator it = welds.find(key);
@@ -51,54 +56,62 @@ int IfcGeomObjects::IfcMesh::addvert(gp_Pnt p) {
return i;
}
IfcGeomObjects::IfcMesh::IfcMesh(int i, TopoDS_Shape s) {
IfcGeomObjects::IfcMesh::IfcMesh(int i, const IfcGeom::ShapeList& shapes) {
id = i;
// Triangulate the shape
try {
BRepTools::Clean(s);
BRepMesh::Mesh(s,0.001f);
} catch(...) {
Ifc::LogMessage("Error","Failed to triangulate mesh:",Ifc::EntityById(i)->entity);
return;
}
TopExp_Explorer exp;
for ( IfcGeom::ShapeList::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
// Iterates over the faces of the shape
for ( exp.Init(s,TopAbs_FACE); exp.More(); exp.Next() ) {
TopoDS_Face face = TopoDS::Face(exp.Current());
TopLoc_Location loc;
Handle_Poly_Triangulation tri = BRep_Tool::Triangulation(face,loc);
const TopoDS_Shape& s = *(*it).second;
const gp_GTrsf& trsf = *(*it).first;
if ( ! tri.IsNull() ) {
// Triangulate the shape
try {
//BRepTools::Clean(s);
BRepMesh::Mesh(s,0.001f);
} catch(...) {
Ifc::LogMessage("Error","Failed to triangulate mesh:",Ifc::EntityById(i)->entity);
continue;
}
TopExp_Explorer exp;
// Iterates over the faces of the shape
for ( exp.Init(s,TopAbs_FACE); exp.More(); exp.Next() ) {
TopoDS_Face face = TopoDS::Face(exp.Current());
TopLoc_Location loc;
Handle_Poly_Triangulation tri = BRep_Tool::Triangulation(face,loc);
if ( ! tri.IsNull() ) {
// Keep track of the number of times an edge is used
// Manifold edges (i.e. edges used twice) are deemed invisible
std::map<std::pair<int,int>,int> edgecount;
std::vector<std::pair<int,int> > edges_temp;
// Keep track of the number of times an edge is used
// Manifold edges (i.e. edges used twice) are deemed invisible
std::map<std::pair<int,int>,int> edgecount;
std::vector<std::pair<int,int> > edges_temp;
const TColgp_Array1OfPnt& nodes = tri->Nodes();
std::map<int,int> dict;
for( int i = 1; i <= nodes.Length(); ++ i ) {
dict[i] = addvert(nodes(i).Transformed(loc));
}
const TColgp_Array1OfPnt& nodes = tri->Nodes();
std::map<int,int> dict;
for( int i = 1; i <= nodes.Length(); ++ i ) {
gp_XYZ xyz = nodes(i).Transformed(loc).XYZ();
trsf.Transforms(xyz);
dict[i] = addvert(xyz);
}
const Poly_Array1OfTriangle& triangles = tri->Triangles();
for( int i = 1; i <= triangles.Length(); ++ i ) {
int n1,n2,n3;
if ( face.Orientation() == TopAbs_REVERSED )
triangles(i).Get(n3,n2,n1);
else triangles(i).Get(n1,n2,n3);
faces.push_back(dict[n1]);
faces.push_back(dict[n2]);
faces.push_back(dict[n3]);
const Poly_Array1OfTriangle& triangles = tri->Triangles();
for( int i = 1; i <= triangles.Length(); ++ i ) {
int n1,n2,n3;
if ( face.Orientation() == TopAbs_REVERSED )
triangles(i).Get(n3,n2,n1);
else triangles(i).Get(n1,n2,n3);
faces.push_back(dict[n1]);
faces.push_back(dict[n2]);
faces.push_back(dict[n3]);
addedge(n1,n2,edgecount,edges_temp);
addedge(n2,n3,edgecount,edges_temp);
addedge(n3,n1,edgecount,edges_temp);
}
for ( std::vector<std::pair<int,int> >::const_iterator it = edges_temp.begin(); it != edges_temp.end(); ++it ) {
edges.push_back(edgecount[*it]==1);
addedge(n1,n2,edgecount,edges_temp);
addedge(n2,n3,edgecount,edges_temp);
addedge(n3,n1,edgecount,edges_temp);
}
for ( std::vector<std::pair<int,int> >::const_iterator it = edges_temp.begin(); it != edges_temp.end(); ++it ) {
edges.push_back(edgecount[*it]==1);
}
}
}
}
@@ -138,14 +151,8 @@ IfcGeomObjects::IfcGeomObject::IfcGeomObject(int my_id,
Ifc2x3::IfcShapeRepresentation::list shapereps;
Ifc2x3::IfcShapeRepresentation::it outer;
// The triangulated shape is stored globally because it can be used by multiple IfcBuildingElements
IfcGeomObjects::IfcMesh* shape;
// The compound shape is stored globally because multiple IfcShapeRepresentations
// can have IfcBuildingElements with different IfcOpeningElements
TopoDS_Shape shapes;
// The object is fetched beforehand to be positive an entity actually exists
IfcGeomObjects::IfcGeomObject* currentGeomObj;
IfcGeomObjects::IfcGeomObject* current_geom_obj;
// A container and iterator for IfcBuildingElements for the current IfcShapeRepresentation referenced by *outer
Ifc2x3::IfcProduct::list entities;
@@ -157,9 +164,6 @@ int total;
// Move the the next IfcShapeRepresentation
void _nextShape() {
if ( shape ) delete shape;
shapes.Nullify();
shape = 0;
entities.reset();
++ outer;
++ done;
@@ -215,13 +219,15 @@ IfcGeomObjects::IfcGeomObject* _get() {
_nextShape();
continue;
}
// Has the TopoDS_Shape been created for this representation?
if ( shapes.IsNull() ) {
if ( !IfcGeom::convert_shape(shaperep,shapes) ) {
_nextShape();
continue;
}
IfcGeomObjects::IfcMesh* shape;
IfcGeom::ShapeList shapes;
if ( !IfcGeom::convert_shapes(shaperep,shapes) ) {
_nextShape();
continue;
}
Ifc2x3::IfcProduct::ptr ifc_product = *inner;
int parent_id = -1;
const std::string name = ifc_product->hasName() ? ifc_product->Name() : "";
@@ -270,42 +276,55 @@ IfcGeomObjects::IfcGeomObject* _get() {
}
}
if ( (openings && openings->Size()) || use_world_coords ) {
if ( shape ) delete shape;
TopoDS_Shape temp_shape = shapes.Moved(gp_Trsf());
if ( openings && openings->Size() ) {
IfcGeom::ShapeList opened_shapes;
try {
if (openings && openings->Size()) {
IfcGeom::convert_openings(ifc_product,openings,temp_shape,trsf);
}
} catch( IfcParse::IfcException& e ) {
Ifc::LogMessage("Error",e.what(),ifc_product->entity);
IfcGeom::convert_openings(ifc_product,openings,shapes,trsf,opened_shapes);
} catch(...) {
Ifc::LogMessage("Error","Error processing openings for:",ifc_product->entity);
}
if ( use_world_coords ) {
shape = new IfcGeomObjects::IfcMesh(shaperep->entity->id(),temp_shape.Moved(trsf));
for ( IfcGeom::ShapeList::const_iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++ it ) {
it->first->PreMultiply(trsf);
}
trsf = gp_Trsf();
} else {
shape = new IfcGeomObjects::IfcMesh(shaperep->entity->id(),temp_shape);
}
} else if ( ! shape ) {
shape = new IfcGeomObjects::IfcMesh(shaperep->entity->id(),opened_shapes);
for ( IfcGeom::ShapeList::const_iterator it = opened_shapes.begin(); it != opened_shapes.end(); ++ it ) {
delete it->first;
delete it->second;
}
} else if ( use_world_coords ) {
for ( IfcGeom::ShapeList::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
it->first->PreMultiply(trsf);
}
trsf = gp_Trsf();
shape = new IfcGeomObjects::IfcMesh(shaperep->entity->id(),shapes);
} else {
shape = new IfcGeomObjects::IfcMesh(shaperep->entity->id(),shapes);
}
return new IfcGeomObjects::IfcGeomObject(ifc_product->entity->id(), parent_id, name,
Ifc2x3::Type::ToString(ifc_product->type()), guid, trsf, shape);
}
IfcGeomObjects::IfcGeomObject* geom_obj = new IfcGeomObjects::IfcGeomObject(ifc_product->entity->id(), parent_id, name,
Ifc2x3::Type::ToString(ifc_product->type()), guid, trsf, shape);
for ( IfcGeom::ShapeList::const_iterator it = shapes.begin(); it != shapes.end(); ++ it ) {
delete it->first;
}
return geom_obj;
}
}
bool IfcGeomObjects::Next() {
if ( current_geom_obj ) {
delete current_geom_obj->mesh;
delete current_geom_obj;
}
if ( entities ) {
++inner;
}
delete currentGeomObj;
currentGeomObj = _get();
if ( ! currentGeomObj ) {
delete shape;
current_geom_obj = _get();
if ( ! current_geom_obj ) {
return false;
} else {
return true;
@@ -362,7 +381,7 @@ const IfcGeomObjects::IfcObject* IfcGeomObjects::GetObject(int id) {
return ifc_object;
}
const IfcGeomObjects::IfcGeomObject* IfcGeomObjects::Get() {
return currentGeomObj;
return current_geom_obj;
}
bool IfcGeomObjects::Init(const char* fn, bool world_coords) {
return IfcGeomObjects::Init(fn, world_coords, 0, 0);
@@ -377,9 +396,9 @@ bool IfcGeomObjects::Init(const char* fn, bool world_coords, std::ostream* log1,
outer = shapereps->begin();
entities.reset();
currentGeomObj = _get();
current_geom_obj = _get();
if ( ! currentGeomObj ) return false;
if ( ! current_geom_obj ) return false;
done = 0;
total = shapereps->Size();
@@ -395,9 +414,9 @@ bool IfcGeomObjects::Init(std::istream& f, int len, bool world_coords, std::ostr
outer = shapereps->begin();
entities.reset();
currentGeomObj = _get();
current_geom_obj = _get();
if ( ! currentGeomObj ) return false;
if ( ! current_geom_obj ) return false;
done = 0;
total = shapereps->Size();
+9 -4
View File
@@ -57,9 +57,14 @@
#include <vector>
#include <algorithm>
#include <gp_Mat.hxx>
#include <gp_Mat2d.hxx>
#include <gp_GTrsf.hxx>
#include <gp_GTrsf2d.hxx>
#include <gp_Trsf.hxx>
#include <gp_Pnt.hxx>
#include <TopoDS.hxx>
#include <gp_Trsf2d.hxx>
#include "../ifcgeom/IfcGeom.h"
namespace IfcGeomObjects {
@@ -77,9 +82,9 @@ namespace IfcGeomObjects {
std::vector<int> edges;
VertKeyMap welds;
IfcMesh(int i, TopoDS_Shape s);
IfcMesh(int i, const IfcGeom::ShapeList& s);
private:
int addvert(gp_Pnt p);
int addvert(const gp_XYZ& p);
inline void addedge(int n1, int n2, std::map<std::pair<int,int>,int>& edgecount, std::vector<std::pair<int,int> >& edges_temp) {
const Edge e = Edge( (std::min)(n1,n2),(std::max)(n1,n2) );
if ( edgecount.find(e) == edgecount.end() ) edgecount[e] = 1;
+53 -47
View File
@@ -29,9 +29,12 @@
#include <gp_Pnt2d.hxx>
#include <gp_Vec2d.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Mat.hxx>
#include <gp_Mat2d.hxx>
#include <gp_GTrsf.hxx>
#include <gp_GTrsf2d.hxx>
#include <gp_Trsf.hxx>
#include <gp_Trsf2d.hxx>
#include <gp_Mat.hxx>
#include <gp_Ax3.hxx>
#include <gp_Ax2d.hxx>
#include <gp_Pln.hxx>
@@ -88,21 +91,22 @@ bool IfcGeom::convert(const Ifc2x3::IfcExtrudedAreaSolid::ptr l, TopoDS_Shape& s
shape.Move(trsf);
return ! shape.IsNull();
}
bool IfcGeom::convert(const Ifc2x3::IfcFacetedBrep::ptr l, TopoDS_Shape& shape) {
return IfcGeom::convert_shape(l->Outer(),shape);
bool IfcGeom::convert(const Ifc2x3::IfcFacetedBrep::ptr l, ShapeList& shape) {
TopoDS_Shape s;
if ( const TopoDS_Shape* shape_id = IfcGeom::convert_shape(l->Outer(),s) ) {
shape.push_back(LocationShape(new gp_GTrsf(),shape_id));
return true;
}
return false;
}
bool IfcGeom::convert(const Ifc2x3::IfcFaceBasedSurfaceModel::ptr l, TopoDS_Shape& shape) {
bool IfcGeom::convert(const Ifc2x3::IfcFaceBasedSurfaceModel::ptr l, ShapeList& shapes) {
Ifc2x3::IfcConnectedFaceSet::list facesets = l->FbsmFaces();
BRep_Builder builder;
TopoDS_Compound c;
builder.MakeCompound(c);
for( Ifc2x3::IfcConnectedFaceSet::it it = facesets->begin(); it != facesets->end(); ++ it ) {
TopoDS_Shape s;
if ( IfcGeom::convert_shape(*it,s) ) {
builder.Add(c,s);
if ( const TopoDS_Shape* shape_id = IfcGeom::convert_shape(*it,s) ) {
shapes.push_back(LocationShape(new gp_GTrsf(),shape_id));
}
}
shape = c;
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcHalfSpaceSolid::ptr l, TopoDS_Shape& shape) {
@@ -128,24 +132,20 @@ bool IfcGeom::convert(const Ifc2x3::IfcPolygonalBoundedHalfSpace::ptr l, TopoDS_
if ( ! IfcGeom::convert_wire(l->PolygonalBoundary(),wire) || ! wire.Closed() ) return false;
gp_Trsf trsf;
convert(l->Position(),trsf);
TopoDS_Shape extrusion = BRepPrimAPI_MakePrism(BRepBuilderAPI_MakeFace(wire),gp_Vec(0,0,20000.0));
gp_Trsf down; down.SetTranslation(gp_Vec(0,0,-10000.0));
TopoDS_Shape extrusion = BRepPrimAPI_MakePrism(BRepBuilderAPI_MakeFace(wire),gp_Vec(0,0,200.0));
gp_Trsf down; down.SetTranslation(gp_Vec(0,0,-100.0));
extrusion.Move(down*trsf);
shape = BRepAlgoAPI_Cut(extrusion,halfspace);
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcShellBasedSurfaceModel::ptr l, TopoDS_Shape& shape) {
bool IfcGeom::convert(const Ifc2x3::IfcShellBasedSurfaceModel::ptr l, ShapeList& shapes) {
IfcUtil::IfcAbstractSelect::list shells = l->SbsmBoundary();
BRep_Builder builder;
TopoDS_Compound c;
builder.MakeCompound(c);
for( IfcUtil::IfcAbstractSelect::it it = shells->begin(); it != shells->end(); ++ it ) {
TopoDS_Shape s;
if ( IfcGeom::convert_shape(*it,s) ) {
builder.Add(c,s);
if ( const TopoDS_Shape* shape_id = IfcGeom::convert_shape(*it,s) ) {
shapes.push_back(LocationShape(new gp_GTrsf(),shape_id));
}
}
shape = c;
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcBooleanClippingResult::ptr l, TopoDS_Shape& shape) {
@@ -200,47 +200,53 @@ bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr l, TopoDS_Shape& sh
} catch(...) {}
return true;
}
bool IfcGeom::convert(const Ifc2x3::IfcMappedItem::ptr l, TopoDS_Shape& shape) {
gp_Trsf trsf1;
bool IfcGeom::convert(const Ifc2x3::IfcMappedItem::ptr l, ShapeList& shapes) {
gp_GTrsf gtrsf;
Ifc2x3::IfcCartesianTransformationOperator::ptr transform = l->MappingTarget();
if ( transform->is(Ifc2x3::Type::IfcCartesianTransformationOperator2DnonUniform) ||
transform->is(Ifc2x3::Type::IfcCartesianTransformationOperator3DnonUniform) ) {
// Not implemented
return false;
} else if ( transform->is(Ifc2x3::Type::IfcCartesianTransformationOperator3D) ) {
if ( transform->is(Ifc2x3::Type::IfcCartesianTransformationOperator3DnonUniform) ) {
IfcGeom::convert(reinterpret_pointer_cast<Ifc2x3::IfcCartesianTransformationOperator,
Ifc2x3::IfcCartesianTransformationOperator3D>(transform),trsf1);
Ifc2x3::IfcCartesianTransformationOperator3DnonUniform>(transform),gtrsf);
} else if ( transform->is(Ifc2x3::Type::IfcCartesianTransformationOperator2DnonUniform) ) {
return false;
} else if ( transform->is(Ifc2x3::Type::IfcCartesianTransformationOperator3D) ) {
gp_Trsf trsf;
IfcGeom::convert(reinterpret_pointer_cast<Ifc2x3::IfcCartesianTransformationOperator,
Ifc2x3::IfcCartesianTransformationOperator3D>(transform),trsf);
gtrsf = trsf;
} else if ( transform->is(Ifc2x3::Type::IfcCartesianTransformationOperator2D) ) {
gp_Trsf2d trsf1_2d;
gp_Trsf2d trsf_2d;
IfcGeom::convert(reinterpret_pointer_cast<Ifc2x3::IfcCartesianTransformationOperator,
Ifc2x3::IfcCartesianTransformationOperator2D>(transform),trsf1_2d);
trsf1 = trsf1_2d;
Ifc2x3::IfcCartesianTransformationOperator2D>(transform),trsf_2d);
gtrsf = (gp_Trsf) trsf_2d;
}
Ifc2x3::IfcRepresentationMap::ptr map = l->MappingSource();
Ifc2x3::IfcAxis2Placement placement = map->MappingOrigin();
gp_Trsf trsf2;
gp_Trsf trsf;
if (placement->is(Ifc2x3::Type::IfcAxis2Placement3D)) {
IfcGeom::convert((Ifc2x3::IfcAxis2Placement3D*)placement,trsf2);
IfcGeom::convert((Ifc2x3::IfcAxis2Placement3D*)placement,trsf);
} else {
gp_Trsf2d trsf2_2d;
IfcGeom::convert((Ifc2x3::IfcAxis2Placement2D*)placement,trsf2_2d);
trsf2 = trsf2_2d;
gp_Trsf2d trsf_2d;
IfcGeom::convert((Ifc2x3::IfcAxis2Placement2D*)placement,trsf_2d);
trsf = trsf_2d;
}
if ( ! IfcGeom::convert_shape(map->MappedRepresentation(),shape) ) return false;
shape = shape.Moved(trsf2 * trsf1);
return !shape.IsNull();
gtrsf.Multiply(trsf);
const unsigned int previous_size = (const unsigned int) shapes.size();
bool b = IfcGeom::convert_shapes(map->MappedRepresentation(),shapes);
for ( unsigned int i = previous_size; i < shapes.size(); ++ i ) {
shapes[i].first->Multiply(gtrsf);
}
return b;
}
bool IfcGeom::convert(const Ifc2x3::IfcShapeRepresentation::ptr l, TopoDS_Shape& shape) {
bool IfcGeom::convert(const Ifc2x3::IfcShapeRepresentation::ptr l, ShapeList& shapes) {
Ifc2x3::IfcRepresentationItem::list items = l->Items();
if ( ! items->Size() ) return false;
BRep_Builder builder;
TopoDS_Compound c;
builder.MakeCompound(c);
for ( Ifc2x3::IfcRepresentationItem::it it = items->begin(); it != items->end(); ++ it ) {
TopoDS_Shape s;
if ( ! IfcGeom::convert_shape(*it,s)) continue;
builder.Add(c,s);
if ( IfcGeom::is_shape_collection(*it) ) IfcGeom::convert_shapes(*it,shapes);
else {
TopoDS_Shape s;
if ( const TopoDS_Shape* shape_id = IfcGeom::convert_shape(*it,s))
shapes.push_back(LocationShape(new gp_GTrsf(),shape_id));
}
}
shape = c;
return !shape.IsNull();
return true;
}
+5 -2
View File
@@ -29,9 +29,12 @@
#include <gp_Pnt2d.hxx>
#include <gp_Vec2d.hxx>
#include <gp_Dir2d.hxx>
#include <gp_Mat.hxx>
#include <gp_Mat2d.hxx>
#include <gp_GTrsf.hxx>
#include <gp_GTrsf2d.hxx>
#include <gp_Trsf.hxx>
#include <gp_Trsf2d.hxx>
#include <gp_Mat.hxx>
#include <gp_Ax3.hxx>
#include <gp_Ax2d.hxx>
#include <gp_Pln.hxx>
@@ -89,7 +92,7 @@ bool IfcGeom::convert(const Ifc2x3::IfcCompositeCurve::ptr l, TopoDS_Wire& wire)
}
if ( ! (*it)->SameSense() ) wire2.Reverse();
ShapeFix_ShapeTolerance FTol;
FTol.SetTolerance(wire2, 0.001, TopAbs_WIRE);
FTol.SetTolerance(wire2, 0.0001, TopAbs_WIRE);
/*if ( it != segments->begin() ) {
TopExp_Explorer exp (wire2,TopAbs_VERTEX);
const TopoDS_Vertex& first_vertex = TopoDS::Vertex(exp.Current());
+14 -5
View File
@@ -31,14 +31,23 @@ namespace IfcGeom {
using namespace Ifc2x3;
using namespace IfcUtil;
bool IfcGeom::convert_shape(const IfcBaseClass* l, TopoDS_Shape& r) {
const unsigned int id = l->entity->id();
std::map<int,TopoDS_Shape>::const_iterator it = Cache::Shape.find(id);
if ( it != Cache::Shape.end() ) { r = it->second; return true; }
#include "IfcRegisterConvertShape.h"
bool IfcGeom::convert_shapes(const IfcBaseClass* l, ShapeList& r) {
#include "IfcRegisterConvertShapes.h"
Ifc::LogMessage("Error","No operation defined for:",l->entity);
return false;
}
bool IfcGeom::is_shape_collection(const IfcBaseClass* l) {
#include "IfcRegisterIsShapeCollection.h"
return false;
}
const TopoDS_Shape* IfcGeom::convert_shape(const IfcBaseClass* l, TopoDS_Shape& r) {
const unsigned int id = l->entity->id();
std::map<int,TopoDS_Shape>::const_iterator it = Cache::Shape.find(id);
if ( it != Cache::Shape.end() ) { r = it->second; return &(it->second); }
#include "IfcRegisterConvertShape.h"
Ifc::LogMessage("Error","No operation defined for:",l->entity);
return 0;
}
bool IfcGeom::convert_wire(const IfcBaseClass* l, TopoDS_Wire& r) {
#include "IfcRegisterConvertWire.h"
Ifc::LogMessage("Error","No operation defined for:",l->entity);
+12 -5
View File
@@ -31,6 +31,10 @@
#include <gp_Pnt.hxx>
#include <gp_Pln.hxx>
#include <gp_Dir.hxx>
#include <gp_Mat.hxx>
#include <gp_Mat2d.hxx>
#include <gp_GTrsf.hxx>
#include <gp_GTrsf2d.hxx>
#include <gp_Trsf.hxx>
#include <gp_Trsf2d.hxx>
@@ -38,14 +42,15 @@
using namespace Ifc2x3;
SHAPES(IfcShellBasedSurfaceModel);
SHAPES(IfcFaceBasedSurfaceModel);
SHAPES(IfcShapeRepresentation);
SHAPES(IfcMappedItem);
SHAPES(IfcFacetedBrep);
SHAPE(IfcExtrudedAreaSolid);
SHAPE(IfcConnectedFaceSet);
SHAPE(IfcFacetedBrep);
SHAPE(IfcShellBasedSurfaceModel);
SHAPE(IfcFaceBasedSurfaceModel);
SHAPE(IfcBooleanClippingResult);
SHAPE(IfcShapeRepresentation);
SHAPE(IfcMappedItem);
SHAPE(IfcPolygonalBoundedHalfSpace);
SHAPE(IfcHalfSpaceSolid);
@@ -72,6 +77,8 @@ CLASS(IfcCartesianPoint,gp_Pnt);
CLASS(IfcDirection,gp_Dir);
CLASS(IfcAxis2Placement2D,gp_Trsf2d);
CLASS(IfcAxis2Placement3D,gp_Trsf);
CLASS(IfcCartesianTransformationOperator2DnonUniform,gp_GTrsf2d);
CLASS(IfcCartesianTransformationOperator3DnonUniform,gp_GTrsf);
CLASS(IfcCartesianTransformationOperator2D,gp_Trsf2d);
CLASS(IfcCartesianTransformationOperator3D,gp_Trsf);
CLASS(IfcObjectPlacement,gp_Trsf);
+2 -2
View File
@@ -3,8 +3,8 @@
if ( l->is(T::Class()) ) { \
try { \
if ( convert((T*)l,r) ) { \
Cache::Shape[l->entity->id()] = r; \
return true; \
Cache::Shape[id] = r; \
return &(Cache::Shape[id]); \
} \
} catch(...) { } \
Ifc::LogMessage("Error","Failed to convert:",l->entity); \
+8
View File
@@ -0,0 +1,8 @@
#include "IfcRegisterUndef.h"
#define SHAPES(T) \
if ( l->is(T::Class()) ) { \
return IfcGeom::convert((T*)l,r); \
}
#include "IfcRegisterDef.h"
#include "IfcRegister.h"
+3
View File
@@ -1,3 +1,6 @@
#ifndef SHAPES
#define SHAPES(T)
#endif
#ifndef SHAPE
#define SHAPE(T)
#endif
+1
View File
@@ -1,5 +1,6 @@
#include "IfcRegisterUndef.h"
#define CLASS(T,V) bool convert(const T::ptr L, V& r);
#define SHAPES(T) CLASS(T,ShapeList)
#define SHAPE(T) CLASS(T,TopoDS_Shape)
#define WIRE(T) CLASS(T,TopoDS_Wire)
#define FACE(T) CLASS(T,TopoDS_Face)
@@ -0,0 +1,6 @@
#include "IfcRegisterUndef.h"
#define SHAPES(T) \
if ( l->is(T::Class()) ) return true;
#include "IfcRegisterDef.h"
#include "IfcRegister.h"
+3
View File
@@ -1,3 +1,6 @@
#ifdef SHAPES
#undef SHAPES
#endif
#ifdef SHAPE
#undef SHAPE
#endif