BlenderBIM: Import Resources for XER files (#1841)

* P6XML Parser failing on calendar type

* add work plan references a get_person which is not an attribute. modified to get_user to work

* Initial support for Primavera XER files

* IFC4D impl XER calendars exceptions and work time

* merged updats

* refactoring code for the 4D model to avoid duplicate code

* Assign process in the api module was missing an atrribute QuantityIn Process

* Merged changes from master

* refactoring

* resolved conflicts

* refactoring code for IFC4D

* refactoring code for IFC4D

* refactoring code for IFC4D

* Reverted the changes to IfcRelAssignsToProcess usecase

* Changed the class to be more discriptive from Utils to ScheduleIfcGenerator

* reverted changes to add_work_plan and Makefile

* Added resource parsing support for Primavera XER

* added relative path for importing common as it was failing in BlenderBIM

* Initial support for Primavera XER files

* merged updats

* Assign process in the api module was missing an atrribute QuantityIn Process

* Merged changes from master

* refactoring

* resolved conflicts

* refactoring code for IFC4D

* refactoring code for IFC4D

* Reverted the changes to IfcRelAssignsToProcess usecase

* Changed the class to be more discriptive from Utils to ScheduleIfcGenerator

* reverted changes to add_work_plan and Makefile

* Added resource parsing support for Primavera XER

* added relative path for importing common as it was failing in BlenderBIM

* deleted repetitive classes for P6XER import

Co-authored-by: Dion Moult <dion@thinkmoult.com>
This commit is contained in:
HassanEmam
2021-10-29 11:16:47 +01:00
committed by GitHub
parent 9f73bd43b4
commit 6a06607f3f
5 changed files with 66 additions and 31 deletions
@@ -1120,28 +1120,6 @@ class ImportP6XER(bpy.types.Operator, ImportHelper):
return {"FINISHED"} return {"FINISHED"}
class ImportP6XER(bpy.types.Operator, ImportHelper):
bl_idname = "import_p6xer.bim"
bl_label = "Import P6 XER"
bl_options = {"REGISTER", "UNDO"}
filename_ext = ".xer"
filter_glob: bpy.props.StringProperty(default="*.xer", options={"HIDDEN"})
def execute(self, context):
from ifc4d.p6xer2ifc import P6XER2Ifc
self.file = IfcStore.get_file()
start = time.time()
p6xer2ifc = P6XER2Ifc()
p6xer2ifc.xer = self.filepath
p6xer2ifc.file = self.file
p6xer2ifc.work_plan = self.file.by_type("IfcWorkPlan")[0] if self.file.by_type("IfcWorkPlan") else None
p6xer2ifc.execute()
Data.load(IfcStore.get_file())
print("Import finished in {:.2f} seconds".format(time.time() - start))
return {"FINISHED"}
class ImportMSP(bpy.types.Operator, ImportHelper): class ImportMSP(bpy.types.Operator, ImportHelper):
bl_idname = "import_msp.bim" bl_idname = "import_msp.bim"
bl_label = "Import MSP" bl_label = "Import MSP"
+39 -2
View File
@@ -7,7 +7,8 @@ from datetime import datetime, timedelta, date
class ScheduleIfcGenerator: class ScheduleIfcGenerator:
def __init__(self, file, work_plan, project, calendars, wbs, root_activites, activities, relationships): def __init__(self, file, work_plan, project, calendars, wbs,
root_activites, activities, relationships, resources):
self.file = file self.file = file
self.work_plan = work_plan self.work_plan = work_plan
self.project = project self.project = project
@@ -16,6 +17,7 @@ class ScheduleIfcGenerator:
self.root_activites = root_activites self.root_activites = root_activites
self.activities = activities self.activities = activities
self.relationships = relationships self.relationships = relationships
self.resources = resources
self.day_map = { self.day_map = {
"Monday": 1, "Monday": 1,
"Tuesday": 2, "Tuesday": 2,
@@ -35,6 +37,7 @@ class ScheduleIfcGenerator:
self.create_calendars() self.create_calendars()
self.create_tasks(work_schedule) self.create_tasks(work_schedule)
self.create_rel_sequences() self.create_rel_sequences()
self.create_resources()
def create_work_schedule(self): def create_work_schedule(self):
return ifcopenshell.api.run( return ifcopenshell.api.run(
@@ -278,9 +281,43 @@ class ScheduleIfcGenerator:
"sequence.assign_lag_time", "sequence.assign_lag_time",
self.file, self.file,
rel_sequence=rel_sequence, rel_sequence=rel_sequence,
lag_value=datetime.timedelta(days=lag / float(calendar["HoursPerDay"])), lag_value=timedelta(days=lag / float(calendar["HoursPerDay"])),
duration_type="WORKTIME", duration_type="WORKTIME",
) )
def create_resources(self):
for id, resource in self.resources.items():
parent = self.resources.get(resource.get("ParentObjectId"))
if parent:
if not parent.get("ifc"):
parent["ifc"] = ifcopenshell.api.run(
"resource.add_resource",
self.file,
**{"ifc_class": "IfcCrewResource",
"name": parent['Name']}
)
if parent:
resource["ifc"] = ifcopenshell.api.run(
"resource.add_resource",
self.file,
**{"parent_resource": parent["ifc"] if parent else None,
"ifc_class": "IfcCrewResource",
"name": resource['Name']
}
)
else:
resource["ifc"] = ifcopenshell.api.run(
"resource.add_resource",
self.file,
**{ "ifc_class": "IfcCrewResource",
"name": resource['Name']
}
)
def create_boilerplate_ifc(self): def create_boilerplate_ifc(self):
self.file = ifcopenshell.file(schema="IFC4") self.file = ifcopenshell.file(schema="IFC4")
+2 -2
View File
@@ -23,7 +23,7 @@ import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.date 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 MSP2Ifc: class MSP2Ifc:
@@ -42,7 +42,7 @@ class MSP2Ifc:
def execute(self): def execute(self):
self.parse_xml() self.parse_xml()
ifcCreator = ScheduleIfcGenerator(self.file, self.work_plan, self.project, self.calendars, ifcCreator = ScheduleIfcGenerator(self.file, self.work_plan, self.project, self.calendars,
self.wbs, self.root_activites, self.activities, self.relationships) self.wbs, self.root_activites, self.activities, self.relationships, None)
ifcCreator.create_ifc() ifcCreator.create_ifc()
#self.create_ifc() #self.create_ifc()
+2 -2
View File
@@ -23,7 +23,7 @@ import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.date 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):
@@ -49,7 +49,7 @@ class P62Ifc:
def execute(self): def execute(self):
self.parse_xml() self.parse_xml()
ifcCreator = ScheduleIfcGenerator(self.file, self.work_plan, self.project, self.calendars, ifcCreator = ScheduleIfcGenerator(self.file, self.work_plan, self.project, self.calendars,
self.wbs, self.root_activites, self.activities, self.relationships) self.wbs, self.root_activites, self.activities, self.relationships, None)
ifcCreator.create_ifc() ifcCreator.create_ifc()
def parse_xml(self): def parse_xml(self):
+23 -3
View File
@@ -21,7 +21,7 @@ import ifcopenshell
import ifcopenshell.api import ifcopenshell.api
import ifcopenshell.util.date import ifcopenshell.util.date
from datetime import datetime, timedelta, date from datetime import datetime, timedelta, date
from common import ScheduleIfcGenerator from .common import ScheduleIfcGenerator
class P6XER2Ifc(): class P6XER2Ifc():
@@ -47,6 +47,12 @@ class P6XER2Ifc():
"PR_FF": "FINISH_FINISH" "PR_FF": "FINISH_FINISH"
} }
RESOURCE_TYPES_MAPPING = {
'RT_Labor': "LABOR",
'RT_Mat': "MATERIAL",
'RT_Equip': "EQUIPMENT"
}
def __init__(self): def __init__(self):
self.xer = None self.xer = None
self.file = None self.file = None
@@ -58,6 +64,7 @@ class P6XER2Ifc():
self.root_activites = [] self.root_activites = []
self.activities = {} self.activities = {}
self.relationships = {} self.relationships = {}
self.resources = {}
self.day_map2 = { self.day_map2 = {
@@ -74,7 +81,7 @@ class P6XER2Ifc():
def execute(self): def execute(self):
self.parse_xer() self.parse_xer()
ifcCreator = ScheduleIfcGenerator(self.file, self.work_plan, self.project, self.calendars, ifcCreator = ScheduleIfcGenerator(self.file, self.work_plan, self.project, self.calendars,
self.wbs, self.root_activites, self.activities, self.relationships) self.wbs, self.root_activites, self.activities, self.relationships, self.resources)
ifcCreator.create_ifc() ifcCreator.create_ifc()
# self.create_ifc() # self.create_ifc()
@@ -84,11 +91,11 @@ class P6XER2Ifc():
# for project in self.model.projects: # for project in self.model.projects:
# if not self.project.get("Name"): # if not self.project.get("Name"):
self.project["Name"] = self.model.projects._projects[0].proj_short_name self.project["Name"] = self.model.projects._projects[0].proj_short_name
print(self.project, type(self.model.projects._projects))
self.parse_calendar_xer() self.parse_calendar_xer()
self.parse_wbs_xer() self.parse_wbs_xer()
self.parse_activity_xer() self.parse_activity_xer()
self.parse_relationship_xer() self.parse_relationship_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)
@@ -160,6 +167,19 @@ class P6XER2Ifc():
} }
def parse_resource_xer(self):
for rsrc in self.model.resources:
self.resources[rsrc.rsrc_id] = {
"Name": rsrc.rsrc_name,
"Code": rsrc.rsrc_short_name,
"ParentObjectId": rsrc.parent_rsrc_id,
"Type": self.RESOURCE_TYPES_MAPPING[rsrc.rsrc_type],
"ifc": None,
"rel": None,
}
print(dir(self.model.resources._rsrcs[0]), self.model.resources._rsrcs[0].rsrc_title_name)
# TODO: add support for resources # TODO: add support for resources