mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-18 14:31:39 +00:00
See #2017. Fix bug in P6 importer where nonlabor types were not considered.
This commit is contained in:
+13
-13
@@ -1,6 +1,5 @@
|
|||||||
|
|
||||||
# Ifc4D - IFC scheduling utility
|
# Ifc4D - IFC scheduling utility
|
||||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of Ifc4D.
|
# This file is part of Ifc4D.
|
||||||
#
|
#
|
||||||
@@ -25,6 +24,7 @@ import ifcopenshell.util.date
|
|||||||
import xml.etree.ElementTree as ET
|
import xml.etree.ElementTree as ET
|
||||||
from .common import ScheduleIfcGenerator
|
from .common import ScheduleIfcGenerator
|
||||||
|
|
||||||
|
|
||||||
class P62Ifc:
|
class P62Ifc:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.xml = None
|
self.xml = None
|
||||||
@@ -53,10 +53,12 @@ class P62Ifc:
|
|||||||
"Finish to Start": "FINISH_START",
|
"Finish to Start": "FINISH_START",
|
||||||
"Finish to Finish": "FINISH_FINISH",
|
"Finish to Finish": "FINISH_FINISH",
|
||||||
}
|
}
|
||||||
self.RESOURCE_TYPES_MAPPING = {
|
self.resource_type_map = {
|
||||||
'Labor': "LABOR",
|
"Labor": "LABOR",
|
||||||
'Mat': "MATERIAL",
|
"Mat": "MATERIAL",
|
||||||
'Equip': "EQUIPMENT"
|
"Equip": "EQUIPMENT",
|
||||||
|
# https://www.primaverascheduling.com/category/primavera-resources/
|
||||||
|
"Nonlabor": "EQUIPMENT",
|
||||||
}
|
}
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
@@ -66,18 +68,18 @@ class P62Ifc:
|
|||||||
print("Started")
|
print("Started")
|
||||||
self.parse_xml()
|
self.parse_xml()
|
||||||
settings = {
|
settings = {
|
||||||
"work_plan":self.work_plan,
|
"work_plan": self.work_plan,
|
||||||
"project": self.project,
|
"project": self.project,
|
||||||
"calendars": self.calendars,
|
"calendars": self.calendars,
|
||||||
"wbs": self.wbs,
|
"wbs": self.wbs,
|
||||||
"root_activities": self.root_activites,
|
"root_activities": self.root_activites,
|
||||||
"activities": self.activities,
|
"activities": self.activities,
|
||||||
"relationships": self.relationships,
|
"relationships": self.relationships,
|
||||||
"resources": self.resources
|
"resources": self.resources,
|
||||||
}
|
}
|
||||||
ifcCreator = ScheduleIfcGenerator(self.file, self.output, settings)
|
ifcCreator = ScheduleIfcGenerator(self.file, self.output, settings)
|
||||||
end = time.time()
|
end = time.time()
|
||||||
|
|
||||||
ifcCreator.create_ifc()
|
ifcCreator.create_ifc()
|
||||||
end2 = time.time()
|
end2 = time.time()
|
||||||
print("Parsing time is", end - start)
|
print("Parsing time is", end - start)
|
||||||
@@ -201,8 +203,7 @@ class P62Ifc:
|
|||||||
|
|
||||||
def get_wbs(self, wbs):
|
def get_wbs(self, wbs):
|
||||||
return {"Name": wbs.find("pr:Name", self.ns).text, "subtasks": []}
|
return {"Name": wbs.find("pr:Name", self.ns).text, "subtasks": []}
|
||||||
|
|
||||||
|
|
||||||
def parse_resources_xml(self, project):
|
def parse_resources_xml(self, project):
|
||||||
resources = project.findall("pr:Resource", self.ns)
|
resources = project.findall("pr:Resource", self.ns)
|
||||||
for resource in resources:
|
for resource in resources:
|
||||||
@@ -211,9 +212,8 @@ class P62Ifc:
|
|||||||
"Name": resource.find("pr:Name", self.ns).text,
|
"Name": resource.find("pr:Name", self.ns).text,
|
||||||
"Code": resource.find("pr:Id", self.ns).text,
|
"Code": resource.find("pr:Id", self.ns).text,
|
||||||
"ParentObjectId": resource.find("pr:ParentObjectId", self.ns).text,
|
"ParentObjectId": resource.find("pr:ParentObjectId", self.ns).text,
|
||||||
"Type": self.RESOURCE_TYPES_MAPPING[resource.find("pr:ResourceType", self.ns).text],
|
"Type": self.resource_type_map[resource.find("pr:ResourceType", self.ns).text],
|
||||||
"ifc": None,
|
"ifc": None,
|
||||||
"rel": None,
|
"rel": None,
|
||||||
}
|
}
|
||||||
print("Resource found", self.resources)
|
print("Resource found", self.resources)
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||||
# Copyright (C) 2020, 2021 Dion Moult <dion@thinkmoult.com>
|
# Copyright (C) 2020, 2021, 2022 Dion Moult <dion@thinkmoult.com>
|
||||||
#
|
#
|
||||||
# This file is part of BlenderBIM Add-on.
|
# This file is part of BlenderBIM Add-on.
|
||||||
#
|
#
|
||||||
@@ -24,35 +24,33 @@ from datetime import datetime, timedelta, date
|
|||||||
from .common import ScheduleIfcGenerator
|
from .common import ScheduleIfcGenerator
|
||||||
|
|
||||||
|
|
||||||
class P6XER2Ifc():
|
class P6XER2Ifc:
|
||||||
status_map = {
|
status_map = {"TK_NotStart": "Not Start", "TK_Complete": "Completed", "TK_Active": "Progress"}
|
||||||
"TK_NotStart": "Not Start",
|
|
||||||
"TK_Complete": "Completed",
|
|
||||||
"TK_Active": "Progress"
|
|
||||||
}
|
|
||||||
|
|
||||||
TASK_TYPE_MAP = {
|
TASK_TYPE_MAP = {
|
||||||
"TT_Task": "Task",
|
"TT_Task": "Task",
|
||||||
"TT_Rsrc": "Resource Dependent Task",
|
"TT_Rsrc": "Resource Dependent Task",
|
||||||
"TT_LOE": "Level of Effort",
|
"TT_LOE": "Level of Effort",
|
||||||
"TT_Mile": "Start Milestone",
|
"TT_Mile": "Start Milestone",
|
||||||
"TT_FinMile": "Finish Milestone",
|
"TT_FinMile": "Finish Milestone",
|
||||||
"TT_WBS": "WBS Summary"
|
"TT_WBS": "WBS Summary",
|
||||||
}
|
}
|
||||||
|
|
||||||
RELATIONSHIP_TYPE_MAPPING = {
|
RELATIONSHIP_TYPE_MAPPING = {
|
||||||
"PR_SS": "START_START",
|
"PR_SS": "START_START",
|
||||||
"PR_FS": "FINISH_START",
|
"PR_FS": "FINISH_START",
|
||||||
"PR_SF": "START_FINISH",
|
"PR_SF": "START_FINISH",
|
||||||
"PR_FF": "FINISH_FINISH"
|
"PR_FF": "FINISH_FINISH",
|
||||||
}
|
}
|
||||||
|
|
||||||
RESOURCE_TYPES_MAPPING = {
|
resource_type_map = {
|
||||||
'RT_Labor': "LABOR",
|
"RT_Labor": "LABOR",
|
||||||
'RT_Mat': "MATERIAL",
|
"RT_Mat": "MATERIAL",
|
||||||
'RT_Equip': "EQUIPMENT"
|
# https://www.primaverascheduling.com/category/primavera-resources/
|
||||||
|
"RT_Nonlabor": "EQUIPMENT",
|
||||||
|
"RT_Equip": "EQUIPMENT",
|
||||||
}
|
}
|
||||||
|
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.xer = None
|
self.xer = None
|
||||||
self.file = None
|
self.file = None
|
||||||
@@ -66,34 +64,32 @@ class P6XER2Ifc():
|
|||||||
self.relationships = {}
|
self.relationships = {}
|
||||||
self.resources = {}
|
self.resources = {}
|
||||||
self.output = None
|
self.output = None
|
||||||
|
|
||||||
self.day_map2 = {
|
self.day_map2 = {
|
||||||
'1': "Monday",
|
"1": "Monday",
|
||||||
'2': "Tuesday",
|
"2": "Tuesday",
|
||||||
'3': "Wednesday",
|
"3": "Wednesday",
|
||||||
'4': "Thursday",
|
"4": "Thursday",
|
||||||
'5': "Friday",
|
"5": "Friday",
|
||||||
'6': "Saturday",
|
"6": "Saturday",
|
||||||
'7': "Sunday",
|
"7": "Sunday",
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def execute(self):
|
def execute(self):
|
||||||
self.parse_xer()
|
self.parse_xer()
|
||||||
settings = {
|
settings = {
|
||||||
"work_plan":self.work_plan,
|
"work_plan": self.work_plan,
|
||||||
"project": self.project,
|
"project": self.project,
|
||||||
"calendars": self.calendars,
|
"calendars": self.calendars,
|
||||||
"wbs": self.wbs,
|
"wbs": self.wbs,
|
||||||
"root_activities": self.root_activites,
|
"root_activities": self.root_activites,
|
||||||
"activities": self.activities,
|
"activities": self.activities,
|
||||||
"relationships": self.relationships,
|
"relationships": self.relationships,
|
||||||
"resources": self.resources
|
"resources": self.resources,
|
||||||
}
|
}
|
||||||
ifcCreator = ScheduleIfcGenerator(self.file, self.output, settings)
|
ifcCreator = ScheduleIfcGenerator(self.file, self.output, settings)
|
||||||
ifcCreator.create_ifc()
|
ifcCreator.create_ifc()
|
||||||
|
|
||||||
|
|
||||||
def parse_xer(self):
|
def parse_xer(self):
|
||||||
self.model = Reader(self.xer)
|
self.model = Reader(self.xer)
|
||||||
# for project in self.model.projects:
|
# for project in self.model.projects:
|
||||||
@@ -104,10 +100,9 @@ class P6XER2Ifc():
|
|||||||
self.parse_activity_xer()
|
self.parse_activity_xer()
|
||||||
self.parse_relationship_xer()
|
self.parse_relationship_xer()
|
||||||
self.parse_resource_xer()
|
self.parse_resource_xer()
|
||||||
#work_schedule = self.create_work_schedule()
|
# work_schedule = self.create_work_schedule()
|
||||||
#self.create_tasks(work_schedule)
|
# self.create_tasks(work_schedule)
|
||||||
|
|
||||||
|
|
||||||
def parse_wbs_xer(self):
|
def parse_wbs_xer(self):
|
||||||
for wbs in self.model.wbss:
|
for wbs in self.model.wbss:
|
||||||
self.wbs[wbs.wbs_id] = {
|
self.wbs[wbs.wbs_id] = {
|
||||||
@@ -118,8 +113,8 @@ class P6XER2Ifc():
|
|||||||
"rel": None,
|
"rel": None,
|
||||||
"activities": [],
|
"activities": [],
|
||||||
}
|
}
|
||||||
#print(self.wbs)
|
# print(self.wbs)
|
||||||
|
|
||||||
def parse_calendar_xer(self):
|
def parse_calendar_xer(self):
|
||||||
standard_work_week = []
|
standard_work_week = []
|
||||||
exceptions = {}
|
exceptions = {}
|
||||||
@@ -127,11 +122,11 @@ class P6XER2Ifc():
|
|||||||
standard_work_week = cal.working_hours
|
standard_work_week = cal.working_hours
|
||||||
except_lst = cal.exceptions
|
except_lst = cal.exceptions
|
||||||
for exception in except_lst:
|
for exception in except_lst:
|
||||||
month = exceptions.setdefault(exception.year, {}).setdefault(exception.month, {})
|
month = exceptions.setdefault(exception.year, {}).setdefault(exception.month, {})
|
||||||
month.setdefault("FullDay", [])
|
month.setdefault("FullDay", [])
|
||||||
month.setdefault("WorkTime", [])
|
month.setdefault("WorkTime", [])
|
||||||
exceptions[exception.year][exception.month]["FullDay"].append(exception.day)
|
exceptions[exception.year][exception.month]["FullDay"].append(exception.day)
|
||||||
|
|
||||||
self.calendars[cal.clndr_id] = {
|
self.calendars[cal.clndr_id] = {
|
||||||
"Name": cal.clndr_name,
|
"Name": cal.clndr_name,
|
||||||
"Type": cal.clndr_type,
|
"Type": cal.clndr_type,
|
||||||
@@ -139,7 +134,7 @@ class P6XER2Ifc():
|
|||||||
"StandardWorkWeek": standard_work_week,
|
"StandardWorkWeek": standard_work_week,
|
||||||
"HolidayOrExceptions": exceptions,
|
"HolidayOrExceptions": exceptions,
|
||||||
}
|
}
|
||||||
|
|
||||||
def parse_activity_xer(self):
|
def parse_activity_xer(self):
|
||||||
for activity in self.model.activities:
|
for activity in self.model.activities:
|
||||||
activity_type = activity.task_type
|
activity_type = activity.task_type
|
||||||
@@ -158,9 +153,9 @@ class P6XER2Ifc():
|
|||||||
"PlannedDuration": activity.target_drtn_hr_cnt,
|
"PlannedDuration": activity.target_drtn_hr_cnt,
|
||||||
"Status": self.status_map[activity.status_code],
|
"Status": self.status_map[activity.status_code],
|
||||||
"CalendarObjectId": activity.clndr_id,
|
"CalendarObjectId": activity.clndr_id,
|
||||||
"ifc": None
|
"ifc": None,
|
||||||
}
|
}
|
||||||
|
|
||||||
def parse_relationship_xer(self):
|
def parse_relationship_xer(self):
|
||||||
for rel in self.model.relations:
|
for rel in self.model.relations:
|
||||||
predecessor = rel.pred_task_id
|
predecessor = rel.pred_task_id
|
||||||
@@ -173,7 +168,6 @@ class P6XER2Ifc():
|
|||||||
"Type": self.RELATIONSHIP_TYPE_MAPPING[rel.pred_type],
|
"Type": self.RELATIONSHIP_TYPE_MAPPING[rel.pred_type],
|
||||||
"Lag": rel.lag_hr_cnt,
|
"Lag": rel.lag_hr_cnt,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
def parse_resource_xer(self):
|
def parse_resource_xer(self):
|
||||||
for rsrc in self.model.resources:
|
for rsrc in self.model.resources:
|
||||||
@@ -181,16 +175,13 @@ class P6XER2Ifc():
|
|||||||
"Name": rsrc.rsrc_name,
|
"Name": rsrc.rsrc_name,
|
||||||
"Code": rsrc.rsrc_short_name,
|
"Code": rsrc.rsrc_short_name,
|
||||||
"ParentObjectId": rsrc.parent_rsrc_id,
|
"ParentObjectId": rsrc.parent_rsrc_id,
|
||||||
"Type": self.RESOURCE_TYPES_MAPPING[rsrc.rsrc_type],
|
"Type": self.resource_type_map[rsrc.rsrc_type],
|
||||||
"ifc": None,
|
"ifc": None,
|
||||||
"rel": None,
|
"rel": None,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: add support for resources
|
# TODO: add support for resources
|
||||||
# TODO: consider showing progress bar for better user experience
|
# TODO: consider showing progress bar for better user experience
|
||||||
# TODO: support multiple projects in a single file
|
# TODO: support multiple projects in a single file
|
||||||
# TODO: prompt user to select activities and/or wbs nodes to import instead of the full project
|
# TODO: prompt user to select activities and/or wbs nodes to import instead of the full project
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user