Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender-addons.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormeta-androcto <meta.androcto1@gmail.com>2016-06-13 04:13:28 +0300
committermeta-androcto <meta.androcto1@gmail.com>2016-06-13 04:13:28 +0300
commiteedce73b26ad84af51b8582a93efe7539b6310ce (patch)
tree1e2e149f7114b557a8356db6e1660867208ae924
parentc4a79435e45610d50dadfacf2ed2c09ce595f70f (diff)
Update mesh_extra_objects: T48640
-rw-r--r--add_mesh_extra_objects/Wallfactory.py647
-rw-r--r--add_mesh_extra_objects/__init__.py47
-rw-r--r--add_mesh_extra_objects/add_mesh_beam_builder.py738
-rw-r--r--add_mesh_extra_objects/geodesic_domes/__init__.py49
-rw-r--r--add_mesh_extra_objects/geodesic_domes/add_shape_geodesic.py100
-rw-r--r--add_mesh_extra_objects/geodesic_domes/forms_271.py232
-rw-r--r--add_mesh_extra_objects/geodesic_domes/geodesic_classes_271.py741
-rw-r--r--add_mesh_extra_objects/geodesic_domes/third_domes_panel_271.py1016
-rw-r--r--add_mesh_extra_objects/geodesic_domes/vefm_271.py1169
-rw-r--r--add_mesh_extra_objects/mesh_discombobulator.py685
10 files changed, 5422 insertions, 2 deletions
diff --git a/add_mesh_extra_objects/Wallfactory.py b/add_mesh_extra_objects/Wallfactory.py
new file mode 100644
index 00000000..8c7fb935
--- /dev/null
+++ b/add_mesh_extra_objects/Wallfactory.py
@@ -0,0 +1,647 @@
+# ***** 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 *****
+
+#
+# This module contains the UI definition, display, and processing (create mesh)
+# functions.
+#
+# The routines to generate the vertices for the wall are found in the "Blocks" module.
+#
+
+
+import bpy
+import mathutils
+from bpy.props import *
+from add_mesh_building_objects.Blocks import *
+#from add_mesh_walls.preset_utils import *
+
+
+#
+class add_mesh_wallb(bpy.types.Operator):
+ """Add a wall mesh"""
+ bl_idname = "mesh.wall_add"
+ bl_label = "Add A Masonry Wall"
+ bl_options = {'REGISTER', 'UNDO'} # removes object, does not reset to "last" modification.
+ bl_description = "adds a block wall"
+
+ # UI items - API for properties - User accessable variables...
+# not all options are via UI, and some operations just don't work yet.
+
+ # only create object when True
+ # False allows modifying several parameters without creating object
+ ConstructTog = BoolProperty(name="Construct",
+ description="Generate the object",
+ default = True)
+
+# need to modify so radial makes a tower (normal); want "flat" setting to make disk (alternate)
+ # make the wall circular - if not sloped it's a flat disc
+ RadialTog = BoolProperty(name="Radial",
+ description="Make masonry radial",
+ default = False)
+
+ # curve the wall - if radial creates dome.
+ SlopeTog = BoolProperty(name="Curved",
+ description="Make masonry sloped, or curved",
+ default = False)
+
+#need to review defaults and limits for all of these UI objects.
+
+ # wall area/size
+ WallStart = FloatProperty(name="Start",
+ description="Left side, or start angle",
+ default=-10.0, min=-100, max=100.0)
+ WallEnd = FloatProperty(name="End",
+ description="Right side, or end angle",
+ default=10.0, min=0.0, max=100.0)
+ WallBottom = FloatProperty(name="Bottom",
+ description="Lower height or radius",
+ default=0.0, min=-100, max=100)
+ WallTop = FloatProperty(name="Top",
+ description="Upper height or radius",
+ default=15.0, min=0.0, max=100.0)
+ EdgeOffset = FloatProperty(name="Edging",
+ description="Block staggering on wall sides",
+ default=0.6, min=0.0, max=100.0)
+
+ # block sizing
+ Width = FloatProperty(name="Width",
+ description="Average width of each block",
+ default=1.5, min=0.01, max=100.0)
+ WidthVariance = FloatProperty(name="Variance",
+ description="Random variance of block width",
+ default=0.5, min=0.0, max=100.0)
+ WidthMinimum = FloatProperty(name="Minimum",
+ description="Absolute minimum block width",
+ default=0.5, min=0.01, max=100.0)
+ Height = FloatProperty(name="Height",
+ description="Average Height of each block",
+ default=0.7, min=0.01, max=100.0)
+ HeightVariance = FloatProperty(name="Variance",
+ description="Random variance of block Height",
+ default=0.3, min=0.0, max=100.0)
+ HeightMinimum = FloatProperty(name="Minimum",
+ description="Absolute minimum block Height",
+ default=0.25, min=0.01, max=100.0)
+ Depth = FloatProperty(name="Depth",
+ description="Average Depth of each block",
+ default=2.0, min=0.01, max=100.0)
+ DepthVariance = FloatProperty(name="Variance",
+ description="Random variance of block Depth",
+ default=0.1, min=0.0, max=100.0)
+ DepthMinimum = FloatProperty(name="Minimum",
+ description="Absolute minimum block Depth",
+ default=1.0, min=0.01, max=100.0)
+ MergeBlock = BoolProperty(name="Merge Blocks",
+ description="Make big blocks (merge closely adjoining blocks)",
+ default = False)
+
+ # edging for blocks
+ Grout = FloatProperty(name="Thickness",
+ description="Distance between blocks",
+ default=0.1, min=-10.0, max=10.0)
+ GroutVariance = FloatProperty(name="Variance",
+ description="Random variance of block Grout",
+ default=0.03, min=0.0, max=100.0)
+ GroutDepth = FloatProperty(name="Depth",
+ description="Grout Depth from the face of the blocks",
+ default=0.1, min=0.0001, max=10.0)
+ GroutDepthVariance = FloatProperty(name="Variance",
+ description="Random variance of block Grout Depth",
+ default=0.03, min=0.0, max=100.0)
+ GroutEdge = BoolProperty(name="Edging",
+ description="Grout perimiter",
+ default = False)
+
+ #properties for openings
+ Opening1Tog = BoolProperty(name="Opening(s)",description="Make windows or doors", default = True)
+ Opening1Width = FloatProperty(name="Width",
+ description="The Width of opening 1",
+ default=2.5, min=0.01, max=100.0)
+ Opening1Height = FloatProperty(name="Height",
+ description="The Height of opening 1",
+ default=3.5, min=0.01, max=100.0)
+ Opening1X = FloatProperty(name="Indent",
+ description="The x position or spacing of opening 1",
+ default=5.0, min=-100, max=100.0)
+ Opening1Z = FloatProperty(name="Bottom",
+ description="The z position of opening 1",
+ default=5.0, min=-100, max=100.0)
+ Opening1Repeat = BoolProperty(name="Repeat",
+ description="make multiple openings, with spacing X1",
+ default=False)
+ Opening1TopArchTog = BoolProperty(name="Top Arch",
+ description="Add an arch to the top of opening 1",
+ default=True)
+ Opening1TopArch = FloatProperty(name="Curve",
+ description="Height of the arch on the top of the opening",
+ default=2.5, min=0.001, max=100.0)
+ Opening1TopArchThickness = FloatProperty(name="Thickness",
+ description="Thickness of the arch on the top of the opening",
+ default=0.75, min=0.001, max=100.0)
+ Opening1BtmArchTog = BoolProperty(name="Bottom Arch",
+ description="Add an arch to the bottom of opening 1",
+ default=False)
+ Opening1BtmArch = FloatProperty(name="Curve",
+ description="Height of the arch on the bottom of the opening",
+ default=1.0, min=0.01, max=100.0)
+ Opening1BtmArchThickness = FloatProperty(name="Thickness",
+ description="Thickness of the arch on the bottom of the opening",
+ default=0.5, min=0.01, max=100.0)
+ Opening1Bevel = FloatProperty(name="Bevel",
+ description="Angle block face",
+ default=0.25, min=-10.0, max=10.0)
+
+
+ # openings on top of wall.
+ CrenelTog = BoolProperty(name="Crenels",
+ description="Make openings along top of wall",
+ default = False)
+ CrenelXP = FloatProperty(name="Width %",
+ description="Gap width in wall based % of wall width",
+ default=0.25, min=0.10, max=1.0)
+ CrenelZP = FloatProperty(name="Height %",
+ description="Crenel Height as % of wall height",
+ default=0.10, min=0.10, max=1.0)
+
+
+ # narrow openings in wall.
+#need to prevent overlap with arch openings - though inversion is an interesting effect.
+ SlotTog = BoolProperty(name="Slots",
+ description="Make narrow openings in wall",
+ default = False)
+ SlotRpt = BoolProperty(name="Repeat",
+ description="Repeat slots along wall",
+ default = False)
+ SlotWdg = BoolProperty(name="Wedged (n/a)",
+ description="Bevel edges of slots",
+ default = False)
+ SlotX = FloatProperty(name="Indent",
+ description="The x position or spacing of slots",
+ default=0.0, min=-100, max=100.0)
+ SlotGap = FloatProperty(name="Opening",
+ description="The opening size of slots",
+ default=0.5, min=0.10, max=100.0)
+ SlotV = BoolProperty(name="Vertical",
+ description="Vertical slots",
+ default = True)
+ SlotVH = FloatProperty(name="Height",
+ description="Height of vertical slot",
+ default=3.5, min=0.10, max=100.0)
+ SlotVBtm = FloatProperty(name="Bottom",
+ description="Z position for slot",
+ default=5.00, min=-100.0, max=100.0)
+ SlotH = BoolProperty(name="Horizontal",
+ description="Horizontal slots",
+ default = False)
+ SlotHW = FloatProperty(name="Width",
+ description="Width of horizontal slot",
+ default=2.5, min=0.10, max=100.0)
+#this should offset from VBtm... maybe make a % like crenels?
+ SlotHBtm = FloatProperty(name="Bottom",
+ description="Z position for horizontal slot",
+ default=5.50, min=-100.0, max=100.0)
+
+
+ #properties for shelf (extend blocks in area)
+ ShelfTog = BoolProperty(name="Shelf",description="Add blocks in area by depth to make shelf/platform", default = False)
+ ShelfX = FloatProperty(name="Left",
+ description="The x position of Shelf",
+ default=-5.00, min=-100, max=100.0)
+ ShelfZ = FloatProperty(name="Bottom",
+ description="The z position of Shelf",
+ default=10.0, min=-100, max=100.0)
+ ShelfH = FloatProperty(name="Height",
+ description="The Height of Shelf area",
+ default=1.0, min=0.01, max=100.0)
+ ShelfW = FloatProperty(name="Width",
+ description="The Width of shelf area",
+ default=5.0, min=0.01, max=100.0)
+ ShelfD = FloatProperty(name="Depth",
+ description="Depth of each block for shelf (from cursor + 1/2 wall depth)",
+ default=2.0, min=0.01, max=100.0)
+ ShelfBack = BoolProperty(name="Backside",description="Shelf on backside of wall", default = False)
+
+
+ #properties for steps (extend blocks in area, progressive width)
+ StepTog = BoolProperty(name="Steps",description="Add blocks in area by depth with progressive width to make steps", default = False)
+ StepX = FloatProperty(name="Left",
+ description="The x position of steps",
+ default=-9.00, min=-100, max=100.0)
+ StepZ = FloatProperty(name="Bottom",
+ description="The z position of steps",
+ default=0.0, min=-100, max=100.0)
+ StepH = FloatProperty(name="Height",
+ description="The Height of step area",
+ default=10.0, min=0.01, max=100.0)
+ StepW = FloatProperty(name="Width",
+ description="The Width of step area",
+ default=8.0, min=0.01, max=100.0)
+ StepD = FloatProperty(name="Depth",
+ description="Depth of each block for steps (from cursor + 1/2 wall depth)",
+ default=1.0, min=0.01, max=100.0)
+ StepV = FloatProperty(name="Riser",
+ description="Height of each step",
+ default=0.70, min=0.01, max=100.0)
+ StepT = FloatProperty(name="Tread",
+ description="Width of each step",
+ default=1.0, min=0.01, max=100.0)
+ StepLeft = BoolProperty(name="High Left",description="Height left; else Height right", default = False)
+ StepOnly = BoolProperty(name="No Blocks",description="Steps only, no supporting blocks", default = False)
+ StepBack = BoolProperty(name="Backside",description="Steps on backside of wall", default = False)
+
+##
+##
+#####
+# Show the UI - expose the properties.
+#####
+##
+##
+ # Display the toolbox options
+
+ def draw(self, context):
+
+ layout = self.layout
+
+ box = layout.box()
+ box.prop(self, 'ConstructTog')
+
+# Wall area (size/position)
+ box = layout.box()
+ box.label(text='Wall Size (area)')
+ box.prop(self, 'WallStart')
+ box.prop(self, 'WallEnd')
+ box.prop(self, 'WallBottom')
+ box.prop(self, 'WallTop')
+ box.prop(self, 'EdgeOffset')
+
+# Wall block sizing
+ box = layout.box()
+ box.label(text='Block Sizing')
+ box.prop(self, 'MergeBlock')
+#add checkbox for "fixed" sizing (ignore variance) a.k.a. bricks.
+ box.prop(self, 'Width')
+ box.prop(self, 'WidthVariance')
+ box.prop(self, 'WidthMinimum')
+ box.prop(self, 'Height')
+ box.prop(self, 'HeightVariance')
+ box.prop(self, 'HeightMinimum')
+ box.prop(self, 'Depth')
+ box.prop(self, 'DepthVariance')
+ box.prop(self, 'DepthMinimum')
+
+# grout settings
+ box = layout.box()
+ bl_label = "Grout"
+ box.label(text='Grout')
+ box.prop(self, 'Grout')
+ box.prop(self, 'GroutVariance')
+ box.prop(self, 'GroutDepth')
+ box.prop(self, 'GroutDepthVariance')
+# box.prop(self, 'GroutEdge')
+
+# Wall shape modifiers
+ box = layout.box()
+ box.label(text='Wall Shape')
+ box.prop(self, 'RadialTog')
+ box.prop(self, 'SlopeTog')
+
+# Openings (doors, windows; arched)
+ box = layout.box()
+ box.prop(self, 'Opening1Tog')
+ if self.properties.Opening1Tog:
+ box.prop(self, 'Opening1Width')
+ box.prop(self, 'Opening1Height')
+ box.prop(self, 'Opening1X')
+ box.prop(self, 'Opening1Z')
+ box.prop(self, 'Opening1Bevel')
+ box.prop(self, 'Opening1Repeat')
+ box.prop(self, 'Opening1TopArchTog')
+ box.prop(self, 'Opening1TopArch')
+ box.prop(self, 'Opening1TopArchThickness')
+ box.prop(self, 'Opening1BtmArchTog')
+ box.prop(self, 'Opening1BtmArch')
+ box.prop(self, 'Opening1BtmArchThickness')
+
+# Slots (narrow openings)
+ box = layout.box()
+ box.prop(self, 'SlotTog')
+ if self.properties.SlotTog:
+# box.prop(self, 'SlotWdg')
+ box.prop(self, 'SlotX')
+ box.prop(self, 'SlotGap')
+ box.prop(self, 'SlotRpt')
+ box.prop(self, 'SlotV')
+ box.prop(self, 'SlotVH')
+ box.prop(self, 'SlotVBtm')
+ box.prop(self, 'SlotH')
+ box.prop(self, 'SlotHW')
+ box.prop(self, 'SlotHBtm')
+
+# Crenels, gaps in top of wall
+ box = layout.box()
+ box.prop(self, 'CrenelTog')
+ if self.properties.CrenelTog:
+ box.prop(self, 'CrenelXP')
+ box.prop(self, 'CrenelZP')
+
+# Shelfing (protrusions)
+ box = layout.box()
+ box.prop(self, 'ShelfTog')
+ if self.properties.ShelfTog:
+ box.prop(self, 'ShelfX')
+ box.prop(self, 'ShelfZ')
+ box.prop(self, 'ShelfH')
+ box.prop(self, 'ShelfW')
+ box.prop(self, 'ShelfD')
+ box.prop(self, 'ShelfBack')
+
+# Steps
+ box = layout.box()
+ box.prop(self, 'StepTog')
+ if self.properties.StepTog:
+ box.prop(self, 'StepX')
+ box.prop(self, 'StepZ')
+ box.prop(self, 'StepH')
+ box.prop(self, 'StepW')
+ box.prop(self, 'StepD')
+ box.prop(self, 'StepV')
+ box.prop(self, 'StepT')
+ box.prop(self, 'StepLeft')
+ box.prop(self, 'StepOnly')
+ box.prop(self, 'StepBack')
+
+##
+#####
+# Respond to UI - get the properties set by user.
+#####
+##
+ # Check and process UI settings to generate masonry
+
+ def execute(self, context):
+
+ global radialized
+ global slope
+ global openingSpecs
+ global bigBlock
+ global shelfExt
+ global stepMod
+ global stepLeft
+ global shelfBack
+ global stepOnly
+ global stepBack
+
+ # Create the wall when enabled (skip regen iterations when off)
+ if not self.properties.ConstructTog: return {'FINISHED'}
+
+ #enter the settings for the wall dimensions (area)
+# start can't be zero - min/max don't matter [if max less than end] but zero don't workie.
+# start can't exceed end.
+ if not self.properties.WallStart or self.properties.WallStart >= self.properties.WallEnd:
+ self.properties.WallStart = NOTZERO # Reset UI if input out of bounds...
+
+ dims['s'] = self.properties.WallStart
+ dims['e'] = self.properties.WallEnd
+ dims['b'] = self.properties.WallBottom
+ dims['t'] = self.properties.WallTop
+
+ settings['eoff'] = self.properties.EdgeOffset
+
+ #retrieve the settings for the wall block properties
+ settings['w'] = self.properties.Width
+ settings['wv'] = self.properties.WidthVariance
+ settings['wm'] = self.properties.WidthMinimum
+ if not radialized: settings['sdv'] = settings['w']
+ else: settings['sdv'] = 0.12
+
+ settings['h'] = self.properties.Height
+ settings['hv'] = self.properties.HeightVariance
+ settings['hm'] = self.properties.HeightMinimum
+
+ settings['d'] = self.properties.Depth
+ settings['dv'] = self.properties.DepthVariance
+ settings['dm'] = self.properties.DepthMinimum
+
+ if self.properties.MergeBlock:
+ bigBlock = 1
+ else: bigBlock = 0
+
+ settings['g'] = self.properties.Grout
+ settings['gv'] = self.properties.GroutVariance
+ settings['gd'] = self.properties.GroutDepth
+ settings['gdv'] = self.properties.GroutDepthVariance
+
+ if self.properties.GroutEdge: settings['ge'] = 1
+ else: settings['ge'] = 0
+
+ # set wall shape modifiers
+ if self.properties.RadialTog:
+ radialized = 1
+#eliminate to allow user control for start/completion?
+ dims['s'] = 0.0 # complete radial
+ if dims['e'] > PI*2: dims['e'] = PI*2 # max end for circle
+ if dims['b'] < settings['g']: dims['b'] = settings['g'] # min bottom for grout extension
+ else: radialized = 0
+
+ if self.properties.SlopeTog: slope = 1
+ else: slope = 0
+
+
+ shelfExt = 0
+ shelfBack = 0
+
+ # Add shelf if enabled
+ if self.properties.ShelfTog:
+ shelfExt = 1
+ shelfSpecs['h'] = self.properties.ShelfH
+ shelfSpecs['w'] = self.properties.ShelfW
+ shelfSpecs['d'] = self.properties.ShelfD
+ shelfSpecs['x'] = self.properties.ShelfX
+ shelfSpecs['z'] = self.properties.ShelfZ
+
+ if self.properties.ShelfBack:
+ shelfBack = 1
+
+
+ stepMod = 0
+ stepLeft = 0
+ stepOnly = 0
+ stepBack = 0
+
+ # Make steps if enabled
+ if self.properties.StepTog:
+ stepMod = 1
+ stepSpecs['x'] = self.properties.StepX
+ stepSpecs['z'] = self.properties.StepZ
+ stepSpecs['h'] = self.properties.StepH
+ stepSpecs['w'] = self.properties.StepW
+ stepSpecs['d'] = self.properties.StepD
+ stepSpecs['v'] = self.properties.StepV
+ stepSpecs['t'] = self.properties.StepT
+
+ if self.properties.StepLeft:
+ stepLeft = 1
+
+ if self.properties.StepOnly:
+ stepOnly = 1
+
+ if self.properties.StepBack:
+ stepBack = 1
+
+
+ #enter the settings for the openings
+#when openings overlap they create inverse stonework - interesting but not the desired effect :)
+#if opening width == indent*2 the edge blocks fail (row of blocks cross opening) - bug.
+ openingSpecs = []
+ openingIdx = 0 # track opening array references for multiple uses
+
+ # general openings with arch options - can be windows or doors.
+ if self.properties.Opening1Tog:
+ # set defaults...
+ openingSpecs += [{'w':0.5, 'h':0.5, 'x':0.8, 'z':2.7, 'rp':1, 'b':0.0, 'v':0, 'vl':0, 't':0, 'tl':0}]
+
+ openingSpecs[openingIdx]['w'] = self.properties.Opening1Width
+ openingSpecs[openingIdx]['h'] = self.properties.Opening1Height
+ openingSpecs[openingIdx]['x'] = self.properties.Opening1X
+ openingSpecs[openingIdx]['z'] = self.properties.Opening1Z
+ openingSpecs[openingIdx]['rp'] = self.properties.Opening1Repeat
+
+ if self.properties.Opening1TopArchTog:
+ openingSpecs[openingIdx]['v'] = self.properties.Opening1TopArch
+ openingSpecs[openingIdx]['t'] = self.properties.Opening1TopArchThickness
+
+ if self.properties.Opening1BtmArchTog:
+ openingSpecs[openingIdx]['vl'] = self.properties.Opening1BtmArch
+ openingSpecs[openingIdx]['tl'] = self.properties.Opening1BtmArchThickness
+
+ openingSpecs[openingIdx]['b'] = self.properties.Opening1Bevel
+
+ openingIdx += 1 # count window/door/arch openings
+
+ # Slots (narrow openings)
+ if self.properties.SlotTog:
+
+ if self.properties.SlotV: # vertical slots
+ # set defaults...
+ openingSpecs += [{'w':0.5, 'h':0.5, 'x':0.0, 'z':2.7, 'rp':0, 'b':0.0, 'v':0, 'vl':0, 't':0, 'tl':0}]
+
+ openingSpecs[openingIdx]['w'] = self.properties.SlotGap
+ openingSpecs[openingIdx]['h'] = self.properties.SlotVH
+ openingSpecs[openingIdx]['x'] = self.properties.SlotX
+ openingSpecs[openingIdx]['z'] = self.properties.SlotVBtm
+ openingSpecs[openingIdx]['rp'] = self.properties.SlotRpt
+
+ # make them pointy...
+ openingSpecs[openingIdx]['v'] = self.properties.SlotGap
+ openingSpecs[openingIdx]['t'] = self.properties.SlotGap/2
+ openingSpecs[openingIdx]['vl'] = self.properties.SlotGap
+ openingSpecs[openingIdx]['tl'] = self.properties.SlotGap/2
+
+ openingIdx += 1 # count vertical slot openings
+
+# need to handle overlap of H and V slots...
+
+ if self.properties.SlotH: # Horizontal slots
+ # set defaults...
+ openingSpecs += [{'w':0.5, 'h':0.5, 'x':0.0, 'z':2.7, 'rp':0, 'b':0.0, 'v':0, 'vl':0, 't':0, 'tl':0}]
+
+ openingSpecs[openingIdx]['w'] = self.properties.SlotHW
+ openingSpecs[openingIdx]['h'] = self.properties.SlotGap
+ openingSpecs[openingIdx]['x'] = self.properties.SlotX
+ openingSpecs[openingIdx]['z'] = self.properties.SlotHBtm
+#horizontal repeat isn't same spacing as vertical...
+ openingSpecs[openingIdx]['rp'] = self.properties.SlotRpt
+
+ # make them pointy...
+# want arc to go sideways... maybe wedge will be sufficient and can skip horiz arcs.
+# openingSpecs[openingIdx]['v'] = self.properties.SlotGap
+# openingSpecs[openingIdx]['t'] = self.properties.SlotGap/2
+# openingSpecs[openingIdx]['vl'] = self.properties.SlotGap
+# openingSpecs[openingIdx]['tl'] = self.properties.SlotGap/2
+
+ openingIdx += 1 # count horizontal slot openings
+
+
+ # Crenellations (top row openings)
+ if self.properties.CrenelTog:
+
+# add bottom arch option?
+# perhaps a repeat toggle...
+# if crenel opening overlaps with arch opening it fills with blocks...
+
+ # set defaults...
+ openingSpecs += [{'w':0.5, 'h':0.5, 'x':0.0, 'z':2.7, 'rp':1, 'b':0.0, 'v':0, 'vl':0, 't':0, 'tl':0}]
+
+ wallW = self.properties.WallEnd - self.properties.WallStart
+ crenelW = wallW*self.properties.CrenelXP # Width % opening.
+
+ wallH = self.properties.WallTop - self.properties.WallBottom
+ crenelH = wallH*self.properties.CrenelZP # % proportional height.
+
+ openingSpecs[openingIdx]['w'] = crenelW
+ openingSpecs[openingIdx]['h'] = crenelH
+
+ # calculate the spacing between openings.
+ # this isn't the absolute start (left), it's opening center offset relative to cursor (space between openings)...
+ openingSpecs[openingIdx]['x'] = crenelW*2-1 # assume standard spacing
+
+ if not radialized: # normal wall?
+ # set indent 0 (center) if opening is 50% or more of wall width, no repeat.
+ if crenelW*2 >= wallW:
+ openingSpecs[openingIdx]['x'] = 0
+ openingSpecs[openingIdx]['rp'] = 0
+
+ openingSpecs[openingIdx]['z'] = self.properties.WallTop - (crenelH/2) # set bottom of opening (center of hole)
+
+ openingIdx += 1 # count crenel openings
+
+ #
+ # Process the user settings to generate a wall
+ #
+ # generate the list of vertices for the wall...
+ verts_array, faces_array = createWall(radialized, slope, openingSpecs, bigBlock,
+ shelfExt, shelfBack, stepMod, stepLeft, stepOnly, stepBack)
+
+ # Create new mesh
+ mesh = bpy.data.meshes.new("Wall")
+
+ # Make a mesh from a list of verts/edges/faces.
+ mesh.from_pydata(verts_array, [], faces_array)
+
+ scene = context.scene
+
+ # Deselect all objects.
+ bpy.ops.object.select_all(action='DESELECT')
+
+ mesh.update()
+
+ ob_new = bpy.data.objects.new("Wall", mesh)
+ scene.objects.link(ob_new)
+# leave this out to prevent 'Tab key" going into edit mode :):):)
+# Use rmb click to select and still modify.
+ scene.objects.active = ob_new
+ ob_new.select = True
+
+ ob_new.location = tuple(context.scene.cursor_location)
+ ob_new.rotation_quaternion = [1.0,0.0,0.0,0.0]
+
+ return {'FINISHED'}
diff --git a/add_mesh_extra_objects/__init__.py b/add_mesh_extra_objects/__init__.py
index 0b14f3dc..98dc1e0c 100644
--- a/add_mesh_extra_objects/__init__.py
+++ b/add_mesh_extra_objects/__init__.py
@@ -32,6 +32,14 @@ bl_info = {
"category": "Add Mesh",
}
+from .geodesic_domes import __init__
+from .geodesic_domes import add_shape_geodesic
+from .geodesic_domes import forms_271
+from .geodesic_domes import geodesic_classes_271
+from .geodesic_domes import third_domes_panel_271
+from .geodesic_domes import vefm_271
+
+
if "bpy" in locals():
import importlib
importlib.reload(add_mesh_star)
@@ -51,6 +59,9 @@ if "bpy" in locals():
importlib.reload(add_mesh_menger_sponge)
importlib.reload(add_mesh_vertex)
importlib.reload(add_empty_as_parent)
+ importlib.reload(mesh_discombobulator)
+ importlib.reload(add_mesh_beam_builder)
+ importlib.reload(Wallfactory)
else:
from . import add_mesh_star
from . import add_mesh_twisted_torus
@@ -69,7 +80,9 @@ else:
from . import add_mesh_menger_sponge
from . import add_mesh_vertex
from . import add_empty_as_parent
-
+ from . import mesh_discombobulator
+ from . import add_mesh_beam_builder
+ from . import Wallfactory
import bpy
@@ -146,6 +159,10 @@ class INFO_MT_mesh_extras_add(bpy.types.Menu):
layout = self.layout
layout.operator_context = 'INVOKE_REGION_WIN'
layout.menu("INFO_MT_mesh_diamonds_add", text="Diamonds", icon="PMARKER_SEL")
+ layout.operator("mesh.add_beam",
+ text="Beam Builder")
+ layout.operator("mesh.wall_add",
+ text="Wall Factory")
layout.operator("mesh.primitive_star_add",
text="Simple Star")
layout.operator("mesh.primitive_steppyramid_add",
@@ -202,6 +219,7 @@ def menu_func(self, context):
self.layout.menu("INFO_MT_mesh_vert_add", text="Single Vert", icon="LAYER_ACTIVE")
self.layout.operator("mesh.primitive_round_cube_add", text="Round Cube", icon="MOD_SUBSURF")
self.layout.menu("INFO_MT_mesh_math_add", text="Math Function", icon="PACKAGE")
+ self.layout.operator("mesh.generate_geodesic_dome", text="Geodesic Dome",icon="MESH_ICOSPHERE")
self.layout.menu("INFO_MT_mesh_pipe_joints_add", text="Pipe Joints", icon="SNAP_PEEL_OBJECT")
self.layout.menu("INFO_MT_mesh_gears_add", text="Gears", icon="SCRIPTWIN")
self.layout.menu("INFO_MT_mesh_torus_add", text="Torus Objects", icon="MESH_TORUS")
@@ -213,7 +231,32 @@ def menu_func(self, context):
def register():
bpy.utils.register_module(__name__)
-
+ # Protusions Buttons:
+ bpy.types.Scene.repeatprot = bpy.props.IntProperty(name="Repeat protusions", description="make several layers of protusion", default = 1, min = 1, max = 10)
+ bpy.types.Scene.doprots = bpy.props.BoolProperty(name="Make protusions", description = "Check if we want to add protusions to the mesh", default = True)
+ bpy.types.Scene.polygonschangedpercent = bpy.props.FloatProperty(name="Polygon %", description = "Percentage of changed polygons", default = 1.0)
+ bpy.types.Scene.minHeight = bpy.props.FloatProperty(name="Min height", description="Minimal height of the protusions", default=0.2)
+ bpy.types.Scene.maxHeight = bpy.props.FloatProperty(name="Max height", description="Maximal height of the protusions", default = 0.4)
+ bpy.types.Scene.minTaper = bpy.props.FloatProperty(name="Min taper", description="Minimal height of the protusions", default=0.15, min = 0.0, max = 1.0, subtype = 'PERCENTAGE')
+ bpy.types.Scene.maxTaper = bpy.props.FloatProperty(name="Max taper", description="Maximal height of the protusions", default = 0.35, min = 0.0, max = 1.0, subtype = 'PERCENTAGE')
+ bpy.types.Scene.subpolygon1 = bpy.props.BoolProperty(name="1", default = True)
+ bpy.types.Scene.subpolygon2 = bpy.props.BoolProperty(name="2", default = True)
+ bpy.types.Scene.subpolygon3 = bpy.props.BoolProperty(name="3", default = True)
+ bpy.types.Scene.subpolygon4 = bpy.props.BoolProperty(name="4", default = True)
+
+ # Doodads buttons:
+ bpy.types.Scene.dodoodads = bpy.props.BoolProperty(name="Make doodads", description = "Check if we want to generate doodads", default = True)
+ bpy.types.Scene.mindoodads = bpy.props.IntProperty(name="Minimum doodads number", description = "Ask for the minimum number of doodads to generate per polygon", default = 1, min = 0, max = 50)
+ bpy.types.Scene.maxdoodads = bpy.props.IntProperty(name="Maximum doodads number", description = "Ask for the maximum number of doodads to generate per polygon", default = 6, min = 1, max = 50)
+ bpy.types.Scene.doodMinScale = bpy.props.FloatProperty(name="Scale min", description="Minimum scaling of doodad", default = 0.5, min = 0.0, max = 1.0, subtype = 'PERCENTAGE')
+ bpy.types.Scene.doodMaxScale = bpy.props.FloatProperty(name="Scale max", description="Maximum scaling of doodad", default = 1.0, min = 0.0, max = 1.0, subtype = 'PERCENTAGE')
+
+ # Materials buttons:
+ bpy.types.Scene.sideProtMat = bpy.props.IntProperty(name="Side's prot mat", description = "Material of protusion's sides", default = 0, min = 0)
+ bpy.types.Scene.topProtMat = bpy.props.IntProperty(name = "Prot's top mat", description = "Material of protusion's top", default = 0, min = 0)
+
+
+
# Add "Extras" menu to the "Add Mesh" menu
bpy.types.INFO_MT_mesh_add.append(menu_func)
diff --git a/add_mesh_extra_objects/add_mesh_beam_builder.py b/add_mesh_extra_objects/add_mesh_beam_builder.py
new file mode 100644
index 00000000..3f7cf285
--- /dev/null
+++ b/add_mesh_extra_objects/add_mesh_beam_builder.py
@@ -0,0 +1,738 @@
+################################################################################
+# ***** BEGIN GPL LICENSE BLOCK *****
+#
+# This is free software; you may redistribute it, and/or modify it,
+# under the terms of the GNU General Public License.
+#
+# 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 (http://www.gnu.org/licenses/) for more details.
+#
+# ***** END GPL LICENSE BLOCK *****
+'''
+Create "Beam" primitives. Based on original script by revolt_randy.
+'''
+# Author(s): revolt_randy, Jambay
+#
+# @todo: track 3D cursor for location.
+#
+################################################################################
+
+import bpy
+from bpy.props import BoolProperty, EnumProperty, FloatProperty, FloatVectorProperty, IntProperty
+from bpy_extras import object_utils
+
+
+########################################
+#
+# Create vertices for end of mesh
+#
+# y_off - verts y-axis origin
+#
+# returns:
+# endVs - x,y,z list
+#
+def beamEndVs(sRef, y_off):
+ thick = sRef.beamW * 2
+
+ if sRef.Type == '2': # swap width and height for C shape
+ bEndX2 = sRef.beamZ / 2
+ bEndXInr = ((sRef.beamZ - thick) / 2)
+ bEndZ2 = sRef.beamX / 2
+ bEndZInr = ((sRef.beamX - thick) / 2)
+ else:
+ bEndX2 = sRef.beamX / 2
+ bEndXInr = ((sRef.beamX - thick) / 2)
+ bEndZ2 = sRef.beamZ / 2
+ bEndZInr = ((sRef.beamZ - thick) / 2)
+
+ endVs = []
+
+ # outer ...
+ endVs.append((bEndX2, y_off, bEndZ2))
+ endVs.append((-bEndX2, y_off, bEndZ2))
+ endVs.append((-bEndX2, y_off, -bEndZ2))
+ endVs.append((bEndX2, y_off, -bEndZ2))
+ # innner ...
+ endVs.append((bEndXInr, y_off, bEndZInr))
+ endVs.append((-bEndXInr, y_off, bEndZInr))
+ endVs.append((-bEndXInr, y_off, -bEndZInr))
+ endVs.append((bEndXInr, y_off, -bEndZInr))
+
+ return endVs
+
+
+########################################
+#
+# Create End Faces
+#
+# verts_list - list of vertices
+#
+# returns:
+# beamFs, a list of tuples defining the end faces.
+#
+def beamEndFaces(verts_list):
+
+ beamFs = []
+
+ num_of_verts = int(len(verts_list) / 2)
+
+ # Create list of faces
+ for index in range(num_of_verts):
+ faces_temp = []
+
+ if index == (num_of_verts - 1):
+ faces_temp.append(verts_list[index])
+ faces_temp.append(verts_list[index - index])
+ faces_temp.append(verts_list[index + 1])
+ faces_temp.append(verts_list[index * 2 + 1])
+ else:
+ faces_temp.append(verts_list[index])
+ faces_temp.append(verts_list[index + 1])
+ faces_temp.append(verts_list[index + num_of_verts + 1])
+ faces_temp.append(verts_list[index + num_of_verts])
+
+ beamFs.append(tuple(faces_temp))
+
+ return beamFs
+
+
+########################################
+#
+# Bridge vertices to create side faces.
+#
+# front_verts - front face vertices
+# back_verts - back face vertices
+# front & back must be ordered in same direction
+# with respect to y-axis
+#
+# returns:
+# sideFaces, a list of the bridged faces
+#
+def beamSides(front_verts, back_verts):
+ sideFaces = []
+
+ num_of_faces = (len(front_verts))
+
+ # add first value to end of lists for looping
+ front_verts.append(front_verts[0])
+ back_verts.append(back_verts[0])
+
+ # Build the faces
+ for index in range(num_of_faces):
+ facestemp = (front_verts[index], front_verts[index + 1], back_verts[index + 1], back_verts[index])
+ sideFaces.append(facestemp)
+
+ return sideFaces
+
+
+####################################################
+#
+# Creates a box beam
+#
+# returns:
+# beamVs - x, y, z, location of each vertice
+# beamFs - vertices that make up each face
+#
+def create_beam(sRef):
+
+ frontVs = []
+ frontFs = []
+ backVs = []
+
+ y_off = sRef.beamY / 2 # offset from center for vertices
+
+ frontVs = beamEndVs(sRef, y_off)
+ backVs = beamEndVs(sRef, -y_off)
+
+ # Combine vertices
+ beamVs = frontVs + backVs
+
+ # Create front face
+ numofverts = len(frontVs)
+ verts_front_list = []
+ for index in range(numofverts):
+ verts_front_list.append(index)
+
+ frontFs = beamEndFaces(verts_front_list)
+
+ # Create back face
+ faces_back_temp = []
+ verts_back_list = []
+
+ numofverts = len(backVs)
+ for index in range(numofverts):
+ verts_back_list.append(index + numofverts)
+
+ faces_back_temp = beamEndFaces(verts_back_list)
+
+ # Create side faces
+ faces_side_temp = []
+
+ # Object has thickness, create list of outside vertices
+ numofverts = len(verts_front_list)
+ halfVerts = int(numofverts / 2)
+ frontVs = verts_front_list[0:halfVerts]
+ backVs = verts_back_list[0:halfVerts]
+
+ faces_side_temp = beamSides(frontVs, backVs)
+
+ # Create list of inside vertices
+ frontVs = verts_front_list[halfVerts:numofverts]
+ backVs = verts_back_list[halfVerts:numofverts]
+
+ faces_side_temp += beamSides(frontVs, backVs)
+
+ # Combine all faces
+ beamFs = frontFs + faces_back_temp + faces_side_temp
+
+ return beamVs, beamFs
+
+
+########################################
+#
+# Taper/angle faces of beam.
+# inner vert toward outer vert
+# based on percentage of taper.
+#
+# returns:
+# adVert - the calculated vertex
+#
+def beamSlant(sRef, outV, inV):
+ bTaper = 100 - sRef.edgeA
+
+ # calcuate variance & adjust vertex
+ deltaV = ((inV - outV) / 100)
+ adVert = outV + (deltaV * bTaper)
+
+ return adVert
+
+
+########################################
+#
+# Modify location to shape beam.
+#
+# verts - tuples for one end of beam
+#
+# returns:
+# verts - modified tuples for beam shape.
+#
+def beamSquareEnds(sRef, verts):
+
+ # match 5th & 6th z locations to 1st & 2nd
+
+ vert_orig = verts[0]
+ vert_temp = verts[4]
+ vert_x = beamSlant(sRef, vert_orig[0], vert_temp[0])
+ verts[4] = (vert_x, vert_temp[1], vert_orig[2])
+
+ vert_orig = verts[1]
+ vert_temp = verts[5]
+ vert_x = beamSlant(sRef, vert_orig[0], vert_temp[0])
+ verts[5] = (vert_x, vert_temp[1], vert_orig[2])
+
+ return verts
+
+
+########################################
+#
+# Create U shaped beam
+# Shared with C shape - see beamEndVs
+# for sizing and rotate in addBeamObj.
+#
+# returns:
+# beamVs - vertice x, y, z, locations
+# beamFs - face vertices
+#
+def create_u_beam(sRef):
+
+ # offset vertices from center
+ y_off = sRef.beamY / 2
+
+ frontVtemp = []
+ frontFtemp = []
+ frontVlist = []
+
+ backVtemp = []
+ backFtemp = []
+ backVlist = []
+
+ sideFs = []
+
+ frontVtemp = beamEndVs(sRef, y_off) # Box beam
+ frontVtemp = beamSquareEnds(sRef, frontVtemp) # U shape
+
+ backVtemp = beamEndVs(sRef, -y_off)
+ backVtemp = beamSquareEnds(sRef, backVtemp)
+
+ beamVs = frontVtemp + backVtemp
+
+ # Create front face
+ for index in range(len(frontVtemp)): # Build vert list
+ frontVlist.append(index)
+
+ frontFtemp = beamEndFaces(frontVlist)
+ frontFtemp = frontFtemp[1:4] # Remove 1st face
+
+ # Create back face
+ numofverts = len(backVtemp)
+ for index in range(numofverts): # Build vertex list
+ backVlist.append(index + numofverts)
+
+ backFtemp = beamEndFaces(backVlist)
+ backFtemp = backFtemp[1:4] # Remove face
+
+ # Create list vertices for outside faces
+ numofverts = int(len(frontVlist))
+ halfVerts = int(numofverts / 2)
+ frontVtemp = frontVlist[0:halfVerts]
+ backVtemp = backVlist[0:halfVerts]
+
+ sideFs = beamSides(frontVtemp, backVtemp)
+ sideFs = sideFs[1:] # Remove face
+
+ # Create inside verts
+ frontVtemp = frontVlist[halfVerts:numofverts]
+ backVtemp = backVlist[halfVerts:numofverts]
+
+ sideFs += beamSides(frontVtemp, backVtemp)
+ sideFs = sideFs[0:3] + sideFs[4:] # Remove face
+
+ # fill in faces
+ sideFs.append((0, 4, 12, 8))
+ sideFs.append((5, 1, 9, 13))
+
+ beamFs = frontFtemp + backFtemp + sideFs # Combine faces
+
+ return beamVs, beamFs
+
+
+###################################
+#
+# returns:
+# verts_final - x, y, z, location of each vertice
+# faces_final - vertices that make up each face
+#
+def create_L_beam(sRef):
+
+ thick = sRef.beamW
+
+ # offset vertices from center
+ x_off = sRef.beamX / 2
+ y_off = sRef.beamY / 2
+ z_off = sRef.beamZ / 2
+
+ # Create temporarylists to hold vertices locations
+ verts_front_temp = []
+ verts_back_temp = []
+
+ # Create front vertices by calculation
+ verts_front_temp = [(-x_off, -y_off, z_off),
+ (-(x_off - thick), -y_off, z_off),
+ (-(x_off - thick), -y_off, -(z_off - thick)),
+ (x_off, -y_off, -(z_off - thick)),
+ (x_off, -y_off, -z_off),
+ (-x_off, -y_off, -z_off)]
+
+ # Adjust taper
+ vert_outside = verts_front_temp[0]
+ vert_inside = verts_front_temp[1]
+ vert_taper = beamSlant(sRef, vert_outside[0], vert_inside[0])
+ verts_front_temp[1] = [vert_taper, vert_inside[1], vert_inside[2]]
+
+ vert_outside = verts_front_temp[4]
+ vert_inside = verts_front_temp[3]
+ vert_taper = beamSlant(sRef, vert_outside[2], vert_inside[2])
+ verts_front_temp[3] = [vert_inside[0], vert_inside[1], vert_taper]
+
+ # Create back vertices by calculation
+ verts_back_temp = [(-x_off, y_off, z_off),
+ (-(x_off - thick), y_off, z_off),
+ (-(x_off - thick), y_off, -(z_off - thick)),
+ (x_off, y_off, -(z_off - thick)),
+ (x_off, y_off, -z_off),
+ (-x_off, y_off, -z_off)]
+
+ # Adjust taper
+ vert_outside = verts_back_temp[0]
+ vert_inside = verts_back_temp[1]
+ vert_taper = beamSlant(sRef, vert_outside[0], vert_inside[0])
+ verts_back_temp[1] = [vert_taper, vert_inside[1], vert_inside[2]]
+
+ vert_outside = verts_back_temp[4]
+ vert_inside = verts_back_temp[3]
+ vert_taper = beamSlant(sRef, vert_outside[2], vert_inside[2])
+ verts_back_temp[3] = [vert_inside[0], vert_inside[1], vert_taper]
+
+ verts_final = verts_front_temp + verts_back_temp
+
+ # define end faces, only 4 so just coded
+ faces_front_temp = []
+ faces_back_temp = []
+ faces_side_temp = []
+
+ faces_front_temp = [(0, 1, 2, 5), (2, 3, 4, 5)]
+ faces_back_temp = [(6, 7, 8, 11), (8, 9, 10, 11)]
+
+ verts_front_list = []
+ verts_back_list = []
+ num_of_verts = len(verts_front_temp)
+
+ # build lists of back and front verts for beamSides function
+ for index in range(num_of_verts):
+ verts_front_list.append(index)
+ for index in range(num_of_verts):
+ verts_back_list.append(index + 6)
+
+ faces_side_temp = beamSides(verts_front_list, verts_back_list)
+
+ faces_final = faces_front_temp + faces_back_temp + faces_side_temp
+
+ return verts_final, faces_final
+
+
+###################################
+#
+# returns:
+# verts_final - a list of tuples of the x, y, z, location of each vertice
+# faces_final - a list of tuples of the vertices that make up each face
+#
+def create_T_beam(sRef):
+
+ thick = sRef.beamW
+
+ # Get offset of vertices from center
+ x_off = sRef.beamX / 2
+ y_off = sRef.beamY / 2
+ z_off = sRef.beamZ / 2
+ thick_off = thick / 2
+
+ # Create temporarylists to hold vertices locations
+ verts_front_temp = []
+ verts_back_temp = []
+
+ # Create front vertices
+ verts_front_temp = [(-x_off, -y_off, z_off),
+ (-thick_off, -y_off, z_off),
+ (thick_off, -y_off, z_off),
+ (x_off, -y_off, z_off),
+ (x_off, -y_off, z_off - thick),
+ (thick_off, -y_off, z_off - thick),
+ (thick_off, -y_off, -z_off),
+ (-thick_off, -y_off, -z_off),
+ (-thick_off, -y_off, z_off - thick),
+ (-x_off, -y_off, z_off - thick)]
+
+ # Adjust taper
+ vert_outside = verts_front_temp[0]
+ vert_inside = verts_front_temp[9]
+ vert_taper = (beamSlant(sRef, vert_outside[2], vert_inside[2]))
+ verts_front_temp[9] = [vert_inside[0], vert_inside[1], vert_taper]
+
+ vert_outside = verts_front_temp[3]
+ vert_inside = verts_front_temp[4]
+ verts_front_temp[4] = [vert_inside[0], vert_inside[1], vert_taper]
+
+ # Adjust taper of bottom of beam, so 0 the center
+ # now becomes vert_outside, and vert_inside is calculated
+ # 1/2 way towards center
+ vert_outside = (0, -y_off, -z_off)
+ vert_inside = verts_front_temp[6]
+ vert_taper = (beamSlant(sRef, vert_outside[0], vert_inside[0]))
+ verts_front_temp[6] = [vert_taper, vert_inside[1], vert_inside[2]]
+
+ vert_outside = (0, -y_off, -z_off)
+ vert_inside = verts_front_temp[7]
+ vert_taper = beamSlant(sRef, vert_outside[0], vert_inside[0])
+ verts_front_temp[7] = [vert_taper, vert_inside[1], vert_inside[2]]
+
+ # Create fack vertices by calculation
+ verts_back_temp = [(-x_off, y_off, z_off),
+ (-thick_off, y_off, z_off),
+ (thick_off, y_off, z_off),
+ (x_off, y_off, z_off),
+ (x_off, y_off, z_off - thick),
+ (thick_off, y_off, z_off - thick),
+ (thick_off, y_off, -z_off),
+ (-thick_off, y_off, -z_off),
+ (-thick_off, y_off, z_off - thick),
+ (-x_off, y_off, z_off - thick)]
+
+ # Adjust taper
+ vert_outside = verts_back_temp[0]
+ vert_inside = verts_back_temp[9]
+ vert_taper = (beamSlant(sRef, vert_outside[2], vert_inside[2]))
+ verts_back_temp[9] = [vert_inside[0], vert_inside[1], vert_taper]
+
+ vert_outside = verts_back_temp[3]
+ vert_inside = verts_back_temp[4]
+ vert_taper = (beamSlant(sRef, vert_outside[2], vert_inside[2]))
+ verts_back_temp[4] = [vert_inside[0], vert_inside[1], vert_taper]
+
+ # Adjust taper of bottom of beam, so 0 the center
+ # now becomes vert_outside, and vert_inside is calculated
+ # 1/2 way towards center
+ vert_outside = (0, -y_off, -z_off)
+ vert_inside = verts_back_temp[6]
+ vert_taper = (beamSlant(sRef, vert_outside[0], vert_inside[0]))
+ verts_back_temp[6] = [vert_taper, vert_inside[1], vert_inside[2]]
+
+ vert_outside = (0, -y_off, -z_off)
+ vert_inside = verts_back_temp[7]
+ vert_taper = (beamSlant(sRef, vert_outside[0], vert_inside[0]))
+ verts_back_temp[7] = [vert_taper, vert_inside[1], vert_inside[2]]
+
+ verts_final = verts_front_temp + verts_back_temp
+
+ # define end faces, only 8 so just coded
+ faces_front_temp = []
+ faces_back_temp = []
+ faces_side_temp = []
+
+ faces_front_temp = [(0, 1, 8, 9), (1, 2, 5, 8),
+ (2, 3, 4, 5), (5, 6, 7, 8)]
+
+ faces_back_temp = [(10, 11, 18, 19), (11, 12, 15, 18),
+ (12, 13, 14, 15), (15, 16, 17, 18)]
+
+ verts_front_list = []
+ verts_back_list = []
+ num_of_verts = len(verts_front_temp)
+
+ # build lists of back and front verts for beamSides function
+ for index in range(num_of_verts):
+ verts_front_list.append(index)
+ for index in range(num_of_verts):
+ verts_back_list.append(index + 10)
+
+ faces_side_temp = beamSides(verts_front_list, verts_back_list)
+
+ faces_final = faces_front_temp + faces_back_temp + faces_side_temp
+
+ return verts_final, faces_final
+
+
+###################################
+#
+# returns:
+# verts_final - a list of tuples of the x, y, z, location of each vertice
+# faces_final - a list of tuples of the vertices that make up each face
+#
+def create_I_beam(sRef):
+
+ thick = sRef.beamW
+
+ # Get offset of vertices from center
+ x_off = sRef.beamX / 2
+ y_off = sRef.beamY / 2
+ z_off = sRef.beamZ / 2
+ thick_off = thick / 2
+
+ # Create temporarylists to hold vertices locations
+ verts_front_temp = []
+ verts_back_temp = []
+
+ # Create front vertices by calculation
+ verts_front_temp = [(-x_off, -y_off, z_off),
+ (-thick_off, -y_off, z_off),
+ (thick_off, -y_off, z_off),
+ (x_off, -y_off, z_off),
+ (x_off, -y_off, z_off - thick),
+ (thick_off, -y_off, z_off - thick),
+ (thick_off, -y_off, -z_off + thick),
+ (x_off, -y_off, -z_off + thick),
+ (x_off, -y_off, -z_off),
+ (thick_off, -y_off, -z_off),
+ (-thick_off, -y_off, -z_off),
+ (-x_off, -y_off, -z_off),
+ (-x_off, -y_off, -z_off + thick),
+ (-thick_off, -y_off, -z_off + thick),
+ (-thick_off, -y_off, z_off - thick),
+ (-x_off, -y_off, z_off - thick)]
+
+ # Adjust taper
+ vert_outside = verts_front_temp[0]
+ vert_inside = verts_front_temp[15]
+ vert_taper = (beamSlant(sRef, vert_outside[2], vert_inside[2]))
+ verts_front_temp[15] = [vert_inside[0], vert_inside[1], vert_taper]
+
+ vert_outside = verts_front_temp[3]
+ vert_inside = verts_front_temp[4]
+ vert_taper = (beamSlant(sRef, vert_outside[2], vert_inside[2]))
+ verts_front_temp[4] = [vert_inside[0], vert_inside[1], vert_taper]
+
+ vert_outside = verts_front_temp[8]
+ vert_inside = verts_front_temp[7]
+ vert_taper = (beamSlant(sRef, vert_outside[2], vert_inside[2]))
+ verts_front_temp[7] = [vert_inside[0], vert_inside[1], vert_taper]
+
+ vert_outside = verts_front_temp[11]
+ vert_inside = verts_front_temp[12]
+ vert_taper = (beamSlant(sRef, vert_outside[2], vert_inside[2]))
+ verts_front_temp[12] = [vert_inside[0], vert_inside[1], vert_taper]
+
+ # Create back vertices by calculation
+ verts_back_temp = [(-x_off, y_off, z_off),
+ (-thick_off, y_off, z_off),
+ (thick_off, y_off, z_off),
+ (x_off, y_off, z_off),
+ (x_off, y_off, z_off - thick),
+ (thick_off, y_off, z_off - thick),
+ (thick_off, y_off, -z_off + thick),
+ (x_off, y_off, -z_off + thick),
+ (x_off, y_off, -z_off),
+ (thick_off, y_off, -z_off),
+ (-thick_off, y_off, -z_off),
+ (-x_off, y_off, -z_off),
+ (-x_off, y_off, -z_off + thick),
+ (-thick_off, y_off, -z_off + thick),
+ (-thick_off, y_off, z_off - thick),
+ (-x_off, y_off, z_off - thick)]
+
+ # Adjust taper
+ vert_outside = verts_back_temp[0]
+ vert_inside = verts_back_temp[15]
+ vert_taper = (beamSlant(sRef, vert_outside[2], vert_inside[2]))
+ verts_back_temp[15] = [vert_inside[0], vert_inside[1], vert_taper]
+
+ vert_outside = verts_back_temp[3]
+ vert_inside = verts_back_temp[4]
+ vert_taper = (beamSlant(sRef, vert_outside[2], vert_inside[2]))
+ verts_back_temp[4] = [vert_inside[0], vert_inside[1], vert_taper]
+
+ vert_outside = verts_back_temp[8]
+ vert_inside = verts_back_temp[7]
+ vert_taper = (beamSlant(sRef, vert_outside[2], vert_inside[2]))
+ verts_back_temp[7] = [vert_inside[0], vert_inside[1], vert_taper]
+
+ vert_outside = verts_back_temp[11]
+ vert_inside = verts_back_temp[12]
+ vert_taper = (beamSlant(sRef, vert_outside[2], vert_inside[2]))
+ verts_back_temp[12] = [vert_inside[0], vert_inside[1], vert_taper]
+
+ verts_final = verts_front_temp + verts_back_temp
+
+# define end faces, only 7 per end, so just coded
+ faces_front_temp = []
+ faces_back_temp = []
+ faces_side_temp = []
+
+ faces_front_temp = [(0, 1, 14, 15), (1, 2, 5, 14),
+ (2, 3, 4, 5), (6, 7, 8, 9),
+ (6, 9, 10, 13), (12, 13, 10, 11),
+ (5, 6, 13, 14)]
+
+ faces_back_temp = [(16, 17, 30, 31), (17, 18, 21, 30),
+ (18, 19, 20, 21), (22, 23, 24, 25),
+ (22, 25, 26, 29), (28, 29, 26, 27),
+ (21, 22, 29, 30)]
+
+ verts_front_list = []
+ verts_back_list = []
+ num_of_verts = len(verts_front_temp)
+
+ # build lists of back and front verts for beamSides function
+ for index in range(num_of_verts):
+ verts_front_list.append(index)
+ for index in range(num_of_verts):
+ verts_back_list.append(index + 16)
+
+ faces_side_temp = beamSides(verts_front_list, verts_back_list)
+
+ faces_final = faces_front_temp + faces_back_temp + faces_side_temp
+
+ return verts_final, faces_final
+
+
+################################################################################
+#
+# Generate beam object.
+#
+def addBeamObj(sRef, context):
+ verts = []
+ faces = []
+
+ # type of beam to add
+ if sRef.Type == '0':
+ verts, faces = create_beam(sRef)
+ elif sRef.Type == '1':
+ verts, faces = create_u_beam(sRef)
+ elif sRef.Type == '2':
+ verts, faces = create_u_beam(sRef)
+ elif sRef.Type == '3':
+ verts, faces = create_L_beam(sRef)
+ elif sRef.Type == '4':
+ verts, faces = create_I_beam(sRef)
+ elif sRef.Type == '5':
+ verts, faces = create_T_beam(sRef)
+ else: # unknown type, use default.
+ verts, faces = create_beam(sRef)
+
+ beamMesh = bpy.data.meshes.new("Beam")
+ beamObj = bpy.data.objects.new("Beam", beamMesh)
+ context.scene.objects.link(beamObj)
+ context.scene.objects.active = beamObj
+ beamObj.select = True
+
+ beamMesh.from_pydata(verts, [], faces)
+ beamMesh.update(calc_edges=True)
+
+ if sRef.Type == '2': # Rotate C shape
+ bpy.ops.transform.rotate(value=1.570796, constraint_axis=[False, True, False])
+ bpy.ops.object.transform_apply(location=False, rotation=True, scale=False)
+
+
+################################################################################
+#
+# Create a beam primitive.
+#
+# UI functions and object creation.
+#
+class addBeam(bpy.types.Operator):
+ bl_idname = "mesh.add_beam"
+ bl_description = "Beam Builder"
+ bl_label = "Beam Builder"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ Type = EnumProperty(items=(
+ ('0', "Box", "Square Beam"),
+ ("1", "U", "U Beam"),
+ ("2", "C", "C Beam"),
+ ("3", "L", "L Beam"),
+ ("4", "I", "T Beam"),
+ ("5", "T", "I Beam")
+ ),
+ description="Beam form.")
+
+ beamZ = FloatProperty(name="Height", min=0.01, max=100, default=1)
+ beamX = FloatProperty(name="Width", min=0.01, max=100, default=.5)
+ beamY = FloatProperty(name="Depth", min=0.01, max=100, default=2)
+ beamW = FloatProperty(name="Thickness", min=0.01, max=1, default=0.1)
+
+ edgeA = IntProperty(name="Taper", min=0, max=100, default=0, description="Angle beam edges.")
+
+ ########################################
+ def draw(self, context):
+ layout = self.layout
+
+ box = layout.box()
+ row = box.row()
+ row.prop(self, 'Type', text='')
+
+ box.prop(self, 'beamZ')
+ box.prop(self, 'beamX')
+ box.prop(self, 'beamY')
+ box.prop(self, 'beamW')
+
+ if self.Type != '0':
+ box.prop(self, 'edgeA')
+
+ ########################################
+ def execute(self, context):
+ if bpy.context.mode == "OBJECT":
+ addBeamObj(self, context)
+ return {'FINISHED'}
+ else:
+ self.report({'WARNING'}, "Option only valid in Object mode")
+ return {'CANCELLED'}
diff --git a/add_mesh_extra_objects/geodesic_domes/__init__.py b/add_mesh_extra_objects/geodesic_domes/__init__.py
new file mode 100644
index 00000000..711de18e
--- /dev/null
+++ b/add_mesh_extra_objects/geodesic_domes/__init__.py
@@ -0,0 +1,49 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Geodesic Domes2",
+ "author": "Noctumsolis, PKHG, Meta Androcto, Andy Houston",
+ "version": (0, 3, 2),
+ "blender": (2, 7, 1),
+ "location": "Toolshelf > Create Tab",
+ "description": "Create geodesic dome type objects.",
+ "warning": "",
+ "wiki_url": "http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Modeling/Geodesic_Domes",
+ "tracker_url": "https://developer.blender.org/maniphest/task/create/?project=3&type=Bug",
+ "category": "Mesh"}
+
+if "bpy" in locals():
+ import imp
+ imp.reload(third_domes_panel_271)
+
+else:
+ from . import third_domes_panel_271
+
+import bpy
+from bpy.props import *
+
+def register():
+ bpy.utils.register_module(__name__)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+if __name__ == "__main__":
+ register()
+
diff --git a/add_mesh_extra_objects/geodesic_domes/add_shape_geodesic.py b/add_mesh_extra_objects/geodesic_domes/add_shape_geodesic.py
new file mode 100644
index 00000000..879f6fa1
--- /dev/null
+++ b/add_mesh_extra_objects/geodesic_domes/add_shape_geodesic.py
@@ -0,0 +1,100 @@
+import bpy
+import mathutils
+
+def reset_transform(ob):
+ m = mathutils.Matrix()
+ ob.matrix_local = m
+
+def func_add_corrective_pose_shape_fast(source, target):
+ result = ""
+ reset_transform(target)
+ # If target object doesn't have Basis shape key, create it.
+ try:
+ num_keys = len( target.data.shape_keys.key_blocks )
+ except:
+ basis = target.shape_key_add()
+ basis.name = "Basis"
+ target.data.update()
+ key_index = target.active_shape_key_index
+ if key_index == 0:
+ # Insert new shape key
+ new_shapekey = target.shape_key_add()
+ new_shapekey.name = "Shape_" + source.name
+ new_shapekey_name = new_shapekey.name
+ key_index = len(target.data.shape_keys.key_blocks)-1
+ target.active_shape_key_index = key_index
+ # else, the active shape will be used (updated)
+ target.show_only_shape_key = True
+ shape_key_verts = target.data.shape_keys.key_blocks[ key_index ].data
+ try:
+ vgroup = target.active_shape_key.vertex_group
+ target.active_shape_key.vertex_group = ''
+ except:
+ print("blub")
+ result = "***ERROR*** blub"
+ pass
+ # copy the local vertex positions to the new shape
+ verts = source.data.vertices
+ try:
+ for n in range( len(verts)):
+ shape_key_verts[n].co = verts[n].co
+ # go to all armature modifies and unpose the shape
+ except:
+ message = "***ERROR***, meshes have different number of vertices"
+ result = message
+ for n in target.modifiers:
+ if n.type == 'ARMATURE' and n.show_viewport:
+ #~ print("got one")
+ n.use_bone_envelopes = False
+ n.use_deform_preserve_volume = False
+ n.use_vertex_groups = True
+ armature = n.object
+ unposeMesh( shape_key_verts, target, armature)
+ break
+
+ # set the new shape key value to 1.0, so we see the result instantly
+ target.data.shape_keys.key_blocks[ target.active_shape_key_index].value = 1.0
+ try:
+ target.active_shape_key.vertex_group = vgroup
+ except:
+ print("bluba")
+ result = result + "bluba"
+ pass
+ target.show_only_shape_key = False
+ target.data.update()
+ return result
+
+class add_corrective_pose_shape_fast(bpy.types.Operator):
+ '''Adds 1st object as shape to 2nd object as pose shape (only 1 armature)'''
+ bl_idname = "object.add_corrective_pose_shape_fast"
+ bl_label = "Add object as corrective shape faster"
+
+ @classmethod
+ def poll(cls, context):
+ return context.active_object != None
+
+ def execute(self, context):
+
+ if len(context.selected_objects) > 2:
+ print("Select source and target objects please")
+ return {'FINISHED'}
+
+ selection = context.selected_objects
+ target = context.active_object
+ if context.active_object == selection[0]:
+ source = selection[1]
+ else:
+ source = selection[0]
+ print(source)
+ print(target)
+ func_add_corrective_pose_shape_fast( source, target)
+ return {'FINISHED'}
+
+def register():
+ bpy.utils.register_module(__name__)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+if __name__ == "__main__":
+ register()
diff --git a/add_mesh_extra_objects/geodesic_domes/forms_271.py b/add_mesh_extra_objects/geodesic_domes/forms_271.py
new file mode 100644
index 00000000..d3e46dca
--- /dev/null
+++ b/add_mesh_extra_objects/geodesic_domes/forms_271.py
@@ -0,0 +1,232 @@
+import math
+from math import sin, cos
+from .vefm_271 import *
+class form(mesh):
+ def __init__(self, uresolution, vresolution, uscale, vscale, upart,\
+ vpart, uphase, vphase, utwist, vtwist, xscale, yscale, sform):
+ mesh.__init__(self)
+
+ self.PKHG_parameters = [uresolution, vresolution, uscale, vscale, upart,
+ vpart, uphase, vphase, utwist, vtwist, xscale, yscale, sform]
+ self.ures = uresolution
+ self.vres = vresolution
+
+ self.uscale = uscale
+ self.vscale = vscale
+ self.upart = upart
+ self.vpart = vpart
+ self.uphase = uphase * self.a360
+ self.vphase = vphase * self.a360
+ self.utwist = utwist
+ self.vtwist = vtwist
+
+ self.xscale = xscale
+ self.yscale = yscale
+ self.sform = sform
+
+ if self.upart != 1.0: ## there is a gap in the major radius
+ self.uflag = 1
+ else:
+ self.uflag = 0
+ if self.vpart != 1.0: ## there is a gap in the minor radius
+ self.vflag = 1
+ else:
+ self.vflag = 0
+ if self.uflag:
+ self.ufinish = self.ures + 1
+ else:
+ self.ufinish = self.ures
+ if self.vflag:
+ self.vfinish = self.vres + 1
+ else:
+ self.vfinish = self.vres
+ self.ustep = (self.a360 / self.ures) * self.upart
+ self.vstep = (self.a360 / self.vres) * self.vpart
+ if self.xscale != 1.0:
+ self.xscaleflag = 1
+ else:
+ self.xscaleflag = 0
+ if self.yscale != 1.0:
+ self.yscaleflag = 1
+ else:
+ self.yscaleflag = 0
+ self.rowlist=[]
+
+ def generatepoints(self):
+ for i in range(self.ufinish):
+ row=[]
+ for j in range(self.vfinish):
+ u = self.ustep * i + self.uphase
+ v = self.vstep * j + self.vphase
+
+ if self.sform[12]:
+ r1 = self.superform(self.sform[0], self.sform[1], self.sform[2],\
+ self.sform[3], self.sform[14] + u, self.sform[4],\
+ self.sform[5], self.sform[16] * v)
+ else:
+ r1 = 1.0
+ if self.sform[13]:
+ r2 = self.superform(self.sform[6], self.sform[7], self.sform[8],\
+ self.sform[9], self.sform[15] + v, self.sform[10],\
+ self.sform[11], self.sform[17] * v)
+ else:
+ r2 = 1.0
+ x, y, z = self.formula(u, v, r1, r2)
+ point = vertex((x, y, z))
+ row.append(point)
+ self.verts.append(point)
+ self.rowlist.append(row)
+
+ if self.vflag:
+ pass
+ else:
+ for i in range(len(self.rowlist)):
+ self.rowlist[i].append(self.rowlist[i][0])
+ if self.uflag:
+ pass
+ else:
+ self.rowlist.append(self.rowlist[0])
+
+ def generatefaces(self):
+ ufin = len(self.rowlist) - 1
+ vfin = len(self.rowlist[0]) - 1
+ for i in range(ufin):
+ for j in range(vfin):
+ top = i
+ bottom = i + 1
+ left = j
+ right = j + 1
+ a = self.rowlist[top][left]
+ b = self.rowlist[top][right]
+ c = self.rowlist[bottom][right]
+ d = self.rowlist[bottom][left]
+ face1 = face([a, b, c, d])
+ self.faces.append(face1)
+ edge1 = edge(a, b)
+ edge2 = edge(a, d)
+ self.edges.append(edge1)
+ self.edges.append(edge2)
+ if i + 1 == ufin:
+ edge3 = edge(d, c)
+ self.edges.append(edge3)
+ if j + 1 == vfin:
+ edge4 = edge(b, c)
+ self.edges.append(edge4)
+
+class grid(form):
+ def __init__(self, uresolution, vresolution, uscale, vscale, upart, vpart,\
+ uphase, vphase, utwist, vtwist, xscale, yscale, sform):
+ form.__init__(self, uresolution, vresolution, uscale, vscale, upart, vpart,\
+ uphase, vphase, utwist, vtwist, xscale, yscale, sform)
+ unit = 1.0 / self.a360
+ if self.ures == 1 :
+ print("\n***ERRORin forms_271.grid L121***, ures is 1, changed into 2\n\n")
+ self.ures = 2
+ if self.vres == 1 :
+ print("\n***ERROR in grid forms_271.grid L124***, vres is 1, changed into 2\n\n")
+ self.vres = 2
+ self.ustep = self.a360 / (self.ures - 1)
+ self.vstep = self.a360 / (self.vres - 1)
+
+ self.uflag = 1
+ self.vflag = 1
+
+ self.xscaleflag = 0
+ self.yscaleflag = 0
+ self.uexpand = unit * self.uscale
+ self.vexpand = unit * self.vscale
+ self.ushift = self.uscale * 0.5
+ self.vshift = self.vscale * 0.5
+
+ self.generatepoints()
+ self.generatefaces()
+ for i in range(len(self.verts)):
+ self.verts[i].index = i
+ self.connectivity()
+
+ def formula(self, u, v, r1, r2):
+ x = u * self.uexpand - self.ushift
+ y = v * self.vexpand - self.vshift
+ z = r1 * r2 - 1.0
+ return x, y, z
+
+
+class cylinder(form):
+ def __init__(self, uresolution, vresolution, uscale, vscale, upart, vpart,\
+ uphase, vphase, utwist, vtwist, xscale, yscale, sform):
+ form.__init__(self, uresolution, vresolution, uscale, vscale, upart, vpart,\
+ uphase, vphase, utwist, vtwist, xscale, yscale, sform)
+ unit = 1.0 / self.a360
+ self.vshift = self.vscale * 0.5
+ self.vexpand = unit * self.vscale
+ self.vflag = 1
+ self.generatepoints()
+ self.generatefaces()
+ for i in range(len(self.verts)):
+ self.verts[i].index = i
+ self.connectivity()
+
+ def formula(self, u, v, r1, r2):
+ x = sin(u) * self.uscale * r1 * r2 * self.xscale
+ y = cos(u) * self.uscale * r1 * r2
+ z = v * self.vexpand - self.vshift
+ return x, y, z
+
+class parabola(form):
+ def __init__(self, uresolution, vresolution, uscale, vscale, upart, vpart,\
+ uphase, vphase, utwist, vtwist, xscale, yscale, sform):
+ form.__init__(self, uresolution, vresolution, uscale, vscale, upart, vpart,\
+ uphase, vphase, utwist, vtwist, xscale, yscale, sform)
+ unit = 1.0 / self.a360
+ self.vshift = self.vscale * 0.5
+ self.vexpand = unit * self.vscale
+ self.vflag = 1
+ self.generatepoints()
+ self.generatefaces()
+ for i in range(len(self.verts)):
+ self.verts[i].index = i
+ self.connectivity()
+
+ def formula(self, u, v, r1, r2):
+ factor = sqrt(v) + 0.001
+ x = sin(u) * factor * self.uscale * r1 * r2 * self.xscale
+ y = cos(u) * factor * self.uscale * r1 * r2
+ z = - v * self.vexpand + self.vshift
+ return x, y, z
+
+class torus(form):
+ def __init__(self, uresolution, vresolution, uscale, vscale, upart, vpart,\
+ uphase, vphase, utwist, vtwist, xscale, yscale, sform):
+ form.__init__(self, uresolution, vresolution, uscale, vscale, upart, vpart,\
+ uphase, vphase, utwist, vtwist, xscale, yscale, sform)
+ self.generatepoints()
+ self.generatefaces()
+ for i in range(len(self.verts)):
+ self.verts[i].index = i
+ self.connectivity()
+
+ def formula(self, u, v, r1, r2):
+ z = sin(v) * self.uscale * r2 * self.yscale
+ y = (self.vscale + self.uscale * cos(v)) * cos(u) * r1 * r2
+ x = (self.vscale + self.uscale * cos(v)) * sin(u) * r1 * r2 * self.xscale
+ return x, y, z
+
+class sphere(form):
+ def __init__(self, uresolution, vresolution, uscale, vscale, upart, vpart,\
+ uphase, vphase, utwist, vtwist, xscale, yscale, sform):
+ form.__init__(self, uresolution, vresolution, uscale, vscale, upart, vpart,\
+ uphase,vphase,utwist,vtwist,xscale,yscale,sform)
+ self.vstep = (self.a360 / (self.vres - 1)) * self.vpart
+ self.vflag = 1
+ self.generatepoints()
+ self.generatefaces()
+ for i in range(len(self.verts)):
+ self.verts[i].index = i
+ self.connectivity()
+
+ def formula(self, u, v, r1, r2):
+ v = (v * 0.5) - (self.a360 * 0.25)
+ x = r1 * cos(u) * r2 * cos(v) * self.uscale * self.xscale
+ y = r1 * sin(u) * r2 * cos(v) * self.uscale
+ z = r2 * sin(v) * self.uscale * self.yscale
+ return x, y, z
diff --git a/add_mesh_extra_objects/geodesic_domes/geodesic_classes_271.py b/add_mesh_extra_objects/geodesic_domes/geodesic_classes_271.py
new file mode 100644
index 00000000..985dcccd
--- /dev/null
+++ b/add_mesh_extra_objects/geodesic_domes/geodesic_classes_271.py
@@ -0,0 +1,741 @@
+
+from .vefm_271 import mesh, vertex, edge, face
+
+import math
+from math import pi,acos,sin,cos,atan,tan,fabs, sqrt
+
+def check_contains(cl,name , print_value = False):
+ dir_class = dir(cl)
+ for el in dir_class:
+ if el.startswith("_"):
+ pass
+ else:
+ if print_value:
+ tmp = getattr(cl,el)
+ print(name , " contains ==>",el," value = ", tmp)
+ else:
+ print(name , " contains ==>",el)
+ print("\ncheck_contains finished\n\n")
+
+class geodesic(mesh):
+
+ def __init__(self):
+ mesh.__init__(self)
+ self.PKHG_parameters = None
+
+ self.panels = []
+ self.vertsdone = []
+ self.skeleton = [] # List of verts in the full skeleton edges.
+ self.vertskeleton = [] # config needs this member
+ self.edgeskeleton = [] # config needs this member
+ self.sphericalverts = []
+ self.a45 = pi * 0.25
+ self.a90 = pi * 0.5
+ self.a180 = pi
+ self.a270 = pi * 1.5
+ self.a360 = pi * 2
+ # define members here
+ # setparams needs:
+ self.frequency = None
+ self.eccentricity = None
+ self.squish = None
+ self.radius = None
+ self.square = None
+ self.squarez = None
+ self.cart = None
+ self.shape = None
+ self.baselevel = None
+ self.faceshape = None
+ self.dualflag = None
+ self.rotxy = None
+ self.rotz = None
+ self.klass = None
+ self.sform = None
+ self.super = None
+ self.odd = None
+ #config needs
+ self.panelpoints = None
+ self.paneledges = None
+ self.reversepanel = None
+ self.edgelength = None
+ self.vertsdone = None
+ self.panels = []
+
+ def setparameters(self,params):
+ parameters = self.PKHG_parameters = params
+ self.frequency = parameters[0] ## How many subdivisions - up to 20.
+ self.eccentricity = parameters[1] ## Elliptical if >1.0.
+ self.squish = parameters[2] ## Flattened if < 1.0.
+ self.radius = parameters[3] ## Exactly what it says.
+ self.square = parameters[4] ## Controls amount of superellipse in X/Y plane.
+ self.squarez = parameters[5] ## Controls amount of superellipse in Z dimension.
+ self.cart = parameters[6] ## Cuts out sphericalisation step.
+ self.shape = parameters[7] ## Full sphere, dome, flatbase.
+ self.baselevel = parameters[8] ## Where the base is cut on a flatbase dome.
+ self.faceshape = parameters[9] ## Triangular, hexagonal, tri-hex.
+ self.dualflag = parameters[10]
+ self.rotxy = parameters[11]
+ self.rotz = parameters[12]
+ self.klass = parameters[13]
+ self.sform = parameters[14]
+ self.super = 0 ## Toggles superellipse.
+ if self.square != 2.0 or self.squarez != 2.0:
+ self.super = 1
+ self.odd = 0 ## Is the frequency odd. It matters for dome building.
+ if self.frequency % 2 != 0:
+ self.odd = 1
+
+ def makegeodesic(self):
+ self.vertedgefacedata() #PKHG only a pass 13okt11
+ self.config() ## Generate all the configuration information.
+ if self.klass:
+ self.class2()
+ if self.faceshape == 1:
+ self.hexify() ## Hexagonal faces
+ elif self.faceshape == 2:
+ self.starify() ## Hex and Triangle faces
+ if self.dualflag:
+ self.dual()
+ if not self.cart:
+ self.sphericalize() ## Convert x,y,z positions into spherical u,v.
+ self.sphere2cartesian() ## Convert spherical uv back into cartesian x,y,z for final shape.
+ for i in range(len( self.verts)):
+ self.verts[i].index = i
+ for edg in self.edges:
+ edg.findvect()
+
+ def vertedgefacedata(self):
+ pass
+
+ def config(self):
+ for i in range(len(self.vertskeleton)):
+ self.vertskeleton[i].index = i
+ for edges in self.edgeskeleton:
+ s = skeletonrow(self.frequency, edges, 0, self) #self a geodesic
+ self.skeleton.append(s)
+ for i in range(len( self.verts)):
+ self.verts[i].index = i
+ for i in range(len(self.panelpoints)):
+ a = self.vertsdone[self.panelpoints[i][0]][1]
+ b = self.vertsdone[self.panelpoints[i][1]][1]
+ c = self.vertsdone[self.panelpoints[i][2]][1]
+ panpoints = [ self.verts[a],
+ self.verts[b],
+ self.verts[c]]
+ panedges = [ self.skeleton[self.paneledges[i][0]],
+ self.skeleton[self.paneledges[i][1]],
+ self.skeleton[self.paneledges[i][2]] ]
+ reverseflag = 0
+ for flag in self.reversepanel:
+ if flag == i:
+ reverseflag = 1
+ p = panel(panpoints, panedges, reverseflag, self)
+
+ def sphericalize(self):
+ if self.shape == 2:
+ self.cutbasecomp()
+ for vert in(self.verts):
+
+ x = vert.vector.x
+ y = vert.vector.y
+ z = vert.vector.z
+
+ u = self.usphericalise(x,y,z)
+ v = self.vsphericalise(x,y,z)
+ self.sphericalverts.append([u,v])
+
+ def sphere2cartesian(self):
+ for i in range(len(self.verts)):
+ if self.cart:
+
+ x = self.verts[i].vector.x * self.radius * self.eccentricity
+ y = self.verts[i].vector.y * self.radius
+ z = self.verts[i].vector.z * self.radius * self.squish
+ else:
+ u = self.sphericalverts[i][0]
+ v = self.sphericalverts[i][1]
+ if self.squish != 1.0 or self.eccentricity>1.0:
+ scalez = 1 / self.squish
+ v = self.ellipsecomp(scalez,v)
+ u = self.ellipsecomp(self.eccentricity,u)
+ if self.super:
+ r1 = self.superell(self.square,u,self.rotxy)
+ r2 = self.superell(self.squarez,v,self.rotz)
+ else:
+ r1 = 1.0
+ r2 = 1.0
+
+ if self.sform[12]:
+ r1 = r1 * self.superform(self.sform[0],self.sform[1],\
+ self.sform[2],self.sform[3],\
+ self.sform[14] + u,self.sform[4],\
+ self.sform[5],self.sform[16] * v)
+ if self.sform[13]:
+ r2 = r2 * self.superform(self.sform[6],self.sform[7],\
+ self.sform[8],self.sform[9],\
+ self.sform[15] + v,self.sform[10],\
+ self.sform[11],self.sform[17] * v)
+ x,y,z = self.cartesian(u,v,r1,r2)
+
+ self.verts[i] = vertex((x,y,z))
+
+ def usphericalise(self,x,y,z):
+ if y == 0.0:
+ if x>0:
+ theta = 0.0
+ else:
+ theta = self.a180
+ elif x == 0.0:
+ if y>0:
+ theta = self.a90
+ else:
+ theta = self.a270
+
+ else:
+ theta = atan(y / x)
+ if x < 0.0 and y < 0.0:
+ theta = theta + self.a180
+ elif x < 0.0 and y>0.0:
+ theta = theta + self.a180
+ u = theta
+ return u
+
+ def vsphericalise(self,x,y,z) :
+ if z == 0.0:
+ phi = self.a90
+ else:
+ rho = sqrt(x ** 2 + y**2 + z**2)
+ phi = acos(z / rho)
+ v = phi
+ return v
+
+ def ellipsecomp(self,efactor,theta):
+ if theta == self.a90:
+ result = self.a90
+ elif theta == self.a270:
+ result = self.a270
+ else:
+ result = atan(tan(theta) / efactor**0.5)
+ if result>=0.0:
+ x = result
+ y = self.a180 + result
+ if fabs(x - theta) <= fabs(y - theta):
+ result = x
+ else:
+ result = y
+ else:
+ x = self.a180 + result
+ y = result
+
+ if fabs(x - theta) <= fabs(y - theta):
+ result = x
+ else:
+ result = y
+ return result
+
+ def cutbasecomp(self):
+ pass
+
+ def cartesian(self,u,v,r1,r2):
+ x = r1 * cos(u) * r2 * sin(v) * self.radius * self.eccentricity
+ y = r1 * sin(u) * r2 * sin(v) * self.radius
+ z = r2 * cos(v) * self.radius * self.squish
+ return x,y,z
+
+
+class edgerow:
+ def __init__(self, count, anchor, leftindex, rightindex, stepvector, endflag, parentgeo):
+ self.points = []
+ self.edges = []
+ ## Make a row of evenly spaced points.
+ for i in range(count + 1):
+ if i == 0:
+ self.points.append(leftindex)
+ elif i == count and not endflag:
+ self.points.append(rightindex)
+ else: #PKHG Vectors added!
+ newpoint = anchor + (stepvector * i)
+ vertcount = len(parentgeo.verts)
+ self.points.append(vertcount)
+ newpoint.index = vertcount
+ parentgeo.verts.append(newpoint)
+ for i in range(count):
+ a = parentgeo.verts[self.points[i]]
+ b = parentgeo.verts[self.points[i + 1]]
+ line = edge(a,b)
+ self.edges.append(len(parentgeo.edges))
+ parentgeo.edges.append(line)
+
+class skeletonrow:
+ def __init__(self, count, skeletonedge, shortflag, parentgeo):
+ self.points = []
+ self.edges = []
+ self.vect = skeletonedge.vect
+ self.step = skeletonedge.vect / float(count)
+ ## Make a row of evenly spaced points.
+ for i in range(count + 1):
+ vert1 = skeletonedge.a
+ vert2 = skeletonedge.b
+ if i == 0:
+ if parentgeo.vertsdone[vert1.index][0]:
+ self.points.append(parentgeo.vertsdone[vert1.index][1])
+ else:
+ newpoint = vertex(vert1.vector)
+ vertcount = len(parentgeo.verts)
+ self.points.append(vertcount)
+ newpoint.index = vertcount
+ parentgeo.vertsdone[vert1.index] = [1,vertcount]
+ parentgeo.verts.append(newpoint)
+
+ elif i == count:
+ if parentgeo.vertsdone[vert2.index][0]:
+ self.points.append(parentgeo.vertsdone[vert2.index][1])
+ else:
+
+ newpoint = vertex(vert2.vector)
+ vertcount = len(parentgeo.verts)
+ self.points.append(vertcount)
+ newpoint.index = vertcount
+ parentgeo.vertsdone[vert2.index] = [1,vertcount]
+ parentgeo.verts.append(newpoint)
+ else:
+ newpoint = vertex(vert1.vector + (self.step * i)) #must be a vertex!
+ vertcount = len(parentgeo.verts)
+ self.points.append(vertcount)
+ newpoint.index = vertcount
+ parentgeo.verts.append(newpoint)
+ for i in range(count):
+ a = parentgeo.verts[self.points[i]]
+ b = parentgeo.verts[self.points[i + 1]]
+ line = edge(a,b)
+ self.edges.append(len(parentgeo.edges))
+ parentgeo.edges.append(line)
+
+class facefill:
+ def __init__(self, upper, lower, reverseflag, parentgeo, finish):
+ for i in range(finish):
+ a,b,c = upper.points[i],lower.points[i + 1],lower.points[i]
+ if reverseflag:
+ upface = face([parentgeo.verts[a],parentgeo.verts[c],parentgeo.verts[b]])
+ else:
+ upface = face([parentgeo.verts[a],parentgeo.verts[b],parentgeo.verts[c]])
+ parentgeo.faces.append(upface)
+ if i == finish - 1:
+ pass
+ else:
+ d = upper.points[i + 1]
+ if reverseflag:
+ downface = face([parentgeo.verts[b],parentgeo.verts[d],parentgeo.verts[a]])
+ else:
+ downface = face([parentgeo.verts[b],parentgeo.verts[a],parentgeo.verts[d]])
+ line = edge(parentgeo.verts[a],parentgeo.verts[b])
+ line2 = edge(parentgeo.verts[d],parentgeo.verts[b])
+ parentgeo.faces.append(downface)
+ parentgeo.edges.append(line)
+ parentgeo.edges.append(line2)
+class panel:
+ def __init__(self, points, edges, reverseflag, parentgeo):
+ self.cardinal = points[0]
+ self.leftv = points[1]
+ self.rightv = points[2]
+ self.leftedge = edges[0]
+ self.rightedge = edges[1]
+ self.baseedge = edges[2]
+ self.rows=[]
+ self.orient(parentgeo,edges)
+ self.createrows(parentgeo)
+ self.createfaces(parentgeo,reverseflag)
+
+ def orient(self,parentgeo,edges):
+ if self.leftedge.points[0] != self.cardinal.index:
+ self.leftedge.points.reverse()
+ self.leftedge.vect.negative()
+
+ if self.rightedge.points[0] != self.cardinal.index:
+ self.rightedge.points.reverse()
+ self.rightedge.vect.negative()
+
+ if self.baseedge.points[0] != self.leftv.index:
+
+ self.baseedge.points.reverse()
+ self.baseedge.vect.negative()
+
+ def createrows(self, parentgeo):
+ for i in range(len(self.leftedge.points)):
+ if i == parentgeo.frequency:
+ newrow = self.baseedge
+ else:
+ newrow = edgerow(i, parentgeo.verts[self.leftedge.points[i]], self.leftedge.points[i], self.rightedge.points[i], self.baseedge.step, 0, parentgeo )
+ self.rows.append(newrow)
+
+ def createfaces(self, parentgeo,reverseflag):
+ for i in range(len(self.leftedge.points) - 1):
+ facefill(self.rows[i], self.rows[i + 1], reverseflag, parentgeo, len(self.rows[i].points))
+
+#for point on top? YES!
+class tetrahedron(geodesic,mesh):
+ def __init__(self,parameter):
+ geodesic.__init__(mesh)
+ geodesic.setparameters(self,parameter)
+ self.set_vert_edge_skeleons()
+
+ def set_vert_edge_skeleons(self):
+ self.vertskeleton=[ vertex(( 0.0 , 0.0 , 1.73205080757 )),
+ vertex(( 0.0 , -1.63299316185 , -0.577350269185 )),
+ vertex(( 1.41421356237 , 0.816496580927 , -0.57735026919 )),
+ vertex(( -1.41421356237 , 0.816496580927 , -0.57735026919 )) ]
+ self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]),
+ edge(self.vertskeleton[0],self.vertskeleton[2]),
+ edge(self.vertskeleton[0],self.vertskeleton[3]),
+ edge(self.vertskeleton[1],self.vertskeleton[2]),
+ edge(self.vertskeleton[2],self.vertskeleton[3]),
+ edge(self.vertskeleton[1],self.vertskeleton[3]) ]
+
+ self.panelpoints=[[0,1,2],[0,2,3],[0,1,3],[1,2,3]]
+ self.paneledges=[[0,1,3],[1,2,4],[0,2,5],[3,5,4]]
+ self.reversepanel=[2,3]
+ self.edgelength=[]
+ self.vertsdone=[[0,0]] * len(self.vertskeleton)
+
+#for edge on top? YES
+class tetraedge(geodesic):
+ def __init__(self,parameter):
+ geodesic.__init__(mesh)
+ geodesic.setparameters(self,parameter)
+ self.set_vert_edge_skeleons()
+
+ def set_vert_edge_skeleons(self):
+ self.vertskeleton=[ vertex(( 0.0 , -1.41421356237 , 1.0 )),
+ vertex(( 0.0 , 1.41421356237 , 1.0 )),
+ vertex(( 1.41421356237 , 0.0 , -1.0 )),
+ vertex(( -1.41421356237 , 0.0 , -1.0 )) ]
+ self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]),
+ edge(self.vertskeleton[0],self.vertskeleton[2]),
+ edge(self.vertskeleton[0],self.vertskeleton[3]),
+ edge(self.vertskeleton[1],self.vertskeleton[3]),
+ edge(self.vertskeleton[1],self.vertskeleton[2]),
+ edge(self.vertskeleton[2],self.vertskeleton[3]) ]
+ for i in range(len(self.vertskeleton)):
+ self.vertskeleton[i].index = i
+ self.panelpoints=[[0,1,2],[1,2,3],[0,1,3],[0,2,3]]
+ self.paneledges=[[0,1,4],[4,3,5],[0,2,3],[1,2,5]]
+ self.reversepanel=[0,3]
+ self.edgelength=[]
+ self.vertsdone=[[0,0]] * len(self.vertskeleton)
+
+#for face on top? YES
+class tetraface(geodesic):
+ def __init__(self,parameter):
+ geodesic.__init__(mesh)
+ geodesic.setparameters(self,parameter)
+ self.set_vert_edge_skeleons()
+
+ def set_vert_edge_skeleons(self):
+ self.vertskeleton=[ vertex(( -1.41421356237 , -0.816496580927 , 0.57735026919 )),
+ vertex(( 1.41421356237 , -0.816496580927 , 0.57735026919 )),
+ vertex(( 0.0 , 1.63299316185 , 0.577350269185 )),
+ vertex(( 0.0 , 0.0 , -1.73205080757 )) ]
+ self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]),
+ edge(self.vertskeleton[2],self.vertskeleton[1]),
+ edge(self.vertskeleton[2],self.vertskeleton[0]),
+ edge(self.vertskeleton[0],self.vertskeleton[3]),
+ edge(self.vertskeleton[1],self.vertskeleton[3]),
+ edge(self.vertskeleton[2],self.vertskeleton[3]) ]
+ self.panelpoints=[[2,0,1],[0,1,3],[2,1,3],[2,0,3]]
+ self.paneledges=[[2,1,0],[0,3,4],[1,5,4],[2,5,3]]
+ self.reversepanel=[1,3]
+ self.edgelength=[]
+ self.vertsdone=[[0,0]] * len(self.vertskeleton)
+
+class octahedron(geodesic):
+ def __init__(self,parameter):
+ geodesic.__init__(mesh)
+ geodesic.setparameters(self,parameter)
+ self.set_vert_edge_skeleons()
+
+ def set_vert_edge_skeleons(self):
+ self.vertskeleton=[ vertex((0.0,0.0,1.0)),
+ vertex((0.0,1.0,0.0)),
+ vertex((-1.0,0.0,0.0)),
+ vertex((0.0,-1.0,0.0)),
+ vertex((1.0,0.0,0.0)),
+ vertex((0.0,0.0,-1.0)) ]
+ for i in range(len(self.vertskeleton)):
+ self.vertskeleton[i].index = i
+ self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]),
+ edge(self.vertskeleton[0],self.vertskeleton[2]),
+ edge(self.vertskeleton[0],self.vertskeleton[3]),
+ edge(self.vertskeleton[0],self.vertskeleton[4]),
+ edge(self.vertskeleton[1],self.vertskeleton[2]),
+ edge(self.vertskeleton[2],self.vertskeleton[3]),
+ edge(self.vertskeleton[3],self.vertskeleton[4]),
+ edge(self.vertskeleton[4],self.vertskeleton[1]),
+ edge(self.vertskeleton[1],self.vertskeleton[5]),
+ edge(self.vertskeleton[2],self.vertskeleton[5]),
+ edge(self.vertskeleton[3],self.vertskeleton[5]),
+ edge(self.vertskeleton[4],self.vertskeleton[5]) ]
+ self.panelpoints=[[0,1,2],[0,2,3],[0,3,4],[0,4,1],[1,2,5],[2,3,5],[3,4,5],[4,1,5]]
+ self.paneledges=[[0,1,4],[1,2,5],[2,3,6],[3,0,7],[4,8,9],[5,9,10],[6,10,11],[7,11,8]]
+ self.reversepanel=[4,5,6,7]
+ self.edgelength=[]
+ self.vertsdone=[[0,0]] * len(self.vertskeleton)
+
+class octaedge(geodesic):
+ def __init__(self,parameter):
+ geodesic.__init__(mesh)
+ geodesic.setparameters(self,parameter)
+ self.set_vert_edge_skeleons()
+
+ def set_vert_edge_skeleons(self):
+ self.vertskeleton=[ vertex(( 0.0 , -0.707106781187 , 0.707106781187 )),
+ vertex(( 0.0 , 0.707106781187 , 0.707106781187 )),
+ vertex(( 1.0 , 0.0 , 0.0 )),
+ vertex(( -1.0 , 0.0 , 0.0 )),
+ vertex(( 0.0 , -0.707106781187 , -0.707106781187 )),
+ vertex(( 0.0 , 0.707106781187 , -0.707106781187 )) ]
+ self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]),
+ edge(self.vertskeleton[0],self.vertskeleton[4]),
+ edge(self.vertskeleton[0],self.vertskeleton[2]),
+ edge(self.vertskeleton[1],self.vertskeleton[2]),
+ edge(self.vertskeleton[1],self.vertskeleton[5]),
+ edge(self.vertskeleton[1],self.vertskeleton[3]),
+ edge(self.vertskeleton[0],self.vertskeleton[3]),
+ edge(self.vertskeleton[2],self.vertskeleton[4]),
+ edge(self.vertskeleton[2],self.vertskeleton[5]),
+ edge(self.vertskeleton[3],self.vertskeleton[5]),
+ edge(self.vertskeleton[3],self.vertskeleton[4]),
+ edge(self.vertskeleton[4],self.vertskeleton[5]) ]
+ self.panelpoints=[[0,1,2],[0,1,3],[0,2,4],[1,2,5],[1,3,5],[0,3,4],[2,4,5],[3,4,5]]
+ self.paneledges=[[0,2,3],[0,6,5],[2,1,7],[3,4,8],[5,4,9],[6,1,10],[7,8,11],[10,9,11]]
+ self.reversepanel=[0,2,4,7]
+ self.edgelength=[]
+ self.vertsdone=[[0,0]] * len(self.vertskeleton)
+
+class octaface(geodesic):
+ def __init__(self,parameter):
+ geodesic.__init__(mesh)
+ geodesic.setparameters(self,parameter)
+ self.set_vert_edge_skeleons()
+
+ def set_vert_edge_skeleons(self):
+ self.vertskeleton=[ vertex(( 0.408248458663 , -0.707106781187 , 0.577350150255 )),
+ vertex(( 0.408248458663 , 0.707106781187 , 0.577350150255 )),
+ vertex(( -0.816496412728 , 0.0 , 0.577350507059 )),
+ vertex(( -0.408248458663 , -0.707106781187 , -0.577350150255 )),
+ vertex(( 0.816496412728 , 0.0 , -0.577350507059 )),
+ vertex(( -0.408248458663 , 0.707106781187 , -0.577350150255 )) ]
+ self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]),
+ edge(self.vertskeleton[2],self.vertskeleton[1]),
+ edge(self.vertskeleton[2],self.vertskeleton[0]),
+ edge(self.vertskeleton[0],self.vertskeleton[3]),
+ edge(self.vertskeleton[0],self.vertskeleton[4]),
+ edge(self.vertskeleton[1],self.vertskeleton[4]),
+ edge(self.vertskeleton[1],self.vertskeleton[5]),
+ edge(self.vertskeleton[2],self.vertskeleton[5]),
+ edge(self.vertskeleton[2],self.vertskeleton[3]),
+ edge(self.vertskeleton[3],self.vertskeleton[4]),
+ edge(self.vertskeleton[4],self.vertskeleton[5]),
+ edge(self.vertskeleton[3],self.vertskeleton[5]) ]
+ self.panelpoints=[[2,0,1],[0,3,4],[0,1,4],[1,4,5],[2,1,5],[2,3,5],[2,0,3],[3,4,5]]
+ self.paneledges=[[2,1,0],[3,4,9],[0,4,5],[5,6,10],[1,7,6],[8,7,11],[2,8,3],[9,11,10]]
+ self.reversepanel=[2,5,6,7]
+ self.edgelength=[]
+ self.vertsdone=[[0,0]] * len(self.vertskeleton)
+
+class icosahedron(geodesic):
+ def __init__(self,parameter):
+ geodesic.__init__(mesh)
+ geodesic.setparameters(self,parameter)
+ self.set_vert_edge_skeleons()
+
+ def set_vert_edge_skeleons(self):
+ self.vertskeleton=[ vertex(( 0.0 , 0.0 , 0.587785252292 )),
+ vertex(( 0.0 , -0.525731096637 , 0.262865587024 )),
+ vertex(( 0.5 , -0.162459832634 , 0.262865565628 )),
+ vertex(( 0.309016994375 , 0.425325419658 , 0.262865531009 )),
+ vertex(( -0.309016994375 , 0.425325419658 , 0.262865531009 )),
+ vertex(( -0.5 , -0.162459832634 , 0.262865565628 )),
+ vertex(( 0.309016994375 , -0.425325419658 , -0.262865531009 )),
+ vertex(( 0.5 , 0.162459832634 , -0.262865565628 )),
+ vertex(( 0.0 , 0.525731096637 , -0.262865587024 )),
+ vertex(( -0.5 , 0.162459832634 , -0.262865565628 )),
+ vertex(( -0.309016994375 , -0.425325419658 , -0.262865531009 )),
+ vertex(( 0.0 , 0.0 , -0.587785252292 )) ]
+ self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]),
+ edge(self.vertskeleton[0],self.vertskeleton[2]),
+ edge(self.vertskeleton[0],self.vertskeleton[3]),
+ edge(self.vertskeleton[0],self.vertskeleton[4]),
+ edge(self.vertskeleton[0],self.vertskeleton[5]),
+ edge(self.vertskeleton[1],self.vertskeleton[2]),
+ edge(self.vertskeleton[2],self.vertskeleton[3]),
+ edge(self.vertskeleton[3],self.vertskeleton[4]),
+ edge(self.vertskeleton[4],self.vertskeleton[5]),
+ edge(self.vertskeleton[5],self.vertskeleton[1]),
+ edge(self.vertskeleton[1],self.vertskeleton[6]),
+ edge(self.vertskeleton[2],self.vertskeleton[6]),
+ edge(self.vertskeleton[2],self.vertskeleton[7]),
+ edge(self.vertskeleton[3],self.vertskeleton[7]),
+ edge(self.vertskeleton[3],self.vertskeleton[8]),
+ edge(self.vertskeleton[4],self.vertskeleton[8]),
+ edge(self.vertskeleton[4],self.vertskeleton[9]),
+ edge(self.vertskeleton[5],self.vertskeleton[9]),
+ edge(self.vertskeleton[5],self.vertskeleton[10]),
+ edge(self.vertskeleton[1],self.vertskeleton[10]),
+ edge(self.vertskeleton[6],self.vertskeleton[7]),
+ edge(self.vertskeleton[7],self.vertskeleton[8]),
+ edge(self.vertskeleton[8],self.vertskeleton[9]),
+ edge(self.vertskeleton[9],self.vertskeleton[10]),
+ edge(self.vertskeleton[10],self.vertskeleton[6]),
+ edge(self.vertskeleton[6],self.vertskeleton[11]),
+ edge(self.vertskeleton[7],self.vertskeleton[11]),
+ edge(self.vertskeleton[8],self.vertskeleton[11]),
+ edge(self.vertskeleton[9],self.vertskeleton[11]),
+ edge(self.vertskeleton[10],self.vertskeleton[11]) ]
+ self.panelpoints=[[0,1,2],[0,2,3],[0,3,4],[0,4,5],[0,5,1],[1,2,6],[2,6,7],[2,3,7],[3,7,8],[3,4,8],[4,8,9],[4,5,9],[5,9,10],[5,1,10],[1,10,6],[6,7,11],[7,8,11],[8,9,11],[9,10,11],[10,6,11]]
+ self.paneledges=[[0,1,5],[1,2,6],[2,3,7],[3,4,8],[4,0,9],[5,10,11],[11,12,20],[6,12,13],[13,14,21],[7,14,15],[15,16,22],[8,16,17],[17,18,23],[9,18,19],[19,10,24],[20,25,26],[21,26,27],[22,27,28],[23,28,29],[24,29,25]]
+ self.reversepanel=[5,7,9,11,13,15,16,17,18,19]
+ self.edgelength=[]
+ self.vertsdone=[[0,0]] * len(self.vertskeleton)
+
+class icoedge(geodesic):
+ def __init__(self,parameter):
+ geodesic.__init__(mesh)
+ geodesic.setparameters(self,parameter)
+ self.set_vert_edge_skeleons()
+
+ def set_vert_edge_skeleons(self):
+ self.vertskeleton=[ vertex(( 0 , 0.309016994375 , 0.5 )),
+ vertex(( 0 , -0.309016994375 , 0.5 )),
+ vertex(( -0.5 , 0 , 0.309016994375 )),
+ vertex(( 0.5 , 0 , 0.309016994375 )),
+ vertex(( -0.309016994375 , -0.5 , 0 )),
+ vertex(( 0.309016994375 , -0.5 , 0 )),
+ vertex(( 0.309016994375 , 0.5 , 0 )),
+ vertex(( -0.309016994375 , 0.5 , 0 )),
+ vertex(( -0.5 , 0 , -0.309016994375 )),
+ vertex(( 0.5 , 0 , -0.309016994375 )),
+ vertex(( 0 , 0.309016994375 , -0.5 )),
+ vertex(( 0 , -0.309016994375 , -0.5 )) ]
+ self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]),
+ edge(self.vertskeleton[0],self.vertskeleton[7]),
+ edge(self.vertskeleton[0],self.vertskeleton[2]),
+ edge(self.vertskeleton[1],self.vertskeleton[2]),
+ edge(self.vertskeleton[1],self.vertskeleton[4]),
+ edge(self.vertskeleton[1],self.vertskeleton[5]),
+ edge(self.vertskeleton[1],self.vertskeleton[3]),
+ edge(self.vertskeleton[0],self.vertskeleton[3]),
+ edge(self.vertskeleton[0],self.vertskeleton[6]),
+ edge(self.vertskeleton[2],self.vertskeleton[7]),
+ edge(self.vertskeleton[2],self.vertskeleton[8]),
+ edge(self.vertskeleton[2],self.vertskeleton[4]),
+ edge(self.vertskeleton[4],self.vertskeleton[5]),
+ edge(self.vertskeleton[3],self.vertskeleton[5]),
+ edge(self.vertskeleton[3],self.vertskeleton[9]),
+ edge(self.vertskeleton[3],self.vertskeleton[6]),
+ edge(self.vertskeleton[6],self.vertskeleton[7]),
+ edge(self.vertskeleton[7],self.vertskeleton[10]),
+ edge(self.vertskeleton[7],self.vertskeleton[8]),
+ edge(self.vertskeleton[4],self.vertskeleton[8]),
+ edge(self.vertskeleton[4],self.vertskeleton[11]),
+ edge(self.vertskeleton[5],self.vertskeleton[11]),
+ edge(self.vertskeleton[5],self.vertskeleton[9]),
+ edge(self.vertskeleton[6],self.vertskeleton[9]),
+ edge(self.vertskeleton[6],self.vertskeleton[10]),
+ edge(self.vertskeleton[8],self.vertskeleton[10]),
+ edge(self.vertskeleton[8],self.vertskeleton[11]),
+ edge(self.vertskeleton[9],self.vertskeleton[11]),
+ edge(self.vertskeleton[9],self.vertskeleton[10]),
+ edge(self.vertskeleton[10],self.vertskeleton[11]) ]
+ self.panelpoints=[ [0,1,2],[0,1,3],[0,2,7],[1,2,4],[1,4,5],[1,3,5],[0,3,6],[0,6,7],[2,7,8],[2,4,8],
+ [3,5,9],[3,6,9],[7,8,10],[4,8,11],[4,5,11],[5,9,11],[6,9,10],[6,7,10],[8,10,11],[9,10,11]]
+ self.paneledges=[[0,2,3],[0,7,6],[2,1,9],[3,4,11],[4,5,12],[6,5,13],[7,8,15],[8,1,16],[9,10,18],[11,10,19],
+ [13,14,22],[15,14,23],[18,17,25],[19,20,26],[12,20,21],[22,21,27],[23,24,28],[16,24,17],[25,26,29],[28,27,29]]
+ self.reversepanel=[0,2,5,9,11,12,14,15,17,19]
+ self.edgelength=[]
+ self.vertsdone=[[0,0]] * len(self.vertskeleton)
+
+class icoface(geodesic):
+ def __init__(self,parameter):
+ geodesic.__init__(mesh)
+ geodesic.setparameters(self,parameter)
+ self.set_vert_edge_skeleons()
+
+ def set_vert_edge_skeleons(self):
+ self.vertskeleton=[ vertex(( -0.17841104489 , 0.309016994375 , 0.46708617948 )),
+ vertex(( -0.17841104489 , -0.309016994375 , 0.46708617948 )),
+ vertex(( 0.35682208977 , 0.0 , 0.467086179484 )),
+ vertex(( -0.57735026919 , 0.0 , 0.110264089705 )),
+ vertex(( -0.288675134594 , -0.5 , -0.11026408971 )),
+ vertex(( 0.288675134594 , -0.5 , 0.11026408971 )),
+ vertex(( 0.57735026919 , 0.0 , -0.110264089705 )),
+ vertex(( 0.288675134594 , 0.5 , 0.11026408971 )),
+ vertex(( -0.288675134594 , 0.5 , -0.11026408971 )),
+ vertex(( -0.35682208977 , 0.0 , -0.467086179484 )),
+ vertex(( 0.17841104489 , -0.309016994375 , -0.46708617948 )),
+ vertex(( 0.17841104489 , 0.309016994375 , -0.46708617948 )) ]
+ self.edgeskeleton=[ edge(self.vertskeleton[0],self.vertskeleton[1]),
+ edge(self.vertskeleton[2],self.vertskeleton[1]),
+ edge(self.vertskeleton[2],self.vertskeleton[0]),
+ edge(self.vertskeleton[0],self.vertskeleton[3]),
+ edge(self.vertskeleton[1],self.vertskeleton[3]),
+ edge(self.vertskeleton[1],self.vertskeleton[4]),
+ edge(self.vertskeleton[1],self.vertskeleton[5]),
+ edge(self.vertskeleton[2],self.vertskeleton[5]),
+ edge(self.vertskeleton[2],self.vertskeleton[6]),
+ edge(self.vertskeleton[2],self.vertskeleton[7]),
+ edge(self.vertskeleton[0],self.vertskeleton[7]),
+ edge(self.vertskeleton[0],self.vertskeleton[8]),
+ edge(self.vertskeleton[3],self.vertskeleton[9]),
+ edge(self.vertskeleton[3],self.vertskeleton[4]),
+ edge(self.vertskeleton[5],self.vertskeleton[4]),
+ edge(self.vertskeleton[5],self.vertskeleton[10]),
+ edge(self.vertskeleton[5],self.vertskeleton[6]),
+ edge(self.vertskeleton[7],self.vertskeleton[6]),
+ edge(self.vertskeleton[7],self.vertskeleton[11]),
+ edge(self.vertskeleton[7],self.vertskeleton[8]),
+ edge(self.vertskeleton[3],self.vertskeleton[8]),
+ edge(self.vertskeleton[4],self.vertskeleton[9]),
+ edge(self.vertskeleton[4],self.vertskeleton[10]),
+ edge(self.vertskeleton[6],self.vertskeleton[10]),
+ edge(self.vertskeleton[6],self.vertskeleton[11]),
+ edge(self.vertskeleton[8],self.vertskeleton[11]),
+ edge(self.vertskeleton[8],self.vertskeleton[9]),
+ edge(self.vertskeleton[9],self.vertskeleton[10]),
+ edge(self.vertskeleton[11],self.vertskeleton[10]),
+ edge(self.vertskeleton[11],self.vertskeleton[9]) ]
+ self.panelpoints=[[2,0,1],[0,1,3],[2,1,5],[2,0,7],[1,3,4],[1,5,4],[2,5,6],[2,7,6],[0,7,8],[0,3,8],[3,4,9],[5,4,10],[5,6,10],[7,6,11],[7,8,11],[3,8,9],[4,9,10],[6,11,10],[8,11,9],[11,9,10]]
+ self.paneledges=[[2,1,0],[0,3,4],[1,7,6],[2,9,10],[4,5,13],[6,5,14],[7,8,16],[9,8,17],[10,11,19],[3,11,20],
+ [13,12,21],[14,15,22],[16,15,23],[17,18,24],[19,18,25],[20,12,26],[21,22,27],[24,23,28],[25,26,29],[29,28,27]]
+ self.reversepanel=[1,3,5,7,9,10,12,14,17,19]
+ self.edgelength=[]
+ self.vertsdone=[[0,0]] * len(self.vertskeleton)
+
+##???PKHG TODO this does not work yet ...
+def creategeo(geo,polytype,orientation,parameters):
+
+ if polytype == 'Tetrahedron':
+ if orientation == 'PointUp':
+ my_tetrahedron = tetrahedron(geodesic)
+ my_tetrahedron.set_vert_edge_skeleons()
+ my_tetrahedron.config()
+ check_contains(my_tetrahedron,"my_tetra",True)
+ vefm_add_object(geo)
+ elif orientation == 'EdgeUp':
+ geo = tetraedge(parameters)
+ else: # orientation==2:
+ geo=tetraface(parameters)
+ elif polytype == 'Octahedron': # octahedron
+ if orientation == 'PointUp':
+ geo = octahedron(parameters)
+ elif orientation == 'EdgeUp':
+ geo = octaedge(parameters)
+ else: #if orientation==2:
+ geo = octaface(parameters)
+ elif polytype == 'Icosahedron': # icosahedron
+ if orientation == 'PointUp':
+ geo = icosahedron(parameters)
+ elif orientation == 'EdgeUp':
+ geo = icoedge(parameters)
+ else: #if orientation==2:
+ geo = icoface(parameters)
+ return geo
diff --git a/add_mesh_extra_objects/geodesic_domes/third_domes_panel_271.py b/add_mesh_extra_objects/geodesic_domes/third_domes_panel_271.py
new file mode 100644
index 00000000..bca0f71f
--- /dev/null
+++ b/add_mesh_extra_objects/geodesic_domes/third_domes_panel_271.py
@@ -0,0 +1,1016 @@
+import bpy
+import os
+from . import vefm_271
+from . import forms_271
+from . import geodesic_classes_271
+from . import add_shape_geodesic
+
+from bpy.props import EnumProperty, IntProperty, FloatProperty, StringProperty, BoolProperty
+from math import pi
+from mathutils import Vector #needed to check vertex.vector values
+
+
+########global######
+last_generated_object = None
+last_imported_mesh = None
+basegeodesic = None
+imported_hubmesh_to_use = None
+########global end######
+
+########EIND FOR SHAPEKEYS######
+### error messages?!
+bpy.types.Scene.error_message = StringProperty(name="actual error", default = "")
+
+
+bpy.types.Scene.geodesic_not_yet_called = BoolProperty(name="geodesic_not_called",default = True)
+
+bpy.types.Scene.gd_help_text_width = IntProperty(name = "Text Width" , description = "The width above which the text wraps" , default = 60 , max = 180 , min = 20)
+
+class GenerateGeodesicDome(bpy.types.Operator):
+ bl_label = "Modify Geodesic Objects"
+ bl_idname = "mesh.generate_geodesic_dome"
+ bl_description = "Create Geodesic Object Types"
+ bl_options = {'REGISTER', 'UNDO'}
+
+#PKHG_NEW saving and loading parameters
+ save_parameters = BoolProperty(name = "save params",\
+ description = "activation save */tmp/GD_0.GD", default = False)
+ load_parameters = BoolProperty(name = "load params",\
+ description = "read */tmp/GD_0.GD", default = False)
+
+ gd_help_text_width = IntProperty(name = "Text Width" , description = "The width above which the text wraps" , default = 60 , max = 180 , min = 20)
+
+
+ mainpages = EnumProperty(
+ name="Menu",
+ description="Create Faces, Struts & Hubs",
+ items=[("Main", "Main", "Geodesic objects"),
+ ("Faces", "Faces", "Generate Faces"),
+ ("Struts", "Struts", "Generate Struts"),
+ ("Hubs", "Hubs", "Generate Hubs"),
+ ("Help", "Help", "Not implemented"),
+ ],
+ default='Main')
+
+#for Faces!
+ facetype_menu = EnumProperty(
+ name="Faces",
+ description="choose a facetype",
+ items=[("0", "strip", "strip"),
+ ("1", "open vertical", "vertical"),
+ ("2", "open slanted", "slanted"),
+ ("3", "closed point", "closed point"),
+ ("4", "pillow", "pillow"),
+ ("5", "closed vertical", "closed vertical"),
+ ("6", "stepped", "stepped"),
+ ("7", "spikes", "spikes"),
+ ("8", "boxed", "boxed"),
+ ("9", "diamond", "diamond"),
+ ("10", "bar", "bar"),
+ ],
+ default='0')
+
+ facetoggle = BoolProperty(name="Activate: Face Object", description = "Activate Faces for Geodesic object", default = False )
+
+ face_use_imported_object = BoolProperty(name="Use: Imported Object",\
+ description = "Activate faces on your Imported object", default = False)
+ facewidth = FloatProperty(name="facewidth", min = -1, soft_min = 0.001, max = 4, default = .50)
+ fwtog = BoolProperty(name="fwtog", default = False )
+ faceheight = FloatProperty(name="faceheight", min = 0.001, max = 4, default = 1 )
+ fhtog = BoolProperty(name="fhtog", default = False )
+ face_detach = BoolProperty(name="face_detach", default = False )
+ fmeshname = StringProperty(name="fmeshname", default = "defaultface")
+
+
+ geodesic_types = EnumProperty(
+ name="Objects",
+ description="Choose Geodesic, Grid, Cylinder, Parabola,\
+ Torus, Sphere, Import your mesh or Superparameters",
+ items=[("Geodesic", "Geodesic", "Generate Geodesic"),
+ ("Grid", "Grid", "Generate Grid"),
+ ("Cylinder", "Cylinder", "Generate Cylinder"),
+ ("Parabola", "Parabola", "Generate Parabola"),
+ ("Torus", "Torus", "Generate Torus"),
+ ("Sphere", "Sphere", "Generate Sphere"),
+ ("Import your mesh", "Import your mesh", "Import Your Mesh"),
+ ],
+ default = 'Geodesic')
+
+ import_mesh_name = StringProperty(name = "mesh to import",\
+ description = "the name has to be the name of a meshobject", default = "None")
+
+ base_type = EnumProperty(
+ name="Hedron",
+ description="Choose between Tetrahedron, Octahedron, Icosahedron ",\
+ items=[("Tetrahedron", "Tetrahedron", "Generate Tetrahedron"),\
+ ("Octahedron", "Octahedron", "Generate Octahedron"),\
+ ("Icosahedron", "Icosahedron", "Generate Icosahedron"),
+ ],
+ default='Tetrahedron')
+
+ orientation = EnumProperty(
+ name="Point^",
+ description="Point (Vert), Edge or Face pointing upwards",
+ items=[("PointUp", "PointUp", "Point up"),
+ ("EdgeUp", "EdgeUp", "Edge up"),
+ ("FaceUp", "FaceUp", "Face up"),
+ ],
+ default='PointUp')
+
+ geodesic_class = EnumProperty(
+ name="Class",
+ description="Subdivide Basic/Triacon",
+ items=[("Class 1", "Class 1", "class one"),
+ ("Class 2", "Class 2", "class two"),
+ ],
+ default='Class 1')
+
+ tri_hex_star = EnumProperty(
+ name="Shape",
+ description="Choose between tri hex star face types",
+ items=[("tri", "tri", "tri faces"),
+ ("hex", "hex", "hex faces(by tri)"),
+ ("star", "star", "star faces(by tri)"),
+ ],
+ default='tri')
+
+ spherical_flat = EnumProperty(
+ name="Round",
+ description="Choose between spherical or flat ",
+ items=[("spherical", "spherical", "Generate spherical"),
+ ("flat", "flat", "Generate flat"),
+ ],
+ default='spherical')
+
+ use_imported_mesh = BoolProperty(name="use import",\
+ description = "Use an imported mesh", default = False)
+
+#Cylinder
+ cyxres= IntProperty(name="Resolution x/y", min = 3, max = 32,\
+ description = "number of faces around x/y", default = 5 )
+ cyyres= IntProperty(name="Resolution z", min = 3, max = 32,\
+ description = "number of faces in z direction", default = 5 )
+ cyxsz= FloatProperty(name="Scale x/y", min = 0.01, max = 10,\
+ description = "scale in x/y direction", default = 1 )
+ cyysz= FloatProperty(name="Scale z", min = 0.01, max = 10,\
+ description = "scale in z direction", default = 1 )
+ cyxell= FloatProperty(name="Stretch x", min = 0.001, max = 4,\
+ description = "stretch in x direction", default = 1 )
+ cygap= FloatProperty(name="Gap", min = -2, max = 2,\
+ description = "shrink in % around radius", default = 1 )
+ cygphase= FloatProperty(name="Phase", min = -4, max = 4,\
+ description = "rotate around pivot x/y", default = 0 )
+#Parabola
+ paxres= IntProperty(name="Resolution x/y", min = 3, max = 32,\
+ description = "number of faces around x/y", default = 5 )
+ payres= IntProperty(name="Resolution z", min = 3, max = 32,\
+ description = "number of faces in z direction", default = 5 )
+ paxsz= FloatProperty(name="Scale x/y", min = 0.001, max = 10,\
+ description = "scale in x/y direction", default = 0.30)
+ paysz= FloatProperty(name="Scale z", min = 0.001, max = 10,\
+ description = "scale in z direction", default = 1 )
+ paxell= FloatProperty(name="Stretch x", min = 0.001, max = 4,\
+ description = "stretch in x direction", default = 1 )
+ pagap= FloatProperty(name="Gap", min = -2, max = 2,\
+ description = "shrink in % around radius", default = 1 )
+ pagphase= FloatProperty(name="Phase", min = -4, max = 4,\
+ description = "rotate around pivot x/y", default = 0 )
+#Torus
+ ures= IntProperty(name="Resolution x/y",min = 3, max = 32,\
+ description = "number of faces around x/y", default = 8 )
+ vres= IntProperty(name="Resolution z", min = 3, max = 32,\
+ description = "number of faces in z direction", default = 8 )
+ urad= FloatProperty(name="Radius x/y", min = 0.001, max = 10,\
+ description = "radius in x/y plane", default = 1 )
+ vrad= FloatProperty(name="Radius z", min = 0.001, max = 10,\
+ description = "radius in z plane", default = 0.250)
+ uellipse= FloatProperty(name="Stretch x", min = 0.001, max = 10,\
+ description = "number of faces in z direction", default = 1 )
+ vellipse= FloatProperty(name="Stretch z", min = 0.001, max = 10,\
+ description = "number of faces in z direction", default = 1 )
+ upart= FloatProperty(name="Gap x/y", min = -4, max = 4,\
+ description = "shrink faces around x/y", default = 1 )
+ vpart= FloatProperty(name="Gap z", min = -4, max = 4,\
+ description = "shrink faces in z direction", default = 1 )
+ ugap= FloatProperty(name="Phase x/y", min = -4, max = 4,\
+ description = "rotate around pivot x/y", default = 0 )
+ vgap= FloatProperty(name="Phase z", min = -4, max = 4,\
+ description = "rotate around pivot z", default = 0 )
+ uphase= FloatProperty(name="uphase", min = -4, max = 4,\
+ description = "number of faces in z direction", default = 0 )
+ vphase= FloatProperty(name="vphase", min = -4, max = 4,\
+ description = "number of faces in z direction", default = 0 )
+ uexp= FloatProperty(name="uexp", min = -4, max = 4,\
+ description = "number of faces in z direction", default = 0 )
+ vexp= FloatProperty(name="vexp", min = -4, max = 4,\
+ description = "number of faces in z direction", default = 0 )
+ usuper= FloatProperty(name="usuper", min = -4, max = 4,\
+ description = "first set of superform parameters", default = 2 )
+ vsuper= FloatProperty(name="vsuper", min = -4, max = 4,\
+ description = "second set of superform parameters", default = 2 )
+ utwist= FloatProperty(name="Twist x/y", min = -4, max = 4,\
+ description = " use with superformular u", default = 0 )
+ vtwist= FloatProperty(name="Twist z", min = -4, max = 4,\
+ description = "use with superformular v", default = 0 )
+
+#Sphere
+ bures= IntProperty(name="Resolution x/y", min = 3, max = 32,\
+ description = "number of faces around x/y", default = 8 )
+ bvres= IntProperty(name="Resolution z", min = 3, max = 32,\
+ description = "number of faces in z direction", default = 8 )
+ burad= FloatProperty(name="Radius", min = -4, max = 4,\
+ description = "overall radius", default = 1 )
+ bupart= FloatProperty(name="Gap x/y", min = -4, max = 4,\
+ description = "shrink faces around x/y", default = 1 )
+ bvpart= FloatProperty(name="Gap z", min = -4, max = 4,\
+ description = "shrink faces in z direction", default = 1 )
+ buphase= FloatProperty(name="Phase x/y", min = -4, max = 4,
+ description = "rotate around pivot x/y", default = 0 )
+ bvphase= FloatProperty(name="Phase z", min = -4, max = 4,\
+ description = "rotate around pivot z", default = 0 )
+ buellipse= FloatProperty(name="Stretch x", min = 0.001, max = 4,\
+ description = "stretch in the x direction", default = 1 )
+ bvellipse= FloatProperty(name="Stretch z", min = 0.001, max = 4,\
+ description = "stretch in the z direction", default = 1 )
+#Grid
+ grxres = IntProperty(name="Resolution x", min = 2, soft_max = 10, max = 20,\
+ description = "number of faces in x direction", default = 5 )
+ gryres = IntProperty(name="Resolution z",min = 2, soft_min = 2, soft_max=10, max = 20,\
+ description = "number of faces in x direction", default = 2)
+ grxsz = FloatProperty(name = "X size", min = 1, soft_min=0.01, soft_max=5, max = 10,\
+ description = "x size", default = 2.0)
+ grysz = FloatProperty(name="Y size",min = 1, soft_min=0.01, soft_max=5, max = 10,\
+ description = "y size", default = 1.0)
+
+#PKHG_TODO_??? what means cart
+ cart = IntProperty(name = "cart",min = 0, max = 2, default = 0)
+ frequency = IntProperty(name="Frequency", min = 1, max = 8,\
+ description ="subdivide base triangles", default = 1 )
+ eccentricity = FloatProperty(name = "Eccentricity", min = 0.01 , max = 4,\
+ description = "scaling in x/y dimension", default = 1 )
+ squish = FloatProperty(name = "Squish",min = 0.01, soft_max = 4, max = 10,\
+ description = "scaling in z dimension", default = 1 )
+ radius = FloatProperty(name = "Radius",min = 0.01, soft_max = 4, max = 10,\
+ description = "overall radius", default = 1 )
+ squareness = FloatProperty(name="Square x/y", min = 0.1, max = 5,\
+ description = "superelipse action in x/y", default = 2 )
+ squarez = FloatProperty(name="Square z", min = 0.1, soft_max = 5, max = 10,\
+ description = "superelipse action in z", default = 2 )
+ baselevel = IntProperty(name="baselevel", default = 5 )
+ dual = BoolProperty(name="Dual", description = "faces become verts,\
+ verts become faces, edges flip", default = False)
+ rotxy = FloatProperty(name="Rotate x/y", min= -4, max = 4,\
+ description = "rotate superelipse action in x/y", default = 0 )
+ rotz = FloatProperty(name="Rotate z", min= -4, max = 4,\
+ description = "rotate superelipse action in z", default = 0 )
+
+#for choice of superformula
+ uact = BoolProperty(name = 'superformula u (x/y)',\
+ description = "activate superformula u parameters", default = False)
+ vact = BoolProperty(name = 'superformula v (z)',\
+ description = "activate superformula v parameters", default = False)
+ um = FloatProperty(name = 'Pinch x/y', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "Pinch the mesh on x/y", default = 3)
+ un1 = FloatProperty(name = 'Squash x/y', min = 0, soft_min=0.1, soft_max=5,max = 20,\
+ description = "Squash the mesh x/y", default = 1)
+ un2 = FloatProperty(name = 'Inflate x/y', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "Inflate the mesh x/y", default = 1)
+ un3 = FloatProperty(name = 'Roundify x/y', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "Roundify x/y", default = 1)
+ ua = FloatProperty(name = 'Shrink', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "Shrink", default = 1.0)
+ ub = FloatProperty(name = 'Shrink x/y', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "Shrink y/x", default = 4.0)
+ vm = FloatProperty(name = 'Scale Z Base', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "Scale Z Base", default = 1)
+ vn1 = FloatProperty(name = 'Scale lock Top Z', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "Scale lock Top Z", default = 1)
+ vn2 = FloatProperty(name = 'Inflate Base', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "Inflate Base", default = 1)
+ vn3 = FloatProperty(name = 'Inflate', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "Inflate", default = 1)
+ va = FloatProperty(name = 'Scale 1', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "Scale 1", default = 1)
+ vb = FloatProperty(name = 'Scale 2', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "Scale 2", default = 1)
+
+ uturn = FloatProperty(name = 'x/y Vert cycle', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "x/y Vert cycle", default = 0)
+ vturn = FloatProperty(name = 'z Vert cycle', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "z Vert cycle", default = 0)
+ utwist = FloatProperty(name = 'x/y Twist cycle', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "x/y Twist cycle", default = 0)
+ vtwist = FloatProperty(name = 'z Twist cycle', min = 0, soft_min=0.1, soft_max=5,max = 10,\
+ description = "z Twist cycle", default = 0)
+
+#Strut
+ struttype= IntProperty(name="struttype", default= 0)
+ struttoggle = BoolProperty(name="struttoggle", default = False )
+ strutimporttoggle= BoolProperty(name="strutimporttoggle", default = False )
+ strutimpmesh= StringProperty(name="strutimpmesh", default = "None")
+ strutwidth= FloatProperty(name="strutwidth", min = -10, soft_min = 5, soft_max = 5,\
+ max = 10, default = 1 )
+ swtog= BoolProperty(name="swtog", default = False )
+ strutheight= FloatProperty(name="strutheight", min = -5, soft_min = -1, soft_max = 5,\
+ max = 10, default = 1 )
+ shtog= BoolProperty(name="shtog", default = False )
+ strutshrink= FloatProperty(name="strutshrink", min = 0.001, max = 4, default = 1 )
+ sstog= BoolProperty(name="sstog", default = False )
+ stretch= FloatProperty(name="stretch", min= -4, max = 4, default = 1.0 )
+ lift= FloatProperty(name="lift", min = 0.001, max = 10, default = 0 )
+ smeshname= StringProperty(name="smeshname", default = "defaultstrut")
+
+#Hubs
+ hubtype = BoolProperty(name ="hubtype", description = "not used", default = True )
+ hubtoggle = BoolProperty(name ="hubtoggle", default = False )
+ hubimporttoggle = BoolProperty(name="new import", description = "import a mesh",\
+ default = False )
+ hubimpmesh = StringProperty(name="hubimpmesh",\
+ description = "name of mesh to import", default = "None")
+ hubwidth = FloatProperty(name="hubwidth", min = 0.01, max = 10,\
+ default = 1 )
+ hwtog = BoolProperty(name="hwtog", default = False )
+ hubheight = FloatProperty(name="hubheight", min = 0.01, max = 10,\
+ default = 1 )
+ hhtog = BoolProperty(name="hhtog", default = False )
+ hublength = FloatProperty(name ="hublength", min = 0.1, max = 10,\
+ default = 1 )
+ hstog= BoolProperty(name="hstog", default = False )
+ hmeshname= StringProperty(name="hmeshname",\
+ description = "Name of an existing mesh needed!", default = "None")
+
+ name_list = ['facetype_menu','facetoggle','face_use_imported_object',
+'facewidth','fwtog','faceheight','fhtog',
+'face_detach','fmeshname','geodesic_types','import_mesh_name',
+'base_type','orientation','geodesic_class','tri_hex_star',
+'spherical_flat','use_imported_mesh','cyxres','cyyres',
+'cyxsz','cyysz','cyxell','cygap',
+'cygphase','paxres','payres','paxsz',
+'paysz','paxell','pagap','pagphase',
+'ures','vres','urad','vrad',
+'uellipse','vellipse','upart','vpart',
+'ugap','vgap','uphase','vphase',
+'uexp','vexp','usuper','vsuper',
+'utwist','vtwist','bures','bvres',
+'burad','bupart','bvpart','buphase',
+'bvphase','buellipse','bvellipse','grxres',
+'gryres','grxsz','grysz',
+'cart','frequency','eccentricity','squish',
+'radius','squareness','squarez','baselevel',
+'dual','rotxy','rotz',
+'uact','vact','um','un1',
+'un2','un3','ua','ub',
+'vm','vn1','vn2','vn3',
+'va','vb','uturn','vturn',
+'utwist','vtwist','struttype','struttoggle',
+'strutimporttoggle','strutimpmesh','strutwidth','swtog',
+'strutheight','shtog','strutshrink','sstog',
+'stretch','lift','smeshname','hubtype',
+'hubtoggle','hubimporttoggle','hubimpmesh','hubwidth',
+'hwtog','hubheight','hhtog','hublength',
+'hstog','hmeshname']
+
+ def write_params(self,filename):
+ file = open(filename, "w", encoding="utf8", newline="\n")
+ fw = file.write
+ #for Faces!
+ for el in self.name_list:
+ fw(el + ", ")
+ fw(repr(getattr(self,el)))
+ fw(",\n")
+ file.close()
+
+ def read_file(self,filename):
+ file = open(filename, "r", newline="\n")
+ result = []
+ line = file.readline()
+ while(line):
+ tmp = line.split(", ")
+ result.append(eval(tmp[1]))
+ line = file.readline()
+ return result
+
+
+ def draw(self,context):
+ sce = context.scene
+ layout = self.layout
+ row = layout.row()
+# row.prop(self, "save_parameters")
+# row.prop(self, "load_parameters")
+ col = layout.column()
+ col.label(" ")
+ col.prop(self, "mainpages")
+ which_mainpages = self.mainpages
+ if which_mainpages == 'Main':
+ col = layout.column()
+ col.prop(self, "geodesic_types")
+ tmp = self.geodesic_types
+ if tmp == "Geodesic":
+ col.label(text="Geodesic Object Types:")
+ col.prop(self, "geodesic_class")
+ col.prop(self, "base_type")
+ col.prop(self, "orientation")
+ col.prop(self, "tri_hex_star")
+ col.prop(self, "spherical_flat")
+ col.label("Geodesic Object Parameters:")
+ row = layout.row()
+ row.prop(self, "frequency")
+ row = layout.row()
+ row.prop(self, "radius")
+ row = layout.row()
+ row.prop(self, "eccentricity")
+ row = layout.row()
+ row.prop(self, "squish")
+ row = layout.row()
+ row.prop(self, "squareness")
+ row = layout.row()
+ row.prop(self, "squarez")
+ row = layout.row()
+ row.prop(self, "rotxy")
+ row = layout.row()
+ row.prop(self, "rotz")
+ row = layout.row()
+ row.prop(self, "dual")
+ elif tmp == 'Torus':
+ col.label("Torus Parameters")
+ row = layout.row()
+ row.prop(self, "ures")
+ row = layout.row()
+ row.prop(self, "vres")
+ row = layout.row()
+ row.prop(self, "urad")
+ row = layout.row()
+ row.prop(self, "vrad")
+ row = layout.row()
+ row.prop(self, "uellipse")
+ row = layout.row()
+ row.prop(self, "vellipse")
+ row = layout.row()
+ row.prop(self, "upart")
+ row = layout.row()
+ row.prop(self, "vpart")
+ row = layout.row()
+ row.prop(self, "ugap")
+ row.prop(self, "vgap")
+ row = layout.row()
+
+ elif tmp == 'Sphere':
+ col.label("Sphere Parameters")
+ row = layout.row()
+ row.prop(self, "bures")
+ row = layout.row()
+ row.prop(self, "bvres")
+ row = layout.row()
+ row.prop(self, "burad")
+ row = layout.row()
+ row.prop(self, "bupart")
+ row = layout.row()
+ row.prop(self, "buphase")
+ row = layout.row()
+ row.prop(self, "bvpart")
+ row = layout.row()
+ row.prop(self, "bvphase")
+ row = layout.row()
+ row.prop(self, "buellipse")
+ row = layout.row()
+ row.prop(self, "bvellipse")
+ elif tmp == 'Parabola':
+ col.label("Parabola Parameters")
+ row = layout.row()
+ row.prop(self, "paxres")
+ row = layout.row()
+ row.prop(self, "payres")
+ row = layout.row()
+ row.prop(self, "paxsz")
+ row = layout.row()
+ row.prop(self, "paysz")
+ row = layout.row()
+ row.prop(self, "paxell")
+ row = layout.row()
+ row.prop(self, "pagap")
+ row = layout.row()
+ row.prop(self, "pagphase")
+ elif tmp == 'Cylinder':
+ col.label("Cylinder Parameters")
+ col.prop(self, "cyxres")
+ col.prop(self, "cyyres")
+ col.prop(self, "cyxsz")
+ col.prop(self, "cyysz")
+ col.prop(self, "cyxell")
+ col.prop(self, "cygap")
+ col.prop(self, "cygphase")
+ elif tmp == 'Grid':
+ col.label("Grid Parameters")
+ row = layout.row()
+ row.prop(self, "grxres")
+ row = layout.row()
+ row.prop(self, "gryres")
+ row = layout.row()
+ row.prop(self, "grxsz")
+ row = layout.row()
+ row.prop(self, "grysz")
+ elif tmp == 'Import your mesh':
+ col.prop(self, "use_imported_mesh")
+ col.prop(self, "import_mesh_name")
+#######superform parameters only where possible
+ row = layout.row()
+ row.prop(self, "uact")
+ row = layout.row()
+ row.prop(self, "vact")
+ row = layout.row()
+ if not(tmp == 'Import your mesh'):
+ if (self.uact == False) and (self.vact == False):
+ row.label("no checkbox active!")
+ else:
+ row.label("Superform Parameters")
+ if self.uact:
+ row = layout.row()
+ row.prop(self, "um")
+ row = layout.row()
+ row.prop(self, "un1")
+ row = layout.row()
+ row.prop(self, "un2")
+ row = layout.row()
+ row.prop(self, "un3")
+ row = layout.row()
+ row.prop(self, "ua")
+ row = layout.row()
+ row.prop(self, "ub")
+ row = layout.row()
+ row.prop(self, "uturn")
+ row = layout.row()
+ row.prop(self, "utwist")
+ if self.vact:
+ row = layout.row()
+ row.prop(self, "vm")
+ row = layout.row()
+ row.prop(self, "vn1")
+ row = layout.row()
+ row.prop(self, "vn2")
+ row = layout.row()
+ row.prop(self, "vn3")
+ row = layout.row()
+ row.prop(self, "va")
+ row = layout.row()
+ row.prop(self, "vb")
+ row = layout.row()
+ row.prop(self, "vturn")
+ row = layout.row()
+ row.prop(self, "vtwist")
+########einde superform
+ elif which_mainpages == "Hubs":
+ row = layout.row()
+ row.prop(self, "hubtoggle")
+
+ row = layout.row()
+
+ row = layout.row()
+ if self.hubimpmesh == "None":
+ row = layout.row()
+ row.label("name of a hub to use")
+ row = layout.row()
+ row.prop(self, "hubimpmesh")
+ row = layout.row()
+ if self.hmeshname == "None":
+ row = layout.row()
+ row.label("name of mesh to be filled in!")
+ row = layout.row()
+ row.prop(self, "hmeshname")
+ row = layout.row()
+ row.prop(self, "hwtog")
+ if self.hwtog:
+ row.prop(self, "hubwidth")
+ row = layout.row()
+ row.prop(self, "hhtog")
+ if self.hhtog:
+ row.prop(self, "hubheight")
+ row = layout.row()
+ row.prop(self, "hublength")
+ elif which_mainpages == "Struts":
+ row = layout.row()
+ row.prop(self, "struttype")
+ row.prop(self, "struttoggle")
+
+ row = layout.row()
+ row.prop(self, "strutimpmesh")
+ row = layout.row()
+ row.prop(self, "swtog")
+ if self.swtog:
+ row.prop(self, "strutwidth")
+ row = layout.row()
+ row.prop(self, "shtog")
+ if self.shtog:
+ row.prop(self, "strutheight")
+ row = layout.row()
+ row.prop(self, "sstog")
+ if self.sstog:
+ row.prop(self, "strutshrink")
+ row = layout.row()
+ row.prop(self, "stretch")
+ row = layout.row()
+ row.prop(self, "lift")
+ row = layout.row()
+ row.prop(self, "smeshname")
+ elif which_mainpages == "Faces":
+ row = layout.row()
+ row.prop(self, "facetoggle")
+ row = layout.row()
+ row.prop(self, "face_use_imported_object")
+ row = layout.row()
+ row.prop(self, "facetype_menu")
+ row = layout.row()
+ row.prop(self, "fwtog")
+ if self.fwtog:
+ row.prop(self, "facewidth")
+ row = layout.row()
+ row.prop(self, "fhtog")
+ if self.fhtog:
+ row.prop(self, "faceheight")
+ row = layout.row()
+ row.prop(self, "face_detach")
+ row = layout.row()
+ row.prop(self, "fmeshname")
+ row = layout.row()
+
+ #help menu GUI
+ elif which_mainpages == "Help":
+ import textwrap
+
+ # a function that allows for multiple labels with text that wraps
+ # you can allow the user to set where the text wraps with the
+ # text_width parameter
+ # other parameters are ui : here you usually pass layout
+ # text: is a list with each index representing a line of text
+
+ def multi_label(text, ui,text_width=120):
+ for x in range(0,len(text)):
+ el = textwrap.wrap(text[x], width = text_width )
+
+ for y in range(0,len(el)):
+ ui.label(text=el[y])
+
+ box = layout.box()
+ help_text = ["NEW!",
+ "New facility: save or load (nearly all) parameters",
+ "A file GD_0.GD will be used, living in:",
+ "geodesic_domes/tmp",
+ "--------",
+ "After loading you have to change a ",
+ "parameter back and forth"
+ "to see it"]
+ text_width = self.gd_help_text_width
+ box.prop(self, "gd_help_text_width",slider=True)
+ multi_label(help_text,box, text_width)
+
+ def execute(self, context):
+ global last_generated_object, last_imported_mesh, basegeodesic, imported_hubmesh_to_use
+ #default superformparam = [3, 10, 10, 10, 1, 1, 4, 10, 10, 10, 1, 1, 0, 0, 0.0, 0.0, 0, 0]]
+ superformparam = [self.um, self.un1, self.un2, self.un3, self.ua,\
+ self.ub, self.vm, self.vn1, self.vn2, self.vn3,\
+ self.va, self.vb, self.uact, self.vact,\
+ self.uturn*pi, self.vturn*pi, \
+ self.utwist, self.vtwist]
+ context.scene.error_message = ""
+ if self.mainpages == 'Main':
+ if self.geodesic_types == "Geodesic":
+ tmp_fs = self.tri_hex_star
+ faceshape = 0 # tri!
+ if tmp_fs == "hex":
+ faceshape = 1
+ elif tmp_fs == "star":
+ faceshape = 2
+ tmp_cl = self.geodesic_class
+ klass = 0
+ if tmp_cl == "Class 2":
+ klass = 1
+ shape = 0
+ parameters = [self.frequency, self.eccentricity, self.squish,\
+ self.radius, self.squareness, self.squarez, 0,\
+ shape, self.baselevel, faceshape, self.dual,\
+ self.rotxy, self.rotz, klass, superformparam]
+ basegeodesic = creategeo(self.base_type,self.orientation,parameters)
+ basegeodesic.makegeodesic()
+ basegeodesic.connectivity()
+ mesh = vefm_271.mesh()
+ vefm_271.finalfill(basegeodesic,mesh) #always! for hexifiy etc. necessarry!!!
+ vefm_271.vefm_add_object(mesh)
+ last_generated_object = context.active_object
+ last_generated_object.location = (0,0,0)
+ context.scene.objects.active = last_generated_object
+ elif self.geodesic_types == 'Grid':
+ basegeodesic = forms_271.grid(self.grxres,self.gryres,\
+ self.grxsz,self.grysz,1.0,1.0,0,0,0,\
+ 0,1.0,1.0,superformparam)
+ vefm_271.vefm_add_object(basegeodesic)
+ bpy.data.objects[-1].location = (0,0,0)
+ elif self.geodesic_types == "Cylinder":
+ basegeodesic = forms_271.cylinder(self.cyxres, self.cyyres, \
+ self.cyxsz, self.cyysz, self.cygap, \
+ 1.0, self.cygphase, 0, 0, 0, self.cyxell,\
+ 1.0, superformparam)
+ vefm_271.vefm_add_object(basegeodesic)
+ bpy.data.objects[-1].location = (0,0,0)
+
+ elif self.geodesic_types == "Parabola":
+ basegeodesic=forms_271.parabola(self.paxres, self.payres,\
+ self.paxsz, self.paysz, self.pagap,1.0, self.pagphase,\
+ 0,0,0, self.paxell,1.0,superformparam)
+ vefm_271.vefm_add_object(basegeodesic)
+ bpy.data.objects[-1].location = (0,0,0)
+ elif self.geodesic_types == "Torus":
+ basegeodesic = forms_271.torus(self.ures, self.vres,\
+ self.vrad, self.urad, self.upart, self.vpart,\
+ self.ugap, self.vgap,0,0, self.uellipse,\
+ self.vellipse, superformparam)
+ vefm_271.vefm_add_object(basegeodesic)
+ bpy.data.objects[-1].location = (0,0,0)
+ elif self.geodesic_types == "Sphere":
+ basegeodesic=forms_271.sphere(self.bures, self.bvres,\
+ self.burad,1.0, self.bupart, self.bvpart,\
+ self.buphase, self.bvphase,0,0, self.buellipse,\
+ self.bvellipse,superformparam)
+
+ vefm_271.vefm_add_object(basegeodesic)
+ bpy.data.objects[-1].location = (0,0,0)
+
+ elif self.geodesic_types == "Import your mesh":
+ obj_name = self.import_mesh_name
+ if obj_name == "None":
+ message = "fill in a name \nof an existing mesh\nto be imported"
+ context.scene.error_message = message
+ self.report({"INFO"}, message)
+ print("***INFO*** you have to fill in the name of an existing mesh")
+ else:
+# obj_in_scene = context.objects
+ names = [el.name for el in context.scene.objects]
+ if obj_name in names and context.scene.objects[obj_name].type == "MESH":
+ obj = context.scene.objects[obj_name]
+# if obj.type == "MESH":
+ your_obj = vefm_271.importmesh(obj.name,False)
+ last_imported_mesh = your_obj
+ vefm_271.vefm_add_object(your_obj)
+ last_generated_object = bpy.context.active_object
+ last_generated_object.name ="Imported mesh"
+ bpy.context.active_object.location = (0,0,0)
+ else:
+ message = obj_name +" does not exist \nor is not a MESH"
+ context.scene.error_message = message
+ bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
+ self.report({'ERROR'}, message)
+ print("***ERROR***" + obj_name +" does not exist or is not a MESH")
+ elif self.mainpages == "Hubs":
+ hubtype = self.hubtype
+ hubtoggle = self.hubtoggle
+ hubimporttoggle = self.hubimporttoggle
+ hubimpmesh = self.hubimpmesh
+ hubwidth = self.hubwidth
+ hwtog = self.hwtog
+ hubheight = self.hubheight
+ hhtog = self.hhtog
+ hublength = self.hublength
+ hstog = self.hstog
+ hmeshname= self.hmeshname
+
+ if not (hmeshname == "None") and not (hubimpmesh == "None") and hubtoggle:
+ try:
+
+ hub_obj = vefm_271.importmesh(hmeshname,0)
+
+ hub = vefm_271.hub(hub_obj, True,\
+ hubwidth, hubheight, hublength,\
+ hwtog, hhtog, hstog, hubimpmesh)
+
+ mesh = vefm_271.mesh("test")
+ vefm_271.finalfill(hub,mesh)
+ vefm_271.vefm_add_object(mesh)
+ bpy.data.objects[-1].location = (0,0,0)
+ except:
+ message = "***ERROR third_domes_panel L811 *** \neither no mesh for hub\nor " + hmeshname + " available"
+ context.scene.error_message = message
+ bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
+ print(message)
+ else:
+ message = "***INFO***\nuse the hub toggle!"
+ context.scene.error_message = message
+ print("\n***INFO*** use the hub toggle!")
+ elif self.mainpages == "Struts":
+ struttype = self.struttype
+ struttoggle = self.struttoggle
+ strutimporttoggle = self.strutimporttoggle
+ strutimpmesh = self.strutimpmesh
+ strutwidth = self.strutwidth
+ swtog = self.swtog
+ strutheight = self.strutheight
+ shtog = self.shtog
+ strutshrink = self.strutshrink
+ sstog = self.sstog
+ stretch = self.stretch
+ lift = self.lift
+ smeshname = self.smeshname
+ if not (strutimpmesh == "None") and struttoggle:
+ names = [el.name for el in context.scene.objects]
+ if strutimpmesh in names and context.scene.objects[strutimpmesh].type == "MESH":
+ strut = vefm_271.strut(basegeodesic, struttype, strutwidth,\
+ strutheight, stretch, swtog, shtog, swtog,\
+ strutimpmesh, sstog, lift)
+ strutmesh = vefm_271.mesh()
+ vefm_271.finalfill(strut,strutmesh)
+ vefm_271.vefm_add_object(strutmesh)
+ last_generated_object = context.active_object
+ last_generated_object.name = smeshname
+ last_generated_object.location = (0,0,0)
+ else:
+ message = "***ERROR***\n" + strutimpmesh + "\nis not a MESH"
+ context.scene.error_message = message
+ bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
+ print("***ERROR*** strut obj is not a MESH")
+ else:
+ vefm_271.vefm_add_object(basegeodesic)
+ elif self.mainpages == "Faces":
+ if self.facetoggle:
+ faceparams=[[self.face_detach,0,[[0.5,0.0]]], #0 strip
+ [self.face_detach,0,[[0.0,0.5]]], #1 vertical
+ [self.face_detach,0,[[0.5,0.5]]], #2 slanted
+ [self.face_detach,1,[[0.25,0.25],[0.5,0.5]]], #3 closed point
+ [self.face_detach,1,[[0.1,0.03],[0.33,0.06],[0.0,0.1]]], #4 pillow
+ [self.face_detach,2,[[0.0,0.5]]], #5 closed vertical
+ [self.face_detach,2,[[0.0,0.25],[0.25,0.25],[0.25,0.5]]], #6 stepped
+ [self.face_detach,1,[[0.2,0.1],[0.4,0.2],[0.0,1.0]]], #7 spikes
+ [self.face_detach,3,[[0.25,0.0],[0.25,0.5],[0.0,0.5]]], #8 boxed
+ [self.face_detach,3,[[0.25,0.5],[0.5,0.0],[0.25,-0.5]]], #9 diamond
+ [self.face_detach,4,[[0.5,0.0],[0.5,0.5],[0.0,0.5]]],] #10 bar
+ facedata = faceparams[int(self.facetype_menu)]
+ if not self.face_use_imported_object:
+ faceobject = vefm_271.facetype(basegeodesic, facedata, self.facewidth,\
+ self.faceheight,self.fwtog)
+ else:
+ if last_imported_mesh:
+ faceobject = vefm_271.facetype(last_imported_mesh, facedata,\
+ self.facewidth, self.faceheight, self.fwtog)
+ else:
+ message = "***ERROR***\nno imported message available\n" + "last geodesic used"
+ context.scene.error_message = message
+ bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
+ print("\n***ERROR*** no imported mesh available")
+ print("last geodesic used!")
+ faceobject = vefm_271.facetype(basegeodesic,facedata,\
+ self.facewidth,self.faceheight,self.fwtog)
+ facemesh = vefm_271.mesh()
+ finalfill(faceobject, facemesh)
+ vefm_271.vefm_add_object(facemesh)
+ obj = bpy.data.objects[-1]
+ obj.name = self.fmeshname
+ obj.location = (0,0,0)
+#PKHG save or load (nearly) all parameters
+ if self.save_parameters:
+ self.save_parameters = False
+ try:
+ scriptpath = bpy.utils.script_paths()[0]
+ sep = os.path.sep
+ tmpdir = os.path.join(scriptpath, "addons", "add_mesh_extra_objects" , "tmp")
+#scriptpath + sep + "addons" + sep + "geodesic_domes" + sep + "tmp"
+ if not os.path.isdir(tmpdir):
+ message = "***ERROR***\n" + tmpdir + "\nnot (yet) available"
+
+ filename = tmpdir + sep + "GD_0.GD"
+# self.read_file(filename)
+ try:
+ self.write_params(filename)
+ message = "***OK***\nparameters saved in\n" + filename
+ print(message)
+ except:
+ message = "***ERRROR***\n" + "writing " + filename + "\nnot possible"
+ #bpy.context.scene.instant_filenames = filenames
+
+ except:
+ message = "***ERROR***\n Contakt PKHG, something wrong happened"
+
+ context.scene.error_message = message
+ bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
+
+ if self.load_parameters:
+ self.load_parameters = False
+ try:
+ scriptpath = bpy.utils.script_paths()[0]
+ sep = os.path.sep
+ tmpdir = os.path.join(scriptpath, "addons", "add_mesh_extra_objects", "tmp")
+ #PKHG>NEXT comment????
+ #scriptpath + sep + "addons" + sep + "geodesic_domes" + sep + "tmp"
+ if not os.path.isdir(tmpdir):
+ message = "***ERROR***\n" + tmpdir + "\nnot available"
+ print(message)
+ filename = tmpdir + sep + "GD_0.GD"
+# self.read_file(filename)
+ try:
+ res = self.read_file(filename)
+ for i,el in enumerate(self.name_list):
+ setattr(self,el,res[i])
+ message = "***OK***\nparameters read from\n" + filename
+ print(message)
+ except:
+ message = "***ERRROR***\n" + "writing " + filename + "\nnot possible"
+ #bpy.context.scene.instant_filenames = filenames
+ except:
+ message = "***ERROR***\n Contakt PKHG,\nsomething went wrong reading params happened"
+ context.scene.error_message = message
+ bpy.ops.object.dialog_operator('INVOKE_DEFAULT')
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ global basegeodesic
+ bpy.ops.view3d.snap_cursor_to_center()
+ tmp = context.scene.geodesic_not_yet_called
+ if tmp:
+ context.scene.geodesic_not_yet_called = False
+ self.execute(context)
+ return {'FINISHED'}
+
+def creategeo(polytype,orientation,parameters):
+ geo = None
+ if polytype == "Tetrahedron":
+ if orientation == "PointUp":
+ geo = geodesic_classes_271.tetrahedron(parameters)
+ elif orientation == "EdgeUp":
+ geo=geodesic_classes_271.tetraedge(parameters)
+ elif orientation == "FaceUp":
+ geo=geodesic_classes_271.tetraface(parameters)
+ elif polytype == "Octahedron":
+ if orientation == "PointUp":
+ geo=geodesic_classes_271.octahedron(parameters)
+ elif orientation == "EdgeUp":
+ geo=geodesic_classes_271.octaedge(parameters)
+ elif orientation == "FaceUp":
+ geo=geodesic_classes_271.octaface(parameters)
+ elif polytype == "Icosahedron":
+ if orientation == "PointUp":
+ geo=geodesic_classes_271.icosahedron(parameters)
+ elif orientation == "EdgeUp":
+ geo=geodesic_classes_271.icoedge(parameters)
+ elif orientation == "FaceUp":
+ geo=geodesic_classes_271.icoface(parameters)
+ return geo
+
+basegeodesic,fmeshname,smeshname,hmeshname,outputmeshname,strutimpmesh,hubimpmesh = [None]*7
+
+def finalfill(source,target):
+ count=0
+ for point in source.verts:
+ newvert = vefm_271.vertex(point.vector)
+ target.verts.append(newvert)
+ point.index = count
+ count += 1
+ for facey in source.faces:
+ row=len(facey.vertices)
+ if row >= 5:
+ newvert = vefm_271.average(facey.vertices).centroid()
+ centre = vefm_271.vertex(newvert.vector)
+ target.verts.append(centre)
+ for i in range(row):
+ if i == row - 1:
+ a = target.verts[facey.vertices[-1].index]
+ b = target.verts[facey.vertices[0].index]
+ else:
+ a = target.verts[facey.vertices[i].index]
+ b = target.verts[facey.vertices[i+1].index]
+ c = centre
+ f = [a,b,c]
+ target.faces.append(f)
+ else:
+ f = []
+ for j in range(len(facey.vertices)):
+
+ a = facey.vertices[j]
+ f.append(target.verts[a.index])
+ target.faces.append(f)
+
+###for error messages
+class DialogOperator(bpy.types.Operator):
+ bl_idname = "object.dialog_operator"
+ bl_label = "INFO"
+
+ def draw(self,context):
+ layout = self.layout
+ message = context.scene.error_message
+ col = layout.column()
+ tmp = message.split("\n")
+ for el in tmp:
+ col.label(el)
+
+ def execute(self, context):
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ wm = context.window_manager
+ return wm.invoke_props_dialog(self)
+
+
+######### register all
+def register():
+ bpy.utils.register_module(__name__)
+
+def unregister():
+ bpy.utils.unregister_module(__name__)
+
+if __name__ == "__main__":
+ register()
+
diff --git a/add_mesh_extra_objects/geodesic_domes/vefm_271.py b/add_mesh_extra_objects/geodesic_domes/vefm_271.py
new file mode 100644
index 00000000..f9965ec7
--- /dev/null
+++ b/add_mesh_extra_objects/geodesic_domes/vefm_271.py
@@ -0,0 +1,1169 @@
+# vert class and overloading experiments
+import bpy
+#PKHG>NEEDED?
+import bmesh
+import math
+from math import sqrt,acos,pi,sin,cos,atan,tan,fabs
+from mathutils import Vector
+
+#PKHG>DBG change the DBG_info and use extra_DBG_info
+DBG_info ={"MeshInfo":False, "StrutMesh":False, "HubMesh":False}
+
+
+def extra_DBG_info(name = "value from DBG_info", info_text="default\n", info_obj=None):
+ global DBG_info
+ DBG_keys = DBG_info.keys()
+ if name in DBG_keys:
+ if DBG_info[name]:
+ print(info_text, info_obj)
+
+sgn = lambda x : (x>0) - (x<0) #missing signum function in Python
+
+from bpy_extras.object_utils import AddObjectHelper, object_data_add
+from collections import Counter
+
+
+def vefm_add_object(selfobj):
+ for i in range(len(selfobj.verts)):
+ selfobj.verts[i].index = i
+ v = [el.vector for el in selfobj.verts]
+
+ e = [[edge.a.index, edge.b.index] for edge in selfobj.edges]
+
+ if type(selfobj.faces[0]) == type([]):
+
+#PKHG should be a list of vertices, which have an index
+ f = [[v.index for v in face] for face in selfobj.faces]
+ else:
+ f = [[v.index for v in face.vertices] for face in selfobj.faces]
+
+ m = bpy.data.meshes.new(name= selfobj.name)
+ m.from_pydata(v, e, f )
+ # useful for development when the mesh may be invalid.
+ m.validate(verbose = False)
+ object_data_add(bpy.context, m, operator = None)
+
+#extra test phase
+
+class vertex:
+ def __init__(self, vec=(0,0,0)): #default x = 0, y = 0, z = 0):
+ self.vector = Vector(vec)
+ self.length = self.vector.length
+ self.index = 0
+ self.normal = 0
+ self.edges = []
+ self.faces = []
+ self.boundary = 0
+
+ def findlength(self):
+ self.length = self.vector.length
+
+ def normalize(self):
+ self.findlength()
+ if self.length > 0:
+ tmp = 1.0/self.length
+ self.vector = tmp * self.vector
+ self.length = 1.0
+
+ def findnormal(self):
+ target = []
+ if self.faces[:] == []:
+ print("vefm vertex L81 pkhg:*****ERROR**** findnormal has no faces")
+ return
+ for currentface in self.faces:
+ target.append(currentface.normal)
+ self.normal = average(target).centroid()
+ self.normal.findlength()
+ if self.length == 0:
+ print("******ERROR*** lenght zero in findnormal, j = (0,1,0) replcaced")
+ self.normal = vertex((0,1,0))
+ self.normal.normalize()
+
+ def clockwise(self): #PKHG self is a vertex
+ if self.boundary:
+ start = self.boundarystart()
+ else:
+ start = self.faces[0]
+
+ self.tempedges = []
+ self.tempfaces = []
+ for i in range(len(self.edges)):
+
+ self.tempfaces.append(start)
+ for corner in start.corners:
+ if corner[0] is not self:
+ pass
+ elif corner[0] is self:
+ self.tempedges.append(corner[1])
+ nextedge = corner[2]
+ for facey in nextedge.faces:
+ if facey is not start:
+ start = facey
+ break
+ self.edges = self.tempedges
+ self.faces = self.tempfaces
+
+ def boundarystart(self):
+
+ pass
+
+ def __add__(self, other):
+ if isinstance(other, Vector):
+ tmp = self.vector + other
+ else:
+ tmp = self.vector + other.vector
+ return vertex(tmp)
+
+ def __sub__(self, other):
+ if isinstance(other, Vector):
+ tmp = self.vector - other
+ else:
+ tmp = self.vector - other.vector
+ return vertex(tmp)
+
+ def __mul__(self, other):
+ tmp = self.vector * other
+ return vertex(tmp)
+
+ def __truediv__(self, other):
+ denom = 1.0/other
+ tmp = self.vector * denom
+ return (tmp)
+
+ def negative(self):
+ return vertex(-self.vector)
+
+class crossp:
+ ## Takes in two vertices(vectors), returns the cross product.
+ def __init__(self, v1, v2):
+ self.v1 = v1
+ self.v2 = v2
+#
+ def docrossproduct(self):
+ tmp = self.v1.vector.cross(self.v2.vector)
+ return vertex(tmp)
+
+class average:
+ ## Takes a list of vertices and returns the average. If two verts are passed, returns midpoint.
+ def __init__(self, vertlist):
+ self.vertlist = vertlist
+
+ def centroid(self):
+ tmp = Vector()
+#PKHG avoid emptylist problems
+ divisor = 1.0
+ nr_vertices = len(self.vertlist)
+ if nr_vertices > 1:
+ divisor = 1.0 / len(self.vertlist)
+ elif nr_vertices == 0:
+ print("\n***WARNING*** empty list in vefm_271.centroid! L180")
+ for vert in self.vertlist:
+ tmp = tmp + vert.vector
+ tmp = tmp * divisor
+ return vertex(tmp)
+
+class edge:
+ def __init__(self, a = 0, b = 0):
+ self.a = a
+ self.b = b
+ self.index = 0
+ self.normal = 0
+ self.cross = 0
+ self.unit = 0
+ self.faces = []
+ self.vect = 0 #PKHG becomes b - a
+ self.vectb = 0 #PKHG becomes a - b
+ self.boundary = 0
+ self.findvect()
+ self.findlength()
+
+
+ def findvect(self):
+ self.vect = self.b - self.a
+ self.vectb = self.a - self.b
+
+ def findlength(self):
+ self.vect.findlength()
+ self.vectb.length = self.vect.length
+
+ def findnormal(self):
+
+ if self.boundary:
+ self.normal = self.faces[0].normal #average([self.a, self.b]).centroid()
+ else:
+ self.normal = average([self.faces[0].normal, self.faces[1].normal]).centroid()
+ self.normal.normalize()
+
+
+class face:
+ def __init__(self, vertices=[]):
+#PKHG ok good for tri's at least
+ self.vertices = vertices ## List of vertex instances.
+ self.edges=[] ## Will be filled with the sides of the face.
+ self.boundary = 0 ## When set will have bool and id of edge concerned.
+ self.normal = 0 ## Face normal found through cross product.
+ self.corners=[]
+ self.spokes=[] ## Vectors of the bisecting angles from each corner
+ ## to the centre + dotproduct.
+ self.index = 0
+
+ #dotproduct is misleading name, it is the hook between two vectors!
+ def dotproduct(self, v1, v2):
+ v1.findlength()
+ v2.findlength()
+ if v1.length == 0 or v2.length == 0:
+ print("\nPKHG warning, =====vefm_271 dotproduct L245====== at least one zero vector 0 used")
+ return 0
+ dot = v1.vector.dot(v2.vector)
+ costheta = dot / (v1.length * v2.length)
+ tmp = acos(costheta)
+ return tmp
+
+ def orderedges(self):
+ temp=[]
+ finish = len(self.vertices)
+ for i in range(finish):
+ current = self.vertices[i]
+ if i==finish-1:
+ next = self.vertices[0]
+ else:
+ next = self.vertices[i+1]
+ for edge in face.edges:
+ if edge.a==current and edge.b==next:
+ face.clockw.append(edge.vect)
+ face.aclockw.append(edge.vectb)
+ temp.append(edge)
+ if edge.b==current and edge.a==next:
+ face.clockw.append(edge.vectb)
+ face.aclockw.append(edge.vect)
+ temp.append(edge)
+ for edge in face.edges:
+ if edge.a==current and edge.b==next:
+ face.clockw.append(edge.vect)
+ face.aclockw.append(edge.vectb)
+ temp.append(edge)
+ if edge.b==current and edge.a==next:
+ face.clockw.append(edge.vectb)
+ face.aclockw.append(edge.vect)
+ temp.append(edge)
+ face.vertices = temp
+
+
+ def docorners(self):
+ ## This function identifies and stores the vectors coming from each vertex
+ ## allowing easier calculation of cross and dot products.
+ finish = len(self.vertices)
+
+ for i in range(finish):
+ current = self.vertices[i]
+ if i==finish-1:
+ next = self.vertices[0]
+ else:
+ next = self.vertices[i+1]
+ if i==0:
+ previous = self.vertices[-1]
+ else:
+ previous = self.vertices[i-1]
+ corner=[current] #PKHG new for each vertex = current
+ #corner = current
+ rightedge = None
+ leftedge = None
+ teller = -1
+ for edge in self.edges:
+
+ if finish == 3 and len(self.edges) == 2 and i == 2:
+ return
+ teller += 1
+ currentinfo = (current, edge.a, edge.b, edge.a is current, edge.b is current)
+ #next and previous are vertex with respect to ith vertex
+ if edge.a is current or edge.b is current: ## does this edge contain our current vert
+ if edge.a is current:
+ if edge.b is next:
+ rightedge = edge
+ rightvect = edge.vect
+ if edge.b is previous:
+ leftedge = edge
+ leftvect = edge.vect
+ elif edge.b is current:
+ if edge.a is next:
+ rightedge = edge
+ rightvect = edge.vectb
+ if edge.a is previous:
+ leftedge = edge
+ leftvect = edge.vectb
+ corner.append(rightedge)
+ corner.append(leftedge)
+ if rightedge and leftedge:
+
+ dotty = self.dotproduct(rightvect, leftvect)
+ corner.append(dotty)
+ self.corners.append(corner)
+
+
+ def findnormal(self):
+ one = self.corners[1][2]
+ two = self.corners[1][1]
+ if one.a is self.corners[1][0]:
+ one = one.vect
+ elif one.b is self.corners[1][0]:
+ one = one.vectb
+ if two.a is self.corners[1][0]:
+ two = two.vect
+ elif two.b is self.corners[1][0]:
+ two = two.vectb
+ self.normal = crossp(one, two).docrossproduct()
+ self.normal.findlength()
+ self.normal.normalize()
+
+ def dospokes(self):
+
+ for corner in self.corners:
+ vert = corner[0]
+ right = corner[1]
+ left = corner[2]
+ if right.a is vert:
+ one = vertex(right.vect.vector)
+ elif right.b is vert:
+ one = vertex(right.vectb.vector)
+ if left.a is vert:
+ two = vertex(left.vect.vector)
+ elif left.b is vert:
+ two = vertex(left.vectb.vector)
+
+ one.normalize()
+ two.normalize()
+ spoke = one+two
+ spoke.normalize()
+ self.spokes.append(spoke)
+
+ def artspokes(self):
+ centre = average(self.vertices).centroid()
+ for point in self.vertices:
+ newedge = edge(point, centre)
+ spokes.append(newedge)
+
+class mesh:
+ def __init__(self , name="GD_mesh"):
+ self.name = name
+ self.verts=[]
+ self.edges=[]
+ self.faces=[]
+ self.edgeflag = 0
+ self.faceflag = 0
+ self.vertexflag = 0
+ self.vertedgeflag = 0
+ self.vertfaceflag = 0
+ self.faceedgeflag = 0
+ self.boundaryflag = 0
+ self.vertnormalflag = 0
+ self.edgenormalflag = 0
+ self.facenormalflag = 0
+ self.a45 = pi * 0.25
+ self.a90 = pi * 0.5
+ self.a180 = pi
+ self.a270 = pi * 1.5
+ self.a360 = pi * 2
+
+
+ def power(self, a, b): ## Returns a power, including negative numbers
+ result = sgn(a)*(abs(a)**b)
+ return result
+
+ def sign(self, d): ## Works out the sign of a number.
+ return sgn(d)
+
+ def ellipsecomp(self, efactor, theta):
+ if theta==self.a90:
+ result = self.a90
+ elif theta==self.a180:
+ result = self.a180
+ elif theta==self.a270:
+ result = self.a270
+ elif theta==self.a360:
+ result = 0.0
+ else:
+ result = atan(tan(theta)/efactor**0.5)
+ if result<0.0:
+ if theta>self.a180:
+ result = result+self.a180
+ elif theta<self.a180:
+ result = result+self.a180
+
+ if result>0.0:
+ if theta>self.a180:
+ result = result+self.a180
+ elif theta<self.a180:
+ result = result
+ return result
+
+ def connectivity(self):
+ self.dovertedge()
+ self.dovertface()
+ self.dofaceedge()
+ self.boundary()
+
+ def superell(self, n1, uv, turn):
+ t1 = sin(uv+turn)
+ t1 = abs(t1)
+ t1 = t1**n1
+ t2 = cos(uv+turn)
+ t2 = abs(t2)
+ t2 = t2**n1
+ r = self.power(1.0/(t1+t2),(1.0/n1))
+ return r
+
+ def superform(self, m, n1, n2, n3, uv, a, b, twist):
+ t1 = cos(m*(uv+twist)*.25)*a
+ t1 = abs(t1)
+ t1 = t1**n2
+ t2 = sin(m*(uv+twist)*.25)*b
+ t2 = abs(t2)
+ t2 = t2**n3
+ r = self.power(1.0/(t1+t2), n1)
+ return r
+
+ def dovertedge(self):
+ if not self.vertedgeflag:
+ for vert in self.verts:
+ vert.edges = []
+ for currentedge in self.edges:
+ currentedge.a.edges.append(currentedge)
+ currentedge.b.edges.append(currentedge)
+ self.vertedgeflag = 1
+
+ def dovertface(self):
+ if not self.vertfaceflag:
+ for vert in self.verts:
+ vert.faces = []
+ for face in self.faces:
+ for vert in face.vertices:
+ vert.faces.append(face)
+ self.vertfaceflag = 1
+
+ def dofaceedge(self):
+ self.dovertedge() ## just in case they haven't been done
+ self.dovertface() ##
+ if not self.faceedgeflag:
+ for edge in self.edges:
+ edge.faces=[]
+ for face in self.faces:
+ face.edges = []
+ for face in self.faces:
+ finish = len(face.vertices)
+ for i in range(finish):
+ current = face.vertices[i]
+ if i == finish-1:
+ next = face.vertices[0]
+ else:
+ next = face.vertices[i+1]
+ for edge in current.edges:
+ if edge.a is current or edge.b is current:
+ if edge.b is next or edge.a is next:
+ edge.faces.append(face)
+ face.edges.append(edge)
+ self.faceedgeflag = 1
+
+ def boundary(self):
+ if not self.boundaryflag:
+ for edge in self.edges:
+ if len(edge.faces) < 2:
+ edge.boundary = 1
+ edge.faces[0].boundary = 1
+ edge.a.boundary = 1
+ edge.b.boundary = 1
+
+## The functions below turn the basic triangular faces into
+## hexagonal faces, creating the buckyball effect.
+#PKHG seems to work only for meshes with tri's ;-) ??!!
+ def hexify(self):
+ self.hexverts=[]
+ self.hexedges=[]
+ self.hexfaces=[]
+ #PKHG renumbering the index of the verts
+ for i in range(len(self.verts)):
+ self.verts[i].index = i
+ #PKHG renumbering the index of the edges
+ for i in range(len(self.edges)):
+ self.edges[i].index = i
+
+ self.connectivity()
+ hexvert_counter = 0
+ for edge in self.edges:
+
+ self.hexshorten(edge, hexvert_counter)
+ hexvert_counter += 2 #PKHG two new vertices done
+
+ for face in self.faces:
+ self.makehexfaces(face)
+
+ for vert in self.verts:
+ vert.clockwise()
+ self.hexvertface(vert)
+ self.verts = self.hexverts
+ self.edges = self.hexedges
+ self.faces = self.hexfaces
+ self.vertedgeflag = 0
+ self.vertfaceflag = 0
+ self.faceedgeflag = 0
+
+
+ def hexshorten(self, currentedge, hexvert_counter):
+ third = vertex(currentedge.vect/3.0)
+ newvert1 = vertex(currentedge.a.vector)
+ newvert2 = vertex(currentedge.b.vector)
+ newvert1 = newvert1 + third
+ newvert1.index = hexvert_counter
+ newvert2 = newvert2 - third
+ newvert2.index = hexvert_counter + 1 #PKHG caller adjusts +=2
+ newedge = edge(newvert1, newvert2)
+ newedge.index = currentedge.index
+ self.hexverts.append(newvert1)
+ self.hexverts.append(newvert2)
+ self.hexedges.append(newedge)
+
+ def makehexfaces(self, currentface):
+ vertices=[]
+ currentface.docorners()
+ for corner in currentface.corners:
+ vert = corner[0]
+ rightedge = corner[1]
+ leftedge = corner[2]
+ lid = leftedge.index
+ rid = rightedge.index
+
+ if leftedge.a is vert:
+ vertices.append(self.hexedges[lid].a)
+ elif leftedge.b is vert:
+ vertices.append(self.hexedges[lid].b)
+
+ if rightedge.a is vert:
+ vertices.append(self.hexedges[rid].a)
+ elif rightedge.b is vert:
+ vertices.append(self.hexedges[rid].b)
+
+ newface = face(vertices)
+ newedge1 = edge(vertices[0], vertices[1])
+ newedge2 = edge(vertices[2], vertices[3])
+ newedge3 = edge(vertices[4], vertices[5])
+ self.hexfaces.append(newface)
+ self.hexedges.append(newedge1)
+ self.hexedges.append(newedge2)
+ self.hexedges.append(newedge3)
+
+ def hexvertface(self, vert):
+ vertices=[]
+ for edge in vert.edges:
+ eid = edge.index
+ if edge.a is vert:
+ vertices.append(self.hexedges[eid].a)
+ elif edge.b is vert:
+ vertices.append(self.hexedges[eid].b)
+ newface = face(vertices)
+ self.hexfaces.append(newface)
+
+ def starify(self):
+ self.starverts=[]
+ self.staredges=[]
+ self.starfaces=[]
+ for i in range(len(self.verts)):
+ self.verts[i].index = i
+ for i in range(len(self.edges)):
+ self.edges[i].index = i
+ self.connectivity()
+ star_vert_counter = 0
+ for currentedge in self.edges:
+ newvert = average([currentedge.a, currentedge.b]).centroid()
+ newvert.index = star_vert_counter
+ star_vert_counter += 1
+ self.starverts.append(newvert)
+ star_face_counter = 0
+ star_edge_counter = 0
+ for currentface in self.faces:
+ currentface.docorners()
+ vertices=[]
+ for corner in currentface.corners:
+ vert = self.starverts[corner[1].index]
+# vert.index = star_vert_counter
+# star_vert_counter += 1
+ vertices.append(vert)
+ newface = face(vertices)
+ newface.index = star_face_counter
+ star_face_counter += 1
+ newedge1 = edge(vertices[0], vertices[1])
+ newedge1.index = star_edge_counter
+ newedge2 = edge(vertices[1], vertices[2])
+ newedge2.index = star_edge_counter + 1
+ newedge3 = edge(vertices[2], vertices[0])
+ newedge3.index = star_edge_counter + 2
+ star_edge_counter += 3
+ self.starfaces.append(newface)
+ self.staredges.append(newedge1)
+ self.staredges.append(newedge2)
+ self.staredges.append(newedge3)
+ for vert in self.verts:
+ vertices=[]
+ vert.clockwise()
+ for currentedge in vert.edges:
+ eid = currentedge.index
+ vertices.append(self.starverts[eid])
+ newface = face(vertices)
+ newface.index = star_face_counter
+ star_face_counter += 1
+ self.starfaces.append(newface)
+ self.verts = self.starverts
+ self.edges = self.staredges
+ self.faces = self.starfaces
+ self.vertedgeflag = 0
+ self.vertfaceflag = 0
+ self.faceedgeflag = 0
+
+ def class2(self):
+ self.class2verts=[]
+ self.class2edges=[]
+ self.class2faces=[]
+
+ newvertstart = len(self.verts)
+ newedgestart = len(self.edges)
+ counter_verts = len(self.verts)
+ for i in range(counter_verts):
+ self.verts[i].index = i
+ for i in range(len(self.edges)):
+ self.edges[i].index = i
+ for i in range(len(self.faces)):
+ self.faces[i].index = i
+ self.connectivity()
+ for currentface in self.faces:
+ currentface.docorners()
+ newvert = average(currentface.vertices).centroid()
+ newvert.index = counter_verts
+
+ counter_verts += 1
+ self.verts.append(newvert)
+ newedge1 = edge(currentface.vertices[0], newvert)
+ newedge2 = edge(currentface.vertices[1], newvert)
+ newedge3 = edge(currentface.vertices[2], newvert)
+ self.edges.append(newedge1)
+ self.edges.append(newedge2)
+ self.edges.append(newedge3)
+ for currentedge in range(newedgestart):
+ self.edges[currentedge].a = self.verts[self.edges[currentedge].faces[0].index+newvertstart]
+ self.edges[currentedge].b = self.verts[self.edges[currentedge].faces[1].index+newvertstart]
+ self.edges[currentedge].findvect()
+
+ for currentvert in range(newvertstart):
+ vert = self.verts[currentvert]
+ vertices=[]
+ vert.clockwise()
+ for currentface in vert.faces:
+ eid = currentface.index
+
+ vertices.append(self.verts[newvertstart + eid])
+
+ for i in range(len(vertices)):
+ if i == len(vertices) - 1:
+ next = vertices[0]
+ else:
+ next = vertices[i+1]
+
+ newface = face([vert, vertices[i], next])
+ self.class2faces.append(newface)
+
+ self.faces = self.class2faces
+ self.vertedgeflag = 0
+ self.vertfaceflag = 0
+ self.faceedgeflag = 0
+
+ def dual(self):
+ self.dualverts=[]
+
+ self.dualfaces=[]
+
+ counter_verts = len(self.verts)
+ for i in range(counter_verts):
+ self.verts[i].index = i
+ for i in range(len(self.edges)):
+ self.edges[i].index = i
+ for i in range(len(self.faces)):
+ self.faces[i].index = i
+ self.connectivity()
+ counter_verts = 0
+ for currentface in self.faces:
+ currentface.docorners()
+ newvert = average(currentface.vertices).centroid()
+ newvert.index = counter_verts #PKHG needed in >= 2.59
+ counter_verts += 1
+ self.dualverts.append(newvert)
+ for vert in self.verts:
+ vertices=[]
+ vert.clockwise()
+ for currentface in vert.faces:
+ eid = currentface.index
+ vertices.append(self.dualverts[eid])
+ newface = face(vertices)
+ self.dualfaces.append(newface)
+ for currentedge in self.edges:
+ currentedge.a = self.dualverts[currentedge.faces[0].index]
+ currentedge.b = self.dualverts[currentedge.faces[1].index]
+ self.verts = self.dualverts
+
+ self.faces = self.dualfaces
+ self.vertedgeflag = 0
+ self.vertfaceflag = 0
+ self.faceedgeflag = 0
+
+class facetype(mesh):
+ def __init__(self, basegeodesic, parameters, width, height, relative):
+ mesh.__init__(self)
+ self.detatch = parameters[0]
+ self.endtype = parameters[1]
+ self.coords = parameters[2]
+ self.base = basegeodesic
+ self.relative = relative
+ self.width = width
+
+ if not self.relative:
+ newwidth = self.findrelative()
+ self.width = width*newwidth
+ self.height = height
+ self.base.connectivity()
+ for coord in self.coords:
+ coord[0]=coord[0]*self.width
+ coord[1]=coord[1]*self.height
+ if not self.base.facenormalflag:
+ for currentface in self.base.faces:
+
+ currentface.docorners()
+ currentface.findnormal()
+
+ self.base.facenormalflag = 1
+ if self.endtype==4 and not self.base.vertnormalflag:
+ for currentvert in self.base.verts:
+ currentvert.findnormal()
+ self.base.vertnormalflag = 1
+ self.createfaces()
+
+ def findrelative(self):
+ centre = average(self.base.faces[0].vertices).centroid()
+ edgelist=[]
+ for point in self.base.faces[0].vertices:
+ newedge = edge(centre, point)
+ edgelist.append(newedge)
+ length = 0
+ for edg in edgelist:
+ extra = edg.vect.length
+ length = length+extra
+
+ length = length/len(edgelist)
+
+ return length
+
+ def createfaces(self):
+ if not self.detatch:
+ for point in self.base.verts:
+ self.verts.append(point)
+ if self.endtype==4:
+ self.createghostverts()
+ for currentface in self.base.faces:
+ self.doface(currentface)
+
+ def createghostverts(self):
+ self.ghoststart = len(self.verts)
+ for vert in self.base.verts:
+ newvert = vert + (vert.normal * self.coords[-1][1])
+ self.verts.append(newvert)
+
+ def doface(self, candidate):
+ grid=[]
+ candidate.dospokes()
+
+ if not self.detatch:
+ line=[]
+ for vert in candidate.vertices:
+ line.append(vert)
+ grid.append(line)
+ else:
+ line=[]
+ for point in candidate.vertices:
+ newvert = vertex(point.vector)
+ self.verts.append(newvert)
+ line.append(newvert)
+ grid.append(line)
+ finish = len(self.coords)
+ if self.endtype==1 or self.endtype==4:
+ finish = finish-1
+ for i in range(finish):
+ up = candidate.normal*self.coords[i][1]
+ line=[]
+ for j in range(len(candidate.vertices)):
+ dotfac = candidate.corners[j][3]*0.5
+ vec=(candidate.spokes[j]*(self.coords[i][0]/sin(dotfac)))
+
+ newvert = candidate.vertices[j]+vec+up
+ line.append(newvert)
+ self.verts.append(newvert)
+ grid.append(line)
+ if self.endtype==4:
+ line=[]
+ for i in range(len(candidate.vertices)):
+ vert = self.verts[candidate.vertices[i].index+self.ghoststart]
+ line.append(vert)
+
+ grid.append(line)
+ for line in grid:
+ line.append(line[0])
+ if self.endtype==3:
+ grid.append(grid[0])
+ for i in range(len(grid)-1):
+ for j in range(len(grid[i])-1):
+ one = grid[i][j]
+ two = grid[i][j+1]
+ three = grid[i+1][j+1]
+ four = grid[i+1][j]
+ newface = face([one, two, three, four])
+ self.faces.append(newface)
+ if self.endtype==2:
+ finalfaceverts = grid[-1]
+ newface = face(finalfaceverts[:-1])
+ self.faces.append(newface)
+ if self.endtype==1:
+ lastvert = average(candidate.vertices).centroid()
+ up = candidate.normal*self.coords[-1][1]
+ newvert = lastvert+up
+ self.verts.append(newvert)
+ ring = grid[-1]
+ for i in range(len(ring)-1):
+ newface = face([newvert, ring[i], ring[i+1]])
+ self.faces.append(newface)
+
+class importmesh(mesh):
+ def __init__(self, meshname, breakquadflag):
+ mesh.__init__(self)
+
+ obj = bpy.data.objects[meshname]
+ bpy.context.scene.objects.active = obj
+ obj.select = True
+ copied_mesh = None
+ impmesh = None
+ if not breakquadflag:
+ bpy.ops.object.mode_set(mode='EDIT')
+ impmesh = bmesh.new() # create an empty BMesh
+ impmesh.from_mesh(obj.data) # fill it in from a Mesh
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ if breakquadflag:
+
+ name = obj.name
+
+ impmesh_name = "Original_" + name
+
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.quads_convert_to_tris()
+ impmesh = bmesh.new() # create an empty BMesh
+ impmesh.from_mesh(obj.data) # fill it in from a Mesh
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+
+ for v in impmesh.verts:
+ vert = vertex(v.co)
+ vert.index = v.index
+ self.verts.append(vert)
+ #PKHG verts is now a list of vertex, so to say a copy of the Vectors
+
+ #PKHG edges
+ for e in impmesh.edges:
+ tmp = []
+ for vert in e.verts:
+ a = self.verts[vert.index]
+ tmp.append(a)
+ newedge = edge(tmp[0], tmp[1])
+ newedge.index = e.index
+ self.edges.append(newedge)
+ #PKHG faces
+ extra_DBG_info("MeshInfo","vefm L995 the mesh impmesh", impmesh.faces[:])
+
+ for f in impmesh.faces:
+ temp=[]
+ for vert in f.verts: #PKHG a list! of indices ??? PKHG>???
+ a = self.verts[vert.index] #PKHG verts contains already vertex objects
+ temp.append(a)
+ newface = face(temp)
+ newface.index = f.index #indexcount
+ self.faces.append(newface)
+ self.dovertedge()
+ self.dovertface()
+ self.temp=[]
+
+ for i in range(len(self.verts)):
+ self.temp.append([])
+ self.verts[i].index = i
+ for i in range(len(self.verts)):
+ target = self.surroundingverts(self.verts[i])
+ for j in range(len(target)): ## go through those verts
+ temptarg = self.temp[target[j].index]
+ flag = 0 ## set a flag up
+
+ for k in range(len(temptarg)): ## go through temp list for each of those verts
+
+ if temptarg[k]==i: ## if we find a match to the current vert...
+ flag = 1 ## raise the flag
+
+ if flag==0: ## if there is no flag after all that...
+ self.temp[target[j].index].append(i) ## add current vert to temp list of this surrounding vert
+ self.temp[i].append(target[j].index) ## add this surrounding vert to the current temp list
+ newedge = edge(self.verts[i], self.verts[target[j].index])
+ self.edges.append(newedge) ## add the newly found edge to the edges list
+
+ for edg in self.edges:
+ edg.findvect()
+ self.vertedgeflag = 0
+ self.vertedgeflag = 0
+ self.connectivity()
+
+ def surroundingverts(self, vert):
+ ''' Find the verts surrounding vert'''
+ surround=[] ## list to be filled and returned
+ for faces in vert.faces: ## loop through faces attached to vert
+ finish = len(faces.vertices)
+ for i in range(finish):
+ if i==finish-1:
+ next = faces.vertices[0]
+ else:
+ next = faces.vertices[i+1]
+ if vert == faces.vertices[i]:
+ surround.append(next)
+ return surround
+
+ def breakquad(self, quad_face):
+ ''' turn quads into triangles'''
+ distance1 = quad_face.vertices[0]-quad_face.vertices[2]
+ distance2 = quad_face.vertices[1]-quad_face.vertices[3]
+ distance1.findlength()
+ distance2.findlength()
+ if abs(distance1.length)<abs(distance2.length):
+ self.faces[quad_face.index]=face([quad_face.vertices[0], quad_face.vertices[1], quad_face.vertices[2]])
+ self.faces.append(face([quad_face.vertices[0], quad_face.vertices[2], quad_face.vertices[3]]))
+ else:
+ self.faces[quad_face.index]=face([quad_face.vertices[0], quad_face.vertices[1], quad_face.vertices[3]])
+ self.faces.append(face([quad_face.vertices[1], quad_face.vertices[2], quad_face.vertices[3]]))
+
+
+class strut(mesh):
+ def __init__(self, base, struttype, width, height, length, widthtog, heighttog, lengthtog, meshname, stretchflag, lift):
+ extra_DBG_info(name = "StrutMesh", info_text="vefm L1026\nstrut called: ", info_obj=[base, struttype, width, height, length, widthtog, heighttog, lengthtog, meshname, stretchflag, lift])
+ mesh.__init__(self)
+ ## put in strut prep stuff here
+ if struttype==None:
+ return
+ total = 0
+ divvy = len(base.faces[0].edges)
+ for lengf in base.faces[0].edges:
+ lengf.vect.findlength()
+ total = total+lengf.vect.length
+ yardstick = total/divvy
+ if widthtog:
+ self.width = width
+ else:
+ self.width = width * yardstick
+ if heighttog:
+ self.height = height
+ else:
+ self.height = height*yardstick
+ if lengthtog:
+ self.shrink = length
+ else:
+ self.shrink = length * yardstick
+ if not base.facenormalflag:
+ for currentface in base.faces:
+ currentface.docorners()
+ currentface.findnormal()
+ base.facenormalflag = 1
+ for edj in base.edges:
+ edj.findnormal()
+ side = edge(edj.a, edj.b)
+ edj.unit = side.vect
+ edj.unit.normalize()
+ edj.cross = crossp(edj.normal, edj.unit).docrossproduct()
+ template = importmesh(meshname,0)
+ maxx = 0
+ minx = 0
+ for vert in template.verts:
+# if vert.x>maxx:
+ if vert.vector.x > maxx:
+# maxx = vert.x
+ maxx = vert.vector.x
+# if vert.x<minx:
+ if vert.vector.x < minx:
+# minx = vert.x
+ minx = vert.vector.x
+ for edj in base.edges:
+ start = len(self.verts)
+ centre = average([edj.a, edj.b]).centroid()
+ split = edj.vect.length/2
+ #PKHG no division by zero!!
+ tmp = 1.0
+ if maxx != minx:
+ tmp = 1.0/(maxx - minx)
+ dubbl = edj.vect.length * tmp
+ #PKHG end no division by zero!!
+ diffplus = split-maxx
+ diffminus=-split-minx
+ for point in template.verts:
+
+ ay=(edj.normal * point.vector.z * self.height) + (edj.normal * lift)
+
+ ce = edj.cross * point.vector.y * self.width
+ if stretchflag:
+# be = edj.unit*self.shrink*dubbl*point.x
+ be = edj.unit * self.shrink * dubbl * point.vector.x
+ else:
+# if point.x > 0.0:
+ if point.vector.x > 0.0:
+# be = edj.unit * self.shrink * (point.x + diffplus)
+ be = edj.unit * self.shrink * (point.vector.x + diffplus)
+# elif point.x < 0.0:
+ elif point.vector.x < 0.0:
+# be = edj.unit * self.shrink * (point.x + diffminus)
+ be = edj.unit * self.shrink * (point.vector.x + diffminus)
+# elif point.x == 0.0:
+ elif point.vector.x == 0.0:
+# be = edj.unit * self.shrink * point.x
+ be = edj.unit * self.shrink * point.vector.x
+ de = ay + be + ce
+ newvert = centre + de
+ self.verts.append(newvert)
+ for edjy in template.edges:
+ one = edjy.a.index+start
+ two = edjy.b.index+start
+ newedge = edge(self.verts[one], self.verts[two])
+ self.edges.append(newedge)
+ for facey in template.faces:
+ faceverts=[]
+ for verty in facey.vertices:
+ index = verty.index+start
+ faceverts.append(self.verts[index])
+ newface = face(faceverts)
+ self.faces.append(newface)
+ self.vertedgeflag = 0
+ self.vertedgeflag = 0
+ self.connectivity()
+
+
+class hub(mesh):
+ def __init__(self, base, hubtype, width, height, length,\
+ widthtog, heighttog, lengthtog, meshname):
+ mesh.__init__(self)
+ self.width = 1.0
+ self.height = 1.0
+ self.shrink = 1.0
+ ## put in strut prep stuff here
+ extra_DBG_info("vefm L1133 HubMesh","base is ", str(dir(base))+"\n and meshname = " + meshname)
+ if hubtype==None:
+ return
+ total = 0
+ divvy = len(base.faces[0].edges)
+ for lengf in base.verts[0].edges:
+ lengf.vect.findlength()
+ total = total+lengf.vect.length
+ yardstick = total / divvy
+ if widthtog:
+ self.width = width
+ else:
+ self.width = width * yardstick
+ if heighttog:
+ self.height = height
+ else:
+ self.height = height * yardstick
+ if lengthtog:
+ self.shrink = length
+ else:
+ self.shrink = length * yardstick
+
+ if not base.facenormalflag:
+ for currentface in base.faces:
+ currentface.docorners()
+ currentface.findnormal()
+ base.facenormalflag = 1
+
+ for apex in base.verts:
+ apex.findnormal()
+ side = edge(apex.edges[0].a, apex.edges[0].b)
+ apex.unit = side.vect #PKHG is Vector: b -a
+ apex.unit.normalize()
+ apex.cross = crossp(apex.normal, apex.unit).docrossproduct()
+ apex.unit = crossp(apex.cross, apex.normal).docrossproduct()
+
+ template = importmesh(meshname,0)
+ for apex in base.verts:
+ start = len(self.verts)
+ centre = apex
+ for point in template.verts:
+ ay = apex.normal * point.vector.z * self.height
+ ce = apex.cross * point.vector.y * self.width
+ be = apex.unit * point.vector.x * self.shrink
+ de = ay+be+ce
+ newvert = centre+de
+ self.verts.append(newvert)
+ for edjy in template.edges:
+ one = edjy.a.index+start
+ two = edjy.b.index+start
+ newedge = edge(self.verts[one], self.verts[two])
+ self.edges.append(newedge)
+ for facey in template.faces:
+ faceverts=[]
+ for verty in facey.vertices:
+ index = verty.index+start
+ faceverts.append(self.verts[index])
+ newface = face(faceverts)
+ self.faces.append(newface)
+ self.vertedgeflag = 0
+ self.vertedgeflag = 0
+ self.connectivity()
+
+#???PKHG TODO Nmesh used yet wrong!
+def finalfill(source, target):
+ if source == target: #PKHG: otherewise >infinite< loop
+ print("\n***WARNING*** vefm_271.finalfill L1148 source == target empty mesh used")
+ target = mesh() #
+#PKHG_??? maybe renumverting and checkkin faces wiht >=4 5 vertices?
+ count = 0
+
+ for point in source.verts:
+
+ newvert = vertex(point.vector)
+ newvert.index = count
+ target.verts.append(newvert)
+ point.index = count #PKHG_INFO source renumbered too!
+
+ count += 1
+
+ for facey in source.faces:
+ row = len(facey.vertices)
+ if row >= 5:
+
+ tmp = Vector()
+ for el in facey.vertices:
+ tmp = tmp + target.verts[el.index].vector
+ tmp = tmp / row
+ centre = vertex(tmp)
+ centre.index = count #PKHG_??? give it a good index
+ count += 1
+
+ target.verts.append(centre)
+ for i in range(row):
+ if i == row - 1:
+ a = target.verts[facey.vertices[-1].index]
+ b = target.verts[facey.vertices[0].index]
+ else:
+ a = target.verts[facey.vertices[i].index]
+ b = target.verts[facey.vertices[i+1].index]
+ target.faces.append([a, b, centre])
+ else:
+ f = []
+
+
+ for j in range(len(facey.vertices)):
+ a = facey.vertices[j]
+
+ f.append(target.verts[a.index])
+ target.faces.append(f)
+
diff --git a/add_mesh_extra_objects/mesh_discombobulator.py b/add_mesh_extra_objects/mesh_discombobulator.py
new file mode 100644
index 00000000..75f9381f
--- /dev/null
+++ b/add_mesh_extra_objects/mesh_discombobulator.py
@@ -0,0 +1,685 @@
+# ##### BEGIN GPL LICENSE BLOCK #####
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software Foundation,
+# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+#
+# ##### END GPL LICENSE BLOCK #####
+
+bl_info = {
+ "name": "Discombobulator",
+ "description": "Its job is to easily add scifi details to a surface to create nice-looking space-ships or futuristic cities.",
+ "author": "Evan J. Rosky (syrux), Chichiri, Jace Priester",
+ "version": (0,2),
+ "blender": (2, 71, 0),
+ "location": "View3D > Toolshelf > Tools Tab",
+ "warning": '',
+ 'wiki_url': 'http://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts',
+ 'tracker_url': 'https://developer.blender.org/maniphest/task/create/?project=3&type=Bug',
+ "category": "Mesh"}
+
+import bpy
+import random
+import mathutils
+import math
+from mathutils import *
+
+doprots = True
+
+# Datas in which we will build the new discombobulated mesh
+nPolygons = []
+nVerts = []
+Verts = []
+Polygons = []
+dVerts = []
+dPolygons = []
+i_prots = [] # index of the top polygons on whow we will generate the doodads
+i_dood_type = [] # type of doodad (given by index of the doodad obj)
+
+bpy.types.Scene.DISC_doodads = []
+
+def randnum(a, b):
+ return random.random()*(b-a)+a
+
+def randVertex(a, b, c, d, Verts):
+ """Return a vector of a random vertex on a quad-polygon"""
+ i = random.randint(1,2)
+ A, B, C, D = 0, 0, 0, 0
+ if(a==1):
+ A, B, C, D = a, b, c, d
+ else:
+ A, B, C, D = a, d, c, b
+
+ i = randnum(0.1, 0.9)
+
+
+ vecAB=Verts[B]-Verts[A]
+ E=Verts[A]+vecAB*i
+
+ vecDC=Verts[C]-Verts[D]
+ F=Verts[D]+vecDC*i
+
+ i = randnum(0.1, 0.9)
+ vecEF=F-E
+
+ O=E+vecEF*i
+ return O
+
+################################ Protusions ###################################
+
+def fill_older_datas(verts, polygon):
+ """ Specifically coded to be called by the function addProtusionToPolygon, its sets up a tuple which contains the vertices from the base and the top of the protusions. """
+ temp_vertices = []
+ temp_vertices.append(verts[polygon[0]].copy())
+ temp_vertices.append(verts[polygon[1]].copy())
+ temp_vertices.append(verts[polygon[2]].copy())
+ temp_vertices.append(verts[polygon[3]].copy())
+ temp_vertices.append(verts[polygon[0]].copy())
+ temp_vertices.append(verts[polygon[1]].copy())
+ temp_vertices.append(verts[polygon[2]].copy())
+ temp_vertices.append(verts[polygon[3]].copy())
+ return temp_vertices
+
+def extrude_top(temp_vertices, normal, height):
+ """ This function extrude the polygon composed of the four first members of the tuple temp_vertices along the normal multiplied by the height of the extrusion."""
+ j = 0
+ while j < 3:
+ temp_vertices[0][j]+=normal[j]*height
+ temp_vertices[1][j]+=normal[j]*height
+ temp_vertices[2][j]+=normal[j]*height
+ temp_vertices[3][j]+=normal[j]*height
+ j+=1
+
+def scale_top(temp_vertices, center, normal, height, scale_ratio):
+ """ This function scale the polygon composed of the four first members of the tuple temp_vertices. """
+ vec1 = [0, 0, 0]
+ vec2 = [0, 0, 0]
+ vec3 = [0, 0, 0]
+ vec4 = [0, 0, 0]
+
+ j = 0
+ while j < 3:
+ center[j]+=normal[j]*height
+ vec1[j] = temp_vertices[0][j] - center[j]
+ vec2[j] = temp_vertices[1][j] - center[j]
+ vec3[j] = temp_vertices[2][j] - center[j]
+ vec4[j] = temp_vertices[3][j] - center[j]
+ temp_vertices[0][j] = center[j] + vec1[j]*(1-scale_ratio)
+ temp_vertices[1][j] = center[j] + vec2[j]*(1-scale_ratio)
+ temp_vertices[2][j] = center[j] + vec3[j]*(1-scale_ratio)
+ temp_vertices[3][j] = center[j] + vec4[j]*(1-scale_ratio)
+ j+=1
+
+def add_prot_polygons(temp_vertices):
+ """ Specifically coded to be called by addProtusionToPolygon, this function put the data from the generated protusion at the end the tuples Verts and Polygons, which will later used to generate the final mesh. """
+ global Verts
+ global Polygons
+ global i_prots
+
+ findex = len(Verts)
+ Verts+=temp_vertices
+
+ polygontop = [findex+0, findex+1, findex+2, findex+3]
+ polygon1 = [findex+0, findex+1, findex+5, findex+4]
+ polygon2 = [findex+1, findex+2, findex+6, findex+5]
+ polygon3 = [findex+2, findex+3, findex+7, findex+6]
+ polygon4 = [findex+3, findex+0, findex+4, findex+7]
+
+ Polygons.append(polygontop)
+ i_prots.append(len(Polygons)-1)
+ Polygons.append(polygon1)
+ Polygons.append(polygon2)
+ Polygons.append(polygon3)
+ Polygons.append(polygon4)
+
+def addProtusionToPolygon(obpolygon, verts, minHeight, maxHeight, minTaper, maxTaper):
+ """Create a protusion from the polygon "obpolygon" of the original object and use several values sent by the user. It calls in this order the following functions:
+ - fill_older_data;
+ - extrude_top;
+ - scale_top;
+ - add_prot_polygons;
+ """
+ # some useful variables
+ polygon = obpolygon.vertices
+ polygontop = polygon
+ polygon1 = []
+ polygon2 = []
+ polygon3 = []
+ polygon4 = []
+ vertices = []
+ tVerts = list(fill_older_datas(verts, polygon)) # list of temp vertices
+ height = randnum(minHeight, maxHeight) # height of generated protusion
+ scale_ratio = randnum(minTaper, maxTaper)
+
+ # extrude the top polygon
+ extrude_top(tVerts, obpolygon.normal, height)
+ # Now, we scale, the top polygon along its normal
+ scale_top(tVerts, GetPolyCentroid(obpolygon,verts), obpolygon.normal, height, scale_ratio)
+ # Finally, we add the protusions to the list of polygons
+ add_prot_polygons(tVerts)
+
+################################## Divide a polygon ##################################
+
+def divide_one(list_polygons, list_vertices, verts, polygon, findex):
+ """ called by divide_polygon, to generate a polygon from one polygon, maybe I could simplify this process """
+ temp_vertices = []
+ temp_vertices.append(verts[polygon[0]].copy())
+ temp_vertices.append(verts[polygon[1]].copy())
+ temp_vertices.append(verts[polygon[2]].copy())
+ temp_vertices.append(verts[polygon[3]].copy())
+
+ list_vertices+=temp_vertices
+
+ list_polygons.append([findex+0, findex+1, findex+2, findex+3])
+
+def divide_two(list_polygons, list_vertices, verts, polygon, findex):
+ """ called by divide_polygon, to generate two polygons from one polygon and add them to the list of polygons and vertices which form the discombobulated mesh"""
+ temp_vertices = []
+ temp_vertices.append(verts[polygon[0]].copy())
+ temp_vertices.append(verts[polygon[1]].copy())
+ temp_vertices.append(verts[polygon[2]].copy())
+ temp_vertices.append(verts[polygon[3]].copy())
+ temp_vertices.append((verts[polygon[0]]+verts[polygon[1]])/2)
+ temp_vertices.append((verts[polygon[2]]+verts[polygon[3]])/2)
+
+ list_vertices+=temp_vertices
+
+ list_polygons.append([findex+0, findex+4, findex+5, findex+3])
+ list_polygons.append([findex+1, findex+2, findex+5, findex+4])
+
+def divide_three(list_polygons, list_vertices, verts, polygon, findex, center):
+ """ called by divide_polygon, to generate three polygons from one polygon and add them to the list of polygons and vertices which form the discombobulated mesh"""
+ temp_vertices = []
+ temp_vertices.append(verts[polygon[0]].copy())
+ temp_vertices.append(verts[polygon[1]].copy())
+ temp_vertices.append(verts[polygon[2]].copy())
+ temp_vertices.append(verts[polygon[3]].copy())
+ temp_vertices.append((verts[polygon[0]]+verts[polygon[1]])/2)
+ temp_vertices.append((verts[polygon[2]]+verts[polygon[3]])/2)
+ temp_vertices.append((verts[polygon[1]]+verts[polygon[2]])/2)
+ temp_vertices.append(center.copy())
+
+ list_vertices+=temp_vertices
+
+ list_polygons.append([findex+0, findex+4, findex+5, findex+3])
+ list_polygons.append([findex+1, findex+6, findex+7, findex+4])
+ list_polygons.append([findex+6, findex+2, findex+5, findex+7])
+
+def divide_four(list_polygons, list_vertices, verts, polygon, findex, center):
+ """ called by divide_polygon, to generate four polygons from one polygon and add them to the list of polygons and vertices which form the discombobulated mesh"""
+ temp_vertices = []
+ temp_vertices.append(verts[polygon[0]].copy())
+ temp_vertices.append(verts[polygon[1]].copy())
+ temp_vertices.append(verts[polygon[2]].copy())
+ temp_vertices.append(verts[polygon[3]].copy())
+ temp_vertices.append((verts[polygon[0]]+verts[polygon[1]])/2)
+ temp_vertices.append((verts[polygon[2]]+verts[polygon[3]])/2)
+ temp_vertices.append((verts[polygon[1]]+verts[polygon[2]])/2)
+ temp_vertices.append(center.copy())
+ temp_vertices.append((verts[polygon[0]]+verts[polygon[3]])/2)
+ temp_vertices.append(center.copy())
+
+ list_vertices+=temp_vertices
+
+ list_polygons.append([findex+0, findex+4, findex+7, findex+8])
+ list_polygons.append([findex+1, findex+6, findex+7, findex+4])
+ list_polygons.append([findex+6, findex+2, findex+5, findex+7])
+ list_polygons.append([findex+8, findex+7, findex+5, findex+3])
+
+def dividepolygon(obpolygon, verts, number):
+ """Divide the poly into the wanted number of polygons"""
+ global nPolygons
+ global nVerts
+
+ poly = obpolygon.vertices
+ tVerts = []
+
+ if(number==1):
+ divide_one(nPolygons, nVerts, verts, poly, len(nVerts))
+ elif(number==2):
+ divide_two(nPolygons, nVerts, verts, poly, len(nVerts))
+ elif(number==3):
+ divide_three(nPolygons, nVerts, verts, poly, len(nVerts), GetPolyCentroid(obpolygon,verts))
+ elif(number==4):
+ divide_four(nPolygons, nVerts, verts, poly, len(nVerts), GetPolyCentroid(obpolygon,verts))
+
+############################### Discombobulate ################################
+
+def GetPolyCentroid(obpolygon,allvertcoords):
+ centroid=mathutils.Vector((0,0,0))
+ for vindex in obpolygon.vertices:
+ centroid+=mathutils.Vector(allvertcoords[vindex])
+ centroid/=len(obpolygon.vertices)
+ return centroid
+
+def division(obpolygons, verts, sf1, sf2, sf3, sf4):
+ """Function to divide each of the selected polygons"""
+ divide = []
+ if(sf1): divide.append(1)
+ if(sf2): divide.append(2)
+ if(sf3): divide.append(3)
+ if(sf4): divide.append(4)
+ for poly in obpolygons:
+ if(poly.select == True and len(poly.vertices)==4):
+ a = random.randint(0, len(divide)-1)
+ dividepolygon(poly, verts, divide[a])
+
+def protusion(obverts, obpolygons, minHeight, maxHeight, minTaper, maxTaper):
+ """function to generate the protusions"""
+ verts = []
+ for vertex in obverts:
+ verts.append(vertex.co)
+
+ for polygon in obpolygons:
+ if(polygon.select == True):
+ if(len(polygon.vertices) == 4):
+ addProtusionToPolygon(polygon, verts, minHeight, maxHeight, minTaper, maxTaper)
+
+def test_v2_near_v1(v1, v2):
+ if(v1.x - 0.1 <= v2.x <= v1.x + 0.1
+ and v1.y - 0.1 <= v2.y <= v1.y + 0.1
+ and v1.z - 0.1 <= v2.z <= v1.z + 0.1):
+ return True
+
+ return False
+
+def angle_between_nor(nor_orig, nor_result):
+ angle = math.acos(nor_orig.dot(nor_result))
+ axis = nor_orig.cross(nor_result).normalized()
+
+ q = mathutils.Quaternion()
+ q.x = axis.x*math.sin(angle/2)
+ q.y = axis.y*math.sin(angle/2)
+ q.z = axis.z*math.sin(angle/2)
+ q.w = math.cos(angle/2)
+
+ return q
+
+def doodads(object1, mesh1, dmin, dmax):
+ """function to generate the doodads"""
+ global dVerts
+ global dPolygons
+ i = 0
+ # on parcoure cette boucle pour ajouter des doodads a toutes les polygons
+ # english translation: this loops adds doodads to all polygons
+ while(i<len(object1.data.polygons)):
+ if object1.data.polygons[i].select==False:
+ continue
+ doods_nbr = random.randint(dmin, dmax)
+ j = 0
+ while(j<=doods_nbr):
+ origin_dood = randVertex(object1.data.polygons[i].vertices[0], object1.data.polygons[i].vertices[1], object1.data.polygons[i].vertices[2], object1.data.polygons[i].vertices[3], Verts)
+ type_dood = random.randint(0, len(bpy.context.scene.DISC_doodads)-1)
+ polygons_add = []
+ verts_add = []
+
+ # First we have to apply scaling and rotation to the mesh
+ bpy.ops.object.select_pattern(pattern=bpy.context.scene.DISC_doodads[type_dood],extend=False)
+ bpy.context.scene.objects.active=bpy.data.objects[bpy.context.scene.DISC_doodads[type_dood]]
+ bpy.ops.object.transform_apply(rotation=True, scale=True)
+
+ for polygon in bpy.data.objects[bpy.context.scene.DISC_doodads[type_dood]].data.polygons:
+ polygons_add.append(polygon.vertices)
+ for vertex in bpy.data.objects[bpy.context.scene.DISC_doodads[type_dood]].data.vertices:
+ verts_add.append(vertex.co.copy())
+ normal_original_polygon = object1.data.polygons[i].normal
+
+ nor_def = mathutils.Vector((0.0, 0.0, 1.0))
+ qr = nor_def.rotation_difference(normal_original_polygon.normalized())
+
+ case_z = False
+ if(test_v2_near_v1(nor_def, -normal_original_polygon)):
+ case_z = True
+ qr = mathutils.Quaternion((0.0, 0.0, 0.0, 0.0))
+ #qr = angle_between_nor(nor_def, normal_original_polygon)
+ for vertex in verts_add:
+ vertex.rotate(qr)
+ vertex+=origin_dood
+ findex = len(dVerts)
+ for polygon in polygons_add:
+ dPolygons.append([polygon[0]+findex, polygon[1]+findex, polygon[2]+findex, polygon[3]+findex])
+ i_dood_type.append(bpy.data.objects[bpy.context.scene.DISC_doodads[type_dood]].name)
+ for vertex in verts_add:
+ dVerts.append(vertex)
+ j+=1
+ i+=5
+
+def protusions_repeat(object1, mesh1, r_prot):
+
+ for j in i_prots:
+ if j<len(object1.data.polygons):
+ object1.data.polygons[j].select=True
+ else:
+ print("Warning: hit end of polygons in object1")
+
+# add material to discombobulated mesh
+def setMatProt(discObj, origObj, sideProtMat, topProtMat):
+ # First we put the materials in their slots
+ bpy.ops.object.select_pattern(pattern = discObj.name,extend=False)
+ bpy.context.scene.objects.active=bpy.data.objects[discObj.name]
+ try:
+ origObj.material_slots[topProtMat]
+ origObj.material_slots[sideProtMat]
+ except:
+ return
+
+ bpy.ops.object.material_slot_add()
+ bpy.ops.object.material_slot_add()
+ discObj.material_slots[0].material = origObj.material_slots[topProtMat].material
+ discObj.material_slots[1].material = origObj.material_slots[sideProtMat].material
+
+ # Then we assign materials to protusions
+ for polygon in discObj.data.polygons:
+ if polygon.index in i_prots:
+ polygon.material_index = 0
+ else:
+ polygon.material_index = 1
+
+def setMatDood(doodObj):
+ # First we add the materials slots
+ bpy.ops.object.select_pattern(pattern = doodObj.name,extend=False)
+ bpy.context.scene.objects.active=doodObj
+ for name in bpy.context.scene.DISC_doodads:
+ try:
+ bpy.ops.object.material_slot_add()
+ doodObj.material_slots[-1].material = bpy.data.objects[name].material_slots[0].material
+ for polygon in doodObj.data.polygons:
+ if i_dood_type[polygon.index] == name:
+ polygon.material_index = len(doodObj.material_slots)-1
+ except:
+ print()
+
+
+def clean_doodads():
+ current_doodads=list(bpy.context.scene.DISC_doodads)
+
+ for name in current_doodads:
+ if name not in bpy.data.objects:
+ bpy.context.scene.DISC_doodads.remove(name)
+
+
+def discombobulate(minHeight, maxHeight, minTaper, maxTaper, sf1, sf2, sf3, sf4, dmin, dmax, r_prot, sideProtMat, topProtMat, isLast):
+ global doprots
+ global nVerts
+ global nPolygons
+ global Verts
+ global Polygons
+ global dVerts
+ global dPolygons
+ global i_prots
+
+
+ bpy.ops.object.mode_set(mode="OBJECT")
+
+
+ #start by cleaning up doodads that don't exist anymore
+ clean_doodads()
+
+
+ # Create the discombobulated mesh
+ mesh = bpy.data.meshes.new("tmp")
+ object = bpy.data.objects.new("tmp", mesh)
+ bpy.context.scene.objects.link(object)
+
+ # init final verts and polygons tuple
+ nPolygons = []
+ nVerts = []
+ Polygons = []
+ Verts = []
+ dPolygons = []
+ dVerts = []
+
+ origObj = bpy.context.active_object
+
+ # There we collect the rotation, translation and scaling datas from the original mesh
+ to_translate = bpy.context.active_object.location
+ to_scale = bpy.context.active_object.scale
+ to_rotate = bpy.context.active_object.rotation_euler
+
+ # First, we collect all the informations we will need from the previous mesh
+ obverts = bpy.context.active_object.data.vertices
+ obpolygons = bpy.context.active_object.data.polygons
+ verts = []
+ for vertex in obverts:
+ verts.append(vertex.co)
+
+ division(obpolygons, verts, sf1, sf2, sf3, sf4)
+
+ # Fill in the discombobulated mesh with the new polygons
+ mesh.from_pydata(nVerts, [], nPolygons)
+ mesh.update(calc_edges = True)
+
+ # Reload the datas
+ bpy.ops.object.select_all(action="DESELECT")
+ bpy.ops.object.select_pattern(pattern = object.name,extend=False)
+ bpy.context.scene.objects.active=bpy.data.objects[object.name]
+ obverts = bpy.context.active_object.data.vertices
+ obpolygons = bpy.context.active_object.data.polygons
+
+ protusion(obverts, obpolygons, minHeight, maxHeight, minTaper, maxTaper)
+
+ # Fill in the discombobulated mesh with the new polygons
+ mesh1 = bpy.data.meshes.new("discombobulated_object")
+ object1 = bpy.data.objects.new("discombobulated_mesh", mesh1)
+ bpy.context.scene.objects.link(object1)
+ mesh1.from_pydata(Verts, [], Polygons)
+ mesh1.update(calc_edges = True)
+
+
+ # Set the material's of discombobulated object
+ setMatProt(object1, origObj, sideProtMat, topProtMat)
+
+ bpy.ops.object.select_pattern(pattern = object1.name,extend=False)
+ bpy.context.scene.objects.active=bpy.data.objects[object1.name]
+ bpy.ops.object.mode_set(mode='EDIT')
+ bpy.ops.mesh.normals_make_consistent(inside=False)
+ bpy.ops.mesh.select_all(action='DESELECT')
+ bpy.ops.object.mode_set(mode='OBJECT')
+
+ #if(bpy.context.scene.repeatprot):
+ protusions_repeat(object1, mesh1, r_prot)
+
+ if(len(bpy.context.scene.DISC_doodads) != 0 and bpy.context.scene.dodoodads and isLast):
+ doodads(object1, mesh1, dmin, dmax)
+ mesh2 = bpy.data.meshes.new("dood_mesh")
+ object2 = bpy.data.objects.new("dood_obj", mesh2)
+ bpy.context.scene.objects.link(object2)
+ mesh2.from_pydata(dVerts, [], dPolygons)
+ mesh2.update(calc_edges = True)
+ setMatDood(object2)
+ object2.location = to_translate
+ object2.rotation_euler = to_rotate
+ object2.scale = to_scale
+
+ bpy.ops.object.select_pattern(pattern = object.name,extend=False)
+ bpy.context.scene.objects.active=bpy.data.objects[object.name]
+ bpy.ops.object.delete()
+
+ bpy.ops.object.select_pattern(pattern=object1.name,extend=False)
+ bpy.context.scene.objects.active=bpy.data.objects[object1.name]
+ bpy.context.scene.update()
+
+ # translate, scale and rotate discombobulated results
+ object1.location = to_translate
+ object1.rotation_euler = to_rotate
+ object1.scale = to_scale
+
+ #set all polys to selected. this allows recursive discombobulating.
+ for poly in mesh1.polygons:
+ poly.select=True
+
+############ Operator to select and deslect an object as a doodad ###############
+
+class chooseDoodad(bpy.types.Operator):
+ bl_idname = "object.discombobulate_set_doodad"
+ bl_label = "Discombobulate set doodad object"
+
+ def execute(self, context):
+ bpy.context.scene.DISC_doodads.append(bpy.context.active_object.name)
+
+ def invoke(self, context, event):
+ self.execute(context)
+ return {'FINISHED'}
+
+class unchooseDoodad(bpy.types.Operator):
+ bl_idname = "object.discombobulate_unset_doodad"
+ bl_label = "Discombobulate unset doodad object"
+
+ def execute(self, context):
+ for name in bpy.context.scene.DISC_doodads:
+ if name == bpy.context.active_object.name:
+ bpy.context.scene.DISC_doodads.remove(name)
+
+ def invoke(self, context, event):
+ self.execute(context)
+ return {'FINISHED'}
+
+################################## Interpolygon ####################################
+
+class discombobulator(bpy.types.Operator):
+ bl_idname = "object.discombobulate"
+ bl_label = "Discombobulate"
+ bl_options = {'REGISTER', 'UNDO'}
+
+ def execute(self, context):
+ scn = context.scene
+ i=0
+ while i<scn.repeatprot:
+ isLast=False
+ if i==scn.repeatprot-1:
+ isLast=True
+ discombobulate(scn.minHeight, scn.maxHeight, scn.minTaper, scn.maxTaper, scn.subpolygon1, scn.subpolygon2, scn.subpolygon3, scn.subpolygon4, scn.mindoodads, scn.maxdoodads, scn.repeatprot, scn.sideProtMat, scn.topProtMat, isLast)
+ i+=1
+ return {'FINISHED'}
+
+class discombob_help(bpy.types.Operator):
+ bl_idname = 'help.discombobulator'
+ bl_label = ''
+
+ def draw(self, context):
+ layout = self.layout
+ layout.label('To use:')
+ layout.label('Works with Quads only not Ngons.')
+ layout.label('Select a face or faces')
+ layout.label('Press Discombobulate to create greebles')
+
+
+
+ def execute(self, context):
+ return {'FINISHED'}
+
+ def invoke(self, context, event):
+ return context.window_manager.invoke_popup(self, width = 300)
+
+class VIEW3D_PT_tools_discombobulate(bpy.types.Panel):
+ bl_space_type = 'VIEW_3D'
+ bl_region_type = 'TOOLS'
+ bl_label = "Discombobulator"
+ bl_context = "objectmode"
+ bl_options = {'DEFAULT_CLOSED'}
+ bl_category = "Create"
+
+ def draw(self, context):
+ layout = self.layout
+ row = layout.row()
+ row = layout.split(0.80)
+ row.operator('object.discombobulate', text = 'Discombobulate', icon = 'PLUGIN')
+ row.operator('help.discombobulator', icon = 'INFO')
+ box = layout.box()
+ box.label("Protusions settings")
+ row = box.row()
+ row.prop(context.scene, 'doprots')
+ row = box.row()
+ row.prop(context.scene, 'minHeight')
+ row = box.row()
+ row.prop(context.scene, 'maxHeight')
+ row = box.row()
+ row.prop(context.scene, 'minTaper')
+ row = box.row()
+ row.prop(context.scene, 'maxTaper')
+ row = box.row()
+ col1 = row.column(align = True)
+ col1.prop(context.scene, "subpolygon1")
+ col2 = row.column(align = True)
+ col2.prop(context.scene, "subpolygon2")
+ col3 = row.column(align = True)
+ col3.prop(context.scene, "subpolygon3")
+ col4 = row.column(align = True)
+ col4.prop(context.scene, "subpolygon4")
+ row = box.row()
+ row.prop(context.scene, "repeatprot")
+ box = layout.box()
+ box.label("Doodads settings")
+ row = box.row()
+ row.prop(context.scene, 'dodoodads')
+ row = box.row()
+ row.prop(context.scene, "mindoodads")
+ row = box.row()
+ row.prop(context.scene, "maxdoodads")
+ row = box.row()
+ row.operator("object.discombobulate_set_doodad", text = "Pick doodad")
+ row = box.row()
+ row.operator("object.discombobulate_unset_doodad", text = "Remove doodad")
+ col = box.column(align = True)
+ for name in bpy.context.scene.DISC_doodads:
+ col.label(text = name)
+ box = layout.box()
+ box.label("Materials settings")
+ row = box.row()
+ row.prop(context.scene, 'topProtMat')
+ row = box.row()
+ row.prop(context.scene, "sideProtMat")
+ row = box.row()
+
+# registering and menu integration
+def register():
+ # Protusions Buttons:
+ bpy.types.Scene.repeatprot = bpy.props.IntProperty(name="Repeat protusions", description="make several layers of protusion", default = 1, min = 1, max = 10)
+ bpy.types.Scene.doprots = bpy.props.BoolProperty(name="Make protusions", description = "Check if we want to add protusions to the mesh", default = True)
+ bpy.types.Scene.polygonschangedpercent = bpy.props.FloatProperty(name="Polygon %", description = "Percentage of changed polygons", default = 1.0)
+ bpy.types.Scene.minHeight = bpy.props.FloatProperty(name="Min height", description="Minimal height of the protusions", default=0.2)
+ bpy.types.Scene.maxHeight = bpy.props.FloatProperty(name="Max height", description="Maximal height of the protusions", default = 0.4)
+ bpy.types.Scene.minTaper = bpy.props.FloatProperty(name="Min taper", description="Minimal height of the protusions", default=0.15, min = 0.0, max = 1.0, subtype = 'PERCENTAGE')
+ bpy.types.Scene.maxTaper = bpy.props.FloatProperty(name="Max taper", description="Maximal height of the protusions", default = 0.35, min = 0.0, max = 1.0, subtype = 'PERCENTAGE')
+ bpy.types.Scene.subpolygon1 = bpy.props.BoolProperty(name="1", default = True)
+ bpy.types.Scene.subpolygon2 = bpy.props.BoolProperty(name="2", default = True)
+ bpy.types.Scene.subpolygon3 = bpy.props.BoolProperty(name="3", default = True)
+ bpy.types.Scene.subpolygon4 = bpy.props.BoolProperty(name="4", default = True)
+
+ # Doodads buttons:
+ bpy.types.Scene.dodoodads = bpy.props.BoolProperty(name="Make doodads", description = "Check if we want to generate doodads", default = True)
+ bpy.types.Scene.mindoodads = bpy.props.IntProperty(name="Minimum doodads number", description = "Ask for the minimum number of doodads to generate per polygon", default = 1, min = 0, max = 50)
+ bpy.types.Scene.maxdoodads = bpy.props.IntProperty(name="Maximum doodads number", description = "Ask for the maximum number of doodads to generate per polygon", default = 6, min = 1, max = 50)
+ bpy.types.Scene.doodMinScale = bpy.props.FloatProperty(name="Scale min", description="Minimum scaling of doodad", default = 0.5, min = 0.0, max = 1.0, subtype = 'PERCENTAGE')
+ bpy.types.Scene.doodMaxScale = bpy.props.FloatProperty(name="Scale max", description="Maximum scaling of doodad", default = 1.0, min = 0.0, max = 1.0, subtype = 'PERCENTAGE')
+
+ # Materials buttons:
+ bpy.types.Scene.sideProtMat = bpy.props.IntProperty(name="Side's prot mat", description = "Material of protusion's sides", default = 0, min = 0)
+ bpy.types.Scene.topProtMat = bpy.props.IntProperty(name = "Prot's top mat", description = "Material of protusion's top", default = 0, min = 0)
+
+ bpy.utils.register_class(discombobulator)
+ bpy.utils.register_class(chooseDoodad)
+ bpy.utils.register_class(unchooseDoodad)
+ bpy.utils.register_class(VIEW3D_PT_tools_discombobulate)
+ bpy.utils.register_class(discombob_help)
+
+# unregistering and removing menus
+def unregister():
+ bpy.utils.unregister_class(discombobulator)
+ bpy.utils.unregister_class(chooseDoodad)
+ bpy.utils.unregister_class(unchooseDoodad)
+ bpy.utils.unregister_class(VIEW3D_PT_tools_discombobulate)
+ bpy.utils.unregister_class(discombob_help)
+
+if __name__ == "__main__":
+ register()