@@ -170,7 +170,6 @@ def createPolygons(self, indices, inputlist, materialid=None):
170170 def load (collada , localscope , node ):
171171 id = node .get ("id" ) or ""
172172 name = node .get ("name" ) or ""
173-
174173 tag_mesh = collada .tag ('mesh' )
175174 tag_source = collada .tag ('source' )
176175 tag_vertices = collada .tag ('vertices' )
@@ -187,55 +186,70 @@ def load(collada, localscope, node):
187186 meshnode = node .find (tag_mesh )
188187 if meshnode is None :
189188 raise DaeUnsupportedError ('Unknown geometry node' )
189+
190+ # Single pass over meshnode: collect sources, vertices, and primitive nodes
190191 sourcebyid = {}
191- sources = []
192- sourcenodes = node .findall ('%s/%s' % (tag_mesh , tag_source ))
193- for sourcenode in sourcenodes :
194- ch = source .Source .load (collada , {}, sourcenode )
195- sources .append (ch )
196- sourcebyid [ch .id ] = ch
197-
198- verticesnode = meshnode .find (tag_vertices )
192+ verticesnode = None
193+ primitive_nodes = []
194+ tri_tags = {tag_triangles , tag_tristrips , tag_trifans }
195+
196+ for subnode in meshnode :
197+ tag = subnode .tag
198+ if tag == tag_source :
199+ ch = source .Source .load (collada , {}, subnode )
200+ sourcebyid [ch .id ] = ch
201+ elif tag == tag_vertices :
202+ verticesnode = subnode
203+ elif tag == tag_polylist :
204+ primitive_nodes .append (('polylist' , subnode ))
205+ elif tag in tri_tags :
206+ primitive_nodes .append (('triangles' , subnode ))
207+ elif tag == tag_lines :
208+ primitive_nodes .append (('lines' , subnode ))
209+ elif tag == tag_polygons :
210+ primitive_nodes .append (('polygons' , subnode ))
211+ elif tag != tag_extra :
212+ raise DaeUnsupportedError ('Unknown geometry tag %s' % tag )
213+
214+ # Process vertices node (needs sourcebyid populated)
199215 if verticesnode is not None :
200216 inputnodes = {}
201- for inputnode in verticesnode .findall (tag_input ):
217+ for inputnode in verticesnode .iterfind (tag_input ):
202218 semantic = inputnode .get ('semantic' )
203219 inputsource = inputnode .get ('source' )
204220 if not semantic or not inputsource or not inputsource .startswith ('#' ):
205221 raise DaeIncompleteError ('Bad input definition inside vertices' )
206222 inputnodes [semantic ] = sourcebyid .get (inputsource [1 :])
207- if ( not verticesnode .get ('id' ) or len ( inputnodes ) == 0 or
208- 'POSITION' not in inputnodes ) :
223+ vertices_id = verticesnode .get ('id' )
224+ if not vertices_id or len ( inputnodes ) == 0 or 'POSITION' not in inputnodes :
209225 raise DaeIncompleteError ('Bad vertices definition in mesh' )
210- sourcebyid [verticesnode .get ('id' )] = inputnodes
211- verticesnode .get ('id' )
226+ sourcebyid [vertices_id ] = inputnodes
212227
213- double_sided_node = node . find ( './/%s//%s' % ( tag_extra , tag_double_sided ) )
228+ # Check for double_sided in extra nodes (on parent node, not meshnode )
214229 double_sided = False
215- if double_sided_node is not None and double_sided_node .text is not None :
216- try :
217- val = int (double_sided_node .text )
218- if val == 1 :
219- double_sided = True
220- except ValueError :
221- pass
222-
230+ for extra in node .iterfind (tag_extra ):
231+ double_sided_node = extra .find (f".//{ tag_double_sided } " )
232+ if double_sided_node is not None and double_sided_node .text is not None :
233+ try :
234+ if int (double_sided_node .text ) == 1 :
235+ double_sided = True
236+ break
237+ except ValueError :
238+ pass
239+
240+ # Load primitives (needs complete sourcebyid with vertices)
223241 _primitives = []
224- tri_tags = (tag_triangles , tag_tristrips , tag_trifans )
225-
226- for subnode in meshnode :
227- if subnode .tag == tag_polylist :
228- _primitives .append (polylist .Polylist .load (collada , sourcebyid , subnode ))
229- elif subnode .tag in tri_tags :
230- _primitives .append (triangleset .TriangleSet .load (collada , sourcebyid , subnode ))
231- elif subnode .tag == tag_lines :
232- _primitives .append (lineset .LineSet .load (collada , sourcebyid , subnode ))
233- elif subnode .tag == tag_polygons :
234- _primitives .append (polygons .Polygons .load (collada , sourcebyid , subnode ))
235- elif subnode .tag != tag_source and subnode .tag != tag_vertices and subnode .tag != tag_extra :
236- raise DaeUnsupportedError ('Unknown geometry tag %s' % subnode .tag )
237- geom = Geometry (collada , id , name , sourcebyid , _primitives , xmlnode = node , double_sided = double_sided )
238- return geom
242+ for ptype , pnode in primitive_nodes :
243+ if ptype == 'polylist' :
244+ _primitives .append (polylist .Polylist .load (collada , sourcebyid , pnode ))
245+ elif ptype == 'triangles' :
246+ _primitives .append (triangleset .TriangleSet .load (collada , sourcebyid , pnode ))
247+ elif ptype == 'lines' :
248+ _primitives .append (lineset .LineSet .load (collada , sourcebyid , pnode ))
249+ else : # polygons
250+ _primitives .append (polygons .Polygons .load (collada , sourcebyid , pnode ))
251+
252+ return Geometry (collada , id , name , sourcebyid , _primitives , xmlnode = node , double_sided = double_sided )
239253
240254 def save (self ):
241255 """Saves the geometry back to :attr:`xmlnode`"""
0 commit comments