-
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathLoop2.cs
333 lines (303 loc) · 9.63 KB
/
Loop2.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
using System;
using System.Text;
/// <summary>
/// Represents the edge loop of vertex indices that form the
/// face of a mesh.
/// </summary>
public class Loop2
{
/// <summary>
/// Array of compound vertex indices.
/// </summary>
protected Index2[] indices;
/// <summary>
/// Array of compound vertex indices.
/// </summary>
/// <value>indices</value>
public Index2[] Indices
{
get
{
return this.indices;
}
set
{
this.indices = value;
}
}
/// <summary>
/// The number of vertex indices in this loop.
/// </summary>
/// <value>length</value>
public int Length { get { return this.indices.Length; } }
/// <summary>
/// Gets or sets a mesh compound index at i. Wraps around, so
/// negative indices may be used.
/// </summary>
/// <value>mesh index</value>
public Index2 this[int i]
{
get
{
return this.indices[Utils.RemFloor(i, this.indices.Length)];
}
set
{
this.indices[Utils.RemFloor(i, this.indices.Length)] = value;
}
}
/// <summary>
/// Constructs a new loop with three indices, the minimum
/// number to form an enclosed face.
/// </summary>
public Loop2()
{
this.indices = new Index2[3];
}
/// <summary>
/// Constructs a loop with the given number of indices,
/// a minimum of three.
/// </summary>
/// <param name="length">index length</param>
public Loop2(in int length)
{
this.indices = new Index2[length < 3 ? 3 : length];
}
/// <summary>
/// Constructs a loop from an index array.
/// </summary>
/// <param name="indices">indices</param>
public Loop2(in Index2[] indices)
{
this.indices = indices;
}
/// <summary>
/// Constructs a loop from a list of indices.
/// </summary>
/// <param name="indices">indices</param>
public Loop2(params Index2[] indices)
{
this.indices = indices;
}
/// <summary>
/// Returns a string representation of this loop.
/// </summary>
/// <returns>string</returns>
public override string ToString()
{
return Loop2.ToString(this);
}
/// <summary>
/// Reverses the indices in this loop.
/// </summary>
/// <returns>this loop</returns>
public Loop2 Reverse()
{
Array.Reverse(this.indices);
return this;
}
/// <summary>
/// Convenience method. Sets the target loop's indices to a new array
/// created from the arguments. Creates a hexagon.
/// </summary>
/// <param name="a">first vertex</param>
/// <param name="b">second vertex</param>
/// <param name="c">third vertex</param>
/// <param name="d">fourth vertex</param>
/// <param name="e">fifth vertex</param>
/// <param name="f">sixth vertex</param>
/// <param name="target">target loop</param>
/// <returns>hexagon loop</returns>
public static Loop2 Hex(
in Index2 a,
in Index2 b,
in Index2 c,
in Index2 d,
in Index2 e,
in Index2 f,
in Loop2 target)
{
target.indices = new Index2[] { a, b, c, d, e, f };
return target;
}
/// <summary>
/// Convenience method. Sets the target loop's indices to a new array
/// created from the arguments. Creates a quadrilateral.
/// </summary>
/// <param name="a">first vertex</param>
/// <param name="b">second vertex</param>
/// <param name="c">third vertex</param>
/// <param name="d">fourth vertex</param>
/// <param name="target">target loop</param>
/// <returns>quadrilateral loop</returns>
public static Loop2 Quad(
in Index2 a,
in Index2 b,
in Index2 c,
in Index2 d,
in Loop2 target)
{
target.indices = new Index2[] { a, b, c, d };
return target;
}
/// <summary>
/// Resizes an array of loops. If the size is less than one, returns an empty array.
/// If the input array is null, creates an array of new loops. Existing loops in the
/// old array are passed to the resized array by reference. There is an option to
/// resize the length of these existing loops to match the length of new loops.
/// </summary>
/// <param name="arr">array</param>
/// <param name="sz">size</param>
/// <param name="vertsPerLoop">vertices per loop</param>
/// <param name="resizeExisting">change existing loop length</param>
/// <returns>resized array</returns>
public static Loop2[] Resize(
in Loop2[] arr,
in int sz,
in int vertsPerLoop = 3,
in bool resizeExisting = false)
{
if (sz < 1) { return new Loop2[] { }; }
Loop2[] result = new Loop2[sz];
int vplVal = vertsPerLoop < 3 ? 3 : vertsPerLoop;
if (arr == null)
{
for (int i = 0; i < sz; ++i)
{
result[i] = new Loop2(vplVal);
}
return result;
}
int last = arr.Length - 1;
for (int i = 0; i < sz; ++i)
{
if (i > last || arr[i] == null)
{
result[i] = new Loop2(vplVal);
}
else
{
result[i] = arr[i];
if (resizeExisting)
{
result[i].indices = Index2.Resize(result[i].indices, vplVal);
}
}
}
return result;
}
/// <summary>
/// Splices an array of loops into the midst of another. For use by
/// subdivision functions. If the number of deletions exceeds the length of
/// the target array, then a copy of the insert array is returned.
/// </summary>
/// <param name="arr">array</param>
/// <param name="index">insertion point</param>
/// <param name="deletions">deletion count</param>
/// <param name="insert">insert</param>
/// <returns>spliced array</returns>
public static Loop2[] Splice(in Loop2[] arr, in int index, in int deletions, in Loop2[] insert)
{
int aLen = arr.Length;
if (deletions >= aLen)
{
Loop2[] result0 = new Loop2[insert.Length];
System.Array.Copy(insert, 0, result0, 0, insert.Length);
return result0;
}
int bLen = insert.Length;
int valIdx = Utils.RemFloor(index, aLen + 1);
if (deletions < 1)
{
Loop2[] result1 = new Loop2[aLen + bLen];
System.Array.Copy(arr, 0, result1, 0, valIdx);
System.Array.Copy(insert, 0, result1, valIdx, bLen);
System.Array.Copy(arr, valIdx, result1, valIdx + bLen, aLen - valIdx);
return result1;
}
int idxOff = valIdx + deletions;
Loop2[] result = new Loop2[aLen + bLen - deletions];
System.Array.Copy(arr, 0, result, 0, valIdx);
System.Array.Copy(insert, 0, result, valIdx, bLen);
System.Array.Copy(arr, idxOff, result, valIdx + bLen, aLen - idxOff);
return result;
}
/// <summary>
/// Returns a string representation of a loop.
/// </summary>
/// <param name="l">loop</param>
/// <param name="padding">padding</param>
/// <returns>string</returns>
public static string ToString(in Loop2 l, in int padding = 3)
{
return Loop2.ToString(new StringBuilder(1024), l, padding).ToString();
}
/// <summary>
/// Appends a string representation of a loop
/// to a string builder.
/// </summary>
/// <param name="sb">string builder</param>
/// <param name="l">loop</param>
/// <param name="padding">padding</param>
/// <returns>string builder</returns>
public static StringBuilder ToString(in StringBuilder sb, in Loop2 l, in int padding = 3)
{
sb.Append("{\"indices\":");
Index2.ToString(sb, l.indices, padding);
sb.Append('}');
return sb;
}
/// <summary>
/// Returns a string representation of an array of loops.
/// </summary>
/// <param name="arr">array</param>
/// <param name="padding">padding</param>
/// <returns>string</returns>
public static string ToString(in Loop2[] arr, in int padding = 3)
{
return Loop2.ToString(new StringBuilder(1024), arr, padding).ToString();
}
/// <summary>
/// Appends a string representation of an array of loops
/// to a string builder.
/// </summary>
/// <param name="sb">string builder</param>
/// <param name="arr">array</param>
/// <param name="padding">padding</param>
/// <returns>string builder</returns>
public static StringBuilder ToString(in StringBuilder sb, in Loop2[] arr, in int padding = 3)
{
sb.Append('[');
if (arr != null)
{
int len = arr.Length;
int last = len - 1;
for (int i = 0; i < last; ++i)
{
Loop2.ToString(sb, arr[i], padding);
sb.Append(',');
}
Loop2.ToString(sb, arr[last], padding);
}
sb.Append(']');
return sb;
}
/// <summary>
/// Convenience method. Sets the target loop's indices to a new array
/// created from the arguments. Creates a triangle.
/// </summary>
/// <param name="a">first vertex</param>
/// <param name="b">second vertex</param>
/// <param name="c">third vertex</param>
/// <param name="target">target loop</param>
/// <returns>triangle loop</returns>
public static Loop2 Tri(
in Index2 a,
in Index2 b,
in Index2 c,
in Loop2 target)
{
target.indices = new Index2[] { a, b, c };
return target;
}
}