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 ON_OBJECT_IMPLEMENT( ON_SumSurface, ON_Surface, "C4CD5359-446D-4690-9FF5-29059732472B" );
00020
00021 void ON_SumSurface::DestroyRuntimeCache( bool bDelete )
00022 {
00023 ON_Surface::DestroyRuntimeCache(bDelete);
00024 if ( 0 != m_curve[0] )
00025 m_curve[0]->DestroyRuntimeCache(bDelete);
00026 if ( 0 != m_curve[1] )
00027 m_curve[1]->DestroyRuntimeCache(bDelete);
00028
00029
00030 m_bbox.Destroy();
00031 }
00032
00033 ON_SumSurface* ON_SumSurface::New()
00034 {
00035 return new ON_SumSurface();
00036 }
00037
00038 ON_SumSurface* ON_SumSurface::New( const ON_SumSurface& rev_surface )
00039 {
00040 return new ON_SumSurface(rev_surface);
00041 }
00042
00043 ON_SumSurface::ON_SumSurface() : m_basepoint(0.0,0.0,0.0)
00044 {
00045 ON__SET__THIS__PTR(m_s_ON_SumSurface_ptr);
00046 m_curve[0] = 0;
00047 m_curve[1] = 0;
00048 }
00049
00050 ON_SumSurface::~ON_SumSurface()
00051 {
00052 Destroy();
00053 }
00054
00055 void ON_SumSurface::Destroy()
00056 {
00057
00058 DestroyRuntimeCache();
00059 for ( int i = 0; i < 2; i++ )
00060 {
00061 if ( m_curve[i] ) {
00062 delete m_curve[i];
00063 m_curve[i] = 0;
00064 }
00065 }
00066 m_bbox.Destroy();
00067 m_basepoint.Set(0.0,0.0,0.0);
00068 }
00069
00070 void ON_SumSurface::EmergencyDestroy()
00071 {
00072 m_curve[0] = 0;
00073 m_curve[1] = 0;
00074 }
00075
00076 ON_SumSurface::ON_SumSurface( const ON_SumSurface& src )
00077 {
00078 ON__SET__THIS__PTR(m_s_ON_SumSurface_ptr);
00079 m_curve[0] = 0;
00080 m_curve[1] = 0;
00081 *this = src;
00082 }
00083
00084 unsigned int ON_SumSurface::SizeOf() const
00085 {
00086 unsigned int sz = ON_Surface::SizeOf();
00087 if ( m_curve[0] )
00088 sz += m_curve[0]->SizeOf();
00089 if ( m_curve[1] )
00090 sz += m_curve[1]->SizeOf();
00091 return sz;
00092 }
00093
00094 ON__UINT32 ON_SumSurface::DataCRC(ON__UINT32 current_remainder) const
00095 {
00096 if ( m_curve[0] )
00097 current_remainder = m_curve[0]->DataCRC(current_remainder);
00098 if ( m_curve[1] )
00099 current_remainder = m_curve[1]->DataCRC(current_remainder);
00100 return current_remainder;
00101 }
00102
00103 ON_SumSurface& ON_SumSurface::operator=(const ON_SumSurface& src )
00104 {
00105 if ( this != &src )
00106 {
00107 Destroy();
00108 for ( int i = 0; i < 2; i++ )
00109 {
00110 if ( src.m_curve[i] )
00111 {
00112 ON_Object* obj = src.m_curve[i]->DuplicateCurve();
00113 m_curve[i] = ON_Curve::Cast(obj);
00114 if ( !m_curve[i] )
00115 delete obj;
00116 }
00117 }
00118 m_basepoint = src.m_basepoint;
00119 m_bbox = src.m_bbox;
00120 }
00121 return *this;
00122 }
00123
00124 ON_BOOL32 ON_SumSurface::Create( const ON_Curve& curve, ON_3dVector vector )
00125 {
00126 Destroy();
00127 ON_BOOL32 rc = false;
00128 if ( !vector.IsZero() )
00129 {
00130 ON_Curve* pCurve = curve.DuplicateCurve();
00131 rc = Create( pCurve, vector );
00132 }
00133 return rc;
00134 }
00135
00136 ON_BOOL32 ON_SumSurface::Create( ON_Curve* pCurve, ON_3dVector vector )
00137 {
00138 Destroy();
00139 ON_BOOL32 rc = false;
00140 if ( !vector.IsZero() )
00141 {
00142 ON_LineCurve* pLineCurve = new ON_LineCurve( ON_Line( ON_origin, vector ) );
00143 pLineCurve->SetDomain( 0.0, vector.Length() );
00144 m_curve[0] = pCurve;
00145 m_curve[1] = pLineCurve;
00146 m_basepoint.Set(0.0,0.0,0.0);
00147 ON_BoundingBox bbox0 = pCurve->BoundingBox();
00148 ON_BoundingBox bbox1 = bbox0;
00149 bbox1.m_min += vector;
00150 bbox1.m_max += vector;
00151 m_bbox.Union( bbox0, bbox1 );
00152 rc = true;
00153 }
00154 return rc;
00155 }
00156
00157 ON_BOOL32 ON_SumSurface::Create( const ON_Curve& curve, const ON_Curve& path_curve )
00158 {
00159 Destroy();
00160 ON_Curve* pCurve = curve.DuplicateCurve();
00161 ON_Curve* pPathCurve = path_curve.DuplicateCurve();
00162 ON_BOOL32 rc = Create( pCurve, pPathCurve );
00163 return rc;
00164 }
00165
00166 ON_BOOL32 ON_SumSurface::Create( ON_Curve* pCurve, ON_Curve* pPathCurve )
00167 {
00168 Destroy();
00169 ON_BOOL32 rc = false;
00170 if ( pCurve && pPathCurve )
00171 {
00172 m_curve[0] = pCurve;
00173 m_curve[1] = pPathCurve;
00174 m_basepoint = ON_origin - pPathCurve->PointAtStart();
00175 m_bbox.Destroy();
00176 BoundingBox();
00177 rc = true;
00178 }
00179 return rc;
00180 }
00181
00183
00184
00185
00186 ON_BOOL32 ON_SumSurface::IsValid( ON_TextLog* text_log ) const
00187 {
00188 for ( int i = 0; i < 2; i++ )
00189 {
00190 if ( !m_curve[i] )
00191 {
00192 if ( text_log )
00193 text_log->Print("ON_SumSurface.m_curve[%d] is NULL.\n",i);
00194 return false;
00195 }
00196 if ( m_curve[i]->Dimension() != 3 )
00197 {
00198 if ( text_log )
00199 text_log->Print("ON_SumSurface.m_curve[%d]->m_dim = %d (should be 3).\n",i,m_curve[i]->Dimension());
00200 return false;
00201 }
00202 if ( !m_curve[i]->IsValid(text_log) )
00203 {
00204 if ( text_log )
00205 text_log->Print("ON_SumSurface.m_curve[%d] is not valid.\n",i);
00206 return false;
00207 }
00208 }
00209 if ( !m_basepoint.IsValid() )
00210 {
00211 if ( text_log )
00212 text_log->Print("ON_SumSurface.m_basepoint is not valid.\n");
00213 return false;
00214 }
00215 return true;
00216 }
00217
00218 void ON_SumSurface::Dump( ON_TextLog& dump ) const
00219 {
00220 ON_Object::Dump(dump);
00221 dump.PushIndent();
00222 dump.Print("basepoint = ");
00223 dump.Print(m_basepoint);
00224 dump.Print("\n");
00225 for ( int i = 0; i < 2; i++ )
00226 {
00227 if ( m_curve[i] )
00228 {
00229 dump.Print("m_curve[%d]:\n",i);
00230 dump.PushIndent();
00231 m_curve[i]->Dump(dump);
00232 dump.PopIndent();
00233 }
00234 else
00235 dump.Print("m_curve[%d] = NULL\n",i);
00236 }
00237 }
00238
00239 ON_BOOL32 ON_SumSurface::Write( ON_BinaryArchive& file ) const
00240 {
00241 ON_BOOL32 rc = file.Write3dmChunkVersion(1,0);
00242 if ( rc ) {
00243 rc = file.WriteVector( m_basepoint );
00244 rc = file.WriteBoundingBox( m_bbox );
00245 if ( rc ) rc = file.WriteObject( m_curve[0] );
00246 if ( rc ) rc = file.WriteObject( m_curve[1] );
00247 }
00248 return rc;
00249 }
00250
00251 ON_BOOL32 ON_SumSurface::Read( ON_BinaryArchive& file )
00252 {
00253 Destroy();
00254 int major_version = 0;
00255 int minor_version = 0;
00256 ON_BOOL32 rc = file.Read3dmChunkVersion( &major_version, &minor_version );
00257 if (rc && major_version == 1 ) {
00258 ON_Object* obj;
00259 rc = file.ReadVector( m_basepoint );
00260 if (rc) rc = file.ReadBoundingBox( m_bbox );
00261 obj = 0;
00262 if (rc) rc = file.ReadObject(&obj);
00263 if (rc) {
00264 m_curve[0] = ON_Curve::Cast(obj);
00265 if ( !m_curve[0] )
00266 delete obj;
00267 }
00268 obj = 0;
00269 if (rc) rc = file.ReadObject(&obj);
00270 if (rc) {
00271 m_curve[1] = ON_Curve::Cast(obj);
00272 if ( !m_curve[1] )
00273 delete obj;
00274 }
00275 }
00276 return rc;
00277 }
00278
00280
00281
00282
00283 int ON_SumSurface::Dimension() const
00284 {
00285 int dim = 0;
00286 if ( m_curve[0] && m_curve[1] ) {
00287 dim = m_curve[0]->Dimension();
00288 if ( dim > 0 ) {
00289 if ( dim != m_curve[1]->Dimension() )
00290 dim = 0;
00291 }
00292 }
00293 return dim;
00294 }
00295
00296 void ON_SumSurface::ClearBoundingBox()
00297 {
00298 m_bbox.Destroy();
00299 }
00300
00301 ON_BOOL32 ON_SumSurface::GetBBox(
00302 double* boxmin,
00303 double* boxmax,
00304 ON_BOOL32 bGrowBox
00305 ) const
00306 {
00307 ON_BOOL32 rc = m_bbox.IsValid();
00308 if (!rc )
00309 {
00310
00311 ON_BoundingBox bboxA, bboxB;
00312 if ( m_curve[0] )
00313 bboxA = m_curve[0]->BoundingBox();
00314 if ( m_curve[1] )
00315 bboxB = m_curve[1]->BoundingBox();
00316 if ( bboxA.IsValid() && bboxB.IsValid() )
00317 {
00318 ON_SumSurface* pS = const_cast<ON_SumSurface*>(this);
00319 pS->m_bbox.m_min = bboxA.m_min + bboxB.m_min + m_basepoint;
00320 pS->m_bbox.m_max = bboxA.m_max + bboxB.m_max + m_basepoint;
00321 }
00322 rc = m_bbox.IsValid();
00323 }
00324
00325 if ( rc )
00326 {
00327 int dim = Dimension();
00328 int j;
00329 ON_BoundingBox bbox;
00330 if ( bGrowBox && boxmin && boxmax )
00331 {
00332 for ( j = 0; j < 3 && j < dim; j++ )
00333 {
00334 bbox.m_min[j] = boxmin[j];
00335 bbox.m_max[j] = boxmax[j];
00336 }
00337 if ( !bbox.IsValid() )
00338 bbox = m_bbox;
00339 else
00340 bbox.Union(m_bbox);
00341 }
00342 else
00343 bbox = m_bbox;
00344 dim = Dimension();
00345 for ( j = 0; j < 3 && j < dim; j++ )
00346 {
00347 if(boxmin)
00348 boxmin[j] = bbox.m_min[j];
00349 if(boxmax)
00350 boxmax[j] = bbox.m_max[j];
00351 }
00352 for ( j = 3; j < dim; j++ )
00353 {
00354 if (boxmin)
00355 boxmin[j] = 0.0;
00356 if (boxmax)
00357 boxmax[j] = 0.0;
00358 }
00359 }
00360 return rc;
00361 }
00362
00363 bool ON_SumSurface::IsDeformable() const
00364 {
00365 bool rc = true;
00366 if ( m_curve[0] )
00367 rc = m_curve[0]->IsDeformable();
00368 if (rc && m_curve[1] )
00369 rc = m_curve[1]->IsDeformable();
00370 return rc;
00371 }
00372
00373 bool ON_SumSurface::MakeDeformable()
00374 {
00375 bool rc = true;
00376 if ( m_curve[0] && !m_curve[0]->IsDeformable() )
00377 {
00378 DestroyRuntimeCache();
00379 rc = rc && m_curve[0]->MakeDeformable();
00380 }
00381 if (m_curve[1] && !m_curve[1]->IsDeformable() )
00382 {
00383 DestroyRuntimeCache();
00384 rc = rc && m_curve[1]->MakeDeformable();
00385 }
00386 return rc;
00387 }
00388
00389 ON_BOOL32 ON_SumSurface::Transform( const ON_Xform& xform )
00390 {
00391 DestroyRuntimeCache();
00392 TransformUserData(xform);
00393 ON_BOOL32 rc = false;
00394
00395 ON_3dPoint A0, A1, A2;
00396 if ( m_curve[0] )
00397 {
00398 A0 = m_curve[0]->PointAtStart();
00399 rc = m_curve[0]->Transform(xform);
00400 }
00401 if ( m_curve[1] )
00402 {
00403 A1 = m_curve[1]->PointAtStart();
00404 if ( !m_curve[1]->Transform(xform) )
00405 rc = false;
00406 }
00407 else
00408 rc = false;
00409 if ( rc )
00410 {
00411
00412 A2 = m_basepoint;
00413 m_basepoint = xform*(A0+A1+A2) - xform*A0 - xform*A1;
00414 }
00415 m_bbox.Destroy();
00416 m_bbox = BoundingBox();
00417 return rc;
00418 }
00419
00421
00422
00423
00424
00425 ON_BOOL32 ON_SumSurface::SetDomain(
00426 int dir,
00427 double t0,
00428 double t1
00429 )
00430 {
00431 bool rc = false;
00432 if ( t0 < t1 && dir >= 0 && dir <= 1 )
00433 {
00434 if ( 0 != m_curve[dir] )
00435 {
00436 rc = m_curve[dir]->SetDomain(t0,t1) ? true : false;
00437 DestroyRuntimeCache();
00438 }
00439 }
00440 return rc;
00441 }
00442
00443
00444
00445 ON_Interval ON_SumSurface::Domain( int dir ) const
00446 {
00447 ON_Interval domain;
00448 if ( dir == 0 && m_curve[0] )
00449 domain = m_curve[0]->Domain();
00450 else if ( dir == 1 && m_curve[1] )
00451 domain = m_curve[1]->Domain();
00452 return domain;
00453 }
00454
00455 ON_BOOL32 ON_SumSurface::GetSurfaceSize(
00456 double* width,
00457 double* height
00458 ) const
00459 {
00460 ON_BOOL32 rc = true;
00461 double* ptr[2];
00462 ptr[0] = width;
00463 ptr[1] = height;
00464 int j;
00465 for ( j = 0; j < 2; j++ )
00466 {
00467 if ( ptr[j] == NULL )
00468 continue;
00469 *ptr[j] = 0.0;
00470 if ( m_curve[j] == NULL )
00471 rc = false;
00472
00473 if ( ! (*ptr[j] > 0.0) )
00474 {
00475 int i, imax = 64, hint = 0;
00476 double length_estimate = 0.0, d = 1.0/((double)imax);
00477 ON_Interval cdom = m_curve[j]->Domain();
00478 ON_3dPoint pt0 = ON_UNSET_POINT;
00479 ON_3dPoint pt;
00480 for ( i = 0; i <= imax; i++ )
00481 {
00482 if ( m_curve[j]->EvPoint( cdom.ParameterAt(i*d), pt, 0, &hint ) )
00483 {
00484 if ( pt0 != ON_UNSET_POINT )
00485 length_estimate += pt0.DistanceTo(pt);
00486 pt0 = pt;
00487 }
00488 }
00489 *ptr[j] = length_estimate;
00490 }
00491 }
00492
00493 return rc;
00494 }
00495
00496
00497 int ON_SumSurface::SpanCount( int dir ) const
00498 {
00499 int span_count = 0;
00500 if ( dir == 0 && m_curve[0] )
00501 span_count = m_curve[0]->SpanCount();
00502 else if ( dir == 1 && m_curve[1] )
00503 span_count = m_curve[1]->SpanCount();
00504 return span_count;
00505 }
00506
00507 ON_BOOL32 ON_SumSurface::GetSpanVector( int dir, double* s ) const
00508 {
00509 ON_BOOL32 rc = false;
00510 if ( dir == 0 && m_curve[0] )
00511 rc = m_curve[0]->GetSpanVector(s);
00512 else if ( dir == 1 && m_curve[1] )
00513 rc = m_curve[1]->GetSpanVector(s);
00514 return rc;
00515 }
00516
00517
00518 int ON_SumSurface::Degree( int dir ) const
00519 {
00520 int degree = 0;
00521 if ( dir == 0 && m_curve[0] )
00522 degree = m_curve[0]->Degree();
00523 else if ( dir == 1 && m_curve[1] )
00524 degree = m_curve[1]->Degree();
00525 return degree;
00526 }
00527
00528
00529 ON_BOOL32 ON_SumSurface::GetParameterTolerance(
00530 int dir,
00531 double t,
00532 double* tminus,
00533 double* tplus
00534 ) const
00535 {
00536 ON_BOOL32 rc = false;
00537 if ( dir == 0 && m_curve[0] )
00538 rc = m_curve[0]->GetParameterTolerance(t,tminus,tplus);
00539 else if ( dir == 1 && m_curve[1] )
00540 rc = m_curve[1]->GetParameterTolerance(t,tminus,tplus);
00541 return rc;
00542 }
00543
00544 ON_BOOL32 ON_SumSurface::IsPlanar(
00545 ON_Plane* plane,
00546 double tolerance
00547 ) const
00548 {
00549 ON_Plane pln;
00550 ON_3dPoint center;
00551 ON_3dVector normal, du, dv;
00552 ON_Interval udom = Domain(0);
00553 ON_Interval vdom = Domain(1);
00554 ON_BOOL32 rc = EvNormal( udom.ParameterAt(0.5), vdom.ParameterAt(0.5), center, du, dv, normal );
00555 if (rc)
00556 {
00557 if ( fabs( normal.Length() - 1.0 ) > 0.01 )
00558 rc = false;
00559 else
00560 {
00561 pln.origin = center;
00562 pln.zaxis = normal;
00563 if ( du.Unitize() )
00564 {
00565 pln.xaxis = du;
00566 pln.yaxis = ON_CrossProduct( pln.zaxis, pln.xaxis );
00567 pln.yaxis.Unitize();
00568 pln.UpdateEquation();
00569 }
00570 else if ( dv.Unitize() )
00571 {
00572 pln.yaxis = dv;
00573 pln.xaxis = ON_CrossProduct( pln.yaxis, pln.zaxis );
00574 pln.xaxis.Unitize();
00575 pln.UpdateEquation();
00576 }
00577 else
00578 {
00579 pln.CreateFromNormal( center, normal );
00580 }
00581 if ( plane )
00582 *plane = pln;
00583
00584 int j;
00585 for ( j = 0; j < 2 && rc ; j++ )
00586 {
00587 pln.origin = m_curve[j]->PointAtStart();
00588 pln.UpdateEquation();
00589 rc = m_curve[j]->IsInPlane( pln, tolerance );
00590 }
00591
00592 if (rc && plane )
00593 {
00594 pln.origin = center;
00595 pln.UpdateEquation();
00596 *plane = pln;
00597 }
00598 }
00599 }
00600 return rc;
00601 }
00602
00603 ON_BOOL32 ON_SumSurface::IsClosed( int dir ) const
00604 {
00605 ON_BOOL32 rc = false;
00606 if ( dir == 0 && m_curve[0] )
00607 rc = m_curve[0]->IsClosed();
00608 else if ( dir == 1 && m_curve[1] )
00609 rc = m_curve[1]->IsClosed();
00610 return rc;
00611 }
00612
00613
00614 ON_BOOL32 ON_SumSurface::IsPeriodic( int dir ) const
00615 {
00616 ON_BOOL32 rc = false;
00617 if ( dir == 0 && m_curve[0] )
00618 rc = m_curve[0]->IsPeriodic();
00619 else if ( dir == 1 && m_curve[1] )
00620 rc = m_curve[1]->IsPeriodic();
00621 return rc;
00622 }
00623
00624 ON_BOOL32 ON_SumSurface::IsSingular( int side ) const
00625 {
00626 return false;
00627 }
00628
00629
00630 bool ON_SumSurface::GetNextDiscontinuity(
00631 int dir,
00632 ON::continuity c,
00633 double t0,
00634 double t1,
00635 double* t,
00636 int* hint,
00637 int* dtype,
00638 double cos_angle_tolerance,
00639 double curvature_tolerance
00640 ) const
00641 {
00642
00643 bool rc = false;
00644 if ( 0 == dir || 1 == dir )
00645 {
00646 if (0 != m_curve[dir] )
00647 {
00648 rc = m_curve[dir]->GetNextDiscontinuity(
00649 c,
00650 t0,t1,t,
00651 (hint?&hint[dir]:0),
00652 dtype,
00653 cos_angle_tolerance,
00654 curvature_tolerance);
00655 }
00656 }
00657 return rc;
00658 }
00659
00660 bool ON_SumSurface::IsContinuous(
00661 ON::continuity desired_continuity,
00662 double s,
00663 double t,
00664 int* hint,
00665 double point_tolerance,
00666 double d1_tolerance,
00667 double d2_tolerance,
00668 double cos_angle_tolerance,
00669 double curvature_tolerance
00670 ) const
00671 {
00672 bool rc = true;
00673 if ( m_curve[0] && m_curve[1] )
00674 {
00675 int crv_hint[2] = {0,0};
00676 if ( hint )
00677 {
00678 crv_hint[0] = (*hint) & 0xFFFF;
00679 crv_hint[1] = ((*hint) & 0xFFFF0000) >> 16;
00680 }
00681 rc = m_curve[0]->IsContinuous( desired_continuity, s, &crv_hint[0],
00682 point_tolerance, d1_tolerance, d2_tolerance,
00683 cos_angle_tolerance, curvature_tolerance );
00684 if (rc )
00685 rc = m_curve[1]->IsContinuous( desired_continuity, t, &crv_hint[1],
00686 point_tolerance, d1_tolerance, d2_tolerance,
00687 cos_angle_tolerance, curvature_tolerance );
00688 if ( hint )
00689 {
00690 *hint = ( (crv_hint[0]&0xFFFF) | (crv_hint[1]<<16) );
00691 }
00692 }
00693 return rc;
00694 }
00695
00696
00697 ON_BOOL32 ON_SumSurface::Reverse( int dir )
00698 {
00699 ON_BOOL32 rc = false;
00700 if ( dir == 0 && m_curve[0] )
00701 rc = m_curve[0]->Reverse();
00702 else if ( dir == 1 && m_curve[1] )
00703 rc = m_curve[1]->Reverse();
00704 DestroySurfaceTree();
00705 return rc;
00706 }
00707
00708
00709 ON_BOOL32 ON_SumSurface::Transpose()
00710 {
00711 ON_Curve* c = m_curve[0];
00712 m_curve[0] = m_curve[1];
00713 m_curve[1] = c;
00714 DestroySurfaceTree();
00715 return true;
00716 }
00717
00718
00719 ON_BOOL32 ON_SumSurface::Evaluate(
00720 double s, double t,
00721 int nder,
00722 int v_stride,
00723 double* v,
00724 int side,
00725
00726
00727
00728
00729
00730 int* hint
00731
00732 ) const
00733 {
00734 ON_BOOL32 rc = false;
00735 const int dim = Dimension();
00736 if ( dim > 0 )
00737 {
00738 int crv_hint[2] = {0,0};
00739 if ( hint )
00740 {
00741 crv_hint[0] = (*hint) & 0xFFFF;
00742 crv_hint[1] = ((*hint) & 0xFFFF0000) >> 16;
00743 }
00744 double* v0 = (double*)onmalloc( 2*(nder+1)*dim*sizeof(*v0) );
00745 double* v1 = v0 + (nder+1)*dim;
00746 int side0, side1;
00747 switch(side)
00748 {
00749 case 1:
00750 side0 = 1;
00751 side1 = 1;
00752 break;
00753 case 2:
00754 side0 = -1;
00755 side1 = 1;
00756 break;
00757 case 3:
00758 side0 = -1;
00759 side1 = -1;
00760 break;
00761 case 4:
00762 side0 = 1;
00763 side1 = -1;
00764 break;
00765 default:
00766 side0 = 1;
00767 side1 = 1;
00768 break;
00769 }
00770 rc = m_curve[0]->Evaluate(s,nder,dim,v0,side0,hint ? &crv_hint[0] : 0);
00771 if ( rc )
00772 rc = m_curve[1]->Evaluate(t,nder,dim,v1,side1,hint ? &crv_hint[1] : 0);
00773 if (rc)
00774 {
00775 int j,ds,dt,der;
00776 for ( j = 0; j < dim; j++ )
00777 {
00778 v[j] = m_basepoint[j] + v0[j] + v1[j];
00779 }
00780 for ( der = 1; der <= nder; der++ )
00781 {
00782 for ( ds = der, dt = 0; ds >= 0; ds--, dt++ )
00783 {
00784 v += v_stride;
00785 for ( j = 0; j < dim; j++ )
00786 v[j] = 0.0;
00787
00788
00789
00790 if (ds && dt)
00791 continue;
00792
00793 if ( ds )
00794 {
00795 for ( j = 0; j < dim; j++ )
00796 v[j] += v0[j+dim*ds];
00797 }
00798 if ( dt )
00799 {
00800 for ( j = 0; j < dim; j++ )
00801 v[j] += v1[j+dim*dt];
00802 }
00803 }
00804 }
00805 }
00806 if ( hint )
00807 {
00808 *hint = crv_hint[0] | (crv_hint[1] << 16);
00809 }
00810 onfree(v0);
00811 }
00812 return rc;
00813 }
00814
00815 ON_Curve* ON_SumSurface::IsoCurve(int dir, double c ) const
00816 {
00817 ON_Curve* iso_curve = 0;
00818 if ( dir >= 0 && dir <= 1 && m_curve[0] && m_curve[1] )
00819 {
00820 iso_curve = m_curve[dir]->Duplicate();
00821 ON_3dPoint p = m_curve[1-dir]->PointAt(c);
00822 ON_3dVector v = p + m_basepoint;
00823 if ( !v.IsZero() )
00824 {
00825 if ( !iso_curve->Translate(v) )
00826 {
00827 delete iso_curve;
00828 iso_curve = 0;
00829 }
00830 }
00831 }
00832 return iso_curve;
00833 }
00834
00835 class ON_SumTensor : public ON_TensorProduct
00836 {
00837 public:
00838 int dim;
00839 ON_3dPoint basepoint;
00840 int DimensionA() const;
00841 int DimensionB() const;
00842 int DimensionC() const;
00843 bool Evaluate( double,
00844 const double*,
00845 double,
00846 const double*,
00847 double*
00848 );
00849 };
00850
00851 int ON_SumTensor::DimensionA() const
00852 {
00853 return dim;
00854 }
00855
00856 int ON_SumTensor::DimensionB() const
00857 {
00858 return dim;
00859 }
00860
00861 int ON_SumTensor::DimensionC() const
00862 {
00863 return dim;
00864 }
00865
00866 bool ON_SumTensor::Evaluate( double a, const double* CurveA, double b, const double* CurveB, double* SrfPoint )
00867 {
00868 SrfPoint[0] = a*CurveA[0] + b*CurveB[0] + basepoint.x;
00869 SrfPoint[1] = a*CurveA[1] + b*CurveB[1] + basepoint.y;
00870 SrfPoint[2] = a*CurveA[2] + b*CurveB[2] + basepoint.z;
00871 return true;
00872 }
00873
00874
00875 int ON_SumSurface::GetNurbForm(
00876 ON_NurbsSurface& nurbs_surface,
00877 double tolerance
00878 ) const
00879 {
00880 nurbs_surface.Destroy();
00881 int rc = 0;
00882 int dim = Dimension();
00883 if ( dim > 0 )
00884 {
00885 ON_NurbsCurve tmpA, tmpB;
00886 int rcA = 0;
00887 int rcB = 0;
00888 const ON_NurbsCurve* nurbs_curveA=0;
00889 const ON_NurbsCurve* nurbs_curveB=0;
00890 nurbs_curveA = ON_NurbsCurve::Cast(m_curve[0]);
00891 if ( !nurbs_curveA )
00892 {
00893 rcA = 1;
00894 rcA = m_curve[0]->GetNurbForm( tmpA, tolerance );
00895 if ( rcA > 0 )
00896 nurbs_curveA = &tmpA;
00897 }
00898 if ( nurbs_curveA )
00899 {
00900 rcB = 1;
00901 nurbs_curveB = ON_NurbsCurve::Cast(m_curve[1]);
00902 if ( !nurbs_curveB )
00903 {
00904 rcB = m_curve[1]->GetNurbForm( tmpB, tolerance );
00905 if ( rcB > 0 )
00906 nurbs_curveB = &tmpB;
00907 }
00908 }
00909 if ( nurbs_curveA && nurbs_curveB )
00910 {
00911 ON_SumTensor sum_tensor;
00912 sum_tensor.dim = dim;
00913 sum_tensor.basepoint = m_basepoint;
00914 if ( !nurbs_surface.TensorProduct( *nurbs_curveA, *nurbs_curveB, sum_tensor ) )
00915 nurbs_surface.Destroy();
00916 else
00917 rc = (rcA >= rcB) ? rcA : rcB;
00918 }
00919 }
00920 return rc;
00921 }
00922
00923 int ON_SumSurface::HasNurbForm() const
00924
00925 {
00926 if (Dimension() <= 0)
00927 return 0;
00928 int rc = 1;
00929 int i;
00930 for (i=0; i<2; i++){
00931 int nf = m_curve[i]->HasNurbForm();
00932 if (nf == 0)
00933 return 0;
00934 if (nf == 2)
00935 rc = 2;
00936 }
00937
00938 return rc;
00939 }
00940
00941
00942
00943 bool ON_SumSurface::GetSurfaceParameterFromNurbFormParameter(
00944 double nurbs_s, double nurbs_t,
00945 double* surface_s, double* surface_t
00946 ) const
00947 {
00948
00949 bool rc = (m_curve[0] && m_curve[1]) ? true : false;
00950 *surface_s = nurbs_s;
00951 *surface_t = nurbs_t;
00952 if ( m_curve[0] )
00953 {
00954 if ( !m_curve[0]->GetCurveParameterFromNurbFormParameter( nurbs_s, surface_s ) )
00955 rc = false;
00956 }
00957
00958 if ( m_curve[1] )
00959 {
00960 if (!m_curve[1]->GetCurveParameterFromNurbFormParameter( nurbs_t, surface_t ))
00961 rc = false;
00962 }
00963
00964 return rc;
00965 }
00966
00967 bool ON_SumSurface::GetNurbFormParameterFromSurfaceParameter(
00968 double surface_s, double surface_t,
00969 double* nurbs_s, double* nurbs_t
00970 ) const
00971 {
00972
00973 bool rc = (m_curve[0] && m_curve[1]) ? true : false;
00974 *nurbs_s = surface_s;
00975 *nurbs_t = surface_t;
00976 if ( m_curve[0] )
00977 {
00978 if ( !m_curve[0]->GetNurbFormParameterFromCurveParameter( surface_s, nurbs_s ) )
00979 rc = false;
00980 }
00981
00982 if ( m_curve[1] )
00983 {
00984 if (!m_curve[1]->GetNurbFormParameterFromCurveParameter( surface_t, nurbs_t ))
00985 rc = false;
00986 }
00987 return rc;
00988 }
00989
00990 ON_BOOL32 ON_SumSurface::Trim(int dir,
00991 const ON_Interval& domain
00992 )
00993
00994 {
00995 if ( dir < 0 || dir > 1 )
00996 return false;
00997 ON_Interval current_domain = Domain(dir);
00998 if ( current_domain[0] == ON_UNSET_VALUE && current_domain[1] == ON_UNSET_VALUE )
00999 current_domain = domain;
01000 ON_Interval trim_domain;
01001 trim_domain.Intersection(domain, Domain(dir) );
01002 if ( !trim_domain.IsIncreasing() )
01003 return false;
01004 if (trim_domain[0] == current_domain[0]
01005 && trim_domain[1] == current_domain[1] )
01006 return true;
01007 m_bbox.Destroy();
01008 DestroySurfaceTree();
01009 return m_curve[dir]->Trim(trim_domain);
01010 }
01011
01012 bool ON_SumSurface::Extend(
01013 int dir,
01014 const ON_Interval& domain
01015 )
01016 {
01017 if ( dir < 0 || dir > 1 ) return false;
01018 if (IsClosed(dir)) return false;
01019 ON_Interval current_domain = Domain(dir);
01020 if (!m_curve[dir]) return false;
01021 bool rc = m_curve[dir]->Extend(domain);
01022 if (rc){
01023 DestroySurfaceTree();
01024 m_bbox.Destroy();
01025 }
01026 return rc;
01027 }
01028
01029 ON_BOOL32 ON_SumSurface::Split(int dir,
01030 double c,
01031 ON_Surface*& west_or_south_side,
01032 ON_Surface*& east_or_north_side
01033 ) const
01034
01035 {
01036 if ( dir < 0 || dir > 1 )
01037 return false;
01038 if ( !Domain(dir).Includes( c, true ) )
01039 return false;
01040 ON_SumSurface* left_srf = 0;
01041 ON_SumSurface* right_srf = 0;
01042
01043
01044 if ( west_or_south_side )
01045 {
01046 left_srf = ON_SumSurface::Cast( west_or_south_side );
01047 if ( !left_srf )
01048 return false;
01049 left_srf->DestroySurfaceTree();
01050 left_srf->m_bbox.Destroy();
01051 }
01052
01053 if ( east_or_north_side )
01054 {
01055 right_srf = ON_SumSurface::Cast( east_or_north_side );
01056 if ( !right_srf )
01057 return false;
01058 right_srf->DestroySurfaceTree();
01059 right_srf->m_bbox.Destroy();
01060 }
01061
01062 if (!left_srf) left_srf = ON_SumSurface::New(*this);
01063 else if (left_srf != this) *left_srf = *this;
01064
01065 if (!right_srf) right_srf = ON_SumSurface::New(*this);
01066 else if (right_srf != this) *right_srf = *this;
01067
01068 if (left_srf == this && right_srf == this)
01069 return false;
01070
01071 if (left_srf != this) {
01072 delete left_srf->m_curve[dir];
01073 left_srf->m_curve[dir] = 0;
01074 }
01075
01076 if (right_srf != this) {
01077 delete right_srf->m_curve[dir];
01078 right_srf->m_curve[dir] = 0;
01079 }
01080
01081
01082 if (!m_curve[dir]->Split(c, left_srf->m_curve[dir],
01083 right_srf->m_curve[dir])){
01084 if (!west_or_south_side) delete left_srf;
01085 if (!east_or_north_side) delete right_srf;
01086 return false;
01087 }
01088
01089 if (!west_or_south_side) west_or_south_side = left_srf;
01090 if (!east_or_north_side) east_or_north_side = right_srf;
01091
01092 return true;
01093
01094 }
01095
01096
01097
01098
01099
01100
01101
01102
01103
01104
01105
01106
01107
01108
01109
01110
01111
01112
01113
01114
01115
01116
01117
01118
01119
01120
01121
01122
01123
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133
01134
01135
01136
01137
01138
01139
01140
01141
01142
01143
01144
01145
01146
01147
01148
01149
01150
01151
01152
01153
01154
01155
01156
01157
01158
01159
01160
01161
01162