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_CurveProxy,ON_Curve,"4ED7D4D9-E947-11d3-BFE5-0010830122F0");
00020
00021 ON_CurveProxy::ON_CurveProxy() : m_real_curve(0), m_bReversed(0)
00022 {}
00023
00024 ON_CurveProxy::ON_CurveProxy( const ON_CurveProxy& src )
00025 : ON_Curve(src), m_real_curve(0), m_bReversed(0)
00026 {
00027 *this = src;
00028 }
00029
00030 ON_CurveProxy::ON_CurveProxy( const ON_Curve* c )
00031 : m_real_curve(c), m_bReversed(0)
00032 {
00033 if ( m_real_curve )
00034 m_real_curve_domain =m_this_domain = m_real_curve->Domain();
00035 }
00036
00037 ON_CurveProxy::ON_CurveProxy( const ON_Curve* c, ON_Interval domain )
00038 : m_real_curve(c),
00039 m_bReversed(0),
00040 m_real_curve_domain(domain),
00041 m_this_domain(domain)
00042 {
00043 }
00044
00045 unsigned int ON_CurveProxy::SizeOf() const
00046 {
00047 unsigned int sz = ON_Curve::SizeOf();
00048 sz += (sizeof(*this) - sizeof(ON_Curve));
00049
00050
00051 return sz;
00052 }
00053
00054 ON__UINT32 ON_CurveProxy::DataCRC(ON__UINT32 current_remainder) const
00055 {
00056 if ( m_real_curve )
00057 current_remainder = m_real_curve->DataCRC(current_remainder);
00058 current_remainder = ON_CRC32(current_remainder,sizeof(m_bReversed),&m_bReversed);
00059 current_remainder = ON_CRC32(current_remainder,sizeof(m_real_curve_domain),&m_real_curve_domain);
00060 current_remainder = ON_CRC32(current_remainder,sizeof(m_this_domain),&m_this_domain);
00061 return current_remainder;
00062 }
00063
00064 ON_CurveProxy& ON_CurveProxy::operator=( const ON_CurveProxy& src )
00065 {
00066 if ( this != &src )
00067 {
00068 ON_Curve::operator=(src);
00069 m_real_curve = src.m_real_curve;
00070 m_bReversed = src.m_bReversed;
00071 m_real_curve_domain = src.m_real_curve_domain;
00072 m_this_domain = src.m_this_domain;
00073 }
00074 return *this;
00075 }
00076
00077 ON_CurveProxy::~ON_CurveProxy()
00078 {
00079 m_real_curve = 0;
00080 }
00081
00082 double ON_CurveProxy::RealCurveParameter( double t ) const
00083 {
00084
00085 double s;
00086 if ( m_bReversed || m_real_curve_domain != m_this_domain )
00087 {
00088 s = m_this_domain.NormalizedParameterAt(t);
00089 if (m_bReversed)
00090 s = 1.0 - s;
00091 t = m_real_curve_domain.ParameterAt(s);
00092 }
00093 return t;
00094 }
00095
00096 double ON_CurveProxy::ThisCurveParameter( double real_curve_parameter ) const
00097 {
00098
00099 double s;
00100 double t = real_curve_parameter;
00101 if ( m_bReversed || m_real_curve_domain != m_this_domain )
00102 {
00103 s = m_real_curve_domain.NormalizedParameterAt(real_curve_parameter);
00104 if (m_bReversed)
00105 s = 1.0 - s;
00106 t = m_this_domain.ParameterAt(s);
00107 }
00108 return t;
00109 }
00110
00111 ON_Interval ON_CurveProxy::RealCurveInterval( const ON_Interval* sub_domain ) const
00112 {
00113 if ( !sub_domain )
00114 return m_real_curve_domain;
00115 ON_Interval d = m_this_domain;
00116 d.Intersection(*sub_domain);
00117 double t0 = RealCurveParameter( d[m_bReversed?1:0] );
00118 double t1 = RealCurveParameter( d[m_bReversed?0:1] );
00119 return ON_Interval(t0,t1);
00120 }
00121
00122
00123 bool ON_CurveProxy::ProxyCurveIsReversed() const
00124 {
00125 return m_bReversed;
00126 }
00127
00128 void ON_CurveProxy::SetProxyCurve( const ON_Curve* real_curve )
00129 {
00130
00131
00132 m_real_curve = 0;
00133
00134 if ( real_curve )
00135 SetProxyCurve( real_curve, real_curve->Domain() );
00136 else
00137 {
00138 DestroyCurveTree();
00139 m_real_curve_domain.Destroy();
00140 m_this_domain.Destroy();
00141 m_bReversed = false;
00142 }
00143 }
00144
00145 void ON_CurveProxy::SetProxyCurve( const ON_Curve* real_curve,
00146 ON_Interval real_curve_subdomain)
00147 {
00148 if ( real_curve != this )
00149 {
00150
00151
00152 m_real_curve = 0;
00153 DestroyCurveTree();
00154 m_real_curve_domain.Destroy();
00155 m_this_domain.Destroy();
00156 m_bReversed = false;
00157 }
00158 else
00159 {
00160
00161
00162
00163
00164 if ( IsValid() && m_this_domain.Includes(real_curve_subdomain) )
00165 {
00166 real_curve = m_real_curve;
00167
00168 double r0 = RealCurveParameter(real_curve_subdomain[0]);
00169 double r1 = RealCurveParameter(real_curve_subdomain[1]);
00170 real_curve_subdomain.Set(r0,r1);
00171 }
00172 else
00173 {
00174 real_curve = 0;
00175 }
00176
00177
00178
00179 m_real_curve = 0;
00180 DestroyCurveTree();
00181 }
00182
00183 m_real_curve = real_curve;
00184 if ( m_real_curve )
00185 {
00186 SetProxyCurveDomain( real_curve_subdomain );
00187 }
00188 else
00189 {
00190 m_real_curve_domain = real_curve_subdomain;
00191 }
00192 m_this_domain = m_real_curve_domain;
00193 }
00194
00195 const ON_Curve* ON_CurveProxy::ProxyCurve() const
00196 {
00197 return m_real_curve;
00198 }
00199
00200 bool ON_CurveProxy::SetProxyCurveDomain( ON_Interval proxy_curve_subdomain )
00201 {
00202 DestroyCurveTree();
00203 bool rc = proxy_curve_subdomain.IsIncreasing();
00204 if ( rc )
00205 {
00206 if ( m_real_curve )
00207 {
00208 ON_Interval cdom = m_real_curve->Domain();
00209 cdom.Intersection( proxy_curve_subdomain );
00210 rc = cdom.IsIncreasing();
00211 if (rc )
00212 m_real_curve_domain = cdom;
00213 }
00214 else
00215 {
00216 m_real_curve_domain = proxy_curve_subdomain;
00217 }
00218 }
00219 return rc;
00220 }
00221
00222 ON_Interval ON_CurveProxy::ProxyCurveDomain() const
00223 {
00224 return m_real_curve_domain;
00225 }
00226
00227 ON_Curve* ON_CurveProxy::DuplicateCurve() const
00228 {
00229
00230 ON_Curve* dup_crv = 0;
00231 if ( m_real_curve && m_real_curve != this )
00232 {
00233 dup_crv = m_real_curve->DuplicateCurve();
00234 if ( dup_crv )
00235 {
00236 dup_crv->Trim(m_real_curve_domain);
00237 if( m_bReversed )
00238 dup_crv->Reverse();
00239 dup_crv->SetDomain( m_this_domain );
00240 }
00241 }
00242 return dup_crv;
00243 }
00244
00245
00246 ON_BOOL32
00247 ON_CurveProxy::IsValid( ON_TextLog* text_log ) const
00248 {
00249 ON_BOOL32 rc = ( m_real_curve ) ? m_real_curve->IsValid(text_log) : false;
00250
00251 if ( rc && !m_real_curve_domain.IsIncreasing() )
00252 {
00253 rc = false;
00254 if ( text_log)
00255 text_log->Print("ON_CurveProxy.m_real_curve_domain is not increasing.\n");
00256 }
00257
00258 if ( rc && !m_real_curve->Domain().Includes( m_real_curve_domain ) )
00259 {
00260 rc = false;
00261 if ( text_log)
00262 text_log->Print("ON_CurveProxy.m_real_curve_domain is not included m_real_curve->Domain().\n");
00263 }
00264
00265 if ( rc && !m_this_domain.IsIncreasing() )
00266 {
00267 rc = false;
00268 if ( text_log)
00269 text_log->Print("ON_CurveProxy.m_this_domain is not increasing.\n");
00270 }
00271
00272 return rc;
00273 }
00274
00275 void
00276 ON_CurveProxy::Dump( ON_TextLog& dump ) const
00277 {
00278 dump.Print("ON_CurveProxy uses %x on [%g,%g]\n",m_real_curve,m_real_curve_domain[0],m_real_curve_domain[1]);
00279 }
00280
00281 ON_BOOL32
00282 ON_CurveProxy::Write(
00283 ON_BinaryArchive&
00284 ) const
00285 {
00286 return false;
00287 }
00288
00289 ON_BOOL32
00290 ON_CurveProxy::Read(
00291 ON_BinaryArchive&
00292 )
00293 {
00294 return false;
00295 }
00296
00297 int
00298 ON_CurveProxy::Dimension() const
00299 {
00300 return ( m_real_curve ) ? m_real_curve->Dimension() : 0;
00301 }
00302
00303 ON_BOOL32
00304 ON_CurveProxy::GetBBox(
00305 double* boxmin,
00306 double* boxmax,
00307 ON_BOOL32 bGrowBox
00308 ) const
00309 {
00310 return ( m_real_curve ) ? m_real_curve->GetBBox(boxmin,boxmax,bGrowBox) : false;
00311 }
00312
00313 ON_BOOL32
00314 ON_CurveProxy::Transform( const ON_Xform& )
00315 {
00316 return false;
00317 }
00318
00319 ON_Interval ON_CurveProxy::Domain() const
00320 {
00321 return m_this_domain;
00322 }
00323
00324 ON_BOOL32 ON_CurveProxy::SetDomain( double t0, double t1 )
00325 {
00326 ON_BOOL32 rc = false;
00327 if (t0 < t1)
00328 {
00329 DestroyCurveTree();
00330 m_this_domain.Set(t0, t1);
00331 rc = true;
00332 }
00333 return rc;
00334 }
00335
00336
00337 bool ON_CurveProxy::SetDomain( ON_Interval domain )
00338 {
00339 return SetDomain( domain[0], domain[1] ) ? true : false;
00340 }
00341
00342
00343 int ON_CurveProxy::SpanCount() const
00344 {
00345 if (!m_real_curve) return 0;
00346 int rsc = m_real_curve->SpanCount();
00347 ON_Interval domain = m_real_curve->Domain();
00348 if (m_real_curve_domain == domain)
00349 return rsc;
00350 double* rsv = (double*)onmalloc((rsc+1)*sizeof(double));
00351 if (!rsv) return 0;
00352 if (!m_real_curve->GetSpanVector(rsv)){
00353 onfree((void*)rsv);
00354 return 0;
00355 }
00356
00357 int i=0;
00358 int sc = 0;
00359
00360 while (i <= rsc && rsv[i] <= m_real_curve_domain[0]) i++;
00361 while (i <= rsc && rsv[i] < m_real_curve_domain[1]){
00362 sc++;
00363 i++;
00364 }
00365 sc++;
00366 onfree((void*)rsv);
00367
00368 return sc;
00369 }
00370
00371
00372
00373 ON_BOOL32 ON_CurveProxy::GetSpanVector( double* d ) const
00374 {
00375
00376 #if 0
00377 ON_BOOL32 rc = m_real_curve ? m_real_curve->GetSpanVector(d) : false;
00378 if (rc && (m_bReversed || m_this_domain != m_real_curve_domain) )
00379 {
00380 double x;
00381 int i, j, count = SpanCount();
00382 for ( i = 0; i <= count; i++ )
00383 {
00384 x = m_real_curve_domain.NormalizedParameterAt(d[i]);
00385 d[i] = x;
00386 }
00387 if ( m_bReversed )
00388 {
00389 for ( i = 0, j = count; i <= j; i++, j-- )
00390 {
00391 x = d[i];
00392 d[i] = 1.0-d[j];
00393 d[j] = 1.0-x;
00394 }
00395 }
00396 for ( i = 0; i <= count; i++ )
00397 {
00398 d[i] = m_this_domain.ParameterAt(d[i]);
00399 }
00400 }
00401 return rc;
00402 #endif
00403
00404 if (!m_real_curve) return false;
00405 int rsc = m_real_curve->SpanCount();
00406 if (rsc < 1) return false;
00407 double* rsv = (double*)onmalloc((rsc+1)*sizeof(double));
00408 if (!rsv || !m_real_curve->GetSpanVector(rsv)) return false;
00409 ON_Interval domain = m_real_curve->Domain();
00410
00411 if (m_real_curve_domain == m_this_domain && m_real_curve_domain == domain){
00412 int i;
00413 for (i=0; i <= rsc; i++) d[i] = rsv[i];
00414 onfree((void*)rsv);
00415 return true;
00416 }
00417
00418 if (m_real_curve_domain[1] <= domain[0] || m_real_curve_domain[0] >= domain[1]){
00419 onfree((void*)rsv);
00420 return false;
00421 }
00422
00423 int i=0;
00424 int sc = 0;
00425 d[0] = m_real_curve_domain[0];
00426
00427 while (i<= rsc && rsv[i] <= d[0]) i++;
00428 while (i <= rsc && rsv[i] < m_real_curve_domain[1]){
00429 sc++;
00430 d[sc] = rsv[i];
00431 i++;
00432 }
00433 sc++;
00434 d[sc] = m_real_curve_domain[1];
00435
00436 onfree((void*)rsv);
00437
00438 if (m_bReversed || m_real_curve_domain != m_this_domain){
00439 double x;
00440 int j;
00441 for ( i = 0; i <= sc; i++ )
00442 {
00443 x = m_real_curve_domain.NormalizedParameterAt(d[i]);
00444 d[i] = x;
00445 }
00446 if ( m_bReversed )
00447 {
00448 for ( i = 0, j = sc; i <= j; i++, j-- )
00449 {
00450 x = d[i];
00451 d[i] = 1.0-d[j];
00452 d[j] = 1.0-x;
00453 }
00454 }
00455 for ( i = 0; i <= sc; i++ )
00456 {
00457 d[i] = m_this_domain.ParameterAt(d[i]);
00458 }
00459 }
00460
00461 return true;
00462 }
00463
00464 int ON_CurveProxy::Degree() const
00465 {
00466 return m_real_curve ? m_real_curve->Degree() : 0;
00467 }
00468
00469 ON_BOOL32
00470 ON_CurveProxy::GetParameterTolerance(
00471 double t,
00472 double* tminus,
00473 double* tplus
00474 ) const
00475 {
00476 ON_BOOL32 rc = ( m_real_curve )
00477 ? m_real_curve->GetParameterTolerance( RealCurveParameter(t),tminus,tplus)
00478 : false;
00479 if (rc)
00480 {
00481 if ( tminus )
00482 *tminus = ThisCurveParameter(*tminus);
00483 if ( tplus )
00484 *tplus = ThisCurveParameter(*tplus);
00485 }
00486 return rc;
00487 }
00488
00489
00490 ON_BOOL32
00491 ON_CurveProxy::IsLinear(
00492 double tolerance
00493 ) const
00494 {
00495
00496
00497
00498 bool rc = false;
00499 if ( 0 != m_real_curve )
00500 {
00501 ON_Interval cdom = m_real_curve->Domain();
00502 if ( cdom == m_real_curve_domain )
00503 {
00504 rc = m_real_curve->IsLinear(tolerance) ? true : false;
00505 }
00506 else
00507 {
00508
00509
00510
00511
00512
00513 ON_Curve* temp_curve = ON_CurveProxy::DuplicateCurve();
00514 if ( 0 != temp_curve )
00515 {
00516 rc = temp_curve->IsLinear(tolerance) ? true : false;
00517 delete temp_curve;
00518 }
00519 }
00520 }
00521 return rc;
00522 }
00523
00524 int ON_CurveProxy::IsPolyline(
00525 ON_SimpleArray<ON_3dPoint>* pline_points,
00526 ON_SimpleArray<double>* pline_t
00527 ) const
00528 {
00529 ON_SimpleArray<double> tmp_t;
00530
00531 if ( pline_points )
00532 pline_points->SetCount(0);
00533 if ( pline_t )
00534 pline_t->SetCount(0);
00535 if ( !m_real_curve_domain.IsIncreasing() )
00536 return 0;
00537 if ( !m_real_curve )
00538 return 0;
00539 const ON_Interval cdom = m_real_curve->Domain();
00540 if ( !cdom.Includes(m_real_curve_domain) )
00541 return 0;
00542
00543
00544 int rc = 0;
00545 if ( m_real_curve_domain == cdom )
00546 {
00547
00548 rc = m_real_curve->IsPolyline(pline_points,pline_t);
00549 if ( rc < 2 )
00550 rc = 0;
00551
00552 if ( pline_points && pline_points->Count() != rc)
00553 {
00554
00555
00556 pline_points->SetCount(0);
00557 if ( pline_t )
00558 pline_t->SetCount(0);
00559 rc = 0;
00560 }
00561
00562 if ( pline_t && pline_t->Count() != rc)
00563 {
00564
00565
00566 pline_t->SetCount(0);
00567 if ( pline_points )
00568 pline_points->SetCount(0);
00569 rc = 0;
00570 }
00571
00572 if ( rc )
00573 {
00574 if ( m_bReversed )
00575 {
00576 if ( pline_points )
00577 pline_points->Reverse();
00578 if ( pline_t )
00579 pline_t->Reverse();
00580 }
00581
00582 if ( pline_points && IsClosed() && pline_points->Count() > 3 )
00583 {
00584
00585
00586
00587
00588 *pline_points->Last() = *pline_points->First();
00589 }
00590
00591 if ( pline_t && (m_bReversed || m_real_curve_domain != m_this_domain) )
00592 {
00593 int i;
00594 for ( i = 0; i < rc; i++ )
00595 {
00596 (*pline_t)[i] = ThisCurveParameter( (*pline_t)[i] );
00597 }
00598 }
00599 }
00600 }
00601 else
00602 {
00603
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 ON_Curve* temp_curve = ON_CurveProxy::DuplicateCurve();
00617 if ( temp_curve )
00618 {
00619 rc = temp_curve->IsPolyline(pline_points,pline_t);
00620 delete temp_curve;
00621 }
00622 }
00623
00624 return rc;
00625 }
00626
00627
00628
00629 ON_BOOL32
00630 ON_CurveProxy::IsArc(
00631 const ON_Plane* plane,
00632 ON_Arc* arc,
00633
00634 double tolerance
00635 ) const
00636 {
00637 ON_BOOL32 rc = false;
00638 const ON_Interval cdom = m_real_curve->Domain();
00639 if ( cdom == m_real_curve_domain )
00640 {
00641 rc = m_real_curve->IsArc(plane,arc,tolerance) ? true : false;
00642 if ( rc && arc && m_bReversed )
00643 arc->Reverse();
00644 }
00645 else
00646 {
00647
00648
00649
00650
00651
00652 ON_Curve* temp_curve = ON_CurveProxy::DuplicateCurve();
00653 if ( 0 != temp_curve )
00654 {
00655 rc = temp_curve->IsArc(plane,arc,tolerance) ? true : false;
00656 delete temp_curve;
00657 }
00658 }
00659 return rc;
00660 }
00661
00662 ON_BOOL32
00663 ON_CurveProxy::IsPlanar(
00664 ON_Plane* plane,
00665
00666 double tolerance
00667 ) const
00668 {
00669 return ( m_real_curve ) ? m_real_curve->IsPlanar(plane,tolerance) : false;
00670 }
00671
00672 ON_BOOL32
00673 ON_CurveProxy::IsInPlane(
00674 const ON_Plane& plane,
00675 double tolerance
00676 ) const
00677 {
00678 return ( m_real_curve ) ? m_real_curve->IsInPlane(plane,tolerance) : false;
00679 }
00680
00681 ON_BOOL32
00682 ON_CurveProxy::IsClosed() const
00683 {
00684 ON_BOOL32 rc = false;
00685 if ( m_real_curve && m_real_curve->Domain() == m_real_curve_domain )
00686 {
00687 rc = m_real_curve->IsClosed();
00688 }
00689 return rc;
00690 }
00691
00692 ON_BOOL32
00693 ON_CurveProxy::IsPeriodic() const
00694 {
00695 ON_BOOL32 rc = false;
00696 if ( m_real_curve && m_real_curve->Domain() == m_real_curve_domain )
00697 {
00698 rc = m_real_curve->IsPeriodic();
00699 }
00700 return rc;
00701 }
00702
00703 bool ON_CurveProxy::GetNextDiscontinuity(
00704 ON::continuity c,
00705 double t0,
00706 double t1,
00707 double* t,
00708 int* hint,
00709 int* dtype,
00710 double cos_angle_tolerance,
00711 double curvature_tolerance
00712 ) const
00713 {
00714 bool rc = false;
00715 if ( 0 != dtype )
00716 *dtype = 0;
00717
00718 if ( 0 != m_real_curve )
00719 {
00720 double s;
00721
00722
00723 double s0 = RealCurveParameter( t0 );
00724 double s1 = RealCurveParameter( t1 );
00725
00726
00727
00728
00729
00730
00731
00732
00733
00734
00735
00736
00737
00738
00739 ON::continuity parametric_c = ON::ParametricContinuity(c);
00740
00741 int realcrv_dtype = 0;
00742 bool realcrv_rc = m_real_curve->GetNextDiscontinuity(parametric_c,s0,s1,&s,hint,&realcrv_dtype,cos_angle_tolerance,curvature_tolerance);
00743
00744 if ( realcrv_rc )
00745 {
00746 double thiscrv_t = ThisCurveParameter(s);
00747 if ( !(t0 < thiscrv_t && thiscrv_t < t1) && !(t1 < thiscrv_t && thiscrv_t < t0) )
00748 {
00749 realcrv_rc = false;
00750 realcrv_dtype = 0;
00751
00752
00753 double s2 = ON_SQRT_EPSILON*s1 + (1.0 - ON_SQRT_EPSILON)*s0;
00754 if ( (s0 < s2 && s2 < s1) || (s1 < s2 && s2 < s0) )
00755 {
00756 realcrv_rc = m_real_curve->GetNextDiscontinuity(parametric_c,s2,s1,&s,hint,&realcrv_dtype,cos_angle_tolerance,curvature_tolerance);
00757 if ( realcrv_rc )
00758 thiscrv_t = ThisCurveParameter(s);
00759 }
00760 }
00761 if ( realcrv_rc )
00762 {
00763 if ( (t0 < thiscrv_t && thiscrv_t < t1) || (t1 < thiscrv_t && thiscrv_t < t0) )
00764 {
00765 *t = thiscrv_t;
00766 if ( dtype )
00767 *dtype = realcrv_dtype;
00768 rc = true;
00769 }
00770 }
00771 }
00772
00773 if ( !rc && parametric_c != c )
00774 {
00775
00776
00777 rc = ON_Curve::GetNextDiscontinuity( c, t0, t1, t, hint, dtype, cos_angle_tolerance, curvature_tolerance );
00778 }
00779 }
00780
00781 return rc;
00782 }
00783
00784
00785 bool ON_CurveProxy::IsContinuous(
00786 ON::continuity desired_continuity,
00787 double t,
00788 int* hint,
00789 double point_tolerance,
00790 double d1_tolerance,
00791 double d2_tolerance,
00792 double cos_angle_tolerance,
00793 double curvature_tolerance
00794 ) const
00795 {
00796 bool rc = true;
00797 if ( m_real_curve )
00798 {
00799 if ( m_real_curve_domain != m_real_curve->Domain() )
00800 {
00801
00802
00803
00804 switch(desired_continuity)
00805 {
00806 case ON::unknown_continuity:
00807 case ON::C0_continuous:
00808 case ON::C1_continuous:
00809 case ON::C2_continuous:
00810 case ON::G1_continuous:
00811 case ON::G2_continuous:
00812 case ON::Cinfinity_continuous:
00813 case ON::Gsmooth_continuous:
00814 break;
00815
00816 case ON::C0_locus_continuous:
00817 case ON::C1_locus_continuous:
00818 case ON::C2_locus_continuous:
00819 case ON::G1_locus_continuous:
00820 case ON::G2_locus_continuous:
00821 if ( t >= Domain()[1] )
00822 {
00823
00824
00825
00826 rc = false;
00827 }
00828 else
00829 {
00830
00831 desired_continuity = ON::ParametricContinuity(desired_continuity);
00832 }
00833 break;
00834 }
00835 }
00836 if (rc)
00837 rc = m_real_curve->IsContinuous( desired_continuity,
00838 RealCurveParameter(t), hint,
00839 point_tolerance, d1_tolerance, d2_tolerance,
00840 cos_angle_tolerance, curvature_tolerance );
00841 }
00842 return rc;
00843 }
00844
00845
00846 ON_BOOL32
00847 ON_CurveProxy::Reverse()
00848 {
00849 if ( m_this_domain.IsIncreasing() )
00850 {
00851 m_bReversed = (m_bReversed) ? false : true;
00852 DestroyCurveTree();
00853 m_this_domain.Reverse();
00854 }
00855 return true;
00856 }
00857
00858 ON_BOOL32
00859 ON_CurveProxy::Evaluate(
00860 double t,
00861 int der_count,
00862 int v_stride,
00863 double* v,
00864 int side,
00865
00866
00867
00868 int* hint
00869
00870 ) const
00871 {
00872
00873
00874
00875
00876 double normt = m_this_domain.NormalizedParameterAt(t);
00877 if( fabs( normt )<ON_ZERO_TOLERANCE)
00878 side = (abs(side) <= 1) ? 1 : 2;
00879 else if( fabs(1.0 - normt)<ON_ZERO_TOLERANCE)
00880 side = (abs(side) <= 1) ? -1 : -2;
00881
00882 if ( 0 != side )
00883 {
00884 if ( m_bReversed )
00885 {
00886 side = -side;
00887 }
00888 if (m_bReversed || m_real_curve_domain != m_this_domain )
00889 {
00890
00891
00892
00893
00894
00895 if ( -1 == side )
00896 side = -2;
00897 else if ( 1 == side )
00898 side = 2;
00899 }
00900 }
00901
00902 double r = RealCurveParameter(t);
00903 ON_BOOL32 rc = ( m_real_curve )
00904 ? m_real_curve->Evaluate( r,der_count,v_stride,v,side,hint)
00905 : false;
00906 if ( rc && m_bReversed )
00907 {
00908
00909 const int dim = m_real_curve->Dimension();
00910 int di, i;
00911 for ( di = 1; di <= der_count; di+=2 )
00912 {
00913 v += v_stride;
00914 for ( i = 0; i < dim; i++ )
00915 {
00916 v[i] = -v[i];
00917 }
00918 v += v_stride;
00919 }
00920 }
00921 return rc;
00922 }
00923
00924 ON_BOOL32 ON_CurveProxy::Trim(
00925 const ON_Interval& domain
00926 )
00927 {
00928 bool rc = false;
00929 if ( m_this_domain.IsIncreasing() && m_real_curve_domain.IsIncreasing() )
00930 {
00931 ON_Interval trim_dom = m_this_domain;
00932 trim_dom.Intersection(domain);
00933 if ( trim_dom.IsIncreasing() )
00934 {
00935 ON_Interval real_dom = RealCurveInterval( &trim_dom );
00936 if ( real_dom.IsIncreasing() )
00937 {
00938 DestroyCurveTree();
00939 m_real_curve_domain = real_dom;
00940 m_this_domain = trim_dom;
00941 rc = true;
00942 }
00943 }
00944 }
00945 return rc;
00946 }
00947
00948
00949
00950 ON_BOOL32 ON_CurveProxy::Split(
00951 double t,
00952 ON_Curve*& left_side,
00953 ON_Curve*& right_side
00954 ) const
00955 {
00956 ON_BOOL32 rc = false;
00957 if ( m_this_domain.IsIncreasing() && m_real_curve_domain.IsIncreasing() && m_this_domain.Includes(t,true) )
00958 {
00959 double crv_t = RealCurveParameter(t);
00960 if ( m_real_curve_domain.Includes(crv_t,true) )
00961 {
00962 ON_CurveProxy* left_proxy = 0;
00963 ON_CurveProxy* right_proxy = 0;
00964 if ( left_side )
00965 {
00966 left_proxy = ON_CurveProxy::Cast(left_side);
00967 if ( !left_proxy )
00968 return false;
00969 }
00970 if ( right_side )
00971 {
00972 right_proxy = ON_CurveProxy::Cast(right_side);
00973 if ( !right_proxy )
00974 return false;
00975 if ( right_side == left_side )
00976 return false;
00977 }
00978
00979 bool bRev = m_bReversed;
00980
00981 ON_Interval left_real_dom, right_real_dom;
00982 if ( bRev )
00983 {
00984 left_real_dom.Set(crv_t,m_real_curve_domain[1]);
00985 right_real_dom.Set(m_real_curve_domain[0],crv_t);
00986 }
00987 else
00988 {
00989 left_real_dom.Set(m_real_curve_domain[0],crv_t);
00990 right_real_dom.Set(crv_t,m_real_curve_domain[1]);
00991 }
00992
00993 ON_Interval left_this_dom(m_this_domain[0],t);
00994 ON_Interval right_this_dom(t,m_this_domain[1]);
00995
00996 if ( left_real_dom.IsIncreasing()
00997 && right_real_dom.IsIncreasing()
00998 && left_this_dom.IsIncreasing()
00999 && right_this_dom.IsIncreasing()
01000 )
01001 {
01002
01003 const ON_Curve* real_crv = m_real_curve;
01004 if ( real_crv )
01005 {
01006 ON_Interval d = real_crv->Domain();
01007 if ( !d.Includes(left_real_dom) )
01008 return false;
01009 if ( !d.Includes(right_real_dom) )
01010 return false;
01011 }
01012
01013 if ( !left_proxy )
01014 left_proxy = new ON_CurveProxy();
01015 if ( !right_proxy )
01016 right_proxy = new ON_CurveProxy();
01017
01018 left_proxy->SetProxyCurve( real_crv, left_real_dom );
01019 right_proxy->SetProxyCurve( real_crv, right_real_dom );
01020
01021 if ( bRev )
01022 {
01023 left_proxy->Reverse();
01024 right_proxy->Reverse();
01025 }
01026
01027 left_proxy->SetDomain(left_this_dom[0],left_this_dom[1]);
01028 right_proxy->SetDomain(right_this_dom[0],right_this_dom[1]);
01029
01030 if (!left_side) left_side = left_proxy;
01031 if (!right_side) right_side = right_proxy;
01032
01033 rc = true;
01034 }
01035 }
01036 }
01037 return rc;
01038 }
01039
01040 int
01041 ON_CurveProxy::GetNurbForm(
01042
01043
01044
01045
01046
01047
01048
01049
01050
01051 ON_NurbsCurve& nurbs,
01052 double tolerance,
01053 const ON_Interval* sub_domain
01054 ) const
01055 {
01056 ON_BOOL32 rc = false;
01057 if ( m_real_curve )
01058 {
01059 ON_Interval scratch_domain = RealCurveInterval( sub_domain );
01060 rc = m_real_curve->GetNurbForm(nurbs,tolerance,&scratch_domain);
01061 if ( rc )
01062 {
01063 if ( m_bReversed )
01064 nurbs.Reverse();
01065 ON_Interval d = m_this_domain;
01066 if ( sub_domain )
01067 d.Intersection( *sub_domain );
01068 nurbs.SetDomain( d[0], d[1] );
01069
01070 if ( nurbs.m_dim <= 3 && nurbs.m_dim >= 1 )
01071 {
01072 double t0 = Domain()[0];
01073 double t1 = Domain()[1];
01074 if ( 0 != sub_domain )
01075 {
01076 if ( t0 < sub_domain->Min() )
01077 t0 = sub_domain->Min();
01078 if ( sub_domain->Max() < t1 )
01079 t1 = sub_domain->Max();
01080 }
01081
01082 ON_3dPoint P0 = PointAt(t0);
01083 ON_3dPoint P1 = PointAt(t1);
01084 ON_3dPoint N0 = nurbs.PointAtStart();
01085 ON_3dPoint N1 = nurbs.PointAtEnd();
01086
01087
01088
01089
01090 ON_BOOL32 clamped = nurbs.IsClamped(2);
01091 if ( clamped && (P0 != N0 || P1 != N1) )
01092 {
01093 if ( 0==nurbs.m_is_rat )
01094 {
01095 nurbs.SetCV(0,P0);
01096 nurbs.SetCV(nurbs.m_cv_count-1,P1);
01097 }
01098 else
01099 {
01100 ON_4dPoint H0, H1;
01101 H0 = P0;
01102 H0.w = nurbs.Weight(0);
01103 H0.x *= H0.w;
01104 H0.y *= H0.w;
01105 H0.z *= H0.w;
01106 nurbs.SetCV(0,H0);
01107
01108 H1 = P1;
01109 H1.w = nurbs.Weight(nurbs.m_cv_count-1);
01110 H1.x *= H1.w;
01111 H1.y *= H1.w;
01112 H1.z *= H1.w;
01113 nurbs.SetCV(nurbs.m_cv_count-1,H1);
01114 }
01115 }
01116 }
01117 }
01118 }
01119 return rc;
01120 }
01121
01122 int
01123 ON_CurveProxy::HasNurbForm(
01124
01125
01126
01127
01128
01129
01130
01131
01132
01133 ) const
01134
01135 {
01136 if (!m_real_curve)
01137 return 0;
01138 return m_real_curve->HasNurbForm();
01139 }
01140
01141 ON_BOOL32 ON_CurveProxy::GetCurveParameterFromNurbFormParameter(
01142 double nurbs_t,
01143 double* curve_t
01144 ) const
01145 {
01146 ON_BOOL32 rc = false;
01147 if ( m_real_curve )
01148 {
01149
01150
01151
01152 const ON_Curve* real_crv = m_real_curve;
01153
01154 ON_Curve* tmp_real_crv = 0;
01155 if ( m_real_curve_domain != m_real_curve->Domain() )
01156 {
01157 const ON_ArcCurve* arc_curve = ON_ArcCurve::Cast(m_real_curve);
01158 if ( 0 != arc_curve )
01159 {
01160 tmp_real_crv = arc_curve->DuplicateCurve();
01161 if ( 0 != tmp_real_crv )
01162 {
01163 if ( tmp_real_crv->Trim(m_real_curve_domain) )
01164 {
01165 real_crv = tmp_real_crv;
01166 }
01167 }
01168 }
01169 }
01170
01171 rc = real_crv->GetCurveParameterFromNurbFormParameter( RealCurveParameter(nurbs_t),curve_t);
01172 if ( rc )
01173 *curve_t = ThisCurveParameter(*curve_t);
01174
01175 if ( 0 != tmp_real_crv )
01176 delete tmp_real_crv;
01177 }
01178 return rc;
01179 }
01180
01181 ON_BOOL32 ON_CurveProxy::GetNurbFormParameterFromCurveParameter(
01182 double curve_t,
01183 double* nurbs_t
01184 ) const
01185 {
01186 ON_BOOL32 rc = false;
01187 if ( m_real_curve )
01188 {
01189
01190
01191
01192 const ON_Curve* real_crv = m_real_curve;
01193
01194 ON_Curve* tmp_real_crv = 0;
01195 if ( m_real_curve_domain != m_real_curve->Domain() )
01196 {
01197 const ON_ArcCurve* arc_curve = ON_ArcCurve::Cast(m_real_curve);
01198 if ( 0 != arc_curve )
01199 {
01200 tmp_real_crv = arc_curve->DuplicateCurve();
01201 if ( 0 != tmp_real_crv )
01202 {
01203 if ( tmp_real_crv->Trim(m_real_curve_domain) )
01204 {
01205 real_crv = tmp_real_crv;
01206 }
01207 }
01208 }
01209 }
01210
01211 rc = real_crv->GetNurbFormParameterFromCurveParameter( RealCurveParameter(curve_t),nurbs_t);
01212 if ( rc )
01213 *nurbs_t = ThisCurveParameter(*nurbs_t);
01214
01215 if ( 0 != tmp_real_crv )
01216 delete tmp_real_crv;
01217 }
01218 return rc;
01219 }