|
|
|
import keras |
|
|
|
import numpy |
|
|
|
import gradio |
|
import pandas |
|
|
|
|
|
|
|
import glob |
|
import os |
|
import shutil |
|
import stat |
|
import math |
|
import platform |
|
import scipy.spatial |
|
|
|
|
|
from tensorflow.python.framework.ops import disable_eager_execution |
|
disable_eager_execution() |
|
|
|
|
|
|
|
import glob |
|
import os |
|
import shutil |
|
import stat |
|
import math |
|
import platform |
|
import scipy.spatial |
|
|
|
class Mesh: |
|
def __init__(self): |
|
|
|
self.np = 0 |
|
self.nf = 0 |
|
self.X = [] |
|
self.Y = [] |
|
self.Z = [] |
|
self.P = [] |
|
|
|
def combine_meshes(self, ob1, ob2): |
|
|
|
if ob1.nf < ob2.nf: |
|
coin_test = ob1.make_coin() |
|
coin_target = ob2.make_coin() |
|
else: |
|
coin_test = ob2.make_coin() |
|
coin_target = ob1.make_coin() |
|
|
|
deletion_list = [] |
|
for iF in range(numpy.size(coin_test[1, 1, :])): |
|
panel_test = coin_test[:, :, iF] |
|
for iFF in range(numpy.size(coin_target[1, 1, :])): |
|
panel_target = coin_target[:, :, iFF] |
|
if numpy.sum(panel_test == panel_target) == 12: |
|
coin_target = numpy.delete(coin_target, iFF, 2) |
|
deletion_list.append(iF) |
|
coin_test = numpy.delete(coin_test, deletion_list, 2) |
|
|
|
|
|
coin = numpy.concatenate((coin_test, coin_target), axis=2) |
|
self.np = numpy.size(coin[1, 1, :]) * 4 |
|
self.nf = numpy.size(coin[1, 1, :]) |
|
self.X = numpy.zeros(numpy.size(coin[1, 1, :]) * 4) |
|
self.Y = numpy.zeros(numpy.size(coin[1, 1, :]) * 4) |
|
self.Z = numpy.zeros(numpy.size(coin[1, 1, :]) * 4) |
|
self.P = numpy.zeros((numpy.size(coin[1, 1, :]), 4), dtype=int) |
|
|
|
iP = 0 |
|
for iF in range(numpy.size(coin[1, 1, :])): |
|
for iC in range(4): |
|
self.X[iP] = coin[0, iC, iF] |
|
self.Y[iP] = coin[1, iC, iF] |
|
self.Z[iP] = coin[2, iC, iF] |
|
iP += 1 |
|
self.P[iF, 0] = 1 + iF * 4 |
|
self.P[iF, 1] = 2 + iF * 4 |
|
self.P[iF, 2] = 3 + iF * 4 |
|
self.P[iF, 3] = 4 + iF * 4 |
|
|
|
def make_coin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
def delete_horizontal_panels(self): |
|
coin = self.make_coin() |
|
apex = numpy.min(self.Z) |
|
zLoc = numpy.zeros(4) |
|
deletion_list = [] |
|
|
|
|
|
for iP in range(self.nf): |
|
for iC in range(4): |
|
zLoc[iC] = coin[2, iC, iP] |
|
if numpy.abs(numpy.mean(zLoc) - zLoc[0]) < 0.001 and numpy.mean(zLoc) > apex: |
|
deletion_list.append(iP) |
|
|
|
|
|
coin = numpy.delete(coin, deletion_list, 2) |
|
|
|
|
|
self.np = numpy.size(coin[1, 1, :]) * 4 |
|
self.nf = numpy.size(coin[1, 1, :]) |
|
self.X = numpy.zeros(numpy.size(coin[1, 1, :]) * 4) |
|
self.Y = numpy.zeros(numpy.size(coin[1, 1, :]) * 4) |
|
self.Z = numpy.zeros(numpy.size(coin[1, 1, :]) * 4) |
|
self.P = numpy.zeros((numpy.size(coin[1, 1, :]), 4), dtype=int) |
|
|
|
iP = 0 |
|
for iF in range(numpy.size(coin[1, 1, :])): |
|
for iC in range(4): |
|
self.X[iP] = coin[0, iC, iF] |
|
self.Y[iP] = coin[1, iC, iF] |
|
self.Z[iP] = coin[2, iC, iF] |
|
iP += 1 |
|
self.P[iF, 0] = 1 + (iF) * 4 |
|
self.P[iF, 1] = 2 + (iF) * 4 |
|
self.P[iF, 2] = 3 + (iF) * 4 |
|
self.P[iF, 3] = 4 + (iF) * 4 |
|
|
|
|
|
|
|
|
|
def writeMesh(msh, filename): |
|
with open(filename, 'w') as f: |
|
f.write('{:d}\n'.format(msh.np)) |
|
f.write('{:d}\n'.format(msh.nf)) |
|
for iP in range(msh.np): |
|
f.write(' {:.7f} {:.7f} {:.7f}\n'.format(msh.X[iP], msh.Y[iP], msh.Z[iP])) |
|
for iF in range(msh.nf): |
|
f.write(' {:d} {:d} {:d} {:d}\n'.format(msh.P[iF, 0], msh.P[iF, 1], msh.P[iF, 2], msh.P[iF, 3])) |
|
return None |
|
|
|
|
|
|
|
class box: |
|
def __init__(self, length, width, height, cCor): |
|
self.length = length |
|
self.width = width |
|
self.height = height |
|
self.xC = cCor[0] |
|
self.yC = cCor[1] |
|
self.zC = cCor[2] |
|
self.name = 'box' |
|
self.panelize() |
|
self.translate(self.xC, self.yC, self.zC) |
|
|
|
def panelize(self): |
|
self.nf = 6 |
|
self.np = 8 |
|
self.X = numpy.array( |
|
[-self.length / 2.0, self.length / 2.0, -self.length / 2.0, self.length / 2.0, -self.length / 2.0, |
|
self.length / 2.0, -self.length / 2.0, self.length / 2.0]) |
|
self.Y = numpy.array([self.width / 2.0, self.width / 2.0, self.width / 2.0, self.width / 2.0, -self.width / 2.0, |
|
-self.width / 2.0, -self.width / 2.0, -self.width / 2.0]) |
|
self.Z = numpy.array( |
|
[-self.height / 2.0, -self.height / 2.0, self.height / 2.0, self.height / 2.0, -self.height / 2.0, |
|
-self.height / 2.0, self.height / 2.0, self.height / 2.0]) |
|
self.P = numpy.zeros([6, 4], dtype=int) |
|
self.P[0, :] = numpy.array([3, 4, 2, 1]) |
|
self.P[1, :] = numpy.array([4, 8, 6, 2]) |
|
self.P[2, :] = numpy.array([8, 7, 5, 6]) |
|
self.P[3, :] = numpy.array([7, 3, 1, 5]) |
|
self.P[4, :] = numpy.array([2, 6, 5, 1]) |
|
self.P[5, :] = numpy.array([8, 4, 3, 7]) |
|
|
|
self.trii = numpy.zeros([2 * self.nf, 3], dtype=int) |
|
iT = 0 |
|
for iTr in range(self.nf): |
|
self.trii[iT, :] = [self.P[iTr, 0] - 1, self.P[iTr, 1] - 1, self.P[iTr, 2] - 1] |
|
self.trii[iT + 1, :] = [self.P[iTr, 0] - 1, self.P[iTr, 2] - 1, self.P[iTr, 3] - 1] |
|
iT += 2 |
|
|
|
def translate(self, xT, yT, zT): |
|
self.X += xT |
|
self.Y += yT |
|
self.Z += zT |
|
|
|
def rotate(self, a1, a2, theta): |
|
R = numpy.zeros([3, 3]) |
|
|
|
u = a2[0] - a1[0] |
|
v = a2[1] - a1[1] |
|
w = a2[2] - a1[2] |
|
u = u / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
v = v / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
w = w / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
|
|
self.X -= a1[0] |
|
self.Y -= a1[1] |
|
self.Z -= a1[2] |
|
|
|
|
|
R[0, 0] = u ** 2 + numpy.cos(theta) * (1 - u ** 2) |
|
R[0, 1] = u * v * (1 - numpy.cos(theta)) - w * numpy.sin(theta) |
|
R[0, 2] = u * w * (1 - numpy.cos(theta)) + v * numpy.sin(theta) |
|
R[1, 0] = u * v * (1 - numpy.cos(theta)) + w * numpy.sin(theta) |
|
R[1, 1] = v ** 2 + numpy.cos(theta) * (1 - v ** 2) |
|
R[1, 2] = v * w * (1 - numpy.cos(theta)) - u * numpy.sin(theta) |
|
R[2, 0] = w * u * (1 - numpy.cos(theta)) - v * numpy.sin(theta) |
|
R[2, 1] = w * v * (1 - numpy.cos(theta)) + u * numpy.sin(theta) |
|
R[2, 2] = w ** 2 + numpy.cos(theta) * (1 - w ** 2) |
|
|
|
for iP in range(self.np): |
|
p1 = numpy.array([self.X[iP], self.Y[iP], self.Z[iP]]) |
|
p2 = numpy.dot(R, p1) |
|
self.X[iP] = p2[0] |
|
self.Y[iP] = p2[1] |
|
self.Z[iP] = p2[2] |
|
|
|
|
|
|
|
self.X += a1[0] |
|
self.Y += a1[1] |
|
self.Z += a1[2] |
|
|
|
def makeCoin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
|
|
|
|
|
|
class cone: |
|
def __init__(self, diameter, height, cCor): |
|
self.diameter = diameter |
|
self.height = height |
|
self.xC = cCor[0] |
|
self.yC = cCor[1] |
|
self.zC = cCor[2] |
|
self.name = 'cone' |
|
self.panelize() |
|
self.translate(self.xC, self.yC, self.zC) |
|
|
|
def panelize(self): |
|
Ntheta = 18 |
|
Nz = 3 |
|
theta = [xx * 2 * numpy.pi / (Ntheta - 1) for xx in range(Ntheta)] |
|
self.nf = 0 |
|
self.np = 0 |
|
r = [0, self.diameter / 2.0, 0] |
|
z = [0, 0, -self.height] |
|
self.X = [] |
|
self.Y = [] |
|
self.Z = [] |
|
self.P = numpy.zeros([(len(r) - 1) * (Ntheta - 1), 4], dtype=int) |
|
n = len(r) |
|
|
|
for iT in range(Ntheta): |
|
for iN in range(n): |
|
self.X.append(r[iN] * numpy.cos(theta[iT])) |
|
self.Y.append(r[iN] * numpy.sin(theta[iT])) |
|
self.Z.append(z[iN]) |
|
self.np += 1 |
|
|
|
iP = 0 |
|
for iN in range(1, n): |
|
for iT in range(1, Ntheta): |
|
self.P[iP, 0] = iN + n * (iT - 1) |
|
self.P[iP, 1] = iN + 1 + n * (iT - 1) |
|
self.P[iP, 2] = iN + 1 + n * iT |
|
self.P[iP, 3] = iN + n * iT |
|
self.nf += 1 |
|
iP += 1 |
|
|
|
self.X = numpy.array(self.X) |
|
self.Y = numpy.array(self.Y) |
|
self.Z = numpy.array(self.Z) |
|
|
|
self.trii = numpy.zeros([2 * self.nf, 3], dtype=int) |
|
iT = 0 |
|
for iTr in range(self.nf): |
|
self.trii[iT, :] = [self.P[iTr, 0] - 1, self.P[iTr, 1] - 1, self.P[iTr, 2] - 1] |
|
self.trii[iT + 1, :] = [self.P[iTr, 0] - 1, self.P[iTr, 2] - 1, self.P[iTr, 3] - 1] |
|
iT += 2 |
|
|
|
def translate(self, xT, yT, zT): |
|
self.X += xT |
|
self.Y += yT |
|
self.Z += zT |
|
|
|
def rotate(self, a1, a2, theta): |
|
R = numpy.zeros([3, 3]) |
|
|
|
u = a2[0] - a1[0] |
|
v = a2[1] - a1[1] |
|
w = a2[2] - a1[2] |
|
u = u / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
v = v / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
w = w / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
|
|
self.X -= a1[0] |
|
self.Y -= a1[1] |
|
self.Z -= a1[2] |
|
|
|
|
|
R[0, 0] = u ** 2 + numpy.cos(theta) * (1 - u ** 2) |
|
R[0, 1] = u * v * (1 - numpy.cos(theta)) - w * numpy.sin(theta) |
|
R[0, 2] = u * w * (1 - numpy.cos(theta)) + v * numpy.sin(theta) |
|
R[1, 0] = u * v * (1 - numpy.cos(theta)) + w * numpy.sin(theta) |
|
R[1, 1] = v ** 2 + numpy.cos(theta) * (1 - v ** 2) |
|
R[1, 2] = v * w * (1 - numpy.cos(theta)) - u * numpy.sin(theta) |
|
R[2, 0] = w * u * (1 - numpy.cos(theta)) - v * numpy.sin(theta) |
|
R[2, 1] = w * v * (1 - numpy.cos(theta)) + u * numpy.sin(theta) |
|
R[2, 2] = w ** 2 + numpy.cos(theta) * (1 - w ** 2) |
|
|
|
for iP in range(self.np): |
|
p1 = numpy.array([self.X[iP], self.Y[iP], self.Z[iP]]) |
|
p2 = numpy.dot(R, p1) |
|
self.X[iP] = p2[0] |
|
self.Y[iP] = p2[1] |
|
self.Z[iP] = p2[2] |
|
|
|
|
|
|
|
self.X += a1[0] |
|
self.Y += a1[1] |
|
self.Z += a1[2] |
|
|
|
def makeCoin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
|
|
|
|
class cylinder: |
|
def __init__(self, diameter, height, cCor): |
|
self.diameter = diameter |
|
self.height = height |
|
self.xC = cCor[0] |
|
self.yC = cCor[1] |
|
self.zC = cCor[2] |
|
self.name = 'cylinder' |
|
self.panelize() |
|
self.translate(self.xC, self.yC, self.zC) |
|
|
|
def panelize(self): |
|
Ntheta = 18 |
|
Nz = 3 |
|
theta = [xx * 2 * numpy.pi / (Ntheta - 1) for xx in range(Ntheta)] |
|
self.nf = 0 |
|
self.np = 0 |
|
r = [0, self.diameter / 2.0, self.diameter / 2.0, 0] |
|
z = [0, 0, -self.height, -self.height] |
|
self.X = [] |
|
self.Y = [] |
|
self.Z = [] |
|
self.P = numpy.zeros([(len(r) - 1) * (Ntheta - 1), 4], dtype=int) |
|
n = len(r) |
|
|
|
for iT in range(Ntheta): |
|
for iN in range(n): |
|
self.X.append(r[iN] * numpy.cos(theta[iT])) |
|
self.Y.append(r[iN] * numpy.sin(theta[iT])) |
|
self.Z.append(z[iN]) |
|
self.np += 1 |
|
|
|
iP = 0 |
|
for iN in range(1, n): |
|
for iT in range(1, Ntheta): |
|
self.P[iP, 0] = iN + n * (iT - 1) |
|
self.P[iP, 1] = iN + 1 + n * (iT - 1) |
|
self.P[iP, 2] = iN + 1 + n * iT |
|
self.P[iP, 3] = iN + n * iT |
|
self.nf += 1 |
|
iP += 1 |
|
|
|
self.X = numpy.array(self.X) |
|
self.Y = numpy.array(self.Y) |
|
self.Z = numpy.array(self.Z) |
|
|
|
self.trii = numpy.zeros([2 * self.nf, 3], dtype=int) |
|
iT = 0 |
|
for iTr in range(self.nf): |
|
self.trii[iT, :] = [self.P[iTr, 0] - 1, self.P[iTr, 1] - 1, self.P[iTr, 2] - 1] |
|
self.trii[iT + 1, :] = [self.P[iTr, 0] - 1, self.P[iTr, 2] - 1, self.P[iTr, 3] - 1] |
|
iT += 2 |
|
|
|
def translate(self, xT, yT, zT): |
|
self.X += xT |
|
self.Y += yT |
|
self.Z += zT |
|
|
|
def rotate(self, a1, a2, theta): |
|
R = numpy.zeros([3, 3]) |
|
|
|
u = a2[0] - a1[0] |
|
v = a2[1] - a1[1] |
|
w = a2[2] - a1[2] |
|
u = u / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
v = v / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
w = w / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
|
|
self.X -= a1[0] |
|
self.Y -= a1[1] |
|
self.Z -= a1[2] |
|
|
|
|
|
R[0, 0] = u ** 2 + numpy.cos(theta) * (1 - u ** 2) |
|
R[0, 1] = u * v * (1 - numpy.cos(theta)) - w * numpy.sin(theta) |
|
R[0, 2] = u * w * (1 - numpy.cos(theta)) + v * numpy.sin(theta) |
|
R[1, 0] = u * v * (1 - numpy.cos(theta)) + w * numpy.sin(theta) |
|
R[1, 1] = v ** 2 + numpy.cos(theta) * (1 - v ** 2) |
|
R[1, 2] = v * w * (1 - numpy.cos(theta)) - u * numpy.sin(theta) |
|
R[2, 0] = w * u * (1 - numpy.cos(theta)) - v * numpy.sin(theta) |
|
R[2, 1] = w * v * (1 - numpy.cos(theta)) + u * numpy.sin(theta) |
|
R[2, 2] = w ** 2 + numpy.cos(theta) * (1 - w ** 2) |
|
|
|
for iP in range(self.np): |
|
p1 = numpy.array([self.X[iP], self.Y[iP], self.Z[iP]]) |
|
p2 = numpy.dot(R, p1) |
|
self.X[iP] = p2[0] |
|
self.Y[iP] = p2[1] |
|
self.Z[iP] = p2[2] |
|
|
|
|
|
|
|
self.X += a1[0] |
|
self.Y += a1[1] |
|
self.Z += a1[2] |
|
|
|
def makeCoin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
|
|
|
|
|
|
class hemicylinder: |
|
def __init__(self, diameter, height, cCor): |
|
self.diameter = diameter |
|
self.height = height |
|
self.xC = cCor[0] |
|
self.yC = cCor[1] |
|
self.zC = cCor[2] |
|
self.name = 'hemicylinder' |
|
self.panelize() |
|
self.translate(self.xC, self.yC, self.zC) |
|
|
|
def panelize(self): |
|
Ntheta = 18 |
|
Nz = 3 |
|
theta = [xx * numpy.pi / (Ntheta - 1) - numpy.pi / 2.0 for xx in range(Ntheta)] |
|
self.nf = 0 |
|
self.np = 0 |
|
r = [0, self.diameter / 2.0, self.diameter / 2.0, 0] |
|
z = [self.height / 2.0, self.height / 2.0, -self.height / 2.0, -self.height / 2.0] |
|
self.X = [] |
|
self.Y = [] |
|
self.Z = [] |
|
self.P = numpy.zeros([(len(r) - 1) * (Ntheta - 1), 4], dtype=int) |
|
n = len(r) |
|
|
|
for iT in range(Ntheta): |
|
for iN in range(n): |
|
self.Z.append(-r[iN] * numpy.cos(theta[iT])) |
|
self.X.append(r[iN] * numpy.sin(theta[iT])) |
|
self.Y.append(z[iN]) |
|
self.np += 1 |
|
|
|
iP = 0 |
|
for iN in range(1, n): |
|
for iT in range(1, Ntheta): |
|
self.P[iP, 3] = iN + n * (iT - 1) |
|
self.P[iP, 2] = iN + 1 + n * (iT - 1) |
|
self.P[iP, 1] = iN + 1 + n * iT |
|
self.P[iP, 0] = iN + n * iT |
|
self.nf += 1 |
|
iP += 1 |
|
|
|
self.X = numpy.array(self.X) |
|
self.Y = numpy.array(self.Y) |
|
self.Z = numpy.array(self.Z) |
|
|
|
self.trii = numpy.zeros([2 * self.nf, 3], dtype=int) |
|
iT = 0 |
|
for iTr in range(self.nf): |
|
self.trii[iT, :] = [self.P[iTr, 0] - 1, self.P[iTr, 1] - 1, self.P[iTr, 2] - 1] |
|
self.trii[iT + 1, :] = [self.P[iTr, 0] - 1, self.P[iTr, 2] - 1, self.P[iTr, 3] - 1] |
|
iT += 2 |
|
|
|
def translate(self, xT, yT, zT): |
|
self.X += xT |
|
self.Y += yT |
|
self.Z += zT |
|
|
|
def rotate(self, a1, a2, theta): |
|
R = numpy.zeros([3, 3]) |
|
|
|
u = a2[0] - a1[0] |
|
v = a2[1] - a1[1] |
|
w = a2[2] - a1[2] |
|
u = u / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
v = v / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
w = w / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
|
|
self.X -= a1[0] |
|
self.Y -= a1[1] |
|
self.Z -= a1[2] |
|
|
|
|
|
R[0, 0] = u ** 2 + numpy.cos(theta) * (1 - u ** 2) |
|
R[0, 1] = u * v * (1 - numpy.cos(theta)) - w * numpy.sin(theta) |
|
R[0, 2] = u * w * (1 - numpy.cos(theta)) + v * numpy.sin(theta) |
|
R[1, 0] = u * v * (1 - numpy.cos(theta)) + w * numpy.sin(theta) |
|
R[1, 1] = v ** 2 + numpy.cos(theta) * (1 - v ** 2) |
|
R[1, 2] = v * w * (1 - numpy.cos(theta)) - u * numpy.sin(theta) |
|
R[2, 0] = w * u * (1 - numpy.cos(theta)) - v * numpy.sin(theta) |
|
R[2, 1] = w * v * (1 - numpy.cos(theta)) + u * numpy.sin(theta) |
|
R[2, 2] = w ** 2 + numpy.cos(theta) * (1 - w ** 2) |
|
|
|
for iP in range(self.np): |
|
p1 = numpy.array([self.X[iP], self.Y[iP], self.Z[iP]]) |
|
p2 = numpy.dot(R, p1) |
|
self.X[iP] = p2[0] |
|
self.Y[iP] = p2[1] |
|
self.Z[iP] = p2[2] |
|
|
|
|
|
|
|
self.X += a1[0] |
|
self.Y += a1[1] |
|
self.Z += a1[2] |
|
|
|
def makeCoin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
|
|
class sphere: |
|
def __init__(self, diameter, cCor): |
|
self.diameter = diameter |
|
self.xC = cCor[0] |
|
self.yC = cCor[1] |
|
self.zC = cCor[2] |
|
self.name = 'sphere' |
|
self.panelize() |
|
self.translate(self.xC, self.yC, self.zC) |
|
|
|
def panelize(self): |
|
Ntheta = 18 |
|
Nthetad2 = int(Ntheta / 2) |
|
Nz = 3 |
|
theta = [xx * 2 * numpy.pi / (Ntheta - 1) for xx in range(Ntheta)] |
|
phi = [xx * numpy.pi / (Ntheta / 2 - 1) for xx in range(Nthetad2)] |
|
self.nf = 0 |
|
self.np = 0 |
|
r = self.diameter / 2.0 |
|
self.X = [] |
|
self.Y = [] |
|
self.Z = [] |
|
self.P = numpy.zeros([(Ntheta - 1) * (Nthetad2 - 1), 4], dtype=int) |
|
|
|
for iT in range(Nthetad2): |
|
for iTT in range(Ntheta): |
|
self.X.append(r * numpy.cos(theta[iTT]) * numpy.sin(phi[iT])) |
|
self.Y.append(r * numpy.sin(theta[iTT]) * numpy.sin(phi[iT])) |
|
self.Z.append(r * numpy.cos(phi[iT])) |
|
self.np += 1 |
|
|
|
iP = 0 |
|
for iN in range(1, Ntheta): |
|
for iT in range(1, Nthetad2): |
|
self.P[iP, 3] = iN + Ntheta * (iT - 1) |
|
self.P[iP, 2] = iN + 1 + Ntheta * (iT - 1) |
|
self.P[iP, 1] = iN + 1 + Ntheta * iT |
|
self.P[iP, 0] = iN + Ntheta * iT |
|
self.nf += 1 |
|
iP += 1 |
|
self.X = numpy.array(self.X) |
|
self.Y = numpy.array(self.Y) |
|
self.Z = numpy.array(self.Z) |
|
|
|
self.trii = numpy.zeros([2 * self.nf, 3], dtype=int) |
|
iT = 0 |
|
for iTr in range(self.nf): |
|
self.trii[iT, :] = [self.P[iTr, 0] - 1, self.P[iTr, 1] - 1, self.P[iTr, 2] - 1] |
|
self.trii[iT + 1, :] = [self.P[iTr, 0] - 1, self.P[iTr, 2] - 1, self.P[iTr, 3] - 1] |
|
iT += 2 |
|
|
|
def translate(self, xT, yT, zT): |
|
self.X += xT |
|
self.Y += yT |
|
self.Z += zT |
|
|
|
def rotate(self, a1, a2, theta): |
|
R = numpy.zeros([3, 3]) |
|
|
|
u = a2[0] - a1[0] |
|
v = a2[1] - a1[1] |
|
w = a2[2] - a1[2] |
|
u = u / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
v = v / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
w = w / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
|
|
self.X -= a1[0] |
|
self.Y -= a1[1] |
|
self.Z -= a1[2] |
|
|
|
|
|
R[0, 0] = u ** 2 + numpy.cos(theta) * (1 - u ** 2) |
|
R[0, 1] = u * v * (1 - numpy.cos(theta)) - w * numpy.sin(theta) |
|
R[0, 2] = u * w * (1 - numpy.cos(theta)) + v * numpy.sin(theta) |
|
R[1, 0] = u * v * (1 - numpy.cos(theta)) + w * numpy.sin(theta) |
|
R[1, 1] = v ** 2 + numpy.cos(theta) * (1 - v ** 2) |
|
R[1, 2] = v * w * (1 - numpy.cos(theta)) - u * numpy.sin(theta) |
|
R[2, 0] = w * u * (1 - numpy.cos(theta)) - v * numpy.sin(theta) |
|
R[2, 1] = w * v * (1 - numpy.cos(theta)) + u * numpy.sin(theta) |
|
R[2, 2] = w ** 2 + numpy.cos(theta) * (1 - w ** 2) |
|
|
|
for iP in range(self.np): |
|
p1 = numpy.array([self.X[iP], self.Y[iP], self.Z[iP]]) |
|
p2 = numpy.dot(R, p1) |
|
self.X[iP] = p2[0] |
|
self.Y[iP] = p2[1] |
|
self.Z[iP] = p2[2] |
|
|
|
|
|
|
|
self.X += a1[0] |
|
self.Y += a1[1] |
|
self.Z += a1[2] |
|
|
|
def makeCoin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
|
|
|
|
|
|
|
|
class hemisphere: |
|
def __init__(self, diameter, cCor): |
|
self.diameter = diameter |
|
self.xC = cCor[0] |
|
self.yC = cCor[1] |
|
self.zC = cCor[2] |
|
self.name = 'hemisphere' |
|
self.panelize() |
|
self.translate(self.xC, self.yC, self.zC) |
|
|
|
def panelize(self): |
|
Ntheta = 18 |
|
theta = [xx * 2 * numpy.pi / (Ntheta - 1) for xx in range(Ntheta)] |
|
phi = [xx * numpy.pi / 2.0 / (Ntheta / 2 - 1) for xx in range(Ntheta / 2)] |
|
self.nf = 0 |
|
self.np = 0 |
|
r = self.diameter / 2.0 |
|
self.X = [] |
|
self.Y = [] |
|
self.Z = [] |
|
self.P = numpy.zeros([(Ntheta - 1) * (Ntheta / 2 - 1), 4], dtype=int) |
|
|
|
for iT in range(Ntheta / 2): |
|
for iTT in range(Ntheta): |
|
self.X.append(r * numpy.cos(theta[iTT]) * numpy.sin(phi[iT])) |
|
self.Y.append(r * numpy.sin(theta[iTT]) * numpy.sin(phi[iT])) |
|
self.Z.append(-r * numpy.cos(phi[iT])) |
|
self.np += 1 |
|
|
|
iP = 0 |
|
for iN in range(1, Ntheta): |
|
for iT in range(1, Ntheta / 2): |
|
self.P[iP, 0] = iN + Ntheta * (iT - 1) |
|
self.P[iP, 1] = iN + 1 + Ntheta * (iT - 1) |
|
self.P[iP, 2] = iN + 1 + Ntheta * iT |
|
self.P[iP, 3] = iN + Ntheta * iT |
|
self.nf += 1 |
|
iP += 1 |
|
|
|
self.X = numpy.array(self.X) |
|
self.Y = numpy.array(self.Y) |
|
self.Z = numpy.array(self.Z) |
|
|
|
self.trii = numpy.zeros([2 * self.nf, 3], dtype=int) |
|
iT = 0 |
|
for iTr in range(self.nf): |
|
self.trii[iT, :] = [self.P[iTr, 0] - 1, self.P[iTr, 1] - 1, self.P[iTr, 2] - 1] |
|
self.trii[iT + 1, :] = [self.P[iTr, 0] - 1, self.P[iTr, 2] - 1, self.P[iTr, 3] - 1] |
|
iT += 2 |
|
|
|
def translate(self, xT, yT, zT): |
|
self.X += xT |
|
self.Y += yT |
|
self.Z += zT |
|
|
|
def rotate(self, a1, a2, theta): |
|
R = numpy.zeros([3, 3]) |
|
|
|
u = a2[0] - a1[0] |
|
v = a2[1] - a1[1] |
|
w = a2[2] - a1[2] |
|
u = u / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
v = v / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
w = w / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
|
|
self.X -= a1[0] |
|
self.Y -= a1[1] |
|
self.Z -= a1[2] |
|
|
|
|
|
R[0, 0] = u ** 2 + numpy.cos(theta) * (1 - u ** 2) |
|
R[0, 1] = u * v * (1 - numpy.cos(theta)) - w * numpy.sin(theta) |
|
R[0, 2] = u * w * (1 - numpy.cos(theta)) + v * numpy.sin(theta) |
|
R[1, 0] = u * v * (1 - numpy.cos(theta)) + w * numpy.sin(theta) |
|
R[1, 1] = v ** 2 + numpy.cos(theta) * (1 - v ** 2) |
|
R[1, 2] = v * w * (1 - numpy.cos(theta)) - u * numpy.sin(theta) |
|
R[2, 0] = w * u * (1 - numpy.cos(theta)) - v * numpy.sin(theta) |
|
R[2, 1] = w * v * (1 - numpy.cos(theta)) + u * numpy.sin(theta) |
|
R[2, 2] = w ** 2 + numpy.cos(theta) * (1 - w ** 2) |
|
|
|
for iP in range(self.np): |
|
p1 = numpy.array([self.X[iP], self.Y[iP], self.Z[iP]]) |
|
p2 = numpy.dot(R, p1) |
|
self.X[iP] = p2[0] |
|
self.Y[iP] = p2[1] |
|
self.Z[iP] = p2[2] |
|
|
|
|
|
|
|
self.X += a1[0] |
|
self.Y += a1[1] |
|
self.Z += a1[2] |
|
|
|
def makeCoin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
|
|
|
|
|
|
class pyramid: |
|
def __init__(self, length, width, height, cCor): |
|
self.length = length |
|
self.width = width |
|
self.height = height |
|
self.xC = cCor[0] |
|
self.yC = cCor[1] |
|
self.zC = cCor[2] |
|
self.name = 'pyramid' |
|
self.panelize() |
|
self.translate(self.xC, self.yC, self.zC) |
|
|
|
def panelize(self): |
|
self.nf = 6 |
|
self.np = 8 |
|
self.X = numpy.array( |
|
[0.0, 0.0, -self.length / 2.0, self.length / 2.0, 0.0, 0.0, -self.length / 2.0, self.length / 2.0]) |
|
self.Y = numpy.array( |
|
[0.0, 0.0, self.width / 2.0, self.width / 2.0, 0.0, 0.0, -self.width / 2.0, -self.width / 2.0]) |
|
self.Z = numpy.array([-self.height, -self.height, 0.0, 0.0, -self.height, -self.height, 0.0, 0.0]) |
|
self.P = numpy.zeros([6, 4], dtype=int) |
|
self.P[0, :] = numpy.array([3, 4, 2, 1]) |
|
self.P[1, :] = numpy.array([4, 8, 6, 2]) |
|
self.P[2, :] = numpy.array([8, 7, 5, 6]) |
|
self.P[3, :] = numpy.array([7, 3, 1, 5]) |
|
self.P[4, :] = numpy.array([5, 6, 5, 1]) |
|
self.P[5, :] = numpy.array([8, 4, 3, 7]) |
|
|
|
self.trii = numpy.zeros([2 * self.nf, 3], dtype=int) |
|
iT = 0 |
|
for iTr in range(self.nf): |
|
self.trii[iT, :] = [self.P[iTr, 0] - 1, self.P[iTr, 1] - 1, self.P[iTr, 2] - 1] |
|
self.trii[iT + 1, :] = [self.P[iTr, 0] - 1, self.P[iTr, 2] - 1, self.P[iTr, 3] - 1] |
|
iT += 2 |
|
|
|
def translate(self, xT, yT, zT): |
|
self.X += xT |
|
self.Y += yT |
|
self.Z += zT |
|
|
|
def rotate(self, a1, a2, theta): |
|
R = numpy.zeros([3, 3]) |
|
|
|
u = a2[0] - a1[0] |
|
v = a2[1] - a1[1] |
|
w = a2[2] - a1[2] |
|
u = u / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
v = v / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
w = w / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
|
|
self.X -= a1[0] |
|
self.Y -= a1[1] |
|
self.Z -= a1[2] |
|
|
|
|
|
R[0, 0] = u ** 2 + numpy.cos(theta) * (1 - u ** 2) |
|
R[0, 1] = u * v * (1 - numpy.cos(theta)) - w * numpy.sin(theta) |
|
R[0, 2] = u * w * (1 - numpy.cos(theta)) + v * numpy.sin(theta) |
|
R[1, 0] = u * v * (1 - numpy.cos(theta)) + w * numpy.sin(theta) |
|
R[1, 1] = v ** 2 + numpy.cos(theta) * (1 - v ** 2) |
|
R[1, 2] = v * w * (1 - numpy.cos(theta)) - u * numpy.sin(theta) |
|
R[2, 0] = w * u * (1 - numpy.cos(theta)) - v * numpy.sin(theta) |
|
R[2, 1] = w * v * (1 - numpy.cos(theta)) + u * numpy.sin(theta) |
|
R[2, 2] = w ** 2 + numpy.cos(theta) * (1 - w ** 2) |
|
|
|
for iP in range(self.np): |
|
p1 = numpy.array([self.X[iP], self.Y[iP], self.Z[iP]]) |
|
p2 = numpy.dot(R, p1) |
|
self.X[iP] = p2[0] |
|
self.Y[iP] = p2[1] |
|
self.Z[iP] = p2[2] |
|
|
|
|
|
|
|
self.X += a1[0] |
|
self.Y += a1[1] |
|
self.Z += a1[2] |
|
|
|
def makeCoin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
|
|
|
|
|
|
|
|
class wedge: |
|
def __init__(self, length, width, height, cCor): |
|
self.length = length |
|
self.width = width |
|
self.height = height |
|
self.xC = cCor[0] |
|
self.yC = cCor[1] |
|
self.zC = cCor[2] |
|
self.name = 'wedge' |
|
self.panelize() |
|
self.translate(self.xC, self.yC, self.zC) |
|
|
|
def panelize(self): |
|
self.nf = 6 |
|
self.np = 8 |
|
self.X = numpy.array( |
|
[0.0, 0.0, -self.length / 2.0, self.length / 2.0, 0.0, 0.0, -self.length / 2.0, self.length / 2.0]) |
|
self.Y = numpy.array([self.width / 2.0, self.width / 2.0, self.width / 2.0, self.width / 2.0, -self.width / 2.0, |
|
-self.width / 2.0, -self.width / 2.0, -self.width / 2.0]) |
|
self.Z = numpy.array([-self.height, -self.height, 0.0, 0.0, -self.height, -self.height, 0.0, 0.0]) |
|
self.P = numpy.zeros([6, 4], dtype=int) |
|
self.P[0, :] = numpy.array([3, 4, 2, 1]) |
|
self.P[1, :] = numpy.array([4, 8, 6, 2]) |
|
self.P[2, :] = numpy.array([8, 7, 5, 6]) |
|
self.P[3, :] = numpy.array([7, 3, 1, 5]) |
|
self.P[4, :] = numpy.array([2, 6, 5, 1]) |
|
self.P[5, :] = numpy.array([8, 4, 3, 7]) |
|
|
|
self.trii = numpy.zeros([2 * self.nf, 3], dtype=int) |
|
iT = 0 |
|
for iTr in range(self.nf): |
|
self.trii[iT, :] = [self.P[iTr, 0] - 1, self.P[iTr, 1] - 1, self.P[iTr, 2] - 1] |
|
self.trii[iT + 1, :] = [self.P[iTr, 0] - 1, self.P[iTr, 2] - 1, self.P[iTr, 3] - 1] |
|
iT += 2 |
|
|
|
def translate(self, xT, yT, zT): |
|
self.X += xT |
|
self.Y += yT |
|
self.Z += zT |
|
|
|
def rotate(self, a1, a2, theta): |
|
R = numpy.zeros([3, 3]) |
|
|
|
u = a2[0] - a1[0] |
|
v = a2[1] - a1[1] |
|
w = a2[2] - a1[2] |
|
u = u / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
v = v / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
w = w / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
|
|
self.X -= a1[0] |
|
self.Y -= a1[1] |
|
self.Z -= a1[2] |
|
|
|
|
|
R[0, 0] = u ** 2 + numpy.cos(theta) * (1 - u ** 2) |
|
R[0, 1] = u * v * (1 - numpy.cos(theta)) - w * numpy.sin(theta) |
|
R[0, 2] = u * w * (1 - numpy.cos(theta)) + v * numpy.sin(theta) |
|
R[1, 0] = u * v * (1 - numpy.cos(theta)) + w * numpy.sin(theta) |
|
R[1, 1] = v ** 2 + numpy.cos(theta) * (1 - v ** 2) |
|
R[1, 2] = v * w * (1 - numpy.cos(theta)) - u * numpy.sin(theta) |
|
R[2, 0] = w * u * (1 - numpy.cos(theta)) - v * numpy.sin(theta) |
|
R[2, 1] = w * v * (1 - numpy.cos(theta)) + u * numpy.sin(theta) |
|
R[2, 2] = w ** 2 + numpy.cos(theta) * (1 - w ** 2) |
|
|
|
for iP in range(self.np): |
|
p1 = numpy.array([self.X[iP], self.Y[iP], self.Z[iP]]) |
|
p2 = numpy.dot(R, p1) |
|
self.X[iP] = p2[0] |
|
self.Y[iP] = p2[1] |
|
self.Z[iP] = p2[2] |
|
|
|
|
|
|
|
self.X += a1[0] |
|
self.Y += a1[1] |
|
self.Z += a1[2] |
|
|
|
def makeCoin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
|
|
|
|
|
|
|
|
class torus: |
|
def __init__(self, diamOut, diamIn, cCor): |
|
self.diamOut = diamOut |
|
self.diamIn = diamIn |
|
self.xC = cCor[0] |
|
self.yC = cCor[1] |
|
self.zC = cCor[2] |
|
self.name = 'torus' |
|
self.panelize() |
|
self.translate(self.xC, self.yC, self.zC) |
|
|
|
def panelize(self): |
|
Ntheta = 18 |
|
Nphi = 18 |
|
theta = [xx * 2 * numpy.pi / (Ntheta - 1) for xx in range(Ntheta)] |
|
phi = [xx * 2 * numpy.pi / (Nphi - 1) for xx in range(Nphi)] |
|
self.nf = 0 |
|
self.np = 0 |
|
self.X = [] |
|
self.Y = [] |
|
self.Z = [] |
|
R = self.diamOut / 2.0 |
|
r = self.diamIn / 2.0 |
|
|
|
for iT in range(Ntheta): |
|
for iP in range(Nphi): |
|
self.X.append((R + r * numpy.cos(theta[iT])) * numpy.cos(phi[iP])) |
|
self.Y.append((R + r * numpy.cos(theta[iT])) * numpy.sin(phi[iP])) |
|
self.Z.append(r * numpy.sin(theta[iT])) |
|
self.np += 1 |
|
|
|
self.nf = (Ntheta - 1) * (Nphi - 1) |
|
self.P = numpy.zeros([self.nf, 4], dtype=int) |
|
iPan = 0 |
|
for iT in range(Ntheta - 1): |
|
for iP in range(Nphi - 1): |
|
self.P[iPan, 0] = iP + iT * Nphi + 1 |
|
self.P[iPan, 1] = iP + 1 + iT * Nphi + 1 |
|
self.P[iPan, 2] = iP + 1 + Ntheta + iT * Nphi + 1 |
|
self.P[iPan, 3] = iP + Ntheta + iT * Nphi + 1 |
|
iPan += 1 |
|
|
|
self.X = numpy.array(self.X) |
|
self.Y = numpy.array(self.Y) |
|
self.Z = numpy.array(self.Z) |
|
|
|
self.trii = numpy.zeros([2 * self.nf, 3], dtype=int) |
|
iT = 0 |
|
for iTr in range(self.nf): |
|
self.trii[iT, :] = [self.P[iTr, 0] - 1, self.P[iTr, 1] - 1, self.P[iTr, 2] - 1] |
|
self.trii[iT + 1, :] = [self.P[iTr, 0] - 1, self.P[iTr, 2] - 1, self.P[iTr, 3] - 1] |
|
iT += 2 |
|
|
|
def translate(self, xT, yT, zT): |
|
self.X += xT |
|
self.Y += yT |
|
self.Z += zT |
|
|
|
def rotate(self, a1, a2, theta): |
|
R = numpy.zeros([3, 3]) |
|
|
|
u = a2[0] - a1[0] |
|
v = a2[1] - a1[1] |
|
w = a2[2] - a1[2] |
|
u = u / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
v = v / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
w = w / numpy.sqrt(u ** 2 + v ** 2 + w ** 2) |
|
|
|
self.X -= a1[0] |
|
self.Y -= a1[1] |
|
self.Z -= a1[2] |
|
|
|
|
|
R[0, 0] = u ** 2 + numpy.cos(theta) * (1 - u ** 2) |
|
R[0, 1] = u * v * (1 - numpy.cos(theta)) - w * numpy.sin(theta) |
|
R[0, 2] = u * w * (1 - numpy.cos(theta)) + v * numpy.sin(theta) |
|
R[1, 0] = u * v * (1 - numpy.cos(theta)) + w * numpy.sin(theta) |
|
R[1, 1] = v ** 2 + numpy.cos(theta) * (1 - v ** 2) |
|
R[1, 2] = v * w * (1 - numpy.cos(theta)) - u * numpy.sin(theta) |
|
R[2, 0] = w * u * (1 - numpy.cos(theta)) - v * numpy.sin(theta) |
|
R[2, 1] = w * v * (1 - numpy.cos(theta)) + u * numpy.sin(theta) |
|
R[2, 2] = w ** 2 + numpy.cos(theta) * (1 - w ** 2) |
|
|
|
for iP in range(self.np): |
|
p1 = numpy.array([self.X[iP], self.Y[iP], self.Z[iP]]) |
|
p2 = numpy.dot(R, p1) |
|
self.X[iP] = p2[0] |
|
self.Y[iP] = p2[1] |
|
self.Z[iP] = p2[2] |
|
|
|
|
|
|
|
self.X += a1[0] |
|
self.Y += a1[1] |
|
self.Z += a1[2] |
|
|
|
def makeCoin(self): |
|
coin = numpy.zeros((3, 4, self.nf)) |
|
for iF in range(self.nf): |
|
for iC in range(4): |
|
coin[0, iC, iF] = self.X[self.P[iF, iC] - 1] |
|
coin[1, iC, iF] = self.Y[self.P[iF, iC] - 1] |
|
coin[2, iC, iF] = self.Z[self.P[iF, iC] - 1] |
|
return coin |
|
|
|
def make_voxels_without_figure(shape, length, height, width, diameter): |
|
pos = [0, 0, 0] |
|
if shape == "box": |
|
mesh = box(length, width, height, pos) |
|
elif shape == "cone": |
|
mesh = cone(diameter, height, pos) |
|
elif shape == "cylinder": |
|
mesh = cylinder(diameter, height, pos) |
|
elif shape == "sphere": |
|
mesh = sphere(diameter, pos) |
|
elif shape == "wedge": |
|
mesh = wedge(length, width, height, pos) |
|
|
|
hull_points = numpy.array([mesh.X.tolist(), mesh.Y.tolist(), mesh.Z.tolist()]).T |
|
|
|
|
|
G = 32 |
|
ex = 5 - 5 / G |
|
x, y, z = numpy.meshgrid(numpy.linspace(-ex, ex, G), |
|
numpy.linspace(-ex, ex, G), |
|
numpy.linspace(-(9.5 - 5 / G), 0.5 - 5 / G, G)) |
|
test_points = numpy.vstack((x.ravel(), y.ravel(), z.ravel())).T |
|
|
|
hull = scipy.spatial.Delaunay(hull_points) |
|
within = hull.find_simplex(test_points) >= 0 |
|
|
|
return within*1.0 |
|
|
|
|
|
def make_voxels(shape, length, height, width, diameter): |
|
return plotly_fig(make_voxels_without_figure(shape, length, height, width, diameter)) |
|
|
|
|
|
def load_data(): |
|
|
|
curves = numpy.load('data_curves.npz')['curves'] |
|
geometry = numpy.load('data_geometry.npz')['geometry'] |
|
constants = numpy.load('constants.npz') |
|
S = constants['S'] |
|
N = constants['N'] |
|
D = constants['D'] |
|
F = constants['F'] |
|
G = constants['G'] |
|
|
|
|
|
new_curves = numpy.zeros((S*N, D * F)) |
|
for i, curveset in enumerate(curves): |
|
new_curves[i, :] = curveset.T.flatten() / 1000000 |
|
|
|
new_geometry = numpy.zeros((S*N, G * G * G)) |
|
for i, geometryset in enumerate(geometry): |
|
new_geometry[i, :] = geometryset.T.flatten() |
|
|
|
|
|
return curves, geometry, S, N, D, F, G, new_curves, new_geometry |
|
|
|
curves, geometry, S, N, D, F, G, new_curves, new_geometry = load_data() |
|
|
|
class Network(object): |
|
|
|
def __init__(self, structure, weights): |
|
|
|
self.curves = curves |
|
self.new_curves = new_curves |
|
self.geometry = geometry |
|
self.new_geometry = new_geometry |
|
self.S = S |
|
self.N = N |
|
self.D = D |
|
self.F = F |
|
self.G = G |
|
|
|
|
|
with open(structure, 'r') as file: |
|
self.network = keras.models.model_from_json(file.read()) |
|
self.network.load_weights(weights) |
|
|
|
def analysis(self, idx=None): |
|
print(idx) |
|
|
|
if idx is None: |
|
idx = numpy.random.randint(1, self.S * self.N) |
|
else: |
|
idx = int(idx) |
|
|
|
|
|
data_input = self.new_geometry[idx:(idx+1), :] |
|
other_data_input = data_input.reshape((self.G, self.G, self.G), order='F') |
|
|
|
|
|
print(data_input.shape) |
|
predicted_output = self.network.predict(data_input) |
|
true_output = self.new_curves[idx].reshape((3, self.F)) |
|
predicted_output = predicted_output.reshape((3, self.F)) |
|
|
|
f = numpy.linspace(0.05, 2.0, 64) |
|
fd = pandas.DataFrame(f).rename(columns={0: "Frequency"}) |
|
df_pred = pandas.DataFrame(predicted_output.transpose()).rename(columns={0: "Surge", 1: "Heave", 2: "Pitch"}) |
|
df_true = pandas.DataFrame(true_output.transpose()).rename(columns={0: "Surge", 1: "Heave", 2: "Pitch"}) |
|
|
|
|
|
return pandas.concat([fd, df_pred], axis=1), pandas.concat([fd, df_true], axis=1) |
|
|
|
|
|
def analysis_from_geometry(self, geometry): |
|
|
|
print(geometry.flatten().shape) |
|
predicted_output = self.network.predict(geometry.flatten()) |
|
predicted_output = predicted_output.reshape((3, self.F)) |
|
|
|
f = numpy.linspace(0.05, 2.0, 64) |
|
fd = pandas.DataFrame(f).rename(columns={0: "Frequency"}) |
|
df_pred = pandas.DataFrame(predicted_output.transpose()).rename(columns={0: "Surge", 1: "Heave", 2: "Pitch"}) |
|
|
|
return pandas.concat([fd, df_pred], axis=1), pandas.DataFrame() |
|
|
|
|
|
def synthesis(self, idx=None): |
|
print(idx) |
|
|
|
if idx is None: |
|
idx = numpy.random.randint(1, self.S * self.N) |
|
else: |
|
idx = int(idx) |
|
|
|
|
|
data_input = self.new_curves[idx:(idx+1), :] |
|
other_data_input = data_input.reshape((3, self.F)) |
|
|
|
|
|
predicted_output = self.network.predict(data_input) |
|
true_output = self.new_geometry[idx].reshape((self.G, self.G, self.G), order='F') |
|
predicted_output = predicted_output.reshape((self.G, self.G, self.G), order='F') |
|
|
|
|
|
return predicted_output, true_output |
|
|
|
|
|
def synthesis_from_spectrum(self, other_data_input): |
|
|
|
data_input = other_data_input.reshape((1, 3*self.F)) |
|
|
|
|
|
predicted_output = self.network.predict(data_input) |
|
predicted_output = predicted_output.reshape((self.G, self.G, self.G), order='F') |
|
|
|
|
|
return predicted_output |
|
|
|
def get_geometry(self, idx=None): |
|
|
|
if idx is None: |
|
idx = numpy.random.randint(1, self.S * self.N) |
|
else: |
|
idx = int(idx) |
|
|
|
idx = int(idx) |
|
|
|
|
|
data_input = self.new_geometry[idx:(idx+1), :] |
|
other_data_input = data_input.reshape((self.G, self.G, self.G), order='F') |
|
|
|
|
|
return other_data_input |
|
|
|
|
|
def get_performance(self, idx=None): |
|
|
|
if idx is None: |
|
idx = numpy.random.randint(1, self.S * self.N) |
|
else: |
|
idx = int(idx) |
|
|
|
idx = int(idx) |
|
|
|
|
|
data_input = self.new_curves[idx:(idx+1), :] |
|
other_data_input = data_input.reshape((3, self.F)) |
|
|
|
f = numpy.linspace(0.05, 2.0, 64) |
|
fd = pandas.DataFrame(f).rename(columns={0: "Frequency"}) |
|
df_pred = pandas.DataFrame(other_data_input.transpose()).rename(columns={0: "Surge", 1: "Heave", 2: "Pitch"}) |
|
table = pandas.concat([fd, df_pred], axis=1) |
|
|
|
return table |
|
|
|
|
|
|
|
import plotly.graph_objects as go |
|
|
|
|
|
def plotly_fig(values): |
|
X, Y, Z = numpy.mgrid[0:1:32j, 0:1:32j, 0:1:32j] |
|
fig = go.Figure(data=go.Volume( |
|
x=X.flatten(), |
|
y=Y.flatten(), |
|
z=Z.flatten(), |
|
value=values.flatten(), |
|
isomin=-0.1, |
|
isomax=0.8, |
|
opacity=0.1, |
|
surface_count=21, |
|
colorscale='haline' |
|
)) |
|
return fig |
|
|
|
value_net = Network("16forward_structure.json", "16forward_weights.h5") |
|
|
|
def performance(index): |
|
return value_net.get_performance(index) |
|
|
|
def geometry(index): |
|
values = value_net.get_geometry(index) |
|
return plotly_fig(values) |
|
|
|
def simple_analysis(index, choice, shape, length, width, height, diameter): |
|
forward_net = Network("16forward_structure.json", "16forward_weights.h5") |
|
if choice == "Construct Shape from Parameters": |
|
return forward_net.analysis_from_geometry(make_voxels_without_figure(shape, length, height, width, diameter)) |
|
elif choice == "Pick Shape from Dataset": |
|
return forward_net.analysis(index) |
|
|
|
|
|
def simple_synthesis(index): |
|
inverse_net = Network("16inverse_structure.json", "16inverse_weights.h5") |
|
pred, true = inverse_net.synthesis(index) |
|
return plotly_fig(pred), plotly_fig(true) |
|
|
|
def synthesis_from_spectrum(df): |
|
inverse_net = Network("16inverse_structure.json", "16inverse_weights.h5") |
|
pred = inverse_net.synthesis_from_spectrum(df.to_numpy()[:, 1:]) |
|
return plotly_fig(pred) |
|
|
|
|
|
|
|
|
|
def change_textbox(choice, length, height, width, diameter): |
|
fig = make_voxels(choice, length, height, width, diameter) |
|
if choice == "cylinder": |
|
return [gradio.Slider.update(visible=True), gradio.Slider.update(visible=False), gradio.Slider.update(visible=True), gradio.Slider.update(visible=False), gradio.Plot.update(fig)] |
|
elif choice == "sphere": |
|
return [gradio.Slider.update(visible=False), gradio.Slider.update(visible=False), gradio.Slider.update(visible=True), gradio.Slider.update(visible=False), gradio.Plot.update(fig)] |
|
elif choice == "box": |
|
return [gradio.Slider.update(visible=True), gradio.Slider.update(visible=True), gradio.Slider.update(visible=False), gradio.Slider.update(visible=True), gradio.Plot.update(fig)] |
|
elif choice == "wedge": |
|
return [gradio.Slider.update(visible=True), gradio.Slider.update(visible=True), gradio.Slider.update(visible=False), gradio.Slider.update(visible=True), gradio.Plot.update(fig)] |
|
elif choice == "cone": |
|
return [gradio.Slider.update(visible=True), gradio.Slider.update(visible=False), gradio.Slider.update(visible=True), gradio.Slider.update(visible=False), gradio.Plot.update(fig)] |
|
|
|
|
|
import random |
|
|
|
def randomize_analysis(choice): |
|
if choice == "Construct Shape from Parameters": |
|
length = random.uniform(3.0, 10.0) |
|
height = random.uniform(3.0, 10.0) |
|
width = random.uniform(3.0, 10.0) |
|
diameter = random.uniform(3.0, 10.0) |
|
choice2 = random.choice(["box", "cone", "sphere", "pyramid", "cone"]) |
|
return [gradio.Radio.update(choice2), gradio.Slider.update(length), gradio.Slider.update(width), gradio.Slider.update(height), gradio.Slider.update(diameter), gradio.Number.update(), gradio.Plot.update(make_voxels(choice2, length, height, width, diameter))] |
|
elif choice == "Pick Shape from Dataset": |
|
num = random.randint(1, 4999) |
|
return [gradio.Radio.update(), gradio.Slider.update(), gradio.Slider.update(), gradio.Slider.update(), gradio.Slider.update(), gradio.Number.update(num), gradio.Plot.update(geometry(num))] |
|
|
|
|
|
|
|
def geometry_change(choice, choice2, num, length, width, height, diameter): |
|
if choice == "Construct Shape from Parameters": |
|
return [gradio.Radio.update(visible=True), gradio.Slider.update(visible=True), gradio.Slider.update(visible=True), gradio.Slider.update(visible=True), gradio.Slider.update(visible=True), gradio.Number.update(visible=False), gradio.Timeseries.update(visible=False), gradio.Plot.update(make_voxels(choice2, length, height, width, diameter))] |
|
elif choice == "Pick Shape from Dataset": |
|
return [gradio.Radio.update(visible=False), gradio.Slider.update(visible=False), gradio.Slider.update(visible=False), gradio.Slider.update(visible=False), gradio.Slider.update(visible=False), gradio.Number.update(visible=True), gradio.Timeseries.update(visible=True), gradio.Plot.update(geometry(num))] |
|
|
|
with gradio.Blocks() as demo: |
|
with gradio.Accordion("✨ Read about the underlying ML model here! ✨", open=False): |
|
with gradio.Row(): |
|
with gradio.Column(): |
|
gradio.Markdown("# Toward the Rapid Design of Engineered Systems Through Deep Neural Networks") |
|
gradio.HTML("Christopher McComb, Carnegie Mellon University") |
|
gradio.Markdown("Additive manufacturing is advantageous for producing lightweight components while maintaining function and form. This ability has been bolstered by the introduction of unit lattice cells and the gradation of those cells. In cases where loading varies throughout a part, it may be necessary to use multiple lattice cell types, also known as multi-lattice structures. In such structures, abrupt transitions between geometries may cause stress concentrations, making the boundary a primary failure point; thus, transition regions should be created between each lattice cell type. Although computational approaches have been proposed, smooth transition regions are still difficult to intuit and design, especially between lattices of drastically different geometries. This work demonstrates and assesses a method for using variational autoencoders to automate the creation of transitional lattice cells. In particular, the work focuses on identifying the relationships that exist within the latent space produced by the variational autoencoder. Through computational experimentation, it was found that the smoothness of transition regions was higher when the endpoints were located closer together in the latent space.") |
|
with gradio.Column(): |
|
download = gradio.HTML("<a href=\"https://huggingface.co/spaces/cmudrc/wecnet/resolve/main/McComb2019_Chapter_TowardTheRapidDesignOfEngineer.pdf\" style=\"width: 60%; display: block; margin: auto;\"><img src=\"https://huggingface.co/spaces/cmudrc/wecnet/resolve/main/coverpage.png\"></a>") |
|
|
|
with gradio.Tab("Analysis"): |
|
|
|
with gradio.Row(): |
|
with gradio.Column(): |
|
whence_commeth_geometry = gradio.Radio( |
|
["Construct Shape from Parameters", "Pick Shape from Dataset"], label="How would you like to generate the shape of the offshore structure for analysis?", value="Construct Shape from Parameters" |
|
) |
|
radio = gradio.Radio( |
|
["box", "cone", "cylinder", "sphere", "wedge"], label="What kind of shape would you like to generate?", value="sphere" |
|
) |
|
height = gradio.Slider(label="Height", interactive=True, minimum=3.0, maximum=10.0, value=6.5, visible=False) |
|
width = gradio.Slider(label="Width", interactive=True, minimum=3.0, maximum=10.0, value=6.5, visible=False) |
|
diameter = gradio.Slider(label="Diameter", interactive=True, minimum=3.0, maximum=10.0, value=6.5, visible=True) |
|
length = gradio.Slider(label="Length", interactive=True, minimum=3.0, maximum=10.0, value=6.5, visible=False) |
|
|
|
|
|
num = gradio.Number(42, label="Type the index of the shape you would like to use or randomly select it.", visible=False) |
|
|
|
btn1 = gradio.Button("Randomize") |
|
with gradio.Column(): |
|
geo = gradio.Plot(make_voxels("sphere", 6.5, 6.5, 6.5, 6.5), label="Geometry") |
|
|
|
|
|
with gradio.Row(): |
|
btn2 = gradio.Button("Estimate Spectrum") |
|
|
|
with gradio.Row(): |
|
with gradio.Column(): |
|
pred = gradio.Timeseries(x="Frequency", y=['Surge', 'Heave', 'Pitch'], label="Predicted") |
|
|
|
with gradio.Column(): |
|
true = gradio.Timeseries(x="Frequency", y=['Surge', 'Heave', 'Pitch'], label="True") |
|
|
|
radio.change(fn=change_textbox, inputs=[radio, length, height, width, diameter], outputs=[height, width, diameter, length, geo]) |
|
height.change(fn=make_voxels, inputs = [radio, length, height, width, diameter], outputs=[geo]) |
|
width.change(fn=make_voxels, inputs = [radio, length, height, width, diameter], outputs=[geo]) |
|
diameter.change(fn=make_voxels, inputs = [radio, length, height, width, diameter], outputs=[geo]) |
|
length.change(fn=make_voxels, inputs = [radio, length, height, width, diameter], outputs=[geo]) |
|
whence_commeth_geometry.change(fn=geometry_change, inputs=[whence_commeth_geometry, radio, num, length, width, height, diameter], outputs=[radio, height, width, diameter, length, num, true, geo]) |
|
num.change(fn=geometry, inputs=[num], outputs=[geo]) |
|
|
|
btn1.click(fn=randomize_analysis, inputs=[whence_commeth_geometry], outputs=[radio, length, height, width, diameter, num, geo]) |
|
btn2.click(fn=simple_analysis, inputs=[num, whence_commeth_geometry, radio, length, width, height, diameter], outputs=[pred, true]) |
|
with gradio.Tab("Synthesis"): |
|
with gradio.Tab("Spectrum from Dataset"): |
|
|
|
with gradio.Row(): |
|
with gradio.Column(): |
|
num = gradio.Number(42, label="data index") |
|
btn1 = gradio.Button("Select") |
|
with gradio.Column(): |
|
perf = gradio.Timeseries(x="Frequency", y=['Surge', 'Heave', 'Pitch'], label="Performance") |
|
|
|
with gradio.Row(): |
|
btn2 = gradio.Button("Synthesize Geometry") |
|
|
|
with gradio.Row(): |
|
with gradio.Column(): |
|
pred = gradio.Plot(label="Predicted") |
|
|
|
with gradio.Column(): |
|
true = gradio.Plot(label="True") |
|
|
|
btn1.click(fn=performance, inputs=[num], outputs=[perf]) |
|
btn2.click(fn=simple_synthesis, inputs=[num], outputs=[pred, true]) |
|
with gradio.Tab("Spectrum from DataFrame"): |
|
with gradio.Row(): |
|
perf = gradio.Timeseries(x="Frequency", y=['Surge', 'Heave', 'Pitch'], label="Performance") |
|
|
|
with gradio.Row(): |
|
btn2 = gradio.Button("Synthesize Geometry") |
|
|
|
with gradio.Row(): |
|
pred = gradio.Plot(label="Predicted") |
|
|
|
btn2.click(fn=synthesis_from_spectrum, inputs=[perf], outputs=[pred]) |
|
|
|
demo.launch() |