File indexing completed on 2026-04-09 07:48:52
0001
0002 """
0003 CSGFoundryLoadTest.py
0004 =======================
0005
0006 This reviews python access to CSGSolid/CSGPrim/CSGNode
0007 to assist with development of importing those from stree/snd::
0008
0009 cf.prim.view(np.int32)[:,:2].reshape(-1,8)
0010
0011 In [2]: expr
0012 Out[2]: 'cf.prim.view(np.int32)[:,:2].reshape(-1,8) '
0013
0014 In [3]: eval(expr)
0015 Out[3]:
0016 array([[ 1, 0, 0, 0, 0, 149, 0, 0],
0017 [ 1, 1, 1, 0, 1, 17, 0, 1],
0018 [ 1, 2, 2, 0, 2, 2, 0, 2],
0019 [ 3, 3, 3, 0, 3, 1, 0, 3],
0020 [ 3, 6, 5, 0, 4, 0, 0, 4],
0021
0022 nn no to po so mx rx px
0023
0024 nn:numNode
0025 no:nodeOffset
0026 to:tranOffset
0027 po:planOffset
0028
0029 so:sbtIndexOffset
0030 mx:meshIdx : corresponds to lvIdx
0031 rx:repeatIdx
0032 px:primIdx
0033
0034 nn = cf.prim.view(np.int32)[:,0,0]
0035
0036 In [7]: np.unique( nn, return_counts=True )
0037 Out[7]:
0038 (array([ 1, 3, 7, 15, 31, 127], dtype=int32),
0039 array([ 933, 127, 2130, 12, 1, 56]))
0040
0041 ## The nn:numNode are all complete binary tree sizes
0042 ## Presumably that means there are no multiunions with subNum/subOffset in use ?
0043
0044 In [9]: cf.prim.view(np.int32)[:,0,0].sum()
0045 Out[9]: 23547
0046
0047 In [10]: cf.node.shape
0048 Out[10]: (23547, 4, 4)
0049
0050 In [66]: mx = cf.prim.view(np.int32)[:,1,1]
0051 In [71]: mx.min(), mx.max()
0052 Out[71]: (0, 149)
0053
0054 In [63]: rx = cf.prim.view(np.int32)[:,1,2] # repeatIndex associating the prim to its solid
0055 In [65]: np.unique(rx, return_counts=True )
0056 Out[65]:
0057 (array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9], dtype=int32),
0058 array([3089, 5, 11, 14, 6, 1, 1, 1, 1, 130]))
0059
0060 ## Those unique ridx counts correspond directly to the solid numPrim
0061
0062 In [98]: cf.solid[:,1,0]
0063 Out[98]: array([3089, 5, 11, 14, 6, 1, 1, 1, 1, 130], dtype=int32)
0064
0065 In [72]: px = cf.prim.view(np.int32)[:,1,3]
0066 In [76]: px.min(), px.max(), len(px)
0067 Out[76]: (0, 3088, 3259)
0068
0069
0070 In [87]: np.all( np.arange(3089) == px[:3089] )
0071 Out[87]: True
0072 # contiguous monotonic up to 3089 : Those are the primIdx for the ridx:0 globals
0073
0074 Beyond 3089 the last 170 prim dont increment the primIdx.
0075 Thats because they are the instances, that reset the primIdx back to zero for each::
0076
0077 In [94]: px[3089:]
0078 Out[94]:
0079 array([
0080 0, 1, 2, 3, 4, # ridx:1 (5)
0081 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, # ridx:2 (11)
0082 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, # ridx:3 (14)
0083 0, 1, 2, 3, 4, 5, # ridx:4 (6)
0084 0, # ridx:5 (1)
0085 0, # ridx:6 (1)
0086 0, # ridx:7 (1)
0087 0, # ridx:8 (1)
0088 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, # ridx:9 (130)
0089 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31,
0090 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47,
0091 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63,
0092 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79,
0093 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95,
0094 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111,
0095 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127,
0096 128, 129]
0097 , dtype=int32)
0098
0099 In [95]: px[3089:].shape
0100 Out[95]: (170,)
0101
0102 Looking at cf.solid makes this plain::
0103
0104 In [51]: cf.solid.view(np.int32)[:,0].copy().view("|S16")
0105 Out[51]:
0106 array([[b'r0'],
0107 [b'r1'],
0108 [b'r2'],
0109 [b'r3'],
0110 [b'r4'],
0111 [b'r5'],
0112 [b'r6'],
0113 [b'r7'],
0114 [b'r8'],
0115 [b'r9']], dtype='|S16')
0116
0117 In [56]: cf.solid.view(np.int32)[:,1]
0118 Out[56]:
0119 array([[3089, 0, 0, 0],
0120 [ 5, 3089, 0, 0],
0121 [ 11, 3094, 0, 0],
0122 [ 14, 3105, 0, 0],
0123 [ 6, 3119, 0, 0],
0124 [ 1, 3125, 0, 0],
0125 [ 1, 3126, 0, 0],
0126 [ 1, 3127, 0, 0],
0127 [ 1, 3128, 0, 0],
0128 [ 130, 3129, 0, 0]], dtype=int32)
0129
0130 numPrim primOffset
0131
0132 In [58]: cf.solid.view(np.int32)[:,1,0].sum()
0133 Out[58]: 3259
0134
0135 In [59]: cf.prim.shape
0136 Out[59]: (3259, 4, 4)
0137
0138
0139 Associating each prim to its nodes::
0140
0141 In [102]: pnn = cf.prim.view(np.int32)[:,0,0]
0142 In [103]: pno = cf.prim.view(np.int32)[:,0,1]
0143
0144
0145
0146 * HMM associating the nodes to each solid
0147
0148 Start of the node index is contiguous monotonic::
0149
0150 In [14]: ix = cf.node.view(np.int32)[:,1,3]
0151 In [36]: np.all( np.arange(23200) == ix[:23200] )
0152 Out[36]: True
0153 In [37]: ix.shape
0154 Out[37]: (23547,)
0155 In [40]: np.all( np.arange(23207) == ix[:23207] )
0156 Out[40]: True
0157 In [41]: np.all( np.arange(23208) == ix[:23208] )
0158 Out[41]: False
0159
0160 """
0161
0162 import numpy as np, logging
0163 log = logging.getLogger(__name__)
0164 from opticks.CSG.CSGFoundry import CSGFoundry, CSGPrim
0165 from opticks.ana.fold import Fold
0166 from opticks.sysrap.stree import stree, snode, snd
0167
0168 np.set_printoptions(edgeitems=16)
0169
0170 if __name__ == '__main__':
0171 logging.basicConfig(level=logging.INFO)
0172
0173 CSGPrim.Type()
0174 cf = CSGFoundry.Load()
0175 print(repr(cf))
0176
0177 stf = Fold.Load(cf.base, "CSGFoundry/SSim/stree")
0178 st = stree(stf)
0179 print(repr(st))
0180
0181 print(cf.descSolids(True))
0182 print(cf.descSolids(False))
0183
0184