# SPDX-License-Identifier: GPL-2.0-or-later # 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 # 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) return m # 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)