Class: JennCad::Thing

Inherits:
Object
  • Object
show all
Defined in:
lib/jenncad/thing.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(args = {}) ⇒ Thing

Returns a new instance of Thing.



15
16
17
# File 'lib/jenncad/thing.rb', line 15

def initialize(args={})
  init(args)
end

Instance Attribute Details

#anchorsObject

Returns the value of attribute anchors.



10
11
12
# File 'lib/jenncad/thing.rb', line 10

def anchors
  @anchors
end

#angleObject

Returns the value of attribute angle.



9
10
11
# File 'lib/jenncad/thing.rb', line 9

def angle
  @angle
end

#calc_hObject

Returns the value of attribute calc_h.



7
8
9
# File 'lib/jenncad/thing.rb', line 7

def calc_h
  @calc_h
end

#calc_xObject

Returns the value of attribute calc_x.



7
8
9
# File 'lib/jenncad/thing.rb', line 7

def calc_x
  @calc_x
end

#calc_yObject

Returns the value of attribute calc_y.



7
8
9
# File 'lib/jenncad/thing.rb', line 7

def calc_y
  @calc_y
end

#calc_zObject

Returns the value of attribute calc_z.



7
8
9
# File 'lib/jenncad/thing.rb', line 7

def calc_z
  @calc_z
end

#csizeObject

Returns the value of attribute csize.



12
13
14
# File 'lib/jenncad/thing.rb', line 12

def csize
  @csize
end

#diameterObject

Returns the value of attribute diameter.



6
7
8
# File 'lib/jenncad/thing.rb', line 6

def diameter
  @diameter
end

#fnObject

Returns the value of attribute fn.



9
10
11
# File 'lib/jenncad/thing.rb', line 9

def fn
  @fn
end

#nameObject

Returns the value of attribute name.



5
6
7
# File 'lib/jenncad/thing.rb', line 5

def name
  @name
end

#optsObject

Returns the value of attribute opts.



3
4
5
# File 'lib/jenncad/thing.rb', line 3

def opts
  @opts
end

#parentObject

Returns the value of attribute parent.



11
12
13
# File 'lib/jenncad/thing.rb', line 11

def parent
  @parent
end

#partsObject

Returns the value of attribute parts.



4
5
6
# File 'lib/jenncad/thing.rb', line 4

def parts
  @parts
end

#posObject

Returns the value of attribute pos.



12
13
14
# File 'lib/jenncad/thing.rb', line 12

def pos
  @pos
end

#shapeObject

Returns the value of attribute shape.



8
9
10
# File 'lib/jenncad/thing.rb', line 8

def shape
  @shape
end

#sits_onObject

Returns the value of attribute sits_on.



13
14
15
# File 'lib/jenncad/thing.rb', line 13

def sits_on
  @sits_on
end

#transformationsObject

Returns the value of attribute transformations.



5
6
7
# File 'lib/jenncad/thing.rb', line 5

def transformations
  @transformations
end

#xObject

Returns the value of attribute x.



6
7
8
# File 'lib/jenncad/thing.rb', line 6

def x
  @x
end

#yObject

Returns the value of attribute y.



6
7
8
# File 'lib/jenncad/thing.rb', line 6

def y
  @y
end

Instance Method Details

#anchor(name, thing = nil, args = {}) ⇒ Object Also known as: a



128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# File 'lib/jenncad/thing.rb', line 128

def anchor(name, thing=nil, args={})
  if thing
    res = thing.anchor(name, nil, args)
    return res unless res.nil?
  end
  @anchors ||= {}
  if anch = @anchors[name]
    return anch
  elsif args[:fail_quick] && args[:fail_quick] == true
    return
  elsif @parent
    return @parent.anchor(name)
  elsif self.respond_to? :get_contents
    con = get_contents
    if con.respond_to? :anchor
      con.anchor(name, nil, fail_quick: true)
    end
  end
end

#at(keys, thing = nil, args = {}, &block) ⇒ Object

Perform something at an anchor location block



414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
# File 'lib/jenncad/thing.rb', line 414

def at(keys, thing=nil, args={}, &block)
  unless keys.kind_of? Array
    keys = [keys]
  end

  part = self
  keys.each do |key|
    if key.kind_of? Hash
      an = key
    else
      thing ||= self
      an = anchor(key, thing, args)
    end
    unless an
      $log.error "at on #{thing.class} could not find anchor #{key}"
      an = {} # this will move by 0,0 and still display the block
    end
    part.movei(an)
    bl = block.yield
    unless bl == nil
      part = bl.move(an)
    end
  end
  part
end

#auto_colorObject



703
704
705
706
707
708
# File 'lib/jenncad/thing.rb', line 703

def auto_color
  if option(:color) == nil && !option(:no_auto_color)
    return auto_color!
  end
  nil
end

#auto_color!Object



710
711
712
# File 'lib/jenncad/thing.rb', line 710

def auto_color!
  color_parse($jenncad_profile.colors.pop)
end

#auto_extrudeObject



196
197
198
199
200
# File 'lib/jenncad/thing.rb', line 196

def auto_extrude
  ret = self.extrude
  ret.set_option(:auto_extrude, true)
  ret
end

#calculate_center_rotation(oldcenter, args) ⇒ Object

experiment



271
272
273
274
275
276
277
278
279
280
281
282
# File 'lib/jenncad/thing.rb', line 271

def calculate_center_rotation(oldcenter, args)
  x,y,z = oldcenter
  v = Vector.point x,y,z
  rot_x = Matrix.rotation_x(radians(args[:x] || 0))
  rot_y = Matrix.rotation_y(radians(args[:y] || 0))
  rot_z = Matrix.rotation_z(radians(args[:z] || 0))
  v = rot_x*v
  v = rot_y*v
  v = rot_z*v

  [v.x,v.y,v.z]
end

#calculated_hObject



733
734
735
736
737
738
# File 'lib/jenncad/thing.rb', line 733

def calculated_h
  return @z unless @z.nil? || @z == 0
  return @h unless @h.nil? || @h == 0
  return @calc_h unless @calc_h.nil? || @calc_h == 0
  return @calc_z unless @calc_z.nil? || @calc_z == 0
end

#children_list(stop_at = nil) ⇒ Object



583
584
585
# File 'lib/jenncad/thing.rb', line 583

def children_list(stop_at=nil)
  get_children(self, stop_at).flatten
end

#color(args = nil) ⇒ Object



654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
# File 'lib/jenncad/thing.rb', line 654

def color(args=nil)
  if args == nil
    return option(:color)
  end

  if args == :auto
    ac = auto_color
    unless ac.nil?
      #puts "auto color to #{ac}"
      if only_color?(get_contents)
        set_option :color, ac
        set_option :auto_color, true
      else
        set_auto_color_for_children(ac, get_contents)
      end

    end
    return self
  end

  c = color_parse(args)
  unless c.nil?
    set_option :color, c
    set_option :auto_color, false
  end

  self
end

#color_or_fallbackObject



714
715
716
717
# File 'lib/jenncad/thing.rb', line 714

def color_or_fallback
  return option(:fallback_color) if option(:color) == nil
  option(:color)
end

#color_parse(args = nil) ⇒ Object



683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
# File 'lib/jenncad/thing.rb', line 683

def color_parse(args=nil)
  case args
  when :none
    set_option :no_auto_color, true
  when :random
    return Color.random
  when Array
    return Color.parse(args)
  when /(?<=#)(?<!^)(\h{6}|\h{3})/
    return args
  when /(?<!^)(\h{6}|\h{3})/
    return "##{args}"
  when String
    return args
  when Symbol
    return args.to_s
  end
  nil
end

#copy_anchor(name, thing = nil) ⇒ Object Also known as: cpa



160
161
162
163
164
165
166
167
# File 'lib/jenncad/thing.rb', line 160

def copy_anchor(name, thing=nil)
  # since it might be confusing to use / use shortcuts for copy_anchor and copy_anchors, let copy_anchor copy all of them when only one parameter is given
  if thing.nil?
    return copy_anchors(name)
  end
  @anchors ||= {}
  @anchors[name] = thing.anchor(name)
end

#copy_anchors(thing) ⇒ Object



156
157
158
# File 'lib/jenncad/thing.rb', line 156

def copy_anchors(thing)
  @anchors = thing.anchors
end

#cut_to(face, part = nil, args = {}) ⇒ Object



59
60
61
62
63
64
65
66
67
68
69
70
71
72
# File 'lib/jenncad/thing.rb', line 59

def cut_to(face, part=nil, args={})
  an = anchor(face, part)
  unless an
    $log.error "Cannot find anchor to cut_to"
    return self
  end
  if an[:z].to_d == 0.0
    $log.error "cut_to only supports cuts to an anchor with Z set. This anchor: #{an}"
    return self
  end
  modify_values(self, z: an[:z].to_d)
  self.name="#{self.class}_cut_to_#{an[:z].to_f}"
  self
end

#dbgObject



54
55
56
57
# File 'lib/jenncad/thing.rb', line 54

def dbg
  set_flag(:debug)
  self
end

#debug?Boolean

Returns:

  • (Boolean)


114
115
116
# File 'lib/jenncad/thing.rb', line 114

def debug?
  option(:debug) || false
end

#find_calculated_h(parts) ⇒ Object



740
741
742
743
744
745
746
747
748
749
750
751
# File 'lib/jenncad/thing.rb', line 740

def find_calculated_h(parts)
  return if parts == nil
  unless parts.kind_of? Array
    parts = [parts]
  end
  parts.each do |part|
    if z = calculated_h
      return z
    end
    get_calculated_h(part.get_contents)
  end
end

#fixateObject Also known as: fix



118
119
120
# File 'lib/jenncad/thing.rb', line 118

def fixate
  Marshal.load(Marshal.dump(self))
end

#flip(dir, args = {}) ⇒ Object



225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
# File 'lib/jenncad/thing.rb', line 225

def flip(dir, args={})
  @sits_on ||= :bottom

  ro = flip_rotation(dir)
  flip_rotation(@sits_on).each do |key, val|
    ro[key] ||= 0
    ro[key] -= val
  end
  unless ro == {}
    self.moveai(:center).rotate(ro)
  end

  @opts ||= {}

  if args[:center]
    if ro == {} # if we didn't move earlier, let's move it now
      self.moveai(:center)
    end
    @opts[:center_z] = true
    set_anchors_z if self.respond_to? :set_anchors_z
  else
    # TODO: fix anchors
    if debug?
      $log.info "flip_axis(#{dir}): #{flip_axis(dir)} csize: #{@csize.size}"
    end

    case flip_axis(dir)
      when :x
        self.move(zh: @csize.x)
      when :y
        self.move(zh: @csize.y)
      when :z
        self.move(zh: @csize.z)
    end
    @opts[:center_z] = false
  end
  @sits_on = dir

  self
end

#flipc(dir, args = {}) ⇒ Object



221
222
223
# File 'lib/jenncad/thing.rb', line 221

def flipc(dir, args={})
  flip(dir, args.merge(rel: true, center: true))
end

#get_children(item, stop_at) ⇒ Object



587
588
589
590
591
592
593
594
595
596
597
# File 'lib/jenncad/thing.rb', line 587

def get_children(item, stop_at)
  res = [item]
  if item.respond_to?(:parts) && item.parts != nil
    item.parts.each do |pa|
      unless stop_at != nil && pa.kind_of?(stop_at)
        res << get_children(pa, stop_at)
      end
    end
  end
  res
end

#get_contentsObject



719
720
721
722
723
724
725
726
727
728
729
730
731
# File 'lib/jenncad/thing.rb', line 719

def get_contents
  return @parts unless @parts.nil?

  if @cache
    return @cache unless option(:no_cache) == true
  end

  if self.respond_to? :part
    # cache things to prevent calling the code in #part multiple times
    @cache = part
    return @cache
  end
end

#ghostObject



775
776
777
778
779
780
781
# File 'lib/jenncad/thing.rb', line 775

def ghost
  set_option :ghost, true
  set_option :no_auto_color, true
  set_option :color, nil
  set_option :auto_color, false
  self
end

#has_explicit_color?Boolean

Returns:

  • (Boolean)


604
605
606
607
608
609
# File 'lib/jenncad/thing.rb', line 604

def has_explicit_color?
  if option(:auto_color) == false
    return true
  end
  return false
end

#hideObject



783
784
785
786
# File 'lib/jenncad/thing.rb', line 783

def hide
  set_option :hide, true
  self
end

#hlObject



793
794
795
796
# File 'lib/jenncad/thing.rb', line 793

def hl
  set_option :highlight, true
  self
end

#inherit_color(other) ⇒ Object



599
600
601
602
# File 'lib/jenncad/thing.rb', line 599

def inherit_color(other)
  self.set_option(:color, other.option(:color))
  self.set_option(:auto_color, other.option(:auto_color))
end

#init(args = {}) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
# File 'lib/jenncad/thing.rb', line 19

def init(args={})
  @csize = Size.new()
  @transformations = []
  # calculated origin; only works for move atm
  @calc_x = 0
  @calc_y = 0
  @calc_z = 0
  @pos = Point.new
  @calc_h = args[:z] || 0
  @anchors = {}
  @parent = args[:parent] || nil
  @opts ||= args
  @cache = nil
end

#is_2d?Boolean

Returns:

  • (Boolean)


841
842
843
# File 'lib/jenncad/thing.rb', line 841

def is_2d?
  !is_3d?
end

#is_3d?Boolean

Returns:

  • (Boolean)


845
846
847
848
849
850
851
852
853
# File 'lib/jenncad/thing.rb', line 845

def is_3d?
  if self.respond_to?(:dimensions) && self.dimensions
    return true if self.dimensions && self.dimensions.include?(:z)
  else
    # assume true if not set
    return true
  end
  false
end

#mhx(v = 0) ⇒ Object



495
496
497
# File 'lib/jenncad/thing.rb', line 495

def mhx(v=0)
  moveh(x:v)
end

#mhy(v = 0) ⇒ Object



499
500
501
# File 'lib/jenncad/thing.rb', line 499

def mhy(v=0)
  moveh(y:v)
end

#mhz(v = 0) ⇒ Object



503
504
505
# File 'lib/jenncad/thing.rb', line 503

def mhz(v=0)
  moveh(z:v)
end

#mirror(args = {}) ⇒ Object Also known as: mi



516
517
518
519
520
# File 'lib/jenncad/thing.rb', line 516

def mirror(args={})
  @transformations ||= []
  @transformations << Mirror.new(args)
  self
end

#mixObject



523
524
525
# File 'lib/jenncad/thing.rb', line 523

def mix
  mirror(x:1)
end

#miyObject



527
528
529
# File 'lib/jenncad/thing.rb', line 527

def miy
  mirror(y:1)
end

#mizObject



531
532
533
# File 'lib/jenncad/thing.rb', line 531

def miz
  mirror(z:1)
end

#modify_values(parts, value, opts = {}) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/jenncad/thing.rb', line 74

def modify_values(parts, value, opts = {})
  case parts
   when Array
      parts.each do |pa|
        modify_values(pa, value, opts)
      end
    else
      if parts.kind_of?(BooleanObject)
        modify_values(parts.only_additives_of(parts), value, opts)
      elsif parts.kind_of?(Part)
        modify_values(parts.part, value, opts)
        modify_values(parts.get_contents, value, opts)
        parts.modify_values!(value, opts)
      elsif parts.kind_of?(Primitive)
        parts.modify_values!(value, opts)
      end
  end
end

#modify_values!(values, opts) ⇒ Object



93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
# File 'lib/jenncad/thing.rb', line 93

def modify_values!(values, opts)
  $log.info "Modify value! #{self.class} #{values}" if self.debug?
  values.each do |key, val|
    if @opts
      case opts[:mode]
        when :add
          @opts[key] = @opts[key].to_d + val.to_d
        when :sub
          @opts[key] = @opts[key].to_d - val.to_d
        else
          @opts[key] = val
      end
    end
    if self.respond_to? key
      self.send("#{key}=", @opts[key])
    end
  end
  $log.info "Modified value now: #{self.inspect}" if self.debug?
end

#move(args = {}) ⇒ Object Also known as: translate, m



348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
# File 'lib/jenncad/thing.rb', line 348

def move(args={})
  return self if args.nil? or args.empty?

  if args.kind_of? Array
    x,y,z = args
    return move(x:x, y:y, z:z)
  end

  chain = if args[:chain]
    args[:chain]
  else
    $jenncad_profile.chain_moves
  end

  point = Point.new(args)

  if point.zero?
    return self
  end
  pre = args[:prepend]
  args = point.to_h

  @transformations ||= []
  if pre
    lt = @transformations.first
    if lt && lt.class == Move && chain == false
      $log.debug "#{self} at move(prepend): Adding to first move #{lt.inspect} , args: #{args}" if self.debug?
      lt.pos.add(point)
    else
      @transformations.prepend(Move.new(pos: point))
    end
  else
    lt = @transformations.last

    if lt && lt.class == Move && chain == false
      $log.debug "#{self} at move: Adding to previous move #{lt.inspect} , args: #{args}" if self.debug?
      lt.pos.add(point) # TODO: figure out why this doesn't work on export
    else
      $log.debug "#{self} at move: Adding move of #{args} to transformations" if self.debug?
      @transformations << Move.new(pos: point)
    end
  end
  @pos ||= Point.new
  @pos.add(point)
  # NOTE: this needs more migration so everythign runs over point
  @calc_x += args[:x].to_d
  @calc_y += args[:y].to_d
  @calc_z += args[:z].to_d
  self
end

#movea(key, thing = nil, args = {}) ⇒ Object Also known as: ma

move to anchor



441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
# File 'lib/jenncad/thing.rb', line 441

def movea(key, thing=nil, args={})
  if thing.kind_of? Hash # if you leave out thing, args may be interpreted as thing
    args = thing
    thing = nil
  end

  an = anchor(key, thing, args)

  unless an
    $log.error "Error: Anchor #{key} not found"
    $log.error "Available anchors: #{@anchors}"
    return self
  else
    m = an.dup
    if args[:chain]
      m[:chain] = args[:chain]
    end
    if args[:inverted]
      self.movei(m)
    else
      self.move(m)
    end
  end
end

#moveai(key, thing = nil, args = {}) ⇒ Object Also known as: mai

move to anchor - inverted



468
469
470
471
472
473
474
475
# File 'lib/jenncad/thing.rb', line 468

def moveai(key, thing=nil, args={})
  if thing.kind_of? Hash # if you leave out thing, args may be interpreted as thing
    args = thing
    thing = nil
  end
  args[:inverted] = true
  movea(key, thing, args)
end

#moveh(args = {}) ⇒ Object Also known as: mh

move half



479
480
481
482
483
484
485
486
487
488
489
490
491
492
# File 'lib/jenncad/thing.rb', line 479

def moveh(args={})
  if args.kind_of? Array
    x,y,z = args
    args = {x: x, y: y, z: z}
  end
  to = {}
  args.each do |key, val|
    to[key] = val.to_d / 2.0 if val.kind_of? Numeric
  end
  to[:chain] = args[:chain]
  to[:prepend] = args[:prepend]

  move(to)
end

#movei(args = {}) ⇒ Object



507
508
509
510
511
512
513
514
# File 'lib/jenncad/thing.rb', line 507

def movei(args={})
  to = {}
  args.each do |key, val|
    to[key] = val.to_d * -1 if val.kind_of? Numeric
   end
  to[:chain] = args[:chain]
  move(to)
end

#multmatrix(args) ⇒ Object



553
554
555
556
557
# File 'lib/jenncad/thing.rb', line 553

def multmatrix(args)
  @transformations ||= []
  @transformations << Multmatrix.new(args)
  self
end

#mx(v = 0) ⇒ Object



401
402
403
# File 'lib/jenncad/thing.rb', line 401

def mx(v=0)
  move(x:v)
end

#my(v = 0) ⇒ Object



405
406
407
# File 'lib/jenncad/thing.rb', line 405

def my(v=0)
  move(y:v)
end

#mz(v = 0) ⇒ Object



409
410
411
# File 'lib/jenncad/thing.rb', line 409

def mz(v=0)
  move(z:v)
end

#on_top_of(other_object) ⇒ Object



579
580
581
# File 'lib/jenncad/thing.rb', line 579

def on_top_of(other_object)
  self.top_of(other_object) + other_object
end

#onlyObject



788
789
790
791
# File 'lib/jenncad/thing.rb', line 788

def only
  set_option :only, true
  self
end

#only_color?(parts, lvl = 0) ⇒ Boolean

Returns:

  • (Boolean)


611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
# File 'lib/jenncad/thing.rb', line 611

def only_color?(parts, lvl=0)
  return true if parts == nil
  unless parts.kind_of? Array
    parts = [parts]
  end

  parts.each do |part|
    #puts "  " * lvl + "[only_color?] #{part}"
    if part.has_explicit_color?
      #puts "  " * lvl + "found explicit color here: #{part.color}"
      return false
    end
    if !only_color?(part.parts, lvl+1)
      return false
    end
  end
  true
end

#openscad(file) ⇒ Object



767
768
769
770
771
772
773
# File 'lib/jenncad/thing.rb', line 767

def openscad(file)
  set_heights_for_auto_extrude(get_contents)

  @parts = get_contents

  JennCad::Exporters::OpenScad.new(self).save(file)
end

#openscad_modifierObject



798
799
800
801
802
803
804
# File 'lib/jenncad/thing.rb', line 798

def openscad_modifier
  return "%" if option(:ghost)
  return "#" if option(:highlight)
  return "!" if option(:only)
  return "*" if option(:hide)
  nil
end

#option(key) ⇒ Object



34
35
36
37
# File 'lib/jenncad/thing.rb', line 34

def option(key)
  @opts ||= {}
  @opts[key]
end

#parse_xyz_shortcuts(args) ⇒ Object

Deprecated, moved to Point



290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
# File 'lib/jenncad/thing.rb', line 290

def parse_xyz_shortcuts(args)
  unless args.kind_of? Hash
    $log.warn "parse_xyz_shortcuts called for type #{args.class} #{args.inspect}"
    return args
  end
  [:x, :y, :z].each do |key|
    args[key] ||= 0.0
  end

  if args[:debug]
    $log.debug "Args: #{args}"
  end

  if args[:xy]
    args[:x] += args[:xy]
    args[:y] += args[:xy]
  end
  if args[:xyz]
    args[:x] += args[:xyz]
    args[:y] += args[:xyz]
    args[:z] += args[:xyz]
  end
  if args[:xz]
    args[:x] += args[:xz]
    args[:z] += args[:xz]
  end
  if args[:yz]
    args[:y] += args[:yz]
    args[:z] += args[:yz]
  end
  if args[:debug]
    $log.debug "After xyz shortcuts #{args}"
  end

 return args
end

#radians(a) ⇒ Object



266
267
268
# File 'lib/jenncad/thing.rb', line 266

def radians(a)
  a.to_d/180.0*PI
end

#referenced_zObject



806
807
808
809
810
# File 'lib/jenncad/thing.rb', line 806

def referenced_z
 return false if @z.to_d != 0.0
 return option(:zref) if option(:zref)
 return false
end

#resetObject Also known as: rst

resets all transformations



341
342
343
344
# File 'lib/jenncad/thing.rb', line 341

def reset
  @transformations = []
  self
end

#reset_last_moveObject Also known as: rstlm

reset last move



328
329
330
331
332
333
334
335
336
337
# File 'lib/jenncad/thing.rb', line 328

def reset_last_move
  lt = @transformations.last
  unless lt.class == Move
    $log.error "Tried to call rst_move but last object is a #{lt.class}"
    return self
  end
  @transformations.delete_at(-1)

  self
end

#rotate(args) ⇒ Object Also known as: rt



202
203
204
205
206
# File 'lib/jenncad/thing.rb', line 202

def rotate(args)
  @transformations ||= []
  @transformations << Rotate.new(args)
  self
end

#rotate_around(point, args) ⇒ Object



284
285
286
287
# File 'lib/jenncad/thing.rb', line 284

def rotate_around(point,args)
  x,y,z= point[:x], point[:y], point[:z]
  self.move(x:-x,y:-y,z:-z).rotate(args).move(x:x,y:y,z:z)
end

#rx(v) ⇒ Object



209
210
211
# File 'lib/jenncad/thing.rb', line 209

def rx(v)
  rt(x:v)
end

#ry(v) ⇒ Object



213
214
215
# File 'lib/jenncad/thing.rb', line 213

def ry(v)
  rt(y:v)
end

#rz(v) ⇒ Object



217
218
219
# File 'lib/jenncad/thing.rb', line 217

def rz(v)
  rt(z:v)
end

#scale(args = {}) ⇒ Object Also known as: sc



536
537
538
539
540
541
542
543
# File 'lib/jenncad/thing.rb', line 536

def scale(args={})
  if args.kind_of? Numeric or args.kind_of? Array
      args = {v:args}
  end
  @transformations ||= []
  @transformations << Scale.new(args)
  self
end

#set_anchor(name, args = {}) ⇒ Object Also known as: sa



149
150
151
152
153
# File 'lib/jenncad/thing.rb', line 149

def set_anchor(name, args={})
  @anchors ||= {}
  @anchors[name] = args
  self
end

#set_anchor_from(name, new_name, args = {}) ⇒ Object Also known as: saf



170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
# File 'lib/jenncad/thing.rb', line 170

def set_anchor_from(name, new_name, args={})
  unless name.kind_of? Symbol or name.kind_of? String
    $log.error "set_anchor_from: name must be a string or symbol. Supplied: #{name}"
    return
  end
  unless new_name.kind_of? Symbol or new_name.kind_of? String
    $log.error "set_anchor_from: new_name must be a string or symbol. Supplied: #{new_name}"
    return
  end


  a = anchor(name, args[:from]).dup
  if !a
    $log.error "set_anchor_from couldn't find anchor #{name}"
    return
  end

  [:x, :y, :z, :xy, :xz, :xyz, :yz].each do |key|
    a[key] ||= 0.to_d
    args[key] ||= 0.to_d
    a[key] += args[key]
  end
  set_anchor new_name, a
end

#set_auto_color(col) ⇒ Object



649
650
651
652
# File 'lib/jenncad/thing.rb', line 649

def set_auto_color(col)
  set_option :color, col
  set_option :auto_color, true
end

#set_auto_color_for_children(col, parts, lvl = 0) ⇒ Object



630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
# File 'lib/jenncad/thing.rb', line 630

def set_auto_color_for_children(col, parts, lvl=0)
  return if parts == nil

  parts.each do |part|
    unless part.has_explicit_color?
      if only_color?(part.parts, lvl+1)
        #puts "  " * lvl + "children have no explicit color, setting it here"
        part.set_auto_color(col)
      else
        #puts "  " * lvl + "[set_auto_color_for_children] #{part}"
        set_auto_color_for_children(col, part.parts, lvl+1)
      end
    else
      #puts "  " * lvl + "[set_auto_color_for_children] this part has a color #{part.color}, ignoring their children"
    end

  end
end

#set_flag(key) ⇒ Object



44
45
46
47
# File 'lib/jenncad/thing.rb', line 44

def set_flag(key)
  set_option(key, true)
  self
end

#set_heights_for_auto_extrude(parts, parent = nil) ⇒ Object



753
754
755
756
757
758
759
760
761
762
763
764
765
# File 'lib/jenncad/thing.rb', line 753

def set_heights_for_auto_extrude(parts, parent=nil)
  return if parts.nil?
  unless parts.kind_of? Array
    parts = [parts]
  end

  parts.each do |part|
    if part.option(:auto_extrude)
      part.z = parent.calculated_h
    end
    set_heights_for_auto_extrude(part.get_contents, part)
  end
end

#set_option(key, val) ⇒ Object



39
40
41
42
# File 'lib/jenncad/thing.rb', line 39

def set_option(key, val)
  @opts ||= {}
  @opts[key] = val
end

#set_parent(parent) ⇒ Object



123
124
125
126
# File 'lib/jenncad/thing.rb', line 123

def set_parent(parent)
  @parent = parent
  self
end

#skew(args) ⇒ Object



559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
# File 'lib/jenncad/thing.rb', line 559

def skew(args)
  xy = args[:xy] || 0
  x = args[:x] || 0
  yx = args[:yx] || 0
  y = args[:y] || 0
  zx = args[:zx] || 0
  zy = args[:zy] || 0

  multmatrix([
    [1, xy, x, 0],
    [yx, 1, y, 0],
    [zx, zy, 1, 0],
    [0, 0, 0, 1]
  ])
end

#to_mod(name) ⇒ Object



835
836
837
838
839
# File 'lib/jenncad/thing.rb', line 835

def to_mod(name)
  a = Aggregation.new(name, self)
  a.transformations = @transformations
  a
end

#top_of(other_object) ⇒ Object



575
576
577
# File 'lib/jenncad/thing.rb', line 575

def top_of(other_object)
  self.move(z:other_object.z+other_object.calc_z.to_d)
end

#transform(obj) ⇒ Object

copies the transformation of obj to self



547
548
549
550
551
# File 'lib/jenncad/thing.rb', line 547

def transform(obj)
  @transformations ||= []
  @transformations += obj.transformations
  self
end

#unset_flag(key) ⇒ Object



49
50
51
52
# File 'lib/jenncad/thing.rb', line 49

def unset_flag(key)
  set_option(key, false)
  self
end

#zObject



817
818
819
820
821
822
823
824
# File 'lib/jenncad/thing.rb', line 817

def z
  case ref = referenced_z
  when nil, false
    @z + z_margin
  else
    ref.z.to_d + ref.z_margin.to_d
  end
end

#z=(args) ⇒ Object



812
813
814
815
# File 'lib/jenncad/thing.rb', line 812

def z=(args)
  set_option(:z, args)
  @z = args
end

#z_marginObject



826
827
828
829
830
831
832
833
# File 'lib/jenncad/thing.rb', line 826

def z_margin
  case m = option(:margins)
  when nil, {}
    0.0
  else
    m[:z].to_d
  end
end