[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [3194] Moving LoopTools from trunk to contrib, as it is broken because of BMesh.

Bart Crouch bartius.crouch at gmail.com
Sat Mar 31 19:27:28 CEST 2012


Revision: 3194
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=3194
Author:   crouch
Date:     2012-03-31 17:27:21 +0000 (Sat, 31 Mar 2012)
Log Message:
-----------
Moving LoopTools from trunk to contrib, as it is broken because of BMesh.

I'm working on fixing it, but that won't be in time for next release. Therefore I'm moving it to contrib until I'm done fixing it.

Added Paths:
-----------
    contrib/py/scripts/addons/mesh_looptools.py

Removed Paths:
-------------
    trunk/py/scripts/addons/mesh_looptools.py

Copied: contrib/py/scripts/addons/mesh_looptools.py (from rev 3193, trunk/py/scripts/addons/mesh_looptools.py)
===================================================================
--- contrib/py/scripts/addons/mesh_looptools.py	                        (rev 0)
+++ contrib/py/scripts/addons/mesh_looptools.py	2012-03-31 17:27:21 UTC (rev 3194)
@@ -0,0 +1,3728 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+#  This program is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License
+#  as published by the Free Software Foundation; either version 2
+#  of the License, or (at your option) any later version.
+#
+#  This program is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+#  GNU General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software Foundation,
+#  Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+bl_info = {
+    'name': "LoopTools",
+    'author': "Bart Crouch",
+    'version': (3, 2, 4),
+    'blender': (2, 6, 2),
+    'location': "View3D > Toolbar and View3D > Specials (W-key)",
+    'warning': "Bridge & Loft functions removed",
+    'description': "Mesh modelling toolkit. Several tools to aid modelling",
+    'wiki_url': "http://wiki.blender.org/index.php/Extensions:2.5/Py/"\
+        "Scripts/Modeling/LoopTools",
+    'tracker_url': "http://projects.blender.org/tracker/index.php?"\
+        "func=detail&aid=26189",
+    'category': 'Mesh'}
+
+
+import bpy
+import mathutils
+import math
+
+
+##########################################
+####### General functions ################
+##########################################
+
+
+# used by all tools to improve speed on reruns
+looptools_cache = {}
+
+
+# force a full recalculation next time
+def cache_delete(tool):
+    if tool in looptools_cache:
+        del looptools_cache[tool]
+
+
+# check cache for stored information
+def cache_read(tool, object, mesh, input_method, boundaries):
+    # current tool not cached yet
+    if tool not in looptools_cache:
+        return(False, False, False, False, False)
+    # check if selected object didn't change
+    if object.name != looptools_cache[tool]["object"]:
+        return(False, False, False, False, False)
+    # check if input didn't change
+    if input_method != looptools_cache[tool]["input_method"]:
+        return(False, False, False, False, False)
+    if boundaries != looptools_cache[tool]["boundaries"]:
+        return(False, False, False, False, False)
+    modifiers = [mod.name for mod in object.modifiers if mod.show_viewport \
+        and mod.type == 'MIRROR']
+    if modifiers != looptools_cache[tool]["modifiers"]:
+        return(False, False, False, False, False)
+    input = [v.index for v in mesh.vertices if v.select and not v.hide]
+    if input != looptools_cache[tool]["input"]:
+        return(False, False, False, False, False)
+    # reading values
+    single_loops = looptools_cache[tool]["single_loops"]
+    loops = looptools_cache[tool]["loops"]
+    derived = looptools_cache[tool]["derived"]
+    mapping = looptools_cache[tool]["mapping"]
+    
+    return(True, single_loops, loops, derived, mapping)
+
+
+# store information in the cache
+def cache_write(tool, object, mesh, input_method, boundaries, single_loops,
+loops, derived, mapping):
+    # clear cache of current tool
+    if tool in looptools_cache:
+        del looptools_cache[tool]
+    # prepare values to be saved to cache
+    input = [v.index for v in mesh.vertices if v.select and not v.hide]
+    modifiers = [mod.name for mod in object.modifiers if mod.show_viewport \
+        and mod.type == 'MIRROR']
+    # update cache
+    looptools_cache[tool] = {"input": input, "object": object.name,
+        "input_method": input_method, "boundaries": boundaries,
+        "single_loops": single_loops, "loops": loops,
+        "derived": derived, "mapping": mapping, "modifiers": modifiers}
+
+
+# calculates natural cubic splines through all given knots
+def calculate_cubic_splines(mesh_mod, tknots, knots):
+    # hack for circular loops
+    if knots[0] == knots[-1] and len(knots) > 1:
+        circular = True
+        k_new1 = []
+        for k in range(-1, -5, -1):
+            if k - 1 < -len(knots):
+                k += len(knots)
+            k_new1.append(knots[k-1])
+        k_new2 = []
+        for k in range(4):
+            if k + 1 > len(knots) - 1:
+                k -= len(knots)
+            k_new2.append(knots[k+1])
+        for k in k_new1:
+            knots.insert(0, k)
+        for k in k_new2:
+            knots.append(k)
+        t_new1 = []
+        total1 = 0
+        for t in range(-1, -5, -1):
+            if t - 1 < -len(tknots):
+                t += len(tknots)
+            total1 += tknots[t] - tknots[t-1]
+            t_new1.append(tknots[0] - total1)
+        t_new2 = []
+        total2 = 0
+        for t in range(4):
+            if t + 1 > len(tknots) - 1:
+                t -= len(tknots)
+            total2 += tknots[t+1] - tknots[t]
+            t_new2.append(tknots[-1] + total2)
+        for t in t_new1:
+            tknots.insert(0, t)
+        for t in t_new2:
+            tknots.append(t)
+    else:
+        circular = False
+    # end of hack
+    
+    n = len(knots)
+    if n < 2:
+        return False
+    x = tknots[:]
+    locs = [mesh_mod.vertices[k].co[:] for k in knots]
+    result = []
+    for j in range(3):
+        a = []
+        for i in locs:
+            a.append(i[j])
+        h = []
+        for i in range(n-1):
+            if x[i+1] - x[i] == 0:
+                h.append(1e-8)
+            else:
+                h.append(x[i+1] - x[i])
+        q = [False]
+        for i in range(1, n-1):
+            q.append(3/h[i]*(a[i+1]-a[i]) - 3/h[i-1]*(a[i]-a[i-1]))
+        l = [1.0]
+        u = [0.0]
+        z = [0.0]
+        for i in range(1, n-1):
+            l.append(2*(x[i+1]-x[i-1]) - h[i-1]*u[i-1])
+            if l[i] == 0:
+                l[i] = 1e-8
+            u.append(h[i] / l[i])
+            z.append((q[i] - h[i-1] * z[i-1]) / l[i])
+        l.append(1.0)
+        z.append(0.0)
+        b = [False for i in range(n-1)]
+        c = [False for i in range(n)]
+        d = [False for i in range(n-1)]
+        c[n-1] = 0.0
+        for i in range(n-2, -1, -1):
+            c[i] = z[i] - u[i]*c[i+1]
+            b[i] = (a[i+1]-a[i])/h[i] - h[i]*(c[i+1]+2*c[i])/3
+            d[i] = (c[i+1]-c[i]) / (3*h[i])
+        for i in range(n-1):
+            result.append([a[i], b[i], c[i], d[i], x[i]])
+    splines = []
+    for i in range(len(knots)-1):
+        splines.append([result[i], result[i+n-1], result[i+(n-1)*2]])
+    if circular: # cleaning up after hack
+        knots = knots[4:-4]
+        tknots = tknots[4:-4]
+    
+    return(splines)
+
+
+# calculates linear splines through all given knots
+def calculate_linear_splines(mesh_mod, tknots, knots):
+    splines = []
+    for i in range(len(knots)-1):
+        a = mesh_mod.vertices[knots[i]].co
+        b = mesh_mod.vertices[knots[i+1]].co
+        d = b-a
+        t = tknots[i]
+        u = tknots[i+1]-t
+        splines.append([a, d, t, u]) # [locStart, locDif, tStart, tDif]
+    
+    return(splines)
+
+
+# calculate a best-fit plane to the given vertices
+def calculate_plane(mesh_mod, loop, method="best_fit", object=False):
+    # getting the vertex locations
+    locs = [mesh_mod.vertices[v].co.copy() for v in loop[0]]
+    
+    # calculating the center of masss
+    com = mathutils.Vector()
+    for loc in locs:
+        com += loc
+    com /= len(locs)
+    x, y, z = com
+    
+    if method == 'best_fit':
+        # creating the covariance matrix
+        mat = mathutils.Matrix(((0.0, 0.0, 0.0),
+                                (0.0, 0.0, 0.0),
+                                (0.0, 0.0, 0.0),
+                                ))
+        for loc in locs:
+            mat[0][0] += (loc[0]-x)**2
+            mat[1][0] += (loc[0]-x)*(loc[1]-y)
+            mat[2][0] += (loc[0]-x)*(loc[2]-z)
+            mat[0][1] += (loc[1]-y)*(loc[0]-x)
+            mat[1][1] += (loc[1]-y)**2
+            mat[2][1] += (loc[1]-y)*(loc[2]-z)
+            mat[0][2] += (loc[2]-z)*(loc[0]-x)
+            mat[1][2] += (loc[2]-z)*(loc[1]-y)
+            mat[2][2] += (loc[2]-z)**2
+        
+        # calculating the normal to the plane
+        normal = False
+        try:
+            mat.invert()
+        except:
+            if sum(mat[0]) == 0.0:
+                normal = mathutils.Vector((1.0, 0.0, 0.0))
+            elif sum(mat[1]) == 0.0:
+                normal = mathutils.Vector((0.0, 1.0, 0.0))
+            elif sum(mat[2]) == 0.0:
+                normal = mathutils.Vector((0.0, 0.0, 1.0))
+        if not normal:
+            # warning! this is different from .normalize()
+            itermax = 500
+            iter = 0
+            vec = mathutils.Vector((1.0, 1.0, 1.0))
+            vec2 = (mat * vec)/(mat * vec).length
+            while vec != vec2 and iter<itermax:
+                iter+=1
+                vec = vec2
+                vec2 = mat * vec
+                if vec2.length != 0:
+                    vec2 /= vec2.length
+            if vec2.length == 0:
+                vec2 = mathutils.Vector((1.0, 1.0, 1.0))
+            normal = vec2
+    
+    elif method == 'normal':
+        # averaging the vertex normals
+        v_normals = [mesh_mod.vertices[v].normal for v in loop[0]]
+        normal = mathutils.Vector()
+        for v_normal in v_normals:
+            normal += v_normal
+        normal /= len(v_normals)
+        normal.normalize()
+        
+    elif method == 'view':
+        # calculate view normal
+        rotation = bpy.context.space_data.region_3d.view_matrix.to_3x3().\
+            inverted()
+        normal = rotation * mathutils.Vector((0.0, 0.0, 1.0))
+        if object:
+            normal = object.matrix_world.inverted().to_euler().to_matrix() * \
+                     normal
+    
+    return(com, normal)
+
+
+# calculate splines based on given interpolation method (controller function)
+def calculate_splines(interpolation, mesh_mod, tknots, knots):
+    if interpolation == 'cubic':

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-extensions-cvs mailing list