Panda3D
 All Classes Functions Variables Enumerations
dxfFile.cxx
00001 // Filename: dxfFile.cxx
00002 // Created by:  drose (04May04)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "dxfFile.h"
00016 #include "string_utils.h"
00017 #include "virtualFileSystem.h"
00018 
00019 DXFFile::Color DXFFile::_colors[DXF_num_colors] = {
00020   { 1, 1, 1 },        // Color 0 is not used.
00021   { 1, 0, 0 },        // Color 1 = Red
00022   { 1, 1, 0 },        // Color 2 = Yellow
00023   { 0, 1, 0 },        // Color 3 = Green
00024   { 0, 1, 1 },        // Color 4 = Cyan
00025   { 0, 0, 1 },        // Color 5 = Blue
00026   { 1, 0, 1 },        // Color 6 = Magenta
00027   { 1, 1, 1 },        // Color 7 = Black/White
00028   { 0.3, 0.3, 0.3 },  // Color 8 = Gray
00029   { 0.7, 0.7, 0.7 },  // Color 9 = Gray
00030   { 1, 0, 0 },        // Remaining colors are from the fancy palette.
00031   { 1, 0.5, 0.5 },
00032   { 0.65, 0, 0 },
00033   { 0.65, 0.325, 0.325 },
00034   { 0.5, 0, 0 },
00035   { 0.5, 0.25, 0.25 },
00036   { 0.3, 0, 0 },
00037   { 0.3, 0.15, 0.15 },
00038   { 0.15, 0, 0 },
00039   { 0.15, 0.075, 0.075 },
00040   { 1, 0.25, 0 },
00041   { 1, 0.625, 0.5 },
00042   { 0.65, 0.1625, 0 },
00043   { 0.65, 0.4063, 0.325 },
00044   { 0.5, 0.125, 0 },
00045   { 0.5, 0.3125, 0.25 },
00046   { 0.3, 0.075, 0 },
00047   { 0.3, 0.1875, 0.15 },
00048   { 0.15, 0.0375, 0 },
00049   { 0.15, 0.0938, 0.075 },
00050   { 1, 0.5, 0 },
00051   { 1, 0.75, 0.5 },
00052   { 0.65, 0.325, 0 },
00053   { 0.65, 0.4875, 0.325 },
00054   { 0.5, 0.25, 0 },
00055   { 0.5, 0.375, 0.25 },
00056   { 0.3, 0.15, 0 },
00057   { 0.3, 0.225, 0.15 },
00058   { 0.15, 0.075, 0 },
00059   { 0.15, 0.1125, 0.075 },
00060   { 1, 0.75, 0 },
00061   { 1, 0.875, 0.5 },
00062   { 0.65, 0.4875, 0 },
00063   { 0.65, 0.5688, 0.325 },
00064   { 0.5, 0.375, 0 },
00065   { 0.5, 0.4375, 0.25 },
00066   { 0.3, 0.225, 0 },
00067   { 0.3, 0.2625, 0.15 },
00068   { 0.15, 0.1125, 0 },
00069   { 0.15, 0.1313, 0.075 },
00070   { 1, 1, 0 },
00071   { 1, 1, 0.5 },
00072   { 0.65, 0.65, 0 },
00073   { 0.65, 0.65, 0.325 },
00074   { 0.5, 0.5, 0 },
00075   { 0.5, 0.5, 0.25 },
00076   { 0.3, 0.3, 0 },
00077   { 0.3, 0.3, 0.15 },
00078   { 0.15, 0.15, 0 },
00079   { 0.15, 0.15, 0.075 },
00080   { 0.75, 1, 0 },
00081   { 0.875, 1, 0.5 },
00082   { 0.4875, 0.65, 0 },
00083   { 0.5688, 0.65, 0.325 },
00084   { 0.375, 0.5, 0 },
00085   { 0.4375, 0.5, 0.25 },
00086   { 0.225, 0.3, 0 },
00087   { 0.2625, 0.3, 0.15 },
00088   { 0.1125, 0.15, 0 },
00089   { 0.1313, 0.15, 0.075 },
00090   { 0.5, 1, 0 },
00091   { 0.75, 1, 0.5 },
00092   { 0.325, 0.65, 0 },
00093   { 0.4875, 0.65, 0.325 },
00094   { 0.25, 0.5, 0 },
00095   { 0.375, 0.5, 0.25 },
00096   { 0.15, 0.3, 0 },
00097   { 0.225, 0.3, 0.15 },
00098   { 0.075, 0.15, 0 },
00099   { 0.1125, 0.15, 0.075 },
00100   { 0.25, 1, 0 },
00101   { 0.625, 1, 0.5 },
00102   { 0.1625, 0.65, 0 },
00103   { 0.4063, 0.65, 0.325 },
00104   { 0.125, 0.5, 0 },
00105   { 0.3125, 0.5, 0.25 },
00106   { 0.075, 0.3, 0 },
00107   { 0.1875, 0.3, 0.15 },
00108   { 0.0375, 0.15, 0 },
00109   { 0.0938, 0.15, 0.075 },
00110   { 0, 1, 0 },
00111   { 0.5, 1, 0.5 },
00112   { 0, 0.65, 0 },
00113   { 0.325, 0.65, 0.325 },
00114   { 0, 0.5, 0 },
00115   { 0.25, 0.5, 0.25 },
00116   { 0, 0.3, 0 },
00117   { 0.15, 0.3, 0.15 },
00118   { 0, 0.15, 0 },
00119   { 0.075, 0.15, 0.075 },
00120   { 0, 1, 0.25 },
00121   { 0.5, 1, 0.625 },
00122   { 0, 0.65, 0.1625 },
00123   { 0.325, 0.65, 0.4063 },
00124   { 0, 0.5, 0.125 },
00125   { 0.25, 0.5, 0.3125 },
00126   { 0, 0.3, 0.075 },
00127   { 0.15, 0.3, 0.1875 },
00128   { 0, 0.15, 0.0375 },
00129   { 0.075, 0.15, 0.0938 },
00130   { 0, 1, 0.5 },
00131   { 0.5, 1, 0.75 },
00132   { 0, 0.65, 0.325 },
00133   { 0.325, 0.65, 0.4875 },
00134   { 0, 0.5, 0.25 },
00135   { 0.25, 0.5, 0.375 },
00136   { 0, 0.3, 0.15 },
00137   { 0.15, 0.3, 0.225 },
00138   { 0, 0.15, 0.075 },
00139   { 0.075, 0.15, 0.1125 },
00140   { 0, 1, 0.75 },
00141   { 0.5, 1, 0.875 },
00142   { 0, 0.65, 0.4875 },
00143   { 0.325, 0.65, 0.5688 },
00144   { 0, 0.5, 0.375 },
00145   { 0.25, 0.5, 0.4375 },
00146   { 0, 0.3, 0.225 },
00147   { 0.15, 0.3, 0.2625 },
00148   { 0, 0.15, 0.1125 },
00149   { 0.075, 0.15, 0.1313 },
00150   { 0, 1, 1 },
00151   { 0.5, 1, 1 },
00152   { 0, 0.65, 0.65 },
00153   { 0.325, 0.65, 0.65 },
00154   { 0, 0.5, 0.5 },
00155   { 0.25, 0.5, 0.5 },
00156   { 0, 0.3, 0.3 },
00157   { 0.15, 0.3, 0.3 },
00158   { 0, 0.15, 0.15 },
00159   { 0.075, 0.15, 0.15 },
00160   { 0, 0.75, 1 },
00161   { 0.5, 0.875, 1 },
00162   { 0, 0.4875, 0.65 },
00163   { 0.325, 0.5688, 0.65 },
00164   { 0, 0.375, 0.5 },
00165   { 0.25, 0.4375, 0.5 },
00166   { 0, 0.225, 0.3 },
00167   { 0.15, 0.2625, 0.3 },
00168   { 0, 0.1125, 0.15 },
00169   { 0.075, 0.1313, 0.15 },
00170   { 0, 0.5, 1 },
00171   { 0.5, 0.75, 1 },
00172   { 0, 0.325, 0.65 },
00173   { 0.325, 0.4875, 0.65 },
00174   { 0, 0.25, 0.5 },
00175   { 0.25, 0.375, 0.5 },
00176   { 0, 0.15, 0.3 },
00177   { 0.15, 0.225, 0.3 },
00178   { 0, 0.075, 0.15 },
00179   { 0.075, 0.1125, 0.15 },
00180   { 0, 0.25, 1 },
00181   { 0.5, 0.625, 1 },
00182   { 0, 0.1625, 0.65 },
00183   { 0.325, 0.4063, 0.65 },
00184   { 0, 0.125, 0.5 },
00185   { 0.25, 0.3125, 0.5 },
00186   { 0, 0.075, 0.3 },
00187   { 0.15, 0.1875, 0.3 },
00188   { 0, 0.0375, 0.15 },
00189   { 0.075, 0.0938, 0.15 },
00190   { 0, 0, 1 },
00191   { 0.5, 0.5, 1 },
00192   { 0, 0, 0.65 },
00193   { 0.325, 0.325, 0.65 },
00194   { 0, 0, 0.5 },
00195   { 0.25, 0.25, 0.5 },
00196   { 0, 0, 0.3 },
00197   { 0.15, 0.15, 0.3 },
00198   { 0, 0, 0.15 },
00199   { 0.075, 0.075, 0.15 },
00200   { 0.25, 0, 1 },
00201   { 0.625, 0.5, 1 },
00202   { 0.1625, 0, 0.65 },
00203   { 0.4063, 0.325, 0.65 },
00204   { 0.125, 0, 0.5 },
00205   { 0.3125, 0.25, 0.5 },
00206   { 0.075, 0, 0.3 },
00207   { 0.1875, 0.15, 0.3 },
00208   { 0.0375, 0, 0.15 },
00209   { 0.0938, 0.075, 0.15 },
00210   { 0.5, 0, 1 },
00211   { 0.75, 0.5, 1 },
00212   { 0.325, 0, 0.65 },
00213   { 0.4875, 0.325, 0.65 },
00214   { 0.25, 0, 0.5 },
00215   { 0.375, 0.25, 0.5 },
00216   { 0.15, 0, 0.3 },
00217   { 0.225, 0.15, 0.3 },
00218   { 0.075, 0, 0.15 },
00219   { 0.1125, 0.075, 0.15 },
00220   { 0.75, 0, 1 },
00221   { 0.875, 0.5, 1 },
00222   { 0.4875, 0, 0.65 },
00223   { 0.5688, 0.325, 0.65 },
00224   { 0.375, 0, 0.5 },
00225   { 0.4375, 0.25, 0.5 },
00226   { 0.225, 0, 0.3 },
00227   { 0.2625, 0.15, 0.3 },
00228   { 0.1125, 0, 0.15 },
00229   { 0.1313, 0.075, 0.15 },
00230   { 1, 0, 1 },
00231   { 1, 0.5, 1 },
00232   { 0.65, 0, 0.65 },
00233   { 0.65, 0.325, 0.65 },
00234   { 0.5, 0, 0.5 },
00235   { 0.5, 0.25, 0.5 },
00236   { 0.3, 0, 0.3 },
00237   { 0.3, 0.15, 0.3 },
00238   { 0.15, 0, 0.15 },
00239   { 0.15, 0.075, 0.15 },
00240   { 1, 0, 0.75 },
00241   { 1, 0.5, 0.875 },
00242   { 0.65, 0, 0.4875 },
00243   { 0.65, 0.325, 0.5688 },
00244   { 0.5, 0, 0.375 },
00245   { 0.5, 0.25, 0.4375 },
00246   { 0.3, 0, 0.225 },
00247   { 0.3, 0.15, 0.2625 },
00248   { 0.15, 0, 0.1125 },
00249   { 0.15, 0.075, 0.1313 },
00250   { 1, 0, 0.5 },
00251   { 1, 0.5, 0.75 },
00252   { 0.65, 0, 0.325 },
00253   { 0.65, 0.325, 0.4875 },
00254   { 0.5, 0, 0.25 },
00255   { 0.5, 0.25, 0.375 },
00256   { 0.3, 0, 0.15 },
00257   { 0.3, 0.15, 0.225 },
00258   { 0.15, 0, 0.075 },
00259   { 0.15, 0.075, 0.1125 },
00260   { 1, 0, 0.25 },
00261   { 1, 0.5, 0.625 },
00262   { 0.65, 0, 0.1625 },
00263   { 0.65, 0.325, 0.4063 },
00264   { 0.5, 0, 0.125 },
00265   { 0.5, 0.25, 0.3125 },
00266   { 0.3, 0, 0.075 },
00267   { 0.3, 0.15, 0.1875 },
00268   { 0.15, 0, 0.0375 },
00269   { 0.15, 0.075, 0.0938 },
00270   { 0.33, 0.33, 0.33 },
00271   { 0.464, 0.464, 0.464 },
00272   { 0.598, 0.598, 0.598 },
00273   { 0.732, 0.732, 0.732 },
00274   { 0.866, 0.866, 0.866 },
00275   { 1, 1, 1 },
00276 };
00277       
00278 
00279 ////////////////////////////////////////////////////////////////////
00280 //     Function: DXFFile::Constructor
00281 //       Access: Public
00282 //  Description:
00283 ////////////////////////////////////////////////////////////////////
00284 DXFFile::
00285 DXFFile() {
00286   _in = NULL;
00287   _owns_in = false;
00288   _layer = NULL;
00289   reset_entity();
00290   _color_index = -1;
00291 }
00292 
00293 ////////////////////////////////////////////////////////////////////
00294 //     Function: DXFFile::Destructor
00295 //       Access: Public, Virtual
00296 //  Description:
00297 ////////////////////////////////////////////////////////////////////
00298 DXFFile::
00299 ~DXFFile() {
00300   if (_owns_in) {
00301     VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00302     vfs->close_read_file(_in);
00303   }
00304 }
00305 
00306 
00307 ////////////////////////////////////////////////////////////////////
00308 //     Function: DXFFile::process
00309 //       Access: Public
00310 //  Description: Opens the indicated filename and reads it as a DXF
00311 //               file.
00312 ////////////////////////////////////////////////////////////////////
00313 void DXFFile::
00314 process(Filename filename) {
00315   filename.set_text();
00316 
00317   VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00318   istream *in = vfs->open_read_file(filename, true);
00319   if (in == (istream *)NULL) {
00320     return;
00321   }
00322   process(in, true);
00323 }
00324 
00325 
00326 ////////////////////////////////////////////////////////////////////
00327 //     Function: DXFFile::process
00328 //       Access: Public
00329 //  Description: Reads the indicated stream as a DXF file.  If owns_in
00330 //               is true, then the istream will be deleted via
00331 //               vfs->close_read_file() when the DXFFile object
00332 //               destructs.
00333 ////////////////////////////////////////////////////////////////////
00334 void DXFFile::
00335 process(istream *in, bool owns_in) {
00336   if (_owns_in) {
00337     VirtualFileSystem *vfs = VirtualFileSystem::get_global_ptr();
00338     vfs->close_read_file(_in);
00339   }
00340   _in = in;
00341   _owns_in = owns_in;
00342   _state = ST_top;
00343 
00344   begin_file();
00345   while (_state != ST_done && _state != ST_error) {
00346     if (get_group()) {
00347       switch (_state) {
00348       case ST_top:
00349         state_top();
00350         break;
00351 
00352       case ST_section:
00353         state_section();
00354         break;
00355 
00356       case ST_entity:
00357         state_entity();
00358         break;
00359 
00360       case ST_verts:
00361         state_verts();
00362         break;
00363 
00364       default:
00365         break;
00366       }
00367     }
00368   }
00369 }
00370 
00371 
00372 
00373 ////////////////////////////////////////////////////////////////////
00374 //     Function: DXFFile::Begin File
00375 //       Access: Public, Virtual
00376 //  Description: A hook for user code, if desired.  This function is
00377 //               called whenever processing begins on the DXF file.
00378 ////////////////////////////////////////////////////////////////////
00379 void DXFFile::
00380 begin_file() {
00381 }
00382       
00383 
00384 ////////////////////////////////////////////////////////////////////
00385 //     Function: DXFFile::begin_section
00386 //       Access: Public, Virtual
00387 //  Description: A hook for user code, if desired.  This function is
00388 //               called whenever a new section in the DXF file is
00389 //               encountered.
00390 ////////////////////////////////////////////////////////////////////
00391 void DXFFile::
00392 begin_section() {
00393 }
00394 
00395 
00396 ////////////////////////////////////////////////////////////////////
00397 //     Function: DXFFile::done_vertex
00398 //       Access: Public, Virtual
00399 //  Description: A hook for user code, if desired.  This function is
00400 //               called whenever a vertex is read from the DXF file.
00401 //               This function has the default behavior of adding the
00402 //               vertex to the _verts list, so that when done_entity()
00403 //               is called later, it will have the complete list of
00404 //               vertices available to it.
00405 ////////////////////////////////////////////////////////////////////
00406 void DXFFile::
00407 done_vertex() {
00408   DXFVertex v;
00409   v._p = _p;
00410   _verts.push_back(v);
00411 }
00412 
00413 
00414 ////////////////////////////////////////////////////////////////////
00415 //     Function: DXFFile::done_entity
00416 //       Access: Public, Virtual
00417 //  Description: This is the primary hook for user code.  This
00418 //               function is called when an entity is read from the
00419 //               DXF file.  This may be something like a polygon,
00420 //               point, or a polygon mesh: any geometry.  It is up to
00421 //               the user code to override this function and do
00422 //               something interesting with each piece of geometry
00423 //               that is read.
00424 ////////////////////////////////////////////////////////////////////
00425 void DXFFile::
00426 done_entity() {
00427 }
00428       
00429 
00430 ////////////////////////////////////////////////////////////////////
00431 //     Function: DXFFile::end_section
00432 //       Access: Public, Virtual
00433 //  Description: A hook for user code, if desired.  This function is
00434 //               called as each section in the DXF file is finished.
00435 ////////////////////////////////////////////////////////////////////
00436 void DXFFile::
00437 end_section() {
00438 }
00439       
00440 
00441 ////////////////////////////////////////////////////////////////////
00442 //     Function: DXFFile::end_file
00443 //       Access: Public, Virtual
00444 //  Description: A hook for user code, if desired.  This function is
00445 //               called when the DXF processing is complete.
00446 ////////////////////////////////////////////////////////////////////
00447 void DXFFile::
00448 end_file() {
00449 }
00450 
00451 
00452 ////////////////////////////////////////////////////////////////////
00453 //     Function: DXFFile::Error
00454 //       Access: Public, Virtual
00455 //  Description: A hook for user code, if desired.  This function is
00456 //               called when some unexpected error occurs while
00457 //               reading the DXF file.
00458 ////////////////////////////////////////////////////////////////////
00459 void DXFFile::
00460 error() {
00461   nout << "Error!\n";
00462 }
00463 
00464 
00465 
00466 ////////////////////////////////////////////////////////////////////
00467 //     Function: DXFFile::find_color
00468 //       Access: Public, Static
00469 //  Description: Returns the index of the closest matching AutoCAD
00470 //               color to the indicated r, g, b.
00471 ////////////////////////////////////////////////////////////////////
00472 int DXFFile::
00473 find_color(double r, double g, double b) {
00474   double best_diff = 4.0;   // 4 is greater than our expected max, 3.
00475   int best_index = 7;
00476 
00477   for (int i = 0; i < 255; i++) {
00478     double diff = ((r - _colors[i].r) * (r - _colors[i].r) +
00479                    (g - _colors[i].g) * (g - _colors[i].g) +
00480                    (b - _colors[i].b) * (b - _colors[i].b));
00481     if (diff < best_diff) {
00482       best_diff = diff;
00483       best_index = i;
00484     }
00485   }
00486 
00487   return best_index;
00488 }
00489 
00490 ////////////////////////////////////////////////////////////////////
00491 //     Function: DXFFile::get_color
00492 //       Access: Public
00493 //  Description: This is a convenience function to return the r,g,b
00494 //               color of the current entity (at the time of
00495 //               done_entity()).  It's based on the _color_index value
00496 //               that was read from the DXF file.
00497 ////////////////////////////////////////////////////////////////////
00498 const DXFFile::Color &DXFFile::
00499 get_color() const {
00500   if (_color_index >= 0 && _color_index <= 255) {
00501     return _colors[_color_index];
00502   }
00503   return _colors[0];
00504 }
00505 
00506 
00507 ////////////////////////////////////////////////////////////////////
00508 //     Function: DXFFile::ocs_2_wcs
00509 //       Access: Public
00510 //  Description: Assuming the current entity is a planar-based entity,
00511 //               for instance, a 2-d polygon (as opposed to a 3-d
00512 //               polygon), this converts the coordinates from the
00513 //               funny planar coordinate system to the world
00514 //               coordinates.  It converts the _p value of the entity,
00515 //               as well as all vertices in the _verts list.
00516 ////////////////////////////////////////////////////////////////////
00517 void DXFFile::
00518 ocs_2_wcs() {
00519   compute_ocs();
00520 
00521   // Convert the entity's position.
00522   _p = _p * _ocs2wcs;
00523 
00524   // Maybe we have these coordinates too.
00525   _q = _q * _ocs2wcs;
00526   _r = _r * _ocs2wcs;
00527   _s = _s * _ocs2wcs;
00528 
00529   // If there are any vertices, convert them too.
00530   DXFVertices::iterator vi;
00531   for (vi = _verts.begin(); vi != _verts.end(); ++vi) {
00532     (*vi)._p = (*vi)._p * _ocs2wcs;
00533   }
00534 }
00535 
00536 
00537 ////////////////////////////////////////////////////////////////////
00538 //     Function: DXFFile::compute_ocs
00539 //       Access: Protected
00540 //  Description: Computes the matrix used to convert from the planar
00541 //               coordinate system to world coordinates.
00542 ////////////////////////////////////////////////////////////////////
00543 void DXFFile::
00544 compute_ocs() {
00545   // A 2-d entity's vertices might be defined in an "Object Coordinate
00546   // System" which has a funny definition.  Its Z axis is defined by
00547   // _z, and its X and Y axes are inferred from that.  The origin is
00548   // the same as the world coordinate system's origin.
00549 
00550   // The Z axis is _z.  Determine the x and y axes.
00551   LVector3d x, y;
00552 
00553   if (fabs(_z[0]) < 1.0/64.0 && fabs(_z[1]) < 1.0/64.0) {
00554     x = cross(LVector3d(0.0, 1.0, 0.0), _z);
00555   } else {
00556     x = cross(LVector3d(0.0, 0.0, 1.0), _z);
00557   }
00558   x.normalize();
00559   y = cross(x, _z);
00560   y.normalize();
00561 
00562   // Now build a rotate matrix from these vectors.
00563   LMatrix4d
00564     ocs( x[0],  x[1],  x[2],    0,
00565          y[0],  y[1],  y[2],    0,
00566         _z[0], _z[1], _z[2],    0,
00567             0,     0,     0,    1);
00568 
00569   _ocs2wcs.invert_from(ocs);
00570 }
00571 
00572 
00573 ////////////////////////////////////////////////////////////////////
00574 //     Function: DXFFile::get_group
00575 //       Access: Protected
00576 //  Description: Reads the next code, string pair from the DXF file.
00577 //               This is the basic unit of data in a DXF file.
00578 ////////////////////////////////////////////////////////////////////
00579 bool DXFFile::
00580 get_group() {
00581   istream &in = *_in;
00582   do {
00583     in >> _code;
00584     if (!in) {
00585       change_state(ST_error);
00586       return false;
00587     }
00588     
00589     // Now skip past exactly one newline character and any number of
00590     // other whitespace characters.
00591     while (in!=0 && in.peek() != '\n') {
00592       in.get();
00593     }
00594     in.get();
00595     while (in!=0 && isspace(in.peek()) && in.peek() != '\n') {
00596       in.get();
00597     }
00598 
00599     getline(in, _string);
00600     _string = trim_right(_string);
00601     
00602     if (!in) {
00603       change_state(ST_error);
00604       return false;
00605     }
00606 
00607     // If we just read a comment, go back and get another one.
00608   } while (_code == 999);
00609 
00610   return true;
00611 }
00612 
00613 
00614 ////////////////////////////////////////////////////////////////////
00615 //     Function: DXFFile::change_state
00616 //       Access: Protected
00617 //  Description: Called as new nodes are read to update the internal
00618 //               state correctly.
00619 ////////////////////////////////////////////////////////////////////
00620 void DXFFile::
00621 change_state(State new_state) {
00622   if (_state == ST_verts) {
00623     done_vertex();
00624     _p.set(0.0, 0.0, 0.0);
00625     _q.set(0.0, 0.0, 0.0);
00626     _r.set(0.0, 0.0, 0.0);
00627     _s.set(0.0, 0.0, 0.0);
00628   }
00629   if ((_state == ST_entity || _state == ST_verts) &&
00630       new_state != ST_verts) {
00631     // We finish an entity when we read a new entity, or when we've
00632     // read the last vertex (if we were scanning the vertices after an
00633     // entity).
00634     done_entity();
00635     reset_entity();
00636   }
00637   switch (new_state) {
00638   case ST_top:
00639     end_section();
00640     break;
00641 
00642   case ST_done:
00643     end_file();
00644     break;
00645 
00646   default:
00647     break;
00648   }
00649   _state = new_state;
00650 }
00651 
00652 
00653 ////////////////////////////////////////////////////////////////////
00654 //     Function: DXFFile::change_section
00655 //       Access: Protected
00656 //  Description:
00657 ////////////////////////////////////////////////////////////////////
00658 void DXFFile::
00659 change_section(Section new_section) {
00660   change_state(ST_section);
00661   _section = new_section;
00662   begin_section();
00663 }
00664 
00665 
00666 ////////////////////////////////////////////////////////////////////
00667 //     Function: DXFFile::change_layer
00668 //       Access: Protected
00669 //  Description: Given a newly read layer name, sets the _layer
00670 //               pointer to point to the associate layer.  If the
00671 //               layer name has not been encountered before, creates a
00672 //               new layer definition.
00673 ////////////////////////////////////////////////////////////////////
00674 void DXFFile::
00675 change_layer(const string &layer_name) {
00676   if (_layer == NULL || _layer->get_name() != layer_name) {
00677     _layer = _layers.get_layer(layer_name, this);
00678   }
00679 }
00680 
00681 
00682 ////////////////////////////////////////////////////////////////////
00683 //     Function: DXFFile::change_entity
00684 //       Access: Protected
00685 //  Description:
00686 ////////////////////////////////////////////////////////////////////
00687 void DXFFile::
00688 change_entity(Entity new_entity) {
00689   if (new_entity == EN_vertex && _vertices_follow) {
00690     // If we read a new vertex and we're still scanning the vertices
00691     // that follow an entity, keep scanning it--we haven't finished
00692     // the entity yet.
00693     change_state(ST_verts);
00694 
00695   } else {
00696     // Otherwise, begin a new entity.
00697     change_state(ST_entity);
00698     _entity = new_entity;
00699   }
00700 }
00701 
00702 
00703 ////////////////////////////////////////////////////////////////////
00704 //     Function: DXFFile::reset_entity
00705 //       Access: Protected
00706 //  Description: Resets the current entity to its initial, default
00707 //               state prior to reading a new entity.
00708 ////////////////////////////////////////////////////////////////////
00709 void DXFFile::
00710 reset_entity() {
00711   _p.set(0.0, 0.0, 0.0);
00712   _q.set(0.0, 0.0, 0.0);
00713   _r.set(0.0, 0.0, 0.0);
00714   _s.set(0.0, 0.0, 0.0);
00715   _z.set(0.0, 0.0, 1.0);
00716   _vertices_follow = false;
00717   //_color_index = -1;
00718 
00719   _verts.erase(_verts.begin(), _verts.end());
00720 }
00721 
00722 
00723 ////////////////////////////////////////////////////////////////////
00724 //     Function: DXFFile::state_top
00725 //       Access: Protected
00726 //  Description: Does the DXF processing when we are at the top of the
00727 //               file, outside of any section.
00728 ////////////////////////////////////////////////////////////////////
00729 void DXFFile::
00730 state_top() {
00731   if (_code != 0) {
00732     nout << "Group code 0 not found at top level; found code " << _code
00733          << " instead.\n";
00734     change_state(ST_error);
00735   } else {
00736     if (_string == "SECTION") {
00737       if (get_group()) {
00738         if (_code != 2) {
00739           nout << "Group code 0 not immediately followed by code 2; found code " 
00740                << _code << " instead.\n";
00741         } else {
00742           if (_string == "HEADER") {
00743             change_section(SE_header);
00744           } else if (_string == "TABLES") {
00745             change_section(SE_tables);
00746           } else if (_string == "BLOCKS") {
00747             change_section(SE_blocks);
00748           } else if (_string == "ENTITIES") {
00749             change_section(SE_entities);
00750           } else if (_string == "OBJECTS") {
00751             change_section(SE_objects);
00752           } else {
00753             change_section(SE_unknown);
00754           }
00755         }
00756       }
00757     } else if (_string == "EOF") {
00758       change_state(ST_done);
00759     } else {
00760       nout << "Unexpected section at top level: '" << _string << "'\n";
00761       change_state(ST_error);
00762     }
00763   }
00764 }
00765 
00766 
00767 
00768 ////////////////////////////////////////////////////////////////////
00769 //     Function: DXFFile::state_section
00770 //       Access: Protected
00771 //  Description: Does the DXF processing when we are within some
00772 //               section.
00773 ////////////////////////////////////////////////////////////////////
00774 void DXFFile::
00775 state_section() {
00776   string tail;
00777 
00778   switch (_code) {
00779   case 0:
00780     if (_string == "ENDSEC") {
00781       change_state(ST_top);
00782     } else {
00783       if (_section == SE_entities) {
00784         if (_string == "3DFACE") {
00785           change_entity(EN_3dface);
00786         } else if (_string == "POINT") {
00787           change_entity(EN_point);
00788         } else if (_string == "INSERT") {
00789           change_entity(EN_insert);
00790         } else if (_string == "VERTEX") {
00791           change_entity(EN_vertex);
00792         } else if (_string == "POLYLINE") {
00793           change_entity(EN_polyline);
00794         } else {
00795           change_entity(EN_unknown);
00796         }
00797       }
00798     }
00799     break;
00800 
00801   case 8:
00802     change_layer(_string);
00803     break;
00804 
00805   case 62:  // Color.
00806     _color_index = string_to_int(_string, tail);
00807     break;
00808 
00809   default:
00810     break;
00811   }
00812 }
00813 
00814 
00815 ////////////////////////////////////////////////////////////////////
00816 //     Function: DXFFile::state_entity
00817 //       Access: Protected
00818 //  Description: Does the DXF processing when we are reading an
00819 //               entity.
00820 ////////////////////////////////////////////////////////////////////
00821 void DXFFile::
00822 state_entity() {
00823   string tail;
00824 
00825   switch (_code) {
00826   case 0:
00827     state_section();
00828     break;
00829 
00830   case 8:
00831     change_layer(_string);
00832     break;
00833 
00834   case 10:
00835     _p[0] = string_to_double(_string, tail);
00836     break;
00837 
00838   case 11:
00839     _q[0] = string_to_double(_string, tail);
00840     break;
00841 
00842   case 12:
00843     _r[0] = string_to_double(_string, tail);
00844     break;
00845 
00846   case 13:
00847     _s[0] = string_to_double(_string, tail);
00848     break;
00849 
00850   case 20:
00851     _p[1] = string_to_double(_string, tail);
00852     break;
00853 
00854   case 21:
00855     _q[1] = string_to_double(_string, tail);
00856     break;
00857 
00858   case 22:
00859     _r[1] = string_to_double(_string, tail);
00860     break;
00861 
00862   case 23:
00863     _s[1] = string_to_double(_string, tail);
00864     break;
00865 
00866   case 30:
00867     _p[2] = string_to_double(_string, tail);
00868     break;
00869 
00870   case 31:
00871     _q[2] = string_to_double(_string, tail);
00872     break;
00873 
00874   case 32:
00875     _r[2] = string_to_double(_string, tail);
00876     break;
00877 
00878   case 33:
00879     _s[2] = string_to_double(_string, tail);
00880     break;
00881 
00882   case 62:  // Color.
00883     _color_index = string_to_int(_string, tail);
00884     break;
00885 
00886   case 66:  // Vertices-follow.
00887     _vertices_follow = (string_to_int(_string, tail) != 0);
00888     break;
00889 
00890   case 70:  // Polyline flags.
00891     _flags = string_to_int(_string, tail);
00892     break;
00893 
00894   case 210:
00895     _z[0] = string_to_double(_string, tail);
00896     break;
00897 
00898   case 220:
00899     _z[1] = string_to_double(_string, tail);
00900     break;
00901 
00902   case 230:
00903     _z[2] = string_to_double(_string, tail);
00904     break;
00905 
00906   default:
00907     break;
00908   }
00909 }
00910 
00911 
00912 ////////////////////////////////////////////////////////////////////
00913 //     Function: DXFFile::state_verts
00914 //       Access: Protected
00915 //  Description: Does the DXF processing when we are reading the list
00916 //               of vertices that might follow an entity.
00917 ////////////////////////////////////////////////////////////////////
00918 void DXFFile::
00919 state_verts() {
00920   string tail;
00921 
00922   switch (_code) {
00923   case 0:
00924     state_section();
00925     break;
00926 
00927   case 8:
00928     change_layer(_string);
00929     break;
00930 
00931   case 10:
00932     _p[0] = string_to_double(_string, tail);
00933     break;
00934 
00935   case 20:
00936     _p[1] = string_to_double(_string, tail);
00937     break;
00938 
00939   case 30:
00940     _p[2] = string_to_double(_string, tail);
00941     break;
00942 
00943   default:
00944     break;
00945   }
00946 }
00947 
00948 
00949 ostream &operator << (ostream &out, const DXFFile::State &state) {
00950   switch (state) {
00951   case DXFFile::ST_top:
00952     return out << "ST_top";
00953   case DXFFile::ST_section:
00954     return out << "ST_section";
00955   case DXFFile::ST_entity:
00956     return out << "ST_entity";
00957   case DXFFile::ST_verts:
00958     return out << "ST_verts";
00959   case DXFFile::ST_error:
00960     return out << "ST_error";
00961   case DXFFile::ST_done:
00962     return out << "ST_done";
00963   }
00964   return out << "Unknown state";
00965 }
00966 
00967 ostream &operator << (ostream &out, const DXFFile::Section &section) {
00968   switch (section) {
00969   case DXFFile::SE_unknown:
00970     return out << "SE_unknown";
00971   case DXFFile::SE_header:
00972     return out << "SE_header";
00973   case DXFFile::SE_tables:
00974     return out << "SE_tables";
00975   case DXFFile::SE_blocks:
00976     return out << "SE_blocks";
00977   case DXFFile::SE_entities:
00978     return out << "SE_entities";
00979   case DXFFile::SE_objects:
00980     return out << "SE_objects";
00981   }
00982   return out << "Unknown section";
00983 }
00984 
00985 ostream &operator << (ostream &out, const DXFFile::Entity &entity) {
00986   switch (entity) {
00987   case DXFFile::EN_unknown:
00988     return out << "EN_unknown";
00989   case DXFFile::EN_3dface:
00990     return out << "EN_3dface";
00991   case DXFFile::EN_point:
00992     return out << "EN_point";
00993   case DXFFile::EN_insert:
00994     return out << "EN_insert";
00995   case DXFFile::EN_vertex:
00996     return out << "EN_vertex";
00997   case DXFFile::EN_polyline:
00998     return out << "EN_polyline";
00999   }
01000   return out << "Unknown entity";
01001 }
01002 
 All Classes Functions Variables Enumerations