diff options
author | Brendon Murphy <meta.androcto1@gmail.com> | 2014-08-04 18:31:22 +0400 |
---|---|---|
committer | Brendon Murphy <meta.androcto1@gmail.com> | 2014-08-04 18:31:22 +0400 |
commit | 263763f2d120000c9d75777afe299418335b4adb (patch) | |
tree | 378df844b21ec5cd8a154c70454140471ec758ac /add_mesh_extra_objects | |
parent | c2d1f06c06097965abdb00bcda557704d917dd19 (diff) |
updates & cleanup, merged pipe joints & solid objects, cleaner integration into shift/a
Diffstat (limited to 'add_mesh_extra_objects')
-rw-r--r-- | add_mesh_extra_objects/__init__.py | 79 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_3d_function_surface.py | 8 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_extra_objects.py | 1 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_gears.py | 21 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_gemstones.py | 14 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_honeycomb.py | 13 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_pipe_joint.py | 992 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_polysphere.py | 8 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_solid.py | 502 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_supertoroid.py | 22 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_teapot.py | 35 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_torusknot.py | 30 | ||||
-rw-r--r-- | add_mesh_extra_objects/add_mesh_twisted_torus.py | 23 |
13 files changed, 1550 insertions, 198 deletions
diff --git a/add_mesh_extra_objects/__init__.py b/add_mesh_extra_objects/__init__.py index 47bb1c1f..9c35a1b7 100644 --- a/add_mesh_extra_objects/__init__.py +++ b/add_mesh_extra_objects/__init__.py @@ -21,8 +21,8 @@ bl_info = { "name": "Extra Objects", "author": "Multiple Authors", - "version": (0, 3), - "blender": (2, 63, 0), + "version": (0, 3, 0), + "blender": (2, 71, 0), "location": "View3D > Add > Mesh > Extra Objects", "description": "Add extra object types", "warning": "", @@ -31,7 +31,6 @@ bl_info = { "category": "Add Mesh", } - if "bpy" in locals(): import imp imp.reload(add_mesh_extra_objects) @@ -45,6 +44,10 @@ if "bpy" in locals(): imp.reload(add_mesh_torusknot) imp.reload(add_mesh_honeycomb) imp.reload(add_mesh_teapot) + imp.reload(add_mesh_pipe_joint) + imp.reload(add_mesh_teapot) + imp.reload(add_mesh_solid) + else: from . import add_mesh_extra_objects from . import add_mesh_twisted_torus @@ -57,37 +60,11 @@ else: from . import add_mesh_torusknot from . import add_mesh_honeycomb from . import add_mesh_teapot -import bpy - - -class INFO_MT_mesh_extras_add(bpy.types.Menu): - # Define the "Extras" menu - bl_idname = "INFO_MT_mesh_extra_objects_add" - bl_label = "Extra Objects" - - def draw(self, context): - layout = self.layout - layout.operator_context = 'INVOKE_REGION_WIN' - layout.menu("INFO_MT_mesh_gemstones_add", text="Gemstones") - layout.menu("INFO_MT_mesh_gears_add", text="Gears") - layout.menu("INFO_MT_mesh_math_add", text="Math Function") - layout.menu("INFO_MT_mesh_basic_add", text="Basic Objects") - layout.menu("INFO_MT_mesh_torus_add", text="Torus Objects") - layout.menu("INFO_MT_mesh_misc_add", text="Misc Objects") - -class INFO_MT_mesh_gemstones_add(bpy.types.Menu): - # Define the "Gemstones" menu - bl_idname = "INFO_MT_mesh_gemstones_add" - bl_label = "Gemstones" - - def draw(self, context): - layout = self.layout - layout.operator_context = 'INVOKE_REGION_WIN' - layout.operator("mesh.primitive_diamond_add", - text="Diamond") - layout.operator("mesh.primitive_gem_add", - text="Gem") + from . import add_mesh_pipe_joint + from . import add_mesh_teapot + from . import add_mesh_solid +import bpy class INFO_MT_mesh_gears_add(bpy.types.Menu): # Define the "Gears" menu @@ -114,6 +91,7 @@ class INFO_MT_mesh_math_add(bpy.types.Menu): text="Z Math Surface") layout.operator("mesh.primitive_xyz_function_surface", text="XYZ Math Surface") + self.layout.operator("mesh.primitive_solid_add", text="Solid") class INFO_MT_mesh_basic_add(bpy.types.Menu): # Define the "Simple Objects" menu @@ -123,6 +101,10 @@ class INFO_MT_mesh_basic_add(bpy.types.Menu): def draw(self, context): layout = self.layout layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator("mesh.primitive_diamond_add", + text="Diamond") + layout.operator("mesh.primitive_gem_add", + text="Gem") layout.operator("mesh.primitive_sqorus_add", text="Sqorus") layout.operator("mesh.primitive_wedge_add") @@ -130,8 +112,6 @@ class INFO_MT_mesh_basic_add(bpy.types.Menu): text="Star") layout.operator("mesh.primitive_trapezohedron_add", text="Trapezohedron") - layout.operator("mesh.primitive_polysphere_add", - text="Polysphere") class INFO_MT_mesh_torus_add(bpy.types.Menu): # Define the "Simple Objects" menu @@ -162,11 +142,37 @@ class INFO_MT_mesh_misc_add(bpy.types.Menu): text="Honeycomb") layout.operator("mesh.primitive_teapot_add", text="Teapot+") + +class INFO_MT_mesh_pipe_joints_add(bpy.types.Menu): + # Define the "Pipe Joints" menu + bl_idname = "INFO_MT_mesh_pipe_joints_add" + bl_label = "Pipe Joints" + + def draw(self, context): + layout = self.layout + layout.operator_context = 'INVOKE_REGION_WIN' + layout.operator("mesh.primitive_elbow_joint_add", + text="Pipe Elbow") + layout.operator("mesh.primitive_tee_joint_add", + text="Pipe T-Joint") + layout.operator("mesh.primitive_wye_joint_add", + text="Pipe Y-Joint") + layout.operator("mesh.primitive_cross_joint_add", + text="Pipe Cross-Joint") + layout.operator("mesh.primitive_n_joint_add", + text="Pipe N-Joint") + # Register all operators and panels # Define "Extras" menu def menu_func(self, context): - self.layout.menu("INFO_MT_mesh_extra_objects_add", icon="PLUGIN") + self.layout.operator("mesh.primitive_polysphere_add", text="Polysphere") + self.layout.menu("INFO_MT_mesh_pipe_joints_add", text="Pipe Joints") + self.layout.menu("INFO_MT_mesh_gears_add", text="Gears") + self.layout.menu("INFO_MT_mesh_math_add", text="Math Function") + self.layout.menu("INFO_MT_mesh_torus_add", text="Torus Objects") + self.layout.menu("INFO_MT_mesh_basic_add", text="Basic Objects") + self.layout.menu("INFO_MT_mesh_misc_add", text="Misc Objects") def register(): @@ -175,7 +181,6 @@ def register(): # Add "Extras" menu to the "Add Mesh" menu bpy.types.INFO_MT_mesh_add.append(menu_func) - def unregister(): bpy.utils.unregister_module(__name__) diff --git a/add_mesh_extra_objects/add_mesh_3d_function_surface.py b/add_mesh_extra_objects/add_mesh_3d_function_surface.py index ca39d544..00227dd7 100644 --- a/add_mesh_extra_objects/add_mesh_3d_function_surface.py +++ b/add_mesh_extra_objects/add_mesh_3d_function_surface.py @@ -16,17 +16,9 @@ # # ##### END GPL LICENSE BLOCK ##### ''' -bl_info = { "name": "3D Function Surfaces", "author": "Buerbaum Martin (Pontiac), Elod Csirmaz", "version": (0, 3, 8), - "blender": (2, 57, 0), - "location": "View3D > Add > Mesh", - "description": "Create Objects using Math Formulas", - "warning": "", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" - "Scripts/Add_Mesh/Add_3d_Function_Surface", - "category": "Add Mesh"} ''' import bpy diff --git a/add_mesh_extra_objects/add_mesh_extra_objects.py b/add_mesh_extra_objects/add_mesh_extra_objects.py index 1007b157..040e13fe 100644 --- a/add_mesh_extra_objects/add_mesh_extra_objects.py +++ b/add_mesh_extra_objects/add_mesh_extra_objects.py @@ -39,7 +39,6 @@ def create_mesh_object(context, verts, edges, faces, name): from bpy_extras import object_utils return object_utils.object_data_add(context, mesh, operator=None) - # A very simple "bridge" tool. # Connects two equally long vertex rows with faces. # Returns a list of the new faces (list of lists) diff --git a/add_mesh_extra_objects/add_mesh_gears.py b/add_mesh_extra_objects/add_mesh_gears.py index d657fcfb..e7196f69 100644 --- a/add_mesh_extra_objects/add_mesh_gears.py +++ b/add_mesh_extra_objects/add_mesh_gears.py @@ -19,18 +19,9 @@ # # ***** END GPL LICENCE BLOCK ***** ''' -bl_info = { "name": "Gears", "author": "Michel J. Anders (varkenvarken)", "version": (2, 4, 2), - "blender": (2, 57, 0), - "location": "View3D > Add > Mesh > Gears ", - "description": "Adds a mesh Gear to the Add Mesh menu", - "warning": "", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" - "Scripts/Add_Mesh/Add_Gear", - "category": "Add Mesh", -} ''' import bpy @@ -54,7 +45,6 @@ def create_mesh_object(context, verts, edges, faces, name): from bpy_extras import object_utils return object_utils.object_data_add(context, mesh, operator=None) - # A very simple "bridge" tool. # Connects two equally long vertex rows with faces. # Returns a list of the new faces (list of lists) @@ -123,7 +113,6 @@ def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False): return faces - # Calculate the vertex coordinates for a single # section of a gear tooth. # Returns 4 lists of vertex coords (list of tuples): @@ -145,6 +134,7 @@ def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False): # 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] @@ -193,7 +183,6 @@ def add_tooth(a, t, d, radius, Ad, De, base, p_angle, rack=0, crown=0.0): 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. @@ -211,6 +200,7 @@ def add_tooth(a, t, d, radius, Ad, De, base, p_angle, rack=0, crown=0.0): # width # # @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 @@ -249,7 +239,6 @@ def add_spoke(a, t, d, radius, De, base, s, w, l, gap=0, width=19): return verts, edgefaces, edgefaces2, sf - # Create gear geometry. # Returns: # * A list of vertices (list of tuples) @@ -270,6 +259,7 @@ def add_spoke(a, t, d, radius, De, base, s, w, l, gap=0, width=19): # 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): @@ -382,7 +372,6 @@ def add_gear(teethNum, radius, Ad, De, base, p_angle, return verts, faces, vgroup_top, vgroup_valley - # Create spokes geometry. # Returns: # * A list of vertices (list of tuples) @@ -404,6 +393,7 @@ def add_gear(teethNum, radius, Ad, De, base, p_angle, # @todo Finish this # @todo Create a function that takes a "Gear" and creates a # matching "Gear Spokes" object. + def add_spokes(teethNum, radius, De, base, width=1, conangle=0, rack=0, spoke=3, spbevel=0.1, spwidth=0.2, splength=1.0, spresol=9): @@ -466,7 +456,6 @@ def add_spokes(teethNum, radius, De, base, width=1, conangle=0, rack=0, return verts, faces - # Create worm geometry. # Returns: # * A list of vertices @@ -568,7 +557,6 @@ def add_worm(teethNum, rowNum, radius, Ad, De, p_angle, return verts, faces, vgroup_top, vgroup_valley - class AddGear(bpy.types.Operator): """Add a gear mesh""" bl_idname = "mesh.primitive_gear" @@ -685,7 +673,6 @@ class AddGear(bpy.types.Operator): return {'FINISHED'} - class AddWormGear(bpy.types.Operator): """Add a worm gear mesh""" bl_idname = "mesh.primitive_worm_gear" diff --git a/add_mesh_extra_objects/add_mesh_gemstones.py b/add_mesh_extra_objects/add_mesh_gemstones.py index d0e7a375..5d4f83ca 100644 --- a/add_mesh_extra_objects/add_mesh_gemstones.py +++ b/add_mesh_extra_objects/add_mesh_gemstones.py @@ -16,18 +16,9 @@ # # ##### END GPL LICENSE BLOCK ##### ''' -bl_info = { "name": "Gemstones", "author": "Pontiac, Fourmadmen, Dreampainter", "version": (0, 4), - "blender": (2, 57, 0), - "location": "View3D > Add > Mesh > Gemstones", - "description": "Adds various gemstone (Diamond & Gem) meshes.", - "warning": "", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" - "Scripts/Add_Mesh/Add_Gemstones", - "category": "Add Mesh", -} ''' import bpy from mathutils import * @@ -52,7 +43,6 @@ def create_mesh_object(context, verts, edges, faces, name): from bpy_extras import object_utils return object_utils.object_data_add(context, mesh, operator=None) - # A very simple "bridge" tool. # Connects two equally long vertex rows with faces. # Returns a list of the new faces (list of lists) @@ -121,7 +111,6 @@ def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False): return faces - # @todo Clean up vertex&face creation process a bit. def add_gem(r1, r2, seg, h1, h2): """ @@ -181,7 +170,6 @@ def add_gem(r1, r2, seg, h1, h2): return verts, faces - def add_diamond(segments, girdle_radius, table_radius, crown_height, pavilion_height): @@ -235,7 +223,6 @@ def add_diamond(segments, girdle_radius, table_radius, return verts, faces - class AddDiamond(bpy.types.Operator): """Add a diamond mesh""" bl_idname = "mesh.primitive_diamond_add" @@ -279,7 +266,6 @@ class AddDiamond(bpy.types.Operator): return {'FINISHED'} - class AddGem(bpy.types.Operator): """Add a diamond gem""" bl_idname = "mesh.primitive_gem_add" diff --git a/add_mesh_extra_objects/add_mesh_honeycomb.py b/add_mesh_extra_objects/add_mesh_honeycomb.py index 37a93036..53194f28 100644 --- a/add_mesh_extra_objects/add_mesh_honeycomb.py +++ b/add_mesh_extra_objects/add_mesh_honeycomb.py @@ -1,4 +1,4 @@ -'''# ##### BEGIN GPL LICENSE BLOCK ##### +# ##### 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 @@ -15,19 +15,10 @@ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # ##### END GPL LICENSE BLOCK ##### - -bl_info = { +''' "name": "HoneyComb", "author": "Kayo Phoenix <kayo@illumium.org>", "version": (0, 1), - "blender": (2, 57, 0), - "location": "View3D > Add > Mesh > HoneyComb", - "description": "Adds HoneyComb Mesh", - "warning": "", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" - "Scripts/Add_Mesh/HoneyComb", - "category": "Add Mesh", -} ''' from math import pi, sin, cos diff --git a/add_mesh_extra_objects/add_mesh_pipe_joint.py b/add_mesh_extra_objects/add_mesh_pipe_joint.py new file mode 100644 index 00000000..e0dcc3e8 --- /dev/null +++ b/add_mesh_extra_objects/add_mesh_pipe_joint.py @@ -0,0 +1,992 @@ +# ##### 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 ##### +''' + "name": "Pipe Joints", + "author": "Buerbaum Martin (Pontiac)", + "version": (0, 10, 7), +''' +import bpy +from math import * +from bpy.props import * + +# Create a new mesh (object) from verts/edges/faces. +# verts/edges/faces ... List of vertices/edges/faces for the +# new mesh (as used in from_pydata). +# name ... Name of the new mesh (& object). +def create_mesh_object(context, verts, edges, faces, name): + # Create new mesh + mesh = bpy.data.meshes.new(name) + + # Make a mesh from a list of verts/edges/faces. + mesh.from_pydata(verts, edges, faces) + + # Update mesh geometry after adding stuff. + mesh.update() + + from bpy_extras import object_utils + return object_utils.object_data_add(context, mesh, operator=None) + +# 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 + +class AddElbowJoint(bpy.types.Operator): + # Create the vertices and polygons for a simple elbow (bent pipe). + """Add an Elbow pipe mesh""" + bl_idname = "mesh.primitive_elbow_joint_add" + bl_label = "Add Pipe Elbow" + bl_options = {'REGISTER', 'UNDO', 'PRESET'} + + radius = FloatProperty(name="Radius", + description="The radius of the pipe", + default=1.0, + min=0.01, + max=100.0, + unit="LENGTH") + div = IntProperty(name="Divisions", + description="Number of vertices (divisions)", + default=32, min=3, max=256) + + angle = FloatProperty(name="Angle", + description="The angle of the branching pipe (i.e. the 'arm' - " \ + "Measured from the center line of the main pipe", + default=radians(45.0), + min=radians(-179.9), + max=radians(179.9), + unit="ROTATION") + + startLength = FloatProperty(name="Length Start", + description="Length of the beginning of the pipe", + default=3.0, + min=0.01, + max=100.0, + unit="LENGTH") + endLength = FloatProperty(name="End Length", + description="Length of the end of the pipe", + default=3.0, + min=0.01, + max=100.0, + unit="LENGTH") + + def execute(self, context): + + radius = self.radius + div = self.div + + angle = self.angle + + startLength = self.startLength + endLength = self.endLength + + verts = [] + faces = [] + + loop1 = [] # The starting circle + loop2 = [] # The elbow circle + loop3 = [] # The end circle + + # Create start circle + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + locX = sin(curVertAngle) + locY = cos(curVertAngle) + locZ = -startLength + loop1.append(len(verts)) + verts.append([locX * radius, locY * radius, locZ]) + + # Create deformed joint circle + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + locX = sin(curVertAngle) + locY = cos(curVertAngle) + locZ = locX * tan(angle / 2.0) + loop2.append(len(verts)) + verts.append([locX * radius, locY * radius, locZ * radius]) + + # Create end circle + baseEndLocX = -endLength * sin(angle) + baseEndLocZ = endLength * cos(angle) + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + # Create circle + locX = sin(curVertAngle) * radius + locY = cos(curVertAngle) * radius + locZ = 0.0 + + # Rotate circle + locZ = locX * cos(pi / 2.0 - angle) + locX = locX * sin(pi / 2.0 - angle) + + loop3.append(len(verts)) + # Translate and add circle vertices to the list. + verts.append([baseEndLocX + locX, locY, baseEndLocZ + locZ]) + + # Create faces + faces.extend(createFaces(loop1, loop2, closed=True)) + faces.extend(createFaces(loop2, loop3, closed=True)) + + base = create_mesh_object(context, verts, [], faces, "Elbow Joint") + + return {'FINISHED'} + +class AddTeeJoint(bpy.types.Operator): + # Create the vertices and polygons for a simple tee (T) joint. + # The base arm of the T can be positioned in an angle if needed though. + """Add a Tee-Joint mesh""" + bl_idname = "mesh.primitive_tee_joint_add" + bl_label = "Add Pipe Tee-Joint" + bl_options = {'REGISTER', 'UNDO', 'PRESET'} + + radius = FloatProperty(name="Radius", + description="The radius of the pipe", + default=1.0, + min=0.01, + max=100.0, + unit="LENGTH") + div = IntProperty(name="Divisions", + description="Number of vertices (divisions)", + default=32, + min=4, + max=256) + + angle = FloatProperty(name="Angle", + description="The angle of the branching pipe (i.e. the 'arm' - " \ + "Measured from the center line of the main pipe", + default=radians(90.0), + min=radians(0.1), + max=radians(179.9), + unit="ROTATION") + + startLength = FloatProperty(name="Length Start", + description="Length of the beginning of the" \ + " main pipe (the straight one)", + default=3.0, + min=0.01, + max=100.0, + unit="LENGTH") + endLength = FloatProperty(name="End Length", + description="Length of the end of the" \ + " main pipe (the straight one)", + default=3.0, + min=0.01, + max=100.0, + unit="LENGTH") + branchLength = FloatProperty(name="Arm Length", + description="Length of the arm pipe (the bent one)", + default=3.0, + min=0.01, + max=100.0, + unit="LENGTH") + + def execute(self, context): + + radius = self.radius + div = self.div + + angle = self.angle + + startLength = self.startLength + endLength = self.endLength + branchLength = self.branchLength + + if (div % 2): + # Odd vertice number not supported (yet). + return {'CANCELLED'} + + verts = [] + faces = [] + + # List of vert indices of each cross section + loopMainStart = [] # Vert indices for the + # beginning of the main pipe. + loopJoint1 = [] # Vert indices for joint that is used + # to connect the joint & loopMainStart. + loopJoint2 = [] # Vert indices for joint that is used + # to connect the joint & loopArm. + loopJoint3 = [] # Vert index for joint that is used + # to connect the joint & loopMainEnd. + loopArm = [] # Vert indices for the end of the arm. + loopMainEnd = [] # Vert indices for the + # end of the main pipe. + + # Create start circle (main pipe) + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + locX = sin(curVertAngle) + locY = cos(curVertAngle) + locZ = -startLength + loopMainStart.append(len(verts)) + verts.append([locX * radius, locY * radius, locZ]) + + # Create deformed joint circle + vertTemp1 = None + vertTemp2 = None + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + locX = sin(curVertAngle) + locY = cos(curVertAngle) + + if vertIdx == 0: + vertTemp1 = len(verts) + if vertIdx == div / 2: + # @todo: This will possibly break if we + # ever support odd divisions. + vertTemp2 = len(verts) + + loopJoint1.append(len(verts)) + if (vertIdx < div / 2): + # Straight side of main pipe. + locZ = 0 + loopJoint3.append(len(verts)) + else: + # Branching side + locZ = locX * tan(angle / 2.0) + loopJoint2.append(len(verts)) + + verts.append([locX * radius, locY * radius, locZ * radius]) + + # Create 2. deformed joint (half-)circle + loopTemp = [] + for vertIdx in range(div): + if (vertIdx > div / 2): + curVertAngle = vertIdx * (2.0 * pi / div) + locX = sin(curVertAngle) + locY = -cos(curVertAngle) + locZ = -(radius * locX * tan((pi - angle) / 2.0)) + loopTemp.append(len(verts)) + verts.append([locX * radius, locY * radius, locZ]) + + loopTemp2 = loopTemp[:] + + # Finalise 2. loop + loopTemp.reverse() + loopTemp.append(vertTemp1) + loopJoint2.reverse() + loopJoint2.extend(loopTemp) + loopJoint2.reverse() + + # Finalise 3. loop + loopTemp2.append(vertTemp2) + loopTemp2.reverse() + loopJoint3.extend(loopTemp2) + + # Create end circle (branching pipe) + baseEndLocX = -branchLength * sin(angle) + baseEndLocZ = branchLength * cos(angle) + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + # Create circle + locX = sin(curVertAngle) * radius + locY = cos(curVertAngle) * radius + locZ = 0.0 + + # Rotate circle + locZ = locX * cos(pi / 2.0 - angle) + locX = locX * sin(pi / 2.0 - angle) + + loopArm.append(len(verts)) + + # Add translated circle. + verts.append([baseEndLocX + locX, locY, baseEndLocZ + locZ]) + + # Create end circle (main pipe) + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + locX = sin(curVertAngle) + locY = cos(curVertAngle) + locZ = endLength + loopMainEnd.append(len(verts)) + verts.append([locX * radius, locY * radius, locZ]) + + # Create faces + faces.extend(createFaces(loopMainStart, loopJoint1, closed=True)) + faces.extend(createFaces(loopJoint2, loopArm, closed=True)) + faces.extend(createFaces(loopJoint3, loopMainEnd, closed=True)) + + base = create_mesh_object(context, verts, [], faces, "Tee Joint") + + return {'FINISHED'} + +class AddWyeJoint(bpy.types.Operator): + """Add a Wye-Joint mesh""" + bl_idname = "mesh.primitive_wye_joint_add" + bl_label = "Add Pipe Wye-Joint" + bl_options = {'REGISTER', 'UNDO', 'PRESET'} + + radius = FloatProperty(name="Radius", + description="The radius of the pipe", + default=1.0, + min=0.01, + max=100.0, + unit="LENGTH") + div = IntProperty(name="Divisions", + description="Number of vertices (divisions)", + default=32, + min=4, + max=256) + + angle1 = FloatProperty(name="Angle 1", + description="The angle of the 1. branching pipe " \ + "(measured from the center line of the main pipe)", + default=radians(45.0), + min=radians(-179.9), + max=radians(179.9), + unit="ROTATION") + angle2 = FloatProperty(name="Angle 2", + description="The angle of the 2. branching pipe " \ + "(measured from the center line of the main pipe) ", + default=radians(45.0), + min=radians(-179.9), + max=radians(179.9), + unit="ROTATION") + + startLength = FloatProperty(name="Length Start", + description="Length of the beginning of the" \ + " main pipe (the straight one)", + default=3.0, + min=0.01, + max=100.0, + unit="LENGTH") + branch1Length = FloatProperty(name="Length Arm 1", + description="Length of the 1. arm", + default=3.0, + min=0.01, + max=100.0, + unit="LENGTH") + branch2Length = FloatProperty(name="Length Arm 2", + description="Length of the 2. arm", + default=3.0, + min=0.01, + max=100.0, + unit="LENGTH") + + def execute(self, context): + + radius = self.radius + div = self.div + + angle1 = self.angle1 + angle2 = self.angle2 + + startLength = self.startLength + branch1Length = self.branch1Length + branch2Length = self.branch2Length + + if (div % 2): + # Odd vertice number not supported (yet). + return {'CANCELLED'} + + verts = [] + faces = [] + + # List of vert indices of each cross section + loopMainStart = [] # Vert indices for + # the beginning of the main pipe. + loopJoint1 = [] # Vert index for joint that is used + # to connect the joint & loopMainStart. + loopJoint2 = [] # Vert index for joint that + # is used to connect the joint & loopArm1. + loopJoint3 = [] # Vert index for joint that is + # used to connect the joint & loopArm2. + loopArm1 = [] # Vert idxs for end of the 1. arm. + loopArm2 = [] # Vert idxs for end of the 2. arm. + + # Create start circle + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + locX = sin(curVertAngle) + locY = cos(curVertAngle) + locZ = -startLength + loopMainStart.append(len(verts)) + verts.append([locX * radius, locY * radius, locZ]) + + # Create deformed joint circle + vertTemp1 = None + vertTemp2 = None + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + locX = sin(curVertAngle) + locY = cos(curVertAngle) + + if vertIdx == 0: + vertTemp2 = len(verts) + if vertIdx == div / 2: + # @todo: This will possibly break if we + # ever support odd divisions. + vertTemp1 = len(verts) + + loopJoint1.append(len(verts)) + if (vertIdx > div / 2): + locZ = locX * tan(angle1 / 2.0) + loopJoint2.append(len(verts)) + else: + locZ = locX * tan(-angle2 / 2.0) + loopJoint3.append(len(verts)) + + verts.append([locX * radius, locY * radius, locZ * radius]) + + # Create 2. deformed joint (half-)circle + loopTemp = [] + angleJoint = (angle2 - angle1) / 2.0 + for vertIdx in range(div): + if (vertIdx > div / 2): + curVertAngle = vertIdx * (2.0 * pi / div) + + locX = (-sin(curVertAngle) * sin(angleJoint) + / sin(angle2 - angleJoint)) + locY = -cos(curVertAngle) + locZ = (-(sin(curVertAngle) * cos(angleJoint) + / sin(angle2 - angleJoint))) + + loopTemp.append(len(verts)) + verts.append([locX * radius, locY * radius, locZ * radius]) + + loopTemp2 = loopTemp[:] + + # Finalise 2. loop + loopTemp.append(vertTemp1) + loopTemp.reverse() + loopTemp.append(vertTemp2) + loopJoint2.reverse() + loopJoint2.extend(loopTemp) + loopJoint2.reverse() + + # Finalise 3. loop + loopTemp2.reverse() + loopJoint3.extend(loopTemp2) + + # Create end circle (1. branching pipe) + baseEndLocX = -branch1Length * sin(angle1) + baseEndLocZ = branch1Length * cos(angle1) + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + # Create circle + locX = sin(curVertAngle) * radius + locY = cos(curVertAngle) * radius + locZ = 0.0 + + # Rotate circle + locZ = locX * cos(pi / 2.0 - angle1) + locX = locX * sin(pi / 2.0 - angle1) + + loopArm1.append(len(verts)) + # Add translated circle. + verts.append([baseEndLocX + locX, locY, baseEndLocZ + locZ]) + + # Create end circle (2. branching pipe) + baseEndLocX = branch2Length * sin(angle2) + baseEndLocZ = branch2Length * cos(angle2) + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + # Create circle + locX = sin(curVertAngle) * radius + locY = cos(curVertAngle) * radius + locZ = 0.0 + + # Rotate circle + locZ = locX * cos(pi / 2.0 + angle2) + locX = locX * sin(pi / 2.0 + angle2) + + loopArm2.append(len(verts)) + # Add translated circle + verts.append([baseEndLocX + locX, locY, baseEndLocZ + locZ]) + + # Create faces + faces.extend(createFaces(loopMainStart, loopJoint1, closed=True)) + faces.extend(createFaces(loopJoint2, loopArm1, closed=True)) + faces.extend(createFaces(loopJoint3, loopArm2, closed=True)) + + base = create_mesh_object(context, verts, [], faces, "Wye Joint") + + return {'FINISHED'} + +class AddCrossJoint(bpy.types.Operator): + """Add a Cross-Joint mesh""" + # Create the vertices and polygons for a coss (+ or X) pipe joint. + bl_idname = "mesh.primitive_cross_joint_add" + bl_label = "Add Pipe Cross-Joint" + bl_options = {'REGISTER', 'UNDO', 'PRESET'} + + radius = FloatProperty(name="Radius", + description="The radius of the pipe", + default=1.0, + min=0.01, + max=100.0, + unit="LENGTH") + div = IntProperty(name="Divisions", + description="Number of vertices (divisions)", + default=32, + min=4, + max=256) + + angle1 = FloatProperty(name="Angle 1", + description="The angle of the 1. arm (from the main axis)", + default=radians(90.0), + min=radians(-179.9), + max=radians(179.9), + unit="ROTATION") + angle2 = FloatProperty(name="Angle 2", + description="The angle of the 2. arm (from the main axis)", + default=radians(90.0), + min=radians(-179.9), + max=radians(179.9), + unit="ROTATION") + angle3 = FloatProperty(name="Angle 3 (center)", + description="The angle of the center arm (from the main axis)", + default=radians(0.0), + min=radians(-179.9), + max=radians(179.9), + unit="ROTATION") + + startLength = FloatProperty(name="Length Start", + description="Length of the beginning of the " \ + "main pipe (the straight one)", + default=3.0, + min=0.01, + max=100.0, + unit="LENGTH") + branch1Length = FloatProperty(name="Length Arm 1", + description="Length of the 1. arm", + default=3.0, + min=0.01, + max=100.0, + unit="LENGTH") + branch2Length = FloatProperty(name="Length Arm 2", + description="Length of the 2. arm", + default=3.0, + min=0.01, + max=100.0, + unit="LENGTH") + branch3Length = FloatProperty(name="Length Arm 3 (center)", + description="Length of the center arm", + default=3.0, + min=0.01, + max=100.0, + unit="LENGTH") + + def execute(self, context): + + radius = self.radius + div = self.div + + angle1 = self.angle1 + angle2 = self.angle2 + angle3 = self.angle3 + + startLength = self.startLength + branch1Length = self.branch1Length + branch2Length = self.branch2Length + branch3Length = self.branch3Length + if (div % 2): + # Odd vertice number not supported (yet). + return {'CANCELLED'} + + verts = [] + faces = [] + + # List of vert indices of each cross section + loopMainStart = [] # Vert indices for the + # beginning of the main pipe. + loopJoint1 = [] # Vert index for joint that is used + # to connect the joint & loopMainStart. + loopJoint2 = [] # Vert index for joint that is used + # to connect the joint & loopArm1. + loopJoint3 = [] # Vert index for joint that is used + # to connect the joint & loopArm2. + loopJoint4 = [] # Vert index for joint that is used + # to connect the joint & loopArm3. + loopArm1 = [] # Vert idxs for the end of the 1. arm. + loopArm2 = [] # Vert idxs for the end of the 2. arm. + loopArm3 = [] # Vert idxs for the center arm end. + + # Create start circle + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + locX = sin(curVertAngle) + locY = cos(curVertAngle) + locZ = -startLength + loopMainStart.append(len(verts)) + verts.append([locX * radius, locY * radius, locZ]) + + # Create 1. deformed joint circle + vertTemp1 = None + vertTemp2 = None + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + locX = sin(curVertAngle) + locY = cos(curVertAngle) + + if vertIdx == 0: + vertTemp2 = len(verts) + if vertIdx == div / 2: + # @todo: This will possibly break if we + # ever support odd divisions. + vertTemp1 = len(verts) + + loopJoint1.append(len(verts)) + if (vertIdx > div / 2): + locZ = locX * tan(angle1 / 2.0) + loopJoint2.append(len(verts)) + else: + locZ = locX * tan(-angle2 / 2.0) + loopJoint3.append(len(verts)) + + verts.append([locX * radius, locY * radius, locZ * radius]) + + # loopTemp2 = loopJoint2[:] # UNUSED + + # Create 2. deformed joint circle + loopTempA = [] + loopTempB = [] + angleJoint1 = (angle1 - angle3) / 2.0 + angleJoint2 = (angle2 + angle3) / 2.0 + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + + # Skip pole vertices + # @todo: This will possibly break if + # we ever support odd divisions. + if not (vertIdx == 0) and not (vertIdx == div / 2): + + if (vertIdx > div / 2): + angleJoint = angleJoint1 + angle = angle1 + Z = -1.0 + loopTempA.append(len(verts)) + + else: + angleJoint = angleJoint2 + angle = angle2 + Z = 1.0 + loopTempB.append(len(verts)) + + locX = (sin(curVertAngle) * sin(angleJoint) + / sin(angle - angleJoint)) + locY = -cos(curVertAngle) + locZ = (Z * (sin(curVertAngle) * cos(angleJoint) + / sin(angle - angleJoint))) + + verts.append([locX * radius, locY * radius, locZ * radius]) + + loopTempA2 = loopTempA[:] + loopTempB2 = loopTempB[:] + loopTempB3 = loopTempB[:] + + # Finalise 2. loop + loopTempA.append(vertTemp1) + loopTempA.reverse() + loopTempA.append(vertTemp2) + loopJoint2.reverse() + loopJoint2.extend(loopTempA) + loopJoint2.reverse() + + # Finalise 3. loop + loopJoint3.extend(loopTempB3) + + # Finalise 4. loop + loopTempA2.append(vertTemp1) + loopTempA2.reverse() + loopTempB2.append(vertTemp2) + loopJoint4.extend(reversed(loopTempB2)) + loopJoint4.extend(loopTempA2) + + # Create end circle (1. branching pipe) + baseEndLocX = -branch1Length * sin(angle1) + baseEndLocZ = branch1Length * cos(angle1) + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + # Create circle + locX = sin(curVertAngle) * radius + locY = cos(curVertAngle) * radius + locZ = 0.0 + + # Rotate circle + locZ = locX * cos(pi / 2.0 - angle1) + locX = locX * sin(pi / 2.0 - angle1) + + loopArm1.append(len(verts)) + # Add translated circle. + verts.append([baseEndLocX + locX, locY, baseEndLocZ + locZ]) + + # Create end circle (2. branching pipe) + baseEndLocX = branch2Length * sin(angle2) + baseEndLocZ = branch2Length * cos(angle2) + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + # Create circle + locX = sin(curVertAngle) * radius + locY = cos(curVertAngle) * radius + locZ = 0.0 + + # Rotate circle + locZ = locX * cos(pi / 2.0 + angle2) + locX = locX * sin(pi / 2.0 + angle2) + + loopArm2.append(len(verts)) + # Add translated circle + verts.append([baseEndLocX + locX, locY, baseEndLocZ + locZ]) + + # Create end circle (center pipe) + baseEndLocX = branch3Length * sin(angle3) + baseEndLocZ = branch3Length * cos(angle3) + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + # Create circle + locX = sin(curVertAngle) * radius + locY = cos(curVertAngle) * radius + locZ = 0.0 + + # Rotate circle + locZ = locX * cos(pi / 2.0 + angle3) + locX = locX * sin(pi / 2.0 + angle3) + + loopArm3.append(len(verts)) + # Add translated circle + verts.append([baseEndLocX + locX, locY, baseEndLocZ + locZ]) + + # Create faces + faces.extend(createFaces(loopMainStart, loopJoint1, closed=True)) + faces.extend(createFaces(loopJoint2, loopArm1, closed=True)) + faces.extend(createFaces(loopJoint3, loopArm2, closed=True)) + faces.extend(createFaces(loopJoint4, loopArm3, closed=True)) + + base = create_mesh_object(context, verts, [], faces, "Cross Joint") + + return {'FINISHED'} + +class AddNJoint(bpy.types.Operator): + """Add a N-Joint mesh""" + # Create the vertices and polygons for a regular n-joint. + bl_idname = "mesh.primitive_n_joint_add" + bl_label = "Add Pipe N-Joint" + bl_options = {'REGISTER', 'UNDO', 'PRESET'} + + radius = FloatProperty(name="Radius", + description="The radius of the pipe", + default=1.0, + min=0.01, + max=100.0, + unit="LENGTH") + div = IntProperty(name="Divisions", + description="Number of vertices (divisions)", + default=32, + min=4, + max=256) + number = IntProperty(name="Arms/Joints", + description="Number of joints/arms", + default=5, + min=2, + max=99999) + length = FloatProperty(name="Length", + description="Length of each joint/arm", + default=3.0, + min=0.01, + max=100.0, + unit="LENGTH") + + def execute(self, context): + radius = self.radius + div = self.div + number = self.number + length = self.length + + if (div % 2): + # Odd vertice number not supported (yet). + return {'CANCELLED'} + + if (number < 2): + return {'CANCELLED'} + + verts = [] + faces = [] + + loopsEndCircles = [] + loopsJointsTemp = [] + loopsJoints = [] + + vertTemp1 = None + vertTemp2 = None + + angleDiv = (2.0 * pi / number) + + # Create vertices for the end circles. + for num in range(number): + circle = [] + # Create start circle + angle = num * angleDiv + + baseEndLocX = length * sin(angle) + baseEndLocZ = length * cos(angle) + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + # Create circle + locX = sin(curVertAngle) * radius + locY = cos(curVertAngle) * radius + locZ = 0.0 + + # Rotate circle + locZ = locX * cos(pi / 2.0 + angle) + locX = locX * sin(pi / 2.0 + angle) + + circle.append(len(verts)) + # Add translated circle + verts.append([baseEndLocX + locX, locY, baseEndLocZ + locZ]) + + loopsEndCircles.append(circle) + + # Create vertices for the joint circles. + loopJoint = [] + for vertIdx in range(div): + curVertAngle = vertIdx * (2.0 * pi / div) + locX = sin(curVertAngle) + locY = cos(curVertAngle) + + skipVert = False + # Store pole vertices + if vertIdx == 0: + if (num == 0): + vertTemp2 = len(verts) + else: + skipVert = True + elif vertIdx == div / 2: + # @todo: This will possibly break if we + # ever support odd divisions. + if (num == 0): + vertTemp1 = len(verts) + else: + skipVert = True + + if not skipVert: + if (vertIdx > div / 2): + locZ = -locX * tan((pi - angleDiv) / 2.0) + loopJoint.append(len(verts)) + + # Rotate the vert + cosAng = cos(-angle) + sinAng = sin(-angle) + LocXnew = locX * cosAng - locZ * sinAng + LocZnew = locZ * cosAng + locX * sinAng + locZ = LocZnew + locX = LocXnew + + verts.append([ + locX * radius, + locY * radius, + locZ * radius]) + else: + # These two vertices will only be + # added the very first time. + if vertIdx == 0 or vertIdx == div / 2: + verts.append([locX * radius, locY * radius, locZ]) + + loopsJointsTemp.append(loopJoint) + + # Create complete loops (loopsJoints) out of the + # double number of half loops in loopsJointsTemp. + for halfLoopIdx in range(len(loopsJointsTemp)): + if (halfLoopIdx == len(loopsJointsTemp) - 1): + idx1 = halfLoopIdx + idx2 = 0 + else: + idx1 = halfLoopIdx + idx2 = halfLoopIdx + 1 + + loopJoint = [] + loopJoint.append(vertTemp2) + loopJoint.extend(reversed(loopsJointsTemp[idx2])) + loopJoint.append(vertTemp1) + loopJoint.extend(loopsJointsTemp[idx1]) + + loopsJoints.append(loopJoint) + + # Create faces from the two + # loop arrays (loopsJoints -> loopsEndCircles). + for loopIdx in range(len(loopsEndCircles)): + faces.extend( + createFaces(loopsJoints[loopIdx], + loopsEndCircles[loopIdx], closed=True)) + + base = create_mesh_object(context, verts, [], faces, "N Joint") + + return {'FINISHED'} + +################################
\ No newline at end of file diff --git a/add_mesh_extra_objects/add_mesh_polysphere.py b/add_mesh_extra_objects/add_mesh_polysphere.py index b250063f..b01e741a 100644 --- a/add_mesh_extra_objects/add_mesh_polysphere.py +++ b/add_mesh_extra_objects/add_mesh_polysphere.py @@ -16,17 +16,9 @@ # # ##### END GPL LICENSE BLOCK ##### ''' -bl_info = { "name": "Add PolySphere", "author": "Andy Davies (metalliandy)", "version": (0,1,6), - "blender": (2, 62, 0), - "location": "View3D > Add > Mesh > PolySphere", - "description": "Adds a PolySphere (all quads) for sculpting", - "warning": "", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" - "Scripts/Add_Mesh/Add_PolySphere", - "category": "Add Mesh"} ''' import bpy diff --git a/add_mesh_extra_objects/add_mesh_solid.py b/add_mesh_extra_objects/add_mesh_solid.py new file mode 100644 index 00000000..20584ea7 --- /dev/null +++ b/add_mesh_extra_objects/add_mesh_solid.py @@ -0,0 +1,502 @@ +# ***** 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 LICENCE BLOCK ***** +''' + "name": "Regular Solids", + "author": "DreamPainter", + "version": (2, 0), +''' +import bpy +from bpy.props import FloatProperty,EnumProperty,BoolProperty +from math import sqrt +from mathutils import Vector +from functools import reduce +from bpy_extras.object_utils import object_data_add + +# this function creates a chain of quads and, when necessary, a remaining tri +# for each polygon created in this script. be aware though, that this function +# assumes each polygon is convex. +# poly: list of faces, or a single face, like those +# needed for mesh.from_pydata. +# returns the tessellated faces. +def createPolys(poly): + # check for faces + if len(poly) == 0: + return [] + # one or more faces + if type(poly[0]) == type(1): + poly = [poly] # if only one, make it a list of one face + faces = [] + for i in poly: + L = len(i) + # let all faces of 3 or 4 verts be + if L < 5: + faces.append(i) + # split all polygons in half and bridge the two halves + else: + f = [[i[x],i[x+1],i[L-2-x],i[L-1-x]] for x in range(L//2-1)] + faces.extend(f) + if L&1 == 1: + faces.append([i[L//2-1+x] for x in [0,1,2]]) + return faces + +# function to make the reduce function work as a workaround to sum a list of vectors +def vSum(list): + return reduce(lambda a,b: a+b, list) + +# creates the 5 platonic solids as a base for the rest +# plato: should be one of {"4","6","8","12","20"}. decides what solid the +# outcome will be. +# returns a list of vertices and faces +def source(plato): + verts = [] + faces = [] + + # Tetrahedron + if plato == "4": + # Calculate the necessary constants + s = sqrt(2)/3.0 + t = -1/3 + u = sqrt(6)/3 + + # create the vertices and faces + v = [(0,0,1),(2*s,0,t),(-s,u,t),(-s,-u,t)] + faces = [[0,1,2],[0,2,3],[0,3,1],[1,3,2]] + + # Hexahedron (cube) + elif plato == "6": + # Calculate the necessary constants + s = 1/sqrt(3) + + # create the vertices and faces + v = [(-s,-s,-s),(s,-s,-s),(s,s,-s),(-s,s,-s),(-s,-s,s),(s,-s,s),(s,s,s),(-s,s,s)] + faces = [[0,3,2,1],[0,1,5,4],[0,4,7,3],[6,5,1,2],[6,2,3,7],[6,7,4,5]] + + # Octahedron + elif plato == "8": + # create the vertices and faces + v = [(1,0,0),(-1,0,0),(0,1,0),(0,-1,0),(0,0,1),(0,0,-1)] + faces = [[4,0,2],[4,2,1],[4,1,3],[4,3,0],[5,2,0],[5,1,2],[5,3,1],[5,0,3]] + + # Dodecahedron + elif plato == "12": + # Calculate the necessary constants + s = 1/sqrt(3) + t = sqrt((3-sqrt(5))/6) + u = sqrt((3+sqrt(5))/6) + + # create the vertices and faces + v = [(s,s,s),(s,s,-s),(s,-s,s),(s,-s,-s),(-s,s,s),(-s,s,-s),(-s,-s,s),(-s,-s,-s), + (t,u,0),(-t,u,0),(t,-u,0),(-t,-u,0),(u,0,t),(u,0,-t),(-u,0,t),(-u,0,-t),(0,t,u), + (0,-t,u),(0,t,-u),(0,-t,-u)] + faces = [[0,8,9,4,16],[0,12,13,1,8],[0,16,17,2,12],[8,1,18,5,9],[12,2,10,3,13], + [16,4,14,6,17],[9,5,15,14,4],[6,11,10,2,17],[3,19,18,1,13],[7,15,5,18,19], + [7,11,6,14,15],[7,19,3,10,11]] + + # Icosahedron + elif plato == "20": + # Calculate the necessary constants + s = (1+sqrt(5))/2 + t = sqrt(1+s*s) + s = s/t + t = 1/t + + # create the vertices and faces + v = [(s,t,0),(-s,t,0),(s,-t,0),(-s,-t,0),(t,0,s),(t,0,-s),(-t,0,s),(-t,0,-s), + (0,s,t),(0,-s,t),(0,s,-t),(0,-s,-t)] + faces = [[0,8,4],[0,5,10],[2,4,9],[2,11,5],[1,6,8],[1,10,7],[3,9,6],[3,7,11], + [0,10,8],[1,8,10],[2,9,11],[3,11,9],[4,2,0],[5,0,2],[6,1,3],[7,3,1], + [8,6,4],[9,4,6],[10,5,7],[11,7,5]] + + # convert the tuples to Vectors + verts = [Vector(i) for i in v] + + return verts,faces + +# processes the raw data from source +def createSolid(plato,vtrunc,etrunc,dual,snub): + # the duals from each platonic solid + dualSource = {"4":"4", + "6":"8", + "8":"6", + "12":"20", + "20":"12"} + + # constants saving space and readability + vtrunc *= 0.5 + etrunc *= 0.5 + supposedSize = 0 + noSnub = (snub == "None") or (etrunc == 0.5) or (etrunc == 0) + lSnub = (snub == "Left") and (0 < etrunc < 0.5) + rSnub = (snub == "Right") and (0 < etrunc < 0.5) + + # no truncation + if vtrunc == 0: + if dual: # dual is as simple as another, but mirrored platonic solid + vInput, fInput = source(dualSource[plato]) + supposedSize = vSum(vInput[i] for i in fInput[0]).length/len(fInput[0]) + vInput = [-i*supposedSize for i in vInput] # mirror it + return vInput, fInput + return source(plato) + elif 0 < vtrunc <= 0.5: # simple truncation of the source + vInput, fInput = source(plato) + else: + # truncation is now equal to simple truncation of the dual of the source + vInput, fInput = source(dualSource[plato]) + supposedSize = vSum(vInput[i] for i in fInput[0]).length / len(fInput[0]) + vtrunc = 1-vtrunc # account for the source being a dual + if vtrunc == 0: # no truncation needed + if dual: + vInput, fInput = source(plato) + vInput = [i*supposedSize for i in vInput] + return vInput, fInput + vInput = [-i*supposedSize for i in vInput] + return vInput, fInput + + # generate connection database + vDict = [{} for i in vInput] + # for every face, store what vertex comes after and before the current vertex + for x in range(len(fInput)): + i = fInput[x] + for j in range(len(i)): + vDict[i[j-1]][i[j]] = [i[j-2],x] + if len(vDict[i[j-1]]) == 1: vDict[i[j-1]][-1] = i[j] + + # the actual connection database: exists out of: + # [vtrunc pos, etrunc pos, connected vert IDs, connected face IDs] + vData = [[[],[],[],[]] for i in vInput] + fvOutput = [] # faces created from truncated vertices + feOutput = [] # faces created from truncated edges + vOutput = [] # newly created vertices + for x in range(len(vInput)): + i = vDict[x] # lookup the current vertex + current = i[-1] + while True: # follow the chain to get a ccw order of connected verts and faces + vData[x][2].append(i[current][0]) + vData[x][3].append(i[current][1]) + # create truncated vertices + vData[x][0].append((1-vtrunc)*vInput[x] + vtrunc*vInput[vData[x][2][-1]]) + current = i[current][0] + if current == i[-1]: break # if we're back at the first: stop the loop + fvOutput.append([]) # new face from truncated vert + fOffset = x*(len(i)-1) # where to start off counting faceVerts + # only create one vert where one is needed (v1 todo: done) + if etrunc == 0.5: + for j in range(len(i)-1): + vOutput.append((vData[x][0][j]+vData[x][0][j-1])*etrunc) # create vert + fvOutput[x].append(fOffset+j) # add to face + fvOutput[x] = fvOutput[x][1:]+[fvOutput[x][0]] # rotate face for ease later on + # create faces from truncated edges. + for j in range(len(i)-1): + if x > vData[x][2][j]: #only create when other vertex has been added + index = vData[vData[x][2][j]][2].index(x) + feOutput.append([fvOutput[x][j],fvOutput[x][j-1], + fvOutput[vData[x][2][j]][index], + fvOutput[vData[x][2][j]][index-1]]) + # edge truncation between none and full + elif etrunc > 0: + for j in range(len(i)-1): + # create snubs from selecting verts from rectified meshes + if rSnub: + vOutput.append(etrunc*vData[x][0][j]+(1-etrunc)*vData[x][0][j-1]) + fvOutput[x].append(fOffset+j) + elif lSnub: + vOutput.append((1-etrunc)*vData[x][0][j]+etrunc*vData[x][0][j-1]) + fvOutput[x].append(fOffset+j) + else: #noSnub, select both verts from rectified mesh + vOutput.append(etrunc*vData[x][0][j]+(1-etrunc)*vData[x][0][j-1]) + vOutput.append((1-etrunc)*vData[x][0][j]+etrunc*vData[x][0][j-1]) + fvOutput[x].append(2*fOffset+2*j) + fvOutput[x].append(2*fOffset+2*j+1) + # rotate face for ease later on + if noSnub: fvOutput[x] = fvOutput[x][2:]+fvOutput[x][:2] + else: fvOutput[x] = fvOutput[x][1:]+[fvOutput[x][0]] + # create single face for each edge + if noSnub: + for j in range(len(i)-1): + if x > vData[x][2][j]: + index = vData[vData[x][2][j]][2].index(x) + feOutput.append([fvOutput[x][j*2],fvOutput[x][2*j-1], + fvOutput[vData[x][2][j]][2*index], + fvOutput[vData[x][2][j]][2*index-1]]) + # create 2 tri's for each edge for the snubs + elif rSnub: + for j in range(len(i)-1): + if x > vData[x][2][j]: + index = vData[vData[x][2][j]][2].index(x) + feOutput.append([fvOutput[x][j],fvOutput[x][j-1], + fvOutput[vData[x][2][j]][index]]) + feOutput.append([fvOutput[x][j],fvOutput[vData[x][2][j]][index], + fvOutput[vData[x][2][j]][index-1]]) + elif lSnub: + for j in range(len(i)-1): + if x > vData[x][2][j]: + index = vData[vData[x][2][j]][2].index(x) + feOutput.append([fvOutput[x][j],fvOutput[x][j-1], + fvOutput[vData[x][2][j]][index-1]]) + feOutput.append([fvOutput[x][j-1],fvOutput[vData[x][2][j]][index], + fvOutput[vData[x][2][j]][index-1]]) + # special rules fro birectified mesh (v1 todo: done) + elif vtrunc == 0.5: + for j in range(len(i)-1): + if x < vData[x][2][j]: # use current vert, since other one has not passed yet + vOutput.append(vData[x][0][j]) + fvOutput[x].append(len(vOutput)-1) + else: + # search for other edge to avoid duplicity + connectee = vData[x][2][j] + fvOutput[x].append(fvOutput[connectee][vData[connectee][2].index(x)]) + else: # vert truncation only + vOutput.extend(vData[x][0]) # use generated verts from way above + for j in range(len(i)-1): # create face from them + fvOutput[x].append(fOffset+j) + + # calculate supposed vertex length to ensure continuity + if supposedSize and not dual: # this to make the vtrunc > 1 work + supposedSize *= len(fvOutput[0])/vSum(vOutput[i] for i in fvOutput[0]).length + vOutput = [-i*supposedSize for i in vOutput] + + # create new faces by replacing old vert IDs by newly generated verts + ffOutput = [[] for i in fInput] + for x in range(len(fInput)): + # only one generated vert per vertex, so choose accordingly + if etrunc == 0.5 or (etrunc == 0 and vtrunc == 0.5) or lSnub or rSnub: + ffOutput[x] = [fvOutput[i][vData[i][3].index(x)-1] for i in fInput[x]] + # two generated verts per vertex + elif etrunc > 0: + for i in fInput[x]: + ffOutput[x].append(fvOutput[i][2*vData[i][3].index(x)-1]) + ffOutput[x].append(fvOutput[i][2*vData[i][3].index(x)-2]) + else: # cutting off corners also makes 2 verts + for i in fInput[x]: + ffOutput[x].append(fvOutput[i][vData[i][3].index(x)]) + ffOutput[x].append(fvOutput[i][vData[i][3].index(x)-1]) + + if not dual: + return vOutput,fvOutput + feOutput + ffOutput + else: + # do the same procedure as above, only now on the generated mesh + # generate connection database + vDict = [{} for i in vOutput] + dvOutput = [0 for i in fvOutput + feOutput + ffOutput] + dfOutput = [] + + for x in range(len(dvOutput)): # for every face + i = (fvOutput + feOutput + ffOutput)[x] # choose face to work with + # find vertex from face + normal = (vOutput[i[0]]-vOutput[i[1]]).cross(vOutput[i[2]]-vOutput[i[1]]).normalized() + dvOutput[x] = normal/(normal.dot(vOutput[i[0]])) + for j in range(len(i)): # create vert chain + vDict[i[j-1]][i[j]] = [i[j-2],x] + if len(vDict[i[j-1]]) == 1: vDict[i[j-1]][-1] = i[j] + + # calculate supposed size for continuity + supposedSize = vSum([vInput[i] for i in fInput[0]]).length/len(fInput[0]) + supposedSize /= dvOutput[-1].length + dvOutput = [i*supposedSize for i in dvOutput] + + # use chains to create faces + for x in range(len(vOutput)): + i = vDict[x] + current = i[-1] + face = [] + while True: + face.append(i[current][1]) + current = i[current][0] + if current == i[-1]: break + dfOutput.append(face) + + return dvOutput,dfOutput + +class Solids(bpy.types.Operator): + """Add one of the (regular) solids (mesh)""" + bl_idname = "mesh.primitive_solid_add" + bl_label = "(Regular) solids" + bl_description = "Add one of the Platonic, Archimedean or Catalan solids" + bl_options = {'REGISTER', 'UNDO', 'PRESET'} + + source = EnumProperty(items = (("4","Tetrahedron",""), + ("6","Hexahedron",""), + ("8","Octahedron",""), + ("12","Dodecahedron",""), + ("20","Icosahedron","")), + name = "Source", + description = "Starting point of your solid") + size = FloatProperty(name = "Size", + description = "Radius of the sphere through the vertices", + min = 0.01, + soft_min = 0.01, + max = 100, + soft_max = 100, + default = 1.0) + vTrunc = FloatProperty(name = "Vertex Truncation", + description = "Ammount of vertex truncation", + min = 0.0, + soft_min = 0.0, + max = 2.0, + soft_max = 2.0, + default = 0.0, + precision = 3, + step = 0.5) + eTrunc = FloatProperty(name = "Edge Truncation", + description = "Ammount of edge truncation", + min = 0.0, + soft_min = 0.0, + max = 1.0, + soft_max = 1.0, + default = 0.0, + precision = 3, + step = 0.2) + snub = EnumProperty(items = (("None","No Snub",""), + ("Left","Left Snub",""), + ("Right","Right Snub","")), + name = "Snub", + description = "Create the snub version") + dual = BoolProperty(name="Dual", + description="Create the dual of the current solid", + default=False) + keepSize = BoolProperty(name="Keep Size", + description="Keep the whole solid at a constant size", + default=False) + preset = EnumProperty(items = (("0","Custom",""), + ("t4","Truncated Tetrahedron",""), + ("r4","Cuboctahedron",""), + ("t6","Truncated Cube",""), + ("t8","Truncated Octahedron",""), + ("b6","Rhombicuboctahedron",""), + ("c6","Truncated Cuboctahedron",""), + ("s6","Snub Cube",""), + ("r12","Icosidodecahedron",""), + ("t12","Truncated Dodecahedron",""), + ("t20","Truncated Icosahedron",""), + ("b12","Rhombicosidodecahedron",""), + ("c12","Truncated Icosidodecahedron",""), + ("s12","Snub Dodecahedron",""), + ("dt4","Triakis Tetrahedron",""), + ("dr4","Rhombic Dodecahedron",""), + ("dt6","Triakis Octahedron",""), + ("dt8","Tetrakis Hexahedron",""), + ("db6","Deltoidal Icositetrahedron",""), + ("dc6","Disdyakis Dodecahedron",""), + ("ds6","Pentagonal Icositetrahedron",""), + ("dr12","Rhombic Triacontahedron",""), + ("dt12","Triakis Icosahedron",""), + ("dt20","Pentakis Dodecahedron",""), + ("db12","Deltoidal Hexecontahedron",""), + ("dc12","Disdyakis Triacontahedron",""), + ("ds12","Pentagonal Hexecontahedron","")), + name = "Presets", + description = "Parameters for some hard names") + + # actual preset values + p = {"t4":["4",2/3,0,0,"None"], + "r4":["4",1,1,0,"None"], + "t6":["6",2/3,0,0,"None"], + "t8":["8",2/3,0,0,"None"], + "b6":["6",1.0938,1,0,"None"], + "c6":["6",1.0572,0.585786,0,"None"], + "s6":["6",1.0875,0.704,0,"Left"], + "r12":["12",1,0,0,"None"], + "t12":["12",2/3,0,0,"None"], + "t20":["20",2/3,0,0,"None"], + "b12":["12",1.1338,1,0,"None"], + "c12":["20",0.921,0.553,0,"None"], + "s12":["12",1.1235,0.68,0,"Left"], + "dt4":["4",2/3,0,1,"None"], + "dr4":["4",1,1,1,"None"], + "dt6":["6",2/3,0,1,"None"], + "dt8":["8",2/3,0,1,"None"], + "db6":["6",1.0938,1,1,"None"], + "dc6":["6",1.0572,0.585786,1,"None"], + "ds6":["6",1.0875,0.704,1,"Left"], + "dr12":["12",1,0,1,"None"], + "dt12":["12",2/3,0,1,"None"], + "dt20":["20",2/3,0,1,"None"], + "db12":["12",1.1338,1,1,"None"], + "dc12":["20",0.921,0.553,1,"None"], + "ds12":["12",1.1235,0.68,1,"Left"]} + + #previous preset, for User-friendly reasons + previousSetting = "" + + def execute(self,context): + # turn off undo for better performance (3-5x faster), also makes sure + # that mesh ops are undoable and entire script acts as one operator + bpy.context.user_preferences.edit.use_global_undo = False + + # piece of code to make presets remain until parameters are changed + if self.preset != "0": + #if preset, set preset + if self.previousSetting != self.preset: + using = self.p[self.preset] + self.source = using[0] + self.vTrunc = using[1] + self.eTrunc = using[2] + self.dual = using[3] + self.snub = using[4] + else: + using = self.p[self.preset] + result0 = self.source == using[0] + result1 = abs(self.vTrunc - using[1]) < 0.004 + result2 = abs(self.eTrunc - using[2]) < 0.0015 + result4 = using[4] == self.snub or ((using[4] == "Left") and + self.snub in ["Left","Right"]) + if (result0 and result1 and result2 and result4): + if self.p[self.previousSetting][3] != self.dual: + if self.preset[0] == "d": + self.preset = self.preset[1:] + else: + self.preset = "d" + self.preset + else: + self.preset = "0" + + self.previousSetting = self.preset + + # generate mesh + verts,faces = createSolid(self.source, + self.vTrunc, + self.eTrunc, + self.dual, + self.snub) + + # turn n-gons in quads and tri's + faces = createPolys(faces) + + # resize to normal size, or if keepSize, make sure all verts are of length 'size' + if self.keepSize: + rad = self.size/verts[-1 if self.dual else 0].length + else: rad = self.size + verts = [i*rad for i in verts] + + # generate object + # Create new mesh + mesh = bpy.data.meshes.new("Solid") + + # Make a mesh from a list of verts/edges/faces. + mesh.from_pydata(verts, [], faces) + + # Update mesh geometry after adding stuff. + mesh.update() + + object_data_add(context, mesh, operator=None) + # object generation done + + # turn undo back on + bpy.context.user_preferences.edit.use_global_undo = True + + return {'FINISHED'} diff --git a/add_mesh_extra_objects/add_mesh_supertoroid.py b/add_mesh_extra_objects/add_mesh_supertoroid.py index 425d2bd3..c9fd8f99 100644 --- a/add_mesh_extra_objects/add_mesh_supertoroid.py +++ b/add_mesh_extra_objects/add_mesh_supertoroid.py @@ -1,14 +1,7 @@ ''' -bl_info = { "name": "Add Mesh: SuperToroid", "author": "DreamPainter", "version": (1, 0, 0), - "blender": (2, 53, 0), - "location": "View3D > Add > Mesh > SuperToroid", - "description": "Add a SuperToroid mesh", - "url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" \ - "Scripts/Add_Mesh/", # no url - "category": "Add Mesh"} ''' import bpy from bpy.props import FloatProperty,BoolProperty,IntProperty @@ -212,18 +205,3 @@ class add_supertoroid(bpy.types.Operator): return {'FINISHED'} -''' -menu_func = lambda self, context: self.layout.operator(add_supertoroid.bl_idname, - text = "SuperToroid", icon = 'PLUGIN') - -def register(): - bpy.types.register(add_supertoroid) - bpy.types.INFO_MT_mesh_add.append(menu_func) - -def unregister(): - bpy.types.unregister(add_supertoroid) - bpy.types.INFO_MT_mesh_add.remove(menu_func) - -if __name__ == "__main__": - register() -''' diff --git a/add_mesh_extra_objects/add_mesh_teapot.py b/add_mesh_extra_objects/add_mesh_teapot.py index cdbdf7ee..d7cdfcd5 100644 --- a/add_mesh_extra_objects/add_mesh_teapot.py +++ b/add_mesh_extra_objects/add_mesh_teapot.py @@ -1,4 +1,4 @@ -'''# +---------------------------------------------------------+ +# +---------------------------------------------------------+ # | Copyright (c) 2005-2010 Anthony D'Agostino | # | http://home.comcast.net/~chronosphere | # | scorpius@netzero.com | @@ -24,18 +24,7 @@ # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # ***** END GPL LICENCE BLOCK ***** - -bl_info = { - "name": "Teapot+", - "author": "Anthony D'Agostino", - "version": (1, 0), - "blender": (2, 57, 0), - "location": "View3D > Add > Mesh ", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" - "Scripts/Add_Teapot", - "category": "Add Mesh", -} -''' +# "version": (1, 0, 0) import bpy from bpy.props import IntProperty @@ -46,7 +35,6 @@ import io import operator import functools - class AddTeapot(bpy.types.Operator): """Add a teapot mesh""" bl_idname = "mesh.primitive_teapot_add" @@ -70,24 +58,6 @@ class AddTeapot(bpy.types.Operator): obj = create_mesh_object(context, verts, [], faces, "Teapot") return {'FINISHED'} - -def menu_func(self, context): - self.layout.operator(AddTeapot.bl_idname, text="Teapot+", icon="MESH_CUBE") - - -def register(): - bpy.utils.register_module(__name__) - bpy.types.INFO_MT_mesh_add.append(menu_func) - - -def unregister(): - bpy.utils.unregister_module(__name__) - bpy.types.INFO_MT_mesh_add.remove(menu_func) - -if __name__ == "__main__": - register() - - def create_mesh_face_hack(faces): # FIXME, faces with duplicate vertices shouldn't be created in the first place. faces_copy = [] @@ -99,7 +69,6 @@ def create_mesh_face_hack(faces): faces_copy.append(f_copy) faces[:] = faces_copy - def create_mesh_object(context, verts, edges, faces, name): create_mesh_face_hack(faces) diff --git a/add_mesh_extra_objects/add_mesh_torusknot.py b/add_mesh_extra_objects/add_mesh_torusknot.py index e932adc8..3803ba62 100644 --- a/add_mesh_extra_objects/add_mesh_torusknot.py +++ b/add_mesh_extra_objects/add_mesh_torusknot.py @@ -1,4 +1,4 @@ -'''# +---------------------------------------------------------+ +# +---------------------------------------------------------+ # | Copyright (c) 2005-2010 Anthony D'Agostino | # | http://home.comcast.net/~chronosphere | # | scorpius@netzero.com | @@ -24,18 +24,7 @@ # Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. # # ***** END GPL LICENCE BLOCK ***** - -bl_info = { - "name": "Torus Knot", - "author": "Anthony D'Agostino", - "version": (1, 0), - "blender": (2, 57, 0), - "location": "View3D > Add > Mesh ", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" - "Scripts/Add_TorusKnot", - "category": "Add Mesh", -} -''' +# "version": (1, 0, 0) import bpy, mathutils, math def create_mesh_object(context, verts, edges, faces, name): @@ -135,18 +124,3 @@ class AddTorusKnot(bpy.types.Operator): self.resolution) obj = create_mesh_object(context, verts, [], faces, "Torus Knot") return {'FINISHED'} -''' -def menu_func(self, context): - self.layout.operator(AddTorusKnot.bl_idname, text="Torus Knot", icon="MESH_CUBE") - -def register(): - bpy.utils.register_module(__name__) - bpy.types.INFO_MT_mesh_add.append(menu_func) - -def unregister(): - bpy.utils.unregister_module(__name__) - bpy.types.INFO_MT_mesh_add.remove(menu_func) - -if __name__ == "__main__": - register() -''' diff --git a/add_mesh_extra_objects/add_mesh_twisted_torus.py b/add_mesh_extra_objects/add_mesh_twisted_torus.py index fd3cb5e8..2392a293 100644 --- a/add_mesh_extra_objects/add_mesh_twisted_torus.py +++ b/add_mesh_extra_objects/add_mesh_twisted_torus.py @@ -19,35 +19,22 @@ # Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # ***** END GPL LICENCE BLOCK ***** -""" -bl_info = { - "name": "Twisted Torus", - "author": "Paulo_Gomes", - "version": (0, 11, 1), - "blender": (2, 57, 0), - "location": "View3D > Add > Mesh ", - "description": "Adds a mesh Twisted Torus to the Add Mesh menu", - "warning": "", - "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.5/Py/" - "Scripts/Add_Mesh/Add_Twisted_Torus", - "category": "Add Mesh", -} +#twisted torus by Paulo_Gomes +# "version": (0, 11, 1) +""" Usage: * Launch from Add Mesh menu * Modify parameters as desired or keep defaults """ - - import bpy from bpy.props import * from mathutils import * from math import cos, sin, pi - # Create a new mesh (object) from verts/edges/faces. # verts/edges/faces ... List of vertices/edges/faces for the # new mesh (as used in from_pydata). @@ -79,6 +66,7 @@ def create_mesh_object(context, verts, edges, faces, name): # 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 = [] @@ -134,7 +122,6 @@ def createFaces(vertIdx1, vertIdx2, closed=False, flipped=False): return faces - def add_twisted_torus(major_rad, minor_rad, major_seg, minor_seg, twists): PI_2 = pi * 2.0 z_axis = (0.0, 0.0, 1.0) @@ -179,7 +166,6 @@ def add_twisted_torus(major_rad, minor_rad, major_seg, minor_seg, twists): return verts, faces - class AddTwistedTorus(bpy.types.Operator): """Add a torus mesh""" bl_idname = "mesh.primitive_twisted_torus_add" @@ -245,4 +231,3 @@ class AddTwistedTorus(bpy.types.Operator): obj = create_mesh_object(context, verts, [], faces, "TwistedTorus") return {'FINISHED'} - |