return
d = self.faces[0].normal.dot(self.faces[1].normal)
- if (d>limit and self.faces[0].use_smooth and self.faces[1].use_smooth) or d>0.999:
- self.smooth = True
+ self.smooth = ((d>limit and self.faces[0].use_smooth and self.faces[1].use_smooth) or d>0.99995)
def other_face(self, f):
if f.index==self.faces[0].index:
if mv.__class__==Vertex:
self._mvert = mv._mvert
self.normal = mv.normal
- self.uv = mv.uv
+ self.uvs = mv.uvs[:]
+ self.tan = mv.tan
+ self.bino = mv.bino
else:
self._mvert = mv
- self.uv = None
+ self.uvs = []
+ self.tan = None
+ self.bino = None
self.flag = False
self.faces = []
- self.tan = None
- self.bino = None
def __getattr__(self, attr):
return getattr(self._mvert, attr)
self._mface = mf
self.edges = []
self.vertices = mf.vertices[:]
- self.uv = None
+ self.uvs = []
self.flag = False
self.material = None
self.flag = False
+def uvtex_unit_number(uvtex):
+ dot = uvtex.name.find('.')
+ if dot!=-1 and uvtex.name[dot+1:dot+5]=="unit" and uvtex.name[dot+5:].isdigit():
+ return int(uvtex.name[dot+5])
+ else:
+ return 1000
+
class Mesh:
def __init__(self, m):
self._mesh = m
- self.vertices = [Vertex(v) for v in m.vertices]
- self.faces = [Face(f) for f in m.faces]
- self.materials = m.materials[:]
- self.has_uv = False
- uvtex = None
- if m.uv_textures:
- uvtex = self.uv_textures[0]
- self.has_uv = True
+ self.vertices = [Vertex(v) for v in self.vertices]
+ self.faces = [Face(f) for f in self.faces]
+
+ self.materials = self.materials[:]
+
+ self.uv_textures = [u for u in self.uv_textures if not u.name.endswith(".hidden")]
+ self.uv_textures.sort(key=uvtex_unit_number)
for f in self.faces:
f.vertices = [self.vertices[i] for i in f.vertices]
- if uvtex:
- f.uv = uvtex.data[f.index].uv
for v in f.vertices:
v.faces.append(f)
+ for u in self.uv_textures:
+ r = u.data[f.index].uv_raw;
+ f.uvs.append([(r[i], r[i+1]) for i in range(0, 8, 2)])
- self.edges = dict([(e.key, Edge(e)) for e in m.edges])
+ self.edges = dict([(e.key, Edge(e)) for e in self.edges])
for f in self.faces:
for k in f.edge_keys:
e = self.edges[k]
self.lines = [Line(e) for e in self.edges.values() if not e.faces]
- if m.use_auto_smooth:
- smooth_limit = math.cos(m.auto_smooth_angle*math.pi/180)
+ if self.use_auto_smooth:
+ smooth_limit = math.cos(self.auto_smooth_angle*math.pi/180)
else:
smooth_limit = -1
self.edges[e.key] = e
self.lines += other.lines
-
+
+ def flatten_faces(self):
+ for f in self.faces:
+ f.use_smooth = False
+
+ for e in self.edges.values():
+ e.check_smooth(1)
+
def generate_material_uv(self):
for f in self.faces:
f.uv = ([(f.material_index+0.5)/len(self.materials), 0.5],)*len(f.vertices)
self.has_uv = True
- def split_vertices(self, find_group_func, progress = None):
+ def split_vertices(self, find_group_func, progress, *args):
groups = []
for i in range(len(self.vertices)):
v = self.vertices[i]
vg = []
for f in v.faces:
if not f.flag:
- vg.append(find_group_func(v, f))
+ vg.append(find_group_func(v, f, *args))
groups.append(vg)
continue
if e.other_face(f) not in g and len(e.faces)>=2:
- k = e.faces.index(f)
e.faces.remove(f)
e = Edge(e)
f.edges[j] = e
def split_smooth(self, progress = None):
self.split_vertices(self.find_smooth_group, progress)
- def split_uv(self, progress = None):
- self.split_vertices(self.find_uv_group, progress)
+ def split_uv(self, index, progress = None):
+ self.split_vertices(self.find_uv_group, progress, index)
def find_smooth_group(self, vertex, face):
face.flag = True
for f in queue:
for e in f.edges:
other = e.other_face(f)
- #if not other or other.index not in face_indices:
if other not in vertex.faces:
continue
return queue
- def find_uv_group(self, vertex, face):
- uv = face.uv[face.vertices.index(vertex)]
+ def find_uv_group(self, vertex, face, index):
+ uv = face.uvs[index][face.vertices.index(vertex)]
face.flag = True
group = [face]
for f in vertex.faces:
- if not f.flag and f.uv[f.vertices.index(vertex)]==uv:
+ if not f.flag and f.uvs[index][f.vertices.index(vertex)]==uv:
f.flag = True
group.append(f)
return group
if v.faces:
v.normal = mathutils.Vector()
for f in v.faces:
- v.normal += f.normal
+ fv = f.pivot_vertices(v)
+ edge1 = fv[1].co-fv[0].co
+ edge2 = fv[-1].co-fv[0].co
+ weight = 1
+ if len(f.get_edge(fv[0], fv[1]).faces)==1:
+ weight += 1
+ if len(f.get_edge(fv[0], fv[-1]).faces)==1:
+ weight += 1
+ v.normal += f.normal*edge1.angle(edge2)*weight
v.normal.normalize()
else:
# XXX Should use edges to compute normal
def compute_uv(self):
for v in self.vertices:
if v.faces:
- v.uv = v.faces[0].uv[v.faces[0].vertices.index(v)]
+ f = v.faces[0]
+ i = f.vertices.index(v)
+ v.uvs = [u[i] for u in f.uvs]
+
+ def compute_tbn(self, index):
+ if not self.uv_textures:
+ return
- def compute_tbn(self):
for v in self.vertices:
v.tan = mathutils.Vector()
v.bino = mathutils.Vector()
for f in v.faces:
- fv = f.pivot_vertices(False, v)
- v1 = fv[1]
- v2 = fv[-1]
- du1 = v1.uv[0]-v.uv[0]
- du2 = v2.uv[0]-v.uv[0]
- dv1 = v1.uv[1]-v.uv[1]
- dv2 = v2.uv[1]-v.uv[1]
- div = du1*dv2-du2*dv1
+ fv = f.pivot_vertices(v)
+ uv0 = fv[0].uvs[index]
+ uv1 = fv[1].uvs[index]
+ uv2 = fv[-1].uvs[index]
+ du1 = uv1[0]-uv0[0]
+ du2 = uv2[0]-uv0[0]
+ dv1 = uv1[1]-uv0[1]
+ dv2 = uv2[1]-uv0[1]
edge1 = fv[1].co-fv[0].co
edge2 = fv[-1].co-fv[0].co
+ div = (du1*dv2-du2*dv1)
if div:
- v.tan += (edge1*dv2-edge2*dv1)/div
- v.bino += (edge2*du1-edge1*du2)/div
+ mul = edge1.angle(edge2)/div
+ v.tan += (edge1*dv2-edge2*dv1)*mul
+ v.bino += (edge2*du1-edge1*du2)*mul
+
if v.tan.length:
v.tan.normalize()
if v.bino.length: