module CrystalScad

This file is part of CrystalScad.

CrystalScad is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

CrystalScad is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with CrystalScad. If not, see <www.gnu.org/licenses/>.

This file is part of CrystalScad.

CrystalScad is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

CrystalScad is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with CrystalScad. If not, see <www.gnu.org/licenses/>.

This file is part of CrystalScad.

CrystalScad is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

CrystalScad is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with CrystalScad. If not, see <www.gnu.org/licenses/>.

Constants

VERSION

Public Instance Methods

*(args) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 405
def *(args)
        return args    if self == nil           
        Intersection.new(self,args)
end
+(args) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 371
def +(args)    
        return Union.new(nil,args)     if self == nil            
        if args.kind_of? Array
                r = self                     
                args.each do |a|
                #    if a.respond_to? :show
                #            r = Union.new(r,a.show)
                #    else
                                r = Union.new(r,a) 
                #    end
                end
                r
        else
                optimize_union(self,args)
        end           
end
-(args) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 388
def -(args)
        return args    if self == nil           
        if args.kind_of? Array
                r = self                     
                args.each do |a|
                        #if a.respond_to? :output
                        #   r = Difference.new(r,a.output)
                        #else
                                r = Difference.new(r,a)    
                        #end
                end
                r
        else
                optimize_difference(self,args)
        end
end
circle(args) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 225
def circle(args)
        Circle.new(args)      
end
color(args) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 539
def color(args)
        return Color.new(self,args)           
end
cube(args={},y=nil,z=nil) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 132
def cube(args={},y=nil,z=nil)
        if args.kind_of? Array
                args = {size:args}
        elsif args.kind_of? Hash
          args[:x] ||= 0
          args[:y] ||= 0
          args[:z] ||= 0
          args = {size:[args[:x],args[:y],args[:z]]}          
        elsif args.kind_of? Numeric
                x = args
                args = {size:[x,y,z]}
        end   
        Cube.new(args)        
end
cylinder(args) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 66
def cylinder(args)
        # inner diameter handling
        if args[:id]          
                id = args.delete(:id)        
                args2 = args.dup
                args2[:d] = id

                if args[:ih]
                        # if it has an inner height, add a tiny bit to the bottom
                        ih = args.delete(:ih)
                        args2[:h] = ih + 0.01
                else 
                        # otherwise add to both bottom and top to make a clear cut in OpenSCAD
                        args2[:h] += 0.02
                end

                # if we have a ifn value, change the fn value of the inner cut
                if args[:ifn]
                        ifn = args.delete(:ifn)
                        args2[:fn] = ifn                    
                end

                return cylinder(args) - cylinder(args2).translate(z:-0.01)
        end

        Cylinder.new(args)            
end
degrees(a) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 629
def degrees(a)
        a*180 /  Math::PI
end
get_classes_from_file(filename) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 677
def get_classes_from_file(filename)
        classes = []
        File.readlines(filename).find_all{|l| l.include?("class")}.each do |line|
                # strip all spaces, tabs
                line.strip!                  
                # ignore comments (Warning: will not worth with ruby multi line comments)
                next if line[0..0] == "#"
                #    strip class definition
                line = line[6..-1]
                # strip until space appears - or if not, to the end
                classes << Object.const_get(line[0..line.index(" ").to_i-1])         
        end

        return classes
end
get_position_rec(obj, level=0) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 589
def get_position_rec(obj, level=0)
        position = [0,0,0]
        return position if obj == nil
        obj.each do |o|
                o.transformations.each do |t|
                        if t.class == Translate
                                t.args[:x] ||= 0
                                t.args[:y] ||= 0
                                t.args[:z] ||= 0
                                position[0] += t.args[:x]
                                position[1] += t.args[:y]
                                position[2] += t.args[:z]
                        end
                end          
#              puts "  " * level + position.inspect
                x,y,z = get_position_rec(o.children,level+1)
                position[0] += x
                position[1] += y
                position[2] += z
        end
        return position
end
hull(*parts) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 410
def hull(*parts)
  Hull.new(*parts)       
end
import(filename) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 447
def import(filename)
        Import.new(filename)
end
linear_extrude(args) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 544
def linear_extrude(args)
        if args[:h]   # rename to height
                args[:height] = args[:h]
                args.delete(:h)
        end
        args = args.collect { |k, v| "#{k} = #{v}" }.join(', ')
        return LinearExtrude.new(self,args)                           
end
long_slot(args) click to toggle source

produces a hull() of 2 cylidners accepts d,r,h for cylinder options l long slot length

# File lib/crystalscad/CrystalScad.rb, line 621
def long_slot(args)
  hull(cylinder(d:args[:d],r:args[:r],h:args[:h]),cylinder(d:args[:d],r:args[:r],h:args[:h]).translate(x:args[:l]))    
end
optimize_difference(top, child) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 362
def optimize_difference(top, child)
        if top.kind_of? Difference and not child.kind_of? Difference
                top.children << child
                return top
        else
                return Difference.new(top,child)
        end
end
optimize_union(top, child) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 353
def optimize_union(top, child)
        if top.kind_of? Union and not child.kind_of? Union and top.transformations.to_a.size == 0
                top.children << child
                return top
        else
                return Union.new(top,child)
        end
end
polygon(args) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 235
def polygon(args)
        Polygon.new(args)     
end
polyhedron(args) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 163
def polyhedron(args)
        Polyhedron.new(args)
end
position(obj) click to toggle source
this is experimental, does only work on simple parts. example:

The bolt head is on the -z plane, this will move it to “zero”

# File lib/crystalscad/CrystalScad.rb, line 614
def position(obj)
        get_position_rec(obj.children)
end
projection(args={}) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 562
def projection(args={})
        args = args.collect { |k, v| "#{k} = #{v}" }.join(', ')
        return Projection.new(self,args)                              
end
radians(a) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 625
def radians(a)
a/180.0 * Math::PI
end
render(args={}) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 471
def render(args={})
        return Render.new(self,args)          
end
rotate_extrude(args={}) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 553
def rotate_extrude(args={})
        if args[:h]   # rename to height
                args[:height] = args[:h]
                args.delete(:h)
        end
        args = args.collect { |k, v| "#{k} = #{v}" }.join(', ')       
        return RotateExtrude.new(self,args)                           
end
save!() click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 634
def save!
        Dir.glob("lib/**/*.rb").map{|l| get_classes_from_file(l)}.flatten.map{|l| save_all(l)}
end
save_all(class_name,fn=$fn) click to toggle source

Saves all files generated of a CrystalScad file Saves outputs of

  • show

  • output

  • view*

# File lib/crystalscad/CrystalScad.rb, line 643
def save_all(class_name,fn=$fn)

        res = class_name.send :new

        # skip defined classes
        skip = class_name.send :get_skip
        skip = [] if skip == nil
        skip << "show_hardware"
        added_views = class_name.send :get_views

        # regexp for output* view* show*
        (res.methods.grep(Regexp.union(/^output/,/^view/,/^show/)) + added_views).each do |i|
                next if skip.include? i.to_s
                output = nil

                res.send :initialize # ensure default values are loaded at each interation
                output = res.send i 

                # if previous call resulted in a CrystalScadObject, don't call the show method again,
                # otherwise call it.
                unless       output.kind_of? CrystalScadObject
                        unless i.to_s.include? "output"     
                                output = res.show                                  
                        else
                                output = res.output
                        end
                end


                output.save("output/#{res.class}_#{i}.scad","$fn=#{fn};") unless output == nil
        end

end
sphere(args) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 153
def sphere(args)
        Sphere.new(args)              
end
square(args,y=nil) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 203
  def square(args,y=nil)
          if args.kind_of? Array
                  args = {size:args}
          elsif args.kind_of? Numeric
                  x = args
                  args = {size:[x,y]}                  
          elsif args.kind_of? Hash
            unless args[:size]
              args[:x] ||= 0
              args[:y] ||= 0
              args = {size:[args[:x],args[:y]]}         
end
          end
          Square.new(args)      
  end
stack(args={}, *parts) click to toggle source
Deprecated: Stacks parts along the Z axis

works on all Assemblies that have a @height definition TODO: Make a better functionality similar to this, that is:

- easier to use
- throws better error messages
- doesn't assume that everything falls down like gravity in every case
# File lib/crystalscad/CrystalScad.rb, line 574
def stack(args={}, *parts)
        args[:method] ||= "show"
        args[:spacing] ||= 0
        puts "CrystalScad Warning: Please note that the stack method is deprecated and will be removed or replaced in the future"
        @assembly = nil               
        z = 0
        parts.each do |part|
                item = (part.send args[:method])
                next if item == nil or !item.respond_to? "translate"
                @assembly += item.translate(z:z)
                z+= part.height      + args[:spacing]
        end
        @assembly
end
text(args={}) click to toggle source
# File lib/crystalscad/CrystalScad.rb, line 299
def text(args={})
        return Text.new(args)                         
end