27#include "../Triangle/triangle.h"
31CMesher::CMesher(
int iBoundaryConditions )
34, m_bProjectMidSideNodes(true)
35, m_dLayerMergeTolerance(1e-3)
36, m_iBoundaryConditions(iBoundaryConditions)
38 switch( iBoundaryConditions )
78 TGLOG(
"Meshing basic volumes in 3D");
81 TGLOG(
"Getting element data");
86 TGLOG(
"Converting mesh to quadratic");
103 TGLOG(
"Save Volume Mesh to VTK");
113 list<MESHER_ELEMENT_DATA>::iterator itElemData;
119 RegionIndex.
m_Data.push_back(itElemData->iRegion);
120 Layer.
m_Data.push_back(itElemData->iLayer);
121 YarnIndex.
m_Data.push_back(itElemData->iYarnIndex);
122 YarnTangent.
m_Data.push_back(itElemData->YarnTangent);
123 Location.
m_Data.push_back(itElemData->Location);
124 VolumeFraction.
m_Data.push_back(itElemData->dVolumeFraction);
125 SurfaceDistance.
m_Data.push_back(itElemData->dSurfaceDistance);
126 Orientation.
m_Data.push_back(itElemData->Orientation);
130 vector<CMeshDataBase*> MeshData;
132 MeshData.push_back(&RegionIndex);
133 MeshData.push_back(&Layer);
134 MeshData.push_back(&YarnIndex);
135 MeshData.push_back(&YarnTangent);
136 MeshData.push_back(&Location);
137 MeshData.push_back(&VolumeFraction);
138 MeshData.push_back(&SurfaceDistance);
139 MeshData.push_back(&Orientation);
141 TGLOG(
"Calling SaveToVTK");
148 if ( pTextile ==
NULL )
150 TGERROR(
"Cannot save to ABAQUS: no textile created");
158 TGLOG(
"Replacing spaces in filename with underscore for ABAQUS compatibility");
160 vector<POINT_INFO> ElementsInfo;
162 list<MESHER_ELEMENT_DATA>::const_iterator itData;
175 Info.
Up = itData->Up;
177 ElementsInfo.push_back(Info);
182 ofstream Output(Filename.c_str(), ofstream::app );
195 Output <<
"*****************" << endl;
196 Output <<
"*** NODE SETS ***" << endl;
197 Output <<
"*****************" << endl;
198 Output <<
"** AllNodes - Node set containing all elements" << endl;
199 Output <<
"*NSet, NSet=AllNodes, Generate" << endl;
204 TGERROR(
"Unable to generate node sets");
220 vector<XYZ>::const_iterator itRepeat;
222 for (itRepeat=Repeats.begin(); itRepeat!=Repeats.end(); ++itRepeat)
226 SortPairs( NodePairs, (*itRepeat).y == 0 ?
true:
false );
227 EdgeNodePairSets.push_back( NodePairs );
233 set<int> CornerIndex;
234 for (i=0; i<iNumNodes; ++i)
242 set<int> PairIndices;
245 if ( !PairIndices.empty() )
247 if ( PairIndices.size() == 4 )
248 CornerIndex = PairIndices;
249 set<int>::iterator itPairIndices;
250 for ( itPairIndices = PairIndices.begin(); itPairIndices != PairIndices.end(); ++itPairIndices )
252 if ( *itPairIndices != i )
267 for (i=0; i<iNumNodes; ++i)
269 pair<int,vector<int> > ProjectedVolumeNode;
270 vector<int> VolumeNodes;
271 ProjectedVolumeNode.first = i;
274 int iRaisedNum = (int)RaisedNodes.size();
275 for (j=0; j<iRaisedNum; ++j)
277 RaisedNodes[j].iIndex = iIndexCount++;
278 Pos.
z = RaisedNodes[j].dZ;
288 list<int>::iterator itIndex;
297 for (itIndex = Indices.begin(), i=0; itIndex != Indices.end(); ++i)
300 Tri.
i[j] = *(itIndex++);
309 set<int> YarnIndices;
310 insert_iterator<set<int> > iiYarnIndices(YarnIndices, YarnIndices.end());
311 set<int>::iterator itYarnIndex;
313 list<int>::iterator itIndex;
315 int i, j, iNode, iRegion;
318 for (itIndex = Indices.begin(), i=0; itIndex != Indices.end(); ++i)
322 iNode = *(itIndex++);
333 pair<double, double> DomainBounds(0,0);
338 map<int, pair<double, double> > YarnBounds;
339 for (itYarnIndex=YarnIndices.begin(); itYarnIndex!=YarnIndices.end(); ++itYarnIndex)
341 pair<double, double> Bounds(0,0);
345 YarnBounds[*itYarnIndex] = Bounds;
349 map<int, pair<double, double> >::iterator itYarnBound, itCompareBound;
350 pair<double, double> *pAbove, *pBelow;
352 for (itYarnBound = YarnBounds.begin(); itYarnBound != YarnBounds.end(); ++itYarnBound)
355 if (itYarnBound->second.first < DomainBounds.first)
356 itYarnBound->second.first = DomainBounds.first;
357 if (itYarnBound->second.second > DomainBounds.second)
358 itYarnBound->second.second = DomainBounds.second;
360 for (itCompareBound = itYarnBound, ++itCompareBound; itCompareBound != YarnBounds.end(); ++itCompareBound)
362 if (itYarnBound->second.first+itYarnBound->second.second >
363 itCompareBound->second.first+itCompareBound->second.second)
365 pAbove = &itYarnBound->second;
366 pBelow = &itCompareBound->second;
370 pAbove = &itCompareBound->second;
371 pBelow = &itYarnBound->second;
374 dAverage = 0.5*(pAbove->first + pBelow->second);
376 pAbove->first = max(pAbove->first, dAverage);
377 pAbove->second = max(pAbove->second, dAverage);
379 pBelow->first = min(pBelow->first, dAverage);
380 pBelow->second = min(pBelow->second, dAverage);
388 RaisedNode.
dZ = DomainBounds.first;
390 RaisedNode.
dZ = DomainBounds.second;
394 for (itYarnBound = YarnBounds.begin(); itYarnBound != YarnBounds.end(); ++itYarnBound)
398 RaisedNode.
dZ = itYarnBound->second.first;
400 RaisedNode.
dZ = itYarnBound->second.second;
416 for (i=0; i<(int)ProjectedNode.
RaisedNodes.size()-1; )
423 bTop = (i == (int)ProjectedNode.
RaisedNodes.size()-2);
434 for (j=0; j<(int)ProjectedNode.
RaisedNodes[i+1].YarnBoundaryIndices.size(); ++j)
436 ProjectedNode.
RaisedNodes[i].YarnBoundaryIndices.push_back(
437 ProjectedNode.
RaisedNodes[i+1].YarnBoundaryIndices[j]);
454 for (i=0; i<iSize-1; ++i)
458 dNumDivs = (dZ2-dZ1)/dSeed;
459 iNumDivisions = int(dNumDivs);
460 if (dNumDivs-iNumDivisions > 0.5)
462 for (j=0; j<iNumDivisions-1; ++j)
464 RaisedNode.
dZ = dZ1 + (j+1)*((dZ2-dZ1)/iNumDivisions);
475 list<int>::iterator itIndex;
479 double dEdgeLength = 0;
481 for (itIndex = Indices.begin(), i=0; itIndex != Indices.end(); ++i)
485 iCorner[i] = *(itIndex++);
489 if (iCorner[i] == iIndex)
500 dSeed = dEdgeLength/iNumEdges;
507 vector<vector<RAISED_NODE> > Column1, Column2, Column3;
513 int i, iNumLayers = YarnIndices.size()*2+1;
516 int iTopYarnIndex, iBottomYarnIndex;
517 for (i=0; i<iNumLayers; ++i)
523 iBottomYarnIndex = -1;
526 iBottomYarnIndex = YarnIndices[(i/2)-1];
527 if (i/2<(
int)YarnIndices.size())
528 iTopYarnIndex = YarnIndices[i/2];
532 iBottomYarnIndex = iTopYarnIndex = ElemData.
iYarnIndex = YarnIndices[i/2];
534 vector<RAISED_NODE> Columns[3];
535 Columns[0] = Column1[i];
536 Columns[1] = Column2[i];
537 Columns[2] = Column3[i];
540 set<pair<int, int> > EdgeConstraints[3];
569 int i, j, iNumLayers = YarnIndices.size()*2+1;
571 Column.resize(iNumLayers);
576 for (j=0; j<(int)Node.
RaisedNodes[i].YarnBoundaryIndices.size(); ++j)
578 if (count(YarnIndices.begin(), YarnIndices.end(), Node.
RaisedNodes[i].YarnBoundaryIndices[j]))
581 if (iLayer < iNumLayers)
603 if (!Columns[i1].empty() && !Columns[i2].empty())
605 if (!Columns[i1].front().bMerged && !Columns[i2].front().bMerged)
606 BuildMidSideNode(Columns[i1].front().iIndex, Columns[i2].front().iIndex, iYarnIndex,
false);
607 if (!Columns[i1].back().bMerged && !Columns[i2].back().bMerged)
608 BuildMidSideNode(Columns[i1].back().iIndex, Columns[i2].back().iIndex, iYarnIndex,
true);
615 if (iNodeIndex2 > iNodeIndex1)
616 swap(iNodeIndex1, iNodeIndex2);
618 pair<int, int> MidIndex(iNodeIndex1, iNodeIndex2);
625 pair<double, double> YarnBounds;
630 MidPos.
z = YarnBounds.second;
632 MidPos.
z = YarnBounds.first;
641 if (iNodeIndex2 > iNodeIndex1)
642 swap(iNodeIndex1, iNodeIndex2);
643 pair<int, int> MidIndex(iNodeIndex1, iNodeIndex2);
646 return itNode->second;
655 list<int>::const_iterator itIndex;
657 for (itIndex = Indices.begin(); itIndex != Indices.end(); )
663 vector<int> QuadraticTet;
664 QuadraticTet.push_back(i1);
665 QuadraticTet.push_back(i2);
666 QuadraticTet.push_back(i3);
667 QuadraticTet.push_back(i4);
687 vector<RAISED_NODE>::iterator itRaisedNode1, itRaisedNode2;
688 vector<int>::iterator itYarnBound1, itYarnBound2;
689 map<int, int> BoundCount1;
690 map<int, int> BoundCount2;
695 for (i1 = 0; i1 < (int)Columns[k].size(); ++i1)
697 vector<int> &YarnBounds1 = Columns[k][i1].YarnBoundaryIndices;
698 for (itYarnBound1 = YarnBounds1.begin(); itYarnBound1 != YarnBounds1.end(); ++itYarnBound1)
700 ++BoundCount1[*itYarnBound1];
702 for (i2 = 0; i2 < (int)Columns[(k+1)%3].size(); ++i2)
704 vector<int> &YarnBounds2 = Columns[(k+1)%3][i2].YarnBoundaryIndices;
705 for (itYarnBound2 = YarnBounds2.begin(); itYarnBound2 != YarnBounds2.end(); ++itYarnBound2)
707 ++BoundCount2[*itYarnBound2];
708 if (*itYarnBound1 == *itYarnBound2 &&
709 BoundCount1[*itYarnBound1] == BoundCount2[*itYarnBound2])
713 EdgeConstraints[k].insert(make_pair(i1, i2));
725 for (i1 = 0; i1 < (int)Columns[k].size(); ++i1)
727 for (i2 = 0; i2 < (int)Columns[(k+1)%3].size(); ++i2)
729 Edge.first = Columns[k][i1].iIndex;
730 Edge.second = Columns[(k+1)%3][i2].iIndex;
731 if (Edge.first > Edge.second)
732 swap(Edge.first, Edge.second);
735 EdgeConstraints[k].insert(make_pair(i1, i2));
753 int h[3] = {0, 0, 0};
757 Sizes[i] = (int)Columns[i].size();
762 int iNumElements = 0;
763 set<pair<int, int> >::iterator itEdge;
764 bool bEdgeConstraintViolation;
765 while (h[0] < Sizes[0] && h[1] < Sizes[1] && h[2] < Sizes[2])
772 if (h[i]+1 < Sizes[i])
774 dZ = Columns[i][h[i]+1].dZ;
775 if (iMinIndex==-1 || dZ < dZMin)
778 bEdgeConstraintViolation =
ViolatesEdgeConstraint(EdgeConstraints[i], EdgeConstraints[i2], h[i], h[i1], h[i2]);
794 if (!bEdgeConstraintViolation)
808 Limits[0] = Limits[3] = h[0];
809 Limits[1] = Limits[4] = h[1];
810 Limits[2] = Limits[5] = h[2];
819 for (itEdge = EdgeConstraints[i].begin(); itEdge != EdgeConstraints[i].end(); ++itEdge)
821 if (Limits[i] <= itEdge->first && itEdge->first < max(Limits[i+3], Limits[i]+1) &&
822 Limits[3+(i+1)%3] < itEdge->second)
824 Limits[3+(i+1)%3] = itEdge->second;
828 for (itEdge = EdgeConstraints[(i+2)%3].begin(); itEdge != EdgeConstraints[(i+2)%3].end(); ++itEdge)
830 if (Limits[i] <= itEdge->second && itEdge->second < max(Limits[i+3], Limits[i]+1) &&
831 Limits[3+(i+2)%3] < itEdge->first)
833 Limits[3+(i+2)%3] = itEdge->first;
840 if (Limits[0] == Limits[3] &&
841 Limits[1] == Limits[4] &&
842 Limits[2] == Limits[5])
864 Indices.push_back(Columns[i][h[i]].iIndex);
867 Indices.push_back(Columns[iMinIndex][h[iMinIndex]].iIndex);
890 dMinZ = dMaxZ = Columns[0][Limits[0]].dZ;
893 for (j=Limits[i]; j<=Limits[i+3]; ++j)
895 if (Columns[i][j].dZ < dMinZ)
896 dMinZ = Columns[i][j].dZ;
897 else if (Columns[i][j].dZ > dMaxZ)
898 dMaxZ = Columns[i][j].dZ;
901 Center.
z = 0.5*(dMinZ + dMaxZ);
906 set<pair<int, int> >::iterator itEdge;
908 int iElementsCreated = 0;
912 Indices.push_back(Columns[0][Limits[0]].iIndex);
913 Indices.push_back(Columns[1][Limits[1]].iIndex);
914 Indices.push_back(Columns[2][Limits[2]].iIndex);
915 Indices.push_back(iCenter);
920 bool bEdgeConstraintViolation;
925 h2 = Limits[(i+1)%3];
926 while (h1 <= Limits[i+3])
928 while (h2 < Limits[(i+1)%3+3])
931 bEdgeConstraintViolation =
false;
932 for (itEdge = EdgeConstraints[i].begin(); itEdge != EdgeConstraints[i].end(); ++itEdge)
934 if (h1 < itEdge->first && h2 >= itEdge->second)
936 bEdgeConstraintViolation =
true;
939 if (bEdgeConstraintViolation)
942 Indices.push_back(iCenter);
943 Indices.push_back(Columns[i][h1].iIndex);
944 Indices.push_back(Columns[(i+1)%3][h2].iIndex);
945 Indices.push_back(Columns[(i+1)%3][h2+1].iIndex);
950 if (h1 < Limits[i+3] && h2 <= Limits[(i+1)%3+3])
953 bEdgeConstraintViolation =
false;
954 for (itEdge = EdgeConstraints[i].begin(); itEdge != EdgeConstraints[i].end(); ++itEdge)
956 if (h1 >= itEdge->first && h2 < itEdge->second)
958 bEdgeConstraintViolation =
true;
961 if (!bEdgeConstraintViolation)
964 Indices.push_back(iCenter);
965 Indices.push_back(Columns[i][h1].iIndex);
966 Indices.push_back(Columns[(i+1)%3][h2].iIndex);
967 Indices.push_back(Columns[i][h1+1].iIndex);
982 Indices.push_back(iCenter);
983 Indices.push_back(Columns[0][Limits[3]].iIndex);
984 Indices.push_back(Columns[1][Limits[4]].iIndex);
985 Indices.push_back(Columns[2][Limits[5]].iIndex);
990 return iElementsCreated;
1221 pair<int, int> EdgeConstraint(i1, i2);
1222 if (EdgeConstraint.first > EdgeConstraint.second)
1223 swap(EdgeConstraint.first, EdgeConstraint.second);
1229 set<pair<int, int> >::const_iterator itEdge;
1230 for (itEdge = EdgeConstraints1.begin(); itEdge != EdgeConstraints1.end(); ++itEdge)
1232 if (h >= itEdge->first && h1 < itEdge->second)
1237 for (itEdge = EdgeConstraints2.begin(); itEdge != EdgeConstraints2.end(); ++itEdge)
1239 if (h >= itEdge->second && h2 < itEdge->first)
1249 if (h1 >= (
int)Column1.size())
1251 if (h2 >= (
int)Column2.size())
1254 double dDist = abs(Column1[h1].dZ - Column2[h2].dZ);
1255 bool bClosest =
true;
1257 for (j=0; j<(int)Column1.size(); ++j)
1261 if (abs(Column1[j].dZ - Column2[h2].dZ) <= dDist)
1270 for (j=0; j<(int)Column2.size(); ++j)
1274 if (abs(Column1[h1].dZ - Column2[j].dZ) <= dDist)
1290 double dTolerance = 1e-5;
1291 list<MESHER_ELEMENT_DATA>::iterator itElementData;
1292 list<int>::const_iterator itIndex;
1296 vector<vector<XYZ> > YarnTranslations;
1297 YarnTranslations.resize(iNumYarns);
1300 for (i=0; i<iNumYarns; ++i)
1311 for (itIndex = Indices.begin(), itElementData = ElementData.begin(); itIndex != Indices.end() && itElementData != ElementData.end(); ++itElementData)
1314 for (i=0; i<iNumNodes; ++i)
1318 AvgPos /= iNumNodes;
1320 if (itElementData->iYarnIndex >= 0 && itElementData->iYarnIndex < iNumYarns)
1323 bInside = pYarn->
PointInsideYarn(AvgPos, YarnTranslations[itElementData->iYarnIndex], &itElementData->YarnTangent, &itElementData->Location, &itElementData->dVolumeFraction, &itElementData->dSurfaceDistance, dTolerance, &itElementData->Orientation, &itElementData->Up);
1326 TGLOG(
"PointInsideYarn false");
1336 TGERROR(
"Unable to get element data, invalid element type: " << ElementType);
1345 bool bFoundFirst =
false, bFoundSecond =
false;
1348 while ( itSets !=
m_NodePairSets.end() && !(bFoundFirst && bFoundSecond) )
1350 NODE_PAIR_SET::iterator itNodePairSet = (*itSets).begin();
1351 bFoundFirst =
false;
1352 bFoundSecond =
false;
1353 while( itNodePairSet != (*itSets).end() && !(bFoundFirst && bFoundSecond) )
1357 if ( (*itNodePairSet).first == iIndex1 )
1359 MatchPair.first = (*itNodePairSet).second;
1362 else if ( (*itNodePairSet).second == iIndex1 )
1364 MatchPair.first = (*itNodePairSet).first;
1368 if ( !bFoundSecond )
1370 if ( (*itNodePairSet).first == iIndex2 )
1372 MatchPair.second = (*itNodePairSet).second;
1373 bFoundSecond =
true;
1375 else if ( (*itNodePairSet).second == iIndex2 )
1377 MatchPair.second = (*itNodePairSet).first;
1378 bFoundSecond =
true;
1385 return ( bFoundFirst && bFoundSecond );
1390 NODE_PAIR_SETS::const_iterator itSets = NodePairSets.begin();
1393 while ( itSets != NodePairSets.end() )
1395 NODE_PAIR_SET::const_iterator itNodePairSet = (*itSets).begin();
1396 pair<set<int>::iterator,
bool> ret;
1397 bool bFound =
false;
1399 while( itNodePairSet != (*itSets).end() && !bFound )
1401 if ( (*itNodePairSet).first == iIndex )
1403 ret = Match.insert( (*itNodePairSet).second );
1410 else if ( (*itNodePairSet).second == iIndex )
1412 ret = Match.insert( (*itNodePairSet).first );
1423 if ( iNumFound > 1 )
1431 NODE_PAIR_SET::iterator itNodePairs;
1433 for ( itNodePairs = NodePairs.begin(); itNodePairs != NodePairs.end(); ++itNodePairs )
1439 if ( Node1.
y > Node2.
y )
1441 swap( (*itNodePairs).first, (*itNodePairs).first );
1446 if ( Node1.
x > Node2.
x )
1448 swap( (*itNodePairs).first, (*itNodePairs).first );
1458 NODE_PAIR_SETS::iterator itEdgeNodeSets;
1460 set<int> CompletedCorners;
1461 set<int> EdgeIndices;
1467 for ( itEdgeNodeSets = EdgeNodePairSets.begin(); itEdgeNodeSets != EdgeNodePairSets.end(); ++itEdgeNodeSets )
1469 NODE_PAIR_SET::iterator itNodePairs;
1471 VolMeshPairs.clear();
1473 bool bConstX = (Repeats[j++].y == 0);
1475 for ( itNodePairs = (*itEdgeNodeSets).begin(); itNodePairs != (*itEdgeNodeSets).end(); ++itNodePairs )
1479 vector<RAISED_NODE>::iterator itRaisedNodes;
1480 int ind1 = (*itNodePairs).first;
1481 int ind2 = (*itNodePairs).second;
1483 EdgeIndices.insert(ind1);
1484 EdgeIndices.insert(ind2);
1487 if ( CornerIndex.find(ind1) != CornerIndex.end() )
1489 if ( CompletedCorners.find(ind1) == CompletedCorners.end() )
1491 vector<int> Edge1, Edge2;
1492 for (
int i = 1; i < size-1; ++i )
1509 if ( !CompletedCorners.empty() )
1521 CompletedCorners.insert(ind1);
1522 CompletedCorners.insert(ind2);
1527 int StartInd = bConstX ? 4 : 8;
1533 for (
int i = 1; i < size-1; ++i )
1552 VolMeshPairs.push_back( NodePair );
1560 for (
int i = 0; i < Size; ++i )
1562 if ( EdgeIndices.find(i) == EdgeIndices.end() )
1574 for (
int i = 0; i < 8; ++i )
1581 for (
int i = 0; i < 12; ++i )
1598 vector< set<int> > FaceSets;
1602 map<int,vector<int> > FaceSetIndices;
1604 for (
int i = 1; i <= NumNodes; ++i )
1607 if ( FaceSet.size() > 0 )
1609 FaceSetIndices[i] = FaceSet;
1615 list<int>::const_iterator itIndex;
1616 map<int,vector<int> >::iterator itEndIndices = FaceSetIndices.end();
1619 for (itIndex = Indices.begin(); itIndex != Indices.end(); )
1624 list<int>::const_iterator itEndIndex = itIndex;
1625 advance( itEndIndex, NumNodes);
1626 iIndex.insert( iIndex.begin(), itIndex, itEndIndex );
1627 for (
int i = 0; i < 4; ++i )
1629 if ( FaceSetIndices.find(iIndex[i]+1) == itEndIndices )
1632 for (
int j = i+1; j < 4; ++j )
1635 if ( FaceSetIndices.find(iIndex[j]+1) == itEndIndices )
1637 AddQuadNodeToSet( i, j, FaceSetIndices[iIndex[i]+1], FaceSetIndices[iIndex[j]+1], iIndex );
1642 advance(itIndex, NumNodes);
1659 FaceSets.push_back( FaceSet );
1671 FaceSets.push_back( FaceSet );
1683 FaceSets.push_back( FaceSet );
1695 FaceSets.push_back( FaceSet );
1707 FaceSets.push_back( FaceSet );
1719 FaceSets.push_back( FaceSet );
1725 vector<int> Indices;
1726 for ( i = 0; i < FaceSets.size(); ++i )
1728 if ( FaceSets[i].find( iIndex ) != FaceSets[i].end() )
1729 Indices.push_back(i);
1736 int iSize1 = FaceSet1.size();
1737 int iSize2 = FaceSet2.size();
1739 if ( iSize1 == 1 && iSize2 == 1 )
1741 if ( FaceSet1[0] == FaceSet2[0] )
1745 else if ( (iSize1 == 1 && iSize2 == 2) || (iSize1 == 2 && iSize2 == 1) )
1749 if ( FaceSet1[0] == FaceSet2[0] || FaceSet1[0] == FaceSet2[1] )
1754 if ( FaceSet2[0] == FaceSet1[0] || FaceSet2[0] == FaceSet1[1] )
1758 else if ( iSize1 == 2 && iSize2 == 2 )
1760 if ( (FaceSet1[0] == FaceSet2[0]) && (FaceSet1[1] == FaceSet2[1]) )
1764 else if ( (FaceSet1[0] == FaceSet2[0]) || (FaceSet1[0] == FaceSet2[1]) )
1768 else if ( (FaceSet1[1] == FaceSet2[0]) || (FaceSet1[1] == FaceSet2[1]) )
1773 else if ( (iSize1 == 1 && iSize2 == 3) || (iSize1 == 3 && iSize2 == 1) )
1777 if ( (FaceSet1[0] == FaceSet2[0]) || (FaceSet1[0] == FaceSet2[1]) || (FaceSet1[0] == FaceSet2[2]) )
1782 if ( (FaceSet2[0] == FaceSet1[0]) || (FaceSet2[0] == FaceSet1[1]) || (FaceSet2[0] == FaceSet1[2]) )
1786 else if ( (iSize1 == 2 && iSize2 == 3) || (iSize1 == 3 && iSize2 == 2) )
1788 vector<int> Face1 = iSize1 == 2 ? FaceSet1 : FaceSet2;
1789 vector<int> Face2 = iSize1 == 2 ? FaceSet2 : FaceSet1;
1791 if ( Face1[0] == Face2[0] )
1793 if ( Face1[1] == Face2[1] || Face1[1] == Face2[2] )
1800 else if ( Face1[0] == Face2[1] )
1802 if ( Face1[1] == Face2[2] )
1809 else if ( Face1[0] == Face2[2] )
1813 else if ( Face1[1] == Face2[0] || Face1[1] == Face2[1] || Face1[1] == Face2[2] )
1818 else if ( iSize1 == 3 && iSize2 == 3 )
1830 m_FaceA.push_back( Indices[iNode]+1 );
1833 m_FaceB.push_back( Indices[iNode]+1 );
1836 m_FaceC.push_back( Indices[iNode]+1 );
1839 m_FaceD.push_back( Indices[iNode]+1 );
1842 m_FaceE.push_back( Indices[iNode]+1 );
1845 m_FaceF.push_back( Indices[iNode]+1 );
1853 m_Edges[iEdge].push_back( Indices[iNode]+1);
1945 vector<vector<int> >::iterator itEdge;
1953 for ( itEdge =
m_Edges.begin(); itEdge !=
m_Edges.end(); ++itEdge )
1961 vector<int>::iterator itNewEnd;
1962 sort( FaceSet.begin(), FaceSet.end() );
1963 itNewEnd = unique(FaceSet.begin(), FaceSet.end());
1964 FaceSet.erase(itNewEnd, FaceSet.end());
#define TGERROR(MESSAGE)
Macros used to report the file name and line number to the TexGenError and TexGenLog functions.
#define TEXGEN
Helper macro to get the texgen instance.
vector< CMesh > m_YarnMeshes
vector< PROJECTED_REGION > m_ProjectedRegions
vector< int > m_TriangleRegions
bool CreateBasicVolumes(CTextile &Textile)
bool GetMeshVerticalBounds(const CMesh &Mesh, XYZ Point, double &dMinZ, double &dMaxZ, bool bForceFind=false)
Abstract base class representing the domain in which a textile cell may lie.
const CMesh & GetMesh() const
Get the mesh representing the domain as a surface mesh.
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.
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.
vector< pair< int, int > > GetNodePairs(XYZ Vector, const double Tolerance=1e-6) const
Return a list of node pairs (A, B) where A == B + Vector.
const vector< XYZ > & GetNodes() const
Get a const reference to the nodes.
bool SaveToABAQUS(string Filename, const vector< POINT_INFO > *pElementInfo=NULL, bool bCreateStep=true, bool bCreateMaterial=true, int iElementType=0)
Save the mesh to ABAQUS input file format with information such as yarn tangents.
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.
bool SaveToVTK(string Filename, const vector< CMeshDataBase * > *pMeshData=NULL) const
Save the mesh to VTK unstructured grid file format (.vtu)
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.
ELEMENT_TYPE
Each element type is represented by a unique integer value.
int GetNumElements(ELEMENT_TYPE Type) const
Get the number of elements of a given type.
void Clear()
Empty mesh nodes and indices.
virtual bool CreateMesh(CTextile &Textile)=0
int TetMeshColumn(vector< RAISED_NODE > Columns[3], set< pair< int, int > > EdgeConstraints[3])
void RaiseNodes(int iIndex)
void BuildEdgeConstraints(vector< RAISED_NODE > Columns[3], set< pair< int, int > > EdgeConstraints[3])
void SaveVolumeMeshToVTK(string Filename)
void AddElement(CMesh::ELEMENT_TYPE Type, const vector< int > &Indices)
bool GetPairIndices(int iIndex1, int iIndex2, NODE_PAIR &MatchPair)
vector< PROJECTED_NODE > m_ProjectedNodes
void BuildMidSideNode(int iNodeIndex1, int iNodeIndex2, int iYarnIndex, bool bTop)
bool m_bProjectMidSideNodes
XYZ GetMidSideNode(int iNodeIndex1, int iNodeIndex2)
pair< int, int > NODE_PAIR
void BuildMidSideNodes(vector< RAISED_NODE > Columns[3], int iYarnIndex)
int GetEdge(int iFace1, int iFace2)
void SetupFaceSets(vector< set< int > > &FaceSets)
bool SplitColumn(PROJECTED_NODE &Node, vector< int > &YarnIndices, vector< vector< RAISED_NODE > > &Column)
void MeshColumn(TRIANGLE Triangle, int iRegion)
double m_dLayerMergeTolerance
set< pair< int, int > > m_EdgeConstraints
bool ViolatesEdgeConstraint(const set< pair< int, int > > &EdgeConstraints1, const set< pair< int, int > > &EdgeConstraints2, int h, int h1, int h2)
void GetEdgePairIndices(const NODE_PAIR_SETS &NodePairSets, int iIndex, set< int > &Match)
CPeriodicBoundaries * m_PeriodicBoundaries
int MeshDifficultRegion(vector< RAISED_NODE > Columns[3], int Limits[6], set< pair< int, int > > EdgeConstraints[3])
vector< NODE_PAIR_SET > NODE_PAIR_SETS
list< MESHER_ELEMENT_DATA > m_ElementData[CMesh::NUM_ELEMENT_TYPES]
NODE_PAIR_SETS m_NodePairSets
void AddEdgeConstraint(int i1, int i2)
bool CreateMesh(CTextile &Textile)
CTextileMaterials * m_Materials
bool ShouldConnect(vector< RAISED_NODE > &Column1, vector< RAISED_NODE > &Column2, int h1, int h2)
void SubdivideNodes(int iIndex)
void SortPairs(NODE_PAIR_SET &NodePairs, bool bSwapY)
double GetBestSeed(int iIndex)
void ConvertMeshToQuadratic()
vector< int > FindFaceSets(vector< set< int > > &FaceSets, int iIndex)
void CreateNodeSets(NODE_PAIR_SETS &EdgeNodePairSets, set< int > &CornerIndex, const vector< XYZ > &Repeats)
void SaveVolumeMeshToABAQUS(string Filename, string TextileName)
void FillYarnTangentsData()
vector< vector< int > > m_Edges
void CreateVolumeMesh(CTextile &Textile)
void AddQuadNodeToEdge(int i, int j, int iEdge, vector< int > &Indices)
map< pair< int, int >, XYZ > m_MidSideNodeLocations
vector< NODE_PAIR > NODE_PAIR_SET
void RemoveDuplicateFaceNodes(vector< int > &FaceSet)
void AddQuadraticNodesToSets()
const list< MESHER_ELEMENT_DATA > * GetElementData(CMesh::ELEMENT_TYPE ElementType)
void RemoveDuplicateNodes()
void AddQuadNodeToFace(int i, int j, int iFace, vector< int > &Indices)
int m_iBoundaryConditions
int GetQuadNodeToAdd(int i, int j)
void AddQuadNodeToSet(int i, int j, vector< int > &FaceSeti, vector< int > &FaceSetj, vector< int > &Indices)
Class used to generate Abaqus output for periodic boundary conditions.
void SetFaceB(vector< int > &B1, vector< int > &B2)
void CreatePeriodicBoundaries(ostream &Output, int iDummyNodeNum, CTextile &Textile, int iBoundarConditions, bool bMatrixOnly)
void SetEdges(vector< int > &Edge)
virtual void SetDomainSize(const CMesh &Mesh)
void SetVertex(int Vertex)
void SetFaceA(vector< int > &A1, vector< int > &A2)
void SetFaceC(vector< int > &C1, vector< int > &C2)
Class used to generate Abaqus input file for periodic boundary conditions for a textile with sheared ...
Represents a textile cell containing yarns.
const CDomain * GetDomain() const
const CYarn * GetYarn(int iIndex) const
void OutputMaterials(ostream &Output, int iNumYarns, bool bMatrixOnly)
Output materials and assign to yarn element sets.
void SetupMaterials(CTextile &Textile)
Set up a material for each unique set of material constants.
Represents a yarn consisting of master nodes, section and interpolation function.
const vector< XYZ > & GetRepeats() const
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...
Namespace containing a series of customised math operations not found in the standard c++ library.
std::string ReplaceFilenameSpaces(std::string Filename)
Replaces spaces in filename with underscore.
double GetLength(const XYZ &Point1, const XYZ &Point2)
Get the length between two points.
vector< RAISED_NODE > RaisedNodes
vector< int > YarnBoundaryIndices
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 points in 3D space.