Copying attributes
Bengt Richter
bokr at oz.net
Sat Jul 23 14:30:29 EDT 2005
On Thu, 21 Jul 2005 00:45:12 +0200, red <red at redplanet.com> 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
More information about the Python-list
mailing list