tri2quadGroupSplit
Below is a demonstration of the features of the tri2quadGroupSplit function
Contents
clear; close all; clc;
Syntax
[F_quad,V_quad,F_tri_remain,V_tri_remain]=tri2quadGroupSplit(F_tri,V_tri,optionStruct);
Description
The tri2quadGroupSplit function converts the triangulated input data F_tri (faces) and V_tri (vertices) to quadrilateral elements F_quad (faces) and V_quad (vertices). Quadrilateral elements are formed by grouping adjacent triangles. Once a maximum number of quadrilateral elements are formes some triagles may remain. If desired these can also be converted to quadrilateral elements through splitting. If splitting is used the grouped quadrilaterals also require splitting to create a mesh with shared nodal connectivity. Splitting based conversion can be turned off. The remaining triangle set can also be obtained if desired through the optional outputs F_tri_remain (faces) and V_tri_remain (vertices). The third input is the option structure optionStruct with the fields:
optionStruct.maxAngleDeviation=60*(pi/180); %The maximum angle used for optionStruct.selectionMethod='best'; % or 'random' optionStruct.triangleConvert=0; %Convert the remaining triangles (1) or not (0)
Examples
Plot settings
plotColors=gjet(4);
Create test data set
[F_tri,V_tri]=geoSphere(3,1);
Convert adjacent triangles by picking the best candidates, keeping unconverted triangles
optionStruct.maxAngleDeviation=60*(pi/180); optionStruct.selectionMethod='best'; optionStruct.triangleConvert=0; optionStruct.fourConnectConvert=0; [FQ,VQ,indIni]=tri2quadGroupSplit(F_tri,V_tri,optionStruct); %Create color data for visualization if iscell(FQ) CQ=FQ; for q=1:1:numel(FQ) CQ{q}=q*ones(size(FQ{q},1),1); end end
Visualize results
cFigure; gtitle('Creating quads with splitting based conversion'); subplot(1,2,1); hold on; gpatch(F_tri,V_tri,'rw','k',1); axisGeom; camlight headlight; subplot(1,2,2); hold on; gpatch(FQ,VQ,'bw','k'); axisGeom; camlight headlight; drawnow;
Convert adjacent triangles by picking best candidates, converting remaining triangles by splitting
Create test data set
[F_tri,V_tri]=stanford_bunny;
optionStruct.maxAngleDeviation=60*(pi/180);
optionStruct.selectionMethod='best';
optionStruct.triangleConvert=1;
optionStruct.fourConnectConvert=0;
[FQ,VQ,indIni]=tri2quadGroupSplit(F_tri,V_tri,optionStruct);
Since subTriDual outputs indIni which are the indices for the initial nodes in the unrefined mesh, smoothing can be performed while holding on to these nodes, i.e. only the newly introduces nodes will be adjusted during smoothing.
%Smoothen newly introduced nodes cPar.Method='HC'; %Smoothing method cPar.n=50; %Number of iterations cPar.RigidConstraints=indIni; %Constrained points [VQ]=tesSmooth(FQ,VQ,[],cPar);
Visualize results
cFigure; gtitle('Creating quads with splitting based conversion'); subplot(1,2,1); hold on; gpatch(F_tri,V_tri,'rw','k',1); plotV(VQ(indIni,:),'r.','MarkerSize',25); axisGeom; camlight headlight; subplot(1,2,2); hold on; gpatch(FQ,VQ,'bw','k'); plotV(VQ(indIni,:),'r.','MarkerSize',25); axisGeom; camlight headlight; drawnow;
Convert adjacent triangles by picking random candidates
Random picking may be useful if the smallest amount of remaining triangles is of interest. E.g. one could randomly pick the next quad such that different results are obtained each time. This way one could keep the results yielding the smallest number of remaining triangles.
Create test data set
[F_tri,V_tri]=parasaurolophus; numAttempts=6; F_cell=cell(1,numAttempts); F_tri_cell=cell(1,numAttempts); V_cell=cell(1,numAttempts); numTrianglesRemaining=nan(1,numAttempts); for q=1:1:numAttempts optionStruct.maxAngleDeviation=45*(pi/180); optionStruct.selectionMethod='random'; optionStruct.triangleConvert=1; optionStruct.fourConnectConvert=0; [FQ,VQ]=tri2quadGroupSplit(F_tri,V_tri,optionStruct); if iscell(FQ) numTrianglesRemaining(q)=numel(FQ{2}); else numTrianglesRemaining(q)=0; end F_cell{q}=FQ; V_cell{q}=VQ; end [~,indMin]=min(numTrianglesRemaining); FQ=F_cell{indMin}; VQ=V_cell{indMin};
Visualize results
cFigure; gtitle('Creating quads with splitting based conversion'); subplot(1,2,1); hold on; gpatch(F_tri,V_tri,'rw','k',1); axisGeom; axis off; camlight headlight; zoom(1.5); subplot(1,2,2); hold on; gpatch(FQ,VQ,'bw','k'); axisGeom; axis off; camlight headlight; zoom(1.5); drawnow;
Create test data set
[X,Y,Z]=peaks(15); Z=Z/4; [Fq,Vq,~]=surf2patch(X,Y,Z,Z); [F_tri,V_tri]=quad2tri(Fq,Vq,'x'); optionStruct.maxAngleDeviation=60*(pi/180); optionStruct.selectionMethod='best'; optionStruct.triangleConvert=0; optionStruct.fourConnectConvert=1; [FQ,VQ]=tri2quadGroupSplit(F_tri,V_tri,optionStruct);
Visualize results
cFigure; gtitle('Converting four-connected sets to quads'); subplot(1,2,1); hold on; gpatch(F_tri,V_tri,'rw','k',1); axisGeom; axis off; camlight headlight; subplot(1,2,2); hold on; gpatch(FQ,VQ,'bw','k'); axisGeom; axis off; camlight headlight; drawnow;
GIBBON www.gibboncode.org
Kevin Mattheus Moerman, [email protected]
GIBBON footer text
License: https://github.com/gibbonCode/GIBBON/blob/master/LICENSE
GIBBON: The Geometry and Image-based Bioengineering add-On. A toolbox for image segmentation, image-based modeling, meshing, and finite element analysis.
Copyright (C) 2006-2023 Kevin Mattheus Moerman and the GIBBON contributors
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/.