mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-19 14:41:25 +00:00
create new shape aspects from UI
example - https://i.imgur.com/BJJZWrC.png
This commit is contained in:
@@ -108,7 +108,8 @@ class RepresentationsData:
|
|||||||
matching_shape_aspects.append(shape_aspect)
|
matching_shape_aspects.append(shape_aspect)
|
||||||
|
|
||||||
# blender enum items
|
# blender enum items
|
||||||
return [(str(s.id()), s.Name or "Unnamed", "") for s in matching_shape_aspects]
|
new_shape_aspect = [("NEW", "Create A New Shape Aspect", "")]
|
||||||
|
return new_shape_aspect + [(str(s.id()), s.Name or "Unnamed", "") for s in matching_shape_aspects]
|
||||||
|
|
||||||
|
|
||||||
class RepresentationItemsData:
|
class RepresentationItemsData:
|
||||||
|
|||||||
@@ -1692,7 +1692,7 @@ class EnableEditingRepresentationItemShapeAspect(bpy.types.Operator, Operator):
|
|||||||
props = context.active_object.BIMGeometryProperties
|
props = context.active_object.BIMGeometryProperties
|
||||||
props.is_editing_item_shape_aspect = True
|
props.is_editing_item_shape_aspect = True
|
||||||
|
|
||||||
# set dropdown to currently active style
|
# set dropdown to currently active shape aspect
|
||||||
shape_aspect_id = props.items[props.active_item_index].shape_aspect_id
|
shape_aspect_id = props.items[props.active_item_index].shape_aspect_id
|
||||||
if shape_aspect_id != 0:
|
if shape_aspect_id != 0:
|
||||||
props.representation_item_shape_aspect = str(shape_aspect_id)
|
props.representation_item_shape_aspect = str(shape_aspect_id)
|
||||||
@@ -1705,21 +1705,36 @@ class EditRepresentationItemShapeAspect(bpy.types.Operator, Operator):
|
|||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
obj = context.active_object
|
obj = context.active_object
|
||||||
|
element = tool.Ifc.get_entity(obj)
|
||||||
props = obj.BIMGeometryProperties
|
props = obj.BIMGeometryProperties
|
||||||
props.is_editing_item_shape_aspect = False
|
props.is_editing_item_shape_aspect = False
|
||||||
ifc_file = tool.Ifc.get()
|
ifc_file = tool.Ifc.get()
|
||||||
|
|
||||||
shape_aspect = ifc_file.by_id(int(props.representation_item_shape_aspect))
|
representation_item_id = props.items[props.active_item_index].ifc_definition_id
|
||||||
|
representation_item = ifc_file.by_id(representation_item_id)
|
||||||
|
|
||||||
|
if props.representation_item_shape_aspect == "NEW":
|
||||||
|
active_representation = tool.Geometry.get_active_representation(obj)
|
||||||
|
# find IfcProductRepresentationSelect based on current representation
|
||||||
|
if hasattr(element, "Representation"): # IfcProduct
|
||||||
|
product_shape = element.Representation
|
||||||
|
else: # IfcTypeProduct
|
||||||
|
for representation_map in element.RepresentationMaps:
|
||||||
|
if representation_map.MappedRepresentation == active_representation:
|
||||||
|
product_shape = representation_map
|
||||||
|
previous_shape_aspect_id = props.items[props.active_item_index].shape_aspect_id
|
||||||
|
# will be None if item didn't had a shape aspect
|
||||||
|
previous_shape_aspect = tool.Ifc.get_entity_by_id(previous_shape_aspect_id)
|
||||||
|
shape_aspect = tool.Geometry.create_shape_aspect(product_shape, active_representation, [representation_item], previous_shape_aspect)
|
||||||
|
else:
|
||||||
|
shape_aspect = ifc_file.by_id(int(props.representation_item_shape_aspect))
|
||||||
|
tool.Geometry.add_representation_item_to_shape_aspect([representation_item], shape_aspect)
|
||||||
|
|
||||||
# set attributes from UI
|
# set attributes from UI
|
||||||
shape_aspect_attrs = props.shape_aspect_attrs
|
shape_aspect_attrs = props.shape_aspect_attrs
|
||||||
shape_aspect.Name = shape_aspect_attrs.name
|
shape_aspect.Name = shape_aspect_attrs.name
|
||||||
shape_aspect.Description = shape_aspect_attrs.description
|
shape_aspect.Description = shape_aspect_attrs.description
|
||||||
|
|
||||||
representation_item_id = props.items[props.active_item_index].ifc_definition_id
|
|
||||||
representation_item = ifc_file.by_id(representation_item_id)
|
|
||||||
|
|
||||||
tool.Geometry.add_representation_item_to_shape_aspect(representation_item, shape_aspect)
|
|
||||||
# reload style ui
|
# reload style ui
|
||||||
bpy.ops.bim.disable_editing_representation_items()
|
bpy.ops.bim.disable_editing_representation_items()
|
||||||
bpy.ops.bim.enable_editing_representation_items()
|
bpy.ops.bim.enable_editing_representation_items()
|
||||||
@@ -1749,7 +1764,7 @@ class RemoveRepresentationItemFromShapeAspect(bpy.types.Operator, Operator):
|
|||||||
representation_item = ifc_file.by_id(representation_item_id)
|
representation_item = ifc_file.by_id(representation_item_id)
|
||||||
shape_aspect = ifc_file.by_id(props.items[props.active_item_index].shape_aspect_id)
|
shape_aspect = ifc_file.by_id(props.items[props.active_item_index].shape_aspect_id)
|
||||||
|
|
||||||
tool.Geometry.remove_representation_item_from_shape_aspect(representation_item, shape_aspect)
|
tool.Geometry.remove_representation_items_from_shape_aspect([representation_item], shape_aspect)
|
||||||
# reload style ui
|
# reload style ui
|
||||||
bpy.ops.bim.disable_editing_representation_items()
|
bpy.ops.bim.disable_editing_representation_items()
|
||||||
bpy.ops.bim.enable_editing_representation_items()
|
bpy.ops.bim.enable_editing_representation_items()
|
||||||
|
|||||||
@@ -72,9 +72,13 @@ def update_shape_aspect(self, context):
|
|||||||
shape_aspect_id = self.representation_item_shape_aspect
|
shape_aspect_id = self.representation_item_shape_aspect
|
||||||
attrs = self.shape_aspect_attrs
|
attrs = self.shape_aspect_attrs
|
||||||
|
|
||||||
shape_aspect = tool.Ifc.get().by_id(int(shape_aspect_id))
|
if shape_aspect_id == "NEW": # new shape aspect
|
||||||
attrs.name = shape_aspect.Name or ""
|
attrs.name = tool.Blender.get_blender_prop_default_value(attrs, "name")
|
||||||
attrs.description = shape_aspect.Description or ""
|
attrs.description = tool.Blender.get_blender_prop_default_value(attrs, "description")
|
||||||
|
else:
|
||||||
|
shape_aspect = tool.Ifc.get().by_id(int(shape_aspect_id))
|
||||||
|
attrs.name = shape_aspect.Name or ""
|
||||||
|
attrs.description = shape_aspect.Description or ""
|
||||||
|
|
||||||
|
|
||||||
class RepresentationItem(PropertyGroup):
|
class RepresentationItem(PropertyGroup):
|
||||||
|
|||||||
@@ -299,6 +299,7 @@ class Geometry(blenderbim.core.tool.Geometry):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_active_representation(cls, obj):
|
def get_active_representation(cls, obj):
|
||||||
|
"""< IfcShapeRepresentation or None"""
|
||||||
if obj.data and hasattr(obj.data, "BIMMeshProperties") and obj.data.BIMMeshProperties.ifc_definition_id:
|
if obj.data and hasattr(obj.data, "BIMMeshProperties") and obj.data.BIMMeshProperties.ifc_definition_id:
|
||||||
return tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
|
return tool.Ifc.get().by_id(obj.data.BIMMeshProperties.ifc_definition_id)
|
||||||
|
|
||||||
@@ -744,31 +745,56 @@ class Geometry(blenderbim.core.tool.Geometry):
|
|||||||
return shape_aspects
|
return shape_aspects
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def remove_representation_item_from_shape_aspect(cls, representation_item, shape_aspect):
|
def create_shape_aspect(cls, product_shape, base_representation, items, previous_shape_aspect=None):
|
||||||
|
"""
|
||||||
|
> `product_shape` - IfcProductDefinitionShape or IfcRepresentationMap\n
|
||||||
|
> `base_representation` - base representation to get context attributes from\n
|
||||||
|
> `items` - representation items\n
|
||||||
|
> `previous_shape_aspect` - (optional) previous shape aspect, if provided\n
|
||||||
|
items will be removed the previous shape aspect first\n
|
||||||
|
|
||||||
|
< IfcShapeAspect
|
||||||
|
"""
|
||||||
|
|
||||||
|
if previous_shape_aspect is not None:
|
||||||
|
cls.remove_representation_items_from_shape_aspect(items, previous_shape_aspect)
|
||||||
|
|
||||||
|
shape_aspect = tool.Ifc.get().createIfcShapeAspect(
|
||||||
|
PartOfProductDefinitionShape=product_shape, ShapeRepresentations=()
|
||||||
|
)
|
||||||
|
# keep IfcShapeAspect and IfcShapeRepresentation valid
|
||||||
|
rep = tool.Geometry.add_shape_aspect_representation(shape_aspect, base_representation)
|
||||||
|
rep.Items = items
|
||||||
|
|
||||||
|
return shape_aspect
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def remove_representation_items_from_shape_aspect(cls, representation_items, shape_aspect):
|
||||||
ifc_file = tool.Ifc.get()
|
ifc_file = tool.Ifc.get()
|
||||||
# as shape aspect might have multiple representations
|
# as shape aspect might have multiple representations
|
||||||
# it's easier to find it from the item
|
# it's easier to find it from the item
|
||||||
for inverse in ifc_file.get_inverse(representation_item):
|
for inverse in ifc_file.get_inverse(representation_items[0]):
|
||||||
if inverse.is_a("IfcShapeRepresentation") and shape_aspect in inverse.OfShapeAspect:
|
if inverse.is_a("IfcShapeRepresentation") and shape_aspect in inverse.OfShapeAspect:
|
||||||
representation = inverse
|
representation = inverse
|
||||||
break
|
break
|
||||||
|
|
||||||
# removing last item would make representation invalid
|
# removing last item would make representation invalid
|
||||||
if len(representation.Items) == 1:
|
if len(representation.Items) == len(representation_items):
|
||||||
# removing last representation would make shape aspect invalid.
|
# removing last representation would make shape aspect invalid.
|
||||||
# remove shape aspect first otherwise remove_representation won't remove it because of the inverse
|
# remove shape aspect first otherwise remove_representation won't remove it because of the inverse
|
||||||
if len(shape_aspect.ShapeRepresentations) == 1:
|
if len(shape_aspect.ShapeRepresentations) == 1:
|
||||||
ifc_file.remove(shape_aspect)
|
ifc_file.remove(shape_aspect)
|
||||||
tool.Ifc.run("geometry.remove_representation", representation=representation)
|
tool.Ifc.run("geometry.remove_representation", representation=representation)
|
||||||
else:
|
else:
|
||||||
items = set(representation.Items) - {representation_item}
|
items = set(representation.Items) - set(representation_items)
|
||||||
representation.Items = tuple(items)
|
representation.Items = tuple(items)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def add_representation_item_to_shape_aspect(cls, representation_item, shape_aspect):
|
def add_representation_item_to_shape_aspect(cls, representation_items, shape_aspect):
|
||||||
|
"""NOTE: we assume that all items belonged to the same representation and to the same shape aspect"""
|
||||||
ifc_file = tool.Ifc.get()
|
ifc_file = tool.Ifc.get()
|
||||||
previous_shape_aspect = None
|
previous_shape_aspect = None
|
||||||
for inverse in ifc_file.get_inverse(representation_item):
|
for inverse in ifc_file.get_inverse(representation_items[0]):
|
||||||
if inverse.is_a("IfcShapeRepresentation"):
|
if inverse.is_a("IfcShapeRepresentation"):
|
||||||
if inverse.OfShapeAspect:
|
if inverse.OfShapeAspect:
|
||||||
# item is already added to the shape aspect
|
# item is already added to the shape aspect
|
||||||
@@ -780,11 +806,11 @@ class Geometry(blenderbim.core.tool.Geometry):
|
|||||||
|
|
||||||
# remove item from previous shape aspect
|
# remove item from previous shape aspect
|
||||||
if previous_shape_aspect:
|
if previous_shape_aspect:
|
||||||
cls.remove_representation_item_from_shape_aspect(representation_item, previous_shape_aspect)
|
cls.remove_representation_items_from_shape_aspect(representation_items, previous_shape_aspect)
|
||||||
shape_aspect_representation = cls.get_shape_aspect_representation(
|
shape_aspect_representation = cls.get_shape_aspect_representation(
|
||||||
shape_aspect, base_representation, create_new=True
|
shape_aspect, base_representation, create_new=True
|
||||||
)
|
)
|
||||||
shape_aspect_representation.Items = shape_aspect_representation.Items + (representation_item,)
|
shape_aspect_representation.Items = shape_aspect_representation.Items + tuple(representation_items)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_shape_aspect_representation(cls, shape_aspect, base_representation, create_new=False):
|
def get_shape_aspect_representation(cls, shape_aspect, base_representation, create_new=False):
|
||||||
@@ -799,11 +825,15 @@ class Geometry(blenderbim.core.tool.Geometry):
|
|||||||
if not create_new:
|
if not create_new:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
return cls.add_shape_aspect_representation(shape_aspect, base_representation)
|
||||||
|
|
||||||
|
@classmethod
|
||||||
|
def add_shape_aspect_representation(cls, shape_aspect, base_representation):
|
||||||
shape_aspect_representation = tool.Ifc.get().createIfcShapeRepresentation(
|
shape_aspect_representation = tool.Ifc.get().createIfcShapeRepresentation(
|
||||||
ContextOfItems=base_representation.ContextOfItems,
|
ContextOfItems=base_representation.ContextOfItems,
|
||||||
RepresentationIdentifier=base_representation.RepresentationIdentifier,
|
RepresentationIdentifier=base_representation.RepresentationIdentifier,
|
||||||
RepresentationType=base_representation.RepresentationType,
|
RepresentationType=base_representation.RepresentationType,
|
||||||
)
|
)
|
||||||
shape_aspect.ShapeRepresentations = shape_aspect.ShapeRepresentations + (shape_aspect_representation,)
|
shape_aspect.ShapeRepresentations = shape_aspect.ShapeRepresentations + (shape_aspect_representation,)
|
||||||
|
|
||||||
return shape_aspect_representation
|
return shape_aspect_representation
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user