Panda3D
|
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 §ion) { 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