Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

DxfFile.C

Go to the documentation of this file.
00001 /*---------------------------------------------------------------------+
00002  | Library QgarLib, graphics analysis and recognition                  |
00003  | Copyright (C) 2002  Qgar Project, LORIA                             |
00004  |                                                                     |
00005  | This library is free software; you can redistribute it and/or       |
00006  | modify it under the terms of the GNU Lesser General Public          |
00007  | License version 2.1, as published by the Free Software Foundation.  |
00008  |                                                                     |
00009  | This library is distributed in the hope that it will be useful,     |
00010  | but WITHOUT ANY WARRANTY; without even the implied warranty of      |
00011  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.                |
00012  | See the GNU Lesser General Public License for more details.         |
00013  |                                                                     |
00014  | The GNU Lesser General Public License is included in the file       |
00015  | LICENSE.LGPL, in the root directory of the Qgar packaging. See      |
00016  | http://www.gnu.org/licenses/lgpl.html for the terms of the licence. |
00017  | To receive a paper copy, write to the Free Software Foundation,     |
00018  | Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.       |
00019  |                                                                     |
00020  | Contact Project Qgar for any information:                           |
00021  |   LORIA - équipe Qgar                                               |
00022  |   B.P. 239, 54506 Vandoeuvre-lès-Nancy Cedex, France                |
00023  |   email: qgar-contact@loria.fr                                      |
00024  |   http://www.qgar.org/                                              |
00025  *---------------------------------------------------------------------*/
00026 
00027 
00028 /**
00029  * @file   DxfFile.C
00030  * @brief  Implementation of class qgar::DxfFile.
00031  *
00032  * See file DxfFile.H for the interface.
00033  *
00034  * @author <a href="mailto:qgar-develop@loria.fr?subject=Qgar fwd Philippe Dosch">Philippe Dosch</a>
00035  * @date   Jul 4, 2001  16:15
00036  * @since  qgar 1.0
00037  */
00038 
00039 
00040 // STL
00041 #include <algorithm>
00042 #include <cstdlib>
00043 #include <cstring>
00044 #include <ctime>
00045 #include <deque>
00046 #include <iterator>
00047 #include <sstream>
00048 // QGAR
00049 #include <qgarlib/AbstractGenPointChain.H>
00050 #include <qgarlib/BoundingBox.H>
00051 #include <qgarlib/ConnectedComponents.H>
00052 #include <qgarlib/DxfFile.H>
00053 #include <qgarlib/GenPointChain.H>
00054 #include <qgarlib/primitives.H>
00055 #include <qgarlib/QgarErrorDeveloper.H>
00056 #include <qgarlib/QgarErrorIO.H>
00057 #include <qgarlib/stl.H>
00058 
00059 
00060 using namespace std;
00061 
00062 
00063 namespace qgar
00064 {
00065 
00066 
00067 // ---------------------------------------------------------------------
00068 // S T A T I C   C O N S T A N T S
00069 // ---------------------------------------------------------------------
00070 
00071 
00072 // Table to convert Qgar colors into DXF colors
00073 const int DxfFile::_s_dxf_colors[] =
00074 {
00075   7,   // QGE_COLOR_NONE             -> DXF black
00076   7,   // QGE_COLOR_DEFAULT          -> DXF black
00077   7,   // QGE_COLOR_BLACK            -> DXF black
00078   8,   // QGE_COLOR_DARK_GRAY        -> DXF gray
00079   8,   // QGE_COLOR_GRAY             -> DXF gray
00080   8,   // QGE_COLOR_LIGHT_GRAY       -> DXF gray
00081   15,  // QGE_COLOR_WHITE            -> DXF white
00082   6,   // QGE_COLOR_MAGENTA          -> DXF magenta
00083   6,   // QGE_COLOR_PURPLE           -> DXF magenta
00084   4,   // QGE_COLOR_CYAN             -> DXF cyan
00085   5,   // QGE_COLOR_MEDIUM_BLUE      -> DXF blue
00086   5,   // QGE_COLOR_BLUE             -> DXF blue
00087   3,   // QGE_COLOR_OLIVE_GREEN      -> DXF green
00088   3,   // QGE_COLOR_DARK_GREEN       -> DXF green
00089   3,   // QGE_COLOR_GREEN            -> DXF green
00090   2,   // QGE_COLOR_YELLOW           -> DXF yellow
00091   1,   // QGE_COLOR_ORANGE           -> DXF red
00092   1,   // QGE_COLOR_RED              -> DXF red
00093   1,   // QGE_COLOR_PINK             -> DXF red
00094   1,   // QGE_COLOR_SALMON_PINK      -> DXF red
00095   7,   // QGE_COLOR_BROWN            -> DXF black
00096   7    // QGE_COLOR_CHOCOLATE_BROWN  -> DXF black
00097 };
00098 
00099 
00100 // DXF codes
00101 const int DxfFile::_s_dxf_code_com      = 999; // Comment
00102 const int DxfFile::_s_dxf_code_ident    = 0;   // Identifier
00103 const int DxfFile::_s_dxf_code_name     = 2;   // Name
00104 const int DxfFile::_s_dxf_code_color   = 62;   // Color
00105 const int DxfFile::_s_dxf_code_x1       = 10;  // X1
00106 const int DxfFile::_s_dxf_code_x2       = 11;  // X2
00107 const int DxfFile::_s_dxf_code_y1       = 20;  // Y1
00108 const int DxfFile::_s_dxf_code_y2       = 21;  // Y2
00109 const int DxfFile::_s_dxf_code_thick    = 39;  // Thickness
00110 const int DxfFile::_s_dxf_code_radius   = 40;  // Radius / total pattern length
00111 const int DxfFile::_s_dxf_code_start    = 50;  // Start angle
00112 const int DxfFile::_s_dxf_code_end      = 51;  // End angle
00113 const int DxfFile::_s_dxf_code_flag     = 70;  // Standard flag value
00114 const int DxfFile::_s_dxf_code_lintp    = 3;   // Descriptive text for linetype
00115 const int DxfFile::_s_dxf_code_algt     = 72;  // Alignment code
00116 const int DxfFile::_s_dxf_code_dash     = 73;  // Number of dash length items
00117 const int DxfFile::_s_dxf_code_ltp      = 6;   // Ltype name
00118 const int DxfFile::_s_dxf_code_layer    = 8;   // Layer name
00119 const int DxfFile::_s_dxf_code_elev     = 38;  // Elevation
00120 const int DxfFile::_s_dxf_code_vertflag = 66;  // Vertices flag
00121 const int DxfFile::_s_dxf_code_txthght  = 40;  // Text height
00122 const int DxfFile::_s_dxf_code_txt      = 1;   // Text value
00123 
00124 
00125 // DXF tags
00126 const char* const DxfFile::_s_dxf_tag_sec   = "SECTION";
00127 const char* const DxfFile::_s_dxf_tag_tbs   = "TABLES";
00128 const char* const DxfFile::_s_dxf_tag_tbl   = "TABLE";
00129 const char* const DxfFile::_s_dxf_tag_layer = "LAYER";
00130 const char* const DxfFile::_s_dxf_tag_ltp   = "LTYPE";
00131 const char* const DxfFile::_s_dxf_tag_ent   = "ENTITIES";
00132 const char* const DxfFile::_s_dxf_tag_arc   = "ARC";
00133 const char* const DxfFile::_s_dxf_tag_seg   = "LINE";
00134 const char* const DxfFile::_s_dxf_tag_polyl = "POLYLINE";
00135 const char* const DxfFile::_s_dxf_tag_vert  = "VERTEX";
00136 const char* const DxfFile::_s_dxf_tag_eof   = "EOF";
00137 const char* const DxfFile::_s_dxf_tag_end   = "ENDSEC";
00138 const char* const DxfFile::_s_dxf_tag_etb   = "ENDTAB";
00139 const char* const DxfFile::_s_dxf_tag_esq   = "SEQEND";
00140 const char* const DxfFile::_s_dxf_tag_txt   = "TEXT";
00141 
00142 
00143 // DXF comments
00144 const char* const DxfFile::_s_dxf_com_create = "** Created by Qgar on ";
00145 const char* const DxfFile::_s_dxf_com_def    = "** Definitions";
00146 const char* const DxfFile::_s_dxf_com_ltp    = "** Linetype definitions";
00147 const char* const DxfFile::_s_dxf_com_layer  = "** Layer definitions";
00148 const char* const DxfFile::_s_dxf_com_ent    = "** Entities";
00149 const char* const DxfFile::_s_dxf_com_seg    = "** Segment";
00150 const char* const DxfFile::_s_dxf_com_arc    = "** Arc";
00151 const char* const DxfFile::_s_dxf_com_dwall  = "** Dividing wall";
00152 const char* const DxfFile::_s_dxf_com_bwall  = "** Bearing wall";
00153 const char* const DxfFile::_s_dxf_com_swind  = "** Simple window";
00154 const char* const DxfFile::_s_dxf_com_dwind  = "** Double window";
00155 const char* const DxfFile::_s_dxf_com_door   = "** Door";
00156 const char* const DxfFile::_s_dxf_com_stairs = "** Stairs";
00157 const char* const DxfFile::_s_dxf_com_pipe   = "** Pipe";
00158 const char* const DxfFile::_s_dxf_com_chain  = "** Chain";
00159 const char* const DxfFile::_s_dxf_com_polyl  = "** Polyline";
00160 const char* const DxfFile::_s_dxf_com_txt    = "** Text";
00161 
00162 
00163 // DXF defaults
00164 const char* const DxfFile::_s_dxf_default_cont = "CONTINUOUS";  // Linetype for LTYPE                  
00165 const char* const DxfFile::_s_dxf_default_dash = "DASHED";      // Linetype for LTYPE
00166 const char* const DxfFile::_s_dxf_default_dltp = "----";        // Descriptive for LTYPE
00167 const int    DxfFile::_s_dxf_default_ltp   = 1;  // Number of LTYPE
00168 const int    DxfFile::_s_dxf_default_fly   = 2;  // Flag value for LAYER
00169 const int    DxfFile::_s_dxf_default_layer = 8;  // Number of LAYERS
00170 const int    DxfFile::_s_dxf_default_flt   = 64; // Flag value for LTYPE
00171 const int    DxfFile::_s_dxf_default_alg   = 65; // Aligment value for LTYPE
00172 const int    DxfFile::_s_dxf_default_dash1 = 0;  // Dash length for LTYPE
00173 const int    DxfFile::_s_dxf_default_dash2 = 2;  // Dash length for LTYPE
00174 const double DxfFile::_s_dxf_default_pat1  = 0.; // Total length pattern for LTYPE
00175 const double DxfFile::_s_dxf_default_pat2  = 2.; // Total length pattern for LTYPE
00176 const int    DxfFile::_s_dxf_default_wpo   = 1;  // Default thickness for POLYLINE
00177 const int    DxfFile::_s_dxf_default_vfg   = 1;  // Vertices follow POLYLINE definition
00178 const int    DxfFile::_s_dxf_default_pfgo  = 0;  // Polylines are opened
00179 const int    DxfFile::_s_dxf_default_pfgc  = 1;  // Polylines are closed
00180 
00181 
00182 // DXF layers
00183 const char* const DxfFile::_s_dxf_layer_prm    = "PRIMITIVE";
00184 const char* const DxfFile::_s_dxf_layer_dwall  = "DIVWALL";
00185 const char* const DxfFile::_s_dxf_layer_bwall  = "BEARWALL";
00186 const char* const DxfFile::_s_dxf_layer_swind  = "SIMWIN";
00187 const char* const DxfFile::_s_dxf_layer_dwind  = "DOUWIN";
00188 const char* const DxfFile::_s_dxf_layer_door   = "DOOR";
00189 const char* const DxfFile::_s_dxf_layer_stairs = "STAIRS";
00190 const char* const DxfFile::_s_dxf_layer_pipe   = "PIPE";
00191 const char* const DxfFile::_s_dxf_layer_chain  = "CHAINE";
00192 const char* const DxfFile::_s_dxf_layer_polyl  = "POLYLINE";
00193 const char* const DxfFile::_s_dxf_layer_txt    = "TEXT";
00194 
00195 
00196 //  Maximum length of a DXF field
00197 const unsigned int DxfFile::_s_dxf_maxbuf = 256;
00198 
00199 
00200 // ---------------------------------------------------------------------
00201 // C O N S T R U C T O R S
00202 // ---------------------------------------------------------------------
00203 
00204 
00205 // INITIALIZE WITH GIVEN FILE NAME
00206 
00207 DxfFile::DxfFile(const char* aFileName)
00208 
00209   : AbstractGraphicsFile(aFileName),
00210     _maxX(0),
00211     _maxY(0),
00212     _lastGroup(new char[_s_dxf_maxbuf])
00213 
00214 {
00215   // VOID
00216 }
00217 
00218 
00219 // ---------------------------------------------------------------------
00220 // D E S T R U C T O R
00221 // ---------------------------------------------------------------------
00222 
00223 
00224 DxfFile::~DxfFile()
00225 {
00226   delete [] _lastGroup;
00227 
00228   // Free all allocated graphical objects
00229   for_each(_segmentList.begin(),  _segmentList.end(),  qstlDeleteObject());
00230   for_each(_arcList.begin(),      _arcList.end(),      qstlDeleteObject());
00231   for_each(_chainList.begin(),    _chainList.end(),    qstlDeleteObject());
00232   for_each(_polylineList.begin(), _polylineList.end(), qstlDeleteObject());
00233 }
00234 
00235 
00236 // -------------------------------------------------------------------
00237 // H E A D E R   &   F O O T E R 
00238 // -------------------------------------------------------------------
00239 
00240 
00241 // READ THE HEADER OF A DXF FILE
00242 
00243 void
00244 DxfFile::readHeader()
00245 
00246   throw(QgarErrorIO)
00247 
00248 {
00249   if (retrieveDxfGroup() == _s_dxf_code_ident)
00250     {
00251       if (!strcmp(_lastGroup, _s_dxf_tag_sec))
00252         {
00253           do
00254             {
00255               // Read to the next name or identifier
00256               while ((retrieveDxfGroup() != _s_dxf_code_name)
00257                      && (_lastGroupCode != _s_dxf_code_ident))
00258                 {
00259                   // VOID
00260                 }
00261               // Entities?
00262               if ((_lastGroupCode == _s_dxf_code_name)
00263                   && (!strcmp(_lastGroup, _s_dxf_tag_ent)))
00264                 {
00265                   retrieveDxfGroup();
00266                   return;
00267                 }
00268             }
00269           // End reached?
00270           while ((_lastGroupCode != _s_dxf_code_ident)
00271                  || strcmp(_lastGroup, _s_dxf_tag_eof));
00272         }
00273     }
00274   else
00275     {
00276       std::ostringstream os;
00277       os << "Bad header in file "
00278          << _fileName;
00279       throw QgarErrorIO(__FILE__, __LINE__,
00280                         "void qgar::DxfFile::readHeader()",
00281                         os.str());
00282     }
00283 }
00284 
00285 
00286 // WRITE THE HEADER OF A DXF FILE
00287 
00288 void
00289 DxfFile::writeHeader()
00290 {
00291   time_t date;
00292   time(&date);
00293   _fileStream << _s_dxf_code_com
00294               << std::endl
00295               << _s_dxf_com_create
00296               << asctime(localtime(&date));
00297 
00298   saveDxfGroup(_s_dxf_code_ident, _s_dxf_tag_sec);
00299 
00300   // 1 - Definition of LTYPE & LAYERS
00301   saveDxfGroup(_s_dxf_code_com,  _s_dxf_com_def);
00302   saveDxfGroup(_s_dxf_code_name, _s_dxf_tag_tbs);
00303 
00304   // 2 - Header for LTYPE
00305   saveDxfGroup(_s_dxf_code_com,   _s_dxf_com_ltp);
00306   saveDxfGroup(_s_dxf_code_ident, _s_dxf_tag_tbl);
00307   saveDxfGroup(_s_dxf_code_name,  _s_dxf_tag_ltp);
00308   saveDxfGroup(_s_dxf_code_flag,  _s_dxf_default_ltp);
00309 
00310   // 3 - LTYPE Continuous
00311   saveDxfGroup(_s_dxf_code_ident,  _s_dxf_tag_ltp);
00312   saveDxfGroup(_s_dxf_code_name,   _s_dxf_default_cont);
00313   saveDxfGroup(_s_dxf_code_flag,   _s_dxf_default_flt);
00314   saveDxfGroup(_s_dxf_code_lintp,  _s_dxf_default_dltp);
00315   saveDxfGroup(_s_dxf_code_algt,   _s_dxf_default_alg);
00316   saveDxfGroup(_s_dxf_code_dash,   _s_dxf_default_dash1);
00317   saveDxfGroup(_s_dxf_code_radius, _s_dxf_default_pat1);
00318 
00319   // 4 - LTYPE Dashed
00320   saveDxfGroup(_s_dxf_code_ident,  _s_dxf_tag_ltp);
00321   saveDxfGroup(_s_dxf_code_name,   _s_dxf_default_dash);
00322   saveDxfGroup(_s_dxf_code_flag,   _s_dxf_default_flt);
00323   saveDxfGroup(_s_dxf_code_lintp,  _s_dxf_default_dltp);
00324   saveDxfGroup(_s_dxf_code_algt,   _s_dxf_default_alg);
00325   saveDxfGroup(_s_dxf_code_dash,   _s_dxf_default_dash2);
00326   saveDxfGroup(_s_dxf_code_radius, _s_dxf_default_pat2);
00327   saveDxfGroup(_s_dxf_code_ident,  _s_dxf_tag_etb);
00328 
00329   // 5 - Header for LAYERS
00330   saveDxfGroup(_s_dxf_code_com,   _s_dxf_com_layer);
00331   saveDxfGroup(_s_dxf_code_ident, _s_dxf_tag_tbl);
00332   saveDxfGroup(_s_dxf_code_name,  _s_dxf_tag_ltp);
00333   saveDxfGroup(_s_dxf_code_flag,  _s_dxf_default_layer);
00334 
00335   // 6 - LAYERS
00336   saveDxfLayer(_s_dxf_layer_prm,   _s_dxf_default_fly, _s_dxf_colors[QGE_COLOR_BLACK],  _s_dxf_default_cont);
00337   saveDxfLayer(_s_dxf_layer_dwall, _s_dxf_default_fly, _s_dxf_colors[QGE_COLOR_GRAY],   _s_dxf_default_cont);
00338   saveDxfLayer(_s_dxf_layer_bwall, _s_dxf_default_fly, _s_dxf_colors[QGE_COLOR_GRAY],   _s_dxf_default_cont);
00339   saveDxfLayer(_s_dxf_layer_swind, _s_dxf_default_fly, _s_dxf_colors[QGE_COLOR_BLUE],   _s_dxf_default_cont);
00340   saveDxfLayer(_s_dxf_layer_dwind, _s_dxf_default_fly, _s_dxf_colors[QGE_COLOR_BLUE],   _s_dxf_default_cont);
00341   saveDxfLayer(_s_dxf_layer_door,  _s_dxf_default_fly, _s_dxf_colors[QGE_COLOR_RED],    _s_dxf_default_cont);
00342   saveDxfLayer(_s_dxf_layer_stairs,_s_dxf_default_fly, _s_dxf_colors[QGE_COLOR_GREEN],  _s_dxf_default_cont);
00343   saveDxfLayer(_s_dxf_layer_pipe,  _s_dxf_default_fly, _s_dxf_colors[QGE_COLOR_YELLOW], _s_dxf_default_cont);
00344   saveDxfLayer(_s_dxf_layer_chain, _s_dxf_default_fly, _s_dxf_colors[QGE_COLOR_BLUE],   _s_dxf_default_cont);
00345   saveDxfLayer(_s_dxf_layer_polyl, _s_dxf_default_fly, _s_dxf_colors[QGE_COLOR_BLACK],  _s_dxf_default_cont);
00346 
00347   saveDxfGroup(_s_dxf_code_ident, _s_dxf_tag_etb);
00348   saveDxfGroup(_s_dxf_code_ident, _s_dxf_tag_end);
00349 
00350   // 7 - Header for ENTITIES
00351   saveDxfGroup(_s_dxf_code_com,   _s_dxf_com_ent);
00352   saveDxfGroup(_s_dxf_code_ident, _s_dxf_tag_sec);
00353   saveDxfGroup(_s_dxf_code_name,  _s_dxf_tag_ent);
00354 }
00355 
00356 
00357 // WRITE THE FOOTER OF A DXF FILE
00358 
00359 void
00360 DxfFile::writeFooter()
00361 {
00362   saveDxfGroup(_s_dxf_code_ident, _s_dxf_tag_end);
00363   saveDxfGroup(_s_dxf_code_ident, _s_dxf_tag_eof);
00364 }
00365 
00366 
00367 // ---------------------------------------------------------------------
00368 // B U F F E R E D   I N P U T
00369 // ----------------------------------------------------------------------
00370 
00371 
00372 // READ ALL DXF ENTITIES CONTAINED IN THE FILE
00373 
00374 void
00375 DxfFile::read(bool convertPolylines)
00376 
00377   throw(QgarErrorIO)
00378 
00379 {
00380   isOpenR();
00381 
00382   // Qgar entities are recognized using the category of DXF entities
00383   bool endReached = false;
00384   while(!endReached)
00385     {
00386     if (_lastGroupCode == _s_dxf_code_ident)
00387       {
00388         // Block 1
00389         if (!(strcmp(_lastGroup, _s_dxf_tag_seg)))
00390           {
00391             retrieveQgarSegment(_segmentList);
00392           }
00393         else
00394           {
00395             // Block 2
00396             if (!(strcmp(_lastGroup, _s_dxf_tag_arc)))
00397               {
00398                 retrieveQgarArc(_arcList);
00399               }
00400             else
00401               {
00402                 // Block 3
00403                 if (!strcmp(_lastGroup, _s_dxf_tag_polyl))
00404                   {
00405                     retrieveChainOrQgarPolyline(_chainList, _polylineList);
00406                   }
00407                 else
00408                   {
00409                     // Block 4
00410                     if (!strcmp(_lastGroup, _s_dxf_tag_eof))
00411                       {
00412                         endReached = true;
00413                       }
00414                     else
00415                       {
00416                         // Block 5
00417                         if (!strcmp(_lastGroup, _s_dxf_tag_end))
00418                           {
00419                             endReached = true;
00420                           }
00421                         else
00422                           {
00423                             std::ostringstream os;
00424                             os << "Junk in file: "
00425                                << _fileName;
00426                             throw QgarErrorIO(__FILE__, __LINE__,
00427                                               "void qgar::DxfFile::read(bool)",
00428                                               os.str());
00429                           }
00430                       } // END Block 5
00431                   }  // END Block 4
00432               } // END Block 3
00433           } // END Block 2
00434       } // END Block 1
00435     else
00436       {
00437       retrieveDxfGroup();
00438       }
00439     } // END while
00440 
00441   if (convertPolylines)
00442     {
00443       list<QgarPolyline*>::iterator itPLL;
00444       for (itPLL = _polylineList.begin();
00445            itPLL != _polylineList.end();
00446            ++itPLL)
00447         {
00448           // Transform polyline into a list of segments
00449           list<QgarSegment> segList = (*itPLL)->toQgarSegList();
00450           
00451           for(list<QgarSegment>::iterator it = segList.begin();
00452               it != segList.end();
00453               ++it)
00454             {
00455               _segmentList.push_back(new QgarSegment(*it));
00456             }
00457 
00458           // Polyline is no longer needed.
00459           delete *itPLL;
00460         }
00461       _polylineList.clear();
00462     }
00463 }
00464 
00465 
00466 // ---------------------------------------------------------------------
00467 // O U T P U T   C H A I N S
00468 // ----------------------------------------------------------------------
00469 
00470 
00471 // CHAIN OF INTEGER POINTS
00472 
00473 void
00474 DxfFile::write(AbstractGenPointChain<int>& aChain,
00475                int aThickness,
00476                QGEcolor aColor)
00477 {
00478   isOpenW();
00479   saveChain(aChain, aThickness, aColor);
00480 }
00481 
00482 
00483 // CHAIN OF FLOAT POINTS
00484 
00485 void
00486 DxfFile::write(AbstractGenPointChain<float>& aChain,
00487                int aThickness,
00488                QGEcolor aColor)
00489 {
00490   isOpenW();
00491   saveChain(aChain, aThickness, aColor);
00492 }
00493 
00494 
00495 // CHAINS OF DOUBLE POINTS
00496 
00497 void
00498 DxfFile::write(AbstractGenPointChain<double>& aChain,
00499                int aThickness,
00500                QGEcolor aColor)
00501 {
00502   isOpenW();
00503   saveChain(aChain, aThickness, aColor);
00504 }
00505 
00506 
00507 // ---------------------------------------------------------------------
00508 // O U T P U T   S E G M E N T S 
00509 // ---------------------------------------------------------------------
00510 
00511 
00512 // SEGMENT WITH INTEGER COORDINATES
00513 
00514 void
00515 DxfFile::write(const GenSegment<int>& aSeg,
00516                int aThickness,
00517                QGEcolor aColor,
00518                QGEoutline anOutline)
00519 {
00520   isOpenW();
00521   saveSegment(aSeg.xSource(),
00522               aSeg.ySource(),
00523               aSeg.xTarget(),
00524               aSeg.yTarget(),
00525               aThickness,
00526               aColor,
00527               anOutline);
00528 }
00529 
00530 
00531 // SEGMENT WITH FLOAT COORDINATES
00532 
00533 void
00534 DxfFile::write(const GenSegment<float>& aSeg,
00535                int aThickness,
00536                QGEcolor aColor,
00537                QGEoutline anOutline)
00538 {
00539   isOpenW();
00540   saveSegment((int) aSeg.xSource(),
00541               (int) aSeg.ySource(),
00542               (int) aSeg.xTarget(),
00543               (int) aSeg.yTarget(),
00544               aThickness,
00545               aColor,
00546               anOutline);
00547 }
00548 
00549 
00550 // SEGMENT WITH DOUBLE COORDINATES
00551 
00552 void
00553 DxfFile::write(const GenSegment<double>& aSeg,
00554                int aThickness,
00555                QGEcolor aColor,
00556                QGEoutline anOutline)
00557 {
00558   isOpenW();
00559   saveSegment((int) aSeg.xSource(),
00560               (int) aSeg.ySource(),
00561               (int) aSeg.xTarget(),
00562               (int) aSeg.yTarget(),
00563               aThickness,
00564               aColor,
00565               anOutline);
00566 }
00567 
00568 
00569 // LIST OF QGAR SEGMENTS WITH INTEGER COORDINATES
00570 
00571 void
00572 DxfFile::write(const list<GenQgarSegment<int>*>& aQSegList,
00573                int aThickness,
00574                QGEcolor aColor,
00575                QGEoutline anOutline)
00576 {
00577   for (list<QgarSegment*>::const_iterator qsegListIter = aQSegList.begin() ;
00578        qsegListIter != aQSegList.end();
00579        qsegListIter++)
00580     {
00581       write((*qsegListIter)->accessGeomStructure(),
00582             aThickness,
00583             aColor,
00584             anOutline);
00585     }
00586 }
00587 
00588 
00589 // ---------------------------------------------------------------------
00590 // O U T P U T   A R C S
00591 // ---------------------------------------------------------------------
00592 
00593 
00594 // ARC WITH INTEGER COORDINATES
00595 
00596 void
00597 DxfFile::write(const GenArc<int>& anArc,
00598                int aThickness,
00599                QGEcolor aColor,
00600                QGEoutline anOutline)
00601 {
00602   isOpenW();
00603 
00604   saveArc(anArc.xSource(),
00605           anArc.ySource(),
00606           anArc.xTarget(),
00607           anArc.yTarget(),
00608           anArc.xCenter(),
00609           anArc.yCenter(),
00610           (int) anArc.sourceAngleDegrees(),
00611           (int) anArc.targetAngleDegrees(),
00612           (int) anArc.radius(),
00613           aThickness,
00614           aColor,
00615           anOutline);
00616 }
00617 
00618 
00619 // ARC WITH FLOAT COORDINATES
00620 
00621 void
00622 DxfFile::write(const GenArc<float>& anArc,
00623                int aThickness,
00624                QGEcolor aColor,
00625                QGEoutline anOutline)
00626 {
00627   isOpenW();
00628 
00629   saveArc((int) anArc.xSource(),
00630           (int) anArc.ySource(),
00631           (int) anArc.xTarget(),
00632           (int) anArc.yTarget(),
00633           (int) anArc.xCenter(),
00634           (int) anArc.yCenter(),
00635           (int) anArc.sourceAngleDegrees(),
00636           (int) anArc.targetAngleDegrees(),
00637           (int) anArc.radius(),
00638           aThickness,
00639           aColor,
00640           anOutline);
00641 }
00642 
00643 
00644 // ARC WITH DOUBLE COORDINATES
00645 
00646 void
00647 DxfFile::write(const GenArc<double>& anArc,
00648                int aThickness,
00649                QGEcolor aColor,
00650                QGEoutline anOutline)
00651 {
00652   isOpenW();
00653 
00654   saveArc((int) anArc.xSource(),
00655           (int) anArc.ySource(),
00656           (int) anArc.xTarget(),
00657           (int) anArc.yTarget(),
00658           (int) anArc.xCenter(),
00659           (int) anArc.yCenter(),
00660           (int) anArc.sourceAngleDegrees(),
00661           (int) anArc.targetAngleDegrees(),
00662           (int) anArc.radius(),
00663           aThickness,
00664           aColor,
00665           anOutline);
00666 }
00667 
00668 
00669 // LIST OF QGAR ARCS WITH INTEGER COORDINATES
00670 
00671 void
00672 DxfFile::write(std::list<GenQgarArc<int>*>& aQArcList,
00673                int aThickness,
00674                QGEcolor aColor,
00675                QGEoutline anOutline)
00676 {
00677   for (list<QgarArc*>::iterator qarcListIter = aQArcList.begin() ;
00678        qarcListIter != aQArcList.end() ;
00679        qarcListIter++)
00680     {
00681       write((*qarcListIter)->accessGeomStructure(),
00682             aThickness,
00683             aColor,
00684             anOutline);
00685     }
00686 }
00687 
00688 
00689 // ---------------------------------------------------------------------
00690 // O U T P U T   P O L Y L I N E S
00691 // ---------------------------------------------------------------------
00692 
00693 
00694 // INTEGER POLYLINE
00695 
00696 void
00697 DxfFile::write(const GenPolyline<int>& aPoly,
00698                int aThickness,
00699                QGEcolor aColor,
00700                QGEoutline anOutline)
00701 {
00702   isOpenW();
00703   savePolyline(aPoly, aThickness, aColor, anOutline);
00704 }
00705 
00706 
00707 // FLOAT POLYLINE
00708 
00709 void
00710 DxfFile::write(const GenPolyline<float>& aPoly,
00711                int aThickness,
00712                QGEcolor aColor,
00713                QGEoutline anOutline)
00714 {
00715   isOpenW();
00716   savePolyline(aPoly, aThickness, aColor, anOutline);
00717 }
00718 
00719 
00720 // DOUBLE POLYLINE
00721 
00722 void
00723 DxfFile::write(const GenPolyline<double>& aPoly,
00724                int aThickness,
00725                QGEcolor aColor,
00726                QGEoutline anOutline)
00727 {
00728   isOpenW();
00729   savePolyline(aPoly, aThickness, aColor, anOutline);
00730 }
00731 
00732 
00733 // ---------------------------------------------------------------------
00734 // O U T P U T   P O L Y G O N S 
00735 // ---------------------------------------------------------------------
00736 
00737 
00738 // POLYGON WITH INTEGER COORDINATES
00739 
00740 void
00741 DxfFile::write(GenPolygon<int>* aPolygon,
00742                int aThickness,
00743                QGEcolor aColor,
00744                QGEoutline anOutline)
00745 {
00746   std::list<Segment> segList = aPolygon->toSegList();
00747 
00748   for(std::list<Segment>::iterator itLSeg = segList.begin();
00749       itLSeg != segList.end();
00750       itLSeg++)
00751     {
00752       write(*itLSeg, aThickness, aColor, anOutline);
00753     }
00754 }
00755 
00756 
00757 // ---------------------------------------------------------------------
00758 // O U T P U T   B O U N D I N G   B O X E S
00759 // ---------------------------------------------------------------------
00760 
00761 
00762 // BOUNDING BOX WITH INTEGER COORDINATES
00763 
00764 void
00765 DxfFile::write(const BoundingBox& aBox,
00766                int aThickness,
00767                QGEcolor aColor,
00768                QGEoutline anOutline)
00769 {
00770   saveBox(aBox.xTopLeft(),
00771           aBox.yTopLeft(),
00772           aBox.xBottomRight(),
00773           aBox.yBottomRight(),
00774           aThickness,
00775           aColor,
00776           anOutline);
00777 }
00778 
00779 
00780 
00781 // ---------------------------------------------------------------------
00782 // O U T P U T   Q G A R   P R I M I T I V E S
00783 // ---------------------------------------------------------------------
00784 
00785 
00786 // void
00787 // DxfFile::write(list<AbstractGenQgarPrimitive<int>*>& aQPrimList,
00788 //                int aThickness,
00789 //                QGEcolor aColor,
00790 //                QGEoutline anOutline)
00791 // {
00792 //   for (list<AbstractGenQgarPrimitive<int>*>::iterator qpListIter
00793 //          = aQPrimList.begin();
00794 //        qpListIter != aQPrimList.end();
00795 //        qpListIter++)
00796 //     {
00797 //       (*qpListIter)->write(*this, aThickness, aColor, anOutline);
00798 //     }
00799 // }
00800 
00801 
00802 // ---------------------------------------------------------------------
00803 // O U T P U T   T E X T S
00804 // ---------------------------------------------------------------------
00805 
00806 
00807 void
00808 DxfFile::write(const char* aText,
00809                int         aX,
00810                int         aY,
00811                int         aHeight,
00812                QGEcolor    aColor)
00813 {
00814   isOpenW();
00815 
00816   saveDxfGroup(_s_dxf_code_com,   _s_dxf_com_txt);
00817   saveDxfGroup(_s_dxf_code_ident, _s_dxf_tag_txt);
00818   saveDxfGroup(_s_dxf_code_layer, _s_dxf_layer_txt);
00819 
00820   if (aColor != QGE_COLOR_DEFAULT)
00821     {
00822       saveDxfGroup(_s_dxf_code_color, _s_dxf_colors[aColor]);
00823     }
00824 
00825   saveDxfGroup(_s_dxf_code_txthght, aHeight);
00826   saveDxfGroup(_s_dxf_code_txt,     aText);
00827   saveDxfGroup(_s_dxf_code_x1,      aX);
00828   saveDxfGroup(_s_dxf_code_y1,      aY);
00829 }
00830 
00831 
00832 // ---------------------------------------------------------------------
00833 // AUXILIARIES: SAVE DXF ENTITIES INTO THE FILE
00834 // ---------------------------------------------------------------------
00835 
00836 
00837 // SAVE A DXF GROUP
00838 
00839 template <class T>
00840 void
00841 DxfFile::saveDxfGroup(int aCode, const T aGroup)
00842 {
00843   char buf[4];
00844 
00845   sprintf(buf, "%3d", aCode);
00846   _fileStream << buf
00847               << std::endl
00848               << aGroup
00849               << std::endl;
00850 }
00851 
00852 
00853 // SAVE THE DEFINITION OF A LAYER
00854 
00855 void
00856 DxfFile::saveDxfLayer(const char* aName,
00857                    int         aFlag,
00858                    int         aColor,
00859                    const char* aLType)
00860 {
00861   saveDxfGroup(_s_dxf_code_ident, _s_dxf_tag_layer);
00862   saveDxfGroup(_s_dxf_code_name,  aName);
00863   saveDxfGroup(_s_dxf_code_flag,  aFlag);
00864   saveDxfGroup(_s_dxf_code_color, aColor);
00865   saveDxfGroup(_s_dxf_code_ltp,   aLType);
00866 }
00867 
00868 
00869 // SAVE COMMON FEATURES
00870 
00871 void
00872 DxfFile::saveDxfFeatures(const char* aLayer,
00873                       int      aThickness,
00874                       QGEcolor aColor,
00875                       bool     isDashed)
00876 {
00877   saveDxfGroup(_s_dxf_code_layer, aLayer);
00878 
00879   if (aColor != QGE_COLOR_DEFAULT)
00880     {
00881       saveDxfGroup(_s_dxf_code_color, _s_dxf_colors[aColor]);
00882     }
00883   if (aThickness != 1)
00884     {
00885     saveDxfGroup(_s_dxf_code_thick, aThickness);
00886     }
00887   if (isDashed)
00888     {
00889     saveDxfGroup(_s_dxf_code_ltp, _s_dxf_default_dash);
00890     }
00891 }
00892 
00893 
00894 // ---------------------------------------------------------------------
00895 // AUXILIARIES: SAVE PRIMITIVES IN THE FILE
00896 // ---------------------------------------------------------------------
00897 
00898 
00899 // SAVE A CHAIN OF POINTS WITH COORDINATES OF TYPE 'T'
00900 
00901 template <class T>
00902 void
00903 DxfFile::saveChain(AbstractGenPointChain<T>& aChain,
00904                    int aThickness,
00905                    QGEcolor aColor)
00906 {
00907   // 1 - Header of the polyline
00908 
00909   saveDxfGroup(_s_dxf_code_com,   _s_dxf_com_chain);
00910   saveDxfGroup(_s_dxf_code_ident, _s_dxf_tag_polyl);
00911 
00912   saveDxfFeatures(_s_dxf_layer_chain,
00913                aThickness,
00914                aColor,
00915                false);
00916 
00917   saveDxfGroup(_s_dxf_code_vertflag, _s_dxf_default_vfg);
00918   saveDxfGroup(_s_dxf_code_flag,     _s_dxf_default_pfgo);
00919 
00920   // 2 - Vertices of the polyline
00921 
00922   aChain.setToBegin();
00923 
00924   while (!aChain.isAtEnd())
00925     {
00926       const GenPoint<T>& currPoint = aChain.accessCurrent();
00927 
00928       saveDxfGroup(_s_dxf_code_ident, _s_dxf_tag_vert);
00929       saveDxfGroup(_s_dxf_code_x1, (int) currPoint.x());
00930       saveDxfGroup(_s_dxf_code_y1, (int) currPoint.y());
00931 
00932       aChain.moveNext();
00933     }
00934 
00935   // 3 - Footer of the polyline
00936 
00937   saveDxfGroup(_s_dxf_code_ident, _s_dxf_tag_esq);
00938 }
00939 
00940 
00941 // SAVE A SEGMENT WITH INTEGER COORDINATES
00942 
00943 void
00944 DxfFile::saveSegment(int aXSource,
00945                      int aYSource,
00946                      int aXTarget,
00947                      int aYTarget,
00948                      int aThickness,
00949                      QGEcolor aColor,
00950                      QGEoutline anOutline)
00951 {
00952   saveDxfGroup(_s_dxf_code_com,   _s_dxf_com_seg);
00953   saveDxfGroup(_s_dxf_code_ident, _s_dxf_tag_seg);
00954 
00955   saveDxfFeatures(_s_dxf_layer_prm,
00956                aThickness,
00957                aColor,
00958                anOutline != QGE_OUTLINE_SOLID);
00959 
00960   saveDxfGroup(_s_dxf_code_x1, aXSource);
00961   saveDxfGroup(_s_dxf_code_y1, aYSource);
00962   
00963   saveDxfGroup(_s_dxf_code_x2, aXTarget);
00964   saveDxfGroup(_s_dxf_code_y2, aYTarget);
00965 }
00966 
00967 
00968 // SAVE AN ARC WITH INTEGER COORDINATES
00969 
00970 void
00971 DxfFile::saveArc(int aXSource,
00972                  int aYSource,
00973                  int aXTarget,
00974                  int aYTarget,
00975                  int aXCenter,
00976                  int aYCenter,
00977                  int aSourceAngle,
00978                  int aTargetAngle,
00979                  int aRadius,
00980                  int aThickness,
00981                  QGEcolor aColor,
00982                  QGEoutline anOutline)
00983 {
00984   saveDxfGroup(_s_dxf_code_com,   _s_dxf_com_arc);
00985   saveDxfGroup(_s_dxf_code_ident, _s_dxf_tag_arc);
00986 
00987   saveDxfFeatures(_s_dxf_layer_prm,
00988                aThickness,
00989                aColor,
00990                anOutline != QGE_OUTLINE_SOLID);
00991 
00992   saveDxfGroup(_s_dxf_code_x1, aXCenter);
00993   saveDxfGroup(_s_dxf_code_y1, aYCenter);
00994 
00995   saveDxfGroup(_s_dxf_code_radius, aRadius);
00996 
00997   saveDxfGroup(_s_dxf_code_start, 360 - aTargetAngle);
00998   saveDxfGroup(_s_dxf_code_end,   360 - aSourceAngle);
00999 }
01000 
01001 
01002 // SAVE A POLYLINE
01003 
01004 template <class T>
01005 void
01006 DxfFile::savePolyline(const GenPolyline<T>& aPoly,
01007                       int aThickness,
01008                       QGEcolor aColor,
01009                       QGEoutline anOutline)
01010 {
01011   // 1 - Header of the polyline
01012   saveDxfGroup(_s_dxf_code_com,   _s_dxf_com_polyl);
01013   saveDxfGroup(_s_dxf_code_ident, _s_dxf_tag_polyl);
01014 
01015   saveDxfFeatures(_s_dxf_layer_polyl,
01016                aThickness,
01017                aColor,
01018                anOutline != QGE_OUTLINE_SOLID);
01019 
01020   saveDxfGroup(_s_dxf_code_vertflag, _s_dxf_default_vfg);
01021   saveDxfGroup(_s_dxf_code_flag,     _s_dxf_default_pfgo);
01022 
01023   // 2 - Vertices of the polyline
01024   deque< GenPoint<T> > pointList = aPoly.accessVertices();
01025 
01026   for (typename deque< GenPoint<T> >::iterator ptListIter = pointList.begin();
01027        ptListIter != pointList.end();
01028        ptListIter++)
01029     {
01030       saveDxfGroup(_s_dxf_code_ident, _s_dxf_tag_vert);
01031       saveDxfGroup(_s_dxf_code_x1, (int) (*ptListIter).x());
01032       saveDxfGroup(_s_dxf_code_y1, (int) (*ptListIter).y());
01033     }
01034 
01035   // 3 - Footer of the polyline
01036   saveDxfGroup(_s_dxf_code_ident, _s_dxf_tag_esq);
01037 }
01038 
01039 
01040 // SAVE A BOUNDING BOX
01041 
01042 void
01043 DxfFile::saveBox(int aXTopLeft,
01044                  int aYTopLeft,
01045                  int aXBottomRight,
01046                  int aYBottomRight,
01047                  int aThickness,
01048                  QGEcolor aColor,
01049                  QGEoutline anOutline)
01050 {
01051   saveSegment(aXTopLeft, aYTopLeft, aXTopLeft, aYBottomRight,
01052               aThickness,
01053               aColor,
01054               anOutline);
01055 
01056   saveSegment(aXTopLeft, aYTopLeft, aXBottomRight, aYTopLeft,
01057               aThickness,
01058               aColor,
01059               anOutline);
01060 
01061   saveSegment(aXBottomRight, aYTopLeft, aXBottomRight, aYBottomRight,
01062               aThickness,
01063               aColor,
01064               anOutline);
01065 
01066   saveSegment(aXTopLeft, aYBottomRight, aXBottomRight, aYBottomRight,
01067               aThickness,
01068               aColor,
01069               anOutline);
01070 }
01071 
01072 
01073 // ---------------------------------------------------------------------
01074 // AUXILIARIES: RETRIEVE DXF ENTITIES FROM THE FILE
01075 // ---------------------------------------------------------------------
01076 
01077 
01078 // RETRIEVE A DXF GROUP FROM THE FILE
01079 // Return the code of the group that has been read, and put 
01080 // the corresponding value in the qgar::DxfFile::lastGroup
01081 // data member as a chain of characters.
01082 // Comment are ignored.
01083 
01084 int
01085 DxfFile::retrieveDxfGroup()
01086 {
01087   char buf[_s_dxf_maxbuf];
01088 
01089   // Read code and value of the group.
01090   _fileStream.getline(buf, _s_dxf_maxbuf);
01091   int code = atoi(buf);
01092 
01093   _fileStream.getline(buf, _s_dxf_maxbuf);
01094 
01095   // If the group is a comment, read the next one
01096   if (code == _s_dxf_code_com)
01097     {
01098       return(retrieveDxfGroup());
01099     }
01100   else
01101     {
01102       int coord;
01103 
01104       _lastGroupCode = code;
01105       strcpy(_lastGroup, buf);
01106 
01107       // Windows ASCII files include lines terminated by '\r\n'. 
01108       // '\r' is replaced by '\0' as it causes trouble
01109       // to the analysis of the DXF file.
01110       if (_lastGroup[strlen(_lastGroup) - 1] == '\r')
01111         _lastGroup[strlen(_lastGroup) - 1] = '\0';
01112 
01113       // Update maximal coordinates
01114       if ((code == _s_dxf_code_x1) || (code == _s_dxf_code_x2))
01115         {
01116           coord = atoi(buf);
01117 
01118           if (coord > _maxX)
01119             {
01120               _maxX = coord;
01121             }
01122         }
01123 
01124       if ((code == _s_dxf_code_y1) || (code == _s_dxf_code_y2))
01125         {
01126           coord = atoi(buf);
01127 
01128           if (coord > _maxY)
01129             {
01130               _maxY = coord;
01131             }
01132         }
01133       
01134       // Return result
01135       return(code);
01136     }
01137 }
01138 
01139 
01140 // RETRIEVE POINTS (VERTICES OF A POLYLINE) FROM THE FILE
01141 //
01142 // aThickness: only significant when the function is called
01143 // to construct a Qgar polyline
01144 
01145 void
01146 DxfFile::retrievePoints(list<Point>& anEdgeList,
01147                         int* aThickness,
01148                         bool* isDashed)
01149 {
01150   *aThickness = 1;
01151   *isDashed   = false;
01152   retrieveDxfGroup();
01153 
01154   while (_lastGroupCode != _s_dxf_code_ident)
01155     {
01156       switch (_lastGroupCode)
01157         {
01158         case _s_dxf_code_thick:
01159           *aThickness = atoi(_lastGroup);
01160           break;
01161         case _s_dxf_code_ltp:
01162           if (!strcmp(_lastGroup, _s_dxf_default_dash))
01163             {
01164               *isDashed = true;
01165             }
01166           break;
01167         default:
01168           break;
01169         }
01170     retrieveDxfGroup();
01171     }
01172 
01173   Point pt;
01174   while (!strcmp(_lastGroup, _s_dxf_tag_vert))
01175     {
01176       while (retrieveDxfGroup() != _s_dxf_code_ident)
01177         {
01178           switch (_lastGroupCode)
01179             {
01180             case _s_dxf_code_x1:
01181               pt.setX(atoi(_lastGroup));
01182               break;
01183             case _s_dxf_code_y1:
01184               pt.setY(atoi(_lastGroup));
01185               break;
01186             default:
01187               break;
01188             }
01189         }
01190       anEdgeList.push_back(pt);
01191     }
01192   
01193   if (!strcmp(_lastGroup, _s_dxf_tag_esq))
01194     {
01195       retrieveDxfGroup();
01196     }
01197 }
01198 
01199 
01200 // ---------------------------------------------------------------------
01201 // AUXILIARIES:
01202 // RETRIEVE A PRIMITIVE FROM THE FILE AND APPEND IT TO A LIST
01203 // ---------------------------------------------------------------------
01204 
01205 
01206 // RETRIEVE A SEGMENT ENTITY FROM THE FILE
01207 
01208 void
01209 DxfFile::retrieveQgarSegment(list<GenQgarSegment<int>*>& aSegList)
01210 
01211   throw(QgarErrorIO)
01212 
01213 {
01214   if (retrieveDxfGroup() == _s_dxf_code_layer)
01215     {
01216       if (!strcmp(_lastGroup, _s_dxf_layer_prm))
01217         {
01218           retrieveDxfGroup();
01219           aSegList.push_back(retrievePQgarSegment());
01220         }
01221       else
01222         {
01223           std::ostringstream os;
01224           os << "Junk in file "
01225              << _fileName;
01226           throw QgarErrorIO(__FILE__, __LINE__,
01227                             "void qgar::DxfFile::retrieveQgarSegment(std::list<qgar::GenQgarSegment<int>*>&)",
01228                             os.str());
01229         }
01230     }
01231   else
01232     {
01233       aSegList.push_back(retrievePQgarSegment());
01234     }
01235 }
01236 
01237 
01238 // RETRIEVE AN ARC ENTITY FROM THE FILE
01239 
01240 void
01241 DxfFile::retrieveQgarArc(list<GenQgarArc<int>*>& anArcList)
01242 
01243   throw(QgarErrorIO)
01244 
01245 {
01246   if (retrieveDxfGroup() == _s_dxf_code_layer)
01247     {
01248       if (!strcmp(_lastGroup, _s_dxf_layer_prm))
01249         {
01250           retrieveDxfGroup();
01251           anArcList.push_back(retrievePQgarArc());
01252         }
01253       else
01254         {
01255           std::ostringstream os;
01256           os << "Junk in file "
01257              << _fileName;
01258           throw QgarErrorIO(__FILE__, __LINE__,
01259                             "void qgar::DxfFile::retrieveQgarArc(std::list<qgar::GenQgarArc<int>*>&)",
01260                             os.str());
01261         }
01262     }
01263   else
01264     {
01265       anArcList.push_back(retrievePQgarArc());
01266     }
01267 }
01268 
01269 
01270 // RETRIEVE A POLYLINE ENTITY FROM THE FILE
01271 //
01272 // aChainList   when the entity is a chain,
01273 //              it is added to the end of the list
01274 // aPolyList    when the entity is a polyline,
01275 //              it is added to the end of the list
01276 
01277 void
01278 DxfFile::retrieveChainOrQgarPolyline(std::list<GenPointChain<int>*>& aChainList,
01279                                      std::list<GenQgarPolyline<int>*>& aPolyList)
01280 
01281   throw(QgarErrorIO)
01282 
01283 {
01284   if (retrieveDxfGroup() == _s_dxf_code_layer)
01285     {
01286       if (!strcmp(_lastGroup, _s_dxf_layer_chain))
01287         {
01288           aChainList.push_back(retrievePChain());
01289         }
01290       else
01291         {
01292           if (!strcmp(_lastGroup, _s_dxf_layer_polyl))
01293             {
01294               aPolyList.push_back(retrievePQgarPolyline());
01295             }
01296           else
01297             {
01298               std::ostringstream os;
01299               os << "Junk in file "
01300                  << _fileName;
01301               throw QgarErrorIO(__FILE__, __LINE__,
01302                                 "void qgar::DxfFile::retrieveChainOrQgarPolyline(std::list<qgar::GenPointChain<int>*>&, std::list<qgar::GenQgarPolyline<int>*>&)",
01303                                 os.str());
01304             }
01305         }
01306     }
01307   else
01308     {
01309       std::ostringstream os;
01310       os << "Junk in file "
01311          << _fileName;
01312       throw QgarErrorIO(__FILE__, __LINE__,
01313                         "void qgar::DxfFile::retrieveChainOrQgarPolyline(std::list<qgar::GenPointChain<int>*>&, std::list<qgar::GenQgarPolyline<int>*>&)",
01314                         os.str());
01315     }
01316 }
01317 
01318 
01319 // ---------------------------------------------------------------------
01320 // AUXILIARIES: GET A POINTER TO A PRIMITIVE OF THE FILE
01321 // ---------------------------------------------------------------------
01322 
01323 
01324 // GET A POINTER TO A (QGAR) SEGMENT FROM THE FILE
01325 
01326 GenQgarSegment<int>*
01327 DxfFile::retrievePQgarSegment()
01328 {
01329   Point p1;
01330   Point p2;
01331   int thickness   = 1;
01332   bool isDashed = false;
01333 
01334   while (_lastGroupCode != _s_dxf_code_ident)
01335     {
01336       switch (_lastGroupCode)
01337         {
01338         case _s_dxf_code_x1:
01339           p1.setX(atoi(_lastGroup));
01340           break;
01341         case _s_dxf_code_y1:
01342           p1.setY(atoi(_lastGroup));
01343           break;
01344         case _s_dxf_code_x2:
01345           p2.setX(atoi(_lastGroup));
01346           break;
01347         case _s_dxf_code_y2:
01348           p2.setY(atoi(_lastGroup));
01349           break;
01350         case _s_dxf_code_thick:
01351           thickness = atoi(_lastGroup);
01352           break;
01353         case _s_dxf_code_ltp:
01354           if (!strcmp(_lastGroup, _s_dxf_default_dash))
01355             {
01356               isDashed = true;
01357             }
01358           break;
01359         default:
01360           break;
01361         }
01362       retrieveDxfGroup();
01363     }
01364 
01365   return new GenQgarSegment<int>(p1,
01366                                  p2,
01367                                  thickness,
01368                                  QGE_COLOR_DEFAULT,
01369                                  isDashed
01370                                    ? QGE_OUTLINE_DASH_SSPACED
01371                                    : QGE_OUTLINE_SOLID);
01372 }
01373 
01374 
01375 // GET A POINTER TO A (QGAR) ARC FROM THE FILE
01376 
01377 GenQgarArc<int>*
01378 DxfFile::retrievePQgarArc()
01379 {
01380   int x;
01381   int y;
01382   double radius;
01383   double startAngle;
01384   double endAngle;
01385   int thickness = 1;
01386   bool isDashed = false;
01387 
01388   while (_lastGroupCode != _s_dxf_code_ident)
01389     {
01390       switch (_lastGroupCode)
01391         {
01392         case _s_dxf_code_x1:
01393           x = atoi(_lastGroup);
01394           break;
01395         case _s_dxf_code_y1:
01396           y = atoi(_lastGroup);
01397           break;
01398         case _s_dxf_code_radius:
01399           radius = atof(_lastGroup);
01400           break;
01401         case _s_dxf_code_start:
01402           startAngle = atof(_lastGroup);
01403           break;
01404         case _s_dxf_code_end:
01405           endAngle = atof(_lastGroup);
01406           break;
01407         case _s_dxf_code_thick:
01408           thickness = atoi(_lastGroup);
01409           break;
01410         case _s_dxf_code_ltp:
01411           if (!strcmp(_lastGroup, _s_dxf_default_dash))
01412             {
01413               isDashed = true;
01414             }
01415           break;
01416         default:
01417           break;
01418         }
01419       retrieveDxfGroup();
01420     }
01421 
01422   double sAng = qgDegreesToRadians(360. - endAngle);
01423   double tAng = qgDegreesToRadians(360. - startAngle);
01424 
01425   return
01426     new GenQgarArc<int>(GenPoint<int>(x + (int) (radius * cos(sAng)),
01427                                       y + (int) (radius * sin(sAng))),
01428                         GenPoint<int>(x + (int) (radius * cos(tAng)),
01429                                       y + (int) (radius * sin(tAng))),
01430                         GenPoint<int>(x,y),
01431                         thickness,
01432                         QGE_COLOR_DEFAULT,
01433                         isDashed
01434                           ? QGE_OUTLINE_DASH_SSPACED
01435                           : QGE_OUTLINE_SOLID);
01436 }
01437 
01438 
01439 // GET A POINTER TO A (QGAR) POLYLINE FROM THE FILE
01440 
01441 GenQgarPolyline<int>*
01442 DxfFile::retrievePQgarPolyline()
01443 {
01444   list<Point> pointList;
01445   int thickness;
01446   bool isDashed;
01447   retrievePoints(pointList, &thickness, &isDashed);
01448 
01449   list<Point>::iterator itPL = pointList.begin();
01450   Segment seg(*itPL++, *itPL++);
01451   QgarPolyline* polyline =
01452     new QgarPolyline(seg,
01453                      thickness,
01454                      QGE_COLOR_DEFAULT,
01455                      isDashed
01456                        ? QGE_OUTLINE_DASH_SSPACED
01457                        : QGE_OUTLINE_SOLID);
01458 
01459   while (itPL != pointList.end())
01460     {
01461       polyline->appendTarget(*itPL);
01462       ++itPL;
01463     }
01464 
01465   return (polyline);
01466 }
01467 
01468 
01469 // GET A POINTER TO A CHAIN OF POINTS FROM THE FILE
01470 
01471 PointChain*
01472 DxfFile::retrievePChain()
01473 {
01474   list<Point> pointList;
01475   list<Point>::iterator itPL;
01476   int  unusedThickness;
01477   bool unusedDashFlag;
01478 
01479   retrievePoints(pointList, &unusedThickness, &unusedDashFlag);
01480   PointChain* chain = new PointChain();
01481 
01482   for (itPL = pointList.begin(); itPL != pointList.end(); ++itPL)
01483     {
01484       chain->push_back(*itPL);
01485     }
01486 
01487   return chain;
01488 }
01489 
01490 
01491 // ---------------------------------------------------------------------
01492 // PRIVATE FUNCTIONS NOT YET IMPLEMENTED
01493 // ---------------------------------------------------------------------
01494 
01495 
01496 // =================
01497 // OUTPUT COMPONENTS
01498 // =================
01499 
01500 
01501 // WRITE A (CONNECTED) COMPONENT
01502 
01503 void
01504 DxfFile::write(const ConnectedComponents::node_type* const aPNode,
01505                int        aThickness,
01506                QGEcolor   aColor,
01507                QGEoutline anOutline)
01508 
01509     throw(QgarErrorDeveloper)
01510 
01511 {
01512   throw QgarErrorDeveloper(__FILE__, __LINE__,
01513                            "void qgar::DxfFile::write(const qgar::ConnectedComponents::node_type* const, int, qgar::QGEcolor, qgar::QGEoutline)",
01514                            "Not yet implemented: See Phil Buzz!");
01515 }
01516 
01517 
01518 // =================================
01519 // OUTPUT CIRCLES AND ARCS OF CIRCLE
01520 // =================================
01521 
01522 
01523 // WRITE AN ARC WITH COORDINATES OF TYPE 'int'
01524 
01525 void
01526 DxfFile::write(const GenPoint<int>& aCenter,
01527                double aRadius,
01528                int        aThickness,
01529                QGEcolor   aColor,
01530                QGEoutline anOutline)
01531 
01532     throw(QgarErrorDeveloper)
01533 
01534 {
01535   throw QgarErrorDeveloper(__FILE__, __LINE__,
01536                            "void qgar::DxfFile::write(const qgar::GenPoint<int>&, double, int, qgar::QGEcolor, qgar::QGEoutline)",
01537                            "Not yet implemented: See Phil Buzz!");
01538 }
01539 
01540 
01541 // WRITE AN ARC WITH COORDINATES OF TYPE 'float'
01542 
01543 void
01544 DxfFile::write(const GenPoint<float>& aCenter,
01545                double aRadius,
01546                int        aThickness,
01547                QGEcolor   aColor,
01548                QGEoutline anOutline)
01549 
01550   throw(QgarErrorDeveloper)
01551 
01552 {
01553   throw QgarErrorDeveloper(__FILE__, __LINE__,
01554                            "void qgar::DxfFile::write(const qgar::GenPoint<float>&, double, int, qgar::QGEcolor, qgar::QGEoutline)",
01555                            "Not yet implemented: See Phil Buzz!");
01556 }
01557 
01558 
01559 // WRITE AN ARC WITH COORDINATES OF TYPE 'double'
01560 
01561 void
01562 DxfFile::write(const GenPoint<double>& aCenter,
01563                double aRadius,
01564                int        aThickness,
01565                QGEcolor   aColor,
01566                QGEoutline anOutline)
01567 
01568   throw(QgarErrorDeveloper)
01569 
01570 {
01571   throw QgarErrorDeveloper(__FILE__, __LINE__,
01572                            "void qgar::DxfFile::write(const qgar::GenPoint<double>&, double, int, qgar::QGEcolor, qgar::QGEoutline)",
01573                            "Not yet implemented: See Phil Buzz!");
01574 }
01575 
01576 
01577 // =============
01578 // OUTPUT POINTS
01579 // =============
01580 
01581 
01582 // WRITE A POINT WITH COORDINATES OF TYPE 'int'
01583 
01584 void
01585 DxfFile::write(const GenPoint<int>& aPt,
01586                int aThickness,
01587                QGEcolor aColor)
01588 
01589   throw(QgarErrorDeveloper)
01590 
01591 {
01592   throw QgarErrorDeveloper(__FILE__, __LINE__,
01593                            "void qgar::DxfFile::write(const qgar::GenPoint<int>&, int, qgar::QGEcolor)",
01594                            "Not yet implemented: See Phil Buzz!");
01595 }
01596 
01597 
01598 // WRITE A POINT WITH COORDINATES OF TYPE 'float'
01599 
01600 void
01601 DxfFile::write(const GenPoint<float>& aPt,
01602                int aThickness,
01603                QGEcolor aColor)
01604 
01605   throw(QgarErrorDeveloper)
01606 
01607 {
01608   throw QgarErrorDeveloper(__FILE__, __LINE__,
01609                            "void qgar::DxfFile::write(const qgar::GenPoint<float>&, int, qgar::QGEcolor)",
01610                            "Not yet implemented: See Phil Buzz!");
01611 }
01612 
01613 
01614 
01615 // WRITE A POINT WITH COORDINATES OF TYPE 'double'
01616 
01617 void
01618 DxfFile::write(const GenPoint<double>& aPt,
01619                int aThickness,
01620                QGEcolor aColor)
01621 
01622   throw(QgarErrorDeveloper)
01623 
01624 {
01625   throw QgarErrorDeveloper(__FILE__, __LINE__,
01626                            "void qgar::DxfFile::write(const qgar::GenPoint<double>&, int, qgar::QGEcolor)",
01627                            "Not yet implemented: See Phil Buzz!");
01628 }
01629 
01630 
01631 // --------------------------------------------------------------------
01632 
01633 } // namespace qgar