mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-17 14:02:27 +00:00
- Fixed a bug regarding IfcUnitAssignment
- Separate IFC parsing library and geometry libraries [#3395025] - Added example for IfcParse usage without geometry or Open CASCADE functionality - Cleanup of vcproj Open CASCADE dependencies - Added function to query parent class type in IfcExpressParser.py
This commit is contained in:
@@ -0,0 +1,50 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 IFCGEOM_H
|
||||
#define IFCGEOM_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 <TopoDS_Face.hxx>
|
||||
#include <Geom_Curve.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
|
||||
#include "../ifcparse/IfcParse.h"
|
||||
#include "../ifcparse/IfcUtil.h"
|
||||
|
||||
namespace IfcGeom {
|
||||
bool convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face);
|
||||
bool convert_shape(const SHARED_PTR<IfcUtil::IfcBaseClass>& L, TopoDS_Shape& result);
|
||||
bool convert_wire(const SHARED_PTR<IfcUtil::IfcBaseClass>& L, TopoDS_Wire& result);
|
||||
bool convert_curve(const SHARED_PTR<IfcUtil::IfcBaseClass>& L, Handle(Geom_Curve)& result);
|
||||
bool convert_face(const SHARED_PTR<IfcUtil::IfcBaseClass>& L, TopoDS_Face& result);
|
||||
bool convert_openings(const Ifc2x3::IfcProduct::ptr& L, const Ifc2x3::IfcRelVoidsElement::list& openings, TopoDS_Shape& result, const gp_Trsf& trsf);
|
||||
bool profile_helper(int numVerts, float* verts, int numFillets, int* filletIndices, float* filletRadii, gp_Trsf2d trsf, TopoDS_Face& face);
|
||||
namespace Cache {
|
||||
void Purge();
|
||||
void PurgeShapeCache();
|
||||
}
|
||||
#include "IfcRegisterGeomHeader.h"
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,116 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 defined in IfcRegister.h *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
#include <gp_Dir2d.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 <gp_Circ.hxx>
|
||||
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
#include <Geom_Line.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>
|
||||
#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 <BRepFilletAPI_MakeFillet2d.hxx>
|
||||
|
||||
#include <TopLoc_Location.hxx>
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcCircle::ptr& l, Handle(Geom_Curve)& curve) {
|
||||
const float r = l->Radius() * Ifc::LengthUnit;
|
||||
if ( r <= 0.0f ) { return false; }
|
||||
gp_Trsf trsf;
|
||||
Ifc2x3::IfcAxis2Placement placement = l->Position();
|
||||
if (placement->is(Ifc2x3::Type::IfcAxis2Placement3D)) {
|
||||
IfcGeom::convert(reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,Ifc2x3::IfcAxis2Placement3D>(placement),trsf);
|
||||
} else {
|
||||
gp_Trsf2d trsf2d;
|
||||
IfcGeom::convert(reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,Ifc2x3::IfcAxis2Placement2D>(placement),trsf2d);
|
||||
trsf = trsf2d;
|
||||
}
|
||||
gp_Ax2 ax = gp_Ax2().Transformed(trsf);
|
||||
curve = new Geom_Circle(ax, r);
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcEllipse::ptr& l, Handle(Geom_Curve)& curve) {
|
||||
float x = l->SemiAxis1() * Ifc::LengthUnit;
|
||||
float y = l->SemiAxis2() * Ifc::LengthUnit;
|
||||
if ( x == 0.0f || y == 0.0f || y > x ) { return false; }
|
||||
gp_Trsf trsf;
|
||||
Ifc2x3::IfcAxis2Placement placement = l->Position();
|
||||
if (placement->is(Ifc2x3::Type::IfcAxis2Placement3D)) {
|
||||
IfcGeom::convert(reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,Ifc2x3::IfcAxis2Placement3D>(placement),trsf);
|
||||
} else {
|
||||
gp_Trsf2d trsf2d;
|
||||
IfcGeom::convert(reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,Ifc2x3::IfcAxis2Placement2D>(placement),trsf2d);
|
||||
trsf = trsf2d;
|
||||
}
|
||||
gp_Ax2 ax = gp_Ax2().Transformed(trsf);
|
||||
curve = new Geom_Ellipse(ax, x, y);
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcLine::ptr& l, Handle(Geom_Curve)& curve) {
|
||||
gp_Pnt pnt;gp_Vec vec;
|
||||
IfcGeom::convert(l->Pnt(),pnt);
|
||||
IfcGeom::convert(l->Dir(),vec);
|
||||
curve = new Geom_Line(pnt,vec);
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,269 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 defined in IfcRegister.h *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include <new>
|
||||
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
#include <gp_Dir2d.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 <gp_Circ.hxx>
|
||||
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
#include <Geom_Line.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>
|
||||
#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 <BRepFilletAPI_MakeFillet2d.hxx>
|
||||
|
||||
#include <TopLoc_Location.hxx>
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcFace::ptr& l, TopoDS_Face& face) {
|
||||
Ifc2x3::IfcFaceBound::list bounds = l->Bounds();
|
||||
Ifc2x3::IfcFaceBound::it it = bounds->begin();
|
||||
Ifc2x3::IfcLoop::ptr loop = (*it)->Bound();
|
||||
TopoDS_Wire wire;
|
||||
if ( ! IfcGeom::convert_wire(loop,wire) ) return false;
|
||||
BRepBuilderAPI_MakeFace mf (wire);
|
||||
BRepBuilderAPI_FaceError er = mf.Error();
|
||||
if ( er == BRepBuilderAPI_NotPlanar ) {
|
||||
ShapeFix_ShapeTolerance FTol;
|
||||
FTol.SetTolerance(wire, 0.01, TopAbs_WIRE);
|
||||
mf.~BRepBuilderAPI_MakeFace();
|
||||
new (&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) {
|
||||
Ifc2x3::IfcLoop::ptr loop = (*it)->Bound();
|
||||
TopoDS_Wire wire;
|
||||
if ( ! IfcGeom::convert_wire(loop,wire) ) return false;
|
||||
mf.Add(wire);
|
||||
}
|
||||
if ( mf.IsDone() ) {
|
||||
ShapeFix_Shape sfs(mf.Face());
|
||||
sfs.Perform();
|
||||
face = TopoDS::Face(sfs.Shape());
|
||||
return true;
|
||||
} else {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcArbitraryClosedProfileDef::ptr& l, TopoDS_Face& face) {
|
||||
TopoDS_Wire wire;
|
||||
if ( ! IfcGeom::convert_wire(l->OuterCurve(),wire) ) return false;
|
||||
return IfcGeom::convert_wire_to_face(wire,face);
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcArbitraryProfileDefWithVoids::ptr& l, TopoDS_Face& face) {
|
||||
TopoDS_Wire profile;
|
||||
if ( ! IfcGeom::convert_wire(l->OuterCurve(),profile) ) return false;
|
||||
BRepBuilderAPI_MakeFace mf(profile);
|
||||
Ifc2x3::IfcCurve::list voids = l->InnerCurves();
|
||||
for( Ifc2x3::IfcCurve::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(const Ifc2x3::IfcRectangleProfileDef::ptr& l, TopoDS_Face& face) {
|
||||
const float x = l->XDim() / 2.0f * Ifc::LengthUnit;
|
||||
const float y = l->YDim() / 2.0f * Ifc::LengthUnit;
|
||||
|
||||
if ( x == 0.0f || y == 0.0f ) {
|
||||
Ifc::LogMessage("Notice","Skipping zero sized profile:",l->entity);
|
||||
return false;
|
||||
}
|
||||
|
||||
gp_Trsf2d trsf2d;
|
||||
IfcGeom::convert(l->Position(),trsf2d);
|
||||
float coords[8] = {-x,-y,x,-y,x,y,-x,y};
|
||||
return IfcGeom::profile_helper(4,coords,0,0,0,trsf2d,face);
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcIShapeProfileDef::ptr& l, TopoDS_Face& face) {
|
||||
const float x = l->OverallWidth() / 2.0f * Ifc::LengthUnit;
|
||||
const float y = l->OverallDepth() / 2.0f * Ifc::LengthUnit;
|
||||
const float d1 = l->WebThickness() / 2.0f * Ifc::LengthUnit;
|
||||
const float d2 = l->FlangeThickness() * Ifc::LengthUnit;
|
||||
bool doFillet = l->hasFilletRadius();
|
||||
float f;
|
||||
if ( doFillet ) {
|
||||
f = l->FilletRadius() * Ifc::LengthUnit;
|
||||
}
|
||||
|
||||
if ( x == 0.0f || y == 0.0f || d1 == 0.0f || d2 == 0.0f ) {
|
||||
Ifc::LogMessage("Notice","Skipping zero sized profile:",l->entity);
|
||||
return false;
|
||||
}
|
||||
|
||||
gp_Trsf2d trsf2d;
|
||||
IfcGeom::convert(l->Position(),trsf2d);
|
||||
|
||||
float coords[24] = {-x,-y,x,-y,x,-y+d2,d1,-y+d2,d1,y-d2,x,y-d2,x,y,-x,y,-x,y-d2,-d1,y-d2,-d1,-y+d2,-x,-y+d2};
|
||||
int fillets[4] = {3,4,9,10};
|
||||
float radii[4] = {f,f,f,f};
|
||||
return IfcGeom::profile_helper(12,coords,doFillet ? 4 : 0,fillets,radii,trsf2d,face);
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcCShapeProfileDef::ptr& l, TopoDS_Face& face) {
|
||||
const float x = l->Depth() / 2.0f * Ifc::LengthUnit;
|
||||
const float y = l->Width() / 2.0f * Ifc::LengthUnit;
|
||||
const float d1 = l->WallThickness() * Ifc::LengthUnit;
|
||||
const float d2 = l->Girth() * Ifc::LengthUnit;
|
||||
bool doFillet = l->hasInternalFilletRadius();
|
||||
float f1,f2;
|
||||
if ( doFillet ) {
|
||||
f1 = l->InternalFilletRadius() * Ifc::LengthUnit;
|
||||
f2 = f1 + d1;
|
||||
}
|
||||
|
||||
if ( x == 0.0f || y == 0.0f || d1 == 0.0f || d2 == 0.0f ) {
|
||||
Ifc::LogMessage("Notice","Skipping zero sized profile:",l->entity);
|
||||
return false;
|
||||
}
|
||||
|
||||
gp_Trsf2d trsf2d;
|
||||
IfcGeom::convert(l->Position(),trsf2d);
|
||||
|
||||
float coords[24] = {-x,-y,x,-y,x,-y+d2,x-d1,-y+d2,x-d1,-y+d1,-x+d1,-y+d1,-x+d1,y-d1,x-d1,y-d1,x-d1,y-d2,x,y-d2,x,y,-x,y};
|
||||
int fillets[8] = {0,1,4,5,6,7,10,11};
|
||||
float radii[8] = {f2,f2,f1,f1,f1,f1,f2,f2};
|
||||
return IfcGeom::profile_helper(12,coords,doFillet ? 8 : 0,fillets,radii,trsf2d,face);
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcLShapeProfileDef::ptr& l, TopoDS_Face& face) {
|
||||
const float y = l->Depth() / 2.0f * Ifc::LengthUnit;
|
||||
const float x = l->Width() / 2.0f * Ifc::LengthUnit;
|
||||
const float d = l->Thickness() * Ifc::LengthUnit;
|
||||
bool doEdgeFillet = l->hasEdgeRadius();
|
||||
bool doFillet = l->hasFilletRadius();
|
||||
float f1 = 0.0f;
|
||||
float f2 = 0.0f;
|
||||
if (doFillet) {
|
||||
f1 = l->FilletRadius() * Ifc::LengthUnit;
|
||||
}
|
||||
if ( doEdgeFillet) {
|
||||
f2 = l->EdgeRadius() * Ifc::LengthUnit;
|
||||
}
|
||||
if ( x == 0.0f || y == 0.0f || d == 0.0f ) {
|
||||
Ifc::LogMessage("Notice","Skipping zero sized profile:",l->entity);
|
||||
return false;
|
||||
}
|
||||
|
||||
gp_Trsf2d trsf2d;
|
||||
IfcGeom::convert(l->Position(),trsf2d);
|
||||
|
||||
float coords[12] = {-x,-y,x,-y,x,-y+d,-x+d,-y+d,-x+d,y,-x,y};
|
||||
int fillets[3] = {2,3,4};
|
||||
float radii[3] = {f2,f1,f2};
|
||||
return IfcGeom::profile_helper(6,coords,doFillet ? 3 : 0,fillets,radii,trsf2d,face);
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcCircleProfileDef::ptr& l, TopoDS_Face& face) {
|
||||
const float r = l->Radius() * Ifc::LengthUnit;
|
||||
if ( r == 0.0f ) {
|
||||
Ifc::LogMessage("Notice","Skipping zero sized profile:",l->entity);
|
||||
return false;
|
||||
}
|
||||
|
||||
gp_Trsf2d trsf;
|
||||
IfcGeom::convert(l->Position(),trsf);
|
||||
|
||||
BRepBuilderAPI_MakeWire w;
|
||||
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);
|
||||
return IfcGeom::convert_wire_to_face(w,face);
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcCircleHollowProfileDef::ptr& l, TopoDS_Face& face) {
|
||||
const float r = l->Radius() * Ifc::LengthUnit;
|
||||
const float t = l->WallThickness() * Ifc::LengthUnit;
|
||||
|
||||
if ( r == 0.0f || t == 0.0f ) {
|
||||
Ifc::LogMessage("Notice","Skipping zero sized profile:",l->entity);
|
||||
return false;
|
||||
}
|
||||
|
||||
gp_Trsf2d trsf;
|
||||
IfcGeom::convert(l->Position(),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;
|
||||
}
|
||||
@@ -0,0 +1,142 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 defined in IfcGeom.h *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
#include <gp_Dir2d.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 <gp_Circ.hxx>
|
||||
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
#include <Geom_Line.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>
|
||||
#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 <BRepFilletAPI_MakeFillet2d.hxx>
|
||||
|
||||
#include <TopLoc_Location.hxx>
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
|
||||
bool IfcGeom::convert_openings(const Ifc2x3::IfcProduct::ptr& entity,
|
||||
const Ifc2x3::IfcRelVoidsElement::list& openings, TopoDS_Shape& result, const gp_Trsf& trsf2) {
|
||||
for ( Ifc2x3::IfcRelVoidsElement::it it = openings->begin(); it != openings->end(); ++ it ) {
|
||||
Ifc2x3::IfcRelVoidsElement::ptr v = *it;
|
||||
Ifc2x3::IfcFeatureElementSubtraction::ptr fes = v->RelatedOpeningElement();
|
||||
if ( fes->is(Ifc2x3::Type::IfcOpeningElement) ) {
|
||||
gp_Trsf trsf;
|
||||
IfcGeom::convert(fes->ObjectPlacement(),trsf);
|
||||
trsf.PreMultiply(trsf2.Inverted());
|
||||
Ifc2x3::IfcProductRepresentation::ptr prodrep = fes->Representation();
|
||||
if ( prodrep->is(Ifc2x3::Type::IfcProductDefinitionShape) ) {
|
||||
Ifc2x3::IfcProductDefinitionShape::ptr pds = reinterpret_pointer_cast<Ifc2x3::IfcProductRepresentation,Ifc2x3::IfcProductDefinitionShape>(prodrep);
|
||||
Ifc2x3::IfcRepresentation::list reps = pds->Representations();
|
||||
for ( Ifc2x3::IfcRepresentation::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) {
|
||||
TopoDS_Shape s;
|
||||
IfcGeom::convert_shape(*it2,s);
|
||||
s.Move(trsf);
|
||||
result = BRepAlgoAPI_Cut(result,s);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face) {
|
||||
BRepBuilderAPI_MakeFace mf(wire, false);
|
||||
BRepBuilderAPI_FaceError er = mf.Error();
|
||||
if ( er == BRepBuilderAPI_NotPlanar ) {
|
||||
ShapeFix_ShapeTolerance FTol;
|
||||
FTol.SetTolerance(wire, 0.01, TopAbs_WIRE);
|
||||
mf = BRepBuilderAPI_MakeFace(wire, false);
|
||||
er = mf.Error();
|
||||
}
|
||||
if ( er != BRepBuilderAPI_FaceDone ) return false;
|
||||
face = mf.Face();
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::profile_helper(int numVerts, float* verts, int numFillets, int* filletIndices, float* filletRadii, gp_Trsf2d trsf, TopoDS_Face& face) {
|
||||
TopoDS_Vertex* vertices = new TopoDS_Vertex[numVerts];
|
||||
|
||||
for ( int i = 0; i < numVerts; i ++ ) {
|
||||
gp_XY xy (verts[2*i],verts[2*i+1]);
|
||||
trsf.Transforms(xy);
|
||||
vertices[i] = BRepBuilderAPI_MakeVertex(gp_Pnt(xy.X(),xy.Y(),0.0f));
|
||||
}
|
||||
|
||||
BRepBuilderAPI_MakeWire w;
|
||||
for ( int i = 0; i < numVerts; i ++ )
|
||||
w.Add(BRepBuilderAPI_MakeEdge(vertices[i],vertices[(i+1)%numVerts]));
|
||||
|
||||
IfcGeom::convert_wire_to_face(w.Wire(),face);
|
||||
|
||||
if ( numFillets ) {
|
||||
BRepFilletAPI_MakeFillet2d fillet (face);
|
||||
for ( int i = 0; i < numFillets; i ++ ) {
|
||||
const float radius = filletRadii[i];
|
||||
if ( radius < 1e-7 ) continue;
|
||||
fillet.AddFillet(vertices[filletIndices[i]],radius);
|
||||
}
|
||||
fillet.Build();
|
||||
face = TopoDS::Face(fillet.Shape());
|
||||
}
|
||||
|
||||
delete[] vertices;
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,211 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 defined in IfcRegister.h *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
#include <gp_Dir2d.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 <gp_Circ.hxx>
|
||||
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
#include <Geom_Line.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>
|
||||
#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 <BRepFilletAPI_MakeFillet2d.hxx>
|
||||
|
||||
#include <TopLoc_Location.hxx>
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
|
||||
|
||||
namespace IfcGeom {
|
||||
namespace Cache {
|
||||
#include "IfcRegisterCreateCache.h"
|
||||
}
|
||||
}
|
||||
#define IN_CACHE(T,E,t,e) std::map<int,t>::const_iterator it = Cache::T.find(E->entity->id());\
|
||||
if ( it != Cache::T.end() ) { e = it->second; return true; }
|
||||
#define CACHE(T,E,e) Cache::T[E->entity->id()] = e;
|
||||
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcCartesianPoint::ptr& l, gp_Pnt& point) {
|
||||
IN_CACHE(IfcCartesianPoint,l,gp_Pnt,point)
|
||||
std::vector<float> xyz = l->Coordinates();
|
||||
point = gp_Pnt(
|
||||
xyz.size() ? (xyz[0]*Ifc::LengthUnit) : 0.0f,
|
||||
xyz.size() > 1 ? (xyz[1]*Ifc::LengthUnit) : 0.0f,
|
||||
xyz.size() > 2 ? (xyz[2]*Ifc::LengthUnit) : 0.0f
|
||||
);
|
||||
CACHE(IfcCartesianPoint,l,point)
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcDirection::ptr& l, gp_Dir& dir) {
|
||||
IN_CACHE(IfcDirection,l,gp_Dir,dir)
|
||||
std::vector<float> xyz = l->DirectionRatios();
|
||||
dir = gp_Dir(
|
||||
xyz.size() ? xyz[0] : 0.0f,
|
||||
xyz.size() > 1 ? xyz[1] : 0.0f,
|
||||
xyz.size() > 2 ? xyz[2] : 0.0f
|
||||
);
|
||||
CACHE(IfcDirection,l,dir)
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcVector::ptr& l, gp_Vec& v) {
|
||||
IN_CACHE(IfcVector,l,gp_Vec,v)
|
||||
gp_Dir d;
|
||||
IfcGeom::convert(l->Orientation(),d);
|
||||
v = l->Magnitude() * Ifc::LengthUnit * d;
|
||||
CACHE(IfcVector,l,v)
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcAxis2Placement3D::ptr& l, gp_Trsf& trsf) {
|
||||
IN_CACHE(IfcAxis2Placement3D,l,gp_Trsf,trsf)
|
||||
gp_Pnt o;gp_Dir axis = gp_Dir(0,0,1);gp_Dir refDirection;
|
||||
IfcGeom::convert(l->Location(),o);
|
||||
bool hasRef = l->hasRefDirection();
|
||||
if ( l->hasAxis() ) IfcGeom::convert(l->Axis(),axis);
|
||||
if ( hasRef ) IfcGeom::convert(l->RefDirection(),refDirection);
|
||||
gp_Ax3 ax3;
|
||||
if ( hasRef ) ax3 = gp_Ax3(o,axis,refDirection);
|
||||
else ax3 = gp_Ax3(o,axis);
|
||||
trsf.SetTransformation(ax3, gp_Ax3(gp_Pnt(),gp_Dir(0,0,1),gp_Dir(1,0,0)));
|
||||
CACHE(IfcAxis2Placement3D,l,trsf)
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcCartesianTransformationOperator3D::ptr& l, gp_Trsf& trsf) {
|
||||
IN_CACHE(IfcCartesianTransformationOperator3D,l,gp_Trsf,trsf)
|
||||
gp_Pnt origin;
|
||||
IfcGeom::convert(l->LocalOrigin(),origin);
|
||||
gp_Dir axis1 (1.,0.,0.);
|
||||
gp_Dir axis2 (0.,1.,0.);
|
||||
gp_Dir axis3;
|
||||
if ( l->hasAxis1() ) IfcGeom::convert(l->Axis1(),axis1);
|
||||
if ( l->hasAxis2() ) IfcGeom::convert(l->Axis2(),axis2);
|
||||
if ( l->hasAxis3() ) IfcGeom::convert(l->Axis3(),axis3);
|
||||
else axis3 = axis1.Crossed(axis2);
|
||||
const gp_Ax3 ax3 (origin,axis3,axis1);
|
||||
trsf.SetTransformation(ax3);
|
||||
if ( l->hasScale() ) trsf.SetScaleFactor(l->Scale());
|
||||
CACHE(IfcCartesianTransformationOperator3D,l,trsf)
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcCartesianTransformationOperator2D::ptr& l, gp_Trsf2d& trsf) {
|
||||
IN_CACHE(IfcCartesianTransformationOperator2D,l,gp_Trsf2d,trsf)
|
||||
gp_Pnt origin;
|
||||
IfcGeom::convert(l->LocalOrigin(),origin);
|
||||
gp_Dir axis1 (1.,0.,0.);
|
||||
if ( l->hasAxis1() ) IfcGeom::convert(l->Axis1(),axis1);
|
||||
const gp_Ax2d ax2d (gp_Pnt2d(origin.X(),origin.Y()),gp_Dir2d(axis1.X(),axis1.Y()));
|
||||
trsf.SetTransformation(ax2d);
|
||||
if ( l->hasScale() ) trsf.SetScaleFactor(l->Scale());
|
||||
CACHE(IfcCartesianTransformationOperator2D,l,trsf)
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcPlane::ptr& pln, gp_Pln& plane) {
|
||||
IN_CACHE(IfcPlane,pln,gp_Pln,plane)
|
||||
Ifc2x3::IfcAxis2Placement3D::ptr l = pln->Position();
|
||||
gp_Pnt o;gp_Dir axis = gp_Dir(0,0,1);gp_Dir refDirection;
|
||||
IfcGeom::convert(l->Location(),o);
|
||||
bool hasRef = l->hasRefDirection();
|
||||
if ( l->hasAxis() ) IfcGeom::convert(l->Axis(),axis);
|
||||
if ( hasRef ) IfcGeom::convert(l->RefDirection(),refDirection);
|
||||
gp_Ax3 ax3;
|
||||
if ( hasRef ) ax3 = gp_Ax3(o,axis,refDirection);
|
||||
else ax3 = gp_Ax3(o,axis);
|
||||
plane = gp_Pln(ax3);
|
||||
CACHE(IfcPlane,pln,plane)
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcAxis2Placement2D::ptr& l, gp_Trsf2d& trsf) {
|
||||
IN_CACHE(IfcAxis2Placement2D,l,gp_Trsf2d,trsf)
|
||||
gp_Pnt P; gp_Dir V (1,0,0);
|
||||
IfcGeom::convert(l->Location(),P);
|
||||
if ( l->hasRefDirection() )
|
||||
IfcGeom::convert(l->RefDirection(),V);
|
||||
|
||||
gp_Ax2d axis(gp_Pnt2d(P.X(),P.Y()),gp_Dir2d(V.X(),V.Y()));
|
||||
trsf.SetTransformation(axis,gp_Ax2d());
|
||||
CACHE(IfcAxis2Placement2D,l,trsf)
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcObjectPlacement::ptr& l, gp_Trsf& trsf) {
|
||||
IN_CACHE(IfcObjectPlacement,l,gp_Trsf,trsf)
|
||||
if ( ! l->is(Ifc2x3::Type::IfcLocalPlacement) ) return false;
|
||||
Ifc2x3::IfcLocalPlacement::ptr current = reinterpret_pointer_cast<Ifc2x3::IfcObjectPlacement,Ifc2x3::IfcLocalPlacement>(l);
|
||||
while (1) {
|
||||
gp_Trsf trsf2;
|
||||
Ifc2x3::IfcAxis2Placement relplacement = current->RelativePlacement();
|
||||
if ( relplacement->is(Ifc2x3::Type::IfcAxis2Placement3D) ) {
|
||||
IfcGeom::convert(reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,Ifc2x3::IfcAxis2Placement3D>(relplacement),trsf2);
|
||||
trsf.PreMultiply(trsf2);
|
||||
}
|
||||
if ( current->hasPlacementRelTo() ) {
|
||||
Ifc2x3::IfcObjectPlacement::ptr relto = current->PlacementRelTo();
|
||||
if ( relto->is(Ifc2x3::Type::IfcLocalPlacement) )
|
||||
current = reinterpret_pointer_cast<Ifc2x3::IfcObjectPlacement,Ifc2x3::IfcLocalPlacement>(current->PlacementRelTo());
|
||||
else break;
|
||||
} else break;
|
||||
}
|
||||
CACHE(IfcObjectPlacement,l,trsf)
|
||||
return true;
|
||||
}
|
||||
void IfcGeom::Cache::Purge() {
|
||||
#include "IfcRegisterCreateCache.h"
|
||||
IfcGeom::Cache::PurgeShapeCache();
|
||||
}
|
||||
@@ -0,0 +1,298 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 <StdFail_NotDone.hxx>
|
||||
|
||||
#include "../ifcgeom/IfcGeomObjects.h"
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
|
||||
// Welds vertices that belong to different faces
|
||||
int IfcGeomObjects::IfcMesh::addvert(gp_Pnt p) {
|
||||
const float X = (float)p.X();const float Y = (float)p.Y();const float Z = (float)p.Z();
|
||||
const VertKey key = VertKey(X,std::pair<float,float>(Y,Z));
|
||||
VertKeyMap::const_iterator it = welds.find(key);
|
||||
if ( it != welds.end() ) return it->second;
|
||||
verts.push_back(X);
|
||||
verts.push_back(Y);
|
||||
verts.push_back(Z);
|
||||
int i = (int) welds.size();
|
||||
welds[key] = i;
|
||||
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(...) {
|
||||
Ifc::LogMessage("Error","Failed to triangulate mesh");
|
||||
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
|
||||
Ifc2x3::IfcShapeRepresentation::list shapereps;
|
||||
Ifc2x3::IfcShapeRepresentation::it outer;
|
||||
|
||||
// The triangulated shape is stored globally because it can be used by multiple IfcBuildingElements
|
||||
IfcGeomObjects::IfcMesh* shape;
|
||||
// The compound shape is stored globally because multiple IfcShapeRepresentations
|
||||
// can have IfcBuildingElements with different IfcOpeningElements
|
||||
TopoDS_Shape shapes;
|
||||
|
||||
// The object is fetched beforehand to be positive an entity actually exists
|
||||
IfcGeomObjects::IfcGeomObject* currentGeomObj;
|
||||
|
||||
// A container and iterator for IfcBuildingElements for the current IfcShapeRepresentation referenced by *outer
|
||||
Ifc2x3::IfcProduct::list entities;
|
||||
Ifc2x3::IfcProduct::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 ) {
|
||||
Ifc2x3::IfcShapeRepresentation::ptr shaperep;
|
||||
|
||||
// Have we reached the end of our list of representations?
|
||||
if ( outer == shapereps->end() ) {
|
||||
shapereps.reset();
|
||||
return 0;
|
||||
}
|
||||
shaperep = *outer;
|
||||
|
||||
// Has the list of IfcProducts for this representation been initialized?
|
||||
if ( ! entities ) {
|
||||
if ( shaperep->RepresentationIdentifier() != "Body" ) {
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
Ifc2x3::IfcProductRepresentation::list prodreps = shaperep->OfProductRepresentation();
|
||||
entities = Ifc2x3::IfcProduct::list( new IfcTemplatedEntityList<Ifc2x3::IfcProduct>() );
|
||||
for ( Ifc2x3::IfcProductRepresentation::it it = prodreps->begin(); it != prodreps->end(); ++it ) {
|
||||
if ( (*it)->is(Ifc2x3::Type::IfcProductDefinitionShape) ) {
|
||||
Ifc2x3::IfcProductDefinitionShape::ptr pds = reinterpret_pointer_cast<Ifc2x3::IfcProductRepresentation,Ifc2x3::IfcProductDefinitionShape>(*it);
|
||||
entities->push(pds->ShapeOfProduct());
|
||||
}
|
||||
}
|
||||
// Does this representation have any IfcProducts?
|
||||
if ( ! entities->Size() ) {
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
inner = entities->begin();
|
||||
}
|
||||
// Have we reached the end of our list of IfcProducts?
|
||||
if ( inner == entities->end() ) {
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
// Has the TopoDS_Shape been created for this representation?
|
||||
if ( shapes.IsNull() ) {
|
||||
if ( !IfcGeom::convert_shape(shaperep,shapes) ) {
|
||||
_nextShape();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
Ifc2x3::IfcProduct::ptr entity = *inner;
|
||||
const std::string guid = entity->GlobalId();
|
||||
|
||||
gp_Trsf trsf;
|
||||
try {
|
||||
IfcGeom::convert(entity->ObjectPlacement(),trsf);
|
||||
} catch (...) {}
|
||||
|
||||
// Does the IfcElement have any IfcOpenings?
|
||||
Ifc2x3::IfcRelVoidsElement::list openings = Ifc2x3::IfcRelVoidsElement::list();
|
||||
if ( entity->is(Ifc2x3::Type::IfcElement) ) {
|
||||
Ifc2x3::IfcElement::ptr element = reinterpret_pointer_cast<Ifc2x3::IfcProduct,Ifc2x3::IfcElement>(entity);
|
||||
openings = element->HasOpenings();
|
||||
}
|
||||
// Is the IfcElement a decomposition of an IfcElement with any IfcOpeningElements?
|
||||
if ( entity->is(Ifc2x3::Type::IfcBuildingElementPart ) ) {
|
||||
Ifc2x3::IfcBuildingElementPart::ptr part = reinterpret_pointer_cast<Ifc2x3::IfcProduct,Ifc2x3::IfcBuildingElementPart>(entity);
|
||||
Ifc2x3::IfcRelDecomposes::list decomposes = part->Decomposes();
|
||||
for ( Ifc2x3::IfcRelDecomposes::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
|
||||
Ifc2x3::IfcObjectDefinition::ptr obdef = (*it)->RelatingObject();
|
||||
if ( obdef->is(Ifc2x3::Type::IfcElement) ) {
|
||||
Ifc2x3::IfcElement::ptr element = reinterpret_pointer_cast<Ifc2x3::IfcObjectDefinition,Ifc2x3::IfcElement>(obdef);
|
||||
openings->push(element->HasOpenings());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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 ) {Ifc::LogMessage("Warning",e.what()); }
|
||||
catch(...) { Ifc::LogMessage("Error","Error processing openings for:",entity->entity); }
|
||||
if ( use_world_coords ) {
|
||||
shape = new IfcGeomObjects::IfcMesh(shaperep->entity->id(),temp_shape.Moved(trsf));
|
||||
trsf = gp_Trsf();
|
||||
} else {
|
||||
shape = new IfcGeomObjects::IfcMesh(shaperep->entity->id(),temp_shape);
|
||||
}
|
||||
} else if ( ! shape ) {
|
||||
shape = new IfcGeomObjects::IfcMesh(shaperep->entity->id(),shapes);
|
||||
}
|
||||
|
||||
return new IfcGeomObjects::IfcGeomObject(guid, Ifc2x3::Type::ToString(entity->type()), trsf, shape);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
extern bool IfcGeomObjects::Next() {
|
||||
if ( entities ) {
|
||||
++inner;
|
||||
}
|
||||
delete currentGeomObj;
|
||||
currentGeomObj = _get();
|
||||
if ( ! currentGeomObj ) {
|
||||
delete shape;
|
||||
Ifc::Dispose();
|
||||
IfcGeom::Cache::Purge();
|
||||
return false;
|
||||
} else {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
extern const IfcGeomObjects::IfcGeomObject* IfcGeomObjects::Get() {
|
||||
return currentGeomObj;
|
||||
}
|
||||
extern bool IfcGeomObjects::Init(const char* fn, bool world_coords, std::ostream* log1, std::ostream* log2) {
|
||||
if ( log1 || log2 ) Ifc::SetOutput(log1,log2);
|
||||
use_world_coords = world_coords;
|
||||
if ( !Ifc::Init(fn) ) return false;
|
||||
|
||||
shapereps = Ifc::EntitiesByType<Ifc2x3::IfcShapeRepresentation>();
|
||||
if ( ! shapereps ) return false;
|
||||
|
||||
outer = shapereps->begin();
|
||||
entities.reset();
|
||||
currentGeomObj = _get();
|
||||
|
||||
if ( ! currentGeomObj ) return false;
|
||||
|
||||
done = 0;
|
||||
total = shapereps->Size();
|
||||
return true;
|
||||
}
|
||||
extern bool IfcGeomObjects::Init(std::istream& f, int len, bool world_coords, std::ostream* log1, std::ostream* log2) {
|
||||
if ( log1 || log2 ) Ifc::SetOutput(log1,log2);
|
||||
use_world_coords = world_coords;
|
||||
if ( !Ifc::Init(f, len) ) return false;
|
||||
|
||||
shapereps = Ifc::EntitiesByType<Ifc2x3::IfcShapeRepresentation>();
|
||||
if ( ! shapereps ) return false;
|
||||
|
||||
outer = shapereps->begin();
|
||||
entities.reset();
|
||||
currentGeomObj = _get();
|
||||
|
||||
if ( ! currentGeomObj ) return false;
|
||||
|
||||
done = 0;
|
||||
total = shapereps->Size();
|
||||
return true;
|
||||
}
|
||||
extern int IfcGeomObjects::Progress() {
|
||||
return 100 * done / total;
|
||||
}
|
||||
@@ -0,0 +1,108 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 <algorithm>
|
||||
|
||||
#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;
|
||||
typedef std::pair< float,std::pair<float,float> > VertKey;
|
||||
typedef std::map<VertKey,int> VertKeyMap;
|
||||
typedef std::pair<int,int> Edge;
|
||||
|
||||
class IfcMesh {
|
||||
public:
|
||||
int id;
|
||||
std::vector<float> verts;
|
||||
std::vector<int> faces;
|
||||
std::vector<int> edges;
|
||||
VertKeyMap welds;
|
||||
|
||||
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) {
|
||||
const Edge e = Edge( (std::min)(n1,n2),(std::max)(n1,n2) );
|
||||
if ( edgecount.find(e) == edgecount.end() ) edgecount[e] = 1;
|
||||
else edgecount[e] ++;
|
||||
edges_temp.push_back(e);
|
||||
}
|
||||
};
|
||||
|
||||
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(const char* fn, bool world_coords = false, std::ostream* log1= 0, std::ostream* log2= 0);
|
||||
extern bool Init(std::istream& f, int len, bool world_coords = false, std::ostream* log1= 0, std::ostream* log2= 0);
|
||||
extern const IfcGeomObject* Get();
|
||||
extern bool Next();
|
||||
extern int Progress();
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,231 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 defined in IfcRegister.h *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
#include <gp_Dir2d.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 <gp_Circ.hxx>
|
||||
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
#include <Geom_Line.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>
|
||||
#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 <BRepFilletAPI_MakeFillet2d.hxx>
|
||||
|
||||
#include <TopLoc_Location.hxx>
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcExtrudedAreaSolid::ptr& l, TopoDS_Shape& shape) {
|
||||
TopoDS_Face face;
|
||||
if ( ! IfcGeom::convert_face(l->SweptArea(),face) ) return false;
|
||||
const float height = l->Depth() * Ifc::LengthUnit;
|
||||
gp_Trsf trsf;
|
||||
IfcGeom::convert(l->Position(),trsf);
|
||||
|
||||
gp_Dir dir;
|
||||
convert(l->ExtrudedDirection(),dir);
|
||||
|
||||
shape = BRepPrimAPI_MakePrism(face,height*dir);
|
||||
shape.Move(trsf);
|
||||
return ! shape.IsNull();
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcFacetedBrep::ptr& l, TopoDS_Shape& shape) {
|
||||
return IfcGeom::convert_shape(l->Outer(),shape);
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcFaceBasedSurfaceModel::ptr& l, TopoDS_Shape& shape) {
|
||||
Ifc2x3::IfcConnectedFaceSet::list facesets = l->FbsmFaces();
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound c;
|
||||
builder.MakeCompound(c);
|
||||
for( Ifc2x3::IfcConnectedFaceSet::it it = facesets->begin(); it != facesets->end(); ++ it ) {
|
||||
TopoDS_Shape s;
|
||||
if ( IfcGeom::convert_shape(*it,s) ) {
|
||||
builder.Add(c,s);
|
||||
}
|
||||
}
|
||||
shape = c;
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcHalfSpaceSolid::ptr& l, TopoDS_Shape& shape) {
|
||||
Ifc2x3::IfcSurface::ptr surface = l->BaseSurface();
|
||||
if ( ! surface->is(Ifc2x3::Type::IfcPlane) ) {
|
||||
// Not implemented
|
||||
return false;
|
||||
}
|
||||
gp_Pln pln;
|
||||
IfcGeom::convert(reinterpret_pointer_cast<Ifc2x3::IfcSurface,Ifc2x3::IfcPlane>(surface),pln);
|
||||
gp_Pnt pnt = pln.Location();
|
||||
bool reverse = l->AgreementFlag();
|
||||
if ( l->is(Ifc2x3::Type::IfcPolygonalBoundedHalfSpace) ) reverse = !reverse;
|
||||
if ( reverse ) pnt.Translate(-pln.Axis().Direction());
|
||||
else pnt.Translate(pln.Axis().Direction());
|
||||
shape = BRepPrimAPI_MakeHalfSpace(BRepBuilderAPI_MakeFace(pln),pnt).Solid();
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcPolygonalBoundedHalfSpace::ptr& l, TopoDS_Shape& shape) {
|
||||
TopoDS_Shape halfspace;
|
||||
if ( ! IfcGeom::convert(reinterpret_pointer_cast<Ifc2x3::IfcPolygonalBoundedHalfSpace,Ifc2x3::IfcHalfSpaceSolid>(l),halfspace) ) return false;
|
||||
TopoDS_Wire wire;
|
||||
if ( ! IfcGeom::convert_wire(l->PolygonalBoundary(),wire) ) return false;
|
||||
gp_Trsf trsf;
|
||||
convert(l->Position(),trsf);
|
||||
TopoDS_Shape extrusion = BRepPrimAPI_MakePrism(BRepBuilderAPI_MakeFace(wire),gp_Vec(0,0,20000.0));
|
||||
gp_Trsf down; down.SetTranslation(gp_Vec(0,0,-10000.0));
|
||||
extrusion.Move(down*trsf);
|
||||
shape = BRepAlgoAPI_Cut(extrusion,halfspace);
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcShellBasedSurfaceModel::ptr& l, TopoDS_Shape& shape) {
|
||||
IfcUtil::IfcAbstractSelect::list shells = l->SbsmBoundary();
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound c;
|
||||
builder.MakeCompound(c);
|
||||
for( IfcUtil::IfcAbstractSelect::it it = shells->begin(); it != shells->end(); ++ it ) {
|
||||
TopoDS_Shape s;
|
||||
if ( IfcGeom::convert_shape(*it,s) ) {
|
||||
builder.Add(c,s);
|
||||
}
|
||||
}
|
||||
shape = c;
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcBooleanClippingResult::ptr& l, TopoDS_Shape& shape) {
|
||||
TopoDS_Shape s1, s2;
|
||||
if ( ! IfcGeom::convert_shape(l->FirstOperand(),s1) )
|
||||
return false;
|
||||
if ( ! IfcGeom::convert_shape(l->SecondOperand(),s2) )
|
||||
return false;
|
||||
shape = BRepAlgoAPI_Cut(s1,s2);
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcClosedShell::ptr& l, TopoDS_Shape& shape) {
|
||||
if ( ! IfcGeom::convert((Ifc2x3::IfcConnectedFaceSet::ptr)l,shape) ) return false;
|
||||
try {
|
||||
ShapeFix_Solid solid;
|
||||
solid.LimitTolerance(0.01);
|
||||
shape = solid.SolidFromShell(TopoDS::Shell(shape));
|
||||
} catch(...) {}
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcConnectedFaceSet::ptr& l, TopoDS_Shape& shape) {
|
||||
BRepOffsetAPI_Sewing builder;
|
||||
builder.SetTolerance(0.01);
|
||||
Ifc2x3::IfcFace::list faces = l->CfsFaces();
|
||||
bool facesAdded = false;
|
||||
for( Ifc2x3::IfcFace::it it = faces->begin(); it != faces->end(); ++ it ) {
|
||||
TopoDS_Face face;
|
||||
if ( IfcGeom::convert_face(*it,face) ) {
|
||||
builder.Add(face);
|
||||
facesAdded = true;
|
||||
} else {
|
||||
Ifc::LogMessage("Warning","Invalid face:",(*it)->entity);
|
||||
}
|
||||
}
|
||||
if ( ! facesAdded ) return false;
|
||||
builder.Perform();
|
||||
shape = builder.SewedShape();
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcMappedItem::ptr& l, TopoDS_Shape& shape) {
|
||||
gp_Trsf trsf1;
|
||||
Ifc2x3::IfcCartesianTransformationOperator::ptr transform = l->MappingTarget();
|
||||
if ( transform->is(Ifc2x3::Type::IfcCartesianTransformationOperator2DnonUniform) ||
|
||||
transform->is(Ifc2x3::Type::IfcCartesianTransformationOperator3DnonUniform) ) {
|
||||
// Not implemented
|
||||
return false;
|
||||
} else if ( transform->is(Ifc2x3::Type::IfcCartesianTransformationOperator3D) ) {
|
||||
IfcGeom::convert(reinterpret_pointer_cast<Ifc2x3::IfcCartesianTransformationOperator,
|
||||
Ifc2x3::IfcCartesianTransformationOperator3D>(transform),trsf1);
|
||||
} else if ( transform->is(Ifc2x3::Type::IfcCartesianTransformationOperator2D) ) {
|
||||
gp_Trsf2d trsf1_2d;
|
||||
IfcGeom::convert(reinterpret_pointer_cast<Ifc2x3::IfcCartesianTransformationOperator,
|
||||
Ifc2x3::IfcCartesianTransformationOperator2D>(transform),trsf1_2d);
|
||||
trsf1 = trsf1_2d;
|
||||
}
|
||||
Ifc2x3::IfcRepresentationMap::ptr map = l->MappingSource();
|
||||
Ifc2x3::IfcAxis2Placement placement = map->MappingOrigin();
|
||||
gp_Trsf trsf2;
|
||||
if (placement->is(Ifc2x3::Type::IfcAxis2Placement3D)) {
|
||||
IfcGeom::convert(reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,Ifc2x3::IfcAxis2Placement3D>(placement),trsf2);
|
||||
} else {
|
||||
gp_Trsf2d trsf2_2d;
|
||||
IfcGeom::convert(reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,Ifc2x3::IfcAxis2Placement2D>(placement),trsf2_2d);
|
||||
trsf2 = trsf2_2d;
|
||||
}
|
||||
if ( ! IfcGeom::convert_shape(map->MappedRepresentation(),shape) ) return false;
|
||||
shape.Move(trsf2 * trsf1);
|
||||
return !shape.IsNull();
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcShapeRepresentation::ptr& l, TopoDS_Shape& shape) {
|
||||
Ifc2x3::IfcRepresentationItem::list items = l->Items();
|
||||
if ( ! items->Size() ) return false;
|
||||
BRep_Builder builder;
|
||||
TopoDS_Compound c;
|
||||
builder.MakeCompound(c);
|
||||
for ( Ifc2x3::IfcRepresentationItem::it it = items->begin(); it != items->end(); ++ it ) {
|
||||
TopoDS_Shape s;
|
||||
if ( ! IfcGeom::convert_shape(*it,s)) continue;
|
||||
builder.Add(c,s);
|
||||
}
|
||||
shape = c;
|
||||
return !shape.IsNull();
|
||||
}
|
||||
@@ -0,0 +1,176 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 defined in IfcRegister.h *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Vec.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Pnt2d.hxx>
|
||||
#include <gp_Vec2d.hxx>
|
||||
#include <gp_Dir2d.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 <gp_Circ.hxx>
|
||||
|
||||
#include <TColgp_Array1OfPnt.hxx>
|
||||
#include <TColgp_Array1OfPnt2d.hxx>
|
||||
#include <TColStd_Array1OfReal.hxx>
|
||||
#include <TColStd_Array1OfInteger.hxx>
|
||||
#include <Geom_Line.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>
|
||||
#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 <BRepFilletAPI_MakeFillet2d.hxx>
|
||||
|
||||
#include <TopLoc_Location.hxx>
|
||||
|
||||
#include "../ifcgeom/IfcGeom.h"
|
||||
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcCompositeCurve::ptr& l, TopoDS_Wire& wire) {
|
||||
Ifc2x3::IfcCompositeCurveSegment::list segments = l->Segments();
|
||||
BRepBuilderAPI_MakeWire w;
|
||||
for( Ifc2x3::IfcCompositeCurveSegment::it it = segments->begin(); it != segments->end(); ++ it ) {
|
||||
const Ifc2x3::IfcCurve::ptr curve = (*it)->ParentCurve();
|
||||
TopoDS_Wire wire2;
|
||||
if ( ! IfcGeom::convert_wire(curve,wire2) ) continue;
|
||||
ShapeFix_ShapeTolerance FTol;
|
||||
FTol.SetTolerance(wire2, 0.01, TopAbs_WIRE);
|
||||
w.Add(wire2);
|
||||
if ( w.Error() != BRepBuilderAPI_WireDone ) {
|
||||
Ifc::LogMessage("Error","Failed to join curve segments:",l->entity);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
wire = w.Wire();
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcTrimmedCurve::ptr& l, TopoDS_Wire& wire) {
|
||||
Ifc2x3::IfcCurve::ptr basis_curve = l->BasisCurve();
|
||||
bool isConic = basis_curve->is(Ifc2x3::Type::IfcConic);
|
||||
float parameterFactor = isConic ? Ifc::PlaneAngleUnit : Ifc::LengthUnit;
|
||||
Handle(Geom_Curve) curve;
|
||||
if ( ! IfcGeom::convert_curve(basis_curve,curve) ) return false;
|
||||
bool trim_cartesian = l->MasterRepresentation() == Ifc2x3::IfcTrimmingPreference::CARTESIAN;
|
||||
IfcUtil::IfcAbstractSelect::list trims1 = l->Trim1();
|
||||
IfcUtil::IfcAbstractSelect::list trims2 = l->Trim2();
|
||||
bool trimmed1 = false;
|
||||
bool trimmed2 = false;
|
||||
float flt1;
|
||||
gp_Pnt pnt1;
|
||||
BRepBuilderAPI_MakeWire w;
|
||||
for ( IfcUtil::IfcAbstractSelect::it it = trims1->begin(); it != trims1->end(); it ++ ) {
|
||||
const IfcUtil::IfcAbstractSelect::ptr i = *it;
|
||||
if ( i->is(Ifc2x3::Type::IfcCartesianPoint) && trim_cartesian ) {
|
||||
IfcGeom::convert(reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,Ifc2x3::IfcCartesianPoint>(i), pnt1 );
|
||||
trimmed1 = true;
|
||||
} else if ( i->is(Ifc2x3::Type::IfcParameterValue) ) {
|
||||
const float value = *reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,IfcUtil::IfcArgumentSelect>(i)->wrappedValue();
|
||||
flt1 = value * parameterFactor;
|
||||
trimmed1 = true;
|
||||
}
|
||||
}
|
||||
for ( IfcUtil::IfcAbstractSelect::it it = trims2->begin(); it != trims2->end(); it ++ ) {
|
||||
const IfcUtil::IfcAbstractSelect::ptr i = *it;
|
||||
if ( i->is(Ifc2x3::Type::IfcCartesianPoint) && trim_cartesian && trimmed1 ) {
|
||||
gp_Pnt pnt2;
|
||||
IfcGeom::convert(reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,Ifc2x3::IfcCartesianPoint>(i), pnt2 );
|
||||
BRepBuilderAPI_MakeEdge e (curve,pnt1,pnt2);
|
||||
w.Add(e.Edge());
|
||||
trimmed2 = true;
|
||||
} else if ( i->is(Ifc2x3::Type::IfcParameterValue) && trimmed1 ) {
|
||||
const float value = *reinterpret_pointer_cast<IfcUtil::IfcAbstractSelect,IfcUtil::IfcArgumentSelect>(i)->wrappedValue();
|
||||
float flt2 = value * parameterFactor;
|
||||
BRepBuilderAPI_MakeEdge e (curve,flt1,flt2);
|
||||
w.Add(e.Edge());
|
||||
trimmed2 = true;
|
||||
}
|
||||
}
|
||||
if ( trimmed2 ) wire = w.Wire();
|
||||
return trimmed2;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcPolyline::ptr& l, TopoDS_Wire& result) {
|
||||
Ifc2x3::IfcCartesianPoint::list points = l->Points();
|
||||
|
||||
BRepBuilderAPI_MakeWire w;
|
||||
gp_Pnt P1;gp_Pnt P2;
|
||||
for( Ifc2x3::IfcCartesianPoint::it it = points->begin(); it != points->end(); ++ it ) {
|
||||
IfcGeom::convert(*it,P2);
|
||||
if ( it != points->begin() && ( P1.X() != P2.X() || P1.Y() != P2.Y() || P1.Z() != P2.Z() ) )
|
||||
w.Add(BRepBuilderAPI_MakeEdge(P1,P2));
|
||||
P1 = P2;
|
||||
}
|
||||
|
||||
result = w.Wire();
|
||||
return true;
|
||||
}
|
||||
bool IfcGeom::convert(const Ifc2x3::IfcPolyLoop::ptr& l, TopoDS_Wire& result) {
|
||||
Ifc2x3::IfcCartesianPoint::list points = l->Polygon();
|
||||
|
||||
BRepBuilderAPI_MakeWire w;
|
||||
gp_Pnt P1;gp_Pnt P2;gp_Pnt F;
|
||||
int count = 0;
|
||||
for( Ifc2x3::IfcCartesianPoint::it it = points->begin(); it != points->end(); ++ it ) {
|
||||
IfcGeom::convert(*it,P2);
|
||||
if ( it != points->begin() && ( P1.X() != P2.X() || P1.Y() != P2.Y() || P1.Z() != P2.Z() ) ) {
|
||||
w.Add(BRepBuilderAPI_MakeEdge(P1,P2));
|
||||
count ++;
|
||||
} else if ( ! count ) F = P2;
|
||||
P1 = P2;
|
||||
}
|
||||
if ( P1.X() != F.X() || P1.Y() != F.Y() || P1.Z() != F.Z() ) {
|
||||
w.Add(BRepBuilderAPI_MakeEdge(P1,F));
|
||||
count ++;
|
||||
}
|
||||
if ( count < 3 ) return false;
|
||||
|
||||
result = w.Wire();
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,80 @@
|
||||
/********************************************************************************
|
||||
* *
|
||||
* 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 registers function prototypes for all supported IFC geometrical *
|
||||
* entities. For entities of type CLASS an std::map is also created to cache *
|
||||
* the output of the conversion functions *
|
||||
* *
|
||||
********************************************************************************/
|
||||
|
||||
#include <TopoDS_Shape.hxx>
|
||||
#include <TopoDS_Wire.hxx>
|
||||
#include <TopoDS_Face.hxx>
|
||||
#include <gp_Pnt.hxx>
|
||||
#include <gp_Pln.hxx>
|
||||
#include <gp_Dir.hxx>
|
||||
#include <gp_Trsf.hxx>
|
||||
#include <gp_Trsf2d.hxx>
|
||||
|
||||
#include "../ifcparse/IfcParse.h"
|
||||
|
||||
using namespace Ifc2x3;
|
||||
|
||||
SHAPE(IfcExtrudedAreaSolid);
|
||||
SHAPE(IfcClosedShell);
|
||||
SHAPE(IfcConnectedFaceSet);
|
||||
SHAPE(IfcFacetedBrep);
|
||||
SHAPE(IfcShellBasedSurfaceModel);
|
||||
SHAPE(IfcFaceBasedSurfaceModel);
|
||||
SHAPE(IfcBooleanClippingResult);
|
||||
SHAPE(IfcShapeRepresentation);
|
||||
SHAPE(IfcMappedItem);
|
||||
SHAPE(IfcPolygonalBoundedHalfSpace);
|
||||
SHAPE(IfcHalfSpaceSolid);
|
||||
|
||||
FACE(IfcArbitraryClosedProfileDef);
|
||||
FACE(IfcArbitraryProfileDefWithVoids);
|
||||
FACE(IfcRectangleProfileDef);
|
||||
FACE(IfcIShapeProfileDef);
|
||||
FACE(IfcCShapeProfileDef);
|
||||
FACE(IfcLShapeProfileDef);
|
||||
FACE(IfcCircleProfileDef);
|
||||
FACE(IfcFace);
|
||||
FACE(IfcCircleHollowProfileDef);
|
||||
|
||||
WIRE(IfcPolyline);
|
||||
WIRE(IfcPolyLoop);
|
||||
WIRE(IfcCompositeCurve);
|
||||
WIRE(IfcTrimmedCurve);
|
||||
|
||||
CURVE(IfcCircle);
|
||||
CURVE(IfcEllipse);
|
||||
CURVE(IfcLine);
|
||||
|
||||
CLASS(IfcCartesianPoint,gp_Pnt);
|
||||
CLASS(IfcDirection,gp_Dir);
|
||||
CLASS(IfcAxis2Placement2D,gp_Trsf2d);
|
||||
CLASS(IfcAxis2Placement3D,gp_Trsf);
|
||||
CLASS(IfcCartesianTransformationOperator2D,gp_Trsf2d);
|
||||
CLASS(IfcCartesianTransformationOperator3D,gp_Trsf);
|
||||
CLASS(IfcObjectPlacement,gp_Trsf);
|
||||
CLASS(IfcVector,gp_Vec);
|
||||
CLASS(IfcPlane,gp_Pln);
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "IfcRegisterUndef.h"
|
||||
#define CURVE(T) \
|
||||
if ( l->is(T::Class()) ) return convert(reinterpret_pointer_cast<IfcBaseClass,T>(l),r);
|
||||
#include "IfcRegisterDef.h"
|
||||
|
||||
#include "IfcRegister.h"
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "IfcRegisterUndef.h"
|
||||
#define FACE(T) \
|
||||
if ( l->is(T::Class()) ) return convert(reinterpret_pointer_cast<IfcBaseClass,T>(l),r);
|
||||
#include "IfcRegisterDef.h"
|
||||
|
||||
#include "IfcRegister.h"
|
||||
@@ -0,0 +1,14 @@
|
||||
#include "IfcRegisterUndef.h"
|
||||
#define SHAPE(T) \
|
||||
if ( l->is(T::Class()) ) { \
|
||||
try { \
|
||||
bool b = convert(reinterpret_pointer_cast<IfcBaseClass,T>(l),r); \
|
||||
if ( b ) { \
|
||||
Cache::Shape[l->entity->id()] = r; \
|
||||
return true; \
|
||||
} else { return false; }\
|
||||
} catch(...) { Ifc::LogMessage("Error","Failed to convert:",l->entity); } \
|
||||
}
|
||||
#include "IfcRegisterDef.h"
|
||||
|
||||
#include "IfcRegister.h"
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "IfcRegisterUndef.h"
|
||||
#define WIRE(T) \
|
||||
if ( l->is(T::Class()) ) return convert(reinterpret_pointer_cast<IfcBaseClass,T>(l),r);
|
||||
#include "IfcRegisterDef.h"
|
||||
|
||||
#include "IfcRegister.h"
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "IfcRegisterUndef.h"
|
||||
#define CLASS(T,V) \
|
||||
std::map<int,V> T;
|
||||
#include "IfcRegisterDef.h"
|
||||
|
||||
#include "IfcRegister.h"
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifndef SHAPE
|
||||
#define SHAPE(T)
|
||||
#endif
|
||||
#ifndef WIRE
|
||||
#define WIRE(T)
|
||||
#endif
|
||||
#ifndef FACE
|
||||
#define FACE(T)
|
||||
#endif
|
||||
#ifndef CURVE
|
||||
#define CURVE(T)
|
||||
#endif
|
||||
#ifndef CLASS
|
||||
#define CLASS(T,V)
|
||||
#endif
|
||||
@@ -0,0 +1,9 @@
|
||||
#include "IfcRegisterUndef.h"
|
||||
#define CLASS(T,V) bool convert(const T::ptr& L, V& r);
|
||||
#define SHAPE(T) CLASS(T,TopoDS_Shape)
|
||||
#define WIRE(T) CLASS(T,TopoDS_Wire)
|
||||
#define FACE(T) CLASS(T,TopoDS_Face)
|
||||
#define CURVE(T) CLASS(T,Handle(Geom_Curve))
|
||||
#include "IfcRegisterDef.h"
|
||||
|
||||
#include "IfcRegister.h"
|
||||
@@ -0,0 +1,6 @@
|
||||
#include "IfcRegisterUndef.h"
|
||||
#define CLASS(T,V) \
|
||||
T.clear();
|
||||
#include "IfcRegisterDef.h"
|
||||
|
||||
#include "IfcRegister.h"
|
||||
@@ -0,0 +1,15 @@
|
||||
#ifdef SHAPE
|
||||
#undef SHAPE
|
||||
#endif
|
||||
#ifdef WIRE
|
||||
#undef WIRE
|
||||
#endif
|
||||
#ifdef FACE
|
||||
#undef FACE
|
||||
#endif
|
||||
#ifdef CURVE
|
||||
#undef CURVE
|
||||
#endif
|
||||
#ifdef CLASS
|
||||
#undef CLASS
|
||||
#endif
|
||||
Reference in New Issue
Block a user