Source code for pycalculix.selector

"""This module stores the Selector object

Selector is used in FeaModel to store the model's selected set.
"""

from . import partmodule
from . import geometry
from . import mesh
from . import components

[docs]class Selector(object): """Makes a selector which stores the selected items in the FeaModel. Args: feamodel (FeaModel): the parent FeaModel object Attributes: __fea (FeaModel): the parent FeaModel __all (bool): If everything is selected all=True parts (set): currently selected parts areas (set): currently selected areas lines (set): currently selected signed lines or arcs points (set): currently selected points elements (set): currently selected elements faces (set): currently selected faces nodes (set): currently selected nodes __parts (set): internal storage set of parts __areas (set): internal storage set of areas __slines (set): internal storage set of signed lines and arcs __points (set): internal storage set of points __elements (set): internal storage set of elements __faces (set): internal storage set of faces __nodes (set): internal storage set of nodes """ def __init__(self, feamodel): self.__fea = feamodel self.__all = True self.__parts = set() self.__areas = set() self.__slines = set() self.__points = set() self.__elements = set() self.__faces = set() self.__nodes = set() @property def parts(self): """Returns selected parts.""" if self.__all: return self.__fea.parts else: return self.__parts @property def areas(self): """Returns selected areas.""" if self.__all: return self.__fea.areas else: return self.__areas @property def lines(self): """Returns selected signed lines or arcs.""" if self.__all: return self.__fea.signlines else: return self.__slines @property def points(self): """Returns selected points.""" if self.__all: points = [pnt for pnt in self.__fea.points if pnt.arc_center == False] return points else: return self.__points @property def elements(self): """Returns selected elements.""" if self.__all: return self.__fea.elements else: return self.__elements @property def faces(self): """Returns selected faces.""" if self.__all: return self.__fea.faces else: return self.__faces @property def nodes(self): """Returns selected nodes.""" if self.__all: return self.__fea.nodes else: return self.__nodes @staticmethod def __add_items(inclusive, items, item, parent_list, this_set): """Adds an item to items if appropriate. Helper function for select_above_all """ if inclusive == False: items.add(item) else: parent_set = set(parent_list) if parent_set.issubset(this_set): items.add(item) def __add_select(self, items): """Adds items to the selection set.""" for item in items: if isinstance(item, partmodule.Part): self.__parts.add(item) elif isinstance(item, geometry.Area): self.__areas.add(item) elif (isinstance(item, geometry.SignLine) or isinstance(item, geometry.SignArc)): self.__slines.add(item) elif isinstance(item, geometry.Point): self.__points.add(item) elif isinstance(item, mesh.Element): self.__elements.add(item) elif isinstance(item, mesh.Face): self.__faces.add(item) elif isinstance(item, mesh.Node): self.__nodes.add(item)
[docs] def allsel_under(self, sel_type, full=True, byfaces=False): """Selects all progeny under current sel_type items. Args: sel_type (str): the item type to select under - 'parts' - 'areas' - 'lines' - 'points' (needs full=True) - 'elements' - 'faces' full (bool): if False selects under one branch - solid modeling branch: area->line->keypoints->points - mesh branch: elements->faces->nodes Cross branch connections: - faces are under lines - elements are under areas - nodes are under lines and points If True, selects all items connected to sub items: - Parts: - Areas - Elements, element faces + element nodes - Lines, line points - Areas: - Elements, element faces + element nodes - Lines, line points -Lines: - Faces, nodes - byfaces=True: elements above faces - byfaces=False: elements above line nodes selected -Points: - Nodes - byfaces=True: no elements selected - byfaces=False: elements above point nodes selected byfaces (bool): If true, the child elements will only be selected if a parent face was selected. If false just an element node needs to be selected to select the element. -This is only applicable when sel_type == 'lines' """ sets = ['parts', 'areas', 'lines', 'points', 'elements', 'faces'] if isinstance(sel_type, str): if sel_type in sets: this_set = getattr(self, sel_type) for item in this_set: if isinstance(item, partmodule.Part): # areas self.select_below_all('parts') # slines self.select_below_all('areas') # points self.select_below_all('lines') # select related elements if full is on if full: elements = item.elements self.select(elements, also=True) # sel faces self.select_below_all('elements') # sel nodes self.select_below_all('faces') elif isinstance(item, geometry.Area): # slines self.select_below_all('areas') # points self.select_below_all('lines') # select related elements if full is on if full: elements = item.elements self.select(elements, also=True) # sel faces self.select_below_all('elements') # sel nodes self.select_below_all('faces') elif (isinstance(item, geometry.SignLine) or isinstance(item, geometry.SignArc)): # sel points self.select_below_all('lines') # select related faces, nodes, and elements if full: # select faces faces = item.faces self.select(faces, also=True) # sel nodes self.select_below_all('faces') # byfaces logic if byfaces: # sel elements above faces self.select_above_all('faces', inclusive=False) else: # select elements connected to nodes elements = set() for node in self.nodes: elements.update(node.elements) self.select(elements, also=True) elif isinstance(item, geometry.Point): if full: # sel nodes and elements self.select(item.nodes, also=True) if byfaces == False: for node in item.nodes: self.select(node.elements, also=True) else: print('The passed sel_type must be a valid type.') else: print('The passed sel_type must be a string!')
[docs] def select_below(self): """Selects children below currently selected items. Only one set must be selected. """ sets = ['parts', 'areas', 'lines', 'points', 'elements', 'faces', 'nodes'] sel_sets = [] for set_name in sets: this_set = getattr(self, set_name) if len(this_set) > 0: sel_sets.append(set_name) # check if number of visible sets is one if len(sel_sets) == 0 or len(sel_sets) > 1: print('Only one set must be selected to use this function.') elif len(sel_sets) == 1: sel_type = sel_sets[0] if sel_type == 'nodes': print("One can't select anything below nodes!'") else: self.select_below_all(sel_type)
[docs] def select_below_all(self, sel_type): """Selects children below all currently selected items of sel_type. Args: sel_type (str): type to select items below - 'parts': selects areas - 'areas': selects lines (type SignLine and SignArc) - 'lines': selects points - 'elements': selects faces - 'faces': selects nodes """ items = set() if sel_type == 'parts': for part in self.parts: for area in part.areas: items.add(area) elif sel_type == 'areas': for area in self.areas: items.update(area.signlines) elif sel_type == 'lines': for sline in self.lines: items.update(sline.line.points) elif sel_type == 'elements': for element in self.elements: items.update(element.faces) elif sel_type == 'faces': for face in self.faces: items.update(face.nodes) self.__add_select(items)
[docs] def select_above(self, inclusive=False): """Selects parents above currently selected items. Only one set must be selected. """ sets = ['parts', 'areas', 'lines', 'points', 'elements', 'faces', 'nodes'] sel_sets = [] for set_name in sets: this_set = getattr(self, set_name) if len(this_set) > 0: sel_sets.append(set_name) # check if number of visible sets is one if len(sel_sets) == 0 or len(sel_sets) > 1: print('Only one set must be selected to use this function.') elif len(sel_sets) == 1: sel_type = sel_sets[0] if sel_type == 'parts': print("One can't select anything above parts!'") else: self.select_above_all(sel_type, inclusive)
[docs] def select_above_all(self, sel_type, inclusive=False): """Selects parents above all currently selected items of sel_type. Args: sel_type (str): type to select items above - 'areas': selects parts - 'lines': selects areas - 'points': selects signlines or signarcs - 'faces': selects elements - 'nodes': selects faces inclusive (bool): if True, all child entities must be selected for the parent to be selected. If false all parents connected to the child are selected. Exampes: - 'areas' + True: all part areas must be selected to select part - 'areas' + False: parts with selected areas in them are selected - 'lines' + True: all lines must be selected to select area - 'lines' + False: areas with selected lines in them are selected """ items = set() if sel_type == 'areas': this_set = self.areas for area in this_set: item = area.parent parent_list = area.parent.areas self.__add_items(inclusive, items, item, parent_list, this_set) elif sel_type == 'lines': this_set = self.lines for sline in this_set: item = sline.parent parent_list = sline.parent.signlines self.__add_items(inclusive, items, item, parent_list, this_set) elif sel_type == 'points': this_set = set(self.points) for point in this_set: for parent_line in point.lines: for sline in parent_line.signlines: item = sline parent_list = sline.points self.__add_items(inclusive, items, item, parent_list, this_set) elif sel_type == 'faces': this_set = set(self.faces) for face in this_set: item = face.element parent_list = item.faces self.__add_items(inclusive, items, item, parent_list, this_set) elif sel_type == 'nodes': this_set = set(self.nodes) for node in this_set: for face in node.faces: item = face parent_list = face.nodes self.__add_items(inclusive, items, item, parent_list, this_set) self.__add_select(items)
[docs] def allselect(self): """Selects all items.""" self.select(items='all')
[docs] def select(self, items='', also=False): """Selects an item or a list of items. Agrs: items (str or item or list): item(s) to select also (bool): whether to add the items to the current selection set - True: add the items to the current selection set - False: only select the passed items """ # empty the selection set if also == False if items == '': print('You must pass in an item or item(s)!') else: if also == False: self.select_none() # Turn on 'all' mode if items == None, otherwise, get the items if items == 'all': self.__all = True else: items = self.__fea.get_items(items) for (ind, item) in enumerate(items): # if a component was passed, get its child items instead if isinstance(item, components.Component): real_items = item.get_children() items[ind] = real_items self.__add_select(items)
[docs] def select_all(self, sel_type='all', also=False): """Selects all items of sel_type from the full feamodel. All items currently selected items are removed from the selection set before the all set is selected. Args: sel_type (str): the items to select - 'all' - 'parts' - 'areas' - 'lines' - 'points' - 'elements' - 'faces' - 'nodes' also (bool): if False, empties the selection set before selecting all items, if True adds new items to the current set """ if also == False: self.__all = False self.select_none() # now select all items of type if sel_type == 'all': self.select() elif sel_type == 'parts': self.__add_select(self.__fea.parts) elif sel_type == 'areas': self.__add_select(self.__fea.areas) elif sel_type == 'lines': self.__add_select(self.__fea.signlines) elif sel_type == 'points': points = [pnt for pnt in self.__fea.points if pnt.arc_center == False] self.__add_select(points) elif sel_type == 'elements': self.__add_select(self.__fea.elements) elif sel_type == 'faces': self.__add_select(self.__fea.faces) elif sel_type == 'nodes': self.__add_select(self.__fea.nodes)
[docs] def deselect(self, items): """Removes the passed item or items from the selection set. """ self.__all = False for item in items: if isinstance(item, partmodule.Part): self.__parts.discard(item) elif isinstance(item, geometry.Area): self.__areas.discard(item) elif (isinstance(item, geometry.SignLine) or isinstance(item, geometry.SignArc)): self.__slines.discard(item) elif isinstance(item, geometry.Point): self.__points.discard(item) elif isinstance(item, mesh.Element): self.__elements.discard(item) elif isinstance(item, mesh.Face): self.__faces.discard(item) elif isinstance(item, mesh.Node): self.__nodes.discard(item)
[docs] def deselect_all(self, sel_type): """Deselects all items of sel_type. All items currently selected items are removed from the selection set before the all set is selected. Args: sel_type (str): the items to select - 'all' - 'parts' - 'areas' - 'lines' - 'points' - 'elements' - 'faces' - 'nodes' """ if self.__all == True: self.__parts = self.parts self.__areas = self.areas self.__slines = self.lines self.__points = self.points self.__elements = self.elements self.__faces = self.faces self.__nodes = self.nodes self.__all = False if sel_type == 'all': self.select_none() elif sel_type == 'parts': self.__parts = set() elif sel_type == 'areas': self.__areas = set() elif sel_type == 'lines': self.__slines = set() elif sel_type == 'points': self.__points = set() elif sel_type == 'elements': self.__elements = set() elif sel_type == 'faces': self.__faces = set() elif sel_type == 'nodes': self.__nodes = set()
[docs] def select_none(self): """Empties out the selection object. """ self.__all = False self.__parts = set() self.__areas = set() self.__slines = set() self.__points = set() self.__elements = set() self.__faces = set() self.__nodes = set()
[docs] def print_summary(self): """Prints a summary of the number so items selected in each sel_type. """ sets = ['parts', 'areas', 'lines', 'points', 'elements', 'faces', 'nodes'] spacer = '----------------------------------' print(spacer) print("View's currently selected items:") for sel_type in sets: items = getattr(self, sel_type) print(' %s: %i selected' % (sel_type, len(items))) print(spacer)