1 package jogamp.opengl.glu.nurbs;
2 
3 /*
4  ** License Applicability. Except to the extent portions of this file are
5  ** made subject to an alternative license as permitted in the SGI Free
6  ** Software License B, Version 2.0 (the "License"), the contents of this
7  ** file are subject only to the provisions of the License. You may not use
8  ** this file except in compliance with the License. You may obtain a copy
9  ** of the License at Silicon Graphics, Inc., attn: Legal Services, 1600
10  ** Amphitheatre Parkway, Mountain View, CA 94043-1351, or at:
11  **
12  ** http://oss.sgi.com/projects/FreeB
13  **
14  ** Note that, as provided in the License, the Software is distributed on an
15  ** "AS IS" basis, with ALL EXPRESS AND IMPLIED WARRANTIES AND CONDITIONS
16  ** DISCLAIMED, INCLUDING, WITHOUT LIMITATION, ANY IMPLIED WARRANTIES AND
17  ** CONDITIONS OF MERCHANTABILITY, SATISFACTORY QUALITY, FITNESS FOR A
18  ** PARTICULAR PURPOSE, AND NON-INFRINGEMENT.
19  **
20  ** Original Code. The Original Code is: OpenGL Sample Implementation,
21  ** Version 1.2.1, released January 26, 2000, developed by Silicon Graphics,
22  ** Inc. The Original Code is Copyright (c) 1991-2000 Silicon Graphics, Inc.
23  ** Copyright in any portions created by third parties is as indicated
24  ** elsewhere herein. All Rights Reserved.
25  **
26  ** Additional Notice Provisions: The application programming interfaces
27  ** established by SGI in conjunction with the Original Code are The
28  ** OpenGL(R) Graphics System: A Specification (Version 1.2.1), released
29  ** April 1, 1999; The OpenGL(R) Graphics System Utility Library (Version
30  ** 1.3), released November 4, 1998; and OpenGL(R) Graphics with the X
31  ** Window System(R) (Version 1.3), released October 19, 1998. This software
32  ** was created using the OpenGL(R) version 1.2.1 Sample Implementation
33  ** published by SGI, but has not been independently verified as being
34  ** compliant with the OpenGL(R) version 1.2.1 Specification.
35  */
36 
37 /**
38  * Class working with curves and surfaces
39  * @author Tomas Hrasky
40  *
41  */
42 public class Subdivider {
43   /**
44    * Cull type
45    */
46   public static final int CULL_TRIVIAL_REJECT = 0;
47 
48   /**
49    * Cull type
50    */
51   public static final int CULL_ACCEPT = 1;
52 
53   /**
54    * Maximum trimming arcs
55    */
56   private static final int MAXARCS = 10;
57 
58   /**
59    * Linked list of Quilts
60    */
61   Quilt qlist;
62 
63   /**
64    * Object holding rendering honts information
65    */
66   private Renderhints renderhints;
67 
68   /**
69    * Backend object
70    */
71   private Backend backend;
72 
73   /**
74    * Number of subdivisions
75    */
76   private int subdivisions;
77 
78   /**
79    * U step when using domain distance sampling
80    */
81   private float domain_distance_u_rate;
82 
83   /**
84    * Use domain distance sampling
85    */
86   private int is_domain_distance_sampling;
87 
88   /**
89    * Initial class holding trimming arcs
90    */
91   private Bin initialbin;
92 
93   /**
94    * Not used
95    */
96   private boolean showDegenerate;
97 
98   /**
99    * Is triming arc type bezier arc
100    */
101   private boolean isArcTypeBezier;
102 
103   /**
104    * Breakpoints in v direction
105    */
106   private Flist tpbrkpts;
107 
108   /**
109    * Breakpoints in u direction
110    */
111   private Flist spbrkpts;
112 
113   /**
114    * Unused
115    */
116   private int s_index;
117 
118   /**
119    * Head of linked list of trimming arcs
120    */
121   private Arc pjarc;
122 
123   /**
124    * Class tesselating trimming arcs
125    */
126   private ArcTesselator arctesselator;
127 
128   /**
129    * Unused
130    */
131   private int t_index;
132 
133   /**
134    * Breakpoints
135    */
136   private final Flist smbrkpts = new Flist();
137 
138   /**
139    * Not used
140    * private float[] stepsizes;
141    */
142 
143   /**
144    * Domain distance in V direction
145    */
146   private float domain_distance_v_rate;
147 
148   /**
149    * Initializes quilt list
150    */
beginQuilts(final Backend backend)151   public void beginQuilts(final Backend backend) {
152     // DONE
153     qlist = null;
154     renderhints = new Renderhints();
155     this.backend = backend;
156 
157     initialbin = new Bin();
158     arctesselator = new ArcTesselator();
159   }
160 
161   /**
162    * Adds quilt to linked list
163    * @param quilt added quilt
164    */
addQuilt(final Quilt quilt)165   public void addQuilt(final Quilt quilt) {
166     // DONE
167     if (qlist == null)
168       qlist = quilt;
169     else {
170       quilt.next = qlist;
171       qlist = quilt;
172     }
173 
174   }
175 
176   /**
177    * Empty method
178    */
endQuilts()179   public void endQuilts() {
180     // DONE
181   }
182 
183   /**
184    * Draws a surface
185    */
drawSurfaces()186   public void drawSurfaces() {
187     renderhints.init();
188 
189     if (qlist == null) {
190       //                System.out.println("qlist is null");
191       return;
192     }
193 
194     for (Quilt q = qlist; q != null; q = q.next) {
195       if (q.isCulled() == CULL_TRIVIAL_REJECT) {
196         freejarcs(initialbin);
197         return;
198       }
199     }
200 
201     final float[] from = new float[2];
202     final float[] to = new float[2];
203 
204     spbrkpts = new Flist();
205     tpbrkpts = new Flist();
206     qlist.getRange(from, to, spbrkpts, tpbrkpts);
207 
208     boolean optimize = (is_domain_distance_sampling > 0 && (renderhints.display_method != NurbsConsts.N_OUTLINE_PATCH));
209 
210     // TODO decide whether to optimize (when there is gluNurbsProperty implemented)
211     optimize = true;
212 
213     if (!initialbin.isnonempty()) {
214       if (!optimize) {
215         makeBorderTrim(from, to);
216       }
217     } else {
218       final float[] rate = new float[2];
219       qlist.findRates(spbrkpts, tpbrkpts, rate);
220       //                System.out.println("subdivider.drawsurfaces decompose");
221     }
222 
223     backend.bgnsurf(renderhints.wiretris, renderhints.wirequads);
224 
225     // TODO partition test
226 
227     if (!initialbin.isnonempty() && optimize) {
228 
229       int i, j;
230       int num_u_steps;
231       int num_v_steps;
232       for (i = spbrkpts.start; i < spbrkpts.end - 1; i++) {
233         for (j = tpbrkpts.start; j < tpbrkpts.end - 1; j++) {
234           final float[] pta = new float[2];
235           final float[] ptb = new float[2];
236 
237           pta[0] = spbrkpts.pts[i];
238           ptb[0] = spbrkpts.pts[i + 1];
239           pta[1] = tpbrkpts.pts[j];
240           ptb[1] = tpbrkpts.pts[j + 1];
241           qlist.downloadAll(pta, ptb, backend);
242 
243           num_u_steps = (int) (domain_distance_u_rate * (ptb[0] - pta[0]));
244           num_v_steps = (int) (domain_distance_v_rate * (ptb[1] - pta[1]));
245 
246           if (num_u_steps <= 0)
247             num_u_steps = 1;
248           if (num_v_steps <= 0)
249             num_v_steps = 1;
250 
251           backend.surfgrid(pta[0], ptb[0], num_u_steps, ptb[1],
252                            pta[1], num_v_steps);
253           backend.surfmesh(0, 0, num_u_steps, num_v_steps);
254 
255         }
256       }
257 
258     } else
259 
260       subdivideInS(initialbin);
261 
262     backend.endsurf();
263   }
264 
265   /**
266    * Empty method
267    * @param initialbin2
268    */
freejarcs(final Bin initialbin2)269   private void freejarcs(final Bin initialbin2) {
270     // TODO Auto-generated method stub
271     //            System.out.println("TODO subdivider.freejarcs");
272   }
273 
274   /**
275    * Subdivide in U direction
276    * @param source Trimming arcs source
277    */
subdivideInS(final Bin source)278   private void subdivideInS(final Bin source) {
279     // DONE
280     if (renderhints.display_method == NurbsConsts.N_OUTLINE_PARAM) {
281       outline(source);
282       freejarcs(source);
283     } else {
284       setArcTypeBezier();
285       setNonDegenerate();
286       splitInS(source, spbrkpts.start, spbrkpts.end);
287     }
288 
289   }
290 
291   /**
292    * Split in U direction
293    * @param source Trimming arcs source
294    * @param start breakpoints start
295    * @param end breakpoints end
296    */
splitInS(final Bin source, final int start, final int end)297   private void splitInS(final Bin source, final int start, final int end) {
298     // DONE
299     if (source.isnonempty()) {
300       if (start != end) {
301         final int i = start + (end - start) / 2;
302         final Bin left = new Bin();
303         final Bin right = new Bin();
304 
305         split(source, left, right, 0, spbrkpts.pts[i]);
306         splitInS(left, start, i);
307         splitInS(right, i + 1, end);
308       } else {
309         if (start == spbrkpts.start || start == spbrkpts.end) {
310           freejarcs(source);
311         } else if (renderhints.display_method == NurbsConsts.N_OUTLINE_PARAM_S) {
312           outline(source);
313           freejarcs(source);
314         } else {
315           setArcTypeBezier();
316           setNonDegenerate();
317           s_index = start;
318           splitInT(source, tpbrkpts.start, tpbrkpts.end);
319         }
320       }
321     } else{
322       //                System.out.println("Source is empty - subdivider.splitins");
323     }
324   }
325 
326   /**
327    * Split in V direction
328    * @param source
329    * @param start
330    * @param end
331    */
splitInT(final Bin source, final int start, final int end)332   private void splitInT(final Bin source, final int start, final int end) {
333     // TODO Auto-generated method stub
334     //            System.out.println("TODO subdivider.splitint");
335 
336     if (source.isnonempty()) {
337       if (start != end) {
338         final int i = start + (end - start) / 2;
339         final Bin left = new Bin();
340         final Bin right = new Bin();
341         split(source, left, right, 1, tpbrkpts.pts[i + 1]);
342         splitInT(left, start, i);
343         splitInT(right, i + 1, end);
344       } else {
345         if (start == tpbrkpts.start || start == tpbrkpts.end) {
346           freejarcs(source);
347         } else if (renderhints.display_method == NurbsConsts.N_OUTLINE_PARAM_ST) {
348           outline(source);
349           freejarcs(source);
350         } else {
351           t_index = start;
352           setArcTypeBezier();
353           setDegenerate();
354 
355           final float[] pta = new float[2];
356           final float[] ptb = new float[2];
357 
358           pta[0] = spbrkpts.pts[s_index - 1];
359           pta[1] = tpbrkpts.pts[t_index - 1];
360 
361           ptb[0] = spbrkpts.pts[s_index];
362           ptb[1] = tpbrkpts.pts[t_index];
363           qlist.downloadAll(pta, ptb, backend);
364 
365           final Patchlist patchlist = new Patchlist(qlist, pta, ptb);
366 
367           samplingSplit(source, patchlist,
368                         renderhints.maxsubdivisions, 0);
369           setNonDegenerate();
370           setArcTypeBezier();
371         }
372       }
373     }
374 
375   }
376 
377   /**
378    * Sample
379    * @param source
380    * @param patchlist
381    * @param subdivisions
382    * @param param
383    */
samplingSplit(final Bin source, final Patchlist patchlist, final int subdivisions, int param)384   private void samplingSplit(final Bin source, final Patchlist patchlist,
385                              final int subdivisions, int param) {
386     // DONE
387     if (!source.isnonempty())
388       return;
389     if (patchlist.cullCheck() == CULL_TRIVIAL_REJECT) {
390       freejarcs(source);
391       return;
392     }
393 
394     patchlist.getstepsize();
395     if (renderhints.display_method == NurbsConsts.N_OUTLINE_PATCH) {
396       tesselation(source, patchlist);
397       outline(source);
398       freejarcs(source);
399       return;
400     }
401 
402     tesselation(source, patchlist);
403     if (patchlist.needsSamplingSubdivision() && subdivisions > 0) {
404       if (!patchlist.needsSubdivision(0)) {
405         param = 1;
406       } else if (patchlist.needsSubdivision(1))
407         param = 0;
408       else
409         param = 1 - param;
410 
411       final Bin left = new Bin();
412       final Bin right = new Bin();
413 
414       final float mid = (float) ((patchlist.pspec[param].range[0] + patchlist.pspec[param].range[1]) * .5);
415 
416       split(source, left, right, param, mid);
417       final Patchlist subpatchlist = new Patchlist(patchlist, param, mid);
418       samplingSplit(left, subpatchlist, subdivisions - 1, param);
419       samplingSplit(right, subpatchlist, subdivisions - 1, param);
420     } else {
421       setArcTypePwl();
422       setDegenerate();
423       nonSamplingSplit(source, patchlist, subdivisions, param);
424       setDegenerate();
425       setArcTypeBezier();
426     }
427   }
428 
429   /**
430    * Not used
431    * @param source
432    * @param patchlist
433    * @param subdivisions
434    * @param param
435    */
nonSamplingSplit(final Bin source, final Patchlist patchlist, final int subdivisions, int param)436   private void nonSamplingSplit(final Bin source, final Patchlist patchlist,
437                                 final int subdivisions, int param) {
438     // DONE
439     if (patchlist.needsNonSamplingSubdivision() && subdivisions > 0) {
440       param = 1 - param;
441 
442       final Bin left = new Bin();
443       final Bin right = new Bin();
444 
445       final float mid = (float) ((patchlist.pspec[param].range[0] + patchlist.pspec[param].range[1]) * .5);
446       split(source, left, right, param, mid);
447       final Patchlist subpatchlist = new Patchlist(patchlist, param, mid);
448       if (left.isnonempty()) {
449         if (subpatchlist.cullCheck() == CULL_TRIVIAL_REJECT)
450           freejarcs(left);
451         else
452           nonSamplingSplit(left, subpatchlist, subdivisions - 1,
453                            param);
454       }
455       if (right.isnonempty()) {
456         if (patchlist.cullCheck() == CULL_TRIVIAL_REJECT)
457           freejarcs(right);
458         else
459           nonSamplingSplit(right, subpatchlist, subdivisions - 1,
460                            param);
461       }
462     } else {
463       patchlist.bbox();
464       backend.patch(patchlist.pspec[0].range[0],
465                     patchlist.pspec[0].range[1], patchlist.pspec[1].range[0],
466                     patchlist.pspec[1].range[1]);
467       if (renderhints.display_method == NurbsConsts.N_OUTLINE_SUBDIV) {
468         outline(source);
469         freejarcs(source);
470       } else {
471         setArcTypePwl();
472         setDegenerate();
473         findIrregularS(source);
474         monosplitInS(source, smbrkpts.start, smbrkpts.end);
475       }
476     }
477 
478   }
479 
480   /**
481    * Not used
482    * @param source
483    * @param start
484    * @param end
485    */
monosplitInS(final Bin source, final int start, final int end)486   private void monosplitInS(final Bin source, final int start, final int end) {
487     // TODO Auto-generated method stub
488     //            System.out.println("TODO subdivider.monosplitins");
489   }
490 
491   /**
492    * Not used
493    * @param source
494    */
findIrregularS(final Bin source)495   private void findIrregularS(final Bin source) {
496     // TODO Auto-generated method stub
497     //            System.out.println("TODO subdivider.findIrregularS");
498   }
499 
500   /**
501    * Not used
502    */
setArcTypePwl()503   private void setArcTypePwl() {
504     // TODO Auto-generated method stub
505     //            System.out.println("TODO subdivider.setarctypepwl");
506   }
507 
508   /**
509    * Not used
510    * @param source
511    * @param patchlist
512    */
tesselation(final Bin source, final Patchlist patchlist)513   private void tesselation(final Bin source, final Patchlist patchlist) {
514     // TODO Auto-generated method stub
515     //            System.out.println("TODO subdivider.tesselation");
516   }
517 
518   /**
519    * Not used
520    */
setDegenerate()521   private void setDegenerate() {
522     // TODO Auto-generated method stub
523     //            System.out.println("TODO subdivider.setdegenerate");
524   }
525 
526   /**
527    * Not used
528    * @param bin
529    * @param left
530    * @param right
531    * @param param
532    * @param value
533    */
split(final Bin bin, final Bin left, final Bin right, final int param, final float value)534   private void split(final Bin bin, final Bin left, final Bin right, final int param, final float value) {
535     // DONE
536     final Bin intersections = new Bin();
537     final Bin unknown = new Bin();
538 
539     partition(bin, left, intersections, right, unknown, param, value);
540 
541     final int count = intersections.numarcs();
542     // TODO jumpbuffer ??
543 
544     if (count % 2 == 0) {
545 
546       final Arc[] arclist = new Arc[MAXARCS];
547       CArrayOfArcs list;
548       if (count >= MAXARCS) {
549         list = new CArrayOfArcs(new Arc[count]);
550       } else {
551         list = new CArrayOfArcs(arclist);
552       }
553 
554       CArrayOfArcs last, lptr;
555       Arc jarc;
556 
557       for (last = new CArrayOfArcs(list); (jarc = intersections
558                                            .removearc()) != null; last.pp())
559         last.set(jarc);
560 
561       if (param == 0) {// sort into incrasing t order
562         final ArcSdirSorter sorter = new ArcSdirSorter(this);
563         sorter.qsort(list, count);
564 
565         for (lptr = new CArrayOfArcs(list); lptr.getPointer() < last
566                .getPointer(); lptr.raisePointerBy(2))
567           check_s(lptr.get(), lptr.getRelative(1));
568         for (lptr = new CArrayOfArcs(list); lptr.getPointer() < last
569                .getPointer(); lptr.raisePointerBy(2))
570           join_s(left, right, lptr.get(), lptr.getRelative(1));
571         for (lptr = new CArrayOfArcs(list); lptr.getPointer() != last
572                .getPointer(); lptr.pp()) {
573           if (lptr.get().head()[0] <= value
574               && lptr.get().tail()[0] <= value)
575             left.addarc(lptr.get());
576           else
577             right.addarc(lptr.get());
578         }
579 
580       } else {// sort into decreasing s order
581         final ArcTdirSorter sorter = new ArcTdirSorter(this);
582         sorter.qsort(list, count);
583 
584         for (lptr = new CArrayOfArcs(list); lptr.getPointer() < last
585                .getPointer(); lptr.raisePointerBy(2))
586           check_t(lptr.get(), lptr.getRelative(1));
587         for (lptr = new CArrayOfArcs(list); lptr.getPointer() < last
588                .getPointer(); lptr.raisePointerBy(2))
589           join_t(left, right, lptr.get(), lptr.getRelative(1));
590         for (lptr = new CArrayOfArcs(list); lptr.getPointer() != last
591                .getPointer(); lptr.raisePointerBy(2)) {
592           if (lptr.get().head()[0] <= value
593               && lptr.get().tail()[0] <= value)
594             left.addarc(lptr.get());
595           else
596             right.addarc(lptr.get());
597         }
598 
599       }
600 
601       unknown.adopt();
602     }
603   }
604 
605   /**
606    * Not used
607    * @param left
608    * @param right
609    * @param arc
610    * @param relative
611    */
join_t(final Bin left, final Bin right, final Arc arc, final Arc relative)612   private void join_t(final Bin left, final Bin right, final Arc arc, final Arc relative) {
613     // TODO Auto-generated method stub
614     //            System.out.println("TODO subdivider.join_t");
615   }
616 
617   /**
618    * Not used
619    * @param arc
620    * @param relative
621    */
check_t(final Arc arc, final Arc relative)622   private void check_t(final Arc arc, final Arc relative) {
623     // TODO Auto-generated method stub
624     //            System.out.println("TODO subdivider.check_t");
625   }
626 
627   /**
628    * Not used
629    * @param left
630    * @param right
631    * @param jarc1
632    * @param jarc2
633    */
join_s(final Bin left, final Bin right, Arc jarc1, Arc jarc2)634   private void join_s(final Bin left, final Bin right, Arc jarc1, Arc jarc2) {
635     // DONE
636     if (!jarc1.getitail())
637       jarc1 = jarc1.next;
638     if (!jarc2.getitail())
639       jarc2 = jarc2.next;
640 
641     final float s = jarc1.tail()[0];
642     final float t1 = jarc1.tail()[1];
643     final float t2 = jarc2.tail()[1];
644 
645     if (t1 == t2) {
646       simplelink(jarc1, jarc2);
647     } else {
648       final Arc newright = new Arc(Arc.ARC_RIGHT);
649       final Arc newleft = new Arc(Arc.ARC_LEFT);
650       if (isBezierArcType()) {
651         arctesselator.bezier(newright, s, s, t1, t2);
652         arctesselator.bezier(newleft, s, s, t2, t1);
653       } else {
654         arctesselator.pwl_right(newright, s, t1, t2, 0 /* stepsizes[0] */);
655         arctesselator.pwl_left(newright, s, t2, t1, 0 /* stepsizes[2] */);
656       }
657       link(jarc1, jarc2, newright, newleft);
658       left.addarc(newright);
659       right.addarc(newleft);
660     }
661 
662   }
663 
664   /**
665    * Not used
666    * @param jarc1
667    * @param jarc2
668    * @param newright
669    * @param newleft
670    */
link(final Arc jarc1, final Arc jarc2, final Arc newright, final Arc newleft)671   private void link(final Arc jarc1, final Arc jarc2, final Arc newright, final Arc newleft) {
672     // TODO Auto-generated method stub
673     //            System.out.println("TODO subdivider.link");
674   }
675 
676   /**
677    * Not used
678    * @return true
679    */
isBezierArcType()680   private boolean isBezierArcType() {
681     // TODO Auto-generated method stub
682     //            System.out.println("TODO subdivider.isbezierarc");
683     return true;
684   }
685 
686   /**
687    * Not used
688    * @param jarc1
689    * @param jarc2
690    */
simplelink(final Arc jarc1, final Arc jarc2)691   private void simplelink(final Arc jarc1, final Arc jarc2) {
692     // TODO Auto-generated method stub
693     //            System.out.println("TODO subdivider.simplelink");
694   }
695 
696   /**
697    * Not used
698    * @param arc
699    * @param relative
700    */
check_s(final Arc arc, final Arc relative)701   private void check_s(final Arc arc, final Arc relative) {
702     // TODO Auto-generated method stub
703     //            System.out.println("TODO subdivider.check_s");
704 
705   }
706 
707   /**
708    * Not used
709    * @param bin
710    * @param left
711    * @param intersections
712    * @param right
713    * @param unknown
714    * @param param
715    * @param value
716    */
partition(final Bin bin, final Bin left, final Bin intersections, final Bin right, final Bin unknown, final int param, final float value)717   private void partition(final Bin bin, final Bin left, final Bin intersections, final Bin right,
718                          final Bin unknown, final int param, final float value) {
719 
720     final Bin headonleft = new Bin();
721     final Bin headonright = new Bin();
722     final Bin tailonleft = new Bin();
723     final Bin tailonright = new Bin();
724 
725     for (Arc jarc = bin.removearc(); jarc != null; jarc = bin.removearc()) {
726       final float tdiff = jarc.tail()[param] - value;
727       final float hdiff = jarc.head()[param] - value;
728 
729       if (tdiff > 0) {
730         if (hdiff > 0) {
731           right.addarc(jarc);
732         } else if (hdiff == 0) {
733           tailonright.addarc(jarc);
734         } else {
735           switch (arc_split(jarc, param, value, 0)) {
736           case 2:
737             tailonright.addarc(jarc);
738             headonleft.addarc(jarc.next);
739             break;
740             // TODO rest cases
741           default:
742             System.out
743               .println("TODO subdivider.partition rest cases");
744             break;
745           }
746         }
747       } else if (tdiff == 0) {
748         if (hdiff > 0) {
749           headonright.addarc(jarc);
750         } else if (hdiff == 0) {
751           unknown.addarc(jarc);
752         } else {
753           headonright.addarc(jarc);
754         }
755       } else {
756         if (hdiff > 0) {
757           // TODO rest
758           //                        System.out.println("TODO subdivider.partition rest of else");
759         } else if (hdiff == 0) {
760           tailonleft.addarc(jarc);
761         } else {
762           left.addarc(jarc);
763         }
764       }
765 
766     }
767     if (param == 0) {
768       classify_headonleft_s(headonleft, intersections, left, value);
769       classify_tailonleft_s(tailonleft, intersections, left, value);
770       classify_headonright_s(headonright, intersections, right, value);
771       classify_tailonright_s(tailonright, intersections, right, value);
772     } else {
773       classify_headonleft_t(headonleft, intersections, left, value);
774       classify_tailonleft_t(tailonleft, intersections, left, value);
775       classify_headonright_t(headonright, intersections, right, value);
776       classify_tailonright_t(tailonright, intersections, right, value);
777     }
778   }
779 
780   /**
781    * Not used
782    * @param tailonright
783    * @param intersections
784    * @param right
785    * @param value
786    */
classify_tailonright_t(final Bin tailonright, final Bin intersections, final Bin right, final float value)787   private void classify_tailonright_t(final Bin tailonright, final Bin intersections,
788                                       final Bin right, final float value) {
789     // TODO Auto-generated method stub
790     //            System.out.println("TODO subdivider.classify_tailonright_t");
791 
792   }
793 
794   /**
795    * Not used
796    * @param bin
797    * @param in
798    * @param out
799    * @param val
800    */
classify_tailonleft_s(final Bin bin, final Bin in, final Bin out, final float val)801   private void classify_tailonleft_s(final Bin bin, final Bin in, final Bin out, final float val) {
802 
803     // DONE
804     Arc j;
805     while ((j = bin.removearc()) != null) {
806       j.clearitail();
807 
808       final float diff = j.next.head()[0] - val;
809       if (diff > 0) {
810         in.addarc(j);
811       } else if (diff < 0) {
812         if (ccwTurn_sl(j, j.next))
813           out.addarc(j);
814         else
815           in.addarc(j);
816       } else {
817         if (j.next.tail()[1] > j.next.head()[1])
818           in.addarc(j);
819         else
820           out.addarc(j);
821       }
822     }
823 
824   }
825 
826   /**
827    * Not used
828    * @param bin
829    * @param in
830    * @param out
831    * @param val
832    */
classify_headonright_s(final Bin bin, final Bin in, final Bin out, final float val)833   private void classify_headonright_s(final Bin bin, final Bin in, final Bin out, final float val) {
834     // DONE
835     Arc j;
836     while ((j = bin.removearc()) != null) {
837       j.setitail();
838 
839       final float diff = j.prev.tail()[0] - val;
840       if (diff > 0) {
841         if (ccwTurn_sr(j.prev, j))
842           out.addarc(j);
843         else
844           in.addarc(j);
845       } else if (diff < 0) {
846         out.addarc(j);
847       } else {
848         if (j.prev.tail()[1] > j.prev.head()[1])
849           out.addarc(j);
850         else
851           in.addarc(j);
852       }
853     }
854   }
855 
856   /**
857    * Not used
858    * @param prev
859    * @param j
860    * @return false
861    */
ccwTurn_sr(final Arc prev, final Arc j)862   private boolean ccwTurn_sr(final Arc prev, final Arc j) {
863     // TODO Auto-generated method stub
864     //            System.out.println("TODO ccwTurn_sr");
865     return false;
866   }
867 
868   /**
869    * Not used
870    * @param headonright
871    * @param intersections
872    * @param right
873    * @param value
874    */
classify_headonright_t(final Bin headonright, final Bin intersections, final Bin right, final float value)875   private void classify_headonright_t(final Bin headonright, final Bin intersections,
876                                       final Bin right, final float value) {
877     // TODO Auto-generated method stub
878     //            System.out.println("TODO subdivider.classify_headonright_t");
879   }
880 
881   /**
882    * Not used
883    * @param tailonleft
884    * @param intersections
885    * @param left
886    * @param value
887    */
classify_tailonleft_t(final Bin tailonleft, final Bin intersections, final Bin left, final float value)888   private void classify_tailonleft_t(final Bin tailonleft, final Bin intersections,
889                                      final Bin left, final float value) {
890     // TODO Auto-generated method stub
891     //            System.out.println("TODO subdivider.classify_tailonleft_t");
892   }
893 
894   /**
895    * Not used
896    * @param bin
897    * @param in
898    * @param out
899    * @param val
900    */
classify_headonleft_t(final Bin bin, final Bin in, final Bin out, final float val)901   private void classify_headonleft_t(final Bin bin, final Bin in, final Bin out, final float val) {
902     // DONE
903     Arc j;
904     while ((j = bin.removearc()) != null) {
905       j.setitail();
906 
907       final float diff = j.prev.tail()[1] - val;
908       if (diff > 0) {
909         out.addarc(j);
910       } else if (diff < 0) {
911         if (ccwTurn_tl(j.prev, j))
912           out.addarc(j);
913         else
914           in.addarc(j);
915       } else {
916         if (j.prev.tail()[0] > j.prev.head()[0])
917           out.addarc(j);
918         else
919           in.addarc(j);
920       }
921     }
922   }
923 
924   /**
925    * Not used
926    * @param prev
927    * @param j
928    * @return false
929    */
ccwTurn_tl(final Arc prev, final Arc j)930   private boolean ccwTurn_tl(final Arc prev, final Arc j) {
931     // TODO Auto-generated method stub
932     //            System.out.println("TODO subdivider.ccwTurn_tl");
933     return false;
934   }
935 
936   /**
937    * Not used
938    * @param bin
939    * @param in
940    * @param out
941    * @param val
942    */
classify_tailonright_s(final Bin bin, final Bin in, final Bin out, final float val)943   private void classify_tailonright_s(final Bin bin, final Bin in, final Bin out, final float val) {
944     // DONE
945     Arc j;
946     while ((j = bin.removearc()) != null) {
947       j.clearitail();
948 
949       final float diff = j.next.head()[0] - val;
950       if (diff > 0) {
951         if (ccwTurn_sr(j, j.next))
952           out.addarc(j);
953         else
954           in.addarc(j);
955       } else if (diff < 0) {
956         in.addarc(j);
957       } else {
958         if (j.next.tail()[1] > j.next.head()[1])
959           out.addarc(j);
960         else
961           in.addarc(j);
962       }
963     }
964 
965   }
966 
967   /**
968    * Not used
969    * @param bin
970    * @param in
971    * @param out
972    * @param val
973    */
classify_headonleft_s(final Bin bin, final Bin in, final Bin out, final float val)974   private void classify_headonleft_s(final Bin bin, final Bin in, final Bin out, final float val) {
975     // DONE
976     Arc j;
977     while ((j = bin.removearc()) != null) {
978       j.setitail();
979 
980       final float diff = j.prev.tail()[0] - val;
981       if (diff > 0) {
982         out.addarc(j);
983       } else if (diff < 0) {
984         if (ccwTurn_sl(j.prev, j))
985           out.addarc(j);
986         else
987           in.addarc(j);
988       } else {
989         if (j.prev.tail()[1] > j.prev.head()[1])
990           in.addarc(j);
991         else
992           out.addarc(j);
993       }
994     }
995 
996   }
997 
998   /**
999    * Not used
1000    * @param prev
1001    * @param j
1002    * @return false
1003    */
ccwTurn_sl(final Arc prev, final Arc j)1004   private boolean ccwTurn_sl(final Arc prev, final Arc j) {
1005     // TODO Auto-generated method stub
1006     //            System.out.println("TODO subdivider.ccwTurn_sl");
1007     return false;
1008   }
1009 
1010   /**
1011    * Not used
1012    * @param jarc
1013    * @param param
1014    * @param value
1015    * @param i
1016    * @return 0
1017    */
arc_split(final Arc jarc, final int param, final float value, final int i)1018   private int arc_split(final Arc jarc, final int param, final float value, final int i) {
1019     // TODO Auto-generated method stub
1020     //            System.out.println("TODO subdivider.arc_split");
1021     return 0;
1022   }
1023 
1024   /**
1025    * Not used
1026    */
setNonDegenerate()1027   private void setNonDegenerate() {
1028     // DONE
1029     this.showDegenerate = false;
1030 
1031   }
1032 
1033   /**
1034    * sets trimming arc default type to bezier
1035    */
setArcTypeBezier()1036   private void setArcTypeBezier() {
1037     // DONE
1038     isArcTypeBezier = true;
1039   }
1040 
1041   /**
1042    * Not used
1043    * @param source
1044    */
outline(final Bin source)1045   private void outline(final Bin source) {
1046     // TODO Auto-generated method stub
1047     //            System.out.println("TODO subdivider.outline");
1048   }
1049 
1050   /**
1051    * Makes default trim along surface borders
1052    * @param from range beginnings
1053    * @param to range ends
1054    */
makeBorderTrim(final float[] from, final float[] to)1055   private void makeBorderTrim(final float[] from, final float[] to) {
1056     // DONE
1057     final float smin = from[0];
1058     final float smax = to[0];
1059 
1060     final float tmin = from[1];
1061     final float tmax = to[1];
1062 
1063     pjarc = null;
1064     Arc jarc = null;
1065 
1066     jarc = new Arc(Arc.ARC_BOTTOM);
1067     arctesselator.bezier(jarc, smin, smax, tmin, tmin);
1068     initialbin.addarc(jarc);
1069     pjarc = jarc.append(pjarc);
1070 
1071     jarc = new Arc(Arc.ARC_RIGHT);
1072     arctesselator.bezier(jarc, smax, smax, tmin, tmax);
1073     initialbin.addarc(jarc);
1074     pjarc = jarc.append(pjarc);
1075 
1076     jarc = new Arc(Arc.ARC_TOP);
1077     arctesselator.bezier(jarc, smax, smin, tmax, tmax);
1078     initialbin.addarc(jarc);
1079     pjarc = jarc.append(pjarc);
1080 
1081     jarc = new Arc(Arc.ARC_LEFT);
1082     arctesselator.bezier(jarc, smin, smin, tmax, tmin);
1083     initialbin.addarc(jarc);
1084     jarc = jarc.append(pjarc);
1085 
1086     // assert (jarc.check() == true);
1087   }
1088 
1089   /**
1090    * Draws NURBS curve
1091    */
drawCurves()1092   public void drawCurves() {
1093     // DONE
1094     final float[] from = new float[1];
1095     final float[] to = new float[1];
1096 
1097     final Flist bpts = new Flist();
1098     qlist.getRange(from, to, bpts);
1099 
1100     renderhints.init();
1101 
1102     backend.bgncurv();
1103 
1104     for (int i = bpts.start; i < bpts.end - 1; i++) {
1105       final float[] pta = new float[1];
1106       final float[] ptb = new float[1];
1107       pta[0] = bpts.pts[i];
1108       ptb[0] = bpts.pts[i + 1];
1109 
1110       qlist.downloadAll(pta, ptb, backend);
1111       final Curvelist curvelist = new Curvelist(qlist, pta, ptb);
1112       samplingSplit(curvelist, renderhints.maxsubdivisions);
1113     }
1114     backend.endcurv();
1115   }
1116 
1117   /**
1118    * Samples a curve in case of need, or sends curve to backend
1119    * @param curvelist list of curves
1120    * @param maxsubdivisions maximum number of subdivisions
1121    */
samplingSplit(final Curvelist curvelist, final int maxsubdivisions)1122   private void samplingSplit(final Curvelist curvelist, final int maxsubdivisions) {
1123     if (curvelist.cullCheck() == CULL_TRIVIAL_REJECT)
1124       return;
1125 
1126     curvelist.getstepsize();
1127 
1128     if (curvelist.needsSamplingSubdivision() && (subdivisions > 0)) {
1129       // TODO kód
1130       //                System.out.println("TODO subdivider-needsSamplingSubdivision");
1131     } else {
1132       final int nu = (int) (1 + curvelist.range[2] / curvelist.stepsize);
1133       backend.curvgrid(curvelist.range[0], curvelist.range[1], nu);
1134       backend.curvmesh(0, nu);
1135     }
1136 
1137   }
1138 
1139   /**
1140    * Sets new domain_distance_u_rate value
1141    * @param d new domain_distance_u_rate value
1142 
1143   */
set_domain_distance_u_rate(final double d)1144   public void set_domain_distance_u_rate(final double d) {
1145     // DONE
1146     domain_distance_u_rate = (float) d;
1147   }
1148 
1149   /**
1150    * Sets new domain_distance_v_rate value
1151    * @param d new domain_distance_v_rate value
1152    */
set_domain_distance_v_rate(final double d)1153   public void set_domain_distance_v_rate(final double d) {
1154     // DONE
1155     domain_distance_v_rate = (float) d;
1156   }
1157 
1158   /**
1159    * Sets new is_domain_distance_sampling value
1160    * @param i new is_domain_distance_sampling value
1161    */
set_is_domain_distance_sampling(final int i)1162   public void set_is_domain_distance_sampling(final int i) {
1163     // DONE
1164     this.is_domain_distance_sampling = i;
1165   }
1166 }
1167