TexGen
TextileWeave.cpp
Go to the documentation of this file.
1/*=============================================================================
2TexGen: Geometric textile modeller.
3Copyright (C) 2006 Martin Sherburn
4
5This program is free software; you can redistribute it and/or
6modify it under the terms of the GNU General Public License
7as published by the Free Software Foundation; either version 2
8of the License, or (at your option) any later version.
9
10This program is distributed in the hope that it will be useful,
11but WITHOUT ANY WARRANTY; without even the implied warranty of
12MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13GNU General Public License for more details.
14
15You should have received a copy of the GNU General Public License
16along with this program; if not, write to the Free Software
17Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18=============================================================================*/
19
20#include "PrecompiledHeaders.h"
21#include "TextileWeave.h"
22#include "SectionEllipse.h"
23#include "SectionPolygon.h"
24
25using namespace TexGen;
26
27CTextileWeave::CTextileWeave(int iNumYYarns, int iNumXYarns, double dSpacing, double dThickness)
28: m_iNumXYarns(iNumXYarns)
29, m_iNumYYarns(iNumYYarns)
30, m_dGapSize(0)
31, m_dFabricThickness(dThickness)
32, m_iResolution(40)
33{
34 m_Pattern.resize(iNumXYarns*iNumYYarns);
35 YARNDATA YarnData;
36 YarnData.dSpacing = dSpacing;
37 YarnData.dWidth = YarnData.dSpacing;
38 YarnData.dHeight = m_dFabricThickness/2;
39 m_XYarnData.resize(iNumXYarns, YarnData);
40 m_YYarnData.resize(iNumYYarns, YarnData);
41}
42
44{
45}
46
47CTextileWeave::CTextileWeave(TiXmlElement &Element)
48: CTextile(Element)
49{
50 Element.Attribute("NumXYarns", &m_iNumXYarns);
51 Element.Attribute("NumYYarns", &m_iNumYYarns);
52 Element.Attribute("GapSize", &m_dGapSize);
53 Element.Attribute("FabricThickness", &m_dFabricThickness);
54 Element.Attribute("Resolution", &m_iResolution);
55 TiXmlElement *pSectionMesh = Element.FirstChildElement("SectionMesh");
56 if (pSectionMesh)
57 {
59 }
60 FOR_EACH_TIXMLELEMENT(pPatternCell, Element, "PatternCell")
61 {
62 vector<PATTERN2D> Cell;
63 FOR_EACH_TIXMLELEMENT(pCell, *pPatternCell, "PatternElement")
64 {
65 Cell.push_back(valueify<bool>(pCell->Attribute("value")));
66 }
67 m_Pattern.push_back(Cell);
68 }
69 YARNDATA YarnData;
70 FOR_EACH_TIXMLELEMENT(pYarnData, Element, "XYarnData")
71 {
72 pYarnData->Attribute("Width", &YarnData.dWidth);
73 pYarnData->Attribute("Height", &YarnData.dHeight);
74 pYarnData->Attribute("Spacing", &YarnData.dSpacing);
75 m_XYarnData.push_back(YarnData);
76 }
77 FOR_EACH_TIXMLELEMENT(pYarnData, Element, "YYarnData")
78 {
79 pYarnData->Attribute("Width", &YarnData.dWidth);
80 pYarnData->Attribute("Height", &YarnData.dHeight);
81 pYarnData->Attribute("Spacing", &YarnData.dSpacing);
82 m_YYarnData.push_back(YarnData);
83 }
84 FOR_EACH_TIXMLELEMENT(pYarns, Element, "XYarns")
85 {
86 vector<int> Indices;
87 FOR_EACH_TIXMLELEMENT(pYarn, *pYarns, "XYarn")
88 {
89 Indices.push_back(valueify<int>(pYarn->Attribute("yarnindex")));
90 }
91 m_XYarns.push_back(Indices);
92 }
93 FOR_EACH_TIXMLELEMENT(pYarns, Element, "YYarns")
94 {
95 vector<int> Indices;
96 FOR_EACH_TIXMLELEMENT(pYarn, *pYarns, "YYarn")
97 {
98 Indices.push_back(valueify<int>(pYarn->Attribute("yarnindex")));
99 }
100 m_YYarns.push_back(Indices);
101 }
102}
103
104void CTextileWeave::PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType)
105{
106 CTextile::PopulateTiXmlElement(Element, OutputType);
107
108 Element.SetAttribute("NumXYarns", m_iNumXYarns);
109 Element.SetAttribute("NumYYarns", m_iNumYYarns);
110 Element.SetAttribute("GapSize", stringify(m_dGapSize));
111 Element.SetAttribute("FabricThickness", stringify(m_dFabricThickness));
112 Element.SetAttribute("Resolution", m_iResolution);
113 if (m_pSectionMesh)
114 {
115 TiXmlElement SectionMesh("SectionMesh");
116 m_pSectionMesh->PopulateTiXmlElement(SectionMesh, OutputType);
117 Element.InsertEndChild(SectionMesh);
118 }
119 int i, j;
120 for (i=0; i<(int)m_Pattern.size(); ++i)
121 {
122 TiXmlElement PatternCell("PatternCell");
123 pair<int, int> Coords = GetCellCoordinates(i);
124 PatternCell.SetAttribute("x", Coords.first);
125 PatternCell.SetAttribute("y", Coords.second);
126// PatternCell.SetAttribute("index", i);
127 for (j=0; j<(int)m_Pattern[i].size(); ++j)
128 {
129 TiXmlElement PatternElement("PatternElement");
130// PatternElement.SetAttribute("index", j);
131 PatternElement.SetAttribute("value", stringify(m_Pattern[i][j]));
132 PatternCell.InsertEndChild(PatternElement);
133 }
134 Element.InsertEndChild(PatternCell);
135 }
136 for (i=0; i<(int)m_XYarnData.size(); ++i)
137 {
138 TiXmlElement XYarnData("XYarnData");
139 XYarnData.SetAttribute("index", i);
140 XYarnData.SetAttribute("Width", stringify(m_XYarnData[i].dWidth));
141 XYarnData.SetAttribute("Height", stringify(m_XYarnData[i].dHeight));
142 XYarnData.SetAttribute("Spacing", stringify(m_XYarnData[i].dSpacing));
143 Element.InsertEndChild(XYarnData);
144 }
145 for (i=0; i<(int)m_YYarnData.size(); ++i)
146 {
147 TiXmlElement YYarnData("YYarnData");
148 YYarnData.SetAttribute("index", i);
149 YYarnData.SetAttribute("Width", stringify(m_YYarnData[i].dWidth));
150 YYarnData.SetAttribute("Height", stringify(m_YYarnData[i].dHeight));
151 YYarnData.SetAttribute("Spacing", stringify(m_YYarnData[i].dSpacing));
152 Element.InsertEndChild(YYarnData);
153 }
154 if (OutputType == OUTPUT_STANDARD ||
155 OutputType == OUTPUT_FULL)
156 {
157 for (i=0; i<(int)m_XYarns.size(); ++i)
158 {
159 TiXmlElement XYarns("XYarns");
160 XYarns.SetAttribute("index", i);
161 for (j=0; j<(int)m_XYarns[i].size(); ++j)
162 {
163 TiXmlElement XYarn("XYarn");
164 // XYarn.SetAttribute("index", j);
165 XYarn.SetAttribute("yarnindex", m_XYarns[i][j]);
166 XYarns.InsertEndChild(XYarn);
167 }
168 Element.InsertEndChild(XYarns);
169 }
170 for (i=0; i<(int)m_YYarns.size(); ++i)
171 {
172 TiXmlElement YYarns("YYarns");
173 YYarns.SetAttribute("index", i);
174 for (j=0; j<(int)m_YYarns[i].size(); ++j)
175 {
176 TiXmlElement YYarn("YYarn");
177 // YYarn.SetAttribute("index", j);
178 YYarn.SetAttribute("yarnindex", m_YYarns[i][j]);
179 YYarns.InsertEndChild(YYarn);
180 }
181 Element.InsertEndChild(YYarns);
182 }
183 }
184}
185
186pair<int, int> CTextileWeave::GetCellCoordinates(int iIndex) const
187{
188 return make_pair(iIndex % m_iNumYYarns, iIndex / m_iNumYYarns);
189}
190
191const vector<PATTERN2D> &CTextileWeave::GetCell(int x, int y) const
192{
193 return m_Pattern[x + m_iNumYYarns*y];
194}
195
196vector<PATTERN2D> &CTextileWeave::GetCell(int x, int y)
197{
198 return m_Pattern[x + m_iNumYYarns*y];
199}
200
202{
203 // Check number of yarns is the same in the x direction
204 int i, j, k, iNumYarns, iFirstNumYarns;
205 for (i=0; i<m_iNumXYarns; ++i)
206 {
207 for (j=0; j<m_iNumYYarns; ++j)
208 {
209 const vector<PATTERN2D> &Cell = GetCell(j, i);
210 iNumYarns = 0;
211 for (k=0; k<(int)Cell.size(); ++k)
212 {
213 if (Cell[k] == PATTERN_XYARN)
214 ++iNumYarns;
215 }
216 if (j==0)
217 {
218 iFirstNumYarns = iNumYarns;
219 }
220 else
221 {
222 if (iFirstNumYarns != iNumYarns)
223 return false;
224 }
225 }
226 }
227 // Check number of yarns is the same in the y direction
228 for (j=0; j<m_iNumYYarns; ++j)
229 {
230 for (i=0; i<m_iNumXYarns; ++i)
231 {
232 const vector<PATTERN2D> &Cell = GetCell(j, i);
233 iNumYarns = 0;
234 for (k=0; k<(int)Cell.size(); ++k)
235 {
236 if (Cell[k] == PATTERN_YYARN)
237 ++iNumYarns;
238 }
239 if (i==0)
240 {
241 iFirstNumYarns = iNumYarns;
242 }
243 else
244 {
245 if (iFirstNumYarns != iNumYarns)
246 return false;
247 }
248 }
249 }
250 return true;
251}
252
254{
255 m_Yarns.clear();
256 m_YYarns.clear();
257 m_XYarns.clear();
258
259 m_YYarns.resize(m_iNumYYarns);
260 m_XYarns.resize(m_iNumXYarns);
261
262 if (!Valid())
263 return false;
264
265 TGLOGINDENT("Building textile weave \"" << GetName() << "\"");
266
267 vector<int> Yarns;
268
269 double x, y, z;
270
271 // Add x yarns (yarns parallel to the x axis)
272 int i, j, k, iYarn;
273 y = 0;
274 for (i=0; i<m_iNumXYarns; ++i)
275 {
276 x = 0;
277 Yarns.clear();
278 for (j=0; j<=m_iNumYYarns; ++j)
279 {
280 const vector<PATTERN2D> &Cell = GetCell(j%m_iNumYYarns, i);
281 if (j==0)
282 {
283 for (k=0; k<(int)Cell.size(); ++k)
284 {
285 if (Cell[k] == PATTERN_XYARN)
286 {
287 Yarns.push_back(AddYarn(CYarn()));
288 }
289 }
290 }
291 m_XYarns[i] = Yarns;
292 iYarn = 0;
293 z = m_dFabricThickness/(2*Cell.size());
294 for (k=0; k<(int)Cell.size(); ++k)
295 {
296 if (Cell[k] == PATTERN_XYARN)
297 {
298 m_Yarns[Yarns[iYarn]].AddNode(CNode(XYZ(x, y, z), XYZ(1, 0, 0)));
299 ++iYarn;
300 }
301 z += m_dFabricThickness/Cell.size();
302 }
303 if (j<m_iNumYYarns)
304 x += m_YYarnData[j].dSpacing;
305 }
306 y += m_XYarnData[i].dSpacing;
307 }
308
309 // Add y yarns (yarns parallel to the y axis)
310 x = 0;
311 for (j=0; j<m_iNumYYarns; ++j)
312 {
313 y = 0;
314 Yarns.clear();
315 for (i=0; i<=m_iNumXYarns; ++i)
316 {
317 const vector<PATTERN2D> &Cell = GetCell(j, i%m_iNumXYarns);
318 if (i==0)
319 {
320 for (k=0; k<(int)Cell.size(); ++k)
321 {
322 if (Cell[k] == PATTERN_YYARN)
323 {
324 Yarns.push_back(AddYarn(CYarn()));
325 }
326 }
327 }
328 m_YYarns[j] = Yarns;
329 iYarn = 0;
330 z = m_dFabricThickness/(2*Cell.size());
331 for (k=0; k<(int)Cell.size(); ++k)
332 {
333 if (Cell[k] == PATTERN_YYARN)
334 {
335 m_Yarns[Yarns[iYarn]].AddNode(CNode(XYZ(x, y, z), XYZ(0, 1, 0)));
336 ++iYarn;
337 }
338 z += m_dFabricThickness/Cell.size();
339 }
340 if (i<m_iNumXYarns)
341 y += m_XYarnData[i].dSpacing;
342 }
343 x += m_YYarnData[j].dSpacing;
344 }
345
346
347 // Assign sections to the yarns
348 vector<int>::iterator itpYarn;
349 double dWidth, dHeight;
350 for (i=0; i<m_iNumXYarns; ++i)
351 {
352 dWidth = m_XYarnData[i].dWidth;
353 dHeight = m_XYarnData[i].dHeight;
354 CSectionEllipse Section(dWidth, dHeight);
355 if (m_pSectionMesh)
357 for (itpYarn = m_XYarns[i].begin(); itpYarn != m_XYarns[i].end(); ++itpYarn)
358 {
359 m_Yarns[*itpYarn].AssignSection(CYarnSectionConstant(Section));
360 }
361 }
362 for (i=0; i<m_iNumYYarns; ++i)
363 {
364 dWidth = m_YYarnData[i].dWidth;
365 dHeight = m_YYarnData[i].dHeight;
366 CSectionEllipse Section(dWidth, dHeight);
367 if (m_pSectionMesh)
369 for (itpYarn = m_YYarns[i].begin(); itpYarn != m_YYarns[i].end(); ++itpYarn)
370 {
371 m_Yarns[*itpYarn].AssignSection(CYarnSectionConstant(Section));
372 }
373 }
374
375 // Add repeats and set interpolation
376 dWidth = GetWidth();
377 dHeight = GetHeight();
378 vector<CYarn>::iterator itYarn;
379 for (itYarn = m_Yarns.begin(); itYarn != m_Yarns.end(); ++itYarn)
380 {
381 itYarn->AssignInterpolation(CInterpolationBezier());
382 itYarn->SetResolution(m_iResolution);
383 itYarn->AddRepeat(XYZ(dWidth, 0, 0));
384 itYarn->AddRepeat(XYZ(0, dHeight, 0));
385 }
386
387 return true;
388}
389
390void CTextileWeave::SetThickness(double dThickness, bool bAdjustYarnHeights)
391{
392 m_dFabricThickness = dThickness;
393 if (bAdjustYarnHeights)
394 {
396 }
397 m_bNeedsBuilding = true;
398}
399
400void CTextileWeave::SetGapSize(double dGapSize)
401{
402 m_dGapSize = dGapSize;
403 m_bNeedsBuilding = true;
404}
405
406void CTextileWeave::SetResolution(int iResolution)
407{
408 m_iResolution = iResolution;
409 m_bNeedsBuilding = true;
410}
411
413{
414 m_pSectionMesh = SectionMesh;
415 m_bNeedsBuilding = true;
416}
417
419{
420 TGLOGINDENT("Adjusting yarn widths for \"" << GetName() << "\" with gap size of " << m_dGapSize);
421
422 vector<vector<int> > *pTransverseYarns;
423 vector<vector<int> > *pLongitudinalYarns;
424 int iTransverseNum;
425 int iLongitudinalNum;
426 int iDir;
427 int i, j;
428 CMesh TransverseYarnsMesh;
429 vector<int>::iterator itpYarn;
430 vector<pair<int, int> > RepeatLimits;
431 vector<pair<double, XYZ> > Intersections;
432 XYZ Center, P;
433 const CYarnSection* pYarnSection;
434 const CInterpolation* pInterpolation;
435 CSlaveNode Node;
436 XYZ Side, Up;
437 YARN_POSITION_INFORMATION YarnPosInfo;
438
439 RepeatLimits.resize(2, pair<int, int>(-1, 0));
440 vector<double> YarnMaxWidth;
441 YarnMaxWidth.resize(m_Yarns.size(), -1);
442
443 // Find the max width of the yarns...
444 for (iDir=0; iDir<2; ++iDir)
445 {
446 switch (iDir)
447 {
448 case 0:
449 pTransverseYarns = &m_YYarns;
450 pLongitudinalYarns = &m_XYarns;
451 iTransverseNum = m_iNumYYarns;
452 iLongitudinalNum = m_iNumXYarns;
453 break;
454 case 1:
455 pTransverseYarns = &m_XYarns;
456 pLongitudinalYarns = &m_YYarns;
457 iTransverseNum = m_iNumXYarns;
458 iLongitudinalNum = m_iNumYYarns;
459 break;
460 }
461 for (i=0; i<iTransverseNum; ++i)
462 {
463 TransverseYarnsMesh.Clear();
464 for (itpYarn = (*pTransverseYarns)[i].begin(); itpYarn != (*pTransverseYarns)[i].end(); ++itpYarn)
465 {
466 m_Yarns[*itpYarn].AddSurfaceToMesh(TransverseYarnsMesh, RepeatLimits);
467 }
468 TransverseYarnsMesh.Convert3Dto2D();
469 TransverseYarnsMesh.ConvertQuadstoTriangles();
470// CElementsOctree Octree;
471// TransverseYarnsMesh.BuildElementOctree(CMesh::TRI, Octree);
472 for (j=0; j<iLongitudinalNum; ++j)
473 {
474 for (itpYarn = (*pLongitudinalYarns)[j].begin(); itpYarn != (*pLongitudinalYarns)[j].end(); ++itpYarn)
475 {
476 YarnPosInfo.iSection = i;
477 YarnPosInfo.dSectionPosition = 0;
478 YarnPosInfo.SectionLengths = m_Yarns[*itpYarn].GetYarnSectionLengths();
479
480 pInterpolation = m_Yarns[*itpYarn].GetInterpolation();
481 Node = pInterpolation->GetNode(m_Yarns[*itpYarn].GetMasterNodes(), i, 0);
482 Up = Node.GetUp();
483 Side = CrossProduct(Node.GetTangent(), Up);
484
485 pYarnSection = m_Yarns[*itpYarn].GetYarnSection();
486 // Get 2 section points, one at either side of the cross-section
487 vector<XY> Points = pYarnSection->GetSection(YarnPosInfo, 2);
488 Center = m_Yarns[*itpYarn].GetMasterNodes()[i].GetPosition();
489 vector<XY>::iterator itPoint;
490 for (itPoint = Points.begin(); itPoint != Points.end(); ++itPoint)
491 {
492 P = itPoint->x * Side + itPoint->y * Up + Center;
493 // Find intersection of side points of longitudinal yarn with transvese yarn meshes
494 if (TransverseYarnsMesh.IntersectLine(Center, P, Intersections, make_pair(true, false)))
495 {
496 double dU = Intersections[0].first;
497 XYZ Normal = Intersections[0].second;
498 double dProjectedGap = m_dGapSize / DotProduct(Normal, Center-P);
499 dU -= 0.5 * dProjectedGap;
500 if (dU < 0)
501 dU = 0;
502 if (dU < 1)
503 {
504 double dWidth = 2 * GetLength(*itPoint) * dU;
505 if (YarnMaxWidth[*itpYarn] < 0 || dWidth < YarnMaxWidth[*itpYarn])
506 {
507 YarnMaxWidth[*itpYarn] = dWidth;
508 }
509 }
510 }
511 }
512 }
513 }
514 }
515 }
516
517 // Adjust yarn widths
518 double dWidth, dHeight;
519 for (i=0; i<m_iNumXYarns; ++i)
520 {
521 for (itpYarn = m_XYarns[i].begin(); itpYarn != m_XYarns[i].end(); ++itpYarn)
522 {
523 if (YarnMaxWidth[*itpYarn] >= 0)
524 {
525 if (m_XYarnData[i].dWidth > YarnMaxWidth[*itpYarn])
526 {
527 TGLOG("Changing X yarn width " << i << " from " << m_XYarnData[i].dWidth << " to " << YarnMaxWidth[*itpYarn]);
528 m_XYarnData[i].dWidth = YarnMaxWidth[*itpYarn];
529 }
530 }
531 }
532 }
533 for (i=0; i<m_iNumYYarns; ++i)
534 {
535 for (itpYarn = m_YYarns[i].begin(); itpYarn != m_YYarns[i].end(); ++itpYarn)
536 {
537 if (YarnMaxWidth[*itpYarn] >= 0)
538 {
539 if (m_YYarnData[i].dWidth > YarnMaxWidth[*itpYarn])
540 {
541 TGLOG("Changing Y yarn width " << i << " from " << m_YYarnData[i].dWidth << " to " << YarnMaxWidth[*itpYarn]);
542 m_YYarnData[i].dWidth = YarnMaxWidth[*itpYarn];
543 }
544 }
545 }
546 }
547
548 // Assign sections to the yarns
549 for (i=0; i<m_iNumXYarns; ++i)
550 {
551 dWidth = m_XYarnData[i].dWidth;
552 dHeight = m_XYarnData[i].dHeight;
553 CSectionEllipse Section(dWidth, dHeight);
554 if (m_pSectionMesh)
556 for (itpYarn = m_XYarns[i].begin(); itpYarn != m_XYarns[i].end(); ++itpYarn)
557 {
558 m_Yarns[*itpYarn].AssignSection(CYarnSectionConstant(Section));
559 }
560 }
561 for (i=0; i<m_iNumYYarns; ++i)
562 {
563 dWidth = m_YYarnData[i].dWidth;
564 dHeight = m_YYarnData[i].dHeight;
565 CSectionEllipse Section(dWidth, dHeight);
566 if (m_pSectionMesh)
568 for (itpYarn = m_YYarns[i].begin(); itpYarn != m_YYarns[i].end(); ++itpYarn)
569 {
570 m_Yarns[*itpYarn].AssignSection(CYarnSectionConstant(Section));
571 }
572 }
573}
574
575bool CTextileWeave::FlattenYarns(double dFlatLevel, int iUpDown)
576{
577 YARN_POSITION_INFORMATION YarnPosInfo;
578 // for all yarns
579 for(unsigned int i=0;i<m_Yarns.size();++i)
580 {
581 // get the Current section and cast
582 const CYarnSection* ysection = m_Yarns[i].GetYarnSection();
583 if (ysection->GetType()!="CYarnSectionInterpNode")
584 {
585 TGERROR("Cannot flatten a yarn with section type: " << ysection->GetType())
586 return false;
587 }
588 CYarnSectionInterpNode NewYarnSection((CYarnSectionInterpNode&)(*ysection));
589 const std::vector<CNode>& m_nodes = m_Yarns[i].GetMasterNodes();
590 const int n_section_points = m_Yarns[i].GetNumSectionPoints();
591 YarnPosInfo.SectionLengths = m_Yarns[i].GetYarnSectionLengths();
592 YarnPosInfo.dSectionPosition = 0;
593 double z_mid = 0.0;
594 XYZ npos;
595 for(unsigned int j=0;j<m_nodes.size();++j)
596 {
597 npos = m_nodes[j].GetPosition();
598 z_mid += npos.z/m_nodes.size();
599 }
600 // for all master nodes on the yarn
601 for(unsigned int j=0;j<m_nodes.size();++j)
602 {
603 YarnPosInfo.iSection = j%(m_nodes.size()-1);
604 npos = m_nodes[j].GetPosition();
605 std::vector<XY> section = NewYarnSection.GetSection(YarnPosInfo, n_section_points);
606 for(unsigned int k=0;k<section.size();++k)
607 {
608 if(npos.z<z_mid)
609 {
610 if(section[k].y<-dFlatLevel && iUpDown<=0)
611 section[k].y = - dFlatLevel;
612 }
613 else if (npos.z>z_mid && iUpDown>=0)
614 {
615 if (section[k].y>dFlatLevel)
616 section[k].y = dFlatLevel;
617 }
618 }
619 NewYarnSection.ReplaceSection(j,CSectionPolygon(section));
620 }
621 m_Yarns[i].AssignSection(NewYarnSection);
622 }
623 return true;
624}
625
627{
628 TGLOGINDENT("Correcting interference for \"" << GetName() <<
629 "\" with gap size of " << m_dGapSize);
630
631 vector<vector<int> > *pTransverseYarns;
632 vector<vector<int> > *pLongitudinalYarns;
633 int iTransverseNum;
634 int iLongitudinalNum;
635 int iDir;
636 int i, j, k;
637 CMesh TransverseYarnsMesh;
638 vector<int>::iterator itpYarn;
639 vector<pair<int, int> > RepeatLimits;
640 vector<pair<double, XYZ> > Intersections;
641 XYZ Center, P;
642 const CYarnSection* pYarnSection;
643 const CInterpolation* pInterpolation;
644 CSlaveNode Node;
645 XYZ Side, Up;
646 YARN_POSITION_INFORMATION YarnPosInfo;
647
648 RepeatLimits.resize(2, pair<int, int>(-1, 0));
649 vector<double> Modifiers;
650 vector<vector<vector<double> > > YarnSectionModifiers;
651 YarnSectionModifiers.resize(m_Yarns.size());
652
653 // Find at how much the cross sections need to be compressed to leave given gap size
654 for (iDir=0; iDir<2; ++iDir)
655 {
656 switch (iDir)
657 {
658 case 0:
659 pTransverseYarns = &m_YYarns;
660 pLongitudinalYarns = &m_XYarns;
661 iTransverseNum = m_iNumYYarns;
662 iLongitudinalNum = m_iNumXYarns;
663 break;
664 case 1:
665 pTransverseYarns = &m_XYarns;
666 pLongitudinalYarns = &m_YYarns;
667 iTransverseNum = m_iNumXYarns;
668 iLongitudinalNum = m_iNumYYarns;
669 break;
670 }
671 for (i=0; i<iTransverseNum; ++i)
672 {
673 TransverseYarnsMesh.Clear();
674 for (itpYarn = (*pTransverseYarns)[i].begin(); itpYarn != (*pTransverseYarns)[i].end(); ++itpYarn)
675 {
676 m_Yarns[*itpYarn].AddSurfaceToMesh(TransverseYarnsMesh, RepeatLimits);
677 }
678 TransverseYarnsMesh.Convert3Dto2D();
679 TransverseYarnsMesh.ConvertQuadstoTriangles();
680// CElementsOctree Octree;
681// TransverseYarnsMesh.BuildElementOctree(CMesh::TRI, Octree);
682 for (j=0; j<iLongitudinalNum; ++j)
683 {
684 for (itpYarn = (*pLongitudinalYarns)[j].begin(); itpYarn != (*pLongitudinalYarns)[j].end(); ++itpYarn)
685 {
686 YarnPosInfo.iSection = i;
687 YarnPosInfo.dSectionPosition = 0;
688 YarnPosInfo.SectionLengths = m_Yarns[*itpYarn].GetYarnSectionLengths();
689
690 pInterpolation = m_Yarns[*itpYarn].GetInterpolation();
691 Node = pInterpolation->GetNode(m_Yarns[*itpYarn].GetMasterNodes(), i, 0);
692 Up = Node.GetUp();
693 Side = CrossProduct(Node.GetTangent(), Up);
694
695 pYarnSection = m_Yarns[*itpYarn].GetYarnSection();
696 vector<XY> Points = pYarnSection->GetSection(YarnPosInfo, m_Yarns[*itpYarn].GetNumSectionPoints());
697 Center = m_Yarns[*itpYarn].GetMasterNodes()[i].GetPosition();
698 vector<XY>::iterator itPoint;
699 Modifiers.clear();
700 for (itPoint = Points.begin(); itPoint != Points.end(); ++itPoint)
701 {
702 P = itPoint->x * Side + itPoint->y * Up + Center;
703 if (TransverseYarnsMesh.IntersectLine(Center, P, Intersections, make_pair(true, false)))
704 {
705 double dU = Intersections[0].first;
706 XYZ Normal = Intersections[0].second;
707 double dProjectedGap = m_dGapSize / DotProduct(Normal, Center-P);
708 dU -= 0.5 * dProjectedGap;
709 if (dU > 1)
710 dU = 1;
711 if (dU < 0)
712 dU = 0;
713 Modifiers.push_back(dU);
714 }
715 else
716 Modifiers.push_back(1);
717 }
718 YarnSectionModifiers[*itpYarn].push_back(Modifiers);
719 }
720 }
721 }
722 }
723 vector<XY> Points;
724 for (i=0; i<(int)m_Yarns.size(); ++i)
725 {
726 CYarnSectionInterpNode NewYarnSection(false, true);
727 pYarnSection = m_Yarns[i].GetYarnSection();
728 YarnPosInfo.SectionLengths = m_Yarns[i].GetYarnSectionLengths();
729 // Add sections at the nodes
730 YarnPosInfo.dSectionPosition = 0;
731 for (j=0; j<(int)YarnSectionModifiers[i].size(); ++j)
732 {
733 YarnPosInfo.iSection = j;
734
735 Points = pYarnSection->GetSection(YarnPosInfo, YarnSectionModifiers[i][j].size());
736 for (k=0; k<(int)Points.size(); ++k)
737 {
738 Points[k] *= YarnSectionModifiers[i][j][k];
739 }
740 CSectionPolygon Section(Points);
741 if (m_pSectionMesh)
743 NewYarnSection.AddSection(Section);
744 }
745 NewYarnSection.AddSection(NewYarnSection.GetNodeSection(0));
746
747 // Add sections between the nodes (not necessary for sections that don't cross)
748 YarnPosInfo.dSectionPosition = 0.5;
749 for (j=0; j<(int)YarnSectionModifiers[i].size(); ++j)
750 {
751 if (NeedsMidSection(i, j))
752 {
753 YarnPosInfo.iSection = j;
754
755 Points = pYarnSection->GetSection(YarnPosInfo, YarnSectionModifiers[i][j].size());
756 for (k=0; k<(int)Points.size(); ++k)
757 {
758 Points[k] *= min(YarnSectionModifiers[i][j][k], YarnSectionModifiers[i][(j+1)%YarnSectionModifiers[i].size()][k]);
759 }
760 CSectionPolygon Section(Points);
761 if (m_pSectionMesh)
763 NewYarnSection.InsertSection(j, 0.5, Section);
764 }
765 }
766 m_Yarns[i].AssignSection(NewYarnSection);
767 }
768}
769
770bool CTextileWeave::NeedsMidSection(int iYarn, int iSection) const
771{
772 int i, j;
773 for (i=0; i<(int)m_XYarns.size(); ++i)
774 {
775 for (j=0; j<(int)m_XYarns[i].size(); ++j) // Steps through layers - why does it need to do this if only used for 2D weaves?
776 {
777 if (m_XYarns[i][j] == iYarn)
778 {
779 int iNextSection = (iSection+1) % m_YYarns.size();
780 return !(GetCell(iSection, i) == GetCell(iNextSection, i));
781 }
782 }
783 }
784 for (i=0; i<(int)m_YYarns.size(); ++i)
785 {
786 for (j=0; j<(int)m_YYarns[i].size(); ++j)
787 {
788 if (m_YYarns[i][j] == iYarn)
789 {
790 int iNextSection = (iSection+1) % m_XYarns.size();
791 return !(GetCell(i, iSection) == GetCell(i, iNextSection));
792 }
793 }
794 }
795 return true;
796}
797
798void CTextileWeave::SetXYarnWidths(int iIndex, double dWidth)
799{
800 if (iIndex<0 || iIndex>=m_iNumXYarns)
801 {
802 TGERROR("Unable to set yarn width, index out of range: " << iIndex);
803 return;
804 }
805 m_XYarnData[iIndex].dWidth = dWidth;
806 m_bNeedsBuilding = true;
807}
808
809void CTextileWeave::SetYYarnWidths(int iIndex, double dWidth)
810{
811 if (iIndex<0 || iIndex>=m_iNumYYarns)
812 {
813 TGERROR("Unable to set yarn width, index out of range: " << iIndex);
814 return;
815 }
816 m_YYarnData[iIndex].dWidth = dWidth;
817 m_bNeedsBuilding = true;
818}
819
820void CTextileWeave::SetXYarnHeights(int iIndex, double dHeight)
821{
822 if (iIndex<0 || iIndex>=m_iNumXYarns)
823 {
824 TGERROR("Unable to set yarn height, index out of range: " << iIndex);
825 return;
826 }
827 m_XYarnData[iIndex].dHeight = dHeight;
828 m_bNeedsBuilding = true;
829}
830
831void CTextileWeave::SetYYarnHeights(int iIndex, double dHeight)
832{
833 if (iIndex<0 || iIndex>=m_iNumYYarns)
834 {
835 TGERROR("Unable to set yarn height, index out of range: " << iIndex);
836 return;
837 }
838 m_YYarnData[iIndex].dHeight = dHeight;
839 m_bNeedsBuilding = true;
840}
841
842void CTextileWeave::SetXYarnSpacings(int iIndex, double dSpacing)
843{
844 if (iIndex<0 || iIndex>=m_iNumXYarns)
845 {
846 TGERROR("Unable to set yarn spacing, index out of range: " << iIndex);
847 return;
848 }
849 m_XYarnData[iIndex].dSpacing = dSpacing;
850 m_bNeedsBuilding = true;
851}
852
853void CTextileWeave::SetYYarnSpacings(int iIndex, double dSpacing)
854{
855 if (iIndex<0 || iIndex>=m_iNumYYarns)
856 {
857 TGERROR("Unable to set yarn spacing, index out of range: " << iIndex);
858 return;
859 }
860 m_YYarnData[iIndex].dSpacing = dSpacing;
861 m_bNeedsBuilding = true;
862}
863
864
865double CTextileWeave::GetXYarnWidths(int iIndex) const
866{
867 if (iIndex<0 || iIndex>=m_iNumXYarns)
868 {
869 TGERROR("Unable to set yarn width, index out of range: " << iIndex);
870 return 0;
871 }
872 return m_XYarnData[iIndex].dWidth;
873}
874
875double CTextileWeave::GetYYarnWidths(int iIndex) const
876{
877 if (iIndex<0 || iIndex>=m_iNumYYarns)
878 {
879 TGERROR("Unable to get yarn width, index out of range: " << iIndex);
880 return 0;
881 }
882 return m_YYarnData[iIndex].dWidth;
883}
884
885double CTextileWeave::GetXYarnHeights(int iIndex) const
886{
887 if (iIndex<0 || iIndex>=m_iNumXYarns)
888 {
889 TGERROR("Unable to get yarn height, index out of range: " << iIndex);
890 return 0;
891 }
892 return m_XYarnData[iIndex].dHeight;
893}
894
895double CTextileWeave::GetYYarnHeights(int iIndex) const
896{
897 if (iIndex<0 || iIndex>=m_iNumYYarns)
898 {
899 TGERROR("Unable to get yarn height, index out of range: " << iIndex);
900 return 0;
901 }
902 return m_YYarnData[iIndex].dHeight;
903}
904
905double CTextileWeave::GetXYarnSpacings(int iIndex) const
906{
907 if (iIndex<0 || iIndex>=m_iNumXYarns)
908 {
909 TGERROR("Unable to get yarn spacing, index out of range: " << iIndex);
910 return 0;
911 }
912 return m_XYarnData[iIndex].dSpacing;
913}
914
915double CTextileWeave::GetYYarnSpacings(int iIndex) const
916{
917 if (iIndex<0 || iIndex>=m_iNumYYarns)
918 {
919 TGERROR("Unable to get yarn spacing, index out of range: " << iIndex);
920 return 0;
921 }
922 return m_YYarnData[iIndex].dSpacing;
923}
924
925double CTextileWeave::GetXYarnGapSize(int iIndex) const
926{
927 if (iIndex<0 || iIndex>=m_iNumXYarns)
928 {
929 TGERROR("Unable to get yarn spacing, index out of range: " << iIndex);
930 return 0;
931 }
932 double dGapSize = m_XYarnData[iIndex].dSpacing;
933 dGapSize -= 0.5*m_XYarnData[iIndex].dWidth;
934 if (iIndex == m_iNumXYarns-1)
935 dGapSize -= 0.5*m_XYarnData[0].dWidth;
936 else
937 dGapSize -= 0.5*m_XYarnData[iIndex+1].dWidth;
938 return dGapSize;
939}
940
941double CTextileWeave::GetYYarnGapSize(int iIndex) const
942{
943 if (iIndex<0 || iIndex>=m_iNumYYarns)
944 {
945 TGERROR("Unable to get yarn spacing, index out of range: " << iIndex);
946 return 0;
947 }
948 double dGapSize = m_YYarnData[iIndex].dSpacing;
949 dGapSize -= 0.5*m_YYarnData[iIndex].dWidth;
950 if (iIndex == m_iNumYYarns-1)
951 dGapSize -= 0.5*m_YYarnData[0].dWidth;
952 else
953 dGapSize -= 0.5*m_YYarnData[iIndex+1].dWidth;
954 return dGapSize;
955}
956
957
959{
960 int i;
961 for (i=0; i<m_iNumXYarns; ++i)
962 {
963 SetXYarnWidths(i, dWidth);
964 }
965}
966
968{
969 int i;
970 for (i=0; i<m_iNumYYarns; ++i)
971 {
972 SetYYarnWidths(i, dWidth);
973 }
974}
975
977{
978 int i;
979 for (i=0; i<m_iNumXYarns; ++i)
980 {
981 SetXYarnHeights(i, dHeight);
982 }
983}
984
986{
987 int i;
988 for (i=0; i<m_iNumYYarns; ++i)
989 {
990 SetYYarnHeights(i, dHeight);
991 }
992}
993
995{
996 int i;
997 for (i=0; i<m_iNumXYarns; ++i)
998 {
999 SetXYarnSpacings(i, dSpacing);
1000 }
1001}
1002
1004{
1005 int i;
1006 for (i=0; i<m_iNumYYarns; ++i)
1007 {
1008 SetYYarnSpacings(i, dSpacing);
1009 }
1010}
1011
1012
1014{
1015 SetXYarnWidths(dWidth);
1016 SetYYarnWidths(dWidth);
1017}
1018
1020{
1021 SetXYarnHeights(dHeight);
1022 SetYYarnHeights(dHeight);
1023}
1024
1026{
1027 SetXYarnSpacings(dSpacing);
1028 SetYYarnSpacings(dSpacing);
1029}
1030
1032{
1033 double dWidth = 0;
1034
1035 int i;
1036
1037 for (i=0; i<m_iNumYYarns; ++i)
1038 {
1039 dWidth += m_YYarnData[i].dSpacing;
1040 }
1041
1042 return dWidth;
1043}
1044
1046{
1047 double dHeight = 0;
1048
1049 int j;
1050
1051 for (j=0; j<m_iNumXYarns; ++j)
1052 {
1053 dHeight += m_XYarnData[j].dSpacing;
1054 }
1055
1056 return dHeight;
1057}
1058
1059CDomainPlanes CTextileWeave::GetDefaultDomain( bool bSheared, bool bAddedHeight )
1060{
1061 XYZ Min, Max;
1062 double dGap = 0.0;
1063 if ( bAddedHeight )
1064 dGap = 0.05*m_dFabricThickness;
1065 Min.x = -0.5*m_YYarnData[m_iNumYYarns-1].dSpacing;
1066 Min.y = -0.5*m_XYarnData[m_iNumXYarns-1].dSpacing;
1067// Min.x = m_YYarnData[0].dSpacing;
1068// Min.y = m_XYarnData[0].dSpacing;
1069 Min.z = -dGap;
1070 Max.x = Min.x + GetWidth();
1071 Max.y = Min.y + GetHeight();
1072 Max.z = m_dFabricThickness+dGap;
1073 return CDomainPlanes(Min, Max);
1074}
1075
1076void CTextileWeave::AssignDefaultDomain( bool bSheared, bool bAddedHeight )
1077{
1078 CDomainPlanes Domain = GetDefaultDomain( bSheared, bAddedHeight );
1079 AssignDomain(Domain);
1080}
1081
1083{
1084 return "Weave(W:" + stringify(m_iNumYYarns) + ",H:" + stringify(m_iNumXYarns) + ")";
1085}
1086
1088{
1089 int i;
1090
1091 double dWidth = 0;
1092 for (i=0; i<m_iNumXYarns; ++i)
1093 {
1094 dWidth += m_XYarnData[i].dWidth;
1095 }
1096 for (i=0; i<m_iNumYYarns; ++i)
1097 {
1098 dWidth += m_YYarnData[i].dWidth;
1099 }
1100
1101 return dWidth/(m_iNumXYarns+m_iNumYYarns);
1102}
1103
1104vector<CYarn*> CTextileWeave::GetXYarns(int iIndex)
1105{
1106 vector<CYarn*> Yarns;
1107 if (!BuildTextileIfNeeded())
1108 return Yarns;
1109 if (iIndex<0 || iIndex>=m_iNumXYarns)
1110 {
1111 TGERROR("Unable to get yarn, index out of range: " << iIndex);
1112 return Yarns;
1113 }
1114 vector<int>::iterator itIndex;
1115 for (itIndex = m_XYarns[iIndex].begin(); itIndex != m_XYarns[iIndex].end(); ++itIndex)
1116 {
1117 Yarns.push_back(&m_Yarns[*itIndex]);
1118 }
1119 return Yarns;
1120}
1121
1122vector<CYarn*> CTextileWeave::GetYYarns(int iIndex)
1123{
1124 vector<CYarn*> Yarns;
1125 if (!BuildTextileIfNeeded())
1126 return Yarns;
1127 if (iIndex<0 || iIndex>=m_iNumYYarns)
1128 {
1129 TGERROR("Unable to get yarn, index out of range: " << iIndex);
1130 }
1131 vector<int>::iterator itIndex;
1132 for (itIndex = m_YYarns[iIndex].begin(); itIndex != m_YYarns[iIndex].end(); ++itIndex)
1133 {
1134 Yarns.push_back(&m_Yarns[*itIndex]);
1135 }
1136 return Yarns;
1137}
1138
1139int CTextileWeave::GetYarnIndex(int x, int y, int z) const
1140{
1141 int iXYarnCount = 0;
1142 int iYYarnCount = 0;
1143 vector<PATTERN2D> Pattern = GetCell(x, y);
1144 int k;
1145 for (k=0; k<z; ++k)
1146 {
1147 if (Pattern[k] == PATTERN_XYARN)
1148 ++iXYarnCount;
1149 else
1150 ++iYYarnCount;
1151 }
1152 if (Pattern[z] == PATTERN_XYARN)
1153 return m_XYarns[y][iXYarnCount];
1154 else
1155 return m_YYarns[x][iYYarnCount];
1156}
1157
1159{
1160 vector<vector<int> > *pTransverseYarns;
1161 vector<vector<int> > *pLongitudinalYarns;
1162 int iTransverseNum;
1163 int iLongitudinalNum;
1164 int iDir;
1165
1166 for (iDir=0; iDir<2; ++iDir)
1167 {
1168 switch (iDir)
1169 {
1170 case 0:
1171 pTransverseYarns = &m_YYarns;
1172 pLongitudinalYarns = &m_XYarns;
1173 iTransverseNum = m_iNumYYarns;
1174 iLongitudinalNum = m_iNumXYarns;
1175 break;
1176 case 1:
1177 pTransverseYarns = &m_XYarns;
1178 pLongitudinalYarns = &m_YYarns;
1179 iTransverseNum = m_iNumXYarns;
1180 iLongitudinalNum = m_iNumYYarns;
1181 break;
1182 }
1183
1184 // if (pYarn->GetYarnSection()->GetType() != "CYarnSectionInterpNode")
1185 // return false;
1186
1187 for ( int i = 0; i < iTransverseNum-1; ++i )
1188 {
1189 CYarn TransverseYarn1 = m_Yarns[(*pTransverseYarns)[i][0]];
1190 CYarn TransverseYarn2 = m_Yarns[(*pTransverseYarns)[i+1][0]];
1191 vector<CNode> TransverseNodes1, TransverseNodes2;
1192 TransverseNodes1 = TransverseYarn1.GetMasterNodes();
1193 TransverseNodes2 = TransverseYarn2.GetMasterNodes();
1194
1195 CYarnSectionInterpNode* pYarnSections1 = (CYarnSectionInterpNode*)TransverseYarn1.GetYarnSection()->Copy();
1196 CYarnSectionInterpNode* pYarnSections2 = (CYarnSectionInterpNode*)TransverseYarn2.GetYarnSection()->Copy();
1197
1198 CYarnSectionInterpNode NewYarnSections1, NewYarnSections2;
1199
1200 for (int j = 0; j < iLongitudinalNum; ++j )
1201 {
1202 CSectionEllipse* YarnSection1 = NULL;
1203 CSectionEllipse* YarnSection2 = NULL;
1204 XYZ Point1 = TransverseNodes1[j].GetPosition();
1205 XYZ Point2 = TransverseNodes2[j].GetPosition();
1206
1207 double dist = GetLength(Point1, Point2);
1208 if ( pYarnSections1->GetNodeSection(j).GetType() != "CSectionEllipse" || pYarnSections2->GetNodeSection(j).GetType() != "CSectionEllipse" )
1209 continue;
1210 YarnSection1 = (CSectionEllipse*)pYarnSections1->GetNodeSection(j).Copy();
1211 YarnSection2 = (CSectionEllipse*)pYarnSections2->GetNodeSection(j).Copy();
1212 double Width1 = YarnSection1->GetWidth();
1213 double Width2 = YarnSection2->GetWidth();
1214
1215 double dist2 = 0.5*(Width1+Width2);
1216 dist -= dist2;
1217 if ( dist < 0.0 )
1218 {
1219 CNode Node1 = TransverseNodes1[j];
1220 CNode Node2 = TransverseNodes2[j];
1221 //double Offset = -0.5 * dist;
1222 if ( iDir == 0 )
1223 {
1224 Point1.x += 0.25 * dist;
1225 Point2.x -= 0.25 * dist; // Keep the opposite edge from the overlap at the same place
1226 }
1227 else
1228 {
1229 Point1.y += 0.25 * dist;
1230 Point2.y -= 0.25 * dist; // Want to add whole dist or just y component?
1231 }
1232
1233 Node1.SetPosition( Point1 );
1234 Node2.SetPosition( Point2 );
1235 //pYarnSections2->ReplaceSection( j, Node );
1236 m_Yarns[(*pTransverseYarns)[i][0]].ReplaceNode( j, Node1 );
1237 m_Yarns[(*pTransverseYarns)[i+1][0]].ReplaceNode(j, Node2 );
1238 YarnSection2->SetWidth( Width2 + 0.5*dist ); // dist is -ve so reduces width by overlap
1239 YarnSection1->SetWidth( Width1 + 0.5*dist );
1240 }
1241 NewYarnSections1.AddSection( *YarnSection1 );
1242 NewYarnSections2.AddSection( *YarnSection2 );
1243
1244 delete YarnSection1;
1245 delete YarnSection2;
1246 }
1247 NewYarnSections1.AddSection( pYarnSections1->GetNodeSection(iLongitudinalNum) );
1248 NewYarnSections2.AddSection( pYarnSections2->GetNodeSection(iLongitudinalNum) );
1249 m_Yarns[(*pTransverseYarns)[i][0]].AssignSection( NewYarnSections1 );
1250 m_Yarns[(*pTransverseYarns)[i+1][0]].AssignSection( NewYarnSections2 );
1251 delete pYarnSections1;
1252 delete pYarnSections2;
1253 }
1254 }
1255}
1256
1257
1258
1259
#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 TGLOG(MESSAGE)
Definition: Logger.h:36
#define FOR_EACH_TIXMLELEMENT(CHILDELEMENT, PARENTELEMENT, ELEMENTNAME)
Macro to enable looping over tinyxml easier.
Definition: Misc.h:45
#define NULL
Definition: ShinyConfig.h:50
Domain implementation described using planes, the simplest of which would be a box.
Definition: DomainPlanes.h:37
Bezier interpolation for yarn paths.
Abstract base class for describing the yarn path interpolations.
Definition: Interpolation.h:33
virtual CSlaveNode GetNode(const vector< CNode > &MasterNodes, int iIndex, double t) const =0
Get a node from parametric function. Initialise should be called first.
Defines the nodes and elements of a surface or volume mesh.
Definition: Mesh.h:58
void ConvertQuadstoTriangles(bool bQuality=true)
Convert the quad elements to triangles.
Definition: Mesh.cpp:1088
void Convert3Dto2D()
Convert all 3D elements to 2D elements representing their surface.
Definition: Mesh.cpp:576
void Clear()
Empty mesh nodes and indices.
Definition: Mesh.cpp:1448
int IntersectLine(const XYZ &P1, const XYZ &P2, vector< pair< double, XYZ > > &IntersectionPoints, pair< bool, bool > TrimResults=make_pair(false, false), bool bForceFind=false) const
Find the points where a line intersects the mesh.
Definition: Mesh.cpp:1633
Represents a point on the centreline of a yarn.
Definition: Node.h:28
XYZ GetUp() const
Definition: Node.h:59
void SetPosition(XYZ Position)
Definition: Node.h:62
XYZ GetTangent() const
Definition: Node.h:58
Elliptical Section.
void SetWidth(double dWidth)
double GetWidth() const
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.
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
Creates a polygonal section, where a list of points are given to form the closed polygon.
A derivation of the CNode class which contains data specific to slave nodes such as sections.
Definition: SlaveNode.h:30
Represents a textile cell containing yarns.
Definition: Textile.h:39
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
int GetYarnIndex(int x, int y, int z) const
pair< int, int > GetCellCoordinates(int iIndex) const
double GetXYarnWidths(int iIndex) const
Get the width of the yarn parallel to the X axis, with given index.
void SetResolution(int iResolution)
Set the resolution of the yarns.
virtual void CorrectInterference() const
Adjust cross section shapes to correct interference.
double GetXYarnGapSize(int iIndex) const
Get the gap size between two yarns parallel to the X axis, with given index.
void SetGapSize(double dGapSize)
Set the size of the gap to leave between yarns when correcting interference.
bool NeedsMidSection(int iYarn, int iSection) const
virtual CDomainPlanes GetDefaultDomain(bool bSheared=false, bool bAddedHeight=true)
Get a domain which describes 6 planes triming the textile to a unit cell.
void SetYarnWidths(double dWidth)
Set the width of all the yarns in the textile.
bool Valid() const
Check that the weave pattern contained in m_Pattern is valid.
double GetXYarnSpacings(int iIndex) const
Get the spacing of the yarn parallel to the X axis, with given index.
void SetYYarnSpacings(int iIndex, double dSpacing)
Set the spacing of the yarn parallel to the Y axis, with given index.
CObjectContainer< CSectionMesh > m_pSectionMesh
Definition: TextileWeave.h:221
void SetYYarnHeights(int iIndex, double dHeight)
Set the height of the yarn parallel to the Y axis, with given index.
void SetXYarnSpacings(int iIndex, double dSpacing)
Set the spacing of the yarn parallel to the X axis, with given index.
double GetXYarnHeights(int iIndex) const
Get the height of the yarn parallel to the X axis, with given index.
void SetXYarnHeights(int iIndex, double dHeight)
Set the height of the yarn parallel to the X axis, with given index.
void AssignDefaultDomain(bool bSheared=false, bool bAddedHeight=true)
Get the default domain and assign it as the domain.
void CorrectYarnWidths() const
Adjust cross section widths to avoid interference.
double GetHeight() const
Get the height of the unit cell.
vector< vector< PATTERN2D > > m_Pattern
Definition: TextileWeave.h:217
virtual string GetDefaultName() const
Get the default name to assign to a textile.
bool FlattenYarns(double dFlatLevel, int iUpDownBoth=0)
void SetYarnHeights(double dHeight)
Set the height of all the yarns in the textile.
double GetYYarnGapSize(int iIndex) const
Get the gap size between two yarns parallel to the Y axis, with given index.
virtual bool BuildTextile() const
Build the textile.
void SetYarnSpacings(double dSpacing)
Set the spacing of all the yarns in the textile.
void SetThickness(double dThickness, bool bAdjustYarnHeights=true)
Set the thickness of the fabric.
const vector< PATTERN2D > & GetCell(int x, int y) const
CTextileWeave(int iNumYYarns, int iNumXYarns, double dSpacing, double dThickness)
Build a weave unit cell of given width, height, yarn spacing and fabric thickness.
virtual ~CTextileWeave(void)
vector< vector< int > > m_XYarns
Definition: TextileWeave.h:225
vector< vector< int > > m_YYarns
Definition: TextileWeave.h:226
void SetYYarnWidths(int iIndex, double dWidth)
Set the width of the yarn parallel to the Y axis, with given index.
double GetYYarnWidths(int iIndex) const
Get the width of the yarn parallel to the Y axis, with given index.
vector< CYarn * > GetXYarns(int iIndex)
double GetAverageYarnWidth() const
virtual void PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType)
Used for saving data to XML.
vector< YARNDATA > m_XYarnData
Definition: TextileWeave.h:223
vector< CYarn * > GetYYarns(int iIndex)
double GetWidth() const
Get the width of the unit cell.
double GetYYarnSpacings(int iIndex) const
Get the spacing of the yarn parallel to the Y axis, with given index.
double GetYYarnHeights(int iIndex) const
Get the height of the yarn parallel to the Y axis, with given index.
vector< YARNDATA > m_YYarnData
Definition: TextileWeave.h:224
void SetXYarnWidths(int iIndex, double dWidth)
Set the width of the yarn parallel to the X axis, with given index.
void AssignSectionMesh(const CSectionMesh &SectionMesh)
Assign a section mesh to the weave.
Represents a yarn consisting of master nodes, section and interpolation function.
Definition: Yarn.h:49
const CYarnSection * GetYarnSection() const
Definition: Yarn.h:449
const vector< CNode > & GetMasterNodes() const
Definition: Yarn.h:447
Creates a section which is constant all along the yarn.
Abstract base class used to define the sections along the length of a yarn.
Definition: YarnSection.h:58
virtual CYarnSection * Copy() const =0
This is a function to allow copying of derived classes correctly.
virtual string GetType() const =0
Derived class should return the class name.
virtual vector< XY > GetSection(const YARN_POSITION_INFORMATION PositionInfo, int iNumPoints, bool bEquiSpaced=false) const =0
This function must be implemented by derived classes.
Creates a section which is linearly interpolated between sections defined at the nodes.
void ReplaceSection(int iIndex, const CSection &Section)
Replace a section at a node.
void AddSection(const CSection &Section)
Add a section at a node.
const CSection & GetNodeSection(int iIndex) const
void InsertSection(int iIndex, const CSection &Section)
Insert a section at a node.
vector< XY > GetSection(const YARN_POSITION_INFORMATION PositionInfo, int iNumPoints, bool bEquiSpaced=false) const
This function must be implemented by derived classes.
Namespace containing a series of customised math operations not found in the standard c++ library.
@ PATTERN_XYARN
Definition: TextileWeave.h:33
@ PATTERN_YYARN
Definition: TextileWeave.h:34
OUTPUT_TYPE
Definition: Misc.h:105
@ OUTPUT_STANDARD
Definition: Misc.h:107
@ OUTPUT_FULL
Definition: Misc.h:108
double Max(XYZ &Vector)
Get maximum element of vector and return it.
Definition: mymath.h:642
double GetLength(const XYZ &Point1, const XYZ &Point2)
Get the length between two points.
Definition: mymath.h:540
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
double DotProduct(const XYZ &left, const XYZ &right)
Get the dot product of two vectors.
Definition: mymath.h:512
XYZ CrossProduct(const XYZ &left, const XYZ &right)
Get the cross product of two vectors.
Definition: mymath.h:524
Data structure to keep track of yarn parameters.
Definition: TextileWeave.h:210
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
Structure used to represent the position along the length of a yarn.
Definition: YarnSection.h:36
double dSectionPosition
This variables varies linearly with distance from 0 to 1 from the start to the end of the current lin...
Definition: YarnSection.h:37
int iSection
This variable represents the index of the current section (where a section is defined as the part bet...
Definition: YarnSection.h:38
vector< double > SectionLengths
This contains a list of lengths representing the length of each section.
Definition: YarnSection.h:39