Table Of Contents

This Page

Subtree Instances Missing Transform

FIX/WORKAROUND not yet sure which

Marking all meshes to be “global” gives them guaranteed gtransform slots GPU side (see NCSG::import_r) which then allows placement transforms to have an effect (see GParts::applyPlacementTransform).

615 void NScene::markGloballyUsedMeshes_r(nd* n)
616 {
617     assert( n->repeatIdx > -1 );
618
619     //if(n->repeatIdx == 0) setIsUsedGlobally(n->mesh, true );
620     setIsUsedGlobally(n->mesh, true );
621
622     for(nd* c : n->children) markGloballyUsedMeshes_r(c) ;
623 }
624

ISSUE : GMergedMesh subtree assemblies missing transform ?

PMT model frame z-shift transforms are not correctly applied when doing GMergedMesh of the PMT assembly of 5 solids.

When instancing a subtree assembly need to bake the subtree-root relative transform into the geometry, that aint happening correctly.

Where is the subtree relative transform being baked into the analytic CSG list of ~5 trees ?

tgltf-;tgltf-gdml --restrictmesh 0   # crazy too big placeholder bbox to fix

tgltf-;tgltf-gdml --restrictmesh 2

tboolean-;tboolean-pmt

A similar issue for global ridx 0 solids was handled with isUsedGlobally

036 NScene::NScene(const char* base, const char* name, const char* config, int scene_idx)
 37    :
 38     NGLTF(base, name, config, scene_idx),
 39     m_verbosity(0),
 40     m_num_global(0),
 41     m_num_csgskip(0),
 42     m_node_count(0),
 43     m_label_count(0),
 44     m_digest_count(new Counts<unsigned>("progenyDigest"))
 45 {
 46     load_asset_extras();
 47     load_csg_metadata();
 48
 49     m_root = import_r(0, NULL, 0);
 50
 51     if(m_verbosity > 1)
 52     dumpNdTree("NScene::NScene");
 53
 54     compare_trees();
 55
 56     count_progeny_digests();
 57
 58     find_repeat_candidates();
 59
 60     dump_repeat_candidates();
 61
 62     labelTree();
 63
 64     if(m_verbosity > 1)
 65     dumpRepeatCount();
 66
 67     markGloballyUsedMeshes_r(m_root);
 68
 69     // move load_mesh_extras later so can know which meshes are non-instanced needing
 70     // gtransform slots for all primitives
 71     load_mesh_extras();
 72
 73 }



614
615 void NScene::markGloballyUsedMeshes_r(nd* n)
616 {
617     assert( n->repeatIdx > -1 );
618     if(n->repeatIdx == 0) setIsUsedGlobally(n->mesh, true );
619
620     for(nd* c : n->children) markGloballyUsedMeshes_r(c) ;
621 }
622

The upshot of the marking is to always have a gtransform slot for all primitives, so they can be transformed later by changing the transforms:

503 nnode* NCSG::import_r(unsigned idx, nnode* parent)
504 {
505     if(idx >= m_num_nodes) return NULL ;
506
507     OpticksCSG_t typecode = (OpticksCSG_t)getTypeCode(idx);
508     int transform_idx = getTransformIndex(idx) ;
509     bool complement = isComplement(idx) ;
510
511     LOG(debug) << "NCSG::import_r"
512               << " idx " << idx
513               << " transform_idx " << transform_idx
514               << " complement " << complement
515               ;
516
517
518     nnode* node = NULL ;
519
520     if(typecode == CSG_UNION || typecode == CSG_INTERSECTION || typecode == CSG_DIFFERENCE)
521     {
522         node = import_operator( idx, typecode ) ;
523         node->parent = parent ;
524
525         node->transform = import_transform_triple( transform_idx ) ;
526
527         node->left = import_r(idx*2+1, node );
528         node->right = import_r(idx*2+2, node );
529
530         // recursive calls after "visit" as full ancestry needed for transform collection once reach primitives
531     }
532     else
533     {
534         node = import_primitive( idx, typecode );
535         node->parent = parent ;                // <-- parent hookup needed prior to gtransform collection
536
537         node->transform = import_transform_triple( transform_idx ) ;
538
539         nmat4triple* gtransform = node->global_transform();
540         if(gtransform == NULL && m_usedglobally)
541         {
542             gtransform = nmat4triple::make_identity() ;
543         }
544
545         unsigned gtransform_idx = gtransform ? addUniqueTransform(gtransform) : 0 ;
546
547         node->gtransform = gtransform ;
548         node->gtransform_idx = gtransform_idx ; // 1-based, 0 for None
549     }
550     assert(node);
551     node->idx = idx ;
552     node->complement = complement ;
553
554     return node ;
555 }

114 // meshes that are used globally need to have gtransform slots for all primitives
115 bool NGLTF::isUsedGlobally(unsigned mesh_idx)
116 {
117     assert( m_mesh_used_globally.count(mesh_idx) == 1 );
118     return m_mesh_used_globally[mesh_idx] ;
119 }
120
121 void NGLTF::setIsUsedGlobally(unsigned mesh_idx, bool iug)
122 {
123     m_mesh_used_globally[mesh_idx] = iug ;
124 }
simon:opticksnpy blyth$ grep setIsUsedGlobally *.*
NCSG.cpp:void NCSG::setIsUsedGlobally(bool usedglobally )
NCSG.cpp:     tree->setIsUsedGlobally(usedglobally);
NCSG.hpp:        void setIsUsedGlobally(bool usedglobally);
NGLTF.cpp:void NGLTF::setIsUsedGlobally(unsigned mesh_idx, bool iug)
NGLTF.hpp:        void                         setIsUsedGlobally(unsigned mesh_idx, bool iug);
NScene.cpp:    if(n->repeatIdx == 0) setIsUsedGlobally(n->mesh, true );
simon:opticksnpy blyth$