[Bf-extensions-cvs] SVN commit: /data/svn/bf-extensions [1920] contrib/py/scripts/addons/ add_mesh_column.py: New script version 0.01 initial test.

Jim Bates jsbates at pacbell.net
Sat May 14 14:31:56 CEST 2011


Revision: 1920
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-extensions&revision=1920
Author:   jambay
Date:     2011-05-14 12:31:55 +0000 (Sat, 14 May 2011)
Log Message:
-----------
New script version 0.01 initial test.

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

Added: contrib/py/scripts/addons/add_mesh_column.py
===================================================================
--- contrib/py/scripts/addons/add_mesh_column.py	                        (rev 0)
+++ contrib/py/scripts/addons/add_mesh_column.py	2011-05-14 12:31:55 UTC (rev 1920)
@@ -0,0 +1,448 @@
+#
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This program is free software; you may 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
+#
+# or go online at: http://www.gnu.org/licenses/ to view license options.
+#
+# ***** END GPL LICENCE BLOCK *****
+#
+
+bl_info = {
+    "name": "Columns",
+    "author": "Jim Bates, jambay",
+    "version": (0, 1),
+    "blender": (2, 5, 7),
+    "api": 36339,
+    "location": "View3D > Add > Mesh > Columns",
+    "description": "Add architectural column(s).",
+    "warning": "WIP - Initial implementation; updates pending and API not final for Blender",
+    "wiki_url": "",
+    "tracker_url": "",
+    "category": "Add Mesh"
+}
+
+"""
+
+Create a column for use as an architectural element in a scene. Basically a glorified cylinder/cube.
+
+A column consists of three elements; base, shaft, and capital. They can be square or round, straight or tapered. The base and capital are optional.
+
+The shaft may be fluted and twisted.
+
+Only one column is created, at the current 3D cursor, expecting the user to duplicate and place as needed.
+
+This script is based on features from add_mesh_gears.
+
+"""
+
+# Version History
+# v0.01 2011/05/13	Initial implementation.
+
+
+import bpy
+import mathutils
+from math import *
+from bpy.props import *
+
+# 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).
+#
+# Note: You can set vertIdx1 to a single vertex index to create
+#       a fan/star of faces.
+# Note: If both vertex idx list are the same length they have
+#       to have at least 2 vertices.
+def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False):
+    faces = []
+
+    if not vertIdx1 or not vertIdx2:
+        return None
+
+    if len(vertIdx1) < 2 and len(vertIdx2) < 2:
+        return None
+
+    fan = False
+    if (len(vertIdx1) != len(vertIdx2)):
+        if (len(vertIdx1) == 1 and len(vertIdx2) > 1):
+            fan = True
+        else:
+            return None
+
+    total = len(vertIdx2)
+
+    if closed:
+        # Bridge the start with the end.
+        if flipped:
+            face = [
+                vertIdx1[0],
+                vertIdx2[0],
+                vertIdx2[total - 1]]
+            if not fan:
+                face.append(vertIdx1[total - 1])
+            faces.append(face)
+
+        else:
+            face = [vertIdx2[0], vertIdx1[0]]
+            if not fan:
+                face.append(vertIdx1[total - 1])
+            face.append(vertIdx2[total - 1])
+            faces.append(face)
+
+    # Bridge the rest of the faces.
+    for num in range(total - 1):
+        if flipped:
+            if fan:
+                face = [vertIdx2[num], vertIdx1[0], vertIdx2[num + 1]]
+            else:
+                face = [vertIdx2[num], vertIdx1[num],
+                    vertIdx1[num + 1], vertIdx2[num + 1]]
+            faces.append(face)
+        else:
+            if fan:
+                face = [vertIdx1[0], vertIdx2[num], vertIdx2[num + 1]]
+            else:
+                face = [vertIdx1[num], vertIdx2[num],
+                    vertIdx2[num + 1], vertIdx1[num + 1]]
+            faces.append(face)
+
+    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
+# radius
+# Ad
+# De
+# base
+# p_angle
+# rack
+# crown
+def add_tooth(a, t, d, radius, Ad, De, base, p_angle, rack=0, crown=0.0):
+    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]
+
+    Ra = radius + Ad
+    Rd = radius - De
+    Rb = Rd - base
+
+    # Pressure angle calc
+    O = Ad * tan(p_angle)
+    if Ra: # prevent div 0 error - useless parameter...
+        p_angle = atan(O / Ra)
+
+    if radius < 0:
+        p_angle = -p_angle
+
+    if rack:
+        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_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 = [
+            0,
+            cos(a + t / 4 + p_angle),
+            cos(a + t / 2),
+            cos(a + 3 * t / 4 - p_angle)]
+        Sp = [0,
+            sin(a + t / 4 + p_angle),
+            sin(a + t / 2),
+            sin(a + 3 * t / 4 - p_angle)]
+
+        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_inner_base, verts_outer_base, verts_middle_tooth, verts_tip_tooth)
+
+
+# Create column geometry.
+# Returns:
+# * A list of vertices
+# * A list of faces
+# * A list (group) of vertices of the tip
+# * A list (group) of vertices of the valley
+#
+#     radius	area of the column, negative for flutes (else extrusions).
+#     sectors	surfaces (faces) on column, 1 = square, increase to smooth, max 360, 180 is plenty.
+#     segNum	number of segments (rows - vertical blocks) for column. Use +1 to complete row (2 is working min).
+#     flutes	make curfs, gouges, gear like indents... true/false.
+# Ad ... Addendum, extent of tooth above radius.
+# De ... Dedendum, extent of tooth below radius.
+# width ... Width, thickness of flute.
+# crown ... Inward pointing extend of crown teeth.
+#
+# @todo: Fix teethNum. Some numbers are not possible yet.
+# @todo: Create start & end geoemetry (closing faces)
+def add_column(radius, sectors, segNum, flutes, Ad, De, p_angle, width, skew, crown):
+
+    numFlutes = 0
+    isFluted = False
+
+    t = 2 * pi / sectors # sectors == 1 makes a square
+
+    verts = []
+    faces = []
+    vgroup_top = []  # Vertex group of top/tip? vertices.
+    vgroup_valley = []  # Vertex group of valley vertices
+
+    #width = width / 2.0
+
+    edgeloop_prev = []
+    for Row in range(segNum):
+        edgeloop = []
+
+        for faceCnt in range(sectors):
+            a = faceCnt * t
+
+            s = Row * skew
+            d = Row * width
+
+            if flutes and not numFlutes % sectors: # making "flutes", and due a flute?
+                numFlutes + 1
+                isFluted = True
+
+                verts1, verts2, verts3, verts4 = add_tooth(a + s, t, d,
+                    radius, Ad, De, 0, 0, 0, crown)
+
+                # Remove various unneeded verts (if we are "inside" the tooth)
+                del(verts2[2])  # Central vertex in the base of the tooth.
+                del(verts3[1])  # Central vertex in the middle of the tooth.
+
+            else: # column surface for section...
+                isFluted = False
+                verts1, verts2, verts3, verts4 = add_tooth(a + s, t, d,
+                    radius - De, 0.0, 0.0, 0, p_angle)
+
+                # Ignore other verts than the "other base".
+                verts1 = verts3 = verts4 = []
+
+            vertsIdx2 = list(range(len(verts), len(verts) + len(verts2)))
+            verts.extend(verts2)
+            vertsIdx3 = list(range(len(verts), len(verts) + len(verts3)))
+            verts.extend(verts3)
+            vertsIdx4 = list(range(len(verts), len(verts) + len(verts4)))
+            verts.extend(verts4)
+
+            if isFluted:
+                verts_current = []
+                verts_current.extend(vertsIdx2[:2])
+                verts_current.append(vertsIdx3[0])
+                verts_current.extend(vertsIdx4)
+                verts_current.append(vertsIdx3[-1])
+                verts_current.append(vertsIdx2[-1])
+
+                # Valley = first 2 vertices of outer base:
+                vgroup_valley.extend(vertsIdx2[:1])
+                # Top/tip vertices:
+                vgroup_top.extend(vertsIdx4)
+
+            else: # Flat
+                verts_current = vertsIdx2
+                vgroup_valley.extend(vertsIdx2) # Valley - all of them
+
+            edgeloop.extend(verts_current)
+
+        # Create faces between rings/rows.
+        if edgeloop_prev:
+            faces_row = createFaces(edgeloop, edgeloop_prev, closed=True)
+            faces.extend(faces_row)
+
+        # Remember last ring/row of vertices for next ring/row iteration.
+        edgeloop_prev = edgeloop
+
+    return verts, faces, vgroup_top, vgroup_valley
+
+
+class AddColumn(bpy.types.Operator):
+    '''Add a column mesh.'''
+    bl_idname = "mesh.primitive_column"
+    bl_label = "Add Column"
+    bl_options = {'REGISTER', 'UNDO'}
+
+    radius = FloatProperty(name="Radius",
+        description="Radius of the column",
+        min=0.01,
+        max=100.0,
+        default=0.5)
+    column_segs = IntProperty(name="Segments",
+        description="Number of segments (faces) in the column",
+        min=1,

@@ Diff output truncated at 10240 characters. @@


More information about the Bf-extensions-cvs mailing list