Code-Eli  0.3.6
piecewise.hpp
Go to the documentation of this file.
1 /*********************************************************************************
2 * Copyright (c) 2013 David D. Marshall <ddmarsha@calpoly.edu>
3 *
4 * All rights reserved. This program and the accompanying materials
5 * are made available under the terms of the Eclipse Public License v1.0
6 * which accompanies this distribution, and is available at
7 * http://www.eclipse.org/legal/epl-v10.html
8 *
9 * Contributors:
10 * David D. Marshall - initial code and implementation
11 ********************************************************************************/
12 
13 #ifndef eli_geom_surface_piecewise_hpp
14 #define eli_geom_surface_piecewise_hpp
15 
16 #include <vector>
17 #include <iterator>
18 #include <utility>
19 #include <algorithm>
20 
21 #include "eli/code_eli.hpp"
22 
23 #include "eli/util/tolerance.hpp"
25 
28 
29 namespace eli
30 {
31  namespace geom
32  {
33 
34  namespace surface
35  {
36  template<template<typename, unsigned short, typename> class surface__, typename data__, unsigned short dim__, typename tol__ >
37  class piecewise;
38  }
39 
40  namespace intersect
41  {
42  template<template<typename, unsigned short, typename> class surface1__, typename data1__, unsigned short dim1__, typename tol1__ >
49  }
50 
51  namespace surface
52  {
53  template<template<typename, unsigned short, typename> class surface__, typename data__, unsigned short dim__, typename tol__=eli::util::tolerance<data__> >
54  class piecewise
55  {
56  public:
57  typedef surface__<data__, dim__, tol__> surface_type;
58  typedef typename surface_type::index_type index_type;
59  typedef typename surface_type::point_type point_type;
60  typedef typename surface_type::control_point_type control_point_type;
61  typedef typename surface_type::rotation_matrix_type rotation_matrix_type;
62  typedef typename surface_type::bounding_box_type bounding_box_type;
63  typedef typename surface_type::curve_type curve_type;
65 
66  typedef data__ data_type;
67  typedef unsigned short dimension_type;
68  typedef tol__ tolerance_type;
70  {
78  };
79 
80  public:
81  piecewise() : nu(0), nv(0) {}
83  : patches(p.patches), ukey(p.ukey), vkey(p.vkey), nu(p.nu), nv(p.nv) {}
85 
87  {
88  if (this==&p)
89  return (*this);
90 
91  patches=p.patches;
92  ukey=p.ukey;
93  vkey=p.vkey;
94  nu=p.nu;
95  nv=p.nv;
96 
97  return (*this);
98  }
99 
101  {
102  if (this==&p)
103  return true;
104  if (nu!=p.nu)
105  return false;
106  if (nv!=p.nv)
107  return false;
108  if (ukey!=p.ukey)
109  return false;
110  if (vkey!=p.vkey)
111  return false;
112  if (number_u_patches()!=p.number_u_patches())
113  return false;
114  if (number_v_patches()!=p.number_v_patches())
115  return false;
116  typename patch_collection_type::const_iterator scit, it;
117  for (scit=patches.begin(), it=p.patches.begin(); scit!=patches.end(); ++scit, ++it)
118  {
119  if ((*it)!=(*scit))
120  return false;
121  }
122 
123  return true;
124  }
125 
127  {
128  return !operator==(p);
129  }
130 
131  static dimension_type dimension() {return dim__;}
132 
133  data_type get_u0() const {return ukey.get_pmin();}
134  void set_u0(const data_type &u0_in) {ukey.set_pmin(u0_in);}
135 
136  data_type get_v0() const {return vkey.get_pmin();}
137  void set_v0(const data_type &v0_in) {vkey.set_pmin(v0_in);}
138 
139  data_type get_umax() const {return ukey.get_pmax();}
140  data_type get_vmax() const {return vkey.get_pmax();}
141 
142  index_type number_u_patches() const {return nu;}
143  index_type number_v_patches() const {return nv;}
144 
145  surface_type * get_patch( const index_type &ui, const index_type &vi)
146  {
147  index_type uk, vk;
148  find_patch(uk, vk, ui, vi);
149  return &patches[uk][vk];
150  }
151 
152  const surface_type * get_patch( const index_type &ui, const index_type &vi) const
153  {
154  index_type uk, vk;
155  find_patch(uk, vk, ui, vi);
156  return &patches[uk][vk];
157  }
158 
159  surface_type * get_patch_unordered( const index_type &uk, const index_type &vk)
160  {
161  return &patches[uk][vk];
162  }
163 
164  const surface_type * get_patch_unordered( const index_type &uk, const index_type &vk) const
165  {
166  return &patches[uk][vk];
167  }
168 
169  void get_parameter_min(data_type &umin, data_type &vmin) const
170  {
171  umin=ukey.get_pmin();
172  vmin=vkey.get_pmin();
173  }
174 
175  void get_parameter_max(data_type &umax, data_type &vmax) const
176  {
177  umax=ukey.get_pmax();
178  vmax=vkey.get_pmax();
179  }
180 
182  {
183  printf("U parameter:\n");
185  printf("V parameter:\n");
187  }
188 
189  void get_pmap_u(std::vector<data_type> &pmap) const
190  {
191  ukey.get_pmap(pmap);
192  }
193 
194  void get_pmap_v(std::vector<data_type> &pmap) const
195  {
196  vkey.get_pmap(pmap);
197  }
198 
199  void get_pmap_uv(std::vector<data_type> &upmap, std::vector<data_type> &vpmap) const
200  {
201  ukey.get_pmap(upmap);
202  vkey.get_pmap(vpmap);
203  }
204 
205  void init_u(const index_type &nsegu, const data_type &du = 1, const data_type &u0 = 0)
206  {
207  patches.clear();
208  resize_store(nsegu, nv);
209  ukey.init(nsegu, du, u0);
210  }
211 
212  void init_v(const index_type &nsegv, const data_type &dv = 1, const data_type &v0 = 0)
213  {
214  patches.clear();
215  resize_store(nu, nsegv);
216  vkey.init(nsegv, dv, v0);
217  }
218 
219  void init_uv(const index_type &nsegu, const index_type &nsegv, const data_type &du = 1, const data_type &dv = 1, const data_type &u0 = 0, const data_type &v0 = 0)
220  {
221  patches.clear();
222  resize_store(nsegu, nsegv);
223  ukey.init(nsegu, du, u0);
224  vkey.init(nsegv, dv, v0);
225  }
226 
227  template<typename it__>
228  void init_u(const it__ &dus, const it__ &due, const data_type &u0 = 0)
229  {
230  patches.clear();
231  ukey.init(dus, due, u0);
232  resize_store(ukey.key.size(), nv);
233  }
234 
235  template<typename it__>
236  void init_v(const it__ &dvs, const it__ &dve, const data_type &v0 = 0)
237  {
238  patches.clear();
239  vkey.init(dvs, dve, v0);
240  resize_store(nu, vkey.key.size());
241  }
242 
243  template<typename it__>
244  void init_uv(const it__ &dus, const it__ &due, const it__ &dvs, const it__ &dve, const data_type &u0 = 0, const data_type &v0 = 0)
245  {
246  patches.clear();
247  ukey.init(dus, due, u0);
248  vkey.init(dvs, dve, v0);
249  resize_store(ukey.key.size(), vkey.key.size());
250  }
251 
252  void degree_u(index_type &mind, index_type &maxd)
253  {
254  typename patch_collection_type::iterator uit;
255  typename patch_strip_type::iterator vit;
256 
257  uit=patches.begin();
258  vit=(*uit).begin();
259 
260  index_type d = vit->degree_u();
261  mind = d;
262  maxd = d;
263 
264  for (uit=patches.begin(); uit!=patches.end(); ++uit)
265  {
266  for (vit=(*uit).begin(); vit!=(*uit).end(); ++vit)
267  {
268  d = vit->degree_u();
269 
270  if(d<mind)
271  {
272  mind = d;
273  }
274  if(d>maxd)
275  {
276  maxd=d;
277  }
278  }
279  }
280  }
281 
282  void degree_v(index_type &mind, index_type &maxd)
283  {
284  typename patch_collection_type::iterator uit;
285  typename patch_strip_type::iterator vit;
286 
287  uit=patches.begin();
288  vit=(*uit).begin();
289 
290  index_type d = vit->degree_v();
291  mind = d;
292  maxd = d;
293 
294  for (uit=patches.begin(); uit!=patches.end(); ++uit)
295  {
296  for (vit=(*uit).begin(); vit!=(*uit).end(); ++vit)
297  {
298  d = vit->degree_v();
299 
300  if(d<mind)
301  {
302  mind = d;
303  }
304  if(d>maxd)
305  {
306  maxd=d;
307  }
308  }
309  }
310  }
311 
312  bool open_u() const
313  {
314  return !closed_u();
315  }
316  bool closed_u() const
317  {
318  index_type ifirst, ilast, j;
319  typename surface_type::curve_type bc0, bc1;
320 
321  ifirst = ukey.key.begin()->second;
322  ilast = ukey.key.rbegin()->second;
323 
324  for (j=0; j<nv; ++j)
325  {
326  patches[ifirst][j].get_uconst_curve(bc0, 0);
327  patches[ilast][j].get_uconst_curve(bc1, 1);
329  return false;
330  }
331 
332  return true;
333  }
334 
335  bool open_v() const
336  {
337  return !closed_v();
338  }
339  bool closed_v() const
340  {
341  index_type i, jfirst, jlast;
342  typename surface_type::curve_type bc0, bc1;
343 
344  jfirst = vkey.key.begin()->second;
345  jlast = vkey.key.rbegin()->second;
346 
347  for (i=0; i<nu; ++i)
348  {
349  patches[i][jfirst].get_vconst_curve(bc0, 0);
350  patches[i][jlast].get_vconst_curve(bc1, 1);
352  {
353  return false;
354  }
355  }
356 
357  return true;
358  }
359 
360  void get_bounding_box(bounding_box_type &bb) const
361  {
362  typename patch_collection_type::const_iterator uit;
363  typename patch_strip_type::const_iterator vit;
364  bounding_box_type bb_local;
365 
366  bb.clear();
367 
368  // cycle through all patches to get each bounding box to compare
369  for (uit=patches.begin(); uit!=patches.end(); ++uit)
370  {
371  for (vit=(*uit).begin(); vit!=(*uit).end(); ++vit)
372  {
373  vit->get_bounding_box(bb_local);
374  bb.add(bb_local);
375  }
376  }
377  }
378 
379  void rotate(const rotation_matrix_type &rmat)
380  {
381  typename patch_collection_type::iterator uit;
382  typename patch_strip_type::iterator vit;
383 
384  for (uit=patches.begin(); uit!=patches.end(); ++uit)
385  {
386  for (vit=(*uit).begin(); vit!=(*uit).end(); ++vit)
387  {
388  vit->rotate(rmat);
389  }
390  }
391  }
392 
393  void rotate(const rotation_matrix_type &rmat, const point_type &rorig)
394  {
395  typename patch_collection_type::iterator uit;
396  typename patch_strip_type::iterator vit;
397 
398  for (uit=patches.begin(); uit!=patches.end(); ++uit)
399  {
400  for (vit=(*uit).begin(); vit!=(*uit).end(); ++vit)
401  {
402  vit->rotate(rmat, rorig);
403  }
404  }
405  }
406 
407  void translate(const point_type &trans)
408  {
409  typename patch_collection_type::iterator uit;
410  typename patch_strip_type::iterator vit;
411 
412  for (uit=patches.begin(); uit!=patches.end(); ++uit)
413  {
414  for (vit=(*uit).begin(); vit!=(*uit).end(); ++vit)
415  {
416  vit->translate(trans);
417  }
418  }
419  }
420 
421  void reverse_u()
422  {
423  typename patch_collection_type::iterator uit;
424  typename patch_strip_type::iterator vit;
425 
426  for (uit=patches.begin(); uit!=patches.end(); ++uit)
427  {
428  for (vit=(*uit).begin(); vit!=(*uit).end(); ++vit)
429  {
430  vit->reverse_u();
431  }
432  }
434  }
435 
436  void reverse_v()
437  {
438  typename patch_collection_type::iterator uit;
439  typename patch_strip_type::iterator vit;
440 
441  for (uit=patches.begin(); uit!=patches.end(); ++uit)
442  {
443  for (vit=(*uit).begin(); vit!=(*uit).end(); ++vit)
444  {
445  vit->reverse_v();
446  }
447  }
449  }
450 
451  void swap_uv()
452  {
453  patch_collection_type old_patches;
454  old_patches.swap(patches);
455 
456  index_type nu_old(nu), nv_old(nv);
457 
458  // Resizes patches and also assigns nu, nv.
459  resize_store(nv_old, nu_old);
460 
461  for (index_type i=0; i<nu; ++i)
462  {
463  for (index_type j=0; j<nv; ++j)
464  {
465  patches[i][j]=old_patches[j][i];
466  patches[i][j].swap_uv();
467  }
468  }
469 
470  data_type pmaxtmp;
471  pmaxtmp = ukey.pmax;
472  ukey.pmax = vkey.pmax;
473  vkey.pmax = pmaxtmp;
474 
475  swap(ukey.key, vkey.key);
476  }
477 
478  void clear()
479  {
480  nu=0;
481  nv=0;
482  patches.clear();
483  ukey.clear();
484  vkey.clear();
485  }
486 
487  error_code get(surface_type &surf, const index_type &ui, const index_type &vi) const
488  {
489  data_type du, dv;
490  return get(surf, du, dv, ui, vi);
491  }
492 
493  error_code get(surface_type &surf, data_type &du, data_type &dv, const index_type &ui, const index_type &vi) const
494  {
495  if ((ui>=number_u_patches()) || (vi>=number_v_patches()))
496  return INVALID_INDEX;
497 
498  index_type uk, vk;
499  typename keymap_type::const_iterator uit, vit;
500  find_patch(uk, vk, uit, vit, ui, vi);
501 
502  du = ukey.get_delta_parm(uit);
503  dv = vkey.get_delta_parm(vit);
504  surf = patches[uk][vk];
505 
506  return NO_ERRORS;
507  }
508 
509  error_code set(const surface_type &surf, const index_type &ui, const index_type &vi)
510  {
511  if ((ui>=number_u_patches()) || (vi>=number_v_patches()))
512  return INVALID_INDEX;
513 
514  index_type uk, vk;
515  typename keymap_type::const_iterator uit, vit;
516  find_patch(uk, vk, uit, vit, ui, vi);
517 
518  // set the new surf
519  patches[uk][vk]=surf;
520 
521  return NO_ERRORS;
522  }
523 
524  error_code replace(const surface_type &surf, const index_type &ui, const index_type &vi)
525  {
526  if ((ui>=number_u_patches()) || (vi>=number_v_patches()))
527  return INVALID_INDEX;
528 
529  // advance to desired index
530  typename surface_type::curve_type bc0, bc1;
531  index_type uk, vk;
532  typename keymap_type::const_iterator uit, vit;
533  find_patch(uk, vk, uit, vit, ui, vi);
534 
535  surface_type s = patches[uk][vk];
536 
537  if (ui>0)
538  {
539  surf.get_uconst_curve(bc0, 0);
540  s.get_uconst_curve(bc1, 0);
542  {
543  return PATCH_NOT_CONNECTED;
544  }
545  }
546  if ((ui+1)<number_u_patches())
547  {
548  surf.get_uconst_curve(bc0, 1);
549  s.get_uconst_curve(bc1, 1);
551  {
552  return PATCH_NOT_CONNECTED;
553  }
554  }
555  if (vi>0)
556  {
557  surf.get_vconst_curve(bc0, 0);
558  s.get_vconst_curve(bc1, 0);
560  {
561  return PATCH_NOT_CONNECTED;
562  }
563  }
564  if ((vi+1)<number_v_patches())
565  {
566  surf.get_vconst_curve(bc0, 1);
567  s.get_vconst_curve(bc1, 1);
569  {
570  return PATCH_NOT_CONNECTED;
571  }
572  }
573 
574  // set the new surf
575  patches[uk][vk]=surf;
576 
578 
579  return NO_ERRORS;
580  }
581 
582  error_code split_u(const data_type &u_in)
583  {
584  index_type uk, vk;
585  typename keymap_type::iterator uit, vit;
586  data_type uu(0), vv(0);
587  data_type vmin = vkey.get_pmin();
588 
589  find_patch(uk, vk, uit, vit, uu, vv, u_in, vmin);
590 
591  // check for out of range input
592  if ((uk == -1) || (vk == -1))
593  return INVALID_PARAM;
594 
595  // check if no need to split
596  tolerance_type tol;
597  if (tol.approximately_equal(uu, 0))
598  return NO_ERRORS;
599  if (tol.approximately_equal(uu, 1))
600  return NO_ERRORS;
601 
602  return split_u(uk, uit, u_in, uu);
603  }
604 
605  error_code split_v(const data_type &v_in)
606  {
607  index_type uk, vk;
608  typename keymap_type::iterator uit, vit;
609  data_type uu(0), vv(0);
610  data_type umin = ukey.get_pmin();
611 
612  find_patch(uk, vk, uit, vit, uu, vv, umin, v_in);
613 
614  // check for out of range input
615  if ((uk == -1) || (vk == -1))
616  return INVALID_PARAM;
617 
618  // check if no need to split
619  tolerance_type tol;
620  if (tol.approximately_equal(vv, 0))
621  return NO_ERRORS;
622  if (tol.approximately_equal(vv, 1))
623  return NO_ERRORS;
624 
625  return split_v(vk, vit, v_in, vv);
626  }
627 
628  void to_cubic_u(const data_type &ttol)
629  {
630  typename keymap_type::iterator uit, vit;
631 
632  // First pass to split patches until cubic approximation is within tolerance.
633  for(uit = ukey.key.begin(); uit != ukey.key.end(); ++uit)
634  {
635  for(vit = vkey.key.begin(); vit != vkey.key.end(); ++vit)
636  {
637  index_type uk = uit->second;
638  index_type vk = vit->second;
639 
640  surface_type s = patches[uk][vk];
641  surface_type sc(s);
642 
643  sc.to_cubic_u();
644 
645  data_type d = s.eqp_distance_bound(sc);
646 
647  while(d > ttol)
648  {
649  data_type delta_u = ukey.get_delta_parm(uit);
650  data_type u_in = uit->first + static_cast<data_type>(0.5) * delta_u;
651 
652  split_u(uk, uit, u_in, 0.5);
653 
654  s = patches[uk][vk];
655  sc = s;
656 
657  sc.to_cubic_u();
658 
659  d = s.eqp_distance_bound(sc);
660  }
661  }
662  }
663 
664  // Second pass to convert all patches to cubic.
665  for (index_type uk=0; uk<nu; ++uk)
666  {
667  for (index_type vk=0; vk<nv; ++vk)
668  {
669  patches[uk][vk].to_cubic_u();
670  }
671  }
672  }
673 
674  void to_cubic_v(const data_type &ttol)
675  {
676  typename keymap_type::iterator uit, vit;
677 
678  // First pass to split patches until cubic approximation is within tolerance.
679  for(uit = ukey.key.begin(); uit != ukey.key.end(); ++uit)
680  {
681  for(vit = vkey.key.begin(); vit != vkey.key.end(); ++vit)
682  {
683  index_type uk = uit->second;
684  index_type vk = vit->second;
685 
686  surface_type s = patches[uk][vk];
687  surface_type sc(s);
688 
689  sc.to_cubic_v();
690 
691  data_type d = s.eqp_distance_bound(sc);
692 
693  while(d > ttol)
694  {
695  data_type delta_v = vkey.get_delta_parm(vit);
696  data_type v_in = vit->first + static_cast<data_type>(0.5) * delta_v;
697 
698  split_v(vk, vit, v_in, 0.5);
699 
700  s = patches[uk][vk];
701  sc = s;
702 
703  sc.to_cubic_v();
704 
705  d = s.eqp_distance_bound(sc);
706  }
707  }
708  }
709 
710  // Second pass to convert all patches to cubic.
711  for (index_type uk=0; uk<nu; ++uk)
712  {
713  for (index_type vk=0; vk<nv; ++vk)
714  {
715  patches[uk][vk].to_cubic_v();
716  }
717  }
718  }
719 
720  void to_cubic(const data_type &ttol)
721  {
722  to_cubic_u(ttol);
723  to_cubic_v(ttol);
724  }
725 
726  void get_uconst_curve(piecewise_curve_type &pwc, const data_type &u) const
727  {
728  index_type uk, vk;
729  typename keymap_type::const_iterator uit, vit;
730  data_type uu(0), vv(0);
731  data_type vmin = vkey.get_pmin();
732 
733  find_patch(uk, vk, uit, vit, uu, vv, u, vmin);
734 
735  assert ((uk != -1) && (vk != -1));
736 
737  pwc.clear();
738  pwc.set_t0(vmin);
739 
740  for( index_type i=0; i<nv; i++)
741  {
742  vkey.find_segment(vk, vit, i);
743 
744  data_type dv=vkey.get_delta_parm(vit);
745 
746  surface_type s=patches[uk][vk];
747 
748  curve_type c;
749 
750  s.get_uconst_curve(c, uu);
751 
752  pwc.push_back(c,dv);
753  }
754  }
755 
756  void get_vconst_curve(piecewise_curve_type &pwc, const data_type &v) const
757  {
758  index_type uk, vk;
759  typename keymap_type::const_iterator uit, vit;
760  data_type uu(0), vv(0);
761  data_type umin = ukey.get_pmin();
762 
763  find_patch(uk, vk, uit, vit, uu, vv, umin, v);
764 
765  assert ((uk != -1) && (vk != -1));
766 
767  pwc.clear();
768  pwc.set_t0(umin);
769 
770  for( index_type i=0; i<nu; i++)
771  {
772  ukey.find_segment(uk, uit, i);
773 
774  data_type du=ukey.get_delta_parm(uit);
775 
776  surface_type s=patches[uk][vk];
777 
778  curve_type c;
779 
780  s.get_vconst_curve(c, vv);
781 
782  pwc.push_back(c,du);
783  }
784  }
785 
786  void find_interior_feature_edges(std::vector<data_type> &uconst, std::vector<data_type> &vconst, const data_type &angle_tol) const
787  {
788  index_type nu, nv, iu, iv;
789 
790  piecewise_curve_type c;
791  std::vector<data_type> pmap, ldis, ldis_out;
792  tolerance_type tol;
793 
794  // initialize the output
795  uconst.clear();
796  vconst.clear();
797 
798  // unnamed function to test if two parameters are close enough
799  auto comp = [&tol](const data_type &x1, const data_type &x2)->bool
800  {
801  return tol.approximately_less_than(x1, x2);
802  };
803 
804  // extract each v-const curve that is an edge of one of the patches to find u-parameters
805  // that contain C0 only edges
806  get_pmap_v(pmap);
807  nv=pmap.size();
808  assert(nv-1==number_v_patches());
809  for (iv=0; iv<nv; ++iv)
810  {
811  get_vconst_curve(c, pmap[iv]);
812  c.find_discontinuities(angle_tol, ldis);
813 
814  // merge these parameters with current list
815  ldis_out.clear();
816  std::set_union(uconst.begin(), uconst.end(), ldis.begin(), ldis.end(), std::back_inserter(ldis_out), comp);
817  std::swap(uconst, ldis_out);
818  }
819 
820  // extract each u-const curve that is an edge of one of the patches to find v-parameters
821  // that contain C0 only edges
822  pmap.clear();
823  get_pmap_u(pmap);
824  nu=pmap.size();
825  assert(nu-1==number_u_patches());
826  for (iu=0; iu<nu; ++iu)
827  {
828  get_uconst_curve(c, pmap[iu]);
829  c.find_discontinuities(angle_tol, ldis);
830 
831  // merge these parameters with current list
832  ldis_out.clear();
833  std::set_union(vconst.begin(), vconst.end(), ldis.begin(), ldis.end(), std::back_inserter(ldis_out), comp);
834  std::swap(vconst, ldis_out);
835  }
836 
837  // TODO: Need to compare actual control points next to edges to catch cases where the
838  // patch corners satisfy the constraints but internally the constraints are not.
839 
840  }
841 
842  void find_interior_C0_edges(std::vector<data_type> &uconst, std::vector<data_type> &vconst) const
843  {
844  index_type nu, nv, iu, iv;
845 
846  piecewise_curve_type c;
847  std::vector<data_type> pmap, ldis, ldis_out;
848  tolerance_type tol;
849 
850  // initialize the output
851  uconst.clear();
852  vconst.clear();
853 
854  // unnamed function to test if two parameters are close enough
855  auto comp = [&tol](const data_type &x1, const data_type &x2)->bool
856  {
857  return tol.approximately_less_than(x1, x2);
858  };
859 
860  // extract each v-const curve that is an edge of one of the patches to find u-parameters
861  // that contain C0 only edges
862  get_pmap_v(pmap);
863  nv=pmap.size();
864  assert(nv-1==number_v_patches());
865  for (iv=0; iv<nv; ++iv)
866  {
867  get_vconst_curve(c, pmap[iv]);
869 
870  // merge these parameters with current list
871  ldis_out.clear();
872  std::set_union(uconst.begin(), uconst.end(), ldis.begin(), ldis.end(), std::back_inserter(ldis_out), comp);
873  std::swap(uconst, ldis_out);
874  }
875 
876  // extract each u-const curve that is an edge of one of the patches to find v-parameters
877  // that contain C0 only edges
878  pmap.clear();
879  get_pmap_u(pmap);
880  nu=pmap.size();
881  assert(nu-1==number_u_patches());
882  for (iu=0; iu<nu; ++iu)
883  {
884  get_uconst_curve(c, pmap[iu]);
886 
887  // merge these parameters with current list
888  ldis_out.clear();
889  std::set_union(vconst.begin(), vconst.end(), ldis.begin(), ldis.end(), std::back_inserter(ldis_out), comp);
890  std::swap(vconst, ldis_out);
891  }
892 
893  // TODO: Need to compare actual control points next to edges to catch cases where the
894  // patch corners are continuous but internally it is not.
895  }
896 
897  point_type f(const data_type &u, const data_type &v) const
898  {
899  // find patch that corresponds to given u & v
900  index_type uk, vk;
901  data_type uu(0), vv(0);
902 
903  find_patch(uk, vk, uu, vv, u, v);
904 
905  assert((uk != -1) && (vk != -1));
906 
907  return patches[uk][vk].f(uu, vv);
908  }
909 
910  point_type f_u(const data_type &u, const data_type &v) const
911  {
912  // find patch that corresponds to given u & v
913  index_type uk, vk;
914  typename keymap_type::const_iterator uit, vit;
915  data_type uu(0), vv(0);
916 
917  find_patch(uk, vk, uit, vit, uu, vv, u, v);
918 
919  assert((uk != -1) && (vk != -1));
920 
921  data_type delta_u = ukey.get_delta_parm(uit);
922 
923  return patches[uk][vk].f_u(uu, vv)/delta_u;
924  }
925 
926  point_type f_v(const data_type &u, const data_type &v) const
927  {
928  // find patch that corresponds to given u & v
929  index_type uk, vk;
930  typename keymap_type::const_iterator uit, vit;
931  data_type uu(0), vv(0);
932 
933  find_patch(uk, vk, uit, vit, uu, vv, u, v);
934 
935  assert((uk != -1) && (vk != -1));
936 
937  data_type delta_v = vkey.get_delta_parm(vit);
938 
939  return patches[uk][vk].f_v(uu, vv)/delta_v;
940  }
941 
942  point_type f_uu(const data_type &u, const data_type &v) const
943  {
944  // find patch that corresponds to given u & v
945  index_type uk, vk;
946  typename keymap_type::const_iterator uit, vit;
947  data_type uu(0), vv(0);
948 
949  find_patch(uk, vk, uit, vit, uu, vv, u, v);
950 
951  assert((uk != -1) && (vk != -1));
952 
953  data_type delta_u = ukey.get_delta_parm(uit);
954 
955  return patches[uk][vk].f_uu(uu, vv)/(delta_u*delta_u);
956  }
957 
958  point_type f_uv(const data_type &u, const data_type &v) const
959  {
960  // find patch that corresponds to given u & v
961  index_type uk, vk;
962  typename keymap_type::const_iterator uit, vit;
963  data_type uu(0), vv(0);
964 
965  find_patch(uk, vk, uit, vit, uu, vv, u, v);
966 
967  assert((uk != -1) && (vk != -1));
968 
969  data_type delta_u = ukey.get_delta_parm(uit);
970  data_type delta_v = vkey.get_delta_parm(vit);
971 
972  return patches[uk][vk].f_uv(uu, vv)/(delta_u*delta_v);
973  }
974 
975  point_type f_vv(const data_type &u, const data_type &v) const
976  {
977  // find patch that corresponds to given u & v
978  index_type uk, vk;
979  typename keymap_type::const_iterator uit, vit;
980  data_type uu(0), vv(0);
981 
982  find_patch(uk, vk, uit, vit, uu, vv, u, v);
983 
984  assert((uk != -1) && (vk != -1));
985 
986  data_type delta_v = vkey.get_delta_parm(vit);
987 
988  return patches[uk][vk].f_vv(uu, vv)/(delta_v*delta_v);
989  }
990 
991  point_type f_uuu(const data_type &u, const data_type &v) const
992  {
993  // find patch that corresponds to given u & v
994  index_type uk, vk;
995  typename keymap_type::const_iterator uit, vit;
996  data_type uu(0), vv(0);
997 
998  find_patch(uk, vk, uit, vit, uu, vv, u, v);
999 
1000  assert((uk != -1) && (vk != -1));
1001 
1002  data_type delta_u = ukey.get_delta_parm(uit);
1003 
1004  return patches[uk][vk].f_uuu(uu, vv)/(delta_u*delta_u*delta_u);
1005  }
1006 
1007  point_type f_uuv(const data_type &u, const data_type &v) const
1008  {
1009  // find patch that corresponds to given u & v
1010  index_type uk, vk;
1011  typename keymap_type::const_iterator uit, vit;
1012  data_type uu(0), vv(0);
1013 
1014  find_patch(uk, vk, uit, vit, uu, vv, u, v);
1015 
1016  assert((uk != -1) && (vk != -1));
1017 
1018  data_type delta_u = ukey.get_delta_parm(uit);
1019  data_type delta_v = vkey.get_delta_parm(vit);
1020 
1021  return patches[uk][vk].f_uuv(uu, vv)/(delta_u*delta_u*delta_v);
1022  }
1023 
1024  point_type f_uvv(const data_type &u, const data_type &v) const
1025  {
1026  // find patch that corresponds to given u & v
1027  index_type uk, vk;
1028  typename keymap_type::const_iterator uit, vit;
1029  data_type uu(0), vv(0);
1030 
1031  find_patch(uk, vk, uit, vit, uu, vv, u, v);
1032 
1033  assert((uk != -1) && (vk != -1));
1034 
1035  data_type delta_u = ukey.get_delta_parm(uit);
1036  data_type delta_v = vkey.get_delta_parm(vit);
1037 
1038  return patches[uk][vk].f_uvv(uu, vv)/(delta_u*delta_v*delta_v);
1039  }
1040 
1041  point_type f_vvv(const data_type &u, const data_type &v) const
1042  {
1043  // find patch that corresponds to given u & v
1044  index_type uk, vk;
1045  typename keymap_type::const_iterator uit, vit;
1046  data_type uu(0), vv(0);
1047 
1048  find_patch(uk, vk, uit, vit, uu, vv, u, v);
1049 
1050  assert((uk != -1) && (vk != -1));
1051 
1052  data_type delta_u = ukey.get_delta_parm(uit);
1053  data_type delta_v = vkey.get_delta_parm(vit);
1054 
1055  return patches[uk][vk].f_vvv(uu, vv)/(delta_v*delta_v*delta_v);
1056  }
1057 
1058  point_type normal(const data_type &u, const data_type &v) const
1059  {
1060  // find patch that corresponds to given u & v
1061  index_type uk, vk;
1062  data_type uu(0), vv(0);
1063 
1064  find_patch(uk, vk, uu, vv, u, v);
1065 
1066  assert((uk != -1) && (vk != -1));
1067 
1068  return patches[uk][vk].normal(uu, vv);
1069  }
1070 
1071  // TODO: NEED TO IMPLEMENT
1072  // * fit
1073  // * interpolate
1074 
1075  private:
1076 // template<template<typename, unsigned short, typename> class surf1__,
1077 // typename data1__, unsigned short dim1__, typename tol1__>
1078 // friend void area(typename piecewise<surf1__, data1__, dim1__, tol1__>::data_type &len,
1079 // const piecewise<surf1__, data1__, dim1__, tol1__> &pc,
1080 // const typename piecewise<surf1__, data1__, dim1__, tol1__>::data_type &tol);
1081 // template<template<typename, unsigned short, typename> class surf1__,
1082 // typename data1__, unsigned short dim1__, typename tol1__>
1083 // friend void area(typename piecewise<surf1__, data1__, dim1__, tol1__>::data_type &len,
1084 // const piecewise<surf1__, data1__, dim1__, tol1__> &pc,
1085 // const typename piecewise<surf1__, data1__, dim1__, tol1__>::data_type &t0,
1086 // const typename piecewise<surf1__, data1__, dim1__, tol1__>::data_type &t1,
1087 // const typename piecewise<surf1__, data1__, dim1__, tol1__>::data_type &tol);
1088 
1089  template<template<typename, unsigned short, typename> class surface1__, typename data1__, unsigned short dim1__, typename tol1__ >
1096 
1097  typedef std::map< data_type, index_type > keymap_type;
1098 
1100  {
1101  keymap_type key;
1102  data_type pmax;
1103 
1104  parameter_key() : pmax(0) {}
1105  parameter_key(const parameter_key &pk) : key(pk.key), pmax(pk.pmax) {}
1107 
1108  bool operator==(const parameter_key &pk) const
1109  {
1110  if (this==&pk)
1111  return true;
1112  if (pmax!=pk.pmax)
1113  return false;
1114  if (key!=pk.key)
1115  return false;
1116 
1117  return true;
1118  }
1119 
1120  bool operator!=(const parameter_key &pk) const
1121  {
1122  return !operator==(pk);
1123  }
1124 
1125  void clear()
1126  {
1127  pmax=0;
1128  key.clear();
1129  }
1130 
1131  data_type get_pmax() const
1132  {
1133  return pmax;
1134  }
1135 
1136  data_type get_pmin() const
1137  {
1138  if(!key.empty())
1139  return key.begin()->first;
1140  else
1141  return pmax;
1142  }
1143 
1144  void set_pmax(const data_type &pmax_in)
1145  {
1146  pmax = pmax_in;
1147  }
1148 
1149  void set_pmin(const data_type &pmin_in)
1150  {
1151  if(!key.empty())
1152  {
1153  if(pmin_in != key.begin()->first)
1154  {
1155  data_type p = pmin_in;
1156  keymap_type shiftkey;
1157  for (typename keymap_type::iterator it=key.begin(); it!=key.end(); ++it)
1158  {
1159  data_type delta_p = get_delta_parm(it);
1160 
1161  shiftkey.insert(shiftkey.end(), std::make_pair(p, it->second));
1162 
1163  p+=delta_p;
1164  }
1165  key.swap(shiftkey);
1166  pmax = p;
1167  }
1168  }
1169  else
1170  {
1171  pmax=pmin_in;
1172  }
1173  }
1174 
1175  void init(const index_type &nseg, const data_type &dp = 1, const data_type &p0 = 0)
1176  {
1177  key.clear();
1178  pmax = p0;
1179  append(nseg, dp);
1180  }
1181 
1182  void append(const index_type &nseg, const data_type &dp = 1)
1183  {
1184  typename keymap_type::iterator itguess = key.end();
1185  index_type j = key.size();
1186  data_type p = pmax;
1187  for(index_type i = 0; i < nseg; ++i)
1188  {
1189  itguess = key.insert(itguess, std::make_pair(p, j));
1190  p += dp;
1191  ++j;
1192  }
1193  pmax = p;
1194  }
1195 
1196  template<typename it__>
1197  void init(const it__ &dps, const it__ &dpe, const data_type &p0 = 0)
1198  {
1199  key.clear();
1200  pmax = p0;
1201  append(dps, dpe);
1202  }
1203 
1204  template<typename it__>
1205  void append(const it__ &dps, const it__ &dpe)
1206  {
1207  typename keymap_type::iterator itguess = key.end();
1208  index_type j = key.size();
1209  data_type p = pmax;
1210  for(it__ dp = dps; dp != dpe; ++dp)
1211  {
1212  itguess = key.insert(itguess, std::make_pair(p, j));
1213  p += (*dp);
1214  ++j;
1215  }
1216  pmax = p;
1217  }
1218 
1219  void parameter_report() const
1220  {
1221  printf("Parameter report:\n");
1222  typename keymap_type::iterator it;
1223 
1224  int i = 0;
1225  // cycle through all segments to get each bounding box to add
1226  for (it=key.begin(); it!=key.end(); ++it)
1227  {
1228  printf(" seg: %d \t p: %f \t pk %d\n", i, it->first, it->second);
1229  ++i;
1230  }
1231  printf(" pmax: %f\n", pmax);
1232  printf("End report\n");
1233  }
1234 
1235  void get_pmap(std::vector<data_type> &pmap) const
1236  {
1237  pmap.clear();
1238 
1239  typename keymap_type::const_iterator it;
1240  for (it=key.cbegin(); it!=key.cend(); ++it)
1241  {
1242  pmap.push_back( it->first );
1243  }
1244  pmap.push_back( pmax );
1245  }
1246 
1248  {
1249  keymap_type rkey;
1250  typename keymap_type::iterator itr;
1251  typename keymap_type::iterator itrguess = rkey.begin();
1252 
1253  data_type p = get_pmin();
1254 
1255  for (typename keymap_type::reverse_iterator it=key.rbegin(); it!=key.rend(); ++it)
1256  {
1257  itr = rkey.insert(itrguess, std::make_pair(p, it->second));
1258 
1259  data_type delta_p = get_delta_parm(it);
1260  p += delta_p;
1261 
1262  itrguess = itr;
1263  }
1264  key.swap(rkey);
1265 
1266  // Parametric length should stay the same.
1267  assert(p == pmax);
1268  }
1269 
1270 
1271  data_type get_delta_parm(const typename keymap_type::iterator &it) const
1272  {
1273  assert (it != key.end());
1274 
1275  typename keymap_type::iterator itnext = it;
1276  itnext++;
1277 
1278  data_type delta_p;
1279 
1280  if(itnext != key.end())
1281  delta_p = itnext->first - it->first;
1282  else
1283  delta_p = pmax - it->first;
1284 
1285  return delta_p;
1286  }
1287 
1288  data_type get_delta_parm(const typename keymap_type::const_iterator &it) const
1289  {
1290  assert (it != key.end());
1291 
1292  typename keymap_type::const_iterator itnext = it;
1293  itnext++;
1294 
1295  data_type delta_p;
1296 
1297  if(itnext != key.end())
1298  delta_p = itnext->first - it->first;
1299  else
1300  delta_p = pmax - it->first;
1301 
1302  return delta_p;
1303  }
1304 
1305  data_type get_delta_parm(const typename keymap_type::reverse_iterator &it) const
1306  {
1307  assert (it != key.rend());
1308 
1309  data_type delta_p;
1310 
1311  if(it != key.rbegin())
1312  {
1313  typename keymap_type::reverse_iterator itprev = it;
1314  itprev--;
1315  delta_p = itprev->first - it->first;
1316  }
1317  else
1318  {
1319  delta_p = pmax - it->first;
1320  }
1321 
1322  return delta_p;
1323  }
1324 
1325  data_type get_delta_parm(const typename keymap_type::const_reverse_iterator &it) const
1326  {
1327  assert (it != key.rend());
1328 
1329  data_type delta_p;
1330 
1331  if(it != key.rbegin())
1332  {
1333  typename keymap_type::const_reverse_iterator itprev = it;
1334  itprev--;
1335  delta_p = itprev->first - it->first;
1336  }
1337  else
1338  {
1339  delta_p = pmax - it->first;
1340  }
1341 
1342  return delta_p;
1343  }
1344 
1345  void find_segment(index_type &ikey, typename keymap_type::const_iterator &it, const index_type &index) const
1346  {
1347  if(index >= (int) key.size() || index < 0)
1348  {
1349  it=key.end();
1350  ikey=-1;
1351  return;
1352  }
1353 
1354  // advance to desired index
1355  index_type i;
1356  for (i=0, it=key.begin(); i<index; ++i, ++it) {}
1357 
1358  ikey=it->second;
1359  }
1360 
1361  void find_segment(index_type &ikey, typename keymap_type::iterator &it, const index_type &index) const
1362  {
1363  if(index >= (int) key.size() || index < 0)
1364  {
1365  it=key.end();
1366  ikey=-1;
1367  return;
1368  }
1369 
1370  // advance to desired index
1371  index_type i;
1372  for (i=0, it=key.begin(); i<index; ++i, ++it) {}
1373 
1374  ikey=it->second;
1375  }
1376 
1377  void find_segment(index_type &ikey, typename keymap_type::iterator &it, data_type &pp, const data_type &p_in)
1378  {
1379  tol__ tol;
1380 
1381  if(p_in>pmax)
1382  {
1383  it=key.end();
1384  ikey = -1;
1385  return;
1386  }
1387 
1388  data_type pmin = get_pmin();
1389 
1390  if(p_in<pmin)
1391  {
1392  it=key.end();
1393  ikey = -1;
1394  return;
1395  }
1396 
1397  // Use map::upper_bound for fast lookup of segment after p_in
1398  it=key.upper_bound(p_in);
1399 
1400  // Decrement to segment containing p_in
1401  if(it != key.begin())
1402  it--;
1403 
1404  ikey = it->second;
1405 
1406  // At start of segment
1407  if(tol.approximately_equal(p_in, it->first))
1408  {
1409  pp=static_cast<data_type>(0);
1410  return;
1411  }
1412 
1413  data_type delta_p = get_delta_parm(it);
1414 
1415  // At end of segment
1416  if(tol.approximately_equal(p_in, it->first + delta_p))
1417  {
1418  pp=static_cast<data_type>(1);
1419  return;
1420  }
1421 
1422  // Typical case
1423  pp=(p_in-it->first)/delta_p;
1424 
1425  // Super careful checks
1426  if (pp>static_cast<data_type>(1))
1427  pp=static_cast<data_type>(1);
1428  if (pp<static_cast<data_type>(0))
1429  pp=static_cast<data_type>(0);
1430  }
1431 
1432  void find_segment(index_type &ikey, typename keymap_type::const_iterator &it, data_type &pp, const data_type &p_in) const
1433  {
1434  tol__ tol;
1435 
1436  if(p_in>pmax)
1437  {
1438  it=key.end();
1439  ikey = -1;
1440  return;
1441  }
1442 
1443  data_type pmin = get_pmin();
1444 
1445  if(p_in<pmin)
1446  {
1447  it=key.end();
1448  ikey = -1;
1449  return;
1450  }
1451 
1452  // Use map::upper_bound for fast lookup of segment after p_in
1453  it=key.upper_bound(p_in);
1454 
1455  // Decrement to segment containing p_in
1456  if(it != key.begin())
1457  it--;
1458 
1459  ikey = it->second;
1460 
1461  // At start of segment
1462  if(tol.approximately_equal(p_in, it->first))
1463  {
1464  pp=static_cast<data_type>(0);
1465  return;
1466  }
1467 
1468  data_type delta_p = get_delta_parm(it);
1469 
1470  // At end of segment
1471  if(tol.approximately_equal(p_in, it->first + delta_p))
1472  {
1473  pp=static_cast<data_type>(1);
1474  return;
1475  }
1476 
1477  // Typical case
1478  pp=(p_in-it->first)/delta_p;
1479 
1480  // Super careful checks
1481  if (pp>static_cast<data_type>(1))
1482  pp=static_cast<data_type>(1);
1483  if (pp<static_cast<data_type>(0))
1484  pp=static_cast<data_type>(0);
1485  }
1486  };
1487 
1488 
1489  typedef std::vector< surface_type > patch_strip_type;
1490  typedef std::vector< patch_strip_type > patch_collection_type;
1491 
1492  patch_collection_type patches;
1493  // By convention, patches[uk][vk]
1494 
1496  index_type nu, nv;
1497 
1498  protected:
1500  {
1501  // TODO: Need to implement this
1502  return true;
1503  }
1504 
1505  bool check_u_continuity(const surface_type &/*s1*/, const surface_type &/*s2*/, const eli::geom::general::continuity &/*cont*/) const
1506  {
1507  // TODO: Need to implement this
1508  return true;
1509  }
1510 
1511  bool check_v_continuity(const surface_type &/*s1*/, const surface_type &/*s2*/, const eli::geom::general::continuity &/*cont*/) const
1512  {
1513  // TODO: Need to implement this
1514  return true;
1515  }
1516 
1517  private:
1518 
1519  void resize_store(const index_type &nu_in, const index_type &nv_in)
1520  {
1521  if ((nu_in<=0) || (nv_in<=0))
1522  return;
1523 
1524  patches.resize(nu_in);
1525  nu = nu_in;
1526 
1527  // Unconditionally do this to make sure newly added rows are properly sized.
1528  for(index_type i = 0; i < nu_in; i++)
1529  patches[i].resize(nv_in);
1530 
1531  nv = nv_in;
1532  }
1533 
1534  error_code split_u(const index_type &uk, const typename keymap_type::iterator &uit, const data_type &u_in, const data_type &uu)
1535  {
1536  tolerance_type tol;
1537  assert(!tol.approximately_equal(uu, 0));
1538  assert(!tol.approximately_equal(uu, 1));
1539 
1540  index_type ukr, vk;
1541  // Right half will be added at end of patch matrix.
1542  ukr=nu;
1543  ukey.key.insert(uit, std::make_pair(u_in, ukr));
1544 
1545  // Increase matrix size.
1546  resize_store(nu+1, nv);
1547 
1548  for (vk=0; vk<nv; ++vk)
1549  {
1550  surface_type s = patches[uk][vk];
1551  s.split_u(patches[uk][vk], patches[ukr][vk], uu);
1552  }
1553 
1554  return NO_ERRORS;
1555  }
1556 
1557  error_code split_v(const index_type &vk, const typename keymap_type::iterator &vit, const data_type &v_in, const data_type &vv)
1558  {
1559  tolerance_type tol;
1560  assert(!tol.approximately_equal(vv, 0));
1561  assert(!tol.approximately_equal(vv, 1));
1562 
1563  index_type uk, vkr;
1564  // Right half will be added at end of patch matrix.
1565  vkr=nv;
1566  vkey.key.insert(vit, std::make_pair(v_in, vkr));
1567 
1568  // Increase matrix size.
1569  resize_store(nu, nv+1);
1570 
1571  for (uk=0; uk<nu; ++uk)
1572  {
1573  surface_type s = patches[uk][vk];
1574  s.split_v(patches[uk][vk], patches[uk][vkr], vv);
1575  }
1576 
1577  return NO_ERRORS;
1578  }
1579 
1580  // Lookup based on i,j
1581  void find_patch(index_type &uk, index_type &vk,
1582  typename keymap_type::iterator &uit, typename keymap_type::iterator &vit,
1583  const index_type & ui, const index_type &vi)
1584  {
1585  ukey.find_segment(uk, uit, ui);
1586  vkey.find_segment(vk, vit, vi);
1587  }
1588 
1589  void find_patch(typename keymap_type::iterator &uit, typename keymap_type::iterator &vit,
1590  const index_type & ui, const index_type &vi)
1591  {
1592  index_type uk, vk;
1593  find_patch(uk, vk, uit, vit, ui, vi);
1594  }
1595 
1596  void find_patch(index_type &uk, index_type &vk,
1597  typename keymap_type::const_iterator &uit, typename keymap_type::const_iterator &vit,
1598  const index_type & ui, const index_type &vi) const
1599  {
1600  ukey.find_segment(uk, uit, ui);
1601  vkey.find_segment(vk, vit, vi);
1602  }
1603 
1604  void find_patch(typename keymap_type::const_iterator &uit, typename keymap_type::const_iterator &vit,
1605  const index_type & ui, const index_type &vi) const
1606  {
1607  index_type uk, vk;
1608  find_patch(uk, vk, uit, vit, ui, vi);
1609  }
1610 
1611  void find_patch(index_type &uk, index_type &vk,
1612  const index_type & ui, const index_type &vi) const
1613  {
1614  typename keymap_type::const_iterator uit, vit;
1615  find_patch(uk, vk, uit, vit, ui, vi);
1616  }
1617 
1618  // Lookup based on u_in, v_in.
1619  void find_patch(index_type &uk, index_type &vk,
1620  typename keymap_type::iterator &uit, typename keymap_type::iterator &vit,
1621  data_type &uu, data_type &vv,
1622  const data_type &u_in, const data_type &v_in)
1623  {
1624  ukey.find_segment(uk, uit, uu, u_in);
1625  vkey.find_segment(vk, vit, vv, v_in);
1626  }
1627 
1628  void find_patch(typename keymap_type::iterator &uit, typename keymap_type::iterator &vit,
1629  data_type &uu, data_type &vv,
1630  const data_type &u_in, const data_type &v_in)
1631  {
1632  index_type uk, vk;
1633  find_patch(uk, vk, uit, vit, uu, vv, u_in, v_in);
1634  }
1635 
1636  void find_patch(index_type &uk, index_type &vk,
1637  typename keymap_type::const_iterator &uit, typename keymap_type::const_iterator &vit,
1638  data_type &uu, data_type &vv,
1639  const data_type &u_in, const data_type &v_in) const
1640  {
1641  ukey.find_segment(uk, uit, uu, u_in);
1642  vkey.find_segment(vk, vit, vv, v_in);
1643  }
1644 
1645  void find_patch(typename keymap_type::const_iterator &uit, typename keymap_type::const_iterator &vit,
1646  data_type &uu, data_type &vv,
1647  const data_type &u_in, const data_type &v_in) const
1648  {
1649  index_type uk, vk;
1650  find_patch(uk, vk, uit, vit, uu, vv, u_in, v_in);
1651  }
1652 
1653  void find_patch(index_type &uk, index_type &vk,
1654  data_type &uu, data_type &vv,
1655  const data_type &u_in, const data_type &v_in) const
1656  {
1657  typename keymap_type::const_iterator uit, vit;
1658  find_patch(uk, vk, uit, vit, uu, vv, u_in, v_in);
1659  }
1660 
1661  };
1662  }
1663  }
1664 }
1665 #endif
void to_cubic(const data_type &ttol)
Definition: piecewise.hpp:720
piecewise(const piecewise< surface__, data_type, dim__, tol__ > &p)
Definition: piecewise.hpp:82
surface_type::point_type point_type
Definition: piecewise.hpp:59
point_type f_uuv(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:1007
void find_patch(index_type &uk, index_type &vk, typename keymap_type::const_iterator &uit, typename keymap_type::const_iterator &vit, const index_type &ui, const index_type &vi) const
Definition: piecewise.hpp:1596
Definition: piecewise.hpp:1099
unsigned short dimension_type
Definition: piecewise.hpp:67
data_type get_pmin() const
Definition: piecewise.hpp:1136
Definition: math.hpp:20
data_type pmax
Definition: piecewise.hpp:1102
void rotate(const rotation_matrix_type &rmat, const point_type &rorig)
Definition: piecewise.hpp:393
curve::piecewise< curve1__, data1__, dim1__, tol1__ >::data_type minimum_distance(typename curve::piecewise< curve1__, data1__, dim1__, tol1__ >::data_type &t, const curve::piecewise< curve1__, data1__, dim1__, tol1__ > &pc, const typename curve::piecewise< curve1__, data1__, dim1__, tol1__ >::point_type &pt)
void resize_store(const index_type &nu_in, const index_type &nv_in)
Definition: piecewise.hpp:1519
parameter_key()
Definition: piecewise.hpp:1104
surface_type * get_patch(const index_type &ui, const index_type &vi)
Definition: piecewise.hpp:145
void set_v0(const data_type &v0_in)
Definition: piecewise.hpp:137
data_type get_delta_parm(const typename keymap_type::reverse_iterator &it) const
Definition: piecewise.hpp:1305
void reverse_u()
Definition: piecewise.hpp:421
void degree_v(index_type &mind, index_type &maxd)
Definition: piecewise.hpp:282
void find_segment(index_type &ikey, typename keymap_type::iterator &it, data_type &pp, const data_type &p_in)
Definition: piecewise.hpp:1377
bool check_v_continuity(const surface_type &, const surface_type &, const eli::geom::general::continuity &) const
Definition: piecewise.hpp:1511
void find_segment(index_type &ikey, typename keymap_type::const_iterator &it, data_type &pp, const data_type &p_in) const
Definition: piecewise.hpp:1432
void find_patch(index_type &uk, index_type &vk, typename keymap_type::iterator &uit, typename keymap_type::iterator &vit, const index_type &ui, const index_type &vi)
Definition: piecewise.hpp:1581
void init_v(const it__ &dvs, const it__ &dve, const data_type &v0=0)
Definition: piecewise.hpp:236
void find_segment(index_type &ikey, typename keymap_type::iterator &it, const index_type &index) const
Definition: piecewise.hpp:1361
void translate(const point_type &trans)
Definition: piecewise.hpp:407
static dimension_type dimension()
Definition: piecewise.hpp:131
bool check_continuity(const eli::geom::general::continuity &) const
Definition: piecewise.hpp:1499
~parameter_key()
Definition: piecewise.hpp:1106
void init_v(const index_type &nsegv, const data_type &dv=1, const data_type &v0=0)
Definition: piecewise.hpp:212
void find_patch(index_type &uk, index_type &vk, typename keymap_type::const_iterator &uit, typename keymap_type::const_iterator &vit, data_type &uu, data_type &vv, const data_type &u_in, const data_type &v_in) const
Definition: piecewise.hpp:1636
piecewise & operator=(const piecewise< surface__, data_type, dim__ > &p)
Definition: piecewise.hpp:86
bool closed_v() const
Definition: piecewise.hpp:339
data__ data_type
Definition: piecewise.hpp:66
void get_pmap_v(std::vector< data_type > &pmap) const
Definition: piecewise.hpp:194
void find_segment(index_type &ikey, typename keymap_type::const_iterator &it, const index_type &index) const
Definition: piecewise.hpp:1345
bool open_v() const
Definition: piecewise.hpp:335
surface_type * get_patch_unordered(const index_type &uk, const index_type &vk)
Definition: piecewise.hpp:159
error_code push_back(const curve_type &curve, const data_type &dt=1.0)
Definition: piecewise.hpp:688
point_type f_u(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:910
data_type get_u0() const
Definition: piecewise.hpp:133
void get_parameter_max(data_type &umax, data_type &vmax) const
Definition: piecewise.hpp:175
void set_u0(const data_type &u0_in)
Definition: piecewise.hpp:134
void get_uconst_curve(piecewise_curve_type &pwc, const data_type &u) const
Definition: piecewise.hpp:726
point_type f(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:897
void set_pmax(const data_type &pmax_in)
Definition: piecewise.hpp:1144
surface_type::curve_type curve_type
Definition: piecewise.hpp:63
const surface_type * get_patch_unordered(const index_type &uk, const index_type &vk) const
Definition: piecewise.hpp:164
data_type get_umax() const
Definition: piecewise.hpp:139
index_type number_v_patches() const
Definition: piecewise.hpp:143
void to_cubic_v(const data_type &ttol)
Definition: piecewise.hpp:674
Definition: piecewise.hpp:37
point_type f_uuu(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:991
void reverse_v()
Definition: piecewise.hpp:436
point_type f_vv(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:975
point_type f_vvv(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:1041
index_type nv
Definition: piecewise.hpp:1496
data_type get_delta_parm(const typename keymap_type::iterator &it) const
Definition: piecewise.hpp:1271
error_code replace(const surface_type &surf, const index_type &ui, const index_type &vi)
Definition: piecewise.hpp:524
void append(const index_type &nseg, const data_type &dp=1)
Definition: piecewise.hpp:1182
bool open_u() const
Definition: piecewise.hpp:312
Definition: continuity.hpp:27
error_code split_u(const index_type &uk, const typename keymap_type::iterator &uit, const data_type &u_in, const data_type &uu)
Definition: piecewise.hpp:1534
error_code split_u(const data_type &u_in)
Definition: piecewise.hpp:582
void find_interior_C0_edges(std::vector< data_type > &uconst, std::vector< data_type > &vconst) const
Definition: piecewise.hpp:842
void find_patch(typename keymap_type::iterator &uit, typename keymap_type::iterator &vit, const index_type &ui, const index_type &vi)
Definition: piecewise.hpp:1589
tol__ tolerance_type
Definition: piecewise.hpp:68
void init(const index_type &nseg, const data_type &dp=1, const data_type &p0=0)
Definition: piecewise.hpp:1175
Definition: tolerance.hpp:26
void find_interior_feature_edges(std::vector< data_type > &uconst, std::vector< data_type > &vconst, const data_type &angle_tol) const
Definition: piecewise.hpp:786
void init_u(const it__ &dus, const it__ &due, const data_type &u0=0)
Definition: piecewise.hpp:228
data_type get_delta_parm(const typename keymap_type::const_iterator &it) const
Definition: piecewise.hpp:1288
error_code split_v(const data_type &v_in)
Definition: piecewise.hpp:605
Definition: continuity.hpp:33
void clear()
Definition: piecewise.hpp:478
void rotate(const rotation_matrix_type &rmat)
Definition: piecewise.hpp:379
void swap_uv()
Definition: piecewise.hpp:451
parameter_key ukey
Definition: piecewise.hpp:1495
std::vector< patch_strip_type > patch_collection_type
Definition: piecewise.hpp:1490
error_code
Definition: piecewise.hpp:69
std::vector< surface_type > patch_strip_type
Definition: piecewise.hpp:1489
void get_pmap_u(std::vector< data_type > &pmap) const
Definition: piecewise.hpp:189
point_type f_uu(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:942
data_type get_v0() const
Definition: piecewise.hpp:136
void find_patch(typename keymap_type::iterator &uit, typename keymap_type::iterator &vit, data_type &uu, data_type &vv, const data_type &u_in, const data_type &v_in)
Definition: piecewise.hpp:1628
data_type get_pmax() const
Definition: piecewise.hpp:1131
void init_u(const index_type &nsegu, const data_type &du=1, const data_type &u0=0)
Definition: piecewise.hpp:205
data_type get_delta_parm(const typename keymap_type::const_reverse_iterator &it) const
Definition: piecewise.hpp:1325
bool check_u_continuity(const surface_type &, const surface_type &, const eli::geom::general::continuity &) const
Definition: piecewise.hpp:1505
void get_parameter_min(data_type &umin, data_type &vmin) const
Definition: piecewise.hpp:169
point_type f_uv(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:958
void clear()
Definition: piecewise.hpp:1125
surface_type::index_type index_type
Definition: piecewise.hpp:58
std::map< data_type, index_type > keymap_type
Definition: piecewise.hpp:1097
bool operator!=(const parameter_key &pk) const
Definition: piecewise.hpp:1120
void to_cubic_u(const data_type &ttol)
Definition: piecewise.hpp:628
void clear()
Definition: piecewise.hpp:599
void get_pmap(std::vector< data_type > &pmap) const
Definition: piecewise.hpp:1235
index_type number_u_patches() const
Definition: piecewise.hpp:142
void init(const it__ &dps, const it__ &dpe, const data_type &p0=0)
Definition: piecewise.hpp:1197
~piecewise()
Definition: piecewise.hpp:84
void find_patch(index_type &uk, index_type &vk, const index_type &ui, const index_type &vi) const
Definition: piecewise.hpp:1611
void find_patch(typename keymap_type::const_iterator &uit, typename keymap_type::const_iterator &vit, data_type &uu, data_type &vv, const data_type &u_in, const data_type &v_in) const
Definition: piecewise.hpp:1645
Definition: piecewise.hpp:71
bool closed_u() const
Definition: piecewise.hpp:316
parameter_key(const parameter_key &pk)
Definition: piecewise.hpp:1105
bool operator==(const piecewise< surface__, data_type, dim__ > &p) const
Definition: piecewise.hpp:100
point_type normal(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:1058
bool operator!=(const piecewise< surface__, data_type, dim__ > &p) const
Definition: piecewise.hpp:126
point_type f_uvv(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:1024
surface_type::bounding_box_type bounding_box_type
Definition: piecewise.hpp:62
surface_type::rotation_matrix_type rotation_matrix_type
Definition: piecewise.hpp:61
surface_type::control_point_type control_point_type
Definition: piecewise.hpp:60
eli::geom::curve::piecewise< eli::geom::curve::bezier, data__, dim__, tol__ > piecewise_curve_type
Definition: piecewise.hpp:64
keymap_type key
Definition: piecewise.hpp:1101
continuity
Definition: continuity.hpp:24
bool equivalent_curves(const bezier< data__, dim__, tol__ > &c0, const bezier< data__, dim__, tol__ > &c1)
Definition: equivalent_curves.hpp:27
void init_uv(const index_type &nsegu, const index_type &nsegv, const data_type &du=1, const data_type &dv=1, const data_type &u0=0, const data_type &v0=0)
Definition: piecewise.hpp:219
void set_t0(const data_type &t0_in)
Definition: piecewise.hpp:340
void get_vconst_curve(piecewise_curve_type &pwc, const data_type &v) const
Definition: piecewise.hpp:756
error_code split_v(const index_type &vk, const typename keymap_type::iterator &vit, const data_type &v_in, const data_type &vv)
Definition: piecewise.hpp:1557
void set_pmin(const data_type &pmin_in)
Definition: piecewise.hpp:1149
data_type get_vmax() const
Definition: piecewise.hpp:140
void append(const it__ &dps, const it__ &dpe)
Definition: piecewise.hpp:1205
patch_collection_type patches
Definition: piecewise.hpp:1492
void find_patch(index_type &uk, index_type &vk, data_type &uu, data_type &vv, const data_type &u_in, const data_type &v_in) const
Definition: piecewise.hpp:1653
const surface_type * get_patch(const index_type &ui, const index_type &vi) const
Definition: piecewise.hpp:152
void get_pmap_uv(std::vector< data_type > &upmap, std::vector< data_type > &vpmap) const
Definition: piecewise.hpp:199
void find_discontinuities(eli::geom::general::continuity cont, std::vector< data_type > &tdisc) const
Definition: piecewise.hpp:1676
void find_patch(typename keymap_type::const_iterator &uit, typename keymap_type::const_iterator &vit, const index_type &ui, const index_type &vi) const
Definition: piecewise.hpp:1604
void get_bounding_box(bounding_box_type &bb) const
Definition: piecewise.hpp:360
surface__< data__, dim__, tol__ > surface_type
Definition: piecewise.hpp:57
error_code set(const surface_type &surf, const index_type &ui, const index_type &vi)
Definition: piecewise.hpp:509
parameter_key vkey
Definition: piecewise.hpp:1495
void reverse_keymap()
Definition: piecewise.hpp:1247
void find_patch(index_type &uk, index_type &vk, typename keymap_type::iterator &uit, typename keymap_type::iterator &vit, data_type &uu, data_type &vv, const data_type &u_in, const data_type &v_in)
Definition: piecewise.hpp:1619
void parameter_report() const
Definition: piecewise.hpp:1219
void init_uv(const it__ &dus, const it__ &due, const it__ &dvs, const it__ &dve, const data_type &u0=0, const data_type &v0=0)
Definition: piecewise.hpp:244
bool operator==(const parameter_key &pk) const
Definition: piecewise.hpp:1108
void degree_u(index_type &mind, index_type &maxd)
Definition: piecewise.hpp:252
void parameter_report()
Definition: piecewise.hpp:181
point_type f_v(const data_type &u, const data_type &v) const
Definition: piecewise.hpp:926
piecewise()
Definition: piecewise.hpp:81
index_type nu
Definition: piecewise.hpp:1496