32, m_iNumSectionPoints(0)
33, m_iNeedsBuilding(ALL)
34, m_bEquiSpacedSectionMesh(true)
47, m_iNumSectionPoints(0)
48, m_iNeedsBuilding(ALL)
49, m_bEquiSpacedSectionMesh(true)
55 TiXmlElement* pInterpolation = Element.FirstChildElement(
"Interpolation");
60 TiXmlElement* pYarnSection = Element.FirstChildElement(
"YarnSection");
65 TiXmlElement* pFibreDistribution = Element.FirstChildElement(
"FibreDistribution");
66 if (pFibreDistribution)
69 const string* pType = pFibreDistribution->Attribute(
string(
"type"));
72 if (*pType ==
"CFibreDistribution1DQuad")
74 else if (*pType ==
"CFibreDistributionConst")
80 m_Repeats.push_back(valueify<XYZ>(pRepeat->Attribute(
"value")));
90 m_AABB.first = valueify<XYZ>(Element.Attribute(
"AABB.first"));
91 m_AABB.second = valueify<XYZ>(Element.Attribute(
"AABB.second"));
95 valueify<XYZ>(pSectionAABB->Attribute(
"first")),
96 valueify<XYZ>(pSectionAABB->Attribute(
"second"))));
100 m_SectionLengths.push_back(valueify<double>(pSectionLength->Attribute(
"value")));
114 TiXmlElement Interpolation(
"Interpolation");
116 Element.InsertEndChild(Interpolation);
120 TiXmlElement YarnSection(
"YarnSection");
122 Element.InsertEndChild(YarnSection);
126 TiXmlElement FibreDistribution(
"FibreDistribution");
128 Element.InsertEndChild(FibreDistribution);
130 vector<XYZ>::iterator itXYZ;
133 TiXmlElement Repeat(
"Repeat");
134 Repeat.SetAttribute(
"value",
stringify(*itXYZ));
135 Element.InsertEndChild(Repeat);
140 TiXmlElement MasterNode(
"MasterNode");
141 MasterNode.SetAttribute(
"index", i);
142 m_MasterNodes[i].PopulateTiXmlElement(MasterNode, OutputType);
143 Element.InsertEndChild(MasterNode);
147 vector<CSlaveNode>::iterator itSlaveNode;
150 TiXmlElement SlaveNode(
"SlaveNode");
151 itSlaveNode->PopulateTiXmlElement(SlaveNode, OutputType);
152 Element.InsertEndChild(SlaveNode);
158 TiXmlElement SectionAABB(
"SectionAABB");
159 SectionAABB.SetAttribute(
"index", i);
162 Element.InsertEndChild(SectionAABB);
166 TiXmlElement SectionLength(
"SectionLength");
167 SectionLength.SetAttribute(
"index", i);
169 Element.InsertEndChild(SectionLength);
175 Element.SetAttribute(
"NeedsBuilding",
ALL);
199 vector<CNode>::iterator itNode;
202 if ( itNode->GetPosition() == NodePos )
204 TGERROR(
"Trying to add duplicate node: node at " << Node.
GetPosition() <<
" not added" );
215 vector<CNode>::iterator itNode;
219 if (&(*itNode) == pBefore)
232 TGERROR(
"Unable to insert node, given node is not contained within the yarn");
240 TGERROR(
"Unable to insert node, index invalid: " << iIndex);
243 vector<CNode>::iterator itNode;
253 delete pInterpNodeSection;
266 vector<CNode>::iterator itNode;
270 if ( itNode->GetPosition() == NodePos && i != iIndex )
272 TGERROR(
"Trying to replace duplicate node: node at " << NodePos <<
" not added" );
325 TGLOGINDENT(
"Calculating slave node resolution given " << iNumSectionPoints <<
" section points");
326 double dNodeDistance;
330 int i, iMaxIterations = 100;
331 for (i=0; i<iMaxIterations; ++i)
338 TGERROR(
"Unable to calculate slave node resolution");
342 vector<CSlaveNode>::iterator itSlaveNode;
348 if (dNodeDistance == 0)
350 TGERROR(
"Unable to calculate slave node resolution");
355 dNodeDistance /=
m_SlaveNodes.size() * iNumSectionPoints;
358 dNumNodes = (dYarnLength / dNodeDistance)+1;
360 iNumNodes = (int)dNumNodes;
361 if (dNumNodes-iNumNodes > 0.5)
371 TGERROR(
"Unable to calculate slave node resolution");
409 TGLOG(
"Building yarn slave nodes");
412 TGERROR(
"Unable to build slave nodes, not enough master nodes specified");
418 TGERROR(
"Unable to build slave nodes, no interpolation function specified");
458 TGLOG(
"Building yarn sections");
461 TGERROR(
"Unable to build sections, no slave nodes created");
470 TGERROR(
"Unable to build sections, no yarn section specified");
485 vector<XYZ>::const_iterator itPoint;
486 vector<CSlaveNode>::iterator itSlaveNode;
498 YarnPositionInfo.
iSection = itSlaveNode->GetIndex();
501 itSlaveNode->UpdateSectionPoints(&Section);
503 PrevPos = itSlaveNode->GetPosition();
505 for (itPoint = itSlaveNode->GetSectionPoints().begin(); itPoint != itSlaveNode->GetSectionPoints().end(); ++itPoint)
555 vector<XYZ>::const_iterator itPoint;
556 vector<CSlaveNode>::iterator itSlaveNode;
568 iIndex = itSlaveNode->GetIndex();
578 for (j=iSlaveNodeMin; j<=iSlaveNodeMax; ++j)
580 for (itPoint =
m_SlaveNodes[j].GetSectionPoints().begin(); itPoint !=
m_SlaveNodes[j].GetSectionPoints().end(); ++itPoint)
596 TGLOG(
"Building yarn section meshes");
599 TGERROR(
"Unable to build section meshes, no slave nodes created");
605 TGERROR(
"Unable to build section meshes, no yarn section specified");
620 vector<CSlaveNode>::iterator itSlaveNode;
626 YarnPositionInfo.
iSection = itSlaveNode->GetIndex();
631 itSlaveNode->UpdateSectionMesh(&Mesh);
633 PrevPos = itSlaveNode->GetPosition();
665 vector<CNode>::iterator itNode;
668 itNode->Rotate(Rotation, Origin);
670 vector<XYZ>::iterator itRepeat;
673 *itRepeat = Rotation * (*itRepeat);
686 vector<CNode>::iterator itNode;
689 itNode->Translate(Vector);
713 vector<CSlaveNode>::iterator itNode;
714 vector<XYZ>::const_iterator itSectionPoint;
718 const vector<XYZ> NodeSectionPoints = itNode->GetSectionPoints();
720 for (itSectionPoint = NodeSectionPoints.begin(); itSectionPoint != NodeSectionPoints.end(); ++itSectionPoint)
722 if (itNode ==
m_SlaveNodes.begin() && itSectionPoint == NodeSectionPoints.begin())
723 Min =
Max = *itSectionPoint;
759 Indices.push_back(0);
760 Indices.push_back(1);
761 Indices.push_back(2);
762 Indices.push_back(3);
763 Indices.push_back(4);
764 Indices.push_back(5);
765 Indices.push_back(6);
766 Indices.push_back(7);
779 if (
m_Repeats.size() != RepeatLimits.size())
781 TGERROR(
"Unable to create repeated AABB mesh, number of repeats (" <<
m_Repeats.size() <<
") doesn't match the number of limits (" << RepeatLimits.size() <<
")");
791 vector<XYZ>::const_iterator itRepeat;
792 vector<pair<int, int> >::const_iterator itLimits;
793 for (itRepeat =
m_Repeats.begin(), itLimits = RepeatLimits.begin(); itRepeat !=
m_Repeats.end() && itLimits != RepeatLimits.end(); ++itRepeat, ++itLimits)
805 vector<CNode>::const_iterator itNode;
808 Mesh.
AddNode(itNode->GetPosition());
818 vector<CSlaveNode>::iterator itSlaveNode;
821 Mesh.
AddNode(itSlaveNode->GetPosition());
826 Indices.push_back(iStartIndex);
827 Indices.push_back(iEndIndex);
862 TGLOG(
"Adding yarn surface to mesh");
870 vector<CSlaveNode>::iterator itNode;
873 if (iNumPoints == -1)
875 iNumPoints = (int)itNode->GetSectionPoints().size();
877 else if (iNumPoints != (
int)itNode->GetSectionPoints().size())
880 TGERROR(
"Unable to create surface mesh, number of section points is not the same for all slave nodes");
887 vector<XYZ>::const_iterator itSectionPoint;
891 for (itSectionPoint = itNode->GetSectionPoints().begin(); itSectionPoint != itNode->GetSectionPoints().end(); ++itSectionPoint)
899 for (i=0; i<iNumNodes-1; ++i)
901 for (j=0; j<iNumPoints; ++j)
905 u = i; v = j;
if (v == iNumPoints) v = 0; Indices.push_back(iFirstNode+v+u*iNumPoints);
906 u = i+1; v = j;
if (v == iNumPoints) v = 0; Indices.push_back(iFirstNode+v+u*iNumPoints);
907 u = i+1; v = j+1;
if (v == iNumPoints) v = 0; Indices.push_back(iFirstNode+v+u*iNumPoints);
908 u = i; v = j+1;
if (v == iNumPoints) v = 0; Indices.push_back(iFirstNode+v+u*iNumPoints);
930 CMesh StartMesh, EndMesh;
949 if (
m_Repeats.size() != RepeatLimits.size())
951 TGERROR(
"Unable to create repeated surface mesh, number of repeats (" <<
m_Repeats.size() <<
") doesn't match the number of limits (" << RepeatLimits.size() <<
")");
961 vector<XYZ>::const_iterator itRepeat;
962 vector<pair<int, int> >::const_iterator itLimits;
963 for (itRepeat =
m_Repeats.begin(), itLimits = RepeatLimits.begin(); itRepeat !=
m_Repeats.end() && itLimits != RepeatLimits.end(); ++itRepeat, ++itLimits)
965 YarnMesh.
CopySelfToRange(*itRepeat, itLimits->first, itLimits->second);
978 CMesh SingleYarnMesh, FinalYarnMesh;
983 vector<XYZ>::const_iterator itTranslation;
984 for (itTranslation = Translations.begin(); itTranslation != Translations.end(); ++itTranslation)
986 FinalYarnMesh.
InsertMesh(SingleYarnMesh, *itTranslation);
1012 TGLOG(
"Adding yarn volume to mesh");
1019 CMesh ReferenceMesh;
1021 vector<CSlaveNode>::iterator itNode;
1026 ReferenceMesh = itNode->GetSectionMesh();
1032 bool bCompatible = ReferenceMesh.
GetNumNodes() == itNode->GetSectionMesh().GetNumNodes();
1039 bCompatible =
false;
1044 TGERROR(
"Unable to create volume mesh, not all section meshes are compatible");
1052 list<int>::const_iterator itIndex;
1053 int iPrevIndex = -1;
1059 const CMesh &SectionMesh = itNode->GetSectionMesh();
1062 for ( itIndex = PolygonIndices.begin(); itIndex != PolygonIndices.end(); ++itIndex )
1067 if (iPrevIndex != -1)
1070 for (itIndex = TriIndices.begin(); itIndex != TriIndices.end(); )
1072 aiTriangles[0] = *(itIndex++);
1073 aiTriangles[1] = *(itIndex++);
1074 aiTriangles[2] = *(itIndex++);
1086 for (itIndex = QuadIndices.begin(); itIndex != QuadIndices.end(); )
1088 aiQuads[0] = *(itIndex++);
1089 aiQuads[1] = *(itIndex++);
1090 aiQuads[2] = *(itIndex++);
1091 aiQuads[3] = *(itIndex++);
1105 iPrevIndex = iIndex;
1112 if (
m_Repeats.size() != RepeatLimits.size())
1114 TGERROR(
"Unable to create repeated volume mesh, number of repeats (" <<
m_Repeats.size() <<
") doesn't match the number of limits (" << RepeatLimits.size() <<
")");
1124 vector<XYZ>::const_iterator itRepeat;
1125 vector<pair<int, int> >::const_iterator itLimits;
1126 for (itRepeat =
m_Repeats.begin(), itLimits = RepeatLimits.begin(); itRepeat !=
m_Repeats.end() && itLimits != RepeatLimits.end(); ++itRepeat, ++itLimits)
1128 YarnMesh.
CopySelfToRange(*itRepeat, itLimits->first, itLimits->second);
1140 CMesh SingleYarnMesh, FinalYarnMesh;
1145 vector<XYZ>::const_iterator itTranslation;
1146 for (itTranslation = Translations.begin(); itTranslation != Translations.end(); ++itTranslation)
1148 FinalYarnMesh.
InsertMesh(SingleYarnMesh, *itTranslation);
1161 TGLOG(
"Adding centre plane to mesh");
1169 vector<CSlaveNode>::iterator itSlaveNode;
1170 vector<XY> Points2D;
1178 vector<XY> StartEnd;
1179 double xSpacing, ySpacing;
1182 YarnPositionInfo.
iSection = itSlaveNode->GetIndex();
1188 xSpacing = (StartEnd[1].x - StartEnd[0].x)/(iNumPoints-1);
1189 ySpacing = (StartEnd[1].y - StartEnd[0].y)/(iNumPoints-1);
1191 for (
int i = 0; i < iNumPoints; ++i )
1193 XY Point(StartEnd[0].x + i*xSpacing, StartEnd[0].y + i*ySpacing);
1194 XYZ Point3D = itSlaveNode->GetPointOnSection(Point);
1202 list<int>::const_iterator itIndex;
1204 int iIndex = 0, iSlaveIndex = 0;
1206 for (iSlaveIndex = 0; iSlaveIndex <
m_SlaveNodes.size()-1; ++iSlaveIndex)
1209 for (
int i = 0; i < iNumPoints-1; ++i )
1235 CMesh SingleYarnMesh, FinalYarnMesh;
1240 vector<XYZ>::const_iterator itTranslation;
1241 for (itTranslation = Translations.begin(); itTranslation != Translations.end(); ++itTranslation)
1243 FinalYarnMesh.
InsertMesh(SingleYarnMesh, *itTranslation);
1274 XYZ YarnVec = End - Origin;
1275 const double dTolerance = 1e-6;
1276 if (
GetLength(YarnVec, Repeat) < dTolerance)
1278 if (
GetLength(YarnVec, -Repeat) < dTolerance)
1285 vector<CNode>::iterator itNode;
1288 itNode->SetTangent(
XYZ());
1289 itNode->SetUp(
XYZ());
1295 TGLOG(
"Straightening yarn " << dStraightness);
1298 XYZ DeltaPos1, DeltaPos2, Pos;
1317 dAngle = acos(dAngle);
1323 dAngle = dAngle * dStraightness;
1324 Rotation =
WXYZ(Axis, dAngle);
1345 bool bSectionConstant =
m_pYarnSection->GetType() ==
"CYarnSectionConstant";
1346 if ( pOrientation && !bSectionConstant )
1361 bool bIsInside =
false;
1364 XYZ Relative, Up, Side;
1367 for (i=0; i<iNumSegments; ++i)
1419 if (pVolumeFraction)
1424 if (dFibreArea == 0)
1429 double CosAng = cos( N.
GetAngle() );
1430 vector<XY>::iterator itSectionPoints;
1431 for ( itSectionPoints = SectionPoints.begin(); itSectionPoints != SectionPoints.end(); ++itSectionPoints )
1433 XY Point = *itSectionPoints;
1434 Point.
x = Point.
x * CosAng;
1435 *itSectionPoints = Point;
1443 *pVolumeFraction = -1;
1446 if (pDistanceToSurface)
1450 if ( dClosestEdgeDistance < dTolerance )
1451 *pDistanceToSurface = dClosestEdgeDistance;
1457 if ( bSectionConstant && N.
GetAngle() == 0.0 )
1476 u1 = u > 0.1 ? u-0.1 : 0;
1491 u2 = u < 0.99 ? u+0.1 : 1;
1508 vector<int> ElementIndices1;
1509 vector<int> ElementIndices2;
1512 for (
int j = 0; j < iNumNodes; ++j )
1514 Ori += End2Mesh.
GetNode( ElementIndices2[Index] ) - End1Mesh.
GetNode( ElementIndices1[Index] );
1519 *pOrientation = Ori;
1520 assert( fabs(Ori.
x) > 1e-14 || fabs(Ori.
y) > 1e-14 || fabs(Ori.
z) > 1e-14 );
1537bool CYarn::PointInsideYarn(
const XYZ &Point,
const vector<XYZ> &Translations,
XYZ *pTangent,
XY* pLoc,
double *pVolumeFraction,
double* pDistanceToSurface,
double dTolerance,
XYZ *pOrientation,
XYZ *pUp,
bool bSurface)
const
1540 vector<XYZ>::const_iterator itXYZ;
1541 for (itXYZ = Translations.begin(); itXYZ != Translations.end(); ++itXYZ)
1543 if (
PointInsideYarn(Point - *itXYZ, pTangent, pLoc, pVolumeFraction, pDistanceToSurface, dTolerance, pOrientation, pUp, bSurface))
1551 const double dConvergenceTolerance = 1e-6;
1554 PLANE Plane1, Plane2, SearchPlane;
1555 double d1, d2, d, dprev;
1571 if (d1 >= -dConvergenceTolerance && d2 >= -dConvergenceTolerance)
1577 else if ( d2 == 0.0 )
1585 dprev = d1 < d2 ? d1 : d2;
1587 SearchPlane = Plane1;
1588 int iIterations = 0;
1589 while(abs(du) > dConvergenceTolerance)
1598 du = d * (du/(dprev-d));
1599 if ( du > (1-u + dConvergenceTolerance) )
1600 du = 1 - u + dConvergenceTolerance;
1601 else if ( du < (-u - dConvergenceTolerance) )
1602 du = -u - dConvergenceTolerance;
1607 if ( iIterations > 100 )
1609 TGLOG(
"Exceeded number of iterations. PointInsideYarn failed");
1633 bool bFound =
false;
1635 XYZ Relative, Up, Side;
1640 double minDist = -1.0;
1641 for (i=0; i<iNumSegments; ++i)
1650 Section =
m_pYarnSection->GetSection(YarnPositionInfo, iNumSectionPoints);
1654 dist =
GetLength( SectionPoints[index], Point);
1655 if ( dist < minDist || minDist == -1 )
1658 SurfacePoint = SectionPoints[index];
1668 vector<XYZ>::const_iterator itXYZ;
1669 double minDist = -1, dist = -1.0;
1671 for (itXYZ = Translations.begin(); itXYZ != Translations.end(); ++itXYZ)
1674 if ( fabs(dist + 1.0) > 1e-9 )
1676 if ( dist < minDist || minDist == -1 )
1680 SurfacePoint = SPoint;
1684 if ( minDist == -1 )
1709 TGERROR(
"Unable to get yarn section length, invalid index: " << iIndex);
1718 return vector<double>();
1726 TGERROR(
"Yarns must contain 2 repeat vectors in order to calculate yarn length per unit area");
1736 return pair<XYZ, XYZ>(
XYZ(),
XYZ());
1743 return pair<XYZ, XYZ>(
XYZ(),
XYZ());
1745 return pair<XYZ, XYZ>(
XYZ(),
XYZ());
1767 if (dRepeatArea == 0)
1786 if (dRepeatArea == 0)
1800 if ( dFibreArea != 0 )
1802 double dVolume = dLength * dFibreArea;
1809 if (dYarnLinearDensity == 0)
1810 dYarnLinearDensity =
m_pParent->GetYarnLinearDensity();
1811 if ( dYarnLinearDensity == 0 )
1813 TGERROR(
"There is no yarn linear density specified" );
1816 double dMass = dYarnLinearDensity*dLength;
1819 if (dFibreDensity == 0)
1820 dFibreDensity =
m_pParent->GetFibreDensity();
1821 if (dFibreDensity == 0)
1823 TGERROR(
"There is no fibre density specified" );
1826 double dVolume = dMass/dFibreDensity;
1835 if (dRepeatArea == 0)
1840 if (dYarnLinearDensity == 0)
1841 dYarnLinearDensity =
m_pParent->GetYarnLinearDensity();
1842 if ( dYarnLinearDensity == 0 )
1844 TGERROR(
"There is no yarn linear density specified" );
1847 double dMassPerUnitArea = dYarnLinearDensity*dLengthPerUnitArea;
1850 if (dFibreDensity == 0)
1851 dFibreDensity =
m_pParent->GetFibreDensity();
1852 if (dFibreDensity == 0)
1854 TGERROR(
"There is no fibre density specified" );
1857 double dVolPerUnitArea = dMassPerUnitArea/dFibreDensity;
1881 list<int>::iterator itIndex;
1884 for ( itIndex = TriIndices.begin(), Index = 0; itIndex != TriIndices.end(); Index += 3 )
1887 for (
int j = 0; j < 3; j++ )
1889 Nodes.push_back( Mesh.
GetNode( *itIndex++ ));
1899 for ( itIndex = QuadIndices.begin(), Index = 0; itIndex != QuadIndices.end(); Index += 4 )
1902 for (
int j = 0; j < 4; j++ )
1904 Nodes.push_back( Mesh.
GetNode( *itIndex++ ));
1916 vector<XY>::const_iterator itP1, itP2;
1917 XY Edge, EdgeNormal;
1918 double dEdgeDistance;
1919 double dClosestEdgeDistance = 1.0;
1922 itP1 = itP2 = SectionPoints.begin();
1924 while (itP1 != SectionPoints.end())
1926 Edge = *itP2 - *itP1;
1929 EdgeNormal.
x = Edge.
y;
1930 EdgeNormal.
y = -Edge.
x;
1933 dEdgeDistance =
DotProduct(EdgeNormal, Loc - *itP1);
1940 if ( dEdgeDistance < dTolerance )
1944 dClosestEdgeDistance = dEdgeDistance;
1948 dClosestEdgeDistance = max(dClosestEdgeDistance, dEdgeDistance);
1953 if (itP2 == SectionPoints.end())
1954 itP2 = SectionPoints.begin();
1956 return dClosestEdgeDistance;
1963 if ( str ==
"CYarnSectionInterpNode" )
1965 if (str !=
"CYarnSectionConstant")
1977 delete pYarnSection;
#define TGLOGINDENT(MESSAGE)
Combines the TGLOG macro and TGLOGAUTOINDENT macro in one.
#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.
Abstract base class representing the domain in which a textile cell may lie.
virtual void ClipMeshToDomain(CMesh &Mesh, bool bFillGaps=true) const =0
Clip the surface elements to the domain.
vector< XYZ > GetTranslations(const CYarn &Yarn) const
Get the translation vectors necessary to fully fill the domain.
Fibre volume fraction is defined as a quadratic equation varying only along the X axis.
Fibre volume fraction is constant throughout the yarn.
Abstract base class that defines how the fibres are distributed within a yarn.
Bezier interpolation for yarn paths.
Abstract base class for describing the yarn path interpolations.
static CObjectContainer< CInterpolation > CreateInterpolation(TiXmlElement &Element)
Create an interpolation from TiXmlElement.
Defines the nodes and elements of a surface or volume mesh.
bool AddElement(ELEMENT_TYPE Type, const vector< int > &Indices)
Add an element to the mesh of given type with node number checking.
int GetNumNodes() const
Return the number of nodes.
int MergeNodes(const double Tolerance=1e-8)
If any nodes share the same coordinates merge the nodes together and adjust indices accordingly.
void InsertMesh(const CMesh &Mesh, XYZ Offset=XYZ(0, 0, 0))
Add the contents of Mesh to this mesh.
const int AddNode(XYZ Node)
Append a node to the list of nodes, the integer returns the index of the node
const XYZ & GetNode(int iIndex) const
Get the node with given ID.
static int GetNumNodes(ELEMENT_TYPE Type)
Get the number of nodes a particular element type contains.
const list< int > & GetIndices(ELEMENT_TYPE ElemType) const
Get the element indices of a given element type.
void RemoveOpposingTriangles()
Remove triangles that have the same indices but opposite normals.
ELEMENT_TYPE
Each element type is represented by a unique integer value.
void CopySelfToRange(XYZ Vector, int iLowerLimit, int iUpperLimit)
Copy the mesh to the range given by the lower limit and upper limit with the given repeat vector.
void FlipNormals()
Flip the normals of the mesh for triangles and quads.
void ConvertElementListToVector(ELEMENT_TYPE ElementType, vector< int > &Indices)
Convert element index list to vector so can access by index.
double CalculateVolume() const
Calculate the volume of the mesh.
void Rotate(WXYZ Rotation, XYZ Origin=XYZ(0, 0, 0))
Rotate the whole mesh by given quaternion.
int InsertNodes(const CMesh &Mesh, XYZ Offset=XYZ(0, 0, 0))
Add the nodes of Mesh to this mesh.
Represents a point on the centreline of a yarn.
XYZ GetSide() const
Get the side vector.
double GetYarnLinearDensity(string Units="kg/m") const
double GetFibreArea(string Units="m^2") const
Get the area occupied by fibres given fibre diameter and number of fibres.
double GetFibreDensity(string Units="kg/m^3") const
Class to store properties related to a textile.
void PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType)
Used for saving data to XML.
Abstract base class respresenting a yarn cross-section.
static double GetCircumference(const vector< XY > &Section)
Get the circumference of a section.
static CMesh GetTriangleMesh(const vector< XY > &Section)
A derivation of the CNode class which contains data specific to slave nodes such as sections.
const CMesh & GetSectionMesh() const
void UpdateSectionMesh(const CMesh *p2DSectionMesh=NULL)
Populate m_SectionMesh from m_2DSectionMesh, Setting m_2DSectionMesh at the same time.
const vector< XY > & Get2DSectionPoints() const
const vector< XYZ > & GetSectionPoints() const
void UpdateSectionPoints(const vector< XY > *p2DSectionPoints=NULL)
Populate m_SectionPoints from m_2DSectionPoints, Setting m_2DSectionPoints at the same time.
Represents a textile cell containing yarns.
bool AddSurfaceToMesh(CMesh &Mesh, bool bAddEndCaps=true) const
Create surface mesh for this yarn and add it to the surface mesh object.
double GetRawYarnSectionLength(int iIndex) const
Get the length of a yarn section (building the yarn if necessary)
bool DeleteNode(int iIndex)
Delete an existing node.
bool m_bEquiSpacedSectionMesh
Whether or not volume meshes of the yarn should be equispaced.
bool BuildSlaveNodes() const
vector< XYZ > m_Repeats
List of infinite repeat vectors, yarns will be repeated to infinite displaced by the specified vector...
CWeakPointer< const CTextile > m_pParent
Stores a pointer to the CTextile it belongs to.
void PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType)
Used for saving data to XML.
const CNode * GetNode(int iIndex) const
Get a master node by index.
pair< XYZ, XYZ > GetAABB() const
Get axis aligned bounding box for the yarn (building the yarn if necessary)
bool BuildSectionMeshes() const
void AddRepeat(XYZ Repeat)
Add a repeat vector.
void AssignInterpolation(const CInterpolation &Interpolation)
Assign an interpolation function to the yarn.
bool RepeatMatchesEnds(XYZ Repeat) const
Check if the repeat vector is the same as the last master node - first master node.
void SetRepeats(const vector< XYZ > &Repeats)
Set the repeat vectors.
bool FindPlaneContainingPoint(const XYZ &Point, double &u, double dTolerance, int iSeg) const
Find the plane normal to the yarn which contains a specified point.
vector< CNode > m_MasterNodes
Ordered list of nodes belonging to this Yarn.
int m_iNumSlaveNodes
Number of slave nodes to create.
void AssignSection(const CYarnSection &YarnSection)
Assign a section to the yarn.
const vector< CSlaveNode > & GetSlaveNodes(BUILD_TYPE Usage) const
Get the slave nodes and build them if necessary.
int m_iNeedsBuilding
Variable used to keep track of wether the yarn needs to be rebuilt or not and what part needs rebuild...
CObjectContainer< CInterpolation > m_pInterpolation
Interpolation applied to smooth the yarn paths.
bool ConvertToInterpNodes()
vector< double > m_SectionLengths
The length of each of the sections in the yarn.
double FindClosestSurfacePoint(const XYZ &Point, XYZ &SurfacePoint, int iNumSectionPoints, double dTolerance=1e-9)
Finds the closest point on the yarn surface to Point.
bool ReplaceNode(int iIndex, CNode NewNode)
Replace an existing node with given node.
void ClearMasterNodeOrientations()
Set the tangents and up vectors of all the master nodes to null.
double GetRawRepeatArea() const
Get repeat area.
CObjectContainer< CYarnSection > m_pYarnSection
Section applied to this yarn, with possibility of a varying cross-section.
bool BuildYarnIfNeeded(int iBuildType) const
Create slave nodes and apply yarn section to them.
bool BuildSections() const
void SetEquiSpacedSectionMesh(bool bEquiSpacedSectionMesh)
Meshes of the yarn should be equispaced if true.
vector< pair< XYZ, XYZ > > m_SectionAABBs
An axis aligned bounding box containing each section of the yarn.
void AddNode(const CNode &Node)
Add a node to the end of the list of nodes (note the nodes must be ordered)
double GetRawYarnVolume() const
Get the volume of the yarn (building the yarn if necessary)
double GetYarnLengthPerUnitArea(string Units="/m") const
Calculate the total yarn length per unit area.
const CYarnSection * GetYarnSection() const
CObjectContainer< CFibreDistribution > m_pFibreDistribution
Fibre distribution given to the yarn, used for getting Fibre Volume Fraction.
void ClearRepeats()
Remove all repeat vectors.
pair< XYZ, XYZ > m_AABB
An axis aligned bounding box containing the full unrepeated yarn.
void SetParent(const CTextile *pParent)
Set the yarn parent.
bool AddNodesToMesh(CMesh &Mesh) const
Add the master nodes to the mesh.
CMesh::ELEMENT_TYPE GetMeshPoint(CMesh &Mesh, const XY &Point, int &Index) const
void AddEndCapsToMesh(CMesh &Mesh) const
Add end caps to the mesh.
void CreateSectionAABBs() const
Create the section Axis aligned bounding boxes.
double GetYarnVolumePerUnitArea(string Units="m") const
Calculate the total yarn volume per unit area.
void StraightenYarn(double dStraightness=1)
Straighten the yarn.
void SetResolution(int iNumSlaveNodes, int iNumSectionPoints)
Set the resolution of the mesh created.
bool AddVolumeToMesh(CMesh &Mesh) const
Create volume mesh for this yarn and add it to the volume mesh object.
double FindClosestEdgeDistance(XY &Loc, const vector< XY > &SectionPoints, double dTolerance) const
Find closest perpendicular distance from point to polygon specified by SectionPoints.
bool InsertNode(const CNode &Node, const CNode *pBefore)
Insert a node before node pBefore.
vector< double > GetYarnSectionLengths() const
Get the lengths of all the yarn sections.
double GetRealYarnLength(string Units="m") const
Calculate the total yarn length.
vector< CSlaveNode > m_SlaveNodes
Ordered list of interpolated slave nodes belonging to this Yarn.
double GetRawYarnLength() const
Get the length of the yarn (building the yarn if necessary)
double GetRealYarnVolume(string Units="m^3") const
Calculate the yarn volume.
double GetFibreVolumePerUnitArea(string Units="m") const
int m_iNumSectionPoints
Number of section points to create.
void AssignFibreDistribution(const CFibreDistribution &Distribution)
Assign a fibre distribution.
void Rotate(WXYZ Rotation, XYZ Origin=XYZ(0, 0, 0))
Rotate the Yarn by given quaternion.
bool PointInsideYarn(const XYZ &Point, XYZ *pTangent=NULL, XY *pLoc=NULL, double *pVolumeFraction=NULL, double *pDistanceToSurface=NULL, double dTolerance=1e-9, XYZ *pOrientation=NULL, XYZ *pUp=NULL, bool bSurface=false) const
Determine if the given point lies within the yarn (this function doesn't take the repeats into accoun...
bool AddPathToMesh(CMesh &Mesh) const
Add yarn centerline path to mesh.
bool AddCentrePlaneToMesh(CMesh &Mesh) const
Create mesh of the centre plane for this yarn and add it to the plane mesh object.
void Translate(XYZ Vector)
Translate the Yarn by given vector.
double GetFibreVolume(string Units="m^3") const
double GetFibreYarnVolumeFraction() const
void SetNodes(const vector< CNode > &Nodes)
Set the nodes for this yarn given as an ordered list of nodes.
bool AddAABBToMesh(CMesh &Mesh) const
Add the axis aligned bounding box of the yarn to the Mesh.
pair< XYZ, XYZ > GetSectionAABB(int iIndex) const
Get axis aligned bounding box for a yarn section (building the yarn if necessary)
Creates a section which is constant all along the yarn.
vector< XY > GetSection(const YARN_POSITION_INFORMATION PositionInfo, int iNumPoints, bool bEquiSpaced=false) const
This function must be implemented by derived classes.
Abstract base class used to define the sections along the length of a yarn.
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.
static CObjectContainer< CYarnSection > CreateYarnSection(TiXmlElement &Element)
Create a yarn section from TiXmlElement.
Creates a section which is linearly interpolated between sections defined at the nodes.
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.
void DeleteSection(int iIndex)
Delete a section at a node.
Namespace containing a series of customised math operations not found in the standard c++ library.
void GetMinMaxXY(const std::vector< XY > &Points, XY &Min, XY &Max)
bool PointInside(const XY &Point, const std::vector< XY > &Nodes)
int GetClosestPointIndex(const std::vector< XY > &Points, const XY Position)
double Max(XYZ &Vector)
Get maximum element of vector and return it.
bool PointInsideBox(const XYZ &Point, const XYZ &BoxMin, const XYZ &BoxMax, double dTolerance=0)
Find if a point is inside an Axis Aligned Bounding Box with given tolerance.
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.
XYZ Min(const XYZ &P1, const XYZ &P2)
Given two points, return a new point who's coordinates are the smaller of the two.
WXYZ & Normalise(WXYZ &Quaternion)
Normalise the quaternion and return it.
double DotProduct(const XYZ &left, const XYZ &right)
Get the dot product of two vectors.
XYZ CrossProduct(const XYZ &left, const XYZ &right)
Get the cross product of two vectors.
double ConvertUnits(double dValue, std::string SourceUnits, std::string TargetUnits)
Struct for representing a Plane.
Struct for representing a quaternion.
Struct for representing points in 2D space.
Struct for representing points in 3D space.
Structure used to represent the position along the length of a yarn.
double dSectionPosition
This variables varies linearly with distance from 0 to 1 from the start to the end of the current lin...
int iSection
This variable represents the index of the current section (where a section is defined as the part bet...
vector< double > SectionLengths
This contains a list of lengths representing the length of each section.