mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-13 10:57:49 +00:00
typing
This commit is contained in:
@@ -26,30 +26,42 @@ import bonsai.bim.helper
|
||||
import bonsai.tool as tool
|
||||
import bonsai.core.attribute as core
|
||||
import bonsai.core.spatial
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
|
||||
def get_objs_for_operation(operator_properties, context):
|
||||
def get_objs_for_operation(
|
||||
operator_properties: "AttributesOperator", context: bpy.types.Context
|
||||
) -> list[bpy.types.Object]:
|
||||
if operator_properties.obj:
|
||||
return [bpy.data.objects[operator_properties.obj]]
|
||||
if operator_properties.mass_operation:
|
||||
return context.selected_objects[:]
|
||||
return [context.active_object]
|
||||
obj = context.active_object
|
||||
assert obj
|
||||
return [obj]
|
||||
|
||||
|
||||
class EnableEditingAttributes(bpy.types.Operator):
|
||||
bl_idname = "bim.enable_editing_attributes"
|
||||
bl_label = "Enable Editing Attributes"
|
||||
bl_description = "ALT + Left Click to enable editing attributes on all selected objects"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
class AttributesOperator:
|
||||
obj: bpy.props.StringProperty(options={"SKIP_SAVE"})
|
||||
mass_operation: bpy.props.BoolProperty(default=False, options={"SKIP_SAVE"})
|
||||
|
||||
if TYPE_CHECKING:
|
||||
obj: str
|
||||
mass_operation: bool
|
||||
|
||||
def invoke(self, context, event):
|
||||
self.mass_operation = event.alt
|
||||
return self.execute(context)
|
||||
|
||||
def enable_editing_attribute_on_obj(self, obj):
|
||||
props = obj.BIMAttributeProperties
|
||||
|
||||
class EnableEditingAttributes(bpy.types.Operator, AttributesOperator):
|
||||
bl_idname = "bim.enable_editing_attributes"
|
||||
bl_label = "Enable Editing Attributes"
|
||||
bl_description = "ALT + Left Click to enable editing attributes on all selected objects"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def enable_editing_attribute_on_obj(self, obj: bpy.types.Object) -> None:
|
||||
props = tool.Blender.get_object_attribute_props(obj)
|
||||
props.attributes.clear()
|
||||
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
@@ -87,20 +99,14 @@ class EnableEditingAttributes(bpy.types.Operator):
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
class DisableEditingAttributes(bpy.types.Operator):
|
||||
class DisableEditingAttributes(bpy.types.Operator, AttributesOperator):
|
||||
bl_idname = "bim.disable_editing_attributes"
|
||||
bl_label = "Disable Editing Attributes"
|
||||
bl_description = "ALT + Left Click to disable editing attributes on all selected objects"
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
obj: bpy.props.StringProperty(options={"SKIP_SAVE"})
|
||||
mass_operation: bpy.props.BoolProperty(default=False, options={"SKIP_SAVE"})
|
||||
|
||||
def invoke(self, context, event):
|
||||
self.mass_operation = event.alt
|
||||
return self.execute(context)
|
||||
|
||||
def disable_editing_attributes_on_obj(self, obj):
|
||||
props = obj.BIMAttributeProperties
|
||||
def disable_editing_attributes_on_obj(self, obj: bpy.types.Object) -> None:
|
||||
props = tool.Blender.get_object_attribute_props(obj)
|
||||
props.is_editing_attributes = False
|
||||
|
||||
def execute(self, context):
|
||||
@@ -118,7 +124,7 @@ class EditAttributes(bpy.types.Operator, tool.Ifc.Operator):
|
||||
def _execute(self, context):
|
||||
self.file = tool.Ifc.get()
|
||||
obj = tool.Blender.get_active_object(is_selected=False)
|
||||
if not (element := tool.Ifc.get_entity(obj)):
|
||||
if not obj or not (element := tool.Ifc.get_entity(obj)):
|
||||
return
|
||||
|
||||
def callback(attributes, prop):
|
||||
@@ -130,7 +136,7 @@ class EditAttributes(bpy.types.Operator, tool.Ifc.Operator):
|
||||
attributes[prop.name] = None
|
||||
return True
|
||||
|
||||
props = obj.BIMAttributeProperties
|
||||
props = tool.Blender.get_object_attribute_props(obj)
|
||||
attributes = bonsai.bim.helper.export_attributes(props.attributes, callback=callback)
|
||||
ifcopenshell.api.attribute.edit_attributes(self.file, product=element, attributes=attributes)
|
||||
|
||||
@@ -165,13 +171,12 @@ class GenerateGlobalId(bpy.types.Operator, tool.Ifc.Operator):
|
||||
element.GlobalId = ifcopenshell.guid.new()
|
||||
|
||||
obj = context.active_object
|
||||
if not obj or not obj.BIMAttributeProperties.is_editing_attributes:
|
||||
if not obj or not (props := tool.Blender.get_object_attribute_props(obj)).is_editing_attributes:
|
||||
return {"FINISHED"}
|
||||
|
||||
props = obj.BIMAttributeProperties
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
|
||||
if not element.is_a("IfcRoot"):
|
||||
if not element or not element.is_a("IfcRoot"):
|
||||
return {"FINISHED"}
|
||||
|
||||
if self.use_selected and obj in context.selected_objects:
|
||||
@@ -191,7 +196,10 @@ class CopyAttributeToSelection(bpy.types.Operator, tool.Ifc.Operator):
|
||||
name: bpy.props.StringProperty()
|
||||
|
||||
def _execute(self, context):
|
||||
value = tool.Blender.get_active_object().BIMAttributeProperties.attributes.get(self.name).get_value()
|
||||
obj = tool.Blender.get_active_object()
|
||||
assert obj
|
||||
props = tool.Blender.get_object_attribute_props(obj)
|
||||
value = props.attributes[self.name].get_value()
|
||||
total = core.copy_attribute_to_selection(
|
||||
tool.Ifc, tool.Blender, tool.Root, tool.Spatial, name=self.name, value=value
|
||||
)
|
||||
|
||||
@@ -29,8 +29,13 @@ from bpy.props import (
|
||||
FloatVectorProperty,
|
||||
CollectionProperty,
|
||||
)
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
|
||||
class BIMAttributeProperties(PropertyGroup):
|
||||
attributes: CollectionProperty(name="Attributes", type=Attribute)
|
||||
is_editing_attributes: BoolProperty(name="Is Editing Attributes")
|
||||
|
||||
if TYPE_CHECKING:
|
||||
attributes: bpy.types.bpy_prop_collection_idprop[Attribute]
|
||||
is_editing_attributes: bool
|
||||
|
||||
@@ -17,14 +17,16 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bonsai.bim.helper
|
||||
import bpy.types
|
||||
from bpy.types import Panel
|
||||
from bonsai.bim.module.attribute.data import AttributesData
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
def draw_ui(context, layout, attributes):
|
||||
def draw_ui(context: bpy.types.Context, layout: bpy.types.UILayout, attributes) -> None:
|
||||
obj = context.active_object
|
||||
props = obj.BIMAttributeProperties
|
||||
assert obj
|
||||
props = tool.Blender.get_object_attribute_props(obj)
|
||||
|
||||
if props.is_editing_attributes:
|
||||
row = layout.row(align=True)
|
||||
|
||||
@@ -43,6 +43,7 @@ from typing_extensions import assert_never
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.prop import BIMProperties, BIMObjectProperties
|
||||
from bonsai.bim.module.attribute.prop import BIMAttributeProperties
|
||||
from bonsai.bim.module.csv.prop import CsvProperties
|
||||
from bonsai.bim.module.diff.prop import DiffProperties
|
||||
|
||||
@@ -1635,6 +1636,10 @@ class Blender(bonsai.core.tool.Blender):
|
||||
def get_object_bim_props(cls, obj: bpy.types.Object) -> BIMObjectProperties:
|
||||
return obj.BIMObjectProperties
|
||||
|
||||
@classmethod
|
||||
def get_object_attribute_props(cls, obj: bpy.types.Object) -> BIMAttributeProperties:
|
||||
return obj.BIMAttributeProperties
|
||||
|
||||
@classmethod
|
||||
def get_ifc_definition_id(cls, obj: IFC_CONNECTED_TYPE) -> int:
|
||||
if isinstance(obj, bpy.types.Object):
|
||||
|
||||
@@ -53,7 +53,7 @@ def execute(args: ArgumentsDict) -> Union[ifcopenshell.file, str]:
|
||||
|
||||
:param args: A dictionary of arguments, corresponding to the parameters
|
||||
listed subsequent to this in this docstring.
|
||||
:type args: dict
|
||||
:type args: ArgumentsDict
|
||||
:param file: An IFC model to apply the patch recipe to.
|
||||
Required for most recipes except the ones that require `input`.
|
||||
:type file: ifcopenshell.file, optional
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.api.project
|
||||
import ifcopenshell.guid
|
||||
import ifcopenshell.util.selector
|
||||
from typing import Union
|
||||
@@ -81,8 +82,8 @@ class Patcher:
|
||||
pass
|
||||
if element.is_a("IfcProject"):
|
||||
return self.new.add(element)
|
||||
return ifcopenshell.api.run(
|
||||
"project.append_asset", self.new, library=self.file, element=element, reuse_identities=self.reuse_identities
|
||||
return ifcopenshell.api.project.append_asset(
|
||||
self.new, library=self.file, element=element, reuse_identities=self.reuse_identities
|
||||
)
|
||||
|
||||
def add_spatial_structures(
|
||||
|
||||
@@ -18,8 +18,10 @@
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.api.type
|
||||
import ifcopenshell.util.element
|
||||
from logging import Logger
|
||||
from typing import Any
|
||||
|
||||
|
||||
class Patcher:
|
||||
@@ -48,7 +50,6 @@ class Patcher:
|
||||
:param attribute: The name of the attribute to merge element types based
|
||||
on. Typically this will be "Tag" as it stores the unique ID from the
|
||||
proprietary BIM software.
|
||||
:type attribute: str
|
||||
|
||||
Example:
|
||||
|
||||
@@ -66,7 +67,7 @@ class Patcher:
|
||||
|
||||
def patch(self):
|
||||
key = self.attribute
|
||||
keys = {}
|
||||
keys: dict[Any, ifcopenshell.entity_instance] = {}
|
||||
for element_type in self.file.by_type("IfcTypeObject"):
|
||||
original_type = keys.get(getattr(element_type, key), None)
|
||||
if original_type:
|
||||
@@ -86,8 +87,7 @@ class Patcher:
|
||||
# since that would do other things like
|
||||
# map type representations or recalculate material set usages which is
|
||||
# risky when we're patching an existing dataset.
|
||||
ifcopenshell.api.run(
|
||||
"type.assign_type",
|
||||
ifcopenshell.api.type.assign_type(
|
||||
self.file,
|
||||
relating_type=relating_type,
|
||||
related_objects=related_objects,
|
||||
|
||||
Reference in New Issue
Block a user