Merge pull request #211 from mitmadness/feature/hierarchy

Represent hierarchy in Collada files
This commit is contained in:
Thomas Krijnen
2017-05-20 19:46:56 +02:00
committed by GitHub
9 changed files with 507 additions and 41 deletions
+35 -2
View File
@@ -81,7 +81,33 @@ namespace IfcGeom {
std::string _unique_id;
Transformation<P> _transformation;
IfcSchema::IfcProduct* product_;
std::vector<const IfcGeom::Element<P>*> _parents;
public:
friend bool operator == (const Element<P> & element1, const Element<P> & element2)
{
return element1.id() == element2.id();
}
// Use the id to compare, or the elevation is the elements are IfcBuildingStoreys and the elevation is set
friend bool operator < (const Element<P> & element1, const Element<P> & element2)
{
if (element1.type() == "IfcBuildingStorey" && element2.type() == "IfcBuildingStorey")
{
IfcSchema::IfcBuildingStorey* storey1 = NULL;
IfcSchema::IfcBuildingStorey* storey2 = NULL;
storey1 = (IfcSchema::IfcBuildingStorey*)element1.product();
storey2 = (IfcSchema::IfcBuildingStorey*)element2.product();
if (storey1 != NULL && storey2 != NULL && storey1->hasElevation() && storey2->hasElevation())
{
return storey1->Elevation() < storey2->Elevation();
}
}
return element1.id() < element2.id();
}
int id() const { return _id; }
int parent_id() const { return _parent_id; }
const std::string& name() const { return _name; }
@@ -91,14 +117,21 @@ namespace IfcGeom {
const std::string& unique_id() const { return _unique_id; }
const Transformation<P>& transformation() const { return _transformation; }
IfcSchema::IfcProduct* product() const { return product_; }
const std::vector<const IfcGeom::Element<P>*> parents() const { return _parents; }
void SetParents(std::vector<const IfcGeom::Element<P>*> newparents) { _parents = newparents; }
Element(const ElementSettings& settings, 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, IfcSchema::IfcProduct *product)
: _id(id), _parent_id(parent_id), _name(name), _type(type), _guid(guid), _context(context), _transformation(settings, trsf)
, product_(product)
{
{
std::ostringstream oss;
oss << "product-" << IfcParse::IfcGlobalId(guid).formatted();
try { oss << "product-" << IfcParse::IfcGlobalId(guid).formatted(); }
catch (std::exception e)
{
oss << "product-cannotfindId";
}
if (!_context.empty()) {
std::string ctx = _context;
boost::to_lower(ctx);
+47 -6
View File
@@ -573,6 +573,52 @@ namespace IfcGeom {
if (current_triangulation) { ret = current_triangulation; }
else if (current_serialization) { ret = current_serialization; }
else if (current_shape_model) { ret = current_shape_model; }
// If we want to organize the element considering their hierarchy
if (settings.get(IteratorSettings::SEARCH_FLOOR))
{
// We are going to build a vector with the element parents.
// First, create the parent vector
std::vector<const IfcGeom::Element<P>*> parents;
// if the element has a parent
if (ret->parent_id() != -1)
{
const IfcGeom::Element<P>* parent_object = NULL;
bool hasParent = true;
// get the parent
try { parent_object = getObject(ret->parent_id()); }
catch (std::exception e)
{
hasParent = false;
}
// Add the previously found parent to the vector
if (hasParent) parents.insert(parents.begin(), parent_object);
// We need to find all the parents
while (parent_object != NULL && hasParent)
{
// Find the next parent
try { parent_object = getObject(parent_object->parent_id()); }
catch (std::exception e)
{
std::cout << e.what();
hasParent = false;
}
// Add the previously found parent to the vector
if (hasParent) parents.insert(parents.begin(), parent_object);
hasParent = hasParent && parent_object->parent_id() != -1;
}
// when done push the parent list in the Element object
ret->SetParents(parents);
}
}
return ret;
}
@@ -584,18 +630,15 @@ namespace IfcGeom {
}
const Element<P>* getObject(int id) {
gp_Trsf trsf;
int parent_id = -1;
std::string instance_type, product_name, product_guid;
IfcSchema::IfcProduct* ifc_product = 0;
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) ) {
ifc_product = (IfcSchema::IfcProduct*)ifc_entity;
product_guid = ifc_product->GlobalId();
product_name = ifc_product->hasName() ? ifc_product->Name() : "";
@@ -606,16 +649,14 @@ namespace IfcGeom {
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<P>* ifc_object = new Element<P>(element_settings, id, parent_id, product_name, instance_type, product_guid, "", trsf, ifc_product);
return ifc_object;
}
+3 -1
View File
@@ -78,8 +78,10 @@ namespace IfcGeom
GENERATE_UVS = 1 << 12,
/// Specifies whether to slice representations according to associated IfcLayerSets.
APPLY_LAYERSETS = 1 << 13,
/// Search for a parent of type IfcBuildingStorey for each representation
SEARCH_FLOOR = 1 << 14,
/// Number of different setting flags.
NUM_SETTINGS = 13
NUM_SETTINGS = 14
};
/// Used to store logical OR combination of setting flags.
typedef unsigned SettingField;