engineering 0 → 0.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|