TexGen
ShearedTextileWeave2D.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"
22#include "SectionEllipse.h"
23#include "SectionRotated.h"
24#include "SectionPolygon.h"
25
26using namespace TexGen;
27
28#define MID_SECTIONS 4
29# define TOL 0.000001
30
31CShearedTextileWeave2D::CShearedTextileWeave2D(int iWidth, int iHeight, double dSpacing, double dThickness, double ShearAngle, bool bRefine, bool bInPlaneTangents )
32: CTextileWeave2D(iWidth, iHeight, dSpacing, dThickness, bRefine, bInPlaneTangents )
33, m_ShearAngle(ShearAngle)
34, m_bShearedDomain(false)
35{
36}
37
39{
40}
41
43: CTextileWeave2D(Element)
44{
45 Element.Attribute("ShearAngle", &m_ShearAngle);
46}
47
48void CShearedTextileWeave2D::PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType)
49{
50 CTextileWeave2D::PopulateTiXmlElement( Element, OutputType );
51 Element.SetAttribute("ShearAngle", stringify(m_ShearAngle));
52}
53
55{
56 m_Yarns.clear();
57 m_YYarns.clear();
58 m_XYarns.clear();
59
60 m_YYarns.resize(m_iNumYYarns);
61 m_XYarns.resize(m_iNumXYarns);
62
63 if (!Valid())
64 return false;
65
66 TGLOGINDENT("Building sheared textile weave \"" << GetName() << "\"");
67
68 vector<int> Yarns;
69
70 double x, y, z;
71
73
74 // Add x yarns (yarns parallel to the x axis)
75 int i, j, k, iYarn;
76 y = 0;
77 double Startx = 0;
78 for (i=0; i<m_iNumXYarns; ++i)
79 {
80 x = Startx;
81 Yarns.clear();
82 for (j=0; j<=m_iNumYYarns; ++j)
83 {
84 const vector<PATTERN2D> &Cell = GetCell(j%m_iNumYYarns, i);
85 if (j==0)
86 {
87 for (k=0; k<(int)Cell.size(); ++k)
88 {
89 if (Cell[k] == PATTERN_XYARN)
90 {
91 Yarns.push_back(AddYarn(CYarn()));
92 }
93 }
94 }
95 m_XYarns[i] = Yarns;
96 iYarn = 0;
97 z = m_dFabricThickness/(2*Cell.size());
98 for (k=0; k<(int)Cell.size(); ++k)
99 {
100 if (Cell[k] == PATTERN_XYARN)
101 {
102 m_Yarns[Yarns[iYarn]].AddNode(CNode(XYZ(x, y, z), XYZ(1, 0, 0)));
103 ++iYarn;
104 }
105 z += m_dFabricThickness/Cell.size();
106 }
107 if (j<m_iNumYYarns)
108 x += m_YYarnData[j].dSpacing;
109 }
110 Startx += m_YSpacing[i].x;
111 y += m_YSpacing[i].y;
112 }
113
114 // Add y yarns (yarns parallel to the y axis)
115 Startx = 0;
116 for (j=0; j<m_iNumYYarns; ++j)
117 {
118 x = Startx;
119 y = 0;
120 Yarns.clear();
121 for (i=0; i<=m_iNumXYarns; ++i)
122 {
123 const vector<PATTERN2D> &Cell = GetCell(j, i%m_iNumXYarns);
124 if (i==0)
125 {
126 for (k=0; k<(int)Cell.size(); ++k)
127 {
128 if (Cell[k] == PATTERN_YYARN)
129 {
130 Yarns.push_back(AddYarn(CYarn()));
131 }
132 }
133 }
134 m_YYarns[j] = Yarns;
135 iYarn = 0;
136 z = m_dFabricThickness/(2*Cell.size());
137 for (k=0; k<(int)Cell.size(); ++k)
138 {
139 if (Cell[k] == PATTERN_YYARN)
140 {
141 m_Yarns[Yarns[iYarn]].AddNode(CNode(XYZ(x, y, z), XYZ(0, 1, 0)));
142 ++iYarn;
143 }
144 z += m_dFabricThickness/Cell.size();
145 }
146 if (i<m_iNumXYarns)
147 {
148 x += m_YSpacing[i].x;
149 y += m_YSpacing[i].y;
150 }
151 }
152 Startx += m_YYarnData[j].dSpacing;
153 }
154
155
156 // Assign sections and interpolation to the yarns
157 vector<int>::iterator itpYarn;
158 double dWidth, dHeight;
159 for (i=0; i<m_iNumXYarns; ++i)
160 {
161 dWidth = m_XYarnData[i].dWidth;
162 dHeight = m_XYarnData[i].dHeight;
163 CSectionEllipse Section(dWidth, dHeight);
164 if (m_pSectionMesh)
166 for (itpYarn = m_XYarns[i].begin(); itpYarn != m_XYarns[i].end(); ++itpYarn)
167 {
168 m_Yarns[*itpYarn].AssignSection(CYarnSectionConstant(Section));
169 m_Yarns[*itpYarn].AssignInterpolation(CInterpolationBezier());
170 }
171 }
172 for (i=0; i<m_iNumYYarns; ++i)
173 {
174 dWidth = m_YYarnData[i].dWidth;
175 dHeight = m_YYarnData[i].dHeight;
176 CSectionEllipse Section(dWidth, dHeight);
177 if (m_pSectionMesh)
179 for (itpYarn = m_YYarns[i].begin(); itpYarn != m_YYarns[i].end(); ++itpYarn)
180 {
181 m_Yarns[*itpYarn].AssignSection(CYarnSectionConstant(Section));
182 m_Yarns[*itpYarn].AssignInterpolation(CInterpolationCubic());
183 }
184 }
185
186
187
188 // Add repeats and set interpolation
189 dWidth = GetWidth();
190 XY Repeat = GetYRepeat();
191
192 vector<CYarn>::iterator itYarn;
193 for (itYarn = m_Yarns.begin(); itYarn != m_Yarns.end(); ++itYarn)
194 {
195 itYarn->SetResolution(m_iResolution);
196 itYarn->AddRepeat(XYZ(dWidth, 0, 0));
197 itYarn->AddRepeat(XYZ(Repeat.x, Repeat.y, 0));
198 }
199
201 return true;
202
203 // Set interpolation to force in-plane tangents at node if m_bInPlaneTangents set
204 if ( m_bInPlaneTangents )
207
208 if ( !m_bRefine )
209 return true;
210
211 //TGLOGINDENT("Refining textile 2d weave \"" << GetName() << "\"");
212
213 Refine();
214
215 return true;
216}
217
218CDomainPlanes CShearedTextileWeave2D::GetDefaultDomain( bool bSheared, bool bAddedDomainHeight )
219{
220 XYZ Min, Max;
221 double dGap = 0.0;
222 if ( bAddedDomainHeight )
223 dGap = 0.05*m_dFabricThickness;
224
225 m_bShearedDomain = bSheared;
226 if ( m_YSpacing.empty() )
227 GetYSpacings();
228 if ( bSheared )
229 Min.x = -0.5*m_YYarnData[m_iNumYYarns-1].dSpacing;
230 else // Work out minimum x taking into account shear angle
231 Min.x = -0.5*(m_YYarnData[m_iNumYYarns-1].dSpacing + m_YSpacing[m_iNumYYarns-1].x);
232 Min.y = -0.5*m_YSpacing[m_iNumXYarns-1].y;
233 Min.z = -dGap;
234
235 Max.x = Min.x + GetWidth();
236 Max.y = Min.y + GetYRepeat().y;
237 Max.z = m_dFabricThickness+dGap;
238 if ( !bSheared )
239 return CDomainPlanes(Min, Max);
240
241 CDomainPlanes Domain;
242 double cosAng = cos(m_ShearAngle);
243 double sinAng = sin(m_ShearAngle);
244
245 Domain.AddPlane( PLANE( XYZ( cosAng, -sinAng, 0), Min.x*cosAng) );
246 Domain.AddPlane( PLANE( XYZ( -cosAng, sinAng, 0), -Max.x*cosAng) );
247 Domain.AddPlane( PLANE( XYZ(0, 1, 0), Min.y ) );
248 Domain.AddPlane( PLANE( XYZ(0, -1, 0), -Max.y ) );
249 Domain.AddPlane( PLANE( XYZ(0, 0, 1), Min.z ) );
250 Domain.AddPlane( PLANE( XYZ(0, 0, -1), -Max.z ) );
251 return Domain;
252}
253
255{
256 m_YSpacing.clear();
257 double sinAngle = sin(m_ShearAngle);
258 double cosAngle = cos(m_ShearAngle);
259
260 for ( int i = 0; i < m_iNumXYarns; ++i )
261 {
262 XY spacing;
263 spacing.x = m_XYarnData[i].dSpacing * sinAngle;
264 spacing.y = m_XYarnData[i].dSpacing * cosAngle;
265 m_YSpacing.push_back( spacing );
266 }
267}
268
270{
271 XY YRepeat;
272 vector<XY>::iterator itYSpacings;
273
274 for ( itYSpacings = m_YSpacing.begin(); itYSpacings != m_YSpacing.end(); ++itYSpacings )
275 {
276 YRepeat += *itYSpacings;
277 }
278 return YRepeat;
279}
280
282{
283 CTimer timer;
284 timer.start("Timing Refine");
285
287
289
291 if ( GetDomain() )
293 else
294 TGERROR("Cannot adjust sections - no domain specified");
295 //CorrectInterference( true );
296 timer.check("End of Refine");
297 timer.stop();
298}
299
301{
302 int i, j;
303 vector<vector<int> > *pTransverseYarns;
304 vector<vector<int> > *pLongitudinalYarns;
305 vector<YARNDATA> *pTransverseData;
306 vector<YARNDATA> *pLongitudinalData;
307 int iTransverseNum;
308 int iLongitudinalNum;
309 bool iTransversePattern;
310 bool iLongitudinalPattern;
311
312 CYarn *pYarn;
313
314 double dTransWidth, dTransHeight;
315 int iPrevTransYarnInd;
316 int iNextTransYarnInd, iNextLongYarnInd;
317
318 for (int iDir=0; iDir<2; ++iDir)
319 {
320 switch (iDir)
321 {
322 case 0:
323 pTransverseYarns = &m_YYarns;
324 pLongitudinalYarns = &m_XYarns;
325 iTransverseNum = m_iNumYYarns;
326 iLongitudinalNum = m_iNumXYarns;
327 pTransverseData = &m_YYarnData;
328 pLongitudinalData = &m_XYarnData;
329 iTransversePattern = PATTERN_YYARN;
330 iLongitudinalPattern = PATTERN_XYARN;
331 break;
332 case 1:
333 pTransverseYarns = &m_XYarns;
334 pLongitudinalYarns = &m_YYarns;
335 iTransverseNum = m_iNumXYarns;
336 iLongitudinalNum = m_iNumYYarns;
337 pTransverseData = &m_XYarnData;
338 pLongitudinalData = &m_YYarnData;
339 iTransversePattern = PATTERN_XYARN;
340 iLongitudinalPattern = PATTERN_YYARN;
341 break;
342 }
343 // Transverse yarns
344 for ( i = 0; i < iTransverseNum; ++i )
345 {
346 iPrevTransYarnInd = i-1;
347 if (iPrevTransYarnInd < 0)
348 iPrevTransYarnInd += iTransverseNum;
349 iNextTransYarnInd = (i+1)%iTransverseNum;
350
351 // Get the yarn width and height for this transverse yarn
352 dTransWidth = (*pTransverseData)[i].dWidth;
353 dTransHeight = (*pTransverseData)[i].dHeight;
354 // Get a pointer to the current yarn
355 pYarn = &m_Yarns[(*pTransverseYarns)[i][0]];
356 CSectionEllipse EllipseSection(dTransWidth, dTransHeight);
357
358 // Get a copy of the yarn sections that are applied to the nodes
359 if (pYarn->GetYarnSection()->GetType() != "CYarnSectionInterpNode")
360 return false;
362
363 // Calculate rotations between each pair of nodes along transverse yarn
364 // u = 0 at current node, u = 1 at next node
365 for (j=0; j<iLongitudinalNum; ++j)
366 {
367 iNextLongYarnInd = (j+1)%iLongitudinalNum;
368
369 // Get widths of current and next longitudinal yarns
370 double dLongWidth = (*pLongitudinalData)[j].dWidth;
371 double dLongHeight = (*pLongitudinalData)[j].dHeight;
372
373 double dNextLongWidth = (*pLongitudinalData)[iNextLongYarnInd].dWidth;
374 double dNextLongHeight = (*pLongitudinalData)[iNextLongYarnInd].dHeight;
375 double dDistToLongYarnEdge = 0.5 * dLongWidth / cos(m_ShearAngle);
376
377 // Get nodes in transverse yarn and distance between them
378 XYZ Node = pYarn->GetNode(j)->GetPosition();
379 XYZ NextNode = pYarn->GetNode(iNextLongYarnInd)->GetPosition();
380 double dDistBetweenNodes = GetLength( Convert(Node), Convert(NextNode) );
381
382 // Calculate value of u between transverse yarn nodes where it crosses edges of this and next longitudinal yarns
383 double dDistToNextLongYarnEdge = 0.5 * dNextLongWidth / cos(m_ShearAngle);
384
385 // Calculate limits of R to avoid square root of -ve number in CalcSinAngle function
386 double RCalc = 1.0 / sqrt( 1.0 - 1.0/((dLongWidth/dLongHeight)*(dLongWidth/dLongHeight)) );
387 double RMax = 0.25 * ( 1.0 + 0.2*sin(m_ShearAngle) + RCalc );
388 if ( RMax > 0.495 ) // Set to max of 0.99 * 0.5
389 RMax = 0.495;
390
391
392 RCalc = 1.0 / sqrt( 1.0 - 1.0/((dNextLongWidth/dNextLongHeight)*(dNextLongWidth/dNextLongHeight)) );
393 double RMin = 0.25 * ( 1.0 - 0.2*sin(m_ShearAngle) - RCalc );
394 if ( RMin < 0.005 )
395 RMin = 0.005;
396
397 // For specified number of equispaced points across each yarn
398 // calculate corresponding R values where R varies from 0 to 0.5 across width of yarn
399 // and use to calculate rotations
400 double dR = (RMax - 0.25) / (MID_SECTIONS/2);
401 for ( int k = 0; k <= MID_SECTIONS/2; ++k )
402 {
403 double u = 0.0;
404 double dist;
405 double R;
406 double dAngle;
407 int iRot = 0;
408
409 R = 0.25 + dR*k;
410
411 dAngle = asin(CalcSinAngle( R, dTransWidth, dTransHeight ));
412 if ( GetCellDir(i,j, iDir)[0] == iTransversePattern )
413 {
414 if ( GetCellDir( i, iNextLongYarnInd, iDir )[1] == iTransversePattern && GetCellDir(iNextTransYarnInd,j, iDir)[0] == iLongitudinalPattern )
415 {
416 if ( iDir == 0 )
417 iRot = -1;
418 else
419 iRot = 1;
420 }
421 }
422 else
423 {
424 if ( GetCellDir( i, iNextLongYarnInd, iDir)[0] == iTransversePattern && GetCellDir(iNextTransYarnInd, j, iDir)[1] == iLongitudinalPattern )
425 {
426 if ( iDir == 0 )
427 iRot = 1;
428 else
429 iRot = -1;
430 }
431 }
432
433 dist = (R - 0.25) * (4.0 * dDistToLongYarnEdge);
434 u = dist/dDistBetweenNodes;
435
436 // If rotation required at node replace section
437 if ( k == 0 )
438 {
439 if ( iRot )
440 pYarnSection->ReplaceSection(j, CSectionRotated(EllipseSection, iRot*dAngle));
441 }
442 else // Add mid-node sections, rotating if necessary
443 {
444 if ( iRot )
445 pYarnSection->InsertSection( j, u, CSectionRotated( EllipseSection, iRot*dAngle));
446 else
447 pYarnSection->InsertSection( j, u, EllipseSection );
448 }
449
450 }
451
452 dR = ( 0.25 - RMin ) / (MID_SECTIONS/2);
453 for ( int k = 0; k < MID_SECTIONS/2; ++k )
454 {
455 double u = 0.0;
456 double dist;
457 double R;
458 double dAngle;
459 int iRot = 0;
460
461 R = RMin + dR*k;
462
463 dAngle = asin(CalcSinAngle( R, dTransWidth, dTransHeight ));
464
465 if ( GetCellDir(i, iNextLongYarnInd, iDir)[0] == iTransversePattern )
466 {
467 if ( GetCellDir( i, j, iDir )[1] == iTransversePattern && GetCellDir(iPrevTransYarnInd,iNextLongYarnInd, iDir)[0] == iLongitudinalPattern )
468 {
469 if ( iDir == 0 )
470 iRot = 1;
471 else
472 iRot = -1;
473 }
474 }
475 else
476 {
477 if ( GetCellDir( i, j, iDir )[0] == iTransversePattern && GetCellDir( iPrevTransYarnInd, iNextLongYarnInd, iDir )[1] == iLongitudinalPattern )
478 {
479 if ( iDir == 0 )
480 iRot = -1;
481 else
482 iRot = 1;
483 }
484 }
485
486 dist = dDistBetweenNodes - (0.25 - R) * ( 4.0 * dDistToNextLongYarnEdge );
487 u = dist/dDistBetweenNodes;
488
489 // Add mid-node sections, rotating if necessary
490 if ( iRot )
491 {
492 pYarnSection->InsertSection( j, u, CSectionRotated( EllipseSection, iRot*dAngle));
493 }
494 else
495 {
496 pYarnSection->InsertSection( j, u, EllipseSection );
497 }
498 }
499 }
500 // Assign the same section to the end as at the start (periodic yarns)
501 pYarnSection->ReplaceSection(j, pYarnSection->GetNodeSection(0));
502 pYarn->AssignSection(*pYarnSection);
503
504 delete pYarnSection;
505 }
506 }
507 return true;
508}
509
510double CShearedTextileWeave2D::CalcSinAngle( double R, double Width, double Height ) const
511{
512 double denom;
513 double WidthHeight = (Width/Height);
514 WidthHeight *= WidthHeight;
515 if (R <= 0.25)
516 {
517 if ( m_ShearAngle >= 0.0 )
518 denom = (1 - 4 * R - 0.2*sin(m_ShearAngle));
519 else
520 denom = (1 - 4 * R + 0.2*sin(m_ShearAngle));
521 }
522 else
523 {
524 if ( m_ShearAngle >= 0.0 )
525 denom = (1 - 4*R + 0.2*sin(m_ShearAngle));
526 else
527 denom = (1 - 4 * R - 0.2*sin(m_ShearAngle));
528 }
529 denom *= denom;
530 denom = 1/denom - 1;
531 denom = 1 + WidthHeight*denom;
532 denom = sqrt(denom);
533
534 return sin(m_ShearAngle)/denom;
535}
536
537void CShearedTextileWeave2D::CorrectInterference( bool bMaxCorrection ) const
538{
539 TGLOGINDENT("Correcting interference for \"" << GetName() <<
540 "\" with gap size of " << m_dGapSize);
541
542 vector<vector<int> > *pTransverseYarns;
543 vector<vector<int> > *pLongitudinalYarns;
544 vector<YARNDATA> *pTransverseData;
545 int iTransverseNum;
546 int iLongitudinalNum;
547 int iDir;
548 int i, j;
549 CMesh TransverseYarnsMesh;
550 CMesh NextTransverseYarnsMesh;
551 vector<int>::iterator itpYarn;
552 vector<pair<int, int> > RepeatLimits;
553 vector<pair<double, XYZ> > Intersections;
554 XYZ Center, P;
555
556 const CInterpolation* pInterpolation;
557 CSlaveNode Node;
558 XYZ Side, Up;
559 YARN_POSITION_INFORMATION YarnPosInfo;
560
561 RepeatLimits.resize(2, pair<int, int>(-1, 1));
562 vector<double> Modifiers;
563 vector<vector<vector<double> > > YarnSectionModifiers;
564 YarnSectionModifiers.resize(m_Yarns.size());
565
566 // Find at how much the cross sections need to be compressed to leave given gap size
567 for (iDir=0; iDir<2; ++iDir)
568 {
569 switch (iDir)
570 {
571 case 0:
572 pTransverseYarns = &m_YYarns;
573 pLongitudinalYarns = &m_XYarns;
574 iTransverseNum = m_iNumYYarns;
575 iLongitudinalNum = m_iNumXYarns;
576 pTransverseData = &m_YYarnData;
577 break;
578 case 1:
579 pTransverseYarns = &m_XYarns;
580 pLongitudinalYarns = &m_YYarns;
581 iTransverseNum = m_iNumXYarns;
582 iLongitudinalNum = m_iNumYYarns;
583 pTransverseData = &m_XYarnData;
584 break;
585 }
586 for (i=0; i<iTransverseNum; ++i)
587 {
588 TransverseYarnsMesh.Clear();
589 if ( i == 0 )
590 {
591 for (itpYarn = (*pTransverseYarns)[i].begin(); itpYarn != (*pTransverseYarns)[i].end(); ++itpYarn)
592 {
593 m_Yarns[*itpYarn].AddSurfaceToMesh(TransverseYarnsMesh, RepeatLimits);
594 }
595 //TransverseYarnsMesh.Convert3Dto2D();
596 TransverseYarnsMesh.ConvertQuadstoTriangles();
597 }
598 else
599 {
600 TransverseYarnsMesh = NextTransverseYarnsMesh;
601 }
602
603 NextTransverseYarnsMesh.Clear();
604 for (itpYarn = (*pTransverseYarns)[(i+1)%iTransverseNum].begin(); itpYarn != (*pTransverseYarns)[(i+1)%iTransverseNum].end(); ++itpYarn)
605 {
606 m_Yarns[*itpYarn].AddSurfaceToMesh(NextTransverseYarnsMesh, RepeatLimits);
607 }
608 //NextTransverseYarnsMesh.Convert3Dto2D();
609 NextTransverseYarnsMesh.ConvertQuadstoTriangles();
610
611 for (j=0; j<iLongitudinalNum; ++j)
612 {
613 for (itpYarn = (*pLongitudinalYarns)[j].begin(); itpYarn != (*pLongitudinalYarns)[j].end(); ++itpYarn)
614 {
615 YarnPosInfo.iSection = i;
616 YarnPosInfo.dSectionPosition = 0;
617 YarnPosInfo.SectionLengths = m_Yarns[*itpYarn].GetYarnSectionLengths();
618
619 XYZ Node = m_Yarns[*itpYarn].GetNode(j)->GetPosition();
620 XYZ NextNode = m_Yarns[*itpYarn].GetNode((j+1)%iLongitudinalNum)->GetPosition();
621
622 double dDistBetweenNodes = GetLength( Convert(Node), Convert(NextNode) );
623
624 pInterpolation = m_Yarns[*itpYarn].GetInterpolation();
625 // Calculate adjustments to section at node
626 CalculateModifiers( pInterpolation, *itpYarn, YarnPosInfo, TransverseYarnsMesh, YarnSectionModifiers, bMaxCorrection );
627
628 // Calculate the value of u at the edge of the yarn crossing the first node
629 double DistToEdgeU = (0.5 * (*pTransverseData)[i].dWidth / cos(m_ShearAngle) )/ dDistBetweenNodes;
630
631 CYarnSectionInterpNode* pYarnSections = (CYarnSectionInterpNode*)m_Yarns[*itpYarn].GetYarnSection()->Copy();
632
633 // Calculate adjustments for each of the mid node sections
634 int iMidSize = pYarnSections->GetNumMidNodeSections(i);
635 for ( int k = 0; k < iMidSize; ++k )
636 {
637 YarnPosInfo.dSectionPosition = pYarnSections->GetMidNodeSectionPos( i, k );
638 if ( YarnPosInfo.dSectionPosition <= DistToEdgeU )
639 CalculateModifiers( pInterpolation, *itpYarn, YarnPosInfo, TransverseYarnsMesh, YarnSectionModifiers, bMaxCorrection );
640 else
641 CalculateModifiers( pInterpolation, *itpYarn, YarnPosInfo, NextTransverseYarnsMesh, YarnSectionModifiers, bMaxCorrection );
642 }
643 delete pYarnSections;
644 }
645 }
646 }
647 }
648
649 // Apply modifiers to yarn sections
650
651 for (i=0; i<(int)m_Yarns.size(); ++i)
652 {
653 CYarnSectionInterpNode NewYarnSection(false, true);
654 CYarnSectionInterpNode* pYarnSection = (CYarnSectionInterpNode*)m_Yarns[i].GetYarnSection()->Copy();
655 YarnPosInfo.SectionLengths = m_Yarns[i].GetYarnSectionLengths();
656
657 int iNodeIndex = 0;
658 for (j=0; j<(int)YarnSectionModifiers[i].size(); )
659 {
660 // Modify section at node
661 YarnPosInfo.iSection = iNodeIndex;
662 YarnPosInfo.dSectionPosition = 0;
663
664 ModifySection(pYarnSection, YarnPosInfo, YarnSectionModifiers[i][j], iNodeIndex);
665
666 // Modify mid node sections
667 int iMidSize = pYarnSection->GetNumMidNodeSections(iNodeIndex);
668 j++;
669 for ( int iMidIndex = 0; iMidIndex < iMidSize; ++iMidIndex )
670 {
671 YarnPosInfo.dSectionPosition = pYarnSection->GetMidNodeSectionPos( iNodeIndex, iMidIndex );
672
673 ModifySection(pYarnSection, YarnPosInfo, YarnSectionModifiers[i][j], iNodeIndex, iMidIndex);
674 j++;
675 }
676 iNodeIndex++;
677 }
678 // Make sure end matches start
679 pYarnSection->ReplaceSection(pYarnSection->GetNumNodeSections()-1, pYarnSection->GetNodeSection(0) );
680
681 m_Yarns[i].AssignSection(*pYarnSection);
682 delete pYarnSection;
683 }
684}
685
686
687void CShearedTextileWeave2D::CalculateModifiers( const CInterpolation *pInterpolation, int Yarn, YARN_POSITION_INFORMATION YarnPosInfo, CMesh& Mesh, vector<vector<vector<double> > >& YarnSectionModifiers, bool bMaxCorrection) const
688{
689 XYZ Up, Side;
690 CSlaveNode Node;
691 const CYarnSection* pYarnSection;
692 XYZ Centre;
693 vector<double> Modifiers;
694
695 Node = pInterpolation->GetNode(m_Yarns[Yarn].GetMasterNodes(), YarnPosInfo.iSection, YarnPosInfo.dSectionPosition);
696 Up = Node.GetUp();
697 Side = CrossProduct(Node.GetTangent(), Up);
698 Centre = Node.GetPosition();
699
700 pYarnSection = m_Yarns[Yarn].GetYarnSection();
701 vector<XY> Points = pYarnSection->GetSection(YarnPosInfo, m_Yarns[Yarn].GetNumSectionPoints());
702
703 // Calculate intersections between line joining centre of section and each point and the yarn mesh
704 vector<XY>::iterator itPoint;
705 Modifiers.clear();
706 for (itPoint = Points.begin(); itPoint != Points.end(); ++itPoint)
707 {
708 XYZ P = itPoint->x * Side + itPoint->y * Up + Centre;
709 vector<pair<double, XYZ> > Intersections;
710 if (Mesh.IntersectLine(Centre, P, Intersections, make_pair(true, false)))
711 {
712 double dU = Intersections[0].first;
713 if ( !bMaxCorrection && dU > 0 && dU < 1 ) // Only want to change by half intersection otherwise create gap
714 dU = 0.5 + 0.5*dU;
715 XYZ Normal = Intersections[0].second;
716 double dProjectedGap = m_dGapSize / DotProduct(Normal, Centre-P);
717 dU -= 0.5 * dProjectedGap;
718 if (dU > 1)
719 dU = 1;
720 if (dU < 0)
721 dU = 0;
722 Modifiers.push_back(dU);
723 }
724 else
725 Modifiers.push_back(1);
726 }
727 YarnSectionModifiers[Yarn].push_back(Modifiers);
728}
729
730void CShearedTextileWeave2D::ModifySection(CYarnSectionInterpNode* pYarnSection, YARN_POSITION_INFORMATION& YarnPosInfo, vector<double>& Modifiers, int iNodeIndex, int iMidIndex) const
731{
732 vector<XY> Points;
733 Points = pYarnSection->GetSection(YarnPosInfo, (int)Modifiers.size());
734 for (int k=0; k<(int)Points.size(); ++k)
735 {
736 Points[k] *= Modifiers[k];
737 }
738 CSectionPolygon Section(Points);
739 if (m_pSectionMesh)
741 if ( iMidIndex == -1 )
742 pYarnSection->ReplaceSection( iNodeIndex, Section );
743 else
744 pYarnSection->ReplaceMidSection( iNodeIndex, iMidIndex, Section );
745}
746
748{
749 int i, j;
750 vector<double> YarnSectionModifiers;
751 const CInterpolation* pInterpolation;
752
753 CMesh TopMesh, BottomMesh;
754 CreateTopAndBottomMeshes( TopMesh, BottomMesh );
755
756 // Y yarns (parallel to y axis)
757 for ( i = 0; i < m_iNumYYarns; ++i )
758 {
759 // Get Y yarn(i)
760 int YarnInd = m_YYarns[i][0];
761 pInterpolation = m_Yarns[YarnInd].GetInterpolation();
762 CYarnSectionInterpNode* pYarnSections = (CYarnSectionInterpNode*)m_Yarns[YarnInd].GetYarnSection()->Copy();
763
764 // Get area of original yarn section
765 CSectionEllipse Section(m_YYarnData[i].dWidth, m_YYarnData[i].dHeight);
766 double dTargetArea = Section.GetArea( Section.GetPoints(40) );
767
768 YarnSectionModifiers.clear();
769 for ( j = 0; j < m_iNumXYarns; ++j )
770 {
771 YARN_POSITION_INFORMATION YarnPosInfo;
772 YarnPosInfo.iSection = j;
773 YarnPosInfo.dSectionPosition = 0;
774 YarnPosInfo.SectionLengths = m_Yarns[YarnInd].GetYarnSectionLengths();
775 // For section at node (i,j)
776 const vector<PATTERN2D> &Cell = GetCell(i,j);
777 if ( Cell[0] == PATTERN_YYARN )
778 CalculateModifiers( pInterpolation, YarnInd, YarnPosInfo, BottomMesh, YarnSectionModifiers );
779 else
780 CalculateModifiers( pInterpolation, YarnInd, YarnPosInfo, TopMesh, YarnSectionModifiers );
781
782 ModifySection( pYarnSections, YarnPosInfo, YarnSectionModifiers, dTargetArea, m_YYarnData[i].dHeight, j );
783
784 // Calculate adjustments for each of the mid node sections
785 for ( int k = 0; k < MID_SECTIONS; ++k )
786 {
787 YarnPosInfo.dSectionPosition = pYarnSections->GetMidNodeSectionPos( j, k );
788 if ( k < MID_SECTIONS/2 )
789 {
790 if ( Cell[0] == PATTERN_YYARN )
791 CalculateModifiers( pInterpolation, YarnInd, YarnPosInfo, BottomMesh, YarnSectionModifiers );
792 else
793 CalculateModifiers( pInterpolation, YarnInd, YarnPosInfo, TopMesh, YarnSectionModifiers );
794 }
795 else
796 {
797 const vector<PATTERN2D> &NextCell = GetCell(i,(j+1)%m_iNumXYarns);
798 if ( NextCell[0] == PATTERN_YYARN )
799 CalculateModifiers( pInterpolation, YarnInd, YarnPosInfo, BottomMesh, YarnSectionModifiers );
800 else
801 CalculateModifiers( pInterpolation, YarnInd, YarnPosInfo, TopMesh, YarnSectionModifiers );
802 }
803 ModifySection( pYarnSections, YarnPosInfo, YarnSectionModifiers, dTargetArea, m_YYarnData[i].dHeight, j, k );
804 }
805 }
806 // Make sure end matches start
807 pYarnSections->ReplaceSection(pYarnSections->GetNumNodeSections()-1, pYarnSections->GetNodeSection(0) );
808 m_Yarns[YarnInd].AssignSection( *pYarnSections );
809 delete pYarnSections;
810 }
811
812 // X yarns (parallel to x axis)
813 for ( j = 0; j < m_iNumXYarns; ++j )
814 {
815 // Get X yarn(j)
816 int YarnInd = m_XYarns[j][0];
817 pInterpolation = m_Yarns[YarnInd].GetInterpolation();
818 CYarnSectionInterpNode* pYarnSections = (CYarnSectionInterpNode*)m_Yarns[YarnInd].GetYarnSection()->Copy();
819
820 // Get area of original yarn section
821 CSectionEllipse Section(m_XYarnData[j].dWidth, m_XYarnData[j].dHeight);
822 double dTargetArea = Section.GetArea( Section.GetPoints(40) );
823
824 YarnSectionModifiers.clear();
825 for ( i = 0; i < m_iNumYYarns; ++i )
826 {
827 YARN_POSITION_INFORMATION YarnPosInfo;
828 YarnPosInfo.iSection = i;
829 YarnPosInfo.dSectionPosition = 0;
830 YarnPosInfo.SectionLengths = m_Yarns[YarnInd].GetYarnSectionLengths();
831 // For section at node (i,j)
832 const vector<PATTERN2D> &Cell = GetCell(i,j);
833 if ( Cell[0] == PATTERN_XYARN )
834 CalculateModifiers( pInterpolation, YarnInd, YarnPosInfo, BottomMesh, YarnSectionModifiers );
835 else
836 CalculateModifiers( pInterpolation, YarnInd, YarnPosInfo, TopMesh, YarnSectionModifiers );
837
838 ModifySection( pYarnSections, YarnPosInfo, YarnSectionModifiers, dTargetArea, m_XYarnData[j].dHeight, i);
839
840 // Calculate adjustments for each of the mid node sections
841 for ( int k = 0; k < MID_SECTIONS; ++k )
842 {
843 YarnPosInfo.dSectionPosition = pYarnSections->GetMidNodeSectionPos( i, k );
844 if ( k < MID_SECTIONS/2 )
845 {
846 if ( Cell[0] == PATTERN_XYARN )
847 CalculateModifiers( pInterpolation, YarnInd, YarnPosInfo, BottomMesh, YarnSectionModifiers );
848 else
849 CalculateModifiers( pInterpolation, YarnInd, YarnPosInfo, TopMesh, YarnSectionModifiers );
850 }
851 else
852 {
853 const vector<PATTERN2D> &NextCell = GetCell((i+1)%m_iNumYYarns,j);
854 if ( NextCell[0] == PATTERN_XYARN )
855 CalculateModifiers( pInterpolation, YarnInd, YarnPosInfo, BottomMesh, YarnSectionModifiers );
856 else
857 CalculateModifiers( pInterpolation, YarnInd, YarnPosInfo, TopMesh, YarnSectionModifiers );
858 }
859 ModifySection( pYarnSections, YarnPosInfo, YarnSectionModifiers, dTargetArea, m_XYarnData[j].dHeight, i, k );
860 }
861 }
862 // Make sure end matches start
863 pYarnSections->ReplaceSection(pYarnSections->GetNumNodeSections()-1, pYarnSections->GetNodeSection(0) );
864 m_Yarns[YarnInd].AssignSection( *pYarnSections );
865 delete pYarnSections;
866 }
867}
868
870{
871 pair<XYZ, XYZ> AABB = GetDomain()->GetMesh().GetAABB();
872 double sizex = AABB.second.x - AABB.first.x;
873 double sizey = AABB.second.y - AABB.first.y;
874 double minx = AABB.first.x - sizex;
875 double maxx = AABB.second + sizex;
876 double miny = AABB.first.y - sizey;
877 double maxy = AABB.second.y + sizey;
878
879 /*TopMesh.AddNode( XYZ(minx, miny, AABB.second.z) );
880 TopMesh.AddNode( XYZ(minx, maxy, AABB.second.z) );
881 TopMesh.AddNode( XYZ(maxx, maxy, AABB.second.z) );
882 TopMesh.AddNode( XYZ(maxx, miny, AABB.second.z) );
883
884 BottomMesh.AddNode( XYZ(minx, miny, AABB.first.z) );
885 BottomMesh.AddNode( XYZ(minx, maxy, AABB.first.z) );
886 BottomMesh.AddNode( XYZ(maxx, maxy, AABB.first.z) );
887 BottomMesh.AddNode( XYZ(maxx, miny, AABB.first.z) );*/
888
889 TopMesh.AddNode( XYZ(minx, miny, m_dFabricThickness) );
890 TopMesh.AddNode( XYZ(minx, maxy, m_dFabricThickness) );
891 TopMesh.AddNode( XYZ(maxx, maxy, m_dFabricThickness) );
892 TopMesh.AddNode( XYZ(maxx, miny, m_dFabricThickness) );
893
894 BottomMesh.AddNode( XYZ(minx, miny, 0.0) );
895 BottomMesh.AddNode( XYZ(minx, maxy, 0.0) );
896 BottomMesh.AddNode( XYZ(maxx, maxy, 0.0) );
897 BottomMesh.AddNode( XYZ(maxx, miny, 0.0) );
898
899 vector<int> Indices;
900 Indices.push_back(0);
901 Indices.push_back(1);
902 Indices.push_back(3);
903 TopMesh.AddElement(CMesh::TRI, Indices);
904 BottomMesh.AddElement(CMesh::TRI, Indices);
905 Indices.clear();
906 Indices.push_back(1);
907 Indices.push_back(2);
908 Indices.push_back(3);
909 TopMesh.AddElement(CMesh::TRI, Indices);
910 BottomMesh.AddElement(CMesh::TRI, Indices);
911}
912
913void CShearedTextileWeave2D::CalculateModifiers( const CInterpolation *pInterpolation, int Yarn, YARN_POSITION_INFORMATION YarnPosInfo, CMesh& Mesh, vector<double>& YarnSectionModifiers) const
914{
915 XYZ Up, Side;
916 CSlaveNode Node;
917 const CYarnSection* pYarnSection = m_Yarns[Yarn].GetYarnSection();
918 XYZ Centre;
919 //vector<double> Modifiers;
920
921 Node = pInterpolation->GetNode(m_Yarns[Yarn].GetMasterNodes(), YarnPosInfo.iSection, YarnPosInfo.dSectionPosition);
922 Up = Node.GetUp();
923 Side = CrossProduct(Node.GetTangent(), Up);
924 Centre = Node.GetPosition();
925
926 int numPoints = m_Yarns[Yarn].GetNumSectionPoints();
927 vector<XY> Points = pYarnSection->GetSection(YarnPosInfo, numPoints);
928 //Centre = m_Yarns[Yarn].GetMasterNodes()[i].GetPosition();
929 vector<XY>::iterator itPoint;
930 double angle = atan2( Points[0].y, Points[0].x );
931 int i = 0;
932
933 YarnSectionModifiers.clear();
934 for (itPoint = Points.begin(); itPoint != Points.end(); ++itPoint, ++i)
935 {
936 if ( i == 0 || i == numPoints/2 )
937 {
938 YarnSectionModifiers.push_back(1); // Don't modify points at max and min x values
939 continue;
940 }
941 XYZ P = itPoint->x * Side + itPoint->y * Up + Centre;
942 XY RefPoint2D = Get2DRefPoint( *itPoint, angle );
943 XYZ RefPoint = RefPoint2D.x * Side + RefPoint2D.y * Up + Centre;
944
945 vector<pair<double, XYZ> > Intersections;
946 if (Mesh.IntersectLine(RefPoint, P, Intersections, make_pair(true, false)))
947 {
948 double dU = Intersections[0].first;
949
950 if (dU < 0)
951 dU = 0;
952 YarnSectionModifiers.push_back(dU);
953 }
954 else
955 YarnSectionModifiers.push_back(1);
956 }
957 //YarnSectionModifiers.push_back(Modifiers);
958}
959
960XY CShearedTextileWeave2D::Get2DRefPoint( XY& Point, double dAngle ) const
961{
962 // Rotate original point
963 XY RotatedPoint = RotatePoint( Point, -dAngle );
964 // Create ref point
965 XY RotRefPoint(RotatedPoint.x, 0.0);
966 // Rotate back to angle of section
967 XY RefPoint = RotatePoint( RotRefPoint, dAngle );
968
969 return RefPoint;
970}
971
972void CShearedTextileWeave2D::ModifySection(CYarnSectionInterpNode* pYarnSection, YARN_POSITION_INFORMATION& YarnPosInfo, vector<double>& Modifiers, double dTargetArea, double dOriginalHeight, int iNodeIndex, int iMidIndex) const
973{
974 vector<XY> Points;
975 vector<XY>::iterator itPoints;
976
977 Points = pYarnSection->GetSection(YarnPosInfo, (int)Modifiers.size());
978 double dAngle = atan2( Points[0].y, Points[0].x );
979 for ( itPoints = Points.begin(); itPoints != Points.end(); ++itPoints )
980 {
981 *itPoints = RotatePoint( *itPoints, -dAngle );
982 }
983
984 // Modify any points which were outside top/bottom plane and get min/max y values
985 // Set up vector of max possible y values
986 double miny, maxy;
987 double dHeight = 0;
988 vector<XY> MaxHeight;
989 double maxdy = 0.0;
990 int k;
991 int iModCount = 0;
992 for ( itPoints = Points.begin(), k=0; itPoints != Points.end(); ++itPoints, ++k )
993 {
994 if ( Modifiers[k] < 1.0 )
995 {
996 itPoints->y = itPoints->y * Modifiers[k];
997 Modifiers[k] = 1.0;
998 ++iModCount;
999 }
1000 else if ( Modifiers[k] == 1.0 )
1001 {
1002 ++iModCount;
1003 }
1004
1005 if ( k == 0 )
1006 {
1007 miny = maxy = itPoints->y;
1008 }
1009 else
1010 {
1011 if ( itPoints->y < miny )
1012 miny = itPoints->y;
1013 if ( itPoints->y > maxy )
1014 maxy = itPoints->y;
1015 }
1016
1017 // Set up vector of maximum possible height points
1018 XY Point( itPoints->x, itPoints->y );
1019 Point.y = itPoints->y * Modifiers[k];
1020 MaxHeight.push_back( Point );
1021 if ( fabs(Point.y - itPoints->y) > maxdy )
1022 maxdy = fabs(Point.y - itPoints->y);
1023 }
1024
1025 double dArea = GetArea( MaxHeight );
1026 if ( dArea < dTargetArea )
1027 {
1028 // Max area available less than area of original section. Needs changing to check volume fraction
1029 TGERROR("Modify Section: all points increased to max value. Unable to achieve original section area");
1030 // Set section to max area section
1031 ReplaceSection( MaxHeight, pYarnSection, iNodeIndex, iMidIndex );
1032 return;
1033 }
1034
1035 dHeight = maxy - miny;
1036
1037 double dy = dOriginalHeight - dHeight;
1038 if ( dy > maxdy )
1039 dy = maxdy;
1040
1041 int iNumPoints = (int)Points.size();
1042 vector<XY> NewPoints;
1043
1044 int iCount = ModifyPoints( Points, Modifiers, MaxHeight, iModCount, dy, NewPoints );
1045
1046 dArea = GetArea( NewPoints );
1047 double mindy = 0.0;
1048 while ( fabs( dArea - dTargetArea ) > TOL )
1049 {
1050 if ( dArea > dTargetArea )
1051 {
1052 maxdy = dy;
1053 }
1054 else
1055 {
1056 if ( iCount == iNumPoints ) // All points increased to max value. Finish as can't increase area any more
1057 { // Add check to see if Vf ok
1058 TGERROR("Modify Section: all points increased to max value. Unable to achieve original section area");
1059 break;
1060 }
1061 mindy = dy;
1062 }
1063 dy = (maxdy + mindy)/2.0;
1064
1065 iCount = ModifyPoints( Points, Modifiers, MaxHeight, iModCount, dy, NewPoints );
1066
1067 dArea = GetArea( NewPoints );
1068 }
1069
1070 for ( itPoints = NewPoints.begin(); itPoints != NewPoints.end(); ++itPoints )
1071 {
1072 *itPoints = RotatePoint( *itPoints, dAngle);
1073 }
1074
1075 ReplaceSection( NewPoints, pYarnSection, iNodeIndex, iMidIndex );
1076}
1077
1078XY CShearedTextileWeave2D::RotatePoint( XY& Point, double dAngle ) const
1079{
1080 XY RotatedPoint;
1081 RotatedPoint.x = Point.x*cos(dAngle) - Point.y*sin(dAngle);
1082 RotatedPoint.y = Point.x*sin(dAngle) + Point.y*cos(dAngle);
1083 return RotatedPoint;
1084}
1085
1086double CShearedTextileWeave2D::GetArea( vector<XY>& Points ) const
1087{
1088 CSectionPolygon Section( Points );
1089 return Section.GetArea( Section.GetPoints(40) );
1090}
1091
1092void CShearedTextileWeave2D::ReplaceSection( vector<XY>& Points, CYarnSectionInterpNode* pYarnSection, int iNodeIndex, int iMidIndex ) const
1093{
1094 CSectionPolygon Section(Points);
1095 if (m_pSectionMesh)
1097 if ( iMidIndex == -1 )
1098 pYarnSection->ReplaceSection( iNodeIndex, Section );
1099 else
1100 pYarnSection->ReplaceMidSection( iNodeIndex, iMidIndex, Section );
1101}
1102
1103const vector<PATTERN2D> &CShearedTextileWeave2D::GetCellDir( int x, int y, int iDir ) const
1104{
1105 if ( iDir )
1106 return GetCell( y, x );
1107 return GetCell( x, y );
1108}
1109
1110int CShearedTextileWeave2D::ModifyPoints( vector<XY>& Points, vector<double>& Modifiers, vector<XY>& MaxHeight, int iModCount, double dy, vector<XY>& NewPoints ) const
1111{
1112 int iCount = iModCount;
1113 vector<XY>::iterator itPoints;
1114 int k;
1115
1116 NewPoints.clear();
1117 for ( itPoints = Points.begin(), k = 0; itPoints != Points.end(); ++itPoints, ++k )
1118 {
1119 XY Point( itPoints->x, itPoints->y );
1120 if ( Modifiers[k] > 1.0 )
1121 {
1122 if ( itPoints->y > 0.0 && (itPoints->y + dy) < MaxHeight[k].y )
1123 Point.y = itPoints->y + dy;
1124 else if ( itPoints->y < 0.0 && (itPoints->y - dy) > MaxHeight[k].y )
1125 Point.y = itPoints->y - dy;
1126 else
1127 {
1128 Point.y = MaxHeight[k].y;
1129 ++iCount;
1130 }
1131 }
1132 NewPoints.push_back( Point );
1133 }
1134 return iCount;
1135}
#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 TOL
#define MID_SECTIONS
const CMesh & GetMesh() const
Get the mesh representing the domain as a surface mesh.
Definition: Domain.h:73
Domain implementation described using planes, the simplest of which would be a box.
Definition: DomainPlanes.h:37
void AddPlane(const PLANE &Plane)
Bezier interpolation for yarn paths.
Cubic spline 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
bool AddElement(ELEMENT_TYPE Type, const vector< int > &Indices)
Add an element to the mesh of given type with node number checking.
Definition: Mesh.cpp:2565
void ConvertQuadstoTriangles(bool bQuality=true)
Convert the quad elements to triangles.
Definition: Mesh.cpp:1088
const int AddNode(XYZ Node)
Append a node to the list of nodes, the integer returns the index of the node
Definition: Mesh.cpp:2624
pair< XYZ, XYZ > GetAABB(double dGrowDistance=0) const
Get an axis aligned bounding box for the mesh.
Definition: Mesh.cpp:340
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
XYZ GetPosition() const
Definition: Node.h:57
XYZ GetTangent() const
Definition: Node.h:58
Elliptical Section.
void AssignSectionMesh(const CSectionMesh &SectionMesh)
Assign a mesh to the section.
Definition: Section.cpp:227
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
Creates a polygonal section, where a list of points are given to form the closed polygon.
Section which represents a rotation of another section angle given in radians.
CDomainPlanes GetDefaultDomain(bool bSheared=false, bool bAddedDomainHeight=true)
void PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType)
Used for saving data to XML.
double CalcSinAngle(double R, double Width, double Height) const
void ModifySection(CYarnSectionInterpNode *pYarnSection, YARN_POSITION_INFORMATION &YarnPosInfo, vector< double > &Modifiers, int iNodeIndex, int iMidIndex=-1) const
int ModifyPoints(vector< XY > &Points, vector< double > &Modifiers, vector< XY > &MaxHeight, int iModCount, double dy, vector< XY > &NewPoints) const
vector< XY > m_YSpacing
Vector containing the dx and dy components for spacings along y yarns.
void CalculateModifiers(const CInterpolation *pInterpolation, int Yarn, YARN_POSITION_INFORMATION YarnPosInfo, CMesh &Mesh, vector< vector< vector< double > > > &YarnSectionModifiers, bool bMaxCorrection) const
const vector< PATTERN2D > & GetCellDir(int x, int y, int iDir) const
Swap x and y in GetCell call if transverse yarn is x yarn.
double GetArea(vector< XY > &Points) const
XY Get2DRefPoint(XY &Point, double dAngle) const
void CreateTopAndBottomMeshes(CMesh &TopMesh, CMesh &BottomMesh) const
Create meshes for top and bottom surfaces of domain.
void ReplaceSection(vector< XY > &Points, CYarnSectionInterpNode *pYarnSection, int iNodeIndex, int iMidIndex) const
bool BuildTextile() const
Build the textile.
CShearedTextileWeave2D(int iWidth, int iHeight, double dSpacing, double dThickness, double ShearAngle, bool bRefine=true, bool bInPlaneTangents=true)
Build a 2d weave unit cell of given width, height, yarn spacing and fabric thickness.
XY RotatePoint(XY &Point, double dAngle) const
void GetYSpacings() const
Get the x and y components of spacings along y yarns.
XY GetYRepeat() const
Sums all y components of spacings to get y repeat.
A derivation of the CNode class which contains data specific to slave nodes such as sections.
Definition: SlaveNode.h:30
const CDomain * GetDomain() const
Definition: Textile.h:287
vector< CYarn > m_Yarns
Vector of yarns contained within this cell.
Definition: Textile.h:323
bool ConvertToInterpNodes() const
Definition: Textile.cpp:1201
string GetName() const
Get the name associated with this textile.
Definition: Textile.cpp:355
int AddYarn(const CYarn &Yarn)
Add a Yarn to the textile.
Definition: Textile.cpp:122
Respresents a 2d woven textile.
void SetInPlaneTangents(bool bInPlaneTangents=true) const
Function to set interpolation so that in-plane tangents are forced at master nodes.
void PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType)
Used for saving data to XML.
virtual void CorrectInterference() const
Adjust cross section shapes to correct interference.
bool Valid() const
Check that the weave pattern contained in m_Pattern is valid.
CObjectContainer< CSectionMesh > m_pSectionMesh
Definition: TextileWeave.h:221
const vector< PATTERN2D > & GetCell(int x, int y) const
vector< vector< int > > m_XYarns
Definition: TextileWeave.h:225
vector< vector< int > > m_YYarns
Definition: TextileWeave.h:226
vector< YARNDATA > m_XYarnData
Definition: TextileWeave.h:223
double GetWidth() const
Get the width of the unit cell.
vector< YARNDATA > m_YYarnData
Definition: TextileWeave.h:224
Class used to meaure the amount of time it takes to perform a certain task.
Definition: Timer.h:12
void stop(const char *msg=0)
Stop the timer and print an optional message.
Definition: Timer.h:86
void check(const char *msg=0)
Definition: Timer.h:96
void start(const char *msg=0)
Definition: Timer.h:57
Represents a yarn consisting of master nodes, section and interpolation function.
Definition: Yarn.h:49
const CNode * GetNode(int iIndex) const
Get a master node by index.
Definition: Yarn.cpp:299
void AssignSection(const CYarnSection &YarnSection)
Assign a section to the yarn.
Definition: Yarn.cpp:649
const CYarnSection * GetYarnSection() const
Definition: Yarn.h:449
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 ReplaceMidSection(int iNodeIndex, int iIndex, const CSection &Section)
Replace a mid node section.
double GetMidNodeSectionPos(int iNodeIndex, int iIndex) const
void ReplaceSection(int iIndex, const CSection &Section)
Replace 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.
int GetNumMidNodeSections(int iIndex) const
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
double Max(XYZ &Vector)
Get maximum element of vector and return it.
Definition: mymath.h:642
XY Convert(const XYZ &Val)
Definition: mymath.h:144
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
Struct for representing a Plane.
Definition: Plane.h:25
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
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