Class: Floorplanner::Design

Inherits:
Object
  • Object
show all
Includes:
ColladaExport, ObjExport, RibExport, SvgExport
Defined in:
lib/floorplanner/design.rb

Constant Summary collapse

DESIGN_QUERY =
"/project/floors/floor/designs/design[id='%s']"
DESIGN_N_QUERY =
"/project/floors/floor/designs/design[name='%s']"
ASSET_QUERY =
DESIGN_QUERY+"/assets/asset[@id='%s']"
ASSET_URL2D =
ASSET_QUERY+"/url2d"
LINES_QUERY =
DESIGN_QUERY+"/lines/line"
OPENINGS_QUERY =
DESIGN_QUERY+"/objects/object[type='opening']"
AREAS_QUERY =
DESIGN_QUERY+"/areas/area"
NAME_QUERY =
DESIGN_QUERY+"/name"

Constants included from ColladaExport

ColladaExport::ASSETS_QUERY, ColladaExport::OBJECTS_QUERY

Instance Method Summary collapse

Methods included from SvgExport

#to_svg

Methods included from RibExport

#to_rib

Methods included from ObjExport

#to_obj

Methods included from ColladaExport

#assets, #objects, #save_textures, #to_dae

Constructor Details

#initialize(fml, design_id) ⇒ Design

Constructs new floorplan design from FML



20
21
22
23
24
25
26
27
28
29
30
31
32
33
# File 'lib/floorplanner/design.rb', line 20

def initialize(fml,design_id)
  begin
    @xml = fml
    unless fml.find(DESIGN_QUERY % design_id).length.zero?
      @design_id = design_id
    else
      @design_id = fml.find(DESIGN_N_QUERY % design_id).first.find("id").first.content
    end
    @name   = @xml.find(NAME_QUERY % @design_id).first.content
    @author = "John Doe" # TODO from <author> element if included in FML
  rescue NoMethodError
    $stderr.puts "Can't find Design with ID or name: %s" % design_id
  end
end

Instance Method Details

#build_geometriesObject

Builds geometries of walls and areas.



38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
# File 'lib/floorplanner/design.rb', line 38

def build_geometries
  @areas = AreaBuilder.new do |b|
    @xml.find(AREAS_QUERY % @design_id).each do |area|
      name  = area.find('name').first.content
      color = area.find('color').first.content
      type  = area.find('type').first.content

      asset_id = area.find('asset').first.attributes['refid']
      texture_url = @xml.find(ASSET_URL2D % [@design_id,asset_id]).first.content

      vertices = Array.new
      area.find('points').first.content.split(',').each do |str_v|
        floats = str_v.strip.split(/\s/).map! {|f| f.to_f}

        # TODO: fix y coords in Flash app
        floats[1] *= -1.0; floats[4] *= -1.0

        vertices << b.vertex(Geom::Vertex.new(*floats[0..2]))
        vertices << b.vertex(Geom::Vertex.new(*floats[3..5]))
      end

      b.area(vertices,
        :color => color,
        :name => name,
        :texture => texture_url,
        :type => type)

    end
  end
  min_height = 10
  @walls = WallBuilder.new do |b|
    @xml.find(LINES_QUERY % @design_id).each do |line|
      floats = line.find('points').first.get_floats

      thickness = line.find('thickness').first.content.to_f
      height = line.find('height').first.content.to_f

      # TODO: fix this in Flash app
      floats[1] *= -1.0; floats[4] *= -1.0

      sp = Geom::Vertex.new(*floats[0..2])
      ep = Geom::Vertex.new(*floats[3..5])
      sp = b.vertex(sp)
      ep = b.vertex(ep)
      b.wall(sp,ep,thickness,height)
      min_height = height if height < min_height
    end
  end
  @areas.update min_height

  @walls.prepare
  @xml.find(OPENINGS_QUERY % @design_id).each do |opening|
    pos_floats  = opening.find('points').first.get_floats

    # TODO: fix y coord in Flash app
    pos_floats[1] *= -1

    size_floats = opening.find('size').first.get_floats
    position = Geom::Number3D.new(*pos_floats)
    size     = Geom::Number3D.new(*size_floats)

    asset_id = opening.find('asset').first.attributes['refid']
    asset    = @xml.find(ASSET_QUERY % [@design_id,asset_id]).first
    type     = asset.find('url2d').first.content.match(/door/i) ? Opening3D::TYPE_DOOR : Opening3D::TYPE_WINDOW
    @walls.opening(position,size,type)
  end
  @walls.update
end