TexGen
PrismVoxelMesh.cpp
Go to the documentation of this file.
1/*=============================================================================
2TexGen: Geometric textile modeller.
3Copyright (C) 2020 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"
21#include "PrismVoxelMesh.h"
22#include "TexGen.h"
23#include "DomainPrism.h"
24#include <iterator>
25//#define SHINY_PROFILER TRUE
26
27
28using namespace TexGen;
29
30CPrismVoxelMesh::CPrismVoxelMesh(string Type)
31 :CVoxelMesh(Type)
32{
33
34}
35
37{
38
39}
40
42{
43 XYZ DomSize;
44
45 CDomainPrism* Domain = Textile.GetDomain()->GetPrismDomain();
46
47 // Get the XYZ size of each axis of the domain,
48 // taking into account that they may be rotated depending on the orientation of the domain yarn specified
50
54
55 // Create map of which elements in the xy bounding box are in the prism cross-section - assumes constant cross-section
56 GetElementMap(Textile);
57
58 return true;
59}
60
61void CPrismVoxelMesh::OutputNodes(ostream &Output, CTextile &Textile, int Filetype)
62{
63 int x, y, z;
64 int iNodeIndex = 1;
65 vector<XYZ> CentrePoints;
66 vector<POINT_INFO> RowInfo;
67 XYZ StartPoint = m_StartPoint;
68
69 for (z = 0; z <= m_ZVoxels; ++z)
70 {
71 StartPoint = m_StartPoint + m_RotatedVoxSize[2] * z;
72
73 for (y = 0; y <= m_YVoxels; ++y)
74 {
75 XYZ YStartPoint;
76 YStartPoint = StartPoint + m_RotatedVoxSize[1] * y;
77
78 for (x = 0; x <= m_XVoxels; ++x)
79 {
80 XYZ Point;
81 Point = YStartPoint + m_RotatedVoxSize[0] * x;
82
83 if (Filetype == INP_EXPORT)
84 {
85 Output << iNodeIndex << ", ";
86 Output << Point << "\n";
87 }
88 else if (Filetype == VTU_EXPORT)
89 m_Mesh.AddNode(Point);
90
91 if ( x < m_XVoxels && y < m_YVoxels && z < m_ZVoxels)
92 {
93 if ( m_ElementMap.at(make_pair(x, z)) ) // Only store centre points for elements within prism
94 {
95 Point.x += 0.5*m_RotatedVoxSize[0].x;
96 Point.x += 0.5*m_RotatedVoxSize[1].x;
97 Point.x += 0.5*m_RotatedVoxSize[2].x;
98 Point.y += 0.5*m_RotatedVoxSize[0].y;
99 Point.y += 0.5*m_RotatedVoxSize[1].y;
100 Point.y += 0.5*m_RotatedVoxSize[2].y;
101 Point.z += 0.5*m_RotatedVoxSize[0].z;
102 Point.z += 0.5*m_RotatedVoxSize[1].z;
103 Point.z += 0.5*m_RotatedVoxSize[2].z;
104 CentrePoints.push_back(Point);
105 }
106 }
107 ++iNodeIndex;
108 }
109
110 }
111 RowInfo.clear(); // Changed to do layer at a time instead of row to optimise
112 Textile.GetPointInformation(CentrePoints, RowInfo);
113 m_ElementsInfo.insert(m_ElementsInfo.end(), RowInfo.begin(), RowInfo.end());
114 CentrePoints.clear();
115 }
116}
117
119{
120 m_ElementMap.clear();
121 m_NumElements = 0;
122 CDomainPrism* Domain = Textile.GetDomain()->GetPrismDomain();
123 vector<XY> PrismPoints = Domain->GetPoints();
124
125 XY Point, Min, Max;
126 GetMinMaxXY( PrismPoints, Min, Max);
127 double XSize = (Max.x - Min.x) / m_XVoxels;
128 double ZSize = (Max.y - Min.y) / m_ZVoxels; // y in 2D polygon translates to z coordinate in 3D
129
130 Point.y = Min.y + 0.5*ZSize;
131 for (int j = 0; j < m_ZVoxels; ++j)
132 {
133 Point.x = Min.x + 0.5*XSize;
134 for (int i = 0; i < m_XVoxels; ++i)
135 {
136 if (PointInside(Point, PrismPoints))
137 {
138 m_ElementMap[make_pair(i, j)] = true;
140 }
141 else
142 m_ElementMap[make_pair(i, j)] = false;
143 Point.x += XSize;
144 }
145 Point.y += ZSize;
146 }
147}
148
149int CPrismVoxelMesh::OutputHexElements(ostream &Output, bool bOutputMatrix, bool bOutputYarn, int Filetype)
150{
151 int numx = m_XVoxels + 1;
152 int numy = m_YVoxels + 1;
153 int x, y, z;
154 vector<POINT_INFO>::iterator itElementInfo = m_ElementsInfo.begin();
155 int iElementNumber = 1;
156
157 vector<POINT_INFO> NewElementInfo;
158
159 if (Filetype == SCIRUN_EXPORT)
160 Output << m_NumElements * m_YVoxels;
161
162 for (z = 0; z < m_ZVoxels; ++z)
163 {
164 for (y = 0; y < m_YVoxels; ++y)
165 {
166 for (x = 0; x < m_XVoxels; ++x)
167 {
168 if (m_ElementMap[make_pair(x, z)]) // Only export elements within domain prism outline
169 {
170 if ((itElementInfo->iYarnIndex == -1 && bOutputMatrix)
171 || (itElementInfo->iYarnIndex >= 0 && bOutputYarn))
172 {
173 if (Filetype == INP_EXPORT)
174 {
175 Output << iElementNumber << ", ";
176 Output << (x + 1) + y*numx + z*numx*numy + 1 << ", " << (x + 1) + (y + 1)*numx + z*numx*numy + 1 << ", ";
177 Output << x + (y + 1)*numx + z*numx*numy + 1 << ", " << x + y*numx + z*numx*numy + 1 << ", ";
178 Output << (x + 1) + y*numx + (z + 1)*numx*numy + 1 << ", " << (x + 1) + (y + 1)*numx + (z + 1)*numx*numy + 1 << ", ";
179 Output << x + (y + 1)*numx + (z + 1)*numx*numy + 1 << ", " << x + y*numx + (z + 1)*numx*numy + 1 << "\n";
180 }
181 else if (Filetype == SCIRUN_EXPORT)
182 {
183 Output << x + y*numx + z*numx*numy + 1 << ", " << (x + 1) + y*numx + z*numx*numy + 1 << ", ";
184 Output << x + y*numx + (z + 1)*numx*numy + 1 << ", " << (x + 1) + y*numx + (z + 1)*numx*numy + 1 << ", ";
185 Output << x + (y + 1)*numx + z*numx*numy + 1 << ", " << (x + 1) + (y + 1)*numx + z*numx*numy + 1 << ", ";
186 Output << x + (y + 1)*numx + (z + 1)*numx*numy + 1 << ", " << (x + 1) + (y + 1)*numx + (z + 1)*numx*numy + 1 << "\n";
187 }
188 else // VTU export
189 {
190 vector<int> Indices;
191 Indices.push_back(x + y*numx + z*numx*numy);
192 Indices.push_back((x + 1) + y*numx + z*numx*numy);
193 Indices.push_back((x + 1) + y*numx + (z + 1)*numx*numy);
194 Indices.push_back(x + y*numx + (z + 1)*numx*numy);
195 Indices.push_back(x + (y + 1)*numx + z*numx*numy);
196 Indices.push_back((x + 1) + (y + 1)*numx + z*numx*numy);
197 Indices.push_back((x + 1) + (y + 1)*numx + (z + 1)*numx*numy);
198 Indices.push_back(x + (y + 1)*numx + (z + 1)*numx*numy);
199 m_Mesh.AddElement(CMesh::HEX, Indices);
200 }
201 ++iElementNumber;
202 if (bOutputYarn && !bOutputMatrix) // Just saving yarn so need to make element array with just yarn info
203 {
204 NewElementInfo.push_back(*itElementInfo);
205 }
206 }
207 ++itElementInfo; // Only saved element info for elements within domain outline
208 }
209 }
210 }
211 }
212
213
214 if (bOutputYarn && !bOutputMatrix)
215 {
216 m_ElementsInfo.clear();
217 m_ElementsInfo = NewElementInfo;
218 }
219 return (iElementNumber - 1);
220}
CDomainPrism * GetPrismDomain()
Definition: Domain.cpp:54
Domain implementation described using extrusion of a polygon outline.
Definition: DomainPrism.h:36
const vector< XY > & GetPoints() const
Definition: DomainPrism.h:70
void GetPolygonLimits(XYZ &StartPoint, XYZ *SizeVecs)
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 int AddNode(XYZ Node)
Append a node to the list of nodes, the integer returns the index of the node
Definition: Mesh.cpp:2624
virtual ~CPrismVoxelMesh(void)
map< pair< int, int >, bool > m_ElementMap
Map of x,z elements within prism polygon.
void OutputNodes(ostream &Output, CTextile &Textile, int Filetype=INP_EXPORT)
Outputs nodes to .inp file and gets element information.
bool CalculateVoxelSizes(CTextile &Textile)
Calculate voxel size based on number of voxels on each axis and domain size.
XYZ m_StartPoint
Reference point for generating voxel grid (Point 0 of domain mesh)
int OutputHexElements(ostream &Output, bool bOutputMatrix, bool bOutputYarn, int Filetype)
Outputs hex elements for the elements in the element map.
void GetElementMap(CTextile &Textile)
Creates a map of elements which are within the prism outline.
XYZ m_RotatedVoxSize[3]
x, y, z lengths of rotated voxels
int m_NumElements
Number of elements in x-z slice which are output.
Represents a textile cell containing yarns.
Definition: Textile.h:39
const CDomain * GetDomain() const
Definition: Textile.h:287
void GetPointInformation(const vector< XYZ > &Points, vector< POINT_INFO > &PointsInfo, double dTolerance=1e-9)
Get useful information of a list of points.
Definition: Textile.cpp:410
Class used to generate voxel mesh for output to ABAQUS.
Definition: VoxelMesh.h:35
int m_XVoxels
Number of voxels along x,y and z axes.
Definition: VoxelMesh.h:115
vector< POINT_INFO > m_ElementsInfo
Element information as calculated by GetPointInformation.
Definition: VoxelMesh.h:123
CMesh m_Mesh
Find intersections of yarn surfaces with grid of lines from node points in each axis.
Definition: VoxelMesh.h:112
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
bool PointInside(const XY &Point, const std::vector< XY > &Nodes)
Definition: mymath.h:1574
@ SCIRUN_EXPORT
Definition: Misc.h:115
@ INP_EXPORT
Definition: Misc.h:113
@ VTU_EXPORT
Definition: Misc.h:114
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 z
Definition: mymath.h:57
double x
Definition: mymath.h:57
double y
Definition: mymath.h:57