Class: Floorplanner::DAE

Inherits:
Object
  • Object
show all
Defined in:
lib/floorplanner/asset.rb

Constant Summary collapse

LIBRARY_GEOMETRIES =
'/COLLADA/library_geometries/geometry'
LIBRARY_EFFECTS =
'/COLLADA/library_effects/effect'
LIBRARY_MATERIALS =
'/COLLADA/library_materials/material'
LIBRARY_NODES =
'/COLLADA/library_nodes/node'
LIBRARY_IMAGES =
'/COLLADA/library_images/image'
VISUAL_SCENE_QUERY =
'/COLLADA/library_visual_scenes/visual_scene/node'
NO_NS_NAME =
%w{ param }
CACHE_PATH =
File.join(Floorplanner.config['dae_cache_path'], 'kmz')

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(id, title, kmz) ⇒ DAE

Returns a new instance of DAE.



42
43
44
45
46
47
48
49
50
51
52
# File 'lib/floorplanner/asset.rb', line 42

def initialize(id, title, kmz)
  @dae_path = kmz.dae_path(id)
  @kmz   = kmz
  @id    = id
  @title = title
  @name  = File.basename(@dae_path.gsub(/\.|dae/,''))
  
  @doc   = Nokogiri::XML.parse(open(@dae_path))
  @doc.remove_namespaces!
  @images_dict = {}
end

Instance Attribute Details

#dae_pathObject (readonly)

Returns the value of attribute dae_path.



14
15
16
# File 'lib/floorplanner/asset.rb', line 14

def dae_path
  @dae_path
end

#idObject (readonly)

Returns the value of attribute id.



14
15
16
# File 'lib/floorplanner/asset.rb', line 14

def id
  @id
end

#nameObject (readonly)

Returns the value of attribute name.



14
15
16
# File 'lib/floorplanner/asset.rb', line 14

def name
  @name
end

#titleObject (readonly)

Returns the value of attribute title.



14
15
16
# File 'lib/floorplanner/asset.rb', line 14

def title
  @title
end

Class Method Details

.get(asset) ⇒ Object



16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
# File 'lib/floorplanner/asset.rb', line 16

def self.get(asset)
  FileUtils.mkdir_p(CACHE_PATH)
  asset_url = Floorplanner.config['content_base_url'] + URI.escape(asset.url3d)

  cached_path = File.join(CACHE_PATH, asset.id)
  if File.exists?(cached_path)
    $stderr.puts("Cached asset: %s" % asset.id)
    @kmz = Keyhole::Archive.new(cached_path)
    DAE.new(asset.id, asset.name, @kmz)
  else
    $stderr.puts("Downloading asset: %s" % asset_url)
    cached = File.new(cached_path,'w')
    remote = open(asset_url)
    cached.write(remote.read)
    cached.close

    @kmz = Keyhole::Archive.new(cached_path)
    dae = DAE.new(asset.id, asset.name, @kmz)
    dae.adjust_paths!
    dae
  end
rescue
  $stderr.puts "Failed to get asset: %s, %s" % [asset.id, asset_url]
  raise
end

Instance Method Details

#adjust_paths!Object



139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/floorplanner/asset.rb', line 139

def adjust_paths!
  images = @doc.xpath(LIBRARY_IMAGES)

  images.each do |image|
    init_from = image.xpath('init_from').first
    img_path = @kmz.image_path(@id,init_from.content,true)
    init_from.content = img_path
  end
  open(@dae_path, 'w') do |f|
    f.write @doc.to_s
  end
end

#bounding_boxObject



97
98
99
100
# File 'lib/floorplanner/asset.rb', line 97

def bounding_box
  mesh = Collada::Geometry.doc @doc
  mesh.bounding_box
end

#bounding_box_sizeObject



102
103
104
105
106
107
108
109
# File 'lib/floorplanner/asset.rb', line 102

def bounding_box_size
  box = bounding_box
  Geom::Number3D.new(
    box[:max].distance_x(box[:min]),
    box[:max].distance_y(box[:min]),
    box[:max].distance_z(box[:min])
  )
end

#library_effectsObject



64
65
66
67
68
69
# File 'lib/floorplanner/asset.rb', line 64

def library_effects
  return @effects if @effects
  effects = @doc.xpath(LIBRARY_EFFECTS)
  effects.each {|eff| namespace!(eff)}
  @effects = effects
end

#library_geometriesObject



71
72
73
74
75
76
# File 'lib/floorplanner/asset.rb', line 71

def library_geometries
  return @geometries if @geometries
  geometries = @doc.xpath(LIBRARY_GEOMETRIES)
  geometries.each{|geo| namespace!(geo)}
  @geometries = geometries
end

#library_imagesObject



85
86
87
88
89
90
# File 'lib/floorplanner/asset.rb', line 85

def library_images
  return @images if @images
  images = @doc.xpath(LIBRARY_IMAGES)
  images.each{|img| namespace!(img) && update_path!(img)}
  @images = images
end

#library_materialsObject



57
58
59
60
61
62
# File 'lib/floorplanner/asset.rb', line 57

def library_materials
  return @materials if @materials
  materials = @doc.xpath(LIBRARY_MATERIALS)
  materials.each {|mat| namespace!(mat)}
  @materials = materials
end

#library_nodesObject



78
79
80
81
82
83
# File 'lib/floorplanner/asset.rb', line 78

def library_nodes
  return @nodes if @nodes
  nodes = @doc.xpath(LIBRARY_NODES)
  nodes.each{|nod| namespace!(nod)}
  @nodes = nodes
end

#measurement_unitObject



54
55
# File 'lib/floorplanner/asset.rb', line 54

def measurement_unit
end

#save_textures(root_path) ⇒ Object



122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
# File 'lib/floorplanner/asset.rb', line 122

def save_textures(root_path)
  images = @doc.xpath(LIBRARY_IMAGES)
  FileUtils.mkdir_p(root_path)

  images.each do |image|
    relative_to_dae = image.xpath('init_from').first.content
    img_path = @kmz.image_path(@id,relative_to_dae)
    target_path = File.join(root_path,@id)
    FileUtils.mkdir_p target_path

    target = open(File.join(target_path,File.basename(img_path)),'w')
    target.write(File.read(img_path))
    target.close
    @images_dict[relative_to_dae] = relative_to_dae[3..-1]
  end
end

#scale_ratio(target_size) ⇒ Object



111
112
113
114
115
116
117
118
119
120
# File 'lib/floorplanner/asset.rb', line 111

def scale_ratio(target_size)
  bbox_size = bounding_box_size
  result = Geom::Number3D.new

  result.x = target_size.x / bbox_size.x
  result.y = target_size.y / bbox_size.y
  result.z = 0.01 # (result.x + result.y) / 2.0 # TODO: correct Z size in FML

  result
end

#visual_scene_nodeObject



92
93
94
95
# File 'lib/floorplanner/asset.rb', line 92

def visual_scene_node
  return @scene_node if @scene_node
  @scene_node = namespace!(@doc.xpath(VISUAL_SCENE_QUERY).first)
end