mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-25 09:32:37 +00:00
Improve support for Powerproject import (#1865)
This is tested with swedish PowerProject 14.0 file
This commit is contained in:
@@ -1083,6 +1083,11 @@ class ImportP6(bpy.types.Operator, ImportHelper):
|
|||||||
filename_ext = ".xml"
|
filename_ext = ".xml"
|
||||||
filter_glob: bpy.props.StringProperty(default="*.xml", options={"HIDDEN"})
|
filter_glob: bpy.props.StringProperty(default="*.xml", options={"HIDDEN"})
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
ifc_file = IfcStore.get_file()
|
||||||
|
return ifc_file is not None
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
from ifc4d.p62ifc import P62Ifc
|
from ifc4d.p62ifc import P62Ifc
|
||||||
|
|
||||||
@@ -1105,6 +1110,11 @@ class ImportP6XER(bpy.types.Operator, ImportHelper):
|
|||||||
filename_ext = ".xer"
|
filename_ext = ".xer"
|
||||||
filter_glob: bpy.props.StringProperty(default="*.xer", options={"HIDDEN"})
|
filter_glob: bpy.props.StringProperty(default="*.xer", options={"HIDDEN"})
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
ifc_file = IfcStore.get_file()
|
||||||
|
return ifc_file is not None
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
from ifc4d.p6xer2ifc import P6XER2Ifc
|
from ifc4d.p6xer2ifc import P6XER2Ifc
|
||||||
|
|
||||||
@@ -1127,6 +1137,11 @@ class ImportPP(bpy.types.Operator, ImportHelper):
|
|||||||
filename_ext = ".pp"
|
filename_ext = ".pp"
|
||||||
filter_glob: bpy.props.StringProperty(default="*.pp", options={"HIDDEN"})
|
filter_glob: bpy.props.StringProperty(default="*.pp", options={"HIDDEN"})
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
ifc_file = IfcStore.get_file()
|
||||||
|
return ifc_file is not None
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
from ifc4d.pp2ifc import PP2Ifc
|
from ifc4d.pp2ifc import PP2Ifc
|
||||||
|
|
||||||
@@ -1149,6 +1164,11 @@ class ImportMSP(bpy.types.Operator, ImportHelper):
|
|||||||
filename_ext = ".xml"
|
filename_ext = ".xml"
|
||||||
filter_glob: bpy.props.StringProperty(default="*.xml", options={"HIDDEN"})
|
filter_glob: bpy.props.StringProperty(default="*.xml", options={"HIDDEN"})
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def poll(cls, context):
|
||||||
|
ifc_file = IfcStore.get_file()
|
||||||
|
return ifc_file is not None
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
from ifc4d.msp2ifc import MSP2Ifc
|
from ifc4d.msp2ifc import MSP2Ifc
|
||||||
|
|
||||||
|
|||||||
@@ -107,14 +107,14 @@ class PP2Ifc:
|
|||||||
def parse_calendar_pp(self):
|
def parse_calendar_pp(self):
|
||||||
calendars = self.get_json("CALENDAR")
|
calendars = self.get_json("CALENDAR")
|
||||||
wp_data = self.get_json("WORK_PATTERN")
|
wp_data = self.get_json("WORK_PATTERN")
|
||||||
|
work_types = self.get_json("EXCEPTIONN")
|
||||||
|
work_type_ids = [wt['ID'] for wt in work_types if wt['EXCEPTION_TYPE'] == 0]
|
||||||
|
|
||||||
for calendar in calendars:
|
for calendar in calendars:
|
||||||
calendar_id = calendar["ID"]
|
calendar_id = calendar["ID"]
|
||||||
calendar_wp = calendar["DOMINANT_WORK_PATTERN"]
|
calendar_wp = calendar["DOMINANT_WORK_PATTERN"]
|
||||||
wp_data = self.get_json_with_filter("WORK_PATTERN", "ID", calendar_wp)
|
wp_data = self.get_json_with_filter("WORK_PATTERN", "ID", calendar_wp)
|
||||||
print("wp_data", wp_data[0]['SHIFTS'])
|
wp = AstaCalendarWorkPattern(wp_data[0]['SHIFTS'], work_type_ids)
|
||||||
wp = AstaCalendarWorkPattern(wp_data[0]['SHIFTS'])
|
|
||||||
print(wp.dict_wp)
|
|
||||||
exceptions = {}
|
exceptions = {}
|
||||||
timex = []
|
timex = []
|
||||||
for times in wp.dict_wp:
|
for times in wp.dict_wp:
|
||||||
@@ -164,6 +164,13 @@ class PP2Ifc:
|
|||||||
for activity in activities:
|
for activity in activities:
|
||||||
activity_type = "TASK"
|
activity_type = "TASK"
|
||||||
activity_id = activity["ID"]
|
activity_id = activity["ID"]
|
||||||
|
if 'PLANNED_DURATION' in activity.keys():
|
||||||
|
activity_duration = float(activity["PLANNED_DURATION"].split(",")[-2].replace("<","").replace(">",""))
|
||||||
|
elif 'GIVEN_DURATION' in activity.keys():
|
||||||
|
activity_duration = float(activity["GIVEN_DURATION"].split(",")[-2].replace("<","").replace(">",""))
|
||||||
|
else:
|
||||||
|
activity_duration = 0.0
|
||||||
|
|
||||||
wbs_id = activity["BAR"]
|
wbs_id = activity["BAR"]
|
||||||
if wbs_id:
|
if wbs_id:
|
||||||
self.wbs[wbs_id]["activities"].append(activity_id)
|
self.wbs[wbs_id]["activities"].append(activity_id)
|
||||||
@@ -174,7 +181,7 @@ class PP2Ifc:
|
|||||||
"Identification": activity["ID"],
|
"Identification": activity["ID"],
|
||||||
"StartDate": datetime.datetime.fromisoformat(activity["LINKABLE_START"]),
|
"StartDate": datetime.datetime.fromisoformat(activity["LINKABLE_START"]),
|
||||||
"FinishDate": datetime.datetime.fromisoformat(activity["LINKABLE_FINISH"]),
|
"FinishDate": datetime.datetime.fromisoformat(activity["LINKABLE_FINISH"]),
|
||||||
"PlannedDuration": float(activity["PLANNED_DURATION"].split(",")[-2].replace("<","").replace(">","") ),
|
"PlannedDuration": activity_duration,
|
||||||
"Status": "PLANNED",
|
"Status": "PLANNED",
|
||||||
"CalendarObjectId": activity["CALENDAR"],
|
"CalendarObjectId": activity["CALENDAR"],
|
||||||
"ifc": None,
|
"ifc": None,
|
||||||
@@ -202,12 +209,15 @@ class PP2Ifc:
|
|||||||
|
|
||||||
def parse_relationship_pp(self, project):
|
def parse_relationship_pp(self, project):
|
||||||
relations = self.get_json('LINK')
|
relations = self.get_json('LINK')
|
||||||
|
print(relations)
|
||||||
for relationship in relations:
|
for relationship in relations:
|
||||||
predecessor = relationship['START_TASK']
|
predecessor = relationship['START_TASK']
|
||||||
successor = relationship['END_TASK']
|
successor = relationship['END_TASK']
|
||||||
if predecessor not in self.activities or successor not in self.activities:
|
if predecessor not in self.activities:
|
||||||
print("!!!!!!!!!!!!!!!!!ERROR!!!!!!!!!!!!!!!!")
|
print(f"Linked predecessor task {predecessor} cannot be found.")
|
||||||
print(predecessor, successor)
|
continue
|
||||||
|
if successor not in self.activities:
|
||||||
|
print(f"Linked successor task {successor} cannot be found.")
|
||||||
continue
|
continue
|
||||||
self.relationships[relationship["ID"]] = {
|
self.relationships[relationship["ID"]] = {
|
||||||
"PredecessorActivity": predecessor,
|
"PredecessorActivity": predecessor,
|
||||||
|
|||||||
+25
-18
@@ -27,9 +27,12 @@ class AstaCalendarWorkPattern:
|
|||||||
data = re.split('<[^<>]+>', s)
|
data = re.split('<[^<>]+>', s)
|
||||||
return data
|
return data
|
||||||
|
|
||||||
def __init__(self, string):
|
def __init__(self, string, work_type_ids):
|
||||||
self.string = string
|
self.string = string
|
||||||
self.Days = ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday']
|
self.Days = {
|
||||||
|
'en': ['Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday'],
|
||||||
|
'sv': ['Söndag', 'Måndag', 'Tisdag', 'Onsdag', 'Torsdag', 'Fredag', 'Lördag'],
|
||||||
|
}
|
||||||
self.keys = self.get_keys(string)
|
self.keys = self.get_keys(string)
|
||||||
self.values = self.get_values(string)
|
self.values = self.get_values(string)
|
||||||
self.dict_wp = {}
|
self.dict_wp = {}
|
||||||
@@ -37,25 +40,29 @@ class AstaCalendarWorkPattern:
|
|||||||
for d, m in zip(self.values[1:], self.keys):
|
for d, m in zip(self.values[1:], self.keys):
|
||||||
splt_data = d.strip().split(",")
|
splt_data = d.strip().split(",")
|
||||||
workhours = []
|
workhours = []
|
||||||
if len(splt_data)>15:
|
if len(splt_data)>=7:
|
||||||
print(splt_data)
|
number_of_work_slots = splt_data[1]
|
||||||
st1_1 = datetime.strptime(splt_data[6], "%H%M%S")
|
for i in range(int(number_of_work_slots)):
|
||||||
st1_2 = datetime.strptime(splt_data[7], "%H%M%S")
|
if int(splt_data[2+i*3]) in work_type_ids:
|
||||||
st = {"Start":time(st1_1.hour, st1_1.minute), "Finish": time(st1_2.hour, st1_2.minute), "ifc": None}
|
st1_1 = datetime.strptime(splt_data[2+i*3+1].ljust(5,'0'), "%H%M%S")
|
||||||
workhours.append(st)
|
st1_2 = datetime.strptime(splt_data[2+i*3+2].ljust(5,'0'), "%H%M%S")
|
||||||
st2_1 = datetime.strptime(splt_data[12], "%H%M%S")
|
st = {"Start":time(st1_1.hour, st1_1.minute), "Finish": time(st1_2.hour, st1_2.minute), "ifc": None}
|
||||||
st2_2 = datetime.strptime(splt_data[13], "%H%M%S")
|
workhours.append(st)
|
||||||
st2 = {"Start":time(st2_1.hour, st2_1.minute), "Finish": time(st2_2.hour, st2_2.minute), "ifc": None}
|
|
||||||
workhours.append(st2)
|
|
||||||
|
|
||||||
self.dict_wp.append({'DayOfWeek': m.replace("\"",""),
|
self.dict_wp.append({'DayOfWeek': m.replace("\"",""),
|
||||||
'WorkTimes': workhours, "ifc": None})
|
'WorkTimes': workhours, "ifc": None})
|
||||||
|
|
||||||
for day in self.Days:
|
# Translate day names to english
|
||||||
|
for index, day in enumerate(self.Days['en']):
|
||||||
|
d = self.dict_wp[-1]['DayOfWeek']
|
||||||
|
for lang in self.Days.keys():
|
||||||
|
if lang == 'en':
|
||||||
|
continue
|
||||||
|
self.dict_wp[-1]['DayOfWeek'] = d.replace(self.Days[lang][index], self.Days['en'][index])
|
||||||
|
|
||||||
|
for day in self.Days['en']:
|
||||||
if not len(list(filter(lambda d: d['DayOfWeek']== day , self.dict_wp))) > 0:
|
if not len(list(filter(lambda d: d['DayOfWeek']== day , self.dict_wp))) > 0:
|
||||||
print("MISSING", day)
|
print("MISSING", day)
|
||||||
self.dict_wp.append({'DayOfWeek': day,
|
self.dict_wp.append({'DayOfWeek': day,
|
||||||
'WorkTimes': [], "ifc": None})
|
'WorkTimes': [], "ifc": None})
|
||||||
print("final", self.dict_wp)
|
print("final", self.dict_wp)
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user