- Parsing: support for comments

- Geometry: support for some complex filleted profiles ( e.g. IfcIShapeProfileDef, IfcCShapeProfileDef )
This commit is contained in:
Thomas Krijnen
2011-06-13 12:28:38 +00:00
parent 93d7b8fba9
commit a7ed78c4a8
5 changed files with 160 additions and 26 deletions
+116 -16
View File
@@ -71,6 +71,8 @@
#include <ShapeFix_ShapeTolerance.hxx>
#include <ShapeFix_Solid.hxx>
#include <BRepFilletAPI_MakeFillet2d.hxx>
#include <TopLoc_Location.hxx>
bool IfcGeom::convert(IfcSchema::ExtrudedAreaSolid* IfcExtrudedAreaSolid, TopoDS_Shape& shape) {
@@ -273,7 +275,7 @@ bool IfcGeom::convert(IfcSchema::ArbitraryProfileDefWithVoids* IfcArbitraryProfi
face = TopoDS::Face(sfs.Shape());
return true;
}
bool IfcGeom::convert(IfcSchema::RectangleProfileDef* IfcRectangleProfileDef,class TopoDS_Wire& wire) {
bool IfcGeom::convert(IfcSchema::RectangleProfileDef* IfcRectangleProfileDef,class TopoDS_Face& face) {
const float x = IfcRectangleProfileDef->Width() / 2.0f * Ifc::LengthUnit;
const float y = IfcRectangleProfileDef->Height() / 2.0f * Ifc::LengthUnit;
@@ -282,21 +284,90 @@ bool IfcGeom::convert(IfcSchema::RectangleProfileDef* IfcRectangleProfileDef,cla
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;
gp_Trsf2d trsf2d;
IfcGeom::convert((IfcSchema::Axis2Placement2D*)IfcRectangleProfileDef->Placement().get(),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(IfcSchema::IShapeProfileDef* IfcIShapeProfileDef,class TopoDS_Face& face) {
const float x = IfcIShapeProfileDef->Width() / 2.0f * Ifc::LengthUnit;
const float y = IfcIShapeProfileDef->Depth() / 2.0f * Ifc::LengthUnit;
const float d1 = IfcIShapeProfileDef->WebThickness() / 2.0f * Ifc::LengthUnit;
const float d2 = IfcIShapeProfileDef->FlangeThickness() * Ifc::LengthUnit;
bool doFillet = false;
float f;
try {
f = IfcIShapeProfileDef->FilletRadius() * Ifc::LengthUnit;
doFillet = true;
} catch ( IfcParse::IfcException& ) {}
if ( x == 0.0f || y == 0.0f || d1 == 0.0f || d2 == 0.0f ) {
std::cout << "[Notice] Skipping zero sized profile:" << std::endl << IfcIShapeProfileDef->toString() << std::endl;
return false;
}
gp_Trsf2d trsf2d;
IfcGeom::convert((IfcSchema::Axis2Placement2D*)IfcIShapeProfileDef->Placement().get(),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(IfcSchema::CShapeProfileDef* IfcCShapeProfileDef,class TopoDS_Face& face) {
const float x = IfcCShapeProfileDef->Depth() / 2.0f * Ifc::LengthUnit;
const float y = IfcCShapeProfileDef->Width() / 2.0f * Ifc::LengthUnit;
const float d1 = IfcCShapeProfileDef->WallThickness() * Ifc::LengthUnit;
const float d2 = IfcCShapeProfileDef->Girth() * Ifc::LengthUnit;
bool doFillet = false;
float f1,f2;
try {
f1 = IfcCShapeProfileDef->InternalFilletRadius() * Ifc::LengthUnit;
f2 = f1 + d1;
doFillet = true;
} catch ( IfcParse::IfcException& ) {}
if ( x == 0.0f || y == 0.0f || d1 == 0.0f || d2 == 0.0f ) {
std::cout << "[Notice] Skipping zero sized profile:" << std::endl << IfcCShapeProfileDef->toString() << std::endl;
return false;
}
gp_Trsf2d trsf2d;
IfcGeom::convert((IfcSchema::Axis2Placement2D*)IfcCShapeProfileDef->Placement().get(),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(IfcSchema::LShapeProfileDef* IfcLShapeProfileDef,class TopoDS_Face& face) {
const float y = IfcLShapeProfileDef->Depth() / 2.0f * Ifc::LengthUnit;
const float x = IfcLShapeProfileDef->Width() / 2.0f * Ifc::LengthUnit;
const float d = IfcLShapeProfileDef->Thickness() * Ifc::LengthUnit;
bool doFillet = false;
float f1 = 0.0f;
float f2 = 0.0f;
try {
f1 = IfcLShapeProfileDef->FilletRadius() * Ifc::LengthUnit;
doFillet = true;
} catch ( IfcParse::IfcException& ) {}
try {
f2 = IfcLShapeProfileDef->EdgeRadius() * Ifc::LengthUnit;
doFillet = true;
} catch ( IfcParse::IfcException& ) {}
if ( x == 0.0f || y == 0.0f || d == 0.0f ) {
std::cout << "[Notice] Skipping zero sized profile:" << std::endl << IfcLShapeProfileDef->toString() << std::endl;
return false;
}
gp_Trsf2d trsf2d;
IfcGeom::convert((IfcSchema::Axis2Placement2D*)IfcLShapeProfileDef->Placement().get(),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(IfcSchema::CircleProfileDef* IfcCircleProfileDef,class TopoDS_Wire& wire) {
const float r = IfcCircleProfileDef->Radius() * Ifc::LengthUnit;
@@ -505,4 +576,33 @@ bool IfcGeom::convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face) {
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;
}
+12 -7
View File
@@ -179,7 +179,9 @@ Entity::Entity(std::istream* ss, std::vector<int>& refs, bool sub) {
std::string curvar;
curvar.reserve(64);
bool inStr = false;
bool inComment = false;
char c[1] = "";
char p[1] = "";
int state = -1;
int previousPos = -1;
args = 0;
@@ -187,8 +189,8 @@ Entity::Entity(std::istream* ss, std::vector<int>& refs, bool sub) {
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())) ) {
if ( !inComment && !inStr && ((*c) == ' ' || (*c) == '\r' || (*c) == '\n' || (*c) == '\t') ) continue;
if ( curvar.size() && !inComment && !inStr && ( term(*c) || term(*curvar.rbegin())) ) {
Argument* v = new Argument(curvar);
curvar.clear();
curvar.push_back(*c);
@@ -234,8 +236,12 @@ Entity::Entity(std::istream* ss, std::vector<int>& refs, bool sub) {
}
previousPos = ss->tellg();
delete v;
} else curvar.push_back(*c);
if ( *c == '\'' ) inStr = !inStr;
}
else if ( ! inComment ) curvar.push_back(*c);
if ( !inComment && *c == '\'' ) inStr = !inStr;
else if ( !inStr && *p == '/' && *c == '*' ) { inComment = true; curvar.clear(); }
else if ( !inStr && *p == '*' && *c == '/' ) inComment = false;
p[0] = c[0];
} while ( !ss->eof() && (*c != ';' || inStr) );
}
Entity::~Entity() {
@@ -316,8 +322,7 @@ EntityPtr Entities::operator[] (int i) {
Entities::Entities() {
size = 0;
}
File::File(std::string fn, bool debug) {
File::File(const std::string& fn, bool debug) {
valid = false;
std::ifstream f(fn.c_str());
if ( ! f.is_open() ) return;
@@ -392,7 +397,7 @@ EntitiesPtr Ifc::EntitiesByReference(int t) {
EntityPtr Ifc::EntityById(int id) {
return f->EntityById(id);
}
bool Ifc::Init(std::string fn) {
bool Ifc::Init(const std::string& fn) {
f = new File(fn, false);
IfcEntity IfcUnitAssigment = *EntitiesByType(IfcSchema::Enum::IfcUnitAssignment)->begin();
IfcEntities units = ((IfcSchema::UnitAssignment*)IfcUnitAssigment.get())->Units();
+2 -2
View File
@@ -156,7 +156,7 @@ namespace IfcParse {
std::map<int,EntitiesPtr> byref;
bool valid;
File(std::string fn, bool debug = false);
File(const std::string& fn, bool debug = false);
EntitiesPtr EntitiesByType(IfcSchema::Enum::IfcTypes t);
EntitiesPtr EntitiesByReference(int id);
EntityPtr EntityById(int id);
@@ -186,7 +186,7 @@ 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 bool Init(const std::string& fn);
static void Dispose();
static float LengthUnit;
static float PlaneAngleUnit;
+29 -1
View File
@@ -114,7 +114,7 @@ IFC_REF(ArbitraryProfileDefWithVoids,Polyline,2)
IFC_REFS(ArbitraryProfileDefWithVoids,Voids,3)
IFC_END_CLASS
IFC_WIRE_CLASS(RectangleProfileDef)
IFC_FACE_CLASS(RectangleProfileDef)
IFC_REF(RectangleProfileDef,Placement,2)
IFC_FLT(RectangleProfileDef,Width,3)
IFC_FLT(RectangleProfileDef,Height,4)
@@ -131,6 +131,34 @@ IFC_FLT(CircleHollowProfileDef,Radius,3)
IFC_FLT(CircleHollowProfileDef,WallThickness,4)
IFC_END_CLASS
IFC_FACE_CLASS(IShapeProfileDef)
IFC_REF(IShapeProfileDef,Placement,2)
IFC_FLT(IShapeProfileDef,Width,3)
IFC_FLT(IShapeProfileDef,Depth,4)
IFC_FLT(IShapeProfileDef,WebThickness,5)
IFC_FLT(IShapeProfileDef,FlangeThickness,6)
IFC_FLT(IShapeProfileDef,FilletRadius,7)
IFC_END_CLASS
IFC_FACE_CLASS(CShapeProfileDef)
IFC_REF(CShapeProfileDef,Placement,2)
IFC_FLT(CShapeProfileDef,Width,3)
IFC_FLT(CShapeProfileDef,Depth,4)
IFC_FLT(CShapeProfileDef,WallThickness,5)
IFC_FLT(CShapeProfileDef,Girth,6)
IFC_FLT(CShapeProfileDef,InternalFilletRadius,7)
IFC_END_CLASS
IFC_FACE_CLASS(LShapeProfileDef)
IFC_REF(LShapeProfileDef,Placement,2)
IFC_FLT(LShapeProfileDef,Depth,3)
IFC_FLT(LShapeProfileDef,Width,4)
IFC_FLT(LShapeProfileDef,Thickness,5)
IFC_FLT(LShapeProfileDef,FilletRadius,6)
IFC_FLT(LShapeProfileDef,EdgeRadius,7)
IFC_FLT(LShapeProfileDef,LegSlope,8)
IFC_END_CLASS
IFC_CURVE_CLASS(Circle)
IFC_REF(Circle,Placement,0)
IFC_FLT(Circle,Radius,1)
+1
View File
@@ -46,6 +46,7 @@ namespace IfcGeom {
bool convert_curve(const IfcEntity L, Handle(Geom_Curve)& result);
bool convert_face(const IfcEntity L, TopoDS_Face& result);
bool convert_openings(const IfcSchema::BuildingElement* IfcBuildingElement, const IfcEntities openings, TopoDS_Shape& result, const gp_Trsf& trsf);
bool profile_helper(int numVerts, float* verts, int numFillets, int* filletIndices, float* filletRadii, gp_Trsf2d trsf, TopoDS_Face& face);
}
#endif