opennurbs_sumsurface.cpp
Go to the documentation of this file.
00001 /* $NoKeywords: $ */
00002 /*
00003 //
00004 // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved.
00005 // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
00006 // McNeel & Associates.
00007 //
00008 // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
00009 // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
00010 // MERCHANTABILITY ARE HEREBY DISCLAIMED.
00011 //                              
00012 // For complete openNURBS copyright information see <http://www.opennurbs.org>.
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   // 15 August 2003 Dale Lear:
00029   //    Added the call to destroy the cached bounding box
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         // GBA 24-Sept-2004. Since there now could be a surface tree it need to be cleared out.
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 // overrides of virtual ON_Object functions
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 // overrides of virtual ON_Geometry functions
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( // returns true if successful
00302        double* boxmin,    // boxmin[dim]
00303        double* boxmax,    // boxmax[dim]
00304        ON_BOOL32 bGrowBox
00305        ) const
00306 {
00307   ON_BOOL32 rc = m_bbox.IsValid();
00308   if (!rc )
00309   {
00310     // lazy bounding box evaluation
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     // because xform may be affine
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 // overrides of virtual ON_Surface functions
00423 //
00424 
00425 ON_BOOL32 ON_SumSurface::SetDomain( 
00426   int dir, // 0 sets first parameter's domain, 1 gets second parameter's domain
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( // returns tminus < tplus: parameters tminus <= s <= tplus
00530        int dir,     // 0 gets first parameter, 1 gets second parameter
00531        double t,  // t = parameter in domain
00532        double* tminus, // tminus
00533        double* tplus // 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   // 28 Jan 2005 - untested code
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, // default = NULL,
00665     double point_tolerance, // default=ON_ZERO_TOLERANCE
00666     double d1_tolerance, // default==ON_ZERO_TOLERANCE
00667     double d2_tolerance, // default==ON_ZERO_TOLERANCE
00668     double cos_angle_tolerance, // default==ON_DEFAULT_ANGLE_TOLERANCE_COSINE
00669     double curvature_tolerance  // default==ON_SQRT_EPSILON
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( // returns false if unable to evaluate
00720        double s, double t, // evaluation parameters
00721        int nder,            // number of derivatives (>=0)
00722        int v_stride,            // array stride (>=Dimension())
00723        double* v,        // array of length stride*(ndir+1)*(ndir+2)/2
00724        int side,        // optional - determines which quadrant to evaluate from
00725                        //         0 = default
00726                        //         1 from NE quadrant
00727                        //         2 from NW quadrant
00728                        //         3 from SW quadrant
00729                        //         4 from SE quadrant
00730        int* hint        // optional - evaluation hint (int[2]) used to speed
00731                        //            repeated evaluations
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           // Mar 18 CCW - Fixed bug in evaluator that
00789           //              returned non-zero values for mixed partials.
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,        // a
00844                  const double*, // A
00845                  double,        // b
00846                  const double*, // B
00847                  double*        // C
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   // NOTE: overrides ON_Surface virtual function
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   // NOTE: overrides ON_Surface virtual function
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 bool ON_SumSurface::GetSurfaceParameterFromNurbFormParameter(
01099       double nurbs_s, double nurbs_t,
01100       double* surface_s, double* surface_t
01101       ) const
01102 {
01103   // NOTE: overrides ON_Surface virtual function
01104   bool rc;
01105   if ( m_curve[0] )
01106   {
01107     rc = m_curve[0]->GetCurveParameterFromNurbFormParameter( nurbs_s, surface_s );
01108   }
01109   else
01110   {
01111     rc = false;
01112     *surface_s = nurbs_s;
01113   }
01114 
01115   if ( m_curve[1] )
01116   {
01117     if ( m_curve[1]->GetCurveParameterFromNurbFormParameter( nurbs_t, surface_t ) )
01118       rc = false;
01119   }
01120   else
01121   {
01122     rc = false;
01123     *surface_t = nurbs_t;
01124   }
01125 
01126   return rc;
01127 }
01128 
01129 
01130 bool ON_SumSurface::GetNurbFormParameterFromSurfaceParameter(
01131       double surface_s, double surface_t,
01132       double* nurbs_s,  double* nurbs_t
01133       ) const
01134 {
01135   // NOTE: overrides ON_Surface virtual function
01136   bool rc;
01137 
01138   if ( m_curve[0] )
01139   {
01140     rc = m_curve[0]->GetNurbFormParameterFromCurveParameter( surface_s, nurbs_s );
01141   }
01142   else
01143   {
01144     rc = false;
01145     *surface_s = nurbs_s;
01146   }
01147 
01148   if ( m_curve[1] )
01149   {
01150     if ( m_curve[1]->GetNurbFormParameterFromCurveParameter( surface_t, nurbs_t ) )
01151       rc = false;
01152   }
01153   else
01154   {
01155     rc = false;
01156     *surface_t = nurbs_t;
01157   }
01158 
01159   return rc;
01160 }
01161 
01162 */


pcl
Author(s): Open Perception
autogenerated on Wed Aug 26 2015 15:27:03