mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-26 18:21:59 +00:00
black .
This commit is contained in:
@@ -1295,6 +1295,7 @@ class IfcImporter:
|
|||||||
if element.is_a("IfcSpace"):
|
if element.is_a("IfcSpace"):
|
||||||
obj.hide_set(True)
|
obj.hide_set(True)
|
||||||
|
|
||||||
|
|
||||||
class IfcImportSettings:
|
class IfcImportSettings:
|
||||||
"""
|
"""
|
||||||
Initialize only using `IfcImportSettings.factory()`.
|
Initialize only using `IfcImportSettings.factory()`.
|
||||||
|
|||||||
@@ -158,6 +158,7 @@ def menu_func(self, context):
|
|||||||
if element and element.is_a("IfcAnnotation") and element.ObjectType in ["SECTION", "ELEVATION"]:
|
if element and element.is_a("IfcAnnotation") and element.ObjectType in ["SECTION", "ELEVATION"]:
|
||||||
self.layout.operator("bim.activate_drawing_by_annotation", text="Go to Drawing")
|
self.layout.operator("bim.activate_drawing_by_annotation", text="Go to Drawing")
|
||||||
|
|
||||||
|
|
||||||
def register():
|
def register():
|
||||||
if not bpy.app.background:
|
if not bpy.app.background:
|
||||||
bpy.utils.register_tool(workspace.AnnotationTool, after={"bim.bim_tool"}, separator=True, group=False)
|
bpy.utils.register_tool(workspace.AnnotationTool, after={"bim.bim_tool"}, separator=True, group=False)
|
||||||
|
|||||||
@@ -353,13 +353,13 @@ class CreateDrawing(bpy.types.Operator):
|
|||||||
|
|
||||||
# Clear any local camera setup and force viewport to use scene camera
|
# Clear any local camera setup and force viewport to use scene camera
|
||||||
for area in context.screen.areas:
|
for area in context.screen.areas:
|
||||||
if area.type == 'VIEW_3D':
|
if area.type == "VIEW_3D":
|
||||||
for space in area.spaces:
|
for space in area.spaces:
|
||||||
if space.type == 'VIEW_3D':
|
if space.type == "VIEW_3D":
|
||||||
# Clear local camera to ensure we use scene.camera
|
# Clear local camera to ensure we use scene.camera
|
||||||
space.use_local_camera = False
|
space.use_local_camera = False
|
||||||
space.camera = context.scene.camera
|
space.camera = context.scene.camera
|
||||||
space.region_3d.view_perspective = 'CAMERA'
|
space.region_3d.view_perspective = "CAMERA"
|
||||||
print(f"Set viewport camera to: {context.scene.camera.name}")
|
print(f"Set viewport camera to: {context.scene.camera.name}")
|
||||||
break
|
break
|
||||||
|
|
||||||
@@ -3080,7 +3080,7 @@ class AddReference(bpy.types.Operator, tool.Ifc.Operator, ImportHelper):
|
|||||||
filename_ext = ".svg"
|
filename_ext = ".svg"
|
||||||
|
|
||||||
files: bpy.props.CollectionProperty(type=bpy.types.OperatorFileListElement)
|
files: bpy.props.CollectionProperty(type=bpy.types.OperatorFileListElement)
|
||||||
directory: bpy.props.StringProperty(subtype='DIR_PATH')
|
directory: bpy.props.StringProperty(subtype="DIR_PATH")
|
||||||
|
|
||||||
def _execute(self, context):
|
def _execute(self, context):
|
||||||
# Handle both single and multiple file selection
|
# Handle both single and multiple file selection
|
||||||
@@ -4307,7 +4307,6 @@ class ActivateDrawingByAnnotation(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
# Found the drawing element!
|
# Found the drawing element!
|
||||||
return rel.RelatingProduct
|
return rel.RelatingProduct
|
||||||
|
|
||||||
|
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
||||||
@@ -5260,10 +5259,7 @@ class FormatElementValueRow(bpy.types.Operator):
|
|||||||
|
|
||||||
custom_expression: bpy.props.StringProperty(
|
custom_expression: bpy.props.StringProperty(
|
||||||
name="Custom Expression",
|
name="Custom Expression",
|
||||||
description=(
|
description=("Custom expression using functions\n" "Use {{value}} as placeholder for the current row's value."),
|
||||||
"Custom expression using functions\n"
|
|
||||||
"Use {{value}} as placeholder for the current row's value."
|
|
||||||
),
|
|
||||||
default='concat({{value}}, " - additional text")',
|
default='concat({{value}}, " - additional text")',
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -5470,7 +5466,7 @@ class ApplyElementValueRowsToLiteral(bpy.types.Operator):
|
|||||||
"""
|
"""
|
||||||
import re
|
import re
|
||||||
|
|
||||||
pattern = r'\{\{[^}]+\}\}'
|
pattern = r"\{\{[^}]+\}\}"
|
||||||
|
|
||||||
new_base_value = f"{{{{{new_element_key}}}}}"
|
new_base_value = f"{{{{{new_element_key}}}}}"
|
||||||
updated_value = re.sub(pattern, new_base_value, old_formatted_value)
|
updated_value = re.sub(pattern, new_base_value, old_formatted_value)
|
||||||
|
|||||||
@@ -714,7 +714,9 @@ class ElementValueRow(PropertyGroup):
|
|||||||
)
|
)
|
||||||
|
|
||||||
element_key: StringProperty(
|
element_key: StringProperty(
|
||||||
name="Element Key", description="The element value key (e.g., 'id', 'Name', 'Pset_WallCommon.Reference')", default=""
|
name="Element Key",
|
||||||
|
description="The element value key (e.g., 'id', 'Name', 'Pset_WallCommon.Reference')",
|
||||||
|
default="",
|
||||||
)
|
)
|
||||||
|
|
||||||
formatted_value: StringProperty(
|
formatted_value: StringProperty(
|
||||||
@@ -764,7 +766,7 @@ def get_category_items_with_counts(self, context):
|
|||||||
element = tool.Ifc.get_entity(obj)
|
element = tool.Ifc.get_entity(obj)
|
||||||
text_element = element
|
text_element = element
|
||||||
|
|
||||||
if hasattr(self, 'product_used'):
|
if hasattr(self, "product_used"):
|
||||||
if self.product_used:
|
if self.product_used:
|
||||||
element = tool.Ifc.get_entity(self.product_used)
|
element = tool.Ifc.get_entity(self.product_used)
|
||||||
else:
|
else:
|
||||||
@@ -845,14 +847,14 @@ class LiteralProps(PropertyGroup):
|
|||||||
element_value_rows: CollectionProperty(
|
element_value_rows: CollectionProperty(
|
||||||
name="Element Value Rows",
|
name="Element Value Rows",
|
||||||
type=ElementValueRow,
|
type=ElementValueRow,
|
||||||
description="Collection of element value rows for building the literal value"
|
description="Collection of element value rows for building the literal value",
|
||||||
)
|
)
|
||||||
|
|
||||||
category_for_adding: EnumProperty(
|
category_for_adding: EnumProperty(
|
||||||
name="Category for Adding",
|
name="Category for Adding",
|
||||||
items=get_category_items_with_counts,
|
items=get_category_items_with_counts,
|
||||||
default=0,
|
default=0,
|
||||||
description="Category to use when adding a new element value row"
|
description="Category to use when adding a new element value row",
|
||||||
)
|
)
|
||||||
|
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
|
|||||||
@@ -115,9 +115,13 @@ def parse_markdown_it(text: str) -> list[dict[str, Union[str, None]]]:
|
|||||||
if tokens[j].type == "inline":
|
if tokens[j].type == "inline":
|
||||||
for child in tokens[j].children or []:
|
for child in tokens[j].children or []:
|
||||||
if child.type == "softbreak":
|
if child.type == "softbreak":
|
||||||
segments.append({"text": None, "url": None, "break": True, "bold": False, "italic": False})
|
segments.append(
|
||||||
|
{"text": None, "url": None, "break": True, "bold": False, "italic": False}
|
||||||
|
)
|
||||||
elif child.type == "html_inline" and child.content.strip().lower() == "<br>":
|
elif child.type == "html_inline" and child.content.strip().lower() == "<br>":
|
||||||
segments.append({"text": None, "url": None, "break": True, "bold": False, "italic": False})
|
segments.append(
|
||||||
|
{"text": None, "url": None, "break": True, "bold": False, "italic": False}
|
||||||
|
)
|
||||||
elif child.type == "strong_open":
|
elif child.type == "strong_open":
|
||||||
bold = True
|
bold = True
|
||||||
elif child.type == "strong_close":
|
elif child.type == "strong_close":
|
||||||
@@ -133,11 +137,27 @@ def parse_markdown_it(text: str) -> list[dict[str, Union[str, None]]]:
|
|||||||
elif child.type == "link_close" and link_opening:
|
elif child.type == "link_close" and link_opening:
|
||||||
url = link_opening.attrGet("href")
|
url = link_opening.attrGet("href")
|
||||||
if url and link_text:
|
if url and link_text:
|
||||||
segments.append({"text": link_text, "url": url, "break": False, "bold": bold, "italic": italic})
|
segments.append(
|
||||||
|
{
|
||||||
|
"text": link_text,
|
||||||
|
"url": url,
|
||||||
|
"break": False,
|
||||||
|
"bold": bold,
|
||||||
|
"italic": italic,
|
||||||
|
}
|
||||||
|
)
|
||||||
link_opening = None
|
link_opening = None
|
||||||
link_text = None
|
link_text = None
|
||||||
elif child.type == "text" and not link_opening:
|
elif child.type == "text" and not link_opening:
|
||||||
segments.append({"text": child.content, "url": None, "break": False, "bold": bold, "italic": italic})
|
segments.append(
|
||||||
|
{
|
||||||
|
"text": child.content,
|
||||||
|
"url": None,
|
||||||
|
"break": False,
|
||||||
|
"bold": bold,
|
||||||
|
"italic": italic,
|
||||||
|
}
|
||||||
|
)
|
||||||
j += 1
|
j += 1
|
||||||
i = j
|
i = j
|
||||||
else:
|
else:
|
||||||
@@ -168,7 +188,9 @@ def parse_markdown_it(text: str) -> list[dict[str, Union[str, None]]]:
|
|||||||
link_opening = None
|
link_opening = None
|
||||||
link_text = None
|
link_text = None
|
||||||
elif child.type == "text" and not link_opening:
|
elif child.type == "text" and not link_opening:
|
||||||
segments.append({"text": child.content, "url": None, "break": False, "bold": bold, "italic": italic})
|
segments.append(
|
||||||
|
{"text": child.content, "url": None, "break": False, "bold": bold, "italic": italic}
|
||||||
|
)
|
||||||
i += 1
|
i += 1
|
||||||
segments = [seg for seg in segments if seg.get("text") is not None or seg.get("break", False)]
|
segments = [seg for seg in segments if seg.get("text") is not None or seg.get("break", False)]
|
||||||
if not segments:
|
if not segments:
|
||||||
@@ -260,7 +282,7 @@ class SvgWriter:
|
|||||||
paths = self.resource_paths["Stylesheet"]
|
paths = self.resource_paths["Stylesheet"]
|
||||||
if not paths:
|
if not paths:
|
||||||
return
|
return
|
||||||
path_list = [p.strip() for p in paths.split(',')]
|
path_list = [p.strip() for p in paths.split(",")]
|
||||||
for path in path_list:
|
for path in path_list:
|
||||||
if not os.path.exists(path):
|
if not os.path.exists(path):
|
||||||
print(f"WARNING. Couldn't find stylesheet for the drawing by the path: {path}")
|
print(f"WARNING. Couldn't find stylesheet for the drawing by the path: {path}")
|
||||||
|
|||||||
@@ -476,7 +476,6 @@ class BIM_PT_sheets(Panel):
|
|||||||
|
|
||||||
op = row3.operator("bim.activate_drawing_from_sheet", icon="OUTLINER_OB_CAMERA", text="")
|
op = row3.operator("bim.activate_drawing_from_sheet", icon="OUTLINER_OB_CAMERA", text="")
|
||||||
|
|
||||||
|
|
||||||
if active_sheet.reference_type == "DRAWING":
|
if active_sheet.reference_type == "DRAWING":
|
||||||
drawingnamesvg = active_sheet.name
|
drawingnamesvg = active_sheet.name
|
||||||
drawingname = drawingnamesvg.split(".svg")[0]
|
drawingname = drawingnamesvg.split(".svg")[0]
|
||||||
@@ -712,7 +711,9 @@ class BIM_PT_text(Panel):
|
|||||||
|
|
||||||
current_product = get_current_product_for_element_values(obj, literal_props)
|
current_product = get_current_product_for_element_values(obj, literal_props)
|
||||||
|
|
||||||
product_name = current_product.name if (current_product and hasattr(current_product, "name")) else "Unknown"
|
product_name = (
|
||||||
|
current_product.name if (current_product and hasattr(current_product, "name")) else "Unknown"
|
||||||
|
)
|
||||||
source_row = values_box.row()
|
source_row = values_box.row()
|
||||||
source_row.label(text=f"Source: {product_name}", icon="OBJECT_DATA")
|
source_row.label(text=f"Source: {product_name}", icon="OBJECT_DATA")
|
||||||
|
|
||||||
@@ -758,7 +759,9 @@ class BIM_PT_text(Panel):
|
|||||||
|
|
||||||
apply_row = values_box.row()
|
apply_row = values_box.row()
|
||||||
apply_row.scale_y = 1.2
|
apply_row.scale_y = 1.2
|
||||||
op = apply_row.operator("bim.apply_element_value_rows_to_literal", text="Apply to Literal", icon="CHECKMARK")
|
op = apply_row.operator(
|
||||||
|
"bim.apply_element_value_rows_to_literal", text="Apply to Literal", icon="CHECKMARK"
|
||||||
|
)
|
||||||
op.literal_prop_id = i
|
op.literal_prop_id = i
|
||||||
else:
|
else:
|
||||||
error_row = values_box.row()
|
error_row = values_box.row()
|
||||||
|
|||||||
@@ -1274,7 +1274,7 @@ class OverrideDuplicateMove(bpy.types.Operator):
|
|||||||
all_objects_to_select.add(part_obj)
|
all_objects_to_select.add(part_obj)
|
||||||
|
|
||||||
# Deselect everything first
|
# Deselect everything first
|
||||||
bpy.ops.object.select_all(action='DESELECT')
|
bpy.ops.object.select_all(action="DESELECT")
|
||||||
|
|
||||||
# Select all the duplicated objects
|
# Select all the duplicated objects
|
||||||
for obj in all_objects_to_select:
|
for obj in all_objects_to_select:
|
||||||
@@ -1666,11 +1666,13 @@ class RefreshLinkedAggregate(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
|
|
||||||
# Get the new group
|
# Get the new group
|
||||||
new_group_entity = next(
|
new_group_entity = next(
|
||||||
(r.RelatingGroup
|
(
|
||||||
for r in getattr(aggregate, "HasAssignments", []) or []
|
r.RelatingGroup
|
||||||
if r.is_a("IfcRelAssignsToGroup")
|
for r in getattr(aggregate, "HasAssignments", []) or []
|
||||||
if self.group_name in r.RelatingGroup.Name),
|
if r.is_a("IfcRelAssignsToGroup")
|
||||||
None
|
if self.group_name in r.RelatingGroup.Name
|
||||||
|
),
|
||||||
|
None,
|
||||||
)
|
)
|
||||||
|
|
||||||
if not new_group_entity:
|
if not new_group_entity:
|
||||||
|
|||||||
@@ -246,7 +246,7 @@ class BIM_PT_object_material(Panel):
|
|||||||
"layer": "Material Layers",
|
"layer": "Material Layers",
|
||||||
"profile": "Material Profiles",
|
"profile": "Material Profiles",
|
||||||
"constituent": "Material Constituents",
|
"constituent": "Material Constituents",
|
||||||
"list_item": "Material List Items"
|
"list_item": "Material List Items",
|
||||||
}
|
}
|
||||||
header_text = header_map.get(set_item_name, "Material Items")
|
header_text = header_map.get(set_item_name, "Material Items")
|
||||||
self.layout.label(text=header_text)
|
self.layout.label(text=header_text)
|
||||||
@@ -395,6 +395,7 @@ class BIM_PT_object_material(Panel):
|
|||||||
if unit_system == "IMPERIAL":
|
if unit_system == "IMPERIAL":
|
||||||
precision = prefs.doc.imperial_precision
|
precision = prefs.doc.imperial_precision
|
||||||
from bonsai.bim.module.drawing.helper import format_distance
|
from bonsai.bim.module.drawing.helper import format_distance
|
||||||
|
|
||||||
formatted_offset = format_distance(
|
formatted_offset = format_distance(
|
||||||
offset_value, precision=precision, suppress_zero_inches=True, in_unit_length=True
|
offset_value, precision=precision, suppress_zero_inches=True, in_unit_length=True
|
||||||
)
|
)
|
||||||
@@ -416,8 +417,9 @@ class BIM_PT_object_material(Panel):
|
|||||||
if unit_system == "IMPERIAL":
|
if unit_system == "IMPERIAL":
|
||||||
precision = prefs.doc.imperial_precision
|
precision = prefs.doc.imperial_precision
|
||||||
from bonsai.bim.module.drawing.helper import format_distance
|
from bonsai.bim.module.drawing.helper import format_distance
|
||||||
|
|
||||||
formatted_custom_offset = format_distance(
|
formatted_custom_offset = format_distance(
|
||||||
pset_data['custom_offset'], precision=precision, suppress_zero_inches=True, in_unit_length=True
|
pset_data["custom_offset"], precision=precision, suppress_zero_inches=True, in_unit_length=True
|
||||||
)
|
)
|
||||||
box_row = box.row(align=True)
|
box_row = box.row(align=True)
|
||||||
box_row.label(text="Custom Offset")
|
box_row.label(text="Custom Offset")
|
||||||
@@ -436,7 +438,7 @@ class BIM_PT_object_material(Panel):
|
|||||||
"layer": "Material Layers",
|
"layer": "Material Layers",
|
||||||
"profile": "Material Profiles",
|
"profile": "Material Profiles",
|
||||||
"constituent": "Material Constituents",
|
"constituent": "Material Constituents",
|
||||||
"list_item": "Material List Items"
|
"list_item": "Material List Items",
|
||||||
}
|
}
|
||||||
header_text = header_map.get(set_item_name, "Material Items")
|
header_text = header_map.get(set_item_name, "Material Items")
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -191,19 +191,19 @@ class FilledOpeningGenerator:
|
|||||||
MappingSource=existing_mapping_source,
|
MappingSource=existing_mapping_source,
|
||||||
MappingTarget=tool.Ifc.get().create_entity(
|
MappingTarget=tool.Ifc.get().create_entity(
|
||||||
"IfcCartesianTransformationOperator3D",
|
"IfcCartesianTransformationOperator3D",
|
||||||
Axis1=tool.Ifc.get().create_entity("IfcDirection", DirectionRatios=(1., 0., 0.)),
|
Axis1=tool.Ifc.get().create_entity("IfcDirection", DirectionRatios=(1.0, 0.0, 0.0)),
|
||||||
Axis2=tool.Ifc.get().create_entity("IfcDirection", DirectionRatios=(0., 1., 0.)),
|
Axis2=tool.Ifc.get().create_entity("IfcDirection", DirectionRatios=(0.0, 1.0, 0.0)),
|
||||||
LocalOrigin=tool.Ifc.get().create_entity("IfcCartesianPoint", Coordinates=(0., 0., 0.)),
|
LocalOrigin=tool.Ifc.get().create_entity("IfcCartesianPoint", Coordinates=(0.0, 0.0, 0.0)),
|
||||||
Scale=1.,
|
Scale=1.0,
|
||||||
Axis3=tool.Ifc.get().create_entity("IfcDirection", DirectionRatios=(0., 0., 1.))
|
Axis3=tool.Ifc.get().create_entity("IfcDirection", DirectionRatios=(0.0, 0.0, 1.0)),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
mapped_representation = tool.Ifc.get().create_entity(
|
mapped_representation = tool.Ifc.get().create_entity(
|
||||||
"IfcShapeRepresentation",
|
"IfcShapeRepresentation",
|
||||||
ContextOfItems=context,
|
ContextOfItems=context,
|
||||||
RepresentationIdentifier="Body",
|
RepresentationIdentifier="Body",
|
||||||
RepresentationType="MappedRepresentation",
|
RepresentationType="MappedRepresentation",
|
||||||
Items=[new_mapped_item]
|
Items=[new_mapped_item],
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
mapped_representation = ifcopenshell.api.geometry.map_representation(
|
mapped_representation = ifcopenshell.api.geometry.map_representation(
|
||||||
@@ -333,19 +333,19 @@ class FilledOpeningGenerator:
|
|||||||
MappingSource=existing_mapping_source,
|
MappingSource=existing_mapping_source,
|
||||||
MappingTarget=tool.Ifc.get().create_entity(
|
MappingTarget=tool.Ifc.get().create_entity(
|
||||||
"IfcCartesianTransformationOperator3D",
|
"IfcCartesianTransformationOperator3D",
|
||||||
Axis1=tool.Ifc.get().create_entity("IfcDirection", DirectionRatios=(1., 0., 0.)),
|
Axis1=tool.Ifc.get().create_entity("IfcDirection", DirectionRatios=(1.0, 0.0, 0.0)),
|
||||||
Axis2=tool.Ifc.get().create_entity("IfcDirection", DirectionRatios=(0., 1., 0.)),
|
Axis2=tool.Ifc.get().create_entity("IfcDirection", DirectionRatios=(0.0, 1.0, 0.0)),
|
||||||
LocalOrigin=tool.Ifc.get().create_entity("IfcCartesianPoint", Coordinates=(0., 0., 0.)),
|
LocalOrigin=tool.Ifc.get().create_entity("IfcCartesianPoint", Coordinates=(0.0, 0.0, 0.0)),
|
||||||
Scale=1.,
|
Scale=1.0,
|
||||||
Axis3=tool.Ifc.get().create_entity("IfcDirection", DirectionRatios=(0., 0., 1.))
|
Axis3=tool.Ifc.get().create_entity("IfcDirection", DirectionRatios=(0.0, 0.0, 1.0)),
|
||||||
)
|
),
|
||||||
)
|
)
|
||||||
mapped_representation = tool.Ifc.get().create_entity(
|
mapped_representation = tool.Ifc.get().create_entity(
|
||||||
"IfcShapeRepresentation",
|
"IfcShapeRepresentation",
|
||||||
ContextOfItems=context,
|
ContextOfItems=context,
|
||||||
RepresentationIdentifier="Body",
|
RepresentationIdentifier="Body",
|
||||||
RepresentationType="MappedRepresentation",
|
RepresentationType="MappedRepresentation",
|
||||||
Items=[new_mapped_item]
|
Items=[new_mapped_item],
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
mapped_representation = ifcopenshell.api.geometry.map_representation(
|
mapped_representation = ifcopenshell.api.geometry.map_representation(
|
||||||
|
|||||||
@@ -397,10 +397,9 @@ class DumbSlabPlaner:
|
|||||||
representation=representation,
|
representation=representation,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
def update_extrusion_direction(
|
||||||
def update_extrusion_direction(element: ifcopenshell.entity_instance,
|
element: ifcopenshell.entity_instance, new_direction_ratios: tuple, obj: bpy.types.Object = None
|
||||||
new_direction_ratios: tuple,
|
) -> None:
|
||||||
obj: bpy.types.Object = None) -> None:
|
|
||||||
"""
|
"""
|
||||||
Update extrusion direction while preserving overall object orientation.
|
Update extrusion direction while preserving overall object orientation.
|
||||||
|
|
||||||
@@ -824,7 +823,7 @@ class EnableEditingExtrusionProfile(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
tool.Model.import_profile(extrusion.SweptArea, obj=obj, position=position, x_angle=0)
|
tool.Model.import_profile(extrusion.SweptArea, obj=obj, position=position, x_angle=0)
|
||||||
|
|
||||||
# Scale the Y coordinates by cos(rotation) to get horizontal projection
|
# Scale the Y coordinates by cos(rotation) to get horizontal projection
|
||||||
bpy.ops.object.mode_set(mode='OBJECT')
|
bpy.ops.object.mode_set(mode="OBJECT")
|
||||||
for vert in obj.data.vertices:
|
for vert in obj.data.vertices:
|
||||||
vert.co.y *= scale_factor
|
vert.co.y *= scale_factor
|
||||||
else:
|
else:
|
||||||
@@ -905,6 +904,7 @@ class EditExtrusionProfile(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
profile = tool.Model.export_profile(obj, position=position, x_angle=existing_x_angle)
|
profile = tool.Model.export_profile(obj, position=position, x_angle=existing_x_angle)
|
||||||
|
|
||||||
if not profile:
|
if not profile:
|
||||||
|
|
||||||
def msg(self, context):
|
def msg(self, context):
|
||||||
self.layout.label(text="INVALID PROFILE")
|
self.layout.label(text="INVALID PROFILE")
|
||||||
|
|
||||||
@@ -953,7 +953,6 @@ class EditExtrusionProfile(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
tool.Ifc.get(), product=element, representation=new_footprint
|
tool.Ifc.get(), product=element, representation=new_footprint
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
footprint_context = ifcopenshell.util.representation.get_context(
|
footprint_context = ifcopenshell.util.representation.get_context(
|
||||||
tool.Ifc.get(), "Plan", "FootPrint", "SKETCH_VIEW"
|
tool.Ifc.get(), "Plan", "FootPrint", "SKETCH_VIEW"
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -514,8 +514,12 @@ class ChangeExtrusionXAngle(bpy.types.Operator, tool.Ifc.Operator):
|
|||||||
if tool.Model.get_usage_type(element) == "LAYER3":
|
if tool.Model.get_usage_type(element) == "LAYER3":
|
||||||
# For slabs, handle polyline scaling
|
# For slabs, handle polyline scaling
|
||||||
existing_obj_x_angle = obj.rotation_euler.x
|
existing_obj_x_angle = obj.rotation_euler.x
|
||||||
existing_obj_x_angle = 0 if tool.Cad.is_x(existing_obj_x_angle, 0, tolerance=0.001) else existing_obj_x_angle
|
existing_obj_x_angle = (
|
||||||
existing_obj_x_angle = 0 if tool.Cad.is_x(existing_obj_x_angle, pi, tolerance=0.001) else existing_obj_x_angle
|
0 if tool.Cad.is_x(existing_obj_x_angle, 0, tolerance=0.001) else existing_obj_x_angle
|
||||||
|
)
|
||||||
|
existing_obj_x_angle = (
|
||||||
|
0 if tool.Cad.is_x(existing_obj_x_angle, pi, tolerance=0.001) else existing_obj_x_angle
|
||||||
|
)
|
||||||
|
|
||||||
# Scale the polyline coordinates
|
# Scale the polyline coordinates
|
||||||
coord_list = builder.get_polyline_coords(extrusion.SweptArea.OuterCurve)
|
coord_list = builder.get_polyline_coords(extrusion.SweptArea.OuterCurve)
|
||||||
|
|||||||
@@ -3165,6 +3165,7 @@ class ImageScalingTool(bpy.types.Operator, PolylineOperator):
|
|||||||
|
|
||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
class LoadBlendMetadataAndIFC(bpy.types.Operator):
|
class LoadBlendMetadataAndIFC(bpy.types.Operator):
|
||||||
bl_idname = "bim.load_blend_metadata_and_ifc"
|
bl_idname = "bim.load_blend_metadata_and_ifc"
|
||||||
bl_label = "Load Blend Metadata and IFC"
|
bl_label = "Load Blend Metadata and IFC"
|
||||||
|
|||||||
@@ -364,8 +364,6 @@ bpy.ops.wm.save_as_mainfile(filepath=r'{blendmetadata_path}')
|
|||||||
return {"FINISHED"}
|
return {"FINISHED"}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
# TODO: Unused operator.
|
# TODO: Unused operator.
|
||||||
# Is there a need for this or 'DIR_PATH' propety subtype does almost the same,
|
# Is there a need for this or 'DIR_PATH' propety subtype does almost the same,
|
||||||
# but also has alt+click?
|
# but also has alt+click?
|
||||||
|
|||||||
@@ -74,7 +74,7 @@ def _has_material_styles(ifc: type[tool.Ifc], element: ifcopenshell.entity_insta
|
|||||||
|
|
||||||
# Check if any of the constituent materials have styles
|
# Check if any of the constituent materials have styles
|
||||||
for material in materials:
|
for material in materials:
|
||||||
if hasattr(material, 'HasRepresentation') and material.HasRepresentation:
|
if hasattr(material, "HasRepresentation") and material.HasRepresentation:
|
||||||
return True
|
return True
|
||||||
|
|
||||||
return False
|
return False
|
||||||
|
|||||||
@@ -34,7 +34,6 @@ def assign_type(
|
|||||||
type: ifcopenshell.entity_instance,
|
type: ifcopenshell.entity_instance,
|
||||||
) -> None:
|
) -> None:
|
||||||
|
|
||||||
|
|
||||||
# Get the instance's current CardinalPoint before type assignment
|
# Get the instance's current CardinalPoint before type assignment
|
||||||
instance_cardinal_point = None
|
instance_cardinal_point = None
|
||||||
instance_material = ifcopenshell.util.element.get_material(element)
|
instance_material = ifcopenshell.util.element.get_material(element)
|
||||||
@@ -54,6 +53,7 @@ def assign_type(
|
|||||||
|
|
||||||
# Force representation regeneration
|
# Force representation regeneration
|
||||||
from bonsai.bim.module.model.profile import DumbProfileRecalculator
|
from bonsai.bim.module.model.profile import DumbProfileRecalculator
|
||||||
|
|
||||||
DumbProfileRecalculator().recalculate([obj])
|
DumbProfileRecalculator().recalculate([obj])
|
||||||
# for now, representation regeneration handled by API listeners
|
# for now, representation regeneration handled by API listeners
|
||||||
else:
|
else:
|
||||||
|
|||||||
@@ -386,10 +386,7 @@ class Blender(bonsai.core.tool.Blender):
|
|||||||
# Add window if screen differs from current context
|
# Add window if screen differs from current context
|
||||||
context = bpy.context
|
context = bpy.context
|
||||||
if context and context.screen != screen:
|
if context and context.screen != screen:
|
||||||
window = next(
|
window = next((w for w in context.window_manager.windows if w.screen == screen), None)
|
||||||
(w for w in context.window_manager.windows if w.screen == screen),
|
|
||||||
None
|
|
||||||
)
|
|
||||||
if window:
|
if window:
|
||||||
context_override["window"] = window
|
context_override["window"] = window
|
||||||
|
|
||||||
|
|||||||
@@ -620,7 +620,6 @@ class Model(bonsai.core.tool.Model):
|
|||||||
if not openings[i].obj:
|
if not openings[i].obj:
|
||||||
openings.remove(i)
|
openings.remove(i)
|
||||||
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def save_custom_offset_to_pset(cls, element: ifcopenshell.entity_instance, obj: bpy.types.Object) -> None:
|
def save_custom_offset_to_pset(cls, element: ifcopenshell.entity_instance, obj: bpy.types.Object) -> None:
|
||||||
"""Save custom offset settings to BBIM_MaterialLayer pset."""
|
"""Save custom offset settings to BBIM_MaterialLayer pset."""
|
||||||
@@ -718,7 +717,9 @@ class Model(bonsai.core.tool.Model):
|
|||||||
)
|
)
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def get_material_layer_custom_offset(cls, element: ifcopenshell.entity_instance, obj: bpy.types.Object) -> Optional[float]:
|
def get_material_layer_custom_offset(
|
||||||
|
cls, element: ifcopenshell.entity_instance, obj: bpy.types.Object
|
||||||
|
) -> Optional[float]:
|
||||||
"""Get custom offset value, reading from pset if props are not set."""
|
"""Get custom offset value, reading from pset if props are not set."""
|
||||||
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
unit_scale = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||||
layer_params = tool.Model.get_material_layer_parameters(element)
|
layer_params = tool.Model.get_material_layer_parameters(element)
|
||||||
|
|||||||
@@ -533,21 +533,29 @@ class Project(bonsai.core.tool.Project):
|
|||||||
doc = tool.Ifc.run("document.add_information", parent=None)
|
doc = tool.Ifc.run("document.add_information", parent=None)
|
||||||
|
|
||||||
if ifc_file.schema == "IFC2X3":
|
if ifc_file.schema == "IFC2X3":
|
||||||
tool.Ifc.run("document.edit_information", information=doc, attributes={
|
tool.Ifc.run(
|
||||||
"DocumentId": "BLEND_METADATA",
|
"document.edit_information",
|
||||||
"Name": "Blend Metadata",
|
information=doc,
|
||||||
"Scope": "BLEND_METADATA",
|
attributes={
|
||||||
"Description": "References to blend metadata file for this IFC project",
|
"DocumentId": "BLEND_METADATA",
|
||||||
"Location": metadata_filename
|
"Name": "Blend Metadata",
|
||||||
})
|
"Scope": "BLEND_METADATA",
|
||||||
|
"Description": "References to blend metadata file for this IFC project",
|
||||||
|
"Location": metadata_filename,
|
||||||
|
},
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
tool.Ifc.run("document.edit_information", information=doc, attributes={
|
tool.Ifc.run(
|
||||||
"Identification": "BLEND_METADATA",
|
"document.edit_information",
|
||||||
"Name": "Blend Metadata",
|
information=doc,
|
||||||
"Scope": "BLEND_METADATA",
|
attributes={
|
||||||
"Description": "References to blend metadata file for this IFC project",
|
"Identification": "BLEND_METADATA",
|
||||||
"Location": metadata_filename
|
"Name": "Blend Metadata",
|
||||||
})
|
"Scope": "BLEND_METADATA",
|
||||||
|
"Description": "References to blend metadata file for this IFC project",
|
||||||
|
"Location": metadata_filename,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
|
||||||
return doc
|
return doc
|
||||||
|
|
||||||
@@ -561,9 +569,7 @@ class Project(bonsai.core.tool.Project):
|
|||||||
if not ifc_file:
|
if not ifc_file:
|
||||||
return
|
return
|
||||||
|
|
||||||
tool.Ifc.run("document.edit_information", information=doc, attributes={
|
tool.Ifc.run("document.edit_information", information=doc, attributes={"Location": metadata_filename})
|
||||||
"Location": metadata_filename
|
|
||||||
})
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def remove_metadata_document_information(cls) -> None:
|
def remove_metadata_document_information(cls) -> None:
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
|
|
||||||
import bonsai, json, bpy
|
import bonsai, json, bpy
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
@@ -11,14 +10,15 @@ settings_path = repo_root / ".vscode" / "settings.json"
|
|||||||
settings_path.parent.mkdir(parents=True, exist_ok=True)
|
settings_path.parent.mkdir(parents=True, exist_ok=True)
|
||||||
|
|
||||||
settings = json.loads(settings_path.read_text()) if settings_path.exists() else {}
|
settings = json.loads(settings_path.read_text()) if settings_path.exists() else {}
|
||||||
settings.update({
|
settings.update(
|
||||||
"bonsai.localRoot": repo_path.as_posix(),
|
{
|
||||||
"bonsai.remoteRoot": install_path.as_posix(),
|
"bonsai.localRoot": repo_path.as_posix(),
|
||||||
"bonsai.blenderPath": Path(bpy.app.binary_path).parent.as_posix(),
|
"bonsai.remoteRoot": install_path.as_posix(),
|
||||||
})
|
"bonsai.blenderPath": Path(bpy.app.binary_path).parent.as_posix(),
|
||||||
|
}
|
||||||
|
)
|
||||||
json_data = json.dumps(settings, indent=2)
|
json_data = json.dumps(settings, indent=2)
|
||||||
|
|
||||||
settings_path.write_text(json_data)
|
settings_path.write_text(json_data)
|
||||||
|
|
||||||
print("\n\nBonsai/VSCode development environment configured successfully!\n\n")
|
print("\n\nBonsai/VSCode development environment configured successfully!\n\n")
|
||||||
|
|
||||||
|
|||||||
@@ -107,10 +107,7 @@ class Usecase:
|
|||||||
for p in self.polyline
|
for p in self.polyline
|
||||||
]
|
]
|
||||||
else:
|
else:
|
||||||
points = [
|
points = [(self.convert_si_to_unit(p[0]), self.convert_si_to_unit(p[1])) for p in self.polyline]
|
||||||
(self.convert_si_to_unit(p[0]), self.convert_si_to_unit(p[1]))
|
|
||||||
for p in self.polyline
|
|
||||||
]
|
|
||||||
|
|
||||||
if self.file.schema == "IFC2X3":
|
if self.file.schema == "IFC2X3":
|
||||||
curve = self.file.createIfcPolyline([self.file.createIfcCartesianPoint(p) for p in points])
|
curve = self.file.createIfcPolyline([self.file.createIfcCartesianPoint(p) for p in points])
|
||||||
|
|||||||
Reference in New Issue
Block a user