Code-Eli  0.3.6
piecewise_capped_surface_creator.hpp
Go to the documentation of this file.
1 /*********************************************************************************
2 * Copyright (c) 2014 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_capped_surface_creator_hpp
14 #define eli_geom_surface_piecewise_capped_surface_creator_hpp
15 
16 #include <list>
17 #include <iterator>
18 
19 #include "eli/code_eli.hpp"
20 
21 #include "eli/util/tolerance.hpp"
22 
25 
30 
31 namespace eli
32 {
33  namespace geom
34  {
35  namespace surface
36  {
37  template<typename data__, unsigned short dim__, typename tol__>
38  class piecewise_capped_surface_creator : public piecewise_creator_base<data__, dim__, tol__>
39  {
40  public:
42  {
48  };
49 
56 
58  : piecewise_creator_base<data__, dim__, tol__>(0, 0), delta_param(1), edge_to_cap(CAP_NONE)
59  {
60  }
61  piecewise_capped_surface_creator(const piecewise_surface_type &os, const data_type &dp, edge_cap_identifier ec)
62  : piecewise_creator_base<data__, dim__, tol__>(0, 0), orig_surface(os), delta_param(dp), edge_to_cap(ec)
63  {
64  }
66  : piecewise_creator_base<data_type, dim__, tolerance_type>(gs), orig_surface(gs.orig_surface),
68  {
69  }
71  {
72  }
73 
74  bool set_conditions(const piecewise_surface_type &os, const data_type &dp, edge_cap_identifier ec)
75  {
76  // all deltas are positive, even on the min edges
77  if (dp<=0)
78  return false;
79 
80  orig_surface = os;
81  edge_to_cap = ec;
82  delta_param = dp;
83 
84  return true;
85  }
86 
87  virtual bool create(piecewise_surface_type &ps) const
88  {
90 
91  tolerance_type tol;
92 
93  // extract the curve corresonding to the edge of surface wanting to cap
94  piecewise_curve_type edge;
95  switch (edge_to_cap)
96  {
97  case (CAP_UMIN):
98  {
100  break;
101  }
102  case (CAP_UMAX):
103  {
105  break;
106  }
107  case (CAP_VMIN):
108  {
110  break;
111  }
112  case (CAP_VMAX):
113  {
115  break;
116  }
117  default:
118  {
119  // must not want any edge capped
120  assert(edge_to_cap==CAP_NONE);
121  return false;
122  }
123  }
124 
125  // make sure extracted curve is closed
126  if (edge.open())
127  {
128  return false;
129  }
130 
131  // make sure that the split location is different than the start/end location otherwise
132  // the edge is a point and no need to cap
133  data_type tmin(edge.get_t0()), tmax(edge.get_tmax()), tsplit((tmin+tmax)/2);
134  if (tol.approximately_equal(edge.f(tmin), edge.f(tsplit)))
135  {
136  return false;
137  }
138 
139  // split the curve at the mid-parameter location and reverse the second piece's parameterization
140  piecewise_curve_type first_half, second_half;
141  edge.split(first_half, second_half, tsplit);
142  second_half.reverse();
143  second_half.set_t0(first_half.get_t0());
144 
145  assert(first_half.get_t0()==second_half.get_t0());
146  assert(first_half.get_tmax()==second_half.get_tmax());
147 
148  // create surface connecting two edges with param spacing of 2*delta_param and points for other two edges
149  // cap u-direction goes from second_half curve to first_half curve
150  // cap v-direction follows first_half direction
151  piecewise_surface_type cap;
152  {
155 
156  std::vector<rib_data_type> ribs(2);
157  std::vector<typename general_creator_type::index_type> max_degree(1);
158  general_creator_type gc;
159  bool rtn_flag;
160 
161  // set the rib data
162  ribs[0].set_f(second_half);
163  ribs[1].set_f(first_half);
164 
165  // set the maximum degrees of each segment
166  max_degree[0]=0;
167 
168  // create surface
169  rtn_flag=gc.set_conditions(ribs, max_degree, false);
170  if (!rtn_flag)
171  {
172  assert(false);
173  return false;
174  }
175  gc.set_u0(orig_surface.get_u0()-2*delta_param);
176  gc.set_segment_du(2*delta_param, 0);
177  rtn_flag=gc.create(cap);
178  if (!rtn_flag)
179  {
180  assert(false);
181  return false;
182  }
183  }
184 
185  // split the cap surface at mid point
186  cap.split_u(orig_surface.get_u0()-delta_param);
187 
188  // resize output surface to needed size
189  data_type u0, v0;
190  std::vector<data_type> ucap_param, vcap_param, uparam, vparam, du, dv;
191  index_type i, j, icap_mid, umin_offset(0), vmin_offset(0);
192 
193  orig_surface.get_pmap_u(uparam);
194  cap.get_pmap_uv(ucap_param, vcap_param);
195  // NOTE: This assumes that there are same number of patches on both sides of split
196  icap_mid=ucap_param.size()/2;
197  switch (edge_to_cap)
198  {
199  case (CAP_UMIN):
200  {
201  // establish the new u and v parameterization of surface
202  const index_type nucap_patch(icap_mid), nvcap_patch(cap.number_v_patches());
203  u0=ucap_param[icap_mid];
204  du.resize(uparam.size()-1+nucap_patch);
205  for (i=icap_mid; i<static_cast<index_type>(ucap_param.size())-1; ++i)
206  {
207  du[i-icap_mid]=ucap_param[i+1]-ucap_param[i];
208  }
209  for (i=0; i<static_cast<index_type>(uparam.size())-1; ++i)
210  {
211  du[i+nucap_patch]=uparam[i+1]-uparam[i];
212  }
213 
214  // set the new v-parameterization
215  vparam.resize(2*vcap_param.size()-1);
216  data_type vmid(vcap_param[vcap_param.size()-1]);
217  for (j=0; j<static_cast<index_type>(vcap_param.size()); ++j)
218  {
219  vparam[j]=vcap_param[j];
220  vparam[vparam.size()-1-j]=2*vmid-vparam[j];
221  }
222 
223  // set the v-parameters
224  v0=vparam[0];
225  dv.resize(vparam.size()-1);
226  for (j=0; j<static_cast<index_type>(dv.size()); ++j)
227  {
228  dv[j]=vparam[j+1]-vparam[j];
229  }
230 
231  // split a copy original surface at any new v-coordinate locations
232  piecewise_surface_type orig_copy(orig_surface);
234 
235  for (j=0; j<static_cast<index_type>(vparam.size()); ++j)
236  {
237  orig_copy.split_v(vparam[j]);
238  }
239  assert(orig_copy.number_v_patches()==(static_cast<index_type>(vparam.size())-1));
240 
241  // resize the output surface
242  ps.init_uv(du.begin(), du.end(), dv.begin(), dv.end(), u0, v0);
243  umin_offset=nucap_patch;
244 
245  // add first half of cap surfaces
246  for (i=0; i<nucap_patch; ++i)
247  {
248  for (j=0; j<nvcap_patch; ++j)
249  {
250  cap.get(patch, i + nucap_patch, j);
251  ps.set(patch, i, j);
252  }
253  }
254 
255  // reverse the cap so that the second half
256  cap.reverse_u();
257  cap.reverse_v();
258 
259  // add second half of cap surfaces
260  for (i=0; i<nucap_patch; ++i)
261  {
262  for (j=nvcap_patch; j<static_cast<index_type>(dv.size()); ++j)
263  {
264  cap.get(patch, i + nucap_patch, j-nvcap_patch);
265  ps.set(patch, i, j);
266  }
267  }
268 
269  // add non-cap surfaces
270  for (i=0; i<orig_copy.number_u_patches(); ++i)
271  {
272  for (j=0; j<orig_copy.number_v_patches(); ++j)
273  {
274  orig_copy.get(patch, i, j);
275  ps.set(patch, i+umin_offset, j+vmin_offset);
276  }
277  }
278 
279  break;
280  }
281  case (CAP_UMAX):
282  {
283  // need to reverse u-direction
284  cap.reverse_u();
285 
286  // establish the new u and v parameterization of surface
287  const index_type nucap_patch(icap_mid), nu_patch(uparam.size()-1), nvcap_patch(cap.number_v_patches());
288  u0=uparam[0];
289  du.resize(uparam.size()-1+nucap_patch);
290  for (i=0; i<static_cast<index_type>(uparam.size())-1; ++i)
291  {
292  du[i]=uparam[i+1]-uparam[i];
293  }
294  for (i=nu_patch; i<static_cast<index_type>(du.size()); ++i)
295  {
296  du[i]=ucap_param[(i-nu_patch)+1]-ucap_param[i-nu_patch];
297  }
298 
299  // set the new v-parameterization
300  vparam.resize(2*vcap_param.size()-1);
301  data_type vmid(vcap_param[vcap_param.size()-1]);
302  for (j=0; j<static_cast<index_type>(vcap_param.size()); ++j)
303  {
304  vparam[j]=vcap_param[j];
305  vparam[vparam.size()-1-j]=2*vmid-vparam[j];
306  }
307 
308  // set the v-parameters
309  v0=vparam[0];
310  dv.resize(vparam.size()-1);
311  for (j=0; j<static_cast<index_type>(dv.size()); ++j)
312  {
313  dv[j]=vparam[j+1]-vparam[j];
314  }
315 
316  // split a copy original surface at any new v-coordinate locations
317  piecewise_surface_type orig_copy(orig_surface);
319 
320  for (j=0; j<static_cast<index_type>(vparam.size()); ++j)
321  {
322  orig_copy.split_v(vparam[j]);
323  }
324  assert(orig_copy.number_v_patches()==(static_cast<index_type>(vparam.size())-1));
325 
326  // resize the output surface
327  ps.init_uv(du.begin(), du.end(), dv.begin(), dv.end(), u0, v0);
328 
329  // add first half of cap surfaces
330  for (i=0; i<nucap_patch; ++i)
331  {
332  for (j=0; j<nvcap_patch; ++j)
333  {
334  cap.get(patch, i, j);
335  ps.set(patch, i + nu_patch, j);
336  }
337  }
338 
339  // reverse the cap so that the second half
340  cap.reverse_u();
341  cap.reverse_v();
342 
343  // add second half of cap surfaces
344  for (i=0; i<nucap_patch; ++i)
345  {
346  for (j=nvcap_patch; j<static_cast<index_type>(dv.size()); ++j)
347  {
348  cap.get(patch, i, j-nvcap_patch);
349  ps.set(patch, i + nu_patch, j);
350  }
351  }
352 
353  // add non-cap surfaces
354  for (i=0; i<orig_copy.number_u_patches(); ++i)
355  {
356  for (j=0; j<orig_copy.number_v_patches(); ++j)
357  {
358  orig_copy.get(patch, i, j);
359  ps.set(patch, i+umin_offset, j+vmin_offset);
360  }
361  }
362 
363  break;
364  }
365  case (CAP_VMIN):
366  {
367  assert(false);
368  return false;
369  break;
370  }
371  case (CAP_VMAX):
372  {
373  assert(false);
374  return false;
375  break;
376  }
377  default:
378  {
379  // must not want any edge capped
380  assert(edge_to_cap==CAP_NONE);
381  return false;
382  }
383  }
384 
385  return true;
386  }
387 
388  private:
389  piecewise_surface_type orig_surface;
390  data_type delta_param;
392  };
393  }
394  }
395 }
396 #endif
Eigen::Matrix< data_type, 1, dim__ > point_type
Definition: piecewise_creator_base.hpp:37
Definition: math.hpp:20
data__ data_type
Definition: piecewise_creator_base.hpp:36
Definition: piecewise_capped_surface_creator.hpp:46
piecewise_capped_surface_creator(const piecewise_surface_type &os, const data_type &dp, edge_cap_identifier ec)
Definition: piecewise_capped_surface_creator.hpp:61
Definition: piecewise_capped_surface_creator.hpp:43
data_type get_u0() const
Definition: piecewise.hpp:133
void get_uconst_curve(piecewise_curve_type &pwc, const data_type &u) const
Definition: piecewise.hpp:726
error_code get(surface_type &surf, const index_type &ui, const index_type &vi) const
Definition: piecewise.hpp:487
data_type get_umax() const
Definition: piecewise.hpp:139
edge_cap_identifier edge_to_cap
Definition: piecewise_capped_surface_creator.hpp:391
index_type number_v_patches() const
Definition: piecewise.hpp:143
data_type delta_param
Definition: piecewise_capped_surface_creator.hpp:390
Definition: piecewise.hpp:37
Definition: piecewise_creator_base.hpp:33
tol__ tolerance_type
Definition: piecewise_creator_base.hpp:39
Definition: piecewise.hpp:244
Definition: piecewise_general_skinning_surface_creator.hpp:40
piecewise_capped_surface_creator(const piecewise_capped_surface_creator< data_type, dim__, tolerance_type > &gs)
Definition: piecewise_capped_surface_creator.hpp:65
Definition: piecewise_connection_data.hpp:32
bool set_conditions(const piecewise_surface_type &os, const data_type &dp, edge_cap_identifier ec)
Definition: piecewise_capped_surface_creator.hpp:74
Definition: piecewise_capped_surface_creator.hpp:45
base_class_type::index_type index_type
Definition: piecewise_capped_surface_creator.hpp:53
base_class_type::piecewise_surface_type piecewise_surface_type
Definition: piecewise_capped_surface_creator.hpp:55
error_code split_v(const data_type &v_in)
Definition: piecewise.hpp:605
void get_pmap_u(std::vector< data_type > &pmap) const
Definition: piecewise.hpp:189
data_type get_v0() const
Definition: piecewise.hpp:136
piecewise_capped_surface_creator()
Definition: piecewise_capped_surface_creator.hpp:57
base_class_type::tolerance_type tolerance_type
Definition: piecewise_capped_surface_creator.hpp:54
param_container_type dv
Definition: piecewise_creator_base.hpp:185
piecewise_creator_base< data__, dim__, tol__ > base_class_type
Definition: piecewise_capped_surface_creator.hpp:50
index_type number_u_patches() const
Definition: piecewise.hpp:142
data_type v0
Definition: piecewise_creator_base.hpp:186
Definition: piecewise_capped_surface_creator.hpp:44
data_type u0
Definition: piecewise_creator_base.hpp:186
edge_cap_identifier
Definition: piecewise_capped_surface_creator.hpp:41
point_type::Index index_type
Definition: piecewise_creator_base.hpp:38
param_container_type du
Definition: piecewise_creator_base.hpp:185
virtual bool create(piecewise_surface_type &ps) const
Definition: piecewise_capped_surface_creator.hpp:87
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 get_vconst_curve(piecewise_curve_type &pwc, const data_type &v) const
Definition: piecewise.hpp:756
data_type get_vmax() const
Definition: piecewise.hpp:140
base_class_type::point_type point_type
Definition: piecewise_capped_surface_creator.hpp:52
base_class_type::data_type data_type
Definition: piecewise_capped_surface_creator.hpp:51
piecewise_surface_type orig_surface
Definition: piecewise_capped_surface_creator.hpp:389
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
virtual ~piecewise_capped_surface_creator()
Definition: piecewise_capped_surface_creator.hpp:70
Definition: piecewise_capped_surface_creator.hpp:38
Definition: piecewise_capped_surface_creator.hpp:47