TexGen
SectionMeshRectangleSection.cpp
Go to the documentation of this file.
1/*=============================================================================
2TexGen: Geometric textile modeller.
3Copyright (C) 2012 Louise Brown
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
23using namespace TexGen;
24CSectionMeshRectangleSection::CSectionMeshRectangleSection(int iNumLayers)
25: m_iNumLayers(iNumLayers)
26{
27 /*if (iNumLayers != -1 && iNumLayers % 2 != 0)
28 {
29 assert(false);
30 TGERROR("Warning: Rectangular mesh specified with an odd number of layers: " << iNumLayers);
31 }*/
32}
33
35{
36}
37
39{
40 Element.Attribute("NumLayers", &m_iNumLayers);
41}
42
43void CSectionMeshRectangleSection::PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType) const
44{
45 CSectionMesh::PopulateTiXmlElement(Element, OutputType);
46 Element.SetAttribute("NumLayers", m_iNumLayers);
47}
48
49bool CSectionMeshRectangleSection::CreateMesh(const vector<XY> &Section) const
50{
51 if (Section.size() % 2 != 0)
52 {
53 assert(false);
54 TGERROR("Unable to create section mesh, the number of sections points specified is odd: " << Section.size());
55 return false;
56 }
57
58 XY p1, p2, dp;
59 p1 = Section[0];
60 p2 = Section[Section.size()/2];
61 dp = p1 - p2;
62 double dAngle = atan2( dp.y, dp.x );
63 bool bRotated = false;
64
65 vector<XY> NewSection;
66 if ( fabs( dAngle ) > 0.0000001 )
67 {
68 bRotated = true;
69 for ( int i = 0; i < (int)Section.size(); ++i )
70 {
71 XY RotPoint;
72 RotPoint.x = Section[i].x*cos(dAngle) + Section[i].y*sin(dAngle);
73 RotPoint.y = Section[i].y*cos(dAngle) - Section[i].x*sin(dAngle);
74 NewSection.push_back(RotPoint);
75 }
76 }
77 else
78 {
79 NewSection.insert(NewSection.begin(), Section.begin(), Section.end() );
80 }
81
82 int iNumLayers = m_iNumLayers;
83 if (m_iNumLayers == -1)
84 iNumLayers = CalculateNumberofLayers(NewSection);
85
86
87 int iNumColumns = NewSection.size()/2-iNumLayers;
88 if (iNumColumns < 1)
89 {
90 assert(false);
91 TGERROR("Unable to create section mesh, the number of columns is less than 1: " << iNumColumns);
92 return false;
93 }
94 int i, j;
95
96 vector<double> YPoints;
97 vector<double> XPoints;
98
99 XY Min, Max;
100 GetMinMaxXY( NewSection, Min, Max );
101
102 double dXSpacing = (Max.x - Min.x)/iNumColumns;
103 double dYSpacing = (Max.y - Min.y)/iNumLayers;
104
105 double YPoint = Min.y;
106
107 for (i=0; i<iNumLayers+1; ++i) // Assemble vertical points
108 {
109 YPoints.push_back(YPoint);
110 YPoint += dYSpacing;
111 }
112
113 double XPoint = Min.x;
114
115 for (i=0; i<iNumColumns+1; ++i) // Assemble top and bottom perimeter points
116 {
117 XPoints.push_back(XPoint);
118 XPoint += dXSpacing;
119 }
120
121 m_Mesh.Clear();
122 m_Mesh.SetNumNodes((iNumLayers+1)*(iNumColumns+1));
123
124 for (i=0; i<iNumLayers+1; ++i)
125 {
126 for (j=0; j<iNumColumns+1; ++j)
127 {
128 XYZ Point( XPoints[j], YPoints[i], 0 );
129 if ( bRotated )
130 {
131 XYZ RotPoint;
132 RotPoint.x = Point.x*cos(-dAngle) + Point.y*sin(-dAngle);
133 RotPoint.y = Point.y*cos(-dAngle) - Point.x*sin(-dAngle);
134 Point = RotPoint;
135 }
136 //m_Mesh.SetNode(j+i*(iNumColumns+1), XYZ(XPoints[j], YPoints[i], 0));
137 m_Mesh.SetNode(j+i*(iNumColumns+1), Point);
138 }
139 }
140
141 for (i=0; i<iNumLayers; ++i)
142 {
143 for (j=0; j<iNumColumns; ++j)
144 {
145 m_Mesh.GetIndices(CMesh::QUAD).push_back((j+0)+(i+0)*(iNumColumns+1));
146 m_Mesh.GetIndices(CMesh::QUAD).push_back((j+1)+(i+0)*(iNumColumns+1));
147 m_Mesh.GetIndices(CMesh::QUAD).push_back((j+1)+(i+1)*(iNumColumns+1));
148 m_Mesh.GetIndices(CMesh::QUAD).push_back((j+0)+(i+1)*(iNumColumns+1));
149 }
150 }
151 bool bSurfaceNodes = true; // Add this to class later
152 if ( bSurfaceNodes )
153 {
154 vector<int> Indices;
155 for ( j = 1; j < iNumColumns; ++j )
156 {
157 Indices.push_back(j); // Nodes along top
158 }
159 for ( i = 1; i < iNumLayers; ++i )
160 {
161 Indices.push_back( iNumColumns + i * (iNumColumns+1) ); // Nodes down right side
162 }
163 for ( j = iNumColumns-1; j > 0; --j )
164 {
165 Indices.push_back( j + iNumLayers * (iNumColumns+1) ); // Nodes across bottom (right to left)
166 }
167 for ( i = iNumLayers-1; i > 0; --i )
168 {
169 Indices.push_back( i * (iNumColumns+1) ); // Nodes up left side
170 }
171 Indices.push_back( Indices[0] );
173 }
174
175 return true;
176}
177
179{
180 // Assuming the section is symmetric about all 4 quadrants
181 int i;
182 XY P1, P2, DP;
183 for (i=0; i<(int)Section.size(); ++i)
184 {
185 P1 = Section[i];
186 P2 = Section[i+1];
187 DP = P2 - P1;
188 if (abs(DP.x) > abs(DP.y))
189 {
190 if ( i == 0 )
191 return 1; // Single layer mesh
192 return i*2;
193 }
194 }
195 // Should never reach this point
196 return 0;
197}
198
200{
201 m_iNumLayers = iNum;
202}
203
204/*void CSectionMeshRectangleSection::GetMinMaxXY( const vector<XY> &Section, XY &Min, XY &Max ) const
205{
206 Min = Section[0];
207 Max = Section[0];
208 for ( int i = 1; i < (int)Section.size(); ++i )
209 {
210 if ( Section[i].x < Min.x )
211 Min.x = Section[i].x;
212 else if ( Section[i].x > Max.x )
213 Max.x = Section[i].x;
214
215 if ( Section[i].y < Min.y )
216 Min.y = Section[i].y;
217 else if ( Section[i].y > Max.y )
218 Max.y = Section[i].y;
219 }
220}*/
#define TGERROR(MESSAGE)
Macros used to report the file name and line number to the TexGenError and TexGenLog functions.
Definition: Logger.h:29
bool AddElement(ELEMENT_TYPE Type, const vector< int > &Indices)
Add an element to the mesh of given type with node number checking.
Definition: Mesh.cpp:2565
const list< int > & GetIndices(ELEMENT_TYPE ElemType) const
Get the element indices of a given element type.
Definition: Mesh.cpp:2671
@ POLYGON
Definition: Mesh.h:76
void SetNode(int iIndex, XYZ Node)
Set the node at given index.
Definition: Mesh.cpp:2630
void SetNumNodes(int NumNodes)
Resize the vector size.
Definition: Mesh.cpp:2666
void Clear()
Empty mesh nodes and indices.
Definition: Mesh.cpp:1448
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
int CalculateNumberofLayers(const vector< XY > &Section) const
bool CreateMesh(const vector< XY > &Section) const
Create a mesh out of given list of points representing the edge of the section.
void PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType) const
Used for saving data to XML.
Namespace containing a series of customised math operations not found in the standard c++ library.
void GetMinMaxXY(const std::vector< XY > &Points, XY &Min, XY &Max)
Definition: Misc.h:244
OUTPUT_TYPE
Definition: Misc.h:105
double Max(XYZ &Vector)
Get maximum element of vector and return it.
Definition: mymath.h:642
XYZ Min(const XYZ &P1, const XYZ &P2)
Given two points, return a new point who's coordinates are the smaller of the two.
Definition: mymath.h:1142
Struct for representing points in 2D space.
Definition: mymath.h:103
double x
Definition: mymath.h:104
double y
Definition: mymath.h:104
Struct for representing points in 3D space.
Definition: mymath.h:56
double x
Definition: mymath.h:57
double y
Definition: mymath.h:57