!XT (BREAK-16) (Sandbox) Remove double-newlines at the end of files.
[CRYENGINE.git] / Code / Sandbox / Plugins / CryDesigner / Core / LoopPolygons.cpp
blob9c71adfb182238a79c15544b91870ed8c62aca24
1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
3 #include "StdAfx.h"
4 #include "LoopPolygons.h"
5 #include "Core/Helper.h"
7 namespace Designer
9 LoopPolygons::LoopPolygons(PolygonPtr polygon, bool bOptimizePolygon) : m_bOptimizedPolygon(bOptimizePolygon)
11 std::vector<EdgeList> loops;
12 FindLoops(polygon, loops);
14 for (int i = 0, nLoopCount(loops.size()); i < nLoopCount; ++i)
16 PolygonPtr loopPolygon;
17 if (CreateNewPolygonFromEdges(polygon, loops[i], bOptimizePolygon, loopPolygon))
19 loopPolygon->SetFlag(polygon->GetFlag());
20 if (loopPolygon->IsCCW())
21 m_OuterLoops.push_back(loopPolygon);
22 else
23 m_Holes.push_back(loopPolygon);
28 const std::vector<PolygonPtr>& LoopPolygons::GetIslands() const
30 if (!m_Islands.empty())
31 return m_Islands;
33 for (int k = 0; k < m_OuterLoops.size(); k++)
35 m_Islands.push_back(m_OuterLoops[k]->Clone());
36 for (int i = 0; i < m_Holes.size(); ++i)
38 if (m_Islands[k]->IncludeAllEdges(m_Holes[i]))
39 m_Islands[k]->Attach(m_Holes[i]);
43 return m_Islands;
46 std::vector<PolygonPtr> LoopPolygons::GetAllLoops() const
48 std::vector<PolygonPtr> loops;
49 if (m_OuterLoops.empty())
50 loops.insert(loops.end(), m_OuterLoops.begin(), m_OuterLoops.end());
51 if (!m_Holes.empty())
52 loops.insert(loops.end(), m_Holes.begin(), m_Holes.end());
53 return loops;
56 std::vector<PolygonPtr> LoopPolygons::GetOuterClones() const
58 std::vector<PolygonPtr> clones = m_OuterLoops;
59 for (auto ii = clones.begin(); ii != clones.end(); ++ii)
60 *ii = (*ii)->Clone();
61 return clones;
64 std::vector<PolygonPtr> LoopPolygons::GetHoleClones() const
66 std::vector<PolygonPtr> clones = m_Holes;
67 for (auto ii = clones.begin(); ii != clones.end(); ++ii)
68 *ii = (*ii)->Clone();
69 return clones;
72 void LoopPolygons::FindLoops(PolygonPtr polygon, std::vector<EdgeList>& outLoopList) const
74 EdgeSet handledEdgeSet;
75 EdgeSet edgeSet;
76 EdgeMap edgeMapFrom1stTo2nd;
78 for (int i = 0, iEdgeCount(polygon->GetEdgeCount()); i < iEdgeCount; ++i)
80 const IndexPair& edge = polygon->GetEdgeIndexPair(i);
81 edgeSet.insert(edge);
82 edgeMapFrom1stTo2nd[edge.m_i[0]].insert(edge.m_i[1]);
85 int nCounter(0);
86 auto iEdgeSet = edgeSet.begin();
87 for (iEdgeSet = edgeSet.begin(); iEdgeSet != edgeSet.end(); ++iEdgeSet)
89 if (handledEdgeSet.find(*iEdgeSet) != handledEdgeSet.end())
90 continue;
92 std::vector<int> subPiece;
93 IndexPair edge = *iEdgeSet;
94 handledEdgeSet.insert(edge);
98 if (edgeMapFrom1stTo2nd.find(edge.m_i[1]) != edgeMapFrom1stTo2nd.end())
100 subPiece.push_back(edge.m_i[0]);
102 else
104 subPiece.clear();
105 break;
108 const EdgeIndexSet& secondIndexSet = edgeMapFrom1stTo2nd[edge.m_i[1]];
110 if (secondIndexSet.size() == 1)
112 edge = IndexPair(edge.m_i[1], *secondIndexSet.begin());
114 else if (secondIndexSet.size() > 1)
116 int edgeidx = polygon->ChooseNextEdge(edge, secondIndexSet);
117 edge = polygon->GetEdgeIndexPair(edgeidx);
120 if (handledEdgeSet.find(edge) != handledEdgeSet.end())
122 subPiece.clear();
123 break;
125 if (++nCounter > 10000)
127 DESIGNER_ASSERT(0 && "Searching connected an edge doesn't seem possible.");
128 return;
131 while (edge.m_i[1] != (*iEdgeSet).m_i[0]);
133 if (!subPiece.empty())
135 EdgeList subLoop;
136 subPiece.push_back(edge.m_i[0]);
137 for (int i = 0, subPieceCount(subPiece.size()); i < subPieceCount; ++i)
139 subLoop.push_back(IndexPair(subPiece[i], subPiece[(i + 1) % subPieceCount]));
140 handledEdgeSet.insert(IndexPair(subPiece[i], subPiece[(i + 1) % subPieceCount]));
142 outLoopList.push_back(subLoop);
147 bool LoopPolygons::CreateNewPolygonFromEdges(PolygonPtr polygon, const std::vector<IndexPair>& inputEdges, bool bOptimizePolygon, PolygonPtr& outPolygon) const
149 std::vector<Vertex> vertices;
150 std::vector<IndexPair> edges;
152 for (int i = 0, iSize(inputEdges.size()); i < iSize; ++i)
154 const IndexPair& edge(inputEdges[i]);
155 int edgeIndex0(Designer::AddVertex(vertices, polygon->GetVertex(edge.m_i[0])));
156 int edgeIndex1(Designer::AddVertex(vertices, polygon->GetVertex(edge.m_i[1])));
158 if (edgeIndex0 != edgeIndex1)
159 edges.push_back(IndexPair(edgeIndex0, edgeIndex1));
162 if (vertices.size() >= 3 && edges.size() >= 3)
164 outPolygon = new Polygon(vertices, edges, polygon->GetPlane(), polygon->GetSubMatID(), &polygon->GetTexInfo(), bOptimizePolygon);
165 return true;
168 outPolygon = NULL;
169 return false;