| 511 | } |
| 512 | |
| 513 | Expected<void> Node::loadBuildData_( ThreeMFLoader& loader, const tinyxml2::XMLElement* xmlNode ) |
| 514 | { |
| 515 | for ( auto itemNode = xmlNode->FirstChildElement( "item" ); itemNode; itemNode = itemNode->NextSiblingElement( "item" ) ) |
| 516 | { |
| 517 | auto objIdAttr = itemNode->Attribute( "objectid" ); |
| 518 | if ( !objIdAttr ) |
| 519 | continue; |
| 520 | |
| 521 | const int objId = std::stoi( objIdAttr ); |
| 522 | |
| 523 | auto nodeRes = loader.getNodeById_( objId, itemNode->Attribute( "p:path" ) ); |
| 524 | if ( !nodeRes.has_value() ) |
| 525 | return unexpected( std::move( nodeRes.error() ) ); |
| 526 | |
| 527 | auto* objNode = *nodeRes; |
| 528 | assert( objNode ); |
| 529 | assert( objNode->obj_ ); |
| 530 | |
| 531 | auto transformAttr = itemNode->Attribute( "transform" ); |
| 532 | if ( objNode->obj_->parent() ) |
| 533 | { |
| 534 | // need to clone in case of referencing existing objects: |
| 535 | // |
| 536 | // obj-1: mesh |
| 537 | // obj-2: mesh |
| 538 | // obj-3: group obj-1,obj-2 |
| 539 | // |
| 540 | // build: obj-3, obj-1 |
| 541 | objNode->obj_ = objNode->obj_->cloneTree(); |
| 542 | // need to clone before setting XF |
| 543 | } |
| 544 | if ( transformAttr ) |
| 545 | { |
| 546 | auto resXf = parseAffineXf( std::string( transformAttr ) ); |
| 547 | if ( !resXf ) |
| 548 | return unexpected( resXf.error() ); |
| 549 | |
| 550 | if ( resXf->A.det() == 0 ) |
| 551 | loader.warnings.append( "Degenerate object transform: " + objNode->obj_->name() + "\n" ); |
| 552 | |
| 553 | objNode->obj_->setXf( *resXf ); |
| 554 | } |
| 555 | loader.objectNodes_.push_back( objNode ); |
| 556 | } |
| 557 | |
| 558 | return {}; |
| 559 | } |
| 560 | |
| 561 | Expected<void> Node::load( ThreeMFLoader& loader ) |
| 562 | { |
nothing calls this directly
no test coverage detected