diff --git a/src/ifcconvert/IfcConvert.cpp b/src/ifcconvert/IfcConvert.cpp index cd08391001..3bdc45bf0f 100644 --- a/src/ifcconvert/IfcConvert.cpp +++ b/src/ifcconvert/IfcConvert.cpp @@ -1446,7 +1446,7 @@ std::vector setup_filters(const std::vector& fil layer_filter.populate(f.values); } else if (f.type == geom_filter::ENTITY_ARG) { attribute_filter.include = f.include; - attribute_filter.traverse = f.traverse; + attribute_filter.traverse = attribute_filter.traverse_openings = f.traverse; attribute_filter.attribute_name = f.arg; attribute_filter.populate(f.values); } diff --git a/src/serializers/USDSerializer.cpp b/src/serializers/USDSerializer.cpp index 50013a95df..82c1131534 100644 --- a/src/serializers/USDSerializer.cpp +++ b/src/serializers/USDSerializer.cpp @@ -117,17 +117,28 @@ void USDSerializer::writeHeader() { stage_->GetRootLayer()->SetComment("File generated by IfcOpenShell " + std::string(IFCOPENSHELL_VERSION)); } -namespace { - std::string nameObject(const IfcGeom::Element* o) { - std::string name = o->name(); - const std::string type = o->type(); - const std::string id = std::to_string(o->id()); - if (name.empty()) { - name = type + "_UnNamed_" + id; - } else { - name = type + "_" + usd_utils::toPath(name) + "_" + id; +std::string USDSerializer::object_id_unique(const IfcGeom::Element* o) { + auto it = element_names_.find(o->id()); + if (it != element_names_.end()) { + return it->second; + } + int postfix = 0; + auto name = object_id(o); + auto suffix = "-" + boost::to_lower_copy(o->context()); + if (name.size() > suffix.size() && std::equal(suffix.rbegin(), suffix.rend(), name.rbegin())) { + name = name.substr(0, name.size() - suffix.size()); + } + while (true) { + auto unique_name = name; + if (postfix) { + unique_name += "_" + std::to_string(postfix); } - return name; + unique_name = usd_utils::toPath(unique_name); + if (emitted_names_.find(unique_name) == emitted_names_.end()) { + emitted_names_.insert(unique_name); + return element_names_[o->id()] = unique_name; + } + postfix += 1; } } @@ -153,7 +164,7 @@ T USDSerializer::writeNode(const IfcGeom::Element* o, const IfcGeom::Element* p) m = placements_[p->id()]->ccomponents().inverse() * m; } else { std::vector names; - std::transform(o->parents().begin(), o->parents().end(), std::back_inserter(names), nameObject); + std::transform(o->parents().begin(), o->parents().end(), std::back_inserter(names), [this](auto& i) { return object_id_unique(i); }); std::ostringstream oss; std::copy(names.begin(), names.end(), std::ostream_iterator(oss, "/")); prefix += oss.str(); @@ -161,12 +172,13 @@ T USDSerializer::writeNode(const IfcGeom::Element* o, const IfcGeom::Element* p) // std::ostringstream pss; // pss << "MATT" << std::endl << std::endl; // pss << m << std::endl << std::endl << o->parents().back()->transformation().data()->ccomponents() << std::endl << std::endl; + if (!o->parents().empty()) m = o->parents().back()->transformation().data()->ccomponents().inverse() * m; // pss << m << std::endl << std::endl; // auto psss = pss.str(); // std::wcout << psss.c_str() << std::endl; } - auto el_path = prefix + nameObject(o); + auto el_path = prefix + object_id_unique(o); paths_[o->id()] = el_path; T t = T::Define(stage_, pxr::SdfPath(el_path)); @@ -189,7 +201,8 @@ void USDSerializer::write(const IfcGeom::TriangulationElement* o) { parents_.push_back({ *it, previous }); previous = *it; } - pxr::UsdGeomMesh usd_mesh = writeNode(o); + pxr::UsdGeomXform usd_mesh_container = writeNode(o); // writeNode(o); + auto usd_mesh = pxr::UsdGeomMesh::Define(stage_, pxr::SdfPath(usd_mesh_container.GetPath().GetString() + "/" + o->context())); const IfcGeom::Representation::Triangulation& mesh = o->geometry(); const auto verts = mesh.verts(); const auto faces = mesh.faces(); diff --git a/src/serializers/USDSerializer.h b/src/serializers/USDSerializer.h index 37cefdb6db..9f795fb88b 100644 --- a/src/serializers/USDSerializer.h +++ b/src/serializers/USDSerializer.h @@ -78,6 +78,8 @@ private: std::set written_; std::map paths_; std::map placements_; + std::set emitted_names_; + std::map element_names_; public: USDSerializer(const std::string&, const ifcopenshell::geometry::Settings&, const ifcopenshell::geometry::SerializerSettings&); virtual ~USDSerializer(); @@ -89,6 +91,7 @@ public: bool isTesselated() const { return true; } void setUnitNameAndMagnitude(const std::string&, float) {} void setFile(IfcParse::IfcFile*) {} + std::string object_id_unique(const IfcGeom::Element* o); }; #endif