Changeset View
Changeset View
Standalone View
Standalone View
extern/opennurbs/opennurbs_surfaceproxy.cpp
- This file was added.
| /* $NoKeywords: $ */ | |||||
| /* | |||||
| // | |||||
| // Copyright (c) 1993-2012 Robert McNeel & Associates. All rights reserved. | |||||
| // OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert | |||||
| // McNeel & Associates. | |||||
| // | |||||
| // THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY. | |||||
| // ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF | |||||
| // MERCHANTABILITY ARE HEREBY DISCLAIMED. | |||||
| // | |||||
| // For complete openNURBS copyright information see <http://www.opennurbs.org>. | |||||
| // | |||||
| //////////////////////////////////////////////////////////////// | |||||
| */ | |||||
| #include "opennurbs.h" | |||||
| #if !defined(ON_COMPILING_OPENNURBS) | |||||
| // This check is included in all opennurbs source .c and .cpp files to insure | |||||
| // ON_COMPILING_OPENNURBS is defined when opennurbs source is compiled. | |||||
| // When opennurbs source is being compiled, ON_COMPILING_OPENNURBS is defined | |||||
| // and the opennurbs .h files alter what is declared and how it is declared. | |||||
| #error ON_COMPILING_OPENNURBS must be defined when compiling opennurbs | |||||
| #endif | |||||
| ON_OBJECT_IMPLEMENT(ON_SurfaceProxy,ON_Surface,"4ED7D4E2-E947-11d3-BFE5-0010830122F0"); | |||||
| ON_SurfaceProxy::ON_SurfaceProxy() : m_surface(0), m_bTransposed(0) | |||||
| {} | |||||
| ON_SurfaceProxy::ON_SurfaceProxy( const ON_Surface* s ) : m_surface(s), m_bTransposed(0) | |||||
| {} | |||||
| ON_SurfaceProxy::ON_SurfaceProxy( const ON_SurfaceProxy& src ) : ON_Surface(src), m_surface(0), m_bTransposed(0) | |||||
| { | |||||
| *this = src; | |||||
| } | |||||
| unsigned int ON_SurfaceProxy::SizeOf() const | |||||
| { | |||||
| unsigned int sz = ON_Surface::SizeOf(); | |||||
| sz += (sizeof(*this) - sizeof(ON_Surface)); | |||||
| // Do not add in size of m_surface - its memory is not | |||||
| // managed by this class. | |||||
| return sz; | |||||
| } | |||||
| ON__UINT32 ON_SurfaceProxy::DataCRC(ON__UINT32 current_remainder) const | |||||
| { | |||||
| if ( m_surface ) | |||||
| current_remainder = m_surface->DataCRC(current_remainder); | |||||
| current_remainder = ON_CRC32(current_remainder,sizeof(m_bTransposed),&m_bTransposed); | |||||
| return current_remainder; | |||||
| } | |||||
| ON_SurfaceProxy& ON_SurfaceProxy::operator=( const ON_SurfaceProxy& src ) | |||||
| { | |||||
| if ( this != &src ) { | |||||
| ON_Surface::operator=(src); | |||||
| m_surface = src.m_surface; | |||||
| m_bTransposed = src.m_bTransposed; | |||||
| } | |||||
| return *this; | |||||
| } | |||||
| ON_SurfaceProxy::~ON_SurfaceProxy() | |||||
| { | |||||
| m_surface = 0; | |||||
| } | |||||
| void ON_SurfaceProxy::SetProxySurface( const ON_Surface* proxy_surface ) | |||||
| { | |||||
| // setting m_surface=0 prevents crashes if user has deleted | |||||
| // "real" surface before calling SetProxySurface(). | |||||
| m_surface = 0; | |||||
| DestroySurfaceTree(); | |||||
| if ( proxy_surface == this ) | |||||
| proxy_surface = 0; | |||||
| m_surface = proxy_surface; | |||||
| m_bTransposed = false; | |||||
| } | |||||
| const ON_Surface* ON_SurfaceProxy::ProxySurface() const | |||||
| { | |||||
| return m_surface; | |||||
| } | |||||
| bool ON_SurfaceProxy::ProxySurfaceIsTransposed() const | |||||
| { | |||||
| return m_bTransposed; | |||||
| } | |||||
| ON_Surface* ON_SurfaceProxy::DuplicateSurface() const | |||||
| { | |||||
| ON_Surface* dup_srf = 0; | |||||
| if ( m_surface ) | |||||
| { | |||||
| dup_srf = m_surface->Duplicate(); | |||||
| if ( m_bTransposed && dup_srf ) | |||||
| dup_srf->Transpose(); | |||||
| } | |||||
| return dup_srf; | |||||
| } | |||||
| bool ON_SurfaceProxy::IsValid( ON_TextLog* text_log ) const | |||||
| { | |||||
| return ( m_surface ) ? m_surface->IsValid(text_log) : false; | |||||
| } | |||||
| void | |||||
| ON_SurfaceProxy::Dump( ON_TextLog& dump ) const | |||||
| { | |||||
| dump.Print("ON_SurfaceProxy uses %x\n",m_surface); | |||||
| if (m_surface ) | |||||
| m_surface->Dump(dump); | |||||
| } | |||||
| bool | |||||
| ON_SurfaceProxy::Write( | |||||
| ON_BinaryArchive& // open binary file | |||||
| ) const | |||||
| { | |||||
| return false; | |||||
| } | |||||
| bool | |||||
| ON_SurfaceProxy::Read( | |||||
| ON_BinaryArchive& // open binary file | |||||
| ) | |||||
| { | |||||
| return false; | |||||
| } | |||||
| int | |||||
| ON_SurfaceProxy::Dimension() const | |||||
| { | |||||
| return ( m_surface ) ? m_surface->Dimension() : 0; | |||||
| } | |||||
| bool ON_SurfaceProxy::GetBBox( // returns true if successful | |||||
| double* boxmin, // minimum | |||||
| double* boxmax, // maximum | |||||
| bool bGrowBox | |||||
| ) const | |||||
| { | |||||
| return ( m_surface ) ? m_surface->GetBBox(boxmin,boxmax,bGrowBox) : false; | |||||
| } | |||||
| bool | |||||
| ON_SurfaceProxy::Transform( | |||||
| const ON_Xform& // xform - formal parameter intentionally ignored in this virtual function | |||||
| ) | |||||
| { | |||||
| return false; // cannot modify m_surface | |||||
| } | |||||
| ON_Interval | |||||
| ON_SurfaceProxy::Domain( int dir ) const | |||||
| { | |||||
| ON_Interval d; | |||||
| if ( m_bTransposed ) { | |||||
| dir = (dir) ? 0 : 1; | |||||
| } | |||||
| if ( m_surface ) | |||||
| d = m_surface->Domain(dir); | |||||
| return d; | |||||
| } | |||||
| bool ON_SurfaceProxy::GetSurfaceSize( | |||||
| double* width, | |||||
| double* height | |||||
| ) const | |||||
| { | |||||
| bool rc = false; | |||||
| if ( m_surface ) | |||||
| { | |||||
| if ( m_bTransposed ) | |||||
| { | |||||
| double* ptr = width; | |||||
| width = height; | |||||
| height = ptr; | |||||
| } | |||||
| rc = m_surface->GetSurfaceSize(width,height); | |||||
| } | |||||
| else | |||||
| { | |||||
| if ( width ) | |||||
| *width = 0.0; | |||||
| if ( height ) | |||||
| *height = 0.0; | |||||
| } | |||||
| return rc; | |||||
| } | |||||
| int | |||||
| ON_SurfaceProxy::SpanCount( int dir ) const | |||||
| { | |||||
| if ( m_bTransposed ) { | |||||
| dir = (dir) ? 0 : 1; | |||||
| } | |||||
| return ( m_surface ) ? m_surface->SpanCount(dir) : false; | |||||
| } | |||||
| bool | |||||
| ON_SurfaceProxy::GetSpanVector( int dir, double* s ) const | |||||
| { | |||||
| if ( m_bTransposed ) { | |||||
| dir = (dir) ? 0 : 1; | |||||
| } | |||||
| return ( m_surface ) ? m_surface->GetSpanVector(dir,s) : false; | |||||
| } | |||||
| int | |||||
| ON_SurfaceProxy::Degree( int dir ) const | |||||
| { | |||||
| if ( m_bTransposed ) { | |||||
| dir = (dir) ? 0 : 1; | |||||
| } | |||||
| return ( m_surface ) ? m_surface->Degree(dir) : false; | |||||
| } | |||||
| bool | |||||
| ON_SurfaceProxy::GetParameterTolerance( | |||||
| int dir, | |||||
| double t, // t = parameter in domain | |||||
| double* tminus, // tminus | |||||
| double* tplus // tplus | |||||
| ) const | |||||
| { | |||||
| if ( m_bTransposed ) { | |||||
| dir = (dir) ? 0 : 1; | |||||
| } | |||||
| return ( m_surface ) ? m_surface->GetParameterTolerance(dir,t,tminus,tplus) : false; | |||||
| } | |||||
| bool | |||||
| ON_SurfaceProxy::IsClosed( int dir ) const | |||||
| { | |||||
| if ( m_bTransposed ) { | |||||
| dir = (dir) ? 0 : 1; | |||||
| } | |||||
| return ( m_surface ) ? m_surface->IsClosed( dir ) : false; | |||||
| } | |||||
| ON_Surface::ISO | |||||
| ON_SurfaceProxy::IsIsoparametric( // returns isoparametric status of 2d curve | |||||
| const ON_Curve& crv, | |||||
| const ON_Interval* subdomain | |||||
| ) const | |||||
| { | |||||
| // this is a virtual overide of an ON_Surface::IsIsoparametric | |||||
| const ON_Curve* pC = &crv; | |||||
| ON_Curve* pTranC = nullptr; | |||||
| if(m_bTransposed) | |||||
| { | |||||
| pTranC = crv.DuplicateCurve(); | |||||
| pTranC->SwapCoordinates(0,1); | |||||
| pC = pTranC; | |||||
| } | |||||
| ON_Surface::ISO iso = m_surface->IsIsoparametric( *pC, subdomain); | |||||
| if (pTranC) | |||||
| { | |||||
| switch(iso) | |||||
| { | |||||
| case x_iso: | |||||
| iso = y_iso; | |||||
| break; | |||||
| case y_iso: | |||||
| iso = x_iso; | |||||
| break; | |||||
| case W_iso: | |||||
| iso = S_iso; | |||||
| break; | |||||
| case S_iso: | |||||
| iso = W_iso; | |||||
| break; | |||||
| case N_iso: | |||||
| iso = E_iso; | |||||
| break; | |||||
| case E_iso: | |||||
| iso = N_iso; | |||||
| break; | |||||
| default: | |||||
| // intentionally ignoring other ON_Surface::ISO enum values | |||||
| break; | |||||
| } | |||||
| delete pTranC; | |||||
| } | |||||
| return iso; | |||||
| } | |||||
| ON_Surface::ISO | |||||
| ON_SurfaceProxy::IsIsoparametric( // returns isoparametric status based on bounding box | |||||
| const ON_BoundingBox& box | |||||
| ) const | |||||
| { | |||||
| // this is a virtual overide of an ON_Surface::IsIsoparametric | |||||
| const ON_BoundingBox* pbox = &box; | |||||
| ON_BoundingBox Tbox( ON_3dPoint( box.m_min[1],box.m_min[0],0.0), | |||||
| ON_3dPoint( box.m_max[1],box.m_max[0],0.0) ); | |||||
| if(m_bTransposed) | |||||
| pbox = &Tbox; | |||||
| ON_Surface::ISO iso = m_surface->IsIsoparametric( *pbox); | |||||
| if( m_bTransposed){ | |||||
| switch(iso) | |||||
| { | |||||
| case x_iso: | |||||
| iso = y_iso; | |||||
| break; | |||||
| case y_iso: | |||||
| iso = x_iso; | |||||
| break; | |||||
| case W_iso: | |||||
| iso = S_iso; | |||||
| break; | |||||
| case S_iso: | |||||
| iso = W_iso; | |||||
| break; | |||||
| case N_iso: | |||||
| iso = E_iso; | |||||
| break; | |||||
| case E_iso: | |||||
| iso = N_iso; | |||||
| break; | |||||
| default: | |||||
| // intentionally ignoring other ON_Surface::ISO enum values | |||||
| break; | |||||
| } | |||||
| } | |||||
| return iso; | |||||
| } | |||||
| bool ON_SurfaceProxy::IsPlanar( | |||||
| ON_Plane* plane, | |||||
| double tolerance | |||||
| ) const | |||||
| { | |||||
| bool rc = false; | |||||
| if ( m_surface ) | |||||
| { | |||||
| rc = m_surface->IsPlanar( plane, tolerance ); | |||||
| if (rc && m_bTransposed && plane ) | |||||
| plane->Flip(); | |||||
| } | |||||
| return rc; | |||||
| } | |||||
| bool | |||||
| ON_SurfaceProxy::IsPeriodic( int dir ) const | |||||
| { | |||||
| if ( m_bTransposed ) { | |||||
| dir = (dir) ? 0 : 1; | |||||
| } | |||||
| return ( m_surface ) ? m_surface->IsPeriodic( dir ) : false; | |||||
| } | |||||
| bool ON_SurfaceProxy::GetNextDiscontinuity( | |||||
| int dir, | |||||
| ON::continuity c, | |||||
| double t0, | |||||
| double t1, | |||||
| double* t, | |||||
| int* hint, | |||||
| int* dtype, | |||||
| double cos_angle_tolerance, | |||||
| double curvature_tolerance | |||||
| ) const | |||||
| { | |||||
| // untested code | |||||
| bool rc = false; | |||||
| if ( 0 != m_surface && dir >= 0 && dir <= 1 ) | |||||
| { | |||||
| rc = m_surface->GetNextDiscontinuity(m_bTransposed?1-dir:dir,c,t0,t1,t,hint,dtype,cos_angle_tolerance,curvature_tolerance); | |||||
| } | |||||
| return rc; | |||||
| } | |||||
| bool | |||||
| ON_SurfaceProxy::IsSingular( int side ) const | |||||
| { | |||||
| if ( m_bTransposed ) { | |||||
| switch(side) { | |||||
| case 0: | |||||
| side = 3; | |||||
| break; | |||||
| case 1: | |||||
| side = 2; | |||||
| break; | |||||
| case 2: | |||||
| side = 1; | |||||
| break; | |||||
| case 3: | |||||
| side = 0; | |||||
| break; | |||||
| } | |||||
| } | |||||
| return ( m_surface ) ? m_surface->IsSingular( side ) : false; | |||||
| } | |||||
| bool | |||||
| ON_SurfaceProxy::Reverse( | |||||
| int // dir - formal parameter intentionally ignored in this virtual function | |||||
| ) | |||||
| { | |||||
| return false; // cannot modify m_surface | |||||
| } | |||||
| bool | |||||
| ON_SurfaceProxy::Transpose() | |||||
| { | |||||
| DestroySurfaceTree(); | |||||
| m_bTransposed = (m_bTransposed) ? false : true; | |||||
| return true; | |||||
| } | |||||
| bool ON_SurfaceProxy::IsContinuous( | |||||
| ON::continuity desired_continuity, | |||||
| double s, | |||||
| double t, | |||||
| int* hint, // default = nullptr, | |||||
| double point_tolerance, // default=ON_ZERO_TOLERANCE | |||||
| double d1_tolerance, // default==ON_ZERO_TOLERANCE | |||||
| double d2_tolerance, // default==ON_ZERO_TOLERANCE | |||||
| double cos_angle_tolerance, // default==ON_DEFAULT_ANGLE_TOLERANCE_COSINE | |||||
| double curvature_tolerance // default==ON_SQRT_EPSILON | |||||
| ) const | |||||
| { | |||||
| bool rc = true; | |||||
| if ( m_surface ) | |||||
| { | |||||
| if ( m_bTransposed ) | |||||
| { | |||||
| double x = s; | |||||
| s = t; | |||||
| t = x; | |||||
| } | |||||
| rc = m_surface->IsContinuous( desired_continuity, s, t, hint, | |||||
| point_tolerance, d1_tolerance, d2_tolerance, | |||||
| cos_angle_tolerance, curvature_tolerance ); | |||||
| } | |||||
| return rc; | |||||
| } | |||||
| bool | |||||
| ON_SurfaceProxy::Evaluate( // returns false if unable to evaluate | |||||
| double s, double t, // evaluation parameters | |||||
| int der_count, // number of derivatives (>=0) | |||||
| int v_stride, // v[] array stride (>=Dimension()) | |||||
| double* v, // v[] array of length stride*(ndir+1) | |||||
| int side, // optional - determines which side to evaluate from | |||||
| // 0 = default | |||||
| // < 0 to evaluate from below, | |||||
| // > 0 to evaluate from above | |||||
| int* hint // optional - evaluation hint (int) used to speed | |||||
| // repeated evaluations | |||||
| ) const | |||||
| { | |||||
| if ( m_bTransposed ) { | |||||
| double x = s; s = t; t = x; | |||||
| } | |||||
| return ( m_surface ) ? m_surface->Evaluate(s,t,der_count,v_stride,v,side,hint) : false; | |||||
| } | |||||
| ON_Curve* ON_SurfaceProxy::IsoCurve( | |||||
| int dir, | |||||
| double c | |||||
| ) const | |||||
| { | |||||
| ON_Curve* isocurve = 0; | |||||
| if ( m_bTransposed ) | |||||
| { | |||||
| dir = 1-dir; | |||||
| } | |||||
| if ( 0 != m_surface && dir >= 0 && dir <= 1 ) | |||||
| { | |||||
| isocurve = m_surface->IsoCurve( dir, c ); | |||||
| } | |||||
| return isocurve; | |||||
| } | |||||
| int ON_SurfaceProxy::GetNurbForm( // returns 0: unable to create NURBS representation | |||||
| // with desired accuracy. | |||||
| // 1: success - returned NURBS parameterization | |||||
| // matches the surface's to wthe desired accuracy | |||||
| // 2: success - returned NURBS point locus matches | |||||
| // the surfaces's to the desired accuracy but, on | |||||
| // the interior of the surface's domain, the | |||||
| // surface's parameterization and the NURBS | |||||
| // parameterization may not match to the | |||||
| // desired accuracy. | |||||
| ON_NurbsSurface& nurbs, | |||||
| double tolerance | |||||
| ) const | |||||
| { | |||||
| int rc = ( m_surface ) ? m_surface->GetNurbForm(nurbs,tolerance) : 0; | |||||
| if ( rc && m_bTransposed ) { | |||||
| if (!nurbs.Transpose()) | |||||
| rc = 0; | |||||
| } | |||||
| return rc; | |||||
| } | |||||
| int | |||||
| ON_SurfaceProxy::HasNurbForm( // returns 0: unable to create NURBS representation | |||||
| // with desired accuracy. | |||||
| // 1: success - returned NURBS parameterization | |||||
| // matches the surface's to wthe desired accuracy | |||||
| // 2: success - returned NURBS point locus matches | |||||
| // the surfaces's to the desired accuracy but, on | |||||
| // the interior of the surface's domain, the | |||||
| // surface's parameterization and the NURBS | |||||
| // parameterization may not match to the | |||||
| // desired accuracy. | |||||
| ) const | |||||
| { | |||||
| if (!m_surface) | |||||
| return 0; | |||||
| return m_surface->HasNurbForm(); | |||||
| } | |||||
| bool ON_SurfaceProxy::GetSurfaceParameterFromNurbFormParameter( | |||||
| double nurbs_s, double nurbs_t, | |||||
| double* surface_s, double* surface_t | |||||
| ) const | |||||
| { | |||||
| bool rc = false; | |||||
| if ( m_surface ) | |||||
| { | |||||
| rc = m_bTransposed | |||||
| ? m_surface->GetSurfaceParameterFromNurbFormParameter(nurbs_t,nurbs_s,surface_t,surface_s) | |||||
| : m_surface->GetSurfaceParameterFromNurbFormParameter(nurbs_s,nurbs_t,surface_s,surface_t); | |||||
| } | |||||
| return rc; | |||||
| } | |||||
| bool ON_SurfaceProxy::GetNurbFormParameterFromSurfaceParameter( | |||||
| double surface_s, double surface_t, | |||||
| double* nurbs_s, double* nurbs_t | |||||
| ) const | |||||
| { | |||||
| bool rc = false; | |||||
| if ( m_surface ) | |||||
| { | |||||
| rc = m_bTransposed | |||||
| ? m_surface->GetNurbFormParameterFromSurfaceParameter(surface_t,surface_s,nurbs_t,nurbs_s) | |||||
| : m_surface->GetNurbFormParameterFromSurfaceParameter(surface_s,surface_t,nurbs_s,nurbs_t); | |||||
| } | |||||
| return rc; | |||||
| } | |||||