mikedh / trimesh

Python library for loading and using triangular meshes.
https://trimesh.org
MIT License
3k stars 580 forks source link

Help Understanding mesh.identifier #2034

Closed plourr03 closed 1 year ago

plourr03 commented 1 year ago

Hello i was wondering if you would be able to explain a little more on how this is being calculated? Would similar Meshes get a similar id?

image

mikedh commented 1 year ago

Hey, yeah it's a hand-tuned unprincipled group of properties picked for the purpose of de-duplicating meshes with identical geometry but different translation/rotation in a scene, you can see the properties listed here: https://github.com/mikedh/trimesh/blob/475f921e3497b5c360c56ff269b29c7535147f62/trimesh/comparison.py#L15-L24

It's used in scene.duplicate_nodes which is how it's able to produce results on both instanced scenes, and "bag of meshes" scenes:

import trimesh

# this is an instanced scene with for example one dowel pin transformed to multiple places
In [2]: s = trimesh.load('models/cycloidal.3DXML')

In [3]: s.duplicate_nodes
Out[3]: 
[['60355K430#1:3:2:7:4:6:5',
  '60355K430#1:3:2:9:8:15:14:16:4:6:5',
  '60355K430#1:3:2:9:8:15:14:26:4:6:5',
  '60355K430#1:3:2:9:8:27:14:16:4:6:5',
  '60355K430#1:3:2:9:8:27:14:26:4:6:5',
  '60355K430#1:3:2:9:8:28:14:16:4:6:5',
  '60355K430#1:3:2:9:8:28:14:26:4:6:5',
  '60355K430#1:3:2:42:4:6:5'],
 ['disc_cam_B#1:3:2:9:8:13:10:12:11'],
 ['camshaft#1:3:2:9:8:15:14:20:17:19:18',
  'camshaft#1:3:2:9:8:27:14:20:17:19:18',
  'camshaft#1:3:2:9:8:28:14:20:17:19:18'],
 ['vxb-6800-2rs#1:3:2:9:8:15:14:24:21:23:22',
  'vxb-6800-2rs#1:3:2:9:8:15:14:25:21:23:22',
  'vxb-6800-2rs#1:3:2:9:8:27:14:24:21:23:22',
  'vxb-6800-2rs#1:3:2:9:8:27:14:25:21:23:22',
  'vxb-6800-2rs#1:3:2:9:8:28:14:24:21:23:22',
  'vxb-6800-2rs#1:3:2:9:8:28:14:25:21:23:22'],
 ['disc_cam_A#1:3:2:9:8:32:29:31:30'],
 ['92320A138_spacer#1:3:2:36:33:35:34', '92320A138_spacer#1:3:2:48:33:35:34'],
 ['vxb-6812RS#1:3:2:40:37:39:38', 'vxb-6812RS#1:3:2:41:37:39:38'],
 ['output#1:3:2:46:43:45:44', 'output#1:3:2:47:43:45:44'],
 ['92510A120_spacer#1:52:49:51:50',
  '92510A120_spacer#1:77:49:51:50',
  '92510A120_spacer#1:84:49:51:50',
  '92510A120_spacer#1:85:49:51:50',
  '92510A120_spacer#1:86:49:51:50'],
 ['bushing_roller#1:56:53:55:54',
  'bushing_roller#1:70:53:55:54',
  'bushing_roller#1:71:53:55:54',
  'bushing_roller#1:72:53:55:54',
  'bushing_roller#1:73:53:55:54',
  'bushing_roller#1:74:53:55:54',
  'bushing_roller#1:75:53:55:54',
  'bushing_roller#1:76:53:55:54',
  'bushing_roller#1:78:53:55:54',
  'bushing_roller#1:79:53:55:54',
  'bushing_roller#1:80:53:55:54',
  'bushing_roller#1:81:53:55:54',
  'bushing_roller#1:82:53:55:54',
  'bushing_roller#1:83:53:55:54',
  'bushing_roller#1:87:53:55:54',
  'bushing_roller#1:88:53:55:54',
  'bushing_roller#1:95:53:55:54',
  'bushing_roller#1:99:53:55:54',
  'bushing_roller#1:101:53:55:54',
  'bushing_roller#1:111:53:55:54'],
 ['fixed_lower#1:60:57:59:58', 'fixed_top#1:68:65:67:66'],
 ['dowel_125#1:64:61:63:62',
  'dowel_125#1:89:61:63:62',
  'dowel_125#1:90:61:63:62',
  'dowel_125#1:91:61:63:62',
  'dowel_125#1:92:61:63:62',
  'dowel_125#1:93:61:63:62',
  'dowel_125#1:94:61:63:62',
  'dowel_125#1:96:61:63:62',
  'dowel_125#1:97:61:63:62',
  'dowel_125#1:98:61:63:62',
  'dowel_125#1:100:61:63:62',
  'dowel_125#1:102:61:63:62',
  'dowel_125#1:103:61:63:62',
  'dowel_125#1:104:61:63:62',
  'dowel_125#1:105:61:63:62',
  'dowel_125#1:106:61:63:62',
  'dowel_125#1:107:61:63:62',
  'dowel_125#1:108:61:63:62',
  'dowel_125#1:109:61:63:62',
  'dowel_125#1:110:61:63:62']]

# this is now a scene with one mesh per position and no references
In [4]: dump = trimesh.Scene(s.dump())

In [5]: dump.duplicate_nodes
Out[5]: 
[['60355K430',
  '60355K430_1',
  '60355K430_2',
  '60355K430_3',
  '60355K430_4',
  '60355K430_5',
  '60355K430_6',
  '60355K430_7'],
 ['disc_cam_B'],
 ['camshaft', 'camshaft_1', 'camshaft_2'],
 ['vxb-6800-2rs',
  'vxb-6800-2rs_1',
  'vxb-6800-2rs_2',
  'vxb-6800-2rs_3',
  'vxb-6800-2rs_4',
  'vxb-6800-2rs_5'],
 ['disc_cam_A'],
 ['92320A138_spacer', '92320A138_spacer_1'],
 ['vxb-6812RS', 'vxb-6812RS_1'],
 ['output', 'output_1'],
 ['92510A120_spacer',
  '92510A120_spacer_1',
  '92510A120_spacer_2',
  '92510A120_spacer_3',
  '92510A120_spacer_4'],
 ['bushing_roller',
  'bushing_roller_1',
  'bushing_roller_2',
  'bushing_roller_3',
  'bushing_roller_4',
  'bushing_roller_5',
  'bushing_roller_6',
  'bushing_roller_7',
  'bushing_roller_8',
  'bushing_roller_9',
  'bushing_roller_10',
  'bushing_roller_11',
  'bushing_roller_12',
  'bushing_roller_13',
  'bushing_roller_14',
  'bushing_roller_15',
  'bushing_roller_16',
  'bushing_roller_17',
  'bushing_roller_18',
  'bushing_roller_19'],
 ['fixed_lower', 'fixed_top'],
 ['dowel_125',
  'dowel_126',
  'dowel_127',
  'dowel_128',
  'dowel_129',
  'dowel_130',
  'dowel_131',
  'dowel_132',
  'dowel_133',
  'dowel_134',
  'dowel_135',
  'dowel_136',
  'dowel_137',
  'dowel_138',
  'dowel_139',
  'dowel_140',
  'dowel_141',
  'dowel_142',
  'dowel_143',
  'dowel_144']]

Anecdotally it works pretty reliably but it's not based on any firm principles, just the result of experimentation.