2 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 // + This file is part of enGrid. +
6 // + Copyright 2008-2013 enGits GmbH +
8 // + enGrid is free software: you can redistribute it and/or modify +
9 // + it under the terms of the GNU General Public License as published by +
10 // + the Free Software Foundation, either version 3 of the License, or +
11 // + (at your option) any later version. +
13 // + enGrid is distributed in the hope that it will be useful, +
14 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
15 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
16 // + GNU General Public License for more details. +
18 // + You should have received a copy of the GNU General Public License +
19 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
21 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
23 #include "surfacealgorithm.h"
25 #include "insertpoints.h"
26 #include "removepoints.h"
27 #include "updatedesiredmeshdensity.h"
28 #include "smoothingutilities.h"
29 #include "swaptriangles.h"
30 #include "laplacesmoother.h"
31 #include "guimainwindow.h"
34 SurfaceAlgorithm::SurfaceAlgorithm()
37 getSet("surface meshing", "maximal number of iterations", 5, m_NumMaxIter
);
38 getSet("surface meshing", "number of smoothing steps" , 2, m_NumSmoothSteps
);
39 getSet("surface meshing", "number of Delaunay sweeps" , 1, m_NumDelaunaySweeps
);
40 m_NodesPerQuarterCircle
= 0;
41 m_RespectFeatureEdgesForDeleteNodes
= false;
42 m_FeatureAngleForDeleteNodes
= deg2rad(45);
43 m_PerformGeometricTests
= true;
44 m_UseProjectionForSmoothing
= true;
45 m_UseNormalCorrectionForSmoothing
= false;
46 m_AllowFeatureEdgeSwapping
= true;
47 m_AllowSmallAreaSwapping
= false;
49 m_FeatureResolution2D
= 0;
50 m_FeatureResolution3D
= 0;
55 void SurfaceAlgorithm::readSettings()
57 QString buffer
= GuiMainWindow::pointer()->getXmlSection("engrid/surface/settings").replace("\n", " ");
58 QTextStream
in(&buffer
, QIODevice::ReadOnly
);
59 in
>> m_MaxEdgeLength
;
60 in
>> m_MinEdgeLength
;
62 in
>> m_NodesPerQuarterCircle
;
66 GuiMainWindow::pointer()->getAllBoundaryCodes(tmp_bcs
);
67 m_BoundaryCodes
.clear();
68 if (num_bcs
== tmp_bcs
.size()) {
69 foreach (int bc
, tmp_bcs
) {
72 if (check_state
== 1) {
73 m_BoundaryCodes
.insert(bc
);
78 in
>> m_FeatureResolution2D
;
79 in
>> m_FeatureResolution3D
;
83 void SurfaceAlgorithm::prepare()
88 EG_VTKDCN(vtkCharArray
, node_type
, m_Grid
, "node_type");//node type
94 void SurfaceAlgorithm::computeMeshDensity()
96 ///\todo Optimize by using only one loop through nodes!
97 UpdateDesiredMeshDensity update_desired_mesh_density
;
98 update_desired_mesh_density
.setGrid(m_Grid
);
99 update_desired_mesh_density
.setVertexMeshDensityVector(m_VMDvector
);
100 update_desired_mesh_density
.setMaxEdgeLength(m_MaxEdgeLength
);
101 update_desired_mesh_density
.setMinEdgeLength(m_MinEdgeLength
);
102 update_desired_mesh_density
.setNodesPerQuarterCircle(m_NodesPerQuarterCircle
);
103 update_desired_mesh_density
.setCellGrowthFactor(m_GrowthFactor
);
104 update_desired_mesh_density
.setBoundaryCodes(m_BoundaryCodes
);
105 update_desired_mesh_density
.setFeatureResolution2D(m_FeatureResolution2D
);
106 update_desired_mesh_density
.setFeatureResolution3D(m_FeatureResolution3D
);
107 update_desired_mesh_density();
110 void SurfaceAlgorithm::swap()
113 swap
.setGrid(m_Grid
);
114 swap
.setRespectBC(true);
115 swap
.setFeatureSwap(m_AllowFeatureEdgeSwapping
);
116 swap
.setFeatureAngle(m_FeatureAngle
);
117 swap
.setMaxNumLoops(m_NumDelaunaySweeps
);
118 swap
.setSmallAreaSwap(m_AllowSmallAreaSwapping
);
119 swap
.setBCodesFeatureDefinition(m_BCodeFeatureDefinition
);
120 QSet
<int> rest_bcs
= GuiMainWindow::pointer()->getAllBoundaryCodes();
121 rest_bcs
-= m_BoundaryCodes
;
122 swap
.setBoundaryCodes(rest_bcs
);
126 void SurfaceAlgorithm::smooth(int N_iter
, bool correct_curveture
)
130 QVector
<vtkIdType
> cls
;
131 getSurfaceCells(m_BoundaryCodes
, cls
, m_Grid
);
133 lap
.setNumberOfIterations(N_iter
);
134 lap
.setBoundaryCodes(m_BoundaryCodes
);//IMPORTANT: so that unselected nodes become fixed when node types are updated!
135 lap
.setCorrectCurvature(correct_curveture
);
136 lap
.setBCodesFeatureDefinition(m_BCodeFeatureDefinition
);
137 if (m_UseProjectionForSmoothing
) {
138 lap
.setProjectionOn();
140 lap
.setProjectionOff();
142 if (m_UseNormalCorrectionForSmoothing
) {
143 lap
.setNormalCorrectionOn();
145 lap
.setNormalCorrectionOff();
148 m_SmoothSuccess
= lap
.succeeded();
151 int SurfaceAlgorithm::insertNodes()
154 InsertPoints insert_points
;
155 insert_points
.setGrid(m_Grid
);
156 insert_points
.setBoundaryCodes(m_BoundaryCodes
);
157 insert_points
.setBCodesFeatureDefinition(m_BCodeFeatureDefinition
);
159 return insert_points
.getNumInserted();
164 int SurfaceAlgorithm::deleteNodes()
167 RemovePoints remove_points
;
168 remove_points
.setGrid(m_Grid
);
169 remove_points
.setBoundaryCodes(m_BoundaryCodes
);
170 remove_points
.setStretchingFactor(m_StretchingFactor
);
171 remove_points
.setFeatureAngle(m_FeatureAngle
);
172 remove_points
.setBCodesFeatureDefinition(m_BCodeFeatureDefinition
);
173 if (m_RespectFeatureEdgesForDeleteNodes
) {
174 remove_points
.setProtectFeatureEdgesOn();
176 remove_points
.setProtectFeatureEdgesOff();
178 //remove_points.setFeatureAngle(m_FeatureAngleForDeleteNodes);
179 if (m_PerformGeometricTests
) {
180 remove_points
.setPerformGeometricChecksOn();
182 remove_points
.setPerformGeometricChecksOff();
185 return remove_points
.getNumRemoved();