mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 09:21:46 +00:00
Refactor Resource module
This commit is contained in:
@@ -27,7 +27,7 @@ from blenderbim.bim.ifc import IfcStore
|
|||||||
from bpy_extras.io_utils import ImportHelper
|
from bpy_extras.io_utils import ImportHelper
|
||||||
from ifcopenshell.api.cost.data import Data
|
from ifcopenshell.api.cost.data import Data
|
||||||
from ifcopenshell.api.unit.data import Data as UnitData
|
from ifcopenshell.api.unit.data import Data as UnitData
|
||||||
from ifcopenshell.api.resource.data import Data as ResourceData
|
from blenderbim.bim.module.resource.data import ResourceData
|
||||||
|
|
||||||
|
|
||||||
class AddCostSchedule(bpy.types.Operator):
|
class AddCostSchedule(bpy.types.Operator):
|
||||||
@@ -604,7 +604,7 @@ class AddCostValue(bpy.types.Operator):
|
|||||||
value = ifcopenshell.api.run("cost.add_cost_value", self.file, parent=parent)
|
value = ifcopenshell.api.run("cost.add_cost_value", self.file, parent=parent)
|
||||||
ifcopenshell.api.run("cost.edit_cost_value", self.file, cost_value=value, attributes=attributes)
|
ifcopenshell.api.run("cost.edit_cost_value", self.file, cost_value=value, attributes=attributes)
|
||||||
if parent.is_a("IfcConstructionResource"):
|
if parent.is_a("IfcConstructionResource"):
|
||||||
ResourceData.load(self.file)
|
ResourceData.load()
|
||||||
else:
|
else:
|
||||||
Data.load(self.file)
|
Data.load(self.file)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
@@ -630,7 +630,7 @@ class RemoveCostItemValue(bpy.types.Operator):
|
|||||||
cost_value=self.file.by_id(self.cost_value),
|
cost_value=self.file.by_id(self.cost_value),
|
||||||
)
|
)
|
||||||
if parent.is_a("IfcConstructionResource"):
|
if parent.is_a("IfcConstructionResource"):
|
||||||
ResourceData.load(self.file)
|
ResourceData.load()
|
||||||
else:
|
else:
|
||||||
Data.load(self.file)
|
Data.load(self.file)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|||||||
@@ -0,0 +1,89 @@
|
|||||||
|
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||||
|
# Copyright (C) 2021-2022 Dion Moult <dion@thinkmoult.com>, Yassine Oualid <yassine@sigmadimensions.com>
|
||||||
|
#
|
||||||
|
# This file is part of BlenderBIM Add-on.
|
||||||
|
#
|
||||||
|
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
import blenderbim.tool as tool
|
||||||
|
from ifcopenshell.api.cost.data import CostValueTrait
|
||||||
|
import ifcopenshell
|
||||||
|
|
||||||
|
|
||||||
|
def refresh():
|
||||||
|
ResourceData.is_loaded = False
|
||||||
|
|
||||||
|
|
||||||
|
class ResourceData(CostValueTrait):
|
||||||
|
data = {}
|
||||||
|
is_loaded = False
|
||||||
|
cost_values = {}
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load(cls):
|
||||||
|
cls.data = {
|
||||||
|
"has_resources": cls.has_resources(),
|
||||||
|
}
|
||||||
|
cls.load_resources()
|
||||||
|
cls.is_loaded = True
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def has_resources(cls):
|
||||||
|
return bool(tool.Ifc.get().by_type("IfcResource"))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def number_of_resources_loaded(cls):
|
||||||
|
return len(tool.Ifc.get().by_type("IfcResource"))
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_resources(cls):
|
||||||
|
cls.data["resources"] = {}
|
||||||
|
for resource in tool.Ifc.get().by_type("IfcResource"):
|
||||||
|
data = resource.get_info()
|
||||||
|
del data["OwnerHistory"]
|
||||||
|
data["IsNestedBy"] = []
|
||||||
|
for rel in resource.IsNestedBy:
|
||||||
|
[data["IsNestedBy"].append(o.id()) for o in rel.RelatedObjects]
|
||||||
|
data["Nests"] = []
|
||||||
|
for rel in resource.Nests:
|
||||||
|
[data["Nests"].append(rel.RelatingObject.id())]
|
||||||
|
data["ResourceOf"] = []
|
||||||
|
for rel in resource.ResourceOf:
|
||||||
|
[data["ResourceOf"].append(o.id()) for o in rel.RelatedObjects]
|
||||||
|
data["HasContext"] = resource.HasContext[0].RelatingContext.id() if resource.HasContext else None
|
||||||
|
if resource.Usage:
|
||||||
|
data["Usage"] = data["Usage"].id()
|
||||||
|
data["TotalCostQuantity"] = cls.get_total_quantity(resource)
|
||||||
|
if resource.BaseQuantity:
|
||||||
|
data["BaseQuantity"] = resource.BaseQuantity.get_info()
|
||||||
|
del data["BaseQuantity"]["Unit"]
|
||||||
|
if resource.BaseCosts:
|
||||||
|
data["BaseCosts"] = [e.id() for e in resource.BaseCosts]
|
||||||
|
cls.load_cost_values(resource, data)
|
||||||
|
cls.data["resources"][resource.id()] = data
|
||||||
|
cls.data["number_of_resources_loaded"] = cls.number_of_resources_loaded()
|
||||||
|
|
||||||
|
def load_resource_times(cls):
|
||||||
|
cls.data["resource_times"] = {}
|
||||||
|
for resource_time in tool.Ifc.get().by_type("IfcResourceTime"):
|
||||||
|
data = resource_time.get_info()
|
||||||
|
for key, value in data.items():
|
||||||
|
if not value:
|
||||||
|
continue
|
||||||
|
if "Start" in key or "Finish" in key or key == "StatusTime":
|
||||||
|
data[key] = ifcopenshell.util.date.ifc2datetime(value)
|
||||||
|
elif "Work" in key or key == "LevelingDelay":
|
||||||
|
data[key] = ifcopenshell.util.date.ifc2datetime(value)
|
||||||
|
cls.data["resource_times"][resource_time.id()] = data
|
||||||
@@ -17,17 +17,9 @@
|
|||||||
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
import bpy
|
import bpy
|
||||||
import json
|
from bpy_extras.io_utils import ImportHelper
|
||||||
import time
|
import blenderbim.core.resource as core
|
||||||
import isodate
|
import blenderbim.tool as tool
|
||||||
import ifcopenshell.api
|
|
||||||
import blenderbim.bim.helper
|
|
||||||
import blenderbim.bim.module.sequence.helper as helper
|
|
||||||
from datetime import datetime
|
|
||||||
from blenderbim.bim.ifc import IfcStore
|
|
||||||
from ifcopenshell.api.resource.data import Data
|
|
||||||
from ifcopenshell.api.unit.data import Data as UnitData
|
|
||||||
|
|
||||||
|
|
||||||
class LoadResources(bpy.types.Operator):
|
class LoadResources(bpy.types.Operator):
|
||||||
bl_idname = "bim.load_resources"
|
bl_idname = "bim.load_resources"
|
||||||
@@ -35,66 +27,9 @@ class LoadResources(bpy.types.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
self.props = context.scene.BIMResourceProperties
|
core.load_resources(tool.Resource)
|
||||||
self.tprops = context.scene.BIMResourceTreeProperties
|
|
||||||
self.tprops.resources.clear()
|
|
||||||
|
|
||||||
self.contracted_resources = json.loads(self.props.contracted_resources)
|
|
||||||
Data.load(IfcStore.get_file())
|
|
||||||
for resource_id, data in Data.resources.items():
|
|
||||||
if not data["HasContext"]:
|
|
||||||
continue
|
|
||||||
self.create_new_resource_li(resource_id, 0)
|
|
||||||
bpy.ops.bim.load_resource_properties()
|
|
||||||
self.props.is_editing = True
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def create_new_resource_li(self, related_object_id, level_index):
|
|
||||||
resource = Data.resources[related_object_id]
|
|
||||||
new = self.tprops.resources.add()
|
|
||||||
new.ifc_definition_id = related_object_id
|
|
||||||
new.is_expanded = related_object_id not in self.contracted_resources
|
|
||||||
new.level_index = level_index
|
|
||||||
if resource["IsNestedBy"]:
|
|
||||||
new.has_children = True
|
|
||||||
if new.is_expanded:
|
|
||||||
for related_object_id in resource["IsNestedBy"]:
|
|
||||||
self.create_new_resource_li(related_object_id, level_index + 1)
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class EnableEditingResource(bpy.types.Operator):
|
|
||||||
bl_idname = "bim.enable_editing_resource"
|
|
||||||
bl_label = "Enable Editing Resource"
|
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
|
||||||
resource: bpy.props.IntProperty()
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
self.props = context.scene.BIMResourceProperties
|
|
||||||
self.props.active_resource_id = self.resource
|
|
||||||
self.props.resource_attributes.clear()
|
|
||||||
self.props.editing_resource_type = "ATTRIBUTES"
|
|
||||||
self.enable_editing_resource()
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
def enable_editing_resource(self):
|
|
||||||
data = Data.resources[self.resource]
|
|
||||||
for attribute in IfcStore.get_schema().declaration_by_name(data["type"]).all_attributes():
|
|
||||||
data_type = ifcopenshell.util.attribute.get_primitive_type(attribute)
|
|
||||||
if data_type == "entity" or isinstance(data_type, tuple):
|
|
||||||
continue
|
|
||||||
new = self.props.resource_attributes.add()
|
|
||||||
new.name = attribute.name()
|
|
||||||
new.is_null = data[attribute.name()] is None
|
|
||||||
new.is_optional = attribute.optional()
|
|
||||||
new.data_type = data_type
|
|
||||||
if data_type == "string":
|
|
||||||
new.string_value = "" if new.is_null else data[attribute.name()]
|
|
||||||
elif data_type == "enum":
|
|
||||||
new.enum_items = json.dumps(ifcopenshell.util.attribute.get_enum_items(attribute))
|
|
||||||
if data[attribute.name()]:
|
|
||||||
new.enum_value = data[attribute.name()]
|
|
||||||
|
|
||||||
|
|
||||||
class LoadResourceProperties(bpy.types.Operator):
|
class LoadResourceProperties(bpy.types.Operator):
|
||||||
bl_idname = "bim.load_resource_properties"
|
bl_idname = "bim.load_resource_properties"
|
||||||
@@ -103,15 +38,36 @@ class LoadResourceProperties(bpy.types.Operator):
|
|||||||
resource: bpy.props.IntProperty()
|
resource: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
self.props = context.scene.BIMResourceProperties
|
core.load_resource_properties(
|
||||||
self.tprops = context.scene.BIMResourceTreeProperties
|
tool.Resource, resource=tool.Ifc.get().by_id(self.resource) if self.resource else None
|
||||||
self.props.is_resource_update_enabled = False
|
)
|
||||||
for item in self.tprops.resources:
|
return {"FINISHED"}
|
||||||
if self.resource and item.ifc_definition_id != self.resource:
|
|
||||||
continue
|
|
||||||
resource = Data.resources[item.ifc_definition_id]
|
class AddResource(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
item.name = resource["Name"] or "Unnamed"
|
bl_idname = "bim.add_resource"
|
||||||
self.props.is_resource_update_enabled = True
|
bl_label = "Add resource"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
ifc_class: bpy.props.StringProperty()
|
||||||
|
parent_resource: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
def _execute(self, context):
|
||||||
|
core.add_resource(
|
||||||
|
tool.Ifc,
|
||||||
|
tool.Resource,
|
||||||
|
ifc_class=self.ifc_class,
|
||||||
|
parent_resource=tool.Ifc.get().by_id(self.parent_resource) if self.parent_resource else None,
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
class EnableEditingResource(bpy.types.Operator):
|
||||||
|
bl_idname = "bim.enable_editing_resource"
|
||||||
|
bl_label = "Enable Editing Resource"
|
||||||
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
resource: bpy.props.IntProperty()
|
||||||
|
|
||||||
|
def execute(self, context):
|
||||||
|
core.enable_editing_resource(tool.Resource, resource=tool.Ifc.get().by_id(self.resource))
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -121,8 +77,7 @@ class DisableEditingResource(bpy.types.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
context.scene.BIMResourceProperties.active_resource_id = 0
|
core.disable_editing_resource(tool.Resource)
|
||||||
context.scene.BIMResourceProperties.active_task_time_id = 0
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -132,73 +87,31 @@ class DisableResourceEditingUI(bpy.types.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
context.scene.BIMResourceProperties.is_editing = False
|
core.disable_resource_editing_ui(tool.Resource)
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class AddResource(bpy.types.Operator):
|
class EditResource(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.add_resource"
|
|
||||||
bl_label = "Add resource"
|
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
|
||||||
ifc_class: bpy.props.StringProperty()
|
|
||||||
resource: bpy.props.IntProperty()
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
return IfcStore.execute_ifc_operator(self, context)
|
|
||||||
|
|
||||||
def _execute(self, context):
|
|
||||||
ifcopenshell.api.run(
|
|
||||||
"resource.add_resource",
|
|
||||||
IfcStore.get_file(),
|
|
||||||
parent_resource=IfcStore.get_file().by_id(self.resource) if self.resource else None,
|
|
||||||
ifc_class=self.ifc_class,
|
|
||||||
)
|
|
||||||
Data.load(IfcStore.get_file())
|
|
||||||
bpy.ops.bim.load_resources()
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class EditResource(bpy.types.Operator):
|
|
||||||
bl_idname = "bim.edit_resource"
|
bl_idname = "bim.edit_resource"
|
||||||
bl_label = "Edit Resource"
|
bl_label = "Edit Resource"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
return IfcStore.execute_ifc_operator(self, context)
|
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMResourceProperties
|
core.edit_resource(
|
||||||
attributes = blenderbim.bim.helper.export_attributes(props.resource_attributes)
|
tool.Ifc,
|
||||||
self.file = IfcStore.get_file()
|
tool.Resource,
|
||||||
ifcopenshell.api.run(
|
resource=tool.Ifc.get().by_id(context.scene.BIMResourceProperties.active_resource_id),
|
||||||
"resource.edit_resource",
|
|
||||||
self.file,
|
|
||||||
**{"resource": self.file.by_id(props.active_resource_id), "attributes": attributes},
|
|
||||||
)
|
)
|
||||||
Data.load(IfcStore.get_file())
|
|
||||||
bpy.ops.bim.load_resource_properties(resource=props.active_resource_id)
|
|
||||||
bpy.ops.bim.disable_editing_resource()
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class RemoveResource(bpy.types.Operator):
|
class RemoveResource(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.remove_resource"
|
bl_idname = "bim.remove_resource"
|
||||||
bl_label = "Remove Resource"
|
bl_label = "Remove Resource"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
resource: bpy.props.IntProperty()
|
resource: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
return IfcStore.execute_ifc_operator(self, context)
|
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
ifcopenshell.api.run(
|
core.remove_resource(tool.Ifc, tool.Resource, resource=tool.Ifc.get().by_id(self.resource))
|
||||||
"resource.remove_resource",
|
|
||||||
IfcStore.get_file(),
|
|
||||||
resource=IfcStore.get_file().by_id(self.resource),
|
|
||||||
)
|
|
||||||
Data.load(IfcStore.get_file())
|
|
||||||
bpy.ops.bim.load_resources()
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class ExpandResource(bpy.types.Operator):
|
class ExpandResource(bpy.types.Operator):
|
||||||
@@ -208,13 +121,7 @@ class ExpandResource(bpy.types.Operator):
|
|||||||
resource: bpy.props.IntProperty()
|
resource: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
props = context.scene.BIMResourceProperties
|
core.expand_resource(tool.Resource, resource=tool.Ifc.get().by_id(self.resource))
|
||||||
self.file = IfcStore.get_file()
|
|
||||||
contracted_resources = json.loads(props.contracted_resources)
|
|
||||||
contracted_resources.remove(self.resource)
|
|
||||||
props.contracted_resources = json.dumps(contracted_resources)
|
|
||||||
Data.load(self.file)
|
|
||||||
bpy.ops.bim.load_resources()
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -225,107 +132,40 @@ class ContractResource(bpy.types.Operator):
|
|||||||
resource: bpy.props.IntProperty()
|
resource: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
props = context.scene.BIMResourceProperties
|
core.contract_resource(tool.Resource, resource=tool.Ifc.get().by_id(self.resource))
|
||||||
self.file = IfcStore.get_file()
|
|
||||||
contracted_resources = json.loads(props.contracted_resources)
|
|
||||||
contracted_resources.append(self.resource)
|
|
||||||
props.contracted_resources = json.dumps(contracted_resources)
|
|
||||||
Data.load(self.file)
|
|
||||||
bpy.ops.bim.load_resources()
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class AssignResource(bpy.types.Operator):
|
class AssignResource(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.assign_resource"
|
bl_idname = "bim.assign_resource"
|
||||||
bl_label = "Assign Resource"
|
bl_label = "Assign Resource"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
resource: bpy.props.IntProperty()
|
resource: bpy.props.IntProperty()
|
||||||
related_object: bpy.props.StringProperty()
|
related_object: bpy.props.StringProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
return IfcStore.execute_ifc_operator(self, context)
|
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
related_objects = (
|
core.assign_resource(tool.Ifc, tool.Resource, resource=tool.Ifc.get().by_id(self.resource))
|
||||||
[bpy.data.objects.get(self.related_object)] if self.related_object else context.selected_objects
|
|
||||||
)
|
|
||||||
for related_object in related_objects:
|
|
||||||
self.file = IfcStore.get_file()
|
|
||||||
ifcopenshell.api.run(
|
|
||||||
"resource.assign_resource",
|
|
||||||
self.file,
|
|
||||||
relating_resource=self.file.by_id(self.resource),
|
|
||||||
related_object=self.file.by_id(related_object.BIMObjectProperties.ifc_definition_id),
|
|
||||||
)
|
|
||||||
Data.load(self.file)
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class UnassignResource(bpy.types.Operator):
|
class UnassignResource(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.unassign_resource"
|
bl_idname = "bim.unassign_resource"
|
||||||
bl_label = "Unassign Resource"
|
bl_label = "Unassign Resource"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
resource: bpy.props.IntProperty()
|
resource: bpy.props.IntProperty()
|
||||||
related_object: bpy.props.StringProperty()
|
related_object: bpy.props.StringProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def _execute(self, context):
|
||||||
related_objects = (
|
core.unassign_resource(tool.Ifc, tool.Resource, resource=tool.Ifc.get().by_id(self.resource))
|
||||||
[bpy.data.objects.get(self.related_object)] if self.related_object else context.selected_objects
|
|
||||||
)
|
|
||||||
for related_object in related_objects:
|
|
||||||
self.file = IfcStore.get_file()
|
|
||||||
ifcopenshell.api.run(
|
|
||||||
"resource.unassign_resource",
|
|
||||||
self.file,
|
|
||||||
relating_resource=self.file.by_id(self.resource),
|
|
||||||
related_object=self.file.by_id(related_object.BIMObjectProperties.ifc_definition_id),
|
|
||||||
)
|
|
||||||
Data.load(self.file)
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class EnableEditingResourceTime(bpy.types.Operator):
|
class EnableEditingResourceTime(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.enable_editing_resource_time"
|
bl_idname = "bim.enable_editing_resource_time"
|
||||||
bl_label = "Enable Editing Resource Usage"
|
bl_label = "Enable Editing Resource Usage"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
resource: bpy.props.IntProperty()
|
resource: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
return IfcStore.execute_ifc_operator(self, context)
|
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMResourceProperties
|
core.enable_editing_resource_time(tool.Ifc, tool.Resource, resource=tool.Ifc.get().by_id(self.resource))
|
||||||
self.file = IfcStore.get_file()
|
|
||||||
resource_time_id = Data.resources[self.resource]["Usage"] or self.add_resource_time().id()
|
|
||||||
props.resource_time_attributes.clear()
|
|
||||||
|
|
||||||
data = Data.resource_times[resource_time_id]
|
|
||||||
|
|
||||||
blenderbim.bim.helper.import_attributes(
|
|
||||||
"IfcResourceTime", props.resource_time_attributes, data, self.import_attributes
|
|
||||||
)
|
|
||||||
props.active_resource_time_id = resource_time_id
|
|
||||||
props.active_resource_id = self.resource
|
|
||||||
props.editing_resource_type = "USAGE"
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
def import_attributes(self, name, prop, data):
|
|
||||||
if prop.data_type == "string":
|
|
||||||
if isinstance(data[name], datetime):
|
|
||||||
prop.string_value = "" if prop.is_null else data[name].isoformat()
|
|
||||||
return True
|
|
||||||
elif isinstance(data[name], isodate.Duration):
|
|
||||||
prop.string_value = (
|
|
||||||
"" if prop.is_null else ifcopenshell.util.date.datetime2ifc(data[name], "IfcDuration")
|
|
||||||
)
|
|
||||||
return True
|
|
||||||
|
|
||||||
def add_resource_time(self):
|
|
||||||
resource_time = ifcopenshell.api.run(
|
|
||||||
"resource.add_resource_time", self.file, resource=self.file.by_id(self.resource)
|
|
||||||
)
|
|
||||||
Data.load(self.file)
|
|
||||||
return resource_time
|
|
||||||
|
|
||||||
|
|
||||||
class DisableEditingResourceTime(bpy.types.Operator):
|
class DisableEditingResourceTime(bpy.types.Operator):
|
||||||
@@ -334,63 +174,31 @@ class DisableEditingResourceTime(bpy.types.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
context.scene.BIMResourceProperties.active_resource_time_id = 0
|
core.disable_editing_resource_time(tool.Resource)
|
||||||
bpy.ops.bim.disable_editing_resource()
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class EditResourceTime(bpy.types.Operator):
|
class EditResourceTime(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.edit_resource_time"
|
bl_idname = "bim.edit_resource_time"
|
||||||
bl_label = "Edit Resource Usage"
|
bl_label = "Edit Resource Usage"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
return IfcStore.execute_ifc_operator(self, context)
|
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.props = context.scene.BIMResourceProperties
|
core.edit_resource_time(
|
||||||
attributes = blenderbim.bim.helper.export_attributes(
|
tool.Ifc,
|
||||||
self.props.resource_time_attributes, self.export_attributes
|
tool.Resource,
|
||||||
|
resource_time=tool.Ifc.get().by_id(context.scene.BIMResourceProperties.active_resource_time_id),
|
||||||
)
|
)
|
||||||
|
|
||||||
self.file = IfcStore.get_file()
|
|
||||||
ifcopenshell.api.run(
|
|
||||||
"resource.edit_resource_time",
|
|
||||||
self.file,
|
|
||||||
**{"resource_time": self.file.by_id(self.props.active_resource_time_id), "attributes": attributes},
|
|
||||||
)
|
|
||||||
Data.load(self.file)
|
|
||||||
bpy.ops.bim.disable_editing_resource_time()
|
|
||||||
bpy.ops.bim.load_resource_properties(resource=self.props.active_resource_id)
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
def export_attributes(self, attributes, prop):
|
class CalculateResourceWork(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
if "Start" in prop.name or "Finish" in prop.name or prop.name == "StatusTime":
|
|
||||||
if prop.is_null:
|
|
||||||
attributes[prop.name] = None
|
|
||||||
return True
|
|
||||||
attributes[prop.name] = helper.parse_datetime(prop.string_value)
|
|
||||||
return True
|
|
||||||
elif prop.name == "LevelingDelay" or "Work" in prop.name:
|
|
||||||
if prop.is_null:
|
|
||||||
attributes[prop.name] = None
|
|
||||||
return True
|
|
||||||
attributes[prop.name] = helper.parse_duration(prop.string_value)
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class CalculateResourceWork(bpy.types.Operator):
|
|
||||||
bl_idname = "bim.calculate_resource_work"
|
bl_idname = "bim.calculate_resource_work"
|
||||||
bl_label = "Calculate Resource Work"
|
bl_label = "Calculate Resource Work"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
resource: bpy.props.IntProperty()
|
resource: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def _execute(self, context):
|
||||||
self.file = IfcStore.get_file()
|
core.calculate_resource_work(tool.Ifc, tool.Resource, resource=tool.Ifc.get().by_id(self.resource))
|
||||||
ifcopenshell.api.run("resource.calculate_resource_work", self.file, resource=self.file.by_id(self.resource))
|
|
||||||
Data.load(self.file)
|
|
||||||
bpy.ops.bim.load_resources()
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class EnableEditingResourceCosts(bpy.types.Operator):
|
class EnableEditingResourceCosts(bpy.types.Operator):
|
||||||
@@ -400,10 +208,7 @@ class EnableEditingResourceCosts(bpy.types.Operator):
|
|||||||
resource: bpy.props.IntProperty()
|
resource: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
props = context.scene.BIMResourceProperties
|
core.enable_editing_resource_costs(tool.Resource, resource=tool.Ifc.get().by_id(self.resource))
|
||||||
props.active_resource_id = self.resource
|
|
||||||
props.editing_resource_type = "COSTS"
|
|
||||||
bpy.ops.bim.disable_editing_resource_cost_value()
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -413,21 +218,7 @@ class DisableEditingResourceCostValue(bpy.types.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
props = context.scene.BIMResourceProperties
|
core.disable_editing_resource_cost_value(tool.Resource)
|
||||||
props.active_cost_value_id = 0
|
|
||||||
props.cost_value_editing_type = ""
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class DisableEditingResourceCostValue(bpy.types.Operator):
|
|
||||||
bl_idname = "bim.disable_editing_resource_cost_value"
|
|
||||||
bl_label = "Disable Editing Resource Cost Value"
|
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
props = context.scene.BIMResourceProperties
|
|
||||||
props.active_cost_value_id = 0
|
|
||||||
props.cost_value_editing_type = ""
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -438,11 +229,7 @@ class EnableEditingResourceCostValueFormula(bpy.types.Operator):
|
|||||||
cost_value: bpy.props.IntProperty()
|
cost_value: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
self.props = context.scene.BIMResourceProperties
|
core.enable_editing_resource_cost_value_formula(tool.Resource, cost_value=tool.Ifc.get().by_id(self.cost_value))
|
||||||
self.props.cost_value_attributes.clear()
|
|
||||||
self.props.active_cost_value_id = self.cost_value
|
|
||||||
self.props.cost_value_editing_type = "FORMULA"
|
|
||||||
self.props.cost_value_formula = Data.cost_values[self.cost_value]["Formula"]
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -453,127 +240,28 @@ class EnableEditingResourceCostValue(bpy.types.Operator):
|
|||||||
cost_value: bpy.props.IntProperty()
|
cost_value: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
self.props = context.scene.BIMResourceProperties
|
core.enable_editing_resource_cost_value(tool.Resource, cost_value=tool.Ifc.get().by_id(self.cost_value))
|
||||||
self.props.cost_value_attributes.clear()
|
|
||||||
self.props.active_cost_value_id = self.cost_value
|
|
||||||
self.props.cost_value_editing_type = "ATTRIBUTES"
|
|
||||||
data = Data.cost_values[self.cost_value]
|
|
||||||
|
|
||||||
blenderbim.bim.helper.import_attributes(
|
|
||||||
data["type"],
|
|
||||||
self.props.cost_value_attributes,
|
|
||||||
data,
|
|
||||||
lambda name, prop, data: self.import_attributes(name, prop, data, context),
|
|
||||||
)
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
def import_attributes(self, name, prop, data, context):
|
|
||||||
if name == "AppliedValue":
|
|
||||||
# TODO: for now, only support simple IfcValues (which are effectively IfcMonetaryMeasure)
|
|
||||||
prop = self.props.cost_value_attributes.add()
|
|
||||||
prop.data_type = "float"
|
|
||||||
prop.name = "AppliedValue"
|
|
||||||
prop.is_optional = True
|
|
||||||
prop.float_value = 0.0 if prop.is_null else data[name]
|
|
||||||
return True
|
|
||||||
elif name == "UnitBasis":
|
|
||||||
prop = self.props.cost_value_attributes.add()
|
|
||||||
prop.name = "UnitBasisValue"
|
|
||||||
prop.data_type = "float"
|
|
||||||
prop.is_null = data["UnitBasis"] is None
|
|
||||||
prop.is_optional = True
|
|
||||||
if data["UnitBasis"]:
|
|
||||||
prop.float_value = data["UnitBasis"]["ValueComponent"] or 0
|
|
||||||
else:
|
|
||||||
prop.float_value = 0
|
|
||||||
|
|
||||||
prop = self.props.cost_value_attributes.add()
|
class EditResourceCostValueFormula(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
prop.name = "UnitBasisUnit"
|
|
||||||
prop.data_type = "enum"
|
|
||||||
prop.is_null = prop.is_optional = False
|
|
||||||
units = {}
|
|
||||||
for unit_id, unit in UnitData.units.items():
|
|
||||||
if unit.get("UnitType", None) in [
|
|
||||||
"AREAUNIT",
|
|
||||||
"LENGTHUNIT",
|
|
||||||
"TIMEUNIT",
|
|
||||||
"VOLUMEUNIT",
|
|
||||||
"MASSUNIT",
|
|
||||||
"USERDEFINED",
|
|
||||||
]:
|
|
||||||
if unit["type"] == "IfcContextDependentUnit":
|
|
||||||
units[unit_id] = f"{unit['UnitType']} / {unit['Name']}"
|
|
||||||
else:
|
|
||||||
name = unit["Name"]
|
|
||||||
if unit.get("Prefix", None):
|
|
||||||
name = f"(unit['Prefix']) {name}"
|
|
||||||
units[unit_id] = f"{unit['UnitType']} / {name}"
|
|
||||||
prop.enum_items = json.dumps(units)
|
|
||||||
if data["UnitBasis"] and data["UnitBasis"]["UnitComponent"]:
|
|
||||||
prop.enum_value = str(data["UnitBasis"]["UnitComponent"])
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class EditResourceCostValueFormula(bpy.types.Operator):
|
|
||||||
bl_idname = "bim.edit_resource_cost_value_formula"
|
bl_idname = "bim.edit_resource_cost_value_formula"
|
||||||
bl_label = "Edit Resource Cost Value Formula"
|
bl_label = "Edit Resource Cost Value Formula"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
cost_value: bpy.props.IntProperty()
|
cost_value: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
return IfcStore.execute_ifc_operator(self, context)
|
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMResourceProperties
|
core.edit_resource_cost_value_formula(tool.Ifc, tool.Resource, cost_value=tool.Ifc.get().by_id(self.cost_value))
|
||||||
self.file = IfcStore.get_file()
|
|
||||||
ifcopenshell.api.run(
|
|
||||||
"cost.edit_cost_value_formula",
|
|
||||||
self.file,
|
|
||||||
**{"cost_value": self.file.by_id(self.cost_value), "formula": props.cost_value_formula},
|
|
||||||
)
|
|
||||||
Data.load(IfcStore.get_file())
|
|
||||||
bpy.ops.bim.disable_editing_resource_cost_value()
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class EditResourceCostValue(bpy.types.Operator):
|
class EditResourceCostValue(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.edit_resource_cost_value"
|
bl_idname = "bim.edit_resource_cost_value"
|
||||||
bl_label = "Edit Resource Cost Value"
|
bl_label = "Edit Resource Cost Value"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
cost_value: bpy.props.IntProperty()
|
cost_value: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
return IfcStore.execute_ifc_operator(self, context)
|
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMResourceProperties
|
core.edit_resource_cost_value(tool.Ifc, tool.Resource, cost_value=tool.Ifc.get().by_id(self.cost_value))
|
||||||
attributes = blenderbim.bim.helper.export_attributes(
|
|
||||||
props.cost_value_attributes, lambda attributes, prop: self.export_attributes(attributes, prop, context)
|
|
||||||
)
|
|
||||||
self.file = IfcStore.get_file()
|
|
||||||
ifcopenshell.api.run(
|
|
||||||
"cost.edit_cost_value",
|
|
||||||
self.file,
|
|
||||||
**{"cost_value": self.file.by_id(self.cost_value), "attributes": attributes},
|
|
||||||
)
|
|
||||||
Data.load(IfcStore.get_file())
|
|
||||||
bpy.ops.bim.disable_editing_resource_cost_value()
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
def export_attributes(self, attributes, prop, context):
|
|
||||||
if prop.name == "UnitBasisValue":
|
|
||||||
if prop.is_null:
|
|
||||||
attributes["UnitBasis"] = None
|
|
||||||
return True
|
|
||||||
attributes["UnitBasis"] = {
|
|
||||||
"ValueComponent": prop.float_value or 1,
|
|
||||||
"UnitComponent": IfcStore.get_file().by_id(
|
|
||||||
int(context.scene.BIMResourceProperties.cost_value_attributes.get("UnitBasisUnit").enum_value)
|
|
||||||
),
|
|
||||||
}
|
|
||||||
return True
|
|
||||||
if prop.name == "UnitBasisUnit":
|
|
||||||
return True
|
|
||||||
|
|
||||||
|
|
||||||
class EnableEditingResourceBaseQuantity(bpy.types.Operator):
|
class EnableEditingResourceBaseQuantity(bpy.types.Operator):
|
||||||
@@ -583,52 +271,29 @@ class EnableEditingResourceBaseQuantity(bpy.types.Operator):
|
|||||||
resource: bpy.props.IntProperty()
|
resource: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
props = context.scene.BIMResourceProperties
|
core.enable_editing_resource_base_quantity(tool.Resource, resource=tool.Ifc.get().by_id(self.resource))
|
||||||
props.active_resource_id = self.resource
|
|
||||||
props.editing_resource_type = "QUANTITY"
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class AddResourceQuantity(bpy.types.Operator):
|
class AddResourceQuantity(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.add_resource_quantity"
|
bl_idname = "bim.add_resource_quantity"
|
||||||
bl_label = "Add Resource Quantity"
|
bl_label = "Add Resource Quantity"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
resource: bpy.props.IntProperty()
|
resource: bpy.props.IntProperty()
|
||||||
ifc_class: bpy.props.StringProperty()
|
ifc_class: bpy.props.StringProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
return IfcStore.execute_ifc_operator(self, context)
|
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.file = IfcStore.get_file()
|
core.add_resource_quantity(tool.Ifc, ifc_class=self.ifc_class, resource=tool.Ifc.get().by_id(self.resource))
|
||||||
ifcopenshell.api.run(
|
|
||||||
"resource.add_resource_quantity",
|
|
||||||
self.file,
|
|
||||||
resource=self.file.by_id(self.resource),
|
|
||||||
ifc_class=self.ifc_class,
|
|
||||||
)
|
|
||||||
Data.load(self.file)
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class RemoveResourceQuantity(bpy.types.Operator):
|
class RemoveResourceQuantity(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.remove_resource_quantity"
|
bl_idname = "bim.remove_resource_quantity"
|
||||||
bl_label = "Remove Resource Quantity"
|
bl_label = "Remove Resource Quantity"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
resource: bpy.props.IntProperty()
|
resource: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
return IfcStore.execute_ifc_operator(self, context)
|
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
self.file = IfcStore.get_file()
|
core.remove_resource_quantity(tool.Ifc, resource=tool.Ifc.get().by_id(self.resource))
|
||||||
ifcopenshell.api.run(
|
|
||||||
"resource.remove_resource_quantity",
|
|
||||||
self.file,
|
|
||||||
resource=self.file.by_id(self.resource),
|
|
||||||
)
|
|
||||||
Data.load(self.file)
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|
||||||
|
|
||||||
class EnableEditingResourceQuantity(bpy.types.Operator):
|
class EnableEditingResourceQuantity(bpy.types.Operator):
|
||||||
@@ -638,11 +303,9 @@ class EnableEditingResourceQuantity(bpy.types.Operator):
|
|||||||
resource: bpy.props.IntProperty()
|
resource: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
self.props = context.scene.BIMResourceProperties
|
core.enable_editing_resource_quantity(
|
||||||
self.props.quantity_attributes.clear()
|
tool.Resource, resource_quantity=tool.Ifc.get().by_id(self.resource).BaseQuantity
|
||||||
self.props.is_editing_quantity = True
|
)
|
||||||
data = Data.resources[self.resource]["BaseQuantity"]
|
|
||||||
blenderbim.bim.helper.import_attributes(data["type"], self.props.quantity_attributes, data)
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
@@ -652,29 +315,18 @@ class DisableEditingResourceQuantity(bpy.types.Operator):
|
|||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
|
|
||||||
def execute(self, context):
|
def execute(self, context):
|
||||||
props = context.scene.BIMResourceProperties
|
core.disable_editing_resource_quantity(tool.Resource)
|
||||||
props.is_editing_quantity = False
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class EditResourceQuantity(bpy.types.Operator):
|
class EditResourceQuantity(bpy.types.Operator, tool.Ifc.Operator):
|
||||||
bl_idname = "bim.edit_resource_quantity"
|
bl_idname = "bim.edit_resource_quantity"
|
||||||
bl_label = "Edit Resource Quantity"
|
bl_label = "Edit Resource Quantity"
|
||||||
bl_options = {"REGISTER", "UNDO"}
|
bl_options = {"REGISTER", "UNDO"}
|
||||||
physical_quantity: bpy.props.IntProperty()
|
physical_quantity: bpy.props.IntProperty()
|
||||||
|
|
||||||
def execute(self, context):
|
|
||||||
return IfcStore.execute_ifc_operator(self, context)
|
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
props = context.scene.BIMResourceProperties
|
core.edit_resource_quantity(
|
||||||
attributes = blenderbim.bim.helper.export_attributes(props.quantity_attributes)
|
tool.Resource, tool.Ifc, physical_quantity=tool.Ifc.get().by_id(self.physical_quantity)
|
||||||
self.file = IfcStore.get_file()
|
|
||||||
ifcopenshell.api.run(
|
|
||||||
"resource.edit_resource_quantity",
|
|
||||||
self.file,
|
|
||||||
**{"physical_quantity": self.file.by_id(self.physical_quantity), "attributes": attributes},
|
|
||||||
)
|
)
|
||||||
Data.load(IfcStore.get_file())
|
|
||||||
bpy.ops.bim.disable_editing_resource_quantity()
|
|
||||||
return {"FINISHED"}
|
|
||||||
|
|||||||
@@ -19,7 +19,7 @@
|
|||||||
import blenderbim.bim.helper
|
import blenderbim.bim.helper
|
||||||
from bpy.types import Panel, UIList
|
from bpy.types import Panel, UIList
|
||||||
from blenderbim.bim.ifc import IfcStore
|
from blenderbim.bim.ifc import IfcStore
|
||||||
from ifcopenshell.api.resource.data import Data
|
from blenderbim.bim.module.resource.data import ResourceData
|
||||||
|
|
||||||
|
|
||||||
class BIM_PT_resources(Panel):
|
class BIM_PT_resources(Panel):
|
||||||
@@ -39,17 +39,21 @@ class BIM_PT_resources(Panel):
|
|||||||
def draw(self, context):
|
def draw(self, context):
|
||||||
self.props = context.scene.BIMResourceProperties
|
self.props = context.scene.BIMResourceProperties
|
||||||
self.tprops = context.scene.BIMResourceTreeProperties
|
self.tprops = context.scene.BIMResourceTreeProperties
|
||||||
|
if not ResourceData.is_loaded:
|
||||||
if not Data.is_loaded:
|
ResourceData.load()
|
||||||
Data.load(IfcStore.get_file())
|
|
||||||
|
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.label(text=f"{len(Data.resources)} Resources Found")
|
if ResourceData.data["has_resources"]:
|
||||||
|
row.label(
|
||||||
|
text="{} Resources Found".format(ResourceData.data["number_of_resources_loaded"]),
|
||||||
|
icon="TEXT",
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
row.label(text="No Resources found.", icon="COMMUNITY")
|
||||||
if self.props.is_editing:
|
if self.props.is_editing:
|
||||||
row.operator("bim.disable_resource_editing_ui", text="", icon="CANCEL")
|
row.operator("bim.disable_resource_editing_ui", text="", icon="CANCEL")
|
||||||
else:
|
else:
|
||||||
row.operator("bim.load_resources", text="", icon="GREASEPENCIL")
|
row.operator("bim.load_resources", text="Load Resources", icon="GREASEPENCIL")
|
||||||
|
|
||||||
if not self.props.is_editing:
|
if not self.props.is_editing:
|
||||||
return
|
return
|
||||||
|
|
||||||
@@ -76,17 +80,17 @@ class BIM_PT_resources(Panel):
|
|||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
op = row.operator("bim.add_resource", text="Add SubContract", icon="TEXT")
|
op = row.operator("bim.add_resource", text="Add SubContract", icon="TEXT")
|
||||||
op.ifc_class = "IfcSubContractResource"
|
op.ifc_class = "IfcSubContractResource"
|
||||||
op.resource = 0
|
op.parent_resource = 0
|
||||||
op = row.operator("bim.add_resource", text="Add Crew", icon="COMMUNITY")
|
op = row.operator("bim.add_resource", text="Add Crew", icon="COMMUNITY")
|
||||||
op.ifc_class = "IfcCrewResource"
|
op.ifc_class = "IfcCrewResource"
|
||||||
op.resource = 0
|
op.parent_resource = 0
|
||||||
|
|
||||||
total_resources = len(self.tprops.resources)
|
total_resources = len(self.tprops.resources)
|
||||||
if not total_resources or self.props.active_resource_index >= total_resources:
|
if not total_resources or self.props.active_resource_index >= total_resources:
|
||||||
return
|
return
|
||||||
|
|
||||||
ifc_definition_id = self.tprops.resources[self.props.active_resource_index].ifc_definition_id
|
ifc_definition_id = self.tprops.resources[self.props.active_resource_index].ifc_definition_id
|
||||||
resource = Data.resources[ifc_definition_id]
|
resource = ResourceData.data["resources"][ifc_definition_id]
|
||||||
|
|
||||||
if resource["type"] != "IfcSubContractResource":
|
if resource["type"] != "IfcSubContractResource":
|
||||||
icon_map = {
|
icon_map = {
|
||||||
@@ -100,26 +104,13 @@ class BIM_PT_resources(Panel):
|
|||||||
for ifc_class, icon in icon_map.items():
|
for ifc_class, icon in icon_map.items():
|
||||||
label = ifc_class.replace("Ifc", "").replace("Construction", "").replace("Resource", "")
|
label = ifc_class.replace("Ifc", "").replace("Construction", "").replace("Resource", "")
|
||||||
op = row.operator("bim.add_resource", text=label, icon=icon)
|
op = row.operator("bim.add_resource", text=label, icon=icon)
|
||||||
op.resource = ifc_definition_id
|
op.parent_resource = ifc_definition_id
|
||||||
op.ifc_class = ifc_class
|
op.ifc_class = ifc_class
|
||||||
|
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
row.alignment = "RIGHT"
|
row.alignment = "RIGHT"
|
||||||
|
|
||||||
if self.props.active_resource_id == ifc_definition_id and self.props.editing_resource_type == "ATTRIBUTES":
|
if not self.props.active_resource_id:
|
||||||
row.operator("bim.edit_resource", text="", icon="CHECKMARK")
|
|
||||||
row.operator("bim.disable_editing_resource", text="", icon="CANCEL")
|
|
||||||
elif self.props.active_resource_id == ifc_definition_id and self.props.editing_resource_type == "USAGE":
|
|
||||||
row.operator("bim.edit_resource_time", text="", icon="CHECKMARK")
|
|
||||||
row.operator("bim.disable_editing_resource_time", text="", icon="CANCEL")
|
|
||||||
elif self.props.active_resource_id == ifc_definition_id and self.props.editing_resource_type == "COSTS":
|
|
||||||
row.operator("bim.disable_editing_resource", text="", icon="CANCEL")
|
|
||||||
elif self.props.active_resource_id == ifc_definition_id and self.props.editing_resource_type == "QUANTITY":
|
|
||||||
row.operator("bim.disable_editing_resource", text="", icon="CANCEL")
|
|
||||||
elif self.props.active_resource_id:
|
|
||||||
row.operator("bim.add_resource", text="", icon="ADD").resource = ifc_definition_id
|
|
||||||
row.operator("bim.remove_resource", text="", icon="X").resource = ifc_definition_id
|
|
||||||
else:
|
|
||||||
if resource["type"] in ["IfcLaborResource", "IfcConstructionEquipmentResource"]:
|
if resource["type"] in ["IfcLaborResource", "IfcConstructionEquipmentResource"]:
|
||||||
op = row.operator("bim.calculate_resource_work", text="", icon="TEMP")
|
op = row.operator("bim.calculate_resource_work", text="", icon="TEMP")
|
||||||
op.resource = ifc_definition_id
|
op.resource = ifc_definition_id
|
||||||
@@ -138,7 +129,7 @@ class BIM_PT_resources(Panel):
|
|||||||
blenderbim.bim.helper.draw_attributes(self.props.resource_time_attributes, self.layout)
|
blenderbim.bim.helper.draw_attributes(self.props.resource_time_attributes, self.layout)
|
||||||
|
|
||||||
def draw_editable_resource_quantity_ui(self):
|
def draw_editable_resource_quantity_ui(self):
|
||||||
resource = Data.resources[self.props.active_resource_id]
|
resource = ResourceData.data["resources"][self.props.active_resource_id]
|
||||||
|
|
||||||
if resource["BaseQuantity"]:
|
if resource["BaseQuantity"]:
|
||||||
quantity = resource["BaseQuantity"]
|
quantity = resource["BaseQuantity"]
|
||||||
@@ -177,16 +168,16 @@ class BIM_PT_resources(Panel):
|
|||||||
if self.props.cost_types == "CATEGORY":
|
if self.props.cost_types == "CATEGORY":
|
||||||
op.cost_category = self.props.cost_category
|
op.cost_category = self.props.cost_category
|
||||||
|
|
||||||
for cost_value_id in Data.resources[self.props.active_resource_id]["BaseCosts"] or []:
|
for cost_value_id in ResourceData.data["resources"][self.props.active_resource_id]["BaseCosts"] or []:
|
||||||
row = self.layout.row(align=True)
|
row = self.layout.row(align=True)
|
||||||
self.draw_readonly_cost_value_ui(row, cost_value_id)
|
self.draw_readonly_cost_value_ui(row, cost_value_id)
|
||||||
|
|
||||||
if self.props.cost_value_editing_type == "ATTRIBUTES":
|
if self.props.cost_value_editing_type == "ATTRIBUTES":
|
||||||
box = self.layout.box()
|
box = self.layout.box()
|
||||||
self.draw_editable_cost_value_ui(box, Data.cost_values[self.props.active_cost_value_id])
|
self.draw_editable_cost_value_ui(box, ResourceData.cost_values[self.props.active_cost_value_id])
|
||||||
|
|
||||||
def draw_readonly_cost_value_ui(self, layout, cost_value_id):
|
def draw_readonly_cost_value_ui(self, layout, cost_value_id):
|
||||||
cost_value = Data.cost_values[cost_value_id]
|
cost_value = ResourceData.cost_values[cost_value_id]
|
||||||
|
|
||||||
if self.props.active_cost_value_id == cost_value_id and self.props.cost_value_editing_type == "FORMULA":
|
if self.props.active_cost_value_id == cost_value_id and self.props.cost_value_editing_type == "FORMULA":
|
||||||
layout.prop(self.props, "cost_value_formula", text="")
|
layout.prop(self.props, "cost_value_formula", text="")
|
||||||
@@ -225,7 +216,7 @@ class BIM_PT_resources(Panel):
|
|||||||
|
|
||||||
class BIM_UL_resources(UIList):
|
class BIM_UL_resources(UIList):
|
||||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
def draw_item(self, context, layout, data, item, icon, active_data, active_propname):
|
||||||
resource = Data.resources[item.ifc_definition_id]
|
resource = ResourceData.data["resources"][item.ifc_definition_id]
|
||||||
icon_map = {
|
icon_map = {
|
||||||
"IfcSubContractResource": "TEXT",
|
"IfcSubContractResource": "TEXT",
|
||||||
"IfcCrewResource": "COMMUNITY",
|
"IfcCrewResource": "COMMUNITY",
|
||||||
@@ -251,13 +242,19 @@ class BIM_UL_resources(UIList):
|
|||||||
else:
|
else:
|
||||||
row.label(text="", icon="DOT")
|
row.label(text="", icon="DOT")
|
||||||
row.prop(item, "name", emboss=False, text="", icon=icon_map[resource["type"]])
|
row.prop(item, "name", emboss=False, text="", icon=icon_map[resource["type"]])
|
||||||
|
if context.active_object and not props.active_resource_id:
|
||||||
if context.active_object:
|
|
||||||
oprops = context.active_object.BIMObjectProperties
|
oprops = context.active_object.BIMObjectProperties
|
||||||
row = layout.row(align=True)
|
row = layout.row(align=True)
|
||||||
if oprops.ifc_definition_id in Data.resources[item.ifc_definition_id]["ResourceOf"]:
|
if oprops.ifc_definition_id in ResourceData.data["resources"][item.ifc_definition_id]["ResourceOf"]:
|
||||||
op = row.operator("bim.unassign_resource", text="", icon="KEYFRAME_HLT", emboss=False)
|
op = row.operator("bim.unassign_resource", text="", icon="KEYFRAME_HLT", emboss=False)
|
||||||
op.resource = item.ifc_definition_id
|
op.resource = item.ifc_definition_id
|
||||||
else:
|
else:
|
||||||
op = row.operator("bim.assign_resource", text="", icon="KEYFRAME", emboss=False)
|
op = row.operator("bim.assign_resource", text="", icon="KEYFRAME", emboss=False)
|
||||||
op.resource = item.ifc_definition_id
|
op.resource = item.ifc_definition_id
|
||||||
|
|
||||||
|
if props.active_resource_id == item.ifc_definition_id:
|
||||||
|
if props.editing_resource_type == "ATTRIBUTES":
|
||||||
|
row.operator("bim.edit_resource", text="", icon="CHECKMARK")
|
||||||
|
elif props.editing_resource_type == "USAGE":
|
||||||
|
row.operator("bim.edit_resource_time", text="", icon="CHECKMARK")
|
||||||
|
row.operator("bim.disable_editing_resource", text="", icon="CANCEL")
|
||||||
|
|||||||
@@ -0,0 +1,172 @@
|
|||||||
|
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||||
|
# Copyright (C) 2022 Dion Moult, Yassine Oualid <dion@thinkmoult.com>
|
||||||
|
#
|
||||||
|
# This file is part of BlenderBIM Add-on.
|
||||||
|
#
|
||||||
|
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# ############################################################################ #
|
||||||
|
|
||||||
|
|
||||||
|
def load_resources(resource):
|
||||||
|
resource.load_resources()
|
||||||
|
resource.load_resource_properties()
|
||||||
|
|
||||||
|
|
||||||
|
def add_resource(tool_ifc, resource_tool, ifc_class, parent_resource=None):
|
||||||
|
tool_ifc.run("resource.add_resource", ifc_class=ifc_class, parent_resource=parent_resource)
|
||||||
|
resource_tool.load_resources()
|
||||||
|
resource_tool.load_resource_properties()
|
||||||
|
|
||||||
|
|
||||||
|
def load_resource_properties(resource_tool, resource=None):
|
||||||
|
resource_tool.load_resource_properties()
|
||||||
|
|
||||||
|
|
||||||
|
def disable_editing_resource(resource_tool):
|
||||||
|
resource_tool.disable_editing_resource()
|
||||||
|
|
||||||
|
|
||||||
|
def disable_resource_editing_ui(resource_tool):
|
||||||
|
resource_tool.disable_resource_editing_ui()
|
||||||
|
|
||||||
|
|
||||||
|
def enable_editing_resource(resource_tool, resource):
|
||||||
|
resource_tool.enable_editing_resource(resource)
|
||||||
|
resource_tool.load_resource_attributes(resource)
|
||||||
|
|
||||||
|
|
||||||
|
def edit_resource(ifc, resource_tool, resource):
|
||||||
|
attributes = resource_tool.get_resource_attributes()
|
||||||
|
ifc.run("resource.edit_resource", resource=resource, attributes=attributes)
|
||||||
|
resource_tool.load_resource_properties()
|
||||||
|
resource_tool.disable_editing_resource()
|
||||||
|
|
||||||
|
|
||||||
|
def remove_resource(ifc, resource_tool, resource=None):
|
||||||
|
ifc.run("resource.remove_resource", resource=resource)
|
||||||
|
resource_tool.load_resources()
|
||||||
|
resource_tool.load_resource_properties()
|
||||||
|
|
||||||
|
|
||||||
|
def enable_editing_resource_time(ifc_tool, resource_tool, resource):
|
||||||
|
resource_time = resource_tool.get_resource_time(resource)
|
||||||
|
if resource_time is None:
|
||||||
|
resource_time = ifc_tool.run("resource.add_resource_time", resource=resource)
|
||||||
|
resource_tool.enable_editing_resource_time(resource)
|
||||||
|
resource_tool.load_resource_time_attributes(resource_time)
|
||||||
|
|
||||||
|
|
||||||
|
def edit_resource_time(ifc, resource_tool, resource_time):
|
||||||
|
attributes = resource_tool.get_resource_time_attributes()
|
||||||
|
ifc.run("resource.edit_resource_time", resource_time=resource_time, attributes=attributes)
|
||||||
|
resource_tool.disable_editing_resource()
|
||||||
|
|
||||||
|
|
||||||
|
def disable_editing_resource_time(resource_tool):
|
||||||
|
resource_tool.disable_editing_resource()
|
||||||
|
|
||||||
|
|
||||||
|
def calculate_resource_work(ifc, resource_tool, resource):
|
||||||
|
ifc.run("calculate_resource_work", resource=resource)
|
||||||
|
resource_tool.load_resources()
|
||||||
|
resource_tool.load_resource_properties()
|
||||||
|
|
||||||
|
|
||||||
|
def enable_editing_resource_costs(resource_tool, resource):
|
||||||
|
resource_tool.enable_editing_resource_costs(resource)
|
||||||
|
resource_tool.disable_editing_resource_cost_value()
|
||||||
|
|
||||||
|
|
||||||
|
def disable_editing_resource_cost_value(resource_tool):
|
||||||
|
resource_tool.disable_editing_resource_cost_value()
|
||||||
|
|
||||||
|
|
||||||
|
def enable_editing_resource_cost_value(resource_tool, cost_value):
|
||||||
|
resource_tool.enable_editing_cost_value_attributes(cost_value)
|
||||||
|
resource_tool.load_cost_value_attributes(cost_value)
|
||||||
|
|
||||||
|
|
||||||
|
def enable_editing_resource_cost_value_formula(resource_tool, cost_value):
|
||||||
|
resource_tool.enable_editing_resource_cost_value_formula(cost_value)
|
||||||
|
|
||||||
|
|
||||||
|
def edit_resource_cost_value_formula(ifc, resource_tool, cost_value):
|
||||||
|
formula = resource_tool.get_resource_cost_value_formula()
|
||||||
|
ifc.run("cost.edit_cost_value_formula", cost_value=cost_value, formula=formula)
|
||||||
|
resource_tool.disable_editing_resource_cost_value()
|
||||||
|
|
||||||
|
|
||||||
|
def edit_resource_cost_value(ifc, resource_tool, cost_value):
|
||||||
|
attributes = resource_tool.get_resource_cost_value_attributes()
|
||||||
|
ifc.run("cost.edit_cost_value", cost_value=cost_value, attributes=attributes)
|
||||||
|
resource_tool.disable_editing_resource_cost_value()
|
||||||
|
|
||||||
|
|
||||||
|
def enable_editing_resource_base_quantity(resource_tool, resource):
|
||||||
|
resource_tool.enable_editing_resource_base_quantity(resource)
|
||||||
|
|
||||||
|
|
||||||
|
def add_resource_quantity(ifc, ifc_class, resource):
|
||||||
|
ifc.run("resource.add_resource_quantity", resource=resource, ifc_class=ifc_class)
|
||||||
|
|
||||||
|
|
||||||
|
def remove_resource_quantity(ifc, resource):
|
||||||
|
ifc.run("resource.remove_resource_quantity", resource=resource)
|
||||||
|
|
||||||
|
|
||||||
|
def enable_editing_resource_quantity(resource_tool, resource_quantity=None):
|
||||||
|
resource_tool.enable_editing_resource_quantity(resource_quantity)
|
||||||
|
|
||||||
|
|
||||||
|
def disable_editing_resource_quantity(resource_tool):
|
||||||
|
resource_tool.disable_editing_resource_quantity()
|
||||||
|
|
||||||
|
|
||||||
|
def edit_resource_quantity(resource_tool, ifc, physical_quantity=None):
|
||||||
|
attributes = resource_tool.get_resource_quantity_attributes()
|
||||||
|
ifc.run("resource.edit_resource_quantity", physical_quantity=physical_quantity, attributes=attributes)
|
||||||
|
resource_tool.disable_editing_resource_quantity()
|
||||||
|
|
||||||
|
|
||||||
|
def import_resources(resource_tool, file_path):
|
||||||
|
resource_tool.import_resources(file_path)
|
||||||
|
resource_tool.load_resources()
|
||||||
|
resource_tool.load_resource_properties()
|
||||||
|
|
||||||
|
|
||||||
|
def expand_resource(resource_tool, resource):
|
||||||
|
resource_tool.expand_resource(resource)
|
||||||
|
resource_tool.load_resources()
|
||||||
|
resource_tool.load_resource_properties()
|
||||||
|
|
||||||
|
|
||||||
|
def contract_resource(resource_tool, resource):
|
||||||
|
resource_tool.contract_resource(resource)
|
||||||
|
resource_tool.load_resources()
|
||||||
|
resource_tool.load_resource_properties()
|
||||||
|
|
||||||
|
|
||||||
|
def assign_resource(ifc, resource_tool, resource=None, products=None):
|
||||||
|
if not products:
|
||||||
|
products = resource_tool.get_selected_products()
|
||||||
|
for product in products:
|
||||||
|
rel = ifc.run("resource.assign_resource", relating_resource=resource, related_object=product)
|
||||||
|
|
||||||
|
|
||||||
|
def unassign_resource(ifc, resource_tool, resource=None, products=None):
|
||||||
|
if not products:
|
||||||
|
products = resource_tool.get_selected_products()
|
||||||
|
for product in products:
|
||||||
|
ifc.run("resource.unassign_resource", relating_resource=resource, related_object=product)
|
||||||
@@ -401,6 +401,33 @@ class Qto:
|
|||||||
def set_qto_result(cls, result): pass
|
def set_qto_result(cls, result): pass
|
||||||
|
|
||||||
|
|
||||||
|
@interface
|
||||||
|
class Resource:
|
||||||
|
def load_resources(cls): pass
|
||||||
|
def load_resource_properties(cls): pass
|
||||||
|
def disable_editing_resource(cls): pass
|
||||||
|
def disable_resource_editing_ui(cls): pass
|
||||||
|
def load_resource_attributes(cls, resource): pass
|
||||||
|
def enable_editing_resource(cls, resource): pass
|
||||||
|
def get_resource_attributes(cls): pass
|
||||||
|
def enable_editing_resource_time(cls, resource): pass
|
||||||
|
def get_resource_time(cls, resource): pass
|
||||||
|
def load_resource_time_attributes(cls, resource_time): pass
|
||||||
|
def get_resource_time_attributes(cls): pass
|
||||||
|
def enable_editing_resource_costs(cls, resource): pass
|
||||||
|
def disable_editing_resource_cost_value(cls): pass
|
||||||
|
def enable_editing_resource_cost_value_formula(cls, cost_value): pass
|
||||||
|
def load_cost_value_attributes(cls, cost_value): pass
|
||||||
|
def enable_editing_cost_value_attributes(cls, cost_value): pass
|
||||||
|
def get_resource_cost_value_formula(cls): pass
|
||||||
|
def get_resource_cost_value_attributes(cls): pass
|
||||||
|
def enable_editing_resource_base_quantity(cls, resource): pass
|
||||||
|
def enable_editing_resource_quantity(cls, resource_quantity): pass
|
||||||
|
def disable_editing_resource_quantity(cls): pass
|
||||||
|
def get_resource_quantity_attributes(cls): pass
|
||||||
|
def expand_resource(cls, resource): pass
|
||||||
|
def contract_resource(cls, resource): pass
|
||||||
|
|
||||||
@interface
|
@interface
|
||||||
class Root:
|
class Root:
|
||||||
def add_dynamic_opening_voids(cls, element, obj): pass
|
def add_dynamic_opening_voids(cls, element, obj): pass
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ from blenderbim.tool.patch import Patch
|
|||||||
from blenderbim.tool.project import Project
|
from blenderbim.tool.project import Project
|
||||||
from blenderbim.tool.pset import Pset
|
from blenderbim.tool.pset import Pset
|
||||||
from blenderbim.tool.qto import Qto
|
from blenderbim.tool.qto import Qto
|
||||||
|
from blenderbim.tool.resource import Resource
|
||||||
from blenderbim.tool.root import Root
|
from blenderbim.tool.root import Root
|
||||||
from blenderbim.tool.sequence import Sequence
|
from blenderbim.tool.sequence import Sequence
|
||||||
from blenderbim.tool.spatial import Spatial
|
from blenderbim.tool.spatial import Spatial
|
||||||
|
|||||||
@@ -0,0 +1,308 @@
|
|||||||
|
# BlenderBIM Add-on - OpenBIM Blender Add-on
|
||||||
|
# Copyright (C) 2022 Dion Moult, Yassine Oualid <dion@thinkmoult.com>
|
||||||
|
#
|
||||||
|
# This file is part of BlenderBIM Add-on.
|
||||||
|
#
|
||||||
|
# BlenderBIM Add-on is free software: you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation, either version 3 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# BlenderBIM Add-on is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with BlenderBIM Add-on. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
|
||||||
|
# ############################################################################ #
|
||||||
|
|
||||||
|
import bpy
|
||||||
|
import blenderbim.core.tool
|
||||||
|
import blenderbim.tool as tool
|
||||||
|
import blenderbim.bim.helper
|
||||||
|
import blenderbim.bim.module.sequence.helper as helper
|
||||||
|
import json
|
||||||
|
import time
|
||||||
|
import isodate
|
||||||
|
from datetime import datetime
|
||||||
|
from dateutil import parser
|
||||||
|
import ifcopenshell.util.date as ifcdateutils
|
||||||
|
import ifcopenshell.util.cost
|
||||||
|
from ifcopenshell.api.unit.data import Data as UnitData
|
||||||
|
|
||||||
|
|
||||||
|
class Resource(blenderbim.core.tool.Resource):
|
||||||
|
@classmethod
|
||||||
|
def load_resources(cls):
|
||||||
|
def create_new_resource_li(resource, level_index):
|
||||||
|
new = bpy.context.scene.BIMResourceTreeProperties.resources.add()
|
||||||
|
new.ifc_definition_id = resource.id()
|
||||||
|
new.is_expanded = resource.id() not in contracted_resources
|
||||||
|
new.level_index = level_index
|
||||||
|
if resource.IsNestedBy:
|
||||||
|
new.has_children = True
|
||||||
|
if new.is_expanded:
|
||||||
|
for rel in resource.IsNestedBy:
|
||||||
|
[
|
||||||
|
create_new_resource_li(nested_resource, level_index + 1)
|
||||||
|
for nested_resource in rel.RelatedObjects
|
||||||
|
]
|
||||||
|
|
||||||
|
props = bpy.context.scene.BIMResourceProperties
|
||||||
|
tprops = bpy.context.scene.BIMResourceTreeProperties
|
||||||
|
tprops.resources.clear()
|
||||||
|
contracted_resources = json.loads(props.contracted_resources)
|
||||||
|
|
||||||
|
for resource in tool.Ifc.get().by_type("IfcResource"):
|
||||||
|
if not resource.HasContext:
|
||||||
|
continue
|
||||||
|
create_new_resource_li(resource, 0)
|
||||||
|
props.is_editing = True
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_resource_properties(cls):
|
||||||
|
props = bpy.context.scene.BIMResourceProperties
|
||||||
|
tprops = bpy.context.scene.BIMResourceTreeProperties
|
||||||
|
props.is_resource_update_enabled = False
|
||||||
|
for item in tprops.resources:
|
||||||
|
resource = tool.Ifc.get().by_id(item.ifc_definition_id)
|
||||||
|
item.name = resource.Name if resource else "Unnamed"
|
||||||
|
props.is_resource_update_enabled = True
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def disable_editing_resource(cls):
|
||||||
|
bpy.context.scene.BIMResourceProperties.active_resource_id = 0
|
||||||
|
bpy.context.scene.BIMResourceProperties.active_resource_time_id = 0
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def disable_resource_editing_ui(cls):
|
||||||
|
bpy.context.scene.BIMResourceProperties.is_editing = False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_resource_attributes(cls, resource):
|
||||||
|
blenderbim.bim.helper.import_attributes2(resource, bpy.context.scene.BIMResourceProperties.resource_attributes)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def enable_editing_resource(cls, resource):
|
||||||
|
props = bpy.context.scene.BIMResourceProperties
|
||||||
|
props.active_resource_id = resource.id()
|
||||||
|
props.resource_attributes.clear()
|
||||||
|
props.editing_resource_type = "ATTRIBUTES"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_resource_attributes(cls):
|
||||||
|
return blenderbim.bim.helper.export_attributes(bpy.context.scene.BIMResourceProperties.resource_attributes)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def enable_editing_resource_time(cls, resource):
|
||||||
|
props = bpy.context.scene.BIMResourceProperties
|
||||||
|
props.resource_time_attributes.clear()
|
||||||
|
props.active_resource_time_id = resource.Usage.id()
|
||||||
|
props.active_resource_id = resource.id()
|
||||||
|
props.editing_resource_type = "USAGE"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_resource_time(cls, resource):
|
||||||
|
return resource.Usage if resource.Usage else None
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_resource_time_attributes(cls, resource_time):
|
||||||
|
def callback(name, prop, data):
|
||||||
|
if prop.data_type == "string":
|
||||||
|
if isinstance(data[name], datetime):
|
||||||
|
prop.string_value = "" if prop.is_null else data[name].isoformat()
|
||||||
|
return True
|
||||||
|
elif isinstance(data[name], isodate.Duration):
|
||||||
|
prop.string_value = "" if prop.is_null else ifcdateutils.datetime2ifc(data[name], "IfcDuration")
|
||||||
|
return True
|
||||||
|
|
||||||
|
blenderbim.bim.helper.import_attributes2(
|
||||||
|
resource_time, bpy.context.scene.BIMResourceProperties.resource_time_attributes, callback
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_resource_time_attributes(cls):
|
||||||
|
def callback(attributes, prop):
|
||||||
|
if "Start" in prop.name or "Finish" in prop.name or prop.name == "StatusTime":
|
||||||
|
if prop.is_null:
|
||||||
|
attributes[prop.name] = None
|
||||||
|
return True
|
||||||
|
attributes[prop.name] = helper.parse_datetime(prop.string_value)
|
||||||
|
return True
|
||||||
|
elif prop.name == "LevelingDelay" or "Work" in prop.name:
|
||||||
|
if prop.is_null:
|
||||||
|
attributes[prop.name] = None
|
||||||
|
return True
|
||||||
|
attributes[prop.name] = helper.parse_duration(prop.string_value)
|
||||||
|
return True
|
||||||
|
|
||||||
|
props = bpy.context.scene.BIMResourceProperties
|
||||||
|
return blenderbim.bim.helper.export_attributes(props.resource_time_attributes, callback)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def enable_editing_resource_costs(cls, resource):
|
||||||
|
props = bpy.context.scene.BIMResourceProperties
|
||||||
|
props.active_resource_id = resource.id()
|
||||||
|
props.editing_resource_type = "COSTS"
|
||||||
|
resource
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def disable_editing_resource_cost_value(cls):
|
||||||
|
props = bpy.context.scene.BIMResourceProperties
|
||||||
|
props.active_cost_value_id = 0
|
||||||
|
props.cost_value_editing_type = ""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def enable_editing_resource_cost_value_formula(cls, cost_value):
|
||||||
|
props = bpy.context.scene.BIMResourceProperties
|
||||||
|
props.cost_value_attributes.clear()
|
||||||
|
props.active_cost_value_id = cost_value.id()
|
||||||
|
props.cost_value_editing_type = "FORMULA"
|
||||||
|
props.cost_value_formula = ifcopenshell.util.cost.serialise_cost_value(cost_value) if cost_value else ""
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def load_cost_value_attributes(cls, cost_value):
|
||||||
|
def callback(name, prop, data):
|
||||||
|
if name == "AppliedValue":
|
||||||
|
# TODO: for now, only support simple IfcValues (which are effectively IfcMonetaryMeasure)
|
||||||
|
prop = props.cost_value_attributes.add()
|
||||||
|
prop.data_type = "float"
|
||||||
|
prop.name = "AppliedValue"
|
||||||
|
prop.is_optional = True
|
||||||
|
prop.float_value = 0.0 if prop.is_null or not data[name] else data[name][0]
|
||||||
|
return True
|
||||||
|
elif name == "UnitBasis":
|
||||||
|
prop = props.cost_value_attributes.add()
|
||||||
|
prop.name = "UnitBasisValue"
|
||||||
|
prop.data_type = "float"
|
||||||
|
prop.is_null = data["UnitBasis"] is None
|
||||||
|
prop.is_optional = True
|
||||||
|
if data["UnitBasis"]:
|
||||||
|
prop.float_value = data["UnitBasis"].ValueComponent[0] or 0
|
||||||
|
else:
|
||||||
|
prop.float_value = 0
|
||||||
|
|
||||||
|
prop = props.cost_value_attributes.add()
|
||||||
|
prop.name = "UnitBasisUnit"
|
||||||
|
prop.data_type = "enum"
|
||||||
|
prop.is_null = prop.is_optional = False
|
||||||
|
units = {}
|
||||||
|
if not UnitData.is_loaded:
|
||||||
|
UnitData.load(tool.Ifc.get())
|
||||||
|
for unit_id, unit in UnitData.units.items():
|
||||||
|
if unit.get("UnitType", None) in [
|
||||||
|
"AREAUNIT",
|
||||||
|
"LENGTHUNIT",
|
||||||
|
"TIMEUNIT",
|
||||||
|
"VOLUMEUNIT",
|
||||||
|
"MASSUNIT",
|
||||||
|
"USERDEFINED",
|
||||||
|
]:
|
||||||
|
if unit["type"] == "IfcContextDependentUnit":
|
||||||
|
units[unit_id] = f"{unit['UnitType']} / {unit['Name']}"
|
||||||
|
else:
|
||||||
|
name = unit["Name"]
|
||||||
|
if unit.get("Prefix", None):
|
||||||
|
name = f"(unit['Prefix']) {name}"
|
||||||
|
units[unit_id] = f"{unit['UnitType']} / {name}"
|
||||||
|
prop.enum_items = json.dumps(units)
|
||||||
|
if data["UnitBasis"] and data["UnitBasis"].UnitComponent:
|
||||||
|
name = data["UnitBasis"].UnitComponent.Name
|
||||||
|
unit_type = data["UnitBasis"].UnitComponent.UnitType
|
||||||
|
prop.enum_value = str(data["UnitBasis"].UnitComponent.id())
|
||||||
|
return True
|
||||||
|
|
||||||
|
props = bpy.context.scene.BIMResourceProperties
|
||||||
|
blenderbim.bim.helper.import_attributes2(cost_value, props.cost_value_attributes, callback)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def enable_editing_cost_value_attributes(cls, cost_value):
|
||||||
|
props = bpy.context.scene.BIMResourceProperties
|
||||||
|
props.cost_value_attributes.clear()
|
||||||
|
props.active_cost_value_id = cost_value.id()
|
||||||
|
props.cost_value_editing_type = "ATTRIBUTES"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_resource_cost_value_formula(cls):
|
||||||
|
return bpy.context.scene.BIMResourceProperties.cost_value_formula
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_resource_cost_value_attributes(cls):
|
||||||
|
def callback(attributes, prop):
|
||||||
|
if prop.name == "UnitBasisValue":
|
||||||
|
if prop.is_null:
|
||||||
|
attributes["UnitBasis"] = None
|
||||||
|
return True
|
||||||
|
attributes["UnitBasis"] = {
|
||||||
|
"ValueComponent": prop.float_value or 1,
|
||||||
|
"UnitComponent": tool.Ifc.get().by_id(
|
||||||
|
int(
|
||||||
|
bpy.context.scene.BIMResourceProperties.cost_value_attributes.get(
|
||||||
|
"UnitBasisUnit"
|
||||||
|
).enum_value
|
||||||
|
)
|
||||||
|
),
|
||||||
|
}
|
||||||
|
return True
|
||||||
|
if prop.name == "UnitBasisUnit":
|
||||||
|
return True
|
||||||
|
|
||||||
|
return blenderbim.bim.helper.export_attributes(
|
||||||
|
bpy.context.scene.BIMResourceProperties.cost_value_attributes, callback
|
||||||
|
)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def enable_editing_resource_base_quantity(cls, resource):
|
||||||
|
props = bpy.context.scene.BIMResourceProperties
|
||||||
|
props.active_resource_id = resource.id()
|
||||||
|
props.editing_resource_type = "QUANTITY"
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def enable_editing_resource_quantity(cls, resource_quantity):
|
||||||
|
props = bpy.context.scene.BIMResourceProperties
|
||||||
|
props.quantity_attributes.clear()
|
||||||
|
props.is_editing_quantity = True
|
||||||
|
blenderbim.bim.helper.import_attributes2(resource_quantity, props.quantity_attributes)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def disable_editing_resource_quantity(cls):
|
||||||
|
bpy.context.scene.BIMResourceProperties.is_editing_quantity = False
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_resource_quantity_attributes(cls):
|
||||||
|
return blenderbim.bim.helper.export_attributes(bpy.context.scene.BIMResourceProperties.quantity_attributes)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def expand_resource(cls, resource):
|
||||||
|
props = bpy.context.scene.BIMResourceProperties
|
||||||
|
contracted_resources = json.loads(props.contracted_resources)
|
||||||
|
contracted_resources.remove(resource.id())
|
||||||
|
props.contracted_resources = json.dumps(contracted_resources)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def contract_resource(cls, resource):
|
||||||
|
props = bpy.context.scene.BIMResourceProperties
|
||||||
|
contracted_resources = json.loads(props.contracted_resources)
|
||||||
|
contracted_resources.append(resource.id())
|
||||||
|
props.contracted_resources = json.dumps(contracted_resources)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def get_selected_products(cls):
|
||||||
|
return [
|
||||||
|
tool.Ifc.get_entity(obj)
|
||||||
|
for obj in bpy.context.selected_objects
|
||||||
|
if obj.BIMObjectProperties.ifc_definition_id
|
||||||
|
] or []
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def import_resources(cls, file_path):
|
||||||
|
from ifc4d.csv2ifc import Csv2Ifc
|
||||||
|
|
||||||
|
start = time.time()
|
||||||
|
p62ifc = Csv2Ifc()
|
||||||
|
p62ifc.csv = file_path
|
||||||
|
p62ifc.file = tool.Ifc.get()
|
||||||
|
p62ifc.execute()
|
||||||
|
print("Importing Resources CSV finished in {:.2f} seconds".format(time.time() - start))
|
||||||
Reference in New Issue
Block a user