floorplanner-fml 0.2 → 0.2.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/.gitignore +8 -0
- data/Rakefile +3 -0
- data/bin/fml2dae.rb +1 -1
- data/bin/fml2obj.rb +1 -1
- data/fml.gemspec +36 -0
- data/lib/floorplanner/area_builder.rb +1 -1
- data/lib/floorplanner/asset.rb +2 -2
- data/lib/floorplanner/collada_export.rb +4 -4
- data/lib/floorplanner/design.rb +2 -2
- data/lib/floorplanner/document.rb +1 -1
- data/lib/floorplanner/opening3d.rb +3 -3
- data/lib/floorplanner/wall_builder.rb +1 -1
- data/lib/geom/ear_trim.rb +2 -2
- data/lib/geom/glu_tess.rb +34 -0
- data/lib/geom/intersection.rb +1 -1
- data/lib/geom/matrix3d.rb +1 -1
- data/lib/geom/number.rb +5 -5
- data/lib/geom/polygon.rb +11 -11
- data/tasks/github-gem.rake +315 -0
- data/xml/fml2kml.xsl +59 -0
- metadata +38 -32
data/.gitignore
ADDED
data/Rakefile
ADDED
data/bin/fml2dae.rb
CHANGED
@@ -3,7 +3,7 @@ $: << File.join(File.dirname(__FILE__), "/../lib" )
|
|
3
3
|
require 'floorplanner'
|
4
4
|
|
5
5
|
if ARGV.length < 2
|
6
|
-
puts "\n Usage: fml2dae.rb [-xrefs] design_id|design_name path/to/fml out.dae"
|
6
|
+
puts "\n Usage: fml2dae.rb [-xrefs] design_id|design_name path/to/fml out.dae"
|
7
7
|
else
|
8
8
|
xrefs = false
|
9
9
|
if ARGV[0] == "-xrefs"
|
data/bin/fml2obj.rb
CHANGED
@@ -3,7 +3,7 @@ $: << File.join(File.dirname(__FILE__), "/../lib" )
|
|
3
3
|
require 'floorplanner'
|
4
4
|
|
5
5
|
if ARGV.length < 2
|
6
|
-
puts "\n Usage: fml2dae.rb design_id path/to/fml"
|
6
|
+
puts "\n Usage: fml2dae.rb design_id path/to/fml"
|
7
7
|
else
|
8
8
|
doc = Floorplanner::Document.new(ARGV[1])
|
9
9
|
doc.to_obj(ARGV[0],ARGV[2])
|
data/fml.gemspec
ADDED
@@ -0,0 +1,36 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = "fml"
|
5
|
+
s.version = "0.2.1"
|
6
|
+
s.date = "2009-09-23"
|
7
|
+
|
8
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 1.3.0") if s.respond_to? :required_rubygems_version=
|
9
|
+
|
10
|
+
s.authors = ["Dusan Maliarik"]
|
11
|
+
s.description = %q{Floor plan document toolkit}
|
12
|
+
s.email = %q{dusan.maliarik@gmail.com}
|
13
|
+
s.executables = ["fml2dae.rb","fml2obj.rb"]
|
14
|
+
s.files = %w(lib/keyhole/archive.rb lib/geom/plane.rb lib/floorplanner/area_builder.rb bin/fml2dae.rb .gitignore xml/fml2kml.xsl xml/collada_schema_1_4.xsd lib/geom/number.rb lib/geom/connection.rb lib/floorplanner/design.rb lib/floorplanner/collada_export.rb lib/geom/polygon.rb lib/geom.rb lib/floorplanner/asset.rb xml/fml.rng views/design.rib.erb lib/geom/matrix3d.rb lib/geom/ear_trim.rb lib/floorplanner/obj_export.rb lib/floorplanner.rb README views/design.obj.erb views/design.dae.erb lib/config.yml lib/geom/intersection.rb lib/floorplanner/svg_export.rb lib/floorplanner/rib_export.rb fml.gemspec Rakefile tasks/github-gem.rake lib/geom/triangle.rb lib/geom/edge.rb bin/fml2obj.rb lib/geom/triangle_mesh.rb lib/floorplanner/wall_builder.rb lib/floorplanner/wall3d.rb lib/floorplanner/document.rb lib/floorplanner/opening3d.rb lib/collada/geometry.rb views/design.svg.erb lib/geom/vertex.rb lib/geom/glu_tess.rb lib/collada/document.rb)
|
15
|
+
s.homepage = %q{http://floorplanner.com/}
|
16
|
+
s.require_paths = ["lib"]
|
17
|
+
s.rubygems_version = %q{1.3.1}
|
18
|
+
s.summary = %q{Floorplanner.com FML document toolkit}
|
19
|
+
|
20
|
+
if s.respond_to? :specification_version then
|
21
|
+
current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
|
22
|
+
s.specification_version = 2
|
23
|
+
|
24
|
+
if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
|
25
|
+
s.add_runtime_dependency(%q<libxml-ruby>)
|
26
|
+
s.add_runtime_dependency(%q<rubyzip>)
|
27
|
+
else
|
28
|
+
s.add_dependency(%q<libxml-ruby>)
|
29
|
+
s.add_dependency(%q<rubyzip>)
|
30
|
+
end
|
31
|
+
else
|
32
|
+
s.add_dependency(%q<libxml-ruby>)
|
33
|
+
s.add_dependency(%q<rubyzip>)
|
34
|
+
end
|
35
|
+
end
|
36
|
+
|
data/lib/floorplanner/asset.rb
CHANGED
@@ -6,7 +6,7 @@ module Floorplanner
|
|
6
6
|
LIBRARY_NODES = '/COLLADA/library_nodes/node'
|
7
7
|
LIBRARY_IMAGES = '/COLLADA/library_images/image'
|
8
8
|
VISUAL_SCENE_QUERY = '/COLLADA/library_visual_scenes/visual_scene/node'
|
9
|
-
|
9
|
+
|
10
10
|
NO_NS_NAME = %w{ param }
|
11
11
|
|
12
12
|
CACHE_PATH = File.join(Floorplanner.config['dae_cache_path'], 'kmz')
|
@@ -16,7 +16,7 @@ module Floorplanner
|
|
16
16
|
def self.get(asset_id,asset_title,asset_url3d)
|
17
17
|
FileUtils.mkdir_p(CACHE_PATH)
|
18
18
|
asset_url = Floorplanner.config['content_base_url'] + URI.escape(asset_url3d)
|
19
|
-
|
19
|
+
|
20
20
|
cached_path = File.join(CACHE_PATH,asset_id)
|
21
21
|
if File.exists?(cached_path)
|
22
22
|
$stderr.puts("Cached asset: %s" % asset_id)
|
@@ -4,9 +4,9 @@ module Floorplanner
|
|
4
4
|
def to_dae(design_id,out_path,xrefs=false)
|
5
5
|
@design = Design.new(@xml,design_id)
|
6
6
|
@design.build_geometries
|
7
|
-
@design.save_textures
|
7
|
+
@design.save_textures(File.dirname(out_path)) unless xrefs
|
8
8
|
dae = File.new(out_path,'w')
|
9
|
-
dae.write
|
9
|
+
dae.write(@design.to_dae(xrefs))
|
10
10
|
dae.close
|
11
11
|
end
|
12
12
|
|
@@ -20,7 +20,7 @@ module Floorplanner
|
|
20
20
|
|
21
21
|
def to_dae(xrefs=false)
|
22
22
|
raise "No geometries to export. Call build_geometries first" unless @areas && @walls
|
23
|
-
@assets = assets
|
23
|
+
@assets = assets
|
24
24
|
@elements = objects
|
25
25
|
|
26
26
|
# somehow...
|
@@ -73,7 +73,7 @@ module Floorplanner
|
|
73
73
|
rotation = Geom::Number3D.from_str(rotation)
|
74
74
|
rotation.z += 360 if rotation.z < 0
|
75
75
|
rotation.z += 180
|
76
|
-
|
76
|
+
|
77
77
|
# find proper scale for object
|
78
78
|
size = object.find('size').first.content
|
79
79
|
scale = asset.scale_ratio(Geom::Number3D.from_str(size))
|
data/lib/floorplanner/design.rb
CHANGED
@@ -68,7 +68,7 @@ module Floorplanner
|
|
68
68
|
@walls = WallBuilder.new do |b|
|
69
69
|
@xml.find(LINES_QUERY % @design_id).each do |line|
|
70
70
|
floats = line.find('points').first.get_floats
|
71
|
-
|
71
|
+
|
72
72
|
thickness = line.find('thickness').first.content.to_f
|
73
73
|
height = line.find('height').first.content.to_f
|
74
74
|
|
@@ -95,7 +95,7 @@ module Floorplanner
|
|
95
95
|
size_floats = opening.find('size').first.get_floats
|
96
96
|
position = Geom::Number3D.new(*pos_floats)
|
97
97
|
size = Geom::Number3D.new(*size_floats)
|
98
|
-
|
98
|
+
|
99
99
|
asset_id = opening.find('asset').first.attributes['refid']
|
100
100
|
asset = @xml.find(ASSET_QUERY % [@design_id,asset_id]).first
|
101
101
|
type = asset.find('url2d').first.content.match(/door/i) ? Opening3D::TYPE_DOOR : Opening3D::TYPE_WINDOW
|
@@ -27,7 +27,7 @@ module Floorplanner
|
|
27
27
|
v1 = Geom::Vertex.new(-width/2,0,0)
|
28
28
|
v2 = Geom::Vertex.new( width/2,0,0)
|
29
29
|
o_base = Geom::Edge.new(v1,v2)
|
30
|
-
|
30
|
+
|
31
31
|
# create opening side
|
32
32
|
o_inner = o_base.offset(thickness/2.0,Wall3D::UP)
|
33
33
|
o_outer = o_base.offset(-thickness/2.0,Wall3D::UP)
|
@@ -50,7 +50,7 @@ module Floorplanner
|
|
50
50
|
|
51
51
|
# flip top cap
|
52
52
|
extrusion.last.reverse
|
53
|
-
|
53
|
+
|
54
54
|
@meshes << @base
|
55
55
|
@meshes.concat(extrusion)
|
56
56
|
|
@@ -131,7 +131,7 @@ module Floorplanner
|
|
131
131
|
else
|
132
132
|
rest.vertices.push(t2,ot,ob,b2)
|
133
133
|
end
|
134
|
-
|
134
|
+
|
135
135
|
mesh.meshes.push(op_top)
|
136
136
|
mesh.meshes.push(op_bot)
|
137
137
|
mesh.meshes.push(rest)
|
@@ -118,7 +118,7 @@ module Floorplanner
|
|
118
118
|
old = @vertices.dup
|
119
119
|
@vertices = Array.new
|
120
120
|
old.each do |v|
|
121
|
-
@vertices.push(v) unless @vertices.include?(v) # find_vertex(@vertices,v) #
|
121
|
+
@vertices.push(v) unless @vertices.include?(v) # find_vertex(@vertices,v) #
|
122
122
|
end
|
123
123
|
$stderr.puts "Walls Vertices: #{@vertices.length.to_s}"
|
124
124
|
$stderr.puts "Walls Faces : #{@faces.length.to_s}"
|
data/lib/geom/ear_trim.rb
CHANGED
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'opengl'
|
2
|
+
|
3
|
+
module Geom
|
4
|
+
class GluTesselator
|
5
|
+
include Gl,Glu,Glut
|
6
|
+
def self.triangulate(poly)
|
7
|
+
result = Array.new
|
8
|
+
|
9
|
+
t = gluNewTess
|
10
|
+
gluTessCallback(t,GLU_TESS_VERTEX,method(:vertex_callback).to_proc)
|
11
|
+
gluTessCallback(t,GLU_TESS_BEGIN,method(:begin_callback).to_proc)
|
12
|
+
gluTessCallback(t,GLU_TESS_EDGE_FLAG,proc{})
|
13
|
+
gluTessBeginPolygon(t,self)
|
14
|
+
gluTessBeginContour(t)
|
15
|
+
|
16
|
+
poly.vertices.each_with_index do |v,i|
|
17
|
+
gluTessVertex(t,[v.x,v.y,v.z],v)
|
18
|
+
end
|
19
|
+
|
20
|
+
gluTessEndContour(t)
|
21
|
+
gluTessEndPolygon(t)
|
22
|
+
end
|
23
|
+
|
24
|
+
private
|
25
|
+
|
26
|
+
def self.vertex_callback(v)
|
27
|
+
puts v
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.begin_callback(a)
|
31
|
+
puts "begin"
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/geom/intersection.rb
CHANGED
@@ -23,7 +23,7 @@ module Geom
|
|
23
23
|
# The lines intersect at a point somewhere
|
24
24
|
ua = ((x4-x3)*(y1-y3)-(y4-y3)*(x1-x3)) / d
|
25
25
|
ub = ((x2-x1)*(y1-y3)-(y2-y1)*(x1-x3)) / d
|
26
|
-
|
26
|
+
|
27
27
|
result.alpha.push(ua,ub)
|
28
28
|
if infinite || ((ua > 0 && ua < 1) && (ub > 0 && ub < 1))
|
29
29
|
x = x1 + ua*(x2-x1)
|
data/lib/geom/matrix3d.rb
CHANGED
data/lib/geom/number.rb
CHANGED
@@ -56,22 +56,22 @@ module Geom
|
|
56
56
|
def distance_x(other)
|
57
57
|
(@x - other.x).abs
|
58
58
|
end
|
59
|
-
|
59
|
+
|
60
60
|
def distance_y(other)
|
61
61
|
(@y - other.y).abs
|
62
62
|
end
|
63
|
-
|
63
|
+
|
64
64
|
def distance_z(other)
|
65
65
|
(@z - other.z).abs
|
66
66
|
end
|
67
|
-
|
67
|
+
|
68
68
|
def distance(other)
|
69
69
|
Math.sqrt(
|
70
70
|
distance_z(other) ** 2 +
|
71
71
|
Math.sqrt(distance_x(other)**2 + distance_y(other)**2) ** 2
|
72
72
|
)
|
73
73
|
end
|
74
|
-
|
74
|
+
|
75
75
|
def == (other)
|
76
76
|
@x == other.x &&
|
77
77
|
@y == other.y &&
|
@@ -90,7 +90,7 @@ module Geom
|
|
90
90
|
class NumberUV
|
91
91
|
|
92
92
|
attr_accessor :u, :v
|
93
|
-
|
93
|
+
|
94
94
|
def initialize(u=0,v=0)
|
95
95
|
@u = u
|
96
96
|
@v = v
|
data/lib/geom/polygon.rb
CHANGED
@@ -102,7 +102,7 @@ module Geom
|
|
102
102
|
result += (point.x * (points[j].y - points[k].y))
|
103
103
|
end
|
104
104
|
end
|
105
|
-
|
105
|
+
|
106
106
|
# scale to get area before projection
|
107
107
|
an = Math.sqrt(ax**2 + ay**2 + az**2) # length of normal vector
|
108
108
|
case coord
|
@@ -130,7 +130,7 @@ module Geom
|
|
130
130
|
dominant = dominant_axis
|
131
131
|
dist = self.plane.distance(pt)
|
132
132
|
result = false
|
133
|
-
|
133
|
+
|
134
134
|
return false if dist.abs > 0.01
|
135
135
|
case dominant
|
136
136
|
when AXIS_X
|
@@ -211,7 +211,7 @@ module Geom
|
|
211
211
|
result = []
|
212
212
|
plane = self.plane
|
213
213
|
up = Number3D.new( 0, 1, 0 )
|
214
|
-
|
214
|
+
|
215
215
|
# get side vector
|
216
216
|
side = Number3D.cross(up, plane.normal)
|
217
217
|
side.normalize
|
@@ -219,13 +219,13 @@ module Geom
|
|
219
219
|
# adjust up vector
|
220
220
|
up = Number3D.cross(self.plane.normal, side)
|
221
221
|
up.normalize
|
222
|
-
|
222
|
+
|
223
223
|
matrix = Matrix3D[
|
224
224
|
[side.x, up.x, plane.normal.x, 0],
|
225
225
|
[side.y, up.y, plane.normal.y, 0],
|
226
226
|
[side.z, up.z, plane.normal.z, 0],
|
227
227
|
[0, 0, 0, 1]]
|
228
|
-
|
228
|
+
|
229
229
|
v, n, t = nil, nil, nil
|
230
230
|
min = Number3D.new(1000,1000,1000)
|
231
231
|
max = Number3D.new(-min.x, -min.y, -min.z)
|
@@ -233,22 +233,22 @@ module Geom
|
|
233
233
|
|
234
234
|
@vertices.each do |v|
|
235
235
|
n = v.position
|
236
|
-
|
236
|
+
|
237
237
|
# Matrix3D.multiplyVector3x3( matrix, n );
|
238
|
-
|
238
|
+
|
239
239
|
min.x = n.x if n.x < min.x
|
240
240
|
min.y = n.y if n.y < min.y
|
241
241
|
max.x = n.x if n.x > max.x
|
242
242
|
max.y = n.y if n.y > max.y
|
243
|
-
|
243
|
+
|
244
244
|
pts << n
|
245
245
|
result << NumberUV.new
|
246
246
|
end
|
247
|
-
|
247
|
+
|
248
248
|
w = max.x - min.x
|
249
249
|
h = max.y - min.y
|
250
250
|
size = w < h ? h : w
|
251
|
-
|
251
|
+
|
252
252
|
@vertices.each_with_index do |v,i|
|
253
253
|
n = pts[i]
|
254
254
|
t = result[i]
|
@@ -256,7 +256,7 @@ module Geom
|
|
256
256
|
t.u = ((n.x - min.x) / size) * size
|
257
257
|
t.v = ((n.y - min.y) / size) * size
|
258
258
|
end
|
259
|
-
|
259
|
+
|
260
260
|
result
|
261
261
|
end
|
262
262
|
|
@@ -0,0 +1,315 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/tasklib'
|
4
|
+
require 'date'
|
5
|
+
require 'git'
|
6
|
+
|
7
|
+
module GithubGem
|
8
|
+
|
9
|
+
# Detects the gemspc file of this project using heuristics.
|
10
|
+
def self.detect_gemspec_file
|
11
|
+
FileList['*.gemspec'].first
|
12
|
+
end
|
13
|
+
|
14
|
+
# Detects the main include file of this project using heuristics
|
15
|
+
def self.detect_main_include
|
16
|
+
if detect_gemspec_file =~ /^(\.*)\.gemspec$/ && File.exist?("lib/#{$1}.rb")
|
17
|
+
"lib/#{$1}.rb"
|
18
|
+
elsif FileList['lib/*.rb'].length == 1
|
19
|
+
FileList['lib/*.rb'].first
|
20
|
+
else
|
21
|
+
nil
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
class RakeTasks
|
26
|
+
|
27
|
+
attr_reader :gemspec, :modified_files, :git
|
28
|
+
attr_accessor :gemspec_file, :task_namespace, :main_include, :root_dir, :spec_pattern, :test_pattern, :remote, :remote_branch, :local_branch
|
29
|
+
|
30
|
+
# Initializes the settings, yields itself for configuration
|
31
|
+
# and defines the rake tasks based on the gemspec file.
|
32
|
+
def initialize(task_namespace = :gem)
|
33
|
+
@gemspec_file = GithubGem.detect_gemspec_file
|
34
|
+
@task_namespace = task_namespace
|
35
|
+
@main_include = GithubGem.detect_main_include
|
36
|
+
@modified_files = []
|
37
|
+
@root_dir = Dir.pwd
|
38
|
+
@test_pattern = 'test/**/*_test.rb'
|
39
|
+
@spec_pattern = 'spec/**/*_spec.rb'
|
40
|
+
@local_branch = 'master'
|
41
|
+
@remote = 'origin'
|
42
|
+
@remote_branch = 'master'
|
43
|
+
|
44
|
+
yield(self) if block_given?
|
45
|
+
|
46
|
+
@git = Git.open(@root_dir)
|
47
|
+
load_gemspec!
|
48
|
+
define_tasks!
|
49
|
+
end
|
50
|
+
|
51
|
+
protected
|
52
|
+
|
53
|
+
# Define Unit test tasks
|
54
|
+
def define_test_tasks!
|
55
|
+
require 'rake/testtask'
|
56
|
+
|
57
|
+
namespace(:test) do
|
58
|
+
Rake::TestTask.new(:basic) do |t|
|
59
|
+
t.pattern = test_pattern
|
60
|
+
t.verbose = true
|
61
|
+
t.libs << 'test'
|
62
|
+
end
|
63
|
+
end
|
64
|
+
|
65
|
+
desc "Run all unit tests for #{gemspec.name}"
|
66
|
+
task(:test => ['test:basic'])
|
67
|
+
end
|
68
|
+
|
69
|
+
# Defines RSpec tasks
|
70
|
+
def define_rspec_tasks!
|
71
|
+
require 'spec/rake/spectask'
|
72
|
+
|
73
|
+
namespace(:spec) do
|
74
|
+
desc "Verify all RSpec examples for #{gemspec.name}"
|
75
|
+
Spec::Rake::SpecTask.new(:basic) do |t|
|
76
|
+
t.spec_files = FileList[spec_pattern]
|
77
|
+
end
|
78
|
+
|
79
|
+
desc "Verify all RSpec examples for #{gemspec.name} and output specdoc"
|
80
|
+
Spec::Rake::SpecTask.new(:specdoc) do |t|
|
81
|
+
t.spec_files = FileList[spec_pattern]
|
82
|
+
t.spec_opts << '--format' << 'specdoc' << '--color'
|
83
|
+
end
|
84
|
+
|
85
|
+
desc "Run RCov on specs for #{gemspec.name}"
|
86
|
+
Spec::Rake::SpecTask.new(:rcov) do |t|
|
87
|
+
t.spec_files = FileList[spec_pattern]
|
88
|
+
t.rcov = true
|
89
|
+
t.rcov_opts = ['--exclude', '"spec/*,gems/*"', '--rails']
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
desc "Verify all RSpec examples for #{gemspec.name} and output specdoc"
|
94
|
+
task(:spec => ['spec:specdoc'])
|
95
|
+
end
|
96
|
+
|
97
|
+
# Defines the rake tasks
|
98
|
+
def define_tasks!
|
99
|
+
|
100
|
+
define_test_tasks! if has_tests?
|
101
|
+
define_rspec_tasks! if has_specs?
|
102
|
+
|
103
|
+
namespace(@task_namespace) do
|
104
|
+
desc "Updates the filelist in the gemspec file"
|
105
|
+
task(:manifest) { manifest_task }
|
106
|
+
|
107
|
+
desc "Builds the .gem package"
|
108
|
+
task(:build => :manifest) { build_task }
|
109
|
+
|
110
|
+
desc "Sets the version of the gem in the gemspec"
|
111
|
+
task(:set_version => [:check_version, :check_current_branch]) { version_task }
|
112
|
+
task(:check_version => :fetch_origin) { check_version_task }
|
113
|
+
|
114
|
+
task(:fetch_origin) { fetch_origin_task }
|
115
|
+
task(:check_current_branch) { check_current_branch_task }
|
116
|
+
task(:check_clean_status) { check_clean_status_task }
|
117
|
+
task(:check_not_diverged => :fetch_origin) { check_not_diverged_task }
|
118
|
+
|
119
|
+
checks = [:check_current_branch, :check_clean_status, :check_not_diverged, :check_version]
|
120
|
+
checks.unshift('spec:basic') if has_specs?
|
121
|
+
checks.unshift('test:basic') if has_tests?
|
122
|
+
checks.push << [:check_rubyforge] if gemspec.rubyforge_project
|
123
|
+
|
124
|
+
desc "Perform all checks that would occur before a release"
|
125
|
+
task(:release_checks => checks)
|
126
|
+
|
127
|
+
release_tasks = [:release_checks, :set_version, :build, :github_release]
|
128
|
+
release_tasks << [:rubyforge_release] if gemspec.rubyforge_project
|
129
|
+
|
130
|
+
desc "Release a new verison of the gem"
|
131
|
+
task(:release => release_tasks) { release_task }
|
132
|
+
|
133
|
+
task(:check_rubyforge) { check_rubyforge_task }
|
134
|
+
task(:rubyforge_release) { rubyforge_release_task }
|
135
|
+
task(:github_release => [:commit_modified_files, :tag_version]) { github_release_task }
|
136
|
+
task(:tag_version) { tag_version_task }
|
137
|
+
task(:commit_modified_files) { commit_modified_files_task }
|
138
|
+
|
139
|
+
desc "Updates the gem release tasks with the latest version on Github"
|
140
|
+
task(:update_tasks) { update_tasks_task }
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
# Updates the files list and test_files list in the gemspec file using the list of files
|
145
|
+
# in the repository and the spec/test file pattern.
|
146
|
+
def manifest_task
|
147
|
+
# Load all the gem's files using "git ls-files"
|
148
|
+
repository_files = git.ls_files.keys
|
149
|
+
test_files = Dir[test_pattern] + Dir[spec_pattern]
|
150
|
+
|
151
|
+
update_gemspec(:files, repository_files)
|
152
|
+
update_gemspec(:test_files, repository_files & test_files)
|
153
|
+
end
|
154
|
+
|
155
|
+
# Builds the gem
|
156
|
+
def build_task
|
157
|
+
sh "gem build -q #{gemspec_file}"
|
158
|
+
Dir.mkdir('pkg') unless File.exist?('pkg')
|
159
|
+
sh "mv #{gemspec.name}-#{gemspec.version}.gem pkg/#{gemspec.name}-#{gemspec.version}.gem"
|
160
|
+
end
|
161
|
+
|
162
|
+
# Updates the version number in the gemspec file, the VERSION constant in the main
|
163
|
+
# include file and the contents of the VERSION file.
|
164
|
+
def version_task
|
165
|
+
update_gemspec(:version, ENV['VERSION']) if ENV['VERSION']
|
166
|
+
update_gemspec(:date, Date.today)
|
167
|
+
|
168
|
+
update_version_file(gemspec.version)
|
169
|
+
update_version_constant(gemspec.version)
|
170
|
+
end
|
171
|
+
|
172
|
+
def check_version_task
|
173
|
+
raise "#{ENV['VERSION']} is not a valid version number!" if ENV['VERSION'] && !Gem::Version.correct?(ENV['VERSION'])
|
174
|
+
proposed_version = Gem::Version.new(ENV['VERSION'] || gemspec.version)
|
175
|
+
# Loads the latest version number using the created tags
|
176
|
+
newest_version = git.tags.map { |tag| tag.name.split('-').last }.compact.map { |v| Gem::Version.new(v) }.max
|
177
|
+
raise "This version (#{proposed_version}) is not higher than the highest tagged version (#{newest_version})" if newest_version && newest_version >= proposed_version
|
178
|
+
end
|
179
|
+
|
180
|
+
# Checks whether the current branch is not diverged from the remote branch
|
181
|
+
def check_not_diverged_task
|
182
|
+
raise "The current branch is diverged from the remote branch!" if git.log.between('HEAD', git.branches["#{remote}/#{remote_branch}"].gcommit).any?
|
183
|
+
end
|
184
|
+
|
185
|
+
# Checks whether the repository status ic clean
|
186
|
+
def check_clean_status_task
|
187
|
+
raise "The current working copy contains modifications" if git.status.changed.any?
|
188
|
+
end
|
189
|
+
|
190
|
+
# Checks whether the current branch is correct
|
191
|
+
def check_current_branch_task
|
192
|
+
raise "Currently not on #{local_branch} branch!" unless git.branch.name == local_branch.to_s
|
193
|
+
end
|
194
|
+
|
195
|
+
# Fetches the latest updates from Github
|
196
|
+
def fetch_origin_task
|
197
|
+
git.fetch('origin')
|
198
|
+
end
|
199
|
+
|
200
|
+
# Commits every file that has been changed by the release task.
|
201
|
+
def commit_modified_files_task
|
202
|
+
if modified_files.any?
|
203
|
+
modified_files.each { |file| git.add(file) }
|
204
|
+
git.commit("Released #{gemspec.name} gem version #{gemspec.version}")
|
205
|
+
end
|
206
|
+
end
|
207
|
+
|
208
|
+
# Adds a tag for the released version
|
209
|
+
def tag_version_task
|
210
|
+
git.add_tag("#{gemspec.name}-#{gemspec.version}")
|
211
|
+
end
|
212
|
+
|
213
|
+
# Pushes the changes and tag to github
|
214
|
+
def github_release_task
|
215
|
+
git.push(remote, remote_branch, true)
|
216
|
+
end
|
217
|
+
|
218
|
+
# Checks whether Rubyforge is configured properly
|
219
|
+
def check_rubyforge_task
|
220
|
+
# Login no longer necessary when using rubyforge 2.0.0 gem
|
221
|
+
# raise "Could not login on rubyforge!" unless `rubyforge login 2>&1`.strip.empty?
|
222
|
+
output = `rubyforge names`.split("\n")
|
223
|
+
raise "Rubyforge group not found!" unless output.any? { |line| %r[^groups\s*\:.*\b#{Regexp.quote(gemspec.rubyforge_project)}\b.*] =~ line }
|
224
|
+
raise "Rubyforge package not found!" unless output.any? { |line| %r[^packages\s*\:.*\b#{Regexp.quote(gemspec.name)}\b.*] =~ line }
|
225
|
+
end
|
226
|
+
|
227
|
+
# Task to release the .gem file toRubyforge.
|
228
|
+
def rubyforge_release_task
|
229
|
+
sh 'rubyforge', 'add_release', gemspec.rubyforge_project, gemspec.name, gemspec.version.to_s, "pkg/#{gemspec.name}-#{gemspec.version}.gem"
|
230
|
+
end
|
231
|
+
|
232
|
+
# Gem release task.
|
233
|
+
# All work is done by the task's dependencies, so just display a release completed message.
|
234
|
+
def release_task
|
235
|
+
puts
|
236
|
+
puts '------------------------------------------------------------'
|
237
|
+
puts "Released #{gemspec.name} version #{gemspec.version}"
|
238
|
+
end
|
239
|
+
|
240
|
+
private
|
241
|
+
|
242
|
+
# Checks whether this project has any RSpec files
|
243
|
+
def has_specs?
|
244
|
+
FileList[spec_pattern].any?
|
245
|
+
end
|
246
|
+
|
247
|
+
# Checks whether this project has any unit test files
|
248
|
+
def has_tests?
|
249
|
+
FileList[test_pattern].any?
|
250
|
+
end
|
251
|
+
|
252
|
+
# Loads the gemspec file
|
253
|
+
def load_gemspec!
|
254
|
+
@gemspec = eval(File.read(@gemspec_file))
|
255
|
+
end
|
256
|
+
|
257
|
+
# Updates the VERSION file with the new version
|
258
|
+
def update_version_file(version)
|
259
|
+
if File.exists?('VERSION')
|
260
|
+
File.open('VERSION', 'w') { |f| f << version.to_s }
|
261
|
+
modified_files << 'VERSION'
|
262
|
+
end
|
263
|
+
end
|
264
|
+
|
265
|
+
# Updates the VERSION constant in the main include file if it exists
|
266
|
+
def update_version_constant(version)
|
267
|
+
if main_include && File.exist?(main_include)
|
268
|
+
file_contents = File.read(main_include)
|
269
|
+
if file_contents.sub!(/^(\s+VERSION\s*=\s*)[^\s].*$/) { $1 + version.to_s.inspect }
|
270
|
+
File.open(main_include, 'w') { |f| f << file_contents }
|
271
|
+
modified_files << main_include
|
272
|
+
end
|
273
|
+
end
|
274
|
+
end
|
275
|
+
|
276
|
+
# Updates an attribute of the gemspec file.
|
277
|
+
# This function will open the file, and search/replace the attribute using a regular expression.
|
278
|
+
def update_gemspec(attribute, new_value, literal = false)
|
279
|
+
|
280
|
+
unless literal
|
281
|
+
new_value = case new_value
|
282
|
+
when Array then "%w(#{new_value.join(' ')})"
|
283
|
+
when Hash, String then new_value.inspect
|
284
|
+
when Date then new_value.strftime('%Y-%m-%d').inspect
|
285
|
+
else raise "Cannot write value #{new_value.inspect} to gemspec file!"
|
286
|
+
end
|
287
|
+
end
|
288
|
+
|
289
|
+
spec = File.read(gemspec_file)
|
290
|
+
regexp = Regexp.new('^(\s+\w+\.' + Regexp.quote(attribute.to_s) + '\s*=\s*)[^\s].*$')
|
291
|
+
if spec.sub!(regexp) { $1 + new_value }
|
292
|
+
File.open(gemspec_file, 'w') { |f| f << spec }
|
293
|
+
modified_files << gemspec_file
|
294
|
+
|
295
|
+
# Reload the gemspec so the changes are incorporated
|
296
|
+
load_gemspec!
|
297
|
+
end
|
298
|
+
end
|
299
|
+
|
300
|
+
# Updates the tasks file using the latest file found on Github
|
301
|
+
def update_tasks_task
|
302
|
+
require 'net/http'
|
303
|
+
|
304
|
+
server = 'github.com'
|
305
|
+
path = '/wvanbergen/github-gem/raw/master/tasks/github-gem.rake'
|
306
|
+
|
307
|
+
Net::HTTP.start(server) do |http|
|
308
|
+
response = http.get(path)
|
309
|
+
open(__FILE__, "w") { |file| file.write(response.body) }
|
310
|
+
end
|
311
|
+
puts "Updated gem release tasks file with latest version."
|
312
|
+
end
|
313
|
+
|
314
|
+
end
|
315
|
+
end
|
data/xml/fml2kml.xsl
ADDED
@@ -0,0 +1,59 @@
|
|
1
|
+
<?xml version="1.0" encoding="ISO-8859-1"?>
|
2
|
+
<xsl:stylesheet version="1.0"
|
3
|
+
xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
|
4
|
+
|
5
|
+
<xsl:template match="/">
|
6
|
+
<kml xmlns="http://www.opengis.net/kml/2.2">
|
7
|
+
<Folder>
|
8
|
+
<name><xsl:value-of select="/project/name"/></name>
|
9
|
+
<xsl:for-each select="/project/floors/floor">
|
10
|
+
<Folder>
|
11
|
+
<name><xsl:value-of select="name"/></name>
|
12
|
+
<xsl:if test="position() > 1">
|
13
|
+
<visibility>0</visibility>
|
14
|
+
</xsl:if>
|
15
|
+
<xsl:apply-templates select="designs/design"/>
|
16
|
+
</Folder>
|
17
|
+
</xsl:for-each>
|
18
|
+
</Folder>
|
19
|
+
</kml>
|
20
|
+
</xsl:template>
|
21
|
+
|
22
|
+
<xsl:template match="design">
|
23
|
+
<Placemark>
|
24
|
+
<name><xsl:value-of select="name"/></name>
|
25
|
+
<visibility>0</visibility>
|
26
|
+
<xsl:for-each select="objects/object">
|
27
|
+
<xsl:variable name="refid" select="asset/@refid"/>
|
28
|
+
<xsl:if test="../../assets/asset[@id=$refid]/url3d">
|
29
|
+
<Model>
|
30
|
+
<altitudeMode>relativeToGround</altitudeMode>
|
31
|
+
<Location>
|
32
|
+
<longitude><xsl:value-of select="points"/></longitude>
|
33
|
+
<latitude><xsl:value-of select="points"/></latitude>
|
34
|
+
<altitude><xsl:value-of select="points"/></altitude>
|
35
|
+
</Location>
|
36
|
+
<Orientation>
|
37
|
+
<heading><xsl:value-of select="rotation"/></heading>
|
38
|
+
<tilt><xsl:value-of select="rotation"/></tilt>
|
39
|
+
<roll><xsl:value-of select="rotation"/></roll>
|
40
|
+
</Orientation>
|
41
|
+
<Scale>
|
42
|
+
<x><xsl:value-of select="size"/></x>
|
43
|
+
<y><xsl:value-of select="size"/></y>
|
44
|
+
<z><xsl:value-of select="size"/></z>
|
45
|
+
</Scale>
|
46
|
+
<xsl:for-each select="asset">
|
47
|
+
<Link>
|
48
|
+
<href>
|
49
|
+
<xsl:value-of select="../../../assets/asset[@id=$refid]/url3d"/>
|
50
|
+
</href>
|
51
|
+
</Link>
|
52
|
+
</xsl:for-each>
|
53
|
+
</Model>
|
54
|
+
</xsl:if>
|
55
|
+
</xsl:for-each>
|
56
|
+
</Placemark>
|
57
|
+
</xsl:template>
|
58
|
+
|
59
|
+
</xsl:stylesheet>
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: floorplanner-fml
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.2.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dusan Maliarik
|
@@ -9,7 +9,7 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-
|
12
|
+
date: 2009-09-23 00:00:00 -07:00
|
13
13
|
default_executable:
|
14
14
|
dependencies:
|
15
15
|
- !ruby/object:Gem::Dependency
|
@@ -42,43 +42,49 @@ extensions: []
|
|
42
42
|
extra_rdoc_files: []
|
43
43
|
|
44
44
|
files:
|
45
|
-
-
|
46
|
-
-
|
47
|
-
- bin/fml2obj.rb
|
48
|
-
- lib/config.yml
|
49
|
-
- lib/floorplanner.rb
|
45
|
+
- lib/keyhole/archive.rb
|
46
|
+
- lib/geom/plane.rb
|
50
47
|
- lib/floorplanner/area_builder.rb
|
51
|
-
-
|
52
|
-
-
|
48
|
+
- bin/fml2dae.rb
|
49
|
+
- .gitignore
|
50
|
+
- xml/fml2kml.xsl
|
51
|
+
- xml/collada_schema_1_4.xsd
|
52
|
+
- lib/geom/number.rb
|
53
|
+
- lib/geom/connection.rb
|
53
54
|
- lib/floorplanner/design.rb
|
54
|
-
- lib/floorplanner/
|
55
|
-
- lib/
|
56
|
-
- lib/floorplanner/opening3d.rb
|
57
|
-
- lib/floorplanner/rib_export.rb
|
58
|
-
- lib/floorplanner/svg_export.rb
|
59
|
-
- lib/floorplanner/wall3d.rb
|
60
|
-
- lib/floorplanner/wall_builder.rb
|
55
|
+
- lib/floorplanner/collada_export.rb
|
56
|
+
- lib/geom/polygon.rb
|
61
57
|
- lib/geom.rb
|
62
|
-
- lib/
|
58
|
+
- lib/floorplanner/asset.rb
|
59
|
+
- xml/fml.rng
|
60
|
+
- views/design.rib.erb
|
61
|
+
- lib/geom/matrix3d.rb
|
63
62
|
- lib/geom/ear_trim.rb
|
64
|
-
- lib/
|
63
|
+
- lib/floorplanner/obj_export.rb
|
64
|
+
- lib/floorplanner.rb
|
65
|
+
- README
|
66
|
+
- views/design.obj.erb
|
67
|
+
- views/design.dae.erb
|
68
|
+
- lib/config.yml
|
65
69
|
- lib/geom/intersection.rb
|
66
|
-
- lib/
|
67
|
-
- lib/
|
68
|
-
-
|
69
|
-
-
|
70
|
-
-
|
70
|
+
- lib/floorplanner/svg_export.rb
|
71
|
+
- lib/floorplanner/rib_export.rb
|
72
|
+
- fml.gemspec
|
73
|
+
- Rakefile
|
74
|
+
- tasks/github-gem.rake
|
71
75
|
- lib/geom/triangle.rb
|
72
|
-
- lib/geom/
|
73
|
-
-
|
76
|
+
- lib/geom/edge.rb
|
77
|
+
- bin/fml2obj.rb
|
78
|
+
- lib/geom/triangle_mesh.rb
|
79
|
+
- lib/floorplanner/wall_builder.rb
|
80
|
+
- lib/floorplanner/wall3d.rb
|
81
|
+
- lib/floorplanner/document.rb
|
82
|
+
- lib/floorplanner/opening3d.rb
|
74
83
|
- lib/collada/geometry.rb
|
75
|
-
- lib/keyhole/archive.rb
|
76
|
-
- views/design.dae.erb
|
77
|
-
- views/design.obj.erb
|
78
84
|
- views/design.svg.erb
|
79
|
-
-
|
80
|
-
-
|
81
|
-
-
|
85
|
+
- lib/geom/vertex.rb
|
86
|
+
- lib/geom/glu_tess.rb
|
87
|
+
- lib/collada/document.rb
|
82
88
|
has_rdoc: false
|
83
89
|
homepage: http://floorplanner.com/
|
84
90
|
licenses:
|
@@ -105,6 +111,6 @@ rubyforge_project:
|
|
105
111
|
rubygems_version: 1.3.5
|
106
112
|
signing_key:
|
107
113
|
specification_version: 2
|
108
|
-
summary:
|
114
|
+
summary: Floorplanner.com FML document toolkit
|
109
115
|
test_files: []
|
110
116
|
|