[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [591] trunk/py/scripts/addons/ add_mesh_gears.py: * Gears Version 2.3

Martin Buerbaum martin.buerbaum at gmx.at
Fri Apr 16 12:29:41 CEST 2010


Revision: 591
          http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-extensions&revision=591
Author:   pontiac
Date:     2010-04-16 12:29:39 +0200 (Fri, 16 Apr 2010)

Log Message:
-----------
* Gears Version 2.3
* Major refractor - removed most of the hardcoded stuff.
* Separated functions into gear, worm gear (and experimental/non-working spokes)
* "Gear" now doesn't have any duplicate vartices.
* New submenu "Gears" (entries "Gear" and "Worm Gear")
* TODO: Prevent doubles in "Worm Gear" (change it so only one row of verts is calculated for each step)
* TODO: Finish/improve spokes code ("add_spokes").
* TODO: Create new "auto-spokes" function that addes a "Gear Spokes" Object for an existing "Gears" obj (either via the "recall" data - this stuff is usefull :-) or by creating 2 objects at the same time.)

Modified Paths:
--------------
    trunk/py/scripts/addons/add_mesh_gears.py

Modified: trunk/py/scripts/addons/add_mesh_gears.py
===================================================================
--- trunk/py/scripts/addons/add_mesh_gears.py	2010-04-16 07:35:56 UTC (rev 590)
+++ trunk/py/scripts/addons/add_mesh_gears.py	2010-04-16 10:29:39 UTC (rev 591)
@@ -23,9 +23,9 @@
 bl_addon_info = {
     'name': 'Add Mesh: Gears',
     'author': 'Michel J. Anders (varkenvarken)',
-    'version': '2.2',
+    'version': '2.3',
     'blender': (2, 5, 3),
-    'location': 'View3D > Add > Mesh ',
+    'location': 'View3D > Add > Mesh > Gears ',
     'description': 'Adds a mesh Gear to the Add Mesh menu',
     'url': 'http://wiki.blender.org/index.php/Extensions:2.5/Py/' \
         'Scripts/Add_Mesh/Add_Gear',
@@ -35,7 +35,7 @@
 What was needed to port it from 2.49 -> 2.50 alpha 0?
 
 The basic functions that calculate the geometry (verts and faces) are mostly
-unchanged (add_tooth, add_spoke2, add_gear)
+unchanged (add_tooth, add_spoke, add_gear)
 
 Also, the vertex group API is changed a little bit but the concepts
 are the same:
@@ -67,28 +67,6 @@
 
 The code to actually implement the AddGear() function is mostly copied from
 add_mesh_torus() (distributed with Blender).
-
-Unresolved issues:
-
-- Removing doubles:
-    The algorithm should not generate a full section to begin with.
-    At least the last 4 vertices don't need to be created, because the
-    next section will have them as their first 4 vertices anyway.
-    OLD COMMENT ON DOUBLES:
-    "The code that produces the teeth of the gears produces some duplicate
-    vertices. The original script just called remove_doubles() but if we
-    do that in 2.50 we have a problem.
-    To apply the bpy.ops.mesh.remove_doubles() operator we have to change
-    to edit mode. The moment we do that we loose to possibilty to
-    interactively change the properties.
-    Also changing back to object mode raises a strange exception (to
-    investigate). So for now, removing doubles is left to the user
-    once satisfied with the chosen setting for a gear."
-
-- No suitable icon:
-    A rather minor point but I reused the torus icon for the add->mesh->gear
-    menu entry as there doesn't seem to be a generic mesh icon or a way to
-    add custom icons. Too bad, but as this is just eye candy it's no big deal.
 """
 
 import bpy
@@ -97,41 +75,7 @@
 from copy import deepcopy
 from bpy.props import *
 
-# Constants
-FACES = [
-    [0, 5, 6, 1],
-    [1, 6, 7, 2],
-    [2, 7, 8, 3],
-    [3, 8, 9, 4],
-    [6, 10, 11, 7],
-    [7, 11, 12, 8],
-    [10, 13, 14, 11],
-    [11, 14, 15, 12]]
 
-VERT_NUM = 16   # Number of vertices
-
-# Edgefaces
-EDGEFACES = [5, 6, 10, 13, 14, 15, 12, 8, 9]
-EDGEFACES2 = [i + VERT_NUM for i in EDGEFACES]  # i.e. Indices are offset by 16
-
-# In python 3, zip() returns a zip object so we have to force the
-# result into a list of lists to keep deepcopy happy later on in the script.
-EFC = [[i, j, k, l] for i, j, k, l
-    in zip(EDGEFACES[:-1], EDGEFACES2[:-1], EDGEFACES2[1:], EDGEFACES[1:])]
-VERTS_TOOTH = [13, 14, 15, 29, 30, 31]        # Vertices on a tooth
-VERTS_VALLEY = [5, 6, 8, 9, 21, 22, 24, 25]   # Vertices in a valley
-
-#SPOKEFACES = (
-#    (0, 1, 2, 5),
-#    (2, 3, 4, 7),
-#    (5, 2, 7, 6),
-#    (5, 6, 9, 8),
-#    (6, 7, 10, 9),
-#    (11, 8, 13, 12),
-#    (8, 9, 10, 13),
-#    (13, 10, 15, 14))
-
-
 # Stores the values of a list of properties and the
 # operator id in a property group ('recall_op') inside the object.
 # Could (in theory) be used for non-objects.
@@ -256,6 +200,54 @@
     return ob_new
 
 
+# A very simple "bridge" tool.
+# Connects two equally long vertex rows with faces.
+# Returns a list of the new faces (list of lists)
+#
+# vertIdx1 ... First vertex list (list of vertex indices).
+# vertIdx2 ... Second vertex list (list of vertex indices).
+# closed ... Creates a loop (first & last are closed).
+# flipped ... Invert the normal of the face(s).
+def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False):
+    faces = []
+
+    if (len(vertIdx1) != len(vertIdx2)) or (len(vertIdx1) < 2):
+        return None
+
+    total = len(vertIdx1)
+
+    if closed:
+        # Bridge the start with the end.
+        if flipped:
+            faces.append([vertIdx1[0], vertIdx2[0],
+                vertIdx2[total - 1], vertIdx1[total - 1]])
+        else:
+            faces.append([vertIdx2[0], vertIdx1[0],
+                vertIdx1[total - 1], vertIdx2[total - 1]])
+
+    # Bridge the rest of the faces.
+    for num in range(total - 1):
+        if flipped:
+            faces.append([vertIdx2[num], vertIdx1[num],
+                vertIdx1[num + 1], vertIdx2[num + 1]])
+        else:
+            faces.append([vertIdx1[num], vertIdx2[num],
+                vertIdx2[num + 1], vertIdx1[num + 1]])
+
+    return faces
+
+
+# Calculate the vertex coordinates for a single
+# section of a gear tooth.
+# Returns 4 lists of vertex coords (list of tuples):
+#  *-*---*---*	(1.) verts_inner_base
+#  | |   |   |
+#  *-*---*---*	(2.) verts_outer_base
+#    |   |   |
+#    *---*---*	(3.) verts_middle_tooth
+#     \  |  /
+#      *-*-*	(4.) verts_tip_tooth
+#
 # a
 # t
 # d
@@ -267,13 +259,7 @@
 # rack
 # crown
 def add_tooth(a, t, d, radius, Ad, De, base, p_angle, rack=0, crown=0.0):
-    """
-    private function: calculate the vertex coords for a single side
-    section of a gear tooth.
-    Returns them as a list of tuples.
-    """
-
-    A = [a, a + t / 4, a + t / 2, a + 3 * t / 4, a + t]
+    A = [a, a + t / 4, a + t / 2, a + 3 * t / 4]
     C = [cos(i) for i in A]
     S = [sin(i) for i in A]
 
@@ -292,10 +278,10 @@
         S = [sin(t / 4) * I for I in range(-2, 3)]
         Sp = [0, sin(-t / 4 + p_angle), 0, sin(t / 4 - p_angle)]
 
-        verts = [(Rb, radius * S[I], d) for I in range(5)]
-        verts.extend([(Rd, radius * S[I], d) for I in range(5)])
-        verts.extend([(radius, radius * S[I], d) for I in range(1, 4)])
-        verts.extend([(Ra, radius * Sp[I], d) for I in range(1, 4)])
+        verts_inner_base = [(Rb, radius * S[I], d) for I in range(4)]
+        verts_outer_base = [(Rd, radius * S[I], d) for I in range(4)]
+        verts_middle_tooth = [(radius, radius * S[I], d) for I in range(1, 4)]
+        verts_tip_tooth = [(Ra, radius * Sp[I], d) for I in range(1, 4)]
 
     else:
         Cp = [
@@ -308,17 +294,23 @@
             sin(a + t / 2),
             sin(a + 3 * t / 4 - p_angle)]
 
-        verts = [(Rb * C[I], Rb * S[I], d)
-            for I in range(5)]
-        verts.extend([(Rd * C[I], Rd * S[I], d) for I in range(5)])
-        verts.extend([(radius * C[I], radius * S[I], d + crown / 3)
-            for I in range(1, 4)])
-        verts.extend([(Ra * Cp[I], Ra * Sp[I], d + crown)
-            for I in range(1, 4)])
+        verts_inner_base = [(Rb * C[I], Rb * S[I], d)
+            for I in range(4)]
+        verts_outer_base = [(Rd * C[I], Rd * S[I], d)
+            for I in range(4)]
+        verts_middle_tooth = [(radius * C[I], radius * S[I], d + crown / 3)
+            for I in range(1, 4)]
+        verts_tip_tooth = [(Ra * Cp[I], Ra * Sp[I], d + crown)
+            for I in range(1, 4)]
 
-    return verts
+    return (verts_inner_base, verts_outer_base,
+        verts_middle_tooth, verts_tip_tooth)
 
 
+# EXPERIMENTAL Calculate the vertex coordinates for a single
+# section of a gearspoke.
+# Returns them as a list of tuples.
+#
 # a
 # t
 # d
@@ -330,13 +322,9 @@
 # l
 # gap
 # width
-def add_spoke2(a, t, d, radius, De, base, s, w, l, gap=0, width=19):
-    """
-    EXPERIMENTAL private function: calculate the vertex coords for
-    a single side section of a gearspoke.
-    Returns them as a list of lists.
-    """
-
+#
+# @todo Finish this.
+def add_spoke(a, t, d, radius, De, base, s, w, l, gap=0, width=19):
     Rd = radius - De
     Rb = Rd - base
     Rl = Rb
@@ -348,7 +336,7 @@
 
     if not gap:
         for N in range(width, 1, -2):
-            edgefaces.append(len(v))
+            edgefaces.append(len(verts))
             ts = t / 4
             tm = a + 2 * ts
             te = asin(w / Rb)
@@ -359,7 +347,7 @@
             S = [sin(i) for i in A]
 
             verts.extend([(Rb * I, Rb * J, d) for (I, J) in zip(C, S)])
-            edgefaces2.append(len(v) - 1)
+            edgefaces2.append(len(verts) - 1)
 
             Rb = Rb - s
 
@@ -372,17 +360,233 @@
 
             n = n + N
 
-    return v, edgefaces, edgefaces2, sf
+    return verts, edgefaces, edgefaces2, sf
 
 
 # Create gear geometry.
 # Returns:
+# * A list of vertices (list of tuples)
+# * A list of faces (list of lists)
+# * A list (group) of vertices of the tip (list of vertex indices).
+# * A list (group) of vertices of the valley (list of vertex indices).
+#
+# teethNum ... Number of teeth on the gear.
+# radius ... Radius of the gear, negative for crown gear
+# Ad ... Addendum, extent of tooth above radius.
+# De ... Dedendum, extent of tooth below radius.
+# base ... Base, extent of gear below radius.
+# p_angle ... Pressure angle. Skewness of tooth tip. (radiant)
+# width ... Width, thickness of gear.
+# skew ... Skew of teeth. (radiant)
+# conangle ... Conical angle of gear. (radiant)
+# rack
+# crown ... Inward pointing extend of crown teeth.
+#
+# inner radius = radius - (De + base)
+def add_gear(teethNum, radius, Ad, De, base, p_angle,
+    width=1, skew=0, conangle=0, rack=0, crown=0.0):
+
+    if teethNum < 2:
+        return None, None, None, None
+
+    t = 2 * pi / teethNum
+
+    if rack:
+        teethNum = 1
+
+    scale = (radius - 2 * width * tan(conangle)) / radius
+
+    verts = []
+    faces = []
+    vgroup_top = []  # Vertex group of top/tip? vertices.
+    vgroup_valley = []  # Vertex group of valley vertices
+
+    verts_bridge_prev = []
+    for toothCnt in range(teethNum):
+        a = toothCnt * t
+
+        verts_bridge_start = []
+        verts_bridge_end = []
+
+        verts_outside_top = []
+        verts_outside_bottom = []
+        for (s, d, c, top) \
+            in [(0, -width, 1, True), \
+            (skew, width, scale, False)]:
+
+            verts1, verts2, verts3, verts4 = add_tooth(a + s, t, d,
+                radius * c, Ad * c, De * c, base * c, p_angle,
+                rack, crown)
+
+            vertsIdx1 = list(range(len(verts), len(verts) + len(verts1)))
+            verts.extend(verts1)
+            vertsIdx2 = list(range(len(verts), len(verts) + len(verts2)))
+            verts.extend(verts2)
+            vertsIdx3 = list(range(len(verts), len(verts) + len(verts3)))

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-extensions-cvs mailing list