mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-12 06:32:09 +00:00
Allow you to select person and organisation when exporting owner history metadata
This commit is contained in:
@@ -97,6 +97,7 @@ if bpy is not None:
|
|||||||
prop.BIMMeshProperties,
|
prop.BIMMeshProperties,
|
||||||
ui.BIM_PT_documentation,
|
ui.BIM_PT_documentation,
|
||||||
ui.BIM_PT_bim,
|
ui.BIM_PT_bim,
|
||||||
|
ui.BIM_PT_owner,
|
||||||
ui.BIM_PT_context,
|
ui.BIM_PT_context,
|
||||||
ui.BIM_PT_qa,
|
ui.BIM_PT_qa,
|
||||||
ui.BIM_PT_library,
|
ui.BIM_PT_library,
|
||||||
|
|||||||
@@ -1,13 +1,30 @@
|
|||||||
[
|
[
|
||||||
{
|
{
|
||||||
"Name": "ACME",
|
"Name": "IfcOpenShell",
|
||||||
"Description": "Does everything",
|
"Description": "IfcOpenShell is an open source (LGPL) software library that helps users and software developers to work with the IFC file format.",
|
||||||
"Roles": [ { "Role": "ARCHITECT" } ],
|
"Roles": [{
|
||||||
"Addresses": [{
|
"Role": "USERDEFINED",
|
||||||
"Purpose": "OFFICE",
|
"UserDefinedRole": "CONTRIBUTOR"
|
||||||
"Description": "Headquarters",
|
}],
|
||||||
"ElectronicMailAddresses": ["acme@example.com"],
|
"Addresses": [
|
||||||
"WWWHomePageURL": "https://example.com"
|
{
|
||||||
}]
|
"Purpose": "USERDEFINED",
|
||||||
|
"UserDefinedPurpose": "WEBPAGE",
|
||||||
|
"Description": "The main webpage of the software collection.",
|
||||||
|
"WWWHomePageURL": "https://ifcopenshell.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Purpose": "USERDEFINED",
|
||||||
|
"UserDefinedPurpose": "WEBPAGE",
|
||||||
|
"Description": "The BlenderBIM webpage of the software collection.",
|
||||||
|
"WWWHomePageURL": "https://blenderbim.org"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"Purpose": "USERDEFINED",
|
||||||
|
"UserDefinedPurpose": "REPOSITORY",
|
||||||
|
"Description": "The source code repository of the software collection.",
|
||||||
|
"WWWHomePageURL": "https://github.com/IfcOpenShell/IfcOpenShell.git"
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ from pathlib import Path
|
|||||||
from mathutils import Vector, Matrix
|
from mathutils import Vector, Matrix
|
||||||
from .helper import SIUnitHelper
|
from .helper import SIUnitHelper
|
||||||
import ifcopenshell
|
import ifcopenshell
|
||||||
|
import addon_utils
|
||||||
|
|
||||||
class ArrayModifier:
|
class ArrayModifier:
|
||||||
count: int
|
count: int
|
||||||
@@ -567,11 +568,11 @@ class IfcParser():
|
|||||||
|
|
||||||
def get_people(self):
|
def get_people(self):
|
||||||
with open(self.data_dir + 'owner/person.json') as file:
|
with open(self.data_dir + 'owner/person.json') as file:
|
||||||
return json.load(file)
|
return [{'raw': p} for p in json.load(file)]
|
||||||
|
|
||||||
def get_organisations(self):
|
def get_organisations(self):
|
||||||
with open(self.data_dir + 'owner/organisation.json') as file:
|
with open(self.data_dir + 'owner/organisation.json') as file:
|
||||||
return json.load(file)
|
return [{'raw': o} for o in json.load(file)]
|
||||||
|
|
||||||
def get_documents(self):
|
def get_documents(self):
|
||||||
documents = {}
|
documents = {}
|
||||||
@@ -930,11 +931,11 @@ class IfcExporter():
|
|||||||
|
|
||||||
def export(self):
|
def export(self):
|
||||||
self.file = ifcopenshell.open(self.template_file)
|
self.file = ifcopenshell.open(self.template_file)
|
||||||
self.set_common_definitions()
|
|
||||||
self.ifc_parser.parse()
|
self.ifc_parser.parse()
|
||||||
self.create_units()
|
self.create_units()
|
||||||
self.create_people()
|
self.create_people()
|
||||||
self.create_organisations()
|
self.create_organisations()
|
||||||
|
self.set_common_definitions()
|
||||||
self.create_rep_context()
|
self.create_rep_context()
|
||||||
self.create_project()
|
self.create_project()
|
||||||
self.create_library_information()
|
self.create_library_information()
|
||||||
@@ -976,7 +977,38 @@ class IfcExporter():
|
|||||||
def set_common_definitions(self):
|
def set_common_definitions(self):
|
||||||
# Owner history doesn't actually work like this, but for now, it does :)
|
# Owner history doesn't actually work like this, but for now, it does :)
|
||||||
self.origin = self.file.by_type('IfcAxis2Placement3D')[0]
|
self.origin = self.file.by_type('IfcAxis2Placement3D')[0]
|
||||||
self.owner_history = self.file.by_type('IfcOwnerHistory')[0]
|
self.create_owner_history()
|
||||||
|
|
||||||
|
def create_owner_history(self):
|
||||||
|
for person in self.ifc_parser.people:
|
||||||
|
if person['ifc'].Identification == bpy.context.scene.BIMProperties.person:
|
||||||
|
break
|
||||||
|
for organisation in self.ifc_parser.organisations:
|
||||||
|
if organisation['ifc'].Name == bpy.context.scene.BIMProperties.organisation:
|
||||||
|
break
|
||||||
|
person_and_organisation = self.file.create_entity('IfcPersonAndOrganization', **{
|
||||||
|
'ThePerson': person['ifc'],
|
||||||
|
'TheOrganization': organisation['ifc'],
|
||||||
|
'Roles': None # TODO
|
||||||
|
})
|
||||||
|
version = '.'.join([str(x) for x in [addon.bl_info.get('version', (-1,-1,-1)) for addon in addon_utils.modules() if addon.bl_info['name'] == 'BlenderBIM'][0]])
|
||||||
|
developer_organisation = [o for o in self.ifc_parser.organisations if o['ifc'].Name == 'IfcOpenShell'][0]['ifc']
|
||||||
|
application = self.file.create_entity('IfcApplication', **{
|
||||||
|
'ApplicationDeveloper': developer_organisation,
|
||||||
|
'Version': version,
|
||||||
|
'ApplicationFullName': 'BlenderBIM',
|
||||||
|
'ApplicationIdentifier': 'BlenderBIM'
|
||||||
|
})
|
||||||
|
self.owner_history = self.file.create_entity('IfcOwnerHistory', **{
|
||||||
|
'OwningUser': person_and_organisation,
|
||||||
|
'OwningApplication': application,
|
||||||
|
'State': 'READWRITE',
|
||||||
|
'ChangeAction': 'NOTDEFINED',
|
||||||
|
'LastModifiedDate': int(time.time()),
|
||||||
|
'LastModifyingUser': person_and_organisation,
|
||||||
|
'LastModifyingApplication': application,
|
||||||
|
'CreationDate': int(time.time()) # illegal, but better than nothing ...
|
||||||
|
})
|
||||||
|
|
||||||
def create_units(self):
|
def create_units(self):
|
||||||
for unit_type, data in self.ifc_parser.units.items():
|
for unit_type, data in self.ifc_parser.units.items():
|
||||||
@@ -1033,19 +1065,21 @@ class IfcExporter():
|
|||||||
|
|
||||||
def create_people(self):
|
def create_people(self):
|
||||||
for person in self.ifc_parser.people:
|
for person in self.ifc_parser.people:
|
||||||
if person['Roles']:
|
data = person['raw'].copy()
|
||||||
person['Roles'] = self.create_roles(person['Roles'])
|
if data['Roles']:
|
||||||
if person['Addresses']:
|
data['Roles'] = self.create_roles(data['Roles'])
|
||||||
person['Addresses'] = self.create_addresses(person['Addresses'])
|
if data['Addresses']:
|
||||||
self.file.create_entity('IfcPerson', **person)
|
data['Addresses'] = self.create_addresses(data['Addresses'])
|
||||||
|
person['ifc'] = self.file.create_entity('IfcPerson', **data)
|
||||||
|
|
||||||
def create_organisations(self):
|
def create_organisations(self):
|
||||||
for organisation in self.ifc_parser.organisations:
|
for organisation in self.ifc_parser.organisations:
|
||||||
if organisation['Roles']:
|
data = organisation['raw'].copy()
|
||||||
organisation['Roles'] = self.create_roles(organisation['Roles'])
|
if data['Roles']:
|
||||||
if organisation['Addresses']:
|
data['Roles'] = self.create_roles(data['Roles'])
|
||||||
organisation['Addresses'] = self.create_addresses(organisation['Addresses'])
|
if data['Addresses']:
|
||||||
self.file.create_entity('IfcOrganization', **organisation)
|
data['Addresses'] = self.create_addresses(data['Addresses'])
|
||||||
|
organisation['ifc'] = self.file.create_entity('IfcOrganization', **data)
|
||||||
|
|
||||||
def create_roles(self, roles):
|
def create_roles(self, roles):
|
||||||
results = []
|
results = []
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ documents_enum = []
|
|||||||
contexts_enum = []
|
contexts_enum = []
|
||||||
subcontexts_enum = []
|
subcontexts_enum = []
|
||||||
target_views_enum = []
|
target_views_enum = []
|
||||||
|
persons_enum = []
|
||||||
|
organisations_enum = []
|
||||||
|
|
||||||
@persistent
|
@persistent
|
||||||
def setDefaultProperties(scene):
|
def setDefaultProperties(scene):
|
||||||
@@ -92,6 +94,26 @@ def getIfcClasses(self, context):
|
|||||||
return classes_enum
|
return classes_enum
|
||||||
|
|
||||||
|
|
||||||
|
def getPersons(self, context):
|
||||||
|
global persons_enum
|
||||||
|
if len(persons_enum) < 1:
|
||||||
|
persons_enum.clear()
|
||||||
|
with open(os.path.join(self.data_dir, 'owner', 'person.json'), 'r') as f:
|
||||||
|
persons = json.load(f)
|
||||||
|
persons_enum.extend([(p['Identification'], p['Identification'], '') for p in persons])
|
||||||
|
return persons_enum
|
||||||
|
|
||||||
|
|
||||||
|
def getOrganisations(self, context):
|
||||||
|
global organisations_enum
|
||||||
|
if len(organisations_enum) < 1:
|
||||||
|
organisations_enum.clear()
|
||||||
|
with open(os.path.join(self.data_dir, 'owner', 'organisation.json'), 'r') as f:
|
||||||
|
organisations = json.load(f)
|
||||||
|
organisations_enum.extend([(o['Name'], o['Name'], '') for o in organisations])
|
||||||
|
return organisations_enum
|
||||||
|
|
||||||
|
|
||||||
def getPsetNames(self, context):
|
def getPsetNames(self, context):
|
||||||
global psetnames_enum
|
global psetnames_enum
|
||||||
if len(psetnames_enum) < 1:
|
if len(psetnames_enum) < 1:
|
||||||
@@ -215,6 +237,8 @@ class BIMProperties(PropertyGroup):
|
|||||||
import_should_use_legacy: BoolProperty(name="Import with Legacy Importer", default=False)
|
import_should_use_legacy: BoolProperty(name="Import with Legacy Importer", default=False)
|
||||||
import_should_use_cpu_multiprocessing: BoolProperty(name="Import with CPU Multiprocessing", default=False)
|
import_should_use_cpu_multiprocessing: BoolProperty(name="Import with CPU Multiprocessing", default=False)
|
||||||
qa_reject_element_reason: StringProperty(name="Element Rejection Reason")
|
qa_reject_element_reason: StringProperty(name="Element Rejection Reason")
|
||||||
|
person: EnumProperty(items=getPersons, name="Person")
|
||||||
|
organisation: EnumProperty(items=getOrganisations, name="Organisation")
|
||||||
pset_name: EnumProperty(items=getPsetNames, name="Pset Name", update=refreshPsetFiles)
|
pset_name: EnumProperty(items=getPsetNames, name="Pset Name", update=refreshPsetFiles)
|
||||||
pset_file: EnumProperty(items=getPsetFiles, name="Pset File")
|
pset_file: EnumProperty(items=getPsetFiles, name="Pset File")
|
||||||
has_georeferencing: BoolProperty(name="Has Georeferencing", default=False)
|
has_georeferencing: BoolProperty(name="Has Georeferencing", default=False)
|
||||||
|
|||||||
@@ -5,16 +5,11 @@ FILE_NAME('$filename','2019-05-12T12:33:45',('$owner','$email'),('$company'),'If
|
|||||||
FILE_SCHEMA(('IFC4'));
|
FILE_SCHEMA(('IFC4'));
|
||||||
ENDSEC;
|
ENDSEC;
|
||||||
DATA;
|
DATA;
|
||||||
#1=IFCPERSON($,$,'$owner',$,$,$,$,$);
|
#1=IFCDIRECTION((1.,0.,0.));
|
||||||
#2=IFCORGANIZATION($,'$company',$,$,$);
|
#2=IFCDIRECTION((0.,0.,1.));
|
||||||
#3=IFCPERSONANDORGANIZATION(#1,#2,$);
|
#3=IFCCARTESIANPOINT((0.,0.,0.));
|
||||||
#4=IFCAPPLICATION(#2,'0.0.1','Blender BIM IFC','118df2cf_ed21_438e_a41');
|
#4=IFCAXIS2PLACEMENT3D(#3,#2,#1);
|
||||||
#5=IFCOWNERHISTORY(#3,#4,$,.ADDED.,$,#3,#4,1557664425);
|
#5=IFCDIRECTION((0.,1.,0.));
|
||||||
#6=IFCDIRECTION((1.,0.,0.));
|
#6=IFCDIMENSIONALEXPONENTS(0,0,0,0,0,0,0);
|
||||||
#7=IFCDIRECTION((0.,0.,1.));
|
|
||||||
#8=IFCCARTESIANPOINT((0.,0.,0.));
|
|
||||||
#9=IFCAXIS2PLACEMENT3D(#8,#7,#6);
|
|
||||||
#10=IFCDIRECTION((0.,1.,0.));
|
|
||||||
#12=IFCDIMENSIONALEXPONENTS(0,0,0,0,0,0,0);
|
|
||||||
ENDSEC;
|
ENDSEC;
|
||||||
END-ISO-10303-21;
|
END-ISO-10303-21;
|
||||||
|
|||||||
@@ -206,6 +206,27 @@ class BIM_PT_documentation(Panel):
|
|||||||
row = layout.row()
|
row = layout.row()
|
||||||
row.operator('bim.generate_digital_twin')
|
row.operator('bim.generate_digital_twin')
|
||||||
|
|
||||||
|
|
||||||
|
class BIM_PT_owner(Panel):
|
||||||
|
bl_label = "Owner History"
|
||||||
|
bl_idname = "BIM_PT_owner"
|
||||||
|
bl_space_type = 'PROPERTIES'
|
||||||
|
bl_region_type = 'WINDOW'
|
||||||
|
bl_context = "scene"
|
||||||
|
|
||||||
|
def draw(self, context):
|
||||||
|
layout = self.layout
|
||||||
|
layout.use_property_split = True
|
||||||
|
|
||||||
|
scene = context.scene
|
||||||
|
props = scene.BIMProperties
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.prop(props, 'person')
|
||||||
|
|
||||||
|
row = layout.row()
|
||||||
|
row.prop(props, 'organisation')
|
||||||
|
|
||||||
class BIM_PT_context(Panel):
|
class BIM_PT_context(Panel):
|
||||||
bl_label = "Geometric Representation Contexts"
|
bl_label = "Geometric Representation Contexts"
|
||||||
bl_idname = "BIM_PT_context"
|
bl_idname = "BIM_PT_context"
|
||||||
|
|||||||
Reference in New Issue
Block a user