[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