~jtaylor/ubuntu/oneiric/soya/fix-780305

« back to all changes in this revision

Viewing changes to facecutter.py

  • Committer: Bazaar Package Importer
  • Author(s): Marc Dequènes (Duck)
  • Date: 2005-01-30 09:55:06 UTC
  • mfrom: (1.2.1 upstream) (2.1.1 hoary)
  • Revision ID: james.westby@ubuntu.com-20050130095506-f21p6v6cgaobhn5j
Tags: 0.9.2-1
New upstream release.

Show diffs side-by-side

added added

removed removed

Lines of Context:
15
15
# along with this program; if not, write to the Free Software
16
16
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
17
17
 
18
 
"""soya.facecutter
 
18
"""soya.facecutter -- A model beautifier
19
19
 
20
20
Cuts some faces in two (or more), in order to get smoother shape."""
21
21
 
22
 
import soya, soya.soya3d as soya3d, soya.model as model
23
 
from soya.math3d import *
 
22
import soya
 
23
from soya import Point, Vector
24
24
 
25
25
import bisect, copy
26
26
 
49
49
  
50
50
  edge_sizes = []
51
51
  def index_face(face):
52
 
    if face.smooth_lit: face.compute_normal() # Normal may be needed later (for smooth_lit faces)
53
52
    for vertex in face: index_vertex(vertex)
54
53
    index_edges(face)
55
54
  def index_edges(face):
64
63
  def add_triangle(face, a, b, c):
65
64
    triangle = copy.deepcopy(face)
66
65
    face.parent.add(triangle)
67
 
    triangle.vertices *= 0
 
66
    while triangle.vertices: del triangle.vertices[0]
68
67
    triangle.append(a); triangle.append(b); triangle.append(c)
69
68
    index_face(triangle)
70
69
    return triangle
71
70
  def add_quad(face, a, b, c, d):
72
71
    quad = copy.deepcopy(face)
73
72
    face.parent.add(quad)
74
 
    quad.vertices *= 0
 
73
    while quad.vertices: del quad.vertices[0]
75
74
    quad.append(a); quad.append(b); quad.append(c); quad.append(d)
76
75
    index_face(quad)
77
76
    return quad
173
172
    
174
173
    
175
174
  # Index faces and vertices
176
 
  faces = filter(lambda face: isinstance(face, model.Face) and (len(face.vertices) in (3, 4)) and (not face.is_morphable()), world.recursive())
 
175
  faces = filter(lambda face: isinstance(face, soya.Face) and (len(face.vertices) in (3, 4)), world.recursive())
177
176
  
178
177
  for face in faces:
179
 
    if face.smooth_lit: face.compute_normal() # Normal may be needed later (for smooth_lit faces)
 
178
    #if face.smooth_lit: face.compute_normal() # Normal may be needed later (for smooth_lit faces)
180
179
    for vertex in face: index_vertex(vertex)
181
180
    
182
181
  for face in faces: index_edges(face)
197
196
      b_normal = normal_at_vertex(b)
198
197
      
199
198
      h_normal = a_normal + b_normal
200
 
      h.add_mul_vector((1.0 - h_normal.length() / 2.0) * add_relief, h_normal)
 
199
      
 
200
      f = (1.0 / h_normal.length() - 0.5) * add_relief * a.distance_to(b)
 
201
      h_normal.normalize()
 
202
      h.add_mul_vector(f, h_normal)
 
203
      
 
204
      # Old (0.6.1) formula
 
205
      #h.add_mul_vector((1.0 - h_normal.length() / 2.0) * add_relief, h_normal)
201
206
      
202
207
    for face, a, b in edges:
203
208
      if face.parent:
230
235
  aa.tex_x = f_ * a.tex_x + f * b.tex_x
231
236
  aa.tex_y = f_ * a.tex_y + f * b.tex_y
232
237
  if not((a.color is None) and (b.color is None)):
233
 
    aa.color = tuple(map(lambda a, b: f_ * a + f * b, a.color or model.WHITE, b.color or model.WHITE))
 
238
    aa.color = tuple(map(lambda a, b: f_ * a + f * b, a.color or soya.WHITE, b.color or soya.WHITE))
234
239
  aa.parent = a.parent
235
240
  return aa
236
241
 
239
244
def check_quads(world, threshold = 0.00001):
240
245
  """check_quads(world) -> int
241
246
 
242
 
Checks if all quads (recursively) in WORLD are coplanar. Non coplanar quads are splitted
243
 
in 2 triangles.
 
247
Checks (recursively) if all quad's vertices in WORLD are coplanar.
 
248
Non coplanar quads are splitted in 2 triangles.
244
249
Returns the number of splits."""
245
250
  
246
251
  nb = 0
247
252
  
248
253
  for face in world.recursive():
249
 
    if isinstance(face, model.Face) and (len(face.vertices) == 4):
250
 
      n1 = soya.points_normal(face.vertices[0], face.vertices[1], face.vertices[2])
251
 
      n2 = soya.points_normal(face.vertices[0], face.vertices[1], face.vertices[3])
252
 
      
253
 
      if (n1.x - n2.x) ** 2 + (n1.y - n2.y) ** 2 + (n1.z - n2.z) ** 2 > threshold:
254
 
        nb += 1
255
 
        
256
 
        t1 = copy.deepcopy(face)
257
 
        face.parent.add(t1)
258
 
        t1.vertices *= 0
259
 
        t1.append(clone(face.vertices[0]))
260
 
        t1.append(clone(face.vertices[1]))
261
 
        t1.append(clone(face.vertices[2]))
262
 
        
263
 
        t2 = copy.deepcopy(face)
264
 
        face.parent.add(t2)
265
 
        t2.vertices *= 0
266
 
        t2.append(clone(face.vertices[2]))
267
 
        t2.append(clone(face.vertices[3]))
268
 
        t2.append(clone(face.vertices[0]))
269
 
        
270
 
        face.parent.remove(face)
 
254
    if isinstance(face, soya.Face) and (not face.is_coplanar()):
 
255
      nb += 1
 
256
      
 
257
      clone = copy.deepcopy(face)
 
258
      face.parent.add(clone)
 
259
      
 
260
      # Cut so as the new edge is the shortest possible one (OpenGL often does a better texture interpolation in this case)
 
261
      if face.vertices[0].distance_to(face.vertices[2]) < face.vertices[1].distance_to(face.vertices[3]):
 
262
        del clone.vertices[1]
 
263
        del face .vertices[3]
 
264
      else:
 
265
        del clone.vertices[0]
 
266
        del face .vertices[2]
271
267
        
272
268
  return nb