On Thu, 21 Jul 2005 00:45:12 +0200, red <[EMAIL PROTECTED]> wrote: >Hi, > >I'm writing a script for Blender and need to build a face array. My >engine needs that all faces must be triangles, so I convert quads to >triangles by dividing them into two triangles. Here is the function: > >def build_face_table(mesh): > face_table = {} # face_table = [] ?? Irrelevant nit: Why a dict? You seem to be building it with all the keys as integers of xrange(last_i), in which case appending a face_table list to build it and later accessing face_table[key] will go faster than your current dict. OTOH, if you will be deleting various elements later, your dict may be best.
> i = 0 > for f in mesh.faces: > if len(f.v) == 3: # triangle > face_table[i] = f # face_table.append(f) # no need for i counting > i += 1 > elif len(f.v) == 4: # quad > f1 = NMesh.Face() > f2 = NMesh.Face() > > f1.mat = f.mat >## f1.normal = copy.deepcopy(f.normal) > f1.normal = NMesh.Vert(f.normal[0], f.normal[1], > f.normal[2]) f is a quad at this point, right? So unless the quad is restricted to a plane, it couldn't have a normal in general. Could that be it? BTW, if it is not a plane, one choice of diagonal may be better than the other in getting two triangles that fit the underlying 3D surface best. If there is a normal, why wouldn't ft.normal = f.normal[::] work? Is normal more than a 3-tuple or list to record unit vector components in some coordinate system? > f1.v.append(f.v[0]) > f1.v.append(f.v[1]) > f1.v.append(f.v[2]) Why append, and is there restricted property magic behind f1.v so that plain old f1.v = f.v[:3] wouldn't work? # or f1.v = [f.v[0], f.v[1], f.v[2]] if you want to be consistent with f2 below > > f2.mat = f.mat # f2.normal = ?? # could this face be picked up later indirectly and cause the missing normal exception? > f2.v.append(f.v[2]) > f2.v.append(f.v[3]) > f2.v.append(f.v[0]) Why appends? Does f2.v ever grow beyond 3 items? E.g., f2.v = [f.v[2], f.v[3], f.v[0]] # are quad vertices listed clockwise or ccw and # are triangles in a sequence totally independent, or # is there some systematic vertex sharing in the order # that something might depend on, or benefit optimization-wise from? > > face_table[i] = f1 #face_table.append(f1) ?? > i += 1 > face_table[i] = f2 #face_table.append(f2) ?? > i += 1 > else: > message = "Can't build face from 2 vertices." Why is len(f.v)>4 not just a 3D surface point cluster, in which case it might be possible to find an internal point to slice radiating triangles from. E.g., imagine an almost-plane small pentagon on a large sphere, and slice from its "center" to each peripheral pair of vertices to make triangles. > Draw.PupMenu("Face Table Error%t|"+message) > return > return face_table # do you need it as a dict? Unless you modify it, a list will get you # the same elements as your dict by writing face_table[some_index] If you need to iterate and have both index key and value, you can use your dict like for i, face in sorted(face_table.items()): # leave out sorted call if order does not matter # ... or use the more efficient list version of face_table like for i, face in enumerate(facetable): # will naturally be in sort order # ... > >Everything seems be ok, but i'm getting: > >Traceback (most recent call last): > File "<string>", line 169, in write > File "<string>", line 102, in build_face_table >AttributeError: normal > >I was wondering why? Though the face has an attribute called "normal"! >Just simply test: > >nv = f.normal > >and it works! But why my new faces (f1 and f2) no? Did it work on a quad face? What about putting in a debug print before places you use f.normal, e.g. assert hasattr(f, 'normal'), 'This "f"\n----\n%r\n----\ndid not have a normal attribute!!' % f If f.repr doesn't give you enough info, you can format something better in the assert message string. > >Greetings. > >-- >_red ____ _ ____ ____ __ _ BTW, I don't know Blender at all, just reading between the lines ;-) Hope I triggered a useful thought. Regards, Bengt Richter -- http://mail.python.org/mailman/listinfo/python-list