Last active
July 19, 2022 17:58
-
-
Save jdegenstein/125f0f59a82121135b7812d0a313aacb to your computer and use it in GitHub Desktop.
CadQuery assembly of a Soma Cube Puzzle using constraints
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
import cadquery as cq | |
from random import randrange as rrr | |
from random import seed | |
#Soma set consists of 7 separate pieces | |
# 4 pieces can be x-y plane only, other 3 require x-y-z | |
#keep the same pseudo random colors later: | |
seed(5)#keep colors run-to-run | |
#(3,4,5,77,777,51221,512796321 are good seeds) | |
def arnco(u = 100, l = 10, cfloat=False): | |
if cfloat: #for two output types depending on need | |
return ((rrr(l,u)/255),(rrr(l,u)/255),(rrr(l,u)/255),1.0) | |
return {"alpha": 0.1,"color": (rrr(l,u),rrr(l,u),rrr(l,u))} | |
cb_w = 12 #cube size | |
chmf = 1 #chamfer | |
def scube(): | |
return cq.Workplane().box(cb_w,cb_w,cb_w) | |
def convtToXYZpt(cenc): #convert cube position encoding to actual xyz points | |
arr = [] | |
for id1,i in enumerate(cenc): | |
for id2,j in enumerate(i): | |
if j==1 and id1==0: #y=0 | |
arr.append((id2*cb_w,0,0)) | |
elif j==1 and id1==1: #y=1 | |
arr.append((id2*cb_w,1*cb_w,0)) | |
elif j==1 and id1==2: #z=1 | |
arr.append((id2*cb_w,0,1*cb_w)) | |
return arr | |
def mcube(cenc): | |
f1 = ( | |
cq.Workplane() | |
.pushPoints(convtToXYZpt(cenc)) | |
.eachpoint(lambda loc: scube().val().moved(loc), combine="a") | |
.edges() | |
.chamfer(chmf) | |
) | |
return f1 | |
#cube position encoding | |
#x runs from L to R of each row | |
#row1 is y=0,z=0 | |
#row2 is y=1,z=0 | |
#row3 is y=0,z=1 | |
#lower case L | |
c0 = [(1,1,0), | |
(1,0,0), | |
(0,0,0)] | |
#upper case L | |
c1 = [(1,1,1), | |
(1,0,0), | |
(0,0,0)] | |
#tee | |
c2 = [(1,1,1), | |
(0,1,0), | |
(0,0,0)] | |
#zee | |
c3 = [(1,1,0), | |
(0,1,1), | |
(0,0,0)] | |
#corner (xyz) | |
c4 = [(1,1,0), | |
(1,0,0), | |
(1,0,0)] | |
#RH (xyz) | |
c5 = [(1,1,0), | |
(1,0,0), | |
(0,1,0)] | |
#LH (xyz) | |
c6 = [(1,1,0), | |
(0,1,0), | |
(1,0,0)] | |
cubes = [c0,c1,c2,c3,c4,c5,c6] | |
#the following commented code will display all the pieces separately | |
# if "show_object" in locals(): | |
# for idx,val in enumerate(cubes): | |
# show_object(mcube(cubes[idx]) | |
# .translate((0,5*cb_w+idx*2.5*cb_w,0)), | |
# options=arnco() | |
# ) | |
def XYPL(): | |
return cq.Workplane().rect(75,75).extrude(-1) | |
def bigL():#big | |
rv = mcube(cubes[1]).rotate((0,0,0),(0,1,0),-90) | |
rv.faces(">Z[1]").tag("Z1").end() | |
rv.faces("<Z").tag("Z").end() | |
rv.faces(">Y").tag("Y").end() | |
rv.faces(">Y[1]").tag("Y1").end() | |
rv.faces(">X").tag("X").end() | |
return rv | |
def littleL():#littleL | |
rv = mcube(cubes[0]) | |
rv.faces(">X").tag("X").end() | |
rv.faces("<X").tag("lX").end() | |
rv.faces(">X[1]").tag("X1").end() | |
rv.faces(">Y[1]").tag("Y1").end() | |
rv.faces(">Z").tag("Z").end() | |
return rv | |
def corner(): #corner | |
rv = mcube(cubes[4]) | |
return rv | |
def LHS(): #LHS | |
rv = mcube(cubes[6]) | |
return rv | |
def zee(): #zee | |
rv = mcube(cubes[3]) | |
return rv | |
def tee(): #tee | |
rv = mcube(cubes[2]) | |
return rv | |
def RHS(): #RHS | |
rv = mcube(cubes[5]) | |
return rv | |
soma = ( | |
cq.Assembly() | |
.add(XYPL(),name="XYPL", color=cq.Color(*arnco(cfloat=True))) | |
.add(bigL(),name="bigL", color=cq.Color(*arnco(cfloat=True))) | |
.add(littleL(),name="littleL", color=cq.Color(*arnco(cfloat=True))) | |
.add(LHS(),name="LHS", color=cq.Color(*arnco(cfloat=True))) | |
.add(zee(),name="zee", color=cq.Color(*arnco(cfloat=True))) | |
.add(tee(),name="tee", color=cq.Color(*arnco(cfloat=True))) | |
.add(corner(),name="corner", color=cq.Color(*arnco(cfloat=True))) | |
.add(RHS(),name="RHS", color=cq.Color(*arnco(cfloat=True))) | |
) | |
( | |
soma | |
.constrain("XYPL","Fixed") | |
.constrain("bigL?Z","XYPL@faces@>Z", "Axis") | |
.constrain("bigL?Z","FixedRotation",(0,0,0)) | |
.constrain("bigL?Z","FixedPoint",(-cb_w,-cb_w/2,0)) | |
.constrain("littleL@faces@>Y","XYPL@faces@>Z", "PointInPlane") | |
.constrain("littleL?X","bigL?Y1", "Axis") | |
.constrain("littleL?X1","bigL?Y", "Plane") | |
.constrain("littleL?Y1","bigL?Z1", "Plane") | |
.constrain("LHS@faces@<Z","XYPL@faces@>Z", "Axis") | |
#.constrain("LHS@faces@<Y","littleL@faces@<X", "Axis", param=0) | |
.constrain("LHS@faces@>Z[1]","tee@faces@>Y", "PointInPlane") | |
.constrain("LHS@faces@>Y[1]","zee@faces@>Z", "PointInPlane") | |
.constrain("LHS@faces@>Y","zee@faces@<Z", "Axis", param=0) | |
#.constrain("LHS@faces@>Y","littleL@faces@>X", "Axis", param=0) | |
.constrain("LHS@faces@>X","tee@faces@>X[1]", "PointInPlane") | |
.constrain("zee@faces@>Y[1]","littleL@faces@<Y", "Axis") | |
.constrain("zee@faces@>Y[1]","littleL@faces@<Y", "PointInPlane") | |
.constrain("zee@faces@>X[1]","littleL@faces@>Z", "Axis") | |
.constrain("zee@faces@>X[1]","littleL@faces@>Z", "PointInPlane") | |
.constrain("zee@faces@<Z","bigL@faces@>Y[1]", "PointInPlane") | |
.constrain("tee@faces@>Y[1]","littleL@faces@<Y", "Axis") | |
.constrain("tee@faces@>Y[1]","littleL@faces@<Y", "PointInPlane") | |
.constrain("tee@faces@>X[1]","littleL@faces@>Z", "PointInPlane") | |
.constrain("tee@faces@<Z","zee@faces@>Z", "Axis") | |
.constrain("tee@faces@<Z","zee@faces@>Z", "PointInPlane") | |
.constrain("corner@faces@<Z","XYPL@faces@>Z", "PointInPlane") | |
.constrain("corner@faces@<X","bigL@faces@<Y", "Axis", param=0) | |
.constrain("corner@faces@<Y","LHS@faces@<X", "Axis", param=0) | |
.constrain("corner@faces@>X[1]","zee@faces@<Z", "PointInPlane") | |
.constrain("corner@faces@>Y","bigL@faces@>X", "PointInPlane") | |
.constrain("RHS@faces@<Z","bigL@faces@>Z", "Axis", param=0) | |
#.constrain("RHS@faces@<Y","bigL@faces@<Y", "Axis", param=0) | |
.constrain("RHS@faces@<X","tee@faces@>X", "Axis", param=0) | |
.constrain("RHS@faces@>Z[1]","corner@faces@>Z", "PointInPlane") | |
.constrain("RHS@faces@>X[1]","zee@faces@<X[1]", "PointInPlane") | |
.constrain("RHS@faces@>Y[1]","zee@faces@<Z", "PointInPlane") | |
) | |
soma.solve() | |
show_object(soma,options=arnco()) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment