1 /*---------------------------------------------------------------------------*\
2 * OpenSG NURBS Library *
5 * Copyright (C) 2001-2006 by the University of Bonn, Computer Graphics Group*
7 * http://cg.cs.uni-bonn.de/ *
9 * contact: edhellon@cs.uni-bonn.de, guthe@cs.uni-bonn.de, rk@cs.uni-bonn.de *
11 \*---------------------------------------------------------------------------*/
12 /*---------------------------------------------------------------------------*\
15 * This library is free software; you can redistribute it and/or modify it *
16 * under the terms of the GNU Library General Public License as published *
17 * by the Free Software Foundation, version 2. *
19 * This library is distributed in the hope that it will be useful, but *
20 * WITHOUT ANY WARRANTY; without even the implied warranty of *
21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
22 * Library General Public License for more details. *
24 * You should have received a copy of the GNU Library General Public *
25 * License along with this library; if not, write to the Free Software *
26 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. *
28 \*---------------------------------------------------------------------------*/
29 /*---------------------------------------------------------------------------*\
37 \*---------------------------------------------------------------------------*/
39 # pragma warning (disable : 985)
41 #include "OSGBSplineTensorSurface.h"
47 // FIXME: clean up all of the copy'n'paste mess...
48 // FIXME: double-check that we actually got it correct...
53 static char THIS_FILE
[] = __FILE__
;
57 const char BSplineTensorSurface::ff_const_1
[] = "BEGINBSPLINETENSORSURFACE";
58 const char BSplineTensorSurface::ff_const_2
[] = "DIMENSIONU";
59 const char BSplineTensorSurface::ff_const_3
[] = "DIMENSIONV";
60 const char BSplineTensorSurface::ff_const_4
[] = "NUMBEROFCONTROLPOINTS";
61 const char BSplineTensorSurface::ff_const_5
[] = "BEGINRATIONALBSPLINETENSORSURFACE";
64 int BSplineTensorSurface::CheckKnotPoints(const DCTPdvector
& knots
, int dim
)
66 //now check knotvector whether it has
67 //(a,a,....a, ......., b,b,....b)
68 // |-dim+1-| |-dim+1-|
71 DCTPdvector::size_type max_index
= knots
.size() - 1;
72 double test_begin
= knots
[0], test_end
= knots
[max_index
];
74 for(DCTPdvector::size_type i
= 1; i
< static_cast<unsigned int>(dim
) + 1; ++i
)
75 if(knots
[i
] != test_begin
|| knots
[max_index
- i
] != test_end
)
76 return -1; //FIXME: double comparison ?!
81 int BSplineTensorSurface::deleteBezierKnot_U(double k
)
83 DCTPdvector knots
= basis_function_u
.getKnotVector();
85 if(k
>= knots
[knots
.size() - 1])
86 return -1; // knot is too high
88 return -2; // knot is too low
90 DCTPdvector::size_type i
= 0;
98 if(mult
< dimension_u
+ 1)
99 return -3; // knot doesn't have enough multiplicity
102 // delete from knotvector
103 knots
.erase(knots
.begin() + i
);
104 // set new knot vector
105 basis_function_u
.setKnotVector(knots
);
106 // delete control points from the control point mesh corresponding to just deleted knot
107 control_points
.erase(control_points
.begin() + i
- dimension_u
);
112 int BSplineTensorSurface::deleteBezierKnot_V(double k
)
114 DCTPdvector knots
= basis_function_v
.getKnotVector();
116 if(k
>= knots
[knots
.size() - 1])
117 return -1; // knot is too high
119 return -2; // knot is too low
121 DCTPdvector::size_type i
= 0;
129 if(mult
< dimension_v
+ 1)
130 return -3; // knot doesn't have enough multiplicity
133 // delete from knotvector
134 knots
.erase(knots
.begin() + i
);
135 // set new knot vector
136 basis_function_v
.setKnotVector(knots
);
138 // delete control points from the control point mesh corresponding to just deleted knot
139 for(DCTPVec4dvector::size_type j
= 0; j
< control_points
.size(); j
++)
141 control_points
[j
].erase(control_points
[j
].begin() + i
- dimension_v
);
149 int BSplineTensorSurface::setKnotsAndDimension(const DCTPdvector
& knots_u
, int dim_u
, const DCTPdvector
& knots_v
, int dim_v
)
151 if(dim_u
< 1 || dim_v
< 1)
152 return -1; //invalid dimension
154 DCTPdvector::size_type max_index
= knots_u
.size() - 1;
156 return -2; //here's an implicit check fer structure, see below
157 if(CheckKnotPoints(knots_u
, dim_u
) )
160 max_index
= knots_v
.size() - 1;
162 return -2; //here's an implicit check fer structure, see below
163 if(CheckKnotPoints(knots_v
, dim_v
) )
166 dimension_u
= dim_u
; dimension_v
= dim_v
;
167 if(basis_function_u
.setKnotVector(knots_u
) )
168 return -4; //error in BSplineBasisFunction.setKno...
169 if(basis_function_v
.setKnotVector(knots_v
) )
170 return -4; //error in BSplineBasisFunction.setKno...
175 void BSplineTensorSurface::setControlPointMatrix(const DCTPVec4dmatrix
&cps
)
177 // FIXME: check that this is really a matrix
178 control_points
= cps
;
181 void BSplineTensorSurface::getParameterInterval_U(double &minpar
, double &maxpar
)
183 basis_function_u
.getParameterInterval(minpar
, maxpar
);
186 void BSplineTensorSurface::getParameterInterval_V(double &minpar
, double &maxpar
)
188 basis_function_v
.getParameterInterval(minpar
, maxpar
);
191 //I/O facilities - FIXME: read( char *fname ), etc. missing
192 //! Read the surface parameters from a given input stream.
195 * \param infile the stream from which the surface should be read.
196 * \return zero on success, a negative value on failure.
199 int BSplineTensorSurface::read(std::istream
&infile
)
201 //FIXME: maybe we need more checks!!!
206 infile
.getline(txtbuffer
, 255); //read line
207 if(strcmp(txtbuffer
, ff_const_1
) &&
208 strcmp(txtbuffer
, ff_const_5
))
210 return -1; //bad file format
212 if(!strcmp(txtbuffer
, ff_const_5
))
218 infile
>> txtbuffer
; //FIXME: error prone: too long string causes problem!!!
219 if(strcmp(txtbuffer
, ff_const_2
) )
220 return -1; //yeah, bad file format again
221 infile
>> dimension_u
>> std::ws
;
223 return -2; //ah, bad dimension
225 infile
>> txtbuffer
; //FIXME: error prone: too long string causes problem!!!
226 if(strcmp(txtbuffer
, ff_const_3
) )
227 return -1; //yeah, bad file format again
228 infile
>> dimension_v
>> std::ws
;
230 return -2; //ah, bad dimension
233 if(basis_function_u
.read(infile
) )
234 return -3; //error reading basis function
235 if(CheckKnotPoints(basis_function_u
.getKnotVector(), dimension_u
) )
238 if(basis_function_v
.read(infile
) )
239 return -3; //error reading basis function
240 if(CheckKnotPoints(basis_function_v
.getKnotVector(), dimension_v
) )
244 infile
>> txtbuffer
; //FIXME: error prone: too long string causes problem!!!
245 if(strcmp(txtbuffer
, ff_const_4
) )
246 return -1; //bad file format once again
248 DCTPVec4dmatrix::size_type num_of_cps_u
;
249 DCTPVec4dvector::size_type num_of_cps_v
;
250 infile
>> num_of_cps_u
>> num_of_cps_v
>> std::ws
;
251 if(num_of_cps_u
< 1 || num_of_cps_v
< 1)
252 return -5; //too few control points
253 control_points
.resize(num_of_cps_u
); //FIXME: whatif not enoght memory?
255 for(DCTPdvector::size_type u
= 0; u
< num_of_cps_u
; ++u
)
257 control_points
[u
].resize(num_of_cps_v
); //FIXME: not enough mem, exception thrown by STL
259 for(DCTPdvector::size_type v
= 0; v
< num_of_cps_v
; ++v
)
264 infile
>> cp
[0] >> cp
[1] >> cp
[2] >> cp
[3] >> std::ws
;
268 infile
>> cp
[0] >> cp
[1] >> cp
[2] >> std::ws
;
271 control_points
[u
][v
] = cp
; //FIXME: ya see, we need ERROR CHECKS!!!
278 //! Write the surface parameters out to a given output stream.
281 * \param outfile the stream into which the surface should be written.
282 * \return zero on success, a negative value on failure.
285 int BSplineTensorSurface::write(std::ostream
&outfile
)
288 DCTPdvector::size_type u
, v
;
289 DCTPVec4dmatrix::size_type num_of_cps_u
= control_points
.size();
290 DCTPVec4dvector::size_type num_of_cps_v
= control_points
[0].size(); //FIXME:what if it's not initialized yet
292 for(u
= 0; u
< num_of_cps_u
; ++u
)
294 for(v
= 0; v
< num_of_cps_v
; ++v
)
296 if(osgAbs(control_points
[u
][v
][3] - 1.0) > DCTP_EPS
)
304 //FIXME: maybe we need more checks!!!
305 outfile
.precision(DCTP_PRECISION
);
308 outfile
<< ff_const_1
<< std::endl
;
312 outfile
<< ff_const_5
<< std::endl
;
314 outfile
<< ff_const_2
<< " " << dimension_u
<< std::endl
;
315 outfile
<< ff_const_3
<< " " << dimension_v
<< std::endl
;
316 basis_function_u
.write(outfile
);
317 basis_function_v
.write(outfile
);
318 outfile
<< ff_const_4
<< " " << num_of_cps_u
<< " " << num_of_cps_v
<< std::endl
;
320 for(u
= 0; u
< num_of_cps_u
; ++u
)
322 for(v
= 0; v
< num_of_cps_v
; ++v
)
324 Vec4d cp
= control_points
[u
][v
];
327 outfile
<< cp
[0] << " " << cp
[1] << " " << cp
[2] << std::endl
;
331 outfile
<< cp
[0] << " " << cp
[1] << " " << cp
[2] << " " << cp
[3] << std::endl
;
340 //! Compute the surface at a given (u,v) point in parameter space.
343 * \param uv the point (in parameter space) where the surface should be
345 * \param error flag to indicate if an error happened. It is set to 0
346 * if everything went fine, otherwise to a negative value.
347 * \return the value of the surface in 3D space.
350 Vec4d
BSplineTensorSurface::compute4D(Vec2d uv
, int &error
)
352 //FIXME: verification before goin' into computation!!
354 int span_u
= basis_function_u
.computeAllNonzero(uv
[0], dimension_u
, nu
);
356 int span_v
= basis_function_v
.computeAllNonzero(uv
[1], dimension_v
, nv
);
358 Vec4d
result(0.0, 0.0, 0.0, 0.0);
359 if(span_u
< 0 || span_v
< 0)
361 std::cerr
<< "spanu: " << span_u
<< " spanv: " << span_v
<< std::endl
;
362 error
= (span_u
< 0) ? span_u
: span_v
;
368 return result
; //error occured in BSplineBasisFunction.computeAll...
371 unsigned int index_v
= span_v
- dimension_v
;
373 unsigned int index_u
;
375 for(int l
= 0; l
<= dimension_v
; ++l
)
377 temp
[0] = temp
[1] = temp
[2] = temp
[3] = 0.0;
378 index_u
= span_u
- dimension_u
;
380 for(DCTPVec4dmatrix::size_type k
= 0; k
<= static_cast<unsigned int>(dimension_u
); ++k
)
382 temp
+= control_points
[index_u
][index_v
] * nu
[k
];
387 result
+= temp
* nv
[l
];
396 Vec3d
BSplineTensorSurface::compute(Vec2d uv
, int &error
)
401 rat_res
= compute4D(uv
, error
);
402 res
[0] = rat_res
[0] / rat_res
[3];
403 res
[1] = rat_res
[1] / rat_res
[3];
404 res
[2] = rat_res
[2] / rat_res
[3];
408 void BSplineTensorSurface::RatSurfaceDerivs(DCTPVec4dmatrix
&rclHomDerivs
, DCTPVec3dmatrix
&rclEuclidDerivs
)
410 unsigned int ui_k
, ui_l
, ui_j
, ui_i
;
413 // FIXME: optimize for special case clHomDervis.size()==2!
414 // FIXME: binomial coefficients are all 1 in this case, so alredy removed
416 for(ui_k
= 0; ui_k
< rclHomDerivs
.size(); ++ui_k
)
418 for(ui_l
= 0; ui_l
< rclHomDerivs
.size() - ui_k
; ++ui_l
)
420 cl_v
[0] = rclHomDerivs
[ui_k
][ui_l
][0];
421 cl_v
[1] = rclHomDerivs
[ui_k
][ui_l
][1];
422 cl_v
[2] = rclHomDerivs
[ui_k
][ui_l
][2];
424 for(ui_j
= 1; ui_j
<= ui_l
; ++ui_j
)
426 //cl_v -= Binomial(ui_l, ui_j) * rclHomDerivs[0][ui_j][3] * rclEuclidDerivs[ui_k][ui_l-ui_j];
427 cl_v
-= rclHomDerivs
[0][ui_j
][3] * rclEuclidDerivs
[ui_k
][ui_l
- ui_j
];
430 for(ui_i
= 1; ui_i
<= ui_k
; ++ui_i
)
432 //cl_v -= Binomial(ui_k, ui_i) * rclHomDerivs[ui_i][0][3] * rclEuclidDerivs[ui_k-ui_i][ui_l];
433 cl_v
-= rclHomDerivs
[ui_i
][0][3] * rclEuclidDerivs
[ui_k
- ui_i
][ui_l
];
434 cl_v2
= Vec3d(0.0, 0.0, 0.0);
436 for(ui_j
= 1; ui_j
<= ui_l
; ++ui_j
)
438 //cl_v2 += Binomial(ui_l, ui_j) * rclHomDerivs[ui_i][ui_j][3] * rclEuclidDerivs[ui_k-ui_i][ui_l-ui_j];
439 cl_v2
+= rclHomDerivs
[ui_i
][ui_j
][3] * rclEuclidDerivs
[ui_k
- ui_i
][ui_l
- ui_j
];
442 // cl_v -= Binomial(ui_k, ui_i) * cl_v2;
446 rclEuclidDerivs
[ui_k
][ui_l
] = cl_v
* (1.0 / rclHomDerivs
[0][0][3]);
452 //! Compute the surface normal at a given (u,v) point in parameter space.
455 * \param uv the point (in parameter space) where the surface should be
457 * \param error flag to indicate if an error happened. It is set to 0
458 * if everything went fine, otherwise to a negative value.
459 * \return the value of the surface in 3D space.
462 Vec3f
BSplineTensorSurface::computeNormal(Vec2d clUV
, int &riError
, Pnt3f
&rclPos
)
468 cl_norm
= computeNormal(clUV
, riError
, cl_pos
);
469 cl_normal
[0] = static_cast<Real32
>(cl_norm
[0]);
470 cl_normal
[1] = static_cast<Real32
>(cl_norm
[1]);
471 cl_normal
[2] = static_cast<Real32
>(cl_norm
[2]);
472 rclPos
[0] = static_cast<Real32
>(cl_pos
[0]);
473 rclPos
[1] = static_cast<Real32
>(cl_pos
[1]);
474 rclPos
[2] = static_cast<Real32
>(cl_pos
[2]);
480 Vec3d
BSplineTensorSurface::computeNormal(Vec2d clUV
, int &riError
, Vec3d
&rclPos
)
491 DCTPVec4dmatrix vvcl_skl
;
492 DCTPVec3dmatrix vvcl_skl_eucl
;
500 vvcl_skl
[0].resize(2);
501 vvcl_skl
[1].resize(2);
502 vvcl_skl_eucl
.resize(2);
503 vvcl_skl_eucl
[0].resize(2);
504 vvcl_skl_eucl
[1].resize(2);
506 i_uspan
= basis_function_u
.computeDersBasisFuns(clUV
[0], dimension_u
, ppd_nu
, 1);
507 i_vspan
= basis_function_v
.computeDersBasisFuns(clUV
[1], dimension_v
, ppd_nv
, 1);
508 if( (i_uspan
< 0) || (i_vspan
< 0) )
514 // vvcl_skl.resize( 2 );
515 // vvcl_skl[ 0 ].resize( 2 );
516 // vvcl_skl[ 1 ].resize( 2 );
517 pcl_temp
= new Vec4d
[dimension_v
+ 1];
518 // vcl_temp.resize( dimension_v + 1 );
520 for(i_k
= 0; i_k
<= 1; ++i_k
)
522 i_v
= i_vspan
- dimension_v
;
524 for(i_s
= 0; i_s
<= dimension_v
; ++i_s
)
526 pcl_temp
[i_s
] = Vec4d(0.0, 0.0, 0.0, 0.0);
527 i_u
= i_uspan
- dimension_u
;
529 for(i_r
= 0; i_r
<= dimension_u
; ++i_r
)
531 pcl_temp
[i_s
] += control_points
[i_u
][i_v
] * ppd_nu
[i_k
][i_r
];
538 for(i_l
= 0; i_l
<= 1 - i_k
; ++i_l
)
540 vvcl_skl
[i_k
][i_l
] = Vec4d(0.0, 0.0, 0.0, 0.0);
542 for(i_s
= 0; i_s
<= dimension_v
; ++i_s
)
544 vvcl_skl
[i_k
][i_l
] += pcl_temp
[i_s
] * ppd_nv
[i_l
][i_s
];
549 RatSurfaceDerivs(vvcl_skl
, vvcl_skl_eucl
);
550 correctDers(clUV
, vvcl_skl_eucl
[0][0], vvcl_skl_eucl
[1][0], vvcl_skl_eucl
[0][1]);
551 cl_temp
= vvcl_skl_eucl
[1][0].cross(vvcl_skl_eucl
[0][1]);
552 d_len
= cl_temp
.squareLength();
553 if(d_len
< DCTP_EPS
* DCTP_EPS
)
555 // std::cerr<<"d_len too small: " << d_len << std::endl;
556 cl_normal
[0] = cl_normal
[1] = cl_normal
[2] = 0.0;
561 cl_temp
*= 1.0 / sqrt(d_len
);
563 cl_normal
[0] = cl_temp
[0];
564 cl_normal
[1] = cl_temp
[1];
565 cl_normal
[2] = cl_temp
[2];
568 rclPos
[0] = vvcl_skl_eucl
[0][0][0];
569 rclPos
[1] = vvcl_skl_eucl
[0][0][1];
570 rclPos
[2] = vvcl_skl_eucl
[0][0][2];
572 // clean up allocated memory
585 //! Compute the surface normal and texture coordinate at a given (u,v) point in parameter space.
588 * \param uv the point (in parameter space) where the surface should be
590 * \param error flag to indicate if an error happened. It is set to 0
591 * if everything went fine, otherwise to a negative value.
592 * \return the value of the surface in 3D space.
595 Vec3d
BSplineTensorSurface::computeNormalTex(Vec2d
& rclUV
,
599 const std::vector
<std::vector
<Pnt2f
> > *cpvvclTexCP
)
609 DCTPVec4dmatrix vvcl_skl
;
610 DCTPVec3dmatrix vvcl_skl_eucl
;
621 vvcl_skl
[0].resize(2);
622 vvcl_skl
[1].resize(2);
623 vvcl_skl_eucl
.resize(2);
624 vvcl_skl_eucl
[0].resize(2);
625 vvcl_skl_eucl
[1].resize(2);
627 i_uspan
= basis_function_u
.computeDersBasisFuns(rclUV
[0], dimension_u
, ppd_nu
, 1);
628 i_vspan
= basis_function_v
.computeDersBasisFuns(rclUV
[1], dimension_v
, ppd_nv
, 1);
629 if( (i_uspan
< 0) || (i_vspan
< 0) )
635 // vvcl_skl.resize( 2 );
636 // vvcl_skl[ 0 ].resize( 2 );
637 // vvcl_skl[ 1 ].resize( 2 );
638 pcl_temp
= new Vec4d
[dimension_v
+ 1];
639 // vcl_temp.resize( dimension_v + 1 );
641 for(i_k
= 0; i_k
<= 1; ++i_k
)
643 i_v
= i_vspan
- dimension_v
;
645 for(i_s
= 0; i_s
<= dimension_v
; ++i_s
)
647 pcl_temp
[i_s
] = Vec4d(0.0, 0.0, 0.0, 0.0);
648 i_u
= i_uspan
- dimension_u
;
650 for(i_r
= 0; i_r
<= dimension_u
; ++i_r
)
652 pcl_temp
[i_s
] += control_points
[i_u
][i_v
] * ppd_nu
[i_k
][i_r
];
659 for(i_l
= 0; i_l
<= 1 - i_k
; ++i_l
)
661 vvcl_skl
[i_k
][i_l
] = Vec4d(0.0, 0.0, 0.0, 0.0);
663 for(i_s
= 0; i_s
<= dimension_v
; ++i_s
)
665 vvcl_skl
[i_k
][i_l
] += pcl_temp
[i_s
] * ppd_nv
[i_l
][i_s
];
670 RatSurfaceDerivs(vvcl_skl
, vvcl_skl_eucl
);
671 rclPos
= vvcl_skl_eucl
[0][0];
673 correctDers(rclUV
, vvcl_skl_eucl
[0][0], vvcl_skl_eucl
[1][0], vvcl_skl_eucl
[0][1]);
674 cl_normal
= vvcl_skl_eucl
[1][0].cross(vvcl_skl_eucl
[0][1]);
675 d_len
= cl_normal
.squareLength();
677 if(d_len
< DCTP_EPS
* DCTP_EPS
)
679 cl_normal
[0] = cl_normal
[1] = cl_normal
[2] = 0.0;
684 cl_normal
*= 1.0 / sqrt(d_len
);
688 // calculate texture coord
689 rclTexCoord
[0] = rclTexCoord
[1] = 0.0;
690 i_v
= i_vspan
- dimension_v
;
693 for(i_l
= 0; i_l
<= dimension_v
; ++i_l
)
695 cl_temp
[0] = cl_temp
[1] = 0.0;
696 i_u
= i_uspan
- dimension_u
;
699 for(i_k
= 0; i_k
<= dimension_u
; ++i_k
)
701 cl_temp
[0] += (*cpvvclTexCP
)[i_u
][i_v
].x() * *pd_nuk
;
702 cl_temp
[1] += (*cpvvclTexCP
)[i_u
][i_v
].y() * *pd_nuk
;
708 rclTexCoord
+= cl_temp
* *pd_nvl
;
712 // clean up allocated memory
725 //! Insert a u knot into the surface. Returns < 0 on error, otherwise 0.
728 * \param k the knot to be inserted.
729 * \return zero on success, and a negative integer if some error occured.
732 int BSplineTensorSurface::insertKnot_U(double k
)
734 DCTPdvector knots
= basis_function_u
.getKnotVector();
735 int span
= basis_function_u
.insertKnot(k
);
737 return span
; // some error happened
739 DCTPVec4dmatrix
newcps(control_points
.size() + 1);
740 DCTPVec4dvector::size_type i
;
742 for(i
= 0; i
< newcps
.size(); i
++)
744 newcps
[i
].resize(control_points
[0].size() ); // this must be 0 (or at least < newcps.size() - 1
747 for(i
= 0; int(i
) <= span
- dimension_u
; i
++)
748 newcps
[i
] = control_points
[i
];
750 for(i
= span
- dimension_u
+ 1; i
<= static_cast<unsigned int>(span
); i
++)
753 if(knots
[i
+ dimension_u
] != knots
[i
])
754 alpha
= (k
- knots
[i
]) / (knots
[i
+ dimension_u
] - knots
[i
]);
758 for(DCTPVec4dvector::size_type j
= 0; j
< newcps
[i
].size(); j
++)
760 newcps
[i
][j
] = control_points
[i
][j
] * alpha
+
761 control_points
[i
- 1][j
] * (1 - alpha
);
766 for(i
= span
+ 1; i
< newcps
.size(); i
++)
768 newcps
[i
] = control_points
[i
- 1];
771 control_points
= newcps
;
776 //! Insert v knot into the surface. Returns < 0 on error, otherwise 0.
779 * \param k the knot to be inserted.
780 * \return zero on success, and a negative integer if some error occured.
783 int BSplineTensorSurface::insertKnot_V(double k
)
785 DCTPdvector knots
= basis_function_v
.getKnotVector();
786 int span
= basis_function_v
.insertKnot(k
);
788 return span
; // some error happened
789 DCTPVec4dmatrix
newcps(control_points
.size() );
790 DCTPVec4dvector::size_type i
, j
;
792 for(i
= 0; i
< newcps
.size(); i
++)
793 newcps
[i
].resize(control_points
[i
].size() + 1);
795 for(i
= 0; i
< control_points
.size(); i
++)
796 for(j
= 0; int(j
) <= span
- dimension_v
; j
++)
797 newcps
[i
][j
] = control_points
[i
][j
];
799 // precalculate alpha values
800 DCTPdvector
alphavec(dimension_v
);
802 for(j
= span
- dimension_v
+ 1; int(j
) <= span
; j
++)
804 if(knots
[j
+ dimension_v
] != knots
[j
])
805 alphavec
[j
- span
+ dimension_v
- 1] = (k
- knots
[j
]) / (knots
[j
+ dimension_v
] - knots
[j
]);
807 alphavec
[j
- span
+ dimension_v
- 1] = 0;
810 for(i
= 0; i
< control_points
.size(); i
++)
811 for(j
= span
- dimension_v
+ 1; int(j
) <= span
; j
++)
813 double alpha
= alphavec
[j
- span
+ dimension_v
- 1];
814 newcps
[i
][j
] = control_points
[i
][j
] * alpha
+ control_points
[i
][j
- 1] * (1 - alpha
);
819 for(i
= 0; i
< control_points
.size(); i
++)
820 for(j
= span
+ 1; j
< newcps
[i
].size(); j
++)
821 newcps
[i
][j
] = control_points
[i
][j
- 1];
823 control_points
= newcps
;
827 //! Convert a surface into Bezier patches.
829 * This function converts a surface into Bezier patches with
830 * appropriate knot insertions. (And if necessary knot deletions. )
831 * Leaves the original surface unchanged.
833 * \param beziers the matrix of BezierTensorSurface's to store the patches
834 * \param upars the u parameter vector to store where each patch begins in the
835 * original parameter space of the surface
836 * \param vpars the same for v parameter.
837 * \return zero on success, and a negative integer if some error occured.
839 * For example, for patch (i, j) it covers the parameter space of the
840 * original surface between upars[ i ]..upars[ i + 1 ] and
841 * vpars[ j ]..vpars[ j + 1 ].
843 int BSplineTensorSurface::makeBezier(beziersurfacematrix
&beziers
, DCTPdvector
&upars
, DCTPdvector
&vpars
)
845 double firstknotu
, lastknotu
;
846 double firstknotv
, lastknotv
;
847 basis_function_u
.getParameterInterval(firstknotu
, lastknotu
);
848 basis_function_v
.getParameterInterval(firstknotv
, lastknotv
);
849 DCTPdvector uknots
= basis_function_u
.getKnotVector();
850 DCTPdvector vknots
= basis_function_v
.getKnotVector();
851 DCTPdvector origuknots
= uknots
; // backup original curve characteristics
852 DCTPdvector origvknots
= vknots
; // same here
853 DCTPVec4dmatrix origcps
= control_points
; // same here
854 double prevknot
= firstknotu
;
859 // first convert along u knots
860 for(i
= 1; i
< int(uknots
.size()); i
++)
862 double actk
= uknots
[i
];
867 for(int j
= mult
+ 1; j
< dimension_u
; j
++) //each interior knot must have the multiplicity of dimension -1
868 { //std::cerr << "about to insert uknot: " << prevknot << std::endl;
869 err
= insertKnot_U(prevknot
);
870 //std::cerr << "inserted uknot..." << std::endl;
872 return err
; // some error happened during insertKnot
876 if(prevknot
!= firstknotu
&& prevknot
!= lastknotu
)
878 for(int j
= mult
; j
> dimension_u
- 1; j
--)
880 //std::cerr << "about to delete knot: " << prevknot << std::endl;
881 err
= deleteBezierKnot_U(prevknot
);
882 //std::cerr << "deleted knot..." << std::endl;
884 return err
; // some error happened during deleteBezierKnot
892 // now convert along v knots
894 prevknot
= firstknotv
;
896 for(i
= 1; i
< int(vknots
.size()); i
++)
898 double actk
= vknots
[i
];
903 for(int j
= mult
+ 1; j
< dimension_v
; j
++) //each interior knot must have the multiplicity of dimension -1
904 { // std::cerr << "about to insert vknot: " << prevknot << std::endl;
905 err
= insertKnot_V(prevknot
);
906 // std::cerr << "inserted vknot..." << std::endl;
908 return err
; // some error happened during insertKnot
912 if(prevknot
!= firstknotv
&& prevknot
!= lastknotv
)
914 for(int j
= mult
; j
> dimension_v
- 1; j
--)
916 // std::cerr << "about to delete knot: " << prevknot << std::endl;
917 err
= deleteBezierKnot_V(prevknot
);
918 // std::cerr << "deleted knot..." << std::endl;
920 return err
; // some error happened during deleteBezierKnot
928 // now do the actual conversation into nxm bezier segments
929 uknots
= basis_function_u
.getKnotVector(); // FIXME: it could be more efficient.
930 int unum_of_beziers
= (UInt32(uknots
.size()) - 2) / dimension_u
- 1;
931 if( (unum_of_beziers
* dimension_u
+ 2) != int(uknots
.size()) - dimension_u
)
933 basis_function_u
.setKnotVector(origuknots
);
934 basis_function_v
.setKnotVector(origuknots
);
935 control_points
= origcps
;
938 vknots
= basis_function_v
.getKnotVector(); // FIXME: it could be more efficient.
939 int vnum_of_beziers
= (UInt32(vknots
.size()) - 2) / dimension_v
- 1;
940 if( (vnum_of_beziers
* dimension_v
+ 2) != int(vknots
.size()) - dimension_v
)
942 basis_function_u
.setKnotVector(origuknots
);
943 basis_function_v
.setKnotVector(origuknots
);
944 control_points
= origcps
;
948 beziers
.resize(unum_of_beziers
);
949 upars
.resize(unum_of_beziers
+ 1);
950 vpars
.resize(vnum_of_beziers
+ 1);
952 for(i
= 0; i
< unum_of_beziers
+ 1; i
++)
953 upars
[i
] = uknots
[1 + dimension_u
* i
];
955 for(i
= 0; i
< vnum_of_beziers
+ 1; i
++)
956 vpars
[i
] = vknots
[1 + dimension_v
* i
];
958 for(i
= 0; i
< unum_of_beziers
; i
++)
959 beziers
[i
].resize(vnum_of_beziers
);
961 DCTPVec4dmatrix
beziercps(dimension_u
+ 1);
963 for(i
= 0; i
< dimension_u
+ 1; i
++)
964 beziercps
[i
].resize(dimension_v
+ 1);
966 for(i
= 0; i
< unum_of_beziers
; i
++)
968 for(int j
= 0; j
< vnum_of_beziers
; j
++)
970 for(int u
= 0; u
< dimension_u
+ 1; u
++)
972 for(int v
= 0; v
< dimension_v
+ 1; v
++)
974 beziercps
[u
][v
] = control_points
[i
* dimension_u
+ u
][j
* dimension_v
+ v
];
979 beziers
[i
][j
].setControlPointMatrix(beziercps
);
984 // restore original curve
985 basis_function_u
.setKnotVector(origuknots
);
986 basis_function_v
.setKnotVector(origvknots
);
987 control_points
= origcps
;
993 int BSplineTensorSurface::getSplitParams(DCTPdvector
&upars
, DCTPdvector
&vpars
)
995 DCTPdvector
&uknots
= basis_function_u
.getKnotVector();
996 DCTPdvector
&vknots
= basis_function_v
.getKnotVector();
997 int unum_of_beziers
= (UInt32(uknots
.size()) - 2) / dimension_u
- 1;
998 int vnum_of_beziers
= (UInt32(vknots
.size()) - 2) / dimension_v
- 1;
1001 upars
.resize(unum_of_beziers
+ 1);
1002 vpars
.resize(vnum_of_beziers
+ 1);
1004 for(i
= 0; i
< unum_of_beziers
+ 1; i
++)
1005 upars
[i
] = uknots
[1 + dimension_u
* i
];
1007 for(i
= 0; i
< vnum_of_beziers
+ 1; i
++)
1008 vpars
[i
] = vknots
[1 + dimension_v
* i
];
1015 // subdivide surface at midpoint into 4 bezier surfaces
1016 int BSplineTensorSurface::midPointSubDivision(std::vector
<std::vector
<BSplineTensorSurface
> > &rvvcl_newbspline
)
1023 std::vector
<std::vector
<Vec4d
> > vvcl_cp
;
1024 unsigned int ui_cpy
;
1025 unsigned int ui_cpy_cnt
;
1027 rvvcl_newbspline
.resize(2);
1028 rvvcl_newbspline
[0].resize(2);
1029 rvvcl_newbspline
[1].resize(2);
1031 // insert knots in u direction
1032 rvvcl_newbspline
[0][0] = *this;
1033 rvvcl_newbspline
[0][0].getParameterInterval_U(d_min
, d_max
);
1034 ui_cnt
= rvvcl_newbspline
[0][0].getDimension_U();
1036 for(ui_idx
= 0; ui_idx
< ui_cnt
; ++ui_idx
)
1038 i_span
= rvvcl_newbspline
[0][0].insertKnot_U( (d_min
+ d_max
) * 0.5);
1041 i_span
-= dimension_u
- 2;
1042 rvvcl_newbspline
[0][1].dimension_u
= dimension_u
;
1043 rvvcl_newbspline
[1][0].dimension_u
= dimension_u
;
1044 rvvcl_newbspline
[1][1].dimension_u
= dimension_u
;
1045 rvvcl_newbspline
[0][1].dimension_v
= dimension_v
;
1046 rvvcl_newbspline
[1][0].dimension_v
= dimension_v
;
1047 rvvcl_newbspline
[1][1].dimension_v
= dimension_v
;
1049 // split in u direction
1050 ui_cnt
= UInt32(rvvcl_newbspline
[0][0].getControlPointMatrix().size());
1052 for(ui_idx
= 0; ui_idx
<= dimension_u
; ++ui_idx
)
1054 rvvcl_newbspline
[1][0].getKnotVector_U().push_back(
1055 rvvcl_newbspline
[0][0].getKnotVector_U()[i_span
]);
1058 for(ui_idx
= i_span
- 1; ui_idx
< ui_cnt
; ++ui_idx
)
1060 rvvcl_newbspline
[1][0].getControlPointMatrix().push_back(
1061 rvvcl_newbspline
[0][0].getControlPointMatrix()[ui_idx
]);
1062 rvvcl_newbspline
[1][0].getKnotVector_U().push_back(
1063 rvvcl_newbspline
[0][0].getKnotVector_U()[ui_idx
+ dimension_u
+ 1]);
1066 rvvcl_newbspline
[0][0].getControlPointMatrix().resize(i_span
);
1067 rvvcl_newbspline
[0][0].getKnotVector_U().resize(i_span
+ dimension_u
);
1068 rvvcl_newbspline
[0][0].getKnotVector_U().push_back(
1069 rvvcl_newbspline
[0][0].getKnotVector_U()[i_span
+ dimension_u
- 1]);
1070 rvvcl_newbspline
[1][0].getKnotVector_V() = rvvcl_newbspline
[0][0].getKnotVector_V();
1072 ui_cnt
= UInt32(rvvcl_newbspline
[0][0].getKnotVector_U().size()) - 1;
1073 ui_idx
= ui_cnt
- dimension_u
- 1;
1074 while(rvvcl_newbspline
[0][0].getKnotVector_U()[ui_cnt
] == rvvcl_newbspline
[0][0].getKnotVector_U()[ui_idx
])
1076 rvvcl_newbspline
[0][0].getKnotVector_U().pop_back();
1077 rvvcl_newbspline
[0][0].getControlPointMatrix().pop_back();
1082 // insert knots in v direction
1083 rvvcl_newbspline
[0][0].getParameterInterval_V(d_min
, d_max
);
1084 ui_cnt
= rvvcl_newbspline
[0][0].getDimension_V();
1086 for(ui_idx
= 0; ui_idx
< ui_cnt
; ++ui_idx
)
1088 i_span
= rvvcl_newbspline
[0][0].insertKnot_V( (d_min
+ d_max
) * 0.5);
1089 i_span
= rvvcl_newbspline
[1][0].insertKnot_V( (d_min
+ d_max
) * 0.5);
1092 i_span
-= dimension_v
- 2;
1094 // split in v direction
1095 ui_cnt
= UInt32(rvvcl_newbspline
[0][0].getControlPointMatrix()[0].size());
1097 for(ui_idx
= 0; ui_idx
<= dimension_v
; ++ui_idx
)
1099 rvvcl_newbspline
[0][1].getKnotVector_V().push_back(
1100 rvvcl_newbspline
[0][0].getKnotVector_V()[i_span
]);
1101 rvvcl_newbspline
[1][1].getKnotVector_V().push_back(
1102 rvvcl_newbspline
[1][0].getKnotVector_V()[i_span
]);
1105 for(ui_idx
= i_span
- 1; ui_idx
< ui_cnt
; ++ui_idx
)
1107 ui_cpy_cnt
= UInt32(rvvcl_newbspline
[0][0].getControlPointMatrix().size());
1108 rvvcl_newbspline
[0][1].getControlPointMatrix().resize(ui_cpy_cnt
);
1110 for(ui_cpy
= 0; ui_cpy
< ui_cpy_cnt
; ++ui_cpy
)
1112 rvvcl_newbspline
[0][1].getControlPointMatrix()[ui_cpy
].push_back(
1113 rvvcl_newbspline
[0][0].getControlPointMatrix()[ui_cpy
][ui_idx
]);
1116 ui_cpy_cnt
= UInt32(rvvcl_newbspline
[1][0].getControlPointMatrix().size());
1117 rvvcl_newbspline
[1][1].getControlPointMatrix().resize(ui_cpy_cnt
);
1119 for(ui_cpy
= 0; ui_cpy
< ui_cpy_cnt
; ++ui_cpy
)
1121 rvvcl_newbspline
[1][1].getControlPointMatrix()[ui_cpy
].push_back(
1122 rvvcl_newbspline
[1][0].getControlPointMatrix()[ui_cpy
][ui_idx
]);
1125 rvvcl_newbspline
[0][1].getKnotVector_V().push_back(
1126 rvvcl_newbspline
[0][0].getKnotVector_V()[ui_idx
+ dimension_v
+ 1]);
1127 rvvcl_newbspline
[1][1].getKnotVector_V().push_back(
1128 rvvcl_newbspline
[1][0].getKnotVector_V()[ui_idx
+ dimension_v
+ 1]);
1131 ui_cnt
= UInt32(rvvcl_newbspline
[0][0].getControlPointMatrix().size());
1133 for(ui_idx
= 0; ui_idx
< ui_cnt
; ++ui_idx
)
1135 rvvcl_newbspline
[0][0].getControlPointMatrix()[ui_idx
].resize(i_span
);
1138 ui_cnt
= UInt32(rvvcl_newbspline
[1][0].getControlPointMatrix().size());
1140 for(ui_idx
= 0; ui_idx
< ui_cnt
; ++ui_idx
)
1142 rvvcl_newbspline
[1][0].getControlPointMatrix()[ui_idx
].resize(i_span
);
1145 rvvcl_newbspline
[0][0].getKnotVector_V().resize(i_span
+ dimension_v
);
1146 rvvcl_newbspline
[0][0].getKnotVector_V().push_back(
1147 rvvcl_newbspline
[0][0].getKnotVector_V()[i_span
+ dimension_v
- 1]);
1148 rvvcl_newbspline
[1][0].getKnotVector_V().resize(i_span
+ dimension_v
);
1149 rvvcl_newbspline
[1][0].getKnotVector_V().push_back(
1150 rvvcl_newbspline
[1][0].getKnotVector_V()[i_span
+ dimension_v
- 1]);
1151 rvvcl_newbspline
[0][1].getKnotVector_U() = rvvcl_newbspline
[0][0].getKnotVector_U();
1152 rvvcl_newbspline
[1][1].getKnotVector_U() = rvvcl_newbspline
[1][0].getKnotVector_U();
1154 ui_cnt
= UInt32(rvvcl_newbspline
[0][0].getKnotVector_V().size()) - 1;
1155 ui_idx
= ui_cnt
- dimension_v
- 1;
1156 while(rvvcl_newbspline
[0][0].getKnotVector_V()[ui_cnt
] == rvvcl_newbspline
[0][0].getKnotVector_V()[ui_idx
])
1158 rvvcl_newbspline
[0][0].getKnotVector_V().pop_back();
1159 ui_cpy_cnt
= UInt32(rvvcl_newbspline
[0][0].getControlPointMatrix().size());
1161 for(ui_cpy
= 0; ui_cpy
< ui_cpy_cnt
; ++ui_cpy
)
1163 rvvcl_newbspline
[0][0].getControlPointMatrix()[ui_cpy
].pop_back();
1166 rvvcl_newbspline
[1][0].getKnotVector_V().pop_back();
1167 ui_cpy_cnt
= UInt32(rvvcl_newbspline
[1][0].getControlPointMatrix().size());
1169 for(ui_cpy
= 0; ui_cpy
< ui_cpy_cnt
; ++ui_cpy
)
1171 rvvcl_newbspline
[1][0].getControlPointMatrix()[ui_cpy
].pop_back();
1182 // subdivide surface at midpoint into 2 bezier surfaces
1183 int BSplineTensorSurface::midPointSubDivisionU(std::vector
<BSplineTensorSurface
> &rvcl_newbspline
)
1190 std::vector
<std::vector
<Vec4d
> > vvcl_cp
;
1191 // unsigned int ui_cpy;
1192 // unsigned int ui_cpy_cnt;
1194 rvcl_newbspline
.resize(2);
1196 // insert knots in u direction
1197 rvcl_newbspline
[0] = *this;
1198 getParameterInterval_U(d_min
, d_max
);
1199 ui_cnt
= rvcl_newbspline
[0].getDimension_U();
1201 for(ui_idx
= 0; ui_idx
<= ui_cnt
; ++ui_idx
)
1203 i_span
= rvcl_newbspline
[0].insertKnot_U( (d_min
+ d_max
) * 0.5);
1206 i_span
-= dimension_u
- 2;
1207 rvcl_newbspline
[1].dimension_u
= dimension_u
;
1208 rvcl_newbspline
[1].dimension_v
= dimension_v
;
1210 // split in u direction
1211 ui_cnt
= UInt32(rvcl_newbspline
[0].getControlPointMatrix().size());
1213 for(ui_idx
= 0; ui_idx
<= dimension_u
; ++ui_idx
)
1215 rvcl_newbspline
[1].getKnotVector_U().push_back(
1216 rvcl_newbspline
[0].getKnotVector_U()[i_span
]);
1219 for(ui_idx
= i_span
- 1; ui_idx
< ui_cnt
; ++ui_idx
)
1221 rvcl_newbspline
[1].getControlPointMatrix().push_back(
1222 rvcl_newbspline
[0].getControlPointMatrix()[ui_idx
]);
1223 rvcl_newbspline
[1].getKnotVector_U().push_back(
1224 rvcl_newbspline
[0].getKnotVector_U()[ui_idx
+ dimension_u
+ 1]);
1227 rvcl_newbspline
[0].getControlPointMatrix().resize(i_span
);
1228 rvcl_newbspline
[0].getKnotVector_U().resize(i_span
+ dimension_u
);
1229 rvcl_newbspline
[0].getKnotVector_U().push_back(
1230 rvcl_newbspline
[0].getKnotVector_U()[i_span
+ dimension_u
- 1]);
1231 rvcl_newbspline
[1].getKnotVector_V() = rvcl_newbspline
[0].getKnotVector_V();
1233 ui_cnt
= UInt32(rvcl_newbspline
[0].getKnotVector_U().size()) - 1;
1234 ui_idx
= ui_cnt
- dimension_u
- 1;
1235 while(rvcl_newbspline
[0].getKnotVector_U()[ui_cnt
] == rvcl_newbspline
[0].getKnotVector_U()[ui_idx
])
1237 rvcl_newbspline
[0].getKnotVector_U().pop_back();
1238 rvcl_newbspline
[0].getControlPointMatrix().pop_back();
1247 // subdivide surface at midpoint into 2 bezier surfaces
1248 int BSplineTensorSurface::midPointSubDivisionV(std::vector
<BSplineTensorSurface
> &rvcl_newbspline
)
1255 std::vector
<std::vector
<Vec4d
> > vvcl_cp
;
1256 unsigned int ui_cpy
;
1257 unsigned int ui_cpy_cnt
;
1259 rvcl_newbspline
.resize(2);
1261 // insert knots in u direction
1262 rvcl_newbspline
[0] = *this;
1263 getParameterInterval_V(d_min
, d_max
);
1264 ui_cnt
= rvcl_newbspline
[0].getDimension_V();
1266 for(ui_idx
= 0; ui_idx
< ui_cnt
; ++ui_idx
)
1268 i_span
= rvcl_newbspline
[0].insertKnot_V( (d_min
+ d_max
) * 0.5);
1271 i_span
-= dimension_v
- 2;
1272 rvcl_newbspline
[1].dimension_u
= dimension_u
;
1273 rvcl_newbspline
[1].dimension_v
= dimension_v
;
1275 // split in v direction
1276 ui_cnt
= UInt32(rvcl_newbspline
[0].getControlPointMatrix()[0].size());
1278 for(ui_idx
= 0; ui_idx
<= dimension_v
; ++ui_idx
)
1280 rvcl_newbspline
[1].getKnotVector_V().push_back(
1281 rvcl_newbspline
[0].getKnotVector_V()[i_span
]);
1284 ui_cpy_cnt
= UInt32(rvcl_newbspline
[0].getControlPointMatrix().size());
1285 rvcl_newbspline
[1].getControlPointMatrix().resize(ui_cpy_cnt
);
1287 for(ui_idx
= i_span
- 1; ui_idx
< ui_cnt
; ++ui_idx
)
1289 for(ui_cpy
= 0; ui_cpy
< ui_cpy_cnt
; ++ui_cpy
)
1291 rvcl_newbspline
[1].getControlPointMatrix()[ui_cpy
].push_back(
1292 rvcl_newbspline
[0].getControlPointMatrix()[ui_cpy
][ui_idx
]);
1295 rvcl_newbspline
[1].getKnotVector_V().push_back(
1296 rvcl_newbspline
[0].getKnotVector_V()[ui_idx
+ dimension_v
+ 1]);
1299 ui_cnt
= UInt32(rvcl_newbspline
[0].getControlPointMatrix().size());
1301 for(ui_idx
= 0; ui_idx
< ui_cnt
; ++ui_idx
)
1303 rvcl_newbspline
[0].getControlPointMatrix()[ui_idx
].resize(i_span
);
1306 rvcl_newbspline
[0].getKnotVector_V().resize(i_span
+ dimension_v
);
1307 rvcl_newbspline
[0].getKnotVector_V().push_back(
1308 rvcl_newbspline
[0].getKnotVector_V()[i_span
+ dimension_v
- 1]);
1309 rvcl_newbspline
[1].getKnotVector_U() = rvcl_newbspline
[0].getKnotVector_U();
1311 ui_cnt
= UInt32(rvcl_newbspline
[0].getKnotVector_V().size()) - 1;
1312 ui_idx
= ui_cnt
- dimension_v
- 1;
1313 while(rvcl_newbspline
[0].getKnotVector_V()[ui_cnt
] == rvcl_newbspline
[0].getKnotVector_V()[ui_idx
])
1315 rvcl_newbspline
[0].getKnotVector_V().pop_back();
1316 ui_cpy_cnt
= UInt32(rvcl_newbspline
[0].getControlPointMatrix().size());
1318 for(ui_cpy
= 0; ui_cpy
< ui_cpy_cnt
; ++ui_cpy
)
1320 rvcl_newbspline
[0].getControlPointMatrix()[ui_cpy
].pop_back();
1331 // subdivide surface at param into 2 bezier surfaces
1332 int BSplineTensorSurface::subDivisionU(std::vector
<BSplineTensorSurface
> &rvcl_newbspline
, double dSplit
)
1339 std::vector
<std::vector
<Vec4d
> > vvcl_cp
;
1340 // unsigned int ui_cpy;
1341 // unsigned int ui_cpy_cnt;
1343 rvcl_newbspline
.clear();
1344 rvcl_newbspline
.resize(2);
1346 // insert knots in u direction
1347 rvcl_newbspline
[0] = *this;
1348 getParameterInterval_U(d_min
, d_max
);
1349 ui_cnt
= rvcl_newbspline
[0].getDimension_U();
1351 for(ui_idx
= 0; ui_idx
<= ui_cnt
; ++ui_idx
)
1353 i_span
= rvcl_newbspline
[0].insertKnot_U(d_min
+ (d_max
- d_min
) * dSplit
);
1356 i_span
-= dimension_u
- 2;
1357 rvcl_newbspline
[1].dimension_u
= dimension_u
;
1358 rvcl_newbspline
[1].dimension_v
= dimension_v
;
1360 // split in u direction
1361 ui_cnt
= UInt32(rvcl_newbspline
[0].getControlPointMatrix().size());
1363 for(ui_idx
= 0; ui_idx
<= dimension_u
; ++ui_idx
)
1365 rvcl_newbspline
[1].getKnotVector_U().push_back(
1366 rvcl_newbspline
[0].getKnotVector_U()[i_span
]);
1369 for(ui_idx
= i_span
- 1; ui_idx
< ui_cnt
; ++ui_idx
)
1371 rvcl_newbspline
[1].getControlPointMatrix().push_back(
1372 rvcl_newbspline
[0].getControlPointMatrix()[ui_idx
]);
1373 rvcl_newbspline
[1].getKnotVector_U().push_back(
1374 rvcl_newbspline
[0].getKnotVector_U()[ui_idx
+ dimension_u
+ 1]);
1377 rvcl_newbspline
[0].getControlPointMatrix().resize(i_span
);
1378 rvcl_newbspline
[0].getKnotVector_U().resize(i_span
+ dimension_u
);
1379 rvcl_newbspline
[0].getKnotVector_U().push_back(
1380 rvcl_newbspline
[0].getKnotVector_U()[i_span
+ dimension_u
- 1]);
1381 rvcl_newbspline
[1].getKnotVector_V() = rvcl_newbspline
[0].getKnotVector_V();
1383 ui_cnt
= UInt32(rvcl_newbspline
[0].getKnotVector_U().size()) - 1;
1384 ui_idx
= ui_cnt
- dimension_u
- 1;
1385 while(rvcl_newbspline
[0].getKnotVector_U()[ui_cnt
] == rvcl_newbspline
[0].getKnotVector_U()[ui_idx
])
1387 rvcl_newbspline
[0].getKnotVector_U().pop_back();
1388 rvcl_newbspline
[0].getControlPointMatrix().pop_back();
1397 // subdivide surface at param into 2 bezier surfaces
1398 int BSplineTensorSurface::subDivisionV(std::vector
<BSplineTensorSurface
> &rvcl_newbspline
, double dSplit
)
1405 std::vector
<std::vector
<Vec4d
> > vvcl_cp
;
1406 unsigned int ui_cpy
;
1407 unsigned int ui_cpy_cnt
;
1409 rvcl_newbspline
.clear();
1410 rvcl_newbspline
.resize(2);
1412 // insert knots in u direction
1413 rvcl_newbspline
[0] = *this;
1414 getParameterInterval_V(d_min
, d_max
);
1415 ui_cnt
= rvcl_newbspline
[0].getDimension_V();
1417 for(ui_idx
= 0; ui_idx
< ui_cnt
; ++ui_idx
)
1419 i_span
= rvcl_newbspline
[0].insertKnot_V(d_min
+ (d_max
- d_min
) * dSplit
);
1422 i_span
-= dimension_v
- 2;
1423 rvcl_newbspline
[1].dimension_u
= dimension_u
;
1424 rvcl_newbspline
[1].dimension_v
= dimension_v
;
1426 // split in v direction
1427 ui_cnt
= UInt32(rvcl_newbspline
[0].getControlPointMatrix()[0].size());
1429 for(ui_idx
= 0; ui_idx
<= dimension_v
; ++ui_idx
)
1431 rvcl_newbspline
[1].getKnotVector_V().push_back(
1432 rvcl_newbspline
[0].getKnotVector_V()[i_span
]);
1435 ui_cpy_cnt
= UInt32(rvcl_newbspline
[0].getControlPointMatrix().size());
1436 rvcl_newbspline
[1].getControlPointMatrix().resize(ui_cpy_cnt
);
1438 for(ui_idx
= i_span
- 1; ui_idx
< ui_cnt
; ++ui_idx
)
1440 for(ui_cpy
= 0; ui_cpy
< ui_cpy_cnt
; ++ui_cpy
)
1442 rvcl_newbspline
[1].getControlPointMatrix()[ui_cpy
].push_back(
1443 rvcl_newbspline
[0].getControlPointMatrix()[ui_cpy
][ui_idx
]);
1446 rvcl_newbspline
[1].getKnotVector_V().push_back(
1447 rvcl_newbspline
[0].getKnotVector_V()[ui_idx
+ dimension_v
+ 1]);
1450 ui_cnt
= UInt32(rvcl_newbspline
[0].getControlPointMatrix().size());
1452 for(ui_idx
= 0; ui_idx
< ui_cnt
; ++ui_idx
)
1454 rvcl_newbspline
[0].getControlPointMatrix()[ui_idx
].resize(i_span
);
1457 rvcl_newbspline
[0].getKnotVector_V().resize(i_span
+ dimension_v
);
1458 rvcl_newbspline
[0].getKnotVector_V().push_back(
1459 rvcl_newbspline
[0].getKnotVector_V()[i_span
+ dimension_v
- 1]);
1460 rvcl_newbspline
[1].getKnotVector_U() = rvcl_newbspline
[0].getKnotVector_U();
1462 ui_cnt
= UInt32(rvcl_newbspline
[0].getKnotVector_V().size()) - 1;
1463 ui_idx
= ui_cnt
- dimension_v
- 1;
1464 while(rvcl_newbspline
[0].getKnotVector_V()[ui_cnt
] == rvcl_newbspline
[0].getKnotVector_V()[ui_idx
])
1466 rvcl_newbspline
[0].getKnotVector_V().pop_back();
1467 ui_cpy_cnt
= UInt32(rvcl_newbspline
[0].getControlPointMatrix().size());
1469 for(ui_cpy
= 0; ui_cpy
< ui_cpy_cnt
; ++ui_cpy
)
1471 rvcl_newbspline
[0].getControlPointMatrix()[ui_cpy
].pop_back();
1482 //new vector-enabled computational functions from Michael
1483 void BSplineTensorSurface::compute(std::vector
<Vec2d
> &rvclUV
,
1484 std::vector
<Pnt3f
> &rvclPos
)
1487 const unsigned int cui_cnt
= UInt32(rvclUV
.size());
1488 unsigned int ui_idx
;
1493 unsigned int ui_index_v
;
1494 Vec4d
*pcl_temp
= new Vec4d
[dimension_u
+ 1];
1495 unsigned int ui_index_u
;
1505 rvclPos
.resize(cui_cnt
);
1507 for(ui_idx
= 0; ui_idx
< cui_cnt
; ++ui_idx
)
1511 i_span_u
= basis_function_u
.computeAllNonzero(rvclUV
[ui_idx
][0], dimension_u
, pd_nu
);
1512 i_span_v
= basis_function_v
.computeAllNonzero(rvclUV
[ui_idx
][1], dimension_v
, pd_nv
);
1513 b_u_new
= b_v_new
= true;
1517 if(osgAbs(rvclUV
[ui_idx
][0] - rvclUV
[ui_idx
- 1][0]) > DCTP_EPS
)
1522 i_span_u
= basis_function_u
.computeAllNonzero(rvclUV
[ui_idx
][0], dimension_u
, pd_nu
);
1524 b_v_new
= (i_old_u
!= i_span_u
) ? true : false;
1531 if(osgAbs(rvclUV
[ui_idx
][1] - rvclUV
[ui_idx
- 1][1]) > DCTP_EPS
)
1535 i_span_v
= basis_function_v
.computeAllNonzero(rvclUV
[ui_idx
][1], dimension_v
, pd_nv
);
1540 if( (i_span_u
< 0) || (i_span_v
< 0) )
1542 rvclPos
[ui_idx
] = Pnt3f(0.0, 0.0, 0.0);
1546 ui_index_u
= i_span_u
- dimension_u
;
1548 pcl_templ
= pcl_temp
;
1549 Vec4d
tempposition(0.0, 0.0, 0.0, 0.0);
1551 for(i_l
= 0; i_l
<= dimension_u
; ++i_l
)
1553 (*pcl_templ
) = Vec4d(0.0, 0.0, 0.0, 0.0);
1554 ui_index_v
= i_span_v
- dimension_v
;
1557 for(i_k
= 0; i_k
<= dimension_v
; ++i_k
)
1559 *pcl_templ
+= control_points
[ui_index_u
][ui_index_v
] * *pd_nvk
;
1565 tempposition
+= *pcl_templ
* *pd_nul
;
1570 rvclPos
[ui_idx
][0] = tempposition
[0] / tempposition
[3];
1571 rvclPos
[ui_idx
][1] = tempposition
[1] / tempposition
[3];
1572 rvclPos
[ui_idx
][2] = tempposition
[2] / tempposition
[3];
1576 ui_index_u
= i_span_u
- dimension_u
;
1578 pcl_templ
= pcl_temp
;
1579 Vec4d
tempposition(0.0, 0.0, 0.0, 0.0);
1581 for(i_l
= 0; i_l
<= dimension_u
; ++i_l
)
1584 tempposition
+= *pcl_templ
* *pd_nul
;
1589 rvclPos
[ui_idx
][0] = tempposition
[0] / tempposition
[3];
1590 rvclPos
[ui_idx
][1] = tempposition
[1] / tempposition
[3];
1591 rvclPos
[ui_idx
][2] = tempposition
[2] / tempposition
[3];
1592 #ifdef OSG_COUNT_COMP
1598 rvclPos
[ui_idx
] = rvclPos
[ui_idx
- 1];
1599 #ifdef OSG_COUNT_COMP
1603 #ifdef OSG_COUNT_COMP
1614 #ifdef OSG_COUNT_COMP
1615 cerr
<< g_uiTotalComp
<< " " << g_uiVSameComp
<< " " << g_uiSameComp
<< endl
;
1620 void BSplineTensorSurface::computeNormal(std::vector
<Vec2d
> &rvclUV
,
1621 std::vector
<Pnt3f
> &rvclPos
,
1622 std::vector
<Vec3f
> &rvclNorm
)
1624 const unsigned int cui_cnt
= UInt32(rvclUV
.size());
1625 unsigned int ui_idx
;
1633 DCTPVec4dmatrix vvcl_skl
;
1634 DCTPVec3dmatrix vvcl_skl_eucl
;
1635 Vec4d
*apcl_temp
[2];
1648 // std::cerr << dimension_u << " " << dimension_v << std::endl;
1651 vvcl_skl
[0].resize(2);
1652 vvcl_skl
[1].resize(2);
1653 vvcl_skl_eucl
.resize(2);
1654 vvcl_skl_eucl
[0].resize(2);
1655 vvcl_skl_eucl
[1].resize(2);
1657 apcl_temp
[0] = new Vec4d
[dimension_u
+ 1];
1658 apcl_temp
[1] = new Vec4d
[dimension_u
+ 1];
1660 rvclPos
.resize(cui_cnt
);
1661 rvclNorm
.resize(cui_cnt
);
1663 for(ui_idx
= 0; ui_idx
< cui_cnt
; ++ui_idx
)
1667 i_uspan
= basis_function_u
.computeDersBasisFuns(rvclUV
[ui_idx
][0], dimension_u
, ppd_nu
, 1);
1668 i_vspan
= basis_function_v
.computeDersBasisFuns(rvclUV
[ui_idx
][1], dimension_v
, ppd_nv
, 1);
1669 b_u_new
= b_v_new
= true;
1673 if(osgAbs(rvclUV
[ui_idx
][0] - rvclUV
[ui_idx
- 1][0]) > DCTP_EPS
)
1682 i_uspan
= basis_function_u
.computeDersBasisFuns(rvclUV
[ui_idx
][0], dimension_u
, ppd_nu
, 1);
1684 b_v_new
= (i_old_u
!= i_uspan
) ? true : false;
1691 if(osgAbs(rvclUV
[ui_idx
][1] - rvclUV
[ui_idx
- 1][1]) > DCTP_EPS
)
1699 i_vspan
= basis_function_v
.computeDersBasisFuns(rvclUV
[ui_idx
][1], dimension_v
, ppd_nv
, 1);
1703 if( (i_uspan
< 0) || (i_vspan
< 0) )
1705 rvclPos
[ui_idx
] = Pnt3f(0.0, 0.0, 0.0);
1706 rvclNorm
[ui_idx
] = Vec3f(0.0, 0.0, 0.0);
1710 for(i_k
= 0; i_k
<= 1; ++i_k
)
1712 i_u
= i_uspan
- dimension_u
;
1713 pcl_temps
= apcl_temp
[i_k
];
1715 for(i_s
= 0; i_s
<= dimension_u
; ++i_s
)
1717 (*pcl_temps
) = Vec4d(0.0, 0.0, 0.0, 0.0);
1718 i_v
= i_vspan
- dimension_v
;
1719 pd_nvkr
= ppd_nv
[i_k
];
1721 for(i_r
= 0; i_r
<= dimension_v
; ++i_r
)
1723 *pcl_temps
+= control_points
[i_u
][i_v
] * *pd_nvkr
;
1732 pcl_sklkl
= &(vvcl_skl
[i_k
][0]);
1734 for(i_l
= 0; i_l
<= 1 - i_k
; ++i_l
)
1736 (*pcl_sklkl
) = Vec4d(0.0, 0.0, 0.0, 0.0);
1737 pcl_temps
= apcl_temp
[i_k
];
1738 pd_nuls
= ppd_nu
[i_l
];
1740 for(i_s
= 0; i_s
<= dimension_u
; ++i_s
)
1742 *pcl_sklkl
+= *pcl_temps
* *pd_nuls
;
1751 RatSurfaceDerivs(vvcl_skl
, vvcl_skl_eucl
);
1752 rvclPos
[ui_idx
][0] = vvcl_skl_eucl
[0][0][0];
1753 rvclPos
[ui_idx
][1] = vvcl_skl_eucl
[0][0][1];
1754 rvclPos
[ui_idx
][2] = vvcl_skl_eucl
[0][0][2];
1756 correctDers(rvclUV
[ui_idx
], vvcl_skl_eucl
[0][0], vvcl_skl_eucl
[1][0], vvcl_skl_eucl
[0][1]);
1757 // rvclNorm[ ui_idx ] = aacl_skl[ 0 ][ 1 ].cross( aacl_skl[ 1 ][ 0 ] ); // switched because of optimization!
1758 // d_len = rvclNorm[ ui_idx ].squareLength( );
1759 Vec3d tempnorm
= vvcl_skl_eucl
[0][1].cross(vvcl_skl_eucl
[1][0]);
1760 rvclNorm
[ui_idx
][0] = tempnorm
[0];
1761 rvclNorm
[ui_idx
][1] = tempnorm
[1];
1762 rvclNorm
[ui_idx
][2] = tempnorm
[2];
1763 d_len
= tempnorm
.squareLength();
1765 if(d_len
> DCTP_EPS
* DCTP_EPS
)
1767 rvclNorm
[ui_idx
] *= 1.0 / sqrt(d_len
);
1771 rvclNorm
[ui_idx
][0] = rvclNorm
[ui_idx
][1] = rvclNorm
[ui_idx
][2] = 0.0;
1776 for(i_k
= 0; i_k
<= 1; ++i_k
)
1778 pcl_sklkl
= &(vvcl_skl
[i_k
][0]);
1780 for(i_l
= 0; i_l
<= 1 - i_k
; ++i_l
)
1782 (*pcl_sklkl
) = Vec4d(0.0, 0.0, 0.0, 0.0);
1783 pcl_temps
= apcl_temp
[i_k
];
1784 pd_nuls
= ppd_nu
[i_l
];
1786 for(i_s
= 0; i_s
<= dimension_u
; ++i_s
)
1788 *pcl_sklkl
+= *pcl_temps
* *pd_nuls
;
1797 RatSurfaceDerivs(vvcl_skl
, vvcl_skl_eucl
);
1798 rvclPos
[ui_idx
][0] = vvcl_skl_eucl
[0][0][0];
1799 rvclPos
[ui_idx
][1] = vvcl_skl_eucl
[0][0][1];
1800 rvclPos
[ui_idx
][2] = vvcl_skl_eucl
[0][0][2];
1802 correctDers(rvclUV
[ui_idx
], vvcl_skl_eucl
[0][0], vvcl_skl_eucl
[1][0], vvcl_skl_eucl
[0][1]);
1803 // rvclNorm[ ui_idx ] = aacl_skl[ 0 ][ 1 ].cross( aacl_skl[ 1 ][ 0 ] ); // switched because of optimization!
1804 // d_len = rvclNorm[ ui_idx ].squareLength( );
1805 Vec3d tempnorm
= vvcl_skl_eucl
[0][1].cross(vvcl_skl_eucl
[1][0]);
1806 rvclNorm
[ui_idx
][0] = tempnorm
[0];
1807 rvclNorm
[ui_idx
][1] = tempnorm
[1];
1808 rvclNorm
[ui_idx
][2] = tempnorm
[2];
1809 if(d_len
> DCTP_EPS
* DCTP_EPS
)
1811 rvclNorm
[ui_idx
] *= 1.0 / sqrt(d_len
);
1815 rvclNorm
[ui_idx
][0] = rvclNorm
[ui_idx
][1] = rvclNorm
[ui_idx
][2] = 0.0;
1817 #ifdef OSG_COUNT_COMP
1823 rvclPos
[ui_idx
] = rvclPos
[ui_idx
- 1];
1824 rvclNorm
[ui_idx
] = rvclNorm
[ui_idx
- 1];
1825 #ifdef OSG_COUNT_COMP
1829 #ifdef OSG_COUNT_COMP
1834 // clean up allocated memory
1847 delete[] apcl_temp
[0];
1848 delete[] apcl_temp
[1];
1850 #ifdef OSG_COUNT_COMP
1851 cerr
<< g_uiTotalComp
<< " " << g_uiVSameComp
<< " " << g_uiSameComp
<< endl
;
1856 void BSplineTensorSurface::computeNormalforTrimming(std::vector
<Vec2d
> &rvclUV
,
1857 std::vector
<Vec3d
> &rvclNorm
,
1858 std::vector
<Vec3d
> *pvclPos
)
1860 const unsigned int cui_cnt
= UInt32(rvclUV
.size());
1861 unsigned int ui_idx
;
1869 DCTPVec4dmatrix vvcl_skl
;
1870 DCTPVec3dmatrix vvcl_skl_eucl
;
1871 Vec4d
*apcl_temp
[2];
1884 // std::cerr << dimension_u << " " << dimension_v << std::endl;
1887 vvcl_skl
[0].resize(2);
1888 vvcl_skl
[1].resize(2);
1889 vvcl_skl_eucl
.resize(2);
1890 vvcl_skl_eucl
[0].resize(2);
1891 vvcl_skl_eucl
[1].resize(2);
1893 apcl_temp
[0] = new Vec4d
[dimension_u
+ 1];
1894 apcl_temp
[1] = new Vec4d
[dimension_u
+ 1];
1898 pvclPos
->resize(cui_cnt
);
1900 rvclNorm
.resize(cui_cnt
);
1902 for(ui_idx
= 0; ui_idx
< cui_cnt
; ++ui_idx
)
1906 i_uspan
= basis_function_u
.computeDersBasisFuns(rvclUV
[ui_idx
][0], dimension_u
, ppd_nu
, 1);
1907 i_vspan
= basis_function_v
.computeDersBasisFuns(rvclUV
[ui_idx
][1], dimension_v
, ppd_nv
, 1);
1908 b_u_new
= b_v_new
= true;
1912 if(osgAbs(rvclUV
[ui_idx
][0] - rvclUV
[ui_idx
- 1][0]) > DCTP_EPS
)
1921 i_uspan
= basis_function_u
.computeDersBasisFuns(rvclUV
[ui_idx
][0], dimension_u
, ppd_nu
, 1);
1923 b_v_new
= (i_old_u
!= i_uspan
) ? true : false;
1930 if(osgAbs(rvclUV
[ui_idx
][1] - rvclUV
[ui_idx
- 1][1]) > DCTP_EPS
)
1938 i_vspan
= basis_function_v
.computeDersBasisFuns(rvclUV
[ui_idx
][1], dimension_v
, ppd_nv
, 1);
1942 if( (i_uspan
< 0) || (i_vspan
< 0) )
1946 (*pvclPos
)[ui_idx
] = Vec3d(0.0, 0.0, 0.0);
1948 rvclNorm
[ui_idx
] = Vec3d(0.0, 0.0, 0.0);
1952 for(i_k
= 0; i_k
<= 1; ++i_k
)
1954 i_u
= i_uspan
- dimension_u
;
1955 pcl_temps
= apcl_temp
[i_k
];
1957 for(i_s
= 0; i_s
<= dimension_u
; ++i_s
)
1959 (*pcl_temps
) = Vec4d(0.0, 0.0, 0.0, 0.0);
1960 i_v
= i_vspan
- dimension_v
;
1961 pd_nvkr
= ppd_nv
[i_k
];
1963 for(i_r
= 0; i_r
<= dimension_v
; ++i_r
)
1965 *pcl_temps
+= control_points
[i_u
][i_v
] * *pd_nvkr
;
1974 pcl_sklkl
= &(vvcl_skl
[i_k
][0]);
1976 for(i_l
= 0; i_l
<= 1 - i_k
; ++i_l
)
1978 (*pcl_sklkl
) = Vec4d(0.0, 0.0, 0.0, 0.0);
1979 pcl_temps
= apcl_temp
[i_k
];
1980 pd_nuls
= ppd_nu
[i_l
];
1982 for(i_s
= 0; i_s
<= dimension_u
; ++i_s
)
1984 *pcl_sklkl
+= *pcl_temps
* *pd_nuls
;
1993 RatSurfaceDerivs(vvcl_skl
, vvcl_skl_eucl
);
1996 (*pvclPos
)[ui_idx
] = vvcl_skl_eucl
[0][0];
1999 correctDers(rvclUV
[ui_idx
], vvcl_skl_eucl
[0][0], vvcl_skl_eucl
[1][0], vvcl_skl_eucl
[0][1]);
2000 // rvclNorm[ ui_idx ] = aacl_skl[ 0 ][ 1 ].cross( aacl_skl[ 1 ][ 0 ] ); // switched because of optimization!
2001 // d_len = rvclNorm[ ui_idx ].squareLength( );
2002 Vec3d tempnorm
= vvcl_skl_eucl
[0][1].cross(vvcl_skl_eucl
[1][0]);
2003 rvclNorm
[ui_idx
][0] = tempnorm
[0];
2004 rvclNorm
[ui_idx
][1] = tempnorm
[1];
2005 rvclNorm
[ui_idx
][2] = tempnorm
[2];
2006 d_len
= tempnorm
.squareLength();
2008 if(d_len
> DCTP_EPS
* DCTP_EPS
)
2010 rvclNorm
[ui_idx
] *= 1.0 / sqrt(d_len
);
2014 rvclNorm
[ui_idx
][0] = rvclNorm
[ui_idx
][1] = rvclNorm
[ui_idx
][2] = 0.0;
2019 for(i_k
= 0; i_k
<= 1; ++i_k
)
2021 pcl_sklkl
= &(vvcl_skl
[i_k
][0]);
2023 for(i_l
= 0; i_l
<= 1 - i_k
; ++i_l
)
2025 (*pcl_sklkl
) = Vec4d(0.0, 0.0, 0.0, 0.0);
2026 pcl_temps
= apcl_temp
[i_k
];
2027 pd_nuls
= ppd_nu
[i_l
];
2029 for(i_s
= 0; i_s
<= dimension_u
; ++i_s
)
2031 *pcl_sklkl
+= *pcl_temps
* *pd_nuls
;
2040 RatSurfaceDerivs(vvcl_skl
, vvcl_skl_eucl
);
2043 (*pvclPos
)[ui_idx
] = vvcl_skl_eucl
[0][0];
2046 correctDers(rvclUV
[ui_idx
], vvcl_skl_eucl
[0][0], vvcl_skl_eucl
[1][0], vvcl_skl_eucl
[0][1]);
2047 // rvclNorm[ ui_idx ] = aacl_skl[ 0 ][ 1 ].cross( aacl_skl[ 1 ][ 0 ] ); // switched because of optimization!
2048 // d_len = rvclNorm[ ui_idx ].squareLength( );
2049 Vec3d tempnorm
= vvcl_skl_eucl
[0][1].cross(vvcl_skl_eucl
[1][0]);
2050 rvclNorm
[ui_idx
][0] = tempnorm
[0];
2051 rvclNorm
[ui_idx
][1] = tempnorm
[1];
2052 rvclNorm
[ui_idx
][2] = tempnorm
[2];
2053 if(d_len
> DCTP_EPS
* DCTP_EPS
)
2055 rvclNorm
[ui_idx
] *= 1.0 / sqrt(d_len
);
2059 rvclNorm
[ui_idx
][0] = rvclNorm
[ui_idx
][1] = rvclNorm
[ui_idx
][2] = 0.0;
2061 #ifdef OSG_COUNT_COMP
2069 (*pvclPos
)[ui_idx
] = (*pvclPos
)[ui_idx
- 1];
2071 rvclNorm
[ui_idx
] = rvclNorm
[ui_idx
- 1];
2072 #ifdef OSG_COUNT_COMP
2076 #ifdef OSG_COUNT_COMP
2081 // clean up allocated memory
2094 delete[] apcl_temp
[0];
2095 delete[] apcl_temp
[1];
2097 #ifdef OSG_COUNT_COMP
2098 cerr
<< g_uiTotalComp
<< " " << g_uiVSameComp
<< " " << g_uiSameComp
<< endl
;
2104 void BSplineTensorSurface::computeNormalTex(std::vector
<Vec2d
> & rvclUV
,
2105 std::vector
<Pnt3f
> & rvclPos
,
2106 std::vector
<Vec3f
> & rvclNorm
,
2107 std::vector
<Pnt2f
> & rvclTexCoord
,
2108 const std::vector
<std::vector
<Pnt2f
> > *cpvvclTexCP
)
2110 const unsigned int cui_cnt
= UInt32(rvclUV
.size());
2111 unsigned int ui_idx
;
2119 DCTPVec4dmatrix vvcl_skl
;
2120 DCTPVec3dmatrix vvcl_skl_eucl
;
2121 Vec4d
*apcl_temp
[2];
2132 Vec2d
*pcl_temp_2d
= new Vec2d
[dimension_u
+ 1];
2133 Vec2d
*pcl_temp_2dl
;
2137 vvcl_skl
[0].resize(2);
2138 vvcl_skl
[1].resize(2);
2139 vvcl_skl_eucl
.resize(2);
2140 vvcl_skl_eucl
[0].resize(2);
2141 vvcl_skl_eucl
[1].resize(2);
2143 apcl_temp
[0] = new Vec4d
[dimension_u
+ 1];
2144 apcl_temp
[1] = new Vec4d
[dimension_u
+ 1];
2146 rvclPos
.resize(cui_cnt
);
2147 rvclNorm
.resize(cui_cnt
);
2148 rvclTexCoord
.resize(cui_cnt
);
2150 for(ui_idx
= 0; ui_idx
< cui_cnt
; ++ui_idx
)
2154 i_uspan
= basis_function_u
.computeDersBasisFuns(rvclUV
[ui_idx
][0], dimension_u
, ppd_nu
, 1);
2155 i_vspan
= basis_function_v
.computeDersBasisFuns(rvclUV
[ui_idx
][1], dimension_v
, ppd_nv
, 1);
2156 b_u_new
= b_v_new
= true;
2160 if(osgAbs(rvclUV
[ui_idx
][0] - rvclUV
[ui_idx
- 1][0]) > DCTP_EPS
)
2169 i_uspan
= basis_function_u
.computeDersBasisFuns(rvclUV
[ui_idx
][0], dimension_u
, ppd_nu
, 1);
2171 b_v_new
= (i_old_u
!= i_uspan
) ? true : false;
2178 if(osgAbs(rvclUV
[ui_idx
][1] - rvclUV
[ui_idx
- 1][1]) > DCTP_EPS
)
2186 i_vspan
= basis_function_v
.computeDersBasisFuns(rvclUV
[ui_idx
][1], dimension_v
, ppd_nv
, 1);
2190 if( (i_uspan
< 0) || (i_vspan
< 0) )
2192 rvclPos
[ui_idx
] = Pnt3f(0.0, 0.0, 0.0);
2193 rvclNorm
[ui_idx
] = Vec3f(0.0, 0.0, 0.0);
2197 for(i_k
= 0; i_k
<= 1; ++i_k
)
2199 i_u
= i_uspan
- dimension_u
;
2200 pcl_temps
= apcl_temp
[i_k
];
2202 for(i_s
= 0; i_s
<= dimension_u
; ++i_s
)
2204 (*pcl_temps
) = Vec4d(0.0, 0.0, 0.0, 0.0);
2205 i_v
= i_vspan
- dimension_v
;
2206 pd_nvkr
= ppd_nv
[i_k
];
2208 for(i_r
= 0; i_r
<= dimension_v
; ++i_r
)
2210 *pcl_temps
+= control_points
[i_u
][i_v
] * *pd_nvkr
;
2219 pcl_sklkl
= &(vvcl_skl
[i_k
][0]);
2221 for(i_l
= 0; i_l
<= 1 - i_k
; ++i_l
)
2223 (*pcl_sklkl
) = Vec4d(0.0, 0.0, 0.0, 0.0);
2224 pcl_temps
= apcl_temp
[i_k
];
2225 pd_nuls
= ppd_nu
[i_l
];
2227 for(i_s
= 0; i_s
<= dimension_u
; ++i_s
)
2229 *pcl_sklkl
+= *pcl_temps
* *pd_nuls
;
2238 RatSurfaceDerivs(vvcl_skl
, vvcl_skl_eucl
);
2240 // rvclPos[ ui_idx ] = aacl_skl[ 0 ][ 0 ];
2241 rvclPos
[ui_idx
][0] = vvcl_skl_eucl
[0][0][0];
2242 rvclPos
[ui_idx
][1] = vvcl_skl_eucl
[0][0][1];
2243 rvclPos
[ui_idx
][2] = vvcl_skl_eucl
[0][0][2];
2245 correctDers(rvclUV
[ui_idx
], vvcl_skl_eucl
[0][0], vvcl_skl_eucl
[1][0], vvcl_skl_eucl
[0][1]);
2246 // rvclNorm[ ui_idx ] = aacl_skl[ 0 ][ 1 ].cross( aacl_skl[ 1 ][ 0 ] );
2247 // d_len = rvclNorm[ ui_idx ].squareLength( );
2248 Vec3d tempnorm
= vvcl_skl_eucl
[0][1].cross(vvcl_skl_eucl
[1][0]);
2249 rvclNorm
[ui_idx
][0] = tempnorm
[0];
2250 rvclNorm
[ui_idx
][1] = tempnorm
[1];
2251 rvclNorm
[ui_idx
][2] = tempnorm
[2];
2252 d_len
= tempnorm
.squareLength();
2254 if(d_len
> DCTP_EPS
* DCTP_EPS
)
2256 rvclNorm
[ui_idx
] *= 1.0 / sqrt(d_len
);
2260 rvclNorm
[ui_idx
][0] = rvclNorm
[ui_idx
][1] = rvclNorm
[ui_idx
][2] = 0.0;
2263 // calculate texture coord
2264 // rvclTexCoord[ ui_idx ].x() = rvclTexCoord[ ui_idx ].y() = 0.0;
2265 Vec2d
temptexcoord(0, 0);
2266 i_u
= i_uspan
- dimension_u
;
2267 pd_nuls
= ppd_nu
[0];
2268 pcl_temp_2dl
= pcl_temp_2d
;
2270 for(i_l
= 0; i_l
<= dimension_u
; ++i_l
)
2272 (*pcl_temp_2dl
)[0] = (*pcl_temp_2dl
)[1] = 0.0;
2273 i_v
= i_vspan
- dimension_v
;
2274 pd_nvkr
= ppd_nv
[0];
2276 for(i_k
= 0; i_k
<= dimension_v
; ++i_k
)
2278 (*pcl_temp_2dl
)[0] += (*cpvvclTexCP
)[i_u
][i_v
].x() * *pd_nvkr
;
2279 (*pcl_temp_2dl
)[1] += (*cpvvclTexCP
)[i_u
][i_v
].y() * *pd_nvkr
;
2285 temptexcoord
+= *pcl_temp_2dl
* *pd_nuls
;
2288 rvclTexCoord
[ui_idx
][0] = temptexcoord
[0];
2289 rvclTexCoord
[ui_idx
][1] = temptexcoord
[1];
2294 for(i_k
= 0; i_k
<= 1; ++i_k
)
2296 pcl_sklkl
= &(vvcl_skl
[i_k
][0]);
2298 for(i_l
= 0; i_l
<= 1 - i_k
; ++i_l
)
2300 (*pcl_sklkl
)[0] = (*pcl_sklkl
)[1] = (*pcl_sklkl
)[2] = 0.0;
2301 pcl_temps
= apcl_temp
[i_k
];
2302 pd_nuls
= ppd_nu
[i_l
];
2304 for(i_s
= 0; i_s
<= dimension_u
; ++i_s
)
2306 *pcl_sklkl
+= *pcl_temps
* *pd_nuls
;
2315 RatSurfaceDerivs(vvcl_skl
, vvcl_skl_eucl
);
2316 //rvclPos[ ui_idx ] = aacl_skl[ 0 ][ 0 ];
2317 rvclPos
[ui_idx
][0] = vvcl_skl_eucl
[0][0][0];
2318 rvclPos
[ui_idx
][1] = vvcl_skl_eucl
[0][0][1];
2319 rvclPos
[ui_idx
][2] = vvcl_skl_eucl
[0][0][2];
2321 correctDers(rvclUV
[ui_idx
], vvcl_skl_eucl
[0][0], vvcl_skl_eucl
[1][0], vvcl_skl_eucl
[0][1]);
2322 // rvclNorm[ ui_idx ] = aacl_skl[ 0 ][ 1 ].cross( aacl_skl[ 1 ][ 0 ] );
2323 // d_len = rvclNorm[ ui_idx ].squareLength( );
2324 Vec3d tempnorm
= vvcl_skl_eucl
[0][1].cross(vvcl_skl_eucl
[1][0]);
2325 rvclNorm
[ui_idx
][0] = tempnorm
[0];
2326 rvclNorm
[ui_idx
][1] = tempnorm
[1];
2327 rvclNorm
[ui_idx
][2] = tempnorm
[2];
2328 d_len
= tempnorm
.squareLength();
2329 if(d_len
> DCTP_EPS
* DCTP_EPS
)
2331 rvclNorm
[ui_idx
] *= 1.0 / sqrt(d_len
);
2335 rvclNorm
[ui_idx
][0] = rvclNorm
[ui_idx
][1] = rvclNorm
[ui_idx
][2] = 0.0;
2338 // calculate texture coord
2339 // rvclTexCoord[ ui_idx ][0] = rvclTexCoord[ ui_idx ][1] = 0.0;
2340 pd_nuls
= ppd_nu
[0];
2341 pcl_temp_2dl
= pcl_temp_2d
;
2342 Vec2d
temptexcoord(0, 0);
2344 for(i_l
= 0; i_l
<= dimension_u
; ++i_l
)
2346 temptexcoord
+= *pcl_temp_2dl
* *pd_nuls
;
2351 rvclTexCoord
[ui_idx
][0] = temptexcoord
[0];
2352 rvclTexCoord
[ui_idx
][1] = temptexcoord
[1];
2353 #ifdef OSG_COUNT_COMP
2359 rvclPos
[ui_idx
] = rvclPos
[ui_idx
- 1];
2360 rvclNorm
[ui_idx
] = rvclNorm
[ui_idx
- 1];
2361 rvclTexCoord
[ui_idx
] = rvclTexCoord
[ui_idx
- 1];
2362 #ifdef OSG_COUNT_COMP
2366 #ifdef OSG_COUNT_COMP
2371 // clean up allocated memory
2384 delete[] apcl_temp
[0];
2385 delete[] apcl_temp
[1];
2386 delete[] pcl_temp_2d
;
2388 #ifdef OSG_COUNT_COMP
2389 cerr
<< g_uiTotalComp
<< " " << g_uiVSameComp
<< " " << g_uiSameComp
<< endl
;
2394 void BSplineTensorSurface::computeTex(std::vector
<Vec2d
> & rvclUV
,
2395 std::vector
<Pnt3f
> & rvclPos
,
2396 std::vector
<Pnt2f
> & rvclTexCoord
,
2397 const std::vector
<std::vector
<Vec2d
> > *cpvvclTexCP
)
2399 const unsigned int cui_cnt
= UInt32(rvclUV
.size());
2400 unsigned int ui_idx
;
2405 unsigned int ui_index_v
;
2406 Vec4d
*pcl_temp
= new Vec4d
[dimension_u
+ 1];
2407 Vec2d
*pcl_ttemp
= new Vec2d
[dimension_u
+ 1];
2408 unsigned int ui_index_u
;
2419 rvclPos
.resize(cui_cnt
);
2420 rvclTexCoord
.resize(cui_cnt
);
2422 for(ui_idx
= 0; ui_idx
< cui_cnt
; ++ui_idx
)
2426 i_span_u
= basis_function_u
.computeAllNonzero(rvclUV
[ui_idx
][0], dimension_u
, pd_nu
);
2427 i_span_v
= basis_function_v
.computeAllNonzero(rvclUV
[ui_idx
][1], dimension_v
, pd_nv
);
2428 b_u_new
= b_v_new
= true;
2432 if(osgAbs(rvclUV
[ui_idx
][0] - rvclUV
[ui_idx
- 1][0]) > DCTP_EPS
)
2437 i_span_u
= basis_function_u
.computeAllNonzero(rvclUV
[ui_idx
][0], dimension_u
, pd_nu
);
2439 b_v_new
= (i_old_u
!= i_span_u
) ? true : false;
2446 if(osgAbs(rvclUV
[ui_idx
][1] - rvclUV
[ui_idx
- 1][1]) > DCTP_EPS
)
2450 i_span_v
= basis_function_v
.computeAllNonzero(rvclUV
[ui_idx
][1], dimension_v
, pd_nv
);
2455 if( (i_span_u
< 0) || (i_span_v
< 0) )
2457 rvclPos
[ui_idx
] = Pnt3f(0.0, 0.0, 0.0);
2458 rvclTexCoord
[ui_idx
] = Pnt2f(0.0, 0.0);
2462 ui_index_u
= i_span_u
- dimension_u
;
2464 pcl_templ
= pcl_temp
;
2465 pcl_ttempl
= pcl_ttemp
;
2466 Vec4d
tempposition(0.0, 0.0, 0.0, 0.0);
2467 Vec2d
temptex(0, 0);
2469 for(i_l
= 0; i_l
<= dimension_u
; ++i_l
)
2471 (*pcl_templ
) = Vec4d(0.0, 0.0, 0.0, 0.0);
2472 (*pcl_ttempl
) = Vec2d(0.0, 0.0);
2473 ui_index_v
= i_span_v
- dimension_v
;
2476 for(i_k
= 0; i_k
<= dimension_v
; ++i_k
)
2478 *pcl_templ
+= control_points
[ui_index_u
][ui_index_v
] * *pd_nvk
;
2479 *pcl_ttempl
+= (*cpvvclTexCP
)[ui_index_u
][ui_index_v
] * *pd_nvk
;
2485 tempposition
+= *pcl_templ
* *pd_nul
;
2486 temptex
+= *pcl_ttempl
* *pd_nul
;
2492 rvclPos
[ui_idx
][0] = tempposition
[0] / tempposition
[3];
2493 rvclPos
[ui_idx
][1] = tempposition
[1] / tempposition
[3];
2494 rvclPos
[ui_idx
][2] = tempposition
[2] / tempposition
[3];
2495 rvclTexCoord
[ui_idx
][0] = temptex
[0];
2496 rvclTexCoord
[ui_idx
][1] = temptex
[1];
2500 ui_index_u
= i_span_u
- dimension_u
;
2502 pcl_templ
= pcl_temp
;
2503 pcl_ttempl
= pcl_ttemp
;
2504 Vec4d
tempposition(0.0, 0.0, 0.0, 0.0);
2505 Vec2d
temptex(0, 0);
2507 for(i_l
= 0; i_l
<= dimension_u
; ++i_l
)
2510 tempposition
+= *pcl_templ
* *pd_nul
;
2511 temptex
+= *pcl_ttempl
* *pd_nul
;
2517 rvclPos
[ui_idx
][0] = tempposition
[0] / tempposition
[3];
2518 rvclPos
[ui_idx
][1] = tempposition
[1] / tempposition
[3];
2519 rvclPos
[ui_idx
][2] = tempposition
[2] / tempposition
[3];
2520 rvclTexCoord
[ui_idx
][0] = temptex
[0];
2521 rvclTexCoord
[ui_idx
][1] = temptex
[1];
2522 #ifdef OSG_COUNT_COMP
2528 rvclPos
[ui_idx
] = rvclPos
[ui_idx
- 1];
2529 rvclTexCoord
[ui_idx
] = rvclTexCoord
[ui_idx
- 1];
2530 #ifdef OSG_COUNT_COMP
2534 #ifdef OSG_COUNT_COMP
2546 #ifdef OSG_COUNT_COMP
2547 cerr
<< g_uiTotalComp
<< " " << g_uiVSameComp
<< " " << g_uiSameComp
<< endl
;
2552 void BSplineTensorSurface::computeTexforTrimming(std::vector
<Vec2d
> & rvclUV
,
2553 std::vector
<Vec2d
> & rvclTexCoord
,
2554 const std::vector
<std::vector
<Vec2d
> > *cpvvclTexCP
)
2556 const unsigned int cui_cnt
= UInt32(rvclUV
.size());
2557 unsigned int ui_idx
;
2562 unsigned int ui_index_v
;
2563 Vec2d
*pcl_ttemp
= new Vec2d
[dimension_u
+ 1];
2564 unsigned int ui_index_u
;
2574 rvclTexCoord
.resize(cui_cnt
);
2576 for(ui_idx
= 0; ui_idx
< cui_cnt
; ++ui_idx
)
2580 i_span_u
= basis_function_u
.computeAllNonzero(rvclUV
[ui_idx
][0], dimension_u
, pd_nu
);
2581 i_span_v
= basis_function_v
.computeAllNonzero(rvclUV
[ui_idx
][1], dimension_v
, pd_nv
);
2582 b_u_new
= b_v_new
= true;
2586 if(osgAbs(rvclUV
[ui_idx
][0] - rvclUV
[ui_idx
- 1][0]) > DCTP_EPS
)
2591 i_span_u
= basis_function_u
.computeAllNonzero(rvclUV
[ui_idx
][0], dimension_u
, pd_nu
);
2593 b_v_new
= (i_old_u
!= i_span_u
) ? true : false;
2600 if(osgAbs(rvclUV
[ui_idx
][1] - rvclUV
[ui_idx
- 1][1]) > DCTP_EPS
)
2604 i_span_v
= basis_function_v
.computeAllNonzero(rvclUV
[ui_idx
][1], dimension_v
, pd_nv
);
2609 if( (i_span_u
< 0) || (i_span_v
< 0) )
2611 rvclTexCoord
[ui_idx
][0] = rvclTexCoord
[ui_idx
][1] = 0.0;
2615 ui_index_u
= i_span_u
- dimension_u
;
2617 pcl_ttempl
= pcl_ttemp
;
2618 rvclTexCoord
[ui_idx
][0] = rvclTexCoord
[ui_idx
][1] = 0.0;
2620 for(i_l
= 0; i_l
<= dimension_u
; ++i_l
)
2622 (*pcl_ttempl
)[0] = (*pcl_ttempl
)[1] = 0.0;
2623 ui_index_v
= i_span_v
- dimension_v
;
2626 for(i_k
= 0; i_k
<= dimension_v
; ++i_k
)
2628 *pcl_ttempl
+= (*cpvvclTexCP
)[ui_index_u
][ui_index_v
] * *pd_nvk
;
2634 rvclTexCoord
[ui_idx
] += *pcl_ttempl
* *pd_nul
;
2641 ui_index_u
= i_span_u
- dimension_u
;
2643 pcl_ttempl
= pcl_ttemp
;
2644 rvclTexCoord
[ui_idx
][0] = rvclTexCoord
[ui_idx
][1] = 0.0;
2646 for(i_l
= 0; i_l
<= dimension_u
; ++i_l
)
2649 rvclTexCoord
[ui_idx
] += *pcl_ttempl
* *pd_nul
;
2654 #ifdef OSG_COUNT_COMP
2660 rvclTexCoord
[ui_idx
] = rvclTexCoord
[ui_idx
- 1];
2661 #ifdef OSG_COUNT_COMP
2665 #ifdef OSG_COUNT_COMP
2676 #ifdef OSG_COUNT_COMP
2677 cerr
<< g_uiTotalComp
<< " " << g_uiVSameComp
<< " " << g_uiSameComp
<< endl
;
2682 void BSplineTensorSurface::correctDers(const Vec2d cclUV
, const Vec3d cclPos
, Vec3d
&rclDU
, Vec3d
&rclDV
)
2685 // TODO: this tried to correct 0 derivs, but it was
2686 // TODO: only half-implemented plus the approach didn't really work.
2687 // TODO: implement something like this someday...
2689 if(rclDU
.squareLength() < DCTP_EPS
)
2701 getParameterInterval_U(d_minpar
, d_maxpar
);
2703 // step in -u direction
2706 d_step
= cl_param
[0] - d_minpar
;
2707 while(d_step
> DCTP_EPS
)
2710 cl_param
[0] -= d_step
;
2711 cl_temp
= compute(cl_param
, i_err
);
2712 if( (cl_temp
- cclPos
).squareLength() > DCTP_EPS
)
2715 cl_param
[0] += d_step
;
2717 /* else if( ( cl_temp - cclPos ).squareLength( ) > ( cl_low - cclPos ).squareLength( ) )
2723 // step in +u direction
2726 d_step
= d_maxpar
- cl_param
[0];
2727 while(d_step
> DCTP_EPS
)
2730 cl_param
[0] += d_step
;
2731 cl_temp
= compute(cl_param
, i_err
);
2732 if( (cl_temp
- cclPos
).squareLength() > DCTP_EPS
)
2735 cl_param
[0] -= d_step
;
2737 /* else if( ( cl_temp - cclPos ).squareLength( ) > ( cl_high - cclPos ).squareLength( ) )
2743 // calculate dirivative
2744 // std::cerr << "du: " << rclDU;
2745 if( (cl_high
- cl_low
).squareLength() > DCTP_EPS
)
2747 rclDU
= cl_high
- cl_low
;
2751 rclDU
[0] = rclDU
[1] = rclDU
[2] = 0.0;
2753 // std::cerr << " -> " << rclDU << std::endl;
2756 if(rclDV
.squareLength() < DCTP_EPS
)
2768 getParameterInterval_V(d_minpar
, d_maxpar
);
2770 // step in -v direction
2773 d_step
= cl_param
[1] - d_minpar
;
2774 while(d_step
> DCTP_EPS
)
2777 cl_param
[1] -= d_step
;
2778 cl_temp
= compute(cl_param
, i_err
);
2779 if( (cl_temp
- cclPos
).squareLength() > DCTP_EPS
)
2782 cl_param
[1] += d_step
;
2784 /* else if( ( cl_temp - cclPos ).squareLength( ) > ( cl_low - cclPos ).squareLength( ) )
2790 // step in +v direction
2793 d_step
= d_maxpar
- cl_param
[1];
2794 while(d_step
> DCTP_EPS
)
2797 cl_param
[1] += d_step
;
2798 cl_temp
= compute(cl_param
, i_err
);
2799 if( (cl_temp
- cclPos
).squareLength() > DCTP_EPS
)
2802 cl_param
[1] -= d_step
;
2804 /* else if( ( cl_temp - cclPos ).squareLength( ) > ( cl_high - cclPos ).squareLength( ) )
2810 // calculate dirivative
2811 // std::cerr << "dv: " << rclDV;
2812 if( (cl_high
- cl_low
).squareLength() > DCTP_EPS
)
2814 rclDV
= cl_high
- cl_low
;
2818 rclDV
[0] = rclDV
[1] = rclDV
[2] = 0.0;
2820 // std::cerr << " -> " << rclDV << std::endl;