31CAdjustMeshInterference::CAdjustMeshInterference(
void)
45 TGERROR(
"Unable to correct intersections: No domain specified");
49 vector<CMesh> YarnMeshes;
53 TGERROR(
" Unable to continue interference correction: failed to create yarn meshes");
57 TGLOG(
"Adjusting mesh");
58 if (!
AdjustMesh(Textile, YarnMeshes, Tolerance))
61 TGLOG(
"Regenerating mesh using adjusted points");
73 vector<CMesh>::iterator itMesh;
77 for (
int i = 0; i < iNumYarns; ++i )
79 TGLOG(
"Volume of yarn mesh " << i <<
" = " << YarnMeshes[i].CalculateVolume() <<
"\n" );
83 for ( itMesh = YarnMeshes.begin(); itMesh != YarnMeshes.end(); ++itMesh )
94 for (
int i = 0; i < (int)YarnMeshes.size(); ++i)
96 YarnMeshes[i].SaveToVTK(
"c:\\Program Files\\TexGen\\InitialAdjustedMesh" +
stringify(i));
101 TGERROR(
"Unable to adjust mesh: Intersection depths too large");
107 TGERROR(
"Unable to adjust mesh: Intersection depths too large");
119 vector<float> InterferenceDepths;
120 vector<int> YarnIndices;
121 CMesh InterferencePoints;
122 double dMinDist, dDist, dMaxDist = 0.0;
125 TGLOG(
"Checking initial intersections");
126 Textile.
DetectInterference( InterferenceDepths, YarnIndices,
true, &InterferencePoints );
131 for (
int i=0; i< (int)InterferenceDepths.size(); ++i )
135 dDist = fabs(InterferenceDepths[i]);
136 if ( dDist > dMaxDist )
139 iIndex = YarnMeshes[YarnIndices[i]].GetClosestNode( InterferencePoints.
GetNode( i ) );
145 PointInfo.
SetYarn( YarnIndices[i] );
147 PointInfo.
SetDepth( InterferenceDepths[i] );
152 vector<XYZ>::const_iterator itRepeat;
153 for (itRepeat=Repeats.begin(); itRepeat!=Repeats.end(); ++itRepeat)
155 iPairIndex = YarnMeshes[YarnIndices[i]].GetClosestNodeDistance( InterferencePoints.
GetNode(i) + (*itRepeat),
TOL);
156 if ( iPairIndex != -1 )
158 iPairIndex = YarnMeshes[YarnIndices[i]].GetClosestNodeDistance( InterferencePoints.
GetNode(i) - (*itRepeat),
TOL );
159 if ( iPairIndex != -1 )
179 vector<CMeshIntersectionData>::iterator itIntersections;
180 vector<CMesh>::iterator itMesh;
183 vector< vector<int> > WedgeElementIndices;
184 vector< vector<int> > HexElementIndices;
186 TGLOG(
"Adjusting initial intersections");
187 for ( itMesh = YarnMeshes.begin(); itMesh != YarnMeshes.end(); ++itMesh )
189 vector<int> ElementIndices;
190 ElementIndices.clear();
192 itMesh->ConvertElementListToVector(
CMesh::WEDGE, ElementIndices );
193 WedgeElementIndices.push_back( ElementIndices );
194 ElementIndices.clear();
195 itMesh->ConvertElementListToVector(
CMesh::HEX, ElementIndices );
196 HexElementIndices.push_back( ElementIndices );
203 int iYarn = itIntersections->GetYarn();
205 itIntersections->FindElements( WedgeElementIndices[iYarn],
CMesh::WEDGE);
206 itIntersections->FindElements( HexElementIndices[iYarn],
CMesh::HEX );
207 itIntersections->FindPolygonPoints( YarnMeshes[iYarn].GetIndices(
CMesh::POLYGON) );
208 bFoundNode = itIntersections->FindInterpolationNode( YarnMeshes[iYarn]);
212 if ( !itIntersections->MoveNode( YarnMeshes[iYarn] ) )
219 AddIntersectElementsToMesh( itIntersections->GetElements(), itIntersections->GetYarn(), YarnMeshes[itIntersections->GetYarn()] );
226 itMesh->SaveToVTK(
"c:\\Program Files\\TexGen\\IntersectionMesh" +
stringify(i) );
228 itMesh->MergeNodes();
229 itMesh->Convert3Dto2D();
231 itMesh->ConvertQuadstoTriangles();
239 vector<ELEMENT_INDICES>::const_iterator itElements;
241 for ( i = 0, itElements = Elements.begin(); itElements != Elements.end(); ++i, ++itElements )
243 vector<int> iNewIndices;
245 for (
int j = 0; j < iNumNodes; ++j )
248 iNewIndices.push_back( iNodeIndex );
255 vector<CMeshIntersectionData>::iterator itIntersections;
256 vector<CMesh>::iterator itIntersectionMeshes;
257 int iNumIntersectPoints = 0, iIterations = 0;
260 vector< pair<XYZ, XYZ> > MeshAABB;
263 pair<XYZ, XYZ> AABB = itIntersectionMeshes->GetAABB();
264 MeshAABB.push_back( AABB );
270 iNumIntersectPoints = 0;
273 if ( fabs(itIntersections->GetDepth()) <
m_Tolerance )
277 if( itIntersections->GetYarn() == i || !
BoundingBoxIntersect(MeshAABB[i].first, MeshAABB[i].second, MeshAABB[itIntersections->GetYarn()].first, MeshAABB[itIntersections->GetYarn()].second ))
280 vector< pair<double, XYZ> > IntersectionPoints;
281 int numIntersect =
m_IntersectionMeshes[i].IntersectLine( itIntersections->GetPoint(), itIntersections->GetInterpPoint(), IntersectionPoints, make_pair(
true,
true) );
282 if ( numIntersect > 0 )
284 itIntersections->SetDepth(
GetLength( itIntersections->GetPoint(), itIntersections->GetInterpPoint() )* IntersectionPoints[0].first );
287 if ( !itIntersections->MoveNode(YarnMeshes[itIntersections->GetYarn()]) )
289 iNumIntersectPoints++;
296 TGLOG(
"Adjusting points: Iteration" << iIterations );
297 }
while ( iNumIntersectPoints );
303 vector<CMeshIntersectionData>::iterator itMeshData;
304 for (
int i = 0; i < iNumYarns; ++i )
306 vector<XYZ> YarnNodeDisplacements;
307 YarnNodeDisplacements.resize( YarnMeshes[i].GetNumNodes() );
312 m_NodeDisplacements[itMeshData->GetYarn()][itMeshData->GetIndex()] = -itMeshData->GetDisplacement();
319 vector<CMeshIntersectionData>::iterator itIntersections;
323 itIntersections->AdjustInterpolationNode(YarnMeshes[itIntersections->GetYarn()]);
331 vector< vector<int> > PolygonIndices;
332 vector< vector<int> > AdjustedPolygonIndices;
335 vector<CMesh>::iterator itMesh;
336 vector<CMesh>::iterator itTempMesh;
342 for ( itMesh = YarnMeshes.begin(), itTempMesh =
m_TempYarnMeshes.begin(); itMesh != YarnMeshes.end(), itTempMesh !=
m_TempYarnMeshes.end(); ++itMesh, ++itTempMesh )
344 vector<int> ElementIndices;
345 ElementIndices.clear();
347 itMesh->ConvertElementListToVector(
CMesh::POLYGON, ElementIndices );
348 AdjustedPolygonIndices.push_back( ElementIndices );
349 ElementIndices.clear();
350 itTempMesh->ConvertElementListToVector(
CMesh::POLYGON, ElementIndices );
351 PolygonIndices.push_back( ElementIndices );
355 for (
int i = 0; i < iNumYarns; ++i )
358 vector<XYZ> Translations;
363 vector<CSlaveNode>::const_iterator itNodes;
374 for ( itNodes = Nodes.begin(); itNodes != Nodes.end(); ++itNodes )
376 YarnPositionInfo.
iSection = itNodes->GetIndex();
377 double T = itNodes->GetT();
381 vector<XYZ> SlaveNodePoints;
382 SlaveNodePoints = itNodes->GetSectionPoints();
383 int iPolygonIndex = -1;
384 int iOffsetIndex = -1;
389 if ( iPolygonIndex == -1 )
396 vector<XYZ> SectionPoints;
397 vector<XYZ> TempPoints;
401 vector<int> Indices = PolygonIndices[i];
402 int iStartIndex = Indices[iPolygonIndex];
408 Point = YarnMeshes[i].GetNode( Indices[iPolygonIndex++] );
410 if ( j < iOffsetIndex )
411 TempPoints.push_back(Point);
413 SectionPoints.push_back( Point );
415 }
while ( Indices[iPolygonIndex] != iStartIndex );
423 SectionPoints.insert( SectionPoints.end(), TempPoints.begin(), TempPoints.end() );
426 vector<XYZ>::iterator itSectionPoints;
427 for ( itSectionPoints = SectionPoints.begin(); itSectionPoints != SectionPoints.end(); ++itSectionPoints )
429 *(itSectionPoints) -= Translations[iTrans];
434 XYZ SlaveNodePos = itNodes->GetPosition();
435 XYZ Up = itNodes->GetUp();
436 XYZ Side = itNodes->GetSide();
438 for ( itSectionPoints = SectionPoints.begin(); itSectionPoints != SectionPoints.end(); ++itSectionPoints )
441 XYZ Relative = *itSectionPoints - SlaveNodePos;
445 Points2D.push_back( Point2D );
458 vector<XYZ>::iterator itSlavePoints;
459 vector< vector<XYZ> > TranslatedSections;
460 vector<XYZ>::iterator itTranslations;
463 for ( itTranslations = Translations.begin(); itTranslations != Translations.end(); ++itTranslations )
465 vector<XYZ> SectionPoints;
466 SectionPoints.clear();
467 for ( itSlavePoints = SlaveNodePoints.begin(); itSlavePoints != SlaveNodePoints.end(); ++itSlavePoints )
469 SectionPoints.push_back( *(itSlavePoints) + *(itTranslations) );
471 TranslatedSections.push_back( SectionPoints );
475 vector<int>::iterator itPolygonIndices;
476 vector<XYZ> PolygonPoints;
477 int iElementIndex = 0;
479 for ( itPolygonIndices = PolygonIndices.begin(); itPolygonIndices != PolygonIndices.end(); )
481 int StartIndex = *(itPolygonIndices);
482 int StartElementIndex = iElementIndex;
484 PolygonPoints.clear();
487 int index = *(itPolygonIndices);
488 Point = TempMesh.
GetNode( index );
491 PolygonPoints.push_back( Point );
493 }
while ( *(itPolygonIndices)!= StartIndex );
500 OffsetIndex =
CompareSections( TranslatedSections, PolygonPoints, iTrans );
501 if ( OffsetIndex >= 0 )
504 return StartElementIndex;
513 vector< vector<XYZ> >::iterator itTransSections;
514 double tolerance = 0.0000001;
518 for ( itTransSections = TranslatedSections.begin(); itTransSections != TranslatedSections.end(); ++ itTransSections )
520 vector<XYZ>::iterator itTransPoints;
521 vector<XYZ>::iterator itPolyPoints;
524 if ( itTransSections->size() != PolygonPoints.size() )
526 vector<XYZ> TransSection = *itTransSections;
530 for( itPolyPoints = PolygonPoints.begin(); itPolyPoints != PolygonPoints.end(); ++itPolyPoints )
532 if(
GetLength(TransSection[0] - *(itPolyPoints)) < tolerance )
536 if ( itPolyPoints == PolygonPoints.end() )
543 for( itTransPoints = TransSection.begin(); itTransPoints != TransSection.end(); ++itTransPoints )
545 if (
GetLength((*itTransPoints) - (*itPolyPoints)) > tolerance )
551 if ( itPolyPoints == PolygonPoints.end() )
552 itPolyPoints = PolygonPoints.begin();
573 int interpNodeIndex = -1;
574 vector<int>::iterator itElementIndex;
580 for( itElementIndex =
m_Elements[0].Index.begin(); itElementIndex !=
m_Elements[0].Index.end(); ++itElementIndex )
582 if ( *itElementIndex ==
m_Index )
584 vector<ELEMENT_INDICES>::iterator itElementArrays =
m_Elements.begin()+1;
586 && find(itElementArrays->Index.begin(), itElementArrays->Index.end(), *itElementIndex) != itElementArrays->Index.end() )
595 interpNodeIndex = *itElementIndex;
603 for (
int i = 0; i < (int)
m_Elements.size(); ++i )
606 for (itElementIndex =
m_Elements[i].Index.begin(), j = 0; itElementIndex !=
m_Elements[i].Index.end(); ++itElementIndex, ++j )
608 if ( *itElementIndex ==
m_Index )
620 vector<int>::iterator itElementStart[2], itElementEnd[2];
621 for (
int i = 0; i < (int)
m_Elements.size(); ++i )
624 itElementStart[i] =
m_Elements[i].Index.begin() + ElementEnd[i] * iNumNodes;
626 itElementEnd[i] =
m_Elements[i].Index.begin() + iNumNodes;
636 for ( itElementIndex = itElementStart[0]; itElementIndex != itElementEnd[0]; ++itElementIndex )
638 if ( *itElementIndex ==
m_Index )
641 if ( find(itElementStart[1], itElementEnd[1], *itElementIndex) != itElementEnd[1] )
646 interpNodeIndex = *itElementIndex;
650 TGLOG(
"Number of elements = 1. Need to test this code" );
652 int PolygonIndex = -1;
654 for ( itElementIndex = itElementStart[0] ; itElementIndex != itElementEnd[0]; ++itElementIndex )
656 if ( *itElementIndex ==
m_Index )
671 for (
int i = 0; i < 2; ++i )
673 if ( i != Index1 && i != PolygonIndex )
675 interpNodeIndex = *(itElementStart[0]+i);
683 if ( PolygonIndex > Index1 )
685 interpNodeIndex = *(itElementStart[0]+((Index1+iNumNodes-1)%(iNumNodes)));
689 interpNodeIndex = *( itElementStart[0]+((Index1+1)%(iNumNodes)));
696 if ( interpNodeIndex != -1 )
710 double absDepth = fabs(
m_Depth);
712 double CheckLength = length;
716 CheckLength -= MinLength;
718 if ( (absDepth * 0.5) > CheckLength )
720 TGERROR(
"Intersection depth in yarn " <<
m_Yarn <<
" too large for adjustment");
745 vector<int>::iterator itIndexArray = IndexArray.begin();
749 while ( itIndexArray != IndexArray.end() )
751 itIndexArray = find( itIndexArray, IndexArray.end(),
m_Index );
752 if ( itIndexArray != IndexArray.end() )
754 int iIndex = (int)(itIndexArray - IndexArray.begin());
756 vector<int>::iterator itStartVertex = itIndexArray - (iIndex %
CMesh::GetNumNodes(ElementType));
762 Element.
Index.clear();
770 list<int>::iterator itPolygons;
771 int iFoundIndex = -1;
773 for ( itPolygons = Polygons.begin(); itPolygons != Polygons.end(); )
775 int StartIndex = *itPolygons;
779 Polygon.push_back( *itPolygons );
784 }
while ( (*itPolygons) != StartIndex );
786 if ( iFoundIndex != -1 )
789 if ( iFoundIndex == 0 )
793 if ( iFoundIndex == i-1 )
813 NewPoint -= Offset/2.0;
#define TGERROR(MESSAGE)
Macros used to report the file name and line number to the TexGenError and TexGenLog functions.
bool AdjustIntersections(vector< CMesh > &YarnMeshes)
Iteratively refines intersections until within tolerance.
void AdjustSectionMeshes(CTextile &Textile, vector< CMesh > &YarnMeshes)
Adjust yarns to interpolate between section meshes and change these to reflect intersection adjustmen...
int CompareSections(vector< vector< XYZ > > &TranslatedSections, vector< XYZ > &PolygonPoints, int &iTrans)
void AdjustInterpolationNodes(vector< CMesh > &YarnMeshes)
Final adjustment of interpolation nodes to even out mesh.
bool AdjustMesh(CTextile &Textile, vector< CMesh > &YarnMeshes, double Tolerance)
Top level function to adjust nodes on all yarns.
bool AdjustInitialIntersections(vector< CMesh > &YarnMeshes)
Takes the individual yarn meshes and corrects intersections based on Textile.DetectInterference()
void AdjustTextileMesh(CTextile &Textile, double Tolerance=0.0000001)
Adjust mesh interference for whole textile by adjusting nodes.
void SetNodeDisplacements(int iNumYarns, vector< CMesh > &YarnMeshes)
bool CheckInitialIntersections(CTextile &Textile, vector< CMesh > &YarnMeshes)
Calls Textile.DetectInterference and sets up MeshIntersectionData base on intersection depths.
int FindMeshPolygonSection(vector< XYZ > &SlaveNodePoints, CMesh &TempMesh, vector< int > &PolygonIndices, vector< XYZ > &Translations, int &OffsetIndex, int &iTrans)
Find the newly created polygon sections in the volume mesh.
vector< vector< XYZ > > m_NodeDisplacements
vector< CMesh > m_TempYarnMeshes
void AddIntersectElementsToMesh(const vector< ELEMENT_INDICES > &Elements, int iYarn, CMesh &YarnMesh)
Creates mesh for each yarn containing elements with intersection nodes.
vector< CMeshIntersectionData > m_Intersections
virtual ~CAdjustMeshInterference(void)
vector< CMesh > m_IntersectionMeshes
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.
Defines the nodes and elements of a surface or volume mesh.
int GetNumNodes() const
Return the number of nodes.
const XYZ & GetNode(int iIndex) const
Get the node with given ID.
ELEMENT_TYPE
Each element type is represented by a unique integer value.
void SetNode(int iIndex, XYZ Node)
Set the node at given index.
Class which holds the information related to each intersection point, used for adjusting the mesh.
virtual ~CMeshIntersectionData(void)
void SetDepth(double Depth)
bool FindInterpolationNode(CMesh &YarnMesh)
Finds the appropriate node in the elements to interpolate towards.
void FindElements(vector< int > &IndexArray, CMesh::ELEMENT_TYPE ElementType)
Given node index, find all elements containing that node.
void SetBoundaryPairIndex(int index)
void FindPolygonPoints(list< int > &Polygons)
Find surface point in polygon & points on either side.
CMeshIntersectionData(void)
void AdjustInterpolationNode(CMesh &YarnMesh)
Make final adjustments to interpolation nodes to even out elements.
void SetInterpIndex(int index)
vector< ELEMENT_INDICES > m_Elements
void SetStartPoint(XYZ Point)
bool MoveNode(CMesh &YarnMesh)
Move node by 0.5 * intersection depth towards the interpolation node.
Creates a polygonal section, where a list of points are given to form the closed polygon.
Represents a textile cell containing yarns.
const CDomain * GetDomain() const
void AddVolumeToMesh(vector< CMesh > &YarnMeshes, bool bTrimToDomain=false)
Create volume mesh for each yarn in this textile and add to a vector of meshes.
const CYarn * GetYarn(int iIndex) const
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.
Represents a yarn consisting of master nodes, section and interpolation function.
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.
const vector< XYZ > & GetRepeats() const
vector< double > GetSectionLengths() const
Interpolate sections between arbritrary positions along the length of the yarn.
void AddSection(double dPosition, const CSection &Section)
Add a section at a specific point along the path of the yarn.
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.
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.
CMesh::ELEMENT_TYPE ElementType
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.
double GetYarnPosition() const