Class: MergeFloorspaceJsWithModel
- Inherits:
-
OpenStudio::Measure::ModelMeasure
- Object
- OpenStudio::Measure::ModelMeasure
- MergeFloorspaceJsWithModel
- Defined in:
- lib/measures/merge_floorspace_js_with_model/measure.rb
Overview
start the measure
Instance Method Summary collapse
-
#arguments(model) ⇒ Object
define the arguments that the user will input.
-
#description ⇒ Object
human readable description.
-
#modeler_description ⇒ Object
human readable description of modeling approach.
-
#name ⇒ Object
human readable name.
-
#run(model, runner, user_arguments) ⇒ Object
define what happens when the measure is run.
Instance Method Details
#arguments(model) ⇒ Object
define the arguments that the user will input
32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/measures/merge_floorspace_js_with_model/measure.rb', line 32 def arguments(model) args = OpenStudio::Measure::OSArgumentVector.new # path to the floorplan JSON file to load floorplan_path = OpenStudio::Measure::OSArgument.makeStringArgument('floorplan_path', true) floorplan_path.setDisplayName('Floorplan Path') floorplan_path.setDescription('Path to the floorplan JSON.') args << floorplan_path return args end |
#description ⇒ Object
human readable description
22 23 24 |
# File 'lib/measures/merge_floorspace_js_with_model/measure.rb', line 22 def description return 'This measure will import a FloorspacJS JSON file into an OpenStudio model. This is meant to function in similar way to the merge function in the geometry editor of the OpenStudio Applicaiton.' end |
#modeler_description ⇒ Object
human readable description of modeling approach
27 28 29 |
# File 'lib/measures/merge_floorspace_js_with_model/measure.rb', line 27 def modeler_description return 'This measure is based off of the ResidentialGeometryCreateFromFloorspaceJS measure on the OpenStudio-Buildstock repository' end |
#name ⇒ Object
human readable name
16 17 18 19 |
# File 'lib/measures/merge_floorspace_js_with_model/measure.rb', line 16 def name # Measure name should be the title case of the class name. return 'Merge FloorspaceJs with Model' end |
#run(model, runner, user_arguments) ⇒ Object
define what happens when the measure is run
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 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 |
# File 'lib/measures/merge_floorspace_js_with_model/measure.rb', line 45 def run(model, runner, user_arguments) super(model, runner, user_arguments) # use the built-in error checking if !runner.validateUserArguments(arguments(model), user_arguments) return false end # assign the user inputs to variables floorplan_path = runner.getStringArgumentValue('floorplan_path', user_arguments) # check the floorplan_path for reasonableness if floorplan_path.empty? runner.registerError('Empty floorplan path was entered.') return false end path = runner.workflow.findFile(floorplan_path) if path.empty? runner.registerError("Cannot find floorplan path '#{floorplan_path}'.") return false end json = nil File.open(path.get.to_s, 'r') do |file| json = file.read end floorplan = OpenStudio::FloorplanJS.load(json) if floorplan.empty? runner.registerError("Cannot load floorplan from '#{floorplan_path}'.") return false end # scene = floorplan.get.toThreeScene(true) # rt = OpenStudio::Model::ThreeJSReverseTranslator.new # new_model = rt.modelFromThreeJS(scene rt = OpenStudio::Model::FloorspaceReverseTranslator.new new_model = rt.modelFromFloorspace(json) unless new_model.is_initialized runner.registerError('Cannot convert floorplan to model.') return false end new_model = new_model.get runner.registerInfo("Model from FloorSpaceJS has #{new_model.getPlanarSurfaceGroups.size} planar surface groups.") puts "hello" puts new_model runner.registerInitialCondition("Initial model has #{model.getPlanarSurfaceGroups.size} planar surface groups.") mm = OpenStudio::Model::ModelMerger.new mm.mergeModels(model, new_model, rt.handleMapping) mm.warnings.each do |warnings| runner.registerWarning(warnings.logMessage) end # put all of the spaces in the model into a vector spaces = OpenStudio::Model::SpaceVector.new model.getSpaces.each do |space| spaces << space end # intersect and match surfaces for each space in the vector # todo - add in diagnostic intersect as option # OpenStudio::Model.intersectSurfaces(spaces) # OpenStudio::Model.matchSurfaces(spaces) # removing duplicate points in a surface model.getPlanarSurfaces.each do |surface| array = [] vertices = surface.vertices fixed = false vertices.each do |vertex| next if fixed if array.include?(vertex) # create a new set of vertices new_vertices = OpenStudio::Point3dVector.new array_b = [] surface.vertices.each do |vertex_b| next if array_b.include?(vertex_b) new_vertices << vertex_b array_b << vertex_b end surface.setVertices(new_vertices) num_removed = vertices.size - surface.vertices.size runner.registerWarning("#{surface.name} has duplicate vertices. Started with #{vertices.size} vertices, removed #{num_removed}.") fixed = true else array << vertex end end end # remove collinear points in a surface model.getPlanarSurfaces.each do |surface| new_vertices = OpenStudio.removeCollinear(surface.vertices) starting_count = surface.vertices.size final_count = new_vertices.size if final_count < starting_count runner.registerWarning("Removing #{starting_count - final_count} collinear vertices from #{surface.name}.") surface.setVertices(new_vertices) end end # remove duplicate surfaces in a space (should be done after remove duplicate and collinear points) model.getSpaces.each do |space| # secondary array to compare against surfaces_b = space.surfaces.sort space.surfaces.sort.each do |surface_a| # delete from secondary array surfaces_b.delete(surface_a) surfaces_b.each do |surface_b| next if surface_a == surface_b # dont' test against same surface if surface_a.equalVertices(surface_b) runner.registerWarning("#{surface_a.name} and #{surface_b.name} in #{space.name} have duplicate geometry, removing #{surface_b.name}.") surface_b.remove elsif surface_a.reverseEqualVertices(surface_b) # TODO: - add logic to determine which face naormal is reversed and which is correct runner.registerWarning("#{surface_a.name} and #{surface_b.name} in #{space.name} have reversed geometry, removing #{surface_b.name}.") surface_b.remove end end end end # secondary array of spaces that we can remove items from once they have gone through in primary loop spaces_b = model.getSpaces.sort # looping through vector of each space model.getSpaces.sort.each do |space_a| runner.registerInfo("Intersecting and matching surfaces for #{space_a.name}.") # delete from secondary array spaces_b.delete(space_a) spaces_b.each do |space_b| # runner.registerInfo("Intersecting and matching surfaces between #{space_a.name} and #{space.name}") spaces = OpenStudio::Model::SpaceVector.new spaces << space_a spaces << space_b # intersect and match surfaces in pair of spaces OpenStudio::Model.intersectSurfaces(spaces) OpenStudio::Model.matchSurfaces(spaces) end end json = JSON.parse(File.read(path.get.to_s)) # error checking if json['space_types'].empty? runner.registerInfo('No space types were created.') end # set the space type standards fields based on what user wrote in the editor json['space_types'].each do |st| model.getSpaceTypes.each do |space_type| next unless space_type.name.to_s.include? st['name'] next if space_type.standardsSpaceType.is_initialized space_type.setStandardsSpaceType(st['name']) end end # remove any unused space types model.getSpaceTypes.each do |space_type| if space_type.spaces.empty? space_type.remove end end # for any spaces with no assigned zone, create (unless another space of the same space type has an assigned zone) a thermal zone based on the space type # todo - add argument to enable disable zone creation model.getSpaceTypes.each do |space_type| space_type.spaces.each do |space| unless space.thermalZone.is_initialized thermal_zone = OpenStudio::Model::ThermalZone.new(model) thermal_zone.setName(space.name.to_s) space.setThermalZone(thermal_zone) end end end # report final condition of model runner.registerFinalCondition("Final model has #{model.getPlanarSurfaceGroups.size} planar surface groups.") return true end |