mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-09 17:31:45 +00:00
Edit profile based representations with TAB (#3142)
* You can now edit profile based representations with TAB * Minor fix * Minor fix * You can now edit parametric railing paths with TAB Still not sure about the implementation though * use shortcut instead of direct link to railing edition * Add utility to check if a mesh is profile based or its representation is a swept solid * Fix bug when trying to edit an empty object * Prevent editing door, window and stair modifiers since they're fully parameterized by the modifier properties * You can now edit roof modifier, railing modifier and various profile based objects * You can now edit axis profile based objects
This commit is contained in:
@@ -738,13 +738,18 @@ class OverrideModeSetEdit(bpy.types.Operator):
|
||||
if not obj:
|
||||
continue
|
||||
|
||||
if not obj.data:
|
||||
obj.select_set(False)
|
||||
continue
|
||||
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element:
|
||||
obj.select_set(False)
|
||||
continue
|
||||
|
||||
# We are switching from OBJECT to EDIT mode.
|
||||
usage_type = tool.Model.get_usage_type(element)
|
||||
if usage_type:
|
||||
if usage_type is not None and usage_type != "PROFILE":
|
||||
# Parametric objects shall not be edited as meshes as they
|
||||
# can be modified to be incompatible with the parametric
|
||||
# constraints.
|
||||
@@ -755,6 +760,37 @@ class OverrideModeSetEdit(bpy.types.Operator):
|
||||
if not representation:
|
||||
continue
|
||||
|
||||
if (
|
||||
tool.Pset.get_element_pset(element, "BBIM_Door")
|
||||
or tool.Pset.get_element_pset(element, "BBIM_Window")
|
||||
or tool.Pset.get_element_pset(element, "BBIM_Stair")
|
||||
):
|
||||
obj.select_set(False)
|
||||
continue
|
||||
if usage_type == "PROFILE":
|
||||
if len(context.selected_objects) == 1:
|
||||
bpy.ops.bim.hotkey(hotkey="A_E", description="")
|
||||
obj.data.BIMMeshProperties.mesh_checksum = tool.Geometry.get_mesh_checksum(obj.data)
|
||||
return {"FINISHED"}
|
||||
else:
|
||||
self.report({"INFO"}, "Only a single profile-based representation can be edited at a time.")
|
||||
obj.select_set(False)
|
||||
continue
|
||||
if (
|
||||
tool.Geometry.is_profile_based(obj.data)
|
||||
or tool.Geometry.is_swept_profile(representation)
|
||||
or tool.Pset.get_element_pset(element, "BBIM_Roof")
|
||||
or tool.Pset.get_element_pset(element, "BBIM_Railing")
|
||||
):
|
||||
if len(context.selected_objects) == 1:
|
||||
bpy.ops.bim.hotkey(hotkey="S_E", description="")
|
||||
obj.data.BIMMeshProperties.mesh_checksum = tool.Geometry.get_mesh_checksum(obj.data)
|
||||
return {"FINISHED"}
|
||||
else:
|
||||
self.report({"INFO"}, "Only a single profile-based representation can be edited at a time.")
|
||||
obj.select_set(False)
|
||||
continue
|
||||
|
||||
if tool.Geometry.is_meshlike(representation):
|
||||
if getattr(element, "HasOpenings", None):
|
||||
# Mesh elements with openings must disable openings
|
||||
@@ -866,7 +902,18 @@ class OverrideModeSetObject(bpy.types.Operator):
|
||||
if not element:
|
||||
continue
|
||||
|
||||
if obj.data.BIMMeshProperties.ifc_definition_id:
|
||||
if tool.Profile.is_editing_profile():
|
||||
if obj.data.BIMMeshProperties.mesh_checksum != tool.Geometry.get_mesh_checksum(obj.data):
|
||||
if tool.Pset.get_element_pset(element, "BBIM_Railing") or tool.Pset.get_element_pset(
|
||||
element, "BBIM_Roof"
|
||||
):
|
||||
bpy.ops.bim.cad_hotkey(hotkey="S_Q")
|
||||
elif tool.Model.get_usage_type(element):
|
||||
bpy.ops.bim.edit_extrusion_axis()
|
||||
else:
|
||||
bpy.ops.bim.edit_extrusion_profile()
|
||||
return self.execute(context)
|
||||
elif obj.data.BIMMeshProperties.ifc_definition_id:
|
||||
if not tool.Geometry.has_geometric_data(obj):
|
||||
self.is_valid = False
|
||||
self.should_save = False
|
||||
|
||||
@@ -356,6 +356,16 @@ class Geometry(blenderbim.core.tool.Geometry):
|
||||
return True
|
||||
return False
|
||||
|
||||
@classmethod
|
||||
def is_profile_based(cls, data):
|
||||
return data.BIMMeshProperties.subshape_type == "PROFILE"
|
||||
|
||||
@classmethod
|
||||
def is_swept_profile(cls, representation):
|
||||
return ifcopenshell.util.representation.resolve_representation(representation).RepresentationType in (
|
||||
"SweptSolid",
|
||||
)
|
||||
|
||||
@classmethod
|
||||
def is_type_product(cls, element):
|
||||
return element.is_a("IfcTypeProduct")
|
||||
|
||||
@@ -21,6 +21,7 @@ import ifcopenshell.util.unit
|
||||
import ifcopenshell.util.placement
|
||||
import ifcopenshell.util.representation
|
||||
import blenderbim.core.tool
|
||||
from blenderbim.bim.module.model.decorator import ProfileDecorator
|
||||
|
||||
|
||||
class Profile(blenderbim.core.tool.Profile):
|
||||
@@ -52,3 +53,7 @@ class Profile(blenderbim.core.tool.Profile):
|
||||
|
||||
for e in grouped_edges:
|
||||
draw.line((tuple(grouped_verts[e[0]]), tuple(grouped_verts[e[1]])), fill="white", width=2)
|
||||
|
||||
@classmethod
|
||||
def is_editing_profile(cls):
|
||||
return ProfileDecorator.installed
|
||||
|
||||
Reference in New Issue
Block a user