lib/from_honeybee/geometry/aperture.rb in honeybee-openstudio-1.8.1 vs lib/from_honeybee/geometry/aperture.rb in honeybee-openstudio-1.8.2
- old
+ new
@@ -1,167 +1,167 @@
-# *******************************************************************************
-# Honeybee OpenStudio Gem, Copyright (c) 2020, Alliance for Sustainable
-# Energy, LLC, Ladybug Tools LLC and other contributors. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are met:
-#
-# (1) Redistributions of source code must retain the above copyright notice,
-# this list of conditions and the following disclaimer.
-#
-# (2) Redistributions in binary form must reproduce the above copyright notice,
-# this list of conditions and the following disclaimer in the documentation
-# and/or other materials provided with the distribution.
-#
-# (3) Neither the name of the copyright holder nor the names of any contributors
-# may be used to endorse or promote products derived from this software without
-# specific prior written permission from the respective party.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
-# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
-# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
-# UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
-# THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
-# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
-# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
-# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
-# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
-# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-# *******************************************************************************
-
-require 'from_honeybee/model_object'
-
-require 'openstudio'
-
-module FromHoneybee
- class Aperture < ModelObject
- attr_reader :errors, :warnings
-
- def initialize(hash)
- super(hash)
- raise "Incorrect model type '#{@type}'" unless @type == 'Aperture'
- end
-
- def defaults
- @@schema[:components][:schemas][:ApertureEnergyPropertiesAbridged][:properties]
- end
-
- def find_existing_openstudio_object(openstudio_model)
- object = openstudio_model.getSubSurfaceByName(@hash[:identifier])
- return object.get if object.is_initialized
- nil
- end
-
- def to_openstudio(openstudio_model)
- # create the OpenStudio aperture object
- os_vertices = OpenStudio::Point3dVector.new
- @hash[:geometry][:boundary].each do |vertex|
- os_vertices << OpenStudio::Point3d.new(vertex[0], vertex[1], vertex[2])
- end
- reordered_vertices = OpenStudio.reorderULC(os_vertices)
-
- # triangulate subsurface if neccesary
- triangulated = false
- final_vertices_list = []
- matching_os_subsurfaces = []
- matching_os_subsurface_indices = []
- if reordered_vertices.size > 4
-
- # if this apeture has a matched apeture, see if the other one has already been created
- # the matched apeture should have been converted to multiple subsurfaces
- if @hash[:boundary_condition][:type] == 'Surface'
- adj_srf_identifier = @hash[:boundary_condition][:boundary_condition_objects][0]
- regex = Regexp.new("#{adj_srf_identifier}\.\.(\\d+)")
- openstudio_model.getSubSurfaces.each do |subsurface|
- if md = regex.match(subsurface.nameString)
- final_vertices_list << OpenStudio.reorderULC(OpenStudio::reverse(subsurface.vertices))
- matching_os_subsurfaces << subsurface
- matching_os_subsurface_indices << md[1]
- end
- end
- end
-
- # if other apeture is not already created, do the triangulation
- if final_vertices_list.empty?
-
- # transform to face coordinates
- t = OpenStudio::Transformation::alignFace(reordered_vertices)
- tInv = t.inverse
- face_vertices = OpenStudio::reverse(tInv*reordered_vertices)
-
- # no holes in the subsurface
- holes = OpenStudio::Point3dVectorVector.new
-
- # triangulate surface
- triangles = OpenStudio::computeTriangulation(face_vertices, holes)
- if triangles.empty?
- raise "Failed to triangulate aperture #{@hash[:identifier]} with #{reordered_vertices.size} vertices"
- end
-
- # create new list of surfaces
- triangles.each do |vertices|
- final_vertices_list << OpenStudio.reorderULC(OpenStudio::reverse(t*vertices))
- end
-
- triangulated = true
-
- end
-
- else
- # reordered_vertices are good as is
- final_vertices_list << reordered_vertices
- end
-
- result = []
- final_vertices_list.each_with_index do |reordered_vertices, index|
- os_subsurface = OpenStudio::Model::SubSurface.new(reordered_vertices, openstudio_model)
-
- if !matching_os_subsurfaces.empty?
- os_subsurface.setName(@hash[:identifier] + "..#{matching_os_subsurface_indices[index]}")
- elsif triangulated
- os_subsurface.setName(@hash[:identifier] + "..#{index}")
- else
- os_subsurface.setName(@hash[:identifier])
- end
-
- # assign the construction if it exists
- if @hash[:properties][:energy][:construction]
- construction_identifier = @hash[:properties][:energy][:construction]
- construction = openstudio_model.getConstructionByName(construction_identifier)
- unless construction.empty?
- os_construction = construction.get
- os_subsurface.setConstruction(os_construction)
- end
- end
-
- # assign the boundary condition object if it's a Surface
- if @hash[:boundary_condition][:type] == 'Surface'
- if !matching_os_subsurfaces.empty?
- # we already have the match because this was created from the matching_os_subsurfaces
- # setAdjacentSubSurface will fail at this point because sub surface is not assigned to surface yet, store data for later
- adj_srf_identifier = matching_os_subsurfaces[index].nameString
- os_subsurface.additionalProperties.setFeature("AdjacentSubSurfaceName", adj_srf_identifier)
- elsif triangulated
- # other subsurfaces haven't been created yet, no-op
- else
- # get adjacent sub surface by identifier from openstudio model
- # setAdjacentSubSurface will fail at this point because sub surface is not assigned to surface yet, store data for later
- adj_srf_identifier = @hash[:boundary_condition][:boundary_condition_objects][0]
- os_subsurface.additionalProperties.setFeature("AdjacentSubSurfaceName", adj_srf_identifier)
- end
- end
-
- # assign the operable property
- if @hash[:is_operable] == false
- os_subsurface.setSubSurfaceType('FixedWindow')
- else
- os_subsurface.setSubSurfaceType('OperableWindow')
- end
-
- result << os_subsurface
- end
-
- return result
- end
- end # Aperture
-end # FromHoneybee
+# *******************************************************************************
+# Honeybee OpenStudio Gem, Copyright (c) 2020, Alliance for Sustainable
+# Energy, LLC, Ladybug Tools LLC and other contributors. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are met:
+#
+# (1) Redistributions of source code must retain the above copyright notice,
+# this list of conditions and the following disclaimer.
+#
+# (2) Redistributions in binary form must reproduce the above copyright notice,
+# this list of conditions and the following disclaimer in the documentation
+# and/or other materials provided with the distribution.
+#
+# (3) Neither the name of the copyright holder nor the names of any contributors
+# may be used to endorse or promote products derived from this software without
+# specific prior written permission from the respective party.
+#
+# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDER(S) AND ANY CONTRIBUTORS
+# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+# THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER(S), ANY CONTRIBUTORS, THE
+# UNITED STATES GOVERNMENT, OR THE UNITED STATES DEPARTMENT OF ENERGY, NOR ANY OF
+# THEIR EMPLOYEES, BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
+# OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
+# STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+# *******************************************************************************
+
+require 'from_honeybee/model_object'
+
+require 'openstudio'
+
+module FromHoneybee
+ class Aperture < ModelObject
+ attr_reader :errors, :warnings
+
+ def initialize(hash)
+ super(hash)
+ raise "Incorrect model type '#{@type}'" unless @type == 'Aperture'
+ end
+
+ def defaults
+ @@schema[:components][:schemas][:ApertureEnergyPropertiesAbridged][:properties]
+ end
+
+ def find_existing_openstudio_object(openstudio_model)
+ object = openstudio_model.getSubSurfaceByName(@hash[:identifier])
+ return object.get if object.is_initialized
+ nil
+ end
+
+ def to_openstudio(openstudio_model)
+ # create the OpenStudio aperture object
+ os_vertices = OpenStudio::Point3dVector.new
+ @hash[:geometry][:boundary].each do |vertex|
+ os_vertices << OpenStudio::Point3d.new(vertex[0], vertex[1], vertex[2])
+ end
+ reordered_vertices = OpenStudio.reorderULC(os_vertices)
+
+ # triangulate subsurface if neccesary
+ triangulated = false
+ final_vertices_list = []
+ matching_os_subsurfaces = []
+ matching_os_subsurface_indices = []
+ if reordered_vertices.size > 4
+
+ # if this apeture has a matched apeture, see if the other one has already been created
+ # the matched apeture should have been converted to multiple subsurfaces
+ if @hash[:boundary_condition][:type] == 'Surface'
+ adj_srf_identifier = @hash[:boundary_condition][:boundary_condition_objects][0]
+ regex = Regexp.new("#{adj_srf_identifier}\.\.(\\d+)")
+ openstudio_model.getSubSurfaces.each do |subsurface|
+ if md = regex.match(subsurface.nameString)
+ final_vertices_list << OpenStudio.reorderULC(OpenStudio::reverse(subsurface.vertices))
+ matching_os_subsurfaces << subsurface
+ matching_os_subsurface_indices << md[1]
+ end
+ end
+ end
+
+ # if other apeture is not already created, do the triangulation
+ if final_vertices_list.empty?
+
+ # transform to face coordinates
+ t = OpenStudio::Transformation::alignFace(reordered_vertices)
+ tInv = t.inverse
+ face_vertices = OpenStudio::reverse(tInv*reordered_vertices)
+
+ # no holes in the subsurface
+ holes = OpenStudio::Point3dVectorVector.new
+
+ # triangulate surface
+ triangles = OpenStudio::computeTriangulation(face_vertices, holes)
+ if triangles.empty?
+ raise "Failed to triangulate aperture #{@hash[:identifier]} with #{reordered_vertices.size} vertices"
+ end
+
+ # create new list of surfaces
+ triangles.each do |vertices|
+ final_vertices_list << OpenStudio.reorderULC(OpenStudio::reverse(t*vertices))
+ end
+
+ triangulated = true
+
+ end
+
+ else
+ # reordered_vertices are good as is
+ final_vertices_list << reordered_vertices
+ end
+
+ result = []
+ final_vertices_list.each_with_index do |reordered_vertices, index|
+ os_subsurface = OpenStudio::Model::SubSurface.new(reordered_vertices, openstudio_model)
+
+ if !matching_os_subsurfaces.empty?
+ os_subsurface.setName(@hash[:identifier] + "..#{matching_os_subsurface_indices[index]}")
+ elsif triangulated
+ os_subsurface.setName(@hash[:identifier] + "..#{index}")
+ else
+ os_subsurface.setName(@hash[:identifier])
+ end
+
+ # assign the construction if it exists
+ if @hash[:properties][:energy][:construction]
+ construction_identifier = @hash[:properties][:energy][:construction]
+ construction = openstudio_model.getConstructionByName(construction_identifier)
+ unless construction.empty?
+ os_construction = construction.get
+ os_subsurface.setConstruction(os_construction)
+ end
+ end
+
+ # assign the boundary condition object if it's a Surface
+ if @hash[:boundary_condition][:type] == 'Surface'
+ if !matching_os_subsurfaces.empty?
+ # we already have the match because this was created from the matching_os_subsurfaces
+ # setAdjacentSubSurface will fail at this point because sub surface is not assigned to surface yet, store data for later
+ adj_srf_identifier = matching_os_subsurfaces[index].nameString
+ os_subsurface.additionalProperties.setFeature("AdjacentSubSurfaceName", adj_srf_identifier)
+ elsif triangulated
+ # other subsurfaces haven't been created yet, no-op
+ else
+ # get adjacent sub surface by identifier from openstudio model
+ # setAdjacentSubSurface will fail at this point because sub surface is not assigned to surface yet, store data for later
+ adj_srf_identifier = @hash[:boundary_condition][:boundary_condition_objects][0]
+ os_subsurface.additionalProperties.setFeature("AdjacentSubSurfaceName", adj_srf_identifier)
+ end
+ end
+
+ # assign the operable property
+ if @hash[:is_operable] == false
+ os_subsurface.setSubSurfaceType('FixedWindow')
+ else
+ os_subsurface.setSubSurfaceType('OperableWindow')
+ end
+
+ result << os_subsurface
+ end
+
+ return result
+ end
+ end # Aperture
+end # FromHoneybee