more blub

This commit is contained in:
2021-02-15 23:26:19 +01:00
parent 0263b37bad
commit e6e3cf479c
9 changed files with 299 additions and 45 deletions

3
.idea/.gitignore generated vendored Normal file
View File

@@ -0,0 +1,3 @@
# Default ignored files
/shelf/
/workspace.xml

8
.idea/hvst.iml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<module type="PYTHON_MODULE" version="4">
<component name="NewModuleRootManager">
<content url="file://$MODULE_DIR$" />
<orderEntry type="inheritedJdk" />
<orderEntry type="sourceFolder" forTests="false" />
</component>
</module>

View File

@@ -0,0 +1,61 @@
<component name="InspectionProjectProfileManager">
<profile version="1.0">
<option name="myName" value="Project Default" />
<inspection_tool class="PyPackageRequirementsInspection" enabled="true" level="WARNING" enabled_by_default="true">
<option name="ignoredPackages">
<value>
<list size="41">
<item index="0" class="java.lang.String" itemvalue="cffi" />
<item index="1" class="java.lang.String" itemvalue="numpy" />
<item index="2" class="java.lang.String" itemvalue="requests" />
<item index="3" class="java.lang.String" itemvalue="markupsafe" />
<item index="4" class="java.lang.String" itemvalue="pyrsistent" />
<item index="5" class="java.lang.String" itemvalue="certifi" />
<item index="6" class="java.lang.String" itemvalue="lxml" />
<item index="7" class="java.lang.String" itemvalue="urllib3" />
<item index="8" class="java.lang.String" itemvalue="itsdangerous" />
<item index="9" class="java.lang.String" itemvalue="jsonschema" />
<item index="10" class="java.lang.String" itemvalue="pynacl" />
<item index="11" class="java.lang.String" itemvalue="flask-restx" />
<item index="12" class="java.lang.String" itemvalue="werkzeug" />
<item index="13" class="java.lang.String" itemvalue="six" />
<item index="14" class="java.lang.String" itemvalue="aniso8601" />
<item index="15" class="java.lang.String" itemvalue="flask-jwt-extended" />
<item index="16" class="java.lang.String" itemvalue="cryptography" />
<item index="17" class="java.lang.String" itemvalue="click" />
<item index="18" class="java.lang.String" itemvalue="attrs" />
<item index="19" class="java.lang.String" itemvalue="bcrypt" />
<item index="20" class="java.lang.String" itemvalue="jinja2" />
<item index="21" class="java.lang.String" itemvalue="pandas" />
<item index="22" class="java.lang.String" itemvalue="paramiko" />
<item index="23" class="java.lang.String" itemvalue="user-agents" />
<item index="24" class="java.lang.String" itemvalue="flask" />
<item index="25" class="java.lang.String" itemvalue="pyjwt" />
<item index="26" class="java.lang.String" itemvalue="idna" />
<item index="27" class="java.lang.String" itemvalue="blinker" />
<item index="28" class="java.lang.String" itemvalue="flask-cors" />
<item index="29" class="java.lang.String" itemvalue="flask-httpauth" />
<item index="30" class="java.lang.String" itemvalue="flask-sitemap" />
<item index="31" class="java.lang.String" itemvalue="mariadb" />
<item index="32" class="java.lang.String" itemvalue="tqdm" />
<item index="33" class="java.lang.String" itemvalue="protobuf" />
<item index="34" class="java.lang.String" itemvalue="tabulate" />
<item index="35" class="java.lang.String" itemvalue="pytimeparse" />
<item index="36" class="java.lang.String" itemvalue="sqlite3-to-mysql" />
<item index="37" class="java.lang.String" itemvalue="packaging" />
<item index="38" class="java.lang.String" itemvalue="mysql-connector-python" />
<item index="39" class="java.lang.String" itemvalue="sqlalchemy" />
<item index="40" class="java.lang.String" itemvalue="simplejson" />
</list>
</value>
</option>
</inspection_tool>
<inspection_tool class="PyPep8Inspection" enabled="true" level="WEAK WARNING" enabled_by_default="true">
<option name="ignoredErrors">
<list>
<option value="E402" />
</list>
</option>
</inspection_tool>
</profile>
</component>

View File

@@ -0,0 +1,6 @@
<component name="InspectionProjectProfileManager">
<settings>
<option name="USE_PROJECT_PROFILE" value="false" />
<version value="1.0" />
</settings>
</component>

4
.idea/misc.xml generated Normal file
View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectRootManager" version="2" project-jdk-name="Pipenv (hvst)" project-jdk-type="Python SDK" />
</project>

8
.idea/modules.xml generated Normal file
View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="ProjectModuleManager">
<modules>
<module fileurl="file://$PROJECT_DIR$/.idea/hvst.iml" filepath="$PROJECT_DIR$/.idea/hvst.iml" />
</modules>
</component>
</project>

6
.idea/vcs.xml generated Normal file
View File

@@ -0,0 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<project version="4">
<component name="VcsDirectoryMappings">
<mapping directory="$PROJECT_DIR$" vcs="Git" />
</component>
</project>

137
hvst.py
View File

@@ -1,5 +1,8 @@
from cadquery import *
import math
import logging
logger = logging.getLogger()
tabletop_depth = 800 # currently, almost all parameters are derived from the table depth
#tabletop_depth = 600
@@ -8,11 +11,13 @@ alpha_max = 70
tabletop_adjuster_assembly_spacing = 100 # symmetric distancing assumed
# cube in adjuster assembly
feet_adjuster_width = 60 # feet_adjuster is moving part inside adjuster assembly
feet_adjuster_lenght = 60
feet_adjuster_height = 60
adjuster_assembly_wall_thickness = 20 # might be different for front and back...
adjuster_assembly_slider_width = 10
adjuster_assembly_length = tabletop_depth - 2*tabletop_adjuster_assembly_spacing
adjuster_assembly_width = feet_adjuster_width + 2*adjuster_assembly_wall_thickness
adjuster_assembly_height = feet_adjuster_height + 2*adjuster_assembly_wall_thickness
@@ -26,9 +31,11 @@ lower_h = ld * math.sqrt(2)*math.sin(math.radians(alpha_max))
lower_feet_assambly_pivot_point_from_fixed_leg = ld * math.sqrt(2)*math.cos(math.radians(alpha_max))
lower_feet_assambly_pivot_point_from_moving_end = ld - lower_feet_assambly_pivot_point_from_fixed_leg
logger.info(f"Lower h is: {lower_h} (between joins of leg only)")
lower_foot_width = 80
lower_foot_height = 50
lower_foot_length = lower_feet_bore_holes_distance + lower_foot_height
lower_foot_length = 2*ld/math.sqrt(2)
lower_feet_assembly_base_plate_height = 20
lower_feet_assembly_side_wall_thickness = 25
lower_feet_assembly_width = 100
@@ -46,58 +53,102 @@ lower_feet_assembly_pin_diameter = 10
## parameter end!
def get_adjuster_assembly_old():
left = Workplane("XZ").vLine(adjuster_assembly_height/2).hLine(adjuster_assembly_wall_thickness+adjuster_assembly_slider_width).vLine(-(adjuster_assembly_height-feet_adjuster_height)/2).hLine(-adjuster_assembly_slider_width).vLineTo(0).mirrorX().extrude(adjuster_assembly_length-2*adjuster_assembly_wall_thickness)
right = left.mirror("YZ", basePointVector = (adjuster_assembly_width/2,0,0))
left = left.union(right)
return left
#return Workplane("XY").box(adjuster_assembly_wall_thickness,adjuster_assembly_length,adjuster_assembly_height).center(10,0).box(10,10,10)
def get_adjuster_assembly_left():
return Workplane("XZ").vLine(adjuster_assembly_height/2).hLine(adjuster_assembly_wall_thickness+adjuster_assembly_slider_width).vLine(-(adjuster_assembly_height-feet_adjuster_height)/2).hLine(-adjuster_assembly_slider_width).vLineTo(0).mirrorX().extrude(adjuster_assembly_length-2*adjuster_assembly_wall_thickness)
def get_adjuster_assembly_right():
#left.mirror("YZ", basePointVector = (adjuster_assembly_width/2,0,0))
return get_adjuster_assembly_left().mirror("YZ")
def get_adjuster_assembly_front_back_plate():
return Workplane("XY").box(adjuster_assembly_width,adjuster_assembly_wall_thickness,adjuster_assembly_height).faces(">Y").workplane().hole(22)
def get_adjuster_assembly():
a = Assembly(None)
a.add(get_adjuster_assembly_left(), name="l")
a.add(get_adjuster_assembly_right(), name="r", color=Color("red"))
a.add(get_adjuster_assembly_front_back_plate(), name="f", color=Color("orange"))
a.add(get_adjuster_assembly_front_back_plate(), name="b")
a.constrain("l@faces@<Y", "b@faces@>Y", "Plane")
a.constrain("l@faces@>Y", "f@faces@<Y", "Plane")
a.constrain("r@faces@<Y", "b@faces@>Y", "Plane")
a.constrain("r@faces@>Y", "f@faces@<Y", "Plane")
a.constrain("r@faces@>X", "f@faces@>X", "Axis")
a.constrain("l@faces@<X", "f@faces@<X", "Axis")
a.constrain("r@faces@>X", "b@faces@>X", "Axis")
a.constrain("l@faces@<X", "b@faces@<X", "Axis")
a.solve()
return a
show_object(get_adjuster_assembly())
# actual parts:
lower_foot_base_plate = Workplane("XY").box(lower_feet_assembly_width,lower_foot_length,lower_feet_assembly_base_plate_height)\
.edges("|Z").fillet(lower_feet_assembly_side_wall_thickness/2)
lower_foot_side_wall_left = Workplane("YZ").box(lower_foot_length,lower_feet_assembly_side_wall_height,lower_feet_assembly_side_wall_thickness)\
.faces("|Y").edges(">Z").fillet(lower_feet_assembly_side_wall_radius)\
.faces("-X").edges(">Z").fillet(lower_feet_assembly_side_wall_thickness/2)\
.faces("+X").workplane()\
.center(lower_foot_length/2-lower_feet_assembly_side_wall_bearing_hole_distance_from_outer,0).hole(2*lower_feet_assembly_bearing_hole_radius,lower_feet_assembly_bearing_hole_depth)\
def get_lower_foot_base_plate():
return Workplane("XY").box(lower_feet_assembly_width,lower_feet_assembly_length,lower_feet_assembly_base_plate_height)\
.edges("|Z").fillet(lower_feet_assembly_side_wall_thickness/2)
lower_foot_bearing_pin_slide = Workplane("YZ",origin=((lower_feet_assembly_side_wall_thickness-lower_feet_assembly_bearing_hole_depth)/2,\
-(lower_feet_bore_holes_distance-lower_feet_assambly_pivot_point_from_moving_end)/2,\
0))\
.box(lower_feet_assambly_pivot_point_from_moving_end,lower_feet_assembly_pin_diameter,lower_feet_assembly_bearing_hole_depth)
def get_lower_foot_side_wall_left():
lower_foot_side_wall_left = Workplane("YZ").box(lower_feet_assembly_length,lower_feet_assembly_side_wall_height,lower_feet_assembly_side_wall_thickness)\
.faces("|Y").edges(">Z").fillet(lower_feet_assembly_side_wall_radius)\
.faces("-X").edges(">Z").fillet(lower_feet_assembly_side_wall_thickness/2)\
.faces("+X").workplane()\
.center(lower_feet_assembly_length/2-lower_feet_assembly_side_wall_bearing_hole_distance_from_outer,0).hole(2*lower_feet_assembly_bearing_hole_radius,lower_feet_assembly_bearing_hole_depth)\
lower_foot_bearing_pin_slide = lower_foot_bearing_pin_slide\
.union(Workplane("YZ",origin=(lower_feet_assembly_side_wall_thickness/2-lower_feet_assembly_bearing_hole_depth,
-(lower_feet_bore_holes_distance/2-lower_feet_assambly_pivot_point_from_moving_end),0.00001))\
.circle(lower_feet_assembly_pin_diameter/2).extrude(lower_feet_assembly_bearing_hole_depth))\
.union(Workplane("YZ",origin=(lower_feet_assembly_side_wall_thickness/2-lower_feet_assembly_bearing_hole_depth,
-(lower_feet_bore_holes_distance/2),0))\
.circle(lower_feet_assembly_pin_diameter/2).extrude(lower_feet_assembly_bearing_hole_depth))
lower_foot_bearing_pin_slide = Workplane("YZ",origin=((lower_feet_assembly_side_wall_thickness-lower_feet_assembly_bearing_hole_depth)/2,\
-(lower_feet_bore_holes_distance-lower_feet_assambly_pivot_point_from_moving_end)/2,\
0))\
.box(lower_feet_assambly_pivot_point_from_moving_end,lower_feet_assembly_pin_diameter,lower_feet_assembly_bearing_hole_depth)
lower_foot_side_wall_left = lower_foot_side_wall_left.cut(lower_foot_bearing_pin_slide)
#show_object(lower_foot_side_wall_left)
#show_object(lower_foot_bearing_pin_slide)
#bearing_pin_slot = Workplane("YZ").center(200,0).box(lower_feet_assambly_pivot_point_from_moving_end,lower_feet_assembly_pin_diameter,lower_feet_assembly_bearing_hole_depth)\
# .workplane(offset=-lower_feet_assembly_bearing_hole_depth/2)\
# .center(-lower_feet_assambly_pivot_point_from_moving_end/2,0).circle(lower_feet_assembly_pin_diameter/2,0).extrude(lower_feet_assembly_bearing_hole_depth)\
# .center(lower_feet_assambly_pivot_point_from_moving_end-0.00001,0).circle(lower_feet_assembly_pin_diameter/2,0).extrude(lower_feet_assembly_bearing_hole_depth)
lower_foot_bearing_pin_slide = lower_foot_bearing_pin_slide\
.union(Workplane("YZ",origin=(lower_feet_assembly_side_wall_thickness/2-lower_feet_assembly_bearing_hole_depth,
-(lower_feet_bore_holes_distance/2-lower_feet_assambly_pivot_point_from_moving_end),0.00001))\
.circle(lower_feet_assembly_pin_diameter/2).extrude(lower_feet_assembly_bearing_hole_depth))\
.union(Workplane("YZ",origin=(lower_feet_assembly_side_wall_thickness/2-lower_feet_assembly_bearing_hole_depth,
-(lower_feet_bore_holes_distance/2),0))\
.circle(lower_feet_assembly_pin_diameter/2).extrude(lower_feet_assembly_bearing_hole_depth))
#show_object(bearing_pin_slot)
#lower_foot_side_wall_left = lower_foot_side_wall_left.cut(bearing_pin_slot)
#show_object(Workplane("YZ").box(lower_feet_assambly_pivot_point_from_moving_end,lower_feet_assembly_pin_diameter,lower_feet_assembly_bearing_hole_depth)\
# .faces("|Y").edges("|X").fillet(4.8))
lower_foot_side_wall_left = lower_foot_side_wall_left.cut(lower_foot_bearing_pin_slide)
return lower_foot_side_wall_left
lower_foot_side_wall_right = lower_foot_side_wall_left.mirror(mirrorPlane="YZ")
def get_lower_foot_side_wall_right():
return get_lower_foot_side_wall_left().mirror(mirrorPlane="YZ")
#show_object(lower_foot_base_plate)
#show_object(lower_foot_side_wall_left)
#show_object(lower_foot_side_wall_right)
def get_lower_foot_front_wall():
return Workplane("XY").box(lower_feet_assembly_width-2*lower_feet_assembly_side_wall_thickness,lower_feet_assembly_side_wall_radius,lower_feet_assembly_side_wall_radius)\
.faces(">X").vertices(">YZ").workplane(centerOption="CenterOfMass")\
.circle(lower_feet_assembly_side_wall_radius).cutThruAll()
def get_lower_foot_end_wall():
return get_lower_foot_front_wall().mirror(mirrorPlane="XZ")
def get_lower_foot_assembly():
return Assembly(get_lower_foot_base_plate(), name='base_plate')\
.add(get_lower_foot_side_wall_left(), name='wall_left',color=Color(1,0,1,0.5), loc=Location(Vector(-(lower_feet_assembly_width-lower_feet_assembly_side_wall_thickness)/2,0,lower_feet_assembly_base_plate_height/2+lower_feet_assembly_side_wall_radius)))\
.add(get_lower_foot_side_wall_right(), name='wall_right',color=Color(0.5,0,1,0.5), loc=Location(Vector((lower_feet_assembly_width-lower_feet_assembly_side_wall_thickness)/2,0,lower_feet_assembly_base_plate_height/2+lower_feet_assembly_side_wall_radius)))\
.add(get_lower_foot_front_wall(), name='wall_front',color=Color(1,0,1,0.5), loc=Location(Vector(0,-(lower_feet_assembly_length-lower_feet_assembly_side_wall_radius)/2,lower_feet_assembly_base_plate_height)))\
.add(get_lower_foot_end_wall(), name='wall_end',color=Color(1,0,1,0.5), loc=Location(Vector(0,(lower_feet_assembly_length-lower_feet_assembly_side_wall_radius)/2,lower_feet_assembly_base_plate_height)))
#show_object(get_lower_foot_assembly())
test_a = Assembly()\
.add(get_lower_foot_assembly(), name="left_foot_assembly", color=Color("red"), loc=Location(Vector(0,0,0)))\
.add(get_lower_foot_assembly(), name="right_foot_assembly", color=Color("white"), loc=Location(Vector(500,0,0)))
lower_foot_assy_left = (
Assembly(lower_foot_base_plate, name='base_plate',loc=Location(Vector(0,0,0)))
.add(lower_foot_side_wall_left, name='wall_left',color=Color(1,0,1,0.5), loc=Location(Vector(-(lower_feet_assembly_width-lower_feet_assembly_side_wall_thickness)/2,0,lower_feet_assembly_base_plate_height/2+lower_feet_assembly_side_wall_radius)))
.add(lower_foot_side_wall_right, name='wall_right',color=Color(0.5,0,1,0.5), loc=Location(Vector((lower_feet_assembly_width-lower_feet_assembly_side_wall_thickness)/2,0,lower_feet_assembly_base_plate_height/2+lower_feet_assembly_side_wall_radius)))
)
show_object(lower_foot_assy_left)
#show_object(get_lower_foot_front_wall())
#show_object(get_lower_foot_end_wall())
#show_object(assy)

107
test_assembly.py Normal file
View File

@@ -0,0 +1,107 @@
from cadquery import *
import math
tabletop_depth = 800 # currently, almost all parameters are derived from the table depth
#tabletop_depth = 600
alpha_max = 70
tabletop_adjuster_assembly_spacing = 100 # symmetric distancing assumed
feet_adjuster_width = 60 # feet_adjuster is moving part inside adjuster assembly
feet_adjuster_lenght = 60
feet_adjuster_height = 60
adjuster_assembly_wall_thickness = 20 # might be different for front and back...
adjuster_assembly_length = tabletop_depth - 2*tabletop_adjuster_assembly_spacing
adjuster_assembly_width = feet_adjuster_width + 2*adjuster_assembly_wall_thickness
adjuster_assembly_height = feet_adjuster_height + 2*adjuster_assembly_wall_thickness
bore_holes_distance_feet_adjuster = adjuster_assembly_length - 2*adjuster_assembly_wall_thickness - feet_adjuster_width
ld = bore_holes_distance_feet_adjuster
lower_feet_bore_holes_distance = bore_holes_distance_feet_adjuster # this is only the case, if min feet angle is 45 degrees
lower_h = ld * math.sqrt(2)*math.sin(math.radians(alpha_max))
lower_feet_assambly_pivot_point_from_fixed_leg = ld * math.sqrt(2)*math.cos(math.radians(alpha_max))
lower_feet_assambly_pivot_point_from_moving_end = ld - lower_feet_assambly_pivot_point_from_fixed_leg
lower_foot_width = 80
lower_foot_height = 50
lower_foot_length = lower_feet_bore_holes_distance + lower_foot_height
lower_feet_assembly_base_plate_height = 20
lower_feet_assembly_side_wall_thickness = 25
lower_feet_assembly_width = 100
lower_feet_assembly_length = lower_feet_bore_holes_distance + lower_foot_height # 2* 1/2 lower_foot_height
lower_feet_assembly_height = lower_feet_assembly_base_plate_height + lower_foot_height
lower_feet_assembly_side_wall_height = lower_foot_height
lower_feet_assembly_side_wall_radius = lower_foot_height/2
lower_feet_assembly_side_wall_bearing_hole_distance_from_outer = lower_feet_assembly_side_wall_radius
lower_feet_assembly_side_wall_bearing_hole_distance_from_bottom = lower_feet_assembly_side_wall_radius
lower_feet_assembly_bearing_hole_distance_from_assembly_bottom = lower_feet_assembly_base_plate_height + lower_foot_height/2
lower_feet_assembly_bearing_hole_radius = 11
lower_feet_assembly_bearing_hole_depth = 10
lower_feet_assembly_pin_diameter = 10
def get_lower_foot_base_plate():
return Workplane("XY").box(lower_feet_assembly_width,lower_foot_length,lower_feet_assembly_base_plate_height)\
.edges("|Z").fillet(lower_feet_assembly_side_wall_thickness/2)
def get_lower_foot_side_wall_left():
lower_foot_side_wall_left = Workplane("YZ").box(lower_foot_length,lower_feet_assembly_side_wall_height,lower_feet_assembly_side_wall_thickness)\
.faces("|Y").edges(">Z").fillet(lower_feet_assembly_side_wall_radius)\
.faces("-X").edges(">Z").fillet(lower_feet_assembly_side_wall_thickness/2)\
.faces("+X").workplane()\
.center(lower_foot_length/2-lower_feet_assembly_side_wall_bearing_hole_distance_from_outer,0).hole(2*lower_feet_assembly_bearing_hole_radius,lower_feet_assembly_bearing_hole_depth)\
lower_foot_bearing_pin_slide = Workplane("YZ",origin=((lower_feet_assembly_side_wall_thickness-lower_feet_assembly_bearing_hole_depth)/2,\
-(lower_feet_bore_holes_distance-lower_feet_assambly_pivot_point_from_moving_end)/2,\
0))\
.box(lower_feet_assambly_pivot_point_from_moving_end,lower_feet_assembly_pin_diameter,lower_feet_assembly_bearing_hole_depth)
lower_foot_bearing_pin_slide = lower_foot_bearing_pin_slide\
.union(Workplane("YZ",origin=(lower_feet_assembly_side_wall_thickness/2-lower_feet_assembly_bearing_hole_depth,
-(lower_feet_bore_holes_distance/2-lower_feet_assambly_pivot_point_from_moving_end),0.00001))\
.circle(lower_feet_assembly_pin_diameter/2).extrude(lower_feet_assembly_bearing_hole_depth))\
.union(Workplane("YZ",origin=(lower_feet_assembly_side_wall_thickness/2-lower_feet_assembly_bearing_hole_depth,
-(lower_feet_bore_holes_distance/2),0))\
.circle(lower_feet_assembly_pin_diameter/2).extrude(lower_feet_assembly_bearing_hole_depth))
lower_foot_side_wall_left = lower_foot_side_wall_left.cut(lower_foot_bearing_pin_slide)
return lower_foot_side_wall_left
def get_lower_foot_side_wall_right():
return get_lower_foot_side_wall_left().mirror(mirrorPlane="YZ")
#show_object(lower_foot_base_plate)
#show_object(lower_foot_side_wall_left)
#show_object(lower_foot_side_wall_right)
b1 = Workplane("XY").box(10,5,5)
b2 = Workplane("XY").box(5,10,5)
b3 = Workplane("YZ").box(4,4,4)
b1 = get_lower_foot_base_plate()
b2 = get_lower_foot_side_wall_left()
b3 = get_lower_foot_side_wall_right()
#show_object(b1)
a1 = Assembly(b1, name="1", color=Color("red"),loc=Location(Vector(0,0,0)))\
.add(b2, name="2", loc=Location(Vector(-(lower_feet_assembly_width-lower_feet_assembly_side_wall_thickness)/2,0,lower_feet_assembly_base_plate_height/2+lower_feet_assembly_side_wall_radius)))\
.add(b3, name="3", color=Color("red"), loc=Location(Vector((lower_feet_assembly_width-lower_feet_assembly_side_wall_thickness)/2,0,lower_feet_assembly_base_plate_height/2+lower_feet_assembly_side_wall_radius)))
#show_object(a1)
a2 = Assembly()\
.add(a1, name="a1", color=Color(0,1,0,0.8))\
.add(a1, name="a2",color=Color(1,1,0,0.8), loc=Location(Vector(200,0,0)))
a3 = Assembly()\
.add(a2, name="a2a", color=Color(0,1,0,0.8))\
.add(a2, name="a3",color=Color(1,1,0,0.8), loc=Location(Vector(0,800,0)))
show_object(a2)