| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
| |
|
|
| __title__ = "FreeCAD FEM postprocessing data visualization base object" |
| __author__ = "Stefan Tröger" |
| __url__ = "https://www.freecad.org" |
|
|
| |
| |
| |
|
|
| from vtkmodules.vtkCommonDataModel import vtkTable |
| from vtkmodules.vtkCommonCore import vtkDoubleArray |
|
|
| from . import base_fempythonobject |
| from . import base_fempostextractors |
|
|
| |
| |
|
|
|
|
| def is_visualization_object(obj): |
| if not obj: |
| return False |
|
|
| if not hasattr(obj, "Proxy"): |
| return False |
|
|
| return hasattr(obj.Proxy, "VisualizationType") |
|
|
|
|
| def get_visualization_type(obj): |
| |
| |
| return obj.Proxy.VisualizationType |
|
|
|
|
| def is_visualization_extractor_type(obj, vistype): |
|
|
| |
| if not base_fempostextractors.is_extractor_object(obj): |
| return False |
|
|
| |
| if not is_visualization_object(obj): |
| return False |
|
|
| |
| if get_visualization_type(obj) != vistype: |
| return False |
|
|
| return True |
|
|
|
|
| |
| |
| |
| |
| class PostVisualization(base_fempythonobject.BaseFemPythonObject): |
|
|
| def __init__(self, obj): |
| super().__init__(obj) |
| self.Type = "Fem::FemPostVisualization" |
| obj.addExtension("App::GroupExtensionPython") |
| self._setup_properties(obj) |
|
|
| def _setup_properties(self, obj): |
| pl = obj.PropertiesList |
| for prop in self._get_properties(): |
| if not prop.name in pl: |
| prop.add_to_object(obj) |
|
|
| def _get_properties(self): |
| |
|
|
| prop = [ |
| base_fempostextractors._PropHelper( |
| type="Fem::PropertyPostDataObject", |
| name="Table", |
| group="Base", |
| doc="The data table that stores the data for visualization", |
| value=vtkTable(), |
| ), |
| ] |
| return prop |
|
|
| def onDocumentRestored(self, obj): |
| |
| |
|
|
| self._setup_properties(obj) |
|
|
| def onChanged(self, obj, prop): |
| |
|
|
| if prop == "Group": |
| |
|
|
| children = obj.Group |
| for child in obj.Group: |
| if not is_visualization_extractor_type(child, self.VisualizationType): |
| FreeCAD.Console.PrintWarning( |
| f"{child.Label} is not a {self.VisualizationType} extraction object, cannot be added" |
| ) |
| children.remove(child) |
|
|
| if len(obj.Group) != len(children): |
| obj.Group = children |
|
|
| def execute(self, obj): |
| |
| |
| |
|
|
| rows = self.getLongestColumnLength(obj) |
| table = vtkTable() |
| for child in obj.Group: |
|
|
| |
| |
| |
| |
| if not child.Source and (child.Table.GetNumberOfColumns() > 0): |
| FreeCAD.Console.PrintWarning( |
| f"{child.Label} has data, but no Source object. Will be ignored" |
| ) |
| continue |
|
|
| c_table = child.Table |
| for i in range(c_table.GetNumberOfColumns()): |
| c_array = c_table.GetColumn(i) |
| array = vtkDoubleArray() |
|
|
| if c_array.GetNumberOfTuples() == rows: |
| |
| array.DeepCopy(c_array) |
|
|
| else: |
| array.SetNumberOfComponents(c_array.GetNumberOfComponents()) |
| array.SetNumberOfTuples(rows) |
| array.Fill(0) |
| for j in range(c_array.GetNumberOfTuples()): |
| array.SetTuple(j, c_array.GetTuple(j)) |
|
|
| array.SetName(f"{child.Source.Name}: {c_array.GetName()}") |
| table.AddColumn(array) |
|
|
| obj.Table = table |
| return False |
|
|
| def getLongestColumnLength(self, obj): |
| |
|
|
| length = 0 |
| for child in obj.Group: |
| if base_fempostextractors.is_extractor_object(child): |
| table = child.Table |
| if table.GetNumberOfColumns() > 0: |
| |
| num = table.GetColumn(0).GetNumberOfTuples() |
| if num > length: |
| length = num |
|
|
| return length |
|
|