Merge remote-tracking branch 'origin/master' into hdf5

Conflicts:
	src/ifcexpressparser/bootstrap.py
	src/ifcexpressparser/templates.py
	src/ifcgeom/IfcGeomFaces.cpp
	src/ifcgeom/IfcGeomFunctions.cpp
	src/ifcgeom/IfcGeomIterator.h
	src/ifcgeom/IfcGeomWires.cpp
	src/ifcparse/Ifc2x3.h
	src/ifcparse/Ifc4.h
	src/ifcparse/IfcLateBoundEntity.cpp
	src/ifcparse/IfcParse.cpp
	src/ifcparse/IfcUtil.h
This commit is contained in:
aothms
2016-02-19 14:19:57 +01:00
100 changed files with 3560 additions and 1002 deletions
+10 -2
View File
@@ -109,6 +109,7 @@ public:
bool convert_openings(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings, const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes);
bool convert_openings_fast(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings, const IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcRepresentationShapeItems& cut_shapes);
IfcSchema::IfcSurfaceStyleShading* get_surface_style(IfcSchema::IfcRepresentationItem* item);
const IfcSchema::IfcRepresentationItem* find_item_carrying_style(const IfcSchema::IfcRepresentationItem* item);
bool create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& solid);
bool is_compound(const TopoDS_Shape& shape);
bool is_convex(const TopoDS_Wire& wire);
@@ -121,9 +122,12 @@ public:
double face_area(const TopoDS_Face& f);
void apply_tolerance(TopoDS_Shape& s, double t);
void setValue(GeomValue var, double value);
double getValue(GeomValue var);
double getValue(GeomValue var) const;
bool fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& shape);
void remove_redundant_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol=-1.);
void remove_duplicate_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol=-1.);
void remove_collinear_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol=-1.);
bool wire_to_sequence_of_point(const TopoDS_Wire&, TColgp_SequenceOfPnt&);
void sequence_of_point_to_wire(const TColgp_SequenceOfPnt&, TopoDS_Wire&, bool closed);
std::pair<std::string, double> initializeUnits(IfcSchema::IfcUnitAssignment*);
@@ -135,6 +139,10 @@ public:
const SurfaceStyle* get_style(const IfcSchema::IfcRepresentationItem* representation_item);
template <typename T> std::pair<IfcSchema::IfcSurfaceStyle*, T*> get_surface_style(const IfcSchema::IfcRepresentationItem* representation_item) {
// For certain representation items, most notably boolean operands,
// a style definition might reside on one of its operands.
representation_item = find_item_carrying_style(representation_item);
IfcSchema::IfcStyledItem::list::ptr styled_items = representation_item->StyledByItem();
for (IfcSchema::IfcStyledItem::list::it jt = styled_items->begin(); jt != styled_items->end(); ++jt) {
#ifdef USE_IFC4
+2 -2
View File
@@ -149,8 +149,8 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBSplineCurveWithKnots* l, Hand
const std::vector<double> knots = l->Knots();
TColgp_Array1OfPnt Poles(0, cps->size() - 1);
TColStd_Array1OfReal Knots(0, knots.size() - 1);
TColStd_Array1OfInteger Mults(0, mults.size() - 1);
TColStd_Array1OfReal Knots(0, (int)knots.size() - 1);
TColStd_Array1OfInteger Mults(0, (int)mults.size() - 1);
Standard_Integer Degree = l->Degree();
Standard_Boolean Periodic = l->ClosedCurve();
+37 -21
View File
@@ -88,6 +88,8 @@
#include <BRepCheck_Face.hxx>
#include <BRepBuilderAPI_Transform.hxx>
#include <Standard_Version.hxx>
#ifdef USE_IFC4
#include <Geom_BSplineSurface.hxx>
#include <TColgp_Array2OfPnt.hxx>
@@ -101,7 +103,6 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) {
IfcSchema::IfcFaceBound::list::ptr bounds = l->Bounds();
Handle(Geom_Surface) face_surface;
bool reversed_face_surface = false;
const bool is_face_surface = l->declaration().is(IfcSchema::Type::IfcFaceSurface);
if (is_face_surface) {
@@ -164,7 +165,11 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) {
if (is_interior == !process_interior) continue;
TopoDS_Wire wire;
if (!convert_wire(loop, wire)) break;
if (!convert_wire(loop, wire)) {
Logger::Message(Logger::LOG_ERROR, "Failed to process face boundary loop", loop);
delete mf;
return false;
}
/*
The approach below does not result in a significant speed-up
@@ -233,9 +238,9 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) {
// If the wires are reversed the face needs to be reversed as well in order
// to maintain the counter-clock-wise ordering of the bounding wire's vertices.
bool all_reversed = true;
TopoDS_Iterator it(outer_face_bound, false);
for (; it.More(); it.Next()) {
const TopoDS_Wire& w = TopoDS::Wire(it.Value());
TopoDS_Iterator jt(outer_face_bound, false);
for (; jt.More(); jt.Next()) {
const TopoDS_Wire& w = TopoDS::Wire(jt.Value());
if ((w.Orientation() != TopAbs_REVERSED) == same_sense) {
all_reversed = false;
}
@@ -252,13 +257,16 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcFace* l, TopoDS_Shape& face) {
// Reinitialize the builder to the outer face
// bound in order to add holes more robustly.
delete mf;
// TODO: What about the face_surface?
mf = new BRepBuilderAPI_MakeFace(outer_face_bound);
} else {
face = outer_face_bound;
success = true;
}
} else {
break;
Logger::Message(Logger::LOG_ERROR, "Failed to process face boundary", bound);
delete mf;
return false;
}
} else {
@@ -849,7 +857,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCompositeProfileDef* l, TopoDS
builder.MakeCompound(compound);
IfcSchema::IfcProfileDef::list::ptr profiles = l->Profiles();
bool first = true;
//bool first = true;
for (IfcSchema::IfcProfileDef::list::it it = profiles->begin(); it != profiles->end(); ++it) {
TopoDS_Face f;
if (convert_face(*it, f)) {
@@ -883,20 +891,32 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcDerivedProfileDef* l, TopoDS_S
}
}
bool IfcGeom::Kernel::convert(const IfcSchema::IfcPlane* l, TopoDS_Shape& face) {
gp_Pln pln;
convert(l, pln);
Handle_Geom_Surface surf = new Geom_Plane(pln);
#if OCC_VERSION_HEX < 0x60502
face = BRepBuilderAPI_MakeFace(surf);
#else
face = BRepBuilderAPI_MakeFace(surf, getValue(GV_PRECISION));
#endif
return true;
}
#ifdef USE_IFC4
bool IfcGeom::Kernel::convert(const IfcSchema::IfcBSplineSurfaceWithKnots* l, TopoDS_Shape& face) {
SHARED_PTR< IfcTemplatedEntityListList<IfcSchema::IfcCartesianPoint> > cps = l->ControlPointsList();
boost::shared_ptr< IfcTemplatedEntityListList<IfcSchema::IfcCartesianPoint> > cps = l->ControlPointsList();
std::vector<double> uknots = l->UKnots();
std::vector<double> vknots = l->VKnots();
std::vector<int> umults = l->UMultiplicities();
std::vector<int> vmults = l->VMultiplicities();
TColgp_Array2OfPnt Poles (0, cps->size() - 1, 0, (*cps->begin()).size() - 1);
TColStd_Array1OfReal UKnots(0, uknots.size() - 1);
TColStd_Array1OfReal VKnots(0, vknots.size() - 1);
TColStd_Array1OfInteger UMults(0, umults.size() - 1);
TColStd_Array1OfInteger VMults(0, vmults.size() - 1);
TColgp_Array2OfPnt Poles (0, (int)cps->size() - 1, 0, (int)(*cps->begin()).size() - 1);
TColStd_Array1OfReal UKnots(0, (int)uknots.size() - 1);
TColStd_Array1OfReal VKnots(0, (int)vknots.size() - 1);
TColStd_Array1OfInteger UMults(0, (int)umults.size() - 1);
TColStd_Array1OfInteger VMults(0, (int)vmults.size() - 1);
Standard_Integer UDegree = l->UDegree();
Standard_Integer VDegree = l->VDegree();
@@ -928,17 +948,13 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBSplineSurfaceWithKnots* l, To
}
Handle_Geom_Surface surf = new Geom_BSplineSurface(Poles, UKnots, VKnots, UMults, VMults, UDegree, VDegree);
#if OCC_VERSION_HEX < 0x60502
face = BRepBuilderAPI_MakeFace(surf);
#else
face = BRepBuilderAPI_MakeFace(surf, getValue(GV_PRECISION));
#endif
return true;
}
bool IfcGeom::Kernel::convert(const IfcSchema::IfcPlane* l, TopoDS_Shape& face) {
gp_Pln pln;
convert(l, pln);
Handle_Geom_Surface surf = new Geom_Plane(pln);
face = BRepBuilderAPI_MakeFace(surf, getValue(GV_PRECISION));
return true;
}
#endif
+256 -21
View File
@@ -63,6 +63,9 @@
#include <TopoDS.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_CompSolid.hxx>
#include <TopExp.hxx>
#include <TopExp_Explorer.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
@@ -95,14 +98,23 @@
#include <Poly_Triangulation.hxx>
#include <Poly_Array1OfTriangle.hxx>
#include <TopExp.hxx>
#include <TopTools_IndexedMapOfShape.hxx>
#include <TopTools_IndexedDataMapOfShapeListOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>
#include <Standard_Version.hxx>
#include "../ifcparse/IfcSIPrefix.h"
#include "../ifcgeom/IfcGeom.h"
#if OCC_VERSION_HEX < 0x60900
#ifdef _MSC_VER
#pragma message("warning: You are linking against Open CASCADE version " OCC_VERSION_COMPLETE ". Version 6.9.0 introduces various improvements with relation to boolean operations. You are advised to upgrade.")
#else
#warning "You are linking against linking against an older version of Open CASCADE. Version 6.9.0 introduces various improvements with relation to boolean operations. You are advised to upgrade."
#endif
#endif
bool IfcGeom::Kernel::create_solid_from_compound(const TopoDS_Shape& compound, TopoDS_Shape& shape) {
BRepOffsetAPI_Sewing builder;
builder.SetTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE));
@@ -160,10 +172,15 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
IfcSchema::IfcRelVoidsElement* v = *it;
IfcSchema::IfcFeatureElementSubtraction* fes = v->RelatedOpeningElement();
if ( fes->declaration().is(IfcSchema::Type::IfcOpeningElement) ) {
if (!fes->hasRepresentation()) continue;
// Convert the IfcRepresentation of the IfcOpeningElement
gp_Trsf opening_trsf;
IfcGeom::Kernel::convert(fes->ObjectPlacement(),opening_trsf);
if (fes->hasObjectPlacement()) {
try {
convert(fes->ObjectPlacement(),opening_trsf);
} catch (...) {}
}
// Move the opening into the coordinate system of the IfcProduct
opening_trsf.PreMultiply(entity_trsf.Inverted());
@@ -208,12 +225,11 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
? BRepBuilderAPI_GTransform(opening_shape_unlocated,opening_shape_gtrsf,true).Shape()
: opening_shape_unlocated.Moved(opening_shape_gtrsf.Trsf());
double opening_volume, original_shape_volume;
double opening_volume;
if ( Logger::Verbosity() >= Logger::LOG_WARNING ) {
opening_volume = shape_volume(opening_shape);
if ( opening_volume <= ALMOST_ZERO )
Logger::Message(Logger::LOG_WARNING, "Empty opening for:", entity);
original_shape_volume = shape_volume(entity_shape);
}
if (entity_shape.ShapeType() == TopAbs_COMPSOLID) {
@@ -228,16 +244,30 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
TopExp_Explorer exp(entity_shape, TopAbs_SOLID);
for (; exp.More(); exp.Next()) {
#if OCC_VERSION_HEX < 0x60900
BRepAlgoAPI_Cut brep_cut(exp.Current(), opening_shape);
#else
BRepAlgoAPI_Cut brep_cut;
TopTools_ListOfShape s1s;
s1s.Append(exp.Current());
TopTools_ListOfShape s2s;
s2s.Append(opening_shape);
brep_cut.SetFuzzyValue(getValue(GV_PRECISION));
brep_cut.SetArguments(s1s);
brep_cut.SetTools(s2s);
brep_cut.Build();
#endif
bool added = false;
if ( brep_cut.IsDone() ) {
TopoDS_Shape brep_cut_result = brep_cut;
BRepCheck_Analyzer analyser(brep_cut_result);
bool is_valid = analyser.IsValid() != 0;
if (is_valid) {
TopExp_Explorer exp(brep_cut_result, TopAbs_SOLID);
for (; exp.More(); exp.Next()) {
builder.Add(compound, exp.Current());
TopExp_Explorer exp2(brep_cut_result, TopAbs_SOLID);
for (; exp2.More(); exp2.Next()) {
builder.Add(compound, exp2.Current());
added = true;
}
}
@@ -253,7 +283,19 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
entity_shape = compound;
} else {
#if OCC_VERSION_HEX < 0x60900
BRepAlgoAPI_Cut brep_cut(entity_shape,opening_shape);
#else
BRepAlgoAPI_Cut brep_cut;
TopTools_ListOfShape s1s;
s1s.Append(entity_shape);
TopTools_ListOfShape s2s;
s2s.Append(opening_shape);
brep_cut.SetFuzzyValue(getValue(GV_PRECISION));
brep_cut.SetArguments(s1s);
brep_cut.SetTools(s2s);
brep_cut.Build();
#endif
if ( brep_cut.IsDone() ) {
TopoDS_Shape brep_cut_result = brep_cut;
@@ -272,7 +314,7 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
entity_shape = brep_cut_result;
if ( Logger::Verbosity() >= Logger::LOG_WARNING ) {
const double volume_after_subtraction = shape_volume(entity_shape);
double original_shape_volume = shape_volume(entity_shape);
if ( ALMOST_THE_SAME(original_shape_volume,volume_after_subtraction) )
Logger::Message(Logger::LOG_WARNING, "Subtraction yields unchanged volume:", entity);
}
@@ -291,6 +333,7 @@ bool IfcGeom::Kernel::convert_openings(const IfcSchema::IfcProduct* entity, cons
return true;
}
#if OCC_VERSION_HEX < 0x60900
bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings,
const IfcGeom::IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcGeom::IfcRepresentationShapeItems& cut_shapes) {
@@ -303,10 +346,15 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
IfcSchema::IfcRelVoidsElement* v = *it;
IfcSchema::IfcFeatureElementSubtraction* fes = v->RelatedOpeningElement();
if ( fes->declaration().is(IfcSchema::Type::IfcOpeningElement) ) {
if (!fes->hasRepresentation()) continue;
// Convert the IfcRepresentation of the IfcOpeningElement
gp_Trsf opening_trsf;
IfcGeom::Kernel::convert(fes->ObjectPlacement(),opening_trsf);
if (fes->hasObjectPlacement()) {
try {
convert(fes->ObjectPlacement(),opening_trsf);
} catch (...) {}
}
// Move the opening into the coordinate system of the IfcProduct
opening_trsf.PreMultiply(entity_trsf.Inverted());
@@ -346,6 +394,7 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
}
BRepAlgoAPI_Cut brep_cut(entity_shape,opening_compound);
bool is_valid = false;
if ( brep_cut.IsDone() ) {
TopoDS_Shape brep_cut_result = brep_cut;
@@ -367,6 +416,93 @@ bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity,
}
return true;
}
#else
bool IfcGeom::Kernel::convert_openings_fast(const IfcSchema::IfcProduct* entity, const IfcSchema::IfcRelVoidsElement::list::ptr& openings,
const IfcGeom::IfcRepresentationShapeItems& entity_shapes, const gp_Trsf& entity_trsf, IfcGeom::IfcRepresentationShapeItems& cut_shapes) {
TopTools_ListOfShape opening_shapelist;
for ( IfcSchema::IfcRelVoidsElement::list::it it = openings->begin(); it != openings->end(); ++ it ) {
IfcSchema::IfcRelVoidsElement* v = *it;
IfcSchema::IfcFeatureElementSubtraction* fes = v->RelatedOpeningElement();
if ( fes->is(IfcSchema::Type::IfcOpeningElement) ) {
if (!fes->hasRepresentation()) continue;
// Convert the IfcRepresentation of the IfcOpeningElement
gp_Trsf opening_trsf;
if (fes->hasObjectPlacement()) {
try {
convert(fes->ObjectPlacement(),opening_trsf);
} catch (...) {}
}
// Move the opening into the coordinate system of the IfcProduct
opening_trsf.PreMultiply(entity_trsf.Inverted());
IfcSchema::IfcProductRepresentation* prodrep = fes->Representation();
IfcSchema::IfcRepresentation::list::ptr reps = prodrep->Representations();
IfcGeom::IfcRepresentationShapeItems opening_shapes;
for ( IfcSchema::IfcRepresentation::list::it it2 = reps->begin(); it2 != reps->end(); ++ it2 ) {
convert_shapes(*it2,opening_shapes);
}
for ( unsigned int i = 0; i < opening_shapes.size(); ++ i ) {
gp_GTrsf gtrsf = opening_shapes[i].Placement();
gtrsf.PreMultiply(opening_trsf);
const TopoDS_Shape& opening_shape = gtrsf.Form() == gp_Other
? BRepBuilderAPI_GTransform(opening_shapes[i].Shape(),gtrsf,true).Shape()
: (opening_shapes[i].Shape()).Moved(gtrsf.Trsf());
opening_shapelist.Append(opening_shape);
}
}
}
// Iterate over the shapes of the IfcProduct
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it3 = entity_shapes.begin(); it3 != entity_shapes.end(); ++ it3 ) {
TopoDS_Shape entity_shape_solid;
const TopoDS_Shape& entity_shape_unlocated = ensure_fit_for_subtraction(it3->Shape(),entity_shape_solid);
const gp_GTrsf& entity_shape_gtrsf = it3->Placement();
TopoDS_Shape entity_shape;
if ( entity_shape_gtrsf.Form() == gp_Other ) {
Logger::Message(Logger::LOG_WARNING,"Applying non uniform transformation to:",entity->entity);
entity_shape = BRepBuilderAPI_GTransform(entity_shape_unlocated,entity_shape_gtrsf,true).Shape();
} else {
entity_shape = entity_shape_unlocated.Moved(entity_shape_gtrsf.Trsf());
}
BRepAlgoAPI_Cut brep_cut;
TopTools_ListOfShape s1s;
s1s.Append(entity_shape);
brep_cut.SetFuzzyValue(getValue(GV_PRECISION));
brep_cut.SetArguments(s1s);
brep_cut.SetTools(opening_shapelist);
brep_cut.Build();
bool is_valid = false;
if ( brep_cut.IsDone() ) {
TopoDS_Shape brep_cut_result = brep_cut;
BRepCheck_Analyzer analyser(brep_cut_result);
is_valid = analyser.IsValid() != 0;
if ( is_valid ) {
cut_shapes.push_back(IfcGeom::IfcRepresentationShapeItem(brep_cut_result, &it3->Style()));
}
}
if ( !is_valid ) {
// Apparently processing the boolean operation failed or resulted in an invalid result
// in which case the original shape without the subtractions is returned instead
// we try convert the openings in the original way, one by one.
Logger::Message(Logger::LOG_WARNING, "Subtracting combined openings compound failed:", entity->entity);
return false;
}
}
return true;
}
#endif
bool IfcGeom::Kernel::convert_wire_to_face(const TopoDS_Wire& wire, TopoDS_Face& face) {
BRepBuilderAPI_MakeFace mf(wire, false);
@@ -554,7 +690,7 @@ void IfcGeom::Kernel::setValue(GeomValue var, double value) {
}
}
double IfcGeom::Kernel::getValue(GeomValue var) {
double IfcGeom::Kernel::getValue(GeomValue var) const {
switch (var) {
case GV_DEFLECTION_TOLERANCE:
return deflection_tolerance;
@@ -615,11 +751,11 @@ IfcSchema::IfcProductDefinitionShape* IfcGeom::tesselate(TopoDS_Shape& shape, do
IfcSchema::IfcFaceOuterBound* bound = new IfcSchema::IfcFaceOuterBound(loop, face.Orientation() != TopAbs_REVERSED);
IfcSchema::IfcFaceBound::list::ptr bounds (new IfcSchema::IfcFaceBound::list);
bounds->push(bound);
IfcSchema::IfcFace* face = new IfcSchema::IfcFace(bounds);
IfcSchema::IfcFace* face2 = new IfcSchema::IfcFace(bounds);
es->push(loop);
es->push(bound);
es->push(face);
faces->push(face);
es->push(face2);
faces->push(face2);
}
}
}
@@ -703,7 +839,6 @@ bool IfcGeom::Kernel::fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& sha
// Now loop over all the vertices that are part of the wire(s) to be filled
for (int i = 1; i <= num_verts; ++i) {
first = current = TopoDS::Vertex(vertex_to_edges.FindKey(i));
const bool isSame = first.IsSame(current);
// We keep track of the vertices we already used
if (visited.find(vertex_to_edges.FindIndex(current)) != visited.end()) {
continue;
@@ -711,7 +846,7 @@ bool IfcGeom::Kernel::fill_nonmanifold_wires_with_planar_faces(TopoDS_Shape& sha
// Given these vertices, try to find closed loops and create new
// wires out of them.
BRepBuilderAPI_MakeWire w;
while (true) {
for (;;) {
visited.insert(vertex_to_edges.FindIndex(current));
// Find the edge that the current vertex is part of and points
// away from the previous vertex (null for the first vertex).
@@ -776,8 +911,14 @@ bool IfcGeom::Kernel::flatten_shape_list(const IfcGeom::IfcRepresentationShapeIt
_trsf = trsf.Trsf();
trsf_valid = true;
} catch (...) {}
const TopoDS_Shape moved_shape = trsf_valid ? merged.Moved(_trsf) :
BRepBuilderAPI_GTransform(merged,trsf,true).Shape();
const TopoDS_Shape moved_shape = trsf.Form() == gp_Identity
? merged
: (
trsf_valid
? merged.Moved(_trsf)
: BRepBuilderAPI_GTransform(merged,trsf,true).Shape()
);
if (shapes.size() == 1) {
result = moved_shape;
@@ -809,6 +950,10 @@ bool IfcGeom::Kernel::flatten_shape_list(const IfcGeom::IfcRepresentationShapeIt
}
}
if (!fuse) {
result = compound;
}
const bool success = !result.IsNull();
if (success) {
const double precision = getValue(GV_PRECISION);
@@ -818,11 +963,11 @@ bool IfcGeom::Kernel::flatten_shape_list(const IfcGeom::IfcRepresentationShapeIt
return success;
}
void IfcGeom::Kernel::remove_redundant_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol) {
void IfcGeom::Kernel::remove_duplicate_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol) {
if (tol <= 0.) tol = getValue(GV_POINT_EQUALITY_TOLERANCE);
tol *= tol;
while (true) {
for (;;) {
bool removed = false;
int n = polygon.Length() - (closed ? 0 : 1);
for (int i = 1; i <= n; ++i) {
@@ -842,6 +987,69 @@ void IfcGeom::Kernel::remove_redundant_points_from_loop(TColgp_SequenceOfPnt& po
}
}
void IfcGeom::Kernel::remove_collinear_points_from_loop(TColgp_SequenceOfPnt& polygon, bool closed, double tol) {
if (tol <= 0.) tol = getValue(GV_POINT_EQUALITY_TOLERANCE);
const int start = closed ? 1 : 2;
const int end = polygon.Length() - (closed ? 0 : 1);
std::vector<bool> to_remove(polygon.Length(), false);
for (int i = start; i <= end; ++i) {
const gp_Pnt& a = polygon.Value(((i - 2 + polygon.Length()) % polygon.Length()) + 1);
const gp_Pnt& b = polygon.Value(i);
const gp_Pnt& c = polygon.Value((i % polygon.Length()) + 1);
const gp_Vec d1 = c.XYZ() - a.XYZ();
const gp_Vec d2 = b.XYZ() - a.XYZ();
const double dt = d2.Dot(d1) / d1.Dot(d1);
const gp_Vec d3 = d1.Scaled(dt);
const gp_Pnt b2 = a.XYZ() + d3.XYZ();
if (b.Distance(b2) < tol) {
to_remove[i-1] = true;
}
}
for (int i = (int) to_remove.size() - 1; i >= 0; --i) {
if (to_remove[i]) {
polygon.Remove(i+1);
}
}
}
bool IfcGeom::Kernel::wire_to_sequence_of_point(const TopoDS_Wire& w, TColgp_SequenceOfPnt& p) {
TopExp_Explorer exp(w, TopAbs_EDGE);
for (; exp.More(); exp.Next()) {
double a, b;
Handle_Geom_Curve crv = BRep_Tool::Curve(TopoDS::Edge(exp.Current()), a, b);
if (crv->DynamicType() != STANDARD_TYPE(Geom_Line)) {
return false;
}
}
exp.ReInit();
int i = 0;
for (; exp.More(); exp.Next(), ++i) {
TopoDS_Vertex v1, v2;
TopExp::Vertices(TopoDS::Edge(exp.Current()), v1, v2, true);
if (exp.More()) {
if (i == 0) {
p.Append(BRep_Tool::Pnt(v1));
}
p.Append(BRep_Tool::Pnt(v2));
}
}
return true;
}
void IfcGeom::Kernel::sequence_of_point_to_wire(const TColgp_SequenceOfPnt& p, TopoDS_Wire& w, bool close) {
BRepBuilderAPI_MakePolygon builder;
for (int i = 1; i <= p.Length(); ++i) {
builder.Add(p.Value(i));
}
if (close) {
builder.Close();
}
w = builder.Wire();
}
template <typename P>
IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_representation_and_product(const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product) {
IfcGeom::Representation::BRep* shape;
@@ -898,7 +1106,12 @@ IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_representation_and_pro
if ( !settings.disable_opening_subtractions() && openings && openings->size() ) {
IfcGeom::IfcRepresentationShapeItems opened_shapes;
try {
if ( settings.faster_booleans() ) {
#if OCC_VERSION_HEX < 0x60900
const bool faster_booleans = settings.faster_booleans();
#else
const bool faster_booleans = true;
#endif
if (faster_booleans) {
bool succes = convert_openings_fast(product,openings,shapes,trsf,opened_shapes);
if ( ! succes ) {
opened_shapes.clear();
@@ -1065,4 +1278,26 @@ std::pair<std::string, double> IfcGeom::Kernel::initializeUnits(IfcSchema::IfcUn
}
return std::pair<std::string, double>(unit_name, unit_magnitude);
}
}
const IfcSchema::IfcRepresentationItem* IfcGeom::Kernel::find_item_carrying_style(const IfcSchema::IfcRepresentationItem* item) {
if (item->StyledByItem()->size()) {
return item;
}
while (item->declaration().is(IfcSchema::Type::IfcBooleanClippingResult)) {
// All instantiations of IfcBooleanOperand (type of FirstOperand) are subtypes of
// IfcGeometricRepresentationItem
item = (IfcSchema::IfcGeometricRepresentationItem*) ((IfcSchema::IfcBooleanClippingResult*) item)->FirstOperand();
if (item->StyledByItem()->size()) {
return item;
}
}
// TODO: Ideally this would be done for other entities (such as IfcCsgSolid) as well.
// But neither are these very prevalent, nor does the current IfcOpenShell style
// mechanism enable to conveniently style subshapes, which would be necessary for
// distinctly styled union operands.
return item;
}
+1 -1
View File
@@ -287,7 +287,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcObjectPlacement* l, gp_Trsf& t
return false;
}
IfcSchema::IfcLocalPlacement* current = (IfcSchema::IfcLocalPlacement*)l;
while (1) {
for (;;) {
gp_Trsf trsf2;
IfcSchema::IfcAxis2Placement* relplacement = current->RelativePlacement();
if ( relplacement->declaration().is(IfcSchema::Type::IfcAxis2Placement3D) ) {
+22 -21
View File
@@ -64,6 +64,8 @@
#include <limits>
#include <algorithm>
#include <boost/algorithm/string.hpp>
#include <gp_Mat.hxx>
#include <gp_Mat2d.hxx>
#include <gp_GTrsf.hxx>
@@ -125,10 +127,7 @@ namespace IfcGeom {
void populate_set(const std::set<std::string>& include_or_ignore) {
entities_to_include_or_exclude.clear();
for (std::set<std::string>::const_iterator it = include_or_ignore.begin(); it != include_or_ignore.end(); ++it) {
std::string uppercase_type = *it;
for (std::string::iterator c = uppercase_type.begin(); c != uppercase_type.end(); ++c) {
*c = toupper(*c);
}
const std::string uppercase_type = boost::to_upper_copy(*it);
IfcSchema::Type::Enum ty;
try {
ty = IfcSchema::Type::FromString(uppercase_type);
@@ -181,15 +180,15 @@ namespace IfcGeom {
// by the parent's context inverse attributes.
continue;
}
if (context->hasContextType()) {
std::string context_type_lc = context->ContextType();
for (std::string::iterator c = context_type_lc.begin(); c != context_type_lc.end(); ++c) {
*c = tolower(*c);
try {
if (context->hasContextType()) {
std::string context_type = context->ContextType();
boost::to_lower(context_type);
if (context_types.find(context_type) != context_types.end()) {
filtered_contexts->push(context);
}
}
if (context_types.find(context_type_lc) != context_types.end()) {
filtered_contexts->push(context);
}
}
} catch (const IfcParse::IfcException&) {}
}
// In case no contexts are identified based on their ContextType, all contexts are
@@ -207,10 +206,12 @@ namespace IfcGeom {
IfcSchema::IfcGeometricRepresentationContext* context = *it;
representations->push(context->RepresentationsInContext());
if (context->hasPrecision() && context->Precision() < lowest_precision_encountered) {
lowest_precision_encountered = context->Precision();
any_precision_encountered = true;
}
try {
if (context->hasPrecision() && context->Precision() < lowest_precision_encountered) {
lowest_precision_encountered = context->Precision();
any_precision_encountered = true;
}
} catch (const IfcParse::IfcException&) {}
IfcSchema::IfcGeometricRepresentationSubContext::list::ptr sub_contexts = context->HasSubContexts();
for (jt = sub_contexts->begin(); jt != sub_contexts->end(); ++jt) {
representations->push((*jt)->RepresentationsInContext());
@@ -288,7 +289,7 @@ namespace IfcGeom {
}
BRepElement<P>* create_shape_model_for_next_entity() {
while ( true ) {
for (;;) {
IfcSchema::IfcRepresentation* representation;
// Have we reached the end of our list of representations?
@@ -321,16 +322,16 @@ namespace IfcGeom {
// Filter the products based on the set of entities being included or excluded for
// processing. The set is iterated over te able to filter on subtypes.
for ( IfcSchema::IfcProduct::list::it it = unfiltered_products->begin(); it != unfiltered_products->end(); ++it ) {
for ( IfcSchema::IfcProduct::list::it jt = unfiltered_products->begin(); jt != unfiltered_products->end(); ++jt ) {
bool found = false;
for (std::set<IfcSchema::Type::Enum>::const_iterator jt = entities_to_include_or_exclude.begin(); jt != entities_to_include_or_exclude.end(); ++jt) {
if ((*it)->declaration().is(*jt)) {
for (std::set<IfcSchema::Type::Enum>::const_iterator kt = entities_to_include_or_exclude.begin(); kt != entities_to_include_or_exclude.end(); ++kt) {
if ((*jt)->declaration().is(*kt)) {
found = true;
break;
}
}
if (found == include_entities_in_processing) {
ifcproducts->push(*it);
ifcproducts->push(*jt);
}
}
+4 -4
View File
@@ -21,7 +21,7 @@
#include "IfcGeom.h"
bool process_colour(IfcSchema::IfcColourRgb* colour, std::tr1::array<double, 3>& rgb) {
bool process_colour(IfcSchema::IfcColourRgb* colour, double* rgb) {
if (colour != 0) {
rgb[0] = colour->Red();
rgb[1] = colour->Green();
@@ -30,7 +30,7 @@ bool process_colour(IfcSchema::IfcColourRgb* colour, std::tr1::array<double, 3>&
return colour != 0;
}
bool process_colour(IfcSchema::IfcNormalisedRatioMeasure* factor, std::tr1::array<double, 3>& rgb) {
bool process_colour(IfcSchema::IfcNormalisedRatioMeasure* factor, double* rgb) {
if (factor != 0) {
const double f = *factor;
rgb[0] = rgb[1] = rgb[2] = f;
@@ -38,7 +38,7 @@ bool process_colour(IfcSchema::IfcNormalisedRatioMeasure* factor, std::tr1::arra
return factor != 0;
}
bool process_colour(IfcSchema::IfcColourOrFactor* colour_or_factor, std::tr1::array<double, 3>& rgb) {
bool process_colour(IfcSchema::IfcColourOrFactor* colour_or_factor, double* rgb) {
if (colour_or_factor == 0) {
return false;
} else if (colour_or_factor->declaration().is(IfcSchema::Type::IfcColourRgb)) {
@@ -66,7 +66,7 @@ const IfcGeom::SurfaceStyle* IfcGeom::Kernel::get_style(const IfcSchema::IfcRepr
} else {
surface_style = SurfaceStyle(surface_style_id);
}
std::tr1::array<double, 3> rgb;
double rgb[3];
if (process_colour(shading_styles.second->SurfaceColour(), rgb)) {
surface_style.Diffuse().reset(SurfaceStyle::ColorComponent(rgb[0], rgb[1], rgb[2]));
}
+1 -11
View File
@@ -20,16 +20,6 @@
#ifndef IFCGEOMRENDERSTYLES_H
#define IFCGEOMRENDERSTYLES_H
#ifdef __GNUC__
#include <tr1/array>
#else
#if _MSC_VER < 1600
#include <boost/tr1/array.hpp>
#else
#include <array>
#endif
#endif
#ifdef USE_IFC4
#include "../ifcparse/Ifc4.h"
#else
@@ -41,7 +31,7 @@ namespace IfcGeom {
public:
class ColorComponent {
private:
std::tr1::array<double, 3> data;
double data[3];
public:
ColorComponent(double r, double g, double b) {
data[0] = r; data[1] = g; data[2] = b;
+20 -18
View File
@@ -41,6 +41,8 @@ namespace IfcGeom {
namespace Representation {
class Representation {
Representation(const Representation&); //N/A
Representation& operator =(const Representation&); //N/A
protected:
const ElementSettings _settings;
public:
@@ -116,33 +118,33 @@ namespace IfcGeom {
: Representation(shape_model.settings())
, _id(shape_model.getId())
{
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator it = shape_model.begin(); it != shape_model.end(); ++ it ) {
for ( IfcGeom::IfcRepresentationShapeItems::const_iterator iit = shape_model.begin(); iit != shape_model.end(); ++ iit ) {
int surface_style_id = -1;
if (it->hasStyle()) {
Material adapter(&it->Style());
if (iit->hasStyle()) {
Material adapter(&iit->Style());
std::vector<Material>::const_iterator jt = std::find(_materials.begin(), _materials.end(), adapter);
if (jt == _materials.end()) {
surface_style_id = _materials.size();
surface_style_id = (int)_materials.size();
_materials.push_back(adapter);
} else {
surface_style_id = jt - _materials.begin();
surface_style_id = (int)(jt - _materials.begin());
}
}
if (settings().apply_default_materials() && surface_style_id == -1) {
Material material(IfcGeom::get_default_style(settings().element_type()));
std::vector<Material>::const_iterator it = std::find(_materials.begin(), _materials.end(), material);
if (it == _materials.end()) {
surface_style_id = _materials.size();
std::vector<Material>::const_iterator mit = std::find(_materials.begin(), _materials.end(), material);
if (mit == _materials.end()) {
surface_style_id = (int)_materials.size();
_materials.push_back(material);
} else {
surface_style_id = it - _materials.begin();
surface_style_id = (int)(mit - _materials.begin());
}
}
const TopoDS_Shape& s = it->Shape();
const gp_GTrsf& trsf = it->Placement();
const TopoDS_Shape& s = iit->Shape();
const gp_GTrsf& trsf = iit->Placement();
// Triangulate the shape
try {
@@ -231,11 +233,11 @@ namespace IfcGeom {
addEdge(dict[n2], dict[n3], edgecount, edges_temp);
addEdge(dict[n3], dict[n1], edgecount, edges_temp);
}
for ( std::vector<std::pair<int,int> >::const_iterator it = edges_temp.begin(); it != edges_temp.end(); ++it ) {
if (edgecount[*it] == 1) {
for ( std::vector<std::pair<int,int> >::const_iterator jt = edges_temp.begin(); jt != edges_temp.end(); ++jt ) {
if (edgecount[*jt] == 1) {
// non manifold edge, face boundary
_edges.push_back(it->first);
_edges.push_back(it->second);
_edges.push_back(jt->first);
_edges.push_back(jt->second);
}
}
}
@@ -245,11 +247,11 @@ namespace IfcGeom {
// Edges are only emitted if there are no faces. A mixed representation of faces
// and loose edges is discouraged by the standard. An alternative would be to use
// TopExp::MapShapesAndAncestors() to find edges that do not belong to any face.
for (TopExp_Explorer exp(s, TopAbs_EDGE); exp.More(); exp.Next()) {
BRepAdaptor_Curve crv(TopoDS::Edge(exp.Current()));
for (TopExp_Explorer texp(s, TopAbs_EDGE); texp.More(); texp.Next()) {
BRepAdaptor_Curve crv(TopoDS::Edge(texp.Current()));
GCPnts_QuasiUniformDeflection tessellater(crv, settings().deflection_tolerance());
int n = tessellater.NbPoints();
int start = _verts.size() / 3;
int start = (int)_verts.size() / 3;
for (int i = 1; i <= n; ++i) {
gp_XYZ p = tessellater.Value(i).XYZ();
trsf.Transforms(p);
+70 -11
View File
@@ -65,6 +65,8 @@
#include <TopoDS.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Face.hxx>
#include <TopoDS_CompSolid.hxx>
#include <TopExp_Explorer.hxx>
#include <BRepPrimAPI_MakePrism.hxx>
@@ -99,10 +101,15 @@
#include "../ifcgeom/IfcGeom.h"
bool IfcGeom::Kernel::convert(const IfcSchema::IfcExtrudedAreaSolid* l, TopoDS_Shape& shape) {
const double height = l->Depth() * getValue(GV_LENGTH_UNIT);
if (height < getValue(GV_PRECISION)) {
Logger::Message(Logger::LOG_ERROR, "Non-positive extrusion height encountered for:", l);
return false;
}
TopoDS_Shape face;
if ( !convert_face(l->SweptArea(),face) ) return false;
const double height = l->Depth() * getValue(GV_LENGTH_UNIT);
gp_Trsf trsf;
IfcGeom::Kernel::convert(l->Position(),trsf);
@@ -244,10 +251,20 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcHalfSpaceSolid* l, TopoDS_Shap
bool IfcGeom::Kernel::convert(const IfcSchema::IfcPolygonalBoundedHalfSpace* l, TopoDS_Shape& shape) {
TopoDS_Shape halfspace;
if ( ! IfcGeom::Kernel::convert((IfcSchema::IfcHalfSpaceSolid*)l,halfspace) ) return false;
TopoDS_Wire wire;
if ( ! convert_wire(l->PolygonalBoundary(),wire) || ! wire.Closed() ) return false;
if ( ! convert_wire(l->PolygonalBoundary(),wire) || ! wire.Closed() ) return false;
gp_Trsf trsf;
convert(l->Position(),trsf);
if ( ! convert(l->Position(),trsf) ) return false;
TColgp_SequenceOfPnt points;
if (wire_to_sequence_of_point(wire, points)) {
remove_duplicate_points_from_loop(points, wire.Closed()); // Note: wire always closed, as per if statement above
remove_collinear_points_from_loop(points, wire.Closed());
sequence_of_point_to_wire(points, wire, wire.Closed());
}
TopoDS_Shape prism = BRepPrimAPI_MakePrism(BRepBuilderAPI_MakeFace(wire),gp_Vec(0,0,200));
gp_Trsf down; down.SetTranslation(gp_Vec(0,0,-100.0));
prism.Move(trsf*down);
@@ -272,6 +289,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcShellBasedSurfaceModel* l, Ifc
}
bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape& shape) {
TopoDS_Shape s1, s2;
IfcRepresentationShapeItems items1, items2;
TopoDS_Wire boundary_wire;
@@ -325,10 +343,36 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape
const IfcSchema::IfcBooleanOperator::IfcBooleanOperator op = l->Operator();
/*
// TK: A little debugging trick to output both operands for visual inspection
BRep_Builder builder;
TopoDS_Compound compound;
builder.MakeCompound(compound);
builder.Add(compound, s1);
builder.Add(compound, s2);
shape = compound;
return true;
*/
if (op == IfcSchema::IfcBooleanOperator::IfcBooleanOperator_DIFFERENCE) {
bool valid_cut = false;
BRepAlgoAPI_Cut brep_cut(s1,s2);
#if OCC_VERSION_HEX < 0x60900
BRepAlgoAPI_Cut brep_cut(s1, s2);
#else
BRepAlgoAPI_Cut brep_cut;
TopTools_ListOfShape s1s;
s1s.Append(s1);
TopTools_ListOfShape s2s;
s2s.Append(s2);
brep_cut.SetFuzzyValue(getValue(GV_PRECISION));
brep_cut.SetArguments(s1s);
brep_cut.SetTools(s2s);
brep_cut.Build();
#endif
if ( brep_cut.IsDone() ) {
TopoDS_Shape result = brep_cut;
@@ -399,7 +443,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcBooleanResult* l, TopoDS_Shape
bool IfcGeom::Kernel::convert(const IfcSchema::IfcConnectedFaceSet* l, TopoDS_Shape& shape) {
IfcSchema::IfcFace::list::ptr faces = l->CfsFaces();
bool facesAdded = false;
const unsigned int num_faces = faces->size();
const unsigned int num_faces = (unsigned)faces->size();
bool valid_shell = false;
if ( num_faces < getValue(GV_MAX_FACES_TO_SEW) ) {
BRepOffsetAPI_Sewing builder;
@@ -492,11 +536,22 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcMappedItem* l, IfcRepresentati
trsf = trsf_2d;
}
gtrsf.Multiply(trsf);
const IfcGeom::SurfaceStyle* mapped_item_style = get_style(l);
const unsigned int previous_size = (const unsigned int) shapes.size();
bool b = convert_shapes(map->MappedRepresentation(),shapes);
bool b = convert_shapes(map->MappedRepresentation(), shapes);
for ( unsigned int i = previous_size; i < shapes.size(); ++ i ) {
shapes[i].append(gtrsf);
// Apply styles assigned to the mapped item only if on
// a more granular level no styles have been applied
if (!shapes[i].hasStyle()) {
shapes[i].setStyle(mapped_item_style);
}
}
return b;
}
@@ -627,9 +682,9 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCurveBoundedPlane* l, TopoDS_S
BRepBuilderAPI_MakeFace mf (outer);
mf.Add(outer);
IfcSchema::IfcCurve::list::ptr inner = l->InnerBoundaries();
IfcSchema::IfcCurve::list::ptr boundaries = l->InnerBoundaries();
for (IfcSchema::IfcCurve::list::it it = inner->begin(); it != inner->end(); ++it) {
for (IfcSchema::IfcCurve::list::it it = boundaries->begin(); it != boundaries->end(); ++it) {
TopoDS_Wire inner;
convert_wire(*it, inner);
@@ -762,8 +817,8 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcSweptDiskSolid* l, TopoDS_Shap
// Subtraction of pipes with small radii is unstable.
hasInnerRadius = false;
} else {
Handle(Geom_Circle) circle = new Geom_Circle(directrix, r2);
section2 = BRepBuilderAPI_MakeWire(BRepBuilderAPI_MakeEdge(circle));
Handle(Geom_Circle) circle2 = new Geom_Circle(directrix, r2);
section2 = BRepBuilderAPI_MakeWire(BRepBuilderAPI_MakeEdge(circle2));
}
}
@@ -817,7 +872,11 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCylindricalSurface* l, TopoDS_
gp_Trsf trsf;
IfcGeom::Kernel::convert(l->Position(),trsf);
#if OCC_VERSION_HEX < 0x60502
face = BRepBuilderAPI_MakeFace(new Geom_CylindricalSurface(gp::XOY(), l->Radius())).Face().Moved(trsf);
#else
face = BRepBuilderAPI_MakeFace(new Geom_CylindricalSurface(gp::XOY(), l->Radius()), getValue(GV_PRECISION)).Face().Moved(trsf);
#endif
return true;
}
@@ -882,7 +941,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTriangulatedFaceSet* l, TopoDS
if (faces.empty()) return false;
const unsigned int num_faces = indices.size();
const unsigned int num_faces = (unsigned)indices.size();
bool valid_shell = false;
if (faces.size() < getValue(GV_MAX_FACES_TO_SEW)) {
+25 -8
View File
@@ -168,6 +168,25 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCompositeCurve* l, TopoDS_Wire
//last_vertex = w.Vertex();
if ( w.Error() != BRepBuilderAPI_WireDone ) {
Logger::Message(Logger::LOG_ERROR, "Failed to join curve segments:", l);
TopoDS_Vertex v1, v2, last;
last = w.Vertex();
if (!last.IsNull()) {
std::stringstream ss;
gp_Pnt p = BRep_Tool::Pnt(last);
ss << std::setprecision(4) << "Last vertex at (" << p.X() << " " << p.Y() << " " << p.Z() << ")";
Logger::Message(Logger::LOG_NOTICE, ss.str());
}
TopExp::Vertices(wire2, v1, v2);
if (!v1.IsNull()) {
std::stringstream ss;
gp_Pnt p = BRep_Tool::Pnt(v1);
ss << std::setprecision(4) << "Segment starts at (" << p.X() << " " << p.Y() << " " << p.Z() << ") for:";
Logger::Message(Logger::LOG_NOTICE, ss.str(), *it);
}
return false;
}
}
@@ -184,8 +203,6 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire&
bool trim_cartesian = l->MasterRepresentation() == IfcSchema::IfcTrimmingPreference::IfcTrimmingPreference_CARTESIAN;
IfcEntityList::ptr trims1 = l->Trim1();
IfcEntityList::ptr trims2 = l->Trim2();
bool trimmed1 = false;
bool trimmed2 = false;
unsigned sense_agreement = l->SenseAgreement() ? 0 : 1;
double flts[2];
gp_Pnt pnts[2];
@@ -257,7 +274,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcTrimmedCurve* l, TopoDS_Wire&
flts[1] -= M_PI / 2.;
}
}
if ( isConic && ALMOST_THE_SAME(fmod(flts[1]-flts[0],(double)(M_PI*2.0)),0.0f) ) {
if ( isConic && ALMOST_THE_SAME(fmod(flts[1]-flts[0],M_PI*2.),0.) ) {
w.Add(BRepBuilderAPI_MakeEdge(curve));
} else {
BRepBuilderAPI_MakeEdge e (curve,flts[0],flts[1]);
@@ -286,7 +303,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcPolyline* l, TopoDS_Wire& resu
}
// Remove points that are too close to one another
remove_redundant_points_from_loop(polygon, false);
remove_duplicate_points_from_loop(polygon, false);
BRepBuilderAPI_MakePolygon w;
for (int i = 1; i <= polygon.Length(); ++i) {
@@ -316,7 +333,7 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcPolyLoop* l, TopoDS_Wire& resu
}
// Remove points that are too close to one another
remove_redundant_points_from_loop(polygon, true);
remove_duplicate_points_from_loop(polygon, true);
int count = polygon.Length();
if (original_count - count != 0) {
@@ -411,9 +428,9 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcEdgeLoop* l, TopoDS_Wire& resu
TopoDS_Wire w;
if (convert_wire(*it, w)) {
if (!(*it)->Orientation()) w.Reverse();
TopoDS_Iterator it(w, false);
for (; it.More(); it.Next()) {
const TopoDS_Edge& e = TopoDS::Edge(it.Value());
TopoDS_Iterator topoit(w, false);
for (; topoit.More(); topoit.Next()) {
const TopoDS_Edge& e = TopoDS::Edge(topoit.Value());
mw.Add(e);
}
// mw.Add(w);
+9
View File
@@ -24,6 +24,15 @@ using namespace IfcSchema;
using namespace IfcUtil;
bool IfcGeom::Kernel::convert_shapes(const IfcBaseClass* l, IfcRepresentationShapeItems& r) {
if (shape_type(l) != ST_SHAPELIST) {
TopoDS_Shape shp;
if (convert_shape(l, shp)) {
r.push_back(IfcGeom::IfcRepresentationShapeItem(shp, get_style(l->as<IfcSchema::IfcRepresentationItem>())));
return true;
}
return false;
}
#include "IfcRegisterConvertShapes.h"
Logger::Message(Logger::LOG_ERROR, "No operation defined for:", l);
return false;
+1 -1
View File
@@ -53,9 +53,9 @@ SHAPE(IfcCylindricalSurface);
SHAPE(IfcAdvancedBrep);
// FIXME: Surfaces should have a shape type of their own
SHAPE(IfcBSplineSurfaceWithKnots);
SHAPE(IfcPlane);
SHAPE(IfcTriangulatedFaceSet);
#endif
SHAPE(IfcPlane);
SHAPE(IfcExtrudedAreaSolid);
SHAPE(IfcRevolvedAreaSolid);
SHAPE(IfcConnectedFaceSet);
+1
View File
@@ -46,6 +46,7 @@ namespace IfcGeom {
const gp_GTrsf& Placement() const { return placement; }
bool hasStyle() const { return style != 0; }
const SurfaceStyle& Style() const { return *style; }
void setStyle(const SurfaceStyle* style) { this->style = style; }
};
typedef std::vector<IfcRepresentationShapeItem> IfcRepresentationShapeItems;
}