TexGen
SectionMeshTriangulate.cpp
Go to the documentation of this file.
1/*=============================================================================
2TexGen: Geometric textile modeller.
3Copyright (C) 2006 Martin Sherburn
4
5This program is free software; you can redistribute it and/or
6modify it under the terms of the GNU General Public License
7as published by the Free Software Foundation; either version 2
8of the License, or (at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18=============================================================================*/
19
20#include "PrecompiledHeaders.h"
22#include "Section.h"
23
24extern "C"
25{
26#include "../Triangle/triangle.h"
27#include "../Triangle/triangle_api.h"
28}
29
30using namespace TexGen;
31
32CSectionMeshTriangulate::CSectionMeshTriangulate(double dMinAngle, double dMaxArea)
33: m_dMinAngle(dMinAngle)
34, m_dMaxArea(dMaxArea)
35{
36}
37
39{
40}
41
43{
44 Element.Attribute("MinAngle", &m_dMinAngle);
45 Element.Attribute("MaxArea", &m_dMaxArea);
46}
47
48void CSectionMeshTriangulate::PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType) const
49{
50 CSectionMesh::PopulateTiXmlElement(Element, OutputType);
51 Element.SetAttribute("MinAngle", stringify(m_dMinAngle));
52 Element.SetAttribute("MaxArea", stringify(m_dMaxArea));
53}
54
55bool CSectionMeshTriangulate::CreateMesh(const vector<XY> &Section) const
56{
57 // Needs testing if start to use - changed to new triangle functions
58 stringstream Switches;
59
60 double dSectionArea = CSection::GetArea(Section);
61
62 double dMaxArea = dSectionArea* m_dMaxArea;
63
64 #ifndef _DEBUG
65 Switches << "Q";
66#endif
67 // Triangle has trouble parsing values given in scientific format so use fixed format with a
68 // rediculously high precision to get around the problem
69 Switches << "pzAPBq" << setiosflags(ios::fixed) << setprecision(20) << m_dMinAngle << "a" << dMaxArea;
70
71 triangleio TriangleInput, TriangleOutput;
72
73 context *ctx;
74 ctx = triangle_context_create();
75
76 triangle_context_options(ctx, (char*)Switches.str().c_str());
77
78 memset(&TriangleInput, 0, sizeof(TriangleInput));
79 memset(&TriangleOutput, 0, sizeof(TriangleOutput));
80
81 // Input nodes
82 TriangleInput.pointlist = new REAL [Section.size()*2];
83 TriangleInput.numberofpoints = (int)Section.size();
84
85 int i;
86 for (i=0; i<(int)Section.size(); ++i)
87 {
88 TriangleInput.pointlist[i*2] = Section[i].x;
89 TriangleInput.pointlist[i*2+1] = Section[i].y;
90 }
91
92 // Input segments
93 TriangleInput.segmentlist = new int [Section.size()*2];
94 TriangleInput.numberofsegments = (int)Section.size();
95
96 for (i=0; i<(int)Section.size(); ++i)
97 {
98 TriangleInput.segmentlist[i*2] = i;
99 TriangleInput.segmentlist[i*2+1] = (i+1)%Section.size();
100 }
101
102 triangle_mesh_create(ctx, &TriangleInput);
103
104 delete [] TriangleInput.pointlist;
105 delete [] TriangleInput.segmentlist;
106
107 m_Mesh.Clear();
108
109 triangle_mesh_copy(ctx, &TriangleOutput, 1, 1);
110
111 XYZ Point;
112 for (i=0; i<TriangleOutput.numberofpoints; ++i)
113 {
114 Point.x = TriangleOutput.pointlist[i*2];
115 Point.y = TriangleOutput.pointlist[i*2+1];
116 m_Mesh.AddNode(Point);
117 }
118
119 for (i=0; i<TriangleOutput.numberoftriangles; ++i)
120 {
121 m_Mesh.GetIndices(CMesh::TRI).push_back(TriangleOutput.trianglelist[i*3]);
122 m_Mesh.GetIndices(CMesh::TRI).push_back(TriangleOutput.trianglelist[i*3+1]);
123 m_Mesh.GetIndices(CMesh::TRI).push_back(TriangleOutput.trianglelist[i*3+2]);
124 }
125
126 triangle_free(TriangleOutput.pointlist);
127 triangle_free(TriangleOutput.trianglelist);
128 triangle_context_destroy(ctx);
129
130 return true;
131}
132
134{
135 stringstream Switches;
136
137 double dSectionArea = CSection::GetArea(Section);
138
139 double dMaxArea = dSectionArea * 0.5;
140 double dMinAngle = 20;
141
142#ifndef _DEBUG
143 Switches << "Q";
144#endif
145 // Triangle has trouble parsing values given in scientific format so use fixed format with a
146 // rediculously high precision to get around the problem
147 Switches << "pzAPBq" << setiosflags(ios::fixed) << setprecision(20) << dMinAngle << "a" << dMaxArea;
148
149 triangleio TriangleInput, TriangleOutput;
150
151 context *ctx;
152 ctx = triangle_context_create();
153
154 triangle_context_options(ctx, (char*)Switches.str().c_str());
155
156 memset(&TriangleInput, 0, sizeof(TriangleInput));
157 memset(&TriangleOutput, 0, sizeof(TriangleOutput));
158
159 // Input nodes
160 TriangleInput.pointlist = new REAL[Section.size() * 2];
161 TriangleInput.numberofpoints = (int)Section.size();
162
163 int i;
164 for (i = 0; i < (int)Section.size(); ++i)
165 {
166 TriangleInput.pointlist[i * 2] = Section[i].x;
167 TriangleInput.pointlist[i * 2 + 1] = Section[i].y;
168 }
169
170 // Input segments
171 TriangleInput.segmentlist = new int[Section.size() * 2];
172 TriangleInput.numberofsegments = (int)Section.size();
173
174 for (i = 0; i < (int)Section.size(); ++i)
175 {
176 TriangleInput.segmentlist[i * 2] = i;
177 TriangleInput.segmentlist[i * 2 + 1] = (i + 1) % Section.size();
178 }
179
180 triangle_mesh_create(ctx, &TriangleInput);
181
182 delete[] TriangleInput.pointlist;
183 delete[] TriangleInput.segmentlist;
184
185 CMesh Mesh;
186
187 triangle_mesh_copy(ctx, &TriangleOutput, 1, 1);
188
189 XYZ Point;
190 for (i = 0; i < TriangleOutput.numberofpoints; ++i)
191 {
192 Point.x = TriangleOutput.pointlist[i * 2];
193 Point.y = TriangleOutput.pointlist[i * 2 + 1];
194 Mesh.AddNode(Point);
195 }
196
197 for (i = 0; i < TriangleOutput.numberoftriangles; ++i)
198 {
199 Mesh.GetIndices(CMesh::TRI).push_back(TriangleOutput.trianglelist[i * 3]);
200 Mesh.GetIndices(CMesh::TRI).push_back(TriangleOutput.trianglelist[i * 3 + 1]);
201 Mesh.GetIndices(CMesh::TRI).push_back(TriangleOutput.trianglelist[i * 3 + 2]);
202 }
203
204 triangle_free(TriangleOutput.pointlist);
205 triangle_free(TriangleOutput.trianglelist);
206 triangle_context_destroy(ctx);
207
208 return Mesh;
209}
210
212{
213 CMesh Mesh;
214
215 vector<int> ClosedLoop;
216
217 vector<XY>::const_iterator itPoint;
218 int i;
219 for (i=0, itPoint = Section.begin(); itPoint != Section.end(); ++itPoint, ++i)
220 {
221 Mesh.AddNode(XYZ(itPoint->x, itPoint->y, 0));
222 ClosedLoop.push_back(i);
223 }
224
225 Mesh.MeshClosedLoop(XYZ(0, 0, -1), ClosedLoop);
226
227 return Mesh;
228}
229
230
Defines the nodes and elements of a surface or volume mesh.
Definition: Mesh.h:58
const int AddNode(XYZ Node)
Append a node to the list of nodes, the integer returns the index of the node
Definition: Mesh.cpp:2624
const list< int > & GetIndices(ELEMENT_TYPE ElemType) const
Get the element indices of a given element type.
Definition: Mesh.cpp:2671
void MeshClosedLoop(const XYZ &Normal, const vector< int > &ClosedLoopVector, bool bQuality=false)
Definition: Mesh.cpp:1200
void Clear()
Empty mesh nodes and indices.
Definition: Mesh.cpp:1448
static double GetArea(const vector< XY > &Section)
Get the area of a section.
Definition: Section.cpp:261
CMesh m_Mesh
Used to cache the result of the previous mesh for efficiency.
Definition: SectionMesh.h:68
virtual void PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType) const
Used for saving data to XML.
Definition: SectionMesh.cpp:44
static CMesh GetSimpleMesh(const vector< XY > &Section)
void PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType) const
Used for saving data to XML.
bool CreateMesh(const vector< XY > &Section) const
Create a mesh out of given list of points representing the edge of the section.
CSectionMeshTriangulate(double dMinAngle=20, double dMaxArea=1)
Set the mesh quality parameters.
static CMesh GetTriangleMesh(const vector< XY > &Section)
Namespace containing a series of customised math operations not found in the standard c++ library.
OUTPUT_TYPE
Definition: Misc.h:105
std::string stringify(const T &x, int iPrecision=12, bool bScientific=true)
Function to convert a value (e.g. int, double, etc...) to a string.
Definition: Misc.h:50
Struct for representing points in 3D space.
Definition: mymath.h:56
double x
Definition: mymath.h:57
double y
Definition: mymath.h:57