();
for (IfcSchema::IfcProduct::list::it lt = prods->begin(); lt != prods->end(); ++lt) {
if (kernel.find_openings(*lt)->size() == 0 || settings.get(IteratorSettings::DISABLE_OPENING_SUBTRACTIONS)) {
if (!unfiltered_products->contains(*lt)) {
unfiltered_products->push(*lt);
}
}
}
}
}
}
}
}
// Filter the products based on the set of entities and/or names being included or excluded for processing.
for (IfcSchema::IfcProduct::list::it jt = unfiltered_products->begin(); jt != unfiltered_products->end(); ++jt) {
IfcSchema::IfcProduct* prod = *jt;
if (boost::all(filters_, filter_match(prod))) {
ifcproducts->push(prod);
}
}
ifcproduct_iterator = ifcproducts->begin();
}
// Have we reached the end of our list of IfcProducts?
if ( ifcproduct_iterator == ifcproducts->end() ) {
_nextShape();
continue;
}
IfcSchema::IfcProduct* product = *ifcproduct_iterator;
Logger::SetProduct(product);
BRepElement* element;
if (ifcproduct_iterator == ifcproducts->begin() || !settings.get(IteratorSettings::USE_WORLD_COORDS)) {
element = kernel.create_brep_for_representation_and_product
(settings, representation, product);
} else {
element = kernel.create_brep_for_processed_representation(settings, representation, product, current_shape_model);
}
Logger::SetProduct(boost::none);
if (!element) {
_nextShape();
continue;
}
return element;
}
}
void free_shapes() {
// Free all possible representations of the current geometrical entity
delete current_triangulation;
current_triangulation = 0;
delete current_serialization;
current_serialization = 0;
delete current_shape_model;
current_shape_model = 0;
}
public:
/// Returns what would be the product for the next shape representation
/// @todo Double-check and test the impl.
//IfcSchema::IfcProduct* peek_next() const
//{
// if (ifcproducts && ifcproduct_iterator + 1 != ifcproducts->end()){
// return *(ifcproduct_iterator + 1);
// } else {
// return 0;
// }
//}
/// @todo Would this be as simple as the following code?
//void skip_next() { if (ifcproducts) { ++ifcproduct_iterator; } }
/// Moves to the next shape representation, create its geometry, and returns the associated product.
/// Use get() to retrieve the created geometry.
IfcSchema::IfcProduct* next() {
// Increment the iterator over the list of products using the current
// shape representation
if (ifcproducts) {
++ifcproduct_iterator;
}
return create();
}
/// Gets the representation of the current geometrical entity.
Element
* get()
{
// TODO: Test settings and throw
Element
* ret = 0;
if (current_triangulation) { ret = current_triangulation; }
else if (current_serialization) { ret = current_serialization; }
else if (current_shape_model) { ret = current_shape_model; }
return ret;
}
/// Gets the native (Open Cascade) representation of the current geometrical entity.
BRepElement
* get_native()
{
// TODO: Test settings and throw
return current_shape_model;
}
const Element
* getObject(int id) {
gp_Trsf trsf;
int parent_id = -1;
std::string instance_type, product_name, product_guid;
try {
const IfcUtil::IfcBaseClass* ifc_entity = ifc_file->entityById(id);
instance_type = IfcSchema::Type::ToString(ifc_entity->type());
if ( ifc_entity->is(IfcSchema::Type::IfcProduct) ) {
IfcSchema::IfcProduct* ifc_product = (IfcSchema::IfcProduct*)ifc_entity;
product_guid = ifc_product->GlobalId();
product_name = ifc_product->hasName() ? ifc_product->Name() : "";
parent_id = -1;
try {
IfcSchema::IfcObjectDefinition* parent_object = kernel.get_decomposing_entity(ifc_product);
if (parent_object) {
parent_id = parent_object->entity->id();
}
} catch (...) {}
try {
kernel.convert(ifc_product->ObjectPlacement(), trsf);
} catch (...) {}
}
} catch(...) {}
ElementSettings element_settings(settings, unit_magnitude, instance_type);
Element
* ifc_object = new Element
(element_settings, id, parent_id, product_name, instance_type, product_guid, "", trsf);
return ifc_object;
}
IfcSchema::IfcProduct* create() {
IfcGeom::BRepElement
* next_shape_model = 0;
IfcGeom::SerializedElement
* next_serialization = 0;
IfcGeom::TriangulationElement
* next_triangulation = 0;
try {
next_shape_model = create_shape_model_for_next_entity();
} catch (...) {}
if (next_shape_model) {
if (settings.get(IteratorSettings::USE_BREP_DATA)) {
try {
next_serialization = new SerializedElement
(*next_shape_model);
} catch (...) {
Logger::Message(Logger::LOG_ERROR, "Getting a serialized element from model failed.");
}
} else if (!settings.get(IteratorSettings::DISABLE_TRIANGULATION)) {
try {
if (ifcproduct_iterator == ifcproducts->begin() || settings.get(IteratorSettings::USE_WORLD_COORDS)) {
next_triangulation = new TriangulationElement
(*next_shape_model);
} else {
next_triangulation = new TriangulationElement
(*next_shape_model, current_triangulation->geometry_pointer());
}
} catch (...) {
Logger::Message(Logger::LOG_ERROR, "Getting a triangulation element from model failed.");
}
}
}
free_shapes();
current_shape_model = next_shape_model;
current_serialization = next_serialization;
current_triangulation = next_triangulation;
return next_shape_model ? next_shape_model->product() : 0;
}
private:
void _initialize() {
current_triangulation = 0;
current_shape_model = 0;
current_serialization = 0;
unit_name = "METER";
unit_magnitude = 1.f;
kernel.setValue(IfcGeom::Kernel::GV_MAX_FACES_TO_SEW, settings.get(IteratorSettings::SEW_SHELLS) ? 1000 : -1);
kernel.setValue(IfcGeom::Kernel::GV_DIMENSIONALITY, (settings.get(IteratorSettings::INCLUDE_CURVES)
? (settings.get(IteratorSettings::EXCLUDE_SOLIDS_AND_SURFACES) ? -1. : 0.) : +1.));
}
bool owns_ifc_file;
public:
Iterator(const IteratorSettings& settings, IfcParse::IfcFile* file)
: settings(settings)
, ifc_file(file)
, owns_ifc_file(false)
{
_initialize();
}
Iterator(const IteratorSettings& settings, const std::string& filename)
: settings(settings)
, ifc_file(new IfcParse::IfcFile)
, owns_ifc_file(true)
{
ifc_file->Init(filename);
_initialize();
}
Iterator(const IteratorSettings& settings, void* data, int length)
: settings(settings)
, ifc_file(new IfcParse::IfcFile)
, owns_ifc_file(true)
{
ifc_file->Init(data, length);
_initialize();
}
Iterator(const IteratorSettings& settings, std::istream& filestream, int length)
: settings(settings)
, ifc_file(new IfcParse::IfcFile)
, owns_ifc_file(true)
{
ifc_file->Init(filestream, length);
_initialize();
}
~Iterator() {
if (owns_ifc_file) {
delete ifc_file;
}
free_shapes();
}
};
}
#endif