IFEM 90A354
ASMs3DInterpolate.C
1#include "GoTools/trivariate/SplineVolume.h"
3#include "MatVec.h"
4
23static Go::SplineVolume*
24leastsquare_approximation(const Go::BsplineBasis& basis_u,
25 const Go::BsplineBasis& basis_v,
26 const Go::BsplineBasis& basis_w,
27 const RealArray& par_u,
28 const RealArray& par_v,
29 const RealArray& par_w,
30 const RealArray& wpar_u,
31 const RealArray& wpar_v,
32 const RealArray& wpar_w,
33 const RealArray& points,
34 int dimension, bool rational,
35 const RealArray& weights)
36{
37 // Check input
38 ASSERT(par_u.size()*par_v.size()*par_w.size() == points.size()/dimension);
39 ASSERT((int)wpar_u.size() == (int)par_u.size());
40 ASSERT((int)wpar_v.size() == (int)par_v.size());
41 ASSERT((int)wpar_w.size() == (int)par_w.size());
42
43 std::vector<double> points2;
44 int perknot=dimension;
45 if (rational)
46 {
47 Go::SplineVolume denom(basis_u, basis_v, basis_w, weights.begin(), 1,false);
48 std::vector<double> wgtval;
49 denom.gridEvaluator(par_u, par_v, par_w, wgtval);
50 size_t nmb_pnt = par_u.size()*par_v.size()*par_w.size();
51 points2.reserve(nmb_pnt*(dimension+1));
52 for (size_t kr=0; kr<nmb_pnt; ++kr)
53 {
54 for (int kh=0; kh<dimension; kh++)
55 points2.push_back(points[kr*dimension+kh]*wgtval[kr]);
56 points2.push_back(wgtval[kr]);
57 }
58 perknot++;
59 }
60 else
61 points2 = points;
62
63 // Interpolate surfaces in the second parameter direction and
64 // curves in the first parameter direction
65 size_t ki, kj;
66 std::vector<double> sf_coefs;
67 std::vector<double> tg_pnt;
68 for (kj=0; kj<par_w.size(); ++kj)
69 {
70 std::vector<double> cv_coefs;
71 for (ki=0; ki<par_v.size(); ++ki)
72 {
73 // Interpolate
74 std::vector<double> coefs;
75 std::vector<double> pnts;
76 pnts.insert(pnts.end(),
77 points2.begin()+(kj*par_v.size()+ki)*perknot*par_u.size(),
78 points2.begin()+(kj*par_v.size()+ki+1)*perknot*par_u.size());
79
80 SplineInterpolator::leastsquare_approximation(par_u, wpar_u, pnts, tg_pnt,
81 basis_u, coefs);
82 cv_coefs.insert(cv_coefs.end(), coefs.begin(), coefs.end());
83 }
84
85 // Interpolate the curves to make a surface
86 std::vector<double> coefs2;
87
88 SplineInterpolator::leastsquare_approximation(par_v, wpar_v, cv_coefs, tg_pnt,
89 basis_v, coefs2);
90 sf_coefs.insert(sf_coefs.end(), coefs2.begin(), coefs2.end());
91 }
92
93 // Interpolate surfaces to create volume
94 std::vector<double> vol_coefs;
95 SplineInterpolator::leastsquare_approximation(par_w, wpar_w, sf_coefs, tg_pnt,
96 basis_w, vol_coefs);
97
98 // Make volume
99 return new Go::SplineVolume(basis_u, basis_v, basis_w, vol_coefs.begin(),
100 dimension, rational);
101}
102
103
119static Go::SplineVolume*
120quasiInterpolation(const Go::BsplineBasis& basis_u,
121 const Go::BsplineBasis& basis_v,
122 const Go::BsplineBasis& basis_w,
123 const RealArray& par_u,
124 const RealArray& par_v,
125 const RealArray& par_w,
126 const RealArray& points,
127 int dimension, bool rational,
128 const RealArray& weights)
129{
130 std::vector< double > knots_simple_u;
131 basis_u.knotsSimple(knots_simple_u);
132 std::vector< double > knots_simple_v;
133 basis_v.knotsSimple(knots_simple_v);
134
135 int count_multipl_knots_u;
136 int count_multipl_knots_v;
137
138 count_multipl_knots_u = basis_u.numCoefs()-basis_u.order()+2 - knots_simple_u.size();
139 count_multipl_knots_v = basis_v.numCoefs()-basis_v.order()+2 - knots_simple_v.size();
140
141 ASSERT(2*basis_u.order()-3 <= (int)par_u.size());
142 ASSERT(2*basis_v.order()-3 <= (int)par_v.size());
143
144 // Check input
145 ASSERT(par_u.size()*par_v.size()*par_w.size() == points.size()/dimension);
146 ASSERT(2*(basis_u.numCoefs()-basis_u.order()+1)+1-2*count_multipl_knots_u == (int)par_u.size());
147 ASSERT(2*(basis_v.numCoefs()-basis_v.order()+1)+1-2*count_multipl_knots_v == (int)par_v.size());
148
149 if (count_multipl_knots_u > 0)
150 ASSERT( (par_u.size()+1)*0.5 - (2*(basis_u.order()-1)-1) >= 0);
151 if (count_multipl_knots_v > 0)
152 ASSERT( (par_v.size()+1)*0.5 - (2*(basis_v.order()-1)-1) >= 0);
153
154 std::vector<double> points2;
155 int perknot=dimension;
156 if (rational)
157 {
158 Go::SplineVolume denom(basis_u, basis_v, basis_w, weights.begin(), 1,false);
159 std::vector<double> wgtval;
160 denom.gridEvaluator(par_u, par_v, par_w, wgtval);
161 size_t nmb_pnt = par_u.size()*par_v.size()*par_w.size();
162 points2.reserve(nmb_pnt*(dimension+1));
163 for (size_t kr=0; kr<nmb_pnt; ++kr)
164 {
165 for (int kh=0; kh<dimension; kh++)
166 points2.push_back(points[kr*dimension+kh]*wgtval[kr]);
167 points2.push_back(wgtval[kr]);
168 }
169 perknot++;
170 }
171 else
172 points2 = points;
173
174
175 // Interpolate surfaces in the second parameter direction and
176 // curves in the first parameter direction
177 size_t ki, kj;
178 int ui;
179 std::vector<double> volinput_coefs;
180 std::vector<double> tg_pnt;
181 int p,q;
182 p = basis_u.order()-1;
183 q = basis_v.order()-1;
184
185 for (kj=0; kj<par_w.size(); ++kj)
186 {
187 std::vector<double> cv_coefs;
188 std::vector<double> multi_u(knots_simple_u.size());
189 std::vector<double> multi_idx_u(knots_simple_u.size());
190 double multi_value_u=-1.0;
191 multi_idx_u[0]=0;
192 multi_u[0]=1;
193 multi_idx_u[knots_simple_u.size()-1]=0;
194 multi_u[knots_simple_u.size()-1]=1;
195 for (int i = 1;i<(int)knots_simple_u.size()-1;i++)
196 {
197 int knot_intern_multipl;
198 knot_intern_multipl = basis_u.knotMultiplicity(knots_simple_u[i]);
199 multi_u[i]=knot_intern_multipl;
200 if (knot_intern_multipl > 1) {
201 multi_idx_u[i]=1;
202 multi_value_u = knots_simple_u[i];
203 } else
204 multi_idx_u[i]= 0;
205 }
206
207 for (ki=0; ki<par_v.size(); ++ki)
208 {
209 // Interpolate
210 std::vector<double> pnts;
211
212 pnts.insert(pnts.end(), points2.begin()+(kj*par_v.size()+ki)*perknot*par_u.size(),points2.begin()+(kj*par_v.size()+ki+1)*perknot*par_u.size());
213 int ui_end = par_u.size()+2*count_multipl_knots_u-basis_u.numCoefs()+1;
214
215 if (count_multipl_knots_u == 0) {
216 for (ui = 0; ui< ui_end;ui++) {
217 std::vector<double> pnts_parts;
218 std::vector<double> par_u_parts;
219 par_u_parts.insert(par_u_parts.end(),par_u.begin()+ui*2,par_u.begin()+ui*2+(2*p-1));
220 pnts_parts.insert(pnts_parts.end(), pnts.begin()+ui*2*perknot, pnts.begin()+(ui*2+(2*p-1))*perknot);
221 std::vector<double> coefs;
222
223 SplineInterpolator::quasiinterpolate(par_u_parts, pnts_parts, tg_pnt,
224 basis_u, ui, coefs);
225 cv_coefs.insert(cv_coefs.end(), coefs.begin(), coefs.end());
226 }
227 }
228 else
229 {
230 if (p>1) {
231 int count = 0;
232 int dcount = 0;
233 int count_intern = 0;
234 int ti = 0;
235 int terminate=ui_end;
236 int m = count_multipl_knots_u+1;
237
238 while(ti<terminate)
239 {
240 std::vector<double> par_u_parts;
241 par_u_parts.insert(par_u_parts.end(),par_u.begin()+ti*2,par_u.begin()+ti*2+(2*p-1));
242
243 if ( par_u_parts[par_u_parts.size()-1]==multi_value_u)
244 {
245 terminate = 2*ti+1;
246
247 if ( (!(p&1) && !(m&1)) || ( (p&1) && (m&1) ) )
248 {
249 int countj=0;
250 for (int j= 0; j < (p-m+2)*0.5;j++){
251 std::vector<double> pnts_parts;
252 std::vector<double> par_u_parts;
253 par_u_parts.insert(par_u_parts.end(),par_u.begin()+(j+count)*2,par_u.begin()+(j+count)*2+(2*p-1));//dp(j+count,:)
254 pnts_parts.insert(pnts_parts.end(), pnts.begin()+(j+count)*2*perknot, pnts.begin()+((j+count)*2+(2*p-1))*perknot);
255 std::vector<double> coefs;
256 SplineInterpolator::quasiinterpolate(par_u_parts, pnts_parts,
257 tg_pnt, basis_u,
258 j+count+countj, coefs);
259 cv_coefs.insert(cv_coefs.end(), coefs.begin(), coefs.end());
260 count_intern = j+count+countj;
261 }
262 countj = count_intern+1;
263 for (int j= 0; j < 2*m-3;j++){
264 std::vector<double> pnts_parts;
265 std::vector<double> par_u_parts;
266 par_u_parts.insert(par_u_parts.end(),par_u.begin()+p-m+1+j+2*count,par_u.begin()+3*p-m-1+j+2*count+1);//dist_vec(p-m+1+j+2*count:3*p-m-1+j+2*count)
267 pnts_parts.insert(pnts_parts.end(), pnts.begin()+(p-m+1+j+2*count)*perknot, pnts.begin()+(3*p-m-1+j+2*count+1)*perknot);
268 std::vector<double> coefs;
269
270 SplineInterpolator::quasiinterpolate(par_u_parts, pnts_parts, tg_pnt,
271 basis_u, j+countj, coefs);
272 cv_coefs.insert(cv_coefs.end(), coefs.begin(), coefs.end());
273 count_intern = j+countj;
274 }
275 countj = count_intern+1;
276 for (int j = 0; j<(p-m+2)*0.5;j++){
277 std::vector<double> pnts_parts;
278 std::vector<double> par_u_parts;
279 par_u_parts.insert(par_u_parts.end(),par_u.begin()+(j+count+((p-m+2)*0.5)+m-2)*2,par_u.begin()+(j+count+((p-m+2)*0.5)+m-2)*2+(2*p-1));//dp(j+count+((p-m+2)*0.5)+m-2,:)
280 pnts_parts.insert(pnts_parts.end(), pnts.begin()+(j+count+((p-m+2)*0.5)+m-2)*2*perknot, pnts.begin()+((j+count+((p-m+2)*0.5)+m-2)*2+(2*p-1))*perknot);
281 std::vector<double> coefs;
282
283 SplineInterpolator::quasiinterpolate(par_u_parts, pnts_parts, tg_pnt,
284 basis_u, j+countj, coefs);
285 cv_coefs.insert(cv_coefs.end(), coefs.begin(), coefs.end());
286 count_intern = j+countj;
287 }
288 }
289 else
290 {
291 int countj=0;
292 for (int j=0; j<(p-m+1)*0.5;j++){
293 std::vector<double> pnts_parts;
294 std::vector<double> par_u_parts;
295 par_u_parts.insert(par_u_parts.end(),par_u.begin()+(j+count)*2,par_u.begin()+(j+count)*2+(2*p-1));//dp(j+count,:)
296 pnts_parts.insert(pnts_parts.end(), pnts.begin()+(j+count)*2*perknot, pnts.begin()+((j+count)*2+(2*p-1))*perknot);
297 std::vector<double> coefs;
298
299 SplineInterpolator::quasiinterpolate(par_u_parts, pnts_parts,
300 tg_pnt, basis_u,
301 j+count+countj, coefs);
302 cv_coefs.insert(cv_coefs.end(), coefs.begin(), coefs.end());
303 count_intern = j+count+countj;
304 }
305 countj = count_intern+1;
306 for (int j = 0;j<m-1;j++){
307 std::vector<double> pnts_parts;
308 std::vector<double> par_u_parts;
309 par_u_parts.insert(par_u_parts.end(),par_u.begin()+p-m+j+2*count,par_u.begin()+3*p-m-2+2*count+j+1);//dist_vec(p-m+j+2*count:3*p-m-2+2*count+j)
310 pnts_parts.insert(pnts_parts.end(), pnts.begin()+(p-m+j+2*count)*perknot, pnts.begin()+(3*p-m-2+2*count+j+1)*perknot);
311 std::vector<double> coefs;
312
313 SplineInterpolator::quasiinterpolate(par_u_parts, pnts_parts,
314 tg_pnt, basis_u,
315 j+countj, coefs);
316 cv_coefs.insert(cv_coefs.end(), coefs.begin(), coefs.end());
317 count_intern = j+countj;
318 }
319 countj = count_intern+1;
320 for (int j=0;j<m-1;j++){
321 std::vector<double> pnts_parts;
322 std::vector<double> par_u_parts;
323 par_u_parts.insert(par_u_parts.end(),par_u.begin()+p+j+2*count,par_u.begin()+3*p-2+j+2*count+1);//dist_vec(p+j+2*count:3*p-2+j+2*count)
324 pnts_parts.insert(pnts_parts.end(), pnts.begin()+(p+j+2*count)*perknot, pnts.begin()+(3*p-2+j+2*count+1)*perknot);
325 std::vector<double> coefs;
326
327 SplineInterpolator::quasiinterpolate(par_u_parts, pnts_parts,
328 tg_pnt, basis_u,
329 j+countj, coefs);
330 cv_coefs.insert(cv_coefs.end(), coefs.begin(), coefs.end());
331 count_intern = j+countj;
332 }
333 countj = count_intern+1;
334 for (int j=0;j<(p-m+1)*0.5;j++){
335 std::vector<double> pnts_parts;
336 std::vector<double> par_u_parts;
337 par_u_parts.insert(par_u_parts.end(),par_u.begin()+(j+count+((p-m+1)*0.5)+m-1)*2,par_u.begin()+(j+count+((p-m+1)*0.5)+m-1)*2+(2*p-1));//dp(j+count+((p-m+1)*0.5)+m-1,:)
338 pnts_parts.insert(pnts_parts.end(), pnts.begin()+(j+count+((p-m+1)*0.5)+m-1)*2*perknot, pnts.begin()+((j+count+((p-m+1)*0.5)+m-1)*2+(2*p-1))*perknot);
339 std::vector<double> coefs;
340
341 SplineInterpolator::quasiinterpolate(par_u_parts, pnts_parts,
342 tg_pnt, basis_u,
343 j+countj, coefs);
344 cv_coefs.insert(cv_coefs.end(), coefs.begin(), coefs.end());
345 }
346 }//else
347 dcount = p+(m-2);
348 }//end if multivalue
349 else
350 {
351 if (dcount > 0)
352 {
353 std::vector<double> pnts_parts;
354 std::vector<double> par_u_parts;
355 par_u_parts.insert(par_u_parts.end(),par_u.begin()+(dcount+ti-(m-1))*2,par_u.begin()+(dcount+ti-(m-1))*2+(2*p-1));
356 pnts_parts.insert(pnts_parts.end(), pnts.begin()+(dcount+ti-(m-1))*2*perknot, pnts.begin()+((dcount+ti-(m-1))*2+(2*p-1))*perknot);
357
358 std::vector<double> coefs;
359
360 SplineInterpolator::quasiinterpolate(par_u_parts, pnts_parts,
361 tg_pnt, basis_u,
362 ti+dcount, coefs);
363 cv_coefs.insert(cv_coefs.end(), coefs.begin(), coefs.end());
364 }
365 else
366 {
367 std::vector<double> pnts_parts;
368 std::vector<double> par_u_parts;
369 par_u_parts.insert(par_u_parts.end(),par_u.begin()+(ti+dcount)*2,par_u.begin()+(ti+dcount)*2+(2*p-1));
370 pnts_parts.insert(pnts_parts.end(), pnts.begin()+(ti+dcount)*2*perknot, pnts.begin()+((ti+dcount)*2+(2*p-1))*perknot);
371 std::vector<double> coefs;
372
373 SplineInterpolator::quasiinterpolate(par_u_parts, pnts_parts,
374 tg_pnt, basis_u, ti, coefs);
375 cv_coefs.insert(cv_coefs.end(), coefs.begin(), coefs.end());
376
377 count = count+1;
378 }
379 }
380 ti++;
381 }// end while
382 }// end if p>1
383 }//else
384
385 }//end ki
386
387
388 //-------------------------------------------------------------------------
389
390 // Interpolate the curves to make a surface
391 std::vector<double> multi_v(knots_simple_v.size());
392 std::vector<double> multi_idx_v(knots_simple_v.size());
393 double multi_value_v=-1.0;
394 multi_idx_v[0]=0;
395 multi_v[0]=1;
396 multi_idx_v[knots_simple_v.size()-1]=0;
397 multi_v[knots_simple_v.size()-1]=1;
398 for (int i = 1;i<(int)knots_simple_v.size()-1;i++)
399 {
400 int knot_intern_multipl;
401 knot_intern_multipl = basis_v.knotMultiplicity(knots_simple_v[i]);
402 multi_v[i]=knot_intern_multipl;
403 if (knot_intern_multipl > 1) {
404 multi_idx_v[i]=1;
405 multi_value_v = knots_simple_v[i];
406 } else
407 multi_idx_v[i]= 0;
408 }
409
410 std::vector<double> sf_coefs;
411 int ucount = (par_u.size() + 2*count_multipl_knots_u - basis_u.numCoefs()+1)*(2*p-1)*perknot;
412 int vi_end = par_v.size() + 2*count_multipl_knots_v - basis_v.numCoefs()+1 ;
413
414 if (count_multipl_knots_v == 0)
415 {
416 for (int vi = 0; vi< vi_end;vi++)
417 {
418 std::vector<double> coefs_parts;
419 std::vector<double> par_v_parts;
420 par_v_parts.insert(par_v_parts.end(),par_v.begin()+vi*2,par_v.begin()+vi*2+(2*q-1));
421 coefs_parts.insert(coefs_parts.end(), cv_coefs.begin()+vi*2*ucount, cv_coefs.begin()+(vi*2+(2*q-1))*ucount);
422 std::vector<double> sf_coefs_parts;
423
424 SplineInterpolator::quasiinterpolate(par_v_parts, coefs_parts, tg_pnt,
425 basis_v, vi, sf_coefs_parts);
426 sf_coefs.insert(sf_coefs.end(), sf_coefs_parts.begin(), sf_coefs_parts.end());
427 }
428 }
429 else
430 {
431 if (q>1)
432 {
433 int count = 0;
434 int dcount = 0;
435 int count_intern = 0;
436 int ti = 0;
437 int terminate=vi_end;
438 int m = count_multipl_knots_v+1;
439
440 while(ti<terminate)
441 {
442 std::vector<double> par_v_parts;
443 par_v_parts.insert(par_v_parts.end(),par_v.begin()+ti*2,par_v.begin()+ti*2+(2*q-1));
444
445 if ( par_v_parts[par_v_parts.size()-1]==multi_value_v)
446 {
447 terminate = 2*ti+1;
448
449 if ( (!(q&1) && !(m&1)) || ( (q&1) && (m&1) ) )
450 {
451 int countj=0;
452 for (int j= 0; j < (q-m+2)*0.5;j++){
453 std::vector<double> coefs_parts;
454 std::vector<double> par_v_parts;
455 par_v_parts.insert(par_v_parts.end(),par_v.begin()+(j+count)*2,par_v.begin()+(j+count)*2+(2*q-1));//dp(j+count,:)
456 coefs_parts.insert(coefs_parts.end(), cv_coefs.begin()+(j+count)*2*ucount, cv_coefs.begin()+((j+count)*2+(2*q-1))*ucount);
457 std::vector<double> sf_coefs_parts;
458
459 SplineInterpolator::quasiinterpolate(par_v_parts, coefs_parts,
460 tg_pnt, basis_v,
461 j+count+countj, sf_coefs_parts);
462 sf_coefs.insert(sf_coefs.end(), sf_coefs_parts.begin(), sf_coefs_parts.end());
463 count_intern = j+count+countj;
464 }
465 countj = count_intern+1;
466 for (int j= 0; j < 2*m-3;j++){
467 std::vector<double> coefs_parts;
468 std::vector<double> par_v_parts;
469 par_v_parts.insert(par_v_parts.end(),par_v.begin()+q-m+1+j+2*count,par_v.begin()+3*q-m-1+j+2*count+1);//dist_vec(q-m+1+j+2*count:3*q-m-1+j+2*count)
470 coefs_parts.insert(coefs_parts.end(), cv_coefs.begin()+(q-m+1+j+2*count)*ucount, cv_coefs.begin()+(3*q-m-1+j+2*count+1)*ucount);
471 std::vector<double> sf_coefs_parts;
472
473 SplineInterpolator::quasiinterpolate(par_v_parts, coefs_parts,
474 tg_pnt, basis_v,
475 j+countj, sf_coefs_parts);
476 sf_coefs.insert(sf_coefs.end(), sf_coefs_parts.begin(), sf_coefs_parts.end());
477 count_intern = j+countj;
478 }
479 countj = count_intern+1;
480 for (int j = 0; j<(q-m+2)*0.5;j++){
481 std::vector<double> coefs_parts;
482 std::vector<double> par_v_parts;
483 par_v_parts.insert(par_v_parts.end(),par_v.begin()+(j+count+((q-m+2)*0.5)+m-2)*2,par_v.begin()+(j+count+((q-m+2)*0.5)+m-2)*2+(2*q-1));//dp(j+count+((q-m+2)*0.5)+m-2,:)
484 coefs_parts.insert(coefs_parts.end(), cv_coefs.begin()+(j+count+((q-m+2)*0.5)+m-2)*2*ucount, cv_coefs.begin()+((j+count+((q-m+2)*0.5)+m-2)*2+(2*q-1))*ucount);
485 std::vector<double> sf_coefs_parts;
486
487 SplineInterpolator::quasiinterpolate(par_v_parts, coefs_parts,
488 tg_pnt, basis_v,
489 j+countj, sf_coefs_parts);
490 sf_coefs.insert(sf_coefs.end(), sf_coefs_parts.begin(), sf_coefs_parts.end());
491 count_intern = j+countj;
492 }
493 }
494 else
495 {
496 int countj=0;
497 for (int j=0; j<(q-m+1)*0.5;j++){
498 std::vector<double> coefs_parts;
499 std::vector<double> par_v_parts;
500 par_v_parts.insert(par_v_parts.end(),par_v.begin()+(j+count)*2,par_v.begin()+(j+count)*2+(2*q-1));//dp(j+count,:)
501 coefs_parts.insert(coefs_parts.end(), cv_coefs.begin()+(j+count)*2*ucount, cv_coefs.begin()+((j+count)*2+(2*q-1))*ucount);
502
503 std::vector<double> sf_coefs_parts;
504
505 SplineInterpolator::quasiinterpolate(par_v_parts, coefs_parts,
506 tg_pnt, basis_v,
507 j+count+countj, sf_coefs_parts);
508 sf_coefs.insert(sf_coefs.end(), sf_coefs_parts.begin(), sf_coefs_parts.end());
509 count_intern = j+count+countj;
510 }
511 countj = count_intern+1;
512 for (int j = 0;j<m-1;j++){
513 std::vector<double> coefs_parts;
514 std::vector<double> par_v_parts;
515 par_v_parts.insert(par_v_parts.end(),par_v.begin()+q-m+j+2*count,par_v.begin()+3*q-m-2+2*count+j+1);//dist_vec(q-m+j+2*count:3*q-m-2+2*count+j)
516 coefs_parts.insert(coefs_parts.end(), cv_coefs.begin()+(q-m+j+2*count)*ucount, cv_coefs.begin()+(3*q-m-2+2*count+j+1)*ucount);
517
518 std::vector<double> sf_coefs_parts;
519
520 SplineInterpolator::quasiinterpolate(par_v_parts, coefs_parts,
521 tg_pnt, basis_v,
522 j+countj, sf_coefs_parts);
523 sf_coefs.insert(sf_coefs.end(), sf_coefs_parts.begin(), sf_coefs_parts.end());
524 count_intern = j+countj;
525 }
526 countj = count_intern+1;
527 for (int j=0;j<m-1;j++){
528 std::vector<double> coefs_parts;
529 std::vector<double> par_v_parts;
530 par_v_parts.insert(par_v_parts.end(),par_v.begin()+q+j+2*count,par_v.begin()+3*q-2+j+2*count+1);//dist_vec(q+j+2*count:3*q-2+j+2*count)
531 coefs_parts.insert(coefs_parts.end(), cv_coefs.begin()+(q+j+2*count)*ucount, cv_coefs.begin()+(3*q-2+j+2*count+1)*ucount);
532
533 std::vector<double> sf_coefs_parts;
534
535 SplineInterpolator::quasiinterpolate(par_v_parts, coefs_parts,
536 tg_pnt, basis_v,
537 j+countj, sf_coefs_parts);
538 sf_coefs.insert(sf_coefs.end(), sf_coefs_parts.begin(), sf_coefs_parts.end());
539 count_intern = j+countj;
540 }
541 countj = count_intern+1;
542 for (int j=0;j<(q-m+1)*0.5;j++){
543 std::vector<double> coefs_parts;
544 std::vector<double> par_v_parts;
545 par_v_parts.insert(par_v_parts.end(),par_v.begin()+(j+count+((q-m+1)*0.5)+m-1)*2,par_v.begin()+(j+count+((q-m+1)*0.5)+m-1)*2+(2*q-1));//dp(j+count+((q-m+1)*0.5)+m-1,:)
546 coefs_parts.insert(coefs_parts.end(), cv_coefs.begin()+(j+count+((q-m+1)*0.5)+m-1)*2*ucount, cv_coefs.begin()+((j+count+((q-m+1)*0.5)+m-1)*2+(2*q-1))*ucount);
547
548 std::vector<double> sf_coefs_parts;
549
550 SplineInterpolator::quasiinterpolate(par_v_parts, coefs_parts,
551 tg_pnt, basis_v,
552 j+countj, sf_coefs_parts);
553 sf_coefs.insert(sf_coefs.end(), sf_coefs_parts.begin(), sf_coefs_parts.end());
554 }
555 }//else
556
557 dcount = q+(m-2);
558 }//end if multivalue
559 else
560 {
561 if (dcount > 0)
562 {
563 std::vector<double> coefs_parts;
564 std::vector<double> par_v_parts;
565
566 par_v_parts.insert(par_v_parts.end(),par_v.begin()+(dcount+ti-(m-1))*2,par_v.begin()+(dcount+ti-(m-1))*2+(2*q-1));
567 coefs_parts.insert(coefs_parts.end(), cv_coefs.begin()+(dcount+ti-(m-1))*2*ucount, cv_coefs.begin()+((dcount+ti-(m-1))*2+(2*q-1))*ucount);
568 std::vector<double> sf_coefs_parts;
569
570 SplineInterpolator::quasiinterpolate(par_v_parts, coefs_parts,
571 tg_pnt, basis_v,
572 ti+dcount, sf_coefs_parts);
573 sf_coefs.insert(sf_coefs.end(), sf_coefs_parts.begin(), sf_coefs_parts.end());
574 }
575 else
576 {
577 std::vector<double> coefs_parts;
578 std::vector<double> par_v_parts;
579 par_v_parts.insert(par_v_parts.end(),par_v.begin()+(ti+dcount)*2,par_v.begin()+(ti+dcount)*2+(2*q-1));
580 coefs_parts.insert(coefs_parts.end(), cv_coefs.begin()+(ti+dcount)*2*ucount, cv_coefs.begin()+((ti+dcount)*2+(2*q-1))*ucount);
581
582 std::vector<double> sf_coefs_parts;
583
584 SplineInterpolator::quasiinterpolate(par_v_parts, coefs_parts,
585 tg_pnt, basis_v,
586 ti, sf_coefs_parts);
587 sf_coefs.insert(sf_coefs.end(), sf_coefs_parts.begin(), sf_coefs_parts.end());
588 count = count+1;
589 }
590 }
591 ti++;
592 }// end while
593 }// end if q>1
594 }//else
595
596
598
599 //eval sf_coefs to generate sf_coefs_solution
600 //boundary conditions
601 int n, m, spxl, spyl, qpxl, qpyl, invxl, invyl, gmxl, gmyl;
602 n = basis_u.numCoefs();
603 m = basis_v.numCoefs();
604 spxl = 2*p-1;
605 spyl = 2*q-1;
606 qpxl = 2*(n-p)+1;
607 qpyl = 2*(m-q)+1;
608 invxl = qpxl-n+1;
609 invyl = qpyl-m+1;
610 gmxl = spxl*invxl;
611 gmyl = spyl*invyl;
612
613 std::vector<std::vector<double> > gm;
614 std::vector<double> tmp;
615 for(int i = 0; i < gmyl ; i++)
616 {
617 for(int j=0 ; j < gmxl*perknot ;j++)
618 {
619 tmp.push_back( 0.0 );
620 }
621 gm.push_back(tmp);
622 }
623
624 std::vector<double> sf_coefs_solution;
625 for(int i = 0; i < n*m*perknot ; i++)
626 sf_coefs_solution.push_back( 0.0 );
627
628 if (invyl == 1 && invxl == 1)
629 {
630 sf_coefs_solution = sf_coefs;
631 }
632 else
633 {
634 for (int b = 0; b < invyl; b++)
635 {
636 for (int a = 0; a < invxl; a++)
637 {
638 int starti = b*(2*q-1);
639 int startj = a*(2*p-1);
640 {if (invyl == 1)
641 {if (a == 0)
642 for (int i = starti;i<(starti+2*q-1);i++)
643 for (int j = startj;j<(startj+p)*perknot;j++)
644 gm[i][j] = 1;
645 else if (a == invxl-1)
646 for (int i = starti;i<(starti+2*q-1);i++)
647 for (int j = (startj+p-1)*perknot; j< (startj+2*p-1)*perknot;j++)
648 gm[i][j] = 1;
649 for (int i = starti;i<(starti+2*q-1);i++)
650 for (int j = (startj+p-1)*perknot;j<(startj+p)*perknot;j++)
651 gm[i][j] = 1;}
652 else if (invxl == 1) //
653 {if (b == 0)
654 for (int i = starti; i< (starti+q);i++)
655 for (int j = startj;j<(startj+2*p-1)*perknot;j++)
656 gm[i][j] = 1;
657 else if (b == invyl-1)
658 for (int i = (starti+q-1);i<(starti+2*q-1);i++)
659 for (int j = startj;j<(startj+2*p-1)*perknot;j++)
660 gm[i][j] = 1;
661 for (int i = (starti+q-1);i<(starti+q);i++)
662 for (int j = startj;j<(startj+2*p-1)*perknot;j++)
663 gm[i][j] = 1;}
664 else if (b==0 && a == 0) //top left corner
665 for (int i = starti;i<(starti+q);i++)
666 for (int j = startj;j<(startj+p)*perknot;j++)
667 gm[i][j]= 1;
668 else if (b == 0 && a == invxl-1) //top right corner
669 for (int i = starti;i<(starti+q);i++)
670 for (int j = (startj+p-1)*perknot;j<(startj+2*p-1)*perknot;j++)
671 gm[i][j]= 1;
672 else if (b == invyl-1 && a == 0) //bottom left corner
673 for (int i = (starti+q-1);i<(starti+2*q-1);i++)
674 for (int j = startj;j<(startj+p)*perknot;j++)
675 gm[i][j]= 1;
676 else if (b == invyl-1 && a == invxl-1) //bottom right corner
677 for (int i = (starti+q-1);i<(starti+2*q-1);i++)
678 for (int j = (startj+p-1)*perknot;j<(startj+2*p-1)*perknot;j++)
679 gm[i][j]= 1;
680 else if (b==0) // top edge
681 for (int i = starti;i<(starti+q);i++)
682 for (int j = (startj+p-1)*perknot;j<(startj+p)*perknot;j++)
683 gm[i][j]= 1;
684 else if (a == invxl-1) // right edge
685 for (int i = (starti+q-1);i<(starti+q);i++)
686 for (int j = (startj+p-1)*perknot;j<(startj+2*p-1)*perknot;j++)
687 gm[i][j]= 1;
688 else if (a == 0) // left edge
689 for (int i = (starti+q-1);i<(starti+q);i++)
690 for (int j = startj;j<(startj+p)*perknot;j++)
691 gm[i][j]= 1;
692 else if (b == invyl-1) // bottom edge
693 for (int i = (starti+q-1);i<(starti+2*q-1);i++)
694 for (int j = (startj+p-1)*perknot;j<(startj+p)*perknot;j++)
695 gm[i][j]= 1;}// interior elements
696 for (int i = (starti+q-1);i<(starti+q);i++)
697 for (int j = (startj+p-1)*perknot;j<(startj+p)*perknot;j++)
698 gm[i][j]= 1;
699
700 }
701 }
702
703 int count = -1;
704 for (int i = 0;i<gmyl;i++)
705 for (int j = 0;j<gmxl*perknot;j++)
706 if (gm[i][j] == 1)
707 {count = count+1;
708 sf_coefs_solution[count] = sf_coefs[i*(gmxl*perknot)+j];}
709 }
710
711 volinput_coefs.insert(volinput_coefs.end(), sf_coefs_solution.begin(), sf_coefs_solution.end());
712
713 }
714
715 // Interpolate surfaces to create volume
716 std::vector<double> vol_coefs;
717 SplineInterpolator::interpolate(par_w, volinput_coefs, tg_pnt, basis_w, vol_coefs);
718
719 // Make volume
720 return new Go::SplineVolume(basis_u, basis_v, basis_w, vol_coefs.begin(),
721 dimension, rational);
722}
723
724
733static Go::SplineVolume*
734VariationDiminishingSplineApproximation(const Go::SplineVolume* svol,
735 const RealArray& points, int dimension)
736{
737 if (!svol->rational()) // Make spline surface
738 return new Go::SplineVolume(svol->basis(0), svol->basis(1), svol->basis(2),
739 points.begin(), dimension);
740
741 RealArray local_coefs, weights;
742 size_t k = 0, sizepoints = points.size()/dimension;
743 local_coefs.reserve((dimension+1)*sizepoints);
744 svol->getWeights(weights);
745 for (size_t i = 0; i < sizepoints; i++)
746 {
747 for (int j = 0; j < dimension; j++, k++)
748 local_coefs.push_back(points[k]*weights[i]);
749 local_coefs.push_back(weights[i]);
750 }
751
752 // Make rational spline volume
753 return new Go::SplineVolume(svol->basis(0), svol->basis(1), svol->basis(2),
754 local_coefs.begin(), dimension, true);
755}
std::vector< Real > RealArray
A real-valued array without algebraic operations.
Definition ImmersedBoundaries.h:32
Global algebraic operations on index 1-based matrices and vectors.
Implementation of interpolation/projection schemes for B-splines.
void leastsquare_approximation(const std::vector< double > &params, const std::vector< double > &paramsweights, const std::vector< double > &points, const std::vector< double > &tangent_points, const Go::BsplineBasis &basis, std::vector< double > &coefs)
Global spline approximation method (Least-Square Fit).
Definition SplineInterpolator.C:114
void quasiinterpolate(const std::vector< double > &params, const std::vector< double > &points, const std::vector< double > &tangent_points, const Go::BsplineBasis &basis, int index, std::vector< double > &coefs)
Local spline approximation method (Quasi-Interpolation).
Definition SplineInterpolator.C:69
void interpolate(const std::vector< double > &params, const std::vector< double > &points, const std::vector< double > &tangent_points, const Go::BsplineBasis &basis, std::vector< double > &coefs)
Global spline interpolation method.
Definition SplineInterpolator.C:21