1 // Copyright 2001-2018 Crytek GmbH / Crytek Group. All rights reserved.
4 #include "LoopPolygons.h"
5 #include "Core/Helper.h"
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
);
23 m_Holes
.push_back(loopPolygon
);
28 const std::vector
<PolygonPtr
>& LoopPolygons::GetIslands() const
30 if (!m_Islands
.empty())
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
]);
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());
52 loops
.insert(loops
.end(), m_Holes
.begin(), m_Holes
.end());
56 std::vector
<PolygonPtr
> LoopPolygons::GetOuterClones() const
58 std::vector
<PolygonPtr
> clones
= m_OuterLoops
;
59 for (auto ii
= clones
.begin(); ii
!= clones
.end(); ++ii
)
64 std::vector
<PolygonPtr
> LoopPolygons::GetHoleClones() const
66 std::vector
<PolygonPtr
> clones
= m_Holes
;
67 for (auto ii
= clones
.begin(); ii
!= clones
.end(); ++ii
)
72 void LoopPolygons::FindLoops(PolygonPtr polygon
, std::vector
<EdgeList
>& outLoopList
) const
74 EdgeSet handledEdgeSet
;
76 EdgeMap edgeMapFrom1stTo2nd
;
78 for (int i
= 0, iEdgeCount(polygon
->GetEdgeCount()); i
< iEdgeCount
; ++i
)
80 const IndexPair
& edge
= polygon
->GetEdgeIndexPair(i
);
82 edgeMapFrom1stTo2nd
[edge
.m_i
[0]].insert(edge
.m_i
[1]);
86 auto iEdgeSet
= edgeSet
.begin();
87 for (iEdgeSet
= edgeSet
.begin(); iEdgeSet
!= edgeSet
.end(); ++iEdgeSet
)
89 if (handledEdgeSet
.find(*iEdgeSet
) != handledEdgeSet
.end())
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]);
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())
125 if (++nCounter
> 10000)
127 DESIGNER_ASSERT(0 && "Searching connected an edge doesn't seem possible.");
131 while (edge
.m_i
[1] != (*iEdgeSet
).m_i
[0]);
133 if (!subPiece
.empty())
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
);