29CTextile::CTextile(
void)
30: m_bNeedsBuilding(true)
35: m_Yarns(Yarns.size())
37 copy(Yarns.begin(), Yarns.end(),
m_Yarns.begin());
57 vector<CYarn>::iterator itYarn;
60 itYarn->SetParent(
this);
68 TiXmlElement* pDomain = Element.FirstChildElement(
"Domain");
71 const string* pType = pDomain->Attribute(
string(
"type"));
74 if (*pType ==
"CDomainPlanes")
76 else if (*pType ==
"CDomainPrism")
91 Element.SetAttribute(
"type",
GetType());
95 TiXmlElement Domain(
"Domain");
96 m_pDomain->PopulateTiXmlElement(Domain, OutputType);
97 Element.InsertEndChild(Domain);
105 Element.SetAttribute(
"NeedsBuilding", 0);
108 for (i=0; i<(int)
m_Yarns.size(); ++i)
110 TiXmlElement Yarn(
"Yarn");
111 Yarn.SetAttribute(
"index", i);
112 m_Yarns[i].PopulateTiXmlElement(Yarn, OutputType);
113 Element.InsertEndChild(Yarn);
118 Element.SetAttribute(
"NeedsBuilding", 1);
129 vector<CYarn>::iterator itYarn;
132 itYarn->SetParent(
this);
144 vector<CYarn>::iterator itYarn;
147 itYarn->SetParent(
this);
154 if (iIndex < 0 || iIndex >= (
int)
m_Yarns.size())
169 vector<CYarn>::iterator itYarn;
172 itYarn->AddNodesToMesh(Mesh);
180 vector<CYarn>::iterator itYarn;
183 itYarn->AddPathToMesh(Mesh);
191 vector<CYarn>::iterator itYarn;
195 itYarn->AddSurfaceToMesh(Mesh, *
m_pDomain);
197 itYarn->AddSurfaceToMesh(Mesh);
207 TGERROR(
"Textile has no domain assigned");
212 if (
m_pDomain->GetType() !=
"CDomainPrism")
220 m_pDomain->GetPrismDomain()->GetMeshWithPolygonEnd( DomainMesh );
223 list<int>::const_iterator itIter;
233 for (itIter = Indices.begin(); itIter != Indices.end(); )
238 for (
int j = 0; j < iNumNodes; ++j )
244 DomainMeshes.push_back(FaceMesh);
250 for (itIter = Indices.begin(); itIter != Indices.end(); )
252 StartIndex = *itIter;
262 }
while (*itIter != StartIndex);
268 DomainMeshes.push_back(FaceMesh);
273 vector<CYarn>::iterator itYarn;
278 if ( !itYarn->AddSurfaceToMesh(Mesh, *
m_pDomain, DomainMeshes ) )
282 itYarn->AddSurfaceToMesh(Mesh);
291 vector<CYarn>::iterator itYarn;
295 itYarn->AddVolumeToMesh(Mesh, *
m_pDomain);
297 itYarn->AddVolumeToMesh(Mesh);
308 vector<CYarn>::iterator itYarn;
310 for (itYarn =
m_Yarns.begin(), i = 0; itYarn !=
m_Yarns.end(); ++itYarn, ++i)
313 itYarn->AddVolumeToMesh(Mesh[i], *
m_pDomain);
315 itYarn->AddVolumeToMesh(Mesh[i]);
323 vector<CYarn>::iterator itYarn;
327 itYarn->AddCentrePlaneToMesh(Mesh, *
m_pDomain);
329 itYarn->AddCentrePlaneToMesh(Mesh);
337 vector<CYarn>::iterator itYarn;
340 itYarn->Rotate(Rotation, Origin);
348 vector<CYarn>::iterator itYarn;
351 itYarn->Translate(Vector);
357 return TEXGEN.GetName(
this);
419 PointsInfo.resize(Points.size());
420 vector<XYZ>::const_iterator itPoint;
421 std::vector<XY>::iterator itLoc;
422 vector<POINT_INFO>::iterator itInfo;
426 for (itPoint = Points.begin(); itPoint != Points.end(); ++itPoint)
428 if (itPoint == Points.begin())
441 vector<CYarn>::iterator itYarn;
443 for (itYarn =
m_Yarns.begin(), iIndex=0; itYarn !=
m_Yarns.end(); ++itYarn, ++iIndex)
446 for (itPoint = Points.begin(), itInfo = PointsInfo.begin(); itPoint != Points.end(); ++itPoint, ++itInfo)
448 if (itYarn->PointInsideYarn(*itPoint, Translations, &Info.
YarnTangent,
455 if (itInfo->iYarnIndex == -1 || Info.
dSurfaceDistance < itInfo->dSurfaceDistance)
474 PointsInfo.resize(Points.size());
475 vector<XYZ>::const_iterator itPoint;
476 std::vector<XY>::iterator itLoc;
477 vector<POINT_INFO>::iterator itInfo;
481 for (itPoint = Points.begin(); itPoint != Points.end(); ++itPoint)
483 if (itPoint == Points.begin())
496 vector<CYarn>::iterator itYarn;
499 for (itPoint = Points.begin(), itInfo = PointsInfo.begin(); itPoint != Points.end(); ++itPoint, ++itInfo)
508 if (itInfo->iYarnIndex == -1 )
523 vector<POINT_INFO> PointsInfo;
533 vector<POINT_INFO>::const_iterator itPointInfo;
534 for (itPointInfo = PointsInfo.begin(); itPointInfo != PointsInfo.end(); ++itPointInfo)
536 YarnIndex.
m_Data.push_back(itPointInfo->iYarnIndex);
537 YarnTangent.
m_Data.push_back(itPointInfo->YarnTangent);
538 Location.
m_Data.push_back(itPointInfo->Location);
539 VolumeFraction.
m_Data.push_back(itPointInfo->dVolumeFraction);
540 SurfaceDistance.
m_Data.push_back(itPointInfo->dSurfaceDistance);
541 Orientation.
m_Data.push_back(itPointInfo->Orientation);
544 vector<CMeshDataBase*> MeshData;
546 MeshData.push_back(&YarnIndex);
547 MeshData.push_back(&YarnTangent);
548 MeshData.push_back(&Location);
549 MeshData.push_back(&VolumeFraction);
550 MeshData.push_back(&SurfaceDistance);
551 MeshData.push_back(&Orientation);
562 vector<CYarn>::const_iterator itYarn;
563 vector<CNode>::const_iterator itNode;
566 const vector<CNode> &Nodes = itYarn->GetMasterNodes();
567 for (itNode = Nodes.begin(); itNode != Nodes.end(); ++itNode)
569 Pos = itNode->GetPosition();
584 TGERROR(
"Cannot trim interference points to domain - no domain specified" );
588 if (pInterferingPoints)
589 pInterferingPoints->
Clear();
591 TGLOGINDENT(
"Detecting interference between yarns in textile \"" <<
GetName() <<
"\"");
592 int iIntersections = 0;
593 vector<CYarn>::iterator itYarn;
594 vector<CYarn>::iterator itYarnCompare;
595 vector<CSlaveNode>::const_iterator itSlaveNode;
596 vector<XYZ>::const_iterator itPoint;
597 pair<XYZ, XYZ> AABB1, AABB2;
601 double pVolumeFraction, pDistanceToSurface;
604 for (itYarn =
m_Yarns.begin(), iIndex = 0; itYarn !=
m_Yarns.end(); ++itYarn, ++iIndex)
606 for (itYarnCompare =
m_Yarns.begin(); itYarnCompare !=
m_Yarns.end(); ++itYarnCompare)
608 if (itYarn == itYarnCompare)
612 CMesh YarnMesh, CompareMesh;
614 itYarn->AddSurfaceToMesh(YarnMesh,
m_pDomain);
616 itYarnCompare->AddSurfaceToMesh( CompareMesh,
m_pDomain );
621 AABB1 = itYarn->GetAABB();
622 AABB2 = itYarnCompare->GetAABB();
627 vector<XYZ> YarnTranslations;
628 vector<XYZ> CompareTranslations;
631 YarnTranslations =
m_pDomain->GetTranslations(*itYarn);
632 CompareTranslations =
m_pDomain->GetTranslations(*itYarnCompare);
636 XYZ Translation(0,0,0);
637 YarnTranslations.push_back(Translation);
638 CompareTranslations.push_back(Translation);
641 const vector<CSlaveNode> &SlaveNodes = itYarn->GetSlaveNodes(
CYarn::SURFACE);
642 for (itSlaveNode = SlaveNodes.begin(); itSlaveNode != SlaveNodes.end(); ++itSlaveNode)
644 for (itPoint = itSlaveNode->GetSectionPoints().begin(); itPoint != itSlaveNode->GetSectionPoints().end(); ++itPoint)
646 vector<XYZ>::const_iterator itXYZ;
647 for( itXYZ = YarnTranslations.begin(); itXYZ != YarnTranslations.end(); ++itXYZ )
649 if ( !bTrimToDomain ||
m_pDomain->PointInDomain( *itPoint + *itXYZ ) )
651 if (itYarnCompare->PointInsideYarn(*itPoint + *itXYZ, CompareTranslations, &pTangent, &pLoc, &pVolumeFraction, &pDistanceToSurface))
653 if (pInterferingPoints)
654 pInterferingPoints->
AddNode(*itPoint + *itXYZ);
655 DistanceToSurface.push_back( (
float)pDistanceToSurface );
656 YarnIndices.push_back( iIndex );
666 TGLOG(
"Found " << iIntersections <<
" intersections between yarns in textile \"" <<
GetName() <<
"\"");
667 return iIntersections;
685 if (iIndex < 0 || iIndex >= (
int)
m_Yarns.size())
687 TGERROR(
"Unable to get yarn, invalid index: " << iIndex);
696 if (iIndex < 0 || iIndex >= (
int)
m_Yarns.size())
698 TGERROR(
"Unable to get yarn, invalid index: " << iIndex);
739 double dYarnLength = 0;
740 for (i=0; i<(int)
m_Yarns.size(); ++i)
742 dYarnLength +=
m_Yarns[i].GetRealYarnLength(Units);
752 double dYarnLength = 0;
753 for (i=0; i<(int)
m_Yarns.size(); ++i)
758 if (
m_Yarns[i].GetRawRepeatArea() == 0)
760 dYarnLength +=
m_Yarns[i].GetYarnLengthPerUnitArea(Units);
771 for (i=0; i<(int)
m_Yarns.size(); ++i)
773 dVolume +=
m_Yarns[i].GetRealYarnVolume(Units);
783 double dVolPerUnitArea = 0;
784 for (i=0; i<(int)
m_Yarns.size(); ++i)
789 if (
m_Yarns[i].GetRawRepeatArea() == 0)
791 dVolPerUnitArea +=
m_Yarns[i].GetYarnVolumePerUnitArea(Units);
793 return dVolPerUnitArea;
802 for (i=0; i<(int)
m_Yarns.size(); ++i)
804 dVolume +=
m_Yarns[i].GetFibreVolume(Units);
823 double dVolPerUnitArea = 0;
824 for (i=0; i<(int)
m_Yarns.size(); ++i)
829 if (
m_Yarns[i].GetRawRepeatArea() == 0)
831 dVolPerUnitArea +=
m_Yarns[i].GetFibreVolumePerUnitArea(Units);
833 return dVolPerUnitArea;
843 if (dYarnVolumePerUnitArea)
952 vector<CYarn>::iterator itYarn;
954 for ( itYarn =
m_Yarns.begin(); itYarn !=
m_Yarns.end(); ++itYarn )
956 itYarn->SetYoungsModulusX( dValue, Units );
964 vector<CYarn>::iterator itYarn;
966 for ( itYarn =
m_Yarns.begin(); itYarn !=
m_Yarns.end(); ++itYarn )
968 itYarn->SetYoungsModulusY( dValue, Units );
976 vector<CYarn>::iterator itYarn;
978 for ( itYarn =
m_Yarns.begin(); itYarn !=
m_Yarns.end(); ++itYarn )
980 itYarn->SetYoungsModulusZ( dValue, Units );
988 vector<CYarn>::iterator itYarn;
990 for ( itYarn =
m_Yarns.begin(); itYarn !=
m_Yarns.end(); ++itYarn )
992 itYarn->SetShearModulusXY( dValue, Units );
1000 vector<CYarn>::iterator itYarn;
1002 for ( itYarn =
m_Yarns.begin(); itYarn !=
m_Yarns.end(); ++itYarn )
1004 itYarn->SetShearModulusXZ( dValue, Units );
1012 vector<CYarn>::iterator itYarn;
1014 for ( itYarn =
m_Yarns.begin(); itYarn !=
m_Yarns.end(); ++itYarn )
1016 itYarn->SetShearModulusYZ( dValue, Units );
1024 vector<CYarn>::iterator itYarn;
1026 for ( itYarn =
m_Yarns.begin(); itYarn !=
m_Yarns.end(); ++itYarn )
1028 itYarn->SetAlphaX( dValue, Units );
1036 vector<CYarn>::iterator itYarn;
1038 for ( itYarn =
m_Yarns.begin(); itYarn !=
m_Yarns.end(); ++itYarn )
1040 itYarn->SetAlphaY( dValue, Units );
1048 vector<CYarn>::iterator itYarn;
1050 for ( itYarn =
m_Yarns.begin(); itYarn !=
m_Yarns.end(); ++itYarn )
1052 itYarn->SetAlphaZ( dValue, Units );
1060 vector<CYarn>::iterator itYarn;
1062 for ( itYarn =
m_Yarns.begin(); itYarn !=
m_Yarns.end(); ++itYarn )
1064 itYarn->SetPoissonsRatioX( dValue );
1072 vector<CYarn>::iterator itYarn;
1074 for ( itYarn =
m_Yarns.begin(); itYarn !=
m_Yarns.end(); ++itYarn )
1076 itYarn->SetPoissonsRatioY( dValue );
1084 vector<CYarn>::iterator itYarn;
1086 for ( itYarn =
m_Yarns.begin(); itYarn !=
m_Yarns.end(); ++itYarn )
1088 itYarn->SetPoissonsRatioZ( dValue );
1096 TGERROR(
"Cannot calculate volume fraction. No domain specified");
1103 vector<CYarn>::iterator itYarn;
1104 double FibreVolume = 0.0;
1108 for ( itYarn =
m_Yarns.begin(); itYarn !=
m_Yarns.end(); ++itYarn, ++i )
1111 double YarnVolume, YarnFibreVf;
1113 itYarn->AddSurfaceToMesh( Mesh,
m_pDomain );
1116 YarnFibreVf = itYarn->GetFibreYarnVolumeFraction();
1117 if ( YarnFibreVf <
TOL )
1119 stringstream Message;
1120 Message <<
"No fibre data specified for yarn " << i <<
". Using Vf = 1.0\n";
1124 FibreVolume += YarnFibreVf * YarnVolume;
1127 return FibreVolume/
m_pDomain->GetVolume();
1134 TGERROR(
"Cannot calculate volume fraction. No domain specified");
1141 vector<CYarn>::iterator itYarn;
1142 double FibreVolume = 0.0;
1145 for ( itYarn =
m_Yarns.begin(); itYarn !=
m_Yarns.end(); ++itYarn, ++i )
1149 vector<XYZ> Centres;
1150 vector<XYZ>::iterator itCentres;
1154 const XYZ *p1, *p2, *p3, *p4;
1155 bool bDefaultVf =
false;
1158 itYarn->AddVolumeToMesh( Mesh, *
m_pDomain );
1161 vector<XYZ> Translations =
m_pDomain->GetTranslations(*itYarn);
1164 list<int>::iterator itTetInd;
1166 YarnFibreVf = itYarn->GetFibreYarnVolumeFraction();
1167 if ( YarnFibreVf <
TOL )
1169 stringstream Message;
1170 Message <<
"No fibre data specified for yarn " << i <<
". Using Vf = 1.0\n";
1177 for ( itCentres = Centres.begin(), itTetInd = TetIndices.begin(); itCentres != Centres.end(); ++itCentres )
1179 XYZ Centre = *itCentres;
1182 itYarn->PointInsideYarn( *itCentres, Translations, &Tangent, &Loc, &YarnFibreVf );
1194 FibreVolume += YarnFibreVf * TetVolume;
1198 return FibreVolume/
m_pDomain->GetVolume();
1203 vector<CYarn>::iterator itYarn;
1205 for (itYarn =
m_Yarns.begin(); itYarn !=
m_Yarns.end(); ++itYarn)
1207 if ( !itYarn->ConvertToInterpNodes() )
1216 vector<CYarn>::iterator itYarn;
1218 for (itYarn =
m_Yarns.begin(); itYarn !=
m_Yarns.end(); ++itYarn)
1220 if (!itYarn->SetResolution(Resolution))
#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.
#define TEXGEN
Helper macro to get the texgen instance.
Abstract base class representing the domain in which a textile cell may lie.
vector< XYZ > GetTranslations(const CYarn &Yarn) const
Get the translation vectors necessary to fully fill the domain.
Domain implementation described using planes, the simplest of which would be a box.
Domain implementation described using extrusion of a polygon outline.
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.
const vector< XYZ > & GetNodes() const
Get a const reference to the nodes.
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.
vector< XYZ > GetElementCenters() const
Get a vector of element centers, one entry for each element.
void ConvertTriToQuad(double Tolerance=1e-6)
Convert Triangel elements to Quads.
bool SaveToVTK(string Filename, const vector< CMeshDataBase * > *pMeshData=NULL) const
Save the mesh to VTK unstructured grid file format (.vtu)
const list< int > & GetIndices(ELEMENT_TYPE ElemType) const
Get the element indices of a given element type.
ELEMENT_TYPE
Each element type is represented by a unique integer value.
double CalculateVolume() const
Calculate the volume of the mesh.
pair< XYZ, XYZ > GetAABB(double dGrowDistance=0) const
Get an axis aligned bounding box for the mesh.
void Clear()
Empty mesh nodes and indices.
Class to store properties related to a textile.
virtual void PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType)
Used for saving data to XML.
double GetSIValue() const
Represents a 3D woven textile.
Represents a 3D angle interlock woven textile.
Represents a textile cell containing yarns.
CTextileWeave * GetWeave()
If this textile is a woven textile get a pointer of that type else return NULL.
bool SetResolution(int Resolution)
Set the resolution for all yarns in textile.
void RemoveDomain()
Remove the domain.
void AddNodesToMesh(CMesh &Mesh)
Add the master nodes to the mesh.
void SetAllYarnsPoissonsRatioY(double dValue)
virtual bool BuildTextile() const
Build the textile even if it is already built (virtual function which does nothing by default)
double GetYarnVolumePerUnitArea(string Units="m")
Calculate the total yarn volume per unit area.
CTextileOrthogonal * GetOrthogonalWeave()
CTextileLayerToLayer * GetLayerToLayerWeave()
void SavePointInformationToVTK(string Filename, const CMesh &Mesh, double dTolerance=1e-9)
Output point information to VTK.
bool DeleteYarn(int iIndex)
Delete an Yarn from the textile.
void SetAllYarnsYoungsModulusY(double dValue, string Units="MPa")
void SetAllYarnsPoissonsRatioZ(double dValue)
double GetFibreVolume(string Units="m^3")
Calculate the volume of fibre in the yarn, for just the nodes specified.
CTextile3DWeave * Get3DWeave()
bool BuildTextileIfNeeded() const
Build the textile only if needed.
void DeleteYarns()
Delete all Yarns in the textile.
void SetAllYarnsAlphaY(double dValue, string Units="/K")
void AddVolumeToMesh(vector< CMesh > &YarnMeshes, bool bTrimToDomain=false)
Create volume mesh for each yarn in this textile and add to a vector of meshes.
void AddCentrePlaneToMesh(CMesh &Mesh, bool bTrimToDomain=false)
Create centre plane mesh for this textile and add it to the mesh object.
void SetAllYarnsAlphaZ(double dValue, string Units="/K")
vector< CYarn > m_Yarns
Vector of yarns contained within this cell.
void SetAllYarnsPoissonsRatioX(double dValue)
Set the Poisson's ratio for all yarns in textile.
CTextile & operator=(const CTextile &CopyMe)
void SetAllYarnsYoungsModulusX(double dValue, string Units="MPa")
Set the Youngs Modulus for all yarns in textile.
void Translate(XYZ Vector)
Translate the Textile by given vector.
void AddSurfaceToMesh(CMesh &Mesh, bool bTrimToDomain=false)
Create surface mesh for this textile and add it to the mesh object.
double GetFibreYarnVolumeFraction()
Calculates the total fibre volume fraction for all yarns.
void Rotate(WXYZ Rotation, XYZ Origin=XYZ(0, 0, 0))
Rotate the Textile by given quaternion.
bool ConvertToInterpNodes() const
virtual string GetType() const
Derived class should return the class name.
void AssignDomain(const CDomain &Domain)
Assign a domain to the textile, will be used by default to trim the domain.
string GetName() const
Get the name associated with this textile.
void AddPathToMesh(CMesh &Mesh)
Add yarn centerline path to mesh.
void SetAllYarnsShearModulusYZ(double dValue, string Units="MPa")
CTextileWeave2D * GetWeave2D()
double GetApproximateSize()
Get an approximate size for the textile.
double GetFibreVolumePerUnitArea(string Units="m")
Calculate the volume of fibre per unit area.
virtual void PopulateTiXmlElement(TiXmlElement &Element, OUTPUT_TYPE OutputType)
Used for saving data to XML.
void SetAllYarnsShearModulusXZ(double dValue, string Units="MPa")
double GetYarnVolume(string Units="m^3")
Calculate the yarn volume.
double GetYarnLength(string Units="m")
Calculate the total yarn length.
int AddYarn(const CYarn &Yarn)
Add a Yarn to the textile.
void GetPointInformation(const vector< XYZ > &Points, vector< POINT_INFO > &PointsInfo, double dTolerance=1e-9)
Get useful information of a list of points.
void SetAllYarnsAlphaX(double dValue, string Units="/K")
Set the coefficient of thermal expansion for all yarns in textile.
const vector< CYarn > & GetYarns() const
double GetQuickDomainVolumeFraction()
Calculates the fibre volume fraction for the domain.
bool m_bNeedsBuilding
Variable which keeps track of wether the textile needs building or not.
CObjectContainer< CDomain > m_pDomain
CTextileDecoupledLToL * GetDecoupledLToLWeave()
const CYarn * GetYarn(int iIndex) const
CTextileLayered * GetLayeredTextile()
CTextileAngleInterlock * GetAngleInterlockWeave()
double GetDomainVolumeFraction()
Calculates the fibre volume fraction for the domain.
int DetectInterference(vector< float > &DistanceToSurface, vector< int > &YarnIndex, bool bTrimToDomain, CMesh *pInterferingPoints=NULL)
Find out if any of the yarns are interfering with each other.
void SetAllYarnsYoungsModulusZ(double dValue, string Units="MPa")
double GetYarnLengthPerUnitArea(string Units="/m")
Calculate the total yarn length per unit area.
void SetAllYarnsShearModulusXY(double dValue, string Units="MPa")
Set the shear modulus for all yarns in textile.
Represents a textile made up from several layers of weaves.
Represents a 3D orthogonal woven textile.
Respresents a 2d woven textile.
Represents a woven textile.
Represents a yarn consisting of master nodes, section and interpolation function.
Namespace containing a series of customised math operations not found in the standard c++ library.
double Max(XYZ &Vector)
Get maximum element of vector and return it.
double GetLength(const XYZ &Point1, const XYZ &Point2)
Get the length between two points.
XYZ Min(const XYZ &P1, const XYZ &P2)
Given two points, return a new point who's coordinates are the smaller of the two.
bool BoundingBoxIntersect(const XYZ &BBox1Min, const XYZ &BBox1Max, const XYZ &BBox2Min, const XYZ &BBox2Max, double dTolerance=0)
Find if two AABBs intersect with given tolerance.
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)
Structure used to retreive information about a particular point in space.
double dSurfaceDistance
Returns the closest distance from the point to the surface of the yarn.
int iYarnIndex
Index of the yarn, -1 when the point is not inside a yarn.
XYZ Orientation
Local fibre orientation.
XY Location
Location of the point relative to the yarn centerline.
XYZ YarnTangent
Tangent of the yarn centreline.
Struct for representing a quaternion.
Struct for representing points in 2D space.
Struct for representing points in 3D space.