engineering 0 → 0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/Gemfile +2 -0
- data/README.markdown +109 -0
- data/Rakefile +7 -0
- data/engineering.gemspec +16 -15
- data/lib/engineering.rb +80 -1
- data/lib/sketchup.rb +164 -0
- data/test/engineering.rb +203 -0
- data/test/fixtures/translated_extrusion.su +7 -0
- data/test/geometry.rb +22 -0
- data/test/geometry/edge.rb +23 -0
- data/test/geometry/point.rb +39 -0
- data/test/geometry/size.rb +39 -0
- data/test/model/builder.rb +35 -0
- data/test/model/extrusion.rb +32 -0
- data/test/sketchup.rb +7 -0
- data/test/sketchup/builder.rb +117 -0
- data/test/units/literal.rb +31 -0
- metadata +95 -8
- data/README +0 -0
data/Gemfile
CHANGED
data/README.markdown
ADDED
@@ -0,0 +1,109 @@
|
|
1
|
+
Engineering for Ruby
|
2
|
+
====================
|
3
|
+
|
4
|
+
This is a meta-gem for all things related to engineering (particularly CAD stuff). The Engineering module
|
5
|
+
is your one stop shop for all of the tools you need for your latest mad-engineering project.
|
6
|
+
|
7
|
+
Activating a dormant volcano? Adding death rays to your secret moon base? Plotting world domination? No problem! There's a gem for that, and you've found it right here.
|
8
|
+
|
9
|
+
If your latest and greatest project, and even your older ones, need something
|
10
|
+
that isn't in Engineering, either let me know, or fork and add it yourself (and
|
11
|
+
send me a pull request). Or feel free to create your own gem that reopens
|
12
|
+
the module and adds whatever is missing, if that's more your style.
|
13
|
+
|
14
|
+
License
|
15
|
+
-------
|
16
|
+
|
17
|
+
Copyright 2012-2013 Brandon Fosdick <bfoz@bfoz.net> and released under the BSD license.
|
18
|
+
|
19
|
+
Dependencies
|
20
|
+
------------
|
21
|
+
|
22
|
+
- DXF [GitHub](http://github.com/bfoz/ruby-dxf) [RubyGems](https://rubygems.org/gems/dxf)
|
23
|
+
- Units [GitHub](https://github.com/bfoz/units)
|
24
|
+
- Geometry [GitHub](https://github.com/bfoz/geometry) [RubyGems](https://rubygems.org/gems/geometry)
|
25
|
+
- Sketch [GitHub](https://github.com/bfoz/sketch)
|
26
|
+
- Model [GitHub](https://github.com/bfoz/model)
|
27
|
+
|
28
|
+
Installation
|
29
|
+
------------
|
30
|
+
|
31
|
+
Engineering has a number of dependencies. Some of which are hosted on rubygems.org
|
32
|
+
and can therefore be handled by the gem utility, but others must be installed
|
33
|
+
manually. The easiest option is to use [Bundler](http://gembundler.com/), but
|
34
|
+
*gem* can be used if you're willing to install the *units* gem manually.
|
35
|
+
|
36
|
+
### Using Bundler
|
37
|
+
|
38
|
+
Installing the *engineering* gem using bundler is very easy, although a little more involved than normal.
|
39
|
+
|
40
|
+
Start with the normal gem command:
|
41
|
+
|
42
|
+
gem install engineering
|
43
|
+
|
44
|
+
Unfortunately, this will either fail, or it will grab the wrong version of the *units* gem. But, not to worry, we can use bundler to fix it:
|
45
|
+
|
46
|
+
bundle install
|
47
|
+
|
48
|
+
And that's it. You're done. Get on with taking over the world already.
|
49
|
+
|
50
|
+
If you happen to be part of the 0.001% of Mad Engineers who don't already have bundler installed, it's very easy to get:
|
51
|
+
|
52
|
+
gem install bundler
|
53
|
+
|
54
|
+
### Using Rubygems
|
55
|
+
|
56
|
+
Sadly, the *units* gem hosted on [Rubygems](http://rubygems.org) is a bit out-of-date, and generally not the gem we're looking for. So, after *gem* does its thing, we need to do a little cleanup.
|
57
|
+
|
58
|
+
Start with the normal gem command:
|
59
|
+
|
60
|
+
gem install engineering
|
61
|
+
|
62
|
+
Then uninstall the bogus *units* gem:
|
63
|
+
|
64
|
+
gem uninstall units
|
65
|
+
|
66
|
+
Clone the gem we're looking for:
|
67
|
+
|
68
|
+
git clone git://github.com/bfoz/units.git
|
69
|
+
|
70
|
+
Install it:
|
71
|
+
|
72
|
+
cd units && rake install
|
73
|
+
|
74
|
+
You do have [rake](http://rake.rubyforge.org/) installed, right? If not, do this before the previous step:
|
75
|
+
|
76
|
+
gem install rake
|
77
|
+
|
78
|
+
And you should be good to go. If you made it through all of that, then I expect to hear about your machinations on the evening news any day now.
|
79
|
+
|
80
|
+
Examples
|
81
|
+
--------
|
82
|
+
|
83
|
+
Creating a custom Cube class, the hard way:
|
84
|
+
|
85
|
+
require 'engineering'
|
86
|
+
|
87
|
+
model :MyCube do
|
88
|
+
extrusion 10.cm do
|
89
|
+
square 10.cm
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
MyCube.new
|
94
|
+
|
95
|
+
Of course, this is ruby, so there's always another way to do it
|
96
|
+
|
97
|
+
extrusion :MyCube do
|
98
|
+
rectangle Size[10.cm, 10.cm]
|
99
|
+
end
|
100
|
+
|
101
|
+
MyCube.new length:10.cm
|
102
|
+
|
103
|
+
### Exporting
|
104
|
+
|
105
|
+
Once a Model has been defined, it can be instantiated and exported to SketchUp with a single line
|
106
|
+
|
107
|
+
SketchUp.write('MyCube.su', MyCube.new)
|
108
|
+
|
109
|
+
Then, launch SketchUp, open the _Ruby Console_ (it's in the Window menu), and _load 'MyCube.su'_. Your new geometry will replace whatever was already in the SketchUp document (a person if you just opened it), so be careful.
|
data/Rakefile
CHANGED
data/engineering.gemspec
CHANGED
@@ -2,22 +2,23 @@
|
|
2
2
|
$:.push File.expand_path("../lib", __FILE__)
|
3
3
|
|
4
4
|
Gem::Specification.new do |s|
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
5
|
+
s.name = "engineering"
|
6
|
+
s.version = 0.1
|
7
|
+
s.authors = ["Brandon Fosdick"]
|
8
|
+
s.email = ["bfoz@bfoz.net"]
|
9
|
+
s.homepage = "http://github.com/bfoz/engineering"
|
10
|
+
s.summary = %q{Mad Engineering, Ruby style}
|
11
|
+
s.description = %q{Tools for Mad Engineers and those who want to be}
|
12
12
|
|
13
|
-
|
13
|
+
s.rubyforge_project = "engineering"
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
15
|
+
s.files = `git ls-files`.split("\n")
|
16
|
+
s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
|
17
|
+
s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
|
18
|
+
s.require_paths = ["lib"]
|
19
19
|
|
20
|
-
|
21
|
-
|
22
|
-
|
20
|
+
s.add_dependency 'dxf'
|
21
|
+
s.add_dependency 'model'
|
22
|
+
s.add_dependency 'sketch'
|
23
|
+
s.add_dependency 'units', '>= 2'
|
23
24
|
end
|
data/lib/engineering.rb
CHANGED
@@ -1,3 +1,82 @@
|
|
1
|
+
require 'mathn'
|
2
|
+
|
3
|
+
require 'dxf'
|
4
|
+
require 'model'
|
5
|
+
require 'sketch'
|
6
|
+
require 'units'
|
7
|
+
|
8
|
+
require_relative 'sketchup'
|
9
|
+
|
10
|
+
=begin
|
11
|
+
A meta-gem for wayward engineering-related gems. Here you can find everything
|
12
|
+
you'll need for your latest engineering project.
|
13
|
+
=end
|
14
|
+
|
1
15
|
module Engineering
|
2
|
-
|
16
|
+
module DSL
|
17
|
+
private
|
18
|
+
|
19
|
+
# Create a new {Extrusion} subclass and initialize it with the given block
|
20
|
+
# @param [Symbol] symbol The name of the resulting subclass
|
21
|
+
# @return [Extrusion]
|
22
|
+
def extrusion(symbol=nil, &block)
|
23
|
+
klass = Class.new(Model::Extrusion)
|
24
|
+
klass.const_set(:INITIALIZER_BLOCK, block)
|
25
|
+
klass.class_eval %q[
|
26
|
+
def initialize(*args)
|
27
|
+
super
|
28
|
+
Model::Extrusion::Builder.new(self).evaluate(&INITIALIZER_BLOCK)
|
29
|
+
end
|
30
|
+
]
|
31
|
+
symbol ? Object.const_set(symbol, klass) : klass
|
32
|
+
end
|
33
|
+
|
34
|
+
# Create a new {Model} subclass and initialize it with the given block
|
35
|
+
# @param [Symbol] symbol The name of the {Model} subclass
|
36
|
+
# @return [Model]
|
37
|
+
def model(symbol=nil, &block)
|
38
|
+
klass = Class.new(Model)
|
39
|
+
klass.const_set(:INITIALIZER_BLOCK, block)
|
40
|
+
klass.class_eval %q[
|
41
|
+
def initialize(*args)
|
42
|
+
super
|
43
|
+
Model::Builder.new(self).evaluate(&INITIALIZER_BLOCK)
|
44
|
+
end
|
45
|
+
]
|
46
|
+
symbol ? Object.const_set(symbol, klass) : klass
|
47
|
+
end
|
48
|
+
|
49
|
+
# Create a new {Sketch} subclass and initialize it with the given block
|
50
|
+
# @param [Symbol] symbol The name of the {Sketch} subclass
|
51
|
+
def sketch(symbol=nil, &block)
|
52
|
+
klass = Class.new(Sketch)
|
53
|
+
klass.const_set(:INITIALIZER_BLOCK, block)
|
54
|
+
klass.class_eval %q[
|
55
|
+
def initialize(*args)
|
56
|
+
super
|
57
|
+
Sketch::Builder.new(self).evaluate(&INITIALIZER_BLOCK)
|
58
|
+
end
|
59
|
+
]
|
60
|
+
symbol ? Object.const_set(symbol, klass) : klass
|
61
|
+
end
|
62
|
+
|
63
|
+
class Geometry::Polygon
|
64
|
+
# Build a {Polygon} instance using the {Sketch} DSL
|
65
|
+
# @return [Polygon]
|
66
|
+
def self.build(&block)
|
67
|
+
Sketch::PolygonBuilder.new.evaluate(&block)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
class Geometry::Polyline
|
72
|
+
# Build a {Polyline} instance using the {Sketch} DSL
|
73
|
+
# @return [Polyline]
|
74
|
+
def self.build(&block)
|
75
|
+
Sketch::PolylineBuilder.new.evaluate(&block)
|
76
|
+
end
|
77
|
+
end
|
78
|
+
end
|
3
79
|
end
|
80
|
+
|
81
|
+
self.extend Engineering::DSL
|
82
|
+
include Geometry # Make Geometry types more readily available
|
data/lib/sketchup.rb
ADDED
@@ -0,0 +1,164 @@
|
|
1
|
+
require 'geometry'
|
2
|
+
require 'model'
|
3
|
+
require 'sketch'
|
4
|
+
require 'units'
|
5
|
+
|
6
|
+
module SketchUp
|
7
|
+
=begin
|
8
|
+
Export to a Ruby script that can be executed by SketchUp to recreate the geometry
|
9
|
+
=end
|
10
|
+
|
11
|
+
HEADER_LINES = [
|
12
|
+
'model = Sketchup.active_model',
|
13
|
+
'model.entities.clear!',
|
14
|
+
'model.definitions.purge_unused',
|
15
|
+
]
|
16
|
+
|
17
|
+
SKETCHUP_UNITS = {
|
18
|
+
'kilometer' => 'km', 'meter' => 'm', 'centimeter'=> 'cm', 'millimeter'=> 'mm',
|
19
|
+
'mile' => 'mile', 'yard' => 'yard', 'feet' => 'feet', 'inch' => 'inch',
|
20
|
+
'radian' => 'radians',
|
21
|
+
'degrees' => 'degrees',
|
22
|
+
}
|
23
|
+
|
24
|
+
class Builder
|
25
|
+
attr_accessor :container
|
26
|
+
|
27
|
+
# Initialize with a Sketch or a Model
|
28
|
+
def initialize(container=nil)
|
29
|
+
@container = container
|
30
|
+
@definition_names = {}
|
31
|
+
end
|
32
|
+
|
33
|
+
def to_a
|
34
|
+
a = to_array(@container) # Generates the definitions as a side effect
|
35
|
+
HEADER_LINES + @definition_names.values.flatten + a
|
36
|
+
end
|
37
|
+
|
38
|
+
def to_s
|
39
|
+
to_a.join("\n") << "\n"
|
40
|
+
end
|
41
|
+
|
42
|
+
private
|
43
|
+
|
44
|
+
def name_for_container(container)
|
45
|
+
case container
|
46
|
+
when Model::Extrusion
|
47
|
+
container.class.to_s + "(#{name_for_container(container.sketch)})_#{to_sketchup(container.length)}"
|
48
|
+
when Model::Group
|
49
|
+
container.class.to_s + "(#{container.object_id.to_s})"
|
50
|
+
when Model # !!! Must be after all subclasses of Model
|
51
|
+
s = container.class.to_s
|
52
|
+
(s == 'Model') ? s + "(#{container.object_id.to_s})" : s
|
53
|
+
when Sketch
|
54
|
+
s = container.class.to_s
|
55
|
+
(s == 'Sketch') ? s + ":#{container.object_id.to_s}" : s
|
56
|
+
end
|
57
|
+
end
|
58
|
+
|
59
|
+
def to_definition(container, definition_name)
|
60
|
+
case container
|
61
|
+
when Model::Extrusion
|
62
|
+
lines = to_array(container.sketch, 'd.entities').map {|l| "#{l}.pushpull(#{to_sketchup(-container.length)})"}
|
63
|
+
elements = lines.flatten.join("\n\t")
|
64
|
+
"lambda {|d|\n\t#{elements}\n}.call(model.definitions.add('#{definition_name}'))"
|
65
|
+
when Model::Group
|
66
|
+
lines = container.elements.map {|element| to_array(element, 'g.entities') }.flatten
|
67
|
+
elements = lines.flatten.join("\n\t")
|
68
|
+
"lambda {|g|\n\t#{elements}\n}.call(model.definitions.add('#{definition_name}'))"
|
69
|
+
when Model # !!! Must be after all subclasses of Model
|
70
|
+
elements = container.elements.map {|element| to_array(element, 'm.entities') }.flatten.join("\n\t")
|
71
|
+
"lambda {|m|\n\t#{elements}\n}.call(model.definitions.add('#{definition_name}'))"
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def add_instance(parent, container)
|
76
|
+
definition_name = name_for_container(container)
|
77
|
+
unless @definition_names.key?(definition_name)
|
78
|
+
@definition_names[definition_name] = to_definition(container, definition_name)
|
79
|
+
end
|
80
|
+
["#{parent}.add_instance(model.definitions['#{definition_name}'], #{to_sketchup(container.transformation)})"]
|
81
|
+
end
|
82
|
+
|
83
|
+
# Convert the given container to an array of strings that SketchUp can read
|
84
|
+
def to_array(container, parent='model.entities', transformation=nil)
|
85
|
+
case container
|
86
|
+
when Model::Extrusion
|
87
|
+
if container.transformation and not container.transformation.identity?
|
88
|
+
add_instance(parent, container)
|
89
|
+
else
|
90
|
+
to_array(container.sketch, parent, container.transformation).map {|l| "#{l}.pushpull(#{to_sketchup(-container.length)})"}
|
91
|
+
end
|
92
|
+
when Model::Group
|
93
|
+
if container.transformation and not container.transformation.identity?
|
94
|
+
add_instance(parent, container)
|
95
|
+
else
|
96
|
+
container.elements.map {|element| to_array(element, parent) }.flatten
|
97
|
+
end
|
98
|
+
when Model # !!! Must be after all subclasses of Model
|
99
|
+
if container.transformation and not container.transformation.identity?
|
100
|
+
add_instance(parent, container)
|
101
|
+
else
|
102
|
+
container.elements.map {|element| to_array(element, parent) }.flatten
|
103
|
+
end
|
104
|
+
when Sketch
|
105
|
+
container.geometry.map {|element| to_sketchup(element, parent, transformation) }
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
# Convert the given entity to a string that SketchUp can read
|
110
|
+
def to_sketchup(entity, parent='model.entities', transformation=nil)
|
111
|
+
case entity
|
112
|
+
when Array
|
113
|
+
entity.map {|v| to_sketchup(v, parent, transformation) }.join(', ')
|
114
|
+
when Geometry::Arc
|
115
|
+
"#{parent}.add_arc(#{to_sketchup(entity.center)}, [1,0,0], [0,0,1], #{to_sketchup(entity.radius)}, #{to_sketchup(entity.start_angle)}, #{to_sketchup(entity.end_angle)})"
|
116
|
+
when Geometry::Circle
|
117
|
+
"lambda{ points = #{parent}.add_circle(#{to_sketchup(entity.center)}, [0,0,1], #{to_sketchup(entity.radius)}); points[0].find_faces; points[0].faces[0]}.call"
|
118
|
+
when Geometry::Edge
|
119
|
+
"#{parent}.add_edges(#{to_sketchup(entity.first)}, #{to_sketchup(entity.last)})"
|
120
|
+
when Geometry::Line
|
121
|
+
"#{parent}.add_line(#{to_sketchup(entity.first)}, #{to_sketchup(entity.last)})"
|
122
|
+
when Geometry::Path
|
123
|
+
edges = entity.elements.map {|e| to_sketchup(e, parent, transformation) }.flatten.join '+'
|
124
|
+
"#{parent}.add_face(#{edges})"
|
125
|
+
when Geometry::Polyline
|
126
|
+
vertices = entity.vertices.map {|v| to_sketchup(v, parent, transformation) }.join ', '
|
127
|
+
method = entity.is_a?(Geometry::Polygon) ? 'add_face' : 'add_curve'
|
128
|
+
"#{parent}.#{method}(#{vertices})"
|
129
|
+
when Geometry::Point
|
130
|
+
if transformation and not transformation.identity?
|
131
|
+
'Geom::Point3d.new(' + to_sketchup(entity.to_a) + ').transform!(' + to_sketchup(transformation) + ')'
|
132
|
+
else
|
133
|
+
'[' + to_sketchup(entity.to_a) + ']'
|
134
|
+
end
|
135
|
+
when Geometry::Polygon
|
136
|
+
"#{parent}.add_face(#{to_sketchup(entity.points, parent, transformation)})"
|
137
|
+
when Geometry::Rectangle
|
138
|
+
"#{parent}.add_face(#{to_sketchup(entity.points, parent, transformation)})"
|
139
|
+
when Geometry::Transformation
|
140
|
+
pt = '[' + (entity.translation ? to_sketchup(entity.translation.to_a) : '0,0,0') + ']'
|
141
|
+
x_axis = '[' + (entity.rotation.x ? to_sketchup(entity.rotation.x.to_a) : '1,0,0') + ']'
|
142
|
+
y_axis = '[' + (entity.rotation.y ? to_sketchup(entity.rotation.y.to_a) : '0,1,0') + ']'
|
143
|
+
"Geom::Transformation.new(#{[pt,x_axis,y_axis].join(',')})"
|
144
|
+
when Geometry::Triangle
|
145
|
+
"#{parent}.add_face(#{to_sketchup(entity.points, parent, transformation)})"
|
146
|
+
when Float
|
147
|
+
entity.to_s
|
148
|
+
when Rational
|
149
|
+
[entity.to_f, entity.respond_to?(:units) ? entity.units : nil].compact.map {|a| to_sketchup(a)}.join '.'
|
150
|
+
when Units
|
151
|
+
s = entity.to_s
|
152
|
+
SKETCHUP_UNITS[s] or raise "SketchUp won't recognize '#{s}'"
|
153
|
+
when Units::Literal
|
154
|
+
[entity.value, entity.units].compact.map {|a| to_sketchup(a)}.join '.'
|
155
|
+
else
|
156
|
+
entity.to_s
|
157
|
+
end
|
158
|
+
end
|
159
|
+
end
|
160
|
+
|
161
|
+
def self.write(filename, container)
|
162
|
+
File.write(filename, Builder.new(container).to_s)
|
163
|
+
end
|
164
|
+
end
|
data/test/engineering.rb
ADDED
@@ -0,0 +1,203 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'engineering'
|
3
|
+
|
4
|
+
#LENGTH = 42
|
5
|
+
|
6
|
+
describe Engineering do
|
7
|
+
include Engineering::DSL
|
8
|
+
|
9
|
+
after do
|
10
|
+
# Cleanup the class constants created by each test
|
11
|
+
ObjectSpace.each_object(Class).select {|k| (k < Model) or (k < Sketch)}.each {|klass|
|
12
|
+
begin
|
13
|
+
Object.send(:remove_const, klass.name.to_sym)
|
14
|
+
rescue NameError
|
15
|
+
end
|
16
|
+
}
|
17
|
+
end
|
18
|
+
|
19
|
+
describe "when creating a named Model subclass" do
|
20
|
+
before do
|
21
|
+
model :TestModel do
|
22
|
+
extrude length:10 do
|
23
|
+
square 5
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
let(:testModel) { TestModel.new }
|
28
|
+
|
29
|
+
it "must create a global constant" do
|
30
|
+
Object.constants.include?(:TestModel).must_equal true
|
31
|
+
end
|
32
|
+
|
33
|
+
it "must support creating instances of the subclass" do
|
34
|
+
TestModel.new.must_be_kind_of Model
|
35
|
+
TestModel.new.must_be_kind_of TestModel
|
36
|
+
end
|
37
|
+
|
38
|
+
it "must call the initializer block when constructed" do
|
39
|
+
TestModel.new.elements.count.must_equal 1
|
40
|
+
TestModel.new.elements.first.must_be_instance_of Model::Extrusion
|
41
|
+
TestModel.new.elements.first.length.must_equal 10
|
42
|
+
end
|
43
|
+
|
44
|
+
describe "when another model class is created with a new name" do
|
45
|
+
before do
|
46
|
+
model :TestModel2 do
|
47
|
+
extrude length:5 do
|
48
|
+
square 10
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
let(:testModel2) { TestModel2.new }
|
53
|
+
|
54
|
+
it "must be able to make new instances" do
|
55
|
+
testModel2.must_be_kind_of Model
|
56
|
+
testModel2.must_be_instance_of TestModel2
|
57
|
+
testModel2.wont_be_instance_of TestModel
|
58
|
+
end
|
59
|
+
|
60
|
+
it "must call the correct initializer block when constructed" do
|
61
|
+
testModel2.elements.count.must_equal 1
|
62
|
+
testModel2.elements.first.must_be_instance_of Model::Extrusion
|
63
|
+
testModel2.elements.first.length.must_equal 5
|
64
|
+
end
|
65
|
+
|
66
|
+
describe "when the original Model class is used again" do
|
67
|
+
let(:anotherTestModel) { TestModel.new }
|
68
|
+
|
69
|
+
it "must call the correct initializer block when constructed" do
|
70
|
+
anotherTestModel.elements.count.must_equal 1
|
71
|
+
anotherTestModel.elements.first.must_be_instance_of Model::Extrusion
|
72
|
+
anotherTestModel.elements.first.length.must_equal 10
|
73
|
+
end
|
74
|
+
end
|
75
|
+
end
|
76
|
+
end
|
77
|
+
|
78
|
+
describe "when creating an Extrusion subclass" do
|
79
|
+
after do
|
80
|
+
Object.send(:remove_const, :TestExtrusion)
|
81
|
+
end
|
82
|
+
|
83
|
+
before do
|
84
|
+
extrusion :TestExtrusion do
|
85
|
+
square 5
|
86
|
+
end
|
87
|
+
end
|
88
|
+
|
89
|
+
it "must create a global constant" do
|
90
|
+
Object.constants.include?(:TestExtrusion).must_equal true
|
91
|
+
end
|
92
|
+
|
93
|
+
it "must be a subclass of Extrusion" do
|
94
|
+
(TestExtrusion < Model::Extrusion).must_equal true
|
95
|
+
end
|
96
|
+
|
97
|
+
describe "when initializing a new instance" do
|
98
|
+
subject { TestExtrusion.new(length: 5) }
|
99
|
+
|
100
|
+
it "must create instances of the proper class" do
|
101
|
+
subject.must_be_kind_of Model::Extrusion
|
102
|
+
end
|
103
|
+
|
104
|
+
it "must call the initializer block" do
|
105
|
+
subject.length.must_equal 5
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
|
110
|
+
describe "when creating a Model that uses global constants" do
|
111
|
+
before do
|
112
|
+
LENGTH = 5
|
113
|
+
model :TestModel3 do
|
114
|
+
extrude length: LENGTH do
|
115
|
+
square 5
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
it "must not complain" do
|
121
|
+
TestModel3.new
|
122
|
+
end
|
123
|
+
|
124
|
+
end
|
125
|
+
|
126
|
+
describe "when creating a named Sketch subclass" do
|
127
|
+
before do
|
128
|
+
sketch :TestSketch do
|
129
|
+
square 5
|
130
|
+
end
|
131
|
+
end
|
132
|
+
let(:testSketch) { TestSketch.new }
|
133
|
+
|
134
|
+
it "must create a global constant" do
|
135
|
+
Object.constants.include?(:TestSketch).must_equal true
|
136
|
+
end
|
137
|
+
|
138
|
+
it "must support creating instances of the subclass" do
|
139
|
+
testSketch.must_be_kind_of Sketch
|
140
|
+
testSketch.must_be_kind_of TestSketch
|
141
|
+
end
|
142
|
+
|
143
|
+
it "must call the initializer block when constructed" do
|
144
|
+
testSketch.elements.count.must_equal 1
|
145
|
+
testSketch.elements.first.must_be_kind_of Geometry::Square
|
146
|
+
end
|
147
|
+
|
148
|
+
describe "when another sketch class is created with a new name" do
|
149
|
+
before do
|
150
|
+
sketch :TestSketch2 do
|
151
|
+
square 10
|
152
|
+
end
|
153
|
+
end
|
154
|
+
let(:testSketch2) { TestSketch2.new }
|
155
|
+
|
156
|
+
it "must be able to make new instances" do
|
157
|
+
testSketch2.must_be_kind_of Sketch
|
158
|
+
testSketch2.must_be_kind_of TestSketch2
|
159
|
+
testSketch2.wont_be_kind_of TestSketch
|
160
|
+
end
|
161
|
+
|
162
|
+
it "must call the correct initializer block when constructed" do
|
163
|
+
testSketch2.elements.count.must_equal 1
|
164
|
+
testSketch2.elements.first.must_be_kind_of Geometry::Square
|
165
|
+
end
|
166
|
+
|
167
|
+
describe "when the original Sketch class is used again" do
|
168
|
+
let(:anotherTestSketch) { TestSketch.new }
|
169
|
+
|
170
|
+
it "must call the correct initializer block when constructed" do
|
171
|
+
anotherTestSketch.elements.count.must_equal 1
|
172
|
+
anotherTestSketch.elements.first.must_be_kind_of Geometry::Square
|
173
|
+
end
|
174
|
+
end
|
175
|
+
end
|
176
|
+
end
|
177
|
+
|
178
|
+
describe "when creating a Polygon" do
|
179
|
+
it "must create a Polygon" do
|
180
|
+
polygon = Polygon.build do
|
181
|
+
start_at [0,0]
|
182
|
+
right 1
|
183
|
+
up 1
|
184
|
+
left 1
|
185
|
+
down 1
|
186
|
+
end
|
187
|
+
polygon.must_be_instance_of(Geometry::Polygon)
|
188
|
+
end
|
189
|
+
end
|
190
|
+
|
191
|
+
describe "when creating a Polyline" do
|
192
|
+
it "must create a Polyline" do
|
193
|
+
polyline = Polyline.build do
|
194
|
+
start_at [0,0]
|
195
|
+
right 1
|
196
|
+
up 1
|
197
|
+
left 1
|
198
|
+
down 1
|
199
|
+
end
|
200
|
+
polyline.must_be_instance_of(Geometry::Polyline)
|
201
|
+
end
|
202
|
+
end
|
203
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
model = Sketchup.active_model
|
2
|
+
model.entities.clear!
|
3
|
+
model.definitions.purge_unused
|
4
|
+
lambda {|d|
|
5
|
+
d.entities.add_face\(\[-5.0, -10.0\], \[-5.0, 10.0\], \[5.0, 10.0\], \[5.0, -10.0\]\).pushpull\(-5\)
|
6
|
+
}.call\(model.definitions.add\('Model::Extrusion\(Sketch:\d+\)_5'\)\)
|
7
|
+
model.entities.add_instance\(model.definitions\['Model::Extrusion\(Sketch:\d+\)_5'\], Geom::Transformation.new\(\[1, 2, 3\],\[1,0,0\],\[0,1,0\]\)\)
|
data/test/geometry.rb
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'geometry'
|
3
|
+
require 'units'
|
4
|
+
|
5
|
+
# This is a bit of integration testing to ensure that the Units gem doesn't break
|
6
|
+
# any of the other gems. None of the individual gems know about each other so
|
7
|
+
# there's no way to test their integration at a lower level.
|
8
|
+
|
9
|
+
describe Geometry do
|
10
|
+
let(:pointA) { Point[2.meters, 3.meters] }
|
11
|
+
let(:pointB) { Point[4.meters, 5.meters] }
|
12
|
+
let(:sizeA) { Size[2.meters, 3.meters] }
|
13
|
+
let(:sizeB) { Size[4.meters, 5.meters] }
|
14
|
+
|
15
|
+
describe "Point and Size arithmetic" do
|
16
|
+
it "should add" do
|
17
|
+
sum = (pointA + sizeA)
|
18
|
+
sum.must_be_instance_of(Point)
|
19
|
+
sum.must_equal Point[4.meters, 6.meters]
|
20
|
+
end
|
21
|
+
end
|
22
|
+
end
|
@@ -0,0 +1,23 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'geometry'
|
3
|
+
require 'units'
|
4
|
+
|
5
|
+
# This is a bit of integration testing to ensure that the Units gem doesn't break
|
6
|
+
# any of the other gems. None of the individual gems know about each other so
|
7
|
+
# there's no way to test their integration at a lower level.
|
8
|
+
|
9
|
+
describe Geometry::Edge do
|
10
|
+
Edge = Geometry::Edge
|
11
|
+
|
12
|
+
let(:pointA) { Point[2.meters, 3.meters] }
|
13
|
+
let(:pointB) { Point[4.meters, 5.meters] }
|
14
|
+
|
15
|
+
describe "should construct an Edge from Points with Units" do
|
16
|
+
let(:edge) { Edge.new(pointA, pointB) }
|
17
|
+
|
18
|
+
it "should preserve the units" do
|
19
|
+
edge.first.must_equal Point[2.meters, 3.meters]
|
20
|
+
edge.last.must_equal Point[4.meters, 5.meters]
|
21
|
+
end
|
22
|
+
end
|
23
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'geometry'
|
3
|
+
require 'units'
|
4
|
+
|
5
|
+
# This is a bit of integration testing to ensure that the Units gem doesn't break
|
6
|
+
# any of the other gems. None of the individual gems know about each other so
|
7
|
+
# there's no way to test their integration at a lower level.
|
8
|
+
|
9
|
+
describe Geometry::Point do
|
10
|
+
Point = Geometry::Point
|
11
|
+
|
12
|
+
it "should not break normal Point construction" do
|
13
|
+
Point[1,2].must_be_instance_of(Point)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "when the elements have units" do
|
17
|
+
let(:pointA) { Point[2.meters, 3.meters] }
|
18
|
+
let(:pointB) { Point[4.meters, 5.meters] }
|
19
|
+
|
20
|
+
describe "arithmetic" do
|
21
|
+
it "should add" do
|
22
|
+
(pointA+pointB).must_equal Point[6.meters, 8.meters]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should subtract" do
|
26
|
+
(pointB-pointA).must_equal Point[2.meters, 2.meters]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should multiply by a constant" do
|
30
|
+
(pointA * 2).must_equal Point[4.meters, 6.meters]
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should divide by a constant" do
|
34
|
+
(pointB / 2).must_equal Point[2.meters, 2.5.meters]
|
35
|
+
(pointB / 2.0).must_equal Point[2.0.meters, 2.5.meters]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,39 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'geometry'
|
3
|
+
require 'units'
|
4
|
+
|
5
|
+
# This is a bit of integration testing to ensure that the Units gem doesn't break
|
6
|
+
# any of the other gems. None of the individual gems know about each other so
|
7
|
+
# there's no way to test their integration at a lower level.
|
8
|
+
|
9
|
+
describe Geometry::Size do
|
10
|
+
Size = Geometry::Size
|
11
|
+
|
12
|
+
it "should not break normal Size construction" do
|
13
|
+
Size[1,2].must_be_instance_of(Size)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "when the elements have units" do
|
17
|
+
let(:sizeA) { Size[2.meters, 3.meters] }
|
18
|
+
let(:sizeB) { Size[4.meters, 5.meters] }
|
19
|
+
|
20
|
+
describe "arithmetic" do
|
21
|
+
it "should add" do
|
22
|
+
(sizeA+sizeB).must_equal Size[6.meters, 8.meters]
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should subtract" do
|
26
|
+
(sizeB-sizeA).must_equal Size[2.meters, 2.meters]
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should multiply by a constant" do
|
30
|
+
(sizeA * 2).must_equal Size[4.meters, 6.meters]
|
31
|
+
end
|
32
|
+
|
33
|
+
it "should divide by a constant" do
|
34
|
+
(sizeB / 2).must_equal Size[2.meters, 2.5.meters]
|
35
|
+
(sizeB / 2.0).must_equal Size[2.0.meters, 2.5.meters]
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'model/builder'
|
3
|
+
require 'units'
|
4
|
+
|
5
|
+
# This is a bit of integration testing to ensure that the Units gem doesn't break
|
6
|
+
# any of the other gems. None of the individual gems know about each other so
|
7
|
+
# there's no way to test their integration at a lower level.
|
8
|
+
|
9
|
+
describe Model::Builder do
|
10
|
+
Builder = Model::Builder
|
11
|
+
|
12
|
+
let(:builder) { Builder.new }
|
13
|
+
|
14
|
+
describe "when adding an Extrusion with a length with units" do
|
15
|
+
before do
|
16
|
+
builder.evaluate do
|
17
|
+
extrude length:10.meters, sketch:Sketch.new do
|
18
|
+
rectangle 5, 6
|
19
|
+
end
|
20
|
+
end
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should have an Extrusion element" do
|
24
|
+
builder.model.elements.last.must_be_instance_of Model::Extrusion
|
25
|
+
builder.model.elements.last.length.must_equal 10.meters
|
26
|
+
end
|
27
|
+
|
28
|
+
it "should make a Rectangle in the Extrusion's Sketch" do
|
29
|
+
extrusion = builder.model.elements.last
|
30
|
+
sketch = extrusion.sketch
|
31
|
+
sketch.elements.last.must_be_kind_of Geometry::Rectangle
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'model/extrusion'
|
3
|
+
require 'units'
|
4
|
+
|
5
|
+
# This is a bit of integration testing to ensure that the Units gem doesn't break
|
6
|
+
# any of the other gems. None of the individual gems know about each other so
|
7
|
+
# there's no way to test their integration at a lower level.
|
8
|
+
|
9
|
+
describe Model::Extrusion do
|
10
|
+
Extrusion = Model::Extrusion
|
11
|
+
|
12
|
+
it "must not break normal construction" do
|
13
|
+
Extrusion.new(length:5, sketch:Sketch.new).must_be_instance_of(Extrusion)
|
14
|
+
end
|
15
|
+
|
16
|
+
describe "when the length parameter has units" do
|
17
|
+
let(:extrusionA) { Extrusion.new length:5.meters, sketch:Sketch.new }
|
18
|
+
|
19
|
+
it "must preserve the units" do
|
20
|
+
extrusionA.length.must_equal 5.meters
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
describe "when the length parameter is a variable with units" do
|
25
|
+
let(:length) { 6.meters }
|
26
|
+
let(:extrusionA) { Extrusion.new length:6.meters, sketch:Sketch.new }
|
27
|
+
|
28
|
+
it "must preserve the units" do
|
29
|
+
extrusionA.length.must_equal 6.meters
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
data/test/sketchup.rb
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'sketchup'
|
3
|
+
|
4
|
+
describe SketchUp::Builder do
|
5
|
+
subject { SketchUp::Builder.new }
|
6
|
+
|
7
|
+
before do
|
8
|
+
@builder = SketchUp::Builder.new
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:empty_fixture) { File.read('test/fixtures/sketchup/empty.su') }
|
12
|
+
let(:rectangle_sketch_fixture) { File.read('test/fixtures/sketchup/rectangle_sketch.su') }
|
13
|
+
|
14
|
+
it "should keep private methods private" do
|
15
|
+
@builder.wont_respond_to :to_array
|
16
|
+
@builder.wont_respond_to :to_sketchup
|
17
|
+
end
|
18
|
+
|
19
|
+
it "should not break Point's to_s method" do
|
20
|
+
5.cm.to_s.must_equal "5"
|
21
|
+
end
|
22
|
+
|
23
|
+
it "should not break Point's inspect method" do
|
24
|
+
5.cm.inspect.must_equal "5 centimeter"
|
25
|
+
end
|
26
|
+
|
27
|
+
describe "when given an empty Model object" do
|
28
|
+
before do
|
29
|
+
model = Model.new
|
30
|
+
model.add_extrusion Model::Extrusion.new(length:5, sketch:Sketch.new)
|
31
|
+
@builder.container = model
|
32
|
+
end
|
33
|
+
|
34
|
+
it "should export the correct file" do
|
35
|
+
@builder.to_s.must_equal empty_fixture
|
36
|
+
end
|
37
|
+
end
|
38
|
+
|
39
|
+
describe "when given a Model of a translated Extrusion" do
|
40
|
+
sketch = Sketch.new
|
41
|
+
sketch.add_rectangle 10, 20
|
42
|
+
before do
|
43
|
+
subject.container = Model.new do
|
44
|
+
add_extrusion Model::Extrusion.new(length:5, sketch:sketch, transformation:Geometry::Transformation.new(origin:[1,2,3]))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
it "must generate the correct text" do
|
49
|
+
subject.to_s.must_match Regexp.new(File.read('test/fixtures/translated_extrusion.su'))
|
50
|
+
end
|
51
|
+
end
|
52
|
+
|
53
|
+
it "should generate the correct text from a Model of a simple extrusion" do
|
54
|
+
sketch = Sketch.new
|
55
|
+
sketch.add_rectangle 10, 20
|
56
|
+
model = Model.new do
|
57
|
+
add_extrusion Model::Extrusion.new(length:5, sketch:sketch)
|
58
|
+
end
|
59
|
+
@builder.container = model
|
60
|
+
@builder.to_s.must_equal File.read('test/fixtures/sketchup/simple_extrusion.su')
|
61
|
+
end
|
62
|
+
|
63
|
+
it "should generate the correct text from a Model of a simple extrusion with units" do
|
64
|
+
sketch = Sketch.new
|
65
|
+
sketch.add_rectangle 1.meter, 10
|
66
|
+
model = Model.new
|
67
|
+
model.add_extrusion Model::Extrusion.new(length:5.meters, sketch:sketch)
|
68
|
+
@builder.container = model
|
69
|
+
@builder.to_s.must_equal File.read('test/fixtures/sketchup/simple_extrusion_units.su')
|
70
|
+
end
|
71
|
+
|
72
|
+
it "should generate correct text from an empty Sketch" do
|
73
|
+
@builder.container = Sketch.new
|
74
|
+
@builder.to_s.must_equal empty_fixture
|
75
|
+
end
|
76
|
+
|
77
|
+
it "should generate correct text from a simple Sketch object" do
|
78
|
+
sketch = Sketch.new
|
79
|
+
sketch.add_line [0,0], [1,0]
|
80
|
+
@builder.container = sketch
|
81
|
+
@builder.to_s.must_equal File.read('test/fixtures/sketchup/line_sketch.su')
|
82
|
+
end
|
83
|
+
|
84
|
+
it "should generate correct text from a Sketch object with a single Rectangle" do
|
85
|
+
sketch = Sketch.new
|
86
|
+
sketch.add_rectangle [0,0], Geometry::Size[1,1]
|
87
|
+
@builder.container = sketch
|
88
|
+
@builder.to_s.must_equal rectangle_sketch_fixture
|
89
|
+
end
|
90
|
+
|
91
|
+
it "should generate correct text from a Sketch object with a single Polygon" do
|
92
|
+
sketch = Sketch.new
|
93
|
+
sketch.add_polygon [0,0], [0,1], [1,1], [1,0], [0,0]
|
94
|
+
@builder.container = sketch
|
95
|
+
@builder.to_s.must_equal rectangle_sketch_fixture
|
96
|
+
end
|
97
|
+
|
98
|
+
it "must handle a Group" do
|
99
|
+
builder = SketchUp::Builder.new( Model::Builder.new.evaluate { group :origin => [1,2,3] })
|
100
|
+
builder.container.elements.count.must_equal 1
|
101
|
+
builder.container.elements.first.must_be_instance_of(Model::Group)
|
102
|
+
builder.to_s.must_match %r{model = Sketchup.active_model\nmodel.entities.clear!\nmodel.definitions.purge_unused\nlambda {|g|\n\t\n}.call(model.definitions.add('Model::Group()'))\nmodel.entities.add_instance(model.definitions\['Model::Group(\d+)'\], Geom::Transformation.new(\[1, 2, 3\],\[1,0,0\],\[0,1,0\]))}
|
103
|
+
end
|
104
|
+
|
105
|
+
it "must handle a sub-model" do
|
106
|
+
builder = SketchUp::Builder.new( Model::Builder.new.evaluate { push Model.new, :origin => [3,2,1] })
|
107
|
+
builder.container.elements.count.must_equal 1
|
108
|
+
builder.container.elements.first.must_be_instance_of(Model)
|
109
|
+
builder.to_s.must_match %r{model = Sketchup.active_model\nmodel.entities.clear!\nmodel.definitions.purge_unused\nlambda {|m|\n\t\n}.call(model.definitions.add('Model(\d+)'))\nmodel.entities.add_instance(model.definitions\['Model(\d+)'\], Geom::Transformation.new(\[3, 2, 1\],\[1,0,0\],\[0,1,0\]))}
|
110
|
+
end
|
111
|
+
|
112
|
+
it "Path" do
|
113
|
+
sketch = Sketch.new
|
114
|
+
sketch.add_path [0,0], Geometry::Arc.new([0,0],5,0,90*Math::PI/180), [0,0]
|
115
|
+
builder = SketchUp::Builder.new( Model::Builder.new.evaluate { extrude length:5, sketch:sketch })
|
116
|
+
end
|
117
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
require 'minitest/autorun'
|
2
|
+
require 'mathn'
|
3
|
+
require 'units'
|
4
|
+
|
5
|
+
# This is a bit of integration testing to ensure that the mathn gem doesn't break
|
6
|
+
# the units gems. Mathn changes a number of the default arithmetic operators,
|
7
|
+
# which tends to cause trouble for Units. Neither gem knows about the other so
|
8
|
+
# there's no good way to test their integration at a lower level.
|
9
|
+
|
10
|
+
def Literal(*args)
|
11
|
+
Units::Literal.new(*args)
|
12
|
+
end
|
13
|
+
|
14
|
+
describe Units::Literal do
|
15
|
+
let(:one_meter) { Literal(1, :meter) }
|
16
|
+
let(:three_meters) { Literal(3, :meters) }
|
17
|
+
let(:four_meters) { Literal(4, :meters) }
|
18
|
+
|
19
|
+
describe "coerced arithmetic" do
|
20
|
+
it "division" do
|
21
|
+
(0 / one_meter).must_equal 0
|
22
|
+
(0 / three_meters).must_equal 0
|
23
|
+
# (4 / three_meters).must_equal Rational(4,3).meters
|
24
|
+
(12.0 / three_meters).must_equal four_meters
|
25
|
+
end
|
26
|
+
|
27
|
+
it "must divide a Rational" do
|
28
|
+
(Rational(2,1) / one_meter).must_equal Rational(2,1).meters(-1)
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: engineering
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: '0'
|
4
|
+
version: '0.1'
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,9 +9,73 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date:
|
13
|
-
dependencies:
|
14
|
-
|
12
|
+
date: 2013-04-21 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: dxf
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
- !ruby/object:Gem::Dependency
|
31
|
+
name: model
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
33
|
+
none: false
|
34
|
+
requirements:
|
35
|
+
- - ! '>='
|
36
|
+
- !ruby/object:Gem::Version
|
37
|
+
version: '0'
|
38
|
+
type: :runtime
|
39
|
+
prerelease: false
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
name: sketch
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
49
|
+
none: false
|
50
|
+
requirements:
|
51
|
+
- - ! '>='
|
52
|
+
- !ruby/object:Gem::Version
|
53
|
+
version: '0'
|
54
|
+
type: :runtime
|
55
|
+
prerelease: false
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
62
|
+
- !ruby/object:Gem::Dependency
|
63
|
+
name: units
|
64
|
+
requirement: !ruby/object:Gem::Requirement
|
65
|
+
none: false
|
66
|
+
requirements:
|
67
|
+
- - ! '>='
|
68
|
+
- !ruby/object:Gem::Version
|
69
|
+
version: '2'
|
70
|
+
type: :runtime
|
71
|
+
prerelease: false
|
72
|
+
version_requirements: !ruby/object:Gem::Requirement
|
73
|
+
none: false
|
74
|
+
requirements:
|
75
|
+
- - ! '>='
|
76
|
+
- !ruby/object:Gem::Version
|
77
|
+
version: '2'
|
78
|
+
description: Tools for Mad Engineers and those who want to be
|
15
79
|
email:
|
16
80
|
- bfoz@bfoz.net
|
17
81
|
executables: []
|
@@ -20,10 +84,22 @@ extra_rdoc_files: []
|
|
20
84
|
files:
|
21
85
|
- .gitignore
|
22
86
|
- Gemfile
|
23
|
-
- README
|
87
|
+
- README.markdown
|
24
88
|
- Rakefile
|
25
89
|
- engineering.gemspec
|
26
90
|
- lib/engineering.rb
|
91
|
+
- lib/sketchup.rb
|
92
|
+
- test/engineering.rb
|
93
|
+
- test/fixtures/translated_extrusion.su
|
94
|
+
- test/geometry.rb
|
95
|
+
- test/geometry/edge.rb
|
96
|
+
- test/geometry/point.rb
|
97
|
+
- test/geometry/size.rb
|
98
|
+
- test/model/builder.rb
|
99
|
+
- test/model/extrusion.rb
|
100
|
+
- test/sketchup.rb
|
101
|
+
- test/sketchup/builder.rb
|
102
|
+
- test/units/literal.rb
|
27
103
|
homepage: http://github.com/bfoz/engineering
|
28
104
|
licenses: []
|
29
105
|
post_install_message:
|
@@ -44,9 +120,20 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
44
120
|
version: '0'
|
45
121
|
requirements: []
|
46
122
|
rubyforge_project: engineering
|
47
|
-
rubygems_version: 1.8.
|
123
|
+
rubygems_version: 1.8.25
|
48
124
|
signing_key:
|
49
125
|
specification_version: 3
|
50
|
-
summary: Engineering
|
51
|
-
test_files:
|
126
|
+
summary: Mad Engineering, Ruby style
|
127
|
+
test_files:
|
128
|
+
- test/engineering.rb
|
129
|
+
- test/fixtures/translated_extrusion.su
|
130
|
+
- test/geometry.rb
|
131
|
+
- test/geometry/edge.rb
|
132
|
+
- test/geometry/point.rb
|
133
|
+
- test/geometry/size.rb
|
134
|
+
- test/model/builder.rb
|
135
|
+
- test/model/extrusion.rb
|
136
|
+
- test/sketchup.rb
|
137
|
+
- test/sketchup/builder.rb
|
138
|
+
- test/units/literal.rb
|
52
139
|
has_rdoc:
|
data/README
DELETED
File without changes
|