| 457 | } |
| 458 | |
| 459 | void ColladaSerializer::ColladaExporter::endDocument() { |
| 460 | // In fact due the XML based nature of Collada and its dependency on library nodes, |
| 461 | // only at this point all objects are written to the stream. |
| 462 | materials.write(); |
| 463 | bool use_hierarchy = serializer->geometry_settings().get<ifcopenshell::geometry::settings::UseElementHierarchy>().get(); |
| 464 | |
| 465 | std::set<std::string> geometries_written; |
| 466 | |
| 467 | //if the setting USE_ELEMENT_HIERARCHY is in use, we sort the deferreds objects by their parents. |
| 468 | |
| 469 | if (use_hierarchy) { |
| 470 | std::sort(deferreds.begin(), deferreds.end()); |
| 471 | } |
| 472 | |
| 473 | for (std::vector<DeferredObject>::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it) { |
| 474 | if (geometries_written.find(it->representation_id) != geometries_written.end()) { |
| 475 | continue; |
| 476 | } |
| 477 | geometries_written.insert(it->representation_id); |
| 478 | geometries.write(it->representation_id, it->type, it->vertices, it->normals, it->faces, it->edges, |
| 479 | it->material_ids, it->materials, it->uvs, it->material_references); |
| 480 | } |
| 481 | geometries.close(); |
| 482 | |
| 483 | for (std::vector<DeferredObject>::const_iterator it = deferreds.begin(); it != deferreds.end(); ++it){ |
| 484 | const std::string object_name = it->unique_id; |
| 485 | |
| 486 | if (use_hierarchy) |
| 487 | { |
| 488 | size_t parentsNumber = it->parents_.size(); |
| 489 | bool finished = false; |
| 490 | |
| 491 | // If we have no parent in the stack and the object has no parent, nothing to do : skip the loop |
| 492 | if (parentsNumber == 0 && serializer->parentStackId.size() == 0) { finished = true; } |
| 493 | |
| 494 | while (!finished) |
| 495 | { |
| 496 | // If we need to add a parent |
| 497 | if (serializer->parentStackId.size() <= parentsNumber) |
| 498 | { |
| 499 | if (serializer->parentStackId.empty()) { scene.addParent(*(it->parents_.at(0))); } |
| 500 | else |
| 501 | { |
| 502 | size_t diff = parentsNumber - serializer->parentStackId.size(); |
| 503 | |
| 504 | // If we have the wrong parent in the list |
| 505 | if (serializer->parentStackId.top() != it->parents_.at(parentsNumber - diff - 1)->id()) { |
| 506 | scene.closeParent(); |
| 507 | } else { |
| 508 | // So far we have the right parents, we just need to add the missing ones |
| 509 | for (size_t i = parentsNumber - diff; i < parentsNumber; i++) { scene.addParent(*(it->parents_.at(i))); } |
| 510 | |
| 511 | // if diff == 0, we can leave the loop. In fact we have the right number of parents, and the last one is ok |
| 512 | if (diff == 0) { finished = true; } |
| 513 | } |
| 514 | } |
| 515 | } else { |
| 516 | // Close the finished nodes. After this we get the first case (serializer->parentStackId.size() <= parentsNumber) |