mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-17 02:49:12 +00:00
typing
This commit is contained in:
@@ -31,7 +31,7 @@ class LoadGroups(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
self.props = context.scene.BIMGroupProperties
|
||||
self.props = tool.Blender.get_group_props()
|
||||
self.expanded_groups = json.loads(context.scene.ExpandedGroups.json_string)
|
||||
self.props.groups.clear()
|
||||
|
||||
@@ -95,8 +95,9 @@ class DisableGroupEditingUI(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
context.scene.BIMGroupProperties.is_editing = False
|
||||
context.scene.BIMGroupProperties.active_group_id = 0
|
||||
props = tool.Blender.get_group_props()
|
||||
props.is_editing = False
|
||||
props.active_group_id = 0
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -122,7 +123,7 @@ class EditGroup(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMGroupProperties
|
||||
props = tool.Blender.get_group_props()
|
||||
attributes = bonsai.bim.helper.export_attributes(props.group_attributes)
|
||||
ifc_file = tool.Ifc.get()
|
||||
ifcopenshell.api.group.edit_group(ifc_file, group=ifc_file.by_id(props.active_group_id), attributes=attributes)
|
||||
@@ -150,7 +151,7 @@ class EnableEditingGroup(bpy.types.Operator, tool.Ifc.Operator):
|
||||
group: bpy.props.IntProperty()
|
||||
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMGroupProperties
|
||||
props = tool.Blender.get_group_props()
|
||||
props.group_attributes.clear()
|
||||
bonsai.bim.helper.import_attributes2(tool.Ifc.get().by_id(self.group), props.group_attributes)
|
||||
props.active_group_id = self.group
|
||||
@@ -163,7 +164,8 @@ class DisableEditingGroup(bpy.types.Operator, tool.Ifc.Operator):
|
||||
bl_options = {"REGISTER", "UNDO"}
|
||||
|
||||
def _execute(self, context):
|
||||
context.scene.BIMGroupProperties.active_group_id = 0
|
||||
props = tool.Blender.get_group_props()
|
||||
props.active_group_id = 0
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -183,9 +185,9 @@ class AssignGroup(bpy.types.Operator, tool.Ifc.Operator):
|
||||
if not self.is_assigning:
|
||||
return bpy.ops.bim.unassign_group(group=self.group)
|
||||
products = [
|
||||
tool.Ifc.get_entity(o)
|
||||
element
|
||||
for o in tool.Blender.get_selected_objects(include_active=False)
|
||||
if tool.Ifc.get_entity(o)
|
||||
if (element := tool.Ifc.get_entity(o))
|
||||
]
|
||||
ifcopenshell.api.group.assign_group(tool.Ifc.get(), products=products, group=tool.Ifc.get().by_id(self.group))
|
||||
|
||||
|
||||
@@ -17,10 +17,10 @@
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
from bonsai.bim.prop import StrProperty, Attribute
|
||||
from bonsai.bim.module.pset.data import refresh as refresh_pset
|
||||
from bpy.types import PropertyGroup
|
||||
import json
|
||||
from bpy.props import (
|
||||
PointerProperty,
|
||||
StringProperty,
|
||||
@@ -31,6 +31,7 @@ from bpy.props import (
|
||||
FloatVectorProperty,
|
||||
CollectionProperty,
|
||||
)
|
||||
from typing import TYPE_CHECKING, Union
|
||||
|
||||
|
||||
def update_active_group_index(self, context):
|
||||
@@ -40,6 +41,9 @@ def update_active_group_index(self, context):
|
||||
class ExpandedGroups(StrProperty):
|
||||
json_string: StringProperty(name="JSON String", default="[]")
|
||||
|
||||
if TYPE_CHECKING:
|
||||
json_string: str
|
||||
|
||||
|
||||
class Group(PropertyGroup):
|
||||
name: StringProperty(name="Name")
|
||||
@@ -48,6 +52,13 @@ class Group(PropertyGroup):
|
||||
has_children: BoolProperty(name="Has Children", default=False)
|
||||
tree_depth: IntProperty(name="Tree Depth")
|
||||
|
||||
if TYPE_CHECKING:
|
||||
name: str
|
||||
ifc_definition_id: int
|
||||
is_expanded: bool
|
||||
has_children: bool
|
||||
tree_depth: int
|
||||
|
||||
|
||||
class BIMGroupProperties(PropertyGroup):
|
||||
group_attributes: CollectionProperty(name="Group Attributes", type=Attribute)
|
||||
@@ -56,7 +67,13 @@ class BIMGroupProperties(PropertyGroup):
|
||||
active_group_index: IntProperty(name="Active Group Index", update=update_active_group_index)
|
||||
active_group_id: IntProperty(name="Active Group Id")
|
||||
|
||||
if TYPE_CHECKING:
|
||||
group_attributes: bpy.types.bpy_prop_collection_idprop[Attribute]
|
||||
is_editing: bool
|
||||
groups: bpy.types.bpy_prop_collection_idprop[Group]
|
||||
active_group_index: int
|
||||
active_group_id: int
|
||||
|
||||
@property
|
||||
def active_group(self):
|
||||
if self.active_group_index < len(self.groups):
|
||||
return self.groups[self.active_group_index]
|
||||
def active_group(self) -> Union[Group, None]:
|
||||
return tool.Blender.get_active_uilist_element(self.groups, self.active_group_index)
|
||||
|
||||
@@ -16,11 +16,16 @@
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with Bonsai. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
from __future__ import annotations
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
from bpy.types import Panel, UIList
|
||||
from bonsai.bim.helper import draw_attributes
|
||||
from bonsai.bim.module.group.data import GroupsData, ObjectGroupsData
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.module.group.prop import BIMGroupProperties, Group
|
||||
|
||||
|
||||
class BIM_PT_groups(Panel):
|
||||
@@ -39,7 +44,7 @@ class BIM_PT_groups(Panel):
|
||||
def draw(self, context):
|
||||
if not GroupsData.is_loaded:
|
||||
GroupsData.load()
|
||||
self.props = context.scene.BIMGroupProperties
|
||||
self.props = tool.Blender.get_group_props()
|
||||
|
||||
row = self.layout.row(align=True)
|
||||
row.label(text=f"{GroupsData.data['total_groups']} Groups Found", icon="OUTLINER")
|
||||
@@ -99,7 +104,8 @@ class BIM_PT_object_groups(Panel):
|
||||
def draw(self, context):
|
||||
if not ObjectGroupsData.is_loaded:
|
||||
ObjectGroupsData.load()
|
||||
self.props = context.scene.BIMGroupProperties
|
||||
assert self.layout
|
||||
self.props = tool.Blender.get_group_props()
|
||||
|
||||
for group in ObjectGroupsData.data["groups"]:
|
||||
row = self.layout.row(align=True)
|
||||
@@ -113,7 +119,17 @@ class BIM_PT_object_groups(Panel):
|
||||
|
||||
|
||||
class BIM_UL_groups(UIList):
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||
def draw_item(
|
||||
self,
|
||||
context: bpy.types.Context,
|
||||
layout: bpy.types.UILayout,
|
||||
data: BIMGroupProperties,
|
||||
item: Group,
|
||||
icon,
|
||||
active_data,
|
||||
active_propname,
|
||||
index: int,
|
||||
):
|
||||
if item:
|
||||
row = layout.row(align=True)
|
||||
for i in range(0, item.tree_depth):
|
||||
|
||||
@@ -153,7 +153,7 @@ class IfcGitData:
|
||||
|
||||
@classmethod
|
||||
def commit(cls):
|
||||
props = bpy.context.scene.IfcGitProperties
|
||||
props = tool.IfcGit.get_ifcgit_props()
|
||||
if cls.repo() and len(props.ifcgit_commits) > 0:
|
||||
item = props.ifcgit_commits[props.commit_index]
|
||||
try:
|
||||
@@ -163,7 +163,7 @@ class IfcGitData:
|
||||
|
||||
@classmethod
|
||||
def current_revision(cls):
|
||||
props = bpy.context.scene.IfcGitProperties
|
||||
props = tool.IfcGit.get_ifcgit_props()
|
||||
if cls.repo() and cls.repo().head.is_valid() and len(props.ifcgit_commits) > 0:
|
||||
return tool.IfcGitRepo.repo.commit()
|
||||
|
||||
|
||||
@@ -68,7 +68,7 @@ class CloneRepo(bpy.types.Operator):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.IfcGitProperties
|
||||
props = tool.IfcGit.get_ifcgit_props()
|
||||
if (
|
||||
props.remote_url
|
||||
and props.local_folder
|
||||
@@ -80,7 +80,7 @@ class CloneRepo(bpy.types.Operator):
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
props = context.scene.IfcGitProperties
|
||||
props = tool.IfcGit.get_ifcgit_props()
|
||||
core.clone_repo(tool.IfcGit, props.remote_url, props.local_folder, self)
|
||||
props.remote_url = ""
|
||||
refresh()
|
||||
@@ -112,7 +112,7 @@ class CommitChanges(bpy.types.Operator):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
IfcGitData.make_sure_is_loaded()
|
||||
props = context.scene.IfcGitProperties
|
||||
props = tool.IfcGit.get_ifcgit_props()
|
||||
repo = IfcGitData.data["repo"]
|
||||
if props.commit_message == "":
|
||||
return False
|
||||
@@ -148,7 +148,7 @@ class AddTag(bpy.types.Operator):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
IfcGitData.make_sure_is_loaded()
|
||||
props = context.scene.IfcGitProperties
|
||||
props = tool.IfcGit.get_ifcgit_props()
|
||||
if props.new_tag_name == "":
|
||||
return False
|
||||
repo = IfcGitData.data["repo"]
|
||||
@@ -218,7 +218,7 @@ class DisplayRevision(bpy.types.Operator):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.IfcGitProperties
|
||||
props = tool.IfcGit.get_ifcgit_props()
|
||||
if props.ifcgit_commits:
|
||||
return True
|
||||
|
||||
@@ -253,7 +253,7 @@ class SwitchRevision(bpy.types.Operator):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.IfcGitProperties
|
||||
props = tool.IfcGit.get_ifcgit_props()
|
||||
if props.ifcgit_commits:
|
||||
return True
|
||||
|
||||
@@ -274,7 +274,7 @@ class Merge(bpy.types.Operator):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
IfcGitData.make_sure_is_loaded()
|
||||
props = context.scene.IfcGitProperties
|
||||
props = tool.IfcGit.get_ifcgit_props()
|
||||
if IfcGitData.data["ifcmerge_exe"] and props.ifcgit_commits and not IfcGitData.data["is_detached"]:
|
||||
return True
|
||||
return False
|
||||
@@ -296,8 +296,7 @@ class Push(bpy.types.Operator):
|
||||
bl_options = {"REGISTER"}
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
props = context.scene.IfcGitProperties
|
||||
props = tool.IfcGit.get_ifcgit_props()
|
||||
repo = IfcGitData.data["repo"]
|
||||
core.push(tool.IfcGit, repo, props.select_remote, self)
|
||||
return {"FINISHED"}
|
||||
@@ -311,8 +310,7 @@ class Fetch(bpy.types.Operator):
|
||||
bl_options = {"REGISTER"}
|
||||
|
||||
def execute(self, context):
|
||||
|
||||
props = context.scene.IfcGitProperties
|
||||
props = tool.IfcGit.get_ifcgit_props()
|
||||
repo = IfcGitData.data["repo"]
|
||||
remote = repo.remotes[props.select_remote]
|
||||
remote.fetch()
|
||||
@@ -329,7 +327,7 @@ class AddRemote(bpy.types.Operator):
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
IfcGitData.make_sure_is_loaded()
|
||||
props = context.scene.IfcGitProperties
|
||||
props = tool.IfcGit.get_ifcgit_props()
|
||||
repo = IfcGitData.data["repo"]
|
||||
if (
|
||||
not repo
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import bpy
|
||||
import bonsai.tool as tool
|
||||
from bpy.types import PropertyGroup
|
||||
from bpy.props import (
|
||||
StringProperty,
|
||||
@@ -8,11 +9,10 @@ from bpy.props import (
|
||||
EnumProperty,
|
||||
)
|
||||
from bonsai.bim.module.ifcgit.data import IfcGitData
|
||||
from typing import TYPE_CHECKING, Literal
|
||||
|
||||
|
||||
def git_branches(self, context):
|
||||
"""branches enum"""
|
||||
|
||||
def git_branches(self: "IfcGitProperties", context: bpy.types.Context) -> tool.Blender.BLENDER_ENUM_ITEMS:
|
||||
# NOTE "Python must keep a reference to the strings returned by
|
||||
# the callback or Blender will misbehave or even crash"
|
||||
IfcGitData.data["branch_names"] = sorted([branch.name for branch in IfcGitData.data["repo"].heads])
|
||||
@@ -29,9 +29,7 @@ def git_branches(self, context):
|
||||
return [(myname, myname, myname) for myname in IfcGitData.data["branch_names"]]
|
||||
|
||||
|
||||
def git_remotes(self, context):
|
||||
"""remotes enum"""
|
||||
|
||||
def git_remotes(self: "IfcGitProperties", context: bpy.types.Context) -> tool.Blender.BLENDER_ENUM_ITEMS:
|
||||
IfcGitData.data["remote_names"] = sorted([remote.name for remote in IfcGitData.data["remotes"]])
|
||||
|
||||
if "origin" in IfcGitData.data["remote_names"]:
|
||||
@@ -41,12 +39,11 @@ def git_remotes(self, context):
|
||||
return [(myname, myname, myname) for myname in IfcGitData.data["remote_names"]]
|
||||
|
||||
|
||||
def update_revlist(self, context):
|
||||
def update_revlist(self: "IfcGitProperties", context: bpy.types.Context) -> None:
|
||||
"""wrapper to trigger update of the revision list"""
|
||||
|
||||
bpy.ops.ifcgit.refresh()
|
||||
props = context.scene.IfcGitProperties
|
||||
props.commit_index = 0
|
||||
self.commit_index = 0
|
||||
|
||||
|
||||
class IfcGitTag(PropertyGroup):
|
||||
@@ -61,6 +58,10 @@ class IfcGitTag(PropertyGroup):
|
||||
default="",
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
name: str
|
||||
message: str
|
||||
|
||||
|
||||
class IfcGitListItem(PropertyGroup):
|
||||
"""Group of properties representing an item in the list."""
|
||||
@@ -89,6 +90,14 @@ class IfcGitListItem(PropertyGroup):
|
||||
)
|
||||
tags: CollectionProperty(type=IfcGitTag, name="List of revision tags")
|
||||
|
||||
if TYPE_CHECKING:
|
||||
hexsha: str
|
||||
relevant: bool
|
||||
author_name: str
|
||||
author_email: str
|
||||
message: str
|
||||
tags: bpy.types.bpy_prop_collection_idprop[IfcGitTag]
|
||||
|
||||
|
||||
class IfcGitProperties(PropertyGroup):
|
||||
|
||||
@@ -140,3 +149,17 @@ class IfcGitProperties(PropertyGroup):
|
||||
],
|
||||
update=update_revlist,
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
ifcgit_commits: bpy.types.bpy_prop_collection_idprop[IfcGitListItem]
|
||||
commit_index: int
|
||||
commit_message: str
|
||||
new_branch_name: str
|
||||
new_tag_name: str
|
||||
new_tag_message: str
|
||||
remote_name: str
|
||||
remote_url: str
|
||||
local_folder: str
|
||||
display_branch: str
|
||||
select_remote: str
|
||||
ifcgit_filter: Literal["all", "tagged", "relevant"]
|
||||
|
||||
@@ -1,10 +1,16 @@
|
||||
from __future__ import annotations
|
||||
import bpy
|
||||
import time
|
||||
import os
|
||||
import platform
|
||||
import bonsai.tool as tool
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
from bonsai.bim.module.ifcgit.data import IfcGitData
|
||||
|
||||
if TYPE_CHECKING:
|
||||
from bonsai.bim.module.ifcgit.prop import IfcGitProperties, IfcGitListItem
|
||||
|
||||
|
||||
class IFCGIT_PT_panel(bpy.types.Panel):
|
||||
"""Scene Properties panel to interact with IFC repository data"""
|
||||
@@ -35,7 +41,7 @@ class IFCGIT_PT_panel(bpy.types.Panel):
|
||||
)
|
||||
return
|
||||
|
||||
props = context.scene.IfcGitProperties
|
||||
props = tool.IfcGit.get_ifcgit_props()
|
||||
|
||||
# TODO if file isn't saved, offer to save to disk
|
||||
|
||||
@@ -195,9 +201,17 @@ class IFCGIT_PT_panel(bpy.types.Panel):
|
||||
class COMMIT_UL_List(bpy.types.UIList):
|
||||
"""List of Git commits"""
|
||||
|
||||
def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
|
||||
|
||||
props = context.scene.IfcGitProperties
|
||||
def draw_item(
|
||||
self,
|
||||
context: bpy.types.UILayout,
|
||||
layout: bpy.types.UILayout,
|
||||
data: IfcGitProperties,
|
||||
item: IfcGitListItem,
|
||||
icon,
|
||||
active_data,
|
||||
active_propname,
|
||||
index: int,
|
||||
):
|
||||
|
||||
current_revision = IfcGitData.data["current_revision"]
|
||||
|
||||
@@ -212,7 +226,7 @@ class COMMIT_UL_List(bpy.types.UIList):
|
||||
refs = ""
|
||||
if item.hexsha in lookup:
|
||||
for branch in lookup[item.hexsha]:
|
||||
if branch.name == props.display_branch:
|
||||
if branch.name == data.display_branch:
|
||||
refs = "[" + branch.name + "] "
|
||||
|
||||
lookup = IfcGitData.data["tags_by_hexsha"]
|
||||
@@ -272,6 +286,7 @@ class IFCGIT_PT_revision_inspector(bpy.types.Panel):
|
||||
IfcGitData.load()
|
||||
|
||||
layout = self.layout
|
||||
assert layout
|
||||
|
||||
if not IfcGitData.data["git_exe"]:
|
||||
row = layout.row()
|
||||
|
||||
@@ -566,6 +566,7 @@ class RefreshIFCMaterials(bpy.types.Operator):
|
||||
|
||||
def execute(self, context):
|
||||
props = context.scene.radiance_exporter_properties
|
||||
ifc_file: ifcopenshell.file
|
||||
ifc_file = tool.Ifc.get() if props.should_load_from_memory else ifcopenshell.open(props.ifc_file)
|
||||
|
||||
props.materials.clear()
|
||||
|
||||
@@ -266,8 +266,9 @@ class GroupQtosData(Data):
|
||||
|
||||
@classmethod
|
||||
def load(cls):
|
||||
props = bpy.context.scene.BIMGroupProperties
|
||||
ifc_definition_id = props.groups[props.active_group_index].ifc_definition_id
|
||||
props = tool.Blender.get_group_props()
|
||||
assert (active_group := props.active_group)
|
||||
ifc_definition_id = active_group.ifc_definition_id
|
||||
cls.data = {"qtos": cls.psetqtos(tool.Ifc.get_entity_by_id(ifc_definition_id), qtos_only=True)}
|
||||
cls.is_loaded = True
|
||||
|
||||
@@ -278,8 +279,9 @@ class GroupPsetData(Data):
|
||||
|
||||
@classmethod
|
||||
def load(cls):
|
||||
props = bpy.context.scene.BIMGroupProperties
|
||||
ifc_definition_id = props.groups[props.active_group_index].ifc_definition_id
|
||||
props = tool.Blender.get_group_props()
|
||||
assert (active_group := props.active_group)
|
||||
ifc_definition_id = active_group.ifc_definition_id
|
||||
cls.data = {"psets": cls.psetqtos(tool.Ifc.get_entity_by_id(ifc_definition_id), psets_only=True)}
|
||||
cls.is_loaded = True
|
||||
|
||||
|
||||
@@ -662,7 +662,7 @@ class BIM_PT_group_qtos(Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.BIMGroupProperties
|
||||
props = tool.Blender.get_group_props()
|
||||
total_resources = len(props.groups)
|
||||
if total_resources > 0 and props.active_group_index < total_resources:
|
||||
return True
|
||||
@@ -696,7 +696,7 @@ class BIM_PT_group_psets(Panel):
|
||||
|
||||
@classmethod
|
||||
def poll(cls, context):
|
||||
props = context.scene.BIMGroupProperties
|
||||
props = tool.Blender.get_group_props()
|
||||
total_resources = len(props.groups)
|
||||
if total_resources > 0 and props.active_group_index < total_resources:
|
||||
return True
|
||||
|
||||
@@ -25,18 +25,18 @@ if TYPE_CHECKING:
|
||||
import bonsai.tool as tool
|
||||
|
||||
|
||||
def enable_editing_aggregate(aggregator: tool.Aggregate, obj: bpy.types.Object) -> None:
|
||||
def enable_editing_aggregate(aggregator: type[tool.Aggregate], obj: bpy.types.Object) -> None:
|
||||
aggregator.enable_editing(obj)
|
||||
|
||||
|
||||
def disable_editing_aggregate(aggregator: tool.Aggregate, obj: bpy.types.Object) -> None:
|
||||
def disable_editing_aggregate(aggregator: type[tool.Aggregate], obj: bpy.types.Object) -> None:
|
||||
aggregator.disable_editing(obj)
|
||||
|
||||
|
||||
def assign_object(
|
||||
ifc: tool.Ifc,
|
||||
aggregator: tool.Aggregate,
|
||||
collector: tool.Collector,
|
||||
ifc: type[tool.Ifc],
|
||||
aggregator: type[tool.Aggregate],
|
||||
collector: type[tool.Collector],
|
||||
relating_obj: Optional[bpy.types.Object] = None,
|
||||
related_obj: Optional[bpy.types.Object] = None,
|
||||
) -> Union[ifcopenshell.entity_instance, None]:
|
||||
@@ -53,9 +53,9 @@ def assign_object(
|
||||
|
||||
|
||||
def unassign_object(
|
||||
ifc: tool.Ifc,
|
||||
aggregate: tool.Aggregate,
|
||||
collector: tool.Collector,
|
||||
ifc: type[tool.Ifc],
|
||||
aggregate: type[tool.Aggregate],
|
||||
collector: type[tool.Collector],
|
||||
relating_obj: Optional[bpy.types.Object] = None,
|
||||
related_obj: Optional[bpy.types.Object] = None,
|
||||
) -> None:
|
||||
@@ -74,10 +74,10 @@ def unassign_object(
|
||||
|
||||
|
||||
def add_part_to_object(
|
||||
ifc: tool.Ifc,
|
||||
aggregator: tool.Aggregate,
|
||||
collector: tool.Collector,
|
||||
blender: tool.Blender,
|
||||
ifc: type[tool.Ifc],
|
||||
aggregator: type[tool.Aggregate],
|
||||
collector: type[tool.Collector],
|
||||
blender: type[tool.Blender],
|
||||
obj: bpy.types.Object,
|
||||
part_class: str,
|
||||
part_name: Optional[str] = None,
|
||||
@@ -88,7 +88,7 @@ def add_part_to_object(
|
||||
|
||||
|
||||
def enter_aggregate_mode(
|
||||
aggregator: tool.Aggregate,
|
||||
aggregator: type[tool.Aggregate],
|
||||
obj: bpy.types.Object,
|
||||
):
|
||||
aggregator.update_previous_aggregate_mode_state()
|
||||
@@ -98,7 +98,7 @@ def enter_aggregate_mode(
|
||||
aggregator.enable_aggregate_mode(obj)
|
||||
|
||||
|
||||
def exit_aggregate_mode(aggregator: tool.Aggregate):
|
||||
def exit_aggregate_mode(aggregator: type[tool.Aggregate]):
|
||||
aggregator.update_previous_aggregate_mode_state()
|
||||
if new_obj := aggregator.get_higher_aggregate():
|
||||
aggregator.disable_aggregate_mode()
|
||||
|
||||
@@ -27,19 +27,19 @@ if TYPE_CHECKING:
|
||||
import git
|
||||
|
||||
|
||||
def create_repo(ifcgit: tool.IfcGit, ifc: tool.Ifc) -> None:
|
||||
def create_repo(ifcgit: type[tool.IfcGit], ifc: type[tool.Ifc]) -> None:
|
||||
path_ifc = ifc.get_path()
|
||||
path_dir = ifcgit.get_path_dir(path_ifc)
|
||||
ifcgit.init_repo(path_dir)
|
||||
|
||||
|
||||
def add_file(ifcgit: tool.IfcGit, ifc: tool.Ifc) -> None:
|
||||
def add_file(ifcgit: type[tool.IfcGit], ifc: type[tool.Ifc]) -> None:
|
||||
path_ifc = ifc.get_path()
|
||||
repo = ifcgit.repo_from_path(path_ifc)
|
||||
ifcgit.add_file_to_repo(repo, path_ifc)
|
||||
|
||||
|
||||
def clone_repo(ifcgit: tool.IfcGit, remote_url: str, local_folder: str, operator: bpy.types.Operator) -> None:
|
||||
def clone_repo(ifcgit: type[tool.IfcGit], remote_url: str, local_folder: str, operator: bpy.types.Operator) -> None:
|
||||
repo = ifcgit.clone_repo(remote_url, local_folder)
|
||||
if not repo:
|
||||
operator.report({"ERROR"}, "Clone failed")
|
||||
@@ -48,14 +48,14 @@ def clone_repo(ifcgit: tool.IfcGit, remote_url: str, local_folder: str, operator
|
||||
ifcgit.load_anyifc(repo)
|
||||
|
||||
|
||||
def discard_uncommitted(ifcgit: tool.IfcGit, ifc: tool.Ifc) -> None:
|
||||
def discard_uncommitted(ifcgit: type[tool.IfcGit], ifc: type[tool.Ifc]) -> None:
|
||||
path_ifc = ifc.get_path()
|
||||
# NOTE this is calling the git binary in a subprocess
|
||||
ifcgit.git_checkout(path_ifc)
|
||||
ifcgit.load_project(path_ifc)
|
||||
|
||||
|
||||
def commit_changes(ifcgit: tool.IfcGit, ifc: tool.Ifc, repo: git.Repo) -> None:
|
||||
def commit_changes(ifcgit: type[tool.IfcGit], ifc: type[tool.Ifc], repo: git.Repo) -> None:
|
||||
"""Commit and create new branches as required"""
|
||||
path_ifc = ifc.get_path()
|
||||
|
||||
@@ -67,34 +67,34 @@ def commit_changes(ifcgit: tool.IfcGit, ifc: tool.Ifc, repo: git.Repo) -> None:
|
||||
ifcgit.git_commit(path_ifc)
|
||||
|
||||
|
||||
def add_tag(ifcgit: tool.IfcGit, repo: git.Repo) -> None:
|
||||
def add_tag(ifcgit: type[tool.IfcGit], repo: git.Repo) -> None:
|
||||
ifcgit.add_tag(repo)
|
||||
|
||||
|
||||
def delete_tag(ifcgit: tool.IfcGit, repo: git.Repo, tag_name: git.TagReference) -> None:
|
||||
def delete_tag(ifcgit: type[tool.IfcGit], repo: git.Repo, tag_name: git.TagReference) -> None:
|
||||
ifcgit.delete_tag(repo, tag_name)
|
||||
|
||||
|
||||
def add_remote(ifcgit: tool.IfcGit, repo: git.Repo) -> None:
|
||||
def add_remote(ifcgit: type[tool.IfcGit], repo: git.Repo) -> None:
|
||||
ifcgit.add_remote(repo)
|
||||
|
||||
|
||||
def delete_remote(ifcgit: tool.IfcGit, repo: git.Repo) -> None:
|
||||
def delete_remote(ifcgit: type[tool.IfcGit], repo: git.Repo) -> None:
|
||||
ifcgit.delete_remote(repo)
|
||||
|
||||
|
||||
def push(ifcgit: tool.IfcGit, repo: git.Repo, remote_name: str, operator: bpy.types.Operator) -> None:
|
||||
def push(ifcgit: type[tool.IfcGit], repo: git.Repo, remote_name: str, operator: bpy.types.Operator) -> None:
|
||||
error_message = ifcgit.push(repo, remote_name, repo.active_branch.name)
|
||||
if error_message:
|
||||
operator.report({"ERROR"}, error_message)
|
||||
|
||||
|
||||
def refresh_revision_list(ifcgit: tool.IfcGit, repo: git.Repo, ifc: tool.Ifc) -> None:
|
||||
def refresh_revision_list(ifcgit: type[tool.IfcGit], repo: git.Repo, ifc: type[tool.Ifc]) -> None:
|
||||
if repo.heads:
|
||||
ifcgit.refresh_revision_list(ifc.get_path())
|
||||
|
||||
|
||||
def colourise_revision(ifcgit: tool.IfcGit) -> None:
|
||||
def colourise_revision(ifcgit: type[tool.IfcGit]) -> None:
|
||||
|
||||
step_ids = ifcgit.get_revisions_step_ids()
|
||||
if not step_ids:
|
||||
@@ -104,7 +104,7 @@ def colourise_revision(ifcgit: tool.IfcGit) -> None:
|
||||
ifcgit.colourise(final_step_ids)
|
||||
|
||||
|
||||
def colourise_uncommitted(ifcgit: tool.IfcGit, ifc: tool.Ifc, repo: git.Repo) -> None:
|
||||
def colourise_uncommitted(ifcgit: type[tool.IfcGit], ifc: type[tool.Ifc], repo: git.Repo) -> None:
|
||||
path_ifc = ifc.get_path()
|
||||
step_ids = ifcgit.ifc_diff_ids(repo, None, "HEAD", path_ifc)
|
||||
if not step_ids:
|
||||
@@ -114,7 +114,7 @@ def colourise_uncommitted(ifcgit: tool.IfcGit, ifc: tool.Ifc, repo: git.Repo) ->
|
||||
ifcgit.colourise(final_step_ids)
|
||||
|
||||
|
||||
def switch_revision(ifcgit: tool.IfcGit, ifc: tool.Ifc) -> None:
|
||||
def switch_revision(ifcgit: type[tool.IfcGit], ifc: type[tool.Ifc]) -> None:
|
||||
# FIXME bad things happen when switching to a revision that predates current project
|
||||
|
||||
path_ifc = ifc.get_path()
|
||||
@@ -124,25 +124,25 @@ def switch_revision(ifcgit: tool.IfcGit, ifc: tool.Ifc) -> None:
|
||||
ifcgit.decolourise()
|
||||
|
||||
|
||||
def merge_branch(ifcgit: tool.IfcGit, ifc: tool.Ifc, operator: bpy.types.Operator) -> None:
|
||||
def merge_branch(ifcgit: type[tool.IfcGit], ifc: type[tool.Ifc], operator: bpy.types.Operator) -> None:
|
||||
path_ifc = ifc.get_path()
|
||||
ifcgit.config_ifcmerge()
|
||||
ifcgit.execute_merge(path_ifc, operator)
|
||||
|
||||
|
||||
def entity_log(ifcgit: tool.IfcGit, ifc: tool.Ifc, step_id: int, operator: bpy.types.Operator) -> None:
|
||||
def entity_log(ifcgit: type[tool.IfcGit], ifc: type[tool.Ifc], step_id: int, operator: bpy.types.Operator) -> None:
|
||||
path_ifc = ifc.get_path()
|
||||
log_text = ifcgit.entity_log(path_ifc, step_id)
|
||||
# ERROR is only way to display a multi-line message
|
||||
operator.report({"ERROR"}, log_text)
|
||||
|
||||
|
||||
def install_git(ifcgit: tool.IfcGit, operator: bpy.types.Operator) -> None:
|
||||
def install_git(ifcgit: type[tool.IfcGit], operator: bpy.types.Operator) -> None:
|
||||
if platform.system() == "Windows":
|
||||
ifcgit.install_git_windows(operator=operator)
|
||||
else:
|
||||
print("install_git() not implemented")
|
||||
|
||||
|
||||
def run_git_diff(ifcgit: tool.IfcGit, operator: bpy.types.Operator) -> None:
|
||||
def run_git_diff(ifcgit: type[tool.IfcGit], operator: bpy.types.Operator) -> None:
|
||||
ifcgit.run_git_diff(operator)
|
||||
|
||||
@@ -52,6 +52,7 @@ if TYPE_CHECKING:
|
||||
from bonsai.bim.module.csv.prop import CsvProperties
|
||||
from bonsai.bim.module.constraint.prop import BIMConstraintProperties, BIMObjectConstraintProperties
|
||||
from bonsai.bim.module.diff.prop import DiffProperties
|
||||
from bonsai.bim.module.group.prop import BIMGroupProperties
|
||||
|
||||
T = TypeVar("T")
|
||||
|
||||
@@ -244,8 +245,9 @@ class Blender(bonsai.core.tool.Blender):
|
||||
wsprops = tool.Sequence.get_work_schedule_props()
|
||||
return wsprops.active_work_schedule_id
|
||||
elif obj_type == "Group":
|
||||
prop = context.scene.BIMGroupProperties
|
||||
return prop.groups[prop.active_group_index].ifc_definition_id
|
||||
props = tool.Blender.get_group_props()
|
||||
assert (active_group := props.active_group)
|
||||
return active_group.ifc_definition_id
|
||||
assert_never(obj_type)
|
||||
|
||||
@classmethod
|
||||
@@ -1664,6 +1666,11 @@ class Blender(bonsai.core.tool.Blender):
|
||||
assert (scene := bpy.context.scene)
|
||||
return scene.DiffProperties
|
||||
|
||||
@classmethod
|
||||
def get_group_props(cls) -> BIMGroupProperties:
|
||||
assert (scene := bpy.context.scene)
|
||||
return scene.BIMGroupProperties
|
||||
|
||||
@classmethod
|
||||
def get_bim_props(cls, scene: Optional[bpy.types.Scene] = None) -> BIMProperties:
|
||||
if scene is None:
|
||||
|
||||
@@ -25,7 +25,7 @@ import logging
|
||||
from bonsai.bim import import_ifc
|
||||
from bonsai.bim.ifc import IfcStore
|
||||
import bonsai.tool as tool
|
||||
from typing import TYPE_CHECKING, Union
|
||||
from typing import TYPE_CHECKING, Union, Literal, Any
|
||||
|
||||
# allows git import even if git executable isn't found
|
||||
os.environ["GIT_PYTHON_REFRESH"] = "quiet"
|
||||
@@ -37,10 +37,17 @@ except ImportError:
|
||||
if TYPE_CHECKING:
|
||||
import git
|
||||
|
||||
from bonsai.bim.module.ifcgit.prop import IfcGitProperties
|
||||
|
||||
|
||||
class IfcGit:
|
||||
STEP_IDS = dict[str, set[int]]
|
||||
|
||||
@classmethod
|
||||
def get_ifcgit_props(cls) -> IfcGitProperties:
|
||||
assert (scene := bpy.context.scene)
|
||||
return scene.IfcGitProperties
|
||||
|
||||
@classmethod
|
||||
def init_repo(cls, path_dir: str) -> None:
|
||||
IfcGitRepo.repo = git.Repo.init(path_dir)
|
||||
@@ -118,7 +125,7 @@ class IfcGit:
|
||||
@classmethod
|
||||
def checkout_new_branch(cls, path_file: str) -> None:
|
||||
"""Create a branch and move uncommitted changes to this branch"""
|
||||
props = bpy.context.scene.IfcGitProperties
|
||||
props = cls.get_ifcgit_props()
|
||||
if props.new_branch_name:
|
||||
IfcGitRepo.repo.git.checkout(b=props.new_branch_name)
|
||||
props.display_branch = props.new_branch_name
|
||||
@@ -127,7 +134,7 @@ class IfcGit:
|
||||
|
||||
@classmethod
|
||||
def git_commit(cls, path_file: str) -> None:
|
||||
props = bpy.context.scene.IfcGitProperties
|
||||
props = cls.get_ifcgit_props()
|
||||
repo = IfcGitRepo.repo
|
||||
if os.name == "nt":
|
||||
cls.dos2unix(path_file)
|
||||
@@ -137,7 +144,7 @@ class IfcGit:
|
||||
|
||||
@classmethod
|
||||
def add_tag(cls, repo: git.Repo) -> None:
|
||||
props = bpy.context.scene.IfcGitProperties
|
||||
props = cls.get_ifcgit_props()
|
||||
item = props.ifcgit_commits[props.commit_index]
|
||||
repo.create_tag(props.new_tag_name, ref=item.hexsha, message=props.new_tag_message)
|
||||
props.new_tag_name = ""
|
||||
@@ -150,14 +157,14 @@ class IfcGit:
|
||||
|
||||
@classmethod
|
||||
def add_remote(cls, repo: git.Repo) -> None:
|
||||
props = bpy.context.scene.IfcGitProperties
|
||||
props = cls.get_ifcgit_props()
|
||||
repo.create_remote(name=props.remote_name, url=props.remote_url)
|
||||
props.remote_name = ""
|
||||
props.remote_url = ""
|
||||
|
||||
@classmethod
|
||||
def delete_remote(cls, repo: git.Repo) -> None:
|
||||
props = bpy.context.scene.IfcGitProperties
|
||||
props = cls.get_ifcgit_props()
|
||||
remote_name = props.select_remote
|
||||
if remote_name in repo.remotes:
|
||||
repo.delete_remote(remote_name)
|
||||
@@ -176,7 +183,7 @@ class IfcGit:
|
||||
@classmethod
|
||||
def create_new_branch(cls) -> None:
|
||||
"""Convert a detached HEAD into a branch"""
|
||||
props = bpy.context.scene.IfcGitProperties
|
||||
props = cls.get_ifcgit_props()
|
||||
repo = IfcGitRepo.repo
|
||||
new_branch = repo.create_head(props.new_branch_name)
|
||||
new_branch.checkout()
|
||||
@@ -187,7 +194,7 @@ class IfcGit:
|
||||
|
||||
@classmethod
|
||||
def clear_commits_list(cls) -> None:
|
||||
props = bpy.context.scene.IfcGitProperties
|
||||
props = cls.get_ifcgit_props()
|
||||
|
||||
# ifcgit_commits is registered list widget
|
||||
props.ifcgit_commits.clear()
|
||||
@@ -195,7 +202,7 @@ class IfcGit:
|
||||
@classmethod
|
||||
def get_commits_list(cls, path_ifc: str, lookup: dict[str, Any]) -> None:
|
||||
|
||||
props = bpy.context.scene.IfcGitProperties
|
||||
props = props = cls.get_ifcgit_props()
|
||||
repo = cls.repo_from_path(path_ifc)
|
||||
commits = list(
|
||||
git.objects.commit.Commit.iter_items(
|
||||
@@ -342,7 +349,7 @@ class IfcGit:
|
||||
def get_revisions_step_ids(cls) -> Union[STEP_IDS, None]:
|
||||
props = tool.Blender.get_bim_props()
|
||||
path_ifc = tool.Blender.get_bim_props().ifc_file
|
||||
props = bpy.context.scene.IfcGitProperties
|
||||
props = cls.get_ifcgit_props()
|
||||
repo = IfcGitRepo.repo
|
||||
item = props.ifcgit_commits[props.commit_index]
|
||||
|
||||
@@ -431,7 +438,7 @@ class IfcGit:
|
||||
|
||||
@classmethod
|
||||
def switch_to_revision_item(cls) -> None:
|
||||
props = bpy.context.scene.IfcGitProperties
|
||||
props = cls.get_ifcgit_props()
|
||||
repo = IfcGitRepo.repo
|
||||
item = props.ifcgit_commits[props.commit_index]
|
||||
|
||||
@@ -500,8 +507,8 @@ class IfcGit:
|
||||
output.write(line + b"\n")
|
||||
|
||||
@classmethod
|
||||
def execute_merge(cls, path_ifc: str, operator: bpy.types.Operator) -> Union[None, False]:
|
||||
props = bpy.context.scene.IfcGitProperties
|
||||
def execute_merge(cls, path_ifc: str, operator: bpy.types.Operator) -> Union[None, Literal[False]]:
|
||||
props = cls.get_ifcgit_props()
|
||||
repo = IfcGitRepo.repo
|
||||
item = props.ifcgit_commits[props.commit_index]
|
||||
lookup = cls.branches_by_hexsha(repo)
|
||||
|
||||
@@ -52,15 +52,11 @@ def assign_cost_item_quantity(
|
||||
count towards the cost item (they only provide value).
|
||||
|
||||
:param cost_item: The IfcCostItem to assign parametric quantities to
|
||||
:type cost_item: ifcopenshell.entity_instance
|
||||
:param products: The IfcObjects to assign parametric quantities to
|
||||
:type products: list[ifcopenshell.entity_instance]
|
||||
:param prop_name: The name of the quantity. If this is not specified,
|
||||
then it is assumed that there is no calculated quantity, and the
|
||||
number of objects are counted instead.
|
||||
:type prop_name: str, optional
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
|
||||
Reference in New Issue
Block a user