| 144 | |
| 145 | template <typename T> |
| 146 | T USDSerializer::writeNode(const IfcGeom::Element* o, const IfcGeom::Element* p) { |
| 147 | written_.insert(o->id()); |
| 148 | |
| 149 | auto m = o->transformation().data()->ccomponents(); |
| 150 | |
| 151 | // store absolute matrix for calculating relative child matrices later on. |
| 152 | placements_[o->id()] = o->transformation().data(); |
| 153 | |
| 154 | bool is_root = false; |
| 155 | std::string prefix = "/"; |
| 156 | if (geometry_settings_.get<ifcopenshell::geometry::settings::UseElementHierarchy>().get() && p == nullptr && o->parents().empty()) { |
| 157 | // Emitting hierarchy |
| 158 | // p == nullptr means we're in the first pass serializing geometric elements |
| 159 | // in that case empty parents vector means it's the root |
| 160 | is_root = true; |
| 161 | } else if (p != nullptr) { |
| 162 | // Providing explicit parent pointer, lookup previously serialized m4 and path |
| 163 | prefix = paths_[p->id()] + "/"; |
| 164 | m = placements_[p->id()]->ccomponents().inverse() * m; |
| 165 | } else { |
| 166 | std::vector<std::string> names; |
| 167 | std::transform(o->parents().begin(), o->parents().end(), std::back_inserter(names), [this](auto& i) { return object_id_unique(i); }); |
| 168 | std::ostringstream oss; |
| 169 | std::copy(names.begin(), names.end(), std::ostream_iterator<std::string>(oss, "/")); |
| 170 | prefix += oss.str(); |
| 171 | |
| 172 | // std::ostringstream pss; |
| 173 | // pss << "MATT" << std::endl << std::endl; |
| 174 | // pss << m << std::endl << std::endl << o->parents().back()->transformation().data()->ccomponents() << std::endl << std::endl; |
| 175 | if (!o->parents().empty()) |
| 176 | m = o->parents().back()->transformation().data()->ccomponents().inverse() * m; |
| 177 | // pss << m << std::endl << std::endl; |
| 178 | // auto psss = pss.str(); |
| 179 | // std::wcout << psss.c_str() << std::endl; |
| 180 | } |
| 181 | auto el_path = prefix + object_id_unique(o); |
| 182 | paths_[o->id()] = el_path; |
| 183 | |
| 184 | T t = T::Define(stage_, pxr::SdfPath(el_path)); |
| 185 | if (is_root) { |
| 186 | stage_->SetDefaultPrim(t.GetPrim()); |
| 187 | } |
| 188 | |
| 189 | t.AddTransformOp().Set(pxr::GfMatrix4d( |
| 190 | m.data()[0], m.data()[1], m.data()[2], m.data()[3], |
| 191 | m.data()[4], m.data()[5], m.data()[6], m.data()[7], |
| 192 | m.data()[8], m.data()[9], m.data()[10], m.data()[11], |
| 193 | m.data()[12], m.data()[13], m.data()[14], m.data()[15] |
| 194 | )); |
| 195 | return t; |
| 196 | } |
| 197 | |
| 198 | void USDSerializer::write(const IfcGeom::TriangulationElement* o) { |
| 199 | IfcGeom::Element const * previous = nullptr; |