Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-04-09 07:48:48

0001 #!/usr/bin/env python
0002 #
0003 # Copyright (c) 2019 Opticks Team. All Rights Reserved.
0004 #
0005 # This file is part of Opticks
0006 # (see https://bitbucket.org/simoncblyth/opticks).
0007 #
0008 # Licensed under the Apache License, Version 2.0 (the "License"); 
0009 # you may not use this file except in compliance with the License.  
0010 # You may obtain a copy of the License at
0011 #
0012 #   http://www.apache.org/licenses/LICENSE-2.0
0013 #
0014 # Unless required by applicable law or agreed to in writing, software 
0015 # distributed under the License is distributed on an "AS IS" BASIS, 
0016 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  
0017 # See the License for the specific language governing permissions and 
0018 # limitations under the License.
0019 #
0020 
0021 """
0022 
0023 Maximum global transform deviation just less than 0.1 mm when using float64 (jumping around up to 0.2mm when using float32)
0024 when comparing global transforms from the G4DAE/GMergedMesh 
0025 cache and the products of the glTF json parsed matrices.
0026 
0027 TODO: perhaps more precision loss later... compare transforms at point of use inside C++
0028 
0029 ::
0030 
0031 In [190]: run gltf.py
0032 [2017-07-01 11:35:10,972] p18709 {/Users/blyth/opticks/ana/base.py:266} INFO - envvar OPTICKS_ANA_DEFAULTS -> defaults {'src': 'torch', 'tag': '1', 'det': 'concentric'} 
0033 args: gltf.py
0034                scenes : 1 
0035                 nodes : 12230 
0036                meshes : 249 
0037  lpo                             [0, 0, 0, 1] : gd32(    0.00000    0.06326 )  gd64(     0.00000    0.09817 ) 
0038  lpo                 [0.001, 0.001, 0.001, 1] : gd32(    0.00000    0.06326 )  gd64(     0.00000    0.09817 ) 
0039  lpo                    [1000, 1000, 1000, 1] : gd32(    0.00000    0.06326 )  gd64(     0.00000    0.09783 ) 
0040  lpo                 [10000, 10000, 10000, 1] : gd32(    0.00000    0.18775 )  gd64(     0.00000    0.09497 ) 
0041  lpo  [10000.0001, 10000.0001, 10000.0001, 1] : gd32(    0.00000    0.18775 )  gd64(     0.00000    0.09497 ) 
0042  lpo                 [20000, 20000, 20000, 1] : gd32(    0.00000    0.12727 )  gd64(     0.00000    0.09218 ) 
0043  lpo                          [1000, 0, 0, 1] : gd32(    0.00000    0.06326 )  gd64(     0.00000    0.09833 ) 
0044  lpo                          [0, 1000, 0, 1] : gd32(    0.00000    0.06326 )  gd64(     0.00000    0.09771 ) 
0045  lpo                          [0, 0, 1000, 1] : gd32(    0.00000    0.06326 )  gd64(     0.00000    0.09813 ) 
0046  lpo                 [-1000, -1000, -1000, 1] : gd32(    0.00000    0.12502 )  gd64(     0.00000    0.09851 ) 
0047  lpo                 [-5000, -5000, -5000, 1] : gd32(    0.00000    0.12514 )  gd64(     0.00000    0.09992 ) 
0048  lpo                    [5000, 5000, 5000, 1] : gd32(    0.00000    0.06443 )  gd64(     0.00000    0.09652 ) 
0049  lpo                         [10000, 0, 0, 1] : gd32(    0.00000    0.06398 )  gd64(     0.00000    0.09997 ) 
0050 
0051 
0052 """
0053 
0054 import os, logging, numpy as np
0055 log = logging.getLogger(__name__)
0056 
0057 from opticks.ana.base import opticks_main, json_load_ , idp_
0058 from opticks.analytic.glm import mdotr_
0059 
0060 
0061 class NN(list):
0062     def __init__(self, volpath):
0063         list.__init__(self,volpath) 
0064     def __repr__(self):
0065         return "\n".join(map(repr, self))
0066 
0067     def _get_transforms32(self):
0068         return map(lambda n:n.transform32, self)
0069     transforms32 = property(_get_transforms32)
0070 
0071     def _get_transforms64(self):
0072         return map(lambda n:n.transform64, self)
0073     transforms64 = property(_get_transforms64)
0074 
0075     gtr32 = property(lambda self:mdotr_(self.transforms32))
0076     gtr64 = property(lambda self:mdotr_(self.transforms64))
0077     gtr32r = property(lambda self:mdotr_(self.transforms32[::-1]))
0078     gtr64r = property(lambda self:mdotr_(self.transforms64[::-1]))
0079 
0080 
0081 class N(object):
0082     def __init__(self, gltfnode):
0083         self.gn = gltfnode
0084         self.children = gltfnode.get('children', [])
0085         self.transform32 = np.asarray( gltfnode.get('matrix'), dtype=np.float32 ).reshape(4,4)
0086         self.transform64 = np.asarray( gltfnode.get('matrix'), dtype=np.float64 ).reshape(4,4)
0087 
0088     def __repr__(self):
0089         return " mesh: %d matrix:%s pvn:%s " % (self.gn['mesh'], repr(self.gn['matrix']), self.gn['extras']['pvname'])      
0090 
0091 
0092 class GLTF(object):
0093     def __init__(self, path="$TMP/tgltf/tgltf-gdml--.gltf", t0=None):
0094          self.path = path
0095          self.gltf = json_load_(path)
0096          self.t0 = t0 
0097          self.nn = {}
0098 
0099     def get_node(self, idx):
0100         return self.gltf['nodes'][idx]
0101 
0102     def get_n(self, idx):
0103         return self.nn[idx]
0104 
0105     def traverse(self):
0106         def traverse_r(idx,ancestors):
0107 
0108             volpath = ancestors[:]
0109 
0110             gn = self.get_node(idx) 
0111             n = N(gn)
0112             volpath.append(n)
0113 
0114             self.nn[idx] = NN(volpath) 
0115 
0116             cc = n.children
0117 
0118             #print "%6d : %6d %6d " % ( idx, len(volpath), len(cc))
0119 
0120             for c in cc:
0121                 traverse_r(c, volpath)
0122             pass
0123         pass
0124         traverse_r(0, [])
0125 
0126 
0127     def __str__(self):
0128         lkeys = filter(lambda k:type(self.gltf[k]) is list, self.gltf.keys() )
0129         return "\n".join([" %20s : %d " % (k, len(self.gltf[k])) for k in lkeys])
0130 
0131 
0132 
0133     def gtransform_delta(self, lpos=[0,0,0,1]):
0134         return self.gtransform_delta_(lpos, np.float32), self.gtransform_delta_(lpos, np.float64)
0135 
0136     def gtransform_delta_(self, lpos_, dtype=np.float64):
0137         """
0138         Check distance between a local frame position transformed with the two 
0139         transforms
0140         """
0141         lpos = np.asarray(lpos_, dtype=dtype)
0142 
0143         num = len(self.nn)
0144         gdelta = np.zeros(num, dtype=dtype)
0145 
0146         for idx in range(num):
0147             t0 = self.t0[idx].reshape(4,4)
0148             nn = self.nn[idx] 
0149 
0150             t1 = nn.gtr32r if dtype is np.float32 else nn.gtr64r
0151 
0152             gpos0 = np.dot( lpos, t0 )[:3]
0153             gpos1 = np.dot( lpos, t1 )[:3]
0154             d = gpos0 - gpos1
0155             gdelta[idx] = np.sqrt(np.dot(d,d))
0156         pass
0157         return gdelta
0158 
0159                 
0160 
0161 
0162 
0163 
0164 
0165 if __name__ == '__main__':
0166      args = opticks_main()
0167 
0168      t0 = np.load(idp_("GMergedMesh/0/transforms.npy"))
0169      
0170      g = GLTF(t0=t0)
0171      print g 
0172 
0173      g.traverse()
0174 
0175      lpos = [
0176                [0,0,0,1],
0177                [1e-3,1e-3,1e-3,1],
0178                [1000,1000,1000,1],
0179                [10000,10000,10000,1],
0180                [10000.0001,10000.0001,10000.0001,1],
0181                [20000,20000,20000,1],
0182                [1000,0,0,1],
0183                [0,1000,0,1],
0184                [0,0,1000,1],
0185                [-1000,-1000,-1000,1],
0186                [-5000,-5000,-5000,1],
0187                [5000,5000,5000,1],
0188                [10000,0,0,1]
0189             ]
0190 
0191 
0192      for lpo in lpos:
0193          gd32,gd64 = g.gtransform_delta(lpo)
0194          print " lpo %40s : gd32( %10.5f %10.5f )  gd64(  %10.5f %10.5f ) " % ( repr(lpo),gd32.min(),gd32.max(), gd64.min(),gd64.max() )
0195      pass
0196 
0197 
0198      nn = g.nn[3159]
0199 
0200