UDocumentation UE5.7 10.02.2026 (Source)
API documentation for Unreal Engine 5.7
PlanarComplex.h
Go to the documentation of this file.
1// Copyright Epic Games, Inc. All Rights Reserved.
2
3#pragma once
4
5// Very approximately ported from geometry3sharp's PlanarComplex
6// Convert a set of polygons into general polygon form, tracking the outer-polygon and hole-polygon indices
7
8#include "SegmentTypes.h"
9#include "VectorTypes.h"
10#include "BoxTypes.h"
11#include "Polygon2.h"
13
14namespace UE
15{
16namespace Geometry
17{
18
19template <typename RealType>
21{
22 //
23 // Inputs
24 //
26
27 bool bTrustOrientations = true;
29
30 //
31 // Outputs
32 //
39
40 // Finds set of "solid" regions -- e.g. boundary loops with interior holes.
41 // Result has outer loops being clockwise, and holes counter-clockwise
43 {
44 Solids.Empty();
45
46 int32 N = Polygons.Num();
49 for (int i = 0; i < N; i++)
50 {
51 PolygonIndices[i] = i;
52 }
53
54 // precomputed useful stats on input polygons
55 struct FPolygonInfo
56 {
57 RealType Area;
58 bool Orientation;
60 };
62 Info.SetNum(N);
63 for (int i = 0; i < N; i++)
64 {
65 RealType SignedArea = Polygons[i].SignedArea();
66 Info[i].Orientation = SignedArea > 0;
67 Info[i].Area = Info[i].Orientation ? SignedArea : -SignedArea;
68 Info[i].Bounds = Polygons[i].Bounds();
69 }
70
71 PolygonIndices.Sort([&Info](int Ind1, int Ind2)
72 {
73 return Info[Ind1].Area > Info[Ind2].Area;
74 }
75 );
76
79 for (int i = 0; i < N; i++)
80 {
81 Parent[i] = -1;
82 }
83
84 // From largest polygon to smallest, greedily assign parents where possible
85 // If a polygon already has a parent, but a smaller containing parent is found, switch to the new parent (unless doing so would create an intersection)
86 for (int ParentCand = 0; ParentCand+1 < N; ParentCand++)
87 {
90 const FPolygonInfo& PInfo = Info[PIdx];
91 if (bTrustOrientations && !PInfo.Orientation)
92 {
93 // orientation tells us this is a hole; skip checking for holes in it
94 continue;
95 }
96 for (int ChildCand = ParentCand + 1; ChildCand < N; ChildCand++)
97 {
100 const FPolygonInfo& CInfo = Info[CIdx];
101 if (bTrustOrientations && CInfo.Orientation)
102 {
103 // orientation tells us this is an outer; skip checking if it could be a hole
104 continue;
105 }
106 if (PInfo.Bounds.Contains(CInfo.Bounds) && PPoly.Contains(CPoly))
107 {
108 bool bOverlapFound = false;
110 {
112 {
114 {
116 {
117 bOverlapFound = true;
118 break;
119 }
120 }
121 }
122 }
123 if (!bOverlapFound)
124 {
126 }
127 }
128 }
129 }
130
131 // Build nests from parent relationship
132 TArray<bool> Taken;
133 Taken.SetNumZeroed(N);
134 for (int NestCand = 0; NestCand < N; NestCand++)
135 {
137 if (Taken[NestCand] || (bTrustOrientations && !Info[NIdx].Orientation))
138 {
139 continue;
140 }
141 FPolygonNesting &Nest = Solids.Emplace_GetRef();
142 Nest.OuterIndex = NIdx;
143 for (int HoleCand = NestCand + 1; HoleCand < N; HoleCand++)
144 {
146 if (Parent[HoleCand] == NestCand)
147 {
148 Nest.HoleIndices.Add(HIdx);
149 Taken[HoleCand] = true;
150 }
151 }
152 }
153 }
154
156 {
158 for (int HoleIdx : Nest.HoleIndices)
159 {
160 GPoly.AddHole(Polygons[HoleIdx], false, false);
161 }
162 return GPoly;
163 }
165 {
167 for (const FPolygonNesting& Nest : Solids)
168 {
170 for (int HoleIdx : Nest.HoleIndices)
171 {
172 GPoly.AddHole(Polygons[HoleIdx], false, false);
173 }
174 }
175 return Output;
176 }
177};
178
181
182
183} // end namespace UE::Geometry
184} // end namespace UE
FPlatformTypes::int32 int32
A 32-bit signed integer.
Definition Platform.h:1125
UE_FORCEINLINE_HINT TSharedRef< CastToType, Mode > StaticCastSharedRef(TSharedRef< CastFromType, Mode > const &InSharedRef)
Definition SharedPointer.h:127
Definition Array.h:670
void SetNumZeroed(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2340
void SetNum(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2308
UE_NODEBUG UE_FORCEINLINE_HINT SizeType Add(ElementType &&Item)
Definition Array.h:2696
void SetNumUninitialized(SizeType NewNum, EAllowShrinking AllowShrinking=UE::Core::Private::AllowShrinkingByDefault< AllocatorType >())
Definition Array.h:2369
Definition GeneralPolygon2.h:28
bool AddHole(TPolygon2< T > Hole, bool bCheckContainment=true, bool bCheckOrientation=true)
Definition GeneralPolygon2.h:77
Definition Polygon2.h:30
TPlanarComplex< double > FPlanarComplexd
Definition PlanarComplex.h:179
TPlanarComplex< float > FPlanarComplexf
Definition PlanarComplex.h:180
Definition AdvancedWidgetsModule.cpp:13
Definition BoxTypes.h:637
int OuterIndex
Definition PlanarComplex.h:35
TArray< int > HoleIndices
Definition PlanarComplex.h:36
Definition PlanarComplex.h:21
void FindSolidRegions()
Definition PlanarComplex.h:42
TArray< TGeneralPolygon2< RealType > > ConvertOutputToGeneralPolygons() const
Definition PlanarComplex.h:164
TArray< TPolygon2< RealType > > Polygons
Definition PlanarComplex.h:25
bool bTrustOrientations
Definition PlanarComplex.h:27
TArray< FPolygonNesting > Solids
Definition PlanarComplex.h:38
TGeneralPolygon2< RealType > ConvertNestToGeneralPolygon(const FPolygonNesting &Nest) const
Definition PlanarComplex.h:155
bool bAllowOverlappingHoles
Definition PlanarComplex.h:28