Project

General

Profile

Download (21.9 KB) Statistics
| Branch: | Revision:

library / src / main / java / org / distorted / library / mesh / MeshMultigon.java @ 0fb3f8b8

1
///////////////////////////////////////////////////////////////////////////////////////////////////
2
// Copyright 2023 Leszek Koltunski  leszek@koltunski.pl                                          //
3
//                                                                                               //
4
// This file is part of Distorted.                                                               //
5
//                                                                                               //
6
// This library is free software; you can redistribute it and/or                                 //
7
// modify it under the terms of the GNU Lesser General Public                                    //
8
// License as published by the Free Software Foundation; either                                  //
9
// version 2.1 of the License, or (at your option) any later version.                            //
10
//                                                                                               //
11
// This library is distributed in the hope that it will be useful,                               //
12
// but WITHOUT ANY WARRANTY; without even the implied warranty of                                //
13
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU                             //
14
// Lesser General Public License for more details.                                               //
15
//                                                                                               //
16
// You should have received a copy of the GNU Lesser General Public                              //
17
// License along with this library; if not, write to the Free Software                           //
18
// Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA                //
19
///////////////////////////////////////////////////////////////////////////////////////////////////
20

    
21
package org.distorted.library.mesh;
22

    
23
import java.util.ArrayList;
24

    
25
///////////////////////////////////////////////////////////////////////////////////////////////////
26

    
27
/**
28
 * Create a 'multigon' mesh - a union of several polygons.
29
 *
30
 * <p>
31
 * Specify several lists of vertices. Each list defines one polygon. (@see MeshPolygon).
32
 * If two such polygons share an edge (or several edges) then the edge in both of them is
33
 * marked 'up'.
34
 */
35
public class MeshMultigon extends MeshBase
36
  {
37
  private static final float MAX_ERROR = 0.000001f;
38
  private float[][][] mOuterAndHoleVertices;
39
  private float[][][] mEdgeVectors;
40

    
41
///////////////////////////////////////////////////////////////////////////////////////////////////
42

    
43
  private static boolean isSame(float dx, float dy)
44
    {
45
    return (dx*dx + dy*dy < MAX_ERROR);
46
    }
47

    
48
///////////////////////////////////////////////////////////////////////////////////////////////////
49

    
50
  private static int isUp(float[][][] vertices, int polygon, int edge)
51
    {
52
    float[][] p= vertices[polygon];
53
    int lenP = p.length;
54
    int len  = vertices.length;
55
    int next = (edge==lenP-1 ? 0 : edge+1);
56

    
57
    float v1x = p[edge][0];
58
    float v1y = p[edge][1];
59
    float v2x = p[next][0];
60
    float v2y = p[next][1];
61

    
62
    for(int i=0; i<len; i++)
63
      if( i!=polygon )
64
        {
65
        int num = vertices[i].length;
66

    
67
        for(int j=0; j<num; j++)
68
          {
69
          int n = (j==num-1 ? 0 : j+1);
70
          float[][] v = vertices[i];
71
          float x1 = v[j][0];
72
          float y1 = v[j][1];
73
          float x2 = v[n][0];
74
          float y2 = v[n][1];
75

    
76
          if( isSame(v2x-x1,v2y-y1) && isSame(v1x-x2,v1y-y2) ) return i;
77
          }
78
        }
79

    
80
    return -1;
81
    }
82

    
83
///////////////////////////////////////////////////////////////////////////////////////////////////
84

    
85
  private static float[] detectFirstOuterVertex(float[][][] vertices)
86
    {
87
    float X = -Float.MAX_VALUE;
88
    int I=0,J=0, len = vertices.length;
89

    
90
    for(int i=0; i<len; i++ )
91
      {
92
      float[][] v = vertices[i];
93
      int num = v.length;
94

    
95
      for(int j=0; j<num; j++)
96
        if( v[j][0]>X )
97
          {
98
          X = v[j][0];
99
          I = i;
100
          J = j;
101
          }
102
      }
103

    
104
    float[] v = vertices[I][J];
105
    return new float[] {v[0],v[1]};
106
    }
107

    
108
///////////////////////////////////////////////////////////////////////////////////////////////////
109

    
110
  private static double computeAngle(float x1,float y1, float x2, float y2)
111
    {
112
    double diff = Math.atan2(y2,x2)-Math.atan2(y1,x1);
113
    return diff<0 ? diff+(2*Math.PI) : diff;
114
    }
115

    
116
///////////////////////////////////////////////////////////////////////////////////////////////////
117

    
118
  private static float[] detectNextOuterVertex(float[][][] vertices, float[] curr, float[] vect, int[][] edgesUp)
119
    {
120
    double maxAngle = 0;
121
    float x=0, y=0;
122
    int numC = vertices.length;
123

    
124
    for( int c=0; c<numC; c++ )
125
      {
126
      float[][] vert = vertices[c];
127
      int numV = vert.length;
128

    
129
      for( int v=0; v<numV; v++)
130
        {
131
        float xc = vert[v][0];
132
        float yc = vert[v][1];
133

    
134
        if( edgesUp[c][v]<0 && isSame(xc-curr[0],yc-curr[1]) )
135
          {
136
          int n = (v==numV-1 ? 0 : v+1);
137
          float xn = vert[n][0];
138
          float yn = vert[n][1];
139

    
140
          double angle = computeAngle(vect[0], vect[1], xn-xc, yn-yc);
141

    
142
          if (angle > maxAngle)
143
            {
144
            maxAngle = angle;
145
            x = xn;
146
            y = yn;
147
            }
148

    
149
          break;
150
          }
151
        }
152
      }
153

    
154
    return new float[] {x,y};
155
    }
156

    
157
///////////////////////////////////////////////////////////////////////////////////////////////////
158

    
159
  private static int getNextIndex(float[][][] vertices, int[][] unclaimedEdges, int currIndex, int numHoleVerts)
160
    {
161
    int[] currEdge = unclaimedEdges[currIndex];
162
    int currP = currEdge[0];
163
    int currE = currEdge[1];
164
    float[][] polygon = vertices[currP];
165
    int numV = polygon.length;
166
    int nextE= currE<numV-1 ? currE+1 : 0;
167

    
168
    float x = polygon[nextE][0];
169
    float y = polygon[nextE][1];
170

    
171
    for(int e=0; e<numHoleVerts; e++)
172
      {
173
      int[] edge = unclaimedEdges[e];
174

    
175
      if( edge[2]==1 )
176
        {
177
        int po = edge[0];
178
        int ed = edge[1];
179

    
180
        float cx = vertices[po][ed][0];
181
        float cy = vertices[po][ed][1];
182

    
183
        if( isSame(cx-x,cy-y) )
184
          {
185
          edge[2] = 0;
186
          return e;
187
          }
188
        }
189
      }
190

    
191
    return -1;
192
    }
193

    
194
///////////////////////////////////////////////////////////////////////////////////////////////////
195

    
196
  private static int generateHole(float[][][] vertices, int[][] unclaimedEdges, float[][] output, int[][] edgesUp, int holeNumber, int numHoleVerts)
197
    {
198
    int firstIndex=-1;
199

    
200
    for(int e=0; e<numHoleVerts; e++)
201
      if( unclaimedEdges[e][2]==1 )
202
        {
203
        firstIndex = e;
204
        break;
205
        }
206

    
207
    int currIndex = firstIndex;
208
    int nextIndex=-1;
209
    int numAdded = 0;
210

    
211
    while( nextIndex!=firstIndex )
212
      {
213
      nextIndex = getNextIndex(vertices,unclaimedEdges,currIndex,numHoleVerts);
214

    
215
      int p = unclaimedEdges[nextIndex][0];
216
      int v = unclaimedEdges[nextIndex][1];
217
      edgesUp[p][v] = -holeNumber-2;
218
      currIndex = nextIndex;
219
      int[] e = unclaimedEdges[nextIndex];
220
      float[] ve = vertices[e[0]][e[1]];
221
      output[numAdded][0] = ve[0];
222
      output[numAdded][1] = ve[1];
223
      numAdded++;
224
      }
225

    
226
    return numAdded;
227
    }
228

    
229
///////////////////////////////////////////////////////////////////////////////////////////////////
230

    
231
  private static boolean doesNotBelongToOuter(float x, float y, float[][] outer)
232
    {
233
    for(float[] v : outer)
234
      if(isSame(x-v[0], y-v[1])) return false;
235

    
236
    return true;
237
    }
238

    
239
///////////////////////////////////////////////////////////////////////////////////////////////////
240

    
241
  private static float[][][] computeHoles(float[][][] vertices, int[][] edgesUp, float[][] outer, int numHoleVerts)
242
    {
243
    int[][] unclaimedEdges = new int[numHoleVerts][];
244
    int index = 0;
245
    int numPoly = vertices.length;
246

    
247
    for(int p=0; p<numPoly; p++)
248
      {
249
      float[][] ve = vertices[p];
250
      int numEdges = ve.length;
251

    
252
      for(int e=0; e<numEdges; e++)
253
        if( edgesUp[p][e]<0 )
254
          {
255
          float x1 = ve[e][0];
256
          float y1 = ve[e][1];
257

    
258
          int n = e<numEdges-1 ? e+1 : 0;
259
          float x2 = ve[n][0];
260
          float y2 = ve[n][1];
261

    
262
          // yes, we need to check both ends of the edge - otherwise the
263
          // following 3x3 situation (x - wall, o - hole ) does not work:
264
          // x x x
265
          // x o x
266
          // o x x
267

    
268
          if( doesNotBelongToOuter(x1,y1,outer) || doesNotBelongToOuter(x2,y2,outer) )
269
            {
270
            unclaimedEdges[index]=new int[] {p, e, 1};
271
            index++;
272
            }
273
          }
274
      }
275

    
276
    int remaining = numHoleVerts;
277
    ArrayList<float[][]> holes = new ArrayList<>();
278
    float[][] output = new float[numHoleVerts][2];
279
    int numHoles = 0;
280

    
281
    while(remaining>0)
282
      {
283
      int num = generateHole(vertices,unclaimedEdges,output,edgesUp,numHoles,numHoleVerts);
284
      remaining -= num;
285
      numHoles++;
286

    
287
      float[][] hole = new float[num][2];
288
      for(int h=0; h<num; h++)
289
        {
290
        hole[h][0] = output[h][0];
291
        hole[h][1] = output[h][1];
292
        }
293

    
294
      holes.add(hole);
295
      }
296

    
297
    float[][][] ret = new float[numHoles][][];
298
    for(int h=0; h<numHoles; h++) ret[h] = holes.remove(0);
299

    
300
    return ret;
301
    }
302

    
303
///////////////////////////////////////////////////////////////////////////////////////////////////
304

    
305
  private static int countEdgesDown(int[][] edgesUp)
306
    {
307
    int numEdgesDown = 0;
308

    
309
    for(int[] edgeUp : edgesUp)
310
      for(int edge : edgeUp)
311
        if( edge<0 ) numEdgesDown++;
312

    
313
    return numEdgesDown;
314
    }
315

    
316
///////////////////////////////////////////////////////////////////////////////////////////////////
317

    
318
  private float[] produceNormalVector(float[][] outerAndHole, float xs, float ys)
319
    {
320
    int vCurr,len = outerAndHole.length;
321

    
322
    for(vCurr=0; vCurr<len; vCurr++)
323
      {
324
      float[] vs = outerAndHole[vCurr];
325
      if( isSame(vs[0]-xs,vs[1]-ys) ) break;
326
      }
327

    
328
    if( vCurr==len ) android.util.Log.e("D", "ERROR in produceNormalVector!!");
329

    
330
    int vPrev = vCurr==0 ? len-1 : vCurr-1;
331
    int vNext = vCurr>=len-1 ? 0 : vCurr+1;
332
    float[] vp = outerAndHole[vPrev];
333
    float[] vn = outerAndHole[vNext];
334

    
335
    return new float[] { vp[1]-vn[1], vn[0]-vp[0] };
336
    }
337

    
338
///////////////////////////////////////////////////////////////////////////////////////////////////
339

    
340
  private float[] produceNormalVector(float[][] outerAndHole, float xs, float ys, float xe, float ye)
341
    {
342
    int vCurr,len = outerAndHole.length;
343

    
344
    for(vCurr=0; vCurr<len; vCurr++)
345
      {
346
      float[] vs = outerAndHole[vCurr];
347

    
348
      if( isSame(vs[0]-xs,vs[1]-ys) )
349
        {
350
        int vNext = vCurr==len-1 ? 0 : vCurr+1;
351
        float[] ve = outerAndHole[vNext];
352
        if( isSame(ve[0]-xe,ve[1]-ye) ) break;
353
        }
354
      }
355

    
356
    int vPrev = vCurr==0 ? len-1 : vCurr-1;
357
    int vNext = vCurr>=len-1 ? 0 : vCurr+1;
358
    float[] vp = outerAndHole[vPrev];
359
    float[] vn = outerAndHole[vNext];
360

    
361
    return new float[] { vp[1]-vn[1], vn[0]-vp[0] };
362
    }
363

    
364
///////////////////////////////////////////////////////////////////////////////////////////////////
365

    
366
  private void computeEdgeVectors(float[][][] vertices, int[][] edgesUp)
367
    {
368
    int numPoly = vertices.length;
369
    mEdgeVectors = new float[numPoly][][];
370

    
371
    for(int c=0; c<numPoly; c++)
372
      {
373
      float[][] polygon = vertices[c];
374
      int numV = polygon.length;
375
      mEdgeVectors[c] = new float[numV][];
376

    
377
      for(int v=0; v<numV; v++)
378
        {
379
        int edgeUp = edgesUp[c][v];
380
        float xs = polygon[v][0];
381
        float ys = polygon[v][1];
382
        int n = v==numV-1 ? 0 : v+1;
383
        float xe = polygon[n][0];
384
        float ye = polygon[n][1];
385

    
386
        if( edgeUp<0 ) // external edge, normal vector
387
          {
388
          float[][] verts = mOuterAndHoleVertices[-edgeUp-1];
389
          mEdgeVectors[c][v] = produceNormalVector(verts,xs,ys,xe,ye);
390
          }
391
        else // internal edge - but the vertex that begins it might still be outer!
392
          {
393
          int numComp = retIndexBelongs(xs,ys);
394

    
395
          if( numComp<0 ) mEdgeVectors[c][v] = null;
396
          else
397
            {
398
            float[][] verts = mOuterAndHoleVertices[numComp];
399
            mEdgeVectors[c][v] = produceNormalVector(verts,xs,ys);
400
            }
401
          }
402
        }
403
      }
404
    }
405

    
406
///////////////////////////////////////////////////////////////////////////////////////////////////
407
// ret:
408
// -1  : vertex (x,y) is 'inner' (does not belong to outer vertices or any hole)
409
// N>=0: vertex (x,y) is outer [ N==0 --> outer, 1--> 1sr hole, 2 --> 2nd hole, etc ]
410

    
411
  private int retIndexBelongs(float x, float y)
412
    {
413
    int numOuterComponents = mOuterAndHoleVertices.length;
414

    
415
    for(int c=0; c<numOuterComponents; c++)
416
      {
417
      float[][] comp = mOuterAndHoleVertices[c];
418

    
419
      for(float[] v : comp)
420
        if( isSame(x-v[0],y-v[1]) ) return c;
421
      }
422

    
423
    return -1;
424
    }
425

    
426
///////////////////////////////////////////////////////////////////////////////////////////////////
427

    
428
  private float[] retOuterVector(int component, int vert)
429
    {
430
    return mEdgeVectors[component][vert];
431
    }
432

    
433
///////////////////////////////////////////////////////////////////////////////////////////////////
434

    
435
  private boolean[][] computeVertsUp(float[][][] vertices)
436
    {
437
    int numPoly = vertices.length;
438
    boolean[][] up = new boolean[numPoly][];
439

    
440
    for(int i=0; i<numPoly; i++)
441
      {
442
      float[][] v = vertices[i];
443
      int len = v.length;
444
      up[i] = new boolean[len];
445

    
446
      for(int j=0; j<len; j++)
447
        {
448
        float[] vect = retOuterVector(i,j);
449
        up[i][j] = (vect==null);
450
        }
451
      }
452

    
453
    return up;
454
    }
455

    
456
///////////////////////////////////////////////////////////////////////////////////////////////////
457

    
458
  private float[] computeCenter(float[][] vertices)
459
    {
460
    int num = vertices.length;
461
    float[] ret = new float[2];
462

    
463
    for(float[] vertex : vertices)
464
      {
465
      ret[0] += vertex[0];
466
      ret[1] += vertex[1];
467
      }
468

    
469
    ret[0] /= num;
470
    ret[1] /= num;
471

    
472
    return ret;
473
    }
474

    
475
///////////////////////////////////////////////////////////////////////////////////////////////////
476

    
477
  private float[][] computeCenters(float[][][] vertices)
478
    {
479
    int num = vertices.length;
480
    float[][] ret = new float[num][];
481
    for(int i=0; i<num; i++) ret[i] = computeCenter(vertices[i]);
482
    return ret;
483
    }
484

    
485
///////////////////////////////////////////////////////////////////////////////////////////////////
486

    
487
  private int computeMode(float[] vL, float[] vR, float[] vT, float[] normL, float[] normR,
488
                          int[][] edgesUp, boolean[][] vertsUp, float[][][] vertices, float[][] centers, int component, int curr)
489
    {
490
    float[][] v = vertices[component];
491
    int[] edges = edgesUp[component];
492
    int numPoly = v.length;
493
    int next= curr==numPoly-1 ? 0 : curr+1;
494
    int prev= curr==0 ? numPoly-1 : curr-1;
495
    int eupc = edges[curr];
496

    
497
    if( eupc<0 )
498
      {
499
      vL[0] = v[curr][0];
500
      vL[1] = v[curr][1];
501
      vR[0] = v[next][0];
502
      vR[1] = v[next][1];
503
      vT[0] = centers[component][0];
504
      vT[1] = centers[component][1];
505

    
506
      float[] outerL = retOuterVector(component,curr);
507
      float[] outerR = retOuterVector(component,next);
508

    
509
      if( outerL!=null && outerR!=null )
510
        {
511
        normL[0] = -outerL[0];
512
        normL[1] = -outerL[1];
513
        normR[0] = -outerR[0];
514
        normR[1] = -outerR[1];
515
        }
516
      else
517
        {
518
        int eupp = edges[prev];
519
        int eupn = edges[next];
520

    
521
        if( eupp<0 )
522
          {
523
          normL[0]= vL[0]-vT[0];
524
          normL[1]= vL[1]-vT[1];
525
          }
526
        else
527
          {
528
          normL[0]= v[curr][0] - v[prev][0];
529
          normL[1]= v[curr][1] - v[prev][1];
530
          }
531

    
532
        if( eupn<0 )
533
          {
534
          normR[0]= vR[0]-vT[0];
535
          normR[1]= vR[1]-vT[1];
536
          }
537
        else
538
          {
539
          int nnxt= next==numPoly-1 ? 0 : next+1;
540
          normR[0]= v[next][0] - v[nnxt][0];
541
          normR[1]= v[next][1] - v[nnxt][1];
542
          }
543
        }
544

    
545
      return MeshBandedTriangle.MODE_NORMAL;
546
      }
547
    else
548
      {
549
      vL[0] = centers[eupc][0];
550
      vL[1] = centers[eupc][1];
551
      vR[0] = centers[component][0];
552
      vR[1] = centers[component][1];
553
      vT[0] = v[curr][0];
554
      vT[1] = v[curr][1];
555

    
556
      boolean vup = vertsUp[component][curr];
557

    
558
      if( vup )
559
        {
560
        normL[0]=0;
561
        normL[1]=1;
562
        normR[0]=0;
563
        normR[1]=1;
564

    
565
        return MeshBandedTriangle.MODE_FLAT;
566
        }
567
      else
568
        {
569
        float[] outerT = retOuterVector(component,curr);
570

    
571
        if( outerT!=null )
572
          {
573
          normL[0]= outerT[0];
574
          normL[1]= outerT[1];
575
          normR[0]= outerT[0];
576
          normR[1]= outerT[1];
577
          }
578
        else
579
          {
580
          float dx = v[next][0]-v[curr][0];
581
          float dy = v[next][1]-v[curr][1];
582
          normL[0]= dx;
583
          normL[1]= dy;
584
          normR[0]= dx;
585
          normR[1]= dy;
586
          }
587

    
588
        return MeshBandedTriangle.MODE_INVERTED;
589
        }
590
      }
591
    }
592

    
593
///////////////////////////////////////////////////////////////////////////////////////////////////
594
// PUBLIC API
595
///////////////////////////////////////////////////////////////////////////////////////////////////
596

    
597
  public static int[][] computeEdgesUp(float[][][] vertices)
598
    {
599
    int numPoly = vertices.length;
600
    int[][] up = new int[numPoly][];
601

    
602
    for(int p=0; p<numPoly; p++)
603
      {
604
      int numEdges = vertices[p].length;
605
      up[p] = new int[numEdges];
606
      for(int e=0; e<numEdges; e++) up[p][e] = isUp(vertices,p,e);
607
      }
608

    
609
    return up;
610
    }
611

    
612
///////////////////////////////////////////////////////////////////////////////////////////////////
613

    
614
  public static float[][][] computeOuterAndHoleVertices(float[][][] vertices, int[][] edgesUp)
615
    {
616
    ArrayList<float[]> tmp = new ArrayList<>();
617

    
618
    float[] vect = new float[] {1,0};
619
    float[] first= detectFirstOuterVertex(vertices);
620
    float[] next = first;
621

    
622
    do
623
      {
624
      float[] prev = next;
625
      next = detectNextOuterVertex(vertices,next,vect,edgesUp);
626
      vect[0] = prev[0]-next[0];
627
      vect[1] = prev[1]-next[1];
628
      tmp.add(next);
629
      }
630
    while( !isSame(next[0]-first[0],next[1]-first[1]) );
631

    
632
    int numOuterVerts= tmp.size();
633
    float[][] outerVertices = new float[numOuterVerts][];
634
    for(int i=0; i<numOuterVerts; i++) outerVertices[i] = tmp.remove(0);
635

    
636
    int numEdgesDown = countEdgesDown(edgesUp);
637
    int numHoleVerts= numEdgesDown-numOuterVerts;
638
    float[][][] holeVertices=null;
639
    if( numHoleVerts>0 ) holeVertices = computeHoles(vertices,edgesUp,outerVertices,numHoleVerts);
640
    int numHoles = holeVertices==null ? 0 : holeVertices.length;
641
    float[][][] ret = new float[1+numHoles][][];
642
    ret[0] = outerVertices;
643
    for(int i=0; i<numHoles; i++) ret[i+1] = holeVertices[i];
644

    
645
    return ret;
646
    }
647

    
648
///////////////////////////////////////////////////////////////////////////////////////////////////
649

    
650
  private void printVertices(float[][][] vertices)
651
    {
652
    StringBuilder sb = new StringBuilder();
653
    int loop=0;
654

    
655
    for(float[][] vert : vertices)
656
      {
657
      sb.append("Loop ");
658
      sb.append(loop);
659
      sb.append(" : { ");
660

    
661
      loop++;
662
      int num=0;
663

    
664
      for( float[] v : vert)
665
        {
666
        if( num>=0 ) sb.append(", ");
667
        num++;
668

    
669
        sb.append(v[0]);
670
        sb.append(", ");
671
        sb.append(v[1]);
672
        }
673

    
674
      sb.append(" }\n");
675
      }
676

    
677
    android.util.Log.e("D", "vertices: \n"+sb);
678
    }
679

    
680
///////////////////////////////////////////////////////////////////////////////////////////////////
681

    
682
  private void printBand(float[] band)
683
    {
684
    StringBuilder sb = new StringBuilder();
685

    
686
    for(float v : band)
687
      {
688
      sb.append(v);
689
      sb.append("f, ");
690
      }
691

    
692
    android.util.Log.e("D", "band: \n"+sb);
693
    }
694

    
695
///////////////////////////////////////////////////////////////////////////////////////////////////
696
/**
697
 * Specify several lists of vertices. Each list defines one polygon. (@see MeshPolygon).
698
 * If two such polygons share an edge (or several edges) then the edge in both of them is
699
 * marked 'up'.
700
 *
701
 * @param vertices   an array float[][]s, each specifying vertices of a single polygon.
702
 * @param band       see MeshPolygon. Shared among all polygons.
703
 * @param exBands    see MeshPolygon. Shared among all polygons.
704
 * @param exVertices see MeshPolygon. Shared among all polygons.
705
 */
706
  public MeshMultigon(float[][][] vertices, float[] band, int exBands, int exVertices)
707
    {
708
    super();
709

    
710
    int numTriangles=0;
711
    for(float[][] vertex : vertices) numTriangles+=vertex.length;
712
    MeshBandedTriangle[] triangles = new MeshBandedTriangle[numTriangles];
713

    
714
    int[][] edgesUp = computeEdgesUp(vertices);
715
    mOuterAndHoleVertices = computeOuterAndHoleVertices(vertices,edgesUp);
716

    
717
    computeEdgeVectors(vertices,edgesUp);
718

    
719
    boolean[][] vertsUp = computeVertsUp(vertices);
720
    float[][] centers = computeCenters(vertices);
721

    
722
    float[] vL = new float[2];
723
    float[] vR = new float[2];
724
    float[] vT = new float[2];
725
    float[] normL = new float[2];
726
    float[] normR = new float[2];
727

    
728
    int index=0,len = vertices.length;
729

    
730
    for(int i=0; i<len; i++)
731
      {
732
      int num=vertices[i].length;
733

    
734
      for(int j=0; j<num; j++)
735
        {
736
        int mode=computeMode(vL, vR, vT, normL, normR, edgesUp, vertsUp,vertices,centers, i,j);
737
        triangles[index++] = new MeshBandedTriangle(vL, vR, vT, band, normL, normR, mode, exBands, exVertices);
738
        }
739
      }
740

    
741
    join(triangles);
742
    mergeEffComponents();
743
    mergeTexComponents();
744
    }
745

    
746
///////////////////////////////////////////////////////////////////////////////////////////////////
747
/**
748
 * Copy constructor.
749
 */
750
  public MeshMultigon(MeshMultigon mesh, boolean deep)
751
    {
752
    super(mesh,deep);
753
    }
754

    
755
///////////////////////////////////////////////////////////////////////////////////////////////////
756
/**
757
 * Copy the Mesh.
758
 *
759
 * @param deep If to be a deep or shallow copy of mVertAttribs1, i.e. the array holding vertices,
760
 *             normals and inflates (the rest, in particular the mVertAttribs2 containing texture
761
 *             coordinates and effect associations, is always deep copied)
762
 */
763
  public MeshMultigon copy(boolean deep)
764
    {
765
    return new MeshMultigon(this,deep);
766
    }
767
 }
(7-7/12)