Download src/Mod/Fem/femobjects/post_extract2D.py from AbdulElahGwaith/FreeCAD: direct link, hf CLI and curl.
- Browser
- Download file 9.33 kB
-
https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/Fem/femobjects/post_extract2D.py
- Command line
-
hf download hf://AbdulElahGwaith/FreeCAD/src/Mod/Fem/femobjects/post_extract2D.py
-
curl -L -o post_extract2D.py https://huggingface.co/AbdulElahGwaith/FreeCAD/resolve/main/src/Mod/Fem/femobjects/post_extract2D.py
9.33 kB
| # *************************************************************************** | |
| # * Copyright (c) 2025 Stefan Tröger <stefantroeger@gmx.net> * | |
| # * * | |
| # * This file is part of the FreeCAD CAx development system. * | |
| # * * | |
| # * This program is free software; you can redistribute it and/or modify * | |
| # * it under the terms of the GNU Lesser General Public License (LGPL) * | |
| # * as published by the Free Software Foundation; either version 2 of * | |
| # * the License, or (at your option) any later version. * | |
| # * for detail see the LICENCE text file. * | |
| # * * | |
| # * This program 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 Library General Public License for more details. * | |
| # * * | |
| # * You should have received a copy of the GNU Library General Public * | |
| # * License along with this program; if not, write to the Free Software * | |
| # * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 * | |
| # * USA * | |
| # * * | |
| # *************************************************************************** | |
| __title__ = "FreeCAD post extractors 2D" | |
| __author__ = "Stefan Tröger" | |
| __url__ = "https://www.freecad.org" | |
| ## @package post_histogram | |
| # \ingroup FEM | |
| # \brief Post processing plot displaying lines | |
| import FreeCAD | |
| from . import base_fempostextractors | |
| from . import base_fempythonobject | |
| _PropHelper = base_fempythonobject._PropHelper | |
| from vtkmodules.vtkCommonCore import vtkDoubleArray | |
| from vtkmodules.vtkCommonDataModel import vtkTable | |
| from vtkmodules.vtkCommonExecutionModel import vtkStreamingDemandDrivenPipeline | |
| from PySide.QtCore import QT_TRANSLATE_NOOP | |
| class PostFieldData2D(base_fempostextractors.Extractor2D): | |
| """ | |
| A post processing extraction of two dimensional field data | |
| """ | |
| ExtractionType = "Field" | |
| def __init__(self, obj): | |
| super().__init__(obj) | |
| def _get_properties(self): | |
| prop = [ | |
| _PropHelper( | |
| type="App::PropertyBool", | |
| name="ExtractFrames", | |
| group="Multiframe", | |
| doc=QT_TRANSLATE_NOOP( | |
| "FEM", "Specify if the field shall be extracted for every available frame" | |
| ), | |
| value=False, | |
| ), | |
| ] | |
| return super()._get_properties() + prop | |
| def execute(self, obj): | |
| # on execution we populate the vtk table | |
| table = vtkTable() | |
| if not obj.Source: | |
| obj.Table = table | |
| return | |
| dataset = obj.Source.getDataSet() | |
| if not dataset: | |
| obj.Table = table | |
| return | |
| timesteps = [] | |
| if obj.ExtractFrames: | |
| # check if we have timesteps | |
| info = obj.Source.getOutputAlgorithm().GetOutputInformation(0) | |
| if info.Has(vtkStreamingDemandDrivenPipeline.TIME_STEPS()): | |
| timesteps = info.Get(vtkStreamingDemandDrivenPipeline.TIME_STEPS()) | |
| else: | |
| FreeCAD.Console.PrintWarning( | |
| 'No frames available in data, ignoring "ExtractFrames" property' | |
| ) | |
| if not timesteps: | |
| # get the dataset and extract the correct array | |
| xarray = self._x_array_from_dataset(obj, dataset) | |
| if xarray.GetNumberOfComponents() > 1: | |
| xarray.SetName(obj.XField + " (" + obj.XComponent + ")") | |
| else: | |
| xarray.SetName(obj.XField) | |
| self._x_array_component_to_table(obj, xarray, table) | |
| yarray = self._y_array_from_dataset(obj, dataset) | |
| if yarray.GetNumberOfComponents() > 1: | |
| yarray.SetName(obj.YField + " (" + obj.YComponent + ")") | |
| else: | |
| yarray.SetName(obj.YField) | |
| self._y_array_component_to_table(obj, yarray, table) | |
| else: | |
| algo = obj.Source.getOutputAlgorithm() | |
| for timestep in timesteps: | |
| algo.UpdateTimeStep(timestep) | |
| dataset = algo.GetOutputDataObject(0) | |
| xarray = self._x_array_from_dataset(obj, dataset) | |
| if xarray.GetNumberOfComponents() > 1: | |
| xarray.SetName(f"X - {obj.XField} ({obj.XComponent}) - {timestep}") | |
| else: | |
| xarray.SetName(f"X - {obj.XField} - {timestep}") | |
| self._x_array_component_to_table(obj, xarray, table) | |
| yarray = self._y_array_from_dataset(obj, dataset) | |
| if yarray.GetNumberOfComponents() > 1: | |
| yarray.SetName(f"{obj.YField} ({obj.YComponent}) - {timestep}") | |
| else: | |
| yarray.SetName(f"{obj.YField} - {timestep}") | |
| self._y_array_component_to_table(obj, yarray, table) | |
| # set the final table | |
| obj.Table = table | |
| class PostIndexOverFrames2D(base_fempostextractors.Extractor2D): | |
| """ | |
| A post processing extraction for two dimensional data with X always being the frames | |
| """ | |
| ExtractionType = "Index" | |
| def __init__(self, obj): | |
| super().__init__(obj) | |
| def _get_properties(self): | |
| prop = [ | |
| _PropHelper( | |
| type="App::PropertyInteger", | |
| name="Index", | |
| group="Data", | |
| doc=QT_TRANSLATE_NOOP( | |
| "FEM", "Specify for which point index the data should be extracted" | |
| ), | |
| value=0, | |
| ), | |
| ] | |
| return super()._get_properties() + prop | |
| def _setup_x_component_property(self, obj, point_data): | |
| # override to only allow "Frames" as X data | |
| obj.XComponent = ["Not a vector"] | |
| def _setup_x_properties(self, obj, dataset): | |
| # override to only allow "Frames" as X data | |
| obj.XField = ["Frames"] | |
| def execute(self, obj): | |
| # on execution we populate the vtk table | |
| table = vtkTable() | |
| if not obj.Source: | |
| obj.Table = table | |
| return | |
| dataset = obj.Source.getDataSet() | |
| if not dataset: | |
| obj.Table = table | |
| return | |
| # check if we have timesteps (required!) | |
| timesteps = [] | |
| info = obj.Source.getOutputAlgorithm().GetOutputInformation(0) | |
| if info.Has(vtkStreamingDemandDrivenPipeline.TIME_STEPS()): | |
| timesteps = info.Get(vtkStreamingDemandDrivenPipeline.TIME_STEPS()) | |
| algo = obj.Source.getOutputAlgorithm() | |
| frame_x_array = vtkDoubleArray() | |
| frame_y_array = vtkDoubleArray() | |
| idx = obj.Index | |
| if timesteps: | |
| setup = False | |
| frame_x_array.SetNumberOfTuples(len(timesteps)) | |
| frame_x_array.SetNumberOfComponents(1) | |
| for i, timestep in enumerate(timesteps): | |
| frame_x_array.SetTuple1(i, timestep) | |
| algo.UpdateTimeStep(timestep) | |
| dataset = algo.GetOutputDataObject(0) | |
| array = self._y_array_from_dataset(obj, dataset, copy=False) | |
| # safeguard for invalid access | |
| if idx < 0 or array.GetNumberOfTuples() - 1 < idx: | |
| raise Exception( | |
| f"Invalid index: {idx} is not in range 0 - {array.GetNumberOfTuples()-1}" | |
| ) | |
| if not setup: | |
| frame_y_array.SetNumberOfComponents(array.GetNumberOfComponents()) | |
| frame_y_array.SetNumberOfTuples(len(timesteps)) | |
| setup = True | |
| frame_y_array.SetTuple(i, idx, array) | |
| else: | |
| frame_x_array.SetNumberOfTuples(1) | |
| frame_x_array.SetNumberOfComponents(1) | |
| frame_x_array.SetTuple1(0, 0) | |
| algo.Update() | |
| dataset = algo.GetOutputDataObject(0) | |
| array = self._y_array_from_dataset(obj, dataset, copy=False) | |
| # safeguard for invalid access | |
| if idx < 0 or array.GetNumberOfTuples() - 1 < idx: | |
| raise Exception( | |
| f"Invalid index: {idx} is not in range 0 - {array.GetNumberOfTuples()-1}" | |
| ) | |
| frame_y_array.SetNumberOfComponents(array.GetNumberOfComponents()) | |
| frame_y_array.SetNumberOfTuples(1) | |
| frame_y_array.SetTuple(0, idx, array) | |
| frame_x_array.SetName("Frames") | |
| if frame_y_array.GetNumberOfComponents() > 1: | |
| frame_y_array.SetName(f"{obj.YField} ({obj.YComponent}) @Idx {obj.Index}") | |
| else: | |
| frame_y_array.SetName(f"{obj.YField} @Idx {obj.Index}") | |
| table.AddColumn(frame_x_array) | |
| self._y_array_component_to_table(obj, frame_y_array, table) | |
| # set the final table | |
| obj.Table = table | |