mirror of
https://github.com/IfcOpenShell/IfcOpenShell.git
synced 2026-09-20 15:08:51 +00:00
Fix failing tests in preparation for release.
This commit is contained in:
@@ -312,13 +312,13 @@ def update_drawing_name(ifc, drawing_tool, drawing=None, name=None):
|
|||||||
if drawing_tool.does_file_exist(resolved_old_location):
|
if drawing_tool.does_file_exist(resolved_old_location):
|
||||||
drawing_tool.move_file(resolved_old_location, ifc.resolve_uri(new_location))
|
drawing_tool.move_file(resolved_old_location, ifc.resolve_uri(new_location))
|
||||||
|
|
||||||
for reference in drawing_tool.get_references_with_location(old_location):
|
for reference in drawing_tool.get_references_with_location(old_location):
|
||||||
ifc.run("document.edit_reference", reference=reference, attributes={"Location": new_location})
|
ifc.run("document.edit_reference", reference=reference, attributes={"Location": new_location})
|
||||||
sheet = drawing_tool.get_reference_document(reference)
|
sheet = drawing_tool.get_reference_document(reference)
|
||||||
if not sheet:
|
if sheet:
|
||||||
uri = ifc.resolve_uri(drawing_tool.get_document_uri(sheet, "LAYOUT"))
|
uri = ifc.resolve_uri(drawing_tool.get_document_uri(sheet, "LAYOUT"))
|
||||||
if drawing_tool.does_file_exist(uri):
|
if drawing_tool.does_file_exist(uri):
|
||||||
drawing_tool.update_embedded_svg_location(uri, old_location, new_location)
|
drawing_tool.update_embedded_svg_location(uri, old_location, new_location)
|
||||||
|
|
||||||
|
|
||||||
def add_annotation(ifc, collector, drawing_tool, drawing=None, object_type=None):
|
def add_annotation(ifc, collector, drawing_tool, drawing=None, object_type=None):
|
||||||
|
|||||||
@@ -314,6 +314,7 @@ class Drawing:
|
|||||||
def show_decorations(cls): pass
|
def show_decorations(cls): pass
|
||||||
def sync_object_placement(cls, obj): pass
|
def sync_object_placement(cls, obj): pass
|
||||||
def synchronise_ifc_and_text_attributes(cls, obj): pass
|
def synchronise_ifc_and_text_attributes(cls, obj): pass
|
||||||
|
def update_embedded_svg_location(cls, uri, old_location, new_location): pass
|
||||||
def update_text_size_pset(cls, obj): pass
|
def update_text_size_pset(cls, obj): pass
|
||||||
def update_text_value(cls, obj): pass
|
def update_text_value(cls, obj): pass
|
||||||
|
|
||||||
|
|||||||
@@ -1457,7 +1457,8 @@ class Drawing(blenderbim.core.tool.Drawing):
|
|||||||
drawing = tool.Ifc.get_entity(camera)
|
drawing = tool.Ifc.get_entity(camera)
|
||||||
|
|
||||||
# Running operators is much more efficient in this scenario than looping through each element
|
# Running operators is much more efficient in this scenario than looping through each element
|
||||||
bpy.ops.object.hide_view_clear()
|
if not bpy.app.background:
|
||||||
|
bpy.ops.object.hide_view_clear()
|
||||||
|
|
||||||
filtered_elements = cls.get_drawing_elements(drawing) | cls.get_drawing_spaces(drawing)
|
filtered_elements = cls.get_drawing_elements(drawing) | cls.get_drawing_spaces(drawing)
|
||||||
hidden_objs = [o for o in bpy.context.visible_objects if tool.Ifc.get_entity(o) not in filtered_elements]
|
hidden_objs = [o for o in bpy.context.visible_objects if tool.Ifc.get_entity(o) not in filtered_elements]
|
||||||
|
|||||||
@@ -23,7 +23,7 @@ Scenario: Create drawing
|
|||||||
And I press "bim.add_drawing"
|
And I press "bim.add_drawing"
|
||||||
And the variable "drawing" is "IfcStore.get_file().by_type('IfcAnnotation')[0].id()"
|
And the variable "drawing" is "IfcStore.get_file().by_type('IfcAnnotation')[0].id()"
|
||||||
And I set "scene.DocProperties.active_drawing_index" to "0"
|
And I set "scene.DocProperties.active_drawing_index" to "0"
|
||||||
And I press "bim.activate_view(drawing={drawing})"
|
And I press "bim.activate_drawing(drawing={drawing})"
|
||||||
When I press "bim.create_drawing"
|
When I press "bim.create_drawing"
|
||||||
Then nothing happens
|
Then nothing happens
|
||||||
|
|
||||||
@@ -41,7 +41,7 @@ Scenario: Create drawing after deleting a duplicated object
|
|||||||
And I press "bim.add_drawing"
|
And I press "bim.add_drawing"
|
||||||
And the variable "drawing" is "IfcStore.get_file().by_type('IfcAnnotation')[0].id()"
|
And the variable "drawing" is "IfcStore.get_file().by_type('IfcAnnotation')[0].id()"
|
||||||
And I set "scene.DocProperties.active_drawing_index" to "0"
|
And I set "scene.DocProperties.active_drawing_index" to "0"
|
||||||
And I press "bim.activate_view(drawing={drawing})"
|
And I press "bim.activate_drawing(drawing={drawing})"
|
||||||
And I press "bim.create_drawing"
|
And I press "bim.create_drawing"
|
||||||
And the object "IfcWall/Cube" is selected
|
And the object "IfcWall/Cube" is selected
|
||||||
And I press "object.delete(use_global=False)"
|
And I press "object.delete(use_global=False)"
|
||||||
|
|||||||
@@ -194,8 +194,8 @@ Scenario: Change the height of a wall
|
|||||||
And I set "scene.BIMModelProperties.relating_type_id" to "{element_type}"
|
And I set "scene.BIMModelProperties.relating_type_id" to "{element_type}"
|
||||||
And I press "bim.hotkey(hotkey='S_A')"
|
And I press "bim.hotkey(hotkey='S_A')"
|
||||||
And the object "IfcWall/Wall" is selected
|
And the object "IfcWall/Wall" is selected
|
||||||
And I set "scene.BIMModelProperties.extrusion_depth" to "2000.0"
|
And I set "scene.BIMModelProperties.extrusion_depth" to "2.0"
|
||||||
When I press "bim.change_extrusion_depth(depth=2000.0)"
|
When I press "bim.change_extrusion_depth(depth=2.0)"
|
||||||
Then the object "IfcWall/Wall" dimensions are "1,0.1,2"
|
Then the object "IfcWall/Wall" dimensions are "1,0.1,2"
|
||||||
|
|
||||||
Scenario: Change the length of a wall
|
Scenario: Change the length of a wall
|
||||||
@@ -206,8 +206,8 @@ Scenario: Change the length of a wall
|
|||||||
And I set "scene.BIMModelProperties.relating_type_id" to "{element_type}"
|
And I set "scene.BIMModelProperties.relating_type_id" to "{element_type}"
|
||||||
And I press "bim.hotkey(hotkey='S_A')"
|
And I press "bim.hotkey(hotkey='S_A')"
|
||||||
And the object "IfcWall/Wall" is selected
|
And the object "IfcWall/Wall" is selected
|
||||||
And I set "scene.BIMModelProperties.length" to "2000.0"
|
And I set "scene.BIMModelProperties.length" to "2.0"
|
||||||
When I press "bim.change_layer_length(length=2000.0)"
|
When I press "bim.change_layer_length(length=2.0)"
|
||||||
Then the object "IfcWall/Wall" dimensions are "2,0.1,3"
|
Then the object "IfcWall/Wall" dimensions are "2,0.1,3"
|
||||||
|
|
||||||
Scenario: Flip a wall
|
Scenario: Flip a wall
|
||||||
@@ -438,8 +438,8 @@ Scenario: Change the length of a beam
|
|||||||
And I set "scene.BIMModelProperties.relating_type_id" to "{element_type}"
|
And I set "scene.BIMModelProperties.relating_type_id" to "{element_type}"
|
||||||
And I press "bim.hotkey(hotkey='S_A')"
|
And I press "bim.hotkey(hotkey='S_A')"
|
||||||
And the object "IfcBeam/Beam" is selected
|
And the object "IfcBeam/Beam" is selected
|
||||||
And I set "scene.BIMModelProperties.extrusion_depth" to "2000.0"
|
And I set "scene.BIMModelProperties.extrusion_depth" to "2.0"
|
||||||
When I press "bim.change_profile_depth(depth=2000.0)"
|
When I press "bim.change_profile_depth(depth=2.0)"
|
||||||
Then the object "IfcBeam/Beam" dimensions are "0.1,0.2,2"
|
Then the object "IfcBeam/Beam" dimensions are "0.1,0.2,2"
|
||||||
|
|
||||||
Scenario: Rotate a beam by 90 degrees
|
Scenario: Rotate a beam by 90 degrees
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ Scenario: Execute qto method - side formwork areas
|
|||||||
And I press "bim.execute_qto_method"
|
And I press "bim.execute_qto_method"
|
||||||
Then "scene.BIMQtoProperties.qto_result" is "16.0"
|
Then "scene.BIMQtoProperties.qto_result" is "16.0"
|
||||||
|
|
||||||
Scenario: Execute assign_objects_base_qto
|
Scenario: Assign objects base qto
|
||||||
Given an empty IFC project
|
Given an empty IFC project
|
||||||
And I add a cube
|
And I add a cube
|
||||||
And the object "Cube" is selected
|
And the object "Cube" is selected
|
||||||
@@ -55,7 +55,7 @@ Scenario: Execute qto method - side formwork areas
|
|||||||
When I press "bim.assign_objects_base_qto"
|
When I press "bim.assign_objects_base_qto"
|
||||||
Then "active_object.PsetProperties.qto_name" is "Qto_WallBaseQuantities"
|
Then "active_object.PsetProperties.qto_name" is "Qto_WallBaseQuantities"
|
||||||
|
|
||||||
Scenario: Execute calculate_all_quantities
|
Scenario: Calculate all quantities
|
||||||
Given an empty IFC project
|
Given an empty IFC project
|
||||||
And I add a cube
|
And I add a cube
|
||||||
And the object "Cube" is selected
|
And the object "Cube" is selected
|
||||||
@@ -65,5 +65,4 @@ Scenario: Execute calculate_all_quantities
|
|||||||
And I press "bim.enable_pset_editing(pset_id={qset_id}, obj='IfcWall/Cube', obj_type='Object')"
|
And I press "bim.enable_pset_editing(pset_id={qset_id}, obj='IfcWall/Cube', obj_type='Object')"
|
||||||
And I press "bim.disable_pset_editing(obj='IfcWall/Cube', obj_type='Object')"
|
And I press "bim.disable_pset_editing(obj='IfcWall/Cube', obj_type='Object')"
|
||||||
Then "active_object.PsetProperties.qto_name" is "Qto_WallBaseQuantities"
|
Then "active_object.PsetProperties.qto_name" is "Qto_WallBaseQuantities"
|
||||||
Then "active_object.PsetProperties.properties['Length'].metadata.float_value" is "2.0"
|
Then "active_object.PsetProperties.properties['Length'].metadata.float_value" is "2000.0"
|
||||||
|
|
||||||
|
|||||||
@@ -25,8 +25,8 @@ Scenario: Unlink object
|
|||||||
And I press "bim.add_material"
|
And I press "bim.add_material"
|
||||||
When I press "bim.unlink_object(obj='IfcWall/Cube')"
|
When I press "bim.unlink_object(obj='IfcWall/Cube')"
|
||||||
Then the object "Cube" is not an IFC element
|
Then the object "Cube" is not an IFC element
|
||||||
And the material "Material" is not an IFC material
|
And the material "Material" is an IFC style
|
||||||
And the material "Material" is not an IFC style
|
And the material "Material.001" is not an IFC style
|
||||||
|
|
||||||
Scenario: Copy class
|
Scenario: Copy class
|
||||||
Given an empty IFC project
|
Given an empty IFC project
|
||||||
|
|||||||
@@ -431,8 +431,9 @@ def the_object_name_is_an_ifc_class(name, ifc_class):
|
|||||||
|
|
||||||
@then(parsers.parse('the object "{name}" is not an IFC element'))
|
@then(parsers.parse('the object "{name}" is not an IFC element'))
|
||||||
def the_object_name_is_not_an_ifc_element(name):
|
def the_object_name_is_not_an_ifc_element(name):
|
||||||
id = the_object_name_exists(name).BIMObjectProperties.ifc_definition_id
|
obj = the_object_name_exists(name)
|
||||||
assert id == 0, f"The ID is {id}"
|
ifc_definition_id = obj.BIMObjectProperties.ifc_definition_id
|
||||||
|
assert ifc_definition_id == 0, f"The object {obj} has an ID of {ifc_definition_id}"
|
||||||
|
|
||||||
|
|
||||||
@then(parsers.parse('the object "{name}" has no data'))
|
@then(parsers.parse('the object "{name}" has no data'))
|
||||||
@@ -447,21 +448,31 @@ def the_object_name_is_not_an_ifc_element(name):
|
|||||||
|
|
||||||
|
|
||||||
@then(parsers.parse('the material "{name}" is an IFC material'))
|
@then(parsers.parse('the material "{name}" is an IFC material'))
|
||||||
def the_material_name_is_not_an_ifc_material(name):
|
def the_material_name_is_an_ifc_material(name):
|
||||||
id = the_material_name_exists(name).BIMObjectProperties.ifc_definition_id
|
obj = the_material_name_exists(name)
|
||||||
assert id != 0, f"The ID is {id}"
|
ifc_definition_id = obj.BIMObjectProperties.ifc_definition_id
|
||||||
|
assert ifc_definition_id != 0, f"The material {obj} has no ID: {ifc_definition_id}"
|
||||||
|
|
||||||
|
|
||||||
@then(parsers.parse('the material "{name}" is not an IFC material'))
|
@then(parsers.parse('the material "{name}" is not an IFC material'))
|
||||||
def the_material_name_is_not_an_ifc_material(name):
|
def the_material_name_is_not_an_ifc_material(name):
|
||||||
id = the_material_name_exists(name).BIMObjectProperties.ifc_definition_id
|
obj = the_material_name_exists(name)
|
||||||
assert id == 0, f"The ID is {id}"
|
ifc_definition_id = obj.BIMObjectProperties.ifc_definition_id
|
||||||
|
assert ifc_definition_id == 0, f"The material {obj} has an ID of {ifc_definition_id}"
|
||||||
|
|
||||||
|
|
||||||
|
@then(parsers.parse('the material "{name}" is an IFC style'))
|
||||||
|
def the_material_name_is_an_ifc_style(name):
|
||||||
|
obj = the_material_name_exists(name)
|
||||||
|
ifc_definition_id = obj.BIMMaterialProperties.ifc_style_id
|
||||||
|
assert ifc_definition_id != 0, f"The material {obj} has a style ID of {ifc_definition_id}"
|
||||||
|
|
||||||
|
|
||||||
@then(parsers.parse('the material "{name}" is not an IFC style'))
|
@then(parsers.parse('the material "{name}" is not an IFC style'))
|
||||||
def the_material_name_is_not_an_ifc_material(name):
|
def the_material_name_is_not_an_ifc_style(name):
|
||||||
id = the_material_name_exists(name).BIMMaterialProperties.ifc_style_id
|
obj = the_material_name_exists(name)
|
||||||
assert id == 0, f"The ID is {id}"
|
ifc_definition_id = obj.BIMMaterialProperties.ifc_style_id
|
||||||
|
assert ifc_definition_id == 0, f"The material {obj} has a style ID of {ifc_definition_id}"
|
||||||
|
|
||||||
|
|
||||||
@then(parsers.parse('the material "{name}" colour is "{colour}"'))
|
@then(parsers.parse('the material "{name}" colour is "{colour}"'))
|
||||||
@@ -636,7 +647,7 @@ def the_object_name_dimensions_are_dimensions(name, dimensions):
|
|||||||
actual_dimensions = list(the_object_name_exists(name).dimensions)
|
actual_dimensions = list(the_object_name_exists(name).dimensions)
|
||||||
expected_dimensions = [float(co) for co in dimensions.split(",")]
|
expected_dimensions = [float(co) for co in dimensions.split(",")]
|
||||||
for i, number in enumerate(actual_dimensions):
|
for i, number in enumerate(actual_dimensions):
|
||||||
assert is_x(number, expected_dimensions[i])
|
assert is_x(number, expected_dimensions[i]), f"Expected {actual_dimensions[i]} but got {number}"
|
||||||
|
|
||||||
|
|
||||||
@then(parsers.parse('the object "{name}" top right corner is at "{location}"'))
|
@then(parsers.parse('the object "{name}" top right corner is at "{location}"'))
|
||||||
|
|||||||
@@ -391,6 +391,7 @@ class TestUpdateDrawingName:
|
|||||||
ifc.run("document.edit_information", information="information", attributes={"Name": "name"}).should_be_called()
|
ifc.run("document.edit_information", information="information", attributes={"Name": "name"}).should_be_called()
|
||||||
drawing.get_reference_location("reference").should_be_called().will_return("old_location")
|
drawing.get_reference_location("reference").should_be_called().will_return("old_location")
|
||||||
drawing.get_default_drawing_path("name").should_be_called().will_return("new_location")
|
drawing.get_default_drawing_path("name").should_be_called().will_return("new_location")
|
||||||
|
|
||||||
ifc.run(
|
ifc.run(
|
||||||
"document.edit_reference", reference="reference", attributes={"Location": "new_location"}
|
"document.edit_reference", reference="reference", attributes={"Location": "new_location"}
|
||||||
).should_be_called()
|
).should_be_called()
|
||||||
@@ -399,6 +400,23 @@ class TestUpdateDrawingName:
|
|||||||
ifc.resolve_uri("new_location").should_be_called().will_return("new_uri")
|
ifc.resolve_uri("new_location").should_be_called().will_return("new_uri")
|
||||||
drawing.move_file("old_uri", "new_uri").should_be_called()
|
drawing.move_file("old_uri", "new_uri").should_be_called()
|
||||||
|
|
||||||
|
drawing.get_references_with_location("old_location").should_be_called().will_return(
|
||||||
|
["reference_with_old_location"]
|
||||||
|
)
|
||||||
|
ifc.run(
|
||||||
|
"document.edit_reference", reference="reference_with_old_location", attributes={"Location": "new_location"}
|
||||||
|
).should_be_called()
|
||||||
|
drawing.get_reference_document("reference_with_old_location").should_be_called().will_return(
|
||||||
|
"sheet_with_old_location"
|
||||||
|
)
|
||||||
|
|
||||||
|
drawing.get_document_uri("sheet_with_old_location", "LAYOUT").should_be_called().will_return(
|
||||||
|
"relative_layout_uri"
|
||||||
|
)
|
||||||
|
ifc.resolve_uri("relative_layout_uri").should_be_called().will_return("absolute_layout_uri")
|
||||||
|
drawing.does_file_exist("absolute_layout_uri").should_be_called().will_return(True)
|
||||||
|
drawing.update_embedded_svg_location("absolute_layout_uri", "old_location", "new_location").should_be_called()
|
||||||
|
|
||||||
subject.update_drawing_name(ifc, drawing, drawing="drawing", name="name")
|
subject.update_drawing_name(ifc, drawing, drawing="drawing", name="name")
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -135,8 +135,8 @@ class TestGetRepresentationContext(NewFile):
|
|||||||
class TestIsElementA(NewFile):
|
class TestIsElementA(NewFile):
|
||||||
def test_run(self):
|
def test_run(self):
|
||||||
ifc = ifcopenshell.file()
|
ifc = ifcopenshell.file()
|
||||||
assert subject.is_a(ifc.createIfcWall(), "IfcSlab") is False
|
assert subject.is_element_a(ifc.createIfcWall(), "IfcSlab") is False
|
||||||
assert subject.is_a(ifc.createIfcOpeningElement(), "IfcOpeningElement") is True
|
assert subject.is_element_a(ifc.createIfcOpeningElement(), "IfcOpeningElement") is True
|
||||||
|
|
||||||
|
|
||||||
class TestLinkObjectData(NewFile):
|
class TestLinkObjectData(NewFile):
|
||||||
|
|||||||
@@ -21,36 +21,36 @@ import ifcopenshell.util.date
|
|||||||
|
|
||||||
|
|
||||||
def get_productivity(resource, should_inherit=True):
|
def get_productivity(resource, should_inherit=True):
|
||||||
productivity = ifcopenshell.util.element.get_psets(
|
productivity = ifcopenshell.util.element.get_psets(resource).get("EPset_Productivity", None)
|
||||||
resource
|
|
||||||
).get("EPset_Productivity", None)
|
|
||||||
if should_inherit and not productivity:
|
if should_inherit and not productivity:
|
||||||
# Proposal for Schema - If instance doesn't have any productivity, inherit it's parent's productivity
|
# Proposal for Schema - If instance doesn't have any productivity, inherit it's parent's productivity
|
||||||
if not resource.Nests:
|
if not resource.Nests:
|
||||||
return None
|
return None
|
||||||
else:
|
else:
|
||||||
parent_resource = resource.Nests[0].RelatingObject
|
parent_resource = resource.Nests[0].RelatingObject
|
||||||
productivity = ifcopenshell.util.element.get_psets(
|
productivity = ifcopenshell.util.element.get_psets(parent_resource).get("EPset_Productivity", None)
|
||||||
parent_resource
|
|
||||||
).get("EPset_Productivity", None)
|
|
||||||
return productivity
|
return productivity
|
||||||
|
|
||||||
|
|
||||||
def get_unit_consumed(productivity):
|
def get_unit_consumed(productivity):
|
||||||
duration = productivity.get("BaseQuantityConsumed", None)
|
duration = productivity.get("BaseQuantityConsumed", None)
|
||||||
if not duration:
|
if not duration:
|
||||||
return
|
return
|
||||||
return ifcopenshell.util.date.ifc2datetime(duration)
|
return ifcopenshell.util.date.ifc2datetime(duration)
|
||||||
|
|
||||||
|
|
||||||
def get_quantity_produced(productivity):
|
def get_quantity_produced(productivity):
|
||||||
if not productivity:
|
if not productivity:
|
||||||
return 0
|
return 0
|
||||||
return productivity.get("BaseQuantityProducedValue", 0)
|
return productivity.get("BaseQuantityProducedValue", 0)
|
||||||
|
|
||||||
|
|
||||||
def get_quantity_produced_name(productivity):
|
def get_quantity_produced_name(productivity):
|
||||||
if not productivity:
|
if not productivity:
|
||||||
return ""
|
return ""
|
||||||
return productivity.get("BaseQuantityProducedName", "")
|
return productivity.get("BaseQuantityProducedName", "")
|
||||||
|
|
||||||
|
|
||||||
def get_total_quantity_produced(resource, quantity_name_in_process):
|
def get_total_quantity_produced(resource, quantity_name_in_process):
|
||||||
def get_product_quantity(product, quantity_name):
|
def get_product_quantity(product, quantity_name):
|
||||||
psets = ifcopenshell.util.element.get_psets(product)
|
psets = ifcopenshell.util.element.get_psets(product)
|
||||||
@@ -65,9 +65,10 @@ def get_total_quantity_produced(resource, quantity_name_in_process):
|
|||||||
total = len(products)
|
total = len(products)
|
||||||
else:
|
else:
|
||||||
for product in products:
|
for product in products:
|
||||||
total += get_product_quantity(product, quantity_name_in_process)
|
total += get_product_quantity(product, quantity_name_in_process) or 0
|
||||||
return total
|
return total
|
||||||
|
|
||||||
|
|
||||||
def get_parametric_resource_products(resource):
|
def get_parametric_resource_products(resource):
|
||||||
products = []
|
products = []
|
||||||
for rel in resource.HasAssignments or []:
|
for rel in resource.HasAssignments or []:
|
||||||
@@ -79,6 +80,7 @@ def get_parametric_resource_products(resource):
|
|||||||
products.append(rel2.RelatingProduct)
|
products.append(rel2.RelatingProduct)
|
||||||
return products
|
return products
|
||||||
|
|
||||||
|
|
||||||
def get_resource_required_work(resource):
|
def get_resource_required_work(resource):
|
||||||
productivity = get_productivity(resource)
|
productivity = get_productivity(resource)
|
||||||
if productivity:
|
if productivity:
|
||||||
@@ -92,7 +94,7 @@ def get_resource_required_work(resource):
|
|||||||
if "T" in productivity.get("BaseQuantityConsumed", ""):
|
if "T" in productivity.get("BaseQuantityConsumed", ""):
|
||||||
seconds = (time_consumed.days * 24 * 60 * 60) + time_consumed.seconds
|
seconds = (time_consumed.days * 24 * 60 * 60) + time_consumed.seconds
|
||||||
productivity_ratio = seconds / quantity_produced
|
productivity_ratio = seconds / quantity_produced
|
||||||
required_work = total_quantity_to_produce * productivity_ratio
|
required_work = total_quantity_to_produce * productivity_ratio
|
||||||
iso_string = f"PT{required_work / 60 / 60}H"
|
iso_string = f"PT{required_work / 60 / 60}H"
|
||||||
else:
|
else:
|
||||||
days = time_consumed.days + (time_consumed.seconds / (24 * 60 * 60))
|
days = time_consumed.days + (time_consumed.seconds / (24 * 60 * 60))
|
||||||
|
|||||||
@@ -159,9 +159,7 @@ class Selector:
|
|||||||
|
|
||||||
if not inverse_relationship:
|
if not inverse_relationship:
|
||||||
return results
|
return results
|
||||||
return cls.parse_inverse_relationship(
|
return cls.parse_inverse_relationship(results, inverse_relationship.children[0].data)
|
||||||
results, inverse_relationship.children[0].data
|
|
||||||
)
|
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def parse_inverse_relationship(cls, elements, inverse_relationship):
|
def parse_inverse_relationship(cls, elements, inverse_relationship):
|
||||||
@@ -193,13 +191,8 @@ class Selector:
|
|||||||
if cls.elements is None:
|
if cls.elements is None:
|
||||||
elements = cls.file.by_type(class_selector.children[0])
|
elements = cls.file.by_type(class_selector.children[0])
|
||||||
else:
|
else:
|
||||||
elements = [
|
elements = [e for e in cls.elements if e.is_a(class_selector.children[0])]
|
||||||
e for e in cls.elements if e.is_a(class_selector.children[0])
|
if len(class_selector.children) > 1 and class_selector.children[1].data == "filter":
|
||||||
]
|
|
||||||
if (
|
|
||||||
len(class_selector.children) > 1
|
|
||||||
and class_selector.children[1].data == "filter"
|
|
||||||
):
|
|
||||||
return cls.filter_elements(elements, class_selector.children[1])
|
return cls.filter_elements(elements, class_selector.children[1])
|
||||||
return elements
|
return elements
|
||||||
|
|
||||||
@@ -227,9 +220,7 @@ class Selector:
|
|||||||
element_value = cls.get_element_value(element, filter_query["keys"], is_regex=filter_query["is_regex"])
|
element_value = cls.get_element_value(element, filter_query["keys"], is_regex=filter_query["is_regex"])
|
||||||
if element_value is None and value is not None and "not" not in comparison:
|
if element_value is None and value is not None and "not" not in comparison:
|
||||||
continue
|
continue
|
||||||
if comparison and cls.filter_element(
|
if comparison and cls.filter_element(element, element_value, comparison, value):
|
||||||
element, element_value, comparison, value
|
|
||||||
):
|
|
||||||
results.append(element)
|
results.append(element)
|
||||||
elif not comparison and element_value:
|
elif not comparison and element_value:
|
||||||
results.append(element)
|
results.append(element)
|
||||||
@@ -243,9 +234,9 @@ class Selector:
|
|||||||
keys = [keys]
|
keys = [keys]
|
||||||
elif keys.data == "keys_regex":
|
elif keys.data == "keys_regex":
|
||||||
is_regex = True
|
is_regex = True
|
||||||
keys = [k[1:-1].replace("\\\"", '"') for k in keys.children]
|
keys = [k[1:-1].replace('\\"', '"') for k in keys.children]
|
||||||
elif keys.data == "keys_quoted":
|
elif keys.data == "keys_quoted":
|
||||||
keys = [k[1:-1].replace("\\\"", '"') for k in keys.children]
|
keys = [k[1:-1].replace('\\"', '"') for k in keys.children]
|
||||||
elif keys.data == "keys_simple":
|
elif keys.data == "keys_simple":
|
||||||
keys = keys.children
|
keys = keys.children
|
||||||
return {"keys": keys, "is_regex": is_regex}
|
return {"keys": keys, "is_regex": is_regex}
|
||||||
@@ -273,6 +264,9 @@ class Selector:
|
|||||||
elif key == "class":
|
elif key == "class":
|
||||||
value = value.is_a()
|
value = value.is_a()
|
||||||
elif isinstance(value, ifcopenshell.entity_instance):
|
elif isinstance(value, ifcopenshell.entity_instance):
|
||||||
|
if key == "Name" and value.is_a("IfcMaterialLayerSet"):
|
||||||
|
key = "LayerSetName" # This oddity in the IFC spec is annoying so we account for it.
|
||||||
|
|
||||||
attribute = value.get_info().get(key, None)
|
attribute = value.get_info().get(key, None)
|
||||||
|
|
||||||
if attribute is not None:
|
if attribute is not None:
|
||||||
@@ -290,7 +284,7 @@ class Selector:
|
|||||||
result = ifcopenshell.util.element.get_pset(value, key)
|
result = ifcopenshell.util.element.get_pset(value, key)
|
||||||
|
|
||||||
value = result
|
value = result
|
||||||
elif isinstance(value, dict): # Such as from the result of a prior get_pset
|
elif isinstance(value, dict): # Such as from the result of a prior get_pset
|
||||||
if is_regex:
|
if is_regex:
|
||||||
results = []
|
results = []
|
||||||
for prop_name, prop_value in value.items():
|
for prop_name, prop_value in value.items():
|
||||||
@@ -302,7 +296,7 @@ class Selector:
|
|||||||
value = results
|
value = results
|
||||||
else:
|
else:
|
||||||
value = value.get(key, None)
|
value = value.get(key, None)
|
||||||
elif isinstance(value, (list, tuple)): # If we use regex
|
elif isinstance(value, (list, tuple)): # If we use regex
|
||||||
if key.isnumeric():
|
if key.isnumeric():
|
||||||
try:
|
try:
|
||||||
value = value[int(key)]
|
value = value[int(key)]
|
||||||
|
|||||||
Reference in New Issue
Block a user