25#define START_DIST -1.0e+6
27CTextileLayered::CTextileLayered()
45 Indices.push_back(valueify<int>(pYarn->Attribute(
"yarnindex")));
51 m_LayerOffset.push_back(valueify<XY>(pOffset->Attribute(
"value")));
63 TiXmlElement Layer(
"Layer");
67 TiXmlElement Yarn(
"Yarn");
69 Layer.InsertEndChild(Yarn);
71 Element.InsertEndChild(Layer);
73 vector<XY>::iterator itXY;
76 TiXmlElement Offset(
"Offset");
77 Offset.SetAttribute(
"value",
stringify(*itXY));
78 Element.InsertEndChild(Offset);
84 if ( Textile.
GetType() ==
"CTextileLayered" )
88 vector< vector<int> >::const_iterator itYarnIndices;
92 for( itYarnIndices = YarnIndices.begin(), i = 0; itYarnIndices != YarnIndices.end(); ++itYarnIndices, ++i )
94 vector<int>::const_iterator itIndex;
96 for ( itIndex = itYarnIndices->begin(); itIndex != itYarnIndices->end(); ++itIndex )
99 Yarns.push_back( *pYarn );
101 XY LayerOffset(Offsets[i].x, Offsets[i].y);
108 vector<CYarn> &Yarns = Textile.
GetYarns();
116 vector<CYarn>::iterator itYarn;
117 vector<int> YarnIndices;
118 XY LayerOffset(Offset.
x, Offset.
y);
121 for ( itYarn = Yarns.begin(); itYarn != Yarns.end(); ++itYarn )
123 CYarn Yarn = *itYarn;
127 YarnIndices.push_back( index );
140 if ( Offsets.size() != size )
142 TGERROR(
"Can't assign offsets: number of offsets does not match number of layers");
153 vector<XY> MoveOffset;
155 for (
int i = 0; i < size; ++i )
168 if ( Offsets.size() != size )
170 TGERROR(
"Can't assign offsets: number of offsets does not match number of layers");
181 vector<XY> TotalOffset;
183 for (
int i = 0; i < size; ++i )
189 m_LayerOffset.assign( TotalOffset.begin(), TotalOffset.end() );
199 for(
int i = 0; i < size; ++i )
201 Offsets.push_back( SumOffset );
211 if ( Offsets.size() != iNumLayers )
213 TGERROR(
"Can't apply offsets: number of offsets does not match number of layers");
216 for (
int i = 0; i < iNumLayers; ++i )
218 vector<int>::iterator itIndices;
219 XYZ Offset( Offsets[i].x, Offsets[i].y, 0 );
229 vector<int>::iterator itIndices;
247 TGERROR(
"Cannot nest layers: no domain specified" );
251 vector<CMesh> LayerMeshes;
259 vector<CMesh>::iterator itMeshes;
260 for ( itMeshes = LayerMeshes.begin(); itMeshes != LayerMeshes.end(); ++itMeshes )
262 string str =
"LayerMeshes" +
stringify(i++);
263 itMeshes->SaveToVTK(str.c_str() );
267 pair<XYZ,XYZ> AABB =
m_pDomain->GetMesh().GetAABB();
268 double XInc = (AABB.second.x - AABB.first.x) / iNumX;
269 double YInc = (AABB.second.y - AABB.first.y) / iNumY;
271 vector< vector<pair<double,double> > > LayerIntersections;
272 LayerIntersections.resize((iNumX+1) * (iNumY+1));
273 XY Pos(AABB.first.x, AABB.first.y);
274 double Height =
GetLength(
XYZ(Pos.
x, Pos.
y, AABB.first.z),
XYZ(Pos.
x, Pos.
y, AABB.second.z) );
277 for (
int j = 0; j <= iNumY; ++j )
279 for (
int i = 0; i <= iNumX; ++i )
281 vector<CMesh>::iterator itMeshes;
282 XYZ P1(Pos.
x,Pos.
y,AABB.first.z);
283 XYZ P2(Pos.
x,Pos.
y,AABB.second.z);
284 for ( itMeshes = LayerMeshes.begin(); itMeshes != LayerMeshes.end(); ++itMeshes )
286 vector<pair<double,XYZ> > IntersectionPoints;
287 int iNum = itMeshes->IntersectLine(P1, P2, IntersectionPoints, make_pair(
true,
true));
290 pair<double,double> Intersects;
291 Intersects.first = IntersectionPoints[0].first * Height;
292 Intersects.second = IntersectionPoints[iNum-1].first * Height;
293 LayerIntersections[j*(iNumX+1)+i].push_back(Intersects);
303 Pos.
x = AABB.first.x;
306 vector<double> MinDist(iNumLayers-1,
START_DIST);
309 for (
int j = 0; j < LayerIntersections.size(); ++j )
311 for (
int i = 0; i < LayerIntersections[j].size()-1; ++i )
313 if ( LayerIntersections[j][i].first > 0.0 && LayerIntersections[j][i+1].second > 0.0 )
315 double dist = LayerIntersections[j][i+1].first - LayerIntersections[j][i].second;
321 if ( MinDist[i] ==
START_DIST || dist < MinDist[i] )
331 for (
int i = 1; i < iNumLayers; ++i )
333 Offset.
z -= MinDist[i-1];
340 XYZ RefPlane(0,0,-1);
341 int index = DomainPlanes->
GetPlane( RefPlane, Plane );
343 DomainPlanes->
SetPlane( index, Plane );
351 TGERROR(
"Cannot nest layers: no domain specified" );
355 vector<CMesh> LayerMeshes;
362 vector<CMesh>::iterator itMeshes;
363 for ( itMeshes = LayerMeshes.begin(); itMeshes != LayerMeshes.end(); ++itMeshes )
365 string str =
"LayerMeshes" +
stringify(i++);
366 itMeshes->SaveToVTK(str.c_str() );
370 pair<XYZ,XYZ> AABB =
m_pDomain->GetMesh().GetAABB();
377 Offsets.push_back( Offset );
380 vector<pair<int,double> > MinDist(iNumLayers-1,make_pair(-1,
START_DIST));
383 for (
int iLayer = 0; iLayer < LayerMeshes.size()-1; ++iLayer )
386 double X1 = Repeats[iLayer].x;
387 double X2 = Repeats[iLayer+1].x;
388 double Y1 = Repeats[iLayer].y;
389 double Y2 = Repeats[iLayer+1].y;
393 int fact = (int)(iGridRes/((AABB.second.x - AABB.first.x)/gcd));
394 double XInc = gcd/fact;
397 fact = (int)(iGridRes/((AABB.second.y - AABB.first.y)/gcd));
398 double YInc = gcd/fact;
400 iNumX = (AABB.second.x - AABB.first.x)/XInc;
401 iNumY = (AABB.second.y - AABB.first.y)/YInc;
404 vector< vector<pair<double,double> > > LayerIntersections;
405 LayerIntersections.resize((iNumX+1) * (iNumY+1));
406 XY Pos(AABB.first.x, AABB.first.y);
407 double Height =
GetLength(
XYZ(Pos.
x, Pos.
y, AABB.first.z),
XYZ(Pos.
x, Pos.
y, AABB.second.z) );
409 for (
int j = 0; j <= iNumY; ++j )
411 for (
int i = 0; i <= iNumX; ++i )
413 vector<CMesh>::iterator itMeshes;
414 XYZ P1(Pos.
x,Pos.
y,AABB.first.z);
415 XYZ P2(Pos.
x,Pos.
y,AABB.second.z);
417 for (
int k = 0; k < 2; ++k )
419 vector<pair<double,XYZ> > IntersectionPoints;
420 int iNum = LayerMeshes[iLayer+k].IntersectLine(P1, P2, IntersectionPoints, make_pair(
true,
true));
423 pair<double,double> Intersects;
424 Intersects.first = IntersectionPoints[0].first * Height;
425 Intersects.second = IntersectionPoints[iNum-1].first * Height;
426 LayerIntersections[j*(iNumX+1)+i].push_back(Intersects);
436 Pos.
x = AABB.first.x;
440 int XSize = (int)(min(Repeats[iLayer].x, Repeats[iLayer+1].x)/XInc);
441 int YSize = (int)(min(Repeats[iLayer].y, Repeats[iLayer+1].y)/YInc);
442 bool bOffsetTop = Repeats[iLayer].x < Repeats[iLayer+1].x ? true :
false;
445 for (
int j = 0; j < (int)YSize; ++j )
447 for (
int i = 0; i < (int)XSize; ++i )
449 GetOffsetMinDist(i, j, iLayer, LayerIntersections, MinDist, iNumX+1, iNumY+1, XSize, YSize, bOffsetTop);
453 int X = MinDist[iLayer].first % (iNumX+1);
454 int Y = (MinDist[iLayer].first - X) / (iNumX+1);
461 Offset.
x += X * XInc;
462 Offset.
y += Y * YInc;
463 Offsets.push_back( Offset );
470 for (
int i = 1; i < iNumLayers; ++i )
472 TGLOG(
"Mindist = " << MinDist[i-1].second );
473 ZOffset.
z -= MinDist[i-1].second;
479 XYZ RefPlane(0,0,-1);
480 int index = DomainPlanes->
GetPlane( RefPlane, Plane );
481 Plane.
d -= ZOffset.
z;
482 DomainPlanes->
SetPlane( index, Plane );
488 vector<double> OffsetMinDist(MinDist.size(),
START_DIST);
490 int incX = iOffset % iNumX;
491 int incY = (iOffset - incX) / iNumX;
492 for (
int j = 0; j < iNumY; ++j )
494 for (
int i = 0; i < iNumX; ++i )
496 int iInd = j*iNumX+i;
497 int iOffsetInd = ((j+incY)%iNumY)*iNumX + ((i+incX)%iNumX);
498 for (
int LayerInd = 0; LayerInd < LayerIntersections[iInd].size()-1; ++LayerInd )
500 if ( LayerIntersections[iInd][LayerInd].second > 0.0 && LayerIntersections[iOffsetInd][LayerInd+1].first > 0.0 )
502 double dist = LayerIntersections[iOffsetInd][LayerInd+1].first - LayerIntersections[iInd][LayerInd].second;
503 if ( OffsetMinDist[LayerInd] ==
START_DIST || dist < OffsetMinDist[LayerInd] )
505 OffsetMinDist[LayerInd] = dist;
513 for (
int index = 0; index < MinDist.size(); ++index )
515 if ( MinDist[index].second ==
START_DIST || OffsetMinDist[index] > MinDist[index].second )
517 MinDist[index].second = OffsetMinDist[index];
518 MinDist[index].first = iOffset;
523void CTextileLayered::GetOffsetMinDist(
int x,
int y,
int iLayer, vector< vector<pair<double,double> > >& LayerIntersections, vector<pair<int,double> >& MinDist,
int iNumX,
int iNumY,
int XSize,
int YSize,
bool bOffsetTop)
548 for (
int j = 0; j < iNumY; ++j )
550 for (
int i = 0; i < iNumX; ++i )
552 int iTopInd, iBottomInd;
555 iBottomInd = j*iNumX+i;
556 iTopInd = ((j+y)%iNumY)*iNumX + ((i+x)%iNumX);
561 iBottomInd = ((j+y)%iNumY)*iNumX + ((i+x)%iNumX);
564 if ( LayerIntersections[iBottomInd][0].second > 0.0 && LayerIntersections[iTopInd][1].first > 0.0 )
566 double dist = LayerIntersections[iTopInd][1].first - LayerIntersections[iBottomInd][0].second;
567 if ( OffsetMinDist ==
START_DIST || dist < OffsetMinDist )
569 OffsetMinDist = dist;
578 if ( MinDist[iLayer].second ==
START_DIST || OffsetMinDist > MinDist[iLayer].second )
580 MinDist[iLayer].second = OffsetMinDist;
581 MinDist[iLayer].first = y*iNumX + x;
588 int iNumSlaveNodes = 0;
591 vector<int>::iterator itIndices;
597 if ( Num > iNumSlaveNodes )
599 iNumSlaveNodes = Num;
604 LayerMeshes.push_back( Mesh );
606 return iNumSlaveNodes;
615 vector<XYZ> YarnRepeats;
616 vector<XYZ>::iterator itYarnRepeats;
618 for ( itYarnRepeats = YarnRepeats.begin(); itYarnRepeats != YarnRepeats.end(); ++itYarnRepeats )
620 if ( itYarnRepeats->x > Repeat.
x )
622 Repeat.
x = itYarnRepeats->x;
624 if ( itYarnRepeats->y > Repeat.
y )
626 Repeat.
y = itYarnRepeats->y;
629 Repeats.push_back( Repeat );
635 int iX1 = (int)(X1 * 1e+6);
636 int iX2 = (int)(X2 * 1e+6);
651 return( (
double)(iX1/1e+6) );
#define TGERROR(MESSAGE)
Macros used to report the file name and line number to the TexGenError and TexGenLog functions.
#define FOR_EACH_TIXMLELEMENT(CHILDELEMENT, PARENTELEMENT, ELEMENTNAME)
Macro to enable looping over tinyxml easier.
Domain implementation described using planes, the simplest of which would be a box.
void SetPlane(int index, PLANE &Plane)
Set plane at given index.
int GetPlane(XYZ &Normal, PLANE &Plane)
Get plane with given normal. Returns both the plane and its index.
Defines the nodes and elements of a surface or volume mesh.
void ConvertQuadstoTriangles(bool bQuality=true)
Convert the quad elements to triangles.
Represents a textile cell containing yarns.
virtual string GetType() const
Derived class should return the class name.
virtual void PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType)
Used for saving data to XML.
int AddYarn(const CYarn &Yarn)
Add a Yarn to the textile.
const vector< CYarn > & GetYarns() const
bool m_bNeedsBuilding
Variable which keeps track of wether the textile needs building or not.
CObjectContainer< CDomain > m_pDomain
const CYarn * GetYarn(int iIndex) const
Represents a textile made up from several layers of weaves.
virtual void PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType)
Used for saving data to XML.
CTextileLayered()
Build a weave unit cell of given width, height, yarn spacing and fabric thickness.
void ApplyOffsets(vector< XY > &Offsets)
const vector< XY > & GetOffsets() const
void GetLayerRepeats(vector< XY > &Repeats)
void ApplyLayerOffset(XYZ &Offset, int iLayer)
void AddLayer(CTextile &Textile, XYZ &Offset)
Adds the layers from the textile passed, maintaining the existing offset of each layer.
string GetDefaultName() const
Get the default name to assign to a textile.
int GetLayerMeshes(vector< CMesh > &LayerMeshes)
const vector< vector< int > > GetLayerYarnIndices()
void SetOffsets(vector< XY > &Offsets)
Sets an xy offset for each layer.
void GetOffsetMinDist(int iOffset, vector< vector< pair< double, double > > > &LayerIntersections, vector< pair< int, double > > &MinDist, int iNumX, int iNumY)
vector< XY > m_LayerOffset
double GreatestCommonDenominator(double X1, double X2)
vector< vector< int > > m_LayerYarnIndices
virtual ~CTextileLayered(void)
void SetRelativeOffsets(vector< XY > &Offsets)
Sets an xy offset for the layer, relative to the existing offset.
Represents a yarn consisting of master nodes, section and interpolation function.
bool AddSurfaceToMesh(CMesh &Mesh, bool bAddEndCaps=true) const
Create surface mesh for this yarn and add it to the surface mesh object.
int GetNumSlaveNodes() const
Get number of slave nodes.
const vector< XYZ > & GetRepeats() const
void Translate(XYZ Vector)
Translate the Yarn by given vector.
Namespace containing a series of customised math operations not found in the standard c++ library.
double GetLength(const XYZ &Point1, const XYZ &Point2)
Get the length between two points.
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.
Struct for representing a Plane.
Struct for representing points in 2D space.
Struct for representing points in 3D space.