openscad-lib and pandahome
This commit is contained in:
commit
8975cbbf4c
54
examples/pandahome.rb
Normal file
54
examples/pandahome.rb
Normal file
|
@ -0,0 +1,54 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
load 'openscad.rb'
|
||||||
|
|
||||||
|
s = OpenSCAD.new
|
||||||
|
|
||||||
|
def r code
|
||||||
|
OpenSCAD::Code.new code
|
||||||
|
end
|
||||||
|
|
||||||
|
s.module :roundedBox, 'size[3]', :radius, :sidesonly do
|
||||||
|
s.rot = s[ [0,0,0], [90,0,90], [90,90,0] ]
|
||||||
|
s-:rot
|
||||||
|
s.if s.sidesonly do
|
||||||
|
s.cube s.size - s[s.radius*2,0,0], true
|
||||||
|
s.cube s.size - s[0,s.radius*2,0], true
|
||||||
|
s.for x: s[s.radius-s.size[0], -s.radius+s.size[0]]/2,
|
||||||
|
y: s[s.radius-s.size[1], -s.radius+s.size[1]]/2 do
|
||||||
|
s.translate( s[s.x,s.y,0]) { s.cylinder s: s.radius, h: s.size[2], center: true }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
s.else do
|
||||||
|
s.cube s.size-s[0,s.radius,s.radius]*2, center: true
|
||||||
|
s.cube s.size-s[s.radius,0,s.radius]*2, center: true
|
||||||
|
s.cube s.size-s[s.radius,s.radius,0]*2, center: true
|
||||||
|
end
|
||||||
|
s.for axis: 0..2 do
|
||||||
|
s.for x: s.radius*s[1,-1] + s.size[s.axis]/2*s[-1,1],
|
||||||
|
y: s.radius*s[1,-1] + s.size[(s.axis+1)%3]/2*s[-1,1] do
|
||||||
|
s.rotate( (s+:rot)[s.axis]) do
|
||||||
|
s.translate s[s.x,s.y,0] do
|
||||||
|
s.cylinder h: s.size[(s.axis+2)%3]-s.radius*2, r: s.radius, center: true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
s.for x: (s.radius*s[1,-1] + s.size[0]*s[-1,1]) /2,
|
||||||
|
y: (s.radius*s[1,-1] + s.size[1]*s[-1,1]) /2,
|
||||||
|
z: (s.radius*s[1,-1] + s.size[2]*s[-1,1]) /2 do
|
||||||
|
s.translate(s[s.x,s.y,s.z]) { s.sphere s.radius }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
s.body = s[ 114.3, 101.6, 40 ]
|
||||||
|
s.gap = 0.2
|
||||||
|
s.thick = 1
|
||||||
|
s.body_inner = s.body+s.gap
|
||||||
|
s.body_outer = s.body_inner+s.thick
|
||||||
|
|
||||||
|
s.difference do
|
||||||
|
s.roundedBox s.body_outer, 2, true
|
||||||
|
s.translate( s[1,1,1] * s.thick) { s.roundedBox s.body_inner, 2, true }
|
||||||
|
s.translate( s[0,0,24]) { s.cube s[150,120,10], true }
|
||||||
|
end
|
179
lib/openscad.rb
Normal file
179
lib/openscad.rb
Normal file
|
@ -0,0 +1,179 @@
|
||||||
|
#!/usr/bin/env ruby
|
||||||
|
|
||||||
|
class OpenSCAD
|
||||||
|
def initialize indent = nil, &out
|
||||||
|
@indent, @out = indent || 0, out || STDOUT
|
||||||
|
@vars = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
def - var
|
||||||
|
var = var.to_s
|
||||||
|
self << __indent__ << var << ' = ' << @vars[var] << ";\n"
|
||||||
|
end
|
||||||
|
|
||||||
|
def + code
|
||||||
|
Code.new code.to_s
|
||||||
|
end
|
||||||
|
|
||||||
|
def << o, &block
|
||||||
|
if block_given?
|
||||||
|
yield self.class.new( @indent+1)
|
||||||
|
else
|
||||||
|
@out << o
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def __indent__ i = nil
|
||||||
|
@indent += i if i
|
||||||
|
"\t"*@indent
|
||||||
|
end
|
||||||
|
|
||||||
|
def module meth, *args, &block
|
||||||
|
@vars = (vars = @vars).dup
|
||||||
|
args = args.collect do |arg|
|
||||||
|
arg = arg.to_s
|
||||||
|
dim = []
|
||||||
|
while arg =~ /(.*)\[(\d+)\]$/
|
||||||
|
dim.push $2.to_i
|
||||||
|
arg = $1
|
||||||
|
end
|
||||||
|
arg = Code.new arg
|
||||||
|
gen = lambda do |ds, is|
|
||||||
|
if ds.empty?
|
||||||
|
Code.new "#{arg}#{is.collect{|i|"[#{i}]"}.join}"
|
||||||
|
else
|
||||||
|
d, *ds = ds
|
||||||
|
List[ *d.times.collect {|i| gen[ ds, is+[i]] }]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
@vars[arg] = gen[dim,[]]
|
||||||
|
arg
|
||||||
|
end
|
||||||
|
method_missing "module #{meth}", *args, &(block||lambda{|*_,&e|})
|
||||||
|
@vars = vars
|
||||||
|
end
|
||||||
|
|
||||||
|
def method_missing meth, *args, &block
|
||||||
|
meth = meth.to_s
|
||||||
|
case meth
|
||||||
|
when /=$/ # setting variable
|
||||||
|
#self << __indent__ << meth << args[0].to_openscad << ";\n"
|
||||||
|
@vars[ meth[0...-1]] = args[0]
|
||||||
|
when *@vars.keys # reading variable
|
||||||
|
@vars[ meth]
|
||||||
|
else # method-calling
|
||||||
|
bkvars = @vars.dup
|
||||||
|
nargs = []
|
||||||
|
args.each do |arg|
|
||||||
|
case arg
|
||||||
|
when Hash
|
||||||
|
arg.each do |k,v|
|
||||||
|
nargs.push "#{k}=#{v.to_openscad}"
|
||||||
|
@vars[k.to_s] = Code.new k.to_s
|
||||||
|
end
|
||||||
|
else nargs.push arg.to_openscad
|
||||||
|
end
|
||||||
|
end
|
||||||
|
join = case meth
|
||||||
|
when 'for'
|
||||||
|
r = ",\n" << __indent__(+2)
|
||||||
|
@indent -= 2
|
||||||
|
r
|
||||||
|
else ', '
|
||||||
|
end
|
||||||
|
self << __indent__ << meth
|
||||||
|
self << "(" << nargs.join( join) << ')' unless 'else' == meth
|
||||||
|
if block_given?
|
||||||
|
@indent += 1
|
||||||
|
self << " {\n"
|
||||||
|
yield
|
||||||
|
@indent -= 1
|
||||||
|
self << __indent__ << "}\n"
|
||||||
|
else
|
||||||
|
self << ";\n"
|
||||||
|
end
|
||||||
|
@vars = bkvars
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class List < Array
|
||||||
|
def self.[]( *as) super *as.collect {|v| Array === v ? self[ *v] : v } end
|
||||||
|
def depth() List === (o = self[0]) ? 1+o.depth : 1 end
|
||||||
|
def map( &e) dup.map! &e end
|
||||||
|
def collect( &e) dup.collect! &e end
|
||||||
|
|
||||||
|
def operation o = nil, &e
|
||||||
|
o = case o
|
||||||
|
when List then o
|
||||||
|
when Array then self.class[ *o]
|
||||||
|
else o
|
||||||
|
end
|
||||||
|
if List === o
|
||||||
|
case depth <=> o.depth
|
||||||
|
when -1 then o.collect {|b| operation b, &e }
|
||||||
|
when 1 then collect {|a| a.operation o, &e }
|
||||||
|
else
|
||||||
|
case depth
|
||||||
|
when 1 then self.class[ *zip( o)].collect {|a,b| e[a,b] }
|
||||||
|
else self.class[ *zip( o)].collect {|a,b| a.operation b, &e }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
else
|
||||||
|
case depth
|
||||||
|
when 1 then collect {|v| e[v,o] }
|
||||||
|
else collect {|v| v.operation o, &e }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def s_operation( s, o) operation( o) {|a,b| Code.new "(#{a.to_openscad}#{s}#{b})" } end
|
||||||
|
def +( o) operation( o) {|a,b| a+b } end
|
||||||
|
def -( o) operation( o) {|a,b| a-b } end
|
||||||
|
def *( o) operation( o) {|a,b| a*b } end
|
||||||
|
def /( o) operation( o) {|a,b| a/b } end
|
||||||
|
def %( o) operation( o) {|a,b| a%b } end
|
||||||
|
def -@() operation {|a| -a } end
|
||||||
|
def +@() operation {|a| +a } end
|
||||||
|
|
||||||
|
def [] i
|
||||||
|
case i
|
||||||
|
when Integer then super i
|
||||||
|
else Code.new "#{self.to_openscad}[#{i}]"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def to_openscad
|
||||||
|
"[#{collect(&:to_openscad).join', '}]"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Code < String
|
||||||
|
def new( a) super a.to_s end
|
||||||
|
def to_openscad() to_s end
|
||||||
|
def s_operation s, o
|
||||||
|
case o
|
||||||
|
when List
|
||||||
|
o.operation( self) {|a,b| self.class.new "(#{b}#{s}#{a.to_openscad})" }
|
||||||
|
else self.class.new "(#{to_openscad}#{s}#{o.to_openscad})"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
def +( o) 0 == o ? self : s_operation( :+, o) end
|
||||||
|
def -( o) 0 == o ? self : s_operation( :-, o) end
|
||||||
|
def *( o) 1 == o ? self : s_operation( :*, o) end
|
||||||
|
def /( o) 1 == o ? self : s_operation( :/, o) end
|
||||||
|
def %( o) s_operation( :%, o) end
|
||||||
|
def -@() s = self.dup; s[0,0] = '-'; s end
|
||||||
|
def +@() s = self.dup; s[0,0] = '+'; s end
|
||||||
|
def []( i) self.class.new "#{self}[#{i}]" end
|
||||||
|
end
|
||||||
|
|
||||||
|
def []( *args) List[ *args] end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Object
|
||||||
|
def to_openscad() inspect end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Range
|
||||||
|
def to_openscad() "[#{self.begin}:#{self.end}]" end
|
||||||
|
end
|
Loading…
Reference in a new issue