GGeo Orientation : Geometry Modelling and Persisting¶
Table of contents
- orientation : Opticks Codebase Orientation for Developers
- https://bitbucket.org/simoncblyth/opticks/src/master/ggeo/
- https://bitbucket.org/simoncblyth/opticks/src/master/ggeo/GGeo.cc
- GGeo
- top level holder of geometry libraries : GMaterialLib, GSurfaceLib, GBndLib, GNodeLib, GGeoLib
- GVolume
- created from G4VPhysicalVolume by X4PhysicalVolume::convertNode
- GNodeLib
- collects GVolume instances GNodeLib::addVolume
- GInstancer
Does multiple traversals over full GVolume tree, identifying repeated geometry and labelling the tree nodes with the repeat index (ridx). Remainder geometry that does not pass instancing cuts on numbers of repeats is left with repeat index zero.
- used from GGeo::prepareVolumes
- GInstancer::createInstancedMergedMeshes
Analytic Geometry Overview : GPt, GPts, GParts¶
GPt
- minimally captures node(ndIdx) to solid(lvIdx,csgIdx) association and boundaryName, can also hold placement transforms
X4PhysicalVolume::convertNode
GPt
structs instanciated and associated with GVolume (NBGParts
instanciation now deferred )GMergedMesh::mergeVolumeAnalytic
GPt
instances are collected intoGPts
afterGPt::setPlacement
with the appropriateGVolume
(base relative or global) transform duringGMergedMesh::mergeVolume
.GPts
- collects
GPt
struct and handles their persisting to/from two transport buffers (ipt and plc) and oneGItemList
of boundary spec GGeo::deferredCreateGParts
- invoked from
GGeo::postLoadFromCache
orGGeo::postDirectTranslation
. GParts
- analytic geometry holding
npy/NCSG
NPY Orientation : array creation, updating and persisting GParts::Create
- from from the volume combined
GPts
andstd::vector<NCSG*>
fromm_meshlib
GPt¶
GPt captures node placement of a solid within the full geometry tree in a minimal way, holding only:
- placement
- global transform
- lvIdx, csgIdx
- indices referencing the solid shape
- ndIdx
- index of the node in the full tree
- spec
- string representing the boundary of this node in the tree (material and surface omat/osur/isur/imat)
GPt are canonically instanciated in X4PhysicalVolume::convertNode where instances are associated with the GVolume of the structural tree.
vectors of GPt instances are collected into GPts m_pts within GMergedMesh. The GPts are persisted into the geocache which allows GParts creation to be deferred postcache.
GPts¶
GPts::export_
serializes a vector of GPt
into transport arrays
m_ipt_buffer(n,4;int)
- four indices from
GPt
struct referencing the solid and the node m_plc_buffer(n,4,4;float)
- placement transforms
m_specs(GItemList)
- list of boundary spec strings
Canonical m_pts instances are residents of GMergedMesh and are instanciated by GMergedMesh::GMergedMesh with GPts::Make.
GPt instances are created in X4PhysicalVolume::convertNode and associated with the GVolume which are also instanciated there.
Motivation for GPts is to allow postcache deferred creation of merged GParts instances. This capability is needed in order to reconcile the different Opticks/Geant4 requirements regarding balanced/unbalanced CSG trees, see notes/issues/x016.rst
Can think of GPts as gathering and persisting the arguments needed for deferred GParts creation and merging.
This GParts creation is done in GGeo::deferredCreateGParts which is invoked from on high in OpticksHub::init after GGeo is loaded or adopted.
GParts¶
handles the concatenation of analytic geometry, by combination of GParts instances
creates primitive buffer from the parts buffer
holds boundary specifications as lists of strings that are only converted into actual boundaries with indices pointing at materials and surface by GParts::registerBoundaries which is invoked by GParts::close which happens late (typically within oxrap just before upload to GPU).
This approach was adopted to allow dynamic addition of geometry and boundaries, which is convenient for testing.
the GParts name derives from the history of being used to hold single primitive parts of Daya Bay PMT which were created by detdesc partitioning from python (pmt-/tree.py)
Buffers¶
- partBuffer
- CSG nodes eg Sphere, Box, Cylinder
- planBuffer
- planes referenced by some shapes such as ConvexPolyhedron like Trapezoid (JUNO geometry does not have any of these)
- primBuffer
- higher level than the partBuffer : references into partBuffer with an offset and a number of nodes eg corresponding to trees of nodes So the primBuffer corresponds (roughly) to a G4VSolid that is used within a LogicalVolume
- tranBuffer
- holds transforms, inverse transforms and transposed-inverse-transforms these transforms are referenced by index from the partBuffer nodes
- ITransformBuffer
- instance transform buffer, for example holding the transforms that position every PMT together with a reference to the prim
- InstanceIdentityBuffer
- holds things like the boundary code of the instance and also identifi
Lifecycle Summary¶
- single tree(ie single solid) GParts created from NCSG by X4PhysicalVolume::convertNode on first encountering an lvIdx, where they get attached to a GVolume
- single tree GParts are merged together into combination GParts by GMergedMesh::mergeVolumeAnalytic where placement transforms are applied with GParts::applyPlacementTransform
- combinend GParts are uses by OGeo::makeAnalyticGeometry to GParts::close and upload the GParts buffers into the OptiX context on GPU
Details on where GParts is used¶
Based on opticks-fl GParts.hh
./ggeo/CMakeLists.txt
./ggeo/GParts.cc
setup
./ggeo/GPmt.cc
./ggeo/tests/GPmtTest.cc
./ggeo/GScene.cc
near dead code : to be removed
./extg4/tests/X4PhysicalVolume2Test.cc
./extg4/tests/X4SolidTest.cc
./ggeo/tests/GPartsTest.cc
tests
./extg4/X4PhysicalVolume.cc
X4PhysicalVolume::convertNode
within the visit of X4PhysicalVolume::convertStructure_r
GParts::Make creates GParts instance from the NCSG
associated to the GMesh for the lvIdx solid. The GParts
are associated with the GVolume nodes of the tree.
./ggeo/GMergedMesh.cc
NB for full(not test?) geometry GMergedMesh is orchestrated
from GGeo::prepare by the GInstancer, but most action is in GMergedMesh
GMergedMesh::mergeMergedMesh
GParts::add the pts from an "other" GMergedMesh into m_parts
GMergedMesh::mergeVolume
invokes GMergedMesh::mergeVolumeAnalytic with the pts
and transform associated to the GVolume.
The transform is the base or root relative flobal transform
GMergedMesh::mergeVolumeAnalytic
GParts::add the pts argument after GParts::applyPlacementTransform
is applied to them, using transform argument
./ggeo/GGeoLib.cc
GGeoLib::loadConstituents
GParts::Load and associates them with corresponding GMergedMesh also loaded
GGeoLib::saveConstituents
GParts::save
./ggeo/GGeoTest.cc
GGeoTest::importCSG
GParts::setIndex to the collected m_meshes index
./ggeo/GMaker.cc
GMaker::makeFromMesh
GParts::Make from NCSG instance and spec : used
from GGeoTest
GMaker::make
GMaker::makePrism
GParts::Make from parameters, type and spec : used for
creation of simple geometries
./optixrap/OGeo.cc
OGeo::makeAnalyticGeometry
GParts::close constructs the primBuffer, also uploads the
various buffers prim/tran/part/identity into OptiX context on GPU
Mesh-type or node-type¶
Boundary spec is a node-type-qty, not a mesh-type-qty so it does not belong inside GParts (a mesh-type-qty) … there are relatively few mesh-type-qty for each distinct shape (~249 DYB), but much more node-type-qty (~12k DYB)
BUT: GParts combination means that it kinda transitions between mesh-type when just for a single unplaced shape into node-type once applyPlacementTransform is used by GMergedMesh::mergeVolumeAnalytic
persisted structure detailed in GParts.rst¶
- for examination of structure of multi-complete tree buffers see GParts.rst
GGeo¶
HMM: thoughts on removing m_ok okc/Opticks to rebase this on top of sysrap skipping NPY and BRAP ?
- removal is too big of a change, as it gets threaded thru most of the geo libs
- also longterm this class can disappear once have a more direct G4->CSGFoundry translation : so it is not worthwhile doing such extreme surgery
- could however change type from okc/Opticks to sysrap/SOpticks with just the subset of Opticks needed
much more readily ?
- BUT: there is a lot of code here based in NPY, BRAP so maybe not worthwile trying to change that until implement direct G4->CSGFoundry
GGeo::deferredCreateGParts
¶
Canonically invoked from GGeo::postLoadFromCache
and GGeo::postDirectTranslation
.
so this happens both on direct translation and on saving.
But beware the –gparts_transform_offset setting : when creating a CSGFoundry
geometry it needs to be enabled.
frame #3: 0x00000001069a76f5 libGGeo.dylib`GParts::Create(ok=0x0000000110100310, pts=0x000000010eed2e60, solids=size=7, num_mismatch_pt=0x00007ffeefbfa7c0, mismatch_placements=0x00007ffeefbfa7a8 size=0, imm=0, global_tranOffset=0)0>, std::__1::allocator<glm::mat<4, 4, float, (glm::qualifier)0> > >*, int, int) at GParts.cc:258
frame #4: 0x0000000106a1b01e libGGeo.dylib`GGeo::deferredCreateGParts(this=0x000000010ee8e360) at GGeo.cc:1472
frame #5: 0x0000000106a185d0 libGGeo.dylib`GGeo::deferred(this=0x000000010ee8e360) at GGeo.cc:622
frame #6: 0x0000000106a18aec libGGeo.dylib`GGeo::postDirectTranslation(this=0x000000010ee8e360) at GGeo.cc:602
frame #7: 0x00000001000e39c3 libG4OK.dylib`G4Opticks::translateGeometry(this=0x000000010ee79720, top=0x000000010ed1f570) at G4Opticks.cc:974
frame #8: 0x00000001000e2874 libG4OK.dylib`G4Opticks::setGeometry(this=0x000000010ee79720, world=0x000000010ed1f570) at G4Opticks.cc:602
This is needed prior to GPU upload of analytic geometry by OGeo, it requires the GMergedMesh from GGeoLib and the NCSG solids from GMeshLib. Thus it can be done postcache, as all the ingredients are loaded from cache.
See ../notes/issues/GPts_GParts_optimization
- option –savegparts Opticks::isSaveGPartsEnabled() writes $TMP/GParts/0,1,2,.. which is read by ana/GParts.py to provide a python interface to the analytic geometry