fixed edge display for volume cells
[engrid-github.git] / src / libengrid / surfacealgorithm.cpp
blob762c60b7f26caa3761f5e4dfd0165c192785fc50
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.setDelaunayThreshold(delaunay_threshold);
118 if (verbose) {
119 swap.setVerboseOn();
121 QSet<int> rest_bcs = GuiMainWindow::pointer()->getAllBoundaryCodes();
122 rest_bcs -= m_BoundaryCodes;
123 swap.setBoundaryCodes(rest_bcs);
124 swap();
127 void SurfaceAlgorithm::smooth(int N_iter, bool correct_curveture)
129 LaplaceSmoother lap;
130 lap.setGrid(m_Grid);
131 QVector<vtkIdType> cls;
132 getSurfaceCells(m_BoundaryCodes, cls, m_Grid);
133 lap.setCells(cls);
134 lap.setNumberOfIterations(N_iter);
135 lap.setBoundaryCodes(m_BoundaryCodes);//IMPORTANT: so that unselected nodes become fixed when node types are updated!
136 lap.setCorrectCurvature(correct_curveture);
137 if (m_UseProjectionForSmoothing) {
138 lap.setProjectionOn();
139 } else {
140 lap.setProjectionOff();
142 if (m_UseNormalCorrectionForSmoothing) {
143 lap.setNormalCorrectionOn();
144 } else {
145 lap.setNormalCorrectionOff();
147 lap();
148 m_SmoothSuccess = lap.succeeded();
151 int SurfaceAlgorithm::insertNodes()
153 if (m_InsertNodes) {
154 InsertPoints insert_points;
155 insert_points.setGrid(m_Grid);
156 insert_points.setBoundaryCodes(m_BoundaryCodes);
157 insert_points();
158 return insert_points.getNumInserted();
160 return 0;
163 int SurfaceAlgorithm::deleteNodes()
165 if (m_DeleteNodes) {
166 RemovePoints remove_points;
167 remove_points.setGrid(m_Grid);
168 remove_points.setBoundaryCodes(m_BoundaryCodes);
169 remove_points.setStretchingFactor(m_StretchingFactor);
170 remove_points.setFeatureAngle(m_FeatureAngle);
171 if (m_RespectFeatureEdgesForDeleteNodes) {
172 remove_points.setProtectFeatureEdgesOn();
173 } else {
174 remove_points.setProtectFeatureEdgesOff();
176 //remove_points.setFeatureAngle(m_FeatureAngleForDeleteNodes);
177 if (m_PerformGeometricTests) {
178 remove_points.setPerformGeometricChecksOn();
179 } else {
180 remove_points.setPerformGeometricChecksOff();
182 remove_points();
183 return remove_points.getNumRemoved();
185 return 0;