mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-25 07:09:22 +00:00
Directly re-use IfcMappedItem triangulated elements when not using world coordinates
This commit is contained in:
@@ -19,10 +19,12 @@
|
|||||||
|
|
||||||
#ifdef WITH_OPENCOLLADA
|
#ifdef WITH_OPENCOLLADA
|
||||||
|
|
||||||
#include <string>
|
|
||||||
|
|
||||||
#include "ColladaSerializer.h"
|
#include "ColladaSerializer.h"
|
||||||
|
|
||||||
|
#include <boost/lexical_cast.hpp>
|
||||||
|
|
||||||
|
#include <string>
|
||||||
|
|
||||||
std::string collada_id(const std::string& s) {
|
std::string collada_id(const std::string& s) {
|
||||||
std::string id;
|
std::string id;
|
||||||
id.reserve(s.size());
|
id.reserve(s.size());
|
||||||
@@ -254,7 +256,7 @@ void ColladaSerializer::ColladaExporter::startDocument(const std::string& unit_n
|
|||||||
asset.add();
|
asset.add();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::ColladaExporter::write(const std::string& unique_id, const std::string& type, const std::vector<double>& matrix, const std::vector<double>& vertices, const std::vector<double>& normals, const std::vector<int>& faces, const std::vector<int>& edges, const std::vector<int>& material_ids, const std::vector<IfcGeom::Material>& _materials) {
|
void ColladaSerializer::ColladaExporter::write(const std::string& unique_id, const std::string& representation_id, const std::string& type, const std::vector<double>& matrix, const std::vector<double>& vertices, const std::vector<double>& normals, const std::vector<int>& faces, const std::vector<int>& edges, const std::vector<int>& material_ids, const std::vector<IfcGeom::Material>& _materials) {
|
||||||
std::vector<std::string> material_references;
|
std::vector<std::string> material_references;
|
||||||
for (std::vector<IfcGeom::Material>::const_iterator it = _materials.begin(); it != _materials.end(); ++it) {
|
for (std::vector<IfcGeom::Material>::const_iterator it = _materials.begin(); it != _materials.end(); ++it) {
|
||||||
const IfcGeom::Material& material = *it;
|
const IfcGeom::Material& material = *it;
|
||||||
@@ -263,21 +265,25 @@ void ColladaSerializer::ColladaExporter::write(const std::string& unique_id, con
|
|||||||
}
|
}
|
||||||
material_references.push_back(collada_id(material.name()));
|
material_references.push_back(collada_id(material.name()));
|
||||||
}
|
}
|
||||||
deferreds.push_back(DeferredObject(unique_id, type, matrix, vertices, normals, faces, edges, material_ids, _materials, material_references));
|
deferreds.push_back(DeferredObject(unique_id, representation_id, type, matrix, vertices, normals, faces, edges, material_ids, _materials, material_references));
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::ColladaExporter::endDocument() {
|
void ColladaSerializer::ColladaExporter::endDocument() {
|
||||||
// In fact due the XML based nature of Collada and its dependency on library nodes,
|
// In fact due the XML based nature of Collada and its dependency on library nodes,
|
||||||
// only at this point all objects are written to the stream.
|
// only at this point all objects are written to the stream.
|
||||||
materials.write();
|
materials.write();
|
||||||
|
std::set<std::string> geometries_written;
|
||||||
for (std::vector<DeferredObject>::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) {
|
for (std::vector<DeferredObject>::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) {
|
||||||
const std::string object_name = it->unique_id + "-representation";
|
if (geometries_written.find(it->representation_id) != geometries_written.end()) {
|
||||||
geometries.write(object_name, it->type, it->vertices, it->normals, it->faces, it->edges, it->material_ids, it->materials);
|
continue;
|
||||||
|
}
|
||||||
|
geometries_written.insert(it->representation_id);
|
||||||
|
geometries.write(it->representation_id, it->type, it->vertices, it->normals, it->faces, it->edges, it->material_ids, it->materials);
|
||||||
}
|
}
|
||||||
geometries.close();
|
geometries.close();
|
||||||
for (std::vector<DeferredObject>::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) {
|
for (std::vector<DeferredObject>::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) {
|
||||||
const std::string object_name = it->unique_id;
|
const std::string object_name = it->unique_id;
|
||||||
scene.add(object_name, object_name, object_name + "-representation", it->material_references, it->matrix);
|
scene.add(object_name, object_name, it->representation_id, it->material_references, it->matrix);
|
||||||
}
|
}
|
||||||
scene.write();
|
scene.write();
|
||||||
stream.endDocument();
|
stream.endDocument();
|
||||||
@@ -293,7 +299,7 @@ void ColladaSerializer::writeHeader() {
|
|||||||
|
|
||||||
void ColladaSerializer::write(const IfcGeom::TriangulationElement<double>* o) {
|
void ColladaSerializer::write(const IfcGeom::TriangulationElement<double>* o) {
|
||||||
const IfcGeom::Representation::Triangulation<double>& mesh = o->geometry();
|
const IfcGeom::Representation::Triangulation<double>& mesh = o->geometry();
|
||||||
exporter.write(o->unique_id(), o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials());
|
exporter.write(o->unique_id(), "representation-" + boost::lexical_cast<std::string>(o->geometry().id()), o->type(), o->transformation().matrix().data(), mesh.verts(), mesh.normals(), mesh.faces(), mesh.edges(), mesh.material_ids(), mesh.materials());
|
||||||
}
|
}
|
||||||
|
|
||||||
void ColladaSerializer::finalize() {
|
void ColladaSerializer::finalize() {
|
||||||
|
|||||||
@@ -111,7 +111,7 @@ private:
|
|||||||
};
|
};
|
||||||
class DeferredObject {
|
class DeferredObject {
|
||||||
public:
|
public:
|
||||||
std::string unique_id, type;
|
std::string unique_id, representation_id, type;
|
||||||
std::vector<double> matrix;
|
std::vector<double> matrix;
|
||||||
std::vector<double> vertices;
|
std::vector<double> vertices;
|
||||||
std::vector<double> normals;
|
std::vector<double> normals;
|
||||||
@@ -120,10 +120,11 @@ private:
|
|||||||
std::vector<int> material_ids;
|
std::vector<int> material_ids;
|
||||||
std::vector<IfcGeom::Material> materials;
|
std::vector<IfcGeom::Material> materials;
|
||||||
std::vector<std::string> material_references;
|
std::vector<std::string> material_references;
|
||||||
DeferredObject(const std::string& unique_id, const std::string& type, const std::vector<double>& matrix, const std::vector<double>& vertices,
|
DeferredObject(const std::string& unique_id, const std::string& representation_id, const std::string& type, const std::vector<double>& matrix, const std::vector<double>& vertices,
|
||||||
const std::vector<double>& normals, const std::vector<int>& faces, const std::vector<int>& edges, const std::vector<int>& material_ids,
|
const std::vector<double>& normals, const std::vector<int>& faces, const std::vector<int>& edges, const std::vector<int>& material_ids,
|
||||||
const std::vector<IfcGeom::Material>& materials, const std::vector<std::string>& material_references)
|
const std::vector<IfcGeom::Material>& materials, const std::vector<std::string>& material_references)
|
||||||
: unique_id(unique_id)
|
: unique_id(unique_id)
|
||||||
|
, representation_id(representation_id)
|
||||||
, type(type)
|
, type(type)
|
||||||
, matrix(matrix)
|
, matrix(matrix)
|
||||||
, vertices(vertices)
|
, vertices(vertices)
|
||||||
@@ -151,7 +152,7 @@ private:
|
|||||||
std::vector<DeferredObject> deferreds;
|
std::vector<DeferredObject> deferreds;
|
||||||
virtual ~ColladaExporter() {}
|
virtual ~ColladaExporter() {}
|
||||||
void startDocument(const std::string& unit_name, float unit_magnitude);
|
void startDocument(const std::string& unit_name, float unit_magnitude);
|
||||||
void write(const std::string& unique_id, const std::string& type, const std::vector<double>& matrix, const std::vector<double>& vertices, const std::vector<double>& normals, const std::vector<int>& faces, const std::vector<int>& edges, const std::vector<int>& material_ids, const std::vector<IfcGeom::Material>& materials);
|
void write(const std::string& unique_id, const std::string& representation_id, const std::string& type, const std::vector<double>& matrix, const std::vector<double>& vertices, const std::vector<double>& normals, const std::vector<int>& faces, const std::vector<int>& edges, const std::vector<int>& material_ids, const std::vector<IfcGeom::Material>& materials);
|
||||||
void endDocument();
|
void endDocument();
|
||||||
};
|
};
|
||||||
ColladaExporter exporter;
|
ColladaExporter exporter;
|
||||||
|
|||||||
@@ -142,6 +142,10 @@ public:
|
|||||||
bool wire_to_sequence_of_point(const TopoDS_Wire&, TColgp_SequenceOfPnt&);
|
bool wire_to_sequence_of_point(const TopoDS_Wire&, TColgp_SequenceOfPnt&);
|
||||||
void sequence_of_point_to_wire(const TColgp_SequenceOfPnt&, TopoDS_Wire&, bool closed);
|
void sequence_of_point_to_wire(const TColgp_SequenceOfPnt&, TopoDS_Wire&, bool closed);
|
||||||
|
|
||||||
|
bool is_identity_transform(IfcUtil::IfcBaseClass*);
|
||||||
|
|
||||||
|
IfcSchema::IfcRelVoidsElement::list::ptr find_openings(IfcSchema::IfcProduct* product);
|
||||||
|
|
||||||
std::pair<std::string, double> initializeUnits(IfcSchema::IfcUnitAssignment*);
|
std::pair<std::string, double> initializeUnits(IfcSchema::IfcUnitAssignment*);
|
||||||
|
|
||||||
IfcSchema::IfcObjectDefinition* get_decomposing_entity(IfcSchema::IfcProduct*);
|
IfcSchema::IfcObjectDefinition* get_decomposing_entity(IfcSchema::IfcProduct*);
|
||||||
@@ -149,6 +153,9 @@ public:
|
|||||||
template <typename P>
|
template <typename P>
|
||||||
IfcGeom::BRepElement<P>* create_brep_for_representation_and_product(const IteratorSettings&, IfcSchema::IfcRepresentation*, IfcSchema::IfcProduct*);
|
IfcGeom::BRepElement<P>* create_brep_for_representation_and_product(const IteratorSettings&, IfcSchema::IfcRepresentation*, IfcSchema::IfcProduct*);
|
||||||
|
|
||||||
|
template <typename P>
|
||||||
|
IfcGeom::BRepElement<P>* create_brep_for_processed_representation(const IteratorSettings&, IfcSchema::IfcRepresentation*, IfcSchema::IfcProduct*, IfcGeom::BRepElement<P>*);
|
||||||
|
|
||||||
const SurfaceStyle* get_style(const IfcSchema::IfcRepresentationItem* representation_item);
|
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) {
|
template <typename T> std::pair<IfcSchema::IfcSurfaceStyle*, T*> get_surface_style(const IfcSchema::IfcRepresentationItem* representation_item) {
|
||||||
|
|||||||
@@ -107,16 +107,14 @@ namespace IfcGeom {
|
|||||||
template <typename P>
|
template <typename P>
|
||||||
class BRepElement : public Element<P> {
|
class BRepElement : public Element<P> {
|
||||||
private:
|
private:
|
||||||
Representation::BRep* _geometry;
|
boost::shared_ptr<Representation::BRep> _geometry;
|
||||||
public:
|
public:
|
||||||
|
const boost::shared_ptr<Representation::BRep>& geometry_pointer() const { return _geometry; }
|
||||||
const Representation::BRep& geometry() const { return *_geometry; }
|
const Representation::BRep& geometry() const { return *_geometry; }
|
||||||
BRepElement(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid, const std::string& context, const gp_Trsf& trsf, Representation::BRep* geometry)
|
BRepElement(int id, int parent_id, const std::string& name, const std::string& type, const std::string& guid, const std::string& context, const gp_Trsf& trsf, const boost::shared_ptr<Representation::BRep>& geometry)
|
||||||
: Element<P>(geometry->settings(),id,parent_id,name,type,guid,context,trsf)
|
: Element<P>(geometry->settings(),id,parent_id,name,type,guid,context,trsf)
|
||||||
, _geometry(geometry)
|
, _geometry(geometry)
|
||||||
{}
|
{}
|
||||||
virtual ~BRepElement() {
|
|
||||||
delete _geometry;
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
BRepElement(const BRepElement& other);
|
BRepElement(const BRepElement& other);
|
||||||
BRepElement& operator=(const BRepElement& other);
|
BRepElement& operator=(const BRepElement& other);
|
||||||
@@ -125,16 +123,18 @@ namespace IfcGeom {
|
|||||||
template <typename P>
|
template <typename P>
|
||||||
class TriangulationElement : public Element<P> {
|
class TriangulationElement : public Element<P> {
|
||||||
private:
|
private:
|
||||||
Representation::Triangulation<P>* _geometry;
|
boost::shared_ptr< Representation::Triangulation<P> > _geometry;
|
||||||
public:
|
public:
|
||||||
const Representation::Triangulation<P>& geometry() const { return *_geometry; }
|
const Representation::Triangulation<P>& geometry() const { return *_geometry; }
|
||||||
|
const boost::shared_ptr< Representation::Triangulation<P> >& geometry_pointer() const { return _geometry; }
|
||||||
TriangulationElement(const BRepElement<P>& shape_model)
|
TriangulationElement(const BRepElement<P>& shape_model)
|
||||||
: Element<P>(shape_model)
|
: Element<P>(shape_model)
|
||||||
, _geometry(new Representation::Triangulation<P>(shape_model.geometry()))
|
, _geometry(boost::shared_ptr<Representation::Triangulation<P>>(new Representation::Triangulation<P>(shape_model.geometry())))
|
||||||
|
{}
|
||||||
|
TriangulationElement(const Element<P>& element, const boost::shared_ptr<Representation::Triangulation<P>>& geometry)
|
||||||
|
: Element<P>(element)
|
||||||
|
, _geometry(geometry)
|
||||||
{}
|
{}
|
||||||
virtual ~TriangulationElement() {
|
|
||||||
delete _geometry;
|
|
||||||
}
|
|
||||||
private:
|
private:
|
||||||
TriangulationElement(const TriangulationElement& other);
|
TriangulationElement(const TriangulationElement& other);
|
||||||
TriangulationElement& operator=(const TriangulationElement& other);
|
TriangulationElement& operator=(const TriangulationElement& other);
|
||||||
|
|||||||
@@ -128,11 +128,13 @@ bool IfcGeom::Kernel::create_solid_from_compound(const TopoDS_Shape& compound, T
|
|||||||
}
|
}
|
||||||
builder.Perform();
|
builder.Perform();
|
||||||
shape = builder.SewedShape();
|
shape = builder.SewedShape();
|
||||||
try {
|
if (shape.ShapeType() == TopAbs_SHELL) {
|
||||||
ShapeFix_Solid sf_solid;
|
try {
|
||||||
sf_solid.LimitTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE));
|
ShapeFix_Solid sf_solid;
|
||||||
shape = sf_solid.SolidFromShell(TopoDS::Shell(shape));
|
sf_solid.LimitTolerance(getValue(GV_POINT_EQUALITY_TOLERANCE));
|
||||||
} catch(...) {}
|
shape = sf_solid.SolidFromShell(TopoDS::Shell(shape));
|
||||||
|
} catch(...) {}
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1050,8 +1052,40 @@ void IfcGeom::Kernel::sequence_of_point_to_wire(const TColgp_SequenceOfPnt& p, T
|
|||||||
w = builder.Wire();
|
w = builder.Wire();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IfcSchema::IfcRelVoidsElement::list::ptr IfcGeom::Kernel::find_openings(IfcSchema::IfcProduct* product) {
|
||||||
|
|
||||||
|
IfcSchema::IfcRelVoidsElement::list::ptr openings(new IfcSchema::IfcRelVoidsElement::list);
|
||||||
|
if ( product->is(IfcSchema::Type::IfcElement) && !product->is(IfcSchema::Type::IfcOpeningElement) ) {
|
||||||
|
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)product;
|
||||||
|
openings = element->HasOpenings();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Is the IfcElement a decomposition of an IfcElement with any IfcOpeningElements?
|
||||||
|
IfcSchema::IfcObjectDefinition* obdef = product->as<IfcSchema::IfcObjectDefinition>();
|
||||||
|
for (;;) {
|
||||||
|
#ifdef USE_IFC4
|
||||||
|
IfcSchema::IfcRelAggregates::list::ptr decomposes = obdef->Decomposes();
|
||||||
|
for ( IfcSchema::IfcRelAggregates::list::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
|
||||||
|
#else
|
||||||
|
IfcSchema::IfcRelDecomposes::list::ptr decomposes = obdef->Decomposes();
|
||||||
|
if (decomposes->size() != 1) break;
|
||||||
|
|
||||||
|
#endif
|
||||||
|
IfcSchema::IfcObjectDefinition* rel_obdef = (*decomposes->begin())->RelatingObject();
|
||||||
|
if ( rel_obdef->is(IfcSchema::Type::IfcElement) && !rel_obdef->is(IfcSchema::Type::IfcOpeningElement) ) {
|
||||||
|
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)rel_obdef;
|
||||||
|
openings->push(element->HasOpenings());
|
||||||
|
}
|
||||||
|
|
||||||
|
obdef = rel_obdef;
|
||||||
|
}
|
||||||
|
|
||||||
|
return openings;
|
||||||
|
}
|
||||||
|
|
||||||
template <typename P>
|
template <typename P>
|
||||||
IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_representation_and_product(const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product) {
|
IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_representation_and_product(const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product) {
|
||||||
|
|
||||||
IfcGeom::Representation::BRep* shape;
|
IfcGeom::Representation::BRep* shape;
|
||||||
IfcGeom::IfcRepresentationShapeItems shapes;
|
IfcGeom::IfcRepresentationShapeItems shapes;
|
||||||
|
|
||||||
@@ -1077,28 +1111,7 @@ IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_representation_and_pro
|
|||||||
|
|
||||||
// Does the IfcElement have any IfcOpenings?
|
// Does the IfcElement have any IfcOpenings?
|
||||||
// Note that openings for IfcOpeningElements are not processed
|
// Note that openings for IfcOpeningElements are not processed
|
||||||
IfcSchema::IfcRelVoidsElement::list::ptr openings;
|
IfcSchema::IfcRelVoidsElement::list::ptr openings = find_openings(product);
|
||||||
if ( product->is(IfcSchema::Type::IfcElement) && !product->is(IfcSchema::Type::IfcOpeningElement) ) {
|
|
||||||
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)product;
|
|
||||||
openings = element->HasOpenings();
|
|
||||||
}
|
|
||||||
// Is the IfcElement a decomposition of an IfcElement with any IfcOpeningElements?
|
|
||||||
if ( product->is(IfcSchema::Type::IfcBuildingElementPart ) ) {
|
|
||||||
IfcSchema::IfcBuildingElementPart* part = (IfcSchema::IfcBuildingElementPart*)product;
|
|
||||||
#ifdef USE_IFC4
|
|
||||||
IfcSchema::IfcRelAggregates::list::ptr decomposes = part->Decomposes();
|
|
||||||
for ( IfcSchema::IfcRelAggregates::list::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
|
|
||||||
#else
|
|
||||||
IfcSchema::IfcRelDecomposes::list::ptr decomposes = part->Decomposes();
|
|
||||||
for ( IfcSchema::IfcRelDecomposes::list::it it = decomposes->begin(); it != decomposes->end(); ++ it ) {
|
|
||||||
#endif
|
|
||||||
IfcSchema::IfcObjectDefinition* obdef = (*it)->RelatingObject();
|
|
||||||
if ( obdef->is(IfcSchema::Type::IfcElement) ) {
|
|
||||||
IfcSchema::IfcElement* element = (IfcSchema::IfcElement*)obdef;
|
|
||||||
openings->push(element->HasOpenings());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
const std::string product_type = IfcSchema::Type::ToString(product->type());
|
const std::string product_type = IfcSchema::Type::ToString(product->type());
|
||||||
ElementSettings element_settings(settings, getValue(GV_LENGTH_UNIT), product_type);
|
ElementSettings element_settings(settings, getValue(GV_LENGTH_UNIT), product_type);
|
||||||
@@ -1155,7 +1168,47 @@ IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_representation_and_pro
|
|||||||
guid,
|
guid,
|
||||||
context_string,
|
context_string,
|
||||||
trsf,
|
trsf,
|
||||||
shape
|
boost::shared_ptr<IfcGeom::Representation::BRep>(shape)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename P>
|
||||||
|
IfcGeom::BRepElement<P>* IfcGeom::Kernel::create_brep_for_processed_representation(const IteratorSettings& /*settings*/, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product, IfcGeom::BRepElement<P>* brep) {
|
||||||
|
|
||||||
|
int parent_id = -1;
|
||||||
|
try {
|
||||||
|
IfcSchema::IfcObjectDefinition* parent_object = get_decomposing_entity(product);
|
||||||
|
if (parent_object) {
|
||||||
|
parent_id = parent_object->entity->id();
|
||||||
|
}
|
||||||
|
} catch (...) {}
|
||||||
|
|
||||||
|
const std::string name = product->hasName() ? product->Name() : "";
|
||||||
|
const std::string guid = product->GlobalId();
|
||||||
|
|
||||||
|
gp_Trsf trsf;
|
||||||
|
try {
|
||||||
|
convert(product->ObjectPlacement(),trsf);
|
||||||
|
} catch (...) {}
|
||||||
|
|
||||||
|
std::string context_string = "";
|
||||||
|
if (representation->hasRepresentationIdentifier()) {
|
||||||
|
context_string = representation->RepresentationIdentifier();
|
||||||
|
} else if (representation->ContextOfItems()->hasContextType()) {
|
||||||
|
context_string = representation->ContextOfItems()->ContextType();
|
||||||
|
}
|
||||||
|
|
||||||
|
const std::string product_type = IfcSchema::Type::ToString(product->type());
|
||||||
|
|
||||||
|
return new BRepElement<P>(
|
||||||
|
product->entity->id(),
|
||||||
|
parent_id,
|
||||||
|
name,
|
||||||
|
product_type,
|
||||||
|
guid,
|
||||||
|
context_string,
|
||||||
|
trsf,
|
||||||
|
brep->geometry_pointer()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1217,6 +1270,9 @@ IfcSchema::IfcObjectDefinition* IfcGeom::Kernel::get_decomposing_entity(IfcSchem
|
|||||||
template IfcGeom::BRepElement<float>* IfcGeom::Kernel::create_brep_for_representation_and_product<float>(const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product);
|
template IfcGeom::BRepElement<float>* IfcGeom::Kernel::create_brep_for_representation_and_product<float>(const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product);
|
||||||
template IfcGeom::BRepElement<double>* IfcGeom::Kernel::create_brep_for_representation_and_product<double>(const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product);
|
template IfcGeom::BRepElement<double>* IfcGeom::Kernel::create_brep_for_representation_and_product<double>(const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product);
|
||||||
|
|
||||||
|
template IfcGeom::BRepElement<float>* IfcGeom::Kernel::create_brep_for_processed_representation<float>(const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product, IfcGeom::BRepElement<float>* brep);
|
||||||
|
template IfcGeom::BRepElement<double>* IfcGeom::Kernel::create_brep_for_processed_representation<double>(const IteratorSettings& settings, IfcSchema::IfcRepresentation* representation, IfcSchema::IfcProduct* product, IfcGeom::BRepElement<double>* brep);
|
||||||
|
|
||||||
std::pair<std::string, double> IfcGeom::Kernel::initializeUnits(IfcSchema::IfcUnitAssignment* unit_assignment) {
|
std::pair<std::string, double> IfcGeom::Kernel::initializeUnits(IfcSchema::IfcUnitAssignment* unit_assignment) {
|
||||||
// Set default units, set length to meters, angles to undefined
|
// Set default units, set length to meters, angles to undefined
|
||||||
setValue(IfcGeom::Kernel::GV_LENGTH_UNIT, 1.0);
|
setValue(IfcGeom::Kernel::GV_LENGTH_UNIT, 1.0);
|
||||||
@@ -1301,3 +1357,42 @@ const IfcSchema::IfcRepresentationItem* IfcGeom::Kernel::find_item_carrying_styl
|
|||||||
|
|
||||||
return item;
|
return item;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool IfcGeom::Kernel::is_identity_transform(IfcUtil::IfcBaseClass* l) {
|
||||||
|
IfcSchema::IfcAxis2Placement2D* ax2d;
|
||||||
|
IfcSchema::IfcAxis2Placement3D* ax3d;
|
||||||
|
|
||||||
|
IfcSchema::IfcCartesianTransformationOperator2D* op2d;
|
||||||
|
IfcSchema::IfcCartesianTransformationOperator3D* op3d;
|
||||||
|
IfcSchema::IfcCartesianTransformationOperator2DnonUniform* op2dnonu;
|
||||||
|
IfcSchema::IfcCartesianTransformationOperator3DnonUniform* op3dnonu;
|
||||||
|
|
||||||
|
if((op2dnonu = l->as<IfcSchema::IfcCartesianTransformationOperator2DnonUniform>()) != 0) {
|
||||||
|
gp_GTrsf2d gtrsf2d;
|
||||||
|
convert(op2dnonu, gtrsf2d);
|
||||||
|
return gtrsf2d.Form() == gp_Identity;
|
||||||
|
} else if ((op2d = l->as<IfcSchema::IfcCartesianTransformationOperator2D>()) != 0) {
|
||||||
|
gp_Trsf2d trsf2d;
|
||||||
|
convert(op2d, trsf2d);
|
||||||
|
return trsf2d.Form() == gp_Identity;
|
||||||
|
} else if((op3dnonu = l->as<IfcSchema::IfcCartesianTransformationOperator3DnonUniform>()) != 0) {
|
||||||
|
gp_GTrsf gtrsf;
|
||||||
|
convert(op3dnonu, gtrsf);
|
||||||
|
return gtrsf.Form() == gp_Identity;
|
||||||
|
} else if ((op3d = l->as<IfcSchema::IfcCartesianTransformationOperator3D>()) != 0) {
|
||||||
|
gp_Trsf trsf;
|
||||||
|
convert(op3d, trsf);
|
||||||
|
return trsf.Form() == gp_Identity;
|
||||||
|
} else if((ax2d = l->as<IfcSchema::IfcAxis2Placement2D>()) != 0) {
|
||||||
|
gp_Trsf2d trsf2d;
|
||||||
|
convert(ax2d, trsf2d);
|
||||||
|
return trsf2d.Form() == gp_Identity;
|
||||||
|
} else if ((ax3d = l->as<IfcSchema::IfcAxis2Placement3D>()) != 0) {
|
||||||
|
gp_Trsf trsf;
|
||||||
|
convert(ax3d, trsf);
|
||||||
|
return trsf.Form() == gp_Identity;
|
||||||
|
} else {
|
||||||
|
throw IfcParse::IfcException("Invalid valuation for IfcAxis2Placement / IfcCartesianTransformationOperator");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -77,6 +77,53 @@
|
|||||||
|
|
||||||
#include "../ifcgeom/IfcGeom.h"
|
#include "../ifcgeom/IfcGeom.h"
|
||||||
|
|
||||||
|
// Helper functions (re)set gp_(G)Trsf(2d) forms explicitly to 'Identity'
|
||||||
|
// so that it can be easily identified in the IfcMappedItem processing
|
||||||
|
|
||||||
|
// For axis placements detect equality early in order for the
|
||||||
|
// relatively computionaly expensive gp_Trsf calculation to be skipped
|
||||||
|
template <typename T>
|
||||||
|
bool axis_equal(const T& a, const T& b, double tolerance);
|
||||||
|
template <>
|
||||||
|
bool axis_equal(const gp_Ax3& a, const gp_Ax3& b, double tolerance) {
|
||||||
|
if (!a.Location().IsEqual(b.Location(), tolerance)) return false;
|
||||||
|
// Note that the tolerance below is angular, above is linear. Since architectural
|
||||||
|
// objects are about 1m'ish in scale, it should be somewhat equivalent. Besides,
|
||||||
|
// this is mostly a filter for NULL or default values in the placements.
|
||||||
|
if (!a.Direction().IsEqual(b.Direction(), tolerance)) return false;
|
||||||
|
if (!a.XDirection().IsEqual(b.XDirection(), tolerance)) return false;
|
||||||
|
if (!a.YDirection().IsEqual(b.YDirection(), tolerance)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool axis_equal(const gp_Ax2d& a, const gp_Ax2d& b, double tolerance) {
|
||||||
|
if (!a.Location().IsEqual(b.Location(), tolerance)) return false;
|
||||||
|
if (!a.Direction().IsEqual(b.Direction(), tolerance)) return false;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <typename T> struct dimension_count {};
|
||||||
|
template <> struct dimension_count <gp_Trsf2d > { static const int n = 2; };
|
||||||
|
template <> struct dimension_count <gp_GTrsf2d> { static const int n = 2; };
|
||||||
|
template <> struct dimension_count < gp_Trsf > { static const int n = 3; };
|
||||||
|
template <> struct dimension_count < gp_GTrsf > { static const int n = 3; };
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
bool is_identity(const T& t, double tolerance) {
|
||||||
|
// Note the {1, n+1} range due to Open Cascade's 1-based indexing
|
||||||
|
// Note the {1, n+2} range due to the translation part of the matrix
|
||||||
|
for (int i = 1; i < dimension_count<T>::n + 2; ++i) {
|
||||||
|
for (int j = 1; j < dimension_count<T>::n + 1; ++j) {
|
||||||
|
const double iden_value = i == j ? 1. : 0.;
|
||||||
|
const double trsf_value = t.Value(j, i);
|
||||||
|
if (fabs(trsf_value - iden_value) > tolerance) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCartesianPoint* l, gp_Pnt& point) {
|
bool IfcGeom::Kernel::convert(const IfcSchema::IfcCartesianPoint* l, gp_Pnt& point) {
|
||||||
IN_CACHE(IfcCartesianPoint,l,gp_Pnt,point)
|
IN_CACHE(IfcCartesianPoint,l,gp_Pnt,point)
|
||||||
std::vector<double> xyz = l->Coordinates();
|
std::vector<double> xyz = l->Coordinates();
|
||||||
@@ -120,7 +167,11 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcAxis2Placement3D* l, gp_Trsf&
|
|||||||
gp_Ax3 ax3;
|
gp_Ax3 ax3;
|
||||||
if ( hasRef ) ax3 = gp_Ax3(o,axis,refDirection);
|
if ( hasRef ) ax3 = gp_Ax3(o,axis,refDirection);
|
||||||
else ax3 = gp_Ax3(o,axis);
|
else ax3 = gp_Ax3(o,axis);
|
||||||
trsf.SetTransformation(ax3, gp_Ax3(gp_Pnt(),gp_Dir(0,0,1),gp_Dir(1,0,0)));
|
|
||||||
|
if (!axis_equal(ax3, (gp_Ax3) gp::XOY(), getValue(GV_PRECISION))) {
|
||||||
|
trsf.SetTransformation(ax3, gp::XOY());
|
||||||
|
}
|
||||||
|
|
||||||
CACHE(IfcAxis2Placement3D,l,trsf)
|
CACHE(IfcAxis2Placement3D,l,trsf)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -147,9 +198,16 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCartesianTransformationOperato
|
|||||||
if ( l->hasAxis3() ) IfcGeom::Kernel::convert(l->Axis3(),axis3);
|
if ( l->hasAxis3() ) IfcGeom::Kernel::convert(l->Axis3(),axis3);
|
||||||
gp_Ax3 ax3 (origin,axis3,axis1);
|
gp_Ax3 ax3 (origin,axis3,axis1);
|
||||||
if ( axis2.Dot(ax3.YDirection()) < 0 ) ax3.YReverse();
|
if ( axis2.Dot(ax3.YDirection()) < 0 ) ax3.YReverse();
|
||||||
trsf.SetTransformation(ax3);
|
|
||||||
trsf.Invert();
|
if (!axis_equal(ax3, (gp_Ax3) gp::XOY(), getValue(GV_PRECISION))) {
|
||||||
if ( l->hasScale() ) trsf.SetScaleFactor(l->Scale());
|
trsf.SetTransformation(ax3);
|
||||||
|
trsf.Invert();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (l->hasScale() && !ALMOST_THE_SAME(l->Scale(), 1.)) {
|
||||||
|
trsf.SetScaleFactor(l->Scale());
|
||||||
|
}
|
||||||
|
|
||||||
CACHE(IfcCartesianTransformationOperator3D,l,trsf)
|
CACHE(IfcCartesianTransformationOperator3D,l,trsf)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -183,7 +241,12 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCartesianTransformationOperato
|
|||||||
}
|
}
|
||||||
|
|
||||||
trsf.Invert();
|
trsf.Invert();
|
||||||
if ( l->hasScale() ) trsf.SetScaleFactor(l->Scale());
|
if ( l->hasScale() && !ALMOST_THE_SAME(l->Scale(), 1.) ) trsf.SetScaleFactor(l->Scale());
|
||||||
|
|
||||||
|
if (is_identity(trsf, getValue(GV_PRECISION))) {
|
||||||
|
trsf = gp_Trsf2d();
|
||||||
|
}
|
||||||
|
|
||||||
CACHE(IfcCartesianTransformationOperator2D,l,trsf)
|
CACHE(IfcCartesianTransformationOperator2D,l,trsf)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -211,6 +274,11 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCartesianTransformationOperato
|
|||||||
gtrsf.SetValue(2,2,scale2);
|
gtrsf.SetValue(2,2,scale2);
|
||||||
gtrsf.SetValue(3,3,scale3);
|
gtrsf.SetValue(3,3,scale3);
|
||||||
gtrsf.PreMultiply(trsf);
|
gtrsf.PreMultiply(trsf);
|
||||||
|
|
||||||
|
if (is_identity(gtrsf, getValue(GV_PRECISION))) {
|
||||||
|
gtrsf = gp_GTrsf();
|
||||||
|
}
|
||||||
|
|
||||||
CACHE(IfcCartesianTransformationOperator3DnonUniform,l,gtrsf)
|
CACHE(IfcCartesianTransformationOperator3DnonUniform,l,gtrsf)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -247,6 +315,11 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcCartesianTransformationOperato
|
|||||||
gtrsf.SetValue(1,1,scale1);
|
gtrsf.SetValue(1,1,scale1);
|
||||||
gtrsf.SetValue(2,2,scale2);
|
gtrsf.SetValue(2,2,scale2);
|
||||||
gtrsf.Multiply(trsf);
|
gtrsf.Multiply(trsf);
|
||||||
|
|
||||||
|
if (is_identity(gtrsf, getValue(GV_PRECISION))) {
|
||||||
|
gtrsf = gp_GTrsf2d();
|
||||||
|
}
|
||||||
|
|
||||||
CACHE(IfcCartesianTransformationOperator2DnonUniform,l,gtrsf)
|
CACHE(IfcCartesianTransformationOperator2DnonUniform,l,gtrsf)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -274,8 +347,12 @@ bool IfcGeom::Kernel::convert(const IfcSchema::IfcAxis2Placement2D* l, gp_Trsf2d
|
|||||||
if ( l->hasRefDirection() )
|
if ( l->hasRefDirection() )
|
||||||
IfcGeom::Kernel::convert(l->RefDirection(),V);
|
IfcGeom::Kernel::convert(l->RefDirection(),V);
|
||||||
|
|
||||||
gp_Ax2d axis(gp_Pnt2d(P.X(),P.Y()),gp_Dir2d(V.X(),V.Y()));
|
gp_Ax2d axis(gp_Pnt2d(P.X(),P.Y()), gp_Dir2d(V.X(),V.Y()));
|
||||||
trsf.SetTransformation(axis,gp_Ax2d());
|
|
||||||
|
if (!axis_equal(axis, gp_Ax2d(), getValue(GV_PRECISION))) {
|
||||||
|
trsf.SetTransformation(axis, gp_Ax2d());
|
||||||
|
}
|
||||||
|
|
||||||
CACHE(IfcAxis2Placement2D,l,trsf)
|
CACHE(IfcAxis2Placement2D,l,trsf)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|||||||
+174
-48
@@ -291,6 +291,8 @@ namespace IfcGeom {
|
|||||||
++ done;
|
++ done;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::set<IfcSchema::IfcRepresentation*> mapped_representations_processed;
|
||||||
|
|
||||||
BRepElement<P>* create_shape_model_for_next_entity() {
|
BRepElement<P>* create_shape_model_for_next_entity() {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
IfcSchema::IfcRepresentation* representation;
|
IfcSchema::IfcRepresentation* representation;
|
||||||
@@ -305,47 +307,147 @@ namespace IfcGeom {
|
|||||||
// Has the list of IfcProducts for this representation been initialized?
|
// Has the list of IfcProducts for this representation been initialized?
|
||||||
if (!ifcproducts) {
|
if (!ifcproducts) {
|
||||||
|
|
||||||
IfcSchema::IfcProductRepresentation::list::ptr prodreps = representation->OfProductRepresentation();
|
|
||||||
ifcproducts = IfcSchema::IfcProduct::list::ptr(new IfcSchema::IfcProduct::list);
|
ifcproducts = IfcSchema::IfcProduct::list::ptr(new IfcSchema::IfcProduct::list);
|
||||||
IfcSchema::IfcProduct::list::ptr unfiltered_products(new IfcSchema::IfcProduct::list);
|
IfcSchema::IfcProduct::list::ptr unfiltered_products(new IfcSchema::IfcProduct::list);
|
||||||
|
|
||||||
for ( IfcSchema::IfcProductRepresentation::list::it it = prodreps->begin(); it != prodreps->end(); ++it ) {
|
{
|
||||||
if ( (*it)->is(IfcSchema::Type::IfcProductDefinitionShape) ) {
|
IfcSchema::IfcProductRepresentation::list::ptr prodreps = representation->OfProductRepresentation();
|
||||||
IfcSchema::IfcProductDefinitionShape* pds = (IfcSchema::IfcProductDefinitionShape*)*it;
|
|
||||||
unfiltered_products->push(pds->ShapeOfProduct());
|
|
||||||
} else {
|
|
||||||
// http://buildingsmart-tech.org/ifc/IFC2x3/TC1/html/ifcrepresentationresource/lexical/ifcproductrepresentation.htm
|
|
||||||
// IFC2x Edition 3 NOTE Users should not instantiate the entity IfcProductRepresentation from IFC2x Edition 3 onwards.
|
|
||||||
// It will be changed into an ABSTRACT supertype in future releases of IFC.
|
|
||||||
|
|
||||||
// IfcProductRepresentation also lacks the INVERSE relation to IfcProduct
|
for (IfcSchema::IfcProductRepresentation::list::it it = prodreps->begin(); it != prodreps->end(); ++it) {
|
||||||
// Let's find the IfcProducts that reference the IfcProductRepresentation anyway
|
if ((*it)->is(IfcSchema::Type::IfcProductDefinitionShape)) {
|
||||||
unfiltered_products->push((*it)->entity->getInverse(IfcSchema::Type::IfcProduct, -1)->as<IfcSchema::IfcProduct>());
|
IfcSchema::IfcProductDefinitionShape* pds = (IfcSchema::IfcProductDefinitionShape*)*it;
|
||||||
|
unfiltered_products->push(pds->ShapeOfProduct());
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// http://buildingsmart-tech.org/ifc/IFC2x3/TC1/html/ifcrepresentationresource/lexical/ifcproductrepresentation.htm
|
||||||
|
// IFC2x Edition 3 NOTE Users should not instantiate the entity IfcProductRepresentation from IFC2x Edition 3 onwards.
|
||||||
|
// It will be changed into an ABSTRACT supertype in future releases of IFC.
|
||||||
|
|
||||||
|
// IfcProductRepresentation also lacks the INVERSE relation to IfcProduct
|
||||||
|
// Let's find the IfcProducts that reference the IfcProductRepresentation anyway
|
||||||
|
unfiltered_products->push((*it)->entity->getInverse(IfcSchema::Type::IfcProduct, -1)->as<IfcSchema::IfcProduct>());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Filter the products based on the set of entities being included or excluded for
|
const int repid = representation->entity->id();
|
||||||
// processing. The set is iterated over te able to filter on subtypes.
|
|
||||||
for ( IfcSchema::IfcProduct::list::it jt = unfiltered_products->begin(); jt != unfiltered_products->end(); ++jt ) {
|
bool has_openings = false;
|
||||||
bool found = false;
|
for (IfcSchema::IfcProduct::list::it it = unfiltered_products->begin(); it != unfiltered_products->end(); ++it) {
|
||||||
for (std::set<IfcSchema::Type::Enum>::const_iterator kt = entities_to_include_or_exclude.begin(); kt != entities_to_include_or_exclude.end(); ++kt) {
|
if (kernel.find_openings(*it)->size()) {
|
||||||
if ((*jt)->is(*kt)) {
|
has_openings = true;
|
||||||
found = true;
|
break;
|
||||||
break;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const bool process_maps_for_current_representation = (!has_openings || settings.disable_opening_subtractions());
|
||||||
|
bool representation_processed_as_mapped_item = false;
|
||||||
|
|
||||||
|
IfcSchema::IfcRepresentation* representation_mapped_to = 0;
|
||||||
|
|
||||||
|
if (process_maps_for_current_representation) {
|
||||||
|
IfcSchema::IfcRepresentationItem::list::ptr items = representation->Items();
|
||||||
|
if (items->size() == 1) {
|
||||||
|
IfcSchema::IfcRepresentationItem* item = *items->begin();
|
||||||
|
if (item->is(IfcSchema::Type::IfcMappedItem)) {
|
||||||
|
if (item->StyledByItem()->size() == 0) {
|
||||||
|
IfcSchema::IfcMappedItem* mapped_item = item->as<IfcSchema::IfcMappedItem>();
|
||||||
|
if (kernel.is_identity_transform(mapped_item->MappingTarget())) {
|
||||||
|
IfcSchema::IfcRepresentationMap* map = mapped_item->MappingSource();
|
||||||
|
if (kernel.is_identity_transform(map->MappingOrigin())) {
|
||||||
|
representation_mapped_to = map->MappedRepresentation();
|
||||||
|
IfcSchema::IfcProductRepresentation::list::ptr prodreps = representation_mapped_to->OfProductRepresentation();
|
||||||
|
|
||||||
|
bool all_product_without_openings = true;
|
||||||
|
IfcSchema::IfcProduct::list::ptr products;
|
||||||
|
|
||||||
|
for (IfcSchema::IfcProductRepresentation::list::it it = prodreps->begin(); it != prodreps->end(); ++it) {
|
||||||
|
IfcSchema::IfcProduct::list::ptr products_of_prodrep = (*it)->entity->getInverse(IfcSchema::Type::IfcProduct, -1)->as<IfcSchema::IfcProduct>();
|
||||||
|
products->push(products_of_prodrep);
|
||||||
|
for (IfcSchema::IfcProduct::list::it jt = products_of_prodrep->begin(); jt != products_of_prodrep->end(); ++jt) {
|
||||||
|
if (kernel.find_openings(*jt)->size() > 0 && !settings.disable_opening_subtractions()) {
|
||||||
|
all_product_without_openings = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (all_product_without_openings) {
|
||||||
|
representation_processed_as_mapped_item = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (found == include_entities_in_processing) {
|
}
|
||||||
ifcproducts->push(*jt);
|
}
|
||||||
}
|
|
||||||
|
if (representation_mapped_to) {
|
||||||
|
if (mapped_representations_processed.find(representation_mapped_to) != mapped_representations_processed.end()) {
|
||||||
|
_nextShape();
|
||||||
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mapped_representations_processed.insert(representation_mapped_to);
|
||||||
}
|
}
|
||||||
// Does this representation have any IfcProducts?
|
|
||||||
if (!ifcproducts->size()) {
|
if (representation_processed_as_mapped_item) {
|
||||||
_nextShape();
|
_nextShape();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
IfcSchema::IfcRepresentationMap::list::ptr maps = representation->RepresentationMap();
|
||||||
|
|
||||||
|
if (process_maps_for_current_representation && maps->size() == 1) {
|
||||||
|
IfcSchema::IfcRepresentationMap* map = *maps->begin();
|
||||||
|
if (kernel.is_identity_transform(map->MappingOrigin())) {
|
||||||
|
IfcSchema::IfcMappedItem::list::ptr items = map->MapUsage();
|
||||||
|
for (IfcSchema::IfcMappedItem::list::it it = items->begin(); it != items->end(); ++it) {
|
||||||
|
IfcSchema::IfcMappedItem* item = *it;
|
||||||
|
if (item->StyledByItem()->size() != 0) continue;
|
||||||
|
|
||||||
|
if (!kernel.is_identity_transform(item->MappingTarget())) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
IfcSchema::IfcRepresentation::list::ptr reps = item->entity->getInverse(IfcSchema::Type::IfcRepresentation, -1)->as<IfcSchema::IfcRepresentation>();
|
||||||
|
for (IfcSchema::IfcRepresentation::list::it jt = reps->begin(); jt != reps->end(); ++jt) {
|
||||||
|
IfcSchema::IfcRepresentation* rep = *jt;
|
||||||
|
if (rep->Items()->size() != 1) continue;
|
||||||
|
IfcSchema::IfcProductRepresentation::list::ptr prodreps = rep->OfProductRepresentation();
|
||||||
|
for (IfcSchema::IfcProductRepresentation::list::it kt = prodreps->begin(); kt != prodreps->end(); ++kt) {
|
||||||
|
IfcSchema::IfcProduct::list::ptr prods = (*kt)->entity->getInverse(IfcSchema::Type::IfcProduct, -1)->as<IfcSchema::IfcProduct>();
|
||||||
|
for (IfcSchema::IfcProduct::list::it lt = prods->begin(); lt != prods->end(); ++lt) {
|
||||||
|
if (kernel.find_openings(*lt)->size() == 0 || settings.disable_opening_subtractions()) {
|
||||||
|
if (!unfiltered_products->contains(*lt)) {
|
||||||
|
unfiltered_products->push(*lt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Filter the products based on the set of entities being included or excluded for
|
||||||
|
// processing. The set is iterated over to able to filter on subtypes.
|
||||||
|
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 kt = entities_to_include_or_exclude.begin(); kt != entities_to_include_or_exclude.end(); ++kt) {
|
||||||
|
if ((*jt)->is(*kt)) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found == include_entities_in_processing) {
|
||||||
|
ifcproducts->push(*jt);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ifcproduct_iterator = ifcproducts->begin();
|
ifcproduct_iterator = ifcproducts->begin();
|
||||||
}
|
}
|
||||||
|
|
||||||
// Have we reached the end of our list of IfcProducts?
|
// Have we reached the end of our list of IfcProducts?
|
||||||
if ( ifcproduct_iterator == ifcproducts->end() ) {
|
if ( ifcproduct_iterator == ifcproducts->end() ) {
|
||||||
_nextShape();
|
_nextShape();
|
||||||
@@ -354,7 +456,12 @@ namespace IfcGeom {
|
|||||||
|
|
||||||
IfcSchema::IfcProduct* product = *ifcproduct_iterator;
|
IfcSchema::IfcProduct* product = *ifcproduct_iterator;
|
||||||
|
|
||||||
BRepElement<P>* element = kernel.create_brep_for_representation_and_product<P>(settings, representation, product);
|
BRepElement<P>* element;
|
||||||
|
if (ifcproduct_iterator == ifcproducts->begin()) {
|
||||||
|
element = kernel.create_brep_for_representation_and_product<P>(settings, representation, product);
|
||||||
|
} else {
|
||||||
|
element = kernel.create_brep_for_processed_representation(settings, representation, product, current_shape_model);
|
||||||
|
}
|
||||||
|
|
||||||
if ( !element ) {
|
if ( !element ) {
|
||||||
_nextShape();
|
_nextShape();
|
||||||
@@ -365,9 +472,7 @@ namespace IfcGeom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
void free_shapes() {
|
||||||
|
|
||||||
bool next() {
|
|
||||||
// Free all possible representations of the current geometrical entity
|
// Free all possible representations of the current geometrical entity
|
||||||
delete current_triangulation;
|
delete current_triangulation;
|
||||||
current_triangulation = 0;
|
current_triangulation = 0;
|
||||||
@@ -375,7 +480,11 @@ namespace IfcGeom {
|
|||||||
current_serialization = 0;
|
current_serialization = 0;
|
||||||
delete current_shape_model;
|
delete current_shape_model;
|
||||||
current_shape_model = 0;
|
current_shape_model = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public:
|
||||||
|
|
||||||
|
bool next() {
|
||||||
// Increment the iterator over the list of products using the current
|
// Increment the iterator over the list of products using the current
|
||||||
// shape representation
|
// shape representation
|
||||||
if (ifcproducts) {
|
if (ifcproducts) {
|
||||||
@@ -429,23 +538,45 @@ namespace IfcGeom {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool create() {
|
bool create() {
|
||||||
|
bool success = true;
|
||||||
|
|
||||||
|
IfcGeom::BRepElement<P>* next_shape_model = 0;
|
||||||
|
IfcGeom::SerializedElement<P>* next_serialization = 0;
|
||||||
|
IfcGeom::TriangulationElement<P>* next_triangulation = 0;
|
||||||
|
|
||||||
try {
|
try {
|
||||||
current_shape_model = create_shape_model_for_next_entity();
|
next_shape_model = create_shape_model_for_next_entity();
|
||||||
} catch (...) {}
|
} catch (...) {}
|
||||||
if (!current_shape_model) return false;
|
|
||||||
if (settings.use_brep_data()) {
|
if (next_shape_model) {
|
||||||
try {
|
if (settings.use_brep_data()) {
|
||||||
current_serialization = new SerializedElement<P>(*current_shape_model);
|
try {
|
||||||
} catch (...) {}
|
next_serialization = new SerializedElement<P>(*next_shape_model);
|
||||||
return !!current_serialization;
|
} catch (...) {
|
||||||
} else if (!settings.disable_triangulation()) {
|
success = false;
|
||||||
try {
|
}
|
||||||
current_triangulation = new TriangulationElement<P>(*current_shape_model);
|
} else if (!settings.disable_triangulation()) {
|
||||||
} catch (...) {}
|
try {
|
||||||
return !!current_triangulation;
|
if (ifcproduct_iterator == ifcproducts->begin() || settings.use_world_coords()) {
|
||||||
|
next_triangulation = new TriangulationElement<P>(*next_shape_model);
|
||||||
|
} else {
|
||||||
|
next_triangulation = new TriangulationElement<P>(*next_shape_model, current_triangulation->geometry_pointer());
|
||||||
|
}
|
||||||
|
} catch (...) {
|
||||||
|
success = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
return true;
|
success = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
free_shapes();
|
||||||
|
|
||||||
|
current_shape_model = next_shape_model;
|
||||||
|
current_serialization = next_serialization;
|
||||||
|
current_triangulation = next_triangulation;
|
||||||
|
|
||||||
|
return success;
|
||||||
}
|
}
|
||||||
private:
|
private:
|
||||||
void _initialize() {
|
void _initialize() {
|
||||||
@@ -503,12 +634,7 @@ namespace IfcGeom {
|
|||||||
delete ifc_file;
|
delete ifc_file;
|
||||||
}
|
}
|
||||||
|
|
||||||
delete current_triangulation;
|
free_shapes();
|
||||||
current_triangulation = 0;
|
|
||||||
delete current_serialization;
|
|
||||||
current_serialization = 0;
|
|
||||||
delete current_shape_model;
|
|
||||||
current_shape_model = 0;
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user