mydxfentities.hpp
Go to the documentation of this file.
00001 
00005 /* Copyright (c) 2010-2011 Taneli Kalvas. All rights reserved.
00006  *
00007  * You can redistribute this software and/or modify it under the terms
00008  * of the GNU General Public License as published by the Free Software
00009  * Foundation; either version 2 of the License, or (at your option)
00010  * any later version.
00011  * 
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
00015  * General Public License for more details.
00016  * 
00017  * You should have received a copy of the GNU General Public License
00018  * along with this library (file "COPYING" included in the package);
00019  * if not, write to the Free Software Foundation, Inc., 51 Franklin
00020  * Street, Fifth Floor, Boston, MA 02110-1301 USA
00021  * 
00022  * If you have questions about your rights to use or distribute this
00023  * software, please contact Berkeley Lab's Technology Transfer
00024  * Department at TTD@lbl.gov. Other questions, comments and bug
00025  * reports should be sent directly to the author via email at
00026  * taneli.kalvas@jyu.fi.
00027  * 
00028  * NOTICE. This software was developed under partial funding from the
00029  * U.S.  Department of Energy.  As such, the U.S. Government has been
00030  * granted for itself and others acting on its behalf a paid-up,
00031  * nonexclusive, irrevocable, worldwide license in the Software to
00032  * reproduce, prepare derivative works, and perform publicly and
00033  * display publicly.  Beginning five (5) years after the date
00034  * permission to assert copyright is obtained from the U.S. Department
00035  * of Energy, and subject to any subsequent five (5) year renewals,
00036  * the U.S. Government is granted for itself and others acting on its
00037  * behalf a paid-up, nonexclusive, irrevocable, worldwide license in
00038  * the Software to reproduce, prepare derivative works, distribute
00039  * copies to the public, perform publicly and display publicly, and to
00040  * permit others to do so.
00041  */
00042 
00043 #ifndef MY_DXF_ENTITIES_HPP
00044 #define MY_DXF_ENTITIES_HPP 1
00045 
00046 
00047 #include <stdint.h>
00048 #include <vector>
00049 #include <cairo.h>
00050 #include "mydxffile.hpp"
00051 #include "vec3d.hpp"
00052 #include "transformation.hpp"
00053 
00054 
00055 #define MYDXF_PERT_EPS 1.1e-12
00056 
00057 
00060 enum EntityType {
00061     ENTITY_UNKNOWN = 0,
00062     ENTITY_LINE,
00063     ENTITY_LWPOLYLINE,
00064     ENTITY_SPLINE,
00065     ENTITY_ARC,
00066     ENTITY_CIRCLE,
00067     ENTITY_MTEXT,
00068     ENTITY_INSERT
00069 };
00070 
00071 
00077 class MyDXFEntity
00078 {
00079 
00080 protected: 
00081 
00082     std::string _handle;
00083     std::string _layer;
00084 
00085     MyDXFEntity();
00086 
00087     //MyDXFEntity( const MyDXFEntity &ent );
00088 
00094     static void bbox_ppoint( Vec3D &min, Vec3D &max, const Vec3D &p );
00095 
00096     void write_common( class MyDXFFile *dxf, std::ofstream &ostr );
00097     void process_group( class MyDXFFile *dxf );
00098     void constructor_debug_print( void ) const;
00099     void debug_print_base( std::ostream &os ) const;
00100 
00101 public:
00102 
00105     virtual ~MyDXFEntity() {}
00106 
00109     virtual MyDXFEntity *copy( void ) const = 0;
00110 
00117     virtual void explode( class MyDXFEntities *ent, MyDXFFile *dxf, const Transformation *t ) const = 0;
00118 
00121     virtual void write( class MyDXFFile *dxf, std::ofstream &ostr ) = 0;
00122 
00125     virtual void scale( class MyDXFFile *dxf, double s ) = 0;
00126 
00129     virtual void translate( class MyDXFFile *dxf, const Vec3D &dx ) = 0;
00130 
00133     void set_layer( const std::string &layer ) { _layer = layer; }
00134 
00137     std::string get_layer( void ) const { return( _layer ); }
00138 
00141     virtual EntityType get_type( void ) const = 0;
00142 
00145     void set_handle( const std::string &handle ) { _handle = handle; }
00146 
00149     std::string get_handle( void ) const { return( _handle ); }
00150 
00158     virtual void plot( const class MyDXFFile *dxf, cairo_t *cairo, 
00159                        const Transformation *t, const double range[4] ) const = 0;
00160 
00163     virtual void get_bbox( Vec3D &min, Vec3D &max, 
00164                            const class MyDXFFile *dxf, const Transformation *t ) const = 0;
00165 
00168     virtual void debug_print( std::ostream &os ) const = 0;
00169 
00170     friend std::ostream &operator<<( std::ostream &os, const MyDXFEntity &ent );
00171 };
00172 
00173 
00180 class MyDXFPathEntity : public MyDXFEntity
00181 {
00182 
00183 protected: 
00184 
00185     MyDXFPathEntity() {}
00186 
00187     MyDXFPathEntity( const MyDXFEntity &ent ) : MyDXFEntity(ent) {}
00188 
00189 public:
00190 
00193     virtual ~MyDXFPathEntity() {}
00194 
00197     virtual Vec3D start( void ) const = 0;
00198 
00201     virtual Vec3D end( void ) const = 0;
00202 
00205     virtual void set_start( const Vec3D &s ) = 0;
00206 
00209     virtual void set_end( const Vec3D &e ) = 0;
00210 
00219     virtual int ray_cross( double x, double y ) const = 0;
00220 };
00221 
00222 
00223 
00224 
00230 class MyDXFEntitySelection
00231 {
00232 
00233     std::vector<uint32_t> _selection;
00234 
00235 public:
00236 
00239     MyDXFEntitySelection() {}
00240 
00243     ~MyDXFEntitySelection() {}
00244 
00247     uint32_t size() const { return( _selection.size() ); }
00248 
00251     void add_entity( uint32_t a ) { _selection.push_back( a ); }
00252 
00255     const uint32_t &operator()( int a ) const { 
00256         if( a < 0 || a >= (int)_selection.size() )
00257             throw( Error( ERROR_LOCATION, "index out of range" ) );
00258         return( _selection[a] ); 
00259     }
00260 
00263     uint32_t &operator()( int a ) { 
00264         if( a < 0 || a >= (int)_selection.size() )
00265             throw( Error( ERROR_LOCATION, "index out of range" ) );
00266         return( _selection[a] ); 
00267     }
00268 
00269     friend std::ostream &operator<<( std::ostream &os, const MyDXFEntitySelection &sel );
00270 };
00271 
00272 
00279 class MyDXFEntities
00280 {
00281 
00282     MyDXFFile                  *_dxf;      
00283     std::vector<MyDXFEntity *>  _entities; 
00285 public:
00286 
00287 
00290     MyDXFEntities( class MyDXFFile *dxf );
00291 
00294     MyDXFEntities( class MyDXFFile *dxf, MyDXFEntities *ent, MyDXFEntitySelection *sel );
00295 
00301     MyDXFEntities( class MyDXFFile *dxf, bool reading_blocks );
00302 
00305     ~MyDXFEntities();
00306 
00307 
00310     void write( class MyDXFFile *dxf, std::ofstream &ostr );
00311 
00317     void write_entities( class MyDXFFile *dxf, std::ofstream &ostr );
00318 
00321     uint32_t size() const { return( _entities.size() ); }
00322 
00325     const MyDXFEntity *get_entity( uint32_t a ) const { return( _entities[a] ); }
00326 
00329     MyDXFEntity *get_entity( uint32_t a ) { return( _entities[a] ); }
00330 
00331 
00332 
00333     
00338     void add_entity( MyDXFEntity *e ) { _entities.push_back( e ); }
00339 
00340 
00343     MyDXFEntitySelection *selection_all( void ) const;
00344 
00347     MyDXFEntitySelection *selection_layer( const std::string &layername ) const;
00348 
00351     MyDXFEntitySelection *selection_type( EntityType type ) const;
00352 
00361     MyDXFEntitySelection *selection_path_loop( MyDXFEntitySelection *selection,
00362                                                double eps = 1.0e-6 );
00363 
00364 
00365 
00366 
00367 
00373     bool geom_same( uint32_t a, uint32_t b, double eps = 1.0e-6 ) const;
00374 
00375     /* ! \brief Check if point is inside a loop defined by a selection
00376      *   of entities.
00377      *
00378      *   The check is done assuming a 2D drawing in xy-plane. The
00379      *   check is done using ray shooting algorithm. If exact crossing
00380      *   happens perturbation algorithm is used. New test is performed
00381      *   at eps distance from the first.
00382      */
00383     bool inside_loop( MyDXFEntitySelection *selection, double x, double y, double eps = 1.0e-6 );
00384 
00394     void plot( const MyDXFEntitySelection *selection, const class MyDXFFile *dxf, 
00395                cairo_t *cairo, const Transformation *t, const double range[4] ) const;
00396 
00399     void get_bbox( const MyDXFEntitySelection *selection, Vec3D &min, Vec3D &max, 
00400                    const class MyDXFFile *dxf, const Transformation *t ) const;
00401 
00402 
00403 
00404     /*
00405     void translate( MyDXFEntitySelection *selection, double dx, double dy, double dz );
00406     void rotate_x( MyDXFEntitySelection *selection, double y, double z, double ang );
00407     void rotate_y( MyDXFEntitySelection *selection, double x, double z, double ang );
00408     void rotate_z( MyDXFEntitySelection *selection, double x, double y, double ang );
00409     */
00410 
00415     void scale( MyDXFEntitySelection *selection, class MyDXFFile *dxf, double s );
00416 
00419     void translate( MyDXFEntitySelection *selection, class MyDXFFile *dxf, const Vec3D &dx );
00420 
00421 
00422 
00430     void remove( MyDXFEntitySelection *selection );
00431 
00432 
00439     void explode( MyDXFEntitySelection *selection, class MyDXFFile *dxf );
00440 
00445     void explode( MyDXFEntities *ent, class MyDXFFile *dxf, const Transformation *t ) const;
00446 
00447 
00450     void debug_print( std::ostream &os ) const;
00451 
00452 
00453 };
00454 
00455 
00456 
00457 
00458 
00459 #endif
00460 
00461 
00462 
00463