00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00015
00016
00017 #include "pcl/surface/3rdparty/opennurbs/opennurbs.h"
00018
00019 bool ON_BezierCage::Read(ON_BinaryArchive& archive)
00020 {
00021 Destroy();
00022
00023 int major_version = 0;
00024 int minor_version = 0;
00025 bool rc = archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
00026 if ( rc )
00027 {
00028 while(rc)
00029 {
00030 if ( major_version != 1 )
00031 {
00032 ON_ERROR("ON_BezierCage::Read - old code unable to read new version of chunk");
00033 rc = false;
00034 break;
00035 }
00036
00037 int dim=0,order0=0,order1=0,order2=0;
00038 bool is_rat=false;
00039
00040 rc = archive.ReadInt(&dim);
00041 if (!rc)
00042 break;
00043 if (dim < 1 || dim > 10000)
00044 {
00045 ON_ERROR("ON_BezierCage::Read - invalid dim");
00046 rc=false;
00047 break;
00048 }
00049
00050 rc = archive.ReadBool(&is_rat);
00051 if (!rc)
00052 break;
00053
00054 rc = archive.ReadInt(&order0);
00055 if (!rc)
00056 break;
00057 if ( order0 < 2 || order0 > 10000 )
00058 {
00059 ON_ERROR("ON_BezierCage::Read - invalid order0");
00060 rc=false;
00061 break;
00062 }
00063
00064 rc = archive.ReadInt(&order1);
00065 if (!rc)
00066 break;
00067 if ( order1 < 2 || order1 > 10000 )
00068 {
00069 ON_ERROR("ON_BezierCage::Read - invalid order1");
00070 rc=false;
00071 break;
00072 }
00073
00074 rc = archive.ReadInt(&order2);
00075 if (!rc)
00076 break;
00077 if ( order2 < 2 || order2 > 10000 )
00078 {
00079 ON_ERROR("ON_BezierCage::Read - invalid order2");
00080 rc=false;
00081 break;
00082 }
00083
00084 rc = Create(dim,is_rat,order0,order1,order2);
00085 if (!rc)
00086 break;
00087
00088 int i,j,k;
00089 const int cv_dim = m_is_rat?(m_dim+1):m_dim;
00090 for(i = 0; i < order0 && rc; i++)
00091 {
00092 for(j = 0; j < order1 && rc; j++)
00093 {
00094 for ( k = 0; k < order2 && rc; k++)
00095 {
00096 rc = archive.ReadDouble(cv_dim,CV(i,j,k));
00097 }
00098 }
00099 }
00100
00101 break;
00102 }
00103
00104 if ( !archive.EndRead3dmChunk() )
00105 {
00106 rc = false;
00107 }
00108 }
00109 return rc;
00110 }
00111
00112 bool ON_BezierCage::Write(ON_BinaryArchive& archive) const
00113 {
00114 bool rc = archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
00115
00116 if (rc)
00117 {
00118 rc = archive.WriteInt(m_dim);
00119 if(rc)
00120 rc = archive.WriteInt(m_is_rat);
00121 if (rc)
00122 rc = archive.WriteInt(m_order[0]);
00123 if (rc)
00124 rc = archive.WriteInt(m_order[1]);
00125 if (rc)
00126 rc = archive.WriteInt(m_order[2]);
00127 int i,j,k;
00128 const int cv_dim = m_is_rat?(m_dim+1):m_dim;
00129 double* bogus_cv = (double*)alloca(cv_dim*sizeof(*bogus_cv));
00130 for ( i = 0; i < cv_dim; i++ )
00131 bogus_cv[i] = ON_UNSET_VALUE;
00132 for(i = 0; i < m_order[0] && rc; i++)
00133 {
00134 for(j = 0; j < m_order[1] && rc; j++)
00135 {
00136 for ( k = 0; k < m_order[2] && rc; k++)
00137 {
00138 const double* cv = CV(i,j,k);
00139 if ( !cv )
00140 cv = bogus_cv;
00141 rc = archive.WriteDouble(cv_dim,cv);
00142 }
00143 }
00144 }
00145
00146 if ( !archive.EndWrite3dmChunk() )
00147 {
00148 rc = false;
00149 }
00150 }
00151
00152 return rc;
00153 }
00154
00155
00156
00157 ON_BezierCage::ON_BezierCage()
00158 : m_dim(0),m_is_rat(0),m_cv_capacity(0),m_cv(0)
00159 {
00160 m_order[0] = 0;
00161 m_order[1] = 0;
00162 m_order[2] = 0;
00163 m_cv_stride[0] = 0;
00164 m_cv_stride[1] = 0;
00165 m_cv_stride[2] = 0;
00166 }
00167
00168 ON_BezierCage::ON_BezierCage( int dim, bool is_rat, int order0, int order1, int order2 )
00169 : m_dim(0),m_is_rat(0),m_cv_capacity(0),m_cv(0)
00170 {
00171 m_order[0] = 0;
00172 m_order[1] = 0;
00173 m_order[2] = 0;
00174 m_cv_stride[0] = 0;
00175 m_cv_stride[1] = 0;
00176 m_cv_stride[2] = 0;
00177 Create( dim, is_rat, order0, order1, order2 );
00178 }
00179
00180 ON_BezierCage::ON_BezierCage( const ON_BoundingBox& bbox, int order0, int order1, int order2 )
00181 : m_dim(0),m_is_rat(0),m_cv_capacity(0),m_cv(0)
00182 {
00183 Create(bbox,order0,order1,order2);
00184 }
00185
00186 ON_BezierCage::ON_BezierCage( const ON_3dPoint* box_corners, int order0, int order1, int order2 )
00187 : m_dim(0),m_is_rat(0),m_cv_capacity(0),m_cv(0)
00188 {
00189 Create(box_corners,order0,order1,order2);
00190 }
00191
00192 ON_BezierCage::~ON_BezierCage()
00193 {
00194 Destroy();
00195 }
00196
00197 ON_BezierCage::ON_BezierCage(const ON_BezierCage& src)
00198 : m_dim(0),m_is_rat(0),m_cv_capacity(0),m_cv(0)
00199 {
00200 m_order[0] = 0;
00201 m_order[1] = 0;
00202 m_order[2] = 0;
00203 m_cv_stride[0] = 0;
00204 m_cv_stride[1] = 0;
00205 m_cv_stride[2] = 0;
00206 *this = src;
00207 }
00208
00209 ON_BezierCage& ON_BezierCage::operator=(const ON_BezierCage& src)
00210 {
00211 if ( this != &src ) {
00212 if ( Create( src.m_dim, src.m_is_rat,
00213 src.m_order[0], src.m_order[1], src.m_order[2] ) )
00214 {
00215 const int sizeof_cv = src.CVSize()*sizeof(m_cv[0]);
00216 int i, j, k;
00217 for ( i = 0; i < m_order[0]; i++ )
00218 for ( j = 0; j < m_order[1]; j++ )
00219 for ( k = 0; k < m_order[2]; k++ )
00220 {
00221 memcpy( CV(i,j,k), src.CV(i,j,k), sizeof_cv );
00222 }
00223 }
00224 else
00225 {
00226 Destroy();
00227 }
00228 }
00229 return *this;
00230 }
00231
00232 bool ON_BezierCage::IsValid() const
00233 {
00234 if ( m_cv == NULL )
00235 return false;
00236
00237 if ( m_order[0] < 2 )
00238 return false;
00239 if ( m_order[1] < 2 )
00240 return false;
00241 if ( m_order[2] < 2 )
00242 return false;
00243
00244 if ( m_dim <= 0 )
00245 return false;
00246 if ( m_is_rat != 0 && m_is_rat != 1 )
00247 return false;
00248
00249 const int cvdim = m_is_rat ? (m_dim+1) : m_dim;
00250
00251 if ( m_cv_capacity > 0 && m_cv_capacity < cvdim*m_order[0]*m_order[1]*m_order[2] )
00252 return false;
00253
00254 int i[3];
00255 i[0] = (m_cv_stride[0] <= m_cv_stride[1]) ? 0 : 1;
00256 i[1] = 1-i[0];
00257 if ( m_cv_stride[2] < m_cv_stride[i[0]] )
00258 {
00259 i[2] = i[1];
00260 i[1] = i[0];
00261 i[0] = 2;
00262 }
00263 else if ( m_cv_stride[2] < m_cv_stride[i[1]] )
00264 {
00265 i[2] = i[1];
00266 i[1] = 2;
00267 }
00268 else
00269 {
00270 i[2] = 2;
00271 }
00272
00273 if ( m_cv_stride[i[0]] < cvdim )
00274 return false;
00275 if ( m_cv_stride[i[1]] < m_cv_stride[i[0]]*m_order[i[0]] )
00276 return false;
00277 if ( m_cv_stride[i[2]] < m_cv_stride[i[1]]*m_order[i[1]] )
00278 return false;
00279
00280 return true;
00281 }
00282
00283 void ON_BezierCage::Dump( ON_TextLog& dump ) const
00284 {
00285 dump.Print( "ON_BezierCage dim = %d is_rat = %d\n"
00286 " order = (%d, %d, %d) \n",
00287 m_dim, m_is_rat, m_order[0], m_order[1], m_order[2] );
00288 dump.Print( "Control Points %d %s points\n"
00289 " index value\n",
00290 m_order[0]*m_order[1]*m_order[2],
00291 (m_is_rat) ? "rational" : "non-rational" );
00292 if ( !m_cv )
00293 {
00294 dump.Print(" NULL cv array\n");
00295 }
00296 else
00297 {
00298 int i,j;
00299 char sPreamble[128];
00300 memset(sPreamble,0,sizeof(sPreamble));
00301 for ( i = 0; i < m_order[0]; i++ )
00302 {
00303 for ( j = 0; j < m_order[1]; j++ )
00304 {
00305 if ( i > 0 || j > 0)
00306 dump.Print("\n");
00307 sPreamble[0] = 0;
00308 sprintf(sPreamble," CV[%2d][%2d]",i,j);
00309 dump.PrintPointList( m_dim, m_is_rat,
00310 m_order[2], m_cv_stride[2],
00311 CV(i,j,0),
00312 sPreamble );
00313 }
00314 if ( i < m_order[0]-1)
00315 dump.Print("\n");
00316 }
00317 }
00318 }
00319
00320 int ON_BezierCage::Dimension() const
00321 {
00322 return m_dim;
00323 }
00324
00325 bool ON_BezierCage::Create( const ON_BoundingBox& bbox, int order0, int order1, int order2 )
00326 {
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340
00341
00342 ON_3dPoint box_corners[8];
00343 box_corners[0] = bbox.Corner(0,0,0);
00344 box_corners[1] = bbox.Corner(1,0,0);
00345 box_corners[2] = bbox.Corner(1,1,0);
00346 box_corners[3] = bbox.Corner(0,1,0);
00347 box_corners[4] = bbox.Corner(0,0,1);
00348 box_corners[5] = bbox.Corner(1,0,1);
00349 box_corners[6] = bbox.Corner(1,1,1);
00350 box_corners[7] = bbox.Corner(0,1,1);
00351 return Create(box_corners,order0,order1,order2);
00352 }
00353
00354 bool ON_BezierCage::Create( int dim, bool is_rat, int order0, int order1, int order2 )
00355 {
00356 if ( m_cv_capacity < 1 )
00357 m_cv = 0;
00358 m_dim = (dim>0) ? dim : 0;
00359 m_is_rat = is_rat ? 1 : 0;
00360 m_order[0] = (order0 >= 2) ? order0 : 0;
00361 m_order[1] = (order1 >= 2) ? order1 : 0;
00362 m_order[2] = (order2 >= 2) ? order2 : 0;
00363 m_cv_stride[2] = (m_dim > 0) ? m_dim+m_is_rat : 0;
00364 m_cv_stride[1] = m_cv_stride[2]*m_order[2];
00365 m_cv_stride[0] = m_cv_stride[1]*m_order[1];
00366 m_cv_capacity = m_cv_stride[0]*m_order[0];
00367 m_cv = (double*)onrealloc( m_cv, m_cv_capacity*sizeof(m_cv[0]) );
00368 return IsValid() ? true : false;
00369 }
00370
00371 bool ON_BezierCage::Create(
00372 const ON_3dPoint* box_corners,
00373 int order0,
00374 int order1,
00375 int order2
00376 )
00377 {
00378 int i, j, k;
00379 double r,s,t;
00380
00381 if ( 0 == box_corners )
00382 return false;
00383 for( i = 0; i < 8; i++ )
00384 {
00385 if ( !box_corners[i].IsValid() )
00386 return false;
00387 }
00388
00389
00390
00391 ON_BezierCage cube(3,0,2,2,2);
00392 cube.SetCV(0,0,0,box_corners[0]);
00393 cube.SetCV(1,0,0,box_corners[1]);
00394 cube.SetCV(1,1,0,box_corners[2]);
00395 cube.SetCV(0,1,0,box_corners[3]);
00396 cube.SetCV(0,0,1,box_corners[4]);
00397 cube.SetCV(1,0,1,box_corners[5]);
00398 cube.SetCV(1,1,1,box_corners[6]);
00399 cube.SetCV(0,1,1,box_corners[7]);
00400
00401 if ( 2 == order0 && 2 == order1 && 2 == order2 )
00402 {
00403 operator=(cube);
00404 }
00405 else
00406 {
00407 if (!Create(3,0,order0,order1,order2))
00408 return false;
00409 const int d0 = Degree(0);
00410 const int d1 = Degree(1);
00411 const int d2 = Degree(2);
00412
00413 for (i = 0; i <= d0; i++)
00414 {
00415 r = ((double)i)/((double)d0);
00416 for (j = 0; j <= d1; j++)
00417 {
00418 s = ((double)j)/((double)d1);
00419 for (k = 0; k <= d2; k++)
00420 {
00421 t = ((double)k)/((double)d2);
00422 SetCV(i,j,k,cube.PointAt(r,s,t));
00423 }
00424 }
00425 }
00426 }
00427 return IsValid();
00428 }
00429
00430
00431 void ON_BezierCage::Destroy()
00432 {
00433 if ( m_cv && m_cv_capacity > 0 )
00434 onfree(m_cv);
00435 m_cv_capacity = 0;
00436 m_cv_stride[0] = 0;
00437 m_cv_stride[1] = 0;
00438 m_cv_stride[2] = 0;
00439 m_cv = 0;
00440 m_dim = 0;
00441 m_is_rat = 0;
00442 m_order[0] = 0;
00443 m_order[1] = 0;
00444 m_order[2] = 0;
00445 }
00446
00447 void ON_BezierCage::EmergencyDestroy()
00448 {
00449 m_cv_capacity = 0;
00450 m_cv_stride[0] = 0;
00451 m_cv_stride[1] = 0;
00452 m_cv_stride[2] = 0;
00453 m_cv = 0;
00454 m_dim = 0;
00455 m_is_rat = 0;
00456 m_order[0] = 0;
00457 m_order[1] = 0;
00458 m_order[2] = 0;
00459 }
00460
00461
00462 bool ON_BezierCage::GetBBox(
00463 double* boxmin,
00464 double* boxmax,
00465 int bGrowBox
00466 ) const
00467 {
00468 int i, j;
00469 bool rc = (m_order[0] > 0 && m_order[1] > 0 && m_order[2] > 0) ? true : false;
00470 for ( i = 0; rc && i < m_order[0]; i++ )
00471 for ( j = 0; rc && j < m_order[1]; j++ )
00472 {
00473 rc = ON_GetPointListBoundingBox( m_dim, m_is_rat, m_order[2], m_cv_stride[2],
00474 CV(i,j,0), boxmin, boxmax, bGrowBox );
00475 bGrowBox = true;
00476 }
00477 return rc;
00478 }
00479
00480 bool ON_BezierCage::Transform( const ON_Xform& xform )
00481 {
00482 int i,j;
00483 bool rc = (m_order[0] > 0 && m_order[1] > 0 && m_order[2]) ? true : false;
00484 if (rc)
00485 {
00486 if ( 0 == m_is_rat )
00487 {
00488 if ( xform.m_xform[3][0] != 0.0 || xform.m_xform[3][1] != 0.0 || xform.m_xform[3][2] != 0.0 )
00489 {
00490 MakeRational();
00491 }
00492 }
00493
00494 for ( i = 0; rc && i < m_order[0]; i++ )
00495 {
00496 for ( j = 0; rc && j < m_order[1]; j++ )
00497 {
00498 rc = ON_TransformPointList( m_dim, m_is_rat,
00499 m_order[2], m_cv_stride[2],
00500 CV(i,j,0), xform );
00501 }
00502 }
00503 }
00504 return rc;
00505 }
00506
00507 bool ON_BezierCage::Rotate(
00508 double sin_angle,
00509 double cos_angle,
00510 const ON_3dVector& axis,
00511 const ON_3dPoint& center
00512 )
00513 {
00514 ON_Xform rot;
00515 rot.Rotation( sin_angle, cos_angle, axis, center );
00516 return Transform( rot );
00517 }
00518
00519 bool ON_BezierCage::Rotate(
00520 double angle,
00521 const ON_3dVector& axis,
00522 const ON_3dPoint& center
00523 )
00524 {
00525 return Rotate( sin(angle), cos(angle), axis, center );
00526 }
00527
00528 bool ON_BezierCage::Translate( const ON_3dVector& delta )
00529 {
00530 ON_Xform tr;
00531 tr.Translation( delta );
00532 return Transform( tr );
00533 }
00534
00535 bool ON_BezierCage::Scale( double x )
00536 {
00537 ON_Xform s;
00538 s.Scale( x, x, x );
00539 return Transform( s );
00540 }
00541
00542 ON_Interval ON_BezierCage::Domain(
00543 int
00544 ) const
00545 {
00546 return ON_Interval(0.0,1.0);
00547 }
00548
00549 bool ON_BezierCage::Evaluate(
00550 double r, double s, double t,
00551 int der_count,
00552 int v_stride,
00553 double* v
00554 ) const
00555 {
00556 const int cvdim = m_is_rat?(m_dim+1):m_dim;
00557 int i,j,k,n;
00558 double Barray[64], vtmparray[10*4], Bi, Bij, Bijk, *Bj, *Bk, *vtmp;
00559 const double* CVi;
00560 const double* CVij;
00561 const double* CVijk;
00562
00563 if ( der_count > 0 )
00564 {
00565
00566 ON_ERROR("ON_BezierCage::Evaluate does not evaluate derivatives");
00567 }
00568
00569 i = cvdim*sizeof(*vtmp);
00570 vtmp = m_is_rat ? (i < ((int)(10*4*sizeof(vtmparray[0]))) ? vtmparray : (double*)alloca(i)) : v;
00571 memset(vtmp,0,i);
00572
00573
00574 Bj = ((m_order[1]+m_order[2]) <= 64)
00575 ? &Barray[0]
00576 : ((double*)alloca((m_order[1]+m_order[2])*sizeof(*Bj)));
00577 Bk = Bj + m_order[1];
00578
00579 const int d2 = m_order[2]-1;
00580 for ( k = 0; k <= d2; k++)
00581 {
00582 Bk[k] = ON_EvaluateBernsteinBasis(d2,k,t);
00583 }
00584
00585 const int d1 = m_order[1]-1;
00586 for ( j = 0; j <= d1; j++)
00587 {
00588 Bj[j] = ON_EvaluateBernsteinBasis(d1,j,s);
00589 }
00590
00591 const int d0 = m_order[0]-1;
00592
00593 for ( i = 0; i <= d0; i++ )
00594 {
00595 CVi = m_cv + i*m_cv_stride[0];
00596 Bi = ON_EvaluateBernsteinBasis(d0,i,r);
00597 for ( j = 0; j <= d1; j++ )
00598 {
00599 CVij = CVi + j*m_cv_stride[1];
00600 Bij = Bi*Bj[j];
00601 for ( k = 0; k <= d2; k++ )
00602 {
00603 CVijk = CVij + k*m_cv_stride[2];
00604 Bijk = Bij*Bk[k];
00605 n = cvdim;
00606 while(n--)
00607 {
00608 *vtmp++ += *CVijk++ * Bijk;
00609 }
00610 vtmp -= cvdim;
00611 }
00612 }
00613 }
00614
00615 if ( m_is_rat )
00616 {
00617
00618 Bi = (vtmp[m_dim] != 0.0) ? (1.0/vtmp[m_dim]) : 1.0;
00619 for ( n = 0; n < m_dim; n++ )
00620 {
00621 v[n] = vtmp[n]*Bi;
00622 }
00623 }
00624
00625 return (0 == der_count);
00626 }
00627
00628 ON_3dPoint ON_BezierCage::PointAt(
00629 double r,
00630 double s,
00631 double t
00632 ) const
00633 {
00634 ON_3dPoint pt;
00635 if ( m_dim <= 3 )
00636 {
00637 pt.x = 0.0;
00638 pt.y = 0.0;
00639 pt.z = 0.0;
00640 Evaluate(r,s,t,0,3,&pt.x);
00641 }
00642 else
00643 {
00644 double* v = (double*)alloca(m_dim*sizeof(*v));
00645 v[0] = 0.0;
00646 v[1] = 0.0;
00647 v[2] = 0.0;
00648 Evaluate(r,s,t,0,m_dim,v);
00649 pt.x = v[0];
00650 pt.y = v[1];
00651 pt.z = v[2];
00652 }
00653 return pt;
00654 }
00655
00656 ON_3dPoint ON_BezierCage::PointAt( ON_3dPoint rst ) const
00657 {
00658 ON_3dPoint pt;
00659 if ( m_dim <= 3 )
00660 {
00661 pt.x = 0.0;
00662 pt.y = 0.0;
00663 pt.z = 0.0;
00664 Evaluate(rst.x,rst.y,rst.z,0,3,&pt.x);
00665 }
00666 else
00667 {
00668 double* v = (double*)alloca(m_dim*sizeof(*v));
00669 v[0] = 0.0;
00670 v[1] = 0.0;
00671 v[2] = 0.0;
00672 Evaluate(rst.x,rst.y,rst.z,0,m_dim,v);
00673 pt.x = v[0];
00674 pt.y = v[1];
00675 pt.z = v[2];
00676 }
00677 return pt;
00678 }
00679
00680 bool ON_BezierCage::IsRational() const
00681 {
00682 return m_is_rat ? true : false;
00683 }
00684
00685 int ON_BezierCage::CVSize() const
00686 {
00687 return ( m_is_rat && m_dim>0 ) ? m_dim+1 : m_dim;
00688 }
00689
00690 int ON_BezierCage::Order( int dir ) const
00691 {
00692 return (dir>=0&&dir<=2) ? m_order[dir] : 0;
00693 }
00694
00695 int ON_BezierCage::Degree(int dir) const
00696 {
00697 int order = Order(dir);
00698 return (order>=2) ? order-1 : 0;
00699 }
00700
00701 double* ON_BezierCage::CV( int i, int j, int k ) const
00702 {
00703 #if defined(ON_DEBUG)
00704 if ( 0 == m_cv )
00705 {
00706 ON_ERROR("ON_BezierCage::CV - NULL m_cv");
00707 return 0;
00708 }
00709 if ( i < 0 || i >= m_order[0] || j< 0 || j >= m_order[1] || k < 0 || k >= m_order[2])
00710 {
00711 ON_ERROR("ON_BezierCage::CV - (i,j,k) out of range");
00712 return 0;
00713 }
00714 #endif
00715 return (m_cv) ? (m_cv + i*m_cv_stride[0] + j*m_cv_stride[1] + k*m_cv_stride[2]) : 0;
00716 }
00717
00718 ON::point_style ON_BezierCage::CVStyle() const
00719 {
00720 return m_is_rat ? ON::homogeneous_rational : ON::not_rational;
00721 }
00722
00723 double ON_BezierCage::Weight( int i, int j, int k ) const
00724 {
00725 return (m_cv && m_is_rat) ? m_cv[i*m_cv_stride[0] + j*m_cv_stride[1] + k*m_cv_stride[2] + + m_dim] : 1.0;
00726 }
00727
00728
00729 bool ON_BezierCage::SetWeight( int i, int j, int k, double w )
00730 {
00731 bool rc = false;
00732 if ( m_is_rat )
00733 {
00734 double* cv = CV(i,j,k);
00735 if (cv)
00736 {
00737 cv[m_dim] = w;
00738 rc = true;
00739 }
00740 }
00741 else if ( w == 1.0 )
00742 {
00743 rc = true;
00744 }
00745 return rc;
00746 }
00747
00748 bool ON_BezierCage::SetCV( int i, int j, int k, ON::point_style style, const double* Point )
00749 {
00750 bool rc = true;
00751 int n;
00752 double w;
00753
00754 double* cv = CV(i,j,k);
00755 if ( !cv )
00756 return false;
00757
00758 switch ( style ) {
00759
00760 case ON::not_rational:
00761 memcpy( cv, Point, m_dim*sizeof(*cv) );
00762 if ( IsRational() ) {
00763
00764 cv[m_dim] = 1.0;
00765 }
00766 break;
00767
00768 case ON::homogeneous_rational:
00769 if ( IsRational() ) {
00770
00771 memcpy( cv, Point, (m_dim+1)*sizeof(*cv) );
00772 }
00773 else {
00774
00775 w = (Point[m_dim] != 0.0) ? 1.0/Point[m_dim] : 1.0;
00776 for ( n = 0; n < m_dim; n++ ) {
00777 cv[n] = w*Point[n];
00778 }
00779 }
00780 break;
00781
00782 case ON::euclidean_rational:
00783 if ( IsRational() ) {
00784
00785 w = Point[m_dim];
00786 for ( n = 0; n < m_dim; n++ )
00787 cv[i] = w*Point[i];
00788 cv[m_dim] = w;
00789 }
00790 else {
00791
00792 memcpy( cv, Point, m_dim*sizeof(*cv) );
00793 }
00794 break;
00795
00796 case ON::intrinsic_point_style:
00797 n = m_is_rat?m_dim+1:m_dim;
00798 memcpy(cv,Point,n*sizeof(*cv));
00799 break;
00800
00801 default:
00802 rc = false;
00803 break;
00804 }
00805 return rc;
00806 }
00807
00808 bool ON_BezierCage::SetCV( int i, int j, int k, const ON_3dPoint& point )
00809 {
00810 bool rc = false;
00811 double* cv = CV(i,j,k);
00812 if ( cv ) {
00813 cv[0] = point.x;
00814 if ( m_dim > 1 ) {
00815 cv[1] = point.y;
00816 if ( m_dim > 2 )
00817 cv[2] = point.z;
00818 }
00819 if ( m_is_rat ) {
00820 cv[m_dim] = 1.0;
00821 }
00822 rc = true;
00823 }
00824 return rc;
00825 }
00826
00827 bool ON_BezierCage::SetCV( int i, int j, int k, const ON_4dPoint& point )
00828 {
00829 bool rc = false;
00830 double* cv = CV(i,j,k);
00831 if ( cv ) {
00832 if ( m_is_rat ) {
00833 cv[0] = point.x;
00834 if ( m_dim > 1 ) {
00835 cv[1] = point.y;
00836 if ( m_dim > 2 )
00837 cv[2] = point.z;
00838 }
00839 cv[m_dim] = point.w;
00840 rc = true;
00841 }
00842 else {
00843 double w;
00844 if ( point.w != 0.0 ) {
00845 w = 1.0/point.w;
00846 rc = true;
00847 }
00848 else {
00849 w = 1.0;
00850 }
00851 cv[0] = w*point.x;
00852 if ( m_dim > 1 ) {
00853 cv[1] = w*point.y;
00854 if ( m_dim > 2 ) {
00855 cv[2] = w*point.z;
00856 }
00857 }
00858 }
00859 }
00860 return rc;
00861 }
00862
00863 bool ON_BezierCage::GetCV( int i, int j, int k, ON::point_style style, double* Point ) const
00864 {
00865 const double* cv = CV(i,j,k);
00866 if ( !cv )
00867 return false;
00868 int dim = Dimension();
00869 double w = ( IsRational() ) ? cv[dim] : 1.0;
00870 switch(style) {
00871 case ON::euclidean_rational:
00872 Point[dim] = w;
00873
00874 case ON::not_rational:
00875 if ( w == 0.0 )
00876 return false;
00877 w = 1.0/w;
00878 while(dim--) *Point++ = *cv++ * w;
00879 break;
00880 case ON::homogeneous_rational:
00881 Point[dim] = w;
00882 memcpy( Point, cv, dim*sizeof(*Point) );
00883 break;
00884 default:
00885 return false;
00886 }
00887 return true;
00888 }
00889
00890 bool ON_BezierCage::GetCV( int i, int j, int k, ON_3dPoint& point ) const
00891 {
00892 bool rc = false;
00893 const double* cv = CV(i,j,k);
00894 if ( cv ) {
00895 if ( m_is_rat ) {
00896 if (cv[m_dim] != 0.0) {
00897 const double w = 1.0/cv[m_dim];
00898 point.x = cv[0]*w;
00899 point.y = (m_dim>1)? cv[1]*w : 0.0;
00900 point.z = (m_dim>2)? cv[2]*w : 0.0;
00901 rc = true;
00902 }
00903 }
00904 else {
00905 point.x = cv[0];
00906 point.y = (m_dim>1)? cv[1] : 0.0;
00907 point.z = (m_dim>2)? cv[2] : 0.0;
00908 rc = true;
00909 }
00910 }
00911 return rc;
00912 }
00913
00914 bool ON_BezierCage::GetCV( int i, int j, int k, ON_4dPoint& point ) const
00915 {
00916 bool rc = false;
00917 const double* cv = CV(i,j,k);
00918 if ( cv ) {
00919 point.x = cv[0];
00920 point.y = (m_dim>1)? cv[1] : 0.0;
00921 point.z = (m_dim>2)? cv[2] : 0.0;
00922 point.w = (m_is_rat) ? cv[m_dim] : 1.0;
00923 rc = true;
00924 }
00925 return rc;
00926 }
00927
00928 bool ON_BezierCage::ZeroCVs()
00929 {
00930
00931 bool rc = false;
00932 int i,j,k;
00933 if ( m_cv ) {
00934 if ( m_cv_capacity > 0 ) {
00935 memset( m_cv, 0, m_cv_capacity*sizeof(*m_cv) );
00936 if ( m_is_rat ) {
00937 for ( i = 0; i < m_order[0]; i++ ) {
00938 for ( j = 0; j < m_order[1]; j++ ) {
00939 for ( k = 0; k < m_order[2]; k++ ) {
00940 SetWeight( i,j,k, 1.0 );
00941 }
00942 }
00943 }
00944 }
00945 rc = true;
00946 }
00947 else {
00948 double* cv;
00949 int s = CVSize()*sizeof(*cv);
00950 for ( i = 0; i < m_order[0]; i++ ) {
00951 for ( j = 0; j < m_order[1]; j++ ) {
00952 for ( k = 0; k < m_order[2]; k++ ) {
00953 cv = CV(i,j,k);
00954 memset(cv,0,s);
00955 if ( m_is_rat )
00956 cv[m_dim] = 1.0;
00957 }
00958 }
00959 }
00960 rc = (i>0) ? true : false;
00961 }
00962 }
00963 return rc;
00964 }
00965
00966 bool ON_BezierCage::MakeRational()
00967 {
00968 if ( !IsRational() )
00969 {
00970 ON_ERROR("TODO: fill in ON_BezierCage::MakeRational()");
00971
00972
00973
00974
00975
00976
00977
00978
00979
00980
00981
00982
00983
00984
00985
00986
00987
00988
00989
00990
00991
00992
00993
00994
00995
00996
00997
00998
00999
01000
01001
01002
01003
01004
01005
01006
01007
01008
01009
01010
01011
01012 }
01013 return IsRational();
01014 }
01015
01016 bool ON_BezierCage::MakeNonRational()
01017 {
01018 if ( IsRational() )
01019 {
01020 ON_ERROR("TODO: fill in ON_BezierCage::MakeNonRational()");
01021
01022
01023
01024
01025
01026
01027
01028
01029
01030
01031
01032
01033
01034
01035
01036
01037
01038
01039
01040
01041
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051
01052
01053
01054
01055
01056
01057
01058
01059 }
01060 return ( !IsRational() ) ? true : false;
01061 }
01062
01064
01065 bool ON_BezierCage::ReserveCVCapacity(
01066 int capacity
01067 )
01068 {
01069 if ( m_cv_capacity < capacity ) {
01070 if ( m_cv ) {
01071 if ( m_cv_capacity ) {
01072 m_cv = (double*)onrealloc( m_cv, capacity*sizeof(*m_cv) );
01073 m_cv_capacity = (m_cv) ? capacity : 0;
01074 }
01075
01076 }
01077 else {
01078 m_cv = (double*)onmalloc( capacity*sizeof(*m_cv) );
01079 m_cv_capacity = (m_cv) ? capacity : 0;
01080 }
01081 }
01082 return ( m_cv ) ? true : false;
01083 }
01084
01085
01086
01087 bool ON_BezierCage::IsSingular(
01088 int side
01089
01090 ) const
01091 {
01092 ON_ERROR("TODO: fill in ON_BezierCage::IsSingular\n");
01093 return false;
01094 }
01095
01096
01097
01098 const ON_Xform& ON_BezierCageMorph::WorldToUnitCube() const
01099 {
01100
01101
01102 return m_xyz2rst;
01103 }
01104
01105 const ON_BezierCage& ON_BezierCageMorph::BezierCage() const
01106 {
01107
01108 return m_rst2xyz;
01109 }
01110
01111
01112 bool ON_BezierCageMorph::Transform(const ON_Xform& xform)
01113 {
01114
01115 return m_rst2xyz.Transform(xform);
01116 }
01117
01118 bool ON_BezierCageMorph::Read(ON_BinaryArchive& archive)
01119 {
01120 int major_version = 0;
01121 int minor_version = 0;
01122 bool rc = archive.BeginRead3dmChunk(TCODE_ANONYMOUS_CHUNK,&major_version,&minor_version);
01123 if ( rc )
01124 {
01125 if ( major_version != 1 )
01126 rc = false;
01127 if (rc)
01128 rc = archive.ReadXform(m_xyz2rst);
01129 if(rc)
01130 rc = m_rst2xyz.Read(archive);
01131 if ( !archive.EndRead3dmChunk() )
01132 rc = false;
01133 }
01134 return rc;
01135 }
01136
01137 bool ON_BezierCageMorph::Write(ON_BinaryArchive& archive) const
01138 {
01139 bool rc = archive.BeginWrite3dmChunk(TCODE_ANONYMOUS_CHUNK,1,0);
01140 if (rc)
01141 {
01142 if (rc)
01143 rc = archive.WriteXform(m_xyz2rst);
01144 if(rc)
01145 rc = m_rst2xyz.Write(archive);
01146 if ( !archive.EndWrite3dmChunk() )
01147 rc = false;
01148 }
01149 return rc;
01150 }
01151
01152
01153 ON_BezierCageMorph::ON_BezierCageMorph() : m_bValid(0)
01154 {
01155 }
01156
01157 ON_BezierCageMorph::~ON_BezierCageMorph()
01158 {
01159 }
01160
01161 bool ON_BezierCageMorph::Create(
01162 ON_3dPoint P0,
01163 ON_3dPoint P1,
01164 ON_3dPoint P2,
01165 ON_3dPoint P3,
01166 int point_countX,
01167 int point_countY,
01168 int point_countZ
01169 )
01170 {
01171 if ( point_countX < 2 || point_countY < 2 || point_countZ < 2
01172 || !P0.IsValid()
01173 || !P1.IsValid()
01174 || !P2.IsValid()
01175 || !P3.IsValid() )
01176 {
01177 ON_ERROR("ON_BezierCageMorph::Create - invalid input");
01178 }
01179
01180 m_bValid = false;
01181 ON_3dVector X = P1-P0;
01182 ON_3dVector Y = P2-P0;
01183 ON_3dVector Z = P3-P0;
01184 ON_Xform xform(1.0);
01185 xform[0][0] = X.x;
01186 xform[1][0] = X.y;
01187 xform[2][0] = X.z;
01188 xform[0][1] = Y.x;
01189 xform[1][1] = Y.y;
01190 xform[2][1] = Y.z;
01191 xform[0][2] = Z.x;
01192 xform[1][2] = Z.y;
01193 xform[2][2] = Z.z;
01194 xform[0][3] = P0.x;
01195 xform[1][3] = P0.y;
01196 xform[2][3] = P0.z;
01197 double min_pivot = 0.0;
01198 m_bValid = xform.Invert(&min_pivot);
01199 if (m_bValid)
01200 {
01201 ON_3dPoint box_corners[8];
01202 box_corners[0] = P0;
01203 box_corners[1] = P1;
01204 box_corners[2] = P0+X+Y;
01205 box_corners[3] = P2;
01206 box_corners[4] = P3;
01207 box_corners[5] = P3+X;
01208 box_corners[6] = P3+X+Y;
01209 box_corners[7] = P3+Y;
01210 m_bValid = m_rst2xyz.Create(box_corners,point_countX,point_countY,point_countZ);
01211 m_xyz2rst = xform;
01212 }
01213 else
01214 {
01215 ON_ERROR("ON_BezierCageMorph::Create - invalid input - P0,P1,P2,P3 are coplanar");
01216 m_rst2xyz.Destroy();
01217 }
01218 return m_bValid;
01219 }
01220
01221 bool ON_BezierCageMorph::SetXform( ON_Xform world2unitcube )
01222 {
01223 m_xyz2rst = world2unitcube;
01224 m_bValid = m_xyz2rst.IsValid() && m_rst2xyz.IsValid();
01225 return m_bValid;
01226 }
01227
01228 bool ON_BezierCageMorph::SetBezierCage( ON_BezierCage& unitcube2world )
01229 {
01230 m_rst2xyz = unitcube2world;
01231 m_bValid = m_xyz2rst.IsValid() && m_rst2xyz.IsValid();
01232 return m_bValid;
01233 }