26#include "../Triangle/triangle.h"
27#include "../Triangle/triangle_api.h"
31CBasicVolumes::CBasicVolumes(
void)
35, m_bCreatePeriodic(false)
65 vector<CYarn> &Yarns = Textile.
GetYarns();
69 vector<CYarn>::iterator itYarn;
70 vector<CMesh>::iterator itMesh;
71 TGLOG(
"Projecting volume outlines onto the x/y plane");
72 for (itYarn = Yarns.begin(), itMesh =
m_YarnMeshes.begin(); itYarn != Yarns.end() && itMesh !=
m_YarnMeshes.end(); ++itYarn, ++itMesh)
74 itYarn->AddSurfaceToMesh(*itMesh, *pDomain);
75 itMesh->ConvertQuadstoTriangles();
89 TGLOG(
"Removing degenerate segments");
91 TGLOG(
"Splitting segments at the nodes");
93 TGLOG(
"Removing duplicate segments");
95 TGLOG(
"Merging straight segments");
99 TGLOG(
"Splitting segments at the nodes");
101 TGLOG(
"Splitting segments by other segments");
110 TGLOG(
"Identifying projected regions");
117 TGLOG(
"Manually seeding boundary segments");
129 TGLOG(
"Identifying region centers");
134 TGLOG(
"Identifying list of yarns contained within each region");
138 TGLOG(
"Meshing projected regions in 2D");
157 ostringstream ProjectedAreaIndexData;
158 vector<PROJECTED_REGION>::iterator itRegion;
160 int iSegment, i1, i2;
161 list<int>::iterator itIndex;
165 for (k=0; k<(int)itRegion->SegmentIndices.size(); ++k)
167 iSegment = itRegion->SegmentIndices[k];
168 itIndex = Indices.begin();
169 advance(itIndex, iSegment*2);
176 AreaIndex.
m_Data.push_back(j);
177 Area.
m_Data.push_back(itRegion->dArea);
178 NumYarns.
m_Data.push_back(itRegion->YarnIndices.size());
182 vector<CMeshDataBase*> MeshData;
184 MeshData.push_back(&AreaIndex);
185 MeshData.push_back(&Area);
186 MeshData.push_back(&NumYarns);
193 vector<TiXmlElement> AdditionalData;
199 ostringstream ProjectedAreaIndexData;
200 vector<int>::iterator itRegion;
203 AreaIndex.
m_Data.push_back(*itRegion);
208 vector<CMeshDataBase*> MeshData;
210 MeshData.push_back(&AreaIndex);
211 MeshData.push_back(&Area);
212 MeshData.push_back(&NumYarns);
224 if (Indices1[i] == Indices2[j])
226 Common[k++] = Indices1[i];
238 list<int>::iterator itIndex, itStart;
239 list<int>::iterator itCompareIndex, itCompareStart;
246 XYZ P, P1, P2, V1, V2;
247 for (itIndex = Indices.begin(); itIndex != Indices.end(); )
252 for (itCompareIndex = itIndex; itCompareIndex != Indices.end(); )
254 itCompareStart = itCompareIndex;
255 j[0] = *(itCompareIndex++);
256 j[1] = *(itCompareIndex++);
283 Indices.erase(itStart, itIndex);
284 if (itIndex == itCompareStart)
285 itIndex = Indices.erase(itCompareStart, itCompareIndex);
287 Indices.erase(itCompareStart, itCompareIndex);
289 Indices.push_back(iEnd1);
290 Indices.push_back(iEnd2);
306 list<int>::iterator itIndex, itStart;
307 list<int>::iterator itCompareIndex;
311 int iDuplicateCount = 0;
312 for (itIndex = Indices.begin(); itIndex != Indices.end(); )
317 for (itCompareIndex = itIndex; itCompareIndex != Indices.end(); )
319 j1 = *(itCompareIndex++);
320 j2 = *(itCompareIndex++);
321 if ((i1 == j1 && i2 == j2) || (i1 == j2 && i2 == j1))
323 Indices.erase(itStart, itIndex);
329 return iDuplicateCount;
334 list<int>::iterator itIndex, itStart;
337 int iDegenerateCount = 0;
338 for (itIndex = Indices.begin(); itIndex != Indices.end(); )
345 Indices.erase(itStart, itIndex);
349 return iDegenerateCount;
355 list<int>::iterator itIndex, itStart;
356 vector<XYZ>::const_iterator itNode;
362 double dLengthSquared;
363 for (itIndex = Indices.begin(); itIndex != Indices.end(); )
374 if (j == i1 || j == i2)
382 dUMin = min(dU, 1-dU);
383 if (dU > 0 && dU < 1 && dUMin*dUMin*dLengthSquared > dToleranceSquared)
387 if (dDistanceSquared <= dToleranceSquared)
391 Indices.erase(itStart, itIndex);
394 Indices.push_back(i1);
397 if (itIndex == Indices.end())
399 Indices.push_back(j);
401 Indices.push_back(j);
402 Indices.push_back(i2);
418 list<int>::iterator itIndex, itStart;
419 list<int>::iterator itCompareIndex, itCompareStart;
424 XYZ P1, P2, P3, P4, P;
426 double dUMin1, dUMin2;
427 double dClosestDistSquared;
429 for (itIndex = Indices.begin(); itIndex != Indices.end(); )
436 for (itCompareIndex = itIndex; itCompareIndex != Indices.end(); )
438 itCompareStart = itCompareIndex;
439 j1 = *(itCompareIndex++);
440 j2 = *(itCompareIndex++);
441 if (i1 != j1 && i1 != j2 && i2 != j1 && i2 != j2)
447 dUMin1 = min(dU1, 1-dU1);
448 dUMin2 = min(dU2, 1-dU2);
451 if (dClosestDistSquared > dToleranceSquared)
453 P = P1 + (P2-P1)*dU1;
454 Indices.erase(itStart, itIndex);
455 if (itIndex == itCompareStart)
456 itIndex = Indices.erase(itCompareStart, itCompareIndex);
458 Indices.erase(itCompareStart, itCompareIndex);
460 iNewNodeIndex = Mesh.
AddNode(P);
462 Indices.push_back(i1);
463 Indices.push_back(iNewNodeIndex);
465 Indices.push_back(iNewNodeIndex);
466 Indices.push_back(i2);
468 Indices.push_back(j1);
469 Indices.push_back(iNewNodeIndex);
471 Indices.push_back(iNewNodeIndex);
472 Indices.push_back(j2);
489 list<int>::iterator itIndex;
490 list<int>::iterator itCompareIndex;
495 for (itIndex = Indices.begin(); itIndex != Indices.end(); )
501 for (itCompareIndex = Indices.begin(); itCompareIndex != Indices.end(); )
503 j1 = *(itCompareIndex++);
504 j2 = *(itCompareIndex++);
505 if (i1 == j1 || i1 == j2)
507 if (i2 == j1 || i2 == j2)
510 if (!bEnd1 || !bEnd2)
523 vector<int> LineState;
525 list<int>::iterator itIndex, itStartIndex;
526 list<int>::iterator itFollowIndex;
527 list<int>::iterator itCompareIndex, itStartCompareIndex;
528 list<int>::iterator itBestFind;
530 int iDir, iCurrentDir;
533 int iBestj1, iBestj2;
534 int iLineCount, iInitialLineCount;
536 int iBestFindDir, iBestLineCount;
537 double dMaxAngle, dAngle;
542 for (itIndex = Indices.begin(), iInitialLineCount = 0; itIndex != Indices.end(); ++iInitialLineCount)
544 itFollowIndex = itIndex;
545 itStartIndex = itIndex;
549 if (LineState[iInitialLineCount] & iDir)
561 itBestFind = Indices.end();
562 for (itCompareIndex = Indices.begin(), iLineCount=0; itCompareIndex != Indices.end(); ++iLineCount)
564 itStartCompareIndex = itCompareIndex;
565 j1 = *(itCompareIndex++);
566 j2 = *(itCompareIndex++);
567 if (itStartCompareIndex == itFollowIndex)
571 if (LineState[iLineCount] &
FORWARD)
576 if (itBestFind == Indices.end() || dAngle > dMaxAngle)
580 itBestFind = itStartCompareIndex;
581 iBestLineCount = iLineCount;
586 else if (iEndIndex == j2)
588 if (LineState[iLineCount] &
REVERSE)
593 if (itBestFind == Indices.end() || dAngle > dMaxAngle)
597 itBestFind = itStartCompareIndex;
598 iBestLineCount = iLineCount;
604 if (itBestFind == Indices.end())
606 LineState[iBestLineCount] |= iBestFindDir;
607 iCurrentDir = iBestFindDir;
608 itFollowIndex = itBestFind;
616 }
while(itFollowIndex != itStartIndex);
625 vector<PROJECTED_REGION>::iterator itRegion;
628 dAreaSum += itRegion->dArea;
631 if (abs(dAreaSum) > 1e-3)
633 TGERROR(
"Error creating projected areas, the total area is non-zero: " << dAreaSum);
645 vector<PROJECTED_REGION>::iterator itOuterRegion =
649 assert(itOuterRegion->dArea <= 0);
654 int i, i1, i2, iPrevIndex, iNewIndex;
655 list<int>::iterator itIndex, itStart;
656 vector<int>::iterator itSegment;
661 const double dAdjustedSeed =
m_dSeed + 1.2345e-3;
662 set<int> DeleteSegments;
664 for (itSegment=itOuterRegion->SegmentIndices.begin(); itSegment!=itOuterRegion->SegmentIndices.end(); ++itSegment)
666 itIndex = Indices.begin();
667 advance(itIndex, (*itSegment)*2);
673 if (dLength > dAdjustedSeed)
675 int iNumSplits = int(floor(dLength / (dAdjustedSeed)));
680 DeleteSegments.insert(*itSegment);
684 for (i=0; i<iNumSplits; ++i)
686 u = double(i+1)/double(iNumSplits+1);
689 Indices.push_back(iPrevIndex);
690 Indices.push_back(iNewIndex);
691 iPrevIndex = iNewIndex;
693 Indices.push_back(iPrevIndex);
694 Indices.push_back(i2);
699 for (itIndex=Indices.begin(), i=0; itIndex!=Indices.end(); ++i)
701 if (DeleteSegments.count(i))
707 itIndex = Indices.erase(itStart, itIndex);
726 vector<PROJECTED_REGION>::iterator itOuterRegion =
735 vector<int>::const_iterator itIndex;
742 return GetArea(&Nodes.front(), Nodes.size());
747 vector<PROJECTED_REGION>::iterator itRegion;
748 vector<int>::iterator itSegment;
749 list<int>::iterator itIndex;
756 for (itSegment=itRegion->SegmentIndices.begin(); itSegment!=itRegion->SegmentIndices.end(); ++itSegment)
758 itIndex = Indices.begin();
759 advance(itIndex, (*itSegment)*2);
764 if (itSegment == itRegion->SegmentIndices.begin())
774 Point /= 2*itRegion->SegmentIndices.size();
782 itRegion->Center = Point;
792 vector<int>::iterator itNodeIndex;
795 int i, N = (int)ContourNodes.size();
802 if (p.
y > min(p1.
y,p2.
y))
804 if (p.
y <= max(p1.
y,p2.
y))
806 if (p.
x <= max(p1.
x,p2.
x))
810 xinters = (p.
y-p1.
y)*(p2.
x-p1.
x)/(p2.
y-p1.
y)+p1.
x;
811 if (p1.
x == p2.
x || p.
x <= xinters)
820 if (counter % 2 == 1)
831 vector<pair<double, int> > YarnHeightIndex;
832 for (i=0; i<iNumRegions; ++i)
835 YarnHeightIndex.clear();
836 for (j=0; j<iNumYarns; ++j)
838 double dMinZ = 0, dMaxZ = 0;
841 YarnHeightIndex.push_back(make_pair((dMinZ+dMaxZ)/2, j));
845 for (j=0; j<(int)YarnHeightIndex.size(); ++j)
854 stringstream Switches;
857 double dMinAngle = 20;
877 Switches <<
"pzAPBq" << setiosflags(ios::fixed) << setprecision(20) << dMinAngle <<
"a" << dMaxArea;
882 triangleio TriangleInput, TriangleOutput;
885 ctx = triangle_context_create();
887 triangle_context_options(ctx, (
char*)Switches.str().c_str());
889 memset(&TriangleInput, 0,
sizeof(TriangleInput));
890 memset(&TriangleOutput, 0,
sizeof(TriangleOutput));
897 for (i=0; i<TriangleInput.numberofpoints; ++i)
904 list<int>::iterator itIndex;
907 TriangleInput.segmentlist =
new int [Indices.size()];
908 TriangleInput.numberofsegments = (int)Indices.size()/2;
910 for (itIndex = Indices.begin(), i = 0; itIndex != Indices.end(); ++itIndex, ++i)
912 TriangleInput.segmentlist[i] = *itIndex;
919 for (i=0; i<TriangleInput.numberofregions; ++i)
923 TriangleInput.regionlist[i*4+2] = i;
924 TriangleInput.regionlist[i*4+3] = 0;
927 triangle_mesh_create(ctx, &TriangleInput);
930 delete [] TriangleInput.pointlist;
931 delete [] TriangleInput.segmentlist;
932 delete [] TriangleInput.regionlist;
936 triangle_mesh_copy(ctx, &TriangleOutput, 1, 1);
939 for (i=0; i<TriangleOutput.numberofpoints; ++i)
941 Point.
x = TriangleOutput.pointlist[i*2];
942 Point.
y = TriangleOutput.pointlist[i*2+1];
947 for (i=0; i<TriangleOutput.numberoftriangles; ++i)
966 triangle_free(TriangleOutput.pointlist);
967 triangle_free(TriangleOutput.trianglelist);
968 triangle_free(TriangleOutput.triangleattributelist);
970 triangle_context_destroy(ctx);
977 vector< pair<double, XYZ> > IntersectionPoints;
978 vector< pair<double, XYZ> >::iterator itIntersectionPt;
984 Mesh.
IntersectLine(P1, P2, IntersectionPoints, make_pair(
false,
false), bForceFind);
985 for (itIntersectionPt = IntersectionPoints.begin(); itIntersectionPt != IntersectionPoints.end(); )
989 (!IntersectionPoints.empty() || !bForceFind))
990 itIntersectionPt = IntersectionPoints.erase(itIntersectionPt);
994 if (IntersectionPoints.empty())
996 for (itIntersectionPt = IntersectionPoints.begin(); itIntersectionPt != IntersectionPoints.end(); ++itIntersectionPt)
998 dZ = itIntersectionPt->first;
999 if (itIntersectionPt == IntersectionPoints.begin() || dZ < dMinZ)
1001 if (itIntersectionPt == IntersectionPoints.begin() || dZ > dMaxZ)
1009 CMesh ProjectedMesh = Mesh;
1011 list<int>::iterator itIndex;
1012 list<int>::iterator itCompareIndex;
1016 int CommonIndices[2];
1017 bool bDirection, bCompareDirection;
1020 for (itIndex = Indices.begin(); itIndex != Indices.end(); )
1022 i[0] = *(itIndex++);
1023 i[1] = *(itIndex++);
1024 i[2] = *(itIndex++);
1028 bDirection = V1.
x*V2.
y-V2.
x*V1.
y>0?
true:
false;
1029 for (itCompareIndex = itIndex; itCompareIndex != Indices.end(); )
1031 j[0] = *(itCompareIndex++);
1032 j[1] = *(itCompareIndex++);
1033 j[2] = *(itCompareIndex++);
1038 bCompareDirection = V1.
x*V2.
y-V2.
x*V1.
y>0?
true:
false;
1039 if (bDirection != bCompareDirection)
1051 vector<XYZ>::iterator itNode;
1052 vector<XYZ> &ProjectedMeshNodes = ProjectedMesh.
GetNodes();
1053 for (itNode = ProjectedMeshNodes.begin(); itNode != ProjectedMeshNodes.end(); ++itNode)
1058 return ProjectedMesh;
#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.
int RemoveDegenerateSegments(CMesh &Mesh)
bool GetCommonEdgeIndices(int Indices1[3], int Indices2[3], int Common[2])
vector< CMesh > m_YarnMeshes
bool PointInsideRegion(XYZ Point, int iRegion)
CMesh GetProjectedMesh(const CMesh &Mesh)
void SaveProjectedContoursToVTK(string Filename)
vector< PROJECTED_REGION > m_ProjectedRegions
bool CreateProjectedAreas()
vector< int > m_TriangleRegions
int SplitLinesByLines(CMesh &Mesh)
bool CreateBasicVolumes(CTextile &Textile)
double GetRegionArea(const PROJECTED_REGION &Region)
bool MeshProjectedAreas()
void SaveProjectedAreasToVTK(string Filename)
bool RemoveOuterBoundary()
void CalculateYarnIndices()
bool ValidProjectedMesh()
int MergeStraightLines(CMesh &Mesh)
int SplitLinesByNodes(CMesh &Mesh)
bool CreateProjectedCenters()
int RemoveDuplicateSegments(CMesh &Mesh)
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.
Defines the nodes and elements of a surface or volume mesh.
void RemoveAllElementsExcept(ELEMENT_TYPE Type)
Remove all elements except those of given type.
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.
void ConvertQuadstoTriangles(bool bQuality=true)
Convert the quad elements to triangles.
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.
int RemoveUnreferencedNodes()
Remove nodes that are not referenced by any elements.
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.
void Clear()
Empty mesh nodes and indices.
vector< XYZ >::const_iterator NodesBegin() const
vector< XYZ >::const_iterator NodesEnd() const
int IntersectLine(const XYZ &P1, const XYZ &P2, vector< pair< double, XYZ > > &IntersectionPoints, pair< bool, bool > TrimResults=make_pair(false, false), bool bForceFind=false) const
Find the points where a line intersects the mesh.
Represents a textile cell containing yarns.
const CDomain * GetDomain() const
const vector< CYarn > & GetYarns() const
Namespace containing a series of customised math operations not found in the standard c++ library.
double GetLengthSquared(const XYZ &Point1, const XYZ &Point2)
Get the length squared between two points.
XYZ ShortestDistPointLine(const XYZ &Point, const XYZ &LineStart, const XYZ &LineEnd, double &dU)
bool LineLineIntersect2D(const XY &p1, const XY &p2, const XY &p3, const XY &p4, double &dU1, double &dU2)
double RandomNumber(double dMin, double dMax)
Generate a random number between the limits given.
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.
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 GetArea(XYZ Points[], int iNumPoints)
Struct representing a region projected onto the XY plane.
vector< int > ContourNodes
Functor defining the < operator based on the projected region's area.
Used to sort double-int pairs.
Struct for representing points in 2D space.
Struct for representing points in 3D space.