From cb4ab225a6affa35b99c5a82df1dfc5f0f77a67e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Stefan=20Tr=C3=B6ger?= Date: Sun, 15 Jun 2025 10:27:27 +0200 Subject: [PATCH] FEM: Plot single frame index data as point --- .../Resources/ui/PostHistogramIndexAppEdit.ui | 3 ++ src/Mod/Fem/femobjects/post_extract1D.py | 38 ++++++++------- src/Mod/Fem/femobjects/post_extract2D.py | 48 +++++++++++-------- src/Mod/Fem/femobjects/post_lineplot.py | 2 +- .../Fem/femviewprovider/view_post_lineplot.py | 4 ++ 5 files changed, 57 insertions(+), 38 deletions(-) diff --git a/src/Mod/Fem/Gui/Resources/ui/PostHistogramIndexAppEdit.ui b/src/Mod/Fem/Gui/Resources/ui/PostHistogramIndexAppEdit.ui index e9dd2a2b3d..496f42229b 100644 --- a/src/Mod/Fem/Gui/Resources/ui/PostHistogramIndexAppEdit.ui +++ b/src/Mod/Fem/Gui/Resources/ui/PostHistogramIndexAppEdit.ui @@ -70,6 +70,9 @@ 0 + + 999999999 + diff --git a/src/Mod/Fem/femobjects/post_extract1D.py b/src/Mod/Fem/femobjects/post_extract1D.py index 987dfdabdd..1ffb946acd 100644 --- a/src/Mod/Fem/femobjects/post_extract1D.py +++ b/src/Mod/Fem/femobjects/post_extract1D.py @@ -149,36 +149,40 @@ class PostIndexOverFrames1D(base_fempostextractors.Extractor1D): obj.Table = table return - # check if we have timesteps (required!) - abort = True + # check if we have timesteps + timesteps = [] info = obj.Source.getOutputAlgorithm().GetOutputInformation(0) if info.Has(vtkStreamingDemandDrivenPipeline.TIME_STEPS()): timesteps = info.Get(vtkStreamingDemandDrivenPipeline.TIME_STEPS()) - if len(timesteps) > 1: - abort = False - if abort: - FreeCAD.Console.PrintWarning("Not sufficient frames available in data, cannot extract data") - obj.Table = table - return algo = obj.Source.getOutputAlgorithm() - setup = False frame_array = vtkDoubleArray() - idx = obj.Index - for i, timestep in enumerate(timesteps): - algo.UpdateTimeStep(timestep) + if timesteps: + setup = False + for i, timestep in enumerate(timesteps): + + algo.UpdateTimeStep(timestep) + dataset = algo.GetOutputDataObject(0) + array = self._x_array_from_dataset(obj, dataset, copy=False) + + if not setup: + frame_array.SetNumberOfComponents(array.GetNumberOfComponents()) + frame_array.SetNumberOfTuples(len(timesteps)) + setup = True + + frame_array.SetTuple(i, idx, array) + else: + algo.Update() dataset = algo.GetOutputDataObject(0) array = self._x_array_from_dataset(obj, dataset, copy=False) - if not setup: - frame_array.SetNumberOfComponents(array.GetNumberOfComponents()) - frame_array.SetNumberOfTuples(len(timesteps)) - setup = True + frame_array.SetNumberOfComponents(array.GetNumberOfComponents()) + frame_array.SetNumberOfTuples(1) + frame_array.SetTuple(0, idx, array) - frame_array.SetTuple(i, idx, array) if frame_array.GetNumberOfComponents() > 1: frame_array.SetName(f"{obj.XField} ({obj.XComponent}) @Idx {obj.Index}") diff --git a/src/Mod/Fem/femobjects/post_extract2D.py b/src/Mod/Fem/femobjects/post_extract2D.py index baa5f3d8c2..3cb17d8ffc 100644 --- a/src/Mod/Fem/femobjects/post_extract2D.py +++ b/src/Mod/Fem/femobjects/post_extract2D.py @@ -174,41 +174,49 @@ class PostIndexOverFrames2D(base_fempostextractors.Extractor2D): return # check if we have timesteps (required!) - abort = True + timesteps = [] info = obj.Source.getOutputAlgorithm().GetOutputInformation(0) if info.Has(vtkStreamingDemandDrivenPipeline.TIME_STEPS()): timesteps = info.Get(vtkStreamingDemandDrivenPipeline.TIME_STEPS()) - if len(timesteps) > 1: - abort = False - if abort: - FreeCAD.Console.PrintWarning("Not sufficient frames available in data, cannot extract data") - obj.Table = table - return algo = obj.Source.getOutputAlgorithm() frame_x_array = vtkDoubleArray() - frame_x_array.SetNumberOfTuples(len(timesteps)) - frame_x_array.SetNumberOfComponents(1) - - frame_y_array = vtkDoubleArray() idx = obj.Index - setup = False - for i, timestep in enumerate(timesteps): - frame_x_array.SetTuple1(i, timestep) + if timesteps: + setup = False + frame_x_array.SetNumberOfTuples(len(timesteps)) + frame_x_array.SetNumberOfComponents(1) + for i, timestep in enumerate(timesteps): - algo.UpdateTimeStep(timestep) + frame_x_array.SetTuple1(i, timestep) + + algo.UpdateTimeStep(timestep) + dataset = algo.GetOutputDataObject(0) + array = self._y_array_from_dataset(obj, dataset, copy=False) + 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) - if not setup: - frame_y_array.SetNumberOfComponents(array.GetNumberOfComponents()) - frame_y_array.SetNumberOfTuples(len(timesteps)) - setup = True - frame_y_array.SetTuple(i, idx, array) + 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: diff --git a/src/Mod/Fem/femobjects/post_lineplot.py b/src/Mod/Fem/femobjects/post_lineplot.py index 8d4b725128..e3483b0bf5 100644 --- a/src/Mod/Fem/femobjects/post_lineplot.py +++ b/src/Mod/Fem/femobjects/post_lineplot.py @@ -1,4 +1,4 @@ -# *************************************************************************** +2# *************************************************************************** # * Copyright (c) 2025 Stefan Tröger * # * * # * This file is part of the FreeCAD CAx development system. * diff --git a/src/Mod/Fem/femviewprovider/view_post_lineplot.py b/src/Mod/Fem/femviewprovider/view_post_lineplot.py index f2b03743d1..0a61fd771d 100644 --- a/src/Mod/Fem/femviewprovider/view_post_lineplot.py +++ b/src/Mod/Fem/femviewprovider/view_post_lineplot.py @@ -516,6 +516,10 @@ class VPPostLineplot(view_base_fempostvisualization.VPPostVisualization): xdata = VTKArray(table.GetColumn(i)) ydata = VTKArray(table.GetColumn(i+1)) + # ensure points are visible if it is a single datapoint + if len(xdata) == 1 and tmp_args["marker"] == "None": + tmp_args["marker"] = "o" + # legend labels if child.ViewObject.Legend: if not legend_multiframe: