131 lines
4.9 KiB
Python
131 lines
4.9 KiB
Python
from enum import Enum
|
|
import json
|
|
from helix.constants.panel_type import PanelType
|
|
from helix.functions import fequal
|
|
from helix.models.coordinate import Coordinate
|
|
|
|
|
|
class PanelData(Enum):
|
|
Handle = 'HANDLE'
|
|
Blockname = 'BLOCKNAME'
|
|
Subarray = 'SUBARRAY'
|
|
PanelType = 'POS'
|
|
WindZone = 'WIND'
|
|
Ballast = 'BAL'
|
|
LinkTray = 'LT_CALCULATED'
|
|
CrossTray = 'XTRAY'
|
|
WindAnchor = 'ANC'
|
|
SeismicAnchor = 'SEISMIC'
|
|
Coordinate = 'COORDINATE'
|
|
Pressure = 'PSF'
|
|
Id = 'ID'
|
|
PresentedLinkTray = 'LTRAY'
|
|
Xcoord = 'XCOORD'
|
|
Ycoord = 'YCOORD'
|
|
Rotation = 'ANGLE'
|
|
FuzzyWindZone = 'FUZZYWINDZONE'
|
|
|
|
|
|
class PanelWarnings(Enum):
|
|
MaxPsf = 'The values highlighted are panels that exceed our UL listed load limit. Please do not place panels in these areas to avoid exceeding the listed limit.'
|
|
|
|
class Panel(object):
|
|
def __init__(self, handle=None, blockname=None, subarray=None, panel_type=None, wind_zone=None, ballast=None,
|
|
link_tray=None, cross_tray=None, wind_anchors=None, seismic_anchors=None, coordinate=None,
|
|
pressure=None, id=None, presented_link_tray=None, original_coordinate=None, fuzzy_wind_zone=False,
|
|
warnings=None):
|
|
self.handle = handle
|
|
self.blockname = blockname
|
|
self.subarray = subarray
|
|
self.panel_type = panel_type
|
|
self.wind_zone = wind_zone
|
|
self.ballast = ballast
|
|
self.link_tray = link_tray
|
|
self.cross_tray = cross_tray
|
|
self.wind_anchors = wind_anchors
|
|
self.seismic_anchors = seismic_anchors
|
|
# this field after DXF parsing and before serialization into CSV contains translated coordinates (all positive)
|
|
# and after deserialization from CSV contains original coordinates - same as original_coordinate field
|
|
self.coordinate = coordinate
|
|
self.original_coordinate = original_coordinate
|
|
self.pressure = pressure
|
|
self.id = id
|
|
self.presented_link_tray = presented_link_tray
|
|
self.fuzzy_wind_zone = fuzzy_wind_zone
|
|
self.warnings = warnings or []
|
|
|
|
def merge(self, other):
|
|
if not isinstance(other, self.__class__):
|
|
return self
|
|
|
|
d = {}
|
|
for key, data in self.__dict__.items():
|
|
if data is not None:
|
|
d[key] = data
|
|
else:
|
|
d[key] = other.__dict__.get(key)
|
|
panel = Panel()
|
|
panel.__dict__.update(d)
|
|
return panel
|
|
|
|
def is_subset(self, other):
|
|
if not isinstance(other, self.__class__):
|
|
return False
|
|
for key, value in self.__dict__.items():
|
|
if value is None:
|
|
continue
|
|
if other.__dict__[key] != value:
|
|
return False
|
|
return True
|
|
|
|
def almost_equal(self, other, decimal=6):
|
|
if not isinstance(other, self.__class__):
|
|
return False
|
|
if self.pressure is not None and other.pressure is not None:
|
|
if not fequal(self.pressure, other.pressure, delta=(10 ** (-decimal))):
|
|
print("Pressures are not equal to within %d decimal places, got %f, expected %f" % (decimal, self.pressure, other.pressure))
|
|
return False
|
|
elif self.pressure != other.pressure:
|
|
return False
|
|
for key, value in self.__dict__.items():
|
|
if key == 'pressure':
|
|
continue
|
|
elif other.__dict__.get(key) != value:
|
|
print("Expected %s to be equal, got %s, expected %s" % (key, str(value), str(other.__dict__.get(key))))
|
|
return False
|
|
return True
|
|
|
|
def __deepcopy__(self, _):
|
|
return Panel(handle=self.handle,
|
|
blockname=self.blockname,
|
|
subarray=self.subarray,
|
|
panel_type=self.panel_type,
|
|
wind_zone=self.wind_zone,
|
|
ballast=self.ballast,
|
|
link_tray=self.link_tray,
|
|
cross_tray=self.cross_tray,
|
|
wind_anchors=self.wind_anchors,
|
|
seismic_anchors=self.seismic_anchors,
|
|
coordinate=self.coordinate,
|
|
original_coordinate=self.original_coordinate,
|
|
pressure=self.pressure,
|
|
id=self.id,
|
|
presented_link_tray=self.presented_link_tray,
|
|
fuzzy_wind_zone=self.fuzzy_wind_zone)
|
|
|
|
def __eq__(self, other):
|
|
if self is other:
|
|
return True
|
|
return self.almost_equal(other, decimal=3)
|
|
|
|
def __repr__(self):
|
|
def json_forcer(x):
|
|
if isinstance(x, PanelType):
|
|
return x.value
|
|
if isinstance(x, Coordinate):
|
|
return x.dictionary
|
|
return x.__dict__
|
|
|
|
d = {key: value for (key, value) in self.__dict__.items() if value is not None}
|
|
return json.dumps(d, sort_keys=True, default=json_forcer)
|