TexGen
Textile3DWeave.cpp
Go to the documentation of this file.
1/*=============================================================================
2TexGen: Geometric textile modeller.
3Copyright (C) 2013 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 "Textile3DWeave.h"
22//#include "SectionEllipse.h"
23#include "SectionPowerEllipse.h"
24#include "SectionPolygon.h"
25#include "SectionHybrid.h"
26#include "PatternDraft.h"
27#include "ReedData.h"
28
29using namespace TexGen;
30
31#define TOL 0.000001
32
33CTextile3DWeave::CTextile3DWeave(int iNumXYarns, int iNumYYarns, double dXSpacing, double dYSpacing,
34 double dXHeight, double dYHeight, bool bRefine )
35: m_iNumXYarns(iNumXYarns)
36, m_iNumYYarns(iNumYYarns)
37, m_dGapSize(0)
38, m_iResolution(40)
39, m_iWarpRatio(1)
40, m_iBinderRatio(1)
41, m_dWarpPower(0.5)
42, m_dWeftPower(0.5)
43, m_dBinderPower(0.5)
44, m_bRefine(bRefine)
45, m_dMaxVolumeFraction(0.78)
46, m_bWeftRepeat(true)
47{
48 m_Pattern.resize(iNumXYarns*iNumYYarns);
49 YARNDATA YarnData;
50 YarnData.dSpacing = dXSpacing;
51 YarnData.dWidth = YarnData.dSpacing;
52 YarnData.dHeight = dXHeight;
53 //YarnData.iFibresPerYarn = 0;
54 //YarnData.dFibreDiameter = 0.0;
55 m_XYarnData.resize(iNumXYarns, YarnData);
56
57 YarnData.dSpacing = dYSpacing;
58 YarnData.dWidth = YarnData.dSpacing;
59 YarnData.dHeight = dYHeight;
60 m_YYarnData.resize(iNumYYarns, YarnData);
61}
62
64{
65}
66
68: CTextile(Element)
69{
70 Element.Attribute("NumXYarns", &m_iNumXYarns);
71 Element.Attribute("NumYYarns", &m_iNumYYarns);
72 Element.Attribute("GapSize", &m_dGapSize);
73 Element.Attribute("FabricThickness", &m_dFabricThickness);
74 Element.Attribute("Resolution", &m_iResolution);
75 Element.Attribute("WarpRatio", &m_iWarpRatio);
76 Element.Attribute("BinderRatio", &m_iBinderRatio);
77 Element.Attribute("WarpPower", &m_dWarpPower);
78 Element.Attribute("WeftPower", &m_dWeftPower);
79 Element.Attribute("BinderPower", &m_dBinderPower);
80 TiXmlElement *pSectionMesh = Element.FirstChildElement("SectionMesh");
81 if (pSectionMesh)
82 {
84 }
85 FOR_EACH_TIXMLELEMENT(pPatternCell, Element, "PatternCell")
86 {
87 vector<PATTERN3D> Cell;
88 FOR_EACH_TIXMLELEMENT(pCell, *pPatternCell, "PatternElement")
89 {
90 Cell.push_back(valueify<int>(pCell->Attribute("value")));
91 }
92 m_Pattern.push_back(Cell);
93 }
94 YARNDATA YarnData;
95 FOR_EACH_TIXMLELEMENT(pYarnData, Element, "XYarnData")
96 {
97 pYarnData->Attribute("Width", &YarnData.dWidth);
98 pYarnData->Attribute("Height", &YarnData.dHeight);
99 pYarnData->Attribute("Spacing", &YarnData.dSpacing);
100 m_XYarnData.push_back(YarnData);
101 }
102 FOR_EACH_TIXMLELEMENT(pYarnData, Element, "YYarnData")
103 {
104 pYarnData->Attribute("Width", &YarnData.dWidth);
105 pYarnData->Attribute("Height", &YarnData.dHeight);
106 pYarnData->Attribute("Spacing", &YarnData.dSpacing);
107 m_YYarnData.push_back(YarnData);
108 }
109 FOR_EACH_TIXMLELEMENT(pYarns, Element, "XYarns")
110 {
111 vector<int> Indices;
112 FOR_EACH_TIXMLELEMENT(pYarn, *pYarns, "XYarn")
113 {
114 Indices.push_back(valueify<int>(pYarn->Attribute("yarnindex")));
115 }
116 m_XYarns.push_back(Indices);
117 }
118 FOR_EACH_TIXMLELEMENT(pYarns, Element, "YYarns")
119 {
120 vector<int> Indices;
121 FOR_EACH_TIXMLELEMENT(pYarn, *pYarns, "YYarn")
122 {
123 Indices.push_back(valueify<int>(pYarn->Attribute("yarnindex")));
124 }
125 m_YYarns.push_back(Indices);
126 }
128}
129
130void CTextile3DWeave::PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType)
131{
132 CTextile::PopulateTiXmlElement(Element, OutputType);
133
134 Element.SetAttribute("NumXYarns", m_iNumXYarns);
135 Element.SetAttribute("NumYYarns", m_iNumYYarns);
136 Element.SetAttribute("GapSize", stringify(m_dGapSize));
137 Element.SetAttribute("FabricThickness", stringify(m_dFabricThickness));
138 Element.SetAttribute("Resolution", m_iResolution);
139 Element.SetAttribute("WarpRatio", m_iWarpRatio);
140 Element.SetAttribute("BinderRatio", m_iBinderRatio);
141 Element.SetAttribute("WarpPower",stringify(m_dWarpPower));
142 Element.SetAttribute("WeftPower", stringify(m_dWeftPower));
143 Element.SetAttribute("BinderPower", stringify(m_dBinderPower));
144 if (m_pSectionMesh)
145 {
146 TiXmlElement SectionMesh("SectionMesh");
147 m_pSectionMesh->PopulateTiXmlElement(SectionMesh, OutputType);
148 Element.InsertEndChild(SectionMesh);
149 }
150 int i, j;
151 for (i=0; i<(int)m_Pattern.size(); ++i)
152 {
153 TiXmlElement PatternCell("PatternCell");
154 pair<int, int> Coords = GetCellCoordinates(i);
155 PatternCell.SetAttribute("x", Coords.first);
156 PatternCell.SetAttribute("y", Coords.second);
157// PatternCell.SetAttribute("index", i);
158 for (j=0; j<(int)m_Pattern[i].size(); ++j)
159 {
160 TiXmlElement PatternElement("PatternElement");
161// PatternElement.SetAttribute("index", j);
162 PatternElement.SetAttribute("value", stringify(m_Pattern[i][j]));
163 PatternCell.InsertEndChild(PatternElement);
164 }
165 Element.InsertEndChild(PatternCell);
166 }
167 for (i=0; i<(int)m_XYarnData.size(); ++i)
168 {
169 TiXmlElement XYarnData("XYarnData");
170 XYarnData.SetAttribute("index", i);
171 XYarnData.SetAttribute("Width", stringify(m_XYarnData[i].dWidth));
172 XYarnData.SetAttribute("Height", stringify(m_XYarnData[i].dHeight));
173 XYarnData.SetAttribute("Spacing", stringify(m_XYarnData[i].dSpacing));
174 Element.InsertEndChild(XYarnData);
175 }
176 for (i=0; i<(int)m_YYarnData.size(); ++i)
177 {
178 TiXmlElement YYarnData("YYarnData");
179 YYarnData.SetAttribute("index", i);
180 YYarnData.SetAttribute("Width", stringify(m_YYarnData[i].dWidth));
181 YYarnData.SetAttribute("Height", stringify(m_YYarnData[i].dHeight));
182 YYarnData.SetAttribute("Spacing", stringify(m_YYarnData[i].dSpacing));
183 Element.InsertEndChild(YYarnData);
184 }
185 if (OutputType == OUTPUT_STANDARD ||
186 OutputType == OUTPUT_FULL)
187 {
188 for (i=0; i<(int)m_XYarns.size(); ++i)
189 {
190 TiXmlElement XYarns("XYarns");
191 XYarns.SetAttribute("index", i);
192 for (j=0; j<(int)m_XYarns[i].size(); ++j)
193 {
194 TiXmlElement XYarn("XYarn");
195 // XYarn.SetAttribute("index", j);
196 XYarn.SetAttribute("yarnindex", m_XYarns[i][j]);
197 XYarns.InsertEndChild(XYarn);
198 }
199 Element.InsertEndChild(XYarns);
200 }
201 for (i=0; i<(int)m_YYarns.size(); ++i)
202 {
203 TiXmlElement YYarns("YYarns");
204 YYarns.SetAttribute("index", i);
205 for (j=0; j<(int)m_YYarns[i].size(); ++j)
206 {
207 TiXmlElement YYarn("YYarn");
208 // YYarn.SetAttribute("index", j);
209 YYarn.SetAttribute("yarnindex", m_YYarns[i][j]);
210 YYarns.InsertEndChild(YYarn);
211 }
212 Element.InsertEndChild(YYarns);
213 }
214 }
215}
216
217pair<int, int> CTextile3DWeave::GetCellCoordinates(int iIndex) const
218{
219 return make_pair(iIndex % m_iNumYYarns, iIndex / m_iNumYYarns);
220}
221
222const vector<PATTERN3D> &CTextile3DWeave::GetCell(int x, int y) const
223{
224 return m_Pattern[x + m_iNumYYarns*y];
225}
226
227vector<PATTERN3D> &CTextile3DWeave::GetCell(int x, int y)
228{
229 return m_Pattern[x + m_iNumYYarns*y];
230}
231
233{
234 m_Pattern.erase(m_Pattern.begin()+(x + m_iNumYYarns*y));
235}
236
238{
239 // Check number of yarns is the same in the x direction
240 int i, j, k, iNumYarns, iFirstNumYarns;
241 for (i=0; i<m_iNumXYarns; ++i)
242 {
243 for (j=0; j<m_iNumYYarns; ++j)
244 {
245 const vector<PATTERN3D> &Cell = GetCell(j, i);
246 iNumYarns = 0;
247 for (k=0; k<(int)Cell.size(); ++k)
248 {
249 if (Cell[k] == PATTERN3D_XYARN)
250 ++iNumYarns;
251 }
252 if (j==0)
253 {
254 iFirstNumYarns = iNumYarns;
255 }
256 else
257 {
258 if (iFirstNumYarns != iNumYarns)
259 return false;
260 }
261 }
262 }
263 // Check number of yarns is the same in the y direction
264 for (j=0; j<m_iNumYYarns; ++j)
265 {
266 for (i=0; i<m_iNumXYarns; ++i)
267 {
268 const vector<PATTERN3D> &Cell = GetCell(j, i);
269 iNumYarns = 0;
270 for (k=0; k<(int)Cell.size(); ++k)
271 {
272 if (Cell[k] == PATTERN3D_YYARN)
273 ++iNumYarns;
274 }
275 if (i==0)
276 {
277 iFirstNumYarns = iNumYarns;
278 }
279 else
280 {
281 if (iFirstNumYarns != iNumYarns)
282 return false;
283 }
284 }
285 }
286 return true;
287}
288
290{
291 m_Yarns.clear();
292 m_YYarns.clear();
293 m_XYarns.clear();
294
295 m_YYarns.resize(m_iNumYYarns);
296 m_XYarns.resize(m_iNumXYarns);
297
298 m_dMinZ = 0.0;
299 m_dMaxZ = 0.0;
300
301/* if (!Valid())
302 return false;*/
303
304 TGLOGINDENT("Building textile weave \"" << GetName() << "\"");
305 m_bNeedsBuilding = false;
306
307 bool bBinderYarns = BinderYarns();
308 vector<int> Yarns;
309
310 double x, y, z;
311
312 // Add x yarns (yarns parallel to the x axis)
313 int i, j, k, iYarn;
314 y = 0;
315 for (i=0; i<m_iNumXYarns; ++i)
316 {
317 y += m_XYarnData[i].dSpacing/2.0;
318 x = 0;
319 Yarns.clear();
320 for (j=0; j<=m_iNumYYarns; ++j)
321 {
322 const vector<PATTERN3D> &Cell = GetCell(j%m_iNumYYarns, i);
323 int NextCellIndex;
324 NextCellIndex = FindNextCellIndex(i);
325 const vector<PATTERN3D> &NextCell = GetCell(j%m_iNumYYarns, NextCellIndex );
326 if (j==0)
327 {
328 for (k=0; k<(int)Cell.size(); ++k)
329 {
330 if (Cell[k] == PATTERN3D_XYARN)
331 {
332 Yarns.push_back(AddYarn(CYarn()));
333 }
334 }
335 }
336 m_XYarns[i] = Yarns;
337 iYarn = 0;
338
339 x += m_YYarnData[j%m_iNumYYarns].dSpacing/2.0;
340
341 z = 0.0;
342 for (k=0; k<(int)Cell.size(); ++k)
343 {
344 if (Cell[k] == PATTERN3D_XYARN)
345 {
346 double dHalfHeight = m_XYarnData[i].dHeight / 2.0;
347 if ( k == 0 && IsBinderYarn(i) )
348 {
349 z -= dHalfHeight;
350 if ( (z - dHalfHeight) < m_dMinZ )
351 m_dMinZ = z - dHalfHeight;
352 }
353 else
354 z += dHalfHeight;
355 m_Yarns[Yarns[iYarn]].AddNode(CNode(XYZ(x, y, z), XYZ(1, 0, 0)));
356 ++iYarn;
357 z += dHalfHeight;
358 if ( z > m_dMaxZ )
359 m_dMaxZ = z;
360 }
361 else if ( Cell[k] == PATTERN3D_YYARN )
362 {
363 z += m_YYarnData[j%m_iNumYYarns].dHeight;
364 }
365 //else //if ( k > 0 )// PATTERN3D_NOYARN and not on bottom binder layer
366 else if ( ((k > 0 && k < (int)Cell.size()-1) && bBinderYarns) || !bBinderYarns )
367 {
368 int CellType = NextCell[k];
369 if ( CellType == PATTERN3D_NOYARN )
370 {
371 do
372 {
373 NextCellIndex = FindNextCellIndex(NextCellIndex);
374 const vector<PATTERN3D> &FindCell = GetCell(j%m_iNumYYarns, NextCellIndex );
375 CellType = FindCell[k];
376 } while ( CellType == PATTERN3D_NOYARN );
377 }
378 if ( CellType == PATTERN3D_XYARN )
379 {
380 z += m_XYarnData[NextCellIndex].dHeight;
381 }
382 else if ( CellType == PATTERN3D_YYARN )
383 {
384 z += m_YYarnData[j%m_iNumYYarns].dHeight;
385 }
386 else // PATTERN3D_NOYARN
387 {
388 }
389 }
390 }
391 if (j<m_iNumYYarns)
392 x += m_YYarnData[j].dSpacing/2.0;
393 }
394 y += m_XYarnData[i].dSpacing/2.0;
395 }
396
397 // Add y yarns (yarns parallel to the y axis)
398 x = 0;
399 for (j=0; j<m_iNumYYarns; ++j)
400 {
401 y = 0;
402 Yarns.clear();
403 x += m_YYarnData[j].dSpacing/2.0;
404 int iYCount = 0;
405
406 int NumXYarns = m_iNumXYarns;
407 if ( !m_bWeftRepeat )
408 NumXYarns--;
409 for (i=0; i<=NumXYarns; ++i)
410 {
411 const vector<PATTERN3D> &Cell = GetCell(j, i%m_iNumXYarns);
412
413 int NextCellIndex = FindNextCellIndex(i);
414 const vector<PATTERN3D> &NextCell = GetCell(j%m_iNumYYarns, NextCellIndex);
415
416 if ( !bBinderYarns )
417 {
418 for (k=0; k<(int)Cell.size(); ++k)
419 {
420 int Count = 0;
421 if (Cell[k] == PATTERN3D_YYARN )
422 {
423 Count++;
424 if ( Count > iYCount ) // Allow for partial weft yarns
425 {
426 Yarns.push_back(AddYarn(CYarn()));
427 iYCount++;
428 }
429 }
430 }
431 }
432 else if ( i == 0 )
433 {
434 for (k=0; k<(int)Cell.size(); ++k)
435 {
436 if (Cell[k] == PATTERN3D_YYARN)
437 {
438 Yarns.push_back(AddYarn(CYarn()));
439 }
440 }
441 }
442
443 m_YYarns[j] = Yarns;
444 iYarn = 0;
445 y += m_XYarnData[i%m_iNumXYarns].dSpacing/2.0;
446 z = 0.0;
447 //z = m_dFabricThickness/(2*Cell.size());
448 for (k=0; k<(int)Cell.size(); ++k)
449 {
450 if (Cell[k] == PATTERN3D_YYARN)
451 {
452 double dHalfHeight = m_YYarnData[j].dHeight / 2.0;
453 z += dHalfHeight;
454 m_Yarns[Yarns[iYarn]].AddNode(CNode(XYZ(x, y, z), XYZ(0, 1, 0)));
455 ++iYarn;
456 z += dHalfHeight;
457 }
458 else if ( Cell[k] == PATTERN3D_XYARN && k > 0 ) // Don't adjust z if it's the binder yarn
459 {
460 z += m_XYarnData[i%m_iNumXYarns].dHeight;
461 }
462 //else //if ( k > 0 ) // PATTERN3D_NOYARN and not on bottom binder layer
463 else if ( ((k > 0 && k < (int)Cell.size()-1) && bBinderYarns) || !bBinderYarns )
464 {
465 int CellType = NextCell[k];
466 if ( CellType == PATTERN3D_NOYARN )
467 {
468 do
469 {
470 NextCellIndex = FindNextCellIndex(NextCellIndex);
471 const vector<PATTERN3D> &FindCell = GetCell(j%m_iNumYYarns, NextCellIndex );
472 CellType = FindCell[k];
473 } while ( CellType == PATTERN3D_NOYARN );
474 }
475 if ( CellType == PATTERN3D_XYARN )
476 {
477 z += m_XYarnData[NextCellIndex].dHeight;
478 }
479 else if ( CellType == PATTERN3D_YYARN )
480 {
481 z += m_YYarnData[j%m_iNumYYarns].dHeight;
482 }
483 else // PATTERN3D_NOYARN
484 {
485 // Does this ever happen?
486 }
487 }
488 }
489 if (i<m_iNumXYarns)
490 y += m_XYarnData[i].dSpacing/2.0;
491 }
492 x += m_YYarnData[j].dSpacing/2.0;
493 }
494
495
496 // Assign sections to the yarns
497 vector<int>::iterator itpYarn;
498 double dWidth, dHeight;
499 for (i=0; i<m_iNumXYarns; ++i)
500 {
501 dWidth = m_XYarnData[i].dWidth;
502 dHeight = m_XYarnData[i].dHeight;
503
504 //CSectionEllipse Section(dWidth, dHeight);
505 CSectionPowerEllipse Section(dWidth, dHeight, IsBinderYarn(i) ? m_dBinderPower : m_dWarpPower );
506 if (m_pSectionMesh)
508 for (itpYarn = m_XYarns[i].begin(); itpYarn != m_XYarns[i].end(); ++itpYarn)
509 {
510 m_Yarns[*itpYarn].AssignSection(CYarnSectionConstant(Section));
511 int iType = IsBinderYarn(i) ? BINDER : WARP;
512 SetYarnProperties( m_Yarns[*itpYarn], iType );
513 }
514 }
515 for (i=0; i<m_iNumYYarns; ++i)
516 {
517 dWidth = m_YYarnData[i].dWidth;
518 dHeight = m_YYarnData[i].dHeight;
519 //CSectionEllipse Section(dWidth, dHeight);
520 CSectionPowerEllipse Section(dWidth, dHeight, m_dWeftPower);
521 if (m_pSectionMesh)
523 for (itpYarn = m_YYarns[i].begin(); itpYarn != m_YYarns[i].end(); ++itpYarn)
524 {
525 m_Yarns[*itpYarn].AssignSection(CYarnSectionConstant(Section));
526 SetYarnProperties( m_Yarns[*itpYarn], WEFT );
527 }
528 }
529
531
532 // Add repeats and set interpolation
533 dWidth = GetWidth();
534 dHeight = GetHeight();
535 vector<CYarn>::iterator itYarn;
536 for (itYarn = m_Yarns.begin(); itYarn != m_Yarns.end(); ++itYarn)
537 {
538 itYarn->AssignInterpolation(CInterpolationBezier());
539 itYarn->SetResolution(m_iResolution);
540 itYarn->AddRepeat(XYZ(dWidth, 0, 0));
541 if ( m_bWeftRepeat )
542 itYarn->AddRepeat(XYZ(0, dHeight, 0));
543 }
544
545 return true;
546}
547
548/*bool CTextile3DWeave::BuildTextile() const
549{
550 m_Yarns.clear();
551 m_YYarns.clear();
552 m_XYarns.clear();
553
554 m_YYarns.resize(m_iNumYYarns);
555 m_XYarns.resize(m_iNumXYarns);
556
557 m_dMinZ = 0.0;
558 m_dMaxZ = 0.0;
559
560 if (!Valid())
561 return false;
562
563 TGLOGINDENT("Building textile weave \"" << GetName() << "\"");
564
565 vector<int> Yarns;
566
567 double x, y, z;
568
569 // Add x yarns (yarns parallel to the x axis)
570 int i, j, k, iYarn;
571 y = 0;
572 for (i=0; i<m_iNumXYarns; ++i)
573 {
574 y += m_XYarnData[i].dSpacing/2.0;
575 x = 0;
576 Yarns.clear();
577 for (j=0; j<=m_iNumYYarns; ++j)
578 {
579 const vector<PATTERN3D> &Cell = GetCell(j%m_iNumYYarns, i);
580 int NextCellIndex;
581 NextCellIndex = FindNextCellIndex(i);
582 const vector<PATTERN3D> &NextCell = GetCell(j%m_iNumYYarns, NextCellIndex );
583 if (j==0)
584 {
585 for (k=0; k<(int)Cell.size(); ++k)
586 {
587 if (Cell[k] == PATTERN3D_XYARN)
588 {
589 Yarns.push_back(AddYarn(CYarn()));
590 }
591 }
592 }
593 m_XYarns[i] = Yarns;
594 iYarn = 0;
595
596 x += m_YYarnData[j%m_iNumYYarns].dSpacing/2.0;
597
598 z = 0.0;
599 for (k=0; k<(int)Cell.size(); ++k)
600 {
601 if (Cell[k] == PATTERN3D_XYARN)
602 {
603 double dHalfHeight = m_XYarnData[i].dHeight / 2.0;
604 if ( k == 0 && IsBinderYarn(i) )
605 {
606 z -= dHalfHeight;
607 if ( (z - dHalfHeight) < m_dMinZ )
608 m_dMinZ = z - dHalfHeight;
609 }
610 else
611 z += dHalfHeight;
612 m_Yarns[Yarns[iYarn]].AddNode(CNode(XYZ(x, y, z), XYZ(1, 0, 0)));
613 ++iYarn;
614 z += dHalfHeight;
615 if ( z > m_dMaxZ )
616 m_dMaxZ = z;
617 }
618 else if ( Cell[k] == PATTERN3D_YYARN )
619 {
620 z += m_YYarnData[j%m_iNumYYarns].dHeight;
621 }
622 else if ( k > 0 )// PATTERN3D_NOYARN and not on bottom binder layer
623 {
624 if ( NextCell[k] == PATTERN3D_XYARN )
625 {
626 z += m_XYarnData[NextCellIndex].dHeight;
627 }
628 else if ( NextCell[k] == PATTERN3D_YYARN )
629 {
630 z += m_YYarnData[j%m_iNumYYarns].dHeight;
631 }
632 else // PATTERN3D_NOYARN
633 {
634 // Does this ever happen?
635 }
636 }
637 }
638 if (j<m_iNumYYarns)
639 x += m_YYarnData[j].dSpacing/2.0;
640 }
641 y += m_XYarnData[i].dSpacing/2.0;
642 }
643
644 // Add y yarns (yarns parallel to the y axis)
645 x = 0;
646 for (j=0; j<m_iNumYYarns; ++j)
647 {
648 y = 0;
649 Yarns.clear();
650 x += m_YYarnData[j].dSpacing/2.0;
651 for (i=0; i<=m_iNumXYarns; ++i)
652 {
653 const vector<PATTERN3D> &Cell = GetCell(j, i%m_iNumXYarns);
654
655 int NextCellIndex = FindNextCellIndex(i);
656 const vector<PATTERN3D> &NextCell = GetCell(j%m_iNumYYarns, NextCellIndex);
657 if (i==0)
658 {
659 for (k=0; k<(int)Cell.size(); ++k)
660 {
661 if (Cell[k] == PATTERN3D_YYARN)
662 {
663 Yarns.push_back(AddYarn(CYarn()));
664 }
665 }
666 }
667 m_YYarns[j] = Yarns;
668 iYarn = 0;
669 y += m_XYarnData[i%m_iNumXYarns].dSpacing/2.0;
670 z = 0.0;
671 //z = m_dFabricThickness/(2*Cell.size());
672 for (k=0; k<(int)Cell.size(); ++k)
673 {
674 if (Cell[k] == PATTERN3D_YYARN)
675 {
676 double dHalfHeight = m_YYarnData[j].dHeight / 2.0;
677 z += dHalfHeight;
678 m_Yarns[Yarns[iYarn]].AddNode(CNode(XYZ(x, y, z), XYZ(0, 1, 0)));
679 ++iYarn;
680 z += dHalfHeight;
681 }
682 else if ( Cell[k] == PATTERN3D_XYARN && k > 0 ) // Don't adjust z if it's the binder yarn
683 {
684 z += m_XYarnData[i%m_iNumXYarns].dHeight;
685 }
686 else if ( k > 0 ) // PATTERN3D_NOYARN and not on bottom binder layer
687 {
688 if ( NextCell[k] == PATTERN3D_XYARN )
689 {
690 z += m_XYarnData[NextCellIndex].dHeight;
691 }
692 else if ( NextCell[k] == PATTERN3D_YYARN )
693 {
694 z += m_YYarnData[j%m_iNumYYarns].dHeight;
695 }
696 else // PATTERN3D_NOYARN
697 {
698 // Does this ever happen?
699 }
700 }
701 }
702 if (i<m_iNumXYarns)
703 y += m_XYarnData[i].dSpacing/2.0;
704 }
705 x += m_YYarnData[j].dSpacing/2.0;
706 }
707
708
709 // Assign sections to the yarns
710 vector<int>::iterator itpYarn;
711 double dWidth, dHeight;
712 for (i=0; i<m_iNumXYarns; ++i)
713 {
714 dWidth = m_XYarnData[i].dWidth;
715 dHeight = m_XYarnData[i].dHeight;
716
717 //CSectionEllipse Section(dWidth, dHeight);
718 CSectionPowerEllipse Section(dWidth, dHeight, IsBinderYarn(i) ? m_dBinderPower : m_dWarpPower );
719 if (m_pSectionMesh)
720 Section.AssignSectionMesh(*m_pSectionMesh);
721 for (itpYarn = m_XYarns[i].begin(); itpYarn != m_XYarns[i].end(); ++itpYarn)
722 {
723 m_Yarns[*itpYarn].AssignSection(CYarnSectionConstant(Section));
724 }
725 }
726 for (i=0; i<m_iNumYYarns; ++i)
727 {
728 dWidth = m_YYarnData[i].dWidth;
729 dHeight = m_YYarnData[i].dHeight;
730 //CSectionEllipse Section(dWidth, dHeight);
731 CSectionPowerEllipse Section(dWidth, dHeight, m_dWeftPower);
732 if (m_pSectionMesh)
733 Section.AssignSectionMesh(*m_pSectionMesh);
734 for (itpYarn = m_YYarns[i].begin(); itpYarn != m_YYarns[i].end(); ++itpYarn)
735 {
736 m_Yarns[*itpYarn].AssignSection(CYarnSectionConstant(Section));
737 }
738 }
739
740 // Add repeats and set interpolation
741 dWidth = GetWidth();
742 dHeight = GetHeight();
743 vector<CYarn>::iterator itYarn;
744 for (itYarn = m_Yarns.begin(); itYarn != m_Yarns.end(); ++itYarn)
745 {
746 itYarn->AssignInterpolation(CInterpolationBezier());
747 itYarn->SetResolution(m_iResolution);
748 itYarn->AddRepeat(XYZ(dWidth, 0, 0));
749 itYarn->AddRepeat(XYZ(0, dHeight, 0));
750 }
751
752 return true;
753}*/
754
755void CTextile3DWeave::SetThickness(double dThickness)
756{
757 m_dFabricThickness = dThickness;
758 m_bNeedsBuilding = true;
759}
760
761void CTextile3DWeave::SetMaxVolFraction( double dVolFraction )
762{
763 m_dMaxVolumeFraction = dVolFraction;
764 m_bNeedsBuilding = true;
765}
766
767void CTextile3DWeave::SetGapSize(double dGapSize)
768{
769 m_dGapSize = dGapSize;
770 m_bNeedsBuilding = true;
771}
772
774{
775 m_iResolution = iResolution;
776 m_bNeedsBuilding = true;
777}
778
780{
781 m_pSectionMesh = SectionMesh;
782 m_bNeedsBuilding = true;
783}
784
785
786
787/*bool CTextile3DWeave::NeedsMidSection(int iYarn, int iSection) const
788{
789 int i, j;
790 for (i=0; i<(int)m_XYarns.size(); ++i)
791 {
792 for (j=0; j<(int)m_XYarns[i].size(); ++j)
793 {
794 if (m_XYarns[i][j] == iYarn)
795 {
796 int iNextSection = (iSection+1) % m_YYarns.size();
797 return !(GetCell(iSection, i) == GetCell(iNextSection, i));
798 }
799 }
800 }
801 for (i=0; i<(int)m_YYarns.size(); ++i)
802 {
803 for (j=0; j<(int)m_YYarns[i].size(); ++j)
804 {
805 if (m_YYarns[i][0] == iYarn)
806 {
807 int iNextSection = (iSection+1) % m_XYarns.size();
808 return !(GetCell(i, iSection) == GetCell(i, iNextSection));
809 }
810 }
811 }
812 return true;
813}*/
814
815void CTextile3DWeave::SetXYarnWidths(int iIndex, double dWidth)
816{
817 if (iIndex<0 || iIndex>=m_iNumXYarns)
818 {
819 TGERROR("Unable to set yarn width, index out of range: " << iIndex);
820 return;
821 }
822 m_XYarnData[iIndex].dWidth = dWidth;
823 m_bNeedsBuilding = true;
824}
825
826void CTextile3DWeave::SetYYarnWidths(int iIndex, double dWidth)
827{
828 if (iIndex<0 || iIndex>=m_iNumYYarns)
829 {
830 TGERROR("Unable to set yarn width, index out of range: " << iIndex);
831 return;
832 }
833 m_YYarnData[iIndex].dWidth = dWidth;
834 m_bNeedsBuilding = true;
835}
836
837void CTextile3DWeave::SetXYarnHeights(int iIndex, double dHeight)
838{
839 if (iIndex<0 || iIndex>=m_iNumXYarns)
840 {
841 TGERROR("Unable to set yarn height, index out of range: " << iIndex);
842 return;
843 }
844 m_XYarnData[iIndex].dHeight = dHeight;
845 m_bNeedsBuilding = true;
846}
847
848void CTextile3DWeave::SetYYarnHeights(int iIndex, double dHeight)
849{
850 if (iIndex<0 || iIndex>=m_iNumYYarns)
851 {
852 TGERROR("Unable to set yarn height, index out of range: " << iIndex);
853 return;
854 }
855 m_YYarnData[iIndex].dHeight = dHeight;
856 m_bNeedsBuilding = true;
857}
858
859void CTextile3DWeave::SetXYarnSpacings(int iIndex, double dSpacing)
860{
861 if (iIndex<0 || iIndex>=m_iNumXYarns)
862 {
863 TGERROR("Unable to set yarn spacing, index out of range: " << iIndex);
864 return;
865 }
866 m_XYarnData[iIndex].dSpacing = dSpacing;
867 m_bNeedsBuilding = true;
868}
869
870void CTextile3DWeave::SetYYarnSpacings(int iIndex, double dSpacing)
871{
872 if (iIndex<0 || iIndex>=m_iNumYYarns)
873 {
874 TGERROR("Unable to set yarn spacing, index out of range: " << iIndex);
875 return;
876 }
877 m_YYarnData[iIndex].dSpacing = dSpacing;
878 m_bNeedsBuilding = true;
879}
880
881/*void CTextile3DWeave::SetXYarnFibresPerYarn( int iIndex, int iNumFibres )
882{
883 if (iIndex<0 || iIndex>=m_iNumXYarns)
884 {
885 TGERROR("Unable to set fibres per yarn, index out of range: " << iIndex);
886 return;
887 }
888 m_XYarnData[iIndex].iFibresPerYarn = iNumFibres;
889 m_bNeedsBuilding = true;
890}
891
892void CTextile3DWeave::SetYYarnFibresPerYarn( int iIndex, int iNumFibres )
893{
894 if (iIndex<0 || iIndex>=m_iNumYYarns)
895 {
896 TGERROR("Unable to set fibres per yarn, index out of range: " << iIndex);
897 return;
898 }
899 m_YYarnData[iIndex].iFibresPerYarn = iNumFibres;
900 m_bNeedsBuilding = true;
901}
902
903void CTextile3DWeave::SetXYarnFibreDiameter( int iIndex, double dFibreDiameter )
904{
905 if (iIndex<0 || iIndex>=m_iNumXYarns)
906 {
907 TGERROR("Unable to set fibre diameter, index out of range: " << iIndex);
908 return;
909 }
910 m_XYarnData[iIndex].dFibreDiameter = dFibreDiameter;
911 m_bNeedsBuilding = true;
912}
913
914void CTextile3DWeave::SetYYarnFibreDiameter( int iIndex, double dFibreDiameter )
915{
916 if (iIndex<0 || iIndex>=m_iNumYYarns)
917 {
918 TGERROR("Unable to set fibre diameter, index out of range: " << iIndex);
919 return;
920 }
921 m_YYarnData[iIndex].dFibreDiameter = dFibreDiameter;
922 m_bNeedsBuilding = true;
923}*/
924
925
926double CTextile3DWeave::GetXYarnWidths(int iIndex) const
927{
928 if (iIndex<0 || iIndex>=m_iNumXYarns)
929 {
930 TGERROR("Unable to set yarn width, index out of range: " << iIndex);
931 return 0;
932 }
933 return m_XYarnData[iIndex].dWidth;
934}
935
936double CTextile3DWeave::GetYYarnWidths(int iIndex) const
937{
938 if (iIndex<0 || iIndex>=m_iNumYYarns)
939 {
940 TGERROR("Unable to get yarn width, index out of range: " << iIndex);
941 return 0;
942 }
943 return m_YYarnData[iIndex].dWidth;
944}
945
946double CTextile3DWeave::GetXYarnHeights(int iIndex) const
947{
948 if (iIndex<0 || iIndex>=m_iNumXYarns)
949 {
950 TGERROR("Unable to get yarn height, index out of range: " << iIndex);
951 return 0;
952 }
953 return m_XYarnData[iIndex].dHeight;
954}
955
956double CTextile3DWeave::GetYYarnHeights(int iIndex) const
957{
958 if (iIndex<0 || iIndex>=m_iNumYYarns)
959 {
960 TGERROR("Unable to get yarn height, index out of range: " << iIndex);
961 return 0;
962 }
963 return m_YYarnData[iIndex].dHeight;
964}
965
966double CTextile3DWeave::GetXYarnSpacings(int iIndex) const
967{
968 if (iIndex<0 || iIndex>=m_iNumXYarns)
969 {
970 TGERROR("Unable to get yarn spacing, index out of range: " << iIndex);
971 return 0;
972 }
973 return m_XYarnData[iIndex].dSpacing;
974}
975
976double CTextile3DWeave::GetYYarnSpacings(int iIndex) const
977{
978 if (iIndex<0 || iIndex>=m_iNumYYarns)
979 {
980 TGERROR("Unable to get yarn spacing, index out of range: " << iIndex);
981 return 0;
982 }
983 return m_YYarnData[iIndex].dSpacing;
984}
985
986/*int CTextile3DWeave::GetXYarnFibresPerYarn( int iIndex ) const
987{
988 if (iIndex<0 || iIndex>=m_iNumXYarns)
989 {
990 TGERROR("Unable to get fibres per yarn, index out of range: " << iIndex);
991 return 0;
992 }
993 return m_XYarnData[iIndex].iFibresPerYarn;
994}
995
996int CTextile3DWeave::GetYYarnFibresPerYarn( int iIndex ) const
997{
998 if (iIndex<0 || iIndex>=m_iNumYYarns)
999 {
1000 TGERROR("Unable to get fibres per yarn, index out of range: " << iIndex);
1001 return 0;
1002 }
1003 return m_YYarnData[iIndex].iFibresPerYarn;
1004}
1005
1006double CTextile3DWeave::GetXYarnFibreDiameter( int iIndex ) const
1007{
1008 if (iIndex<0 || iIndex>=m_iNumXYarns)
1009 {
1010 TGERROR("Unable to get fibre diameter, index out of range: " << iIndex);
1011 return 0;
1012 }
1013 return m_XYarnData[iIndex].dFibreDiameter;
1014}
1015
1016double CTextile3DWeave::GetYYarnFibreDiameter( int iIndex ) const
1017{
1018 if (iIndex<0 || iIndex>=m_iNumYYarns)
1019 {
1020 TGERROR("Unable to get fibre diameter, index out of range: " << iIndex);
1021 return 0;
1022 }
1023 return m_YYarnData[iIndex].dFibreDiameter;
1024}*/
1025
1026double CTextile3DWeave::GetXYarnGapSize(int iIndex) const
1027{
1028 if (iIndex<0 || iIndex>=m_iNumXYarns)
1029 {
1030 TGERROR("Unable to get yarn spacing, index out of range: " << iIndex);
1031 return 0;
1032 }
1033 double dGapSize = m_XYarnData[iIndex].dSpacing;
1034 dGapSize -= 0.5*m_XYarnData[iIndex].dWidth;
1035 if (iIndex == m_iNumXYarns-1)
1036 dGapSize -= 0.5*m_XYarnData[0].dWidth;
1037 else
1038 dGapSize -= 0.5*m_XYarnData[iIndex+1].dWidth;
1039 return dGapSize;
1040}
1041
1042double CTextile3DWeave::GetYYarnGapSize(int iIndex) const
1043{
1044 if (iIndex<0 || iIndex>=m_iNumYYarns)
1045 {
1046 TGERROR("Unable to get yarn spacing, index out of range: " << iIndex);
1047 return 0;
1048 }
1049 double dGapSize = m_YYarnData[iIndex].dSpacing;
1050 dGapSize -= 0.5*m_YYarnData[iIndex].dWidth;
1051 if (iIndex == m_iNumYYarns-1)
1052 dGapSize -= 0.5*m_YYarnData[0].dWidth;
1053 else
1054 dGapSize -= 0.5*m_YYarnData[iIndex+1].dWidth;
1055 return dGapSize;
1056}
1057
1058
1060{
1061 int i;
1062 for (i=0; i<m_iNumXYarns; ++i)
1063 {
1064 SetXYarnWidths(i, dWidth);
1065 }
1066}
1067
1069{
1070 int i;
1071 for ( i=0; i < m_iNumXYarns; ++i )
1072 {
1073 if ( !IsBinderYarn( i ) )
1074 {
1075 SetXYarnWidths( i, dWidth );
1076 }
1077 }
1078}
1079
1081{
1082 int i;
1083 for ( i=0; i < m_iNumXYarns; ++i )
1084 {
1085 if ( IsBinderYarn( i ) )
1086 {
1087 SetXYarnWidths( i, dWidth );
1088 }
1089 }
1090}
1091
1093{
1094 int i;
1095 for (i=0; i<m_iNumYYarns; ++i)
1096 {
1097 SetYYarnWidths(i, dWidth);
1098 }
1099}
1100
1102{
1103 int i;
1104 for (i=0; i<m_iNumXYarns; ++i)
1105 {
1106 SetXYarnHeights(i, dHeight);
1107 }
1108}
1109
1111{
1112 int i;
1113 for (i=0; i<m_iNumYYarns; ++i)
1114 {
1115 SetYYarnHeights(i, dHeight);
1116 }
1117}
1118
1120{
1121 int i;
1122 for ( i=0; i < m_iNumXYarns; ++i )
1123 {
1124 if ( !IsBinderYarn( i ) )
1125 {
1126 SetXYarnHeights( i, dHeight );
1127 }
1128 }
1129}
1130
1132{
1133 int i;
1134 for ( i=0; i < m_iNumXYarns; ++i )
1135 {
1136 if ( IsBinderYarn( i ) )
1137 {
1138 SetXYarnHeights( i, dHeight );
1139 }
1140 }
1141}
1142
1144{
1145 int i;
1146 for (i=0; i<m_iNumXYarns; ++i)
1147 {
1148 SetXYarnSpacings(i, dSpacing);
1149 }
1150}
1151
1153{
1154 int i;
1155 for (i=0; i<m_iNumXYarns; ++i)
1156 {
1157 if ( !IsBinderYarn( i ) )
1158 {
1159 SetXYarnSpacings(i, dSpacing);
1160 }
1161 }
1162}
1163
1165{
1166 int i;
1167 for (i=0; i<m_iNumXYarns; ++i)
1168 {
1169 if ( IsBinderYarn( i ) )
1170 {
1171 SetXYarnSpacings(i, dSpacing);
1172 }
1173 }
1174}
1175
1177{
1178 int i;
1179 for (i=0; i<m_iNumYYarns; ++i)
1180 {
1181 SetYYarnSpacings(i, dSpacing);
1182 }
1183}
1184
1185/*void CTextile3DWeave::SetWarpYarnFibresPerYarn( int iNumFibres )
1186{
1187 int i;
1188 for (i=0; i<m_iNumXYarns; ++i)
1189 {
1190 if ( !IsBinderYarn(i) )
1191 {
1192 SetXYarnFibresPerYarn(i, iNumFibres);
1193 }
1194 }
1195}
1196
1197void CTextile3DWeave::SetYYarnFibresPerYarn( int iNumFibres )
1198{
1199 int i;
1200 for (i=0; i<m_iNumYYarns; ++i)
1201 {
1202 SetYYarnFibresPerYarn(i, iNumFibres);
1203 }
1204}
1205
1206void CTextile3DWeave::SetBinderYarnFibresPerYarn( int iNumFibres )
1207{
1208 int i;
1209 for (i=0; i<m_iNumXYarns; ++i)
1210 {
1211 if ( IsBinderYarn(i) )
1212 {
1213 SetXYarnFibresPerYarn(i, iNumFibres);
1214 }
1215 }
1216}
1217
1218void CTextile3DWeave::SetWarpYarnFibreDiameter( double dFibreDiameter )
1219{
1220 int i;
1221 for (i=0; i<m_iNumXYarns; ++i)
1222 {
1223 if ( !IsBinderYarn(i) )
1224 {
1225 SetXYarnFibreDiameter(i, dFibreDiameter);
1226 }
1227 }
1228}
1229
1230void CTextile3DWeave::SetYYarnFibreDiameter( double dFibreDiameter )
1231{
1232 int i;
1233 for (i=0; i<m_iNumYYarns; ++i)
1234 {
1235 SetYYarnFibreDiameter(i, dFibreDiameter);
1236 }
1237}
1238
1239void CTextile3DWeave::SetBinderYarnFibreDiameter( double dFibreDiameter )
1240{
1241 int i;
1242 for (i=0; i<m_iNumXYarns; ++i)
1243 {
1244 if ( IsBinderYarn(i) )
1245 {
1246 SetXYarnFibreDiameter(i, dFibreDiameter);
1247 }
1248 }
1249}*/
1250
1251void CTextile3DWeave::SetYarnLinearDensity( int iYarnType, double dValue, string Units )
1252{
1253 m_Properties[iYarnType].SetYarnLinearDensity( dValue, Units );
1254}
1255
1256void CTextile3DWeave::SetFibreDensity(int iYarnType, double dValue, string Units)
1257{
1258 m_Properties[iYarnType].SetFibreDensity(dValue, Units);
1259}
1260
1261void CTextile3DWeave::SetFibreArea(int iYarnType, double dValue, string Units)
1262{
1263 m_Properties[iYarnType].SetFibreArea(dValue, Units);
1264}
1265
1266void CTextile3DWeave::SetFibresPerYarn( int iYarnType, int iNumFibres )
1267{
1268 m_Properties[iYarnType].SetFibresPerYarn( iNumFibres );
1269}
1270
1271void CTextile3DWeave::SetFibreDiameter( int iYarnType, double dValue, string Units )
1272{
1273 m_Properties[iYarnType].SetFibreDiameter( dValue, Units );
1274}
1275
1276double CTextile3DWeave::GetFibreArea( int iYarnType, string Units )
1277{
1278 return m_Properties[iYarnType].GetFibreArea( Units );
1279}
1280
1282{
1283 SetXYarnWidths(dWidth);
1284 SetYYarnWidths(dWidth);
1285}
1286
1288{
1289 SetXYarnHeights(dHeight);
1290 SetYYarnHeights(dHeight);
1291}
1292
1294{
1295 SetXYarnSpacings(dSpacing);
1296 SetYYarnSpacings(dSpacing);
1297}
1298
1300{
1301 double dWidth = 0;
1302
1303 int i;
1304
1305 for (i=0; i<m_iNumYYarns; ++i)
1306 {
1307 dWidth += m_YYarnData[i].dSpacing;
1308 }
1309
1310 return dWidth;
1311}
1312
1314{
1315 double dHeight = 0;
1316
1317 int j;
1318
1319 for (j=0; j<m_iNumXYarns; ++j)
1320 {
1321 dHeight += m_XYarnData[j].dSpacing;
1322 }
1323
1324 return dHeight;
1325}
1326
1328{
1329 XYZ Min, Max;
1330
1331 FindMinMaxZ( Min.z, Max.z );
1332 double dGap = 0.0;
1333 if ( bAddedHeight )
1334 dGap = 0.05 * ( Max.z - Min.z );
1335 Min.z -= dGap;
1336 Max.z += dGap;
1337
1338 Min.x = 0.0;
1339 Min.y = 0.0;
1340
1341 Max.x = Min.x + GetWidth();
1342 Max.y = Min.y + GetHeight();
1343
1344 return CDomainPlanes(Min, Max);
1345}
1346
1348{
1349 CDomainPlanes Domain = GetDefaultDomain( bAddedHeight );
1350 AssignDomain(Domain);
1351}
1352
1354{
1355 CDomain* Domain = GetDomain();
1356 if ( Domain && Domain->GetType() == "CDomainPlanes" )
1357 {
1358 XYZ Min, Max;
1359 if ( ((CDomainPlanes*)Domain)->GetBoxLimits( Min, Max ) )
1360 {
1362 {
1363 Min.z = m_dMinZ;
1364 Max.z = m_dMaxZ;
1365 RemoveDomain();
1366 CDomainPlanes NewDomain = CDomainPlanes( Min, Max );
1367 AssignDomain( NewDomain );
1368 }
1369 }
1370 }
1371}
1372
1374{
1375 return "3DWeave(W:" + stringify(m_iNumYYarns) + ",H:" + stringify(m_iNumXYarns) + ")";
1376}
1377
1379{
1380 int i;
1381
1382 double dWidth = 0;
1383 for (i=0; i<m_iNumXYarns; ++i)
1384 {
1385 dWidth += m_XYarnData[i].dWidth;
1386 }
1387 for (i=0; i<m_iNumYYarns; ++i)
1388 {
1389 dWidth += m_YYarnData[i].dWidth;
1390 }
1391
1392 return dWidth/(m_iNumXYarns+m_iNumYYarns);
1393}
1394
1396{
1397 int i;
1398
1399 double dWidth = 0;
1400 for (i=0; i<m_iNumYYarns; ++i)
1401 {
1402 dWidth += m_YYarnData[i].dWidth;
1403 }
1404
1405 return dWidth/m_iNumYYarns;
1406}
1407
1409{
1410 int i;
1411
1412 double dHeight = 0;
1413 for (i=0; i<m_iNumYYarns; ++i)
1414 {
1415 dHeight += m_YYarnData[i].dHeight;
1416 }
1417
1418 return dHeight/m_iNumYYarns;
1419}
1420
1421
1422vector<CYarn*> CTextile3DWeave::GetXYarns(int iIndex)
1423{
1424 vector<CYarn*> Yarns;
1425 if (!BuildTextileIfNeeded())
1426 return Yarns;
1427 if (iIndex<0 || iIndex>=m_iNumXYarns)
1428 {
1429 TGERROR("Unable to get yarn, index out of range: " << iIndex);
1430 return Yarns;
1431 }
1432 vector<int>::iterator itIndex;
1433 for (itIndex = m_XYarns[iIndex].begin(); itIndex != m_XYarns[iIndex].end(); ++itIndex)
1434 {
1435 Yarns.push_back(&m_Yarns[*itIndex]);
1436 }
1437 return Yarns;
1438}
1439
1440vector<CYarn*> CTextile3DWeave::GetYYarns(int iIndex)
1441{
1442 vector<CYarn*> Yarns;
1443 if (!BuildTextileIfNeeded())
1444 return Yarns;
1445 if (iIndex<0 || iIndex>=m_iNumYYarns)
1446 {
1447 TGERROR("Unable to get yarn, index out of range: " << iIndex);
1448 }
1449 vector<int>::iterator itIndex;
1450 for (itIndex = m_YYarns[iIndex].begin(); itIndex != m_YYarns[iIndex].end(); ++itIndex)
1451 {
1452 Yarns.push_back(&m_Yarns[*itIndex]);
1453 }
1454 return Yarns;
1455}
1456
1457int CTextile3DWeave::GetYarnIndex(int x, int y, int z) const
1458{
1459 int iXYarnCount = 0;
1460 int iYYarnCount = 0;
1461 vector<PATTERN3D> Pattern = GetCell(x, y);
1462 int k;
1463 if ( Pattern[z] == PATTERN3D_NOYARN )
1464 return -1;
1465
1466 for (k=0; k<z; ++k)
1467 {
1468 if (Pattern[k] == PATTERN3D_XYARN)
1469 ++iXYarnCount;
1470 else if (Pattern[k] == PATTERN3D_YYARN)
1471 ++iYYarnCount;
1472 }
1473 if (Pattern[z] == PATTERN3D_XYARN)
1474 return m_XYarns[y][iXYarnCount];
1475 else
1476 return m_YYarns[x][iYYarnCount];
1477}
1478
1479void CTextile3DWeave::AddYLayers(int x, int iNumberLayers)
1480{
1481 if (x<0 || x>=m_iNumYYarns)
1482 {
1483 TGERROR("Unable to add yarn layer, index out of range: " << x);
1484 return;
1485 }
1486 int i, j;
1487 for (i=0; i<m_iNumXYarns; ++i)
1488 {
1489 for (j=0; j<iNumberLayers; ++j)
1490 GetCell(x, i).push_back(PATTERN3D_YYARN);
1491 }
1492 m_bNeedsBuilding = true;
1493}
1494
1495void CTextile3DWeave::AddXLayers(int y, int iNumberLayers)
1496{
1497 if (y<0 || y>=m_iNumXYarns)
1498 {
1499 TGERROR("Unable to add yarn layer, index out of range: " << y);
1500 return;
1501 }
1502 int i, j;
1503 for (i=0; i<m_iNumYYarns; ++i)
1504 {
1505 for (j=0; j<iNumberLayers; ++j)
1506 GetCell(i, y).push_back(PATTERN3D_XYARN);
1507 }
1508 m_bNeedsBuilding = true;
1509}
1510
1512{
1513 if (y<0 || y>=m_iNumXYarns)
1514 {
1515 TGERROR("Unable to add yarn layer, index out of range: " << y);
1516 return;
1517 }
1518 int i;
1519 for (i=0; i<m_iNumYYarns; ++i)
1520 {
1521 GetCell(i, y).push_back( Pattern );
1522 }
1523 m_bNeedsBuilding = true;
1524}
1525
1527{
1528 if ( x<0 || x>=m_iNumYYarns)
1529 {
1530 TGERROR("Unable to add yarn layer, index out of range: " << x);
1531 return;
1532 }
1533
1534 for ( int i = 0; i < m_iNumXYarns; ++i )
1535 {
1536 GetCell(x,i).push_back( Pattern );
1537 }
1538 m_bNeedsBuilding = true;
1539}
1540
1541void CTextile3DWeave::AddYLayers(int iNumberLayers)
1542{
1543 int i;
1544 for (i=0; i<m_iNumYYarns; ++i)
1545 {
1546 AddYLayers(i, iNumberLayers);
1547 }
1548}
1549
1550void CTextile3DWeave::AddXLayers(int iNumberLayers)
1551{
1552 int i;
1553 for (i=0; i<m_iNumXYarns; ++i)
1554 {
1555 AddXLayers(i, iNumberLayers);
1556 }
1557}
1558
1560{
1561 int i;
1562 for ( i = 0; i < m_iNumXYarns; ++i )
1563 {
1565 }
1566}
1567
1569{
1570 int i;
1571 for (i=0; i<m_iNumXYarns; ++i)
1572 {
1573 if ( IsBinderYarn( i ) )
1574 {
1576 }
1577 else
1578 {
1580 }
1581 }
1582}
1583
1585{
1586 int i;
1587 for (i=0; i<m_iNumXYarns; ++i)
1588 {
1589 if ( IsBinderYarn( i ) )
1590 {
1592 }
1593 else
1594 {
1596 }
1597 }
1598}
1599
1600void CTextile3DWeave::DeleteYLayers(int x, int iNumberLayers)
1601{
1602 if (x<0 || x>=m_iNumYYarns)
1603 {
1604 TGERROR("Unable to delete yarn layer, index out of range: " << x);
1605 return;
1606 }
1607 int i, j;
1608 vector<PATTERN3D>::reverse_iterator itCell;
1609 for (i=0; i<m_iNumXYarns; ++i)
1610 {
1611 for (j=0; j<iNumberLayers; ++j)
1612 {
1613 vector<PATTERN3D> &Cell = GetCell(x, i);
1614 itCell = find(Cell.rbegin(), Cell.rend(), (int)PATTERN3D_YYARN);
1615 if (itCell != Cell.rend())
1616 {
1617 Cell.erase(itCell.base()-1);
1618 }
1619 }
1620 }
1621 m_bNeedsBuilding = true;
1622}
1623
1624void CTextile3DWeave::DeleteXLayers(int y, int iNumberLayers)
1625{
1626 if (y<0 || y>=m_iNumXYarns)
1627 {
1628 TGERROR("Unable to delete yarn layer, index out of range: " << y);
1629 return;
1630 }
1631 int i, j;
1632 vector<PATTERN3D>::reverse_iterator itCell;
1633 for (i=0; i<m_iNumYYarns; ++i)
1634 {
1635 for (j=0; j<iNumberLayers; ++j)
1636 {
1637 vector<PATTERN3D> &Cell = GetCell(i, y);
1638 itCell = find(Cell.rbegin(), Cell.rend(), (int)PATTERN3D_XYARN);
1639 if (itCell != Cell.rend())
1640 {
1641 Cell.erase(itCell.base()-1);
1642 }
1643 }
1644 }
1645 m_bNeedsBuilding = true;
1646}
1647
1648void CTextile3DWeave::DeleteYLayers(int iNumberLayers)
1649{
1650 int i;
1651 for (i=0; i<m_iNumYYarns; ++i)
1652 {
1653 DeleteYLayers(i, iNumberLayers);
1654 }
1655}
1656
1657void CTextile3DWeave::DeleteXLayers(int iNumberLayers)
1658{
1659 int i;
1660 for (i=0; i<m_iNumXYarns; ++i)
1661 {
1662 DeleteXLayers(i, iNumberLayers);
1663 }
1664}
1665
1667{
1668 const vector<PATTERN3D> &Cell = GetCell(x, 0);
1669 return count(Cell.begin(), Cell.end(), (int)PATTERN3D_YYARN);
1670}
1671
1673{
1674 const vector<PATTERN3D> &Cell = GetCell(0, y);
1675 return count(Cell.begin(), Cell.end(), (int)PATTERN3D_XYARN);
1676}
1677
1679{
1680 int i, j;
1681 int iMaxLayers = 0;
1682 for (i=0; i<m_iNumYYarns; ++i)
1683 {
1684 for (j=0; j<m_iNumXYarns; ++j)
1685 {
1686 iMaxLayers = max(iMaxLayers, (int)GetCell(i, j).size());
1687 }
1688 }
1689 return iMaxLayers;
1690}
1691
1692void CTextile3DWeave::SwapPosition(int x, int y, int iLevel1, int iLevel2)
1693{
1694 if (x<0 || x>=m_iNumYYarns || y<0 || y>=m_iNumXYarns)
1695 {
1696 TGERROR("Unable to swap position, index out of range: " << x << ", " << y);
1697 return;
1698 }
1699 vector<PATTERN3D> &Cell = GetCell(x, y);
1700 if (iLevel1 < 0 || iLevel1 >= (int)Cell.size())
1701 {
1702 TGERROR("Unable to swap position, level out of range: " << iLevel1);
1703 return;
1704 }
1705 if (iLevel2 < 0 || iLevel2 >= (int)Cell.size())
1706 {
1707 TGERROR("Unable to swap position, level out of range: " << iLevel2);
1708 return;
1709 }
1710 int bTemp;
1711 bTemp = Cell[iLevel1];
1712 Cell[iLevel1] = Cell[iLevel2];
1713 Cell[iLevel2] = bTemp;
1714 m_bNeedsBuilding = true;
1715}
1716
1717/*double CTextile3DWeave::GetFabricThickness()
1718{
1719 return (
1720}*/
1721
1722bool CTextile3DWeave::IsBinderYarn( int index ) const
1723{
1724 if ( m_BinderPattern.size() > index )
1725 return m_BinderPattern[index];
1726
1727 int iRepeat = m_iWarpRatio + m_iBinderRatio;
1728
1729 if ( (index % iRepeat) < m_iWarpRatio )
1730 return WARP;
1731 return BINDER;
1732}
1733
1735{
1736 for ( int i = 0; i < m_XYarns.size(); ++i )
1737 {
1738 vector<int>::iterator itYarns;
1739 for ( itYarns = m_XYarns[i].begin(); itYarns != m_XYarns[i].end(); ++itYarns )
1740 {
1741 if ( *itYarns == YarnInd )
1742 return i;
1743 }
1744 }
1745 return -1;
1746}
1747
1749{
1750 for ( int i = 0; i < m_BinderPattern.size(); ++i )
1751 {
1752 if ( m_BinderPattern[i] )
1753 return true;
1754 }
1755 return false;
1756}
1757
1758void CTextile3DWeave::SetWarpRatio( int iWarpRatio )
1759{
1760 m_iWarpRatio = iWarpRatio;
1762}
1763
1764void CTextile3DWeave::SetBinderRatio( int iBinderRatio )
1765{
1766 if ( iBinderRatio < 1 )
1767 {
1768 TGERROR("Binder ratio must be greater than 0");
1769 return;
1770 }
1771 m_iBinderRatio = iBinderRatio;
1773}
1774
1776{
1777 m_BinderPattern.clear();
1778 int iRepeat = m_iWarpRatio + m_iBinderRatio;
1779 for ( int i = 0; i < m_iNumXYarns; ++i )
1780 {
1781 if ( (i % iRepeat) < m_iWarpRatio )
1782 m_BinderPattern.push_back( false );
1783 else
1784 m_BinderPattern.push_back( true );
1785 }
1786}
1787
1788void CTextile3DWeave::SetBinderPattern( vector<bool> &BinderPattern )
1789{
1790 m_BinderPattern.clear();
1791 m_BinderPattern = BinderPattern;
1792}
1793
1794int CTextile3DWeave::FindNextCellIndex( int StartIndex ) const
1795{
1796 int i = StartIndex + 1;
1797 while ( i < m_iNumXYarns && IsBinderYarn( i ) )
1798 {
1799 i++;
1800 }
1801 if ( i < m_iNumXYarns )
1802 return i;
1803
1804 if ( StartIndex == 0 )
1805 return StartIndex;
1806 i = StartIndex - 1;
1807 while( i >= 0 && IsBinderYarn( i ) )
1808 {
1809 i--;
1810 }
1811 if ( i == -1 )
1812 return StartIndex;
1813 return i;
1814}
1815
1816int CTextile3DWeave::FindNextYCellIndex( int Starti, int j, int k ) const
1817{
1818 int i = Starti + 1;
1819 while ( i < m_iNumYYarns )
1820 {
1821 const vector<PATTERN3D> &Cell = GetCell( i, j );
1822 if ( Cell[k] != PATTERN3D_NOYARN )
1823 break;
1824 i++;
1825 }
1826 if ( i < m_iNumYYarns )
1827 return i;
1828
1829 if ( Starti == 0 )
1830 return Starti;
1831 i = Starti - 1;
1832 while( i >= 0 )
1833 {
1834 const vector<PATTERN3D> &Cell = GetCell( i, j );
1835 if ( Cell[k] != PATTERN3D_NOYARN )
1836 break;
1837 i--;
1838 }
1839 if ( i == -1 )
1840 return Starti;
1841 return i;
1842}
1843
1844int CTextile3DWeave::FindPrevYCellIndex( int Starti, int j, int k ) const
1845{
1846 int i = Starti - 1;
1847 if ( i == -1 )
1848 i = m_iNumYYarns-1;
1849
1850 while ( i >= 0 )
1851 {
1852 const vector<PATTERN3D> &Cell = GetCell( i, j );
1853 if ( Cell[k] != PATTERN3D_NOYARN )
1854 break;
1855 i--;
1856 }
1857 if ( i >= 0 )
1858 return i;
1859
1860 if ( Starti == 0 )
1861 return Starti;
1862
1863 i = Starti + 1;
1864 while( i < m_iNumYYarns )
1865 {
1866 const vector<PATTERN3D> &Cell = GetCell( i, j );
1867 if ( Cell[k] != PATTERN3D_NOYARN )
1868 break;
1869 i++;
1870 }
1871 if ( i == m_iNumYYarns )
1872 return Starti;
1873 return i;
1874}
1875
1876void CTextile3DWeave::FindMinMaxZ( double &dMinZ, double &dMaxZ )
1877{
1878 dMinZ = dMaxZ = 0.0;
1879 for (int i=0; i<m_iNumXYarns; ++i)
1880 {
1881 for (int j=0; j<=m_iNumYYarns; ++j)
1882 {
1883 const vector<PATTERN3D> &Cell = GetCell(j%m_iNumYYarns, i);
1884 int NextCellIndex;
1885 NextCellIndex = FindNextCellIndex(i);
1886 const vector<PATTERN3D> &NextCell = GetCell(j%m_iNumYYarns, NextCellIndex%m_iNumXYarns );
1887 double z = 0.0;
1888 for (int k=0; k<(int)Cell.size(); ++k)
1889 {
1890 if (Cell[k] == PATTERN3D_XYARN)
1891 {
1892
1893 double dHalfHeight = m_XYarnData[i].dHeight / 2.0;
1894 if ( IsBinderYarn(i) && k != (int)Cell.size()-1 )
1895 {
1896 if ( k == 0 )
1897 {
1898 z -= dHalfHeight + m_dGapSize;
1899 if ( (z - dHalfHeight) < dMinZ )
1900 dMinZ = z - dHalfHeight;
1901 }
1902 else
1903 {
1904 if ( m_XYarnData[NextCellIndex].dHeight > m_XYarnData[i].dHeight )
1905 dHalfHeight = m_XYarnData[NextCellIndex].dHeight / 2.0;
1906 z += dHalfHeight;
1907 }
1908 }
1909 else
1910 z += dHalfHeight;
1911
1912 z += dHalfHeight + m_dGapSize;
1913
1914 }
1915 else if ( Cell[k] == PATTERN3D_YYARN )
1916 {
1917 z += m_YYarnData[j%m_iNumYYarns].dHeight + m_dGapSize;
1918 }
1919 else if ( k > 0 && k < (int)Cell.size()-1)// PATTERN3D_NOYARN and not on bottom binder layer
1920 {
1921 if ( NextCell[k] == PATTERN3D_XYARN )
1922 {
1923 z += m_XYarnData[NextCellIndex%m_iNumXYarns].dHeight + m_dGapSize;
1924 }
1925 else if ( NextCell[k] == PATTERN3D_YYARN )
1926 {
1927 z += m_YYarnData[j%m_iNumYYarns].dHeight + m_dGapSize;
1928 }
1929 else // PATTERN3D_NOYARN
1930 {
1931 // Will get here if all x yarns are binder yarns so just use binder yarn height to give spacing
1932 z += m_XYarnData[i%m_iNumXYarns].dHeight + m_dGapSize;
1933 }
1934 }
1935 if ( z > dMaxZ )
1936 dMaxZ = z;
1937 }
1938 }
1939 }
1940}
1941
1942void CTextile3DWeave::SetupLayers( int iNumWarpLayers, int iNumWeftLayers, int iNumBinderLayers )
1943{
1944}
1945
1947{
1948 return 1;
1949}
1950
1951void CTextile3DWeave::ReplaceLastNode( int BinderYarnIndex, XYZ& NewNode, XYZ& BinderNode ) const
1952{
1953 int iLastNode = m_Yarns[BinderYarnIndex].GetNumNodes() - 1;
1954 XYZ LastNode = m_Yarns[BinderYarnIndex].GetNode(iLastNode)->GetPosition();
1955 XYZ Offset = BinderNode - NewNode;
1956
1957 LastNode -= Offset;
1958 m_Yarns[BinderYarnIndex].ReplaceNode( iLastNode, LastNode );
1959}
1960
1962{
1963 if (m_Yarns[WeftYarnIndex].GetYarnSection()->GetType() != "CYarnSectionConstant")
1964 return NULL;
1965 CYarnSectionConstant* pYarnSection = (CYarnSectionConstant*)m_Yarns[WeftYarnIndex].GetYarnSection()->Copy();
1966 CSectionPowerEllipse* Section = (CSectionPowerEllipse*)pYarnSection->GetSection().Copy();
1967 delete pYarnSection;
1968 return Section;
1969
1970}
1971
1972CSection* CTextile3DWeave::GetCrossSection( int YarnIndex, int Node ) const
1973{
1974 string Type = m_Yarns[YarnIndex].GetYarnSection()->GetType();
1975 CSection* pSection;
1976 if ( Type == "CYarnSectionConstant" )
1977 {
1978 CYarnSectionConstant* pYarnSection = (CYarnSectionConstant*)m_Yarns[YarnIndex].GetYarnSection()->Copy();
1979 pSection = pYarnSection->GetSection().Copy();
1980 delete pYarnSection;
1981 return pSection;
1982 }
1983 else if ( Type == "CYarnSectionInterpNode" )
1984 {
1985 CYarnSectionInterpNode* pYarnSection = (CYarnSectionInterpNode*)m_Yarns[YarnIndex].GetYarnSection()->Copy();
1986 pSection = pYarnSection->GetNodeSection(Node).Copy();
1987 delete pYarnSection;
1988 return pSection;
1989 }
1990 else
1991 return NULL;
1992}
1993
1995{
1996
1997 //PROFILE_FUNC();
1998 int iNumXYarns = m_iNumXYarns;
1999 //if ( !m_bWeftRepeat )
2000 // iNumXYarns--;
2001 vector<int> XNodes( iNumXYarns, 0 );
2002 for ( int i = 0; i < m_iNumYYarns; ++i )
2003 {
2004 int CurrentYNode = 0;
2005 for ( int j = 0; j < iNumXYarns; ++j )
2006 {
2007 CurrentYNode = AddWeftNodes( CurrentYNode, XNodes[j], i, j );
2008 if ( CurrentYNode >= 0 )
2009 XNodes[j]++; //move along to next warp stack
2010 CurrentYNode++;
2011 }
2012 m_bNeedsBuilding = false;
2014 }
2015
2016}
2017
2018int CTextile3DWeave::FindWeftHeight( const vector<PATTERN3D>& Cell ) const
2019{
2020 int i = Cell.size() - 1;
2021 while( i >= 0 )
2022 {
2023 if ( Cell[i] == PATTERN3D_YYARN )
2024 return i;
2025 --i;
2026 }
2027 return i;
2028}
2029
2030int CTextile3DWeave::FindWarpAboveIndex( const vector<PATTERN3D> &Cell, int iIndex ) const
2031{
2032 iIndex++;
2033 while ( iIndex < (int)Cell.size() )
2034 {
2035 if ( Cell[iIndex] == PATTERN3D_XYARN )
2036 return iIndex;
2037 ++iIndex;
2038 }
2039 return -1;
2040}
2041
2042int CTextile3DWeave::FindWarpBelowIndex( const vector<PATTERN3D> &Cell, int iIndex ) const
2043{
2044 iIndex--;
2045 while ( iIndex >= 0 )
2046 {
2047 if ( Cell[iIndex] == PATTERN3D_XYARN )
2048 return iIndex;
2049 --iIndex;
2050 }
2051 return iIndex;
2052}
2053
2054int CTextile3DWeave::AddWeftNodes( int CurrentNode, int XNode, int i, int j ) const
2055{
2056
2057 const vector<PATTERN3D> &Cell = GetCell(i,j);
2058 int iIndex = FindWeftHeight( Cell );
2059 if ( iIndex == -1 )
2060 return -1; // Partial weft - no weft yarn at this location
2061
2062 /*if ( !m_bWeftRepeat && j == m_iNumXYarns - 1 )
2063 {
2064 // Insert node at end half x yarn width away
2065 // Change CurrentNode accordingly
2066 return CurrentNode;
2067 }
2068
2069 if ( !m_bWeftRepeat && j == 0 ) // Also need to catch start of partial weft insertions?
2070 {
2071 // Insert node at beginning half x yarn width away
2072 // Change CurrentNode accordingly
2073 return CurrentNode;
2074 }*/
2075 int NextCellIndex = (j+1)%m_iNumXYarns;
2076 int PrevCellIndex = (j+m_iNumXYarns-1)%m_iNumXYarns;
2077
2078 const vector<PATTERN3D> &NextCell = GetCell( i, NextCellIndex );
2079 const vector<PATTERN3D> &PrevCell = GetCell( i, PrevCellIndex );
2080
2081
2082 int iPrevIndex = FindWeftHeight( PrevCell ); //finds z-location of weft in textile
2083 int iNextIndex = FindWeftHeight( NextCell );
2084 int iMaxIndex = Cell.size() - 1; //max z-location of weft
2085
2086 XY SectionPoint;
2087 XYZ WarpBelowNode, WarpAboveNode;
2088 int iStartNode = CurrentNode;
2089
2090 if ( iIndex < 0 )
2091 return CurrentNode;
2092
2093 //double dBinderOffset = m_XYarnData[j].dHeight/2.0;
2094 double dWeftOffset = m_YYarnData[i].dHeight/2.0;
2095
2096 int WeftYarnIndex = GetYarnIndex( i, j, iIndex );
2097 if ( WeftYarnIndex == -1 ) // Can this happen?
2098 return CurrentNode;
2099 int WarpAboveIndex, WarpBelowIndex;
2100 int WarpAboveCellIndex, WarpBelowCellIndex;
2101
2102 // Get yarn indices and positions of nodes of warp yarns above and below weft node
2103 if ( iIndex < (int)Cell.size() - 1 )
2104 {
2105 WarpAboveCellIndex = FindWarpAboveIndex( Cell, iIndex );
2106 if ( WarpAboveCellIndex != -1 ) //there is a warp above weft
2107 {
2108 WarpAboveIndex = GetYarnIndex( i, j, WarpAboveCellIndex );
2109 if ( WarpAboveIndex >= 0 )
2110 WarpAboveNode = m_Yarns[WarpAboveIndex].GetNode( XNode )->GetPosition();
2111 }
2112 else
2113 WarpAboveIndex = -1; //no warp above weft
2114 }
2115 else
2116 WarpAboveIndex = -1;
2117
2118 if ( iIndex > 0 )
2119 {
2120 WarpBelowCellIndex = FindWarpBelowIndex( Cell, iIndex );
2121 //WarpBelowIndex = GetYarnIndex( i, j, iIndex - 1 );
2122 if ( WarpBelowCellIndex != -1 )
2123 {
2124 WarpBelowIndex = GetYarnIndex( i, j, WarpBelowCellIndex );
2125 if ( WarpBelowIndex >= 0 )
2126 WarpBelowNode = m_Yarns[WarpBelowIndex].GetNode( XNode )->GetPosition();
2127 }
2128 else
2129 WarpBelowIndex = -1;
2130 }
2131 else
2132 WarpBelowIndex = -1;
2133
2134 //XYZ BinderNode = m_Yarns[BinderYarnIndex].GetNode( CurrentNode )->GetPosition();
2135 //Get current node position
2136 XYZ WeftNode = m_Yarns[WeftYarnIndex].GetNode( CurrentNode )->GetPosition();
2137 if ( iIndex > 0 && iPrevIndex != -1 && iPrevIndex < iIndex-1 && PrevCell[iPrevIndex] == PATTERN3D_YYARN // Check for being more than one layer apart
2138 && GetYarnIndex( i,PrevCellIndex, iPrevIndex ) == WeftYarnIndex)
2139 {
2140 // Get cross section of warp yarn below
2141 if ( WarpBelowIndex == -1 )
2142 return CurrentNode;
2143 CSection* YarnSection = GetCrossSection( WarpBelowIndex );
2144 if ( YarnSection == NULL )
2145 return CurrentNode;
2146
2147 // Insert points around Top left quadrant of warp yarn
2148 XYZ NewNode = WarpBelowNode;
2149
2150 if ( iIndex - iPrevIndex > 2 ) //Presumably hard coded because differences greater than 1 weft pos cause intersections
2151 {
2152 SectionPoint = YarnSection->GetPoint(0.5);
2153 NewNode.y = NewNode.y + SectionPoint.x - dWeftOffset - m_dGapSize;
2154 NewNode.z = NewNode.z + SectionPoint.y;
2155 m_Yarns[WeftYarnIndex].InsertNode( NewNode, CurrentNode);
2156 CurrentNode++;
2157 }
2158
2159 InsertWeftNode( YarnSection, 0.45, WarpBelowNode, CurrentNode, WeftYarnIndex, dWeftOffset + m_dGapSize );
2160 InsertWeftNode( YarnSection, 0.4, WarpBelowNode, CurrentNode, WeftYarnIndex, dWeftOffset + m_dGapSize );
2161 if( !( iIndex < iMaxIndex && iNextIndex > iIndex && NextCell[iNextIndex] == PATTERN3D_YYARN
2162 && GetYarnIndex( i, NextCellIndex, iNextIndex ) == WeftYarnIndex ) )
2163 {
2164 InsertWeftNode( YarnSection, 0.35, WarpBelowNode, CurrentNode, WeftYarnIndex, dWeftOffset + m_dGapSize );
2165 InsertWeftNode( YarnSection, 0.3, WarpBelowNode, CurrentNode, WeftYarnIndex, dWeftOffset + m_dGapSize );
2166 }
2167
2168 /*if ( iNextIndex <= iIndex && NextCell[iNextIndex] == PATTERN3D_XYARN
2169 && GetYarnIndex( NextCellIndex, j, iNextIndex ) == BinderYarnIndex)
2170 {
2171 InsertBinderNode( YarnSection, 0.25, WeftBelowNode, CurrentNode, BinderYarnIndex, dBinderOffset + m_dGapSize, false );
2172 }*/
2173 delete YarnSection;
2174 }
2175 else if ( iIndex < iMaxIndex && iPrevIndex != -1 && iPrevIndex > iIndex+1 && PrevCell[iPrevIndex] == PATTERN3D_YYARN
2176 && GetYarnIndex( i, PrevCellIndex, iPrevIndex ) == WeftYarnIndex )
2177 {
2178 if ( WarpAboveCellIndex != iIndex+1 ) // Warp not directly above so don't need to change weft
2179 return CurrentNode;
2180 // Get cross section of warp yarn below
2181 CSection* YarnSection = GetCrossSection( WarpAboveIndex );
2182 if ( YarnSection == NULL )
2183 return CurrentNode;
2184 // Insert points around lower left quadrant of weft yarn
2185 XYZ NewNode = WarpAboveNode;
2186
2187 if ( iPrevIndex - iIndex > 2 )
2188 {
2189 SectionPoint = YarnSection->GetPoint(0.5);
2190 NewNode.y = NewNode.y + SectionPoint.x - dWeftOffset - m_dGapSize;
2191 NewNode.z = NewNode.z + SectionPoint.y;
2192 m_Yarns[WeftYarnIndex].InsertNode( NewNode, CurrentNode);
2193 CurrentNode++;
2194 }
2195
2196 NewNode = WarpAboveNode;
2197
2198 InsertWeftNode( YarnSection, 0.55, WarpAboveNode, CurrentNode, WeftYarnIndex, -(dWeftOffset + m_dGapSize) );
2199 InsertWeftNode( YarnSection, 0.6, WarpAboveNode, CurrentNode, WeftYarnIndex, -(dWeftOffset + m_dGapSize) );
2200
2201 if ( !( iIndex > 0 && iNextIndex < iIndex && NextCell[iNextIndex] == PATTERN3D_YYARN
2202 && GetYarnIndex( i, NextCellIndex, iNextIndex ) == WeftYarnIndex ) )
2203 {
2204 InsertWeftNode( YarnSection, 0.65, WarpAboveNode, CurrentNode, WeftYarnIndex, -(dWeftOffset + m_dGapSize) );
2205 InsertWeftNode( YarnSection, 0.7, WarpAboveNode, CurrentNode, WeftYarnIndex, -(dWeftOffset + m_dGapSize) );
2206 }
2207
2208 if ( iNextIndex >= iIndex && NextCell[iNextIndex] == PATTERN3D_YYARN
2209 && GetYarnIndex( i, NextCellIndex, iNextIndex ) == WeftYarnIndex )
2210 {
2211 InsertWeftNode( YarnSection, 0.75, WarpAboveNode, CurrentNode, WeftYarnIndex, -(dWeftOffset + m_dGapSize), false );
2212 }
2213 delete YarnSection;
2214 }
2215
2216
2217
2218 if ( iIndex > 0 && iNextIndex != -1 && iNextIndex < iIndex-1 && NextCell[iNextIndex] == PATTERN3D_YYARN
2219 && GetYarnIndex( i, NextCellIndex, iNextIndex ) == WeftYarnIndex )
2220 {
2221 // Get cross section of weft yarn below
2222 CSection* YarnSection = GetCrossSection( WarpBelowIndex );
2223 if ( YarnSection == NULL )
2224 return CurrentNode;
2225
2226 if ( iPrevIndex <= iIndex && PrevCell[iPrevIndex] == PATTERN3D_YYARN
2227 && GetYarnIndex( i, PrevCellIndex, iPrevIndex ) == WeftYarnIndex )
2228 {
2229 InsertWeftNode( YarnSection, 0.25, WarpBelowNode, CurrentNode, WeftYarnIndex, dWeftOffset + m_dGapSize, false );
2230 }
2231 // Insert points around upper right quadrant of weft
2232
2233 XYZ NewNode = WarpBelowNode;
2234 CurrentNode++; // Need to insert after node (ie before next node)
2235 if ( !(iIndex < iMaxIndex && iPrevIndex > iIndex && PrevCell[iPrevIndex] == PATTERN3D_YYARN
2236 && GetYarnIndex( i, PrevCellIndex, iPrevIndex ) == WeftYarnIndex ) )
2237 {
2238 InsertWeftNode( YarnSection, 0.2, WarpBelowNode, CurrentNode, WeftYarnIndex, dWeftOffset + m_dGapSize );
2239 InsertWeftNode( YarnSection, 0.15, WarpBelowNode, CurrentNode, WeftYarnIndex, dWeftOffset + m_dGapSize );
2240 }
2241 InsertWeftNode( YarnSection, 0.1, WarpBelowNode, CurrentNode, WeftYarnIndex, dWeftOffset + m_dGapSize );
2242 InsertWeftNode( YarnSection, 0.05, WarpBelowNode, CurrentNode, WeftYarnIndex, dWeftOffset + m_dGapSize );
2243 CurrentNode--;
2244
2245 if ( iIndex - iNextIndex > 2 )
2246 {
2247 SectionPoint = YarnSection->GetPoint(0);
2248 NewNode = WarpBelowNode;
2249 NewNode.y = NewNode.y + SectionPoint.x + dWeftOffset + m_dGapSize;
2250 NewNode.z = NewNode.z + SectionPoint.y;
2251 m_Yarns[WeftYarnIndex].InsertNode( NewNode, CurrentNode+1 );
2252 CurrentNode++;
2253 }
2254
2255 delete YarnSection;
2256 }
2257 else if( iIndex < iMaxIndex && iNextIndex != -1 && iNextIndex > iIndex+1 && NextCell[iNextIndex] == PATTERN3D_YYARN
2258 && GetYarnIndex( i, NextCellIndex, iNextIndex ) == WeftYarnIndex )
2259 {
2260 if ( WarpAboveCellIndex != iIndex+1 ) // Warp not directly above so don't need to change weft
2261 return CurrentNode;
2262
2263 // Get cross section of weft yarn below
2264 CSection* YarnSection = GetCrossSection( WarpAboveIndex );
2265 if ( YarnSection == NULL )
2266 return CurrentNode;
2267
2268 if ( iPrevIndex >= iIndex && PrevCell[iPrevIndex] == PATTERN3D_YYARN
2269 && GetYarnIndex( i, PrevCellIndex, iPrevIndex ) == WeftYarnIndex )
2270 {
2271 InsertWeftNode( YarnSection, 0.75, WarpAboveNode, CurrentNode, WeftYarnIndex, -(dWeftOffset + m_dGapSize), false );
2272 }
2273 // Insert points around lower right quadrant of weft yarn
2274 {
2275 XYZ NewNode = WarpAboveNode;
2276 CurrentNode++; // Need to insert after node (ie before next node)
2277 if ( !(iIndex > 0 && iPrevIndex < iIndex && PrevCell[iPrevIndex] == PATTERN3D_YYARN
2278 && GetYarnIndex( i, PrevCellIndex, iPrevIndex ) == WeftYarnIndex) )
2279 {
2280 InsertWeftNode( YarnSection, 0.8, WarpAboveNode, CurrentNode, WeftYarnIndex, -(dWeftOffset + m_dGapSize) );
2281 InsertWeftNode( YarnSection, 0.85, WarpAboveNode, CurrentNode, WeftYarnIndex, -(dWeftOffset + m_dGapSize) );
2282 }
2283 InsertWeftNode( YarnSection, 0.9, WarpAboveNode, CurrentNode, WeftYarnIndex, -(dWeftOffset + m_dGapSize) );
2284 InsertWeftNode( YarnSection, 0.95, WarpAboveNode, CurrentNode, WeftYarnIndex, -(dWeftOffset + m_dGapSize) );
2285 CurrentNode--;
2286
2287 if ( iNextIndex - iIndex > 2 )
2288 {
2289 SectionPoint = YarnSection->GetPoint(0);
2290 NewNode = WarpAboveNode;
2291 NewNode.y = NewNode.y + SectionPoint.x + dWeftOffset + m_dGapSize;
2292 NewNode.z = NewNode.z + SectionPoint.y;
2293 m_Yarns[WeftYarnIndex].InsertNode( NewNode, CurrentNode+1 );
2294 CurrentNode++;
2295 }
2296 }
2297
2298 delete YarnSection;
2299 }
2300
2301 if ( iStartNode == 0 && m_bWeftRepeat )
2302 {
2303 XYZ NewNode = m_Yarns[WeftYarnIndex].GetNode(0)->GetPosition();
2304 ReplaceLastNode( WeftYarnIndex, NewNode, WeftNode );
2305 }
2306
2307 return CurrentNode;
2308}
2309
2310void CTextile3DWeave::CheckUpVectors( int Index, bool bYarn, bool bYarnsIndex ) const
2311{
2313 int YarnIndex = 0;
2314 if ( bYarnsIndex )
2315 {
2316 if ( Index > m_Yarns.size()-1 )
2317 return;
2318 YarnIndex = Index;
2319 }
2320 else
2321 {
2322 if ( bYarn == PATTERN3D_XYARN )
2323 {
2324 if ( Index > m_iNumXYarns-1 )
2325 return;
2326 YarnIndex = m_XYarns[Index][0];
2327 }
2328 else
2329 {
2330 if ( Index > m_iNumYYarns-1 )
2331 return;
2332 YarnIndex = m_YYarns[Index][0];
2333 }
2334 }
2335
2336 vector<CNode> Nodes = m_Yarns[YarnIndex].GetMasterNodes();
2337 vector<CNode>::iterator itNodes;
2338
2339 XYZ CheckNodes[3];
2340 XYZ UpVector, StartUp;
2341 int size = Nodes.size();
2342
2343
2344 for ( int i = 0; i < size-1; ++i)
2345 {
2346 CheckNodes[1] = Nodes[i].GetPosition();
2347 if ( i == 0 )
2348 {
2349 CheckNodes[0] = CheckNodes[1];
2350 CheckNodes[2] = Nodes[i+1].GetPosition();
2351 }
2352 else
2353 {
2354 CheckNodes[2] = Nodes[i+1].GetPosition();
2355 }
2356 UpVector = GetUpVector( CheckNodes, bYarn );
2357 Nodes[i].SetUp( UpVector );
2358 if ( i == 0 )
2359 Nodes[size-1].SetUp(UpVector);
2360 CheckNodes[0] = CheckNodes[1];
2361 }
2362 m_Yarns[YarnIndex].SetNodes( Nodes );
2363}
2364
2365XYZ CTextile3DWeave::GetUpVector( XYZ CheckNodes[], bool bYarn ) const
2366{
2367 double dHorz, dz;
2368 dz = CheckNodes[2].z - CheckNodes[0].z;
2369
2370 if ( bYarn == PATTERN3D_XYARN )
2371 dHorz = CheckNodes[2].x - CheckNodes[0].x;
2372 else
2373 dHorz = CheckNodes[2].y - CheckNodes[0].y;
2374 XYZ UpVector;
2375
2376 if ( fabs(dz) > fabs(dHorz) )
2377 {
2378 if ( dz >= 0.0 )
2379 {
2380 if ( bYarn == PATTERN3D_XYARN )
2381 UpVector.x = -1;
2382 else
2383 UpVector.y = -1;
2384 }
2385 else
2386 {
2387 if ( bYarn == PATTERN3D_XYARN )
2388 UpVector.x = 1;
2389 else
2390 UpVector.y = 1;
2391
2392 }
2393 }
2394 else
2395 {
2396 if ( dHorz >= 0.0 )
2397 {
2398 UpVector.z = 1;
2399 }
2400 else
2401 {
2402 UpVector.z = -1;
2403 }
2404 }
2405 return UpVector;
2406}
2407
2408void CTextile3DWeave::InsertBinderNode( CSectionPowerEllipse* YarnSection, double t, XYZ& WeftNode, int& CurrentNode, int BinderYarnIndex, double Offset, bool bInsert ) const
2409{
2410 XY SectionPoint = YarnSection->GetPoint(t);
2411 XYZ NewNode = WeftNode;
2412
2413 NewNode.x = NewNode.x + SectionPoint.x;
2414 NewNode.z = NewNode.z + SectionPoint.y + Offset;
2415 if ( bInsert )
2416 {
2417 m_Yarns[BinderYarnIndex].InsertNode( NewNode, CurrentNode);
2418 CurrentNode++;
2419 }
2420 else
2421 m_Yarns[BinderYarnIndex].ReplaceNode( CurrentNode, NewNode );
2422
2423}
2424
2425void CTextile3DWeave::InsertBinderNode( CSection* YarnSection, double t, XYZ& WeftNode, int& CurrentNode, int BinderYarnIndex, double Offset, bool bInsert ) const
2426{
2427 string Type = YarnSection->GetType();
2428 XY SectionPoint;
2429 if ( Type == "CSectionPowerEllipse" )
2430 SectionPoint = ((CSectionPowerEllipse*)YarnSection)->GetPoint(t);
2431 else
2432 SectionPoint = ((CSectionHybrid*)YarnSection)->GetPoint(t);
2433 XYZ NewNode = WeftNode;
2434
2435 NewNode.x = NewNode.x + SectionPoint.x;
2436 NewNode.z = NewNode.z + SectionPoint.y + Offset;
2437 if ( bInsert )
2438 {
2439 m_Yarns[BinderYarnIndex].InsertNode( NewNode, CurrentNode);
2440 CurrentNode++;
2441 }
2442 else
2443 m_Yarns[BinderYarnIndex].ReplaceNode( CurrentNode, NewNode );
2444
2445}
2446
2447void CTextile3DWeave::InsertWeftNode( CSection* YarnSection, double t, XYZ& WarpNode, int& CurrentNode, int WeftYarnIndex, double Offset, bool bInsert ) const
2448{
2449
2450 string Type = YarnSection->GetType();
2451 XY SectionPoint;
2452 if ( Type == "CSectionPowerEllipse" )
2453 SectionPoint = ((CSectionPowerEllipse*)YarnSection)->GetPoint(t);
2454 else
2455 SectionPoint = ((CSectionHybrid*)YarnSection)->GetPoint(t);
2456 XYZ NewNode = WarpNode;
2457
2458 NewNode.y = NewNode.y + SectionPoint.x;
2459 NewNode.z = NewNode.z + SectionPoint.y + Offset;
2460 if ( bInsert )
2461 {
2462 m_Yarns[WeftYarnIndex].InsertNode( NewNode, CurrentNode);
2463 CurrentNode++;
2464 }
2465 else
2466 m_Yarns[WeftYarnIndex].ReplaceNode( CurrentNode, NewNode );
2467
2468
2469}
2470
2471bool CTextile3DWeave::AdjustPowerEllipseSectionWidth( double &HeightReduction, double &MaxWidth, double TargetArea, CSectionPowerEllipse* YarnSection ) const
2472{
2473 double StartHeight = YarnSection->GetHeight();
2474 double TargetHeight = StartHeight * HeightReduction;
2475 double NewWidth;
2476 if ( fabs( 1 - HeightReduction ) > TOL )
2477 NewWidth = YarnSection->GetWidth() * 1.1 / HeightReduction;
2478 else
2479 NewWidth = YarnSection->GetWidth() * 1.1;
2480
2481 if ( NewWidth > MaxWidth )
2482 NewWidth = MaxWidth;
2483
2484 double dWidth = NewWidth - YarnSection->GetWidth();
2485
2486 CSectionPowerEllipse NewSection( NewWidth, TargetHeight, YarnSection->GetPower() );
2487
2488 if ( fabs(dWidth) < TOL )
2489 {
2490 *YarnSection = NewSection;
2491 return false;
2492 }
2493
2494
2495
2496 double Area = NewSection.GetArea( NewSection.GetPoints(40));
2497 bool bFoundRange = false;
2498
2499 while( fabs( Area - TargetArea ) > TOL )
2500 {
2501 if ( Area > TargetArea )
2502 {
2503 dWidth /= 2.0;
2504 NewWidth -= dWidth;
2505 bFoundRange = true;
2506 }
2507 else if ( Area < TargetArea )
2508 {
2509 if ( NewWidth > MaxWidth )
2510 {
2511 CSectionPowerEllipse Section( MaxWidth, TargetHeight, YarnSection->GetPower() );
2512 *YarnSection = Section;
2513 /* if ( HeightReduction == 1.0 )
2514 StartHeight *= 1.5;
2515 FindPowerEllipseSectionHeight( StartHeight, TargetArea, YarnSection );*/
2516 return false;
2517 }
2518 if ( bFoundRange )
2519 dWidth /= 2;
2520 NewWidth += dWidth;
2521 }
2522
2523 CSectionPowerEllipse Section( NewWidth, TargetHeight, YarnSection->GetPower() );
2524 Area = Section.GetArea( Section.GetPoints(40));
2525 }
2526 if ( NewWidth > MaxWidth )
2527 {
2528 NewSection.SetWidth( MaxWidth );
2529 *YarnSection = NewSection;
2530 /*if ( HeightReduction == 1.0 )
2531 StartHeight *= 1.5;
2532 FindPowerEllipseSectionHeight( StartHeight, TargetArea, YarnSection );*/
2533 return false;
2534 }
2535 CSectionPowerEllipse Section( NewWidth, TargetHeight, YarnSection->GetPower() );
2536 *YarnSection = Section;
2537 return true;
2538}
2539
2540void CTextile3DWeave::FindPowerEllipseSectionHeight( double& MaxHeight, double& TargetArea, CSectionPowerEllipse* YarnSection ) const
2541{
2542 double NewHeight = MaxHeight;
2543 double StartHeight = NewHeight;
2544 double dHeight = StartHeight - YarnSection->GetHeight();
2545
2546 string Type = YarnSection->GetType();
2547
2548 CSectionPowerEllipse NewSection( YarnSection->GetWidth(), StartHeight, YarnSection->GetPower() );
2549 double Area = NewSection.GetArea( NewSection.GetPoints(40));
2550
2551 if ( Area < TargetArea ) // Max available area less than target area so return section with max height
2552 {
2553 *YarnSection = NewSection;
2554 return;
2555 }
2556
2557 while( fabs( Area - TargetArea ) > TOL )
2558 {
2559 if ( Area > TargetArea )
2560 {
2561 dHeight /= 2.0;
2562 NewHeight -= dHeight;
2563 }
2564 else if ( Area < TargetArea )
2565 {
2566 dHeight /= 2;
2567 NewHeight += dHeight;
2568 }
2569
2570 CSectionPowerEllipse Section( YarnSection->GetWidth(), NewHeight, YarnSection->GetPower() );
2571 Area = Section.GetArea( Section.GetPoints(40));
2572 }
2573
2574 CSectionPowerEllipse Section( YarnSection->GetWidth(), NewHeight, YarnSection->GetPower() );
2575 *YarnSection = Section;
2576}
2577
2578bool CTextile3DWeave::AdjustPowerEllipsePower( double &HeightReduction, double TargetArea, CSectionPowerEllipse* YarnSection, double MinPower ) const
2579{
2580 double MaxPower = YarnSection->GetPower();
2581 double TargetHeight = YarnSection->GetHeight() * HeightReduction;
2582 double dWidth = YarnSection->GetWidth();
2583
2584 CSectionPowerEllipse MinPowerSection( dWidth, TargetHeight, MinPower );
2585
2586 double Area = MinPowerSection.GetArea( MinPowerSection.GetPoints(40));
2587 if ( Area < TargetArea )
2588 return false; // Can't achieve target area by just increasing power
2589
2590 double MidPower = ( MaxPower + MinPower )/2.0;
2591 CSectionPowerEllipse MidSection( dWidth, TargetHeight, MidPower );
2592 double MidArea = MidSection.GetArea( MidSection.GetPoints(40));
2593
2594 while ( fabs( MidArea - TargetArea ) > TOL )
2595 {
2596 if ( MidArea > TargetArea )
2597 {
2598 MinPower = MidPower;
2599 }
2600 else
2601 {
2602 MaxPower = MidPower;
2603 }
2604 MidPower = ( MinPower + MaxPower ) / 2.0;
2605 CSectionPowerEllipse Section( dWidth, TargetHeight, MidPower ); // Need to create new section rather than just setting power as doesn't recalculate section points
2606 MidArea = Section.GetArea( Section.GetPoints(40));
2607 }
2608 CSectionPowerEllipse Section( dWidth, TargetHeight, MidPower );
2609 *YarnSection = Section;
2610 return true;
2611}
2612
2613void CTextile3DWeave::ReducePowerEllipseHeight( double& TargetArea, CSectionPowerEllipse* YarnSection ) const
2614{
2615 double Area = YarnSection->GetArea( YarnSection->GetPoints(40) );
2616 if ( Area <= TargetArea )
2617 return;
2618
2619 double MaxHeight = YarnSection->GetHeight();
2620 double MinHeight = YarnSection->GetHeight() / 2.0;
2621 double Width = YarnSection->GetWidth();
2622 double MidHeight = ( MaxHeight + MinHeight )/2.0;
2623 double Power = YarnSection->GetPower();
2624
2625 CSectionPowerEllipse MidSection( Width, MidHeight, Power );
2626 double MidArea = MidSection.GetArea( MidSection.GetPoints(40));
2627
2628 while ( fabs( MidArea - TargetArea ) > TOL )
2629 {
2630 if ( MidArea > TargetArea )
2631 {
2632 MaxHeight = MidHeight;
2633 }
2634 else
2635 {
2636 MinHeight = MidHeight;
2637 }
2638 MidHeight = ( MinHeight + MaxHeight ) / 2.0;
2639 CSectionPowerEllipse Section( Width, MidHeight, Power );
2640 MidArea = Section.GetArea( Section.GetPoints(40));
2641 }
2642 CSectionPowerEllipse Section( Width, MidHeight, Power );
2643 *YarnSection = Section;
2644}
2645
2646void CTextile3DWeave::SetYarnProperties( CYarn& Yarn, int iType ) const
2647{
2648 // Only want to set values if actually input otherwise sets Property m_bSet to true & returns zeros for area
2649 if ( m_Properties[iType].GetFibresPerYarn() )
2651 if ( m_Properties[iType].GetFibreDiameter() != 0.0 )
2653 if ( m_Properties[iType].GetYarnLinearDensity() != 0.0 )
2655 if ( m_Properties[iType].GetFibreDensity() != 0.0 )
2657 if ( m_Properties[iType].GetFibreArea() != 0.0 )
2658 Yarn.SetFibreArea( m_Properties[iType].GetFibreArea());
2659}
2660
2661void CTextile3DWeave::GetWarpYarnInfo( int& iNumBinderYarns, int& iNumWarpYarns, int& iBinderRatio, int& iWarpRatio, YARNDATA& AveWarp, YARNDATA& AveBinder ) const
2662{
2663 double WarpWidth = 0.0;
2664 double BinderWidth = 0.0;
2665 double WarpHeight = 0.0;
2666 double BinderHeight = 0.0;
2667 iNumWarpYarns = 0;
2668 iNumBinderYarns = 0;
2669 iBinderRatio = 0;
2670 iWarpRatio = 0;
2671 bool bRatioFound = false;
2672 for ( int i=0; i < m_iNumXYarns; ++i )
2673 {
2674 if ( !IsBinderYarn(i) )
2675 {
2676 iNumWarpYarns++;
2677 WarpWidth += m_XYarnData[i].dWidth;
2678 WarpHeight += m_XYarnData[i].dHeight;
2679 if ( iBinderRatio == 0 ) // First set of warps so count up ratio
2680 {
2681 iWarpRatio++;
2682 }
2683 else
2684 {
2685 bRatioFound = true;
2686 }
2687 }
2688 else
2689 {
2690 iNumBinderYarns++;
2691 BinderWidth += m_XYarnData[i].dWidth;
2692 BinderHeight += m_XYarnData[i].dHeight;
2693 if ( !bRatioFound ) // First set of binders so count up ratio
2694 {
2695 iBinderRatio++;
2696 }
2697 }
2698 }
2699
2700 if ( iNumWarpYarns )
2701 {
2702 AveWarp.dWidth = WarpWidth / iNumWarpYarns;
2703 AveWarp.dHeight = WarpHeight / iNumWarpYarns;
2704 }
2705 else // all binder yarns
2706 {
2707 AveWarp.dHeight = AveWarp.dWidth = 0.0;
2708 }
2709
2710 AveBinder.dWidth = BinderWidth / iNumBinderYarns;
2711 AveBinder.dHeight = BinderHeight / iNumBinderYarns;
2712
2713 double AveGap = ( GetHeight() - (WarpWidth+BinderWidth) ) / m_iNumXYarns;
2714 AveBinder.dSpacing = AveBinder.dWidth + AveGap;
2715 AveWarp.dSpacing = AveWarp.dWidth + AveGap;
2716
2717 iNumWarpYarns += iNumBinderYarns; // NumWarpYarns is total number of yarns in warp direction
2718}
2719
2720void CTextile3DWeave::SetupWeftRow( vector<int>& Layers, vector<int>& Warp, int NumWarps, int Weft )
2721{
2722 int NumLayers = *(max_element( Layers.begin(), Layers.end() )) + 1;
2723 m_iTotalXYarns = Layers.size();
2724 vector<int>::iterator itWarp;
2725 vector<int>::iterator itLayers;
2726
2727 if ( Layers.size() != Warp.size() )
2728 TGERROR("Can't add weft row, warp and layer sizes do not match");
2729
2730 itWarp = Warp.begin();
2731 int j = NumWarps-1;
2732 int PrevYCellIndex = -1;
2733 // Left hand side of weave pattern corresponds to maximum y value (or max j in cell array)
2734 for ( itLayers = Layers.begin(); itLayers != Layers.end(); )
2735 {
2736 vector<PATTERN3D> &Cell = GetCell(Weft, j);
2737 bool bFirst = true; // bFirst is true until the weft yarn has been set for the current cell
2738 int WarpIndex = -1;
2739 do
2740 {
2741 if ( *itWarp == 0 && bFirst ) // Warp yarn is down and weft not yet set
2742 {
2743 // Set the weft yarn (y yarn) at the cell index above the current layer
2744 if ( PrevYCellIndex != -1 && WarpIndex != -1 && PrevYCellIndex >= WarpIndex-1 )
2745 {
2746 Cell[WarpIndex-1] = PATTERN3D_YYARN;
2747 PrevYCellIndex = WarpIndex-1;
2748 }
2749 else
2750 {
2751 Cell[NumLayers - (*itLayers)] = PATTERN3D_YYARN;
2752 PrevYCellIndex = NumLayers - (*itLayers);
2753 }
2754 // Set the cell for the warp yarn
2755 Cell[NumLayers - (*itLayers)-1] = PATTERN3D_XYARN;
2756 bFirst = false;
2757 }
2758 else if ( *itWarp != PATTERN3D_NOYARN )
2759 {
2760 if ( !bFirst ) // Warp is up so set the x yarn cell allowing for one cell having been taken by weft yarn
2761 Cell[NumLayers - (*itLayers)-1] = PATTERN3D_XYARN;
2762 else
2763 { // Warp is up and no weft yarn yet. Set x yarn cell without space allowed for weft yarn
2764 WarpIndex = NumLayers - (*itLayers);
2765 Cell[WarpIndex] = PATTERN3D_XYARN;
2766 }
2767 }
2768
2769 ++itLayers;
2770 ++itWarp;
2771 } while ( itLayers != Layers.end() && *itLayers != 1 ); // Contunue until reach end of current stack of layers
2772 if ( bFirst && *(itWarp-1) != PATTERN3D_NOYARN ) // If reached end of stack without setting weft yarn need to set it at bottom of cell entries
2773 {
2774 Cell[NumLayers - *(itLayers-1)-1] = PATTERN3D_YYARN;
2775 PrevYCellIndex = NumLayers - *(itLayers-1)-1;
2776 }
2777 --j; // Move to next cell
2778
2779 }
2780 m_bNeedsBuilding = true;
2781}
2782
2784{
2786 for ( int i = m_iNumYYarns-1; i >=0; --i )
2787 {
2788 string Row;
2789 for ( int j = m_iNumXYarns-1; j >= 0 ; --j ) // Row of cells in y direction correspond to one row of weave pattern. lhs of weave pattern at max j
2790 {
2791 vector<PATTERN3D> &Cell = GetCell(i, j);
2792 if ( NoYarnCell( Cell ) )
2793 continue;
2794 bool bWeftSet = false;
2795 for ( int k = Cell.size()-1; k > 0; --k ) // Top of cell at lhs of weave pattern
2796 {
2797 if ( !( k == 1 && Cell[0] == PATTERN3D_NOYARN) )
2798 {
2799 switch (Cell[k])
2800 {
2801 case PATTERN3D_XYARN:
2802 if ( !bWeftSet )
2803 Row.push_back('1');
2804 else
2805 Row.push_back('0'); // Assumes only one weft. Anything after the weft must be a warp down
2806 break;
2807 case PATTERN3D_YYARN:
2808 Row.push_back('0');
2809 bWeftSet = true;
2810 break;
2811 case PATTERN3D_NOYARN:
2812 //Row.push_back('2');
2813 break;
2814 }
2815 }
2816 }
2817 }
2818 if ( (int)Row.size() < m_iTotalXYarns )
2819 {
2820 for ( int i = (int)Row.size()+1; i <= m_iTotalXYarns; ++i )
2821 {
2822 Row.push_back('2');
2823 }
2824 }
2825 m_PatternDraft.AddRow( Row );
2826 }
2827}
2828
2829bool CTextile3DWeave::NoYarnCell( vector<PATTERN3D> &Cell )
2830{
2831 for ( int i = 0; i < Cell.size(); ++i )
2832 {
2833 if ( Cell[i] != PATTERN3D_NOYARN )
2834 return false;
2835 }
2836 return true;
2837}
2838
2840{
2841 vector<int> LayerInfo;
2842 double dReedWidth = 0; // Calculate total width based on spacings. At later date could use individual spacings to get distribution of ends in dents
2843 double dMaxWarpWidth = 0.0;
2844 for ( int j = m_iNumXYarns-1; j >= 0 ; --j )
2845 {
2846 int Layers = 0;
2847 vector<PATTERN3D> &Cell = GetCell(0, j);
2848 for ( int k = Cell.size()-1; k >= 0; --k )
2849 {
2850 if ( Cell[k] == PATTERN3D_XYARN )
2851 ++Layers;
2852 }
2853 LayerInfo.push_back( Layers );
2854 dReedWidth += m_XYarnData[j].dSpacing;
2855 if ( m_XYarnData[j].dWidth > dMaxWarpWidth )
2856 dMaxWarpWidth = m_XYarnData[j].dWidth;
2857 }
2858 double dReedDensity = (m_iNumXYarns / dReedWidth); // Reed density in ends/mm
2859 double dDentWidth = 1.0/dReedDensity;
2860 double dToothSize = 0.2 * dDentWidth;
2861
2862 CReedData ReedData;
2863 dToothSize = ReedData.GetClosestReedThickness( dToothSize );
2864 // Need to add check that gap left (dent width - tooth thickness) is ok for yarn width
2865 double dDentGap = dDentWidth - dToothSize;
2866 if ( dMaxWarpWidth/3.0 > dDentGap )
2867 {
2868 TGERROR( "Yarn width greater than dent gap. Compressed yarn width = " << dMaxWarpWidth << ", Dent gap = " << dDentGap );
2869 }
2870
2871 double dWeftWidth = 0;
2872 for ( int i = 0; i < m_iNumYYarns; ++i )
2873 {
2874 dWeftWidth += m_YYarnData[i].dSpacing;
2875 }
2876 double dWeftDensity = (m_iNumYYarns / dWeftWidth) * 10.0; // Wefts/cm
2877
2878 AddExtensionIfMissing(Filename, ".txt");
2879 ofstream Output(Filename.c_str());
2880
2881 Output << "Reed width: " << dReedWidth << "mm" << endl;
2882 Output << "Reed density: " << dReedDensity * 10.0 << " dents/cm" << endl;
2883 Output << "Tooth thickness: " << dToothSize << "mm" << endl;
2884 Output << "Weft density: " << dWeftDensity << " wefts/cm" << endl;
2885 Output << "Number of used dents: " << m_iNumXYarns << endl;
2886 Output << endl;
2887 Output << "Dent Number of ends" << endl;
2888
2889 for ( int i = 0; i < LayerInfo.size(); ++i )
2890 {
2891 Output.width(10);
2892 Output << std::left << i+1;
2893 Output.width(10);
2894 Output << std::left << LayerInfo[i] << endl;
2895 }
2896}
2897
2899{
2900 for (int i=0; i<m_iNumXYarns; ++i)
2901 {
2902 for (int j=0; j<m_iNumYYarns; ++j)
2903 {
2904 const vector<PATTERN3D> &Cell = GetCell(j, i);
2905 if ( Cell.size() == 0 )
2906 return false;
2907 }
2908 }
2909 return true;
2910}
#define TGLOGINDENT(MESSAGE)
Combines the TGLOG macro and TGLOGAUTOINDENT macro in one.
Definition: Logger.h:68
#define TGERROR(MESSAGE)
Macros used to report the file name and line number to the TexGenError and TexGenLog functions.
Definition: Logger.h:29
#define FOR_EACH_TIXMLELEMENT(CHILDELEMENT, PARENTELEMENT, ELEMENTNAME)
Macro to enable looping over tinyxml easier.
Definition: Misc.h:45
#define NULL
Definition: ShinyConfig.h:50
#define TOL
Abstract base class representing the domain in which a textile cell may lie.
Definition: Domain.h:34
virtual string GetType() const =0
Derived class should return the class name.
Domain implementation described using planes, the simplest of which would be a box.
Definition: DomainPlanes.h:37
Bezier interpolation for yarn paths.
Represents a point on the centreline of a yarn.
Definition: Node.h:28
void AddRow(string Row)
Add a row representing one weft insertion '1' indicates warp up, '0' warp down and '2' no yarn.
int GetFibresPerYarn() const
Definition: Properties.cpp:284
double GetYarnLinearDensity(string Units="kg/m") const
Definition: Properties.cpp:241
void SetFibreArea(double dValue, string Units="m^2")
Set the area occupied by fibres in a yarn cross-section.
Definition: Properties.cpp:140
double GetFibreDiameter(string Units="m") const
Definition: Properties.cpp:279
void SetFibresPerYarn(int iValue)
Set the number of fibres in a yarn.
Definition: Properties.cpp:156
void SetYarnLinearDensity(double dValue, string Units="kg/m")
Set the fibre linear density, i.e. the mass per unit length of fibre.
Definition: Properties.cpp:120
void SetFibreDiameter(double dValue, string Units="m")
Set the fibre diameter.
Definition: Properties.cpp:145
void SetFibreDensity(double dValue, string Units="kg/m^3")
Set the fibre density, i.e. the mass per unit volume of fibre.
Definition: Properties.cpp:130
double GetFibreArea(string Units="m^2") const
Get the area occupied by fibres given fibre diameter and number of fibres.
Definition: Properties.cpp:251
double GetFibreDensity(string Units="kg/m^3") const
Definition: Properties.cpp:246
double GetClosestReedThickness(double dThickness)
Definition: ReedData.cpp:33
Abstract base class respresenting a yarn cross-section.
Definition: Section.h:31
virtual CSection * Copy() const =0
Create a copy of the derived section and return a pointer to the newly created instance.
void AssignSectionMesh(const CSectionMesh &SectionMesh)
Assign a mesh to the section.
Definition: Section.cpp:227
virtual string GetType() const =0
Derived class should return the class name.
static double GetArea(const vector< XY > &Section)
Get the area of a section.
Definition: Section.cpp:261
virtual const vector< XY > & GetPoints(int iNumPoints, bool bEquiSpaced=false) const
Get a section with given number of points on the perimeter.
Definition: Section.cpp:119
virtual XY GetPoint(double t) const =0
Get a point lying on the perimeter correspending to parametric value t.
Hybrid of any number of other sections.
Definition: SectionHybrid.h:29
Abstract base class to create a 2D mesh of a section.
Definition: SectionMesh.h:33
static CObjectContainer< CSectionMesh > CreateSectionMesh(TiXmlElement &Element)
Create a section from TiXmlElement.
Definition: SectionMesh.cpp:52
string GetType() const
Derived class should return the class name.
XY GetPoint(double t) const
Get a point lying on the perimeter correspending to parametric value t.
void AddNoYarnLayer()
Add empty layer.
void SetYarnSpacings(double dSpacing)
Set the spacing of all the yarns in the textile.
void SetWarpYarnWidths(double dWidth)
Set the width of yarns parallel to the X axis in warp yarn positions.
void ReplaceLastNode(int BinderYarnIndex, XYZ &NewNode, XYZ &BinderNode) const
Replace last node with node offset to match node 0.
double GetYYarnGapSize(int iIndex) const
Get the gap size between two yarns parallel to the Y axis, with given index.
void AddXYarn(int y, PATTERN3D Pattern)
Add yarn of type XYARN or NOYARN parallel to the X axis.
vector< YARNDATA > m_XYarnData
vector< vector< int > > m_XYarns
virtual int GetNumBinderLayers() const
Retrieve the number of binder layers.
void AssignSectionMesh(const CSectionMesh &SectionMesh)
Assign a section mesh to the weave.
int FindWarpBelowIndex(const vector< PATTERN3D > &Cell, int iIndex) const
int GetMaxNumLayers() const
Retreive the maximum number of layers at any crossover.
double GetYYarnSpacings(int iIndex) const
Get the spacing of the yarn parallel to the Y axis, with given index.
int GetYarnIndex(int x, int y, int z) const
void FindPowerEllipseSectionHeight(double &MaxHeight, double &TargetArea, CSectionPowerEllipse *YarnSection) const
void SetYarnProperties(CYarn &Yarn, int iType) const
CDomainPlanes GetDefaultDomain(bool bAddedDomainHeight=true)
Get a domain which describes 6 planes triming the textile to a unit cell.
void SetFibreDiameter(int iYarnType, double dValue, string Units="m")
void CheckUpVectors(int WarpIndex, bool Yarn=PATTERN3D_XYARN, bool bYarnsIndex=false) const
void AddYYarn(int x, PATTERN3D Pattern)
Add yarn of type XYARN or NOTYARN parallel to the Y axis.
void AssignDefaultDomain(bool bAddedDomainHeight=true)
Get the default domain and assign it as the domain.
void CalculateReedDesign(string Filename)
XYZ GetUpVector(XYZ CheckNodes[], bool bYarn) const
Gets an up vector for a pair of nodes.
int FindWarpAboveIndex(const vector< PATTERN3D > &Cell, int iIndex) const
virtual void SetupLayers(int iNumWarpLayers, int iNumWeftLayers, int iNumBinderLayers=1)
Setup the layers given a specified number of layers.
double GetYYarnHeights(int iIndex) const
Get the height of the yarn parallel to the Y axis, with given index.
void SetFibreDensity(int iYarnType, double dValue, string Units="kg/m^3")
Set the fibre density, i.e. the mass per unit volume of fibre.
void DeleteXLayers(int y, int iNumberLayers)
Delete given number of yarns parallel to the X axis, with given index y.
bool AdjustPowerEllipseSectionWidth(double &HeightReduction, double &MaxWidth, double TargetArea, CSectionPowerEllipse *YarnSection) const
Adjust section to target height whilst maintaining cross-sectional area.
bool CheckCells() const
Check that all cells are populated.
double GetAverageWeftYarnHeight() const
virtual ~CTextile3DWeave(void)
bool Valid() const
Check that the weave pattern contained in m_Pattern is valid.
void SetXYarnHeights(int iIndex, double dHeight)
Set the height of the yarn parallel to the X axis, with given index.
double GetHeight() const
Get the height of the unit cell.
void SetBinderYarnHeights(double dHeight)
Set the height of yarns parallel to the X axis in binder yarn positions.
void SwapPosition(int x, int y, int iLevel1, int iLevel2)
Swap the positions of two yarns in the patter with given index x, y and level iLevel1,...
virtual void ConvertToPatternDraft(int iWeftOrder=BOTTOM_TO_TOP)
void SetBinderYarnSpacings(double dWidth)
Set the spacing of yarns parallel to the X axis in binder yarn positions.
pair< int, int > GetCellCoordinates(int iIndex) const
virtual void FindMinMaxZ(double &dMinZ, double &dMaxZ)
Find max and min Z values for textile.
virtual string GetType() const
Derived class should return the class name.
double GetAverageYarnWidth() const
void SetYarnLinearDensity(int iYarnType, double dValue, string Units="kg/m")
Set the fibre linear density, i.e. the mass per unit length of fibre.
int GetNumYLayers(int x) const
Retreive the number of yarns parallel to the Y axis, with given index x.
double GetXYarnSpacings(int iIndex) const
Get the spacing of the yarn parallel to the X axis, with given index.
vector< CYarn * > GetYYarns(int iIndex)
int FindPrevYCellIndex(int Starti, int j, int k) const
Find next cell in x direction which isn't a noyarn, searching backwards.
CProperties m_Properties[3]
int FindWeftHeight(const vector< PATTERN3D > &Cell) const
CSectionPowerEllipse * GetWeftCrossSection(int WeftYarnIndex) const
Adjust cross section shapes to correct interference.
double GetYYarnWidths(int iIndex) const
Get the width of the yarn parallel to the Y axis, with given index.
vector< bool > m_BinderPattern
virtual string GetDefaultName() const
Get the default name to assign to a textile.
void SetMaxVolFraction(double dVolFraction)
Set the maximum yarn volume fraction for use in refinement.
void SetBinderYarnWidths(double dWidth)
Set the width of yarns parallel to the X axis in binder yarn positions.
bool BinderYarns() const
Check if any binder yarns in weave.
double GetXYarnHeights(int iIndex) const
Get the height of the yarn parallel to the X axis, with given index.
void SetBinderRatio(int iBinderRatio)
Set the number of binder yarns grouped together.
void SetFibresPerYarn(int iYarnType, int iNumFibres)
Set the number of fibres per yarn.
int FindNextCellIndex(int index) const
Find next cell in y direction which isn't a binder yarn.
int GetNumXLayers(int y) const
Retreive the number of yarns parallel to the X axis, with given index y.
void SetWarpRatio(int iWarpRatio)
Set the number of warp yarns grouped together.
int FindNextYCellIndex(int Starti, int j, int k) const
Find next cell in x direction which isn't a noyarn.
void SetYYarnWidths(int iIndex, double dWidth)
Set the width of the yarn parallel to the Y axis, with given index.
double GetAverageWeftYarnWidth() const
virtual void SetupWeftRow(vector< int > &Layers, vector< int > &Row, int NumWarps, int Weft)
Set up row of pattern cells for one weft pattern using one row of weave pattern data and the layers p...
bool NoYarnCell(vector< PATTERN3D > &Cell)
vector< CYarn * > GetXYarns(int iIndex)
void SetXYarnWidths(int iIndex, double dWidth)
Set the width of the yarn parallel to the X axis, with given index.
void SetXYarnSpacings(int iIndex, double dSpacing)
Set the spacing of the yarn parallel to the X axis, with given index.
void SetThickness(double dThickness)
Set the thickness of the fabric.
bool IsBinderYarn(int index) const
Check if X yarn is binder or warp. Returns true if binder.
void SetWarpYarnHeights(double dHeight)
Set the height of yarns parallel to the X axis in warp yarn positions.
vector< YARNDATA > m_YYarnData
void AddBinderLayer()
Add yarns parallel to the X axis in binder yarn positions, no yarns in warp positions.
vector< vector< PATTERN3D > > m_Pattern
void SetYYarnHeights(int iIndex, double dHeight)
Set the height of the yarn parallel to the Y axis, with given index.
void SetWarpYarnSpacings(double dWidth)
Set the spacing of yarns parallel to the X axis in warp yarn positions.
CSection * GetCrossSection(int YarnIndex, int Node=-1) const
Gets the cross-section of a yarn, either constant or interp node, power elliptical sections.
void AddWarpLayer()
Add yarns parallel to the X axis in warp yarn positions, no yarns in binder positions.
void InsertWeftNode(CSection *YarnSection, double t, XYZ &WarpNode, int &CurrentNode, int WeftYarnIndex, double Offset, bool bInsert=true) const
void SetBinderPattern()
Setup the binder pattern from the warp and binder ratios.
CTextile3DWeave(int iNumXYarns, int iNumYYarns, double dXSpacing, double dYSpacing, double dXHeight, double dYHeight, bool bRefine=false)
Build a weave unit cell of given width, height, yarn spacing and fabric thickness.
void AddXLayers(int y, int iNumberLayers)
Add given number of yarns parallel to the X axis, with given index y.
void ReducePowerEllipseHeight(double &TargetArea, CSectionPowerEllipse *YarnSection) const
double GetXYarnGapSize(int iIndex) const
Get the gap size between two yarns parallel to the X axis, with given index.
void GetWarpYarnInfo(int &iNumBinderYarns, int &iNumWarpYarns, int &iBinderRatio, int &iWarpRatio, YARNDATA &AveWarp, YARNDATA &AveBinder) const
Retrieve number of warp and binder yarns and ratios.
void RemoveCell(int x, int y)
void SetFibreArea(int iYarnType, double dValue, string Units="m^2")
Set the area occupied by fibres in a yarn cross-section.
int GetXYarnIndex(int YarnInd)
Get the XYarn index (ie the y position) of a yarn given the yarn index.
void SetYarnHeights(double dHeight)
Set the height of all the yarns in the textile.
bool AdjustPowerEllipsePower(double &HeightReduction, double TargetArea, CSectionPowerEllipse *YarnSection, double MinPower) const
double GetXYarnWidths(int iIndex) const
Get the width of the yarn parallel to the X axis, with given index.
vector< vector< int > > m_YYarns
virtual double GetWidth() const
Get the width of the unit cell.
void AddYLayers(int x, int iNumberLayers)
Add given number of yarns parallel to the Y axis, with given index x.
void InsertBinderNode(CSectionPowerEllipse *YarnSection, double t, XYZ &WeftNode, int &CurrentNode, int BinderYarnIndex, double Offset, bool bInsert=true) const
Calculates a point at given point on power ellipse cross section and inserts into binder yarn.
virtual void PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType)
Used for saving data to XML.
virtual bool BuildTextile() const
Build the textile.
void DeleteYLayers(int x, int iNumberLayers)
Delete given number of yarns parallel to the Y axis, with given index x.
CPatternDraft m_PatternDraft
Class for generating pattern draft from weave pattern.
int AddWeftNodes(int CurrentNode, int XNode, int i, int j) const
const vector< PATTERN3D > & GetCell(int x, int y) const
void SetYarnWidths(double dWidth)
Set the width of all the yarns in the textile.
void SetResolution(int iResolution)
Set the resolution of the yarns.
CObjectContainer< CSectionMesh > m_pSectionMesh
double GetFibreArea(int iYarnType, string Units)
Get the area occupied by fibres given fibre diameter and number of fibres.
void SetGapSize(double dGapSize)
Set the size of the gap to leave between yarns when correcting interference.
void SetYYarnSpacings(int iIndex, double dSpacing)
Set the spacing of the yarn parallel to the Y axis, with given index.
Represents a textile cell containing yarns.
Definition: Textile.h:39
void RemoveDomain()
Remove the domain.
Definition: Textile.cpp:729
const CDomain * GetDomain() const
Definition: Textile.h:287
bool BuildTextileIfNeeded() const
Build the textile only if needed.
Definition: Textile.cpp:710
vector< CYarn > m_Yarns
Vector of yarns contained within this cell.
Definition: Textile.h:323
void AssignDomain(const CDomain &Domain)
Assign a domain to the textile, will be used by default to trim the domain.
Definition: Textile.cpp:724
string GetName() const
Get the name associated with this textile.
Definition: Textile.cpp:355
virtual void PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType)
Used for saving data to XML.
Definition: Textile.cpp:87
int AddYarn(const CYarn &Yarn)
Add a Yarn to the textile.
Definition: Textile.cpp:122
bool m_bNeedsBuilding
Variable which keeps track of wether the textile needs building or not.
Definition: Textile.h:330
Represents a yarn consisting of master nodes, section and interpolation function.
Definition: Yarn.h:49
Creates a section which is constant all along the yarn.
vector< XY > GetSection(const YARN_POSITION_INFORMATION PositionInfo, int iNumPoints, bool bEquiSpaced=false) const
This function must be implemented by derived classes.
Creates a section which is linearly interpolated between sections defined at the nodes.
const CSection & GetNodeSection(int iIndex) const
Namespace containing a series of customised math operations not found in the standard c++ library.
OUTPUT_TYPE
Definition: Misc.h:105
@ OUTPUT_STANDARD
Definition: Misc.h:107
@ OUTPUT_FULL
Definition: Misc.h:108
int PATTERN3D
double Max(XYZ &Vector)
Get maximum element of vector and return it.
Definition: mymath.h:642
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
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
@ PATTERN3D_NOYARN
@ PATTERN3D_XYARN
@ PATTERN3D_YYARN
void AddExtensionIfMissing(std::string &Filename, std::string Extension)
Adds an extension to the filename if it is missing otherwise do nothing (e.g. picture -> picture....
Definition: Misc.cpp:116
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
Data structure to keep track of yarn parameters.