diff options
author | Spivak Vladimir (cwolf3d) <cwolf3d@gmail.com> | 2019-02-05 03:33:12 +0300 |
---|---|---|
committer | Spivak Vladimir (cwolf3d) <cwolf3d@gmail.com> | 2019-02-05 03:33:12 +0300 |
commit | d6b0e690e3e323ac805d90f49ffb98264e13b7ee (patch) | |
tree | 669970d674f18718403048f4b5d3549612c03f29 /add_mesh_geodesic_domes | |
parent | 288fa42419d70dd7709d15f00e8a6bee10c24e89 (diff) |
Separated geodesic_domes from add_mesh_extra_objects
Diffstat (limited to 'add_mesh_geodesic_domes')
-rw-r--r-- | add_mesh_geodesic_domes/__init__.py | 82 | ||||
-rw-r--r-- | add_mesh_geodesic_domes/add_shape_geodesic.py | 95 | ||||
-rw-r--r-- | add_mesh_geodesic_domes/forms_271.py | 238 | ||||
-rw-r--r-- | add_mesh_geodesic_domes/geodesic_classes_271.py | 804 | ||||
-rw-r--r-- | add_mesh_geodesic_domes/third_domes_panel_271.py | 1450 | ||||
-rw-r--r-- | add_mesh_geodesic_domes/vefm_271.py | 1144 |
6 files changed, 3813 insertions, 0 deletions
diff --git a/add_mesh_geodesic_domes/__init__.py b/add_mesh_geodesic_domes/__init__.py new file mode 100644 index 00000000..b1954214 --- /dev/null +++ b/add_mesh_geodesic_domes/__init__.py @@ -0,0 +1,82 @@ +# ##### 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, 3), + "blender": (2, 80, 0), + "location": "View3D > Add > Mesh", + "description": "Create geodesic dome type objects.", + "warning": "", + "wiki_url": "https://wiki.blender.org/index.php/Extensions:2.6/Py/Scripts/Modeling/Geodesic_Domes", + "tracker_url": "", + "category": "Add Mesh"} + +if "bpy" in locals(): + import importlib + importlib.reload(add_shape_geodesic) + importlib.reload(forms_271) + importlib.reload(geodesic_classes_271) + importlib.reload(third_domes_panel_271) + importlib.reload(vefm_271) + +else: + from . import add_shape_geodesic + from . import forms_271 + from . import geodesic_classes_271 + from . import third_domes_panel_271 + from . import vefm_271 + +import bpy + +# Define "Extras" menu +def menu_func(self, context): + lay_out = self.layout + lay_out.operator_context = 'INVOKE_REGION_WIN' + + lay_out.separator() + lay_out.operator("mesh.generate_geodesic_dome", + text="Geodesic Dome") + +# Register +classes = [ + add_shape_geodesic.add_corrective_pose_shape_fast, + third_domes_panel_271.GenerateGeodesicDome, + third_domes_panel_271.DialogOperator, +] + +def register(): + from bpy.utils import register_class + for cls in classes: + register_class(cls) + + # Add "Extras" menu to the "Add Mesh" menu + bpy.types.VIEW3D_MT_mesh_add.append(menu_func) + + +def unregister(): + # Remove "Extras" menu from the "Add Mesh" menu. + bpy.types.VIEW3D_MT_mesh_add.remove(menu_func) + + from bpy.utils import unregister_class + for cls in reversed(classes): + unregister_class(cls) + +if __name__ == "__main__": + register() diff --git a/add_mesh_geodesic_domes/add_shape_geodesic.py b/add_mesh_geodesic_domes/add_shape_geodesic.py new file mode 100644 index 00000000..70cd1201 --- /dev/null +++ b/add_mesh_geodesic_domes/add_shape_geodesic.py @@ -0,0 +1,95 @@ +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): + bl_idname = "object.add_corrective_pose_shape_fast" + bl_label = "Add object as corrective shape faster" + bl_description = "Adds 1st object as shape to 2nd object as pose shape (only 1 armature)" + + @classmethod + def poll(cls, context): + return context.active_object is not 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'} diff --git a/add_mesh_geodesic_domes/forms_271.py b/add_mesh_geodesic_domes/forms_271.py new file mode 100644 index 00000000..f4dd5119 --- /dev/null +++ b/add_mesh_geodesic_domes/forms_271.py @@ -0,0 +1,238 @@ +from math import sin, cos, sqrt +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 L126***, ures is 1, changed into 2\n\n") + self.ures = 2 + if self.vres == 1: + print("\n***ERROR in grid forms_271.grid L129***, 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_geodesic_domes/geodesic_classes_271.py b/add_mesh_geodesic_domes/geodesic_classes_271.py new file mode 100644 index 00000000..6f54bff7 --- /dev/null +++ b/add_mesh_geodesic_domes/geodesic_classes_271.py @@ -0,0 +1,804 @@ +from .vefm_271 import mesh, vertex, edge, face +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': + if orientation == 'PointUp': + geo = octahedron(parameters) + elif orientation == 'EdgeUp': + geo = octaedge(parameters) + else: # if orientation == 2: + geo = octaface(parameters) + elif polytype == '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_geodesic_domes/third_domes_panel_271.py b/add_mesh_geodesic_domes/third_domes_panel_271.py new file mode 100644 index 00000000..2a5a4409 --- /dev/null +++ b/add_mesh_geodesic_domes/third_domes_panel_271.py @@ -0,0 +1,1450 @@ +import bpy +import os +from . import vefm_271 +from . import forms_271 +from . import geodesic_classes_271 +from . import add_shape_geodesic + +from bpy.types import Operator +from bpy.props import ( + EnumProperty, + IntProperty, + FloatProperty, + StringProperty, + BoolProperty, + ) +from math import pi +from mathutils import Vector # used for vertex.vector values + +# global # +last_generated_object = None +last_imported_mesh = None +basegeodesic = None +imported_hubmesh_to_use = None +error_message = "" +geodesic_not_yet_called = True +# global end # + +# ###### EIND FOR SHAPEKEYS ###### + + +class GenerateGeodesicDome(Operator): + bl_label = "Modify Geodesic Objects" + bl_idname = "mesh.generate_geodesic_dome" + bl_description = "Create Geodesic Object Types" + bl_options = {'REGISTER', 'UNDO', 'PRESET'} + + # 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="Face Width", + min=-1, soft_min=0.001, max=4, + default=.50 + ) + fwtog: BoolProperty( + name="Width tweak", + default=False + ) + faceheight: FloatProperty( + name="Face Height", + min=0.001, max=4, + default=1 + ) + fhtog: BoolProperty( + name="Height tweak", + default=False + ) + face_detach: BoolProperty( + name="Detach Faces", + default=False + ) + fmeshname: StringProperty( + name="Face Mesh name", + 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="Strut type", + default=0 + ) + struttoggle: BoolProperty( + name="Use Struts", + default=False + ) + strutimporttoggle: BoolProperty( + name="Strut import toggle", + default=False + ) + strutimpmesh: StringProperty( + name="Strut import mesh", + default="None" + ) + strutwidth: FloatProperty( + name="Strut width", + min=-10, soft_min=5, + #soft_max=5, max=10, + default=1 + ) + swtog: BoolProperty( + name="Width enable", + default=False + ) + strutheight: FloatProperty( + name="Strut height", + min=-5, soft_min=-1, + #soft_max=5, max=10, + default=1 + ) + shtog: BoolProperty( + name="Height tweak", + default=False + ) + strutshrink: FloatProperty( + name="Strut shrink", + min=0.001, #max=4, + default=1 + ) + sstog: BoolProperty( + name="Shrink tweak", + 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="Strut mesh name", + default="defaultstrut" + ) + # Hubs + hubtype: BoolProperty( + name="Hub type", + description="not used", + default=True + ) + hubtoggle: BoolProperty( + name="Use Hubs", + default=False + ) + hubimporttoggle: BoolProperty( + name="New import", + description="Import a mesh", + default=False + ) + hubimpmesh: StringProperty( + name="Hub mesh import", + description="Name of mesh to import", + default="None" + ) + hubwidth: FloatProperty( + name="Hub width", + min=0.01, #max=10, + default=1 + ) + hwtog: BoolProperty( + name="Width tweak", + default=False + ) + hubheight: FloatProperty( + name="Hub height", + min=0.01, #max=10, + default=1 + ) + hhtog: BoolProperty( + name="Height tweak", + default=False + ) + hublength: FloatProperty( + name="Hub length", + min=0.1, #max=10, + default=1 + ) + hstog: BoolProperty( + name="Hub s tweak", + default=False + ) + hmeshname: StringProperty( + name="Hub mesh name", + 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): + layout = self.layout + row = layout.row() + col = layout.column() + 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(text="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(text="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(text="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(text="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(text="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(text="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 is False) and (self.vact is False): + row.label(text="No checkbox active", icon="INFO") + else: + row.label(text="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() + if self.hubimpmesh == "None": + row = layout.row() + row.label(text="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(text="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 = ["To Use", + "If normals look inverted:", + "Once mesh is finished,", + "You may recalc normals outside.", + "--------", + "To use your own mesh with the:", + "Faces:", + "Import your mesh in the:", + "Objects: Geodesic menu.", + "You must type in the name", + "Of your custom object first.", + "--------", + "To use your own mesh with the: ", + "Struts/Hubs:", + "You must type in the name", + "Of your custom object/s first,"] + 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, error_message + # 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] + 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. necessary!!! + vefm_271.vefm_add_object(mesh) + last_generated_object = context.active_object + last_generated_object.location = (0, 0, 0) + context.view_layer.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" + error_message = message + self.report({"INFO"}, message) + print("***INFO*** You have to fill in the name of an existing mesh") + else: + 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] + 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" + 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*** \nEither no mesh for hub\nor " + \ + hmeshname + " available" + error_message = message + bpy.ops.object.dialog_operator('INVOKE_DEFAULT') + print(message) + else: + message = "***INFO***\nEnable Hubs first" + error_message = message + print("\n***INFO*** Enable Hubs first") + 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***\nStrut object " + strutimpmesh + "\nis not a Mesh" + error_message = message + bpy.ops.object.dialog_operator('INVOKE_DEFAULT') + print("***ERROR*** Strut object 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" + error_message = message + bpy.ops.object.dialog_operator('INVOKE_DEFAULT') + print("\n***ERROR*** No imported mesh available \nLast 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 = "***ERROR***\n" + "Writing " + filename + "\nis not possible" + # bpy.context.scene.instant_filenames = filenames + + except: + message = "***ERROR***\n Contakt PKHG, something wrong happened" + + 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 + "\nis not 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 = "***ERROR***\n" + "Writing " + filename + "\nnot possible" + # bpy.context.scene.instant_filenames = filenames + except: + message = "***ERROR***\n Contakt PKHG,\nsomething went wrong reading params happened" + error_message = message + bpy.ops.object.dialog_operator('INVOKE_DEFAULT') + + return {'FINISHED'} + + def invoke(self, context, event): + global basegeodesic, geodesic_not_yet_called + bpy.ops.view3d.snap_cursor_to_center() + if geodesic_not_yet_called: + 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(Operator): + bl_idname = "object.dialog_operator" + bl_label = "INFO" + + def draw(self, context): + layout = self.layout + message = 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) diff --git a/add_mesh_geodesic_domes/vefm_271.py b/add_mesh_geodesic_domes/vefm_271.py new file mode 100644 index 00000000..4c7fc19d --- /dev/null +++ b/add_mesh_geodesic_domes/vefm_271.py @@ -0,0 +1,1144 @@ +# vert class and overloading experiments +import bpy +# PKHG>NEEDED? +import bmesh +from math import acos, pi, sin, cos, atan, tan +from mathutils import Vector +from bpy_extras.object_utils import AddObjectHelper, object_data_add + +# 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 + + +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 L68 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*** length zero in findnormal, j = (0,1,0) replaced") + 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! L158") + 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 L212 ======" + " 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 + # 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) + self.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] + 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.detach = 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.detach: + 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.detach: + 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.view_layer.objects.active = obj + obj.select_set(True) + 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: + 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 L868 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 L940\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 is 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.vector.x > maxx: + maxx = vert.vector.x + if vert.vector.x < minx: + 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.vector.x + else: + if point.vector.x > 0.0: + be = edj.unit * self.shrink * (point.vector.x + diffplus) + elif point.vector.x < 0.0: + be = edj.unit * self.shrink * (point.vector.x + diffminus) + elif point.vector.x == 0.0: + 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 L1037 HubMesh", "base is ", str(dir(base)) + "\n and meshname = " + meshname) + if hubtype is 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: otherwise >infinite< loop + print("\n***WARNING*** vefm_271.finalfill L1104 source == target empty mesh used") + target = mesh() + # PKHG_??? maybe renumverting and checking faces with >=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) |