Dies ist eine alte Version des Dokuments!
18.03.2020
[18:58 Uhr] Das Skript ist momentan in der Lage, die einzelnen Zellwände entsprechend der Generierung im Raum zu erstellen und diese durch den neuen Code sauber darzustellen. Wie im Bild zu sehen kann nun ohne Probleme auf Wireframe-Modus umgestellt werden, ohne dass der PC abstürzt (wir verbuchen das als plus).
import bpy from random import random, randint from math import * import numpy as np import time from bpy_extras.mesh_utils import ngon_tessellate # KLASSEN class Sphere(object): pos = np.array([0,0,0]) radius = 0 epsilon = 0.001 def __init__(self, pos, radius): self.pos = pos self.radius = radius def punktInKugel(self, p): if (abstandPunkte(self.pos, p) < self.radius - self.epsilon): return True else: return False class Tetraeder(object): verts = [] faces = [] sp = np.array([0,0,0]) name = "tetraeder" umkugel = Sphere(np.array([0,0,0]), 0) def __init__(self, verts, name): self.name = name self.verts = verts self.faces = [(0,1,2),(1,2,3),(2,3,0),(3,0,1)] if (self.schwerpunkt()[0] != None): self.sp = self.schwerpunkt() self.umkugel = Sphere(self.sp,abstandPunkte(self.sp,self.verts[0])) else: self.sp = np.array([None,None,None]) def schwerpunkt(self): v1 = np.subtract(self.verts[1],self.verts[0]) v2 = np.subtract(self.verts[2],self.verts[0]) v3 = np.subtract(self.verts[3],self.verts[0]) sp = tetraSchwerpunkt(self.verts[0],v1,v2,v3) return sp def selfRender(self, ker, col, tetra): frei = True for m in range(0, len(ker)): if (self.umkugel.punktInKugel(ker[m]) == True): frei = False if (frei == True): generateObj("Tetraeder", t.verts, t.faces, (0,0,0), col) tetra.append(self) class Gerade(object): ov = (0,0,0) rv = (0,0,0) kreuzt = False kerne = [0,0] def __init__(self,ov,rv,kerne = [0,0]): self.ov = ov self.rv = rv self.kerne = kerne def punktAn(self,k): punkt = np.add(self.ov,(self.rv[0]*k,self.rv[1]*k,self.rv[2]*k)) return punkt # FUNKTIONEN def schnittTest(g1,g2): a = [[g2.rv[0],-g1.rv[0]],[g2.rv[1],-g1.rv[1]]] b = [[g1.ov[0]-g2.ov[0]],[g1.ov[1]-g2.ov[1]]] c = [[g2.rv[2],-g1.rv[2]],[g2.rv[1],-g1.rv[1]]] d = [[g1.ov[2]-g2.ov[2]],[g1.ov[1]-g2.ov[1]]] e = [[g2.rv[2],-g1.rv[2]],[g2.rv[0],-g1.rv[0]]] f = [[g1.ov[2]-g2.ov[2]],[g1.ov[0]-g2.ov[0]]] #print("Det :",np.linalg.det(a)) if (np.linalg.det(a) != 0): return np.linalg.solve(a,b)[0][0] elif (np.linalg.det(c) != 0): print(">> ERGEBNIS") return np.linalg.solve(c,d)[0][0] elif (np.linalg.det(e) != 0): print(">> SINBEGRE") return np.linalg.solve(e,f)[0][0] else: return None def schnittPunkt(g1,g2): z = schnittTest(g1,g2) if (z != None): return g2.punktAn(z) else: return np.array([None,None,None]) def dreieckSchwerpunkt(pos,a,b): g1 = Gerade(pos,a) g2 = Gerade(pos,b) c = kreuzProdukt(a,b) d = kreuzProdukt(a,c) e = kreuzProdukt(b,c) g3 = Gerade(g1.punktAn(.5), np.divide(d, 40)) g4 = Gerade(g2.punktAn(.5), np.divide(e, 40)) schnitt = schnittPunkt(g3,g4) return schnitt def tetraSchwerpunkt(pos, v1, v2, v3): #print("tetraSchwerpunkt") sp1 = dreieckSchwerpunkt(pos, v1, v2) sp2 = dreieckSchwerpunkt(pos, v1, v3) #print(pos, v1, v2, v3, sp1, sp2) if (sp1[0] != None and sp2[0] != None): g1 = Gerade(sp1, kreuzProdukt(v1, v2)) g2 = Gerade(sp2, kreuzProdukt(v1, v3)) schnitt = schnittPunkt(g1, g2) #print("Tetraschwerpunkt :",schnitt) return schnitt else: return np.array([None,None,None]) def abstandPunkte(p1, p2): a = sqrt(((p1[0]-p2[0])**2) + ((p1[1]-p2[1])**2) + ((p1[2]-p2[2])**2)) return a def zeichnePunkt(pos, name = "Punkt"): verts = [(0.1,0.1,0.1),(-0.1,0.1,0.1),(-0.1,-0.1,0.1),(0.1,-0.1,0.1) ,(0.1,0.1,-0.1),(-0.1,0.1,-0.1),(-0.1,-0.1,-0.1),(0.1,-0.1,-0.1)] faces = [(0,1,2,3),(4,5,6,7),(0,1,5,4),(1,2,6,5),(2,3,7,6),(3,0,4,7)] generateObj(name,verts,faces,pos) def kreuzProdukt(a,b): c = (a[1]*b[2]-a[2]*b[1] , a[2]*b[0]-a[0]*b[2] , a[0]*b[1]-a[1]*b[0]) return c def genKerne(anzahl, x_max, y_max, z_max): ker = [] for n in range(0, anzahl): x = randint(-x_max, x_max)*((random()/(1+random()))) y = randint(-y_max, y_max)*((random()/(1+random()))) z = randint(-z_max, z_max)*((random()/(1+random()))) if (len(ker) != 0): neu = True for m in range(0, len(ker)): if (x == ker[m][0] and y == ker[m][1] and z == ker[m][2]): neu = False if (neu == True): ker.append([x,y,z]) #zeichnePunkt(ker[n]) else: n = n-1 else: ker.append([x,y,z]) #zeichnePunkt(ker[n]) return ker # AB HIER ERSTELLUNG DER ZELLWÄNDE def radianBetweenVectors(v1, v2, n): # berechnet den Zwischenwinkel zweier Vektoren unter Beachtung eines Normalenwinkels # (später wird für n die Flächennormale der Zellwand eingesetzt, welche die Verbindung der # beiden Knotenpunkte ist, zwischen denen sich die Zellwand befindet). a = v1[0]*v2[0] + v1[1]*v2[1] + v1[2]*v2[2] b = v1[0]*v2[1]*n[2] + v2[0]*n[1]*v1[2] + n[0]*v1[1]*v2[2] - v1[2]*v2[1]*n[0] - v2[2]*n[1]*v1[0] - n[2]*v1[1]*v2[0] rad = np.arctan2(b, a) if (rad < 0): rad = (2*np.pi) +rad deg = rad*180/np.pi #print(">> v02", rad, deg, "\n") return deg def polySortListNEW(v_list, normal): # soll eine Liste von Punkten im Kreis herum links herum anordnen # falls es ein Dreieck ist, ist die Reihenfolge egal if (len(v_list) == 3): return v_list # Startvariablen werden gesetzt geordnet = [] start = v_list[0] aktu = start vv = np.subtract(v_list[0], v_list[1]) # Vergleichswinkel, der zufällig gewählt wird (zeigt immer aus dem Kreis raus) geordnet.append(start) while True: print(">>", aktu) # loop start values min_angle = 360 min_stelle = 0 # suche nach nächstem Punkt for v in range(0, len(v_list)): if (aktu[0] != v_list[v][0] or aktu[1] != v_list[v][1] or aktu[2] != v_list[v][2]): dir = np.subtract(v_list[v], aktu) deg = radianBetweenVectors(vv, dir, normal) #np.array([0,0,1])) if (deg < min_angle): min_angle = deg min_stelle = v geordnet.append(v_list[min_stelle]) vv = np.subtract(v_list[min_stelle], aktu) aktu = v_list[min_stelle] print(" >", aktu) if (aktu[0] == start[0] and aktu[1] == start[1] and aktu[2] == start[2]): break return geordnet def genPoly(liste, normal): # sortiert die gegebene Vertecie- Liste im Kreis herum und erstellt dann daraus eine saubere Fläche. geordnet = polySortListNEW(liste, normal) f = [] for i in range(0, len(geordnet)): f.append(i) facelist = [] facelist.append(f) generateObj("Zellwand", geordnet, facelist) def generateObj(name, verts, faces, loc = np.array([0,0,0]), col = ( 1.0, 1.0, 1.0, 1.0 )): # generiert ein Objekt mit den Übergebenen Parametern (Name, Eckpunkte, Seiten) mymesh = bpy.data.meshes.new(name) myobject = bpy.data.objects.new(name,mymesh) mymat = bpy.data.materials.new("Mesh_mat") mymat.diffuse_color = col mymesh.materials.append(mymat) myobject.location = loc bpy.context.collection.objects.link(myobject) mymesh.from_pydata(verts,[],faces) mymesh.update(calc_edges=True) # ZUORDNUNG DER WÄNDE ZU KOLLEKTIONEN def createCollection(name): col = bpy.data.collections.new(name) bpy.context.scene.collection.children.link(col) return col def linkToCollection(obj, col): col.objects.link(obj) # CODE col = createCollection('Delaunay') col = createCollection('Voronoi') x_max = 100 y_max = 100 z_max = 100 anzahlKerne = 25 del_col = (1.0, 0.0, 0.0, 1) tetra = [] ker = genKerne(anzahlKerne, x_max, y_max, z_max) #ker = [[0.5993280181021913, -0.4902980267777478, -0.49501317000167505], [-0.5435355585699094, -0.5797131146501373, 5.358814201657665], [0.3314129669573313, 0.06170948842793362, -0.7049448015853017], [3.1586485852091704, -3.5930246037937623, 0.4050221351432125], [2.3720126622528435, -0.1444049711022323, -0.8239078280684086], [2.737558129947007, 3.263776842262023, -4.292689464037283], [-2.3210411603088885, -3.869616290303755, 0.9243976566069152], [0.2993804076152454, -0.5199510038865012, 0.28987243247419864], [8.201747317589948, 0.6535831987234019, 3.6830815010667664], [-0.42647813347859526, -1.5289270142358882, -0.08034527427391898], [3.9377606048318166, -4.865271969576239, 1.2243584468694046], [0.806041393229286, 0.0, 0.07921029485036851], [0.6137190460585324, 1.535243528493868, -1.600612893884901], [1.1540597542694828, 3.1304758799406356, 2.411227237265708], [1.5083371322537722, 0.059994185768576916, -1.96459150755497], [0.00978110076824692, 0.5153349359712261, 7.447412675253049], [-2.162426719288622, -0.18758603781988797, 1.874187393501292], [-1.2861520576937593, 2.255844853091784, -1.9755975108667347], [4.448892338753108, -2.247797498228902, -2.316136846836149], [0.0, 0.0, 0.2953965724182989]] print("\n\n",ker,"\n\n") for i in range(0, len(ker)): for j in range(i+1, len(ker)): for k in range(j+1, len(ker)): for l in range(k+1, len(ker)): t = Tetraeder([ker[i], ker[j], ker[k], ker[l]],"Tetraeder") t.selfRender(ker, del_col, tetra) print(tetra, len(tetra)) count = 0 for u in range(0, len(ker)): for v in range(u+1, len(ker)): z_verts = [] count = 0 for w in range(0, len(tetra)): if ((ker[u] in tetra[w].verts) and (ker[v] in tetra[w].verts)): z_verts.append(tetra[w].sp) if (len(z_verts) > 2): normal = np.subtract(ker[u], ker[v]) genPoly(z_verts, normal)