Created
December 21, 2012 14:16
-
-
Save jstults/4353086 to your computer and use it in GitHub Desktop.
functions for generating mged (BRLCAD) commands to make octet truss primitives
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# | |
# http://www.variousconsequences.com/2012/12/octet-truss-for-topology-optimization.html | |
# | |
import scipy as sp | |
class rcc_shape(): | |
def __init__(self, name, origin, height, radius): | |
self.name = name | |
self.origin = origin | |
self.height = height | |
self.radius = radius | |
def mged_string(self): | |
return("in %s rcc %g %g %g %g %g %g %g\n" % (self.name, self.origin[0], self.origin[1], self.origin[2], self.height[0], self.height[1], self.height[2], self.radius)) | |
#class mged_commands(): | |
# def __init__(self, fname): | |
# self.fname = fname | |
# self.fout = open(fname,"w") | |
# self.part_count = 0 | |
class octet_prim(): | |
""" | |
generate an octet truss primative (one cell) with specified element radius | |
""" | |
def __init__(self, name, origin, length, radius): | |
self.name = name | |
self.origin = origin | |
self.length = length # length of members | |
self.radius = radius # radius of members | |
self.unit = sp.sqrt(length**2 + length**2) # unit cube side length | |
self.x1 = sp.array([0.0, 0.0, 0.0]) | |
self.x2 = sp.array([self.length, 0.0, 0.0]) | |
self.x3 = sp.array([0.0, self.length, 0.0]) | |
self.x4 = sp.array([self.length, self.length, 0.0]) | |
self.x5 = sp.array([self.length/2.0, self.length/2.0, self.length*sp.sin(sp.pi/4.0)]) | |
self.x6 = sp.array([self.length/2.0, self.length/2.0, -self.length*sp.sin(sp.pi/4.0)]) | |
self.shape_list = [] | |
self.shape_list.append( rcc_shape("%s-rcc1.s"%self.name, self.x1, self.x2, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc2.s"%self.name, self.x1, self.x3, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc3.s"%self.name, self.x2, self.x3, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc4.s"%self.name, self.x3, self.x2, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc5.s"%self.name, self.x1, self.x5, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc6.s"%self.name, self.x2, self.x5-self.x2, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc7.s"%self.name, self.x3, self.x5-self.x3, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc8.s"%self.name, self.x4, self.x5-self.x4, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc9.s"%self.name, self.x1, self.x6, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc10.s"%self.name, self.x2, self.x6-self.x2, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc11.s"%self.name, self.x3, self.x6-self.x3, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc12.s"%self.name, self.x4, self.x6-self.x4, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc13.s"%self.name, self.x5, self.x2, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc14.s"%self.name, self.x5, -self.x2, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc15.s"%self.name, self.x5, self.x3, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc16.s"%self.name, self.x5, -self.x3, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc17.s"%self.name, self.x6, self.x2, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc18.s"%self.name, self.x6, -self.x2, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc19.s"%self.name, self.x6, self.x3, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc20.s"%self.name, self.x6, -self.x3, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc21.s"%self.name, self.x1, self.x5-self.x3, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc22.s"%self.name, self.x2, self.x5-self.x3-self.x2, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc23.s"%self.name, self.x1, self.x6-self.x3, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc24.s"%self.name, self.x2, self.x6-self.x3-self.x2, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc25.s"%self.name, self.x1, self.x5-self.x2, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc26.s"%self.name, self.x1, self.x6-self.x2, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc27.s"%self.name, self.x3, self.x5-self.x2-self.x3, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc28.s"%self.name, self.x3, self.x6-self.x2-self.x3, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc29.s"%self.name, self.x3, self.x5, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc30.s"%self.name, self.x3, self.x6, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc31.s"%self.name, self.x4, self.x5-self.x2, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc32.s"%self.name, self.x4, self.x6-self.x2, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc33.s"%self.name, self.x4, self.x5-self.x3, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc34.s"%self.name, self.x4, self.x6-self.x3, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc35.s"%self.name, self.x2, self.x5, radius) ) | |
self.shape_list.append( rcc_shape("%s-rcc36.s"%self.name, self.x2, self.x6, radius) ) | |
def mged_string(self): | |
# insert all the right circular cylinders | |
mged_string = "" | |
for s in self.shape_list: | |
mged_string = mged_string + s.mged_string() | |
# union the cylinders | |
mged_string = mged_string + "r %s"%self.name | |
for s in self.shape_list: | |
mged_string = mged_string + " u " + s.name | |
mged_string = mged_string + "\n" | |
# rotate and translate to put a corner on the origin | |
mged_string = mged_string + "B %s\n"%self.name | |
mged_string = mged_string + "oed / %s/%s-rcc1.s\n"%(self.name,self.name) | |
mged_string = mged_string + "rot 0 0 45\n" | |
mged_string = mged_string + "translate %g %g %g\n" % (0,self.length*sp.sin(sp.pi/4.0),self.length*sp.sin(sp.pi/4.0)) | |
mged_string = mged_string + "accept\n" | |
# offset to self.origin | |
mged_string = mged_string + "oed / %s/%s-rcc1.s\n"%(self.name,self.name) | |
mged_string = mged_string + "translate %g %g %g\n" % (self.origin[0], self.origin[1], self.origin[2]) | |
mged_string = mged_string + "accept\n" | |
return(mged_string) | |
if __name__ == "__main__": | |
# make a BRL-CAD database with an octet truss made of rcc | |
# primitives, union the rcc's into a region, convert the region | |
# into an stl | |
import os | |
# Path to the mged executables: | |
MGED_PATH = "~/brlcad/.build/bin/" | |
# octet truss parameters, member radius and length | |
radius = 0.4 | |
length = 8.0 | |
# command file: | |
mged_commands = "octet_prim_%s_%s.mged" % (radius, length) | |
brlcad_dbase = "octet_prim_%s_%s.g" % (radius, length) | |
stl_file = "octet_prim_%s_%s.stl" % (radius, length) | |
rname = "region1.r" | |
fout = open(mged_commands, "w") | |
x1 = sp.array([0.0, 0.0, 0.0]) | |
x2 = sp.array([length, 0.0, 0.0]) | |
x3 = sp.array([0.0, length, 0.0]) | |
x4 = sp.array([length, length, 0.0]) | |
x5 = sp.array([length/2.0, length/2.0, length*sp.sin(sp.pi/4.0)]) | |
x6 = sp.array([length/2.0, length/2.0, -length*sp.sin(sp.pi/4.0)]) | |
offset = sp.array([length*sp.sin(sp.pi/4.0),0.0,length*sp.sin(sp.pi/4.0)]) | |
angle = sp.pi / 4.0 | |
rotation = sp.array([[sp.cos(angle), -sp.sin(angle), 0],[sp.sin(angle), sp.cos(angle), 0],[0, 0, 1.0]]) | |
shape_list = [] | |
shape_list.append( rcc_shape("rcc1.s", x1, x2, radius) ) | |
shape_list.append( rcc_shape("rcc2.s", x1, x3, radius) ) | |
shape_list.append( rcc_shape("rcc3.s", x2, x3, radius) ) | |
shape_list.append( rcc_shape("rcc4.s", x3, x2, radius) ) | |
shape_list.append( rcc_shape("rcc5.s", x1, x5, radius) ) | |
shape_list.append( rcc_shape("rcc6.s", x2, x5-x2, radius) ) | |
shape_list.append( rcc_shape("rcc7.s", x3, x5-x3, radius) ) | |
shape_list.append( rcc_shape("rcc8.s", x4, x5-x4, radius) ) | |
shape_list.append( rcc_shape("rcc9.s", x1, x6, radius) ) | |
shape_list.append( rcc_shape("rcc10.s", x2, x6-x2, radius) ) | |
shape_list.append( rcc_shape("rcc11.s", x3, x6-x3, radius) ) | |
shape_list.append( rcc_shape("rcc12.s", x4, x6-x4, radius) ) | |
shape_list.append( rcc_shape("rcc13.s", x5, x2, radius) ) | |
shape_list.append( rcc_shape("rcc14.s", x5, -x2, radius) ) | |
shape_list.append( rcc_shape("rcc15.s", x5, x3, radius) ) | |
shape_list.append( rcc_shape("rcc16.s", x5, -x3, radius) ) | |
shape_list.append( rcc_shape("rcc17.s", x6, x2, radius) ) | |
shape_list.append( rcc_shape("rcc18.s", x6, -x2, radius) ) | |
shape_list.append( rcc_shape("rcc19.s", x6, x3, radius) ) | |
shape_list.append( rcc_shape("rcc20.s", x6, -x3, radius) ) | |
shape_list.append( rcc_shape("rcc21.s", x1, x5-x3, radius) ) | |
shape_list.append( rcc_shape("rcc22.s", x2, x5-x3-x2, radius) ) | |
shape_list.append( rcc_shape("rcc23.s", x1, x6-x3, radius) ) | |
shape_list.append( rcc_shape("rcc24.s", x2, x6-x3-x2, radius) ) | |
shape_list.append( rcc_shape("rcc25.s", x1, x5-x2, radius) ) | |
shape_list.append( rcc_shape("rcc26.s", x1, x6-x2, radius) ) | |
shape_list.append( rcc_shape("rcc27.s", x3, x5-x2-x3, radius) ) | |
shape_list.append( rcc_shape("rcc28.s", x3, x6-x2-x3, radius) ) | |
shape_list.append( rcc_shape("rcc29.s", x3, x5, radius) ) | |
shape_list.append( rcc_shape("rcc30.s", x3, x6, radius) ) | |
shape_list.append( rcc_shape("rcc31.s", x4, x5-x2, radius) ) | |
shape_list.append( rcc_shape("rcc32.s", x4, x6-x2, radius) ) | |
shape_list.append( rcc_shape("rcc33.s", x4, x5-x3, radius) ) | |
shape_list.append( rcc_shape("rcc34.s", x4, x6-x3, radius) ) | |
shape_list.append( rcc_shape("rcc35.s", x2, x5, radius) ) | |
shape_list.append( rcc_shape("rcc36.s", x2, x6, radius) ) | |
# commands to make all the parts: | |
for s in shape_list: | |
fout.write(s.mged_string()) | |
# command to make a region out of all the parts in the shape list: | |
mgedr = "r region1.r" | |
for s in shape_list: | |
mgedr = mgedr + " u " + s.name # union parts to region | |
fout.write(mgedr + "\n") | |
fout.write("B region1.r\n") | |
fout.write("oed / region1.r/rcc1.s\n") | |
fout.write("rot 0 0 45\n") | |
fout.write("translate %g %g %g\n" % (0,length*sp.sin(sp.pi/4.0),length*sp.sin(sp.pi/4.0))) | |
fout.write("accept\n") | |
fout.close() | |
# run the commands in mged | |
retval = os.system("cat %s | %smged -c %s" % (mged_commands, MGED_PATH, brlcad_dbase) ) | |
# export the region to an stl file | |
atol = 0.001 # absolute tolerance | |
D = 0.000001 # calculation accuracy | |
retval = os.system("%sg-stl -a %f -D %f -o %s %s %s" % (MGED_PATH, atol, D, stl_file, brlcad_dbase, rname)) | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment