opennurbs_defines.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 // {EA2EFFD2-C9A9-4cb1-BE15-D2F46290F1A1}
00020 //const ON_UUID ON_MaterialRef::material_from_layer = 
00021 //{ 0xea2effd2, 0xc9a9, 0x4cb1, { 0xbe, 0x15, 0xd2, 0xf4, 0x62, 0x90, 0xf1, 0xa1 } };
00022 
00023 
00024 
00025 // {86EDFDE4-8AAF-4bcd-AB7C-F7111978D7FE}
00026 //const ON_UUID ON_MaterialRef::material_from_parent = 
00027 //{ 0x86edfde4, 0x8aaf, 0x4bcd, { 0xab, 0x7c, 0xf7, 0x11, 0x19, 0x78, 0xd7, 0xfe } };
00028 
00029 
00030 // on_stricmp() is a wrapper for case insensitive string compare
00031 // and calls one of _stricmp(), stricmp(), or strcasecmp()
00032 // depending on OS.
00033 int on_stricmp(const char * s1, const char * s2)
00034 {
00035 #if defined(ON_OS_WINDOWS)
00036   //return stricmp(s1,s2);
00037   return _stricmp(s1,s2);
00038 #else
00039   return strcasecmp(s1,s2);
00040 #endif
00041 }
00042 
00043 // on_strupr() calls _strupr() or strupr() depending on OS
00044 char* on_strupr(char* s)
00045 {
00046 #if defined(ON_OS_WINDOWS)
00047   return _strupr(s); // ANSI name
00048 #else
00049   if (s) {
00050     while (*s) {
00051       *s = toupper(*s);
00052       s++;
00053     }
00054   }
00055   return s;
00056 #endif
00057 }
00058 
00059 // on_strlwr() calls _strlwr() or strlwr() depending on OS
00060 char* on_strlwr(char* s)
00061 {
00062 #if defined(ON_OS_WINDOWS)
00063   return _strlwr(s); // ANSI name
00064 #else
00065   if (s) {
00066     while (*s) {
00067       *s = tolower(*s);
00068       s++;
00069     }
00070   }
00071   return s;
00072 #endif
00073 }
00074 
00075 // on_strrev() calls _strrev() or strrev() depending on OS
00076 char* on_strrev(char* s)
00077 {
00078 #if defined(ON_OS_WINDOWS)
00079   return _strrev(s); // ANSI name
00080 #else
00081   int i, j;
00082   char c;
00083   for ( i = 0, j = ((int)strlen(s))-1; i < j; i++, j-- ) {
00084     c = s[i];
00085     s[i] = s[j];
00086     s[j] = c;
00087   }
00088   return s;
00089 #endif
00090 }
00091 
00092 // Windows code page support 
00093 //   Only ON_SetStringConversionWindowsLocaleID,
00094 //   ON_GetStringConversionWindowsLocaleID, and 
00095 //   on_wcsicmp should look at g_s__windows_locale_id
00096 //   and g_s__windows_locale_os.
00097 static unsigned int g_s__windows_locale_id = 0;
00098 static unsigned int g_s__windows_locale_os = 0; // 0 = Win 95/98/ME...
00099                                               // 1 = Win NT/2000/XP...
00100 
00101 unsigned int ON_SetStringConversionWindowsLocaleID(unsigned int locale_id, ON_BOOL32 bWin9X)
00102 {
00103   unsigned int rc = g_s__windows_locale_id;
00104   g_s__windows_locale_os = bWin9X ? 0 : 1;
00105   g_s__windows_locale_id = locale_id?true:false;
00106   return rc;
00107 }
00108 
00109 unsigned int ON_GetStringConversionWindowsLocaleID()
00110 {
00111   return g_s__windows_locale_id;
00112 }
00113 
00114 
00115 static int on__hack__tolower(int c)
00116 {
00117   // This tolower is a simple "hack" to provide something that
00118   // sort of works when OpenNURBS is used with a compiler that
00119   // fails to provide functional localization tools.
00120 
00121 
00122   // TODO: 
00123   //   Expand these switch statments as users provide support
00124   //   for symbols.  This is not the correct way to solve this
00125   //   problem, but it will work in some simple cases.
00126   //   If you are using Microsoft Developer studio in Windows,
00127   //   then this code is never called.
00128   //  
00129   // Before you get too carried away, study 
00130   //
00131   //  http://www.microsoft.com/globaldev/wrguide/WRG_sort.asp
00132   //
00133   // and make sure what you are attempting to do is worth the
00134   // trouble.  In short, this approach is doomed to fail
00135   // and is not good enough for robust applications that want
00136   // to work well with most languages.
00137   //
00138   // That said, please post your additions to the OpenNURBS
00139   // newsgroup so they can be included in future
00140   // distrubutions.
00141 
00142   int i;
00143   if ( c <= 0 )
00144   {
00145     i = c;
00146   }
00147   else if ( c <= 127 )
00148   {
00149     // ASCII character
00150     i = tolower(c);
00151   }
00152   else if ( c <= 255 )
00153   {
00154     // "extended" ASCII character
00155     switch(c)
00156     {
00157       case 192:  // UNICODE Latin capital letter A with grave  (A`)
00158         i = 224; // UNICODE Latin small letter A with grave    (a`)
00159         break;
00160 
00161       case 193:  // UNICODE Latin capital letter A with acute  (A')
00162         i = 225; // UNICODE Latin small letter A with acute    (a')
00163         break;
00164 
00165       case 194:  // UNICODE Latin capital letter A with circumflex (A^)
00166         i = 226; // UNICODE Latin small letter A with circumflex   (a^)
00167         break;
00168 
00169       case 195:  // UNICODE Latin capital letter A with tilde (A~)
00170         i = 227; // UNICODE Latin small letter A with tilde   (a~)
00171         break;
00172 
00173       case 196:  // UNICODE Latin capital letter A with diaeresis (A")
00174         i = 228; // UNICODE Latin small letter A with diaeresis   (a")
00175         break;
00176 
00177       case 197:  // UNICODE Latin capital letter A with ring above (A ring above)
00178         i = 229; // UNICODE Latin small letter A with ring above   (a ring above)
00179         break;
00180 
00181       case 198:  // UNICODE Latin capital letter Ae
00182         i = 230; // UNICODE Latin small letter Ae
00183         break;
00184 
00185       case 199:  // UNICODE Latin capital letter C with cedilla (C,)
00186         i = 231; // UNICODE Latin small letter C with cedilla   (c,)
00187         break;
00188 
00189       case 200:  // UNICODE Latin capital letter E with grave (E`)
00190         i = 232; // UNICODE Latin small letter E with grave   (e`)
00191         break;
00192 
00193       case 201:  // UNICODE Latin capital letter E with acute (E')
00194         i = 233; // UNICODE Latin small letter E with acute   (e')
00195         break;
00196 
00197       case 202:  // UNICODE Latin capital letter E with circumflex (E^)
00198         i = 234; // UNICODE Latin small letter E with circumflex   (e^)
00199         break;
00200 
00201       case 203:  // UNICODE Latin capital letter E with diaeresis (E")
00202         i = 235; // UNICODE Latin small letter E with diaeresis   (e")
00203         break;
00204 
00205       case 204:  // UNICODE Latin capital letter I with grave (I`)
00206         i = 236; // UNICODE Latin small letter I with grave   (i`)
00207         break;
00208 
00209       case 205:  // UNICODE Latin capital letter I with acute (I')
00210         i = 237; // UNICODE Latin small letter I with acute   (i')
00211         break;
00212 
00213       case 206:  // UNICODE Latin capital letter I with circumflex (I^)
00214         i = 238; // UNICODE Latin small letter I with circumflex   (i^)
00215         break;
00216 
00217       case 207:  // UNICODE Latin capital letter I with diaeresis (I")
00218         i = 239; // UNICODE Latin small letter I with diaeresis   (i")
00219         break;
00220 
00221       case 208:  // UNICODE Latin capital letter Eth (ED)
00222         i = 240; // UNICODE Latin small letter Eth (ed)
00223         break;
00224 
00225       case 209:  // UNICODE Latin capital letter N with tilde (N~)
00226         i = 241; // UNICODE Latin small letter n with tilde (n~)
00227         break;
00228 
00229       case 210:  // UNICODE Latin capital letter O with grave (O`)
00230         i = 242; // UNICODE Latin small letter O with grave   (o`)
00231         break;
00232 
00233       case 211:  // UNICODE Latin capital letter O with acute (O')
00234         i = 243; // UNICODE Latin small letter O with acute   (o')
00235         break;
00236 
00237       case 212:  // UNICODE Latin capital letter O with circumflex (O^)
00238         i = 244; // UNICODE Latin small letter O with circumflex   (o^)
00239         break;
00240 
00241       case 213:  // UNICODE Latin capital letter O with tilde (O~)
00242         i = 245; // UNICODE Latin small letter O with tilde   (o~)
00243         break;
00244 
00245       case 214:  // UNICODE Latin capital letter O with diaeresis (O")
00246         i = 246; // UNICODE Latin small letter O with diaeresis   (o")
00247         break;
00248 
00249       case 216:  // UNICODE Latin capital letter O with stroke (O/)
00250         i = 248; // UNICODE Latin small letter O with stroke   (o/)
00251         break;
00252 
00253       case 217:  // UNICODE Latin capital letter U with grave (U`)
00254         i = 249; // UNICODE Latin small letter U with grave   (u`)
00255         break;
00256 
00257       case 218:  // UNICODE Latin capital letter U with acute (U')
00258         i = 250; // UNICODE Latin small letter U with acute   (u')
00259         break;
00260 
00261       case 219:  // UNICODE Latin capital letter U with circumflex (U^)
00262         i = 251; // UNICODE Latin small letter U with circumflex   (u^)
00263         break;
00264 
00265       case 220:  // UNICODE Latin capital letter U with diaeresis (U")
00266         i = 252; // UNICODE Latin small letter U with diaeresis   (u")
00267         break;
00268 
00269       case 221:  // UNICODE Latin capital letter Y with acute (Y')
00270         i = 253; // UNICODE Latin small letter Y with acute   (y')
00271         break;
00272 
00273       case 222:  // UNICODE Latin capital letter Thorn (P|)
00274         i = 254; // UNICODE Latin small letter Thorn   (p|)
00275         break;
00276 
00277       default:
00278         i = c;
00279         break;
00280     }
00281   }
00282   else if ( c <= 0x0177 )
00283   {
00284     if ( 0 == (c % 2) )
00285       i = c+1;
00286     else
00287       i = c;
00288   }
00289   else if ( c <= 0x0192 )
00290   {
00291     switch( c)
00292     {
00293     case 0x0178:  // UNICODE Latin capital letter Y with diaeresis (Y")
00294       i = 0x00FF; // UNICODE Latin small letter Y with diaeresis   (y")
00295       break;
00296 
00297     case 0x0179:  // UNICODE Latin capital letter Z with acute (Z')
00298       i = 0x017A; // UNICODE Latin small letter Z with acute   (z')
00299       break;
00300 
00301     case 0x017B:  // UNICODE Latin capital letter Z with dot above
00302       i = 0x017C; // UNICODE Latin small letter Z with dot above
00303       break;
00304 
00305     case 0x017D:  // UNICODE Latin capital letter Z with caron
00306       i = 0x017E; // UNICODE Latin small letter Z with caron
00307       break;
00308 
00309     case 0x018F:  // UNICODE Latin capital letter Schwa
00310       i = 0x0259; // UNICODE Latin small letter Schwa
00311       break;
00312 
00313     default:
00314       i = c;
00315       break;
00316     }
00317   }
00318   else if ( c <= 0x01FF )
00319   {
00320     if ( 0 == (c % 2) )
00321       i = c+1;
00322     else
00323       i = c;
00324   }
00325   else
00326   {
00327     // My apologies to those of you whose languages use these symbols.
00328     // I am too ignorant to make good guesses at what to do here.
00329     // Please fill in as needed and post your changes so I can include
00330     // them in future versions of OpenNURBS.
00331     switch (c)
00332     {
00333       // example
00334       case 0x0391:  // UNICODE Greek capital letter alpha
00335         i = 0x03B1; // UNICODE Greek small letter alpha
00336         break;
00337 
00338       default:
00339         i = c;
00340     }
00341   }
00342 
00343   return i;
00344 }
00345 
00346 static
00347 int on__hack__wcsicmp( const wchar_t* s1, const wchar_t* s2)
00348 {
00349   // This "hack" case insensitive wchar_t compare tool is used
00350   // when OpenNURBS is compiled in a development environment
00351   // that does not provide proper localization support.
00352 
00353   // handle NULL strings consistently and without crashing.
00354   if ( !s1 ) 
00355   {
00356     return s2 ? -1 : 0;
00357   }
00358   else if ( !s2 ) 
00359   {
00360     return 1;
00361   }
00362 
00363   int rc, c1, c2;
00364   
00365   do
00366   {
00367     c1 = on__hack__tolower(*s1++);
00368     c2 = on__hack__tolower(*s2++);
00369     rc = c1-c2;
00370   }
00371   while( 0 == rc && c1 && c2 );
00372 
00373   return rc;
00374 }
00375 
00376 #if defined(ON_COMPILER_MSC)
00377 // Disable the MSC /W4 unreachable code warning for the call to on__hack__wcsicmp()
00378 #pragma warning( push )
00379 #pragma warning( disable : 4702 )
00380 #endif
00381 
00382 int on_wcsicmp( const wchar_t* s1, const wchar_t* s2)
00383 {
00384   // handle NULL strings consistently and without crashing.
00385   if ( !s1 ) 
00386   {
00387     return s2 ? -1 : 0;
00388   }
00389   else if ( !s2 ) 
00390   {
00391     return 1;
00392   }
00393 
00394 #if defined(ON_OS_WINDOWS)
00395 
00396 #if defined(ON_COMPILER_BORLAND)
00397   // Borland's compiler / C library
00398   return wcscmpi(s1,s2); 
00399 #else
00400   // Microsoft compiler
00401 
00402   if ( 0 != g_s__windows_locale_id )
00403   {
00404     if ( 0 == g_s__windows_locale_os )
00405     {
00406       // On Win 95/98/ME, CompareStringW() doesn't work
00407       // and CompareStringA() is glacial.  So we test 
00408       // strings and use wcsicmp() whenever it will return
00409       // the right answer.  
00410       {
00411         const wchar_t* c1 = s1;
00412         const wchar_t* c2 = s2;
00413         while ( *c1 > 0 && *c1 < 128 && *c2 > 0 && *c2 < 128 )
00414         {
00415           c1++;
00416           c2++;
00417         }      
00418         if ( 0 == *c1 || 0 == *c2 )
00419         {
00420 #if defined(ON_COMPILER_MSC1400)
00421           return _wcsicmp(s1,s2);
00422 #else
00423           return wcsicmp(s1,s2);
00424 #endif
00425         }
00426       }
00427 
00428       // These convert UNICODE to wide character strings
00429       ON_String a(s1);
00430       ON_String b(s2);
00431 
00432       // Wide char conversion
00433       int rc = ::CompareStringA(g_s__windows_locale_id,
00434                            NORM_IGNORECASE | NORM_IGNOREWIDTH,
00435                            a.Array(),
00436                            -1,
00437                            b.Array(),
00438                            -1);
00439       if (rc == CSTR_LESS_THAN)
00440         return -1;
00441       if (rc == CSTR_EQUAL)
00442         return 0;
00443       if (rc == CSTR_GREATER_THAN)
00444         return 1;
00445     }
00446     else
00447     {
00448       // a version of Windows with working UNICODE support
00449       int rc = ::CompareStringW(g_s__windows_locale_id,
00450                            NORM_IGNORECASE | NORM_IGNOREWIDTH,
00451                            s1,
00452                            -1,
00453                            s2,
00454                            -1);
00455 
00456       if (rc == CSTR_LESS_THAN)
00457         return -1;
00458       if (rc == CSTR_EQUAL)
00459         return 0;
00460       if (rc == CSTR_GREATER_THAN)
00461         return 1;
00462     }
00463   }
00464 
00465   // Microsoft's wcsicmp() doesn't work right for
00466   // upper/lower case accented latin characters, 
00467   // upper/lower case cyrillic, upper/lower case Greek,
00468   // Asian characters, etc.  
00469   //
00470   // Basically, if the character code >= 127 or you are
00471   // using a language other than US english, then 
00472   // Microsoft's wcsicmp() blows it.
00473   //
00474 #if defined(ON_COMPILER_MSC1400)
00475   return _wcsicmp(s1,s2); // Microsoft's compiler / C library
00476 #else
00477   return wcsicmp(s1,s2); // Microsoft's compiler / C library
00478 #endif
00479 
00480 #endif
00481 
00482 
00483 #endif
00484 
00485   // If your compiler does not have a way to perform
00486   // a case insensitive compare of UNICODE strings,
00487   // then use the "hack" version below.
00488   return on__hack__wcsicmp(s1,s2);
00489 }
00490 
00491 #if defined(ON_COMPILER_MSC)
00492 #pragma warning( pop )
00493 #endif
00494 
00495 wchar_t* on_wcsupr(wchar_t* s)
00496 {
00497 #if defined(ON_OS_WINDOWS)
00498 #if defined(ON_COMPILER_BORLAND)
00499   // Borland's compiler / C library
00500   return _wcsupr(s);
00501 #else
00502   // Microsoft compiler
00503   return _wcsupr(s);
00504 #endif
00505 #else
00506   if (s) 
00507   {
00508     wchar_t c;
00509     while (*s) 
00510     {
00511       if ( 0 != (c = toupper(*s)) )
00512         *s = c;
00513       s++;
00514     }
00515   }
00516   return s;
00517 #endif
00518 }
00519 
00520 // on_wcslwr() calls _wcslwr() or wcslwr() depending on OS
00521 wchar_t* on_wcslwr(wchar_t* s)
00522 {
00523 #if defined(ON_OS_WINDOWS)
00524 #if defined(ON_COMPILER_BORLAND)
00525   // Borland's compiler / C library
00526   return _wcslwr(s);
00527 #else
00528   // Microsoft compiler
00529   return _wcslwr(s);
00530 #endif
00531 #else
00532   if (s) 
00533   {
00534     wchar_t c;
00535     while (*s) 
00536     {
00537       if ( 0 != (c = tolower(*s)) )
00538         *s = c;
00539       s++;
00540     }
00541   }
00542   return s;
00543 #endif
00544 }
00545 
00546 void ON_wString::MakeUpper()
00547 {
00548   if ( !IsEmpty() ) 
00549   {
00550 #if defined(ON_OS_WINDOWS)
00551     if ( 0 != g_s__windows_locale_id )
00552     {
00553       if ( 0 == g_s__windows_locale_os )
00554       {
00555         // On Win 95/98/ME, LCMapStringW() doesn't work.
00556         // (I hope you don't need the right answer in a hurry on Win9X.)
00557 
00558         // These convert UNICODE to wide character strings
00559         ON_String in(*this);
00560         int len_in = in.Length();
00561         int max_len_out = 2*len_in+16; // if 2x for wide char expansion
00562         ON_String out;
00563         out.ReserveArray(max_len_out+1);
00564         out.SetLength(max_len_out+1);
00565 
00566         // Wide char conversion
00567         int rc = ::LCMapStringA(g_s__windows_locale_id, 
00568                               LCMAP_UPPERCASE, 
00569                               in.Array(), 
00570                               len_in,
00571                               out.Array(), 
00572                               max_len_out);
00573         if (rc > 0 && rc <= max_len_out)
00574         {
00575           out.SetLength(rc);
00576           operator=(out); // multi-byte to wchar conversion
00577           return;
00578         }
00579       }
00580       else
00581       {
00582         // a version of Windows with working UNICODE support
00583         int len_in = Length();
00584         int max_len_out = len_in+16;
00585         ON_wString out;
00586         out.ReserveArray(max_len_out+1);
00587         out.SetLength(max_len_out+1);
00588 
00589         // Wide char conversion
00590         int rc = ::LCMapStringW(g_s__windows_locale_id, 
00591                               LCMAP_UPPERCASE, 
00592                               Array(), 
00593                               len_in,
00594                               out.Array(), 
00595                               max_len_out);
00596         if (rc > 0 && rc <= max_len_out)
00597         {
00598           out.SetLength(rc);
00599           operator=(out); // very fast - simply changes reference count
00600           return;
00601         }
00602       }
00603     }
00604 #endif
00605 
00606     // If ::LCMapStringA() or ::LCMapStringW() failed or we are
00607     // running on a non-Windows OS, then we fall through to the
00608     // wcslwr() function which will handle most most characters
00609     // in most Western European languages but is not adequate for
00610     // commercial quality software.
00611         CopyArray();
00612     on_wcsupr(m_s);
00613   }
00614 }
00615 
00616 void ON_wString::MakeLower()
00617 {
00618   if ( !IsEmpty() ) 
00619   {
00620 #if defined(ON_OS_WINDOWS)
00621     if ( 0 != g_s__windows_locale_id )
00622     {
00623       if ( 0 == g_s__windows_locale_os )
00624       {
00625         // On Win 95/98/ME, LCMapStringW() doesn't work.
00626         // (I hope you don't need the right answer in a hurry on Win9X.)
00627 
00628         // These convert UNICODE to wide character strings
00629         ON_String in(*this);
00630         int len_in = in.Length();
00631         int max_len_out = 2*len_in+16; // if 2x for wide char expansion
00632         ON_String out;
00633         out.ReserveArray(max_len_out+1);
00634         out.SetLength(max_len_out+1);
00635 
00636         // Wide char conversion to multi-byte lower case string
00637         int rc = ::LCMapStringA(g_s__windows_locale_id, 
00638                               LCMAP_LOWERCASE, 
00639                               in.Array(), 
00640                               len_in,
00641                               out.Array(), 
00642                               max_len_out);
00643         if (rc > 0 && rc <= max_len_out)
00644         {
00645           out.SetLength(rc);
00646           operator=(out); // multi-byte to wchar conversion
00647           return;
00648         }
00649       }
00650       else
00651       {
00652         // a version of Windows with working UNICODE support
00653         int len_in = Length();
00654         int max_len_out = len_in+16;
00655 
00656         // ReserveArray(max_len_out+1) allocates max_len_out+2
00657         // wchars (room for the NULL terminator is allocatcated).
00658         // The +1 is just in case LCMapStringW() has a bug and
00659         // writes an extra wchar or puts a NULL terminator
00660         // in s[max_len_out]. This is a lot of paranoia, but
00661         // the memory cost is negligable and it will prevent
00662         // difficult to diagnose crashes if MS releases a buggy
00663         // version of LCMapStringW().
00664         ON_wString out;
00665         out.ReserveArray(max_len_out+1);
00666         out.SetLength(max_len_out+1);
00667         
00668         // Wide char conversion to lower case.
00669         // Note that changing to lower case in some languages
00670         // can change the string length.
00671         int rc = ::LCMapStringW(g_s__windows_locale_id, 
00672                               LCMAP_LOWERCASE, 
00673                               Array(), 
00674                               len_in,
00675                               out.Array(), 
00676                               max_len_out);
00677         if (rc > 0 && rc <= max_len_out)
00678         {
00679           out.SetLength(rc);
00680           operator=(out); // very fast - simply changes reference count
00681           return;
00682         }
00683       }
00684     }
00685 #endif
00686 
00687     // If ::LCMapStringA() or ::LCMapStringW() failed or we are
00688     // running on a non-Windows OS, then we fall through to the
00689     // wcslwr() function which will handle most most characters
00690     // in most Western European languages but is not adequate for
00691     // commercial quality software.
00692     CopyArray();
00693     on_wcslwr(m_s);
00694   }
00695 }
00696 
00697 wchar_t* on_wcsrev(wchar_t* s)
00698 {
00699   if ( !s )
00700     return 0;
00701   int i, j;
00702   wchar_t w;
00703   for ( j = 0; 0 != s[j]; j++ )
00704   {
00705     // empty for body
00706   }
00707 
00708   for ( i = 0, j--; i < j; i++, j-- ) 
00709   {
00710     w = s[i];
00711     if ( w >= 0xD800 && w <= 0xDBFF && s[i+1] >= 0xDC00 && s[i+1] <= 0xDFFF )
00712     {
00713       // UTF-16 surrogate pair
00714       if ( i+1 < j-1 )
00715       {
00716         s[i] = s[j-1];
00717         s[j-1] = w;
00718         w = s[i+1];
00719         s[i+1] = s[j];
00720         s[j] = w;
00721       }
00722       i++;
00723       j--;
00724     }
00725     else
00726     {
00727       s[i] = s[j];
00728       s[j] = w;
00729     }
00730   }
00731   return s;
00732 }
00733 
00734 int on_WideCharToMultiByte(
00735     const wchar_t* lpWideCharStr,
00736     int cchWideChar,
00737     char* lpMultiByteStr,
00738     int cchMultiByte
00739     )
00740 {
00741   // 14 March 2011 Dale Lear
00742   //   It turns out that Windows WideCharToMultiByte does correctly
00743   //   convert UTF-16 to UTF-8 in Windows 7 when the code page 
00744   //   is CP_ACP and calls with CP_UTF8 sometimes fail to do
00745   //   any conversion.  So, I wrote ON_ConvertWideCharToUTF8()
00746   //   and opennurbs will use ON_ConvertWideCharToUTF8 to get 
00747   //   consistent results on all platforms.
00748   unsigned int error_status = 0;
00749   unsigned int error_mask = 0xFFFFFFFF;
00750   ON__UINT32 error_code_point = 0xFFFD;
00751   const wchar_t* p1 = 0;
00752   int count = ON_ConvertWideCharToUTF8(false,lpWideCharStr,cchWideChar,lpMultiByteStr,cchMultiByte,
00753                                        &error_status,error_mask,error_code_point,&p1);
00754   if ( 0 != error_status )
00755   {
00756     ON_ERROR("Error converting UTF-16 encoded wchar_t string to UTF-8 encoded char string.");
00757   }
00758   return count;
00759 }
00760 
00761 int on_MultiByteToWideChar(
00762     const char* lpMultiByteStr,
00763     int cchMultiByte,
00764     wchar_t* lpWideCharStr,
00765     int cchWideChar
00766     )
00767 {
00768   // 14 March 2011 Dale Lear
00769   //   It turns out that Windows WideCharToMultiByte does correctly
00770   //   convert UTF-16 to UTF-8 in Windows 7 when the code page 
00771   //   is CP_ACP and calls with CP_UTF8 sometimes fail to do
00772   //   any conversion.  So, I wrote ON_ConvertUTF8ToWideChar()
00773   //   and opennurbs will use ON_ConvertUTF8ToWideChar to get 
00774   //   consistent results on all platforms.
00775   unsigned int error_status = 0;
00776   unsigned int error_mask = 0xFFFFFFFF;
00777   ON__UINT32 error_code_point = 0xFFFD;
00778   const char* p1 = 0;
00779   int count = ON_ConvertUTF8ToWideChar(lpMultiByteStr,cchMultiByte,lpWideCharStr,cchWideChar,
00780                                        &error_status,error_mask,error_code_point,&p1);
00781   if ( 0 != error_status )
00782   {
00783     ON_ERROR("Error converting UTF-8 encoded char string to UTF-16 encoded wchar_t string.");
00784   }
00785   return count;
00786 }
00787 
00788 int on_vsnprintf( char *buffer, size_t count, const char *format, va_list argptr )
00789 {
00790 #if defined(ON_OS_WINDOWS)
00791 
00792 #if defined(ON_COMPILER_BORLAND)
00793   return vsprintf( buffer, format, argptr );
00794 #else
00795   return _vsnprintf( buffer, count, format, argptr );
00796 #endif
00797 
00798 #else
00799   return vsnprintf( buffer, count, format, argptr );
00800 #endif
00801 }
00802 
00803 int on_vsnwprintf( wchar_t *buffer, size_t count, const wchar_t *format, va_list argptr )
00804 {
00805 #if defined(ON_OS_WINDOWS)
00806 
00807 #if defined(ON_COMPILER_BORLAND)
00808   return vswprintf( buffer, format, argptr );
00809 #else
00810   return _vsnwprintf( buffer, count, format, argptr );
00811 #endif
00812 
00813 #else
00814   // if an OS doesn't support vsnwprintf(), use ASCII and hope for the best
00815 
00816   ON_String aformat = format; // convert format from UNICODE to ASCII
00817 
00818   // format an ASCII buffer
00819   char* abuffer = (char*)onmalloc(4*count*sizeof(*abuffer));
00820   int rc = on_vsnprintf( abuffer, 4*count, aformat.Array(), argptr );
00821 
00822   // convert formatted ASCII buffer to UNICODE
00823   on_MultiByteToWideChar( abuffer, (int)strlen(abuffer), buffer, (int)count );
00824   onfree(abuffer);  
00825   return rc;
00826 #endif
00827 }
00828 
00829 void on_splitpath(
00830   const char* path,
00831   const char** drive,
00832   const char** dir,
00833   const char** fname,
00834   const char** ext
00835   )
00836 {
00837   // The "const char* path" parameter is a UTF-8 encoded string. 
00838   // Since the unicode code point values for the characters we 
00839   // are searching for ( '/' '\' '.' ':' A-Z a-z) are all > 0 
00840   // and < 128, we can simply check for an array element having
00841   // the character value and not have to worry about dealing
00842   // with UTF-8 continuation values (>= 128).
00843 
00844   const char slash1 = '/';
00845   const char slash2 = '\\'; // do this even with the os is unix because
00846                             // we might be parsing a file name saved
00847                             // in Windows.
00848 
00849   const char* f;
00850   const char* e;
00851   const char* s;
00852   const char* s1;
00853 
00854   if ( 0 != drive )
00855     *drive = 0;
00856   if ( 0 != dir )
00857     *dir = 0;
00858   if ( 0 != fname )
00859     *fname = 0;
00860   if ( 0 != ext )
00861     *ext = 0;
00862 
00863   if ( 0 != path && 0 != *path )
00864   {
00865     // deal with Windows' drive letter (even when the os is unix)
00866     if ( ':' == path[1] )
00867     {
00868       if ( (path[0] >= 'A' && path[0] <= 'Z') || (path[0] >= 'a' && path[0] <= 'z') )
00869       {
00870         if ( drive )
00871           *drive = path;
00872         path += 2;
00873         if ( 0 == *path )
00874           return;
00875       }
00876     }
00877   }
00878 
00879   if ( 0 != path && 0 != *path )
00880   {
00881     e = 0;
00882     f = 0;
00883     s1 = path;
00884     while ( 0 != *s1 )
00885       s1++;
00886     s = (s1 > path) ? s1 - 1 : path;
00887   
00888     while ( s > path && '.' != *s && slash1 != *s && slash2 != *s )
00889       s--;
00890 
00891     if ( '.' == *s && 0 != s[1] )
00892     {
00893       // extensions must have something after the dot.
00894       e = s;
00895       s1 = e;
00896       s--;
00897     }
00898 
00899     while ( s > path && slash1 != *s && slash2 != *s )
00900       s--;
00901 
00902     if ( s >= path && s < s1 )
00903     {
00904       if (slash1 == *s || slash2 == *s ) 
00905       {
00906         if ( s+1 < s1 )
00907           f = s+1;
00908       }
00909       else if ( s == path )
00910       {
00911         f = s;
00912       }
00913     }
00914 
00915     if ( 0 == f )
00916     {
00917       // must have a non-empty filename in order to have and "extension"
00918       f = e;
00919       e = 0;
00920     }
00921 
00922     if ( 0 != dir && (0 == f || path < f) )
00923       *dir = path;
00924 
00925     if ( 0 != f && 0 != fname )
00926       *fname = f;
00927 
00928     if ( 0 != e && 0 != ext )
00929       *ext = e;
00930   }
00931 
00932 }
00933 
00934 void on_wsplitpath(
00935   const wchar_t* path,
00936   const wchar_t** drive,
00937   const wchar_t** dir,
00938   const wchar_t** fname,
00939   const wchar_t** ext
00940   )
00941 {
00942   // The "const wchar_t* path" parameter is a UTF-8, UTF-16 or UTF-32
00943   // encoded string. Since the unicode code point values for the 
00944   // characters we are searching for ( '/' '\' '.' ':' A-Z a-z) are
00945   // all > 0 and < 128, we can simply check for an array element 
00946   // having the character value and not have to worry about dealing
00947   // with UTF-16 surrogate pair values (0xD800-0xDBFF and DC00-DFFF)
00948   // and UTF-8 continuation values (>= 128).
00949 
00950   const wchar_t slash1 = '/';
00951   const wchar_t slash2 = '\\'; // do this even with the os is unix because
00952                                // we might be parsing a file name saved
00953                                // in Windows.
00954 
00955   const wchar_t* f;
00956   const wchar_t* e;
00957   const wchar_t* s;
00958   const wchar_t* s1;
00959 
00960   if ( 0 != drive )
00961     *drive = 0;
00962   if ( 0 != dir )
00963     *dir = 0;
00964   if ( 0 != fname )
00965     *fname = 0;
00966   if ( 0 != ext )
00967     *ext = 0;
00968 
00969   if ( 0 != path && 0 != *path )
00970   {
00971     // deal with Windows' drive letter (even when the os is unix)
00972     if ( ':' == path[1] )
00973     {
00974       if ( (path[0] >= 'A' && path[0] <= 'Z') || (path[0] >= 'a' && path[0] <= 'z') )
00975       {
00976         if ( drive )
00977           *drive = path;
00978         path += 2;
00979         if ( 0 == *path )
00980           return;
00981       }
00982     }
00983   }
00984 
00985   if ( 0 != path && 0 != *path )
00986   {
00987     e = 0;
00988     f = 0;
00989     s1 = path;
00990     while ( 0 != *s1 )
00991       s1++;
00992     s = (s1 > path) ? s1 - 1 : path;
00993   
00994     while ( s > path && '.' != *s && slash1 != *s && slash2 != *s )
00995       s--;
00996 
00997     if ( '.' == *s && 0 != s[1] )
00998     {
00999       // extensions must have something after the dot.
01000       e = s;
01001       s1 = e;
01002       s--;
01003     }
01004 
01005     while ( s > path && slash1 != *s && slash2 != *s )
01006       s--;
01007 
01008     if ( s >= path && s < s1 )
01009     {
01010       if (slash1 == *s || slash2 == *s ) 
01011       {
01012         if ( s+1 < s1 )
01013           f = s+1;
01014       }
01015       else if ( s == path )
01016       {
01017         f = s;
01018       }
01019     }
01020 
01021     if ( 0 == f )
01022     {
01023       // must have a non-empty filename in order to have and "extension"
01024       f = e;
01025       e = 0;
01026     }
01027 
01028     if ( 0 != dir && (0 == f || path < f) )
01029       *dir = path;
01030 
01031     if ( 0 != f && 0 != fname )
01032       *fname = f;
01033 
01034     if ( 0 != e && 0 != ext )
01035       *ext = e;
01036   }
01037 
01038 }
01039 
01040 
01041 
01042 int ON::Version()
01043 {
01044 #define OPENNURBS_VERSION_DEFINITION
01045 #include "pcl/surface/3rdparty/opennurbs/opennurbs_version.h"
01046   return OPENNURBS_VERSION;
01047 #undef OPENNURBS_VERSION
01048 #undef OPENNURBS_VERSION_DEFINITION
01049 }
01050 
01051 const char* ON::SourceRevision()
01052 {
01053   return OPENNURBS_SRC_SVN_REVISION;
01054 }
01055 
01056 const char* ON::SourceBranch()
01057 {
01058   return OPENNURBS_SRC_SVN_BRANCH;
01059 }
01060 
01061 const char* ON::DocumentationRevision()
01062 {
01063   return OPENNURBS_DOC_SVN_REVISION;
01064 }
01065 
01066 const char* ON::DocumentationBranch()
01067 {
01068   return OPENNURBS_DOC_SVN_BRANCH;
01069 }
01070 
01071 FILE* ON::OpenFile( // like fopen() - needed when OpenNURBS is used as a DLL
01072         const char* filename, // file name
01073         const char* filemode // file mode
01074         )
01075 {
01076   return ON_FileStream::Open(filename,filemode);
01077 }
01078 
01079 FILE* ON::OpenFile( // like fopen() - needed when OpenNURBS is used as a DLL
01080         const wchar_t* filename, // file name
01081         const wchar_t* filemode // file mode
01082         )
01083 {
01084   return ON_FileStream::Open(filename,filemode);
01085 }
01086 
01087 int ON::CloseFile( // like fclose() - needed when OpenNURBS is used as a DLL
01088         FILE* fp // pointer returned by OpenFile()
01089         )
01090 {
01091   return ON_FileStream::Close(fp);
01092 }
01093 
01094 int ON::CloseAllFiles()
01095 {
01096   // returns number of files closed or EOF for error
01097 #if defined(ON_OS_WINDOWS)
01098   return _fcloseall(); // ANSI C name
01099 #else
01100   // I can't find an fcloseall() or _fcloseall() in
01101   // gcc version egcs-2.91.66 19990314/Linux (egcs-1.1.2 release)
01102   return EOF;
01103 #endif
01104 }
01105 
01106 
01107 
01108 ON::active_space ON::ActiveSpace(int i)
01109 {
01110   ON::active_space as;
01111 
01112   switch(i)
01113   {
01114   case no_space:    as = no_space;    break;
01115   case model_space: as = model_space; break;
01116   case page_space:  as = page_space;  break;
01117   default:          as = no_space;    break;
01118   }
01119 
01120   return as;
01121 }
01122 
01123 
01124 ON::unit_system ON::UnitSystem(int i)
01125 {
01126   unit_system us = no_unit_system;
01127   switch(i) {
01128   case no_unit_system: us = no_unit_system; break;
01129 
01130   case angstroms: us = angstroms; break;
01131 
01132   case nanometers: us = nanometers; break;
01133   case microns: us = microns; break;
01134   case millimeters: us = millimeters; break;
01135   case centimeters: us = centimeters; break;
01136   case decimeters: us = decimeters; break;
01137   case meters: us = meters; break;
01138   case dekameters: us = dekameters; break;
01139   case hectometers: us = hectometers; break;
01140   case kilometers: us = kilometers; break;
01141   case megameters: us = megameters; break;
01142   case gigameters: us = gigameters; break;
01143   case microinches: us = microinches; break;
01144   case mils: us = mils; break;
01145   case inches: us = inches; break;
01146   case feet: us = feet; break;
01147   case yards: us = yards; break;
01148   case miles: us = miles; break;
01149   case printer_point: us = printer_point; break;
01150   case printer_pica: us = printer_pica; break;
01151   case nautical_mile: us = nautical_mile; break;
01152   case astronomical: us = astronomical; break;
01153   case lightyears: us = lightyears; break;
01154   case parsecs: us = parsecs; break;
01155   case custom_unit_system: us = custom_unit_system; break;
01156   default: us = no_unit_system; break;
01157   }
01158   return us;
01159 }
01160 
01161 double ON::UnitScale(
01162                      const class ON_3dmUnitsAndTolerances& u_and_t_from, 
01163                      const class ON_3dmUnitsAndTolerances& u_and_t_to
01164                      )
01165 {
01166   return ON::UnitScale( u_and_t_from.m_unit_system, u_and_t_to.m_unit_system );
01167 }
01168 
01169 double ON::UnitScale(
01170     ON::unit_system us_from,
01171     const class ON_UnitSystem& us_to
01172     )
01173 {
01174   double scale = 1.0;
01175   ON::unit_system us1 = us_to.m_unit_system;
01176   if ( ON::custom_unit_system == us1 )
01177   {
01178     if ( us_to.m_custom_unit_scale > 0.0 && ON_IsValid(us_to.m_custom_unit_scale) )
01179     {
01180       scale *= us_to.m_custom_unit_scale;
01181       us1 = ON::meters;
01182     }
01183   }
01184   return scale*ON::UnitScale(us_from,us1);
01185 }
01186 
01187 double ON::UnitScale(
01188     const class ON_UnitSystem& us_from, 
01189     ON::unit_system us_to
01190     )
01191 {
01192   double scale = 1.0;
01193   ON::unit_system us0 = us_from.m_unit_system;
01194   if ( ON::custom_unit_system == us0 )
01195   {
01196     if ( us_from.m_custom_unit_scale > 0.0 && ON_IsValid(us_from.m_custom_unit_scale) )
01197     {
01198       scale /= us_from.m_custom_unit_scale;
01199       us0 = ON::meters;
01200     }
01201   }
01202   return scale*ON::UnitScale(us0,us_to);
01203 }
01204 
01205 double ON::UnitScale(
01206                      const class ON_UnitSystem& u_and_t_from, 
01207                      const class ON_UnitSystem& u_and_t_to
01208                      )
01209 {
01210   double scale = 1.0;
01211   ON::unit_system us_from = u_and_t_from.m_unit_system;
01212   ON::unit_system us_to   = u_and_t_to.m_unit_system;
01213 
01214   if ( ON::no_unit_system != us_from && ON::no_unit_system != us_to )
01215   {
01216     if ( ON::custom_unit_system == us_from 
01217          && ON_IsValid(u_and_t_from.m_custom_unit_scale) 
01218          && u_and_t_from.m_custom_unit_scale > 0.0 )
01219     {
01220       scale /= u_and_t_from.m_custom_unit_scale;
01221       us_from = ON::meters;
01222     }
01223 
01224     if ( ON::custom_unit_system == us_to 
01225          && ON_IsValid(u_and_t_to.m_custom_unit_scale) 
01226          && u_and_t_to.m_custom_unit_scale > 0.0 )
01227     {
01228       scale *= u_and_t_to.m_custom_unit_scale;
01229       us_to = ON::meters;
01230     }
01231 
01232     scale *= ON::UnitScale( us_from, us_to );
01233   }
01234 
01235   return scale;
01236 }
01237 
01238 static bool IsEnglishUnit( ON::unit_system us )
01239 {
01240   return (
01241           ON::microinches == us
01242           || ON::mils == us
01243           || ON::inches == us
01244           || ON::feet == us
01245           || ON::yards == us
01246           || ON::miles == us
01247           || ON::printer_point == us
01248           || ON::printer_pica == us
01249          );
01250 }
01251 
01252 double ON::UnitScale(
01253             ON::unit_system u0, // from
01254             ON::unit_system u1  // to
01255             )
01256 {
01257   // Scale factor for changing unit systems
01258   // Examples 
01259   //   100.0  = UnitScale( ON::meters, ON::centimeters ) 
01260   //     2.54 = UnitScale( ON::inches, ON::centimeters ) 
01261   //    12.0  = UnitScale( ON::feet, ON::inches ) 
01262 
01263   // the default cases are here to keep lint quiet
01264   double scale = 1.0;
01265   
01266   if (  u0 != u1
01267         && u1 != ON::custom_unit_system
01268         && ((int)u1) > 0 && ((int)u1) < 26
01269         // switch weeds out bogus values of u0
01270       ) 
01271   switch( u0 ) 
01272   {
01273   case ON::angstroms:
01274     scale = UnitScale( meters, u1)*1.0e-10;
01275     break;
01276 
01277   case ON::nanometers:
01278     scale = UnitScale( meters, u1)*1.0e-9;
01279     break;
01280 
01281   case ON::microns:
01282     scale = UnitScale( meters, u1)*1.0e-6;
01283     break;
01284 
01285   case ON::millimeters:
01286     switch( u1 ) 
01287     {
01288     case ON::meters:      scale = 1.0e-3; break;
01289     case ON::microns:     scale = 1.0e+3; break;
01290     case ON::centimeters: scale = 1.0e-1; break;
01291 
01292     default:
01293       scale = IsEnglishUnit(u1)
01294             ? UnitScale( inches, u1 )/25.4
01295             : UnitScale( meters, u1 )*1.0e-3;
01296       break;
01297     }
01298     break;
01299 
01300   case ON::centimeters:
01301     switch( u1 ) 
01302     {
01303     case ON::meters:      scale = 1.0e-2; break;
01304     case ON::millimeters: scale = 1.0e+1; break;
01305 
01306     default:
01307       scale = IsEnglishUnit(u1)
01308             ? UnitScale( inches, u1 )/2.54
01309             : UnitScale( meters, u1 )*1.0e-2;
01310       break;
01311     }
01312     break;
01313 
01314   case ON::decimeters:
01315     scale = IsEnglishUnit(u1)
01316           ? UnitScale( inches, u1 )/0.254
01317           : UnitScale( meters, u1 )*1.0e-1;
01318     break;
01319 
01320   case ON::meters:
01321     switch( u1 ) 
01322     {
01323     case ON::angstroms:      scale = 1.0e+10; break;
01324     case ON::nanometers:     scale = 1.0e+9;  break;
01325     case ON::microns:        scale = 1.0e+6;  break;
01326     case ON::millimeters:    scale = 1.0e+3;  break;
01327     case ON::centimeters:    scale = 1.0e+2;  break;
01328     case ON::decimeters:     scale = 1.0e1;   break;
01329     case ON::meters:         scale = 1.0;     break;
01330     case ON::dekameters:     scale = 1.0e-1;  break;
01331     case ON::hectometers:    scale = 1.0e-2;  break;
01332     case ON::kilometers:     scale = 1.0e-3;  break;
01333     case ON::megameters:     scale = 1.0e-6;  break;
01334     case ON::gigameters:     scale = 1.0e-9;  break;
01335 
01336     case ON::nautical_mile:  scale = 1.0/1852.0; break;
01337     case ON::astronomical:   scale = 1.0/1.4959787e+11; break;
01338     case ON::lightyears:     scale = 1.0/9.4607304725808e+15; break;
01339     case ON::parsecs:        scale = 1.0/3.08567758e+16; break;
01340 
01341     default:
01342       if ( IsEnglishUnit(u1) )
01343         scale = UnitScale( inches, u1 )/0.0254;
01344       break;
01345     }
01346     break;
01347 
01348   case ON::dekameters:
01349     scale = UnitScale( meters, u1 )*10.0;
01350     break;
01351 
01352   case ON::hectometers:
01353     scale = UnitScale( meters, u1 )*100.0;
01354     break;
01355 
01356   case ON::kilometers:
01357     scale = IsEnglishUnit(u1)
01358           ? UnitScale( inches, u1 )/0.0000254
01359           : UnitScale( meters, u1 )*1000.0;
01360     break;
01361 
01362   case ON::megameters:
01363     scale = UnitScale( meters, u1 )*1.0e6;
01364     break;
01365 
01366   case ON::gigameters:
01367     scale = UnitScale( meters, u1 )*1.0e9;
01368     break;
01369 
01370   case ON::microinches:
01371     scale = UnitScale( inches, u1 )*1.0e-6;
01372     break;
01373 
01374   case ON::mils:
01375     scale = UnitScale( inches, u1 )*1.0e-3;
01376     break;
01377 
01378   case ON::inches:
01379     switch( u1 ) 
01380     {
01381     case ON::angstroms:       scale = 2.54e+8; break;
01382     case ON::nanometers:      scale = 2.54e+7; break;
01383     case ON::microns:         scale = 2.54e+4; break;
01384     case ON::millimeters:     scale = 25.4; break;
01385     case ON::centimeters:     scale = 2.54; break;
01386     case ON::decimeters:      scale = 2.54e-1; break;
01387     case ON::meters:          scale = 2.54e-2; break;
01388     case ON::dekameters:      scale = 2.54e-3; break;
01389     case ON::hectometers:     scale = 2.54e-4; break;
01390     case ON::kilometers:      scale = 2.54e-5; break;
01391     case ON::megameters:      scale = 2.54e-8; break;
01392     case ON::gigameters:      scale = 2.54e-11; break;
01393 
01394     case ON::printer_point: scale = 72.0;            break;
01395     case ON::printer_pica:  scale = 6.0;             break;
01396     case ON::microinches: scale = 1.0e+6;            break;
01397     case ON::mils:        scale = 1.0e+3;            break;
01398     case ON::inches:      scale = 1.0;               break;
01399     case ON::feet:        scale = 1.0/12.0;          break;
01400     case ON::yards:       scale = 1.0/36.0;          break;
01401     case ON::miles:       scale = 1.0/(12.0*5280.0); break;
01402 
01403     default:
01404       scale = UnitScale( meters, u1 )*2.54e-2;
01405       break;
01406     }
01407     break;
01408 
01409   case ON::feet:
01410     switch( u1 ) 
01411     {      
01412     case ON::yards:       scale = 1.0/3.0; break;
01413     case ON::miles:       scale = 1.0/5280.0; break;
01414     default:
01415       scale = UnitScale( inches, u1 )*12.0;
01416       break;
01417     }
01418     break;
01419 
01420   case ON::yards:
01421     switch( u1 ) 
01422     {      
01423     case ON::feet:        scale = 3.0; break;
01424     case ON::miles:       scale = 1.0/1760.0; break;
01425     default:
01426       scale = UnitScale( inches, u1 )*36.0;
01427       break;
01428     }
01429     break;
01430 
01431   case ON::miles:
01432     if ( ON::feet == u1 )
01433     {
01434       scale = 5280.0;
01435     }
01436     else
01437     {
01438       scale = IsEnglishUnit(u1)
01439             ? UnitScale( inches, u1 )*12.0*5280.0
01440             : UnitScale( meters, u1 )*1609.344;
01441     }
01442     break;
01443 
01444   case ON::printer_point:
01445     scale = UnitScale( inches, u1 )/72.0;
01446     break;
01447 
01448   case ON::printer_pica:
01449     scale = UnitScale( inches, u1 )/6.0;
01450     break;
01451 
01452   case ON::nautical_mile:
01453     scale = UnitScale( meters, u1 )*1852.0;
01454     break;
01455 
01456   case ON::astronomical:
01457     // 1.4959787e+11  http://en.wikipedia.org/wiki/Astronomical_unit
01458     // 1.495979e+11   http://units.nist.gov/Pubs/SP811/appenB9.htm  
01459     //    An astronomical unit (au) is the mean distance from the 
01460     //    center of the earth to the center of the sun.
01461     scale = UnitScale( meters, u1 )*1.4959787e+11;
01462     break;
01463 
01464   case ON::lightyears:
01465     // 9.4607304725808e+15 http://en.wikipedia.org/wiki/Light_year
01466     // 9.46073e+15 meters  http://units.nist.gov/Pubs/SP811/appenB9.htm
01467     //    A light year is the distance light travels in one Julian year.
01468     //    The speed of light is exactly 299792458 meters/second.
01469     //    A Julian year is exactly 365.25 * 86400 seconds and is 
01470     //    approximately the time it takes for one earth orbit.
01471     scale = UnitScale( meters, u1 )*9.4607304725808e+15;
01472     break;
01473 
01474   case ON::parsecs:
01475     // 3.08567758e+16  // http://en.wikipedia.org/wiki/Parsec
01476     // 3.085678e+16    // http://units.nist.gov/Pubs/SP811/appenB9.htm  
01477     scale = UnitScale( meters, u1 )*3.08567758e+16;
01478     break;
01479 
01480   case ON::custom_unit_system:
01481   case ON::no_unit_system:
01482     // nothing to do here
01483     break;
01484   }
01485 
01486   return scale;
01487 }
01488 
01489 
01491 enum distance_display_mode
01492 {
01493   decimal     = 0, 
01494   fractional  = 1,
01495   feet_inches = 2
01496 };
01497 
01498 ON::distance_display_mode ON::DistanceDisplayMode(int i)
01499 {
01500   distance_display_mode dm = decimal;
01501   switch (i) 
01502   {
01503   case decimal:
01504     dm = decimal;
01505     break;
01506   case fractional:
01507     dm = fractional;
01508     break;
01509   case feet_inches:
01510     dm = feet_inches;
01511     break;
01512   }
01513   return dm;
01514 }
01515 
01516 
01517 ON::point_style ON::PointStyle(int i)
01518 {
01519   //convertintegertopoint_styleenum
01520   point_style ps = unknown_point_style;
01521   switch (i) {
01522   case not_rational: ps = not_rational; break;
01523   case homogeneous_rational: ps = homogeneous_rational; break;
01524   case euclidean_rational: ps = euclidean_rational; break;
01525   default: ps = unknown_point_style; break;
01526   }
01527   return ps;
01528 }
01529 
01530 
01531 ON::knot_style ON::KnotStyle(int i)
01532 {
01533   //convertintegertoknot_styleenum
01534   knot_style ks = unknown_knot_style;
01535   switch (i) {
01536   case uniform_knots: ks = uniform_knots; break;
01537   case quasi_uniform_knots: ks = quasi_uniform_knots; break;
01538   case piecewise_bezier_knots: ks = piecewise_bezier_knots; break;
01539   case clamped_end_knots: ks = clamped_end_knots; break;
01540   case non_uniform_knots: ks = non_uniform_knots; break;
01541   default: ks = unknown_knot_style; break;
01542   }
01543   return ks;
01544 }
01545 
01546 ON::continuity ON::Continuity(int i)
01547 {
01548   continuity c = unknown_continuity;
01549 
01550   switch(i)
01551   {
01552   case unknown_continuity: c = unknown_continuity; break;
01553   case C0_continuous: c = C0_continuous; break;
01554   case C1_continuous: c = C1_continuous; break;
01555   case C2_continuous: c = C2_continuous; break;
01556   case G1_continuous: c = G1_continuous; break;
01557   case G2_continuous: c = G2_continuous; break;
01558   
01559   // 30 March 2003 Dale Lear added these
01560   case C0_locus_continuous: c = C0_locus_continuous; break;
01561   case C1_locus_continuous: c = C1_locus_continuous; break;
01562   case C2_locus_continuous: c = C2_locus_continuous; break;
01563   case G1_locus_continuous: c = G1_locus_continuous; break;
01564   case G2_locus_continuous: c = G2_locus_continuous; break;
01565 
01566   case Cinfinity_continuous: c = Cinfinity_continuous; break;
01567 
01568   case Gsmooth_continuous: c = Gsmooth_continuous; break;
01569   };
01570 
01571   return c;
01572 }
01573 
01574 ON::continuity ON::ParametricContinuity(int i)
01575 {
01576   // "erase" the locus setting.
01577   continuity c = unknown_continuity;
01578 
01579   switch(i)
01580   {
01581   case unknown_continuity: c = unknown_continuity; break;
01582   case C0_continuous: c = C0_continuous; break;
01583   case C1_continuous: c = C1_continuous; break;
01584   case C2_continuous: c = C2_continuous; break;
01585   case G1_continuous: c = G1_continuous; break;
01586   case G2_continuous: c = G2_continuous; break;
01587   case C0_locus_continuous: c = C0_continuous; break;
01588   case C1_locus_continuous: c = C1_continuous; break;
01589   case C2_locus_continuous: c = C2_continuous; break;
01590   case G1_locus_continuous: c = G1_continuous; break;
01591   case G2_locus_continuous: c = G2_continuous; break;
01592   case Cinfinity_continuous: c = Cinfinity_continuous; break;
01593   case Gsmooth_continuous: c = Gsmooth_continuous; break;
01594   };
01595 
01596   return c;
01597 }
01598 
01599 
01600 ON::continuity ON::PolylineContinuity(int i)
01601 {
01602   continuity c = unknown_continuity;
01603 
01604   switch(i)
01605   {
01606   case unknown_continuity: c = unknown_continuity; break;
01607   case C0_continuous: c = C0_continuous; break;
01608   case C1_continuous: c = C1_continuous; break;
01609   case C2_continuous: c = C1_continuous; break;
01610   case G1_continuous: c = G1_continuous; break;
01611   case G2_continuous: c = G1_continuous; break;
01612   case C0_locus_continuous: c = C0_locus_continuous; break;
01613   case C1_locus_continuous: c = C1_locus_continuous; break;
01614   case C2_locus_continuous: c = C1_locus_continuous; break;
01615   case G1_locus_continuous: c = G1_locus_continuous; break;
01616   case G2_locus_continuous: c = G1_locus_continuous; break;
01617   case Cinfinity_continuous: c = C1_continuous; break;
01618   case Gsmooth_continuous: c = G1_continuous; break;
01619   };
01620 
01621   return c;
01622 }
01623 
01624 
01625 ON::curve_style ON::CurveStyle(int i)
01626 {
01627   //convertintegertocurve_styleenum
01628   curve_style cs = unknown_curve_style;
01629   switch (i) {
01630   case line: cs = line; break;
01631   case circle: cs = circle; break;
01632   case ellipse: cs = ellipse; break;
01633   case parabola: cs = parabola; break;
01634   case hyperbola: cs = hyperbola; break;
01635   case planar_polyline: cs = planar_polyline; break;
01636   case polyline: cs = polyline; break;
01637   case planar_freeform_curve: cs = planar_freeform_curve; break;
01638   case freeform_curve: cs = freeform_curve; break;
01639   default: cs = unknown_curve_style; break;
01640   }
01641   return cs;
01642 }
01643 
01644 ON::surface_style ON::SurfaceStyle(int i)
01645 {
01646   //convertintegertosurface_styleenum
01647   surface_style ss = unknown_surface_style;
01648   
01649   switch (i) {
01650   case plane: ss = plane; break;
01651   case circular_cylinder: ss = circular_cylinder; break;
01652   case elliptical_cylinder: ss = elliptical_cylinder; break;
01653   case circular_cone: ss = circular_cone; break;
01654   case elliptical_cone: ss = elliptical_cone; break;
01655   case sphere: ss = sphere; break;
01656   case torus: ss = torus; break;
01657   case surface_of_revolution: ss = surface_of_revolution; break;
01658   case ruled_surface: ss = ruled_surface; break;
01659   case freeform_surface: ss = freeform_surface; break;
01660   default: ss = unknown_surface_style; break;
01661   }
01662   return ss;
01663 }
01664 
01665 ON::sort_algorithm ON::SortAlgorithm(int i)
01666 {
01667   sort_algorithm sa = ON::quick_sort;
01668   
01669   switch (i) {
01670   case ON::heap_sort: sa = ON::heap_sort; break;
01671   case ON::quick_sort: sa = ON::quick_sort; break;
01672   default: sa = ON::quick_sort; break;
01673   }
01674   return sa;
01675 }
01676 
01677 ON::endian ON::Endian(int i)
01678 { // convert integer to endian enum
01679   endian e = (i<=0) ? little_endian : big_endian;
01680   return e;
01681 }
01682 
01683 ON::endian ON::Endian()
01684 {
01685   // returns endian-ness of cpu.
01686   union {
01687     int i;
01688     unsigned char b[sizeof(int)];
01689   } u;
01690   u.i = 1;
01691   return (u.b[0] == 1) ? little_endian : big_endian;
01692 }
01693 
01694 ON::archive_mode ON::ArchiveMode(int i)
01695 {
01696   // convert integer to endian enum
01697   archive_mode a = read;
01698   switch(i) {
01699   case read:      a = read; break;
01700   case write:     a = write; break;
01701   case readwrite: a = readwrite; break;
01702   case read3dm:   a = read3dm; break;
01703   case write3dm:  a = write3dm; break;
01704   }
01705   return a;
01706 }
01707 
01708 ON::view_projection ON::ViewProjection(int i)
01709 {
01710   // convert integer to view_projection enum
01711   view_projection v = ON::unknown_view;
01712   switch(i) 
01713   {
01714   case ON::parallel_view:          v = ON::parallel_view;          break;
01715   case ON::perspective_view:       v = ON::perspective_view;       break;
01716   }
01717   return v;
01718 }
01719 
01720 bool ON::IsParallelProjection( ON::view_projection proj )
01721 {
01722   return ON::parallel_view == proj;
01723 }
01724 
01725 bool ON::IsPerspectiveProjection( ON::view_projection proj )
01726 {
01727   return ( ON::perspective_view == proj );
01728 }
01729 
01730 ON::coordinate_system ON::CoordinateSystem(int i)
01731 {
01732   // convert integer to coordinate_system enum
01733   coordinate_system cs = world_cs;
01734   switch(i) {
01735   case world_cs:  cs = world_cs; break;
01736   case camera_cs: cs = camera_cs; break;
01737   case clip_cs:   cs = clip_cs; break;
01738   case screen_cs: cs = screen_cs; break;
01739   }
01740   return cs;
01741 }
01742 
01743 ON::exception_type ON::ExceptionType(int i)
01744 {
01745   // convert integer to exception_type enum
01746   ON::exception_type e = unknown_exception;
01747   switch(i) {
01748   case out_of_memory:               e = out_of_memory; break;
01749   case unable_to_write_archive:     e = unable_to_write_archive; break;
01750   case unable_to_read_archive:      e = unable_to_read_archive; break;
01751   case unable_to_seek_archive:      e = unable_to_seek_archive; break;
01752   case unexpected_end_of_archive:   e = unexpected_end_of_archive; break;
01753   case unexpected_value_in_archive: e = unexpected_value_in_archive; break;
01754   };
01755   return e;
01756 }
01757 
01758 ON::layer_mode ON::LayerMode(int i)
01759 {
01760   ON::layer_mode m = normal_layer;
01761         switch(i)
01762   {
01763     case normal_layer:        m = normal_layer;       break;
01764     case hidden_layer:        m = hidden_layer;       break;
01765     case locked_layer:        m = locked_layer;       break;
01766   }
01767   return m;
01768 }
01769 
01770 ON::object_mode ON::ObjectMode(int i)
01771 {
01772   ON::object_mode m = normal_object;
01773         switch(i)
01774   {
01775     case normal_object:  m = normal_object;  break;
01776     case hidden_object:  m = hidden_object;  break;
01777     case locked_object:  m = locked_object;  break;
01778     case idef_object:    m = idef_object;    break;
01779   }
01780   return m;
01781 }
01782 
01783 ON::object_color_source ON::ObjectColorSource(int i)
01784 {
01785   // convert integer to object_mode enum
01786   ON::object_color_source cs = color_from_layer;
01787   switch (i) 
01788   {
01789   case color_from_layer: // use color assigned to layer
01790     cs = color_from_layer;
01791     break;
01792   case color_from_object: // use color assigned to object
01793     cs = color_from_object;
01794     break;
01795   case color_from_material:  // use diffuse render material color
01796     cs = color_from_material;
01797     break;
01798   case color_from_parent:
01799     cs = color_from_parent;
01800     break;
01801   }
01802   return cs;
01803 }
01804 
01805 ON::plot_color_source ON::PlotColorSource(int i)
01806 {
01807   // convert integer to object_mode enum
01808   ON::plot_color_source cs = plot_color_from_layer;
01809   switch (i) 
01810   {
01811   case plot_color_from_layer:
01812     cs = plot_color_from_layer;
01813     break;
01814   case plot_color_from_object:
01815     cs = plot_color_from_object;
01816     break;
01817   case plot_color_from_display: 
01818     cs = plot_color_from_display;
01819     break;
01820   case plot_color_from_parent:
01821     cs = plot_color_from_parent;
01822     break;
01823   }
01824   return cs;
01825 }
01826 
01827 ON::plot_weight_source ON::PlotWeightSource(int pw)
01828 {
01829   switch(pw)
01830   {
01831   case plot_weight_from_layer:  return plot_weight_from_layer;  break;
01832   case plot_weight_from_object: return plot_weight_from_object; break;
01833   case plot_weight_from_parent: return plot_weight_from_parent; break;
01834   }
01835   return plot_weight_from_layer;
01836 }
01837 
01838 
01839 ON::object_linetype_source ON::ObjectLinetypeSource(int i)
01840 {
01841   // convert integer to object_mode enum
01842   ON::object_linetype_source ls = linetype_from_layer;
01843   switch (i) {
01844   case linetype_from_layer: // use linetype assigned to layer
01845     ls = linetype_from_layer;
01846     break;
01847   case linetype_from_object: // use linetype assigned to object
01848     ls = linetype_from_object;
01849     break;
01850   case linetype_from_parent:
01851     ls = linetype_from_parent;
01852     break;
01853   }
01854   return ls;
01855 }
01856 
01857 ON::object_material_source ON::ObjectMaterialSource(int i)
01858 {
01859   ON::object_material_source ms = material_from_layer;
01860   switch(i) {
01861   case material_from_layer:
01862     ms = material_from_layer;
01863     break;
01864   case material_from_object:
01865     ms = material_from_object;
01866     break;
01867   case material_from_parent:
01868     ms = material_from_parent;
01869     break;
01870   }
01871   return ms;
01872 }
01873 
01874 ON::light_style ON::LightStyle(int i)
01875 {
01876   // convert integer to light_style enum
01877   light_style ls = unknown_light_style;
01878   switch(i)
01879   {
01880     case unknown_light_style: ls = unknown_light_style; break;
01881     //case view_directional_light: ls = view_directional_light; break;
01882     //case view_point_light: ls = view_point_light; break;
01883     //case view_spot_light: ls = view_spot_light; break;
01884     case camera_directional_light: ls = camera_directional_light; break;
01885     case camera_point_light: ls = camera_point_light; break;
01886     case camera_spot_light: ls = camera_spot_light; break;
01887     case world_directional_light: ls = world_directional_light; break;
01888     case world_point_light: ls = world_point_light; break;
01889     case world_spot_light: ls = world_spot_light; break;
01890     case ambient_light: ls = ambient_light; break;
01891     case world_linear_light: ls = world_linear_light; break;
01892     case world_rectangular_light: ls = world_rectangular_light; break;
01893   }
01894   return ls;
01895 }
01896 
01897 ON::curvature_style ON::CurvatureStyle(int i)
01898 {
01899   // convert integer to light_style enum
01900   ON::curvature_style cs = unknown_curvature_style;
01901   switch(i) {
01902   case gaussian_curvature:
01903     cs = gaussian_curvature;
01904     break;
01905   case mean_curvature:
01906     cs = mean_curvature;
01907     break;
01908   case min_curvature: 
01909     // minimum unsigned radius of curvature
01910     cs = min_curvature;
01911     break;
01912   case max_curvature: 
01913     // maximum unsigned radius of curvature
01914     cs = max_curvature;
01915     break;
01916   //case section_curvature_x:
01917     // unsigned normal curvature with respect to sections cut perp to world x axis
01918     //cs = section_curvature_x;
01919     //break;
01920   //case section_curvature_y:
01921     // unsigned normal curvature with respect to sections cut perp to world y axis
01922     //cs = section_curvature_y;
01923     //break;
01924   //case section_curvature_z:
01925     // unsigned normal curvature with respect to sections cut perp to world z axis
01926     //cs = section_curvature_z;
01927     //break;
01928   }
01929   return cs;
01930 }
01931 
01932 /*enum view_type // This is already in the header. I commented it out to see if it would compile and it does. John Croudy.
01933 {
01934   model_view_type     = 0,
01935   plot_page_view_type = 1,
01936   nested_view_type    = 2 
01937 };*/
01938 
01939 ON::view_type ON::ViewType(int vt)
01940 {
01941   switch(vt)
01942   {
01943   case model_view_type:  return (model_view_type);  break;
01944   case page_view_type:   return (page_view_type);   break;
01945   case nested_view_type: return (nested_view_type); break;
01946   }
01947 
01948   return (model_view_type);
01949 }
01950 
01951 
01952 ON::display_mode ON::DisplayMode(int i)
01953 {
01954   // convert integer to light_style enum
01955   ON::display_mode dm = default_display;
01956   switch(i) {
01957   case default_display:
01958     dm = default_display;
01959     break;
01960   case wireframe_display:
01961     dm = wireframe_display;
01962     break;
01963   case shaded_display:
01964     dm = shaded_display;
01965     break;
01966   case renderpreview_display: 
01967     dm = renderpreview_display;
01968     break;
01969   }
01970   return dm;
01971 }
01972 
01973 ON::texture_mode ON::TextureMode(int i)
01974 {
01975   // convert integer to texture_mode enum
01976   ON::texture_mode tm;
01977   switch (i) {
01978   case no_texture:
01979     tm = no_texture;
01980     break;
01981   case modulate_texture:
01982     tm = modulate_texture;
01983     break;
01984   case decal_texture:
01985     tm = decal_texture;
01986     break;
01987   default:
01988     tm = no_texture;
01989     break;
01990   }
01991   return tm;
01992 }
01993 
01994 ON::object_type ON::ObjectType(int i)
01995 {
01996   // convert integer to object_type enum
01997   object_type ot = unknown_object_type;
01998   switch(i) 
01999   {
02000   case unknown_object_type:  ot = unknown_object_type; break;
02001 
02002   case point_object:         ot = point_object; break;
02003   case pointset_object:      ot = pointset_object; break;
02004   case curve_object:         ot = curve_object; break;
02005   case surface_object:       ot = surface_object; break;
02006   case brep_object:          ot = brep_object; break;
02007   case mesh_object:          ot = mesh_object; break;
02008   case layer_object:         ot = layer_object; break;
02009   case material_object:      ot = material_object; break;
02010   case light_object:         ot = light_object; break;
02011   case annotation_object:    ot = annotation_object; break;
02012   case userdata_object:      ot = userdata_object; break;
02013   case instance_definition:  ot = instance_definition; break;
02014   case instance_reference:   ot = instance_reference; break;
02015   case text_dot:             ot = text_dot; break;
02016   case grip_object:          ot = grip_object; break;
02017   case detail_object:        ot = detail_object; break;
02018   case hatch_object:         ot = hatch_object; break;
02019   case morph_control_object: ot = morph_control_object; break;
02020   case loop_object:          ot = loop_object; break;
02021   case polysrf_filter:       ot = polysrf_filter; break;
02022   case edge_filter:          ot = edge_filter; break;
02023   case polyedge_filter:      ot = polyedge_filter; break;
02024   case meshvertex_object:    ot = meshvertex_object; break;
02025   case meshedge_object:      ot = meshedge_object; break;
02026   case meshface_object:      ot = meshface_object; break;
02027   case cage_object:          ot = cage_object; break;
02028   case phantom_object:       ot = phantom_object; break;
02029   case extrusion_object:     ot = extrusion_object; break;
02030 
02031   default: ot = unknown_object_type; break;
02032   }
02033 
02034   return ot;
02035 }
02036 
02037 ON::bitmap_type ON::BitmapType(int i)
02038 {
02039   // convert integer to object_type enum
02040   bitmap_type bt = unknown_bitmap_type;
02041   switch(i) {
02042   case unknown_bitmap_type: bt = unknown_bitmap_type; break;
02043   case windows_bitmap:      bt = windows_bitmap; break;
02044   case opengl_bitmap:       bt = opengl_bitmap; break;
02045   case png_bitmap:          bt = png_bitmap; break;
02046   default: bt = unknown_bitmap_type; break;
02047   }
02048   return bt;
02049 }
02050 
02051 ON::object_decoration ON::ObjectDecoration(int i)
02052 {
02053   ON::object_decoration d;
02054   switch(i)
02055   {
02056   case no_object_decoration: d = no_object_decoration; break;
02057   case start_arrowhead:      d = start_arrowhead; break;
02058   case end_arrowhead:        d = end_arrowhead;   break;
02059   case both_arrowhead:       d = both_arrowhead;  break;
02060   default:                   d = no_object_decoration; break;
02061   }
02062   return d;
02063 }
02064 
02065 
02066 ON::osnap_mode ON::OSnapMode(int i)
02067 {
02068   ON::osnap_mode osm;
02069   switch((unsigned int)i)
02070   {
02071   case os_none:          osm = os_none; break;
02072   case os_near:          osm = os_near; break;
02073   case os_focus:         osm = os_focus; break;
02074   case os_center:        osm = os_center; break;
02075   case os_vertex:        osm = os_vertex; break;
02076   case os_knot:          osm = os_knot; break;
02077   case os_quadrant:      osm = os_quadrant; break;
02078   case os_midpoint:      osm = os_midpoint; break;
02079   case os_intersection:  osm = os_intersection; break;
02080   case os_end:           osm = os_end; break;
02081   case os_perpendicular: osm = os_perpendicular; break;
02082   case os_tangent:       osm = os_tangent; break;
02083   case os_point:         osm = os_point; break;
02084   case os_all_snaps:     osm = os_all_snaps; break;
02085   default:
02086     osm = os_none;
02087     break;
02088   };
02089   return osm;
02090 }
02091 
02092 
02093 ON::cubic_loft_end_condition ON::CubicLoftEndCondition(int i)
02094 {
02095   ON::cubic_loft_end_condition e;
02096   switch(i)
02097   {
02098   case cubic_loft_ec_quadratic:
02099     e = ON::cubic_loft_ec_quadratic;
02100     break;
02101   case cubic_loft_ec_linear:
02102     e = ON::cubic_loft_ec_linear;
02103     break;
02104   case cubic_loft_ec_cubic:
02105     e = ON::cubic_loft_ec_cubic;
02106     break;
02107   case cubic_loft_ec_natural:
02108     e = ON::cubic_loft_ec_natural;
02109     break;
02110   case cubic_loft_ec_unit_tangent:
02111     e = ON::cubic_loft_ec_unit_tangent;
02112     break;
02113   case cubic_loft_ec_1st_derivative:
02114     e = ON::cubic_loft_ec_1st_derivative;
02115     break;
02116   case cubic_loft_ec_2nd_derivative:
02117     e = ON::cubic_loft_ec_2nd_derivative;
02118     break;
02119   case cubic_loft_ec_free_cv:
02120     e = ON::cubic_loft_ec_free_cv;
02121     break;
02122   default:
02123     ON_ERROR("ON::CubicLoftEndCondition(i) value of i is not valid.");
02124     e = ON::cubic_loft_ec_quadratic;
02125     break;
02126   }
02127   return e;
02128 }
02129 
02130 
02131 ON::mesh_type ON::MeshType(int i)
02132 {
02133   mesh_type mt = default_mesh;
02134   switch(i)
02135   {
02136   case default_mesh:  mt = default_mesh;  break;
02137   case render_mesh:   mt = render_mesh;   break;
02138   case analysis_mesh: mt = analysis_mesh; break;
02139   case preview_mesh:  mt = preview_mesh; break;
02140   case any_mesh:      mt = any_mesh;      break;
02141   default:            mt = default_mesh;  break;
02142   }
02143   return mt;
02144 }
02145 
02146 
02147 ON::eAnnotationType ON::AnnotationType(int i)
02148 {
02149   // convert integer to eAnnotationType enum
02150   eAnnotationType at = dtNothing;
02151   switch(i) {
02152   case dtNothing:
02153     at = dtNothing;
02154     break;
02155   case dtDimLinear:
02156     at = dtDimLinear;
02157     break;
02158   case dtDimAligned:
02159     at = dtDimAligned;
02160     break;
02161   case dtDimAngular:
02162     at = dtDimAngular;
02163     break;
02164   case dtDimDiameter:
02165     at = dtDimDiameter;
02166     break;
02167   case dtDimRadius:
02168     at = dtDimRadius;
02169     break;
02170   case dtLeader:
02171     at = dtLeader;
02172     break;
02173   case dtTextBlock:
02174     at = dtTextBlock;
02175     break;
02176   case dtDimOrdinate:
02177     at = dtDimOrdinate;
02178     break;
02179   }
02180   return at;
02181 }
02182 
02183 ON::eTextDisplayMode ON::TextDisplayMode( int i)
02184 {
02185   eTextDisplayMode m = dtAboveLine;
02186   switch( i)
02187   {
02188   case dtHorizontal:
02189     m = dtHorizontal;
02190     break;
02191   case dtAboveLine:
02192     m = dtAboveLine;
02193     break;
02194   case dtInLine:
02195     m = dtInLine;
02196     break;
02197   }
02198   return m;
02199 }
02200 
02201 
02202 // Windows code page support 
02203 //   Only ON_SetStringConversionWindowsCodePage
02204 //   and ON_GetStringConversionWindowsCodePage 
02205 //   should look at g_s__windows_code_page.
02206 static unsigned int g_s__windows_code_page = 0;
02207 
02208 unsigned int ON_SetStringConversionWindowsCodePage( unsigned int code_page )
02209 {
02210   unsigned int prev_cp = g_s__windows_code_page;
02211   g_s__windows_code_page = code_page;
02212   return prev_cp;
02213 }
02214 
02215 unsigned int ON_GetStringConversionWindowsCodePage()
02216 {
02217   return g_s__windows_code_page;
02218 }
02219 
02220 /*
02221 ON_TimeLimit::ON_TimeLimit()
02222 {
02223   m_time_limit[0] = 0;
02224   m_time_limit[1] = 0;
02225 }
02226 
02227 ON_TimeLimit::ON_TimeLimit(ON__UINT64 time_limit_seconds)
02228 {
02229   SetTimeLimit(time_limit_seconds);
02230 }
02231 
02232 void ON_TimeLimit::SetTimeLimit(ON__UINT64 time_limit_seconds)
02233 {
02234   m_time_limit[0] = 0;
02235   m_time_limit[1] = 0;
02236   if ( time_limit_seconds > 0 )
02237   {
02238     // This is a crude implementation that works
02239     // unless clock() is close to wrapping around
02240     // or time_limit_seconds is unreasonably large.
02241     clock_t max_ticks = (clock_t)(time_limit_seconds*((double)CLOCKS_PER_SEC));
02242     if ( max_ticks > 0 )
02243     {
02244       clock_t now_clock = ::clock();
02245       clock_t max_clock = max_ticks + now_clock;
02246       time_t ::time()
02247       if ( now_clock < max_clock )
02248       {
02249         *((clock_t*)(&m_time_limit[0])) = max_clock;
02250       }
02251     }
02252   }
02253 }
02254 
02255 bool ON_TimeLimit::Continue() const
02256 {
02257   clock_t max_clock = *((clock_t*)&m_time_limit[0]);
02258   return ( max_clock <= 0 || ::clock() <= max_clock );
02259 }
02260 
02261 bool ON_TimeLimit::IsSet() const
02262 {
02263   clock_t max_clock = *((clock_t*)&m_time_limit[0]);
02264   return ( max_clock > 0 );
02265 }
02266 */


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