From 11204ea7b72a48418e86d920a5c817d7d90e9f8d Mon Sep 17 00:00:00 2001 From: Michael Innerberger <michael.innerberger@asc.tuwien.ac.at> Date: Tue, 8 Aug 2023 16:16:54 -0400 Subject: [PATCH] Use MooAFEM plotting in triangulation plots --- examples/storingLevelOrientedData.m | 2 +- .../@LevelData/plotLevelTriangulation.m | 83 ------------- lib/storage/@LevelData/plotTriangulation.m | 34 +++--- .../@LevelData/plotTriangulationToFile.m | 112 ++++-------------- 4 files changed, 44 insertions(+), 187 deletions(-) delete mode 100644 lib/storage/@LevelData/plotLevelTriangulation.m diff --git a/examples/storingLevelOrientedData.m b/examples/storingLevelOrientedData.m index 5aa2c31..7488882 100644 --- a/examples/storingLevelOrientedData.m +++ b/examples/storingLevelOrientedData.m @@ -123,7 +123,7 @@ function leveldata = storingLevelOrientedData(doPlots, doStore) figure(); leveldata.plotTriangulation(); - % export refinement video (generates video of about 110 MB) + % export refinement video (generates video of about 2MB) leveldata.plotTriangulationToFile(); end end diff --git a/lib/storage/@LevelData/plotLevelTriangulation.m b/lib/storage/@LevelData/plotLevelTriangulation.m deleted file mode 100644 index deae87b..0000000 --- a/lib/storage/@LevelData/plotLevelTriangulation.m +++ /dev/null @@ -1,83 +0,0 @@ -function plotLevelTriangulation(obj, ax, jLevel) -%%PLOTLEVELTRIANGULATION auxiliary private function for creation of plots -%of triangulations, it extracts the triangulation data in various possible -%formats (compatible with octAFEM and MooAFEM) -% PLOTLEVELTRIANGULATION(obj, ax, jLevel) - -% Copyright 2023 Philipp Bringmann -% -% This program is free software: you can redistribute it and/or modify -% it under the terms of the GNU General Public License as published by -% the Free Software Foundation, either version 3 of the License, or -% (at your option) any later version. -% -% 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 General Public License for more details. -% -% You should have received a copy of the GNU General Public License -% along with this program. If not, see <http://www.gnu.org/licenses/>. -% - - - % This functions plots a single level only - assert(numel(jLevel) == 1); - - % Determine names of variables containing mesh information - arrayDataFound = false; - transposeArrays = false; - if isfield(obj.level(jLevel), 'c4n') - % Arrays in octAFEM style - coordinatesName = 'c4n'; - elementsName = 'n4e'; - arrayDataFound = true; - elseif isfield(obj.level(jLevel), 'coordinates') - % Arrays in MooAFEM style - coordinatesName = 'coordinates'; - elementsName = 'elements'; - arrayDataFound = true; - transposeArrays = true; - end - - % Extract mesh information - if arrayDataFound - % Extract data present as coordinates / elements arrays - c4n = obj.level(jLevel).(coordinatesName); - n4e = obj.level(jLevel).(elementsName); - if transposeArrays - c4n = permute(c4n, [2 1]); - n4e = permute(n4e, [2 1]); - end - % Reorganise mesh information - c4e = permute(reshape(c4n(n4e,:), length(n4e), 3, 2), ... - [3 2 1]); - else - % Extract data present as mesh object - for k = 1:length(obj.label) - data = obj.level(jLevel).(obj.label(k)); - if isa(data, 'MeshData') - % octAFEM MeshData object - c4e = data.c4e; - break - elseif isa(data, 'Mesh') - % MooAFEM Mesh object - c4n = permute(obj.level(jLevel).(coordinatesName), [2 1]); - n4e = permute(obj.level(jLevel).(elementsName), [2 1]); - % Reorganise mesh information - c4e = permute(reshape(c4n(n4e,:), length(n4e), 3, 2), ... - [3 2 1]); - end - end - end - - % Plot mesh - edgecolor = [0 0.4470 0.7410]; - patch(ax, permute(c4e(1,:,:), [2 3 1]), permute(c4e(2,:,:), [2 3 1]), ... - 'white', 'EdgeColor', edgecolor); - - % Format plot - title(ax, {'Mesh plot'; [num2str(size(c4e, 3)), ' triangles']}); - axis(ax, 'equal'); - axis(ax, 'tight'); -end \ No newline at end of file diff --git a/lib/storage/@LevelData/plotTriangulation.m b/lib/storage/@LevelData/plotTriangulation.m index 9870913..caae924 100644 --- a/lib/storage/@LevelData/plotTriangulation.m +++ b/lib/storage/@LevelData/plotTriangulation.m @@ -1,11 +1,11 @@ -function ax = plotTriangulation(obj, jLevel) +function ax = plotTriangulation(obj, jLevel, opt) %%PLOTTRIANGULATION creates (a series of) plots for triangulations (must be %stored as pair c4n (double: nNodes x 2) and n4e (int: nElem x 3) or as %pair coordinates (double: 2 x nNodes) and elements (int: 3 x nElem) % ax = PLOTTRIANGULATION(obj) plots all levels -% ax = PLOTTRIANGULATION(obj, ':') -% ax = PLOTTRIANGULATION(obj, jLevel) -% ax = PLOTTRIANGULATION(obj, 'end') +% ax = PLOTTRIANGULATION(obj, jLevel) plots levels specified in jLevel +% ax = PLOTTRIANGULATION(obj, jLevel, opt) additionally specifies options: +% - timePerLevel (default 1s) % Copyright 2023 Philipp Bringmann % @@ -23,26 +23,26 @@ function ax = plotTriangulation(obj, jLevel) % along with this program. If not, see <http://www.gnu.org/licenses/>. % + arguments + obj + jLevel (1,:) {mustBeIndexVector} = ':' + opt.timePerLevel {mustBeNumeric} = 1 + end - % Proceed input - if nargin < 2 - jLevel = 1:obj.nLevel; - elseif strcmp(jLevel, ':') + if strcmp(jLevel, ':') jLevel = 1:obj.nLevel; - elseif strcmp(jLevel, 'end') - jLevel = obj.nLevel; end - % Compute time per frame to obtain an overall duration of 20 seconds - DURATION = 20; - timePerLevel = DURATION / length(jLevel); - % Create axes object ax = gca; % Plot every frame - for k = 1:length(jLevel) - obj.plotLevelTriangulation(ax, jLevel(k)); - pause(timePerLevel); + % TODO: store whole mesh such that also boundary can be plotted? + for k = jLevel + coordinates = obj.level(k).coordinates; + elements = obj.level(k).elements; + mesh = Mesh(coordinates, elements, {}); + plot(mesh, 'FaceAlpha', 0.0); + pause(opt.timePerLevel); end end \ No newline at end of file diff --git a/lib/storage/@LevelData/plotTriangulationToFile.m b/lib/storage/@LevelData/plotTriangulationToFile.m index a5b9827..65db0d8 100644 --- a/lib/storage/@LevelData/plotTriangulationToFile.m +++ b/lib/storage/@LevelData/plotTriangulationToFile.m @@ -1,11 +1,11 @@ -function plotTriangulationToFile(obj, jLevel) +function plotTriangulationToFile(obj, jLevel, opt) %%PLOTTRIANGULATIONTOFILE creates (a series of) plots for triangulations %and stores it to a file, filename is generated automatically from %information in LevelData object % ax = PLOTTRIANGULATIONTOFILE(obj) plots all levels -% ax = PLOTTRIANGULATIONTOFILE(obj, ':') -% ax = PLOTTRIANGULATIONTOFILE(obj, jLevel) -% ax = PLOTTRIANGULATIONTOFILE(obj, 'end') +% ax = PLOTTRIANGULATIONTOFILE(obj, jLevel) plots levels specified in jLevel +% ax = PLOTTRIANGULATIONTOFILE(obj, jLevel, opt) additionally specifies options: +% - timePerLevel (default 1s) % % See also LevelData/plotTriangulation @@ -25,115 +25,55 @@ function plotTriangulationToFile(obj, jLevel) % along with this program. If not, see <http://www.gnu.org/licenses/>. % + arguments + obj + jLevel (1,:) {mustBeIndexVector} = ':' + opt.timePerLevel {mustBeNumeric} = 1 + end - % Proceed input - if nargin < 2 - jLevel = 1:obj.nLevel; - elseif strcmp(jLevel, ':') + if strcmp(jLevel, ':') jLevel = 1:obj.nLevel; - elseif strcmp(jLevel, 'end') - jLevel = obj.nLevel; end - % Create problem- and method-specific folder ensureFolderExists(obj.foldername); - - % Create new figure h = createStandardFigure(); if length(jLevel) == 1 % Create single image - h = createStandardisedFigure(); - obj.plotLevelTriangulation(gca(), jLevel); - % Export plot - print(h, '-dpng', '-r600', [obj.foldername, '/', obj.filename, '.png']); + coordinates = obj.level(jLevel).coordinates; + elements = obj.level(jLevel).elements; + mesh = Mesh(coordinates, elements, {}); + plot(mesh); + print(h, '-dpng', '-r600', obj.foldername + '/' + obj.filename + '.png'); else - % Set duration of video in seconds - DURATION = 20; % Create video as series of images - if isOctave() - createTriangulationGIF(obj, h, jLevel, DURATION); - else - createTriangulationAVI(obj, h, jLevel, DURATION); - end + createTriangulationAVI(obj, h, jLevel, opt.timePerLevel); end - % Close figure close(h); end -function createTriangulationAVI(obj, h, jLevel, duration) -%%CREATETRIANGULATIONAVI creates a video of the mesh refinement in AVI format - - % Set video quality parameter - FPS = 30; +function createTriangulationAVI(obj, h, jLevel, secondsPerFrame) + % video quality parameter + FPS = 1 / secondsPerFrame; % Create video writer - videowriter = VideoWriter([obj.foldername, '/', obj.filename, '.avi']); + videowriter = VideoWriter(obj.foldername + '/' + obj.filename + '.avi'); set(videowriter, 'FrameRate', FPS); open(videowriter); - % Compute time per frame to obtain a fixed overall duration - framesPerLevel = fix(FPS * duration / length(jLevel)); ax = gca(); set(ax, 'NextPlot', 'replaceChildren'); % Plot every frame - for k = 1:length(jLevel) - obj.plotLevelTriangulation(ax, jLevel(k)); - for l = 1:framesPerLevel - writeVideo(videowriter, getframe(h)); - end + for k = jLevel + coordinates = obj.level(k).coordinates; + elements = obj.level(k).elements; + mesh = Mesh(coordinates, elements, {}); + plot(mesh, 'FaceAlpha', 0.0); + writeVideo(videowriter, getframe(h)); end - % Close video writer close(videowriter); end - - -function createTriangulationGIF(obj, h, jLevel, duration) -%%CREATETRIANGULATIONGIF creates a video of the mesh refinement in GIF format - - error('not working yet') - - ax = gca(); - - % Determine time for delay in GIF - delayTime = duration / length(jLevel); - - % Define path - filepath = [obj.foldername, '/', obj.filename, '.gif']; - - % Assign plot to a frame - frame = getframe(h); - - % Convert frame to RGB image (3 dimensional) - im = frame2im(frame); - - % Transform RGB samples to 1 dimension with a color map "cm". - [imind, cm] = rgb2ind(im); - - % Compute time per frame to obtain a fixed overall duration - imwrite(imind, cm, filepath, 'gif', ... - 'DelayTime', delayTime, 'Compression' , 'lzw'); - - % Plot every frame - for k = 1:length(jLevel) - obj.plotLevelTriangulation(ax, jLevel(k)); - % Assign plot to a frame - frame = getframe(h); - - % Convert frame to RGB image (3 dimensional) - im = frame2im(frame); - - % Transform RGB samples to 1 dimension with a color map "cm". - [imind, cm] = rgb2ind(im); - - % Create GIF file - % Add each new plot to GIF - imwrite(imind, cm, filepath, 'gif', ... - 'WriteMode', 'append', 'DelayTime', delayTime, ... - 'Compression', 'lzw'); - end -end -- GitLab