New Search and Spatial selection Tools

+ refactor sequence modules
This commit is contained in:
Sigma Dimensions
2023-02-11 11:22:40 +01:00
parent 5cfc122b79
commit d4eb56e360
10 changed files with 126 additions and 56 deletions
@@ -368,11 +368,12 @@ class AssignProduct(bpy.types.Operator, tool.Ifc.Operator):
core.assign_products( core.assign_products(
tool.Ifc, tool.Ifc,
tool.Sequence, tool.Sequence,
tool.Spatial,
task=tool.Ifc.get().by_id(self.task), task=tool.Ifc.get().by_id(self.task),
products=[tool.Ifc.get().by_id(self.relating_product)], products=[tool.Ifc.get().by_id(self.relating_product)],
) )
else: else:
core.assign_products(tool.Ifc, tool.Sequence, task=tool.Ifc.get().by_id(self.task)) core.assign_products(tool.Ifc, tool.Sequence, tool.Spatial, task=tool.Ifc.get().by_id(self.task))
class UnassignProduct(bpy.types.Operator, tool.Ifc.Operator): class UnassignProduct(bpy.types.Operator, tool.Ifc.Operator):
@@ -387,11 +388,12 @@ class UnassignProduct(bpy.types.Operator, tool.Ifc.Operator):
core.unassign_products( core.unassign_products(
tool.Ifc, tool.Ifc,
tool.Sequence, tool.Sequence,
tool.Spatial,
task=tool.Ifc.get().by_id(self.task), task=tool.Ifc.get().by_id(self.task),
products=[tool.Ifc.get().by_id(self.relating_product)], products=[tool.Ifc.get().by_id(self.relating_product)],
) )
else: else:
core.unassign_products(tool.Ifc, tool.Sequence, task=tool.Ifc.get().by_id(self.task)) core.unassign_products(tool.Ifc, tool.Sequence, tool.Spatial, task=tool.Ifc.get().by_id(self.task))
class AssignProcess(bpy.types.Operator, tool.Ifc.Operator): class AssignProcess(bpy.types.Operator, tool.Ifc.Operator):
@@ -410,11 +412,12 @@ class AssignProcess(bpy.types.Operator, tool.Ifc.Operator):
core.assign_input_products( core.assign_input_products(
tool.Ifc, tool.Ifc,
tool.Sequence, tool.Sequence,
tool.Spatial,
task=tool.Ifc.get().by_id(self.task), task=tool.Ifc.get().by_id(self.task),
products=[tool.Ifc.get().by_id(self.related_object)], products=[tool.Ifc.get().by_id(self.related_object)],
) )
else: else:
core.assign_input_products(tool.Ifc, tool.Sequence, task=tool.Ifc.get().by_id(self.task)) core.assign_input_products(tool.Ifc, tool.Sequence, tool.Spatial, task=tool.Ifc.get().by_id(self.task))
elif self.related_object_type == "CONTROL": elif self.related_object_type == "CONTROL":
pass # TODO pass # TODO
@@ -445,11 +448,17 @@ class UnassignProcess(bpy.types.Operator):
core.unassign_input_products( core.unassign_input_products(
tool.Ifc, tool.Ifc,
tool.Sequence, tool.Sequence,
tool.Spatial,
task=tool.Ifc.get().by_id(self.task), task=tool.Ifc.get().by_id(self.task),
products=[tool.Ifc.get().by_id(self.related_object)], products=[tool.Ifc.get().by_id(self.related_object)],
) )
else: else:
core.unassign_input_products(tool.Ifc, tool.Sequence, task=tool.Ifc.get().by_id(self.task)) core.unassign_input_products(
tool.Ifc,
tool.Sequence,
tool.Spatial,
task=tool.Ifc.get().by_id(self.task)
)
elif self.related_object_type == "CONTROL": elif self.related_object_type == "CONTROL":
pass # TODO pass # TODO
return {"FINISHED"} return {"FINISHED"}
@@ -945,7 +954,7 @@ class SelectTaskRelatedProducts(bpy.types.Operator, tool.Ifc.Operator):
task: bpy.props.IntProperty() task: bpy.props.IntProperty()
def _execute(self, context): def _execute(self, context):
core.select_task_outputs(tool.Ifc, tool.Sequence, task=tool.Ifc.get().by_id(self.task)) core.select_task_outputs(tool.Sequence, tool.Spatial, task=tool.Ifc.get().by_id(self.task))
class SelectTaskRelatedInputs(bpy.types.Operator, tool.Ifc.Operator): class SelectTaskRelatedInputs(bpy.types.Operator, tool.Ifc.Operator):
@@ -955,7 +964,7 @@ class SelectTaskRelatedInputs(bpy.types.Operator, tool.Ifc.Operator):
task: bpy.props.IntProperty() task: bpy.props.IntProperty()
def _execute(self, context): def _execute(self, context):
core.select_task_inputs(tool.Ifc, tool.Sequence, task=tool.Ifc.get().by_id(self.task)) core.select_task_inputs(tool.Sequence, tool.Spatial, task=tool.Ifc.get().by_id(self.task))
class VisualiseWorkScheduleDate(bpy.types.Operator): class VisualiseWorkScheduleDate(bpy.types.Operator):
@@ -1204,7 +1213,7 @@ class HighlightProductRelatedTask(bpy.types.Operator, tool.Ifc.Operator):
product_type: bpy.props.StringProperty() product_type: bpy.props.StringProperty()
def _execute(self, context): def _execute(self, context):
core.highlight_product_related_task(tool.Sequence, product_type=self.product_type) core.highlight_product_related_task(tool.Sequence, tool.Spatial, product_type=self.product_type)
class ExpandAllTasks(bpy.types.Operator, tool.Ifc.Operator): class ExpandAllTasks(bpy.types.Operator, tool.Ifc.Operator):
+10
View File
@@ -0,0 +1,10 @@
def show_all_ifc_elements(spatial):
spatial.show_scene_objects()
def search(search, spatial, query, action):
products = search.from_selector_query(query)
spatial.deselect_objects()
try:
spatial.filter_products(products, action)
except:
return "One or More Products could not be found because they are hidden in the ViewLayer"
+14 -24
View File
@@ -207,37 +207,29 @@ def unassign_successor(ifc, sequence, task=None):
sequence.load_task_properties() sequence.load_task_properties()
def assign_products(ifc, sequence, task=None, products=None): def assign_products(ifc, sequence, spatial, task=None, products=None):
if not products: for product in products or spatial.get_selected_products() or []:
products = sequence.get_selected_products()
for product in products:
ifc.run("sequence.assign_product", relating_product=product, related_object=task) ifc.run("sequence.assign_product", relating_product=product, related_object=task)
outputs = sequence.get_task_outputs(task) outputs = sequence.get_task_outputs(task)
sequence.load_task_outputs(outputs) sequence.load_task_outputs(outputs)
def unassign_products(ifc, sequence, task=None, products=None): def unassign_products(ifc, sequence, spatial, task=None, products=None):
if not products: for product in products or spatial.get_selected_products() or []:
products = sequence.get_selected_products()
for product in products:
ifc.run("sequence.unassign_product", relating_product=product, related_object=task) ifc.run("sequence.unassign_product", relating_product=product, related_object=task)
outputs = sequence.get_task_outputs(task) outputs = sequence.get_task_outputs(task)
sequence.load_task_outputs(outputs) sequence.load_task_outputs(outputs)
def assign_input_products(ifc, sequence, task=None, products=None): def assign_input_products(ifc, sequence, spatial, task=None, products=None):
if not products: for product in products or spatial.get_selected_products() or []:
products = sequence.get_selected_products()
for product in products:
ifc.run("sequence.assign_process", relating_process=task, related_object=product) ifc.run("sequence.assign_process", relating_process=task, related_object=product)
inputs = sequence.get_task_inputs(task) inputs = sequence.get_task_inputs(task)
sequence.load_task_inputs(inputs) sequence.load_task_inputs(inputs)
def unassign_input_products(ifc, sequence, task=None, products=None): def unassign_input_products(ifc, sequence, spatial, task=None, products=None):
if not products: for product in products or spatial.get_selected_products() or []:
products = sequence.get_selected_products()
for product in products:
ifc.run("sequence.unassign_process", relating_process=task, related_object=product) ifc.run("sequence.unassign_process", relating_process=task, related_object=product)
inputs = sequence.get_task_inputs(task) inputs = sequence.get_task_inputs(task)
sequence.load_task_inputs(inputs) sequence.load_task_inputs(inputs)
@@ -423,14 +415,12 @@ def disable_editing_rel_sequence(sequence):
sequence.disable_editing_rel_sequence() sequence.disable_editing_rel_sequence()
def select_task_outputs(ifc, sequence, task=None): def select_task_outputs(spatial, sequence, task=None):
outputs = sequence.get_task_outputs(task) spatial.select_products(products=sequence.get_task_outputs(task))
sequence.select_products(outputs)
def select_task_inputs(ifc, sequence, task=None): def select_task_inputs(spatial, sequence, task=None):
inputs = sequence.get_task_inputs(task) spatial.select_products(products=sequence.get_task_inputs(task))
sequence.select_products(inputs)
def recalculate_schedule(ifc, work_schedule=None): def recalculate_schedule(ifc, work_schedule=None):
@@ -457,8 +447,8 @@ def calculate_task_duration(ifc, sequence, task=None):
sequence.load_task_properties() sequence.load_task_properties()
def highlight_product_related_task(sequence, product_type=None): def highlight_product_related_task(sequence, spatial, product_type=None):
products = sequence.get_selected_products() products = spatial.get_selected_products()
if products: if products:
if product_type == "Output": if product_type == "Output":
tasks = sequence.find_related_output_tasks(products[0]) tasks = sequence.find_related_output_tasks(products[0])
+1 -4
View File
@@ -91,7 +91,4 @@ def select_similar_container(ifc, spatial, obj=None):
element = ifc.get_entity(obj) element = ifc.get_entity(obj)
if not element: if not element:
return return
for subelement in spatial.get_decomposed_elements(spatial.get_container(element)): spatial.select_products(products=spatial.get_decomposed_elements(spatial.get_container(element)))
obj = ifc.get_object(subelement)
if obj:
spatial.select_object(obj)
+13 -5
View File
@@ -498,6 +498,9 @@ class Root:
class Selector: class Selector:
def set_active(cls, obj): pass def set_active(cls, obj): pass
@interface
class Search:
def from_selector_query(cls, query): pass
@interface @interface
class Sequence: class Sequence:
@@ -548,7 +551,7 @@ class Sequence:
def get_recurrence_pattern_attributes(cls, recurrence_pattern): pass def get_recurrence_pattern_attributes(cls, recurrence_pattern): pass
def get_recurrence_pattern_times(cls): pass def get_recurrence_pattern_times(cls): pass
def get_rel_sequence_attributes(cls): pass def get_rel_sequence_attributes(cls): pass
def get_selected_products(cls): pass
def get_selected_resource(cls): pass def get_selected_resource(cls): pass
def get_start_date(cls): pass def get_start_date(cls): pass
def get_task_attribute_value(cls, attribute_name): pass def get_task_attribute_value(cls, attribute_name): pass
@@ -580,37 +583,42 @@ class Sequence:
def load_work_plan_attributes(cls, work_plan): pass def load_work_plan_attributes(cls, work_plan): pass
def load_work_schedule_attributes(cls, work_schedule): pass def load_work_schedule_attributes(cls, work_schedule): pass
def load_work_time_attributes(cls, work_time): pass def load_work_time_attributes(cls, work_time): pass
def override_end_date(cls): pass
def process_construction_state(cls, work_schedule, date): pass def process_construction_state(cls, work_schedule, date): pass
def process_task_status(cls, task, date): pass def process_task_status(cls, task, date): pass
def remove_task_column(cls, name): pass def remove_task_column(cls, name): pass
def reset_time_period(cls): pass def reset_time_period(cls): pass
def select_products(cls, products): pass
def set_object_shading(cls): pass def set_object_shading(cls): pass
def set_task_sort_column(cls, column): pass def set_task_sort_column(cls, column): pass
def setup_default_task_columns(cls): pass def setup_default_task_columns(cls): pass
def show_snapshot(cls, product_states): pass def show_snapshot(cls, product_states): pass
def update_visualisation_date(cls, start_date, finish_date): pass def update_visualisation_date(cls, start_date, finish_date): pass
@interface @interface
class Spatial: class Spatial:
def can_contain(cls, structure_obj, element_obj): pass def can_contain(cls, structure_obj, element_obj): pass
def can_reference(cls, structure, element): pass def can_reference(cls, structure, element): pass
def copy_xy(cls, src_obj, destination_obj): pass
def deselect_objects(cls): pass
def disable_editing(cls, obj): pass def disable_editing(cls, obj): pass
def duplicate_object_and_data(cls, obj): pass def duplicate_object_and_data(cls, obj): pass
def enable_editing(cls, obj): pass def enable_editing(cls, obj): pass
def filter_products(cls, products, action): pass
def get_container(cls, element): pass def get_container(cls, element): pass
def get_decomposed_elements(cls, container): pass def get_decomposed_elements(cls, container): pass
def get_object_matrix(cls, obj): pass def get_object_matrix(cls, obj): pass
def get_relative_object_matrix(cls, target_obj, relative_to_obj): pass def get_relative_object_matrix(cls, target_obj, relative_to_obj): pass
def get_selected_product_types(cls): pass
def get_selected_products_and_types(cls): pass
def get_selected_products(cls): pass
def get_selected_products(cls): pass
def import_containers(cls, parent=None): pass def import_containers(cls, parent=None): pass
def run_root_copy_class(cls, obj=None): pass def run_root_copy_class(cls, obj=None): pass
def run_spatial_assign_container(cls, structure_obj=None, element_obj=None): pass def run_spatial_assign_container(cls, structure_obj=None, element_obj=None): pass
def select_object(cls, obj): pass def select_object(cls, obj): pass
def select_products(cls, products, unhide): pass
def set_active_object(cls, obj): pass def set_active_object(cls, obj): pass
def set_relative_object_matrix(cls, target_obj, relative_to_obj, matrix): pass def set_relative_object_matrix(cls, target_obj, relative_to_obj, matrix): pass
def show_scene_objects(cls): pass
@interface @interface
class Structural: class Structural:
@@ -50,4 +50,5 @@ from blenderbim.tool.surveyor import Surveyor
from blenderbim.tool.system import System from blenderbim.tool.system import System
from blenderbim.tool.type import Type from blenderbim.tool.type import Type
from blenderbim.tool.unit import Unit from blenderbim.tool.unit import Unit
from blenderbim.tool.search import Search
from blenderbim.tool.cost import Cost from blenderbim.tool.cost import Cost
+8 -8
View File
@@ -286,14 +286,6 @@ class Resource(blenderbim.core.tool.Resource):
contracted_resources.append(resource.id()) contracted_resources.append(resource.id())
props.contracted_resources = json.dumps(contracted_resources) props.contracted_resources = json.dumps(contracted_resources)
@classmethod
def get_selected_products(cls):
return [
tool.Ifc.get_entity(obj)
for obj in bpy.context.selected_objects
if obj.BIMObjectProperties.ifc_definition_id
] or []
@classmethod @classmethod
def import_resources(cls, file_path): def import_resources(cls, file_path):
from ifc4d.csv2ifc import Csv2Ifc from ifc4d.csv2ifc import Csv2Ifc
@@ -304,3 +296,11 @@ class Resource(blenderbim.core.tool.Resource):
p62ifc.file = tool.Ifc.get() p62ifc.file = tool.Ifc.get()
p62ifc.execute() p62ifc.execute()
print("Importing Resources CSV finished in {:.2f} seconds".format(time.time() - start)) print("Importing Resources CSV finished in {:.2f} seconds".format(time.time() - start))
@classmethod
def get_highlighted_resource(cls):
return tool.Ifc.get().by_id(
bpy.context.scene.BIMResourceTreeProperties.resources[
bpy.context.scene.BIMResourceProperties.active_resource_index
].ifc_definition_id
)
+11
View File
@@ -0,0 +1,11 @@
import bpy
import blenderbim.core.tool
import blenderbim.tool as tool
from ifcopenshell.util.selector import Selector
class Search(blenderbim.core.tool.Search):
@classmethod
def from_selector_query(cls, query):
"""Returns a list of products from a selector query"""
return Selector().parse(tool.Ifc.get(), query)
@@ -329,14 +329,6 @@ class Sequence(blenderbim.core.tool.Sequence):
props.task_attributes.clear() props.task_attributes.clear()
blenderbim.bim.helper.import_attributes2(task, props.task_attributes) blenderbim.bim.helper.import_attributes2(task, props.task_attributes)
@classmethod
def get_selected_products(cls):
return [
tool.Ifc.get_entity(obj)
for obj in bpy.context.selected_objects
if obj.BIMObjectProperties.ifc_definition_id
] or []
@classmethod @classmethod
def enable_editing_task(cls, task): def enable_editing_task(cls, task):
props = bpy.context.scene.BIMWorkScheduleProperties props = bpy.context.scene.BIMWorkScheduleProperties
+52
View File
@@ -133,3 +133,55 @@ class Spatial(blenderbim.core.tool.Spatial):
@classmethod @classmethod
def set_relative_object_matrix(cls, target_obj, relative_to_obj, matrix): def set_relative_object_matrix(cls, target_obj, relative_to_obj, matrix):
target_obj.matrix_world = relative_to_obj.matrix_world @ matrix target_obj.matrix_world = relative_to_obj.matrix_world @ matrix
@classmethod
def select_products(cls, products, unhide=False):
bpy.ops.object.select_all(action="DESELECT")
for product in products:
obj = tool.Ifc.get_object(product)
if obj:
obj.select_set(True)
if unhide:
obj.hide_set(False)
@classmethod
def filter_products(cls, products, action):
objects = [tool.Ifc.get_object(product) for product in products if tool.Ifc.get_object(product)]
if action == "select":
[obj.select_set(True) for obj in objects]
elif action == "isolate":
[obj.hide_set(False) for obj in objects]
[obj.hide_set(True) for obj in bpy.context.visible_objects if not obj in objects] # this is slow
elif action == "unhide":
[obj.hide_set(False) for obj in objects]
elif action == "hide":
[obj.hide_set(True) for obj in objects]
@classmethod
def deselect_objects(cls):
[obj.select_set(False) for obj in bpy.context.selected_objects]
# bpy.ops.object.select_all(action='DESELECT')
@classmethod
def show_scene_objects(cls):
[obj.hide_set(False) for obj in bpy.data.scenes["Scene"].objects]
@classmethod
def get_selected_products(cls):
for obj in bpy.context.selected_objects:
entity = tool.Ifc.get_entity(obj)
if entity and entity.is_a("IfcProduct"):
yield entity
@classmethod
def get_selected_product_types(cls):
for obj in bpy.context.selected_objects:
entity = tool.Ifc.get_entity(obj)
if entity and entity.is_a("IfcTypeProduct"):
yield entity
@classmethod
def copy_xy(cls, src_obj, destination_obj):
z = src_obj.location[2]
src_obj.location = (destination_obj.location[0], destination_obj.location[1], z)