- Parsing: support for nested types

- Parsing: some support for units
- Geometry: IfcCircleProfileDef, IfcCircleHollowProfileDef, IfcCompositeCurve, IfcTrimmedCurve, IfcCircle, IfcEllipse
This commit is contained in:
Thomas Krijnen
2011-06-13 07:23:09 +00:00
parent 7bd1a3e7e4
commit 93d7b8fba9
8 changed files with 385 additions and 79 deletions
+160 -24
View File
@@ -39,23 +39,27 @@
#include <gp_Ax3.hxx>
#include <gp_Ax2d.hxx>
#include <gp_Pln.hxx>
#include <gp_Circ.hxx>
#include <TColgp_Array1OfPnt.hxx>
#include <TColgp_Array1OfPnt2d.hxx>
#include <TColStd_Array1OfReal.hxx>
#include <TColStd_Array1OfInteger.hxx>
#include <Geom2d_BSplineCurve.hxx>
#include <Geom_BSplineCurve.hxx>
#include <Geom_Circle.hxx>
#include <Geom_Ellipse.hxx>
#include <Geom_TrimmedCurve.hxx>
#include <BRepOffsetAPI_Sewing.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>
#include <BRepBuilderAPI_MakeEdge.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepBuilderAPI_MakePolygon.hxx>
#include <BRepBuilderAPI_MakeVertex.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Face.hxx>
#include <TopExp_Explorer.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
#include <BRepBuilderAPI_MakeShell.hxx>
@@ -72,7 +76,7 @@
bool IfcGeom::convert(IfcSchema::ExtrudedAreaSolid* IfcExtrudedAreaSolid, TopoDS_Shape& shape) {
TopoDS_Face face;
if ( ! IfcGeom::convert_face(IfcExtrudedAreaSolid->Profile(),face) ) return false;
const float height = IfcExtrudedAreaSolid->Height() * Ifc::Scale;
const float height = IfcExtrudedAreaSolid->Height() * Ifc::LengthUnit;
gp_Trsf trsf;
convert((IfcSchema::Axis2Placement3D*) IfcExtrudedAreaSolid->Placement().get(),trsf);
@@ -98,7 +102,7 @@ bool IfcGeom::convert(IfcSchema::HalfSpaceSolid* IfcHalfSpaceSolid, TopoDS_Shape
gp_Pln pln;
IfcGeom::convert(IfcPlane,pln);
gp_Pnt pnt = pln.Location();
if ( !IfcHalfSpaceSolid->Flag() ^ (IfcHalfSpaceSolid->dt == IfcSchema::Enum::IfcPolygonalBoundedHalfSpace) ) pnt.Translate(pln.Axis().Direction());
if ( !IfcHalfSpaceSolid->Flag() != (IfcHalfSpaceSolid->dt == IfcSchema::Enum::IfcPolygonalBoundedHalfSpace) ) pnt.Translate(pln.Axis().Direction());
else pnt.Translate(-pln.Axis().Direction());
shape = BRepPrimAPI_MakeHalfSpace(BRepBuilderAPI_MakeFace(pln),pnt).Solid();
return true;
@@ -142,17 +146,19 @@ bool IfcGeom::convert(IfcSchema::BooleanClippingResult* IfcBooleanClippingResult
}
bool IfcGeom::convert(IfcSchema::ClosedShell* IfcClosedShell, TopoDS_Shape& shape) {
if ( ! IfcGeom::convert((IfcSchema::OpenShell*) IfcClosedShell,shape) ) return false;
ShapeFix_Solid solid;
solid.LimitTolerance(0.001);
shape = solid.SolidFromShell(TopoDS::Shell(shape));
try {
ShapeFix_Solid solid;
solid.LimitTolerance(0.01);
shape = solid.SolidFromShell(TopoDS::Shell(shape));
} catch(...) {}
return true;
}
bool IfcGeom::convert(IfcSchema::ConnectedFaceSet* IfcConnectedFaceSet, TopoDS_Shape& shape) {
return IfcGeom::convert((IfcSchema::OpenShell*) IfcConnectedFaceSet,shape);
return IfcGeom::convert((IfcSchema::ClosedShell*) IfcConnectedFaceSet,shape);
}
bool IfcGeom::convert(IfcSchema::OpenShell* IfcOpenShell, TopoDS_Shape& shape) {
BRepOffsetAPI_Sewing builder;
builder.SetTolerance(0.001);
builder.SetTolerance(0.01);
IfcEntities faces = IfcOpenShell->Faces();
bool facesAdded = false;
for( IfcParse::Entities::it it = faces->begin(); it != faces->end(); ++ it ) {
@@ -180,7 +186,7 @@ bool IfcGeom::convert(IfcSchema::Face* IfcFace, TopoDS_Face& face) {
BRepBuilderAPI_MakeFace mf(wire, false);
BRepBuilderAPI_FaceError er = mf.Error();
if ( er == BRepBuilderAPI_NotPlanar ) {
std::cout << "[Notice] Trying to fix non-planar face" << std::endl;
std::cout << "[Notice] Trying to fix non-planar face:" << std::endl << IfcFace->toString() << std::endl;
ShapeFix_ShapeTolerance FTol;
FTol.SetTolerance(wire, 0.01, TopAbs_WIRE);
mf = BRepBuilderAPI_MakeFace(wire, false);
@@ -206,11 +212,39 @@ bool IfcGeom::convert(IfcSchema::Face* IfcFace, TopoDS_Face& face) {
face = TopoDS::Face(sfs.Shape());
return true;
}
bool IfcGeom::convert(IfcSchema::CircleHollowProfileDef* IfcCircleHollowProfileDef, TopoDS_Face& face) {
const float r = IfcCircleHollowProfileDef->Radius() * Ifc::LengthUnit;
const float t = IfcCircleHollowProfileDef->WallThickness() * Ifc::LengthUnit;
if ( r == 0.0f || t == 0.0f ) {
std::cout << "[Notice] Skipping zero sized profile:" << std::endl << IfcCircleHollowProfileDef->toString() << std::endl;
return false;
}
gp_Trsf2d trsf;
IfcGeom::convert((IfcSchema::Axis2Placement2D*)IfcCircleHollowProfileDef->Placement().get(),trsf);
gp_Ax2 ax = gp_Ax2().Transformed(trsf);
BRepBuilderAPI_MakeWire outer;
Handle(Geom_Circle) outerCircle = new Geom_Circle(ax, r);
outer.Add(BRepBuilderAPI_MakeEdge(outerCircle));
BRepBuilderAPI_MakeFace mf(outer.Wire(), false);
BRepBuilderAPI_MakeWire inner;
Handle(Geom_Circle) innerCirlce = new Geom_Circle(ax, r-t);
inner.Add(BRepBuilderAPI_MakeEdge(innerCirlce));
mf.Add(inner);
ShapeFix_Shape sfs(mf.Face());
sfs.Perform();
face = TopoDS::Face(sfs.Shape());
return true;
}
bool IfcGeom::convert(IfcSchema::CartesianPoint* IfcCartesianPoint, gp_Pnt& p) {
if ( IfcCartesianPoint->arg(0)->count() == 3 )
p = gp_Pnt(IfcCartesianPoint->X() * Ifc::Scale,IfcCartesianPoint->Y() * Ifc::Scale,IfcCartesianPoint->Z() * Ifc::Scale);
p = gp_Pnt(IfcCartesianPoint->X() * Ifc::LengthUnit,IfcCartesianPoint->Y() * Ifc::LengthUnit,IfcCartesianPoint->Z() * Ifc::LengthUnit);
else
p = gp_Pnt(IfcCartesianPoint->X() * Ifc::Scale,IfcCartesianPoint->Y() * Ifc::Scale,0.0f);
p = gp_Pnt(IfcCartesianPoint->X() * Ifc::LengthUnit,IfcCartesianPoint->Y() * Ifc::LengthUnit,0.0f);
return true;
}
bool IfcGeom::convert(IfcSchema::Direction* IfcDirection, gp_Vec& v) {
@@ -226,7 +260,7 @@ bool IfcGeom::convert(IfcSchema::ArbitraryClosedProfileDef* IfcArbitraryClosedPr
bool IfcGeom::convert(IfcSchema::ArbitraryProfileDefWithVoids* IfcArbitraryProfileDefWithVoids, TopoDS_Face& face) {
TopoDS_Wire profile;
if ( ! IfcGeom::convert_wire(IfcArbitraryProfileDefWithVoids->Polyline(),profile) ) return false;
BRepBuilderAPI_MakeFace mf(profile, false);
BRepBuilderAPI_MakeFace mf(profile, false);
IfcEntities voids = IfcArbitraryProfileDefWithVoids->Voids();
for( IfcParse::Entities::it it = voids->begin(); it != voids->end(); ++ it ) {
TopoDS_Wire hole;
@@ -240,14 +274,14 @@ bool IfcGeom::convert(IfcSchema::ArbitraryProfileDefWithVoids* IfcArbitraryProfi
return true;
}
bool IfcGeom::convert(IfcSchema::RectangleProfileDef* IfcRectangleProfileDef,class TopoDS_Wire& wire) {
const float x = IfcRectangleProfileDef->Width() / 2.0f * Ifc::Scale;
const float y = IfcRectangleProfileDef->Height() / 2.0f * Ifc::Scale;
const float x = IfcRectangleProfileDef->Width() / 2.0f * Ifc::LengthUnit;
const float y = IfcRectangleProfileDef->Height() / 2.0f * Ifc::LengthUnit;
if ( x == 0.0f || y == 0.0f ) {
std::cout << "[Notice] Skipping zero sized profile" << std::endl;
std::cout << "[Notice] Skipping zero sized profile:" << std::endl << IfcRectangleProfileDef->toString() << std::endl;
return false;
}
gp_Trsf2d trsf;
IfcGeom::convert((IfcSchema::Axis2Placement2D*)IfcRectangleProfileDef->Placement().get(),trsf);
@@ -264,6 +298,105 @@ bool IfcGeom::convert(IfcSchema::RectangleProfileDef* IfcRectangleProfileDef,cla
wire = w.Wire();
return true;
}
bool IfcGeom::convert(IfcSchema::CircleProfileDef* IfcCircleProfileDef,class TopoDS_Wire& wire) {
const float r = IfcCircleProfileDef->Radius() * Ifc::LengthUnit;
if ( r == 0.0f ) {
std::cout << "[Notice] Skipping zero sized profile:" << std::endl << IfcCircleProfileDef->toString() << std::endl;
return false;
}
gp_Trsf2d trsf;
IfcGeom::convert((IfcSchema::Axis2Placement2D*)IfcCircleProfileDef->Placement().get(),trsf);
BRepBuilderAPI_MakeWire w;
#ifdef SEGMENTED_CIRCLE
TopoDS_Vertex previous,current,first;
for ( int i = 0; i <= Ifc::CircleSegments; i ++ ) {
const float theta = (float) PI * i / Ifc::CircleSegments * 2;
current = i == Ifc::CircleSegments ? first :
BRepBuilderAPI_MakeVertex ( gp_Pnt(r * sin(theta), r * cos(theta), 0.0f) ).Vertex();
if ( i ) {
w.Add(BRepBuilderAPI_MakeEdge(previous,current));
} else {
first = current;
}
previous = current;
}
#else
gp_Ax2 ax = gp_Ax2().Transformed(trsf);
Handle(Geom_Circle) circle = new Geom_Circle(ax, r);
TopoDS_Edge edge = BRepBuilderAPI_MakeEdge(circle);
w.Add(edge);
#endif
wire = w.Wire();
return true;
}
bool IfcGeom::convert(IfcSchema::CompositeCurve* IfcCompositeCurve, class TopoDS_Wire& wire) {
IfcEntities segments = IfcCompositeCurve->Segments();
BRepBuilderAPI_MakeWire w;
for( IfcParse::Entities::it it = segments->begin(); it != segments->end(); ++ it ) {
IfcSchema::CompositeCurveSegment* segment = (IfcSchema::CompositeCurveSegment*)(*it).get();
TopoDS_Wire wire2;
if ( ! IfcGeom::convert_wire(segment->ParentCurve(),wire2) ) continue;
ShapeFix_ShapeTolerance FTol;
FTol.SetTolerance(wire2, 0.01, TopAbs_WIRE);
w.Add(wire2);
if ( w.Error() != BRepBuilderAPI_WireDone ) {
std::cout << "[Error] Failed to join curve segments:" << std::endl << IfcCompositeCurve->toString() << std::endl;
return false;
}
}
wire = w.Wire();
return true;
}
bool IfcGeom::convert(IfcSchema::TrimmedCurve* IfcTrimmedCurve, class TopoDS_Wire& wire) {
IfcEntity basis = IfcTrimmedCurve->BasisCurve();
IfcEntity trim1 = *IfcTrimmedCurve->Trim1()->begin();
IfcEntity trim2 = *IfcTrimmedCurve->Trim2()->begin();
Handle(Geom_Curve) curve;
if ( ! IfcGeom::convert_curve(basis,curve) ) return false;
if ( trim1->dt != trim2->dt ) return false;
BRepBuilderAPI_MakeWire w;
if ( trim1->dt == IfcSchema::Enum::IfcParameterValue ) {
const float p1 = ((IfcSchema::ParameterValue*)trim1.get())->Value() * Ifc::PlaneAngleUnit;
const float p2 = ((IfcSchema::ParameterValue*)trim2.get())->Value() * Ifc::PlaneAngleUnit;
BRepBuilderAPI_MakeEdge e (curve,p1,p2);
w.Add(e.Edge());
} else if ( trim1->dt == IfcSchema::Enum::IfcCartesianPoint ) {
gp_Pnt v1,v2;
IfcGeom::convert((IfcSchema::CartesianPoint*)trim1.get(),v1);
IfcGeom::convert((IfcSchema::CartesianPoint*)trim2.get(),v2);
BRepBuilderAPI_MakeEdge e (curve,v1,v2);
w.Add(e.Edge());
}
wire = w.Wire();
return true;
}
bool IfcGeom::convert(IfcSchema::Circle* IfcCircle, Handle(Geom_Curve)& curve) {
const float r = IfcCircle->Radius() * Ifc::LengthUnit;
if ( r == 0.0f ) { return false; }
IfcSchema::Axis2Placement2D* placement = (IfcSchema::Axis2Placement2D*) IfcCircle->Placement().get();
gp_Trsf2d trsf;
IfcGeom::convert(placement, trsf);
gp_Ax2 ax = gp_Ax2().Transformed(trsf);
curve = new Geom_Circle(ax, r);
return true;
}
bool IfcGeom::convert(IfcSchema::Ellipse* IfcEllipse, Handle(Geom_Curve)& curve) {
float x = IfcEllipse->Axis1() * Ifc::LengthUnit;
float y = IfcEllipse->Axis2() * Ifc::LengthUnit;
if ( x == 0.0f || y == 0.0f || y > x ) { return false; }
IfcSchema::Axis2Placement2D* placement = (IfcSchema::Axis2Placement2D*) IfcEllipse->Placement().get();
gp_Trsf2d trsf;
IfcGeom::convert(placement, trsf);
gp_Ax2 ax;
ax = gp_Ax2().Transformed(trsf);
curve = new Geom_Ellipse(ax, x, y);
return true;
}
bool IfcGeom::convert(IfcSchema::Polyline* IfcPolyline, TopoDS_Wire& result) {
IfcEntities points = IfcPolyline->Points();
@@ -272,7 +405,10 @@ bool IfcGeom::convert(IfcSchema::Polyline* IfcPolyline, TopoDS_Wire& result) {
gp_Pnt P1;gp_Pnt P2;
IfcGeom::convert((IfcSchema::CartesianPoint*)(*it).get(),P1);
IfcParse::Entities::it next = it + 1;
if ( next == points->end() ) next = points->begin();
if ( next == points->end() ) {
if ( IfcPolyline->dt == IfcSchema::Enum::IfcPolyloop ) next = points->begin();
else break;
}
IfcGeom::convert((IfcSchema::CartesianPoint*)(*next).get(),P2);
if ( P1.X() == P2.X() && P1.Y() == P2.Y() && P1.Z() == P2.Z() ) continue;
TopoDS_Edge e = BRepBuilderAPI_MakeEdge(P1,P2);
@@ -290,8 +426,8 @@ bool IfcGeom::convert(IfcSchema::Axis2Placement3D* IfcAxis2Placement3D, gp_Trsf&
IfcGeom::convert((IfcSchema::CartesianPoint*) IfcAxis2Placement3D->Origin().get(),o);
try {
IfcGeom::convert((IfcSchema::Direction*) IfcAxis2Placement3D->Dir1().get(),z);
IfcGeom::convert((IfcSchema::Direction*) IfcAxis2Placement3D->Dir2().get(),x);
IfcGeom::convert((IfcSchema::Direction*) IfcAxis2Placement3D->Dir1().get(),z);
IfcGeom::convert((IfcSchema::Direction*) IfcAxis2Placement3D->Dir2().get(),x);
} catch( IfcParse::IfcException& ) {}
gp_Ax3 axis(o,z,x);
@@ -311,13 +447,13 @@ bool IfcGeom::convert(IfcSchema::Plane* IfcPlane, gp_Pln& plane) {
plane = gp_Pln(axis);
return true;
}
bool IfcGeom::convert(IfcSchema::Axis2Placement2D* IfcAxis2Placement2D, gp_Trsf2d& trsf) {
bool IfcGeom::convert(IfcSchema::Axis2Placement2D* IfcAxis2Placement2D, gp_Trsf2d& trsf) {
gp_Pnt P; gp_Vec V;
IfcGeom::convert((IfcSchema::CartesianPoint*) IfcAxis2Placement2D->Origin().get(),P);
IfcGeom::convert((IfcSchema::Direction*) IfcAxis2Placement2D->Dir1().get(),V);
gp_Ax2d axis (gp_Pnt2d(P.X(),P.Y()),gp_Vec2d(V.X(),V.Y()));
gp_Ax2d axis(gp_Pnt2d(P.X(),P.Y()),gp_Vec2d(V.X(),V.Y()));
trsf.SetTransformation(axis,gp_Ax2d());
return true;
}
@@ -347,7 +483,7 @@ bool IfcGeom::convert_openings(const IfcSchema::BuildingElement* IfcBuildingElem
IfcEntities IfcShapes = IfcShapeRepresentation->Shapes();
for ( IfcParse::Entities::it shape = IfcShapes->begin(); shape != IfcShapes->end(); ++shape ) {
TopoDS_Shape s;
if ( ! IfcGeom::convert_shape(*shape,s) ) continue;
if ( ! IfcGeom::convert_shape(*shape,s)) continue;
s.Move(trsf);
s.Move(trsf3);
result = BRepAlgoAPI_Cut(result,s);
@@ -369,4 +505,4 @@ bool IfcGeom::convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face) {
if ( er != BRepBuilderAPI_FaceDone ) return false;
face = mf.Face();
return true;
}
}
+7 -2
View File
@@ -31,6 +31,7 @@
#include <TColgp_Array1OfPnt.hxx>
#include <TShort_Array1OfShortReal.hxx>
#include <Poly_Array1OfTriangle.hxx>
#include <StdFail_NotDone.hxx>
#include "../ifcparse/IfcGeomObjects.h"
#include "../ifcparse/IfcGeom.h"
@@ -58,8 +59,8 @@ IfcGeomObjects::IfcMesh::IfcMesh(int i, TopoDS_Shape s) {
// Triangulate the shape
try {
BRepTools::Clean(s);
BRepMesh::Mesh(s,0.001f);
BRepTools::Clean(s);
BRepMesh::Mesh(s,0.001f);
} catch(...) {
std::cout << "[Error] Failed to triangulate IFC Entity #" << i << std::endl;
return;
@@ -167,8 +168,11 @@ IfcGeomObjects::IfcGeomObject* _get() {
#endif
// Find the IfcBuildingElements that refer to the current IfcShapeRepresentation
entities = shaperep->parents(IfcSchema::Enum::IfcProductDefinitionShape)->parents();
entities->pushs(shaperep->parents(IfcSchema::Enum::IfcProductRepresentation)->parents()); // 2x2 compatibility
entities->pushs(shaperep->parents(IfcSchema::Enum::IfcRepresentationMap)->parents(IfcSchema::Enum::IfcMappedItem)
->parents(IfcSchema::Enum::IfcShapeRepresentation,1,"Body")->parents(IfcSchema::Enum::IfcProductDefinitionShape)->parents());
entities->pushs(shaperep->parents(IfcSchema::Enum::IfcRepresentationMap)->parents(IfcSchema::Enum::IfcMappedItem)
->parents(IfcSchema::Enum::IfcShapeRepresentation,1,"Body")->parents(IfcSchema::Enum::IfcProductRepresentation)->parents());
if ( ! entities->size ) {
_nextShape();
continue;
@@ -223,6 +227,7 @@ IfcGeomObjects::IfcGeomObject* _get() {
try {
if (openings && openings->size) IfcGeom::convert_openings(entity,openings,temp_shape,trsf);
} catch( IfcParse::IfcException& e ) {std::cout << "[Warning] " << e.what() << std::endl; }
catch(StdFail_NotDone&) { std::cout << "[Error] Unknown modelling processing openings for:" << std::endl << entity->toString() << std::endl; }
if ( use_world_coords ) {
shape = new IfcGeomObjects::IfcMesh(shaperep->id,temp_shape.Moved(trsf));
trsf = gp_Trsf();
+28
View File
@@ -29,6 +29,7 @@
#undef IFC_FACE_CLASS
#undef IFC_SKIP_CLASS
#undef IFC_WIRE_CLASS
#undef IFC_CURVE_CLASS
#undef IFC_HELPER_CLASS
#undef IFC_END_CLASS
#undef IFC_REF
@@ -44,6 +45,7 @@
#define IFC_SHAPE_CLASS(N) IFC_CLASS(N,"")
#define IFC_FACE_CLASS(N) IFC_CLASS(N,"")
#define IFC_WIRE_CLASS(N) IFC_CLASS(N,"")
#define IFC_CURVE_CLASS(N) IFC_CLASS(N,"")
#define IFC_HELPER_CLASS(N) IFC_CLASS(N,"")
#define IFC_SKIP_CLASS(N)
#define IFC_END_CLASS };
@@ -61,6 +63,7 @@
#define IFC_SHAPE_CLASS(N)
#define IFC_FACE_CLASS(N)
#define IFC_WIRE_CLASS(N)
#define IFC_CURVE_CLASS(N)
#define IFC_HELPER_CLASS(N)
#define IFC_SKIP_CLASS(N)
#define IFC_END_CLASS
@@ -76,6 +79,7 @@
#ifdef IFC_PARSE_ENUM
#define IFC_SHAPE_CLASS(N) Ifc##N,
#define IFC_WIRE_CLASS(N) Ifc##N,
#define IFC_CURVE_CLASS(N) Ifc##N,
#define IFC_FACE_CLASS(N) Ifc##N,
#define IFC_CLASS(N,T) Ifc##N,
#define IFC_HELPER_CLASS(N) Ifc##N,
@@ -94,6 +98,7 @@
#define IFC_SHAPE_CLASS(N) if ( strcasecmp(a.c_str()+3,#N) == 0 ) { return IfcSchema::Enum::Ifc##N; }
#define IFC_FACE_CLASS(N) IFC_SHAPE_CLASS(N)
#define IFC_WIRE_CLASS(N) IFC_SHAPE_CLASS(N)
#define IFC_CURVE_CLASS(N) IFC_SHAPE_CLASS(N)
#define IFC_HELPER_CLASS(N) IFC_SHAPE_CLASS(N)
#define IFC_CLASS(N,T) IFC_SHAPE_CLASS(N)
#define IFC_SKIP_CLASS(N) if ( strcasecmp(a.c_str()+3,#N) == 0 ) { return IfcSchema::Enum::IfcDontCare; }
@@ -111,6 +116,7 @@
#define IFC_SHAPE_CLASS(N) if ( t == IfcSchema::Enum::Ifc##N ) return "Ifc" #N;
#define IFC_FACE_CLASS(N) IFC_SHAPE_CLASS(N)
#define IFC_WIRE_CLASS(N) IFC_SHAPE_CLASS(N)
#define IFC_CURVE_CLASS(N) IFC_SHAPE_CLASS(N)
#define IFC_HELPER_CLASS(N) IFC_SHAPE_CLASS(N)
#define IFC_CLASS(N,T) IFC_SHAPE_CLASS(N)
#define IFC_SKIP_CLASS(N)
@@ -128,6 +134,7 @@
#define IFC_SHAPE_CLASS(N) bool convert(IfcSchema::N* Ifc##N,TopoDS_Shape& result);
#define IFC_FACE_CLASS(N) bool convert(IfcSchema::N* Ifc##N,TopoDS_Face& result);
#define IFC_WIRE_CLASS(N) bool convert(IfcSchema::N* Ifc##N,TopoDS_Wire& result);
#define IFC_CURVE_CLASS(N) bool convert(IfcSchema::N* Ifc##N,Handle(Geom_Curve)& result);
#define IFC_HELPER_CLASS(N)
#define IFC_CLASS(N,T) bool convert(IfcSchema::N* Ifc##N,T& result);
#define IFC_SKIP_CLASS(N)
@@ -145,6 +152,7 @@
#define IFC_SHAPE_CLASS(N) if ( L->dt == IfcSchema::Enum::Ifc##N ) { IfcSchema::N* x = (IfcSchema::N*) L.get(); bool b = false; try { b = IfcGeom::convert(x,result); } catch(IfcParse::IfcException& e) { std::cout << "[Error] " << e.what() << std::endl;} catch(StdFail_NotDone&) { std::cout << "[Error] Unknown modelling error" << std::endl; } if (!b) std::cout << "[Error] Failed to convert:" << std::endl << x->toString() << std::endl; return b; }
#define IFC_FACE_CLASS(N)
#define IFC_WIRE_CLASS(N)
#define IFC_CURVE_CLASS(N)
#define IFC_HELPER_CLASS(N)
#define IFC_CLASS(N,T)
#define IFC_SKIP_CLASS(N)
@@ -162,6 +170,7 @@
#define IFC_SHAPE_CLASS(N)
#define IFC_FACE_CLASS(N)
#define IFC_WIRE_CLASS(N) if ( L->dt == IfcSchema::Enum::Ifc##N ) { IfcSchema::N* x = (IfcSchema::N*) L.get(); return IfcGeom::convert(x,result); }
#define IFC_CURVE_CLASS(N)
#define IFC_HELPER_CLASS(N)
#define IFC_CLASS(N,T)
#define IFC_SKIP_CLASS(N)
@@ -179,6 +188,25 @@
#define IFC_SHAPE_CLASS(N)
#define IFC_FACE_CLASS(N) if ( L->dt == IfcSchema::Enum::Ifc##N ) { IfcSchema::N* x = (IfcSchema::N*) L.get(); return IfcGeom::convert(x,result); }
#define IFC_WIRE_CLASS(N) if ( L->dt == IfcSchema::Enum::Ifc##N ) { IfcSchema::N* x = (IfcSchema::N*) L.get(); if ( ! IfcGeom::convert(x,wire) ) return false; return IfcGeom::convert_wire_to_face(wire,result); }
#define IFC_CURVE_CLASS(N)
#define IFC_HELPER_CLASS(N)
#define IFC_CLASS(N,T)
#define IFC_SKIP_CLASS(N)
#define IFC_END_CLASS
#define IFC_REF(C,N,I)
#define IFC_REFS(C,N,I)
#define IFC_FLT(C,N,I)
#define IFC_FLT_SUB(C,N,I,J)
#define IFC_INT(C,N,I)
#define IFC_STR(C,N,I)
#define IFC_BOOL(C,N,I)
#endif
#ifdef IFC_CURVE_SRC
#define IFC_SHAPE_CLASS(N)
#define IFC_FACE_CLASS(N)
#define IFC_WIRE_CLASS(N)
#define IFC_CURVE_CLASS(N) if ( L->dt == IfcSchema::Enum::Ifc##N ) { IfcSchema::N* x = (IfcSchema::N*) L.get(); return IfcGeom::convert(x,result); }
#define IFC_HELPER_CLASS(N)
#define IFC_CLASS(N,T)
#define IFC_SKIP_CLASS(N)
+94 -39
View File
@@ -57,6 +57,10 @@ Argument::Argument(const std::string& s) {
if ( _data == -1 ) { _data = datatypes.size(); datatypes.push_back(s); }
}
}
Argument::Argument(const EntityPtr e) {
type = SUB_ENTITY;
_entity = e;
}
std::string Argument::s() const {
if ( type == OPERATOR ) { std::string r; r.push_back((char)_data); return r; }
if ( type == DATATYPE ) return datatypes[_data];
@@ -76,6 +80,10 @@ bool Argument::b() const {
if ( type != ENUMERATION ) throw IfcException();
return s() == "T";
}
EntityPtr Argument::r() const {
if ( type != SUB_ENTITY ) throw IfcException();
return _entity;
}
bool Argument::isOp(char op) const {
return type == OPERATOR && ( op == 0 || op == ((char)_data) );
}
@@ -87,6 +95,7 @@ std::string Argument::toString() const {
else if ( type == STRING ) ss << "'" << s() << "'";
else if ( type == ENUMERATION ) ss << "." << s() << ".";
else if ( type == IDENTIFIER ) ss << "#" << i();
else if ( type == SUB_ENTITY ) ss << _entity->toString();
return ss.str();
}
std::vector<std::string> Argument::datatypes;
@@ -104,10 +113,11 @@ void ArgumentList::_push() {
_args.push_back(a);
_current = a;
}
void ArgumentList::_pop() {
if ( _levels.empty() ) return;
_current = _levels.back();
bool ArgumentList::_pop() {
_levels.pop_back();
if ( _levels.empty() ) return true;
_current = _levels.back();
return _levels.empty();
}
void ArgumentList::_append(const Argument* v) {
ArgumentList* a = new ArgumentList();
@@ -120,7 +130,7 @@ std::string ArgumentList::toString() const {
std::stringstream ss; ss << "(";
std::vector<ArgumentList*>::const_iterator it;
for ( it = _args.begin() ; it != _args.end(); ++ it ) {
if ( it != _args.begin() ) ss << ",";
if ( it != _args.begin() ) ss << ",";
ss << (*it)->toString();
}
ss << ")";
@@ -135,8 +145,11 @@ int ArgumentList::count() const { return _arg ? 1 : _args.size(); }
ArgumentList* ArgumentList::arg(int i) const { return _args[i]; }
EntityPtr ArgumentList::ref() const {
if ( _arg->isOp('$') ) throw IfcException();
return Ifc::EntityById(_arg->i());
if ( _arg->type == Argument::IDENTIFIER ) {
return Ifc::EntityById(_arg->i());
} else {
return _arg->r();
}
}
EntitiesPtr ArgumentList::refs() const {
EntitiesPtr l (new Entities());
@@ -145,6 +158,8 @@ EntitiesPtr ArgumentList::refs() const {
ArgumentList* a = *it;
if ( a->_arg && a->_arg->type == Argument::IDENTIFIER ) {
l->push(Ifc::EntityById(a->_arg->i()));
} else if ( a->_arg && a->_arg->type == Argument::SUB_ENTITY ) {
l->push(a->_arg->r());
}
}
return l;
@@ -160,12 +175,13 @@ ArgumentList::~ArgumentList() {
inline bool Entity::term(char last) {
return last == '(' || last == ')' || last == '=' || last == ',' || last == ';';
}
Entity::Entity(std::istream* ss, std::vector<int>& refs) {
Entity::Entity(std::istream* ss, std::vector<int>& refs, bool sub) {
std::string curvar;
curvar.reserve(64);
bool inStr = false;
char c[1] = "";
int state = -1;
int previousPos = -1;
args = 0;
_dt = 0;
id = -1;
@@ -177,31 +193,46 @@ Entity::Entity(std::istream* ss, std::vector<int>& refs) {
curvar.clear();
curvar.push_back(*c);
if ( state < 10 ) state ++;
if ( state == 0 ) {
if ( !sub && !state ) {
if ( v->type == Argument::IDENTIFIER ) {
id = v->i();
} else {
state = -1;
}
} else if ( state == 1 ) {
} else if ( ! sub && (state == 1) ) {
if ( ! v->isOp('=') ) state = -1;
} else if ( state == 2 ) {
} else if ( (sub && !state) || (!sub && state == 2) ) {
if ( v->type == Argument::DATATYPE ) {
dt = IfcSchema::Enum::FromString(v->s());
_dt = v;
continue;
}
} else if ( args ) {
if ( v->isOp('(') ) args->_push();
else if ( v->isOp(')') ) args->_pop();
else if ( ! v->isOp(',') && !v->isOp(';') ) {
args->_append(v);
if ( v->type == Argument::IDENTIFIER ) refs.push_back(v->i());
continue;
if ( v->isOp('(') )
args->_push();
else if ( v->isOp(')') ) {
bool closed = args->_pop();
if ( closed && sub ) {
delete v;
return;
}
} else if ( ! v->isOp(',') && !v->isOp(';') ) {
if ( v->type == Argument::DATATYPE ) {
ss->seekg(previousPos-1,std::ios_base::beg);
Argument* a = new Argument(EntityPtr(new Entity(ss,refs,true)));
ss->seekg(-1,std::ios_base::cur);
curvar.clear();
args->_append(a);
} else {
args->_append(v);
if ( v->type == Argument::IDENTIFIER ) refs.push_back(v->i());
continue;
}
}
} else if ( v->isOp('(') ) {
args = new ArgumentList();
}
previousPos = ss->tellg();
delete v;
} else curvar.push_back(*c);
if ( *c == '\'' ) inStr = !inStr;
@@ -224,7 +255,8 @@ ArgumentList* Entity::arg(int i) const {
std::string Entity::toString() const {
std::stringstream ss;
if ( isAssignment() ) {
ss << "#" << id << "=" << datatype() << args->toString();
if ( id > 0 ) ss << "#" << id << "=";
ss << datatype() << args->toString();
}
return ss.str();
}
@@ -296,7 +328,7 @@ File::File(std::string fn, bool debug) {
EntityPtr il (new Entity(pf,refs));
if ( il->isAssignment() ) {
if ( debug )
std::cout << il->toString();
std::cout << il->toString() << std::endl;
if ( il->dt == IfcSchema::Enum::IfcDontCare ) {
continue;
}
@@ -362,28 +394,29 @@ EntityPtr Ifc::EntityById(int id) {
}
bool Ifc::Init(std::string fn) {
f = new File(fn, false);
IfcEntities units = EntitiesByType(IfcSchema::Enum::IfcSIUnit);
Ifc::Scale = 1.0f;
IfcEntity IfcUnitAssigment = *EntitiesByType(IfcSchema::Enum::IfcUnitAssignment)->begin();
IfcEntities units = ((IfcSchema::UnitAssignment*)IfcUnitAssigment.get())->Units();
Ifc::LengthUnit = 1.0f;
if ( units )
for ( IfcParse::Entities::it it = units->begin(); it != units->end(); it ++ ) {
IfcSchema::SIUnit* unit = (IfcSchema::SIUnit*)(*it).get();
if ( unit->Type() == "LENGTHUNIT" ) {
if ( unit->Prefix() == "EXA" ) Ifc::Scale = (float) 1e18;
else if ( unit->Prefix() == "PETA" ) Ifc::Scale = (float) 1e15;
else if ( unit->Prefix() == "TERA" ) Ifc::Scale = (float) 1e12;
else if ( unit->Prefix() == "GIGA" ) Ifc::Scale = (float) 1e9;
else if ( unit->Prefix() == "MEGA" ) Ifc::Scale = (float) 1e6;
else if ( unit->Prefix() == "KILO" ) Ifc::Scale = (float) 1e3;
else if ( unit->Prefix() == "HECTO" ) Ifc::Scale = (float) 1e2;
else if ( unit->Prefix() == "DECA" ) Ifc::Scale = (float) 1;
else if ( unit->Prefix() == "DECI" ) Ifc::Scale = (float) 1e-1;
else if ( unit->Prefix() == "CENTI" ) Ifc::Scale = (float) 1e-2;
else if ( unit->Prefix() == "MILLI" ) Ifc::Scale = (float) 1e-3;
else if ( unit->Prefix() == "MICRO" ) Ifc::Scale = (float) 1e-6;
else if ( unit->Prefix() == "NANO" ) Ifc::Scale = (float) 1e-9;
else if ( unit->Prefix() == "PICO" ) Ifc::Scale = (float) 1e-12;
else if ( unit->Prefix() == "FEMTO" ) Ifc::Scale = (float) 1e-15;
else if ( unit->Prefix() == "ATTO" ) Ifc::Scale = (float) 1e-18;
IfcEntity unit = *it;
float value = 1.0f;
std::string UnitType = "";
if ( unit->dt == IfcSchema::Enum::IfcConversionBasedUnit ) {
IfcSchema::ConversionBasedUnit* IfcConversionBasedUnit = (IfcSchema::ConversionBasedUnit*)(*it).get();
IfcSchema::MeasureWithUnit* IfcMeasureWithUnit = (IfcSchema::MeasureWithUnit*)IfcConversionBasedUnit->ConversionFactor().get();
unit = IfcMeasureWithUnit->Unit();
value = IfcMeasureWithUnit->Value()->arg(0)->f();
}
if ( unit->dt == IfcSchema::Enum::IfcSIUnit ) {
IfcSchema::SIUnit* IfcSIUnit = (IfcSchema::SIUnit*)(*it).get();
value *= UnitPrefixToValue(IfcSIUnit->UnitPrefix());
UnitType = IfcSIUnit->UnitType();
}
if ( UnitType == "LENGTHUNIT" ) {
Ifc::LengthUnit = value;
} else if ( UnitType == "PLANEANGLEUNIT" ) {
Ifc::PlaneAngleUnit = value;
}
}
return f->valid;
@@ -395,4 +428,26 @@ void Ifc::Dispose() {
Argument::enumstrings.clear();
}
File* Ifc::f = 0;
float Ifc::Scale = 1.0f;
float Ifc::LengthUnit = 1.0f;
float Ifc::PlaneAngleUnit = 1.0f;
int Ifc::CircleSegments = 32;
float UnitPrefixToValue( const std::string& s ) {
if ( s == "EXA" ) return (float) 1e18;
else if ( s == "PETA" ) return (float) 1e15;
else if ( s == "TERA" ) return (float) 1e12;
else if ( s == "GIGA" ) return (float) 1e9;
else if ( s == "MEGA" ) return (float) 1e6;
else if ( s == "KILO" ) return (float) 1e3;
else if ( s == "HECTO" ) return (float) 1e2;
else if ( s == "DECA" ) return (float) 1;
else if ( s == "DECI" ) return (float) 1e-1;
else if ( s == "CENTI" ) return (float) 1e-2;
else if ( s == "MILLI" ) return (float) 1e-3;
else if ( s == "MICRO" ) return (float) 1e-6;
else if ( s == "NANO" ) return (float) 1e-9;
else if ( s == "PICO" ) return (float) 1e-12;
else if ( s == "FEMTO" ) return (float) 1e-15;
else if ( s == "ATTO" ) return (float) 1e-18;
else return 1.0f;
}
+17 -10
View File
@@ -49,6 +49,11 @@ class Ifc;
namespace IfcParse {
class Entity;
class Entities;
typedef SHARED_PTR<Entity> EntityPtr;
typedef SHARED_PTR<Entities> EntitiesPtr;
class Argument {
private:
static std::vector<std::string> datatypes;
@@ -56,12 +61,14 @@ namespace IfcParse {
static std::vector<std::string> argstrings;
int _data;
float _number;
float _number;
EntityPtr _entity;
public:
enum vartype { IDENTIFIER, STRING, NUMBER, OPERATOR, ENUMERATION, DATATYPE };
enum vartype { IDENTIFIER, STRING, NUMBER, OPERATOR, ENUMERATION, DATATYPE, SUB_ENTITY };
vartype type;
Argument(const std::string& s);
Argument(const EntityPtr e);
bool isOp(char op = 0) const;
@@ -69,6 +76,7 @@ namespace IfcParse {
int i() const;
std::string s() const;
bool b() const;
EntityPtr r() const;
std::string toString() const;
@@ -77,11 +85,6 @@ namespace IfcParse {
friend class ::Ifc;
};
class Entity;
class Entities;
typedef SHARED_PTR<Entity> EntityPtr;
typedef SHARED_PTR<Entities> EntitiesPtr;
class ArgumentList {
private:
std::vector<ArgumentList*> _levels;
@@ -89,7 +92,7 @@ namespace IfcParse {
ArgumentList* _current;
const Argument* _arg;
void _push();
void _pop();
bool _pop();
void _append(const Argument* v);
public:
ArgumentList();
@@ -118,7 +121,7 @@ namespace IfcParse {
ArgumentList* args;
Argument* _dt;
Entity(std::istream* ss, std::vector<int>& refs);
Entity(std::istream* ss, std::vector<int>& refs, bool sub = false);
~Entity();
ArgumentList* arg(int i) const;
@@ -174,6 +177,8 @@ namespace IfcParse {
typedef IfcParse::EntityPtr IfcEntity;
typedef IfcParse::EntitiesPtr IfcEntities;
float UnitPrefixToValue(const std::string& s);
class Ifc {
private:
static IfcParse::File* f;
@@ -183,7 +188,9 @@ public:
static IfcEntity EntityById(int id);
static bool Init(std::string fn);
static void Dispose();
static float Scale;
static float LengthUnit;
static float PlaneAngleUnit;
static int CircleSegments;
};
#endif
+67 -3
View File
@@ -120,6 +120,28 @@ IFC_FLT(RectangleProfileDef,Width,3)
IFC_FLT(RectangleProfileDef,Height,4)
IFC_END_CLASS
IFC_WIRE_CLASS(CircleProfileDef)
IFC_REF(CircleProfileDef,Placement,2)
IFC_FLT(CircleProfileDef,Radius,3)
IFC_END_CLASS
IFC_FACE_CLASS(CircleHollowProfileDef)
IFC_REF(CircleHollowProfileDef,Placement,2)
IFC_FLT(CircleHollowProfileDef,Radius,3)
IFC_FLT(CircleHollowProfileDef,WallThickness,4)
IFC_END_CLASS
IFC_CURVE_CLASS(Circle)
IFC_REF(Circle,Placement,0)
IFC_FLT(Circle,Radius,1)
IFC_END_CLASS
IFC_CURVE_CLASS(Ellipse)
IFC_REF(Ellipse,Placement,0)
IFC_FLT(Ellipse,Axis1,1)
IFC_FLT(Ellipse,Axis2,2)
IFC_END_CLASS
IFC_CLASS(CartesianPoint,gp_Pnt)
IFC_FLT_SUB(CartesianPoint,X,0,0)
IFC_FLT_SUB(CartesianPoint,Y,0,1)
@@ -152,10 +174,23 @@ IFC_WIRE_CLASS(Polyline)
IFC_REFS(Polyline,Points,0)
IFC_END_CLASS
IFC_WIRE_CLASS(CompositeCurve)
IFC_REFS(CompositeCurve,Segments,0)
IFC_BOOL(CompositeCurve,SelfIntersects,1)
IFC_END_CLASS
IFC_WIRE_CLASS(Polyloop)
IFC_REFS(Polyloop,Points,0)
IFC_END_CLASS
IFC_WIRE_CLASS(TrimmedCurve)
IFC_REF(TrimmedCurve,BasisCurve,0)
IFC_REFS(TrimmedCurve,Trim1,1)
IFC_REFS(TrimmedCurve,Trim2,2)
IFC_BOOL(TrimmedCurve,SenseAgreement,3)
IFC_STR(TrimmedCurve,MasterRepresentation,4)
IFC_END_CLASS
IFC_HELPER_CLASS(BuildingElement)
IFC_STR(BuildingElement,Guid,0)
IFC_REF(BuildingElement,Owner,1)
@@ -168,15 +203,43 @@ IFC_HELPER_CLASS(ShapeRepresentation)
IFC_REFS(ShapeRepresentation,Shapes,3)
IFC_END_CLASS
IFC_HELPER_CLASS(CompositeCurveSegment)
IFC_STR(CompositeCurveSegment,Transition,0)
IFC_BOOL(CompositeCurveSegment,SameSense,1)
IFC_REF(CompositeCurveSegment,ParentCurve,2)
IFC_END_CLASS
IFC_HELPER_CLASS(SIUnit)
IFC_STR(SIUnit,Type,1)
IFC_STR(SIUnit,Prefix,2)
IFC_STR(SIUnit,UnitType,1)
IFC_STR(SIUnit,UnitPrefix,2)
IFC_STR(SIUnit,Name,3)
IFC_END_CLASS
IFC_HELPER_CLASS(ConversionBasedUnit)
IFC_REF(ConversionBasedUnit,Dimensions,0)
IFC_STR(ConversionBasedUnit,UnitType,1)
IFC_STR(ConversionBasedUnit,Name,2)
IFC_REF(ConversionBasedUnit,ConversionFactor,3)
IFC_END_CLASS
IFC_HELPER_CLASS(MeasureWithUnit)
IFC_REF(MeasureWithUnit,Value,0)
IFC_REF(MeasureWithUnit,Unit,1)
IFC_END_CLASS
IFC_HELPER_CLASS(UnitAssignment)
IFC_REFS(UnitAssignment,Units,0)
IFC_END_CLASS
IFC_HELPER_CLASS(ParameterValue)
IFC_FLT(ParameterValue,Value,0)
IFC_END_CLASS
IFC_HELPER_CLASS(RatioMeasure)
IFC_FLT(RatioMeasure,Value,0)
IFC_END_CLASS
IFC_HELPER_CLASS(ProductDefinitionShape)
IFC_REFS(ProductDefinitionShape,ShapeReps,2)
IFC_END_CLASS
IFC_HELPER_CLASS(ProductRepresentation) // 2x2 compatibility
IFC_END_CLASS
IFC_HELPER_CLASS(RepresentationMap)
IFC_END_CLASS
IFC_HELPER_CLASS(MappedItem)
@@ -193,4 +256,5 @@ IFC_SKIP_CLASS(ComplexProperty)
IFC_SKIP_CLASS(RelDefinesByProperty)
IFC_SKIP_CLASS(MaterialLayer)
IFC_SKIP_CLASS(MaterialLayerSet)
IFC_SKIP_CLASS(MaterialLayerSetUsage)
IFC_SKIP_CLASS(MaterialLayerSetUsage)
IFC_SKIP_CLASS(PresentationLayerAssignment)
+10 -1
View File
@@ -17,7 +17,7 @@
* *
********************************************************************************/
#include "StdFail_NotDone.hxx"
#include <StdFail_NotDone.hxx>
#include "../ifcparse/IfcTypes.h"
#include "../ifcparse/IfcEnum.h"
@@ -46,6 +46,15 @@ bool IfcGeom::convert_wire(const IfcEntity L, TopoDS_Wire &result) {
return false;
}
bool IfcGeom::convert_curve(const IfcEntity L, Handle(Geom_Curve) &result) {
if ( ! L ) return false;
#define IFC_CURVE_SRC
#include "../ifcparse/IfcSchema.h"
#undef IFC_CURVE_SRC
std::cout << "[Error] Failed to interpret:" << std::endl << L->toString() << std::endl;
return false;
}
bool IfcGeom::convert_face(const IfcEntity L, TopoDS_Face &result) {
if ( ! L ) return false;
TopoDS_Wire wire;
+2
View File
@@ -26,6 +26,7 @@
#include <gp_Trsf2d.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Wire.hxx>
#include <Geom_Curve.hxx>
#include "../ifcparse/IfcParse.h"
@@ -42,6 +43,7 @@ namespace IfcGeom {
bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face);
bool convert_shape(const IfcEntity L, TopoDS_Shape& result);
bool convert_wire(const IfcEntity L, TopoDS_Wire& result);
bool convert_curve(const IfcEntity L, Handle(Geom_Curve)& result);
bool convert_face(const IfcEntity L, TopoDS_Face& result);
bool convert_openings(const IfcSchema::BuildingElement* IfcBuildingElement, const IfcEntities openings, TopoDS_Shape& result, const gp_Trsf& trsf);
}