mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-08-08 17:01:40 +00:00
Compare commits
28 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 0f835ca739 | |||
| 87442f549f | |||
| bf27e41275 | |||
| 66cf06c990 | |||
| 5757a62b6f | |||
| e2552e3d46 | |||
| 1b91540c96 | |||
| 274b12e5a0 | |||
| 496ba6f22d | |||
| b7737cb6d3 | |||
| 55026ca996 | |||
| 3fa573e3c1 | |||
| 00ae6809a9 | |||
| c3fbb11093 | |||
| a0d27c3f1c | |||
| 811a908cc3 | |||
| 94e5baf48a | |||
| cd2570cdbb | |||
| 6df6553935 | |||
| 8e6c372a4f | |||
| 371e11de9b | |||
| d2a708fcc4 | |||
| 845d772a08 | |||
| 1e630ede08 | |||
| c50d1ea2fe | |||
| e7eb00eaa3 | |||
| cd6eac3c8f | |||
| 69e21da60c |
@@ -5,7 +5,7 @@ FILE_NAME('EPset_Drawing.ifc','2020-01-01T00:00:00',(),(),'EPset_Drawing','EPset
|
||||
FILE_SCHEMA(('IFC4'));
|
||||
ENDSEC;
|
||||
DATA;
|
||||
#1=IFCPROPERTYSETTEMPLATE('2JhNIvqZrFnAgxfhK0XVQX',$,'EPset_Drawing','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation',(#2,#3,#4,#5,#6,#7,#8,#9,#10,#11,#12,#13,#14,#15,#16,#17,#18,#19,#20,#21,#22,#23));
|
||||
#1=IFCPROPERTYSETTEMPLATE('2JhNIvqZrFnAgxfhK0XVQX',$,'EPset_Drawing','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation/DRAWING',(#2,#3,#4,#5,#6,#7,#8,#9,#10,#11,#12,#13,#14,#15,#16,#17,#18,#19,#20,#21,#22,#23));
|
||||
#2=IFCSIMPLEPROPERTYTEMPLATE('23JavTMk98ZxXhrUEnjAcf',$,'TargetView','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#3=IFCSIMPLEPROPERTYTEMPLATE('1yVWUt5H9DAOuu0OaMMLpe',$,'Scale','The scale of this drawing represented as a numerator and denominator, such as 1/100',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#4=IFCSIMPLEPROPERTYTEMPLATE('3gsuPBtU93b8f0gg1pjkq6',$,'HumanScale','The scale of this drawing in human readable format, such as 1:100',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
|
||||
@@ -5,20 +5,20 @@ FILE_NAME('Psets_BBIM_Annotation.ifc','2020-01-01T00:00:00',(),(),'Psets_BBIM_An
|
||||
FILE_SCHEMA(('IFC4'));
|
||||
ENDSEC;
|
||||
DATA;
|
||||
#1=IFCPROPERTYSETTEMPLATE('3VuPUwdCD2Qx3XDDRs0R1N',$,'EPset_Annotation','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation,IfcTypeProduct',(#2,#3,#4));
|
||||
#1=IFCPROPERTYSETTEMPLATE('3VuPUwdCD2Qx3XDDRs0R1N',$,'EPset_Annotation','',.PSET_TYPEDRIVENOVERRIDE.,'IfcAnnotation,IfcTypeProduct',(#2,#3,#4));
|
||||
#2=IFCSIMPLEPROPERTYTEMPLATE('2P7JN79n96Q9pElZ83LKe4',$,'ZIndex','',.P_SINGLEVALUE.,'IfcInteger',$,$,$,$,$,.READWRITE.);
|
||||
#3=IFCSIMPLEPROPERTYTEMPLATE('1Wpx_r2xj1_9w5JpI0QRJy',$,'Symbol','',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#4=IFCSIMPLEPROPERTYTEMPLATE('3q0oxMUKP47vZ4jnyG$dDb',$,'Classes','Classes separarated by spaces that end up in classes for this element in svg. Can be used to specify the text font size: small - 1.8mm; regular - 2.5mm; large - 3.5mm; header - 5mm; title - 7mm. By default regular size is used.',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#5=IFCPROPERTYSETTEMPLATE('0iKwujnQL9IevVQato8f7Z',$,'BBIM_Batting','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation,IfcTypeProduct',(#6,#7));
|
||||
#5=IFCPROPERTYSETTEMPLATE('0iKwujnQL9IevVQato8f7Z',$,'BBIM_Batting','',.PSET_TYPEDRIVENOVERRIDE.,'IfcAnnotation/BATTING,IfcTypeProduct',(#6,#7));
|
||||
#6=IFCSIMPLEPROPERTYTEMPLATE('0t2LEesGT1QRQtrIZUAR8L',$,'Thickness','Batting thickness',.P_SINGLEVALUE.,'IfcPositiveLengthMeasure',$,$,$,$,$,.READWRITE.);
|
||||
#7=IFCSIMPLEPROPERTYTEMPLATE('082PndS6v2kBOiJoSboMnh',$,'Reverse pattern direction','Reverse batting pattern (swap starting and ending points)',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#8=IFCPROPERTYSETTEMPLATE('1Dx2EiZnP67xotInXpwz90',$,'BBIM_Section','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation,IfcTypeProduct',(#9,#10,#11,#12,#13));
|
||||
#8=IFCPROPERTYSETTEMPLATE('1Dx2EiZnP67xotInXpwz90',$,'BBIM_Section','',.PSET_TYPEDRIVENOVERRIDE.,'IfcAnnotation/SECTION,IfcTypeProduct',(#9,#10,#11,#12,#13));
|
||||
#9=IFCSIMPLEPROPERTYTEMPLATE('2a_9s8spHDc9dZHtgg71XL',$,'ShowStartArrow','Display start arrow.',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#10=IFCSIMPLEPROPERTYTEMPLATE('3i6SH_GbT7zhKea$wVE56A',$,'StartArrowSymbol','Custom symbol for the start of the section marker arrow. Need to make sure it''s present in "symbols.svg".',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#11=IFCSIMPLEPROPERTYTEMPLATE('1DtsPn5a9FG8$zXHDDMavY',$,'ShowEndArrow','Display end arrow.',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#12=IFCSIMPLEPROPERTYTEMPLATE('2$6U0mLI9AiPRWeBabdY3u',$,'EndArrowSymbol','Custom symbol for the end of the section marker arrow. Need to make sure it''s present in "symbols.svg".',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#13=IFCSIMPLEPROPERTYTEMPLATE('1naFqntIL7igCY7hCaE7kq',$,'HasConnectedSectionLine','Connect or disconnect section markers with line (by default = True).',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#14=IFCPROPERTYSETTEMPLATE('3V8oZ8YRD3_O7uR5vcUleS',$,'BBIM_Documentation','',.PSET_OCCURRENCEDRIVEN.,'IfcProject',(#15,#16,#17,#18,#19,#20,#21,#22,#23));
|
||||
#14=IFCPROPERTYSETTEMPLATE('3V8oZ8YRD3_O7uR5vcUleS',$,'BBIM_Documentation','',.PSET_TYPEDRIVENOVERRIDE.,'IfcProject',(#15,#16,#17,#18,#19,#20,#21,#22,#23));
|
||||
#15=IFCSIMPLEPROPERTYTEMPLATE('0ulAhgk3v9qfGlDILauR6J',$,'SheetsDir','Default sheets directory',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#16=IFCSIMPLEPROPERTYTEMPLATE('2yvlVKiQXASucfH40deCvu',$,'LayoutsDir','Default layouts directory',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#17=IFCSIMPLEPROPERTYTEMPLATE('2kXZqXicL3jRwsOnLM_0ho',$,'TitleblocksDir','Default titleblocks directory',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
@@ -28,7 +28,7 @@ DATA;
|
||||
#21=IFCSIMPLEPROPERTYTEMPLATE('1UDakJ5_f7kBhggNSW4$h5',$,'SymbolsPath','Default symbols SVG',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#22=IFCSIMPLEPROPERTYTEMPLATE('0d53LEtgLDQxnv__NfgH7i',$,'PatternsPath','Default patterns SVG',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#23=IFCSIMPLEPROPERTYTEMPLATE('26qFNMv7nCHgU6Jd7Anga5',$,'ShadingStylesPath','Default shading styles',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
#24=IFCPROPERTYSETTEMPLATE('0I9merLinF5Ap$aZwaclgm',$,'BBIM_Dimension','',.PSET_OCCURRENCEDRIVEN.,'IfcAnnotation,IfcTypeProduct',(#25,#26,#27,#28));
|
||||
#24=IFCPROPERTYSETTEMPLATE('0I9merLinF5Ap$aZwaclgm',$,'BBIM_Dimension','',.PSET_TYPEDRIVENOVERRIDE.,'IfcAnnotation/DIMENSION,IfcTypeProduct',(#25,#26,#27,#28));
|
||||
#25=IFCSIMPLEPROPERTYTEMPLATE('1rL2AbQsXD8RbpoWH5pYOV',$,'ShowDescriptionOnly','Hide the measurement values and show only annotation description',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#26=IFCSIMPLEPROPERTYTEMPLATE('0SVyOfB0rC2xNfdRYf3XvY',$,'SuppressZeroInches','Suppress 0 inch values in dimension annotation text (for example: 12'' - 0" -> 12'')',.P_SINGLEVALUE.,'IfcBoolean',$,$,$,$,$,.READWRITE.);
|
||||
#27=IFCSIMPLEPROPERTYTEMPLATE('2bUmj458PBqPAtUoI3MXsb',$,'TextPrefix','Text to add before annotation measurement value',.P_SINGLEVALUE.,'IfcLabel',$,$,$,$,$,.READWRITE.);
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
import os
|
||||
import bpy
|
||||
import uuid
|
||||
import shutil
|
||||
import hashlib
|
||||
import zipfile
|
||||
import tempfile
|
||||
@@ -121,7 +122,13 @@ class IfcStore:
|
||||
ifc_hash = hashlib.md5(ifc_key.encode("utf-8")).hexdigest()
|
||||
new_cache_path = os.path.join(bpy.context.scene.BIMProperties.data_dir, "cache", f"{ifc_hash}.h5")
|
||||
IfcStore.cache = None
|
||||
os.replace(IfcStore.cache_path, new_cache_path)
|
||||
try:
|
||||
shutil.move(IfcStore.cache_path, new_cache_path)
|
||||
except PermissionError:
|
||||
try:
|
||||
shutil.copy2(IfcStore.cache_path, new_cache_path)
|
||||
except PermissionError:
|
||||
pass # Well we tried. No cache for you!
|
||||
IfcStore.get_cache()
|
||||
|
||||
@staticmethod
|
||||
|
||||
@@ -702,15 +702,17 @@ class IfcImporter:
|
||||
mat = np.array(
|
||||
([m[0], m[3], m[6], m[9]], [m[1], m[4], m[7], m[10]], [m[2], m[5], m[8], m[11]], [0, 0, 0, 1])
|
||||
)
|
||||
point = np.array(
|
||||
point = mat @ np.array(
|
||||
(
|
||||
shape.geometry.verts[0] / self.unit_scale,
|
||||
shape.geometry.verts[1] / self.unit_scale,
|
||||
shape.geometry.verts[2] / self.unit_scale,
|
||||
shape.geometry.verts[0],
|
||||
shape.geometry.verts[1],
|
||||
shape.geometry.verts[2],
|
||||
0.0,
|
||||
)
|
||||
)
|
||||
return mat @ point
|
||||
point = point / self.unit_scale
|
||||
if self.is_point_far_away(point, is_meters=False):
|
||||
return point
|
||||
|
||||
def does_element_likely_have_geometry_far_away(self, element):
|
||||
for representation in element.Representation.Representations:
|
||||
@@ -1500,10 +1502,9 @@ class IfcImporter:
|
||||
project_collection = bpy.context.view_layer.layer_collection.children[self.project["blender"].name]
|
||||
types_collection = project_collection.children[self.type_collection.name]
|
||||
types_collection.hide_viewport = False
|
||||
for obj in types_collection.collection.objects: #turn off all objects inside Types collection.
|
||||
for obj in types_collection.collection.objects: # turn off all objects inside Types collection.
|
||||
obj.hide_set(True)
|
||||
|
||||
|
||||
def clean_mesh(self):
|
||||
obj = None
|
||||
last_obj = None
|
||||
@@ -1912,11 +1913,7 @@ class IfcImporter:
|
||||
and geometry.verts
|
||||
and self.is_point_far_away((geometry.verts[0], geometry.verts[1], geometry.verts[2]))
|
||||
):
|
||||
m = shape.transformation.matrix.data
|
||||
mat = np.array(
|
||||
([m[0], m[3], m[6], m[9]], [m[1], m[4], m[7], m[10]], [m[2], m[5], m[8], m[11]], [0, 0, 0, 1])
|
||||
)
|
||||
offset_point = np.linalg.inv(mat) @ np.array(
|
||||
offset_point = np.array(
|
||||
(
|
||||
float(props.blender_eastings),
|
||||
float(props.blender_northings),
|
||||
@@ -1924,8 +1921,15 @@ class IfcImporter:
|
||||
0.0,
|
||||
)
|
||||
)
|
||||
if geometry != shape:
|
||||
m = shape.transformation.matrix.data
|
||||
mat = np.array(
|
||||
([m[0], m[3], m[6], m[9]], [m[1], m[4], m[7], m[10]], [m[2], m[5], m[8], m[11]], [0, 0, 0, 1])
|
||||
)
|
||||
offset_point = np.linalg.inv(mat) @ offset_point
|
||||
verts = [None] * len(geometry.verts)
|
||||
for i in range(0, len(geometry.verts), 3):
|
||||
# Note: this enh2xyz call is crazy slow.
|
||||
verts[i], verts[i + 1], verts[i + 2] = ifcopenshell.util.geolocation.enh2xyz(
|
||||
geometry.verts[i],
|
||||
geometry.verts[i + 1],
|
||||
|
||||
@@ -73,7 +73,7 @@ class BIM_PT_aggregate(Panel):
|
||||
row.operator("bim.add_aggregate", icon="ADD", text="")
|
||||
op = row.operator("bim.aggregate_unassign_object", icon="X", text="")
|
||||
else:
|
||||
row.label(text="No Aggregate", icon="TRIA_UP")
|
||||
row.label(text="No Whole relation defined", icon="TRIA_UP")
|
||||
row.operator("bim.enable_editing_aggregate", icon="GREASEPENCIL", text="")
|
||||
row.operator("bim.add_aggregate", icon="ADD", text="")
|
||||
|
||||
|
||||
@@ -1515,7 +1515,14 @@ class ActivateDrawing(bpy.types.Operator):
|
||||
if not self.camera_view_point:
|
||||
viewport_position = tool.Blender.get_viewport_position()
|
||||
|
||||
core.activate_drawing_view(tool.Ifc, tool.Drawing, drawing=drawing)
|
||||
try:
|
||||
core.activate_drawing_view(tool.Ifc, tool.Blender, tool.Drawing, drawing=drawing)
|
||||
except core.CameraNotAvailableError:
|
||||
self.report(
|
||||
{"ERROR"},
|
||||
"The drawing view is not available. Ensure you have not excluded it in the active view layer.",
|
||||
)
|
||||
return {"CANCELLED"}
|
||||
|
||||
if not self.camera_view_point:
|
||||
tool.Blender.set_viewport_position(viewport_position)
|
||||
|
||||
@@ -136,19 +136,23 @@ class AddRepresentation(bpy.types.Operator, Operator):
|
||||
"for Profile - 2D bounding box by local XZ axes.\n"
|
||||
"For other contexts - bounding box is 3d.",
|
||||
),
|
||||
("PROJECT", "Full Representation", ""),
|
||||
("OBJECT", "From Object", "Copies geometry from another object"),
|
||||
("PROJECT", "Full Representation", "Reuses the current representation"),
|
||||
],
|
||||
name="Representation Conversion Method",
|
||||
)
|
||||
|
||||
def _execute(self, context):
|
||||
obj = context.active_object
|
||||
props = obj.BIMGeometryProperties
|
||||
ifc_context = int(props.contexts or "0") or None
|
||||
props = context.scene.BIMGeometryProperties
|
||||
oprops = obj.BIMGeometryProperties
|
||||
ifc_context = int(oprops.contexts or "0") or None
|
||||
if not ifc_context:
|
||||
return
|
||||
ifc_context = tool.Ifc.get().by_id(ifc_context)
|
||||
|
||||
original_data = obj.data
|
||||
|
||||
if self.representation_conversion_method == "OUTLINE":
|
||||
if ifc_context.ContextType == "Plan":
|
||||
data = tool.Geometry.generate_outline_mesh(obj, axis="+Z")
|
||||
@@ -165,17 +169,31 @@ class AddRepresentation(bpy.types.Operator, Operator):
|
||||
else:
|
||||
data = tool.Geometry.generate_3d_box_mesh(obj)
|
||||
tool.Geometry.change_object_data(obj, data, is_global=True)
|
||||
elif (
|
||||
self.representation_conversion_method == "OBJECT"
|
||||
and props.representation_from_object
|
||||
and props.representation_from_object.data
|
||||
):
|
||||
data = tool.Geometry.duplicate_object_data(props.representation_from_object)
|
||||
tool.Geometry.change_object_data(obj, data, is_global=True)
|
||||
|
||||
core.add_representation(
|
||||
tool.Ifc,
|
||||
tool.Geometry,
|
||||
tool.Style,
|
||||
tool.Surveyor,
|
||||
obj=obj,
|
||||
context=ifc_context,
|
||||
ifc_representation_class=None,
|
||||
profile_set_usage=None,
|
||||
)
|
||||
try:
|
||||
core.add_representation(
|
||||
tool.Ifc,
|
||||
tool.Geometry,
|
||||
tool.Style,
|
||||
tool.Surveyor,
|
||||
obj=obj,
|
||||
context=ifc_context,
|
||||
ifc_representation_class=None,
|
||||
profile_set_usage=None,
|
||||
)
|
||||
except core.IncompatibleRepresentationError:
|
||||
if obj.data != original_data:
|
||||
tool.Geometry.change_object_data(obj, original_data, is_global=True)
|
||||
bpy.data.meshes.remove(data)
|
||||
self.report({"ERROR"}, "No compatible representation for the context could be created.")
|
||||
return {"CANCELLED"}
|
||||
|
||||
def invoke(self, context, event):
|
||||
return context.window_manager.invoke_props_dialog(self)
|
||||
@@ -183,6 +201,9 @@ class AddRepresentation(bpy.types.Operator, Operator):
|
||||
def draw(self, context):
|
||||
row = self.layout.row()
|
||||
row.prop(self, "representation_conversion_method", text="")
|
||||
if self.representation_conversion_method == "OBJECT":
|
||||
row = self.layout.row()
|
||||
row.prop(context.scene.BIMGeometryProperties, "representation_from_object", text="")
|
||||
|
||||
|
||||
class SelectConnection(bpy.types.Operator, Operator):
|
||||
|
||||
@@ -138,3 +138,4 @@ class BIMGeometryProperties(PropertyGroup):
|
||||
name="IFC Interaction Mode",
|
||||
update=update_mode,
|
||||
)
|
||||
representation_from_object: PointerProperty(type=bpy.types.Object)
|
||||
|
||||
@@ -83,8 +83,17 @@ class EnableEditingArray(bpy.types.Operator, tool.Ifc.Operator):
|
||||
def _execute(self, context):
|
||||
obj = context.active_object
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
data = json.loads(ifcopenshell.util.element.get_pset(element, "BBIM_Array", "Data"))[self.item]
|
||||
props = obj.BIMArrayProperties
|
||||
|
||||
relating_obj = props.relating_array_object
|
||||
|
||||
if relating_obj:
|
||||
element = tool.Ifc.get_entity(relating_obj)
|
||||
parent_globalid = ifcopenshell.util.element.get_pset(element, "BBIM_Array", "Parent")
|
||||
parent_element = tool.Ifc.get().by_guid(parent_globalid)
|
||||
data = json.loads(ifcopenshell.util.element.get_pset(parent_element, "BBIM_Array", "Data"))[self.item]
|
||||
else:
|
||||
data = json.loads(ifcopenshell.util.element.get_pset(element, "BBIM_Array", "Data"))[self.item]
|
||||
props.count = data["count"]
|
||||
si_conversion = ifcopenshell.util.unit.calculate_unit_scale(tool.Ifc.get())
|
||||
props.x = data["x"] * si_conversion
|
||||
@@ -93,7 +102,9 @@ class EnableEditingArray(bpy.types.Operator, tool.Ifc.Operator):
|
||||
props.use_local_space = data.get("use_local_space", False)
|
||||
props.sync_children = data.get("sync_children", False)
|
||||
props.method = data.get("method", "OFFSET")
|
||||
|
||||
props.is_editing = self.item
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
@@ -137,6 +148,10 @@ class EditArray(bpy.types.Operator, tool.Ifc.Operator):
|
||||
|
||||
tool.Blender.Modifier.Array.set_children_lock_state(element, self.item, True)
|
||||
tool.Blender.Modifier.Array.constrain_children_to_parent(element)
|
||||
|
||||
#clears the relating_array_object so it doesn't show again next time
|
||||
props.relating_array_object = None
|
||||
|
||||
return {"FINISHED"}
|
||||
|
||||
|
||||
|
||||
@@ -87,6 +87,21 @@ def update_type_page(self, context):
|
||||
AuthoringData.data["paginated_relating_types"] = AuthoringData.paginated_relating_types()
|
||||
|
||||
|
||||
def update_relating_array_from_object(self, context):
|
||||
bpy.ops.bim.enable_editing_array(item=self.is_editing)
|
||||
return
|
||||
|
||||
|
||||
def is_object_array_applicable(self, obj):
|
||||
element = tool.Ifc.get_entity(obj)
|
||||
if not element:
|
||||
return False
|
||||
return ifcopenshell.util.element.get_pset(element, "BBIM_Array")
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
class BIMModelProperties(PropertyGroup):
|
||||
ifc_class: bpy.props.EnumProperty(items=get_ifc_class, name="Construction Class", update=update_ifc_class)
|
||||
relating_type_id: bpy.props.EnumProperty(
|
||||
@@ -203,6 +218,14 @@ class BIMArrayProperties(PropertyGroup):
|
||||
description="Regenerate all children based on the parent object",
|
||||
default=False,
|
||||
)
|
||||
relating_array_object: bpy.props.PointerProperty(
|
||||
type=bpy.types.Object,
|
||||
name="Copy Array Properties",
|
||||
update=update_relating_array_from_object,
|
||||
poll=is_object_array_applicable,
|
||||
)
|
||||
|
||||
|
||||
|
||||
|
||||
class BIMStairProperties(PropertyGroup):
|
||||
|
||||
@@ -223,6 +223,8 @@ class BIM_PT_array(bpy.types.Panel):
|
||||
row = col.row(align=True)
|
||||
row.prop(props, "z")
|
||||
row.operator("bim.input_cursor_z_array", icon="CURSOR", text="")
|
||||
row = col.row(align=True)
|
||||
row.prop(props, "relating_array_object", icon="COPYDOWN")
|
||||
else:
|
||||
row = box.row(align=True)
|
||||
name = f"{array['count']} Items ({array.get('method', 'OFFSET').capitalize()})"
|
||||
|
||||
@@ -268,7 +268,6 @@ class RemovePropTemplate(bpy.types.Operator, Operator):
|
||||
prop_template: bpy.props.IntProperty()
|
||||
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMPsetTemplateProperties
|
||||
ifcopenshell.api.run(
|
||||
"pset_template.remove_prop_template",
|
||||
IfcStore.pset_template_file,
|
||||
@@ -287,21 +286,21 @@ class EditPropTemplate(bpy.types.Operator, Operator):
|
||||
def _execute(self, context):
|
||||
props = context.scene.BIMPsetTemplateProperties
|
||||
if props.active_prop_template.template_type == "P_ENUMERATEDVALUE":
|
||||
enumerator = self.generate_prop_enum(props)
|
||||
data_type = props.active_prop_template.get_value_name()
|
||||
prop = props.active_prop_template
|
||||
enumerators = [getattr(ev, data_type) for ev in prop.enum_values]
|
||||
else:
|
||||
enumerator = None
|
||||
enumerators = None
|
||||
ifcopenshell.api.run(
|
||||
"pset_template.edit_prop_template",
|
||||
IfcStore.pset_template_file,
|
||||
**{
|
||||
"prop_template": IfcStore.pset_template_file.by_id(props.active_prop_template_id),
|
||||
"attributes": {
|
||||
"Name": props.active_prop_template.name,
|
||||
"Description": props.active_prop_template.description,
|
||||
"PrimaryMeasureType": props.active_prop_template.primary_measure_type,
|
||||
"TemplateType": props.active_prop_template.template_type,
|
||||
"Enumerators": enumerator,
|
||||
},
|
||||
prop_template=IfcStore.pset_template_file.by_id(props.active_prop_template_id),
|
||||
attributes={
|
||||
"Name": props.active_prop_template.name,
|
||||
"Description": props.active_prop_template.description,
|
||||
"PrimaryMeasureType": props.active_prop_template.primary_measure_type,
|
||||
"TemplateType": props.active_prop_template.template_type,
|
||||
"Enumerators": enumerators,
|
||||
}
|
||||
)
|
||||
bpy.ops.bim.disable_editing_prop_template()
|
||||
@@ -309,18 +308,3 @@ class EditPropTemplate(bpy.types.Operator, Operator):
|
||||
blenderbim.bim.handler.refresh_ui_data()
|
||||
if tool.Ifc.get():
|
||||
blenderbim.bim.schema.reload(tool.Ifc.get().schema)
|
||||
|
||||
# TODO -This will need to go into the
|
||||
# api code at some point - vulevukusej
|
||||
def generate_prop_enum(self, props):
|
||||
self.file = IfcStore.pset_template_file
|
||||
data_type = props.active_prop_template.get_value_name()
|
||||
prop = props.active_prop_template
|
||||
prop_enum = self.file.create_entity(
|
||||
"IFCPROPERTYENUMERATION",
|
||||
Name=prop.name,
|
||||
EnumerationValues=tuple(
|
||||
self.file.create_entity(prop.primary_measure_type, getattr(ev, data_type)) for ev in prop.enum_values
|
||||
),
|
||||
)
|
||||
return prop_enum
|
||||
|
||||
@@ -441,9 +441,19 @@ def select_assigned_product(drawing, context):
|
||||
drawing.select_assigned_product(context)
|
||||
|
||||
|
||||
def activate_drawing_view(ifc, drawing_tool, drawing):
|
||||
def activate_drawing_view(ifc, blender, drawing_tool, drawing):
|
||||
camera = ifc.get_object(drawing)
|
||||
if not camera:
|
||||
camera = drawing_tool.import_drawing(drawing)
|
||||
drawing_tool.import_annotations_in_group(drawing_tool.get_drawing_group(drawing))
|
||||
blender.activate_camera(camera)
|
||||
drawing_tool.isolate_camera_collection(camera)
|
||||
try:
|
||||
blender.set_active_object(camera)
|
||||
except:
|
||||
raise CameraNotAvailableError()
|
||||
drawing_tool.activate_drawing(camera)
|
||||
|
||||
|
||||
class CameraNotAvailableError(Exception):
|
||||
pass
|
||||
|
||||
@@ -47,7 +47,7 @@ def add_representation(
|
||||
data = geometry.get_object_data(obj)
|
||||
|
||||
if not data and ifc_representation_class != "IfcTextLiteral":
|
||||
return
|
||||
raise IncompatibleRepresentationError()
|
||||
|
||||
representation = ifc.run(
|
||||
"geometry.add_representation",
|
||||
@@ -63,6 +63,9 @@ def add_representation(
|
||||
profile_set_usage=profile_set_usage,
|
||||
)
|
||||
|
||||
if not representation:
|
||||
raise IncompatibleRepresentationError()
|
||||
|
||||
if geometry.is_body_representation(representation):
|
||||
[geometry.run_style_add_style(obj=mat) for mat in geometry.get_object_materials_without_styles(obj)]
|
||||
ifc.run(
|
||||
@@ -221,3 +224,7 @@ def edit_similar_opening_placement(geometry, opening=None, similar_openings=None
|
||||
old_placement = similar_opening.ObjectPlacement
|
||||
similar_opening.ObjectPlacement = opening.ObjectPlacement
|
||||
geometry.delete_opening_object_placement(old_placement)
|
||||
|
||||
|
||||
class IncompatibleRepresentationError(Exception):
|
||||
pass
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
|
||||
import abc
|
||||
import inspect
|
||||
from typing import Optional
|
||||
|
||||
# fmt: off
|
||||
# pylint: skip-file
|
||||
@@ -72,20 +73,21 @@ class Aggregate:
|
||||
|
||||
@interface
|
||||
class Blender:
|
||||
def set_active_object(cls, obj): pass
|
||||
def get_name(cls, ifc_class, name): pass
|
||||
def get_selected_objects(cls): pass
|
||||
def create_ifc_object(cls, ifc_class: str, name: str = None, data=None): pass
|
||||
def get_obj_ifc_definition_id(cls, obj=None, obj_type=None, context=None): pass
|
||||
def is_ifc_object(cls, obj): pass
|
||||
def is_ifc_class_active(cls, ifc_class): pass
|
||||
def get_viewport_context(cls): pass
|
||||
def update_viewport(cls): pass
|
||||
def get_default_selection_keypmap(cls): pass
|
||||
def get_object_bounding_box(cls, obj): pass
|
||||
def activate_camera(cls, obj): pass
|
||||
def apply_bmesh(cls, mesh, bm, obj=None): pass
|
||||
def get_bmesh_for_mesh(cls, mesh, clean=False): pass
|
||||
def bmesh_join(cls, bm_a, bm_b, callback=None): pass
|
||||
def create_ifc_object(cls, ifc_class: str, name: Optional[str] = None, data=None): pass
|
||||
def get_bmesh_for_mesh(cls, mesh, clean=False): pass
|
||||
def get_default_selection_keypmap(cls): pass
|
||||
def get_name(cls, ifc_class, name): pass
|
||||
def get_obj_ifc_definition_id(cls, obj=None, obj_type=None, context=None): pass
|
||||
def get_object_bounding_box(cls, obj): pass
|
||||
def get_selected_objects(cls): pass
|
||||
def get_viewport_context(cls): pass
|
||||
def is_ifc_class_active(cls, ifc_class): pass
|
||||
def is_ifc_object(cls, obj): pass
|
||||
def set_active_object(cls, obj): pass
|
||||
def update_viewport(cls): pass
|
||||
|
||||
|
||||
@interface
|
||||
|
||||
@@ -49,6 +49,23 @@ class Blender(blenderbim.core.tool.Blender):
|
||||
OBJECT_TYPES_THAT_SUPPORT_EDIT_GPENCIL_MODE = ("GPENCIL",)
|
||||
TYPE_MANAGER_ICON = "LIGHTPROBE_VOLUME" if bpy.app.version >= (4, 1, 0) else "LIGHTPROBE_GRID"
|
||||
|
||||
@classmethod
|
||||
def activate_camera(cls, obj: bpy.types.Object) -> None:
|
||||
area = tool.Blender.get_view3d_area()
|
||||
is_local_view = area.spaces[0].local_view is not None
|
||||
if is_local_view:
|
||||
# Turn off local view before activating drawing, and then turn it on again.
|
||||
for a in bpy.context.screen.areas:
|
||||
if a.type == "VIEW_3D":
|
||||
override = bpy.context.copy()
|
||||
override["area"] = a
|
||||
bpy.ops.view3d.localview(override)
|
||||
bpy.context.scene.camera = obj
|
||||
bpy.ops.view3d.localview(override)
|
||||
else:
|
||||
bpy.context.scene.camera = obj
|
||||
area.spaces[0].region_3d.view_perspective = "CAMERA"
|
||||
|
||||
@classmethod
|
||||
def get_area_props(cls, context: bpy.types.Context) -> Any:
|
||||
try:
|
||||
@@ -845,9 +862,7 @@ class Blender(blenderbim.core.tool.Blender):
|
||||
bpy.utils.register_tool(ws_model.PipeTool, after={"bim.duct_tool"}, separator=False, group=False)
|
||||
bpy.utils.register_tool(ws_model.BimTool, after={"bim.pipe_tool"}, separator=False, group=False)
|
||||
bpy.utils.register_tool(ws_drawing.AnnotationTool, after={"bim.bim_tool"}, separator=True, group=False)
|
||||
bpy.utils.register_tool(
|
||||
ws_spatial.SpatialTool, after={"bim.annotation_tool"}, separator=False, group=False
|
||||
)
|
||||
bpy.utils.register_tool(ws_spatial.SpatialTool, after={"bim.annotation_tool"}, separator=False, group=False)
|
||||
bpy.utils.register_tool(
|
||||
ws_structural.StructuralTool, after={"bim.spatial_tool"}, separator=False, group=False
|
||||
)
|
||||
|
||||
@@ -1743,21 +1743,7 @@ class Drawing(blenderbim.core.tool.Drawing):
|
||||
bpy.ops.bim.activate_model()
|
||||
|
||||
@classmethod
|
||||
def activate_drawing(cls, camera: bpy.types.Object) -> None:
|
||||
area = tool.Blender.get_view3d_area()
|
||||
is_local_view = area.spaces[0].local_view is not None
|
||||
if is_local_view:
|
||||
# turn off local view before activating drawing, and then turn it on again.
|
||||
for a in bpy.context.screen.areas:
|
||||
if a.type == "VIEW_3D":
|
||||
override = bpy.context.copy()
|
||||
override["area"] = a
|
||||
bpy.ops.view3d.localview(override)
|
||||
bpy.context.scene.camera = camera
|
||||
bpy.ops.view3d.localview(override)
|
||||
else:
|
||||
bpy.context.scene.camera = camera
|
||||
area.spaces[0].region_3d.view_perspective = "CAMERA"
|
||||
def isolate_camera_collection(cls, camera: bpy.types.Object) -> None:
|
||||
views_collection = bpy.data.collections.get("Views")
|
||||
for collection in views_collection.children:
|
||||
# We assume the project collection is at the top level
|
||||
@@ -1775,8 +1761,9 @@ class Drawing(blenderbim.core.tool.Drawing):
|
||||
camera.BIMObjectProperties.collection.name
|
||||
].hide_viewport = False
|
||||
camera.BIMObjectProperties.collection.hide_render = False
|
||||
tool.Spatial.set_active_object(camera)
|
||||
|
||||
@classmethod
|
||||
def activate_drawing(cls, camera: bpy.types.Object) -> None:
|
||||
# Sync viewport objects visibility with selectors from EPset_Drawing/Include and /Exclude
|
||||
drawing = tool.Ifc.get_entity(camera)
|
||||
|
||||
|
||||
@@ -72,8 +72,8 @@ def get_facility_data(ifc_file, element):
|
||||
"ModelProjectID": ifc_file.by_type("IfcProject")[0].GlobalId,
|
||||
"ModelSiteID": getattr(get_facility_parent(element, "IfcSite"), "GlobalId", None),
|
||||
"ModelBuildingID": element.GlobalId,
|
||||
"LinearUnits": "millimeters",
|
||||
"AreaUnits": "square meters",
|
||||
"LengthUnit": "millimeters",
|
||||
"AreaUnit": "square meters",
|
||||
"Phase": ifc_file.by_type("IfcProject")[0].Phase,
|
||||
}
|
||||
|
||||
@@ -99,7 +99,7 @@ def get_space_data(ifc_file, element):
|
||||
"Description": element.LongName,
|
||||
"ClassificationIdentification": get_classification_identification(element),
|
||||
"ClassificationName": get_classification_name(element),
|
||||
"LevelName": getattr(get_facility_parent(element, "IfcBuildingStorey"), "Name", None),
|
||||
"StoreyName": getattr(get_facility_parent(element, "IfcBuildingStorey"), "Name", None),
|
||||
"OrganizationName": get_owner_name(element),
|
||||
"CreationDate": get_owner_creation_date(element),
|
||||
"ModelSoftware": get_owner_application(element),
|
||||
@@ -261,8 +261,8 @@ config = {
|
||||
"ModelProjectID",
|
||||
"ModelSiteID",
|
||||
"ModelBuildingID",
|
||||
"LinearUnits",
|
||||
"AreaUnits",
|
||||
"LengthUnit",
|
||||
"AreaUnit",
|
||||
"Phase",
|
||||
],
|
||||
"colours": "ppppreeeeesss",
|
||||
@@ -295,7 +295,7 @@ config = {
|
||||
"Description",
|
||||
"ClassificationIdentification",
|
||||
"ClassificationName",
|
||||
"LevelName",
|
||||
"StoreyName",
|
||||
"OrganizationName",
|
||||
"CreationDate",
|
||||
"ModelSoftware",
|
||||
@@ -305,7 +305,7 @@ config = {
|
||||
"NetFloorArea",
|
||||
],
|
||||
"colours": "ppprreeess",
|
||||
"sort": [{"name": "LevelName", "order": "ASC"}, {"name": "Name", "order": "ASC"}],
|
||||
"sort": [{"name": "StoreyName", "order": "ASC"}, {"name": "Name", "order": "ASC"}],
|
||||
"get_category_elements": get_spaces,
|
||||
"get_element_data": get_space_data,
|
||||
},
|
||||
|
||||
@@ -186,6 +186,7 @@ Valid keys are:
|
||||
"``material`` or ``mat``", "Gets the assigned material, which may be a material set."
|
||||
"``item`` or ``i``", "If the previous key returns a material set, gets the relevant material set items"
|
||||
"``materials`` or ``mats``", "Gets a list of IfcMaterials assigned directly or indirectly (such as via a material set) to the element"
|
||||
"``profiles``", "Gets a list of IfcProfileDefs assigned (such as via a material profile) or used (such as in an extrusion) in the element"
|
||||
"``x``", "Gets the X coordinate of the element's placement"
|
||||
"``y``", "Gets the Y coordinate of the element's placement"
|
||||
"``z``", "Gets the Z coordinate of the element's placement"
|
||||
|
||||
@@ -350,7 +350,8 @@ def wrap_usecases(path, name):
|
||||
module_name = name.split(".")[-1]
|
||||
module = sys.modules[name]
|
||||
for loader, usecase_name, is_pkg in pkgutil.iter_modules(path):
|
||||
usecase = getattr(module, usecase_name)
|
||||
# We may not be able to get the usecase if we are missing a dependency.
|
||||
usecase = getattr(module, usecase_name, None)
|
||||
if callable(usecase):
|
||||
usecase_path = f"{module_name}.{usecase_name}"
|
||||
setattr(module, usecase_name, wrap_usecase(usecase_path, usecase))
|
||||
|
||||
@@ -56,11 +56,8 @@ def add_information(
|
||||
attributes={"Identification": "A-GA-6100", "Name": "Overall Plan",
|
||||
"Location": "A-GA-6100 - Overall Plan.pdf"})
|
||||
"""
|
||||
settings = {"parent": parent}
|
||||
|
||||
id_attribute = "DocumentId" if file.schema == "IFC2X3" else "Identification"
|
||||
information = file.create_entity("IfcDocumentInformation", **{id_attribute: "X", "Name": "Unnamed"})
|
||||
parent = settings["parent"]
|
||||
if not parent and file.by_type("IfcProject"):
|
||||
parent = file.by_type("IfcProject")[0]
|
||||
if parent.is_a("IfcProject") or parent.is_a("IfcContext"):
|
||||
|
||||
@@ -352,12 +352,10 @@ class Usecase:
|
||||
)
|
||||
|
||||
def create_curve3d_representation(self):
|
||||
return self.file.createIfcShapeRepresentation(
|
||||
self.settings["context"],
|
||||
self.settings["context"].ContextIdentifier,
|
||||
"Curve3D",
|
||||
self.create_curves(),
|
||||
)
|
||||
if curves := self.create_curves():
|
||||
return self.file.createIfcShapeRepresentation(
|
||||
self.settings["context"], self.settings["context"].ContextIdentifier, "Curve3D", curves
|
||||
)
|
||||
|
||||
def create_curve2d_representation(self):
|
||||
return self.file.createIfcShapeRepresentation(
|
||||
@@ -425,7 +423,7 @@ class Usecase:
|
||||
results.append(self.file.createIfcSweptDiskSolid(curve, radius))
|
||||
return results
|
||||
|
||||
def is_mesh_curve_consequtive(self, geom_data):
|
||||
def is_mesh_curve_consecutive(self, geom_data):
|
||||
import blenderbim.tool as tool
|
||||
|
||||
bm = tool.Blender.get_bmesh_for_mesh(geom_data)
|
||||
@@ -475,11 +473,11 @@ class Usecase:
|
||||
geom_data = self.settings["geometry"]
|
||||
|
||||
if isinstance(geom_data, bpy.types.Mesh):
|
||||
if self.is_mesh_curve_consequtive(geom_data):
|
||||
if self.file.schema == "IFC2X3":
|
||||
return self.create_curves_from_mesh_ifc2x3(should_exclude_faces=should_exclude_faces, is_2d=is_2d)
|
||||
else:
|
||||
return self.create_curves_from_mesh(should_exclude_faces=should_exclude_faces, is_2d=is_2d)
|
||||
if not self.is_mesh_curve_consecutive(geom_data):
|
||||
return
|
||||
if self.file.schema == "IFC2X3":
|
||||
return self.create_curves_from_mesh_ifc2x3(should_exclude_faces=should_exclude_faces, is_2d=is_2d)
|
||||
return self.create_curves_from_mesh(should_exclude_faces=should_exclude_faces, is_2d=is_2d)
|
||||
|
||||
import blenderbim.tool as tool
|
||||
|
||||
|
||||
@@ -19,9 +19,15 @@
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.api.owner.settings
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def append_asset(file, library=None, element=None, reuse_identities=None) -> None:
|
||||
def append_asset(
|
||||
file: ifcopenshell.file,
|
||||
library: ifcopenshell.file,
|
||||
element: ifcopenshell.entity_instance,
|
||||
reuse_identities: Optional[dict[int, ifcopenshell.entity_instance]] = None,
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Appends an asset from a library into the active project
|
||||
|
||||
A BIM library asset may be a type product (e.g. wall type), product
|
||||
|
||||
@@ -17,10 +17,11 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.guid
|
||||
|
||||
|
||||
def add_pset(file, product=None, name=None) -> None:
|
||||
def add_pset(file: ifcopenshell.file, product: ifcopenshell.entity_instance, name: str) -> ifcopenshell.entity_instance:
|
||||
"""Adds a new property set to a product
|
||||
|
||||
Products, such as physical objects or types in IFC may have properties
|
||||
@@ -120,27 +121,36 @@ def add_pset(file, product=None, name=None) -> None:
|
||||
has_property_sets.append(pset)
|
||||
settings["product"].HasPropertySets = has_property_sets
|
||||
return pset
|
||||
elif settings["product"].is_a("IfcMaterialDefinition"):
|
||||
for definition in settings["product"].HasProperties or []:
|
||||
if definition.Name == settings["name"]:
|
||||
# in IFC2X3 IfcMaterialDefinition not yet existed
|
||||
elif settings["product"].is_a("IfcMaterialDefinition") or settings["product"].is_a("IfcMaterial"):
|
||||
if file.schema == "IFC2X3":
|
||||
ifc_class = "IfcExtendedMaterialProperties"
|
||||
definitions = (d for d in file.by_type("IfcMaterialProperties") if d.Material == settings["product"])
|
||||
else:
|
||||
ifc_class = "IfcMaterialProperties"
|
||||
definitions = settings["product"].HasProperties
|
||||
for definition in definitions:
|
||||
# In IFC2X3 not all IfcMaterialProperties has Name
|
||||
if getattr(definition, "Name") == settings["name"]:
|
||||
return definition
|
||||
|
||||
return file.create_entity(
|
||||
"IfcMaterialProperties",
|
||||
ifc_class,
|
||||
**{
|
||||
"Name": settings["name"],
|
||||
"Material": settings["product"],
|
||||
}
|
||||
)
|
||||
elif settings["product"].is_a("IfcProfileDef"):
|
||||
for definition in settings["product"].HasProperties or []:
|
||||
if definition.Name == settings["name"]:
|
||||
return definition
|
||||
# in IFC2X3 IfcProfileProperties doesn't have Name and we cannot identify them
|
||||
if file.schema != "IFC2X3":
|
||||
for definition in settings["product"].HasProperties or []:
|
||||
if definition.Name == settings["name"]:
|
||||
return definition
|
||||
|
||||
return file.create_entity(
|
||||
"IfcProfileProperties",
|
||||
**{
|
||||
"Name": settings["name"],
|
||||
"ProfileDefinition": settings["product"],
|
||||
}
|
||||
)
|
||||
kwargs = {}
|
||||
kwargs["ProfileDefinition"] = settings["product"]
|
||||
if file.schema != "IFC2X3":
|
||||
kwargs["Name"] = settings["name"]
|
||||
|
||||
return file.create_entity("IfcProfileProperties", **kwargs)
|
||||
|
||||
@@ -21,7 +21,7 @@ import ifcopenshell.api
|
||||
import ifcopenshell.guid
|
||||
|
||||
|
||||
def add_qto(file, product=None, name=None) -> None:
|
||||
def add_qto(file: ifcopenshell.file, product: ifcopenshell.entity_instance, name: str) -> ifcopenshell.entity_instance:
|
||||
"""Adds a new quantity set to a product
|
||||
|
||||
Products, such as physical objects or types in IFC may have quantities
|
||||
|
||||
@@ -18,9 +18,16 @@
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.pset
|
||||
from typing import Optional, Any
|
||||
|
||||
|
||||
def edit_qto(file, qto=None, name=None, properties=None, pset_template=None) -> None:
|
||||
def edit_qto(
|
||||
file: ifcopenshell.file,
|
||||
qto: ifcopenshell.entity_instance,
|
||||
name: Optional[str] = None,
|
||||
properties: Optional[dict[str, Any]] = None,
|
||||
pset_template: Optional[ifcopenshell.entity_instance] = None,
|
||||
) -> None:
|
||||
"""Edits a quantity set and its quantities
|
||||
|
||||
At its simplest usage, this may be used to edit the name of a quantity
|
||||
@@ -50,7 +57,7 @@ def edit_qto(file, qto=None, name=None, properties=None, pset_template=None) ->
|
||||
:param pset_template: If a quantity set template is provided, this will
|
||||
be used to determine data types. If no user-defined template is
|
||||
provided, the built-in buildingSMART templates will be loaded.
|
||||
:type pset_template: ifcopenshell.entity_instance
|
||||
:type pset_template: ifcopenshell.entity_instance, optional
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
|
||||
@@ -20,7 +20,9 @@ import ifcopenshell
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def remove_pset(file, product=None, pset=None) -> None:
|
||||
def remove_pset(
|
||||
file: ifcopenshell.file, product: ifcopenshell.entity_instance, pset: ifcopenshell.entity_instance
|
||||
) -> None:
|
||||
"""Removes a property set from a product
|
||||
|
||||
All properties that are part of this property set are also removed.
|
||||
|
||||
@@ -18,16 +18,17 @@
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.guid
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def add_prop_template(
|
||||
file,
|
||||
pset_template=None,
|
||||
name="NewProperty",
|
||||
description=None,
|
||||
template_type="P_SINGLEVALUE",
|
||||
primary_measure_type="IfcLabel",
|
||||
) -> None:
|
||||
file: ifcopenshell.file,
|
||||
pset_template: ifcopenshell.entity_instance,
|
||||
name: str = "NewProperty",
|
||||
description: Optional[str] = None,
|
||||
template_type: str = "P_SINGLEVALUE",
|
||||
primary_measure_type: str = "IfcLabel",
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Adds new property templates to a property set template
|
||||
|
||||
Assuming you first have a property set template, this allows you to add
|
||||
|
||||
@@ -21,11 +21,11 @@ import ifcopenshell.guid
|
||||
|
||||
|
||||
def add_pset_template(
|
||||
file,
|
||||
name="New_Pset",
|
||||
template_type="PSET_TYPEDRIVENOVERRIDE",
|
||||
applicable_entity="IfcObject,IfcTypeObject",
|
||||
) -> None:
|
||||
file: ifcopenshell.file,
|
||||
name: str = "New_Pset",
|
||||
template_type: str = "PSET_TYPEDRIVENOVERRIDE",
|
||||
applicable_entity: str = "IfcObject,IfcTypeObject",
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Adds a new property set template
|
||||
|
||||
This creates a new template for property sets. A template defines what
|
||||
|
||||
@@ -15,9 +15,13 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
import ifcopenshell
|
||||
from typing import Any
|
||||
|
||||
|
||||
def edit_prop_template(file, prop_template=None, attributes=None) -> None:
|
||||
def edit_prop_template(
|
||||
file: ifcopenshell.file, prop_template: ifcopenshell.entity_instance, attributes: dict[str, Any]
|
||||
) -> None:
|
||||
"""Edits the attributes of an IfcSimplePropertyTemplate
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
@@ -26,7 +30,7 @@ def edit_prop_template(file, prop_template=None, attributes=None) -> None:
|
||||
:param prop_template: The IfcSimplePropertyTemplate entity you want to edit
|
||||
:type prop_template: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict, optional
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
@@ -43,7 +47,20 @@ def edit_prop_template(file, prop_template=None, attributes=None) -> None:
|
||||
ifcopenshell.api.run("pset_template.edit_prop_template", model,
|
||||
prop_template=prop, attributes={"Name": "DemoA", "PrimaryMeasureType": "IfcLengthMeasure"})
|
||||
"""
|
||||
settings = {"prop_template": prop_template, "attributes": attributes or {}}
|
||||
if enum_values := attributes.get("Enumerators", None):
|
||||
prop_name = attributes.get("Name", None) or getattr(prop_template, "Name", None) or "Unnamed"
|
||||
primary_measure_type = (
|
||||
attributes.get("PrimaryMeasureType", None) or getattr(prop_template, "PrimaryMeasureType", None) or "IfcLabel"
|
||||
)
|
||||
enum_values = [file.create_entity(primary_measure_type, v) for v in enum_values]
|
||||
if enumerators := prop_template.Enumerators:
|
||||
enumerators.Name = prop_name
|
||||
enumerators.EnumerationValues = enum_values
|
||||
else:
|
||||
prop_template.Enumerators = file.create_entity("IfcPropertyEnumeration", prop_name, enum_values)
|
||||
|
||||
for name, value in settings["attributes"].items():
|
||||
setattr(settings["prop_template"], name, value)
|
||||
if "Enumerators" in attributes:
|
||||
del attributes["Enumerators"]
|
||||
|
||||
for name, value in attributes.items():
|
||||
setattr(prop_template, name, value)
|
||||
|
||||
@@ -15,9 +15,13 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
import ifcopenshell
|
||||
from typing import Any
|
||||
|
||||
|
||||
def edit_pset_template(file, pset_template=None, attributes=None) -> None:
|
||||
def edit_pset_template(
|
||||
file: ifcopenshell.file, pset_template: ifcopenshell.entity_instance, attributes: dict[str, Any]
|
||||
) -> None:
|
||||
"""Edits the attributes of an IfcPropertySetTemplate
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
@@ -26,7 +30,7 @@ def edit_pset_template(file, pset_template=None, attributes=None) -> None:
|
||||
:param pset_template: The IfcPropertySetTemplate entity you want to edit
|
||||
:type pset_template: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict, optional
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
@@ -41,7 +45,7 @@ def edit_pset_template(file, pset_template=None, attributes=None) -> None:
|
||||
ifcopenshell.api.run("pset_template.edit_pset_template", model,
|
||||
pset_template=template, attributes={"Name": "ABC_RiskFactors"})
|
||||
"""
|
||||
settings = {"pset_template": pset_template, "attributes": attributes or {}}
|
||||
settings = {"pset_template": pset_template, "attributes": attributes}
|
||||
|
||||
for name, value in settings["attributes"].items():
|
||||
setattr(settings["pset_template"], name, value)
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def remove_prop_template(file, prop_template=None) -> None:
|
||||
def remove_prop_template(file: ifcopenshell.file, prop_template: ifcopenshell.entity_instance) -> None:
|
||||
"""Removes a property template
|
||||
|
||||
Note that a property set template should always have at least one
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def remove_pset_template(file, pset_template=None) -> None:
|
||||
def remove_pset_template(file: ifcopenshell.file, pset_template: ifcopenshell.entity_instance) -> None:
|
||||
"""Removes a property set template
|
||||
|
||||
All property templates within the property set template are also removed
|
||||
|
||||
@@ -17,15 +17,16 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell.api
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def add_resource(
|
||||
file,
|
||||
parent_resource=None,
|
||||
ifc_class="IfcCrewResource",
|
||||
name=None,
|
||||
predefined_type="NOTDEFINED",
|
||||
) -> None:
|
||||
file: ifcopenshell.file,
|
||||
parent_resource: Optional[ifcopenshell.entity_instance] = None,
|
||||
ifc_class: str = "IfcCrewResource",
|
||||
name: Optional[str] = None,
|
||||
predefined_type: str = "NOTDEFINED",
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Add a new construction resource
|
||||
|
||||
Construction resources may be managed and connected to cost schedules
|
||||
@@ -48,7 +49,7 @@ def add_resource(
|
||||
|
||||
:param parent_resource: If this is a child resource (typically to a crew
|
||||
resource), then nominate the parent IfcConstructionResource here.
|
||||
:type parent_resource: ifcopenshell.entity_instance
|
||||
:type parent_resource: ifcopenshell.entity_instance, optional
|
||||
:param ifc_class: The class of resource chosen from
|
||||
IfcConstructionEquipmentResource, IfcConstructionMaterialResource,
|
||||
IfcConstructionProductResource, IfcCrewResource, IfcLaborResource,
|
||||
@@ -96,7 +97,7 @@ def add_resource(
|
||||
related_objects=[resource],
|
||||
relating_object=settings["parent_resource"],
|
||||
)
|
||||
else:
|
||||
elif file.schema != "IFC2X3":
|
||||
context = file.by_type("IfcContext")[0]
|
||||
ifcopenshell.api.run(
|
||||
"project.assign_declaration",
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def add_resource_quantity(file, resource=None, ifc_class="IfcQuantityCount") -> None:
|
||||
def add_resource_quantity(
|
||||
file: ifcopenshell.file, resource: ifcopenshell.entity_instance, ifc_class: str = "IfcQuantityCount"
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Adds a quantity to a resource
|
||||
|
||||
The quantity of a resource represents the "unit quantity" of that
|
||||
@@ -65,6 +67,7 @@ def add_resource_quantity(file, resource=None, ifc_class="IfcQuantityCount") ->
|
||||
settings = {"resource": resource, "ifc_class": ifc_class}
|
||||
|
||||
quantity = file.create_entity(settings["ifc_class"], Name="Unnamed")
|
||||
# 3 IfcPhysicalSimpleQuantity Value
|
||||
quantity[3] = 0.0
|
||||
old_quantity = settings["resource"].BaseQuantity
|
||||
settings["resource"].BaseQuantity = quantity
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
import ifcopenshell.util.date
|
||||
|
||||
|
||||
def add_resource_time(file, resource=None) -> None:
|
||||
def add_resource_time(file: ifcopenshell.file, resource: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
|
||||
"""Adds the time that a resource is used for
|
||||
|
||||
For labour and equipment resources, the total duration that the resource
|
||||
@@ -56,10 +56,6 @@ def add_resource_time(file, resource=None) -> None:
|
||||
ifcopenshell.api.run("resource.edit_resource_time", model,
|
||||
resource_time=time, attributes={"ScheduleWork": "PT16H"})
|
||||
"""
|
||||
settings = {
|
||||
"resource": resource,
|
||||
}
|
||||
|
||||
resource_time = file.create_entity("IfcResourceTime")
|
||||
settings["resource"].Usage = resource_time
|
||||
resource.Usage = resource_time
|
||||
return resource_time
|
||||
|
||||
@@ -21,7 +21,11 @@ import ifcopenshell.api
|
||||
import ifcopenshell.guid
|
||||
|
||||
|
||||
def assign_resource(file, relating_resource=None, related_object=None) -> None:
|
||||
def assign_resource(
|
||||
file: ifcopenshell.file,
|
||||
relating_resource: ifcopenshell.entity_instance,
|
||||
related_object: ifcopenshell.entity_instance,
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Assigns a resource to an object
|
||||
|
||||
Two types of objects are typically assigned to resources: products and
|
||||
@@ -89,7 +93,7 @@ def assign_resource(file, relating_resource=None, related_object=None) -> None:
|
||||
assignment.is_a("IfclRelAssignsToResource")
|
||||
and assignment.RelatingResource == settings["relating_resource"]
|
||||
):
|
||||
return
|
||||
return assignment
|
||||
|
||||
resource_of = None
|
||||
if settings["relating_resource"].ResourceOf:
|
||||
|
||||
@@ -18,12 +18,13 @@
|
||||
|
||||
import math
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.util.constraint
|
||||
import ifcopenshell.util.date
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.resource
|
||||
|
||||
|
||||
def calculate_resource_usage(file, resource=None) -> None:
|
||||
def calculate_resource_usage(file: ifcopenshell.file, resource: ifcopenshell.entity_instance) -> None:
|
||||
"""Calculates the number of resources required to perform scheduled work on a task."""
|
||||
settings = {"resource": resource}
|
||||
|
||||
|
||||
@@ -18,12 +18,13 @@
|
||||
|
||||
import math
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.util.constraint
|
||||
import ifcopenshell.util.date
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.resource
|
||||
|
||||
|
||||
def calculate_resource_work(file, resource=None) -> None:
|
||||
def calculate_resource_work(file: ifcopenshell.file, resource: ifcopenshell.entity_instance) -> None:
|
||||
"""Calculates the work that a resource is used for
|
||||
|
||||
This is an unofficial parametric calculation that may be done on a
|
||||
@@ -55,17 +56,15 @@ def calculate_resource_work(file, resource=None) -> None:
|
||||
:return None:
|
||||
:rtype: None:
|
||||
"""
|
||||
settings = {"resource": resource}
|
||||
|
||||
if ifcopenshell.util.constraint.is_attribute_locked(settings["resource"], "Usage.ScheduleWork"):
|
||||
if ifcopenshell.util.constraint.is_attribute_locked(resource, "Usage.ScheduleWork"):
|
||||
return
|
||||
amount_worked = ifcopenshell.util.resource.get_resource_required_work(settings["resource"])
|
||||
amount_worked = ifcopenshell.util.resource.get_resource_required_work(resource)
|
||||
if not amount_worked:
|
||||
return
|
||||
if not settings["resource"].Usage:
|
||||
if not resource.Usage:
|
||||
ifcopenshell.api.run(
|
||||
"resource.add_resource_time",
|
||||
file,
|
||||
resource=settings["resource"],
|
||||
resource=resource,
|
||||
)
|
||||
settings["resource"].Usage.ScheduleWork = amount_worked
|
||||
resource.Usage.ScheduleWork = amount_worked
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
import ifcopenshell
|
||||
from typing import Any
|
||||
|
||||
|
||||
def edit_resource(file, resource=None, attributes=None) -> None:
|
||||
def edit_resource(file: ifcopenshell.file, resource: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
|
||||
"""Edits the attributes of an IfcResource
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
@@ -26,7 +28,7 @@ def edit_resource(file, resource=None, attributes=None) -> None:
|
||||
:param resource: The IfcResource entity you want to edit
|
||||
:type resource: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict, optional
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
@@ -40,7 +42,7 @@ def edit_resource(file, resource=None, attributes=None) -> None:
|
||||
# Change the name of the resource to "Zone A Crew"
|
||||
ifcopenshell.api.run("resource.edit_resource", model, resource=resource, attributes={"Name": "Foo"})
|
||||
"""
|
||||
settings = {"resource": resource, "attributes": attributes or {}}
|
||||
settings = {"resource": resource, "attributes": attributes}
|
||||
|
||||
for name, value in settings["attributes"].items():
|
||||
setattr(settings["resource"], name, value)
|
||||
|
||||
@@ -15,9 +15,13 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
import ifcopenshell
|
||||
from typing import Any
|
||||
|
||||
|
||||
def edit_resource_quantity(file, physical_quantity=None, attributes=None) -> None:
|
||||
def edit_resource_quantity(
|
||||
file: ifcopenshell.file, physical_quantity: ifcopenshell.entity_instance, attributes: dict[str, Any]
|
||||
) -> None:
|
||||
"""Edits the attributes of an IFC quantity
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
@@ -26,7 +30,7 @@ def edit_resource_quantity(file, physical_quantity=None, attributes=None) -> Non
|
||||
:param physical_quantity: The IfC quantity entity you want to edit
|
||||
:type physical_quantity: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict, optional
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
@@ -51,7 +55,7 @@ def edit_resource_quantity(file, physical_quantity=None, attributes=None) -> Non
|
||||
"""
|
||||
settings = {
|
||||
"physical_quantity": physical_quantity,
|
||||
"attributes": attributes or {},
|
||||
"attributes": attributes,
|
||||
}
|
||||
|
||||
for name, value in settings["attributes"].items():
|
||||
|
||||
@@ -18,9 +18,12 @@
|
||||
|
||||
import datetime
|
||||
import ifcopenshell
|
||||
from typing import Any
|
||||
|
||||
|
||||
def edit_resource_time(file, resource_time=None, attributes=None) -> None:
|
||||
def edit_resource_time(
|
||||
file: ifcopenshell.file, resource_time: ifcopenshell.entity_instance, attributes: dict[str, Any]
|
||||
) -> None:
|
||||
"""Edits the attributes of an IfcResourceTime
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
@@ -29,7 +32,7 @@ def edit_resource_time(file, resource_time=None, attributes=None) -> None:
|
||||
:param resource_time: The IfcResourceTime entity you want to edit
|
||||
:type resource_time: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict, optional
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
@@ -59,7 +62,7 @@ def edit_resource_time(file, resource_time=None, attributes=None) -> None:
|
||||
"""
|
||||
usecase = Usecase()
|
||||
usecase.file = file
|
||||
usecase.settings = {"resource_time": resource_time, "attributes": attributes or {}}
|
||||
usecase.settings = {"resource_time": resource_time, "attributes": attributes}
|
||||
return usecase.execute()
|
||||
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ import ifcopenshell.api
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def remove_resource(file, resource=None) -> None:
|
||||
def remove_resource(file: ifcopenshell.file, resource: ifcopenshell.entity_instance) -> None:
|
||||
"""Removes a resource and all relationships
|
||||
|
||||
Example:
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def remove_resource_quantity(file, resource=None) -> None:
|
||||
def remove_resource_quantity(file: ifcopenshell.file, resource: ifcopenshell.entity_instance) -> None:
|
||||
"""Removes the base quantity of a resource
|
||||
|
||||
Example:
|
||||
|
||||
@@ -21,7 +21,11 @@ import ifcopenshell.api
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def unassign_resource(file, relating_resource=None, related_object=None) -> None:
|
||||
def unassign_resource(
|
||||
file: ifcopenshell.file,
|
||||
relating_resource: ifcopenshell.entity_instance,
|
||||
related_object: ifcopenshell.entity_instance,
|
||||
) -> None:
|
||||
"""Removes the relationship between a resource and object
|
||||
|
||||
:param relating_resource: The IfcResource to assign the object to.
|
||||
@@ -29,8 +33,8 @@ def unassign_resource(file, relating_resource=None, related_object=None) -> None
|
||||
:param related_object: The IfcProduct or IfcActor to assign to the
|
||||
object.
|
||||
:type related_object: ifcopenshell.entity_instance
|
||||
:return: The newly created IfcRelAssignsToResource
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
Example:
|
||||
|
||||
@@ -74,4 +78,3 @@ def unassign_resource(file, relating_resource=None, related_object=None) -> None
|
||||
related_objects.remove(settings["related_object"])
|
||||
rel.RelatedObjects = related_objects
|
||||
ifcopenshell.api.run("owner.update_owner_history", file, **{"element": rel})
|
||||
return rel
|
||||
|
||||
@@ -17,11 +17,13 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.util.system
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.placement
|
||||
|
||||
|
||||
def copy_class(file, product=None) -> None:
|
||||
def copy_class(file: ifcopenshell.file, product: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
|
||||
"""Copies a product
|
||||
|
||||
The following relationships are also duplicated:
|
||||
|
||||
@@ -20,14 +20,15 @@ import ifcopenshell
|
||||
import ifcopenshell.util.type
|
||||
import ifcopenshell.util.schema
|
||||
import ifcopenshell.util.element
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def reassign_class(
|
||||
file,
|
||||
product=None,
|
||||
ifc_class="IfcBuildingElementProxy",
|
||||
predefined_type=None,
|
||||
) -> None:
|
||||
file: ifcopenshell.file,
|
||||
product: ifcopenshell.entity_instance,
|
||||
ifc_class: str = "IfcBuildingElementProxy",
|
||||
predefined_type: Optional[str] = None,
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Changes the class of a product
|
||||
|
||||
If you ever created a wall then realised it's meant to be something
|
||||
|
||||
@@ -183,6 +183,14 @@ def remove_product(file: ifcopenshell.file, product: ifcopenshell.entity_instanc
|
||||
file.remove(inverse)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
elif inverse.is_a("IfcRelConnectsPortToElement"):
|
||||
if inverse.RelatedElement == settings["product"]:
|
||||
ifcopenshell.api.run("root.remove_product", file, product=inverse.RelatingPort)
|
||||
elif inverse.RelatingPort == settings["product"]:
|
||||
history = inverse.OwnerHistory
|
||||
file.remove(inverse)
|
||||
if history:
|
||||
ifcopenshell.util.element.remove_deep2(file, history)
|
||||
elif inverse.is_a("IfcRelConnectsPorts"):
|
||||
if settings["product"] not in (inverse.RelatingPort, inverse.RelatedPort):
|
||||
# if it's not RelatingPort/RelatedPort then it's optional RealizingElement
|
||||
|
||||
@@ -49,7 +49,6 @@ from .edit_work_calendar import edit_work_calendar
|
||||
from .edit_work_plan import edit_work_plan
|
||||
from .edit_work_schedule import edit_work_schedule
|
||||
from .edit_work_time import edit_work_time
|
||||
from .get_related_products import get_related_products
|
||||
|
||||
try:
|
||||
from .recalculate_schedule import recalculate_schedule
|
||||
|
||||
@@ -19,17 +19,18 @@
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell
|
||||
import ifcopenshell.guid
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def add_task(
|
||||
file,
|
||||
work_schedule=None,
|
||||
parent_task=None,
|
||||
name=None,
|
||||
description=None,
|
||||
identification=None,
|
||||
predefined_type="NOTDEFINED",
|
||||
) -> None:
|
||||
file: ifcopenshell.file,
|
||||
work_schedule: Optional[ifcopenshell.entity_instance] = None,
|
||||
parent_task: Optional[ifcopenshell.entity_instance] = None,
|
||||
name: Optional[str] = None,
|
||||
description: Optional[str] = None,
|
||||
identification: Optional[str] = None,
|
||||
predefined_type: str = "NOTDEFINED",
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Adds a new task
|
||||
|
||||
Tasks are typically used for two purposes: construction scheduling and
|
||||
@@ -66,11 +67,11 @@ def add_task(
|
||||
:param work_schedule: The work schedule to group the task in, if the
|
||||
task is to be a top-level or root task. This is mutually exclusive
|
||||
with the parent_task parameter.
|
||||
:type work_schedule: ifcopenshell.entity_instance
|
||||
:type work_schedule: ifcopenshell.entity_instance, optional
|
||||
:param parent_task: The parent task, if the task is to be a subtask or
|
||||
child task. This is mutually exclusive with the work_schedule
|
||||
parameter.
|
||||
:type parent_task: ifcopenshell.entity_instance
|
||||
:type parent_task: ifcopenshell.entity_instance, optioanl
|
||||
:param name: The name of the task.
|
||||
:type name: str,optional
|
||||
:param description: The description of the task.
|
||||
@@ -174,6 +175,6 @@ def add_task(
|
||||
related_objects=[task],
|
||||
relating_object=settings["parent_task"],
|
||||
)
|
||||
if settings["parent_task"].Identification:
|
||||
if file.schema != "IFC2X3" and settings["parent_task"].Identification:
|
||||
task.Identification = settings["parent_task"].Identification + "." + str(len(rel.RelatedObjects))
|
||||
return task
|
||||
|
||||
@@ -15,9 +15,12 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
import ifcopenshell
|
||||
|
||||
|
||||
def add_task_time(file, task=None, is_recurring=False) -> None:
|
||||
def add_task_time(
|
||||
file: ifcopenshell.file, task: ifcopenshell.entity_instance, is_recurring: bool = False
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Adds a task time to a task
|
||||
|
||||
Some tasks, such as activities within a work breakdown structure or
|
||||
|
||||
@@ -19,11 +19,17 @@
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.util.date
|
||||
import ifcopenshell.util.sequence
|
||||
from datetime import datetime
|
||||
from datetime import datetime, time
|
||||
from datetime import timedelta
|
||||
from typing import Optional, Union
|
||||
|
||||
|
||||
def add_time_period(file, recurrence_pattern=None, start_time=None, end_time=None) -> None:
|
||||
def add_time_period(
|
||||
file: ifcopenshell.file,
|
||||
recurrence_pattern: ifcopenshell.entity_instance,
|
||||
start_time: Optional[Union[str, time]] = None,
|
||||
end_time: Optional[Union[str, time]] = None,
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Adds a time period to a recurrence pattern
|
||||
|
||||
A recurring time may be an all-day event, or only during certain time
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
import ifcopenshell.api
|
||||
|
||||
|
||||
def add_work_calendar(file, name="Unnamed", predefined_type="NOTDEFINED") -> None:
|
||||
def add_work_calendar(
|
||||
file: ifcopenshell.file, name: str = "Unnamed", predefined_type: str = "NOTDEFINED"
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Add a work calendar
|
||||
|
||||
A work calendar defines when work is allowed to occur and when the
|
||||
|
||||
@@ -17,11 +17,18 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.api.owner.settings
|
||||
import ifcopenshell.util.date
|
||||
from datetime import datetime
|
||||
from datetime import datetime, time
|
||||
from typing import Optional, Union
|
||||
|
||||
|
||||
def add_work_plan(file, name=None, predefined_type="NOTDEFINED", start_time=None) -> None:
|
||||
def add_work_plan(
|
||||
file: ifcopenshell.file,
|
||||
name: Optional[str] = None,
|
||||
predefined_type: str = "NOTDEFINED",
|
||||
start_time: Optional[Union[str, time]] = None,
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Add a new work plan
|
||||
|
||||
A work plan is a group of work schedules. Since work schedules may have
|
||||
|
||||
@@ -17,18 +17,21 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.api.owner.settings
|
||||
import ifcopenshell.util.date
|
||||
from datetime import time
|
||||
from datetime import datetime
|
||||
from typing import Union, Optional
|
||||
|
||||
|
||||
def add_work_schedule(
|
||||
file,
|
||||
name="Unnamed",
|
||||
predefined_type="NOTDEFINED",
|
||||
file: ifcopenshell.file,
|
||||
name: str = "Unnamed",
|
||||
predefined_type: str = "NOTDEFINED",
|
||||
object_type=None,
|
||||
start_time=None,
|
||||
work_plan=None,
|
||||
) -> None:
|
||||
start_time: Optional[Union[str, time]] = None,
|
||||
work_plan: Optional[ifcopenshell.entity_instance] = None,
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Add a new work schedule
|
||||
|
||||
A work schedule is a group of tasks, where the tasks are typically
|
||||
@@ -87,11 +90,17 @@ def add_work_schedule(
|
||||
predefined_type=settings["predefined_type"],
|
||||
name=settings["name"],
|
||||
)
|
||||
work_schedule.CreationDate = ifcopenshell.util.date.datetime2ifc(datetime.now(), "IfcDateTime")
|
||||
if file.schema == "IFC2X3":
|
||||
work_schedule.CreationDate = createIfcDateAndTime(file, datetime.now())
|
||||
else:
|
||||
work_schedule.CreationDate = ifcopenshell.util.date.datetime2ifc(datetime.now(), "IfcDateTime")
|
||||
user = ifcopenshell.api.owner.settings.get_user(file)
|
||||
if user:
|
||||
work_schedule.Creators = [user.ThePerson]
|
||||
work_schedule.StartTime = ifcopenshell.util.date.datetime2ifc(settings["start_time"], "IfcDateTime")
|
||||
if file.schema == "IFC2X3":
|
||||
work_schedule.StartTime = createIfcDateAndTime(file, settings["start_time"])
|
||||
else:
|
||||
work_schedule.StartTime = ifcopenshell.util.date.datetime2ifc(settings["start_time"], "IfcDateTime")
|
||||
if settings["object_type"]:
|
||||
work_schedule.ObjectType = settings["object_type"]
|
||||
if settings["work_plan"]:
|
||||
@@ -103,7 +112,7 @@ def add_work_schedule(
|
||||
"relating_object": settings["work_plan"],
|
||||
}
|
||||
)
|
||||
else:
|
||||
elif file.schema != "IFC2X3":
|
||||
# TODO: this is an ambiguity by buildingSMART
|
||||
# See https://forums.buildingsmart.org/t/is-the-ifcworkschedule-project-declaration-mutually-exclusive-to-aggregation-within-a-relating-ifcworkplan/3510
|
||||
context = file.by_type("IfcContext")[0]
|
||||
@@ -114,3 +123,12 @@ def add_work_schedule(
|
||||
relating_context=context,
|
||||
)
|
||||
return work_schedule
|
||||
|
||||
|
||||
def createIfcDateAndTime(file: ifcopenshell.file, dt: datetime):
|
||||
ifc_dt = file.create_entity("IfcDateAndTime")
|
||||
ifc_dt.DateComponent = file.create_entity(
|
||||
"IfcCalendarDate", **ifcopenshell.util.date.datetime2ifc(dt, "IfcCalendarDate")
|
||||
)
|
||||
ifc_dt.TimeComponent = file.create_entity("IfcLocalTime", **ifcopenshell.util.date.datetime2ifc(dt, "IfcLocalTime"))
|
||||
return ifc_dt
|
||||
|
||||
@@ -15,9 +15,12 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
import ifcopenshell
|
||||
|
||||
|
||||
def add_work_time(file, work_calendar=None, time_type="WorkingTimes") -> None:
|
||||
def add_work_time(
|
||||
file: ifcopenshell.file, work_calendar: ifcopenshell.entity_instance, time_type: str = "WorkingTimes"
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Add either working times or holiday times to a calendar
|
||||
|
||||
A calendar defines when work occurs by defining working times and
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
import ifcopenshell.util.date
|
||||
|
||||
|
||||
def assign_lag_time(file, rel_sequence=None, lag_value=None, duration_type="WORKTIME") -> None:
|
||||
def assign_lag_time(
|
||||
file: ifcopenshell.file, rel_sequence: ifcopenshell.entity_instance, lag_value: str, duration_type: str = "WORKTIME"
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Assign a lag time to a sequence relationship between tasks
|
||||
|
||||
A task sequence (e.g. finish to start) may optionally have a lag time
|
||||
@@ -94,3 +96,4 @@ def assign_lag_time(file, rel_sequence=None, lag_value=None, duration_type="WORK
|
||||
if settings["rel_sequence"].TimeLag and len(file.get_inverse(settings["rel_sequence"].TimeLag)) == 1:
|
||||
file.remove(settings["rel_sequence"].TimeLag)
|
||||
settings["rel_sequence"].TimeLag = lag_time
|
||||
return lag_time
|
||||
|
||||
@@ -21,7 +21,11 @@ import ifcopenshell.api
|
||||
import ifcopenshell.guid
|
||||
|
||||
|
||||
def assign_process(file, relating_process=None, related_object=None) -> None:
|
||||
def assign_process(
|
||||
file: ifcopenshell.file,
|
||||
relating_process: ifcopenshell.entity_instance,
|
||||
related_object: ifcopenshell.entity_instance,
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Assigns an object to be related to a process, typically a construction task
|
||||
|
||||
Processes work using the ICOM (Input, Controls, Outputs, Mechanisms)
|
||||
|
||||
@@ -21,7 +21,11 @@ import ifcopenshell.api
|
||||
import ifcopenshell.guid
|
||||
|
||||
|
||||
def assign_product(file, relating_product=None, related_object=None) -> None:
|
||||
def assign_product(
|
||||
file: ifcopenshell.entity_instance,
|
||||
relating_product: ifcopenshell.entity_instance,
|
||||
related_object: ifcopenshell.entity_instance,
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Assigns a product to be produced as a result of a process
|
||||
|
||||
A construction task may result in products (e.g. a wall) being
|
||||
@@ -71,7 +75,7 @@ def assign_product(file, relating_product=None, related_object=None) -> None:
|
||||
if settings["related_object"].HasAssignments:
|
||||
for assignment in settings["related_object"].HasAssignments:
|
||||
if assignment.is_a("IfcRelAssignsToProduct") and assignment.RelatingProduct == settings["relating_product"]:
|
||||
return
|
||||
return assignment
|
||||
|
||||
referenced_by = None
|
||||
if settings["relating_product"].ReferencedBy:
|
||||
|
||||
@@ -15,9 +15,12 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
import ifcopenshell
|
||||
|
||||
|
||||
def assign_recurrence_pattern(file, parent=None, recurrence_type="WEEKLY") -> None:
|
||||
def assign_recurrence_pattern(
|
||||
file: ifcopenshell.file, parent: ifcopenshell.entity_instance, recurrence_type: str = "WEEKLY"
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Define a time to recur at a particular interval
|
||||
|
||||
There are two scenarios where you might want to define a recurring time
|
||||
|
||||
@@ -22,11 +22,11 @@ import ifcopenshell.guid
|
||||
|
||||
|
||||
def assign_sequence(
|
||||
file,
|
||||
relating_process=None,
|
||||
related_process=None,
|
||||
sequence_type="FINISH_START",
|
||||
) -> None:
|
||||
file: ifcopenshell.file,
|
||||
relating_process: ifcopenshell.entity_instance,
|
||||
related_process: ifcopenshell.entity_instance,
|
||||
sequence_type: str = "FINISH_START",
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Assign a sequential relationship between tasks
|
||||
|
||||
Tasks in construction sequencing typically have sequence relationships
|
||||
|
||||
@@ -20,7 +20,9 @@ import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
|
||||
|
||||
def assign_workplan(file, work_schedule=None, work_plan=None) -> None:
|
||||
def assign_workplan(
|
||||
file: ifcopenshell.file, work_schedule: ifcopenshell.entity_instance, work_plan: ifcopenshell.entity_instance
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Assigns a work schedule to a work plan
|
||||
|
||||
Typically, work schedules would be assigned to a work plan at creation.
|
||||
|
||||
@@ -22,7 +22,7 @@ import ifcopenshell.util.date
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def calculate_task_duration(file, task=None) -> None:
|
||||
def calculate_task_duration(file: ifcopenshell.file, task: ifcopenshell.entity_instance) -> None:
|
||||
"""Calculates the task duration based on resource usage
|
||||
|
||||
If a task has labour or equipment resources assigned to it, its duration
|
||||
|
||||
@@ -21,7 +21,7 @@ import ifcopenshell.util.date
|
||||
import ifcopenshell.util.sequence
|
||||
|
||||
|
||||
def cascade_schedule(file, task=None) -> None:
|
||||
def cascade_schedule(file: ifcopenshell.file, task: ifcopenshell.entity_instance) -> None:
|
||||
"""Cascades start and end dates of tasks based on durations
|
||||
|
||||
Given a start task with a start date and duration, the end date, and the
|
||||
|
||||
@@ -17,12 +17,17 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.guid
|
||||
import ifcopenshell.util.system
|
||||
import ifcopenshell.util.element
|
||||
import ifcopenshell.util.sequence
|
||||
import ifcopenshell.util.system
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def create_baseline(file, work_schedule=None, name=None) -> None:
|
||||
def create_baseline(
|
||||
file: ifcopenshell.file, work_schedule: ifcopenshell.entity_instance, name: Optional[str] = None
|
||||
) -> None:
|
||||
"""Creates a baseline for your Work Schedule
|
||||
|
||||
Using a IfcWorkSchdule having PredefinedType=PLANNED,
|
||||
@@ -38,6 +43,8 @@ def create_baseline(file, work_schedule=None, name=None) -> None:
|
||||
|
||||
:param work_schedule: The planned work_schedule to baseline
|
||||
:type work_schedule: ifcopenshell.entity_instance
|
||||
:param name: baseline work schedule name
|
||||
:type name: str, optional
|
||||
:return: The baseline work_schedule
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ import ifcopenshell.util.element
|
||||
import ifcopenshell.util.sequence
|
||||
|
||||
|
||||
def duplicate_task(file, task=None) -> None:
|
||||
def duplicate_task(file: ifcopenshell.file, task: ifcopenshell.entity_instance) -> ifcopenshell.entity_instance:
|
||||
"""Duplicates a task in the project
|
||||
|
||||
The following relationships are also duplicated:
|
||||
|
||||
@@ -18,9 +18,10 @@
|
||||
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.util.date
|
||||
from typing import Any
|
||||
|
||||
|
||||
def edit_lag_time(file, lag_time=None, attributes=None) -> None:
|
||||
def edit_lag_time(file: ifcopenshell.file, lag_time: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
|
||||
"""Edits the attributes of an IfcLagTime
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
@@ -29,7 +30,7 @@ def edit_lag_time(file, lag_time=None, attributes=None) -> None:
|
||||
:param lag_time: The IfcLagTime entity you want to edit
|
||||
:type lag_time: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict, optional
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
@@ -74,7 +75,7 @@ def edit_lag_time(file, lag_time=None, attributes=None) -> None:
|
||||
# Or, let's make it 2 days instead.
|
||||
ifcopenshell.api.run("sequence.edit_lag_time", model, lag_time=lag, attributes={"LagValue": "P2D"})
|
||||
"""
|
||||
settings = {"lag_time": lag_time, "attributes": attributes or {}}
|
||||
settings = {"lag_time": lag_time, "attributes": attributes}
|
||||
|
||||
for name, value in settings["attributes"].items():
|
||||
if name == "LagValue" and value is not None:
|
||||
|
||||
@@ -18,9 +18,12 @@
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.util.sequence
|
||||
from typing import Any
|
||||
|
||||
|
||||
def edit_recurrence_pattern(file, recurrence_pattern=None, attributes=None) -> None:
|
||||
def edit_recurrence_pattern(
|
||||
file: ifcopenshell.file, recurrence_pattern: ifcopenshell.entity_instance, attributes: dict[str, Any]
|
||||
) -> None:
|
||||
"""Edits the attributes of an IfcRecurrencePattern
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
@@ -29,7 +32,7 @@ def edit_recurrence_pattern(file, recurrence_pattern=None, attributes=None) -> N
|
||||
:param recurrence_pattern: The IfcRecurrencePattern entity you want to edit
|
||||
:type recurrence_pattern: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict, optional
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
@@ -54,7 +57,7 @@ def edit_recurrence_pattern(file, recurrence_pattern=None, attributes=None) -> N
|
||||
"""
|
||||
settings = {
|
||||
"recurrence_pattern": recurrence_pattern,
|
||||
"attributes": attributes or {},
|
||||
"attributes": attributes,
|
||||
}
|
||||
|
||||
for name, value in settings["attributes"].items():
|
||||
|
||||
@@ -18,9 +18,12 @@
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
from typing import Any
|
||||
|
||||
|
||||
def edit_sequence(file, rel_sequence=None, attributes=None) -> None:
|
||||
def edit_sequence(
|
||||
file: ifcopenshell.file, rel_sequence: ifcopenshell.entity_instance, attributes: dict[str, Any]
|
||||
) -> None:
|
||||
"""Edits the attributes of an IfcRelSequence
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
@@ -29,7 +32,7 @@ def edit_sequence(file, rel_sequence=None, attributes=None) -> None:
|
||||
:param rel_sequence: The IfcRelSequence entity you want to edit
|
||||
:type rel_sequence: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict, optional
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
@@ -59,7 +62,7 @@ def edit_sequence(file, rel_sequence=None, attributes=None) -> None:
|
||||
ifcopenshell.api.run("sequence.edit_sequence", model,
|
||||
rel_sequence=sequence, attributes={"SequenceType": "START_START"})
|
||||
"""
|
||||
settings = {"rel_sequence": rel_sequence, "attributes": attributes or {}}
|
||||
settings = {"rel_sequence": rel_sequence, "attributes": attributes}
|
||||
|
||||
for name, value in settings["attributes"].items():
|
||||
setattr(settings["rel_sequence"], name, value)
|
||||
|
||||
@@ -15,9 +15,11 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
import ifcopenshell
|
||||
from typing import Any
|
||||
|
||||
|
||||
def edit_task(file, task=None, attributes=None) -> None:
|
||||
def edit_task(file: ifcopenshell.file, task: ifcopenshell.entity_instance, attributes: dict[str, Any]) -> None:
|
||||
"""Edits the attributes of an IfcTask
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
@@ -26,7 +28,7 @@ def edit_task(file, task=None, attributes=None) -> None:
|
||||
:param task: The IfcTask entity you want to edit
|
||||
:type task: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict, optional
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
|
||||
@@ -20,13 +20,13 @@ import datetime
|
||||
import ifcopenshell.util.constraint
|
||||
import ifcopenshell.util.date
|
||||
import ifcopenshell.util.sequence
|
||||
from typing import Any, Optional
|
||||
from typing import Any
|
||||
|
||||
|
||||
def edit_task_time(
|
||||
file: ifcopenshell.file,
|
||||
task_time: ifcopenshell.entity_instance,
|
||||
attributes: Optional[dict[str, Any]] = None,
|
||||
attributes: dict[str, Any],
|
||||
) -> None:
|
||||
"""Edits the attributes of an IfcTaskTime
|
||||
|
||||
@@ -36,7 +36,7 @@ def edit_task_time(
|
||||
:param task_time: The IfcTaskTime entity you want to edit
|
||||
:type task_time: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict, optional
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
@@ -59,7 +59,7 @@ def edit_task_time(
|
||||
"""
|
||||
usecase = Usecase()
|
||||
usecase.file = file
|
||||
usecase.settings = {"task_time": task_time, "attributes": attributes or {}}
|
||||
usecase.settings = {"task_time": task_time, "attributes": attributes}
|
||||
return usecase.execute()
|
||||
|
||||
|
||||
|
||||
@@ -15,9 +15,13 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
import ifcopenshell
|
||||
from typing import Any
|
||||
|
||||
|
||||
def edit_work_calendar(file, work_calendar=None, attributes=None) -> None:
|
||||
def edit_work_calendar(
|
||||
file: ifcopenshell.file, work_calendar: ifcopenshell.entity_instance, attributes: dict[str, Any]
|
||||
) -> None:
|
||||
"""Edits the attributes of an IfcWorkCalendar
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
@@ -26,7 +30,7 @@ def edit_work_calendar(file, work_calendar=None, attributes=None) -> None:
|
||||
:param work_calendar: The IfcWorkCalendar entity you want to edit
|
||||
:type work_calendar: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict, optional
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
@@ -41,7 +45,7 @@ def edit_work_calendar(file, work_calendar=None, attributes=None) -> None:
|
||||
ifcopenshell.api.run("sequence.edit_work_calendar", model,
|
||||
work_calendar=calendar, attributes={"Description": "Monday to Friday 8 hour days"})
|
||||
"""
|
||||
settings = {"work_calendar": work_calendar, "attributes": attributes or {}}
|
||||
settings = {"work_calendar": work_calendar, "attributes": attributes}
|
||||
|
||||
for name, value in settings["attributes"].items():
|
||||
setattr(settings["work_calendar"], name, value)
|
||||
|
||||
@@ -17,9 +17,12 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell.util.date
|
||||
from typing import Any
|
||||
|
||||
|
||||
def edit_work_plan(file, work_plan=None, attributes=None) -> None:
|
||||
def edit_work_plan(
|
||||
file: ifcopenshell.file, work_plan: ifcopenshell.entity_instance, attributes: dict[str, Any]
|
||||
) -> None:
|
||||
"""Edits the attributes of an IfcWorkPlan
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
@@ -28,7 +31,7 @@ def edit_work_plan(file, work_plan=None, attributes=None) -> None:
|
||||
:param work_plan: The IfcWorkPlan entity you want to edit
|
||||
:type work_plan: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict, optional
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
@@ -43,7 +46,7 @@ def edit_work_plan(file, work_plan=None, attributes=None) -> None:
|
||||
ifcopenshell.api.run("sequence.edit_work_plan", model,
|
||||
work_plan=work_plan, attributes={"Description": "Construction of phase 1"})
|
||||
"""
|
||||
settings = {"work_plan": work_plan, "attributes": attributes or {}}
|
||||
settings = {"work_plan": work_plan, "attributes": attributes}
|
||||
|
||||
for name, value in settings["attributes"].items():
|
||||
if value:
|
||||
|
||||
@@ -17,9 +17,12 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell.util.date
|
||||
from typing import Any
|
||||
|
||||
|
||||
def edit_work_schedule(file, work_schedule=None, attributes=None) -> None:
|
||||
def edit_work_schedule(
|
||||
file: ifcopenshell.entity_instance, work_schedule: ifcopenshell.entity_instance, attributes: dict[str, Any]
|
||||
) -> None:
|
||||
"""Edits the attributes of an IfcWorkSchedule
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
@@ -28,7 +31,7 @@ def edit_work_schedule(file, work_schedule=None, attributes=None) -> None:
|
||||
:param work_schedule: The IfcWorkSchedule entity you want to edit
|
||||
:type work_schedule: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict, optional
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
@@ -47,7 +50,7 @@ def edit_work_schedule(file, work_schedule=None, attributes=None) -> None:
|
||||
ifcopenshell.api.run("sequence.edit_work_schedule", model,
|
||||
work_schedule=work_schedule, attributes={"Description": "3 crane design option"})
|
||||
"""
|
||||
settings = {"work_schedule": work_schedule, "attributes": attributes or {}}
|
||||
settings = {"work_schedule": work_schedule, "attributes": attributes}
|
||||
|
||||
for name, value in settings["attributes"].items():
|
||||
if value:
|
||||
|
||||
@@ -17,13 +17,13 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell.util.date
|
||||
from typing import Any, Optional
|
||||
from typing import Any
|
||||
|
||||
|
||||
def edit_work_time(
|
||||
file: ifcopenshell.file,
|
||||
work_time: ifcopenshell.entity_instance,
|
||||
attributes: Optional[dict[str, Any]] = None,
|
||||
attributes: dict[str, Any],
|
||||
) -> None:
|
||||
"""Edits the attributes of an IfcWorkTime
|
||||
|
||||
@@ -33,7 +33,7 @@ def edit_work_time(
|
||||
:param work_time: The IfcWorkTime entity you want to edit
|
||||
:type work_time: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict, optional
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
|
||||
@@ -54,7 +54,7 @@ def edit_work_time(
|
||||
ifcopenshell.api.run("sequence.edit_work_time", model,
|
||||
work_time=work_time, attributes={"StartDate": "2000-01-01", "FinishDate": "2000-01-02"})
|
||||
"""
|
||||
settings = {"work_time": work_time, "attributes": attributes or {}}
|
||||
settings = {"work_time": work_time, "attributes": attributes}
|
||||
|
||||
for name, value in settings["attributes"].items():
|
||||
if name in ("Start", "StartDate"):
|
||||
|
||||
@@ -1,76 +0,0 @@
|
||||
# IfcOpenShell - IFC toolkit and geometry engine
|
||||
# Copyright (C) 2021 Dion Moult <dion@thinkmoult.com>
|
||||
#
|
||||
# This file is part of IfcOpenShell.
|
||||
#
|
||||
# IfcOpenShell is free software: you can redistribute it and/or modify
|
||||
# it under the terms of the GNU Lesser General Public License as published by
|
||||
# the Free Software Foundation, either version 3 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# IfcOpenShell is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU Lesser General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
|
||||
|
||||
def get_related_products(file, relating_product=None, related_object=None) -> None:
|
||||
"""Gets the related products being output by a task
|
||||
|
||||
This API function will be removed in the future and migrated to a
|
||||
utility module.
|
||||
|
||||
:param relating_product: One of the products already output by the task.
|
||||
:type relating_product: ifcopenshell.entity_instance
|
||||
:param related_object: The IfcTask that you want to get all the related
|
||||
products for.
|
||||
:type related_object: ifcopenshell.entity_instance
|
||||
:return: A set of IfcProducts output by the IfcTask.
|
||||
:rtype: set[ifcopenshell.entity_instance]
|
||||
|
||||
Example:
|
||||
|
||||
.. code:: python
|
||||
|
||||
# Let's imagine we are creating a construction schedule. All tasks
|
||||
# need to be part of a work schedule.
|
||||
schedule = ifcopenshell.api.run("sequence.add_work_schedule", model, name="Construction Schedule A")
|
||||
|
||||
# Let's create a construction task. Note that the predefined type is
|
||||
# important to distinguish types of tasks.
|
||||
task = ifcopenshell.api.run("sequence.add_task", model,
|
||||
work_schedule=schedule, name="Build wall", identification="A", predefined_type="CONSTRUCTION")
|
||||
|
||||
# Let's say we have a wall somewhere.
|
||||
wall = ifcopenshell.api.run("root.create_entity", model, ifc_class="IfcWall")
|
||||
|
||||
# Let's construct that wall!
|
||||
ifcopenshell.api.run("sequence.assign_product", relating_product=wall, related_object=task)
|
||||
|
||||
# This will give us a set with that wall in it.
|
||||
products = ifcopenshell.api.run("sequence.get_related_products", model, related_object=task)
|
||||
"""
|
||||
settings = {
|
||||
"relating_product": relating_product,
|
||||
"related_object": related_object,
|
||||
}
|
||||
|
||||
products = set()
|
||||
related_object = None
|
||||
if settings["related_object"]:
|
||||
related_object = settings["related_object"]
|
||||
elif settings["relating_product"]:
|
||||
for reference in settings["relating_product"].ReferencedBy:
|
||||
if reference.is_a("IfcRelAssignsToProduct"):
|
||||
related_object = reference.RelatedObjects[0]
|
||||
if related_object:
|
||||
assignments = settings["related_object"].HasAssignments
|
||||
for assignment in assignments:
|
||||
if assignment.is_a("IfcRelAssignsToProduct"):
|
||||
products.add(assignment.RelatingProduct.id())
|
||||
return products
|
||||
@@ -23,7 +23,7 @@ import ifcopenshell.util.date
|
||||
import ifcopenshell.util.sequence
|
||||
|
||||
|
||||
def recalculate_schedule(file, work_schedule=None) -> None:
|
||||
def recalculate_schedule(file: ifcopenshell.file, work_schedule: ifcopenshell.entity_instance) -> None:
|
||||
"""Calculate the critical path and floats for a work schedule
|
||||
|
||||
This implements critical path analysis, using the forward pass and
|
||||
|
||||
@@ -21,7 +21,7 @@ import ifcopenshell.api
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def remove_task(file, task=None) -> None:
|
||||
def remove_task(file: ifcopenshell.file, task: ifcopenshell.entity_instance) -> None:
|
||||
"""Removes a task
|
||||
|
||||
All subtasks are also removed recursively. Any relationships such as
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
import ifcopenshell.api
|
||||
|
||||
|
||||
def remove_time_period(file, time_period=None) -> None:
|
||||
def remove_time_period(file: ifcopenshell.file, time_period: ifcopenshell.entity_instance) -> None:
|
||||
"""Removes a time period
|
||||
|
||||
:param time_period: The IfcTimePeriod to remove.
|
||||
|
||||
@@ -17,10 +17,11 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def remove_work_calendar(file, work_calendar=None) -> None:
|
||||
def remove_work_calendar(file: ifcopenshell.file, work_calendar: ifcopenshell.entity_instance) -> None:
|
||||
"""Removes a work calendar
|
||||
|
||||
All relationships are also removed, such as if a task is set to use that
|
||||
|
||||
@@ -20,7 +20,7 @@ import ifcopenshell
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def remove_work_plan(file, work_plan=None) -> None:
|
||||
def remove_work_plan(file: ifcopenshell.entity_instance, work_plan: ifcopenshell.entity_instance) -> None:
|
||||
"""Removes a work plan
|
||||
|
||||
Note that schedules that are grouped under the work plan are not
|
||||
|
||||
@@ -21,7 +21,7 @@ import ifcopenshell.api
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def remove_work_schedule(file, work_schedule=None) -> None:
|
||||
def remove_work_schedule(file: ifcopenshell.file, work_schedule: ifcopenshell.entity_instance) -> None:
|
||||
"""Removes a work schedule
|
||||
|
||||
All tasks in the work schedule are also removed recursively.
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
import ifcopenshell
|
||||
|
||||
|
||||
def remove_work_time(file, work_time=None) -> None:
|
||||
def remove_work_time(file: ifcopenshell.file, work_time: ifcopenshell.entity_instance) -> None:
|
||||
"""Removes a work time
|
||||
|
||||
:param work_time: The IfcWorkTime to remove.
|
||||
|
||||
@@ -19,7 +19,7 @@
|
||||
import ifcopenshell.api
|
||||
|
||||
|
||||
def unassign_lag_time(file, rel_sequence=None) -> None:
|
||||
def unassign_lag_time(file: ifcopenshell.file, rel_sequence: ifcopenshell.entity_instance) -> None:
|
||||
"""Removes any lag time in a sequence
|
||||
|
||||
The schedule is cascaded afterwards.
|
||||
|
||||
@@ -21,7 +21,11 @@ import ifcopenshell.api
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def unassign_process(file, relating_process=None, related_object=None) -> None:
|
||||
def unassign_process(
|
||||
file: ifcopenshell.file,
|
||||
relating_process: ifcopenshell.entity_instance,
|
||||
related_object: ifcopenshell.entity_instance,
|
||||
) -> None:
|
||||
"""Unassigns a process and object relationship
|
||||
|
||||
See ifcopenshell.api.sequence.assign_process for details.
|
||||
|
||||
@@ -21,7 +21,11 @@ import ifcopenshell.api
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def unassign_product(file, relating_product=None, related_object=None) -> None:
|
||||
def unassign_product(
|
||||
file: ifcopenshell.file,
|
||||
relating_product: ifcopenshell.entity_instance,
|
||||
related_object: ifcopenshell.entity_instance,
|
||||
) -> None:
|
||||
"""Unassigns a product and object relationship
|
||||
|
||||
See ifcopenshell.api.sequence.assign_product for details.
|
||||
|
||||
@@ -15,9 +15,10 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
import ifcopenshell
|
||||
|
||||
|
||||
def unassign_recurrence_pattern(file, recurrence_pattern=None) -> None:
|
||||
def unassign_recurrence_pattern(file: ifcopenshell.file, recurrence_pattern: ifcopenshell.entity_instance) -> None:
|
||||
"""Unassigns a recurrence pattern
|
||||
|
||||
Note that a recurring task time must have a recurrence pattern, so if
|
||||
|
||||
@@ -21,7 +21,11 @@ import ifcopenshell.api
|
||||
import ifcopenshell.util.element
|
||||
|
||||
|
||||
def unassign_sequence(file, relating_process=None, related_process=None) -> None:
|
||||
def unassign_sequence(
|
||||
file: ifcopenshell.file,
|
||||
relating_process: ifcopenshell.entity_instance,
|
||||
related_process: ifcopenshell.entity_instance,
|
||||
) -> None:
|
||||
"""Removes a sequence relationship between tasks
|
||||
|
||||
:param relating_process: The previous / predecessor task.
|
||||
|
||||
@@ -17,15 +17,16 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell.api
|
||||
from typing import Literal
|
||||
|
||||
|
||||
def add_structural_activity(
|
||||
file,
|
||||
ifc_class="IfcStructuralPlanarAction",
|
||||
predefined_type="CONST",
|
||||
global_or_local="GLOBAL_COORDS",
|
||||
applied_load=None,
|
||||
structural_member=None,
|
||||
file: ifcopenshell.file,
|
||||
applied_load: ifcopenshell.entity_instance,
|
||||
structural_member: ifcopenshell.entity_instance,
|
||||
ifc_class: str = "IfcStructuralPlanarAction",
|
||||
predefined_type: str = "CONST",
|
||||
global_or_local: Literal["GLOBAL_COORDS", "LOCAL_COORDS"] = "GLOBAL_COORDS",
|
||||
) -> None:
|
||||
"""Adds a new structural activity
|
||||
|
||||
|
||||
+1
-3
@@ -20,7 +20,7 @@ import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
|
||||
|
||||
def add_structural_analysis_model(file) -> None:
|
||||
def add_structural_analysis_model(file: ifcopenshell.file) -> ifcopenshell.entity_instance:
|
||||
"""Add a new structural analysis model
|
||||
|
||||
A structural analysis model is a group of all the loads, reactions,
|
||||
@@ -39,8 +39,6 @@ def add_structural_analysis_model(file) -> None:
|
||||
# Create a fresh blank structural analysis
|
||||
analysis = ifcopenshell.api.run("structural.add_structural_analysis_model", model)
|
||||
"""
|
||||
settings = {}
|
||||
|
||||
return ifcopenshell.api.run(
|
||||
"root.create_entity", file, ifc_class="IfcStructuralAnalysisModel", predefined_type="LOADING_3D"
|
||||
)
|
||||
|
||||
+11
-2
@@ -15,9 +15,16 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
import ifcopenshell
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def add_structural_boundary_condition(file, name=None, connection=None, ifc_class="IfcBoundaryNodeCondition") -> None:
|
||||
def add_structural_boundary_condition(
|
||||
file: ifcopenshell.file,
|
||||
name: Optional[str] = None,
|
||||
connection: Optional[ifcopenshell.entity_instance] = None,
|
||||
ifc_class: str = "IfcBoundaryNodeCondition",
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Adds a new structural boundary condition to a structural connection
|
||||
|
||||
The type of boundary condition depends on the connection. Point
|
||||
@@ -60,7 +67,9 @@ def add_structural_boundary_condition(file, name=None, connection=None, ifc_clas
|
||||
elif related_connection.is_a("IfcStructuralSurfaceConnection"):
|
||||
boundary_class = "IfcBoundaryFaceCondition"
|
||||
|
||||
settings["connection"].AppliedCondition = file.create_entity(boundary_class, Name=settings["name"])
|
||||
condition = file.create_entity(boundary_class, Name=settings["name"])
|
||||
settings["connection"].AppliedCondition = condition
|
||||
return condition
|
||||
else:
|
||||
# add an orphan boundary condition
|
||||
return file.create_entity(settings["ifc_class"], Name=settings["name"])
|
||||
|
||||
@@ -17,9 +17,12 @@
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
import ifcopenshell.api
|
||||
from typing import Optional
|
||||
|
||||
|
||||
def add_structural_load(file, name=None, ifc_class="IfcStructuralLoadLinearForce") -> None:
|
||||
def add_structural_load(
|
||||
file: ifcopenshell.file, name: Optional[str] = None, ifc_class: str = "IfcStructuralLoadLinearForce"
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Adds a new structural load
|
||||
|
||||
Structural loads may be actions or reactions. A simple load might be a
|
||||
@@ -42,9 +45,4 @@ def add_structural_load(file, name=None, ifc_class="IfcStructuralLoadLinearForce
|
||||
# Create a simple linear load
|
||||
ifcopenshell.api.run("structural.add_structural_load", model)
|
||||
"""
|
||||
settings = {
|
||||
"name": name,
|
||||
"ifc_class": ifc_class,
|
||||
}
|
||||
|
||||
return file.create_entity(settings["ifc_class"], Name=settings["name"])
|
||||
return file.create_entity(ifc_class, Name=name)
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
import ifcopenshell.api
|
||||
|
||||
|
||||
def add_structural_load_case(file, name="Unnamed", action_type="NOTDEFINED", action_source="NOTDEFINED") -> None:
|
||||
def add_structural_load_case(
|
||||
file: ifcopenshell.file, name: str = "Unnamed", action_type: str = "NOTDEFINED", action_source: str = "NOTDEFINED"
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Adds a new load case, which is a collection of related load groups
|
||||
|
||||
:param name: The name of the load case
|
||||
@@ -34,19 +36,14 @@ def add_structural_load_case(file, name="Unnamed", action_type="NOTDEFINED", act
|
||||
:return: The new IfcStructuralLoadCase
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
"""
|
||||
settings = {
|
||||
"name": name,
|
||||
"action_type": action_type,
|
||||
"action_source": action_source,
|
||||
}
|
||||
|
||||
load_case = ifcopenshell.api.run(
|
||||
"root.create_entity",
|
||||
file,
|
||||
ifc_class="IfcStructuralLoadCase",
|
||||
predefined_type="LOAD_CASE",
|
||||
name=settings["name"],
|
||||
name=name
|
||||
)
|
||||
load_case.ActionType = settings["action_type"]
|
||||
load_case.ActionSource = settings["action_source"]
|
||||
load_case.ActionType = action_type
|
||||
load_case.ActionSource = action_source
|
||||
return load_case
|
||||
|
||||
@@ -19,7 +19,9 @@
|
||||
import ifcopenshell.api
|
||||
|
||||
|
||||
def add_structural_load_group(file, name="Unnamed", action_type="NOTDEFINED", action_source="NOTDEFINED") -> None:
|
||||
def add_structural_load_group(
|
||||
file: ifcopenshell.file, name: str = "Unnamed", action_type: str = "NOTDEFINED", action_source: str = "NOTDEFINED"
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Adds a new load group, which is a collection of related loads
|
||||
|
||||
:param name: The name of the load group
|
||||
@@ -34,19 +36,14 @@ def add_structural_load_group(file, name="Unnamed", action_type="NOTDEFINED", ac
|
||||
:return: The new IfcStructuralLoadCase
|
||||
:rtype: ifcopenshell.entity_instance
|
||||
"""
|
||||
settings = {
|
||||
"name": name,
|
||||
"action_type": action_type,
|
||||
"action_source": action_source,
|
||||
}
|
||||
|
||||
load_group = ifcopenshell.api.run(
|
||||
"root.create_entity",
|
||||
file,
|
||||
ifc_class="IfcStructuralLoadGroup",
|
||||
predefined_type="LOAD_GROUP",
|
||||
name=settings["name"],
|
||||
name=name,
|
||||
)
|
||||
load_group.ActionType = settings["action_type"]
|
||||
load_group.ActionSource = settings["action_source"]
|
||||
load_group.ActionType = action_type
|
||||
load_group.ActionSource = action_source
|
||||
return load_group
|
||||
|
||||
+6
-2
@@ -20,7 +20,11 @@ import ifcopenshell
|
||||
import ifcopenshell.api
|
||||
|
||||
|
||||
def add_structural_member_connection(file, relating_structural_member=None, related_structural_connection=None) -> None:
|
||||
def add_structural_member_connection(
|
||||
file: ifcopenshell.file,
|
||||
relating_structural_member: ifcopenshell.entity_instance,
|
||||
related_structural_connection: ifcopenshell.entity_instance,
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Relates a structural member and a structural connection
|
||||
|
||||
:param relating_structural_member: The IfcStructuralMember to have a
|
||||
@@ -39,7 +43,7 @@ def add_structural_member_connection(file, relating_structural_member=None, rela
|
||||
|
||||
for connection in settings["related_structural_connection"].ConnectsStructuralMembers or []:
|
||||
if connection.RelatingStructuralMember == settings["relating_structural_member"]:
|
||||
return
|
||||
return connection
|
||||
rel = ifcopenshell.api.run("root.create_entity", file, ifc_class="IfcRelConnectsStructuralMember")
|
||||
rel.RelatingStructuralMember = settings["relating_structural_member"]
|
||||
rel.RelatedStructuralConnection = settings["related_structural_connection"]
|
||||
|
||||
+6
-1
@@ -21,7 +21,11 @@ import ifcopenshell.api
|
||||
import ifcopenshell.guid
|
||||
|
||||
|
||||
def assign_structural_analysis_model(file, product=None, structural_analysis_model=None) -> None:
|
||||
def assign_structural_analysis_model(
|
||||
file: ifcopenshell.file,
|
||||
product: ifcopenshell.entity_instance,
|
||||
structural_analysis_model: ifcopenshell.entity_instance,
|
||||
) -> ifcopenshell.entity_instance:
|
||||
"""Assigns a load or structural member to an analysis model
|
||||
|
||||
:param product: The structural element that is part of the analysis.
|
||||
@@ -52,3 +56,4 @@ def assign_structural_analysis_model(file, product=None, structural_analysis_mod
|
||||
related_objects.add(settings["product"])
|
||||
rel.RelatedObjects = list(related_objects)
|
||||
ifcopenshell.api.run("owner.update_owner_history", file, **{"element": rel})
|
||||
return rel
|
||||
|
||||
+6
-2
@@ -15,9 +15,13 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
import ifcopenshell
|
||||
from typing import Any
|
||||
|
||||
|
||||
def edit_structural_analysis_model(file, structural_analysis_model=None, attributes=None) -> None:
|
||||
def edit_structural_analysis_model(
|
||||
file: ifcopenshell.file, structural_analysis_model: ifcopenshell.entity_instance, attributes: dict[str, Any]
|
||||
) -> None:
|
||||
"""Edits the attributes of an IfcStructuralAnalysisModel
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
@@ -26,7 +30,7 @@ def edit_structural_analysis_model(file, structural_analysis_model=None, attribu
|
||||
:param structural_analysis_model: The IfcStructuralAnalysisModel entity you want to edit
|
||||
:type structural_analysis_model: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict, optional
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
"""
|
||||
|
||||
+7
-3
@@ -15,9 +15,13 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
import ifcopenshell
|
||||
from typing import Any
|
||||
|
||||
|
||||
def edit_structural_boundary_condition(file, condition=None, attributes=None) -> None:
|
||||
def edit_structural_boundary_condition(
|
||||
file: ifcopenshell.file, condition: ifcopenshell.entity_instance, attributes: dict[str, Any]
|
||||
) -> None:
|
||||
"""Edits the attributes of an IfcBoundaryCondition
|
||||
|
||||
For more information about the attributes and data types of an
|
||||
@@ -26,11 +30,11 @@ def edit_structural_boundary_condition(file, condition=None, attributes=None) ->
|
||||
:param condition: The IfcBoundaryCondition entity you want to edit
|
||||
:type condition: ifcopenshell.entity_instance
|
||||
:param attributes: a dictionary of attribute names and values.
|
||||
:type attributes: dict, optional
|
||||
:type attributes: dict
|
||||
:return: None
|
||||
:rtype: None
|
||||
"""
|
||||
settings = {"condition": condition, "attributes": attributes or {}}
|
||||
settings = {"condition": condition, "attributes": attributes}
|
||||
|
||||
for name, data in settings["attributes"].items():
|
||||
if data["type"] == "string" or data["type"] == "null":
|
||||
|
||||
+13
-7
@@ -15,26 +15,32 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
import ifcopenshell
|
||||
|
||||
|
||||
def edit_structural_connection_cs(file, structural_item=None, axis=None, ref_direction=None) -> None:
|
||||
def edit_structural_connection_cs(
|
||||
file: ifcopenshell.file,
|
||||
structural_item: ifcopenshell.entity_instance,
|
||||
axis: tuple[float, float, float] = (0.0, 0.0, 1.0),
|
||||
ref_direction: tuple[float, float, float] = (1.0, 0.0, 0.0),
|
||||
) -> None:
|
||||
"""Edits the coordinate system of a structural connection
|
||||
|
||||
:param structural_item: The IfcStructuralItem you want to modify.
|
||||
:type structural_item: ifcopenshell.entity_instance
|
||||
:param axis: The unit Z axis vector defined as a list of 3 floats.
|
||||
Defaults to [0., 0., 1.].
|
||||
:type axis: list[float]
|
||||
Defaults to (0., 0., 1.).
|
||||
:type axis: tuple[float, float, float]
|
||||
:param ref_direction: The unit X axis vector defined as a list of 3
|
||||
floats. Defaults to [1., 0., 0.].
|
||||
:type ref_direction: list[float]
|
||||
floats. Defaults to (1., 0., 0.).
|
||||
:type ref_direction: tuple[float, float, float]
|
||||
:return: None
|
||||
:rtype: None
|
||||
"""
|
||||
settings = {
|
||||
"structural_item": structural_item,
|
||||
"axis": axis or [0.0, 0.0, 1.0],
|
||||
"ref_direction": ref_direction or [1.0, 0.0, 0.0],
|
||||
"axis": axis,
|
||||
"ref_direction": ref_direction,
|
||||
}
|
||||
|
||||
if settings["structural_item"].ConditionCoordinateSystem is None:
|
||||
|
||||
@@ -15,20 +15,25 @@
|
||||
#
|
||||
# You should have received a copy of the GNU Lesser General Public License
|
||||
# along with IfcOpenShell. If not, see <http://www.gnu.org/licenses/>.
|
||||
import ifcopenshell
|
||||
|
||||
|
||||
def edit_structural_item_axis(file, structural_item=None, axis=None) -> None:
|
||||
def edit_structural_item_axis(
|
||||
file: ifcopenshell.file,
|
||||
structural_item: ifcopenshell.entity_instance,
|
||||
axis: tuple[float, float, float] = (0.0, 0.0, 1.0),
|
||||
) -> None:
|
||||
"""Edits the coordinate system of a structural connection
|
||||
|
||||
:param structural_item: The IfcStructuralItem you want to modify.
|
||||
:type structural_item: ifcopenshell.entity_instance
|
||||
:param axis: The unit Z axis vector defined as a list of 3 floats.
|
||||
Defaults to [0., 0., 1.].
|
||||
:type axis: list[float]
|
||||
Defaults to (0., 0., 1.).
|
||||
:type axis: tuple[float, float, float]
|
||||
:return: None
|
||||
:rtype: None
|
||||
"""
|
||||
settings = {"structural_item": structural_item, "axis": axis or [0.0, 0.0, 1.0]}
|
||||
settings = {"structural_item": structural_item, "axis": axis}
|
||||
|
||||
if len(file.get_inverse(settings["structural_item"].Axis)) == 1:
|
||||
file.remove(settings["structural_item"].Axis)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user