implemented method to access individual variables from an XML section
[engrid-github.git] / src / libengrid / surfacealgorithm.cpp
blob22146a70b158a2aea39b520d80e0c574ca2bb61e
1 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
2 // + +
3 // + This file is part of enGrid. +
4 // + +
5 // + Copyright 2008-2014 enGits GmbH +
6 // + +
7 // + enGrid is free software: you can redistribute it and/or modify +
8 // + it under the terms of the GNU General Public License as published by +
9 // + the Free Software Foundation, either version 3 of the License, or +
10 // + (at your option) any later version. +
11 // + +
12 // + enGrid is distributed in the hope that it will be useful, +
13 // + but WITHOUT ANY WARRANTY; without even the implied warranty of +
14 // + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +
15 // + GNU General Public License for more details. +
16 // + +
17 // + You should have received a copy of the GNU General Public License +
18 // + along with enGrid. If not, see <http://www.gnu.org/licenses/>. +
19 // + +
20 // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
21 #include "surfacealgorithm.h"
23 #include "insertpoints.h"
24 #include "removepoints.h"
25 #include "updatedesiredmeshdensity.h"
26 #include "smoothingutilities.h"
27 #include "swaptriangles.h"
28 #include "laplacesmoother.h"
29 #include "guimainwindow.h"
32 SurfaceAlgorithm::SurfaceAlgorithm()
34 EG_TYPENAME;
35 getSet("surface meshing", "maximal number of iterations", 5, m_NumMaxIter);
36 getSet("surface meshing", "number of smoothing steps" , 2, m_NumSmoothSteps);
37 getSet("surface meshing", "number of Delaunay sweeps" , 1, m_NumDelaunaySweeps);
38 m_NodesPerQuarterCircle = 0;
39 m_RespectFeatureEdgesForDeleteNodes = false;
40 m_FeatureAngleForDeleteNodes = deg2rad(45);
41 m_PerformGeometricTests = true;
42 m_UseProjectionForSmoothing = true;
43 m_UseNormalCorrectionForSmoothing = false;
44 m_AllowFeatureEdgeSwapping = true;
45 m_AllowSmallAreaSwapping = false;
46 m_GrowthFactor = 1.5;
47 m_FeatureResolution2D = 0;
48 m_FeatureResolution3D = 0;
49 setDeleteNodesOn();
50 setInsertNodesOn();
53 void SurfaceAlgorithm::readSettings()
55 QString buffer = GuiMainWindow::pointer()->getXmlSection("engrid/surface/settings").replace("\n", " ");
56 QTextStream in(&buffer, QIODevice::ReadOnly);
57 in >> m_MaxEdgeLength;
58 in >> m_MinEdgeLength;
59 in >> m_GrowthFactor;
60 in >> m_NodesPerQuarterCircle;
61 int num_bcs;
62 in >> num_bcs;
63 QVector<int> tmp_bcs;
64 GuiMainWindow::pointer()->getAllBoundaryCodes(tmp_bcs);
65 m_BoundaryCodes.clear();
66 if (num_bcs == tmp_bcs.size()) {
67 foreach (int bc, tmp_bcs) {
68 int check_state;
69 in >> check_state;
70 if (check_state == 1) {
71 m_BoundaryCodes.insert(bc);
75 if (!in.atEnd()) {
76 in >> m_FeatureResolution2D;
77 in >> m_FeatureResolution3D;
81 void SurfaceAlgorithm::prepare()
83 setAllCells();
84 readSettings();
86 EG_VTKDCN(vtkCharArray, node_type, m_Grid, "node_type");//node type
88 updateNodeInfo();
92 void SurfaceAlgorithm::computeMeshDensity()
94 ///\todo Optimize by using only one loop through nodes!
95 UpdateDesiredMeshDensity update_desired_mesh_density;
96 update_desired_mesh_density.setGrid(m_Grid);
97 update_desired_mesh_density.setVertexMeshDensityVector(m_VMDvector);
98 update_desired_mesh_density.setMaxEdgeLength(m_MaxEdgeLength);
99 update_desired_mesh_density.setMinEdgeLength(m_MinEdgeLength);
100 update_desired_mesh_density.setNodesPerQuarterCircle(m_NodesPerQuarterCircle);
101 update_desired_mesh_density.setCellGrowthFactor(m_GrowthFactor);
102 update_desired_mesh_density.setBoundaryCodes(m_BoundaryCodes);
103 update_desired_mesh_density.setFeatureResolution2D(m_FeatureResolution2D);
104 update_desired_mesh_density.setFeatureResolution3D(m_FeatureResolution3D);
105 update_desired_mesh_density();
108 void SurfaceAlgorithm::swap(double delaunay_threshold, bool verbose)
110 SwapTriangles swap;
111 swap.setGrid(m_Grid);
112 swap.setRespectBC(true);
113 swap.setFeatureSwap(m_AllowFeatureEdgeSwapping);
114 swap.setFeatureAngle(m_FeatureAngle);
115 swap.setMaxNumLoops(m_NumDelaunaySweeps);
116 swap.setSmallAreaSwap(m_AllowSmallAreaSwapping);
117 swap.setBCodesFeatureDefinition(m_BCodeFeatureDefinition);
118 swap.setDelaunayThreshold(delaunay_threshold);
119 if (verbose) {
120 swap.setVerboseOn();
122 QSet<int> rest_bcs = GuiMainWindow::pointer()->getAllBoundaryCodes();
123 rest_bcs -= m_BoundaryCodes;
124 swap.setBoundaryCodes(rest_bcs);
125 swap();
128 void SurfaceAlgorithm::smooth(int N_iter, bool correct_curveture)
130 LaplaceSmoother lap;
131 lap.setGrid(m_Grid);
132 QVector<vtkIdType> cls;
133 getSurfaceCells(m_BoundaryCodes, cls, m_Grid);
134 lap.setCells(cls);
135 lap.setNumberOfIterations(N_iter);
136 lap.setBoundaryCodes(m_BoundaryCodes);//IMPORTANT: so that unselected nodes become fixed when node types are updated!
137 lap.setCorrectCurvature(correct_curveture);
138 lap.setBCodesFeatureDefinition(m_BCodeFeatureDefinition);
139 if (m_UseProjectionForSmoothing) {
140 lap.setProjectionOn();
141 } else {
142 lap.setProjectionOff();
144 if (m_UseNormalCorrectionForSmoothing) {
145 lap.setNormalCorrectionOn();
146 } else {
147 lap.setNormalCorrectionOff();
149 lap();
150 m_SmoothSuccess = lap.succeeded();
153 int SurfaceAlgorithm::insertNodes()
155 if (m_InsertNodes) {
156 InsertPoints insert_points;
157 insert_points.setGrid(m_Grid);
158 insert_points.setBoundaryCodes(m_BoundaryCodes);
159 insert_points.setBCodesFeatureDefinition(m_BCodeFeatureDefinition);
160 insert_points();
161 return insert_points.getNumInserted();
163 return 0;
166 int SurfaceAlgorithm::deleteNodes()
168 if (m_DeleteNodes) {
169 RemovePoints remove_points;
170 remove_points.setGrid(m_Grid);
171 remove_points.setBoundaryCodes(m_BoundaryCodes);
172 remove_points.setStretchingFactor(m_StretchingFactor);
173 remove_points.setFeatureAngle(m_FeatureAngle);
174 remove_points.setBCodesFeatureDefinition(m_BCodeFeatureDefinition);
175 if (m_RespectFeatureEdgesForDeleteNodes) {
176 remove_points.setProtectFeatureEdgesOn();
177 } else {
178 remove_points.setProtectFeatureEdgesOff();
180 //remove_points.setFeatureAngle(m_FeatureAngleForDeleteNodes);
181 if (m_PerformGeometricTests) {
182 remove_points.setPerformGeometricChecksOn();
183 } else {
184 remove_points.setPerformGeometricChecksOff();
186 remove_points();
187 return remove_points.getNumRemoved();
189 return 0;