mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-14 03:14:23 +00:00
Initial commit
This commit is contained in:
@@ -0,0 +1,42 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include <string>
|
||||
|
||||
#include "../ifcparse/IfcEnum.h"
|
||||
|
||||
IfcSchema::Enum::IfcTypes IfcSchema::Enum::FromString(const std::string& a) {
|
||||
|
||||
#define IFC_PARSE_STR_ENUM
|
||||
#include "../ifcparse/IfcSchema.h"
|
||||
#undef IFC_PARSE_STR_ENUM
|
||||
|
||||
return IfcUnknown;
|
||||
}
|
||||
|
||||
std::string IfcSchema::Enum::ToString(IfcTypes t) {
|
||||
std::string r = "Ifc";
|
||||
r.reserve(64);
|
||||
|
||||
#define IFC_PARSE_ENUM_STR
|
||||
#include "../ifcparse/IfcSchema.h"
|
||||
#undef IFC_PARSE_ENUM_STR
|
||||
|
||||
return "";
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFC_ENUM_H
|
||||
#define IFC_ENUM_H
|
||||
|
||||
#include <string>
|
||||
#ifdef _MSC_VER
|
||||
#define strcasecmp _stricmp
|
||||
#else
|
||||
#include <strings.h>
|
||||
#endif
|
||||
|
||||
namespace IfcSchema {
|
||||
namespace Enum {
|
||||
|
||||
enum IfcTypes {
|
||||
|
||||
#define IFC_PARSE_ENUM
|
||||
#include "../ifcparse/IfcSchema.h"
|
||||
#undef IFC_PARSE_ENUM
|
||||
|
||||
IfcUnknown,
|
||||
IfcDontCare,
|
||||
ALL
|
||||
};
|
||||
IfcTypes FromString(const std::string& a);
|
||||
std::string ToString(IfcTypes t);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,372 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* Implementations of the various conversion functions required by IfcSchema.h. *
|
||||
* The functions are prototyped in IfcTypes.h. Functions that convert a *
|
||||
* TopoDS_Shape or TopoDS_Wire are called from IfcGeom::convert_shape and *
|
||||
* IfcGeom::convert_wire respectively *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "../ifcparse/IfcParse.h"
|
||||
#include "../ifcparse/IfcTypes.h"
|
||||
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec2d.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>
|
||||
|
||||
#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 <BRepOffsetAPI_Sewing.hxx>
|
||||
#include <BRepBuilderAPI_MakeFace.hxx>
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include <BRepBuilderAPI_MakeWire.hxx>
|
||||
#include <BRepBuilderAPI_MakePolygon.hxx>
|
||||
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
|
||||
#include <BRepPrimAPI_MakePrism.hxx>
|
||||
#include <BRepBuilderAPI_MakeShell.hxx>
|
||||
#include <BRepBuilderAPI_MakeSolid.hxx>
|
||||
#include <BRepPrimAPI_MakeHalfSpace.hxx>
|
||||
#include <BRepAlgoAPI_Cut.hxx>
|
||||
|
||||
#include <ShapeFix_Shape.hxx>
|
||||
#include <ShapeFix_ShapeTolerance.hxx>
|
||||
#include <ShapeFix_Solid.hxx>
|
||||
|
||||
#include <TopLoc_Location.hxx>
|
||||
|
||||
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;
|
||||
gp_Trsf trsf;
|
||||
convert((IfcSchema::Axis2Placement3D*) IfcExtrudedAreaSolid->Placement().get(),trsf);
|
||||
|
||||
gp_Vec dir3;
|
||||
convert((IfcSchema::Direction*) IfcExtrudedAreaSolid->Dir().get(),dir3);
|
||||
|
||||
gp_Vec extrude = dir3.Scaled(height);
|
||||
|
||||
shape = BRepPrimAPI_MakePrism(face,extrude);
|
||||
shape.Move(trsf);
|
||||
return ! shape.IsNull();
|
||||
}
|
||||
bool IfcGeom::convert(IfcSchema::FacetedBrep* IfcFacetedBrep, TopoDS_Shape& shape) {
|
||||
return IfcGeom::convert_shape(IfcFacetedBrep->Shell(),shape);
|
||||
}
|
||||
bool IfcGeom::convert(IfcSchema::FaceBasedSurfaceModel* IfcFaceBasedSurfaceModel, TopoDS_Shape& shape) {
|
||||
return IfcGeom::convert((IfcSchema::ShellBasedSurfaceModel*) IfcFaceBasedSurfaceModel,shape);
|
||||
}
|
||||
bool IfcGeom::convert(IfcSchema::HalfSpaceSolid* IfcHalfSpaceSolid, TopoDS_Shape& shape) {
|
||||
IfcEntity surf = IfcHalfSpaceSolid->Surface();
|
||||
if ( surf->dt != IfcSchema::Enum::IfcPlane ) return false;
|
||||
IfcSchema::Plane* IfcPlane = (IfcSchema::Plane*)surf.get();
|
||||
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());
|
||||
else pnt.Translate(-pln.Axis().Direction());
|
||||
shape = BRepPrimAPI_MakeHalfSpace(BRepBuilderAPI_MakeFace(pln),pnt).Solid();
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(IfcSchema::PolygonalBoundedHalfSpace* IfcPolygonalBoundedHalfSpace, TopoDS_Shape& shape) {
|
||||
TopoDS_Shape halfspace;
|
||||
if ( ! IfcGeom::convert((IfcSchema::HalfSpaceSolid*)IfcPolygonalBoundedHalfSpace,halfspace) ) return false;
|
||||
TopoDS_Wire wire;
|
||||
if ( ! IfcGeom::convert_wire(IfcPolygonalBoundedHalfSpace->Boundary(),wire) ) return false;
|
||||
gp_Trsf trsf;
|
||||
convert((IfcSchema::Axis2Placement3D*) IfcPolygonalBoundedHalfSpace->Placement().get(),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));
|
||||
extrusion.Move(down);
|
||||
extrusion.Move(trsf);
|
||||
shape = BRepAlgoAPI_Cut(extrusion,halfspace);
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(IfcSchema::ShellBasedSurfaceModel* IfcShellBasedSurfaceModel, TopoDS_Shape& shape) {
|
||||
IfcEntities shells = IfcShellBasedSurfaceModel->Shells();
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound c;
|
||||
builder.MakeCompound(c);
|
||||
for( IfcParse::Entities::it it = shells->begin(); it != shells->end(); ++ it ) {
|
||||
TopoDS_Shape s;
|
||||
if ( IfcGeom::convert_shape(*it,s) ) {
|
||||
builder.Add(c,s);
|
||||
}
|
||||
}
|
||||
shape = c;
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(IfcSchema::BooleanClippingResult* IfcBooleanClippingResult, TopoDS_Shape& shape) {
|
||||
TopoDS_Shape s1, s2;
|
||||
bool res1 = IfcGeom::convert_shape(IfcBooleanClippingResult->First(),s1);
|
||||
if ( ! res1 ) return false;
|
||||
bool res2 = IfcGeom::convert_shape(IfcBooleanClippingResult->Second(),s2);
|
||||
if ( res2 )
|
||||
shape = BRepAlgoAPI_Cut(s1,s2);
|
||||
return true;
|
||||
}
|
||||
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));
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(IfcSchema::ConnectedFaceSet* IfcConnectedFaceSet, TopoDS_Shape& shape) {
|
||||
return IfcGeom::convert((IfcSchema::OpenShell*) IfcConnectedFaceSet,shape);
|
||||
}
|
||||
bool IfcGeom::convert(IfcSchema::OpenShell* IfcOpenShell, TopoDS_Shape& shape) {
|
||||
BRepOffsetAPI_Sewing builder;
|
||||
builder.SetTolerance(0.001);
|
||||
IfcEntities faces = IfcOpenShell->Faces();
|
||||
bool facesAdded = false;
|
||||
for( IfcParse::Entities::it it = faces->begin(); it != faces->end(); ++ it ) {
|
||||
TopoDS_Face face;
|
||||
if ( IfcGeom::convert((IfcSchema::Face*) (*it).get(),face) ) {
|
||||
builder.Add(face);
|
||||
facesAdded = true;
|
||||
} else {
|
||||
std::cout << "[Warning] Invalid face:" << std::endl << (*it).get()->toString() << std::endl;
|
||||
}
|
||||
}
|
||||
if ( ! facesAdded ) return false;
|
||||
builder.Perform();
|
||||
shape = builder.SewedShape();
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(IfcSchema::Face* IfcFace, TopoDS_Face& face) {
|
||||
IfcEntities bounds = IfcFace->Bounds();
|
||||
IfcParse::Entities::it it = bounds->begin();
|
||||
IfcSchema::FaceBound* bound = (IfcSchema::FaceBound*)(*it).get();
|
||||
|
||||
IfcEntity loop = bound->Loop();
|
||||
TopoDS_Wire wire;
|
||||
if ( ! IfcGeom::convert_wire(loop,wire) ) return false;
|
||||
BRepBuilderAPI_MakeFace mf = BRepBuilderAPI_MakeFace(wire);
|
||||
BRepBuilderAPI_FaceError er = mf.Error();
|
||||
if ( er == BRepBuilderAPI_NotPlanar ) {
|
||||
std::cout << "[Notice] Trying to fix non-planar face" << std::endl;
|
||||
ShapeFix_ShapeTolerance FTol;
|
||||
FTol.SetTolerance(wire, 0.01, TopAbs_WIRE);
|
||||
mf = BRepBuilderAPI_MakeFace(wire);
|
||||
er = mf.Error();
|
||||
}
|
||||
if ( er != BRepBuilderAPI_FaceDone ) return false;
|
||||
|
||||
if ( bounds->size == 1 ) {
|
||||
face = mf.Face();
|
||||
return true;
|
||||
}
|
||||
|
||||
for( ++ it; it != bounds->end(); ++ it ) {
|
||||
IfcSchema::FaceBound* bound = (IfcSchema::FaceBound*)(*it).get();
|
||||
IfcEntity loop = bound->Loop();
|
||||
TopoDS_Wire hole;
|
||||
IfcGeom::convert_wire(loop,hole);
|
||||
mf.Add(hole);
|
||||
}
|
||||
|
||||
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);
|
||||
else
|
||||
p = gp_Pnt(IfcCartesianPoint->X() * Ifc::Scale,IfcCartesianPoint->Y() * Ifc::Scale,0.0f);
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(IfcSchema::Direction* IfcDirection, gp_Vec& v) {
|
||||
if ( IfcDirection->arg(0)->count() == 3 )
|
||||
v = gp_Vec(IfcDirection->X(),IfcDirection->Y(),IfcDirection->Z());
|
||||
else
|
||||
v = gp_Vec(IfcDirection->X(),IfcDirection->Y(),0.0f);
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(IfcSchema::ArbitraryClosedProfileDef* IfcArbitraryClosedProfileDef, TopoDS_Wire& wire) {
|
||||
return IfcGeom::convert_wire(IfcArbitraryClosedProfileDef->Polyline(),wire);
|
||||
}
|
||||
bool IfcGeom::convert(IfcSchema::ArbitraryProfileDefWithVoids* IfcArbitraryProfileDefWithVoids, TopoDS_Face& face) {
|
||||
TopoDS_Wire profile;
|
||||
if ( ! IfcGeom::convert_wire(IfcArbitraryProfileDefWithVoids->Polyline(),profile) ) return false;
|
||||
BRepBuilderAPI_MakeFace mf = BRepBuilderAPI_MakeFace(profile);
|
||||
IfcEntities voids = IfcArbitraryProfileDefWithVoids->Voids();
|
||||
for( IfcParse::Entities::it it = voids->begin(); it != voids->end(); ++ it ) {
|
||||
TopoDS_Wire hole;
|
||||
if ( IfcGeom::convert_wire(*it,hole) ) {
|
||||
mf.Add(hole);
|
||||
}
|
||||
}
|
||||
ShapeFix_Shape sfs(mf.Face());
|
||||
sfs.Perform();
|
||||
face = TopoDS::Face(sfs.Shape());
|
||||
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;
|
||||
|
||||
if ( x == 0.0f || y == 0.0f ) {
|
||||
std::cout << "[Notice] Skipping zero sized profile" << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
gp_Trsf2d trsf;
|
||||
IfcGeom::convert((IfcSchema::Axis2Placement2D*)IfcRectangleProfileDef->Placement().get(),trsf);
|
||||
|
||||
gp_XY p1 (-x,-y);trsf.Transforms(p1);gp_Pnt P1(p1.X(),p1.Y(),0.0f);
|
||||
gp_XY p2 ( x,-y);trsf.Transforms(p2);gp_Pnt P2(p2.X(),p2.Y(),0.0f);
|
||||
gp_XY p3 ( x, y);trsf.Transforms(p3);gp_Pnt P3(p3.X(),p3.Y(),0.0f);
|
||||
gp_XY p4 (-x, y);trsf.Transforms(p4);gp_Pnt P4(p4.X(),p4.Y(),0.0f);
|
||||
|
||||
BRepBuilderAPI_MakeWire w;
|
||||
w.Add(BRepBuilderAPI_MakeEdge(P1,P2));
|
||||
w.Add(BRepBuilderAPI_MakeEdge(P2,P3));
|
||||
w.Add(BRepBuilderAPI_MakeEdge(P3,P4));
|
||||
w.Add(BRepBuilderAPI_MakeEdge(P4,P1));
|
||||
wire = w.Wire();
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(IfcSchema::Polyline* IfcPolyline, TopoDS_Wire& result) {
|
||||
IfcEntities points = IfcPolyline->Points();
|
||||
|
||||
BRepBuilderAPI_MakeWire w;
|
||||
for( IfcParse::Entities::it it = points->begin(); it != points->end(); ++ it ) {
|
||||
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();
|
||||
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);
|
||||
w.Add(e);
|
||||
}
|
||||
|
||||
result = w.Wire();
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(IfcSchema::Polyloop* IfcPolyloop, TopoDS_Wire& result) {
|
||||
return IfcGeom::convert((IfcSchema::Polyline*)IfcPolyloop,result);
|
||||
}
|
||||
bool IfcGeom::convert(IfcSchema::Axis2Placement3D* IfcAxis2Placement3D, gp_Trsf& trsf) {
|
||||
gp_Pnt o;gp_Vec x = gp_Vec(1,0,0);gp_Vec z = gp_Vec(0,0,1);
|
||||
|
||||
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);
|
||||
} catch( IfcParse::IfcException& ) {}
|
||||
|
||||
gp_Ax3 axis(o,z,x);
|
||||
gp_Ax3 def(gp_Pnt(),gp_Dir(0,0,1),gp_Dir(1,0,0));
|
||||
trsf.SetTransformation(axis,def);
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(IfcSchema::Plane* IfcPlane, gp_Pln& plane) {
|
||||
IfcSchema::Axis2Placement3D* IfcAxis2Placement3D = (IfcSchema::Axis2Placement3D*) IfcPlane->Placement().get();
|
||||
gp_Pnt o;gp_Vec x;gp_Vec z;
|
||||
|
||||
IfcGeom::convert((IfcSchema::CartesianPoint*) IfcAxis2Placement3D->Origin().get(),o);
|
||||
IfcGeom::convert((IfcSchema::Direction*) IfcAxis2Placement3D->Dir1().get(),z);
|
||||
IfcGeom::convert((IfcSchema::Direction*) IfcAxis2Placement3D->Dir2().get(),x);
|
||||
|
||||
gp_Ax3 axis(o,z,x);
|
||||
plane = gp_Pln(axis);
|
||||
return true;
|
||||
}
|
||||
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()));
|
||||
trsf.SetTransformation(axis,gp_Ax2d());
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(IfcSchema::LocalPlacement* IfcLocalPlacement, gp_Trsf& trsf) {
|
||||
while (1) {
|
||||
gp_Trsf trsf2;
|
||||
IfcGeom::convert((IfcSchema::Axis2Placement3D*) IfcLocalPlacement->Placement().get(),trsf2);
|
||||
trsf.PreMultiply(trsf2);
|
||||
try {
|
||||
IfcLocalPlacement = (IfcSchema::LocalPlacement*) IfcLocalPlacement->Parent().get();
|
||||
} catch ( IfcParse::IfcException ) { break; }
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert_openings(const IfcSchema::BuildingElement* IfcBuildingElement,
|
||||
const IfcEntities openings, TopoDS_Shape& result, const gp_Trsf& trsf2) {
|
||||
for ( IfcParse::Entities::it it = openings->begin(); it != openings->end(); ++ it ) {
|
||||
IfcSchema::RelVoidsElement* IfcRelVoidsElement = (IfcSchema::RelVoidsElement*)(*it).get();
|
||||
IfcSchema::BuildingElement* IfcOpeningElement = (IfcSchema::BuildingElement*) IfcRelVoidsElement->Opening().get();
|
||||
gp_Trsf trsf;
|
||||
IfcGeom::convert((IfcSchema::LocalPlacement*) IfcOpeningElement->Placement().get(),trsf);
|
||||
gp_Trsf trsf3 = trsf2.Inverted();
|
||||
IfcSchema::ProductDefinitionShape* IfcProductDefinitionShape = (IfcSchema::ProductDefinitionShape*) IfcOpeningElement->Shape().get();
|
||||
IfcEntities IfcShapeReps = IfcProductDefinitionShape->ShapeReps();
|
||||
for ( IfcParse::Entities::it shaperep = IfcShapeReps->begin(); shaperep != IfcShapeReps->end(); ++shaperep ) {
|
||||
IfcSchema::ShapeRepresentation* IfcShapeRepresentation = (IfcSchema::ShapeRepresentation*) (*shaperep).get();
|
||||
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;
|
||||
s.Move(trsf);
|
||||
s.Move(trsf3);
|
||||
result = BRepAlgoAPI_Cut(result,s);
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face) {
|
||||
BRepBuilderAPI_MakeFace mf = BRepBuilderAPI_MakeFace(wire);
|
||||
BRepBuilderAPI_FaceError er = mf.Error();
|
||||
if ( er == BRepBuilderAPI_NotPlanar ) {
|
||||
std::cout << "[Notice] Trying to fix non-planar face" << std::endl;
|
||||
ShapeFix_ShapeTolerance FTol;
|
||||
FTol.SetTolerance(wire, 0.01, TopAbs_WIRE);
|
||||
mf = BRepBuilderAPI_MakeFace(wire);
|
||||
er = mf.Error();
|
||||
}
|
||||
if ( er != BRepBuilderAPI_FaceDone ) return false;
|
||||
face = mf.Face();
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,67 @@
|
||||
#ifndef IFCGEOM_H
|
||||
#define IFCGEOM_H
|
||||
#include "../ifcparse/IfcParse.h"
|
||||
#include "../ifcparse/IfcTypes.h"
|
||||
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec2d.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>
|
||||
|
||||
#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 <BRepOffsetAPI_Sewing.hxx>
|
||||
#include <BRepBuilderAPI_MakeFace.hxx>
|
||||
#include <BRepBuilderAPI_MakeEdge.hxx>
|
||||
#include <BRepBuilderAPI_MakeWire.hxx>
|
||||
#include <BRepBuilderAPI_MakePolygon.hxx>
|
||||
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
|
||||
#include <BRepPrimAPI_MakePrism.hxx>
|
||||
#include <BRepBuilderAPI_MakeShell.hxx>
|
||||
#include <BRepBuilderAPI_MakeSolid.hxx>
|
||||
#include <BRepPrimAPI_MakeHalfSpace.hxx>
|
||||
#include <BRepAlgoAPI_Cut.hxx>
|
||||
|
||||
#include <ShapeFix_Shape.hxx>
|
||||
#include <ShapeFix_ShapeTolerance.hxx>
|
||||
|
||||
#include <TopLoc_Location.hxx>
|
||||
|
||||
#define SCALE 1000.0f
|
||||
|
||||
/*
|
||||
namespace IFCgeom {
|
||||
bool convert( Entity* L, gp_Vec*& CC );
|
||||
bool convert( Entity* L, gp_Pnt*& CC );
|
||||
bool convert( Entity* L, gp_Vec2d*& CC );
|
||||
bool convert( Entity* L, gp_Pnt2d*& CC );
|
||||
bool convert ( Entity* L, gp_Ax3*& ax3 );
|
||||
bool convert ( Entity* L, gp_Trsf*& trsf );
|
||||
bool convert ( Entity* L, gp_Trsf2d*& trsf );
|
||||
bool convert ( Entity* L, gp_Pln*& pln );
|
||||
bool convert ( const Entity* L, TopoDS_Wire& wire, int& count );
|
||||
bool convert( const Entity* L, TopoDS_Face& face);
|
||||
bool convert( const Entity* L, TopoDS_Shape& shape);
|
||||
bool move ( const Entity* L, gp_Trsf& trsf );
|
||||
bool move ( const Entity* L, TopoDS_Shape& shape );
|
||||
bool hasopenings( const Entity* L );
|
||||
bool open( const Entity* L, TopoDS_Shape& shape );
|
||||
bool open( const Entity* L, TopoDS_Shape& shape, gp_Trsf trsf2 );
|
||||
}
|
||||
*/
|
||||
#endif
|
||||
@@ -0,0 +1,275 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include <map>
|
||||
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <TopoDS_Compound.hxx>
|
||||
#include <BRep_Builder.hxx>
|
||||
#include <BRepTools.hxx>
|
||||
#include <BRep_Tool.hxx>
|
||||
#include <TopExp_Explorer.hxx>
|
||||
#include <BRepMesh.hxx>
|
||||
#include <Poly_Triangulation.hxx>
|
||||
#include <Poly_PolygonOnTriangulation.hxx>
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TShort_Array1OfShortReal.hxx>
|
||||
#include <Poly_Array1OfTriangle.hxx>
|
||||
|
||||
#include "../ifcparse/IfcGeomObjects.h"
|
||||
#include "../ifcparse/IfcGeom.h"
|
||||
#include "../ifcparse/IfcEnum.h"
|
||||
#include "../ifcparse/IfcTypes.h"
|
||||
|
||||
// Welds vertices that belong to different faces
|
||||
int IfcGeomObjects::IfcMesh::addvert(gp_Pnt p) {
|
||||
int i = 0; const float X = (float)p.X();const float Y = (float)p.Y();const float Z = (float)p.Z();
|
||||
for ( std::vector<float>::const_iterator it = verts.begin(); it != verts.end(); ) {
|
||||
const float x = *it; ++it;
|
||||
const float y = *it; ++it;
|
||||
const float z = *it; ++it;
|
||||
if ( X == x && Y == y && Z == z ) return i;
|
||||
++i;
|
||||
}
|
||||
verts.push_back(X);
|
||||
verts.push_back(Y);
|
||||
verts.push_back(Z);
|
||||
return i;
|
||||
}
|
||||
|
||||
IfcGeomObjects::IfcMesh::IfcMesh(int i, TopoDS_Shape s) {
|
||||
id = i;
|
||||
|
||||
// Triangulate the shape
|
||||
try {
|
||||
BRepTools::Clean(s);
|
||||
BRepMesh::Mesh(s,0.001f);
|
||||
} catch(...) {
|
||||
std::cout << "[Error] Failed to triangulate IFC Entity #" << i << std::endl;
|
||||
return;
|
||||
}
|
||||
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;
|
||||
|
||||
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 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
IfcGeomObjects::IfcGeomObject::IfcGeomObject( const std::string& n, const std::string& t, gp_Trsf trsf, IfcMesh* m ) {
|
||||
// Convert the gp_Trsf into a 4x3 Matrix
|
||||
for( int i = 1; i < 5; ++ i )
|
||||
for ( int j = 1; j < 4; ++ j )
|
||||
matrix.push_back((float)trsf.Value(j,i));
|
||||
|
||||
name = n;
|
||||
type = t;
|
||||
mesh = m;
|
||||
}
|
||||
|
||||
// A container and iterator for IfcShapeRepresentations
|
||||
IfcEntities shapereps;
|
||||
IfcParse::Entities::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_Compound shapes;
|
||||
|
||||
// The object is fetched beforehand to be positive an entity actually exists
|
||||
IfcGeomObjects::IfcGeomObject* currentGeomObj;
|
||||
|
||||
// A container and iterator for IfcBuildingElements for the current IfcShapeRepresentation referenced by *outer
|
||||
IfcEntities entities;
|
||||
IfcParse::Entities::it inner;
|
||||
|
||||
bool use_world_coords;
|
||||
int done;
|
||||
int total;
|
||||
|
||||
// Move the the next IfcShapeRepresentation
|
||||
void _nextShape() {
|
||||
if ( shape ) delete shape;
|
||||
shapes.Nullify();
|
||||
shape = 0;
|
||||
entities.reset();
|
||||
++ outer;
|
||||
++ done;
|
||||
}
|
||||
|
||||
// Returns the current IfcGeomObject*
|
||||
IfcGeomObjects::IfcGeomObject* _get() {
|
||||
while ( true ) {
|
||||
IfcEntity shaperep;
|
||||
if ( outer == shapereps->end() ) {
|
||||
shapereps.reset();
|
||||
return 0;
|
||||
}
|
||||
shaperep = *outer;
|
||||
if ( ! entities ) {
|
||||
if ( shaperep->arg(1)->s() != "Body" ) {
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
#ifdef _DEBUG
|
||||
std::cout << shaperep->toString() << std::endl;
|
||||
#endif
|
||||
// Find the IfcBuildingElements that refer to the current IfcShapeRepresentation
|
||||
entities = shaperep->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::IfcProductDefinitionShape)->parents());
|
||||
if ( ! entities->size ) {
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
inner = entities->begin();
|
||||
}
|
||||
if ( inner == entities->end() ) {
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
if ( shapes.IsNull() ) {
|
||||
BRep_Builder builder;
|
||||
builder.MakeCompound (shapes);
|
||||
|
||||
bool hasShapes = false;
|
||||
IfcEntities l = ((IfcSchema::ShapeRepresentation*)shaperep.get())->Shapes();
|
||||
for( IfcParse::Entities::it it = l->begin(); it != l->end(); ++ it ) {
|
||||
const IfcEntity ifcshape = *it;
|
||||
if ( ifcshape->dt == IfcSchema::Enum::IfcMappedItem ) continue;
|
||||
TopoDS_Shape ss;
|
||||
if ( IfcGeom::convert_shape(ifcshape,ss) ) {
|
||||
builder.Add(shapes,ss);
|
||||
hasShapes = true;
|
||||
#ifdef _DEBUG
|
||||
std::cout << ifcshape->toString() << std::endl;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
if ( ! hasShapes || shapes.IsNull() ) {
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
IfcSchema::BuildingElement* entity = (IfcSchema::BuildingElement*)(*inner).get();
|
||||
#ifdef _DEBUG
|
||||
std::cout << entity->toString() << std::endl;
|
||||
#endif
|
||||
const std::string guid = entity->Guid();
|
||||
gp_Trsf trsf;
|
||||
try {
|
||||
IfcGeom::convert((IfcSchema::LocalPlacement*)(entity->Placement().get()),trsf);
|
||||
} catch( IfcParse::IfcException& e ) {std::cout << "[Error] " << e.what() << std::endl; _nextShape(); }
|
||||
IfcEntities openings = IfcEntities();
|
||||
if ( entity->dt != IfcSchema::Enum::IfcOpeningElement ) {
|
||||
openings = entity->parents(IfcSchema::Enum::IfcRelVoidsElement);
|
||||
}
|
||||
|
||||
if ( (openings && openings->size) || use_world_coords ) {
|
||||
if ( shape ) delete shape;
|
||||
TopoDS_Shape temp_shape (shapes);
|
||||
try {
|
||||
if (openings && openings->size) IfcGeom::convert_openings(entity,openings,temp_shape,trsf);
|
||||
} catch( IfcParse::IfcException& e ) {std::cout << "[Warning] " << e.what() << std::endl; }
|
||||
if ( use_world_coords ) {
|
||||
shape = new IfcGeomObjects::IfcMesh(shaperep->id,temp_shape.Moved(trsf));
|
||||
trsf = gp_Trsf();
|
||||
} else {
|
||||
shape = new IfcGeomObjects::IfcMesh(shaperep->id,temp_shape);
|
||||
}
|
||||
} else if ( ! shape ) {
|
||||
shape = new IfcGeomObjects::IfcMesh(shaperep->id,shapes);
|
||||
}
|
||||
return new IfcGeomObjects::IfcGeomObject(guid, entity->datatype(), trsf, shape);
|
||||
}
|
||||
}
|
||||
|
||||
extern bool IfcGeomObjects::Next() {
|
||||
if ( entities ) {
|
||||
++inner;
|
||||
}
|
||||
delete currentGeomObj;
|
||||
currentGeomObj = _get();
|
||||
if ( ! currentGeomObj ) {
|
||||
delete shape;
|
||||
Ifc::Dispose();
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
extern const IfcGeomObjects::IfcGeomObject* IfcGeomObjects::Get() {
|
||||
return currentGeomObj;
|
||||
}
|
||||
extern bool IfcGeomObjects::Init(char* fn, bool world_coords) {
|
||||
use_world_coords = world_coords;
|
||||
if ( !Ifc::Init(fn) ) return false;
|
||||
|
||||
shapereps = Ifc::EntitiesByType(IfcSchema::Enum::IfcShapeRepresentation);
|
||||
if ( ! shapereps ) return false;
|
||||
|
||||
outer = shapereps->begin();
|
||||
entities.reset();
|
||||
currentGeomObj = _get();
|
||||
|
||||
if ( ! currentGeomObj ) return false;
|
||||
|
||||
done = 0;
|
||||
total = shapereps->size;
|
||||
return 1;
|
||||
}
|
||||
extern int IfcGeomObjects::Progress() {
|
||||
return 100 * done / total;
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* Geometrical data in an IFC file consists of shapes (IfcShapeRepresentation) *
|
||||
* and instances (SUBTYPE OF IfcBuildingElement e.g. IfcWindow). *
|
||||
* *
|
||||
* IfcMesh is a class that represents a triangulated IfcShapeRepresentation. *
|
||||
* IfcMesh.verts is a 1 dimensional vector of float defining the cartesian *
|
||||
* coordinates of the vertices of the triangulated shape in the format of *
|
||||
* [x1,y1,z1,..,xn,yn,zn] *
|
||||
* IfcMesh.faces is a 1 dimensional vector of int containing the indices of *
|
||||
* the triangles referencing positions in IfcMesh.verts *
|
||||
* IfcMesh.edges is a 1 dimensional vector of int in {0,1} that dictates *
|
||||
* the visibility of the edges that span the faces in IfcMesh.faces *
|
||||
* *
|
||||
* IfcGeomObject represents the actual IfcBuildingElements. *
|
||||
* IfcGeomObject.name is the GUID of the element *
|
||||
* IfcGeomObject.type is the datatype of the element e.g. IFCWINDOW *
|
||||
* IfcGeomObject.mesh is a pointer to an IfcMesh *
|
||||
* 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
|
||||
* *
|
||||
* Get() returns a pointer to the current IfcGeomObject
|
||||
* *
|
||||
* Next() returns true if there is an entity yet available
|
||||
* *
|
||||
* Progress() returns an int in [0..100] that indicates the overall progress
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCOBJECTS_H
|
||||
#define IFCOBJECTS_H
|
||||
|
||||
#include <map>
|
||||
#include <vector>
|
||||
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
|
||||
namespace IfcGeomObjects {
|
||||
|
||||
typedef std::vector<int>::const_iterator IntIt;
|
||||
typedef std::vector<float>::const_iterator FltIt;
|
||||
|
||||
class IfcMesh {
|
||||
public:
|
||||
int id;
|
||||
std::vector<float> verts;
|
||||
std::vector<int> faces;
|
||||
std::vector<int> edges;
|
||||
|
||||
IfcMesh(int i, TopoDS_Shape s);
|
||||
private:
|
||||
int addvert(gp_Pnt p);
|
||||
inline void addedge(int n1, int n2, std::map<std::pair<int,int>,int>& edgecount, std::vector<std::pair<int,int> >& edges_temp) {
|
||||
if ( edgecount.find(std::pair<int,int>((std::min)(n1,n2),(std::max)(n1,n2))) == edgecount.end() )
|
||||
edgecount[std::pair<int,int>((std::min)(n1,n2),(std::max)(n1,n2))] = 0;
|
||||
edgecount[std::pair<int,int>((std::min)(n1,n2),(std::max)(n1,n2))] ++;
|
||||
edges_temp.push_back(std::pair<int,int>((std::min)(n1,n2),(std::max)(n1,n2)));
|
||||
}
|
||||
};
|
||||
|
||||
class IfcGeomObject {
|
||||
public:
|
||||
std::string name;
|
||||
std::string type;
|
||||
std::vector<float> matrix;
|
||||
IfcMesh* mesh;
|
||||
IfcGeomObject( const std::string& n, const std::string& t, gp_Trsf trsf, IfcMesh* m );
|
||||
};
|
||||
|
||||
extern bool Init(char* fn, bool world_coords = false);
|
||||
extern const IfcGeomObject* Get();
|
||||
extern bool Next();
|
||||
extern int Progress();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,193 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* Macro definitions that expand the schema definition in IfcSchema.h into *
|
||||
* C++ code. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#undef IFC_CLASS
|
||||
#undef IFC_SHAPE_CLASS
|
||||
#undef IFC_FACE_CLASS
|
||||
#undef IFC_SKIP_CLASS
|
||||
#undef IFC_WIRE_CLASS
|
||||
#undef IFC_HELPER_CLASS
|
||||
#undef IFC_END_CLASS
|
||||
#undef IFC_REF
|
||||
#undef IFC_REFS
|
||||
#undef IFC_FLT
|
||||
#undef IFC_FLT_SUB
|
||||
#undef IFC_INT
|
||||
#undef IFC_STR
|
||||
#undef IFC_BOOL
|
||||
|
||||
#ifdef IFC_PARSE_HEADER
|
||||
#define IFC_CLASS(N,T) class N : public IfcParse::Entity { public:
|
||||
#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_HELPER_CLASS(N) IFC_CLASS(N,"")
|
||||
#define IFC_SKIP_CLASS(N)
|
||||
#define IFC_END_CLASS };
|
||||
#define IFC_REF(C,N,I) IfcEntity N();
|
||||
#define IFC_REFS(C,N,I) IfcEntities N();
|
||||
#define IFC_FLT(C,N,I) float N();
|
||||
#define IFC_FLT_SUB(C,N,I,J) float N();
|
||||
#define IFC_INT(C,N,I) int N();
|
||||
#define IFC_STR(C,N,I) std::string N();
|
||||
#define IFC_BOOL(C,N,I) bool N();
|
||||
#endif
|
||||
|
||||
#ifdef IFC_PARSE_SOURCE
|
||||
#define IFC_CLASS(N,T)
|
||||
#define IFC_SHAPE_CLASS(N)
|
||||
#define IFC_FACE_CLASS(N)
|
||||
#define IFC_WIRE_CLASS(N)
|
||||
#define IFC_HELPER_CLASS(N)
|
||||
#define IFC_SKIP_CLASS(N)
|
||||
#define IFC_END_CLASS
|
||||
#define IFC_REF(C,N,I) IfcEntity C::N() { return this->arg(I)->ref(); }
|
||||
#define IFC_REFS(C,N,I) IfcEntities C::N() { return this->arg(I)->refs(); }
|
||||
#define IFC_FLT(C,N,I) float C::N() { return this->arg(I)->f(); }
|
||||
#define IFC_FLT_SUB(C,N,I,J) float C::N() { return this->arg(I)->arg(J)->f(); }
|
||||
#define IFC_INT(C,N,I) int C::N() { return this->arg(I)->i(); }
|
||||
#define IFC_STR(C,N,I) std::string C::N() { return this->arg(I)->s(); }
|
||||
#define IFC_BOOL(C,N,I) bool C::N() { return this->arg(I)->b(); }
|
||||
#endif
|
||||
|
||||
#ifdef IFC_PARSE_ENUM
|
||||
#define IFC_SHAPE_CLASS(N) Ifc##N,
|
||||
#define IFC_WIRE_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,
|
||||
#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_PARSE_STR_ENUM
|
||||
#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_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; }
|
||||
#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_PARSE_ENUM_STR
|
||||
#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_HELPER_CLASS(N) IFC_SHAPE_CLASS(N)
|
||||
#define IFC_CLASS(N,T) IFC_SHAPE_CLASS(N)
|
||||
#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_GEOM_HEADER
|
||||
#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_HELPER_CLASS(N)
|
||||
#define IFC_CLASS(N,T) bool convert(IfcSchema::N* Ifc##N,T& result);
|
||||
#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_SHAPE_SRC
|
||||
#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_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_WIRE_SRC
|
||||
#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_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_FACE_SRC
|
||||
#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_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
|
||||
@@ -0,0 +1,398 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "../ifcparse/IfcParse.h"
|
||||
#include "../ifcparse/IfcEnum.h"
|
||||
#include "../ifcparse/IfcTypes.h"
|
||||
|
||||
using namespace IfcParse;
|
||||
|
||||
Argument::Argument(const std::string& s) {
|
||||
const char first = s[0];
|
||||
const int strlen = s.size();
|
||||
const char last = s[strlen-1];
|
||||
if ( first == '#' ) {
|
||||
type = IDENTIFIER;
|
||||
std::istringstream iss(s.substr(1));
|
||||
iss >> _data;
|
||||
} else if ( first == '(' || first == ')' || first == '=' || first == '$' || first == '*' || first == ';' || first == ',' ) {
|
||||
type = OPERATOR;
|
||||
_data = first;
|
||||
} else if ( first == '\'' && last == '\'' ) {
|
||||
type = STRING;
|
||||
_data = -1;
|
||||
std::string t = s.substr(1,s.size()-2);
|
||||
for ( int i = 0; i < (int)argstrings.size(); ++ i ) if ( argstrings[i] == t ) { _data = i; break; }
|
||||
if ( _data == -1 ) { _data = argstrings.size(); argstrings.push_back(t); }
|
||||
} else if ( first == '.' && last == '.' ) {
|
||||
type = ENUMERATION;
|
||||
_data = -1;
|
||||
std::string t = s.substr(1,s.size()-2);
|
||||
for ( int i = 0; i < (int)enumstrings.size(); ++ i ) if ( enumstrings[i] == t ) { _data = i; break; }
|
||||
if ( _data == -1 ) { _data = enumstrings.size(); enumstrings.push_back(t); }
|
||||
} else if ( ( first >= 48 && first <= 57 ) || first == '-' || first == '.' ) {
|
||||
type = NUMBER;
|
||||
std::istringstream iss(s);
|
||||
iss >> _number;
|
||||
} else {
|
||||
type = DATATYPE;
|
||||
_data = -1;
|
||||
for ( int i = 0; i < (int)datatypes.size(); ++ i ) if ( datatypes[i] == s ) { _data = i; break; }
|
||||
if ( _data == -1 ) { _data = datatypes.size(); datatypes.push_back(s); }
|
||||
}
|
||||
}
|
||||
std::string Argument::s() const {
|
||||
if ( type == OPERATOR ) { std::string r; r.push_back((char)_data); return r; }
|
||||
if ( type == DATATYPE ) return datatypes[_data];
|
||||
if ( type == STRING ) return argstrings[_data];
|
||||
if ( type == ENUMERATION ) return enumstrings[_data];
|
||||
throw IfcException();
|
||||
}
|
||||
float Argument::f() const {
|
||||
if ( type != NUMBER ) throw IfcException();
|
||||
return _number;
|
||||
}
|
||||
int Argument::i() const {
|
||||
if ( type != IDENTIFIER ) throw IfcException();
|
||||
return _data;
|
||||
}
|
||||
bool Argument::b() const {
|
||||
if ( type != ENUMERATION ) throw IfcException();
|
||||
return s() == "T";
|
||||
}
|
||||
bool Argument::isOp(char op) const {
|
||||
return type == OPERATOR && ( op == 0 || op == ((char)_data) );
|
||||
}
|
||||
std::string Argument::toString() const {
|
||||
if ( type == DATATYPE ) return s();
|
||||
else if ( type == OPERATOR ) return s();
|
||||
std::stringstream ss;
|
||||
if ( type == NUMBER ) ss << f();
|
||||
else if ( type == STRING ) ss << "'" << s() << "'";
|
||||
else if ( type == ENUMERATION ) ss << "." << s() << ".";
|
||||
else if ( type == IDENTIFIER ) ss << "#" << i();
|
||||
return ss.str();
|
||||
}
|
||||
std::vector<std::string> Argument::datatypes;
|
||||
std::vector<std::string> Argument::argstrings;
|
||||
std::vector<std::string> Argument::enumstrings;
|
||||
|
||||
ArgumentList::ArgumentList() {
|
||||
_levels.push_back(this);
|
||||
_current = this;
|
||||
_arg = 0;
|
||||
}
|
||||
void ArgumentList::_push() {
|
||||
ArgumentList* a = new ArgumentList();
|
||||
_levels.push_back(a);
|
||||
_args.push_back(a);
|
||||
_current = a;
|
||||
}
|
||||
void ArgumentList::_pop() {
|
||||
if ( _levels.empty() ) return;
|
||||
_current = _levels.back();
|
||||
_levels.pop_back();
|
||||
}
|
||||
void ArgumentList::_append(const Argument* v) {
|
||||
ArgumentList* a = new ArgumentList();
|
||||
a->_arg = v;
|
||||
_current->_args.push_back(a);
|
||||
}
|
||||
|
||||
std::string ArgumentList::toString() const {
|
||||
if ( _arg ) return _arg->toString();
|
||||
std::stringstream ss; ss << "(";
|
||||
std::vector<ArgumentList*>::const_iterator it;
|
||||
for ( it = _args.begin() ; it != _args.end(); ++ it ) {
|
||||
if ( it != _args.begin() ) ss << ",";
|
||||
ss << (*it)->toString();
|
||||
}
|
||||
ss << ")";
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
float ArgumentList::f() const { return _arg->f(); }
|
||||
bool ArgumentList::b() const { return _arg->b(); }
|
||||
int ArgumentList::i() const { return _arg->i(); }
|
||||
std::string ArgumentList::s() const { return _arg->s(); }
|
||||
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());
|
||||
}
|
||||
EntitiesPtr ArgumentList::refs() const {
|
||||
EntitiesPtr l (new Entities());
|
||||
std::vector<ArgumentList*>::const_iterator it;
|
||||
for ( it = _args.begin(); it != _args.end(); ++ it ) {
|
||||
ArgumentList* a = *it;
|
||||
if ( a->_arg && a->_arg->type == Argument::IDENTIFIER ) {
|
||||
l->push(Ifc::EntityById(a->_arg->i()));
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
ArgumentList::~ArgumentList() {
|
||||
if ( _arg ) delete _arg;
|
||||
else {
|
||||
while( ! _args.empty() ) {
|
||||
delete _args.back(); _args.pop_back();
|
||||
}
|
||||
}
|
||||
}
|
||||
inline bool Entity::term(char last) {
|
||||
return last == '(' || last == ')' || last == '=' || last == ',' || last == ';';
|
||||
}
|
||||
Entity::Entity(std::istream* ss, std::vector<int>& refs) {
|
||||
std::string curvar;
|
||||
curvar.reserve(64);
|
||||
bool inStr = false;
|
||||
char c[1] = "";
|
||||
int state = -1;
|
||||
args = 0;
|
||||
_dt = 0;
|
||||
id = -1;
|
||||
do {
|
||||
ss->read(c,1);
|
||||
if ( !inStr && ((*c) == ' ' || (*c) == '\r' || (*c) == '\n' || (*c) == '\t') ) continue;
|
||||
if ( curvar.size() && !inStr && ( term(*c) || term(*curvar.rbegin())) ) {
|
||||
Argument* v = new Argument(curvar);
|
||||
curvar.clear();
|
||||
curvar.push_back(*c);
|
||||
if ( state < 10 ) state ++;
|
||||
if ( state == 0 ) {
|
||||
if ( v->type == Argument::IDENTIFIER ) {
|
||||
id = v->i();
|
||||
} else {
|
||||
state = -1;
|
||||
}
|
||||
} else if ( state == 1 ) {
|
||||
if ( ! v->isOp('=') ) state = -1;
|
||||
} else if ( 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;
|
||||
}
|
||||
} else if ( v->isOp('(') ) {
|
||||
args = new ArgumentList();
|
||||
}
|
||||
delete v;
|
||||
} else curvar.push_back(*c);
|
||||
if ( *c == '\'' ) inStr = !inStr;
|
||||
} while ( !ss->eof() && (*c != ';' || inStr) );
|
||||
}
|
||||
Entity::~Entity() {
|
||||
delete args;
|
||||
delete _dt;
|
||||
}
|
||||
bool Entity::isAssignment() const {
|
||||
return args > 0;
|
||||
}
|
||||
std::string Entity::datatype() const {
|
||||
if ( _dt ) return _dt->s();
|
||||
else return IfcSchema::Enum::ToString(dt);
|
||||
}
|
||||
ArgumentList* Entity::arg(int i) const {
|
||||
return this->args->arg(i);
|
||||
}
|
||||
std::string Entity::toString() const {
|
||||
std::stringstream ss;
|
||||
if ( isAssignment() ) {
|
||||
ss << "#" << id << "=" << datatype() << args->toString();
|
||||
}
|
||||
return ss.str();
|
||||
}
|
||||
EntitiesPtr Entity::parents(IfcSchema::Enum::IfcTypes c) {
|
||||
EntitiesPtr l = EntitiesPtr(new Entities());
|
||||
EntitiesPtr all = Ifc::EntitiesByReference(id);
|
||||
if ( ! all ) return l;
|
||||
for( Entities::it it = all->begin(); it != all->end();++ it ) {
|
||||
if ( c == IfcSchema::Enum::ALL || (*it)->dt == c ) {
|
||||
l->push(*it);
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
EntitiesPtr Entity::parents(IfcSchema::Enum::IfcTypes c, int i, const std::string& a) {
|
||||
EntitiesPtr l = EntitiesPtr(new Entities());
|
||||
EntitiesPtr all = parents(c);
|
||||
for( Entities::it it = all->begin(); it != all->end();++ it ) {
|
||||
if ( (*it)->arg(i)->s() == a ) {
|
||||
l->push(*it);
|
||||
}
|
||||
}
|
||||
return l;
|
||||
}
|
||||
|
||||
void Entities::push(EntityPtr l) {
|
||||
if ( l ) {
|
||||
ls.push_back(l);
|
||||
size = ls.size();
|
||||
}
|
||||
}
|
||||
void Entities::pushs(EntitiesPtr l) {
|
||||
for( it i = l->begin(); i != l->end(); ++i ) {
|
||||
if ( *i ) ls.push_back(*i);
|
||||
}
|
||||
size = ls.size();
|
||||
}
|
||||
Entities::it Entities::begin() { return ls.begin(); }
|
||||
Entities::it Entities::end() { return ls.end(); }
|
||||
EntitiesPtr Entities::parents(IfcSchema::Enum::IfcTypes c) {
|
||||
EntitiesPtr l = EntitiesPtr(new Entities());
|
||||
for( it i = begin(); i != end(); ++i ) {
|
||||
l->pushs((*i)->parents(c));
|
||||
}
|
||||
return l;
|
||||
}
|
||||
EntitiesPtr Entities::parents(IfcSchema::Enum::IfcTypes c, int ar, const std::string& a) {
|
||||
EntitiesPtr l = EntitiesPtr(new Entities());
|
||||
for( it i = begin(); i != end(); ++i ) {
|
||||
l->pushs((*i)->parents(c,ar,a));
|
||||
}
|
||||
return l;
|
||||
}
|
||||
EntityPtr Entities::operator[] (int i) {
|
||||
return ls[i];
|
||||
}
|
||||
Entities::Entities() {
|
||||
size = 0;
|
||||
}
|
||||
|
||||
File::File(std::string fn, bool debug) {
|
||||
valid = false;
|
||||
std::ifstream f(fn.c_str());
|
||||
if ( ! f.is_open() ) return;
|
||||
valid = true;
|
||||
std::istream *pf = (std::istream*) &f;
|
||||
while( !pf->eof() ) {
|
||||
std::vector<int> refs;
|
||||
EntityPtr il (new Entity(pf,refs));
|
||||
if ( il->isAssignment() ) {
|
||||
if ( debug )
|
||||
std::cout << il->toString();
|
||||
if ( il->dt == IfcSchema::Enum::IfcDontCare ) {
|
||||
continue;
|
||||
}
|
||||
EntitiesPtr l = EntitiesByType(il->dt);
|
||||
if ( l == 0 ) {
|
||||
l = EntitiesPtr(new Entities());
|
||||
bytype[il->dt] = l;
|
||||
}
|
||||
l->push(il);
|
||||
byid[il->id] = il;
|
||||
|
||||
std::vector<int>::const_iterator it;
|
||||
for( it = refs.begin(); it != refs.end();++ it ) {
|
||||
const int _id = *it;
|
||||
EntitiesPtr L = EntitiesByReference(_id);
|
||||
if ( L == 0 ) {
|
||||
L = EntitiesPtr(new Entities());
|
||||
byref[_id] = L;
|
||||
}
|
||||
L->push(il);
|
||||
}
|
||||
}
|
||||
}
|
||||
f.close();
|
||||
}
|
||||
EntitiesPtr File::EntitiesByType(IfcSchema::Enum::IfcTypes t) {
|
||||
std::map<IfcSchema::Enum::IfcTypes,EntitiesPtr>::const_iterator it;
|
||||
it = bytype.find(t);
|
||||
return (it == bytype.end()) ? EntitiesPtr() : (*it).second;
|
||||
}
|
||||
EntitiesPtr File::EntitiesByReference(int t) {
|
||||
std::map<int,EntitiesPtr>::const_iterator it;
|
||||
it = byref.find(t);
|
||||
return (it == byref.end()) ? EntitiesPtr() : (*it).second;
|
||||
}
|
||||
EntityPtr File::EntityById(int id) {
|
||||
std::map<int,EntityPtr>::const_iterator it;
|
||||
it = byid.find(id);
|
||||
if ( it == byid.end() ) throw IfcException(id);
|
||||
return (*it).second;
|
||||
}
|
||||
IfcException::IfcException(int id) {
|
||||
std::stringstream ss;
|
||||
ss << "Unable to find IFC Entity #" << id;
|
||||
w = ss.str();
|
||||
}
|
||||
|
||||
IfcException::IfcException() {
|
||||
w = "Unexpected argument supplied";
|
||||
}
|
||||
|
||||
const char* IfcException::what() const throw(){ return w.c_str(); }
|
||||
IfcException::~IfcException() throw(){ }
|
||||
|
||||
EntitiesPtr Ifc::EntitiesByType(IfcSchema::Enum::IfcTypes t) {
|
||||
return f->EntitiesByType(t);
|
||||
}
|
||||
EntitiesPtr Ifc::EntitiesByReference(int t) {
|
||||
return f->EntitiesByReference(t);
|
||||
}
|
||||
EntityPtr Ifc::EntityById(int id) {
|
||||
return f->EntityById(id);
|
||||
}
|
||||
bool Ifc::Init(std::string fn) {
|
||||
f = new File(fn, false);
|
||||
IfcEntities units = EntitiesByType(IfcSchema::Enum::IfcSIUnit);
|
||||
Ifc::Scale = 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;
|
||||
}
|
||||
}
|
||||
return f->valid;
|
||||
}
|
||||
void Ifc::Dispose() {
|
||||
delete f;
|
||||
Argument::datatypes.clear();
|
||||
Argument::argstrings.clear();
|
||||
Argument::enumstrings.clear();
|
||||
}
|
||||
File* Ifc::f = 0;
|
||||
float Ifc::Scale = 1.0f;
|
||||
@@ -0,0 +1,189 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCPARSE_H
|
||||
#define IFCPARSE_H
|
||||
|
||||
#include <string>
|
||||
#include <sstream>
|
||||
#include <iostream>
|
||||
#include <vector>
|
||||
#include <fstream>
|
||||
#include <cstring>
|
||||
#include <map>
|
||||
#include <exception>
|
||||
|
||||
// Pick a shared pointer implementation
|
||||
#ifdef __GNUC__
|
||||
#include <tr1/memory>
|
||||
#define SHARED_PTR std::tr1::shared_ptr
|
||||
#else
|
||||
#ifdef _MSC_VER
|
||||
#include <memory>
|
||||
#define SHARED_PTR std::tr1::shared_ptr
|
||||
#else
|
||||
#include <boost/shared_ptr.hpp>
|
||||
#define SHARED_PTR boost::shared_ptr
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#include "../ifcparse/IfcEnum.h"
|
||||
|
||||
class Ifc;
|
||||
|
||||
namespace IfcParse {
|
||||
|
||||
class Argument {
|
||||
private:
|
||||
static std::vector<std::string> datatypes;
|
||||
static std::vector<std::string> enumstrings;
|
||||
static std::vector<std::string> argstrings;
|
||||
|
||||
int _data;
|
||||
float _number;
|
||||
public:
|
||||
enum vartype { IDENTIFIER, STRING, NUMBER, OPERATOR, ENUMERATION, DATATYPE };
|
||||
vartype type;
|
||||
|
||||
Argument(const std::string& s);
|
||||
|
||||
bool isOp(char op = 0) const;
|
||||
|
||||
float f() const;
|
||||
int i() const;
|
||||
std::string s() const;
|
||||
bool b() const;
|
||||
|
||||
std::string toString() const;
|
||||
|
||||
std::string typeString() const;
|
||||
|
||||
friend class ::Ifc;
|
||||
};
|
||||
|
||||
class Entity;
|
||||
class Entities;
|
||||
typedef SHARED_PTR<Entity> EntityPtr;
|
||||
typedef SHARED_PTR<Entities> EntitiesPtr;
|
||||
|
||||
class ArgumentList {
|
||||
private:
|
||||
std::vector<ArgumentList*> _levels;
|
||||
std::vector<ArgumentList*> _args;
|
||||
ArgumentList* _current;
|
||||
const Argument* _arg;
|
||||
void _push();
|
||||
void _pop();
|
||||
void _append(const Argument* v);
|
||||
public:
|
||||
ArgumentList();
|
||||
~ArgumentList();
|
||||
|
||||
float f() const;
|
||||
int i() const;
|
||||
std::string s() const;
|
||||
bool b() const;
|
||||
EntityPtr ref() const;
|
||||
EntitiesPtr refs() const;
|
||||
ArgumentList* arg(int i) const;
|
||||
|
||||
int count() const;
|
||||
std::string toString() const;
|
||||
|
||||
friend class Entity;
|
||||
};
|
||||
|
||||
class Entity {
|
||||
private:
|
||||
inline bool term(char last);
|
||||
public:
|
||||
int id;
|
||||
IfcSchema::Enum::IfcTypes dt;
|
||||
ArgumentList* args;
|
||||
Argument* _dt;
|
||||
|
||||
Entity(std::istream* ss, std::vector<int>& refs);
|
||||
~Entity();
|
||||
|
||||
ArgumentList* arg(int i) const;
|
||||
std::string toString() const;
|
||||
|
||||
EntitiesPtr parents(IfcSchema::Enum::IfcTypes c = IfcSchema::Enum::ALL);
|
||||
EntitiesPtr parents(IfcSchema::Enum::IfcTypes c, int i, const std::string& a);
|
||||
bool isAssignment() const;
|
||||
std::string datatype() const;
|
||||
};
|
||||
|
||||
class Entities {
|
||||
private:
|
||||
std::vector<EntityPtr> ls;
|
||||
public:
|
||||
int size;
|
||||
typedef std::vector<EntityPtr>::const_iterator it;
|
||||
void push(EntityPtr l);
|
||||
void pushs(EntitiesPtr l);
|
||||
it begin();
|
||||
it end();
|
||||
EntitiesPtr parents(IfcSchema::Enum::IfcTypes c = IfcSchema::Enum::ALL);
|
||||
EntitiesPtr parents(IfcSchema::Enum::IfcTypes c, int i, const std::string& a);
|
||||
Entities();
|
||||
EntityPtr operator[] (int i);
|
||||
};
|
||||
|
||||
class File {
|
||||
public:
|
||||
std::map<IfcSchema::Enum::IfcTypes,EntitiesPtr> bytype;
|
||||
std::map<int,EntityPtr> byid;
|
||||
std::map<int,EntitiesPtr> byref;
|
||||
bool valid;
|
||||
|
||||
File(std::string fn, bool debug = false);
|
||||
EntitiesPtr EntitiesByType(IfcSchema::Enum::IfcTypes t);
|
||||
EntitiesPtr EntitiesByReference(int id);
|
||||
EntityPtr EntityById(int id);
|
||||
};
|
||||
|
||||
class IfcException : public std::exception {
|
||||
private:
|
||||
std::string w;
|
||||
public:
|
||||
IfcException(int id);
|
||||
IfcException();
|
||||
~IfcException() throw();
|
||||
virtual const char* what() const throw();
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
typedef IfcParse::EntityPtr IfcEntity;
|
||||
typedef IfcParse::EntitiesPtr IfcEntities;
|
||||
|
||||
class Ifc {
|
||||
private:
|
||||
static IfcParse::File* f;
|
||||
public:
|
||||
static IfcEntities EntitiesByType(IfcSchema::Enum::IfcTypes t);
|
||||
static IfcEntities EntitiesByReference(int id);
|
||||
static IfcEntity EntityById(int id);
|
||||
static bool Init(std::string fn);
|
||||
static void Dispose();
|
||||
static float Scale;
|
||||
};
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,196 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file provides a (quite ugly) partial reproduction of the entities *
|
||||
* defined in IFC2X3.exp. Macro's are used to expand the definitions into C++ *
|
||||
* code in various contexts, several enumerations, class defenitions and *
|
||||
* conversion functions. *
|
||||
* *
|
||||
* IFC_SHAPE_CLASS A class that will be mapped directly to a TopoDS_Shape *
|
||||
* IFC_FACE_CLASS A class that will be mapped directly to a TopoDS_Face *
|
||||
* IFC_WIRE_CLASS A class that will be mapped directly to a TopoDS_Wire *
|
||||
* These functions are automatically injected in *
|
||||
* IfcGeom::convert_shape and IfcGeom::convert_wire *
|
||||
* respectively and their function is called when the *
|
||||
* corresponding datatype is encountered. *
|
||||
* IFC_CLASS A class that will be mapped to another class aiding *
|
||||
* generation of shapes or wires. *
|
||||
* IFC_HELPER_CLASS A class that is not mapped to a geometrical representation *
|
||||
* but is included in IfcSchema::Enum and has a class def *
|
||||
* IFC_SKIP_CLASS This datatype will not be stored when encountered, use to *
|
||||
* save memory. Enumeration type: IfcDontCare. *
|
||||
* *
|
||||
* Other datatypes will be assigned IfcUnknown, but their *
|
||||
* datatypes can still be checked using string comparisons *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "../ifcparse/IfcMacro.h"
|
||||
|
||||
IFC_SHAPE_CLASS(ExtrudedAreaSolid)
|
||||
IFC_REF(ExtrudedAreaSolid,Profile,0)
|
||||
IFC_REF(ExtrudedAreaSolid,Placement,1)
|
||||
IFC_REF(ExtrudedAreaSolid,Dir,2)
|
||||
IFC_FLT(ExtrudedAreaSolid,Height,3)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_SHAPE_CLASS(FacetedBrep)
|
||||
IFC_REF(FacetedBrep,Shell,0)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_SHAPE_CLASS(ClosedShell)
|
||||
IFC_REFS(ClosedShell,Faces,0)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_SHAPE_CLASS(OpenShell)
|
||||
IFC_REFS(OpenShell,Faces,0)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_SHAPE_CLASS(ShellBasedSurfaceModel)
|
||||
IFC_REFS(ShellBasedSurfaceModel,Shells,0)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_SHAPE_CLASS(FaceBasedSurfaceModel)
|
||||
IFC_REFS(FaceBasedSurfaceModel,FaceSets,0)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_SHAPE_CLASS(ConnectedFaceSet)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_SHAPE_CLASS(HalfSpaceSolid)
|
||||
IFC_REF(HalfSpaceSolid,Surface,0)
|
||||
IFC_BOOL(HalfSpaceSolid,Flag,1)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_SHAPE_CLASS(PolygonalBoundedHalfSpace)
|
||||
IFC_REF(PolygonalBoundedHalfSpace,Surface,0)
|
||||
IFC_BOOL(PolygonalBoundedHalfSpace,Flag,1)
|
||||
IFC_REF(PolygonalBoundedHalfSpace,Placement,2)
|
||||
IFC_REF(PolygonalBoundedHalfSpace,Boundary,3)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_SHAPE_CLASS(BooleanClippingResult)
|
||||
IFC_REF(BooleanClippingResult,First,1)
|
||||
IFC_REF(BooleanClippingResult,Second,2)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_CLASS(Face,TopoDS_Face)
|
||||
IFC_REFS(Face,Bounds,0)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_HELPER_CLASS(FaceBound)
|
||||
IFC_REF(FaceBound,Loop,0)
|
||||
IFC_BOOL(FaceBound,Flag,1)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_CLASS(Plane,gp_Pln)
|
||||
IFC_REF(Plane,Placement,0)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_WIRE_CLASS(ArbitraryClosedProfileDef)
|
||||
IFC_REF(ArbitraryClosedProfileDef,Polyline,2)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_FACE_CLASS(ArbitraryProfileDefWithVoids)
|
||||
IFC_REF(ArbitraryProfileDefWithVoids,Polyline,2)
|
||||
IFC_REFS(ArbitraryProfileDefWithVoids,Voids,3)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_WIRE_CLASS(RectangleProfileDef)
|
||||
IFC_REF(RectangleProfileDef,Placement,2)
|
||||
IFC_FLT(RectangleProfileDef,Width,3)
|
||||
IFC_FLT(RectangleProfileDef,Height,4)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_CLASS(CartesianPoint,gp_Pnt)
|
||||
IFC_FLT_SUB(CartesianPoint,X,0,0)
|
||||
IFC_FLT_SUB(CartesianPoint,Y,0,1)
|
||||
IFC_FLT_SUB(CartesianPoint,Z,0,2)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_CLASS(Direction,gp_Vec)
|
||||
IFC_FLT_SUB(Direction,X,0,0)
|
||||
IFC_FLT_SUB(Direction,Y,0,1)
|
||||
IFC_FLT_SUB(Direction,Z,0,2)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_CLASS(Axis2Placement3D,gp_Trsf)
|
||||
IFC_REF(Axis2Placement3D,Origin,0)
|
||||
IFC_REF(Axis2Placement3D,Dir1,1)
|
||||
IFC_REF(Axis2Placement3D,Dir2,2)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_CLASS(Axis2Placement2D,gp_Trsf2d)
|
||||
IFC_REF(Axis2Placement2D,Origin,0)
|
||||
IFC_REF(Axis2Placement2D,Dir1,1)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_CLASS(LocalPlacement,gp_Trsf)
|
||||
IFC_REF(LocalPlacement,Parent,0)
|
||||
IFC_REF(LocalPlacement,Placement,1)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_WIRE_CLASS(Polyline)
|
||||
IFC_REFS(Polyline,Points,0)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_WIRE_CLASS(Polyloop)
|
||||
IFC_REFS(Polyloop,Points,0)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_HELPER_CLASS(BuildingElement)
|
||||
IFC_STR(BuildingElement,Guid,0)
|
||||
IFC_REF(BuildingElement,Owner,1)
|
||||
IFC_STR(BuildingElement,Name,2)
|
||||
IFC_REF(BuildingElement,Placement,5)
|
||||
IFC_REF(BuildingElement,Shape,6)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_HELPER_CLASS(ShapeRepresentation)
|
||||
IFC_REFS(ShapeRepresentation,Shapes,3)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_HELPER_CLASS(SIUnit)
|
||||
IFC_STR(SIUnit,Type,1)
|
||||
IFC_STR(SIUnit,Prefix,2)
|
||||
IFC_STR(SIUnit,Name,3)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_HELPER_CLASS(ProductDefinitionShape)
|
||||
IFC_REFS(ProductDefinitionShape,ShapeReps,2)
|
||||
IFC_END_CLASS
|
||||
IFC_HELPER_CLASS(RepresentationMap)
|
||||
IFC_END_CLASS
|
||||
IFC_HELPER_CLASS(MappedItem)
|
||||
IFC_END_CLASS
|
||||
IFC_HELPER_CLASS(RelVoidsElement)
|
||||
IFC_REF(RelVoidsElement,Opening,5)
|
||||
IFC_END_CLASS
|
||||
IFC_HELPER_CLASS(OpeningElement)
|
||||
IFC_END_CLASS
|
||||
|
||||
IFC_SKIP_CLASS(PropertySingleValue)
|
||||
IFC_SKIP_CLASS(PropertySet)
|
||||
IFC_SKIP_CLASS(ComplexProperty)
|
||||
IFC_SKIP_CLASS(RelDefinesByProperty)
|
||||
IFC_SKIP_CLASS(MaterialLayer)
|
||||
IFC_SKIP_CLASS(MaterialLayerSet)
|
||||
IFC_SKIP_CLASS(MaterialLayerSetUsage)
|
||||
@@ -0,0 +1,57 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include "StdFail_NotDone.hxx"
|
||||
|
||||
#include "../ifcparse/IfcTypes.h"
|
||||
#include "../ifcparse/IfcEnum.h"
|
||||
|
||||
using namespace IfcSchema;
|
||||
|
||||
#define IFC_PARSE_SOURCE
|
||||
#include "../ifcparse/IfcSchema.h"
|
||||
#undef IFC_PARSE_SOURCE
|
||||
|
||||
bool IfcGeom::convert_shape(const IfcEntity L, TopoDS_Shape &result) {
|
||||
if ( ! L ) return false;
|
||||
#define IFC_SHAPE_SRC
|
||||
#include "../ifcparse/IfcSchema.h"
|
||||
#undef IFC_SHAPE_SRC
|
||||
std::cout << "[Error] Failed to interpret:" << std::endl << L->toString() << std::endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
bool IfcGeom::convert_wire(const IfcEntity L, TopoDS_Wire &result) {
|
||||
if ( ! L ) return false;
|
||||
#define IFC_WIRE_SRC
|
||||
#include "../ifcparse/IfcSchema.h"
|
||||
#undef IFC_WIRE_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;
|
||||
#define IFC_FACE_SRC
|
||||
#include "../ifcparse/IfcSchema.h"
|
||||
#undef IFC_FACE_SRC
|
||||
std::cout << "[Error] Failed to interpret:" << std::endl << L->toString() << std::endl;
|
||||
return false;
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* This file is part of IfcOpenShell. *
|
||||
* *
|
||||
* IfcOpenShell is free software: you can redistribute it and/or modify *
|
||||
* it under the terms of the Lesser GNU General Public License as published by *
|
||||
* the Free Software Foundation, either version 3.0 of the License, or *
|
||||
* (at your option) any later version. *
|
||||
* *
|
||||
* IfcOpenShell is distributed in the hope that it will be useful, *
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
|
||||
* Lesser GNU General Public License for more details. *
|
||||
* *
|
||||
* You should have received a copy of the Lesser GNU General Public License *
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>. *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#ifndef IFCTYPES_H
|
||||
#define IFCTYPES_H
|
||||
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <gp_Trsf2d.hxx>
|
||||
#include <TopoDS.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
|
||||
#include "../ifcparse/IfcParse.h"
|
||||
|
||||
namespace IfcSchema {
|
||||
#define IFC_PARSE_HEADER
|
||||
#include "../ifcparse/IfcSchema.h"
|
||||
#undef IFC_PARSE_HEADER
|
||||
}
|
||||
|
||||
namespace IfcGeom {
|
||||
#define IFC_GEOM_HEADER
|
||||
#include "../ifcparse/IfcSchema.h"
|
||||
#undef IFC_GEOM_HEADER
|
||||
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_face(const IfcEntity L, TopoDS_Face& result);
|
||||
bool convert_openings(const IfcSchema::BuildingElement* IfcBuildingElement, const IfcEntities openings, TopoDS_Shape& result, const gp_Trsf& trsf);
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user