IBSimu
1.0.4
|
00001 00005 /* Copyright (c) 2010 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 00057 enum EntityType { 00058 ENTITY_UNKNOWN = 0, 00059 ENTITY_LINE, 00060 ENTITY_LWPOLYLINE, 00061 ENTITY_ARC, 00062 ENTITY_CIRCLE, 00063 ENTITY_MTEXT, 00064 ENTITY_INSERT 00065 }; 00066 00067 00073 class MyDXFEntity 00074 { 00075 00076 protected: 00077 00078 std::string _handle; 00079 std::string _layer; 00080 00081 MyDXFEntity(); 00082 00083 //MyDXFEntity( const MyDXFEntity &ent ); 00084 00090 static void bbox_ppoint( Vec3D &min, Vec3D &max, const Vec3D &p ); 00091 00092 void write_common( class MyDXFFile *dxf, std::ofstream &ostr ); 00093 void process_group( class MyDXFFile *dxf ); 00094 void constructor_debug_print( void ) const; 00095 void debug_print_base( std::ostream &os ) const; 00096 virtual void debug_print( std::ostream &os ) const = 0; 00097 00098 public: 00099 00102 virtual ~MyDXFEntity() {} 00103 00106 virtual MyDXFEntity *copy( void ) const = 0; 00107 00114 virtual void explode( class MyDXFEntities *ent, MyDXFFile *dxf, const Transformation *t ) const = 0; 00115 00118 virtual void write( class MyDXFFile *dxf, std::ofstream &ostr ) = 0; 00119 00122 virtual void scale( class MyDXFFile *dxf, double s ) = 0; 00123 00126 void set_layer( const std::string &layer ) { _layer = layer; } 00127 00130 std::string get_layer( void ) const { return( _layer ); } 00131 00134 virtual EntityType get_type( void ) const = 0; 00135 00138 void set_handle( const std::string &handle ) { _handle = handle; } 00139 00142 std::string get_handle( void ) const { return( _handle ); } 00143 00151 virtual void plot( const class MyDXFFile *dxf, cairo_t *cairo, 00152 const Transformation *t, const double range[4] ) const = 0; 00153 00156 virtual void get_bbox( Vec3D &min, Vec3D &max, 00157 const class MyDXFFile *dxf, const Transformation *t ) const = 0; 00158 00159 friend std::ostream &operator<<( std::ostream &os, const MyDXFEntity &ent ); 00160 }; 00161 00162 00169 class MyDXFPathEntity : public MyDXFEntity 00170 { 00171 00172 protected: 00173 00174 MyDXFPathEntity() {} 00175 00176 MyDXFPathEntity( const MyDXFEntity &ent ) : MyDXFEntity(ent) {} 00177 00178 public: 00179 00182 virtual ~MyDXFPathEntity() {} 00183 00186 virtual Vec3D start( void ) const = 0; 00187 00190 virtual Vec3D end( void ) const = 0; 00191 00194 virtual void set_start( const Vec3D &s ) = 0; 00195 00198 virtual void set_end( const Vec3D &e ) = 0; 00199 00208 virtual int ray_cross( double x, double y ) const = 0; 00209 }; 00210 00211 00216 class MyDXFLine : public MyDXFPathEntity 00217 { 00218 00219 Vec3D _p1; 00220 Vec3D _p2; 00221 00222 virtual void debug_print( std::ostream &os ) const; 00223 00224 public: 00225 00228 MyDXFLine() {} 00229 00232 MyDXFLine( const MyDXFEntity &ent ) : MyDXFPathEntity(ent) {} 00233 00236 MyDXFLine( class MyDXFFile *dxf ); 00237 00240 virtual ~MyDXFLine() {} 00241 00244 virtual MyDXFLine *copy( void ) const { return( new MyDXFLine( *this ) ); } 00245 00252 virtual void explode( class MyDXFEntities *ent, MyDXFFile *dxf, const Transformation *t ) const; 00253 00256 virtual void write( class MyDXFFile *dxf, std::ofstream &ostr ); 00257 00260 virtual EntityType get_type( void ) const { return( ENTITY_LINE ); } 00261 00264 virtual Vec3D start( void ) const { return( _p1 ); } 00265 00268 virtual Vec3D end( void ) const { return( _p2 ); } 00269 00272 virtual void set_start( const Vec3D &s ); 00273 00276 virtual void set_end( const Vec3D &e ); 00277 00286 virtual int ray_cross( double x, double y ) const; 00287 00293 bool geom_same( const MyDXFLine &line, double eps = 1.0e-6 ) const; 00294 00302 virtual void plot( const class MyDXFFile *dxf, cairo_t *cairo, 00303 const Transformation *t, const double range[4] ) const; 00304 00307 virtual void get_bbox( Vec3D &min, Vec3D &max, 00308 const class MyDXFFile *dxf, const Transformation *t ) const; 00309 00312 virtual void scale( class MyDXFFile *dxf, double s ); 00313 }; 00314 00315 00316 /* Polyline flags */ 00317 #define LWPOLYLINE_CLOSED_MASK 1 00318 #define LWPOLYLINE_LINEGEN_MASK 128 00319 00320 00325 class MyDXFLWPolyline : public MyDXFPathEntity 00326 { 00327 00328 std::vector<Vec3D> _p; 00330 int16_t _flags; 00331 00332 virtual void debug_print( std::ostream &os ) const; 00333 00334 public: 00335 00338 MyDXFLWPolyline( class MyDXFFile *dxf ); 00339 00342 virtual ~MyDXFLWPolyline() {} 00343 00346 virtual MyDXFLWPolyline *copy( void ) const { return( new MyDXFLWPolyline( *this ) ); } 00347 00354 virtual void explode( class MyDXFEntities *ent, MyDXFFile *dxf, const Transformation *t ) const; 00355 00358 virtual void write( class MyDXFFile *dxf, std::ofstream &ostr ); 00359 00362 virtual EntityType get_type( void ) const { return( ENTITY_LWPOLYLINE ); } 00363 00366 virtual Vec3D start( void ) const { return( _p[0] ); } 00367 00370 virtual Vec3D end( void ) const { return( _p[_p.size()-1] ); } 00371 00374 virtual void set_start( const Vec3D &s ); 00375 00378 virtual void set_end( const Vec3D &e ); 00379 00388 virtual int ray_cross( double x, double y ) const; 00389 00395 bool geom_same( const MyDXFLWPolyline &line, double eps = 1.0e-6 ) const; 00396 00399 uint32_t size() const { return( _p.size() ); } 00400 00403 Vec3D vertex( uint32_t i ) const { return( _p[i] ); } 00404 00407 bool closed( void ) const { return( _flags & LWPOLYLINE_CLOSED_MASK ); } 00408 00416 virtual void plot( const class MyDXFFile *dxf, cairo_t *cairo, 00417 const Transformation *t, const double range[4] ) const; 00418 00421 virtual void get_bbox( Vec3D &min, Vec3D &max, 00422 const class MyDXFFile *dxf, const Transformation *t ) const; 00423 00426 virtual void scale( class MyDXFFile *dxf, double s ); 00427 }; 00428 00429 00435 class MyDXFArc : public MyDXFPathEntity 00436 { 00437 00438 Vec3D _pc; 00439 double _r; 00440 double _ang1; // Must be between 0 and 2 pi. 00441 double _ang2; // Must be between 0 and 2 pi. 00442 00443 virtual void debug_print( std::ostream &os ) const; 00444 00445 public: 00446 00449 MyDXFArc() : _r(1.0), _ang1(0.0), _ang2(2.0*M_PI) {}; 00450 00453 MyDXFArc( class MyDXFFile *dxf ); 00454 00457 virtual ~MyDXFArc() {} 00458 00461 virtual MyDXFArc *copy( void ) const { return( new MyDXFArc( *this ) ); } 00462 00469 virtual void explode( class MyDXFEntities *ent, MyDXFFile *dxf, const Transformation *t ) const; 00470 00473 virtual void write( class MyDXFFile *dxf, std::ofstream &ostr ); 00474 00477 virtual EntityType get_type( void ) const { return( ENTITY_ARC ); } 00478 00481 Vec3D center( void ) const { return( _pc ); } 00482 00485 double radius( void ) const { return( _r ); } 00486 00489 virtual Vec3D start( void ) const { 00490 return( Vec3D(_pc[0] + _r*cos(_ang1), _pc[1] + _r*sin(_ang1), _pc[2] ) ); 00491 } 00492 00495 virtual Vec3D end( void ) const { 00496 return( Vec3D(_pc[0] + _r*cos(_ang2), _pc[1] + _r*sin(_ang2), _pc[2] ) ); 00497 } 00498 00501 void set_pc( const Vec3D &pc ) { _pc = pc; } 00502 00505 void set_r( double r ) { _r = r; } 00506 00509 void set_ang1( double ang1 ); 00510 00513 void set_ang2( double ang2 ); 00514 00517 double get_ang1( void ) const { return( _ang1 ); } 00518 00521 double get_ang2( void ) const { return( _ang2 ); } 00522 00527 void set_center_and_ends( const Vec3D &c, const Vec3D &s, const Vec3D &e ); 00528 00539 void set_center_point( const Vec3D &s, const Vec3D &e ); 00540 00543 virtual void set_start( const Vec3D &s ); 00544 00547 virtual void set_end( const Vec3D &e ); 00548 00557 virtual int ray_cross( double x, double y ) const; 00558 00564 bool geom_same( const MyDXFArc &arc, double eps = 1.0e-6 ) const; 00565 00573 virtual void plot( const class MyDXFFile *dxf, cairo_t *cairo, 00574 const Transformation *t, const double range[4] ) const; 00575 00578 virtual void get_bbox( Vec3D &min, Vec3D &max, 00579 const class MyDXFFile *dxf, const Transformation *t ) const; 00580 00583 virtual void scale( class MyDXFFile *dxf, double s ); 00584 }; 00585 00586 00591 class MyDXFCircle : public MyDXFPathEntity 00592 { 00593 00594 Vec3D _pc; 00595 double _r; 00596 00597 virtual void debug_print( std::ostream &os ) const; 00598 00599 public: 00600 00603 MyDXFCircle() : _r(1.0) {}; 00604 00607 MyDXFCircle( class MyDXFFile *dxf ); 00608 00611 virtual ~MyDXFCircle() {} 00612 00615 virtual MyDXFCircle *copy( void ) const { return( new MyDXFCircle( *this ) ); } 00616 00623 virtual void explode( class MyDXFEntities *ent, MyDXFFile *dxf, const Transformation *t ) const; 00624 00627 virtual void write( class MyDXFFile *dxf, std::ofstream &ostr ); 00628 00631 virtual EntityType get_type( void ) const { return( ENTITY_CIRCLE ); } 00632 00635 Vec3D center( void ) const { return( _pc ); } 00636 00639 double radius( void ) const { return( _r ); } 00640 00643 virtual Vec3D start( void ) const { return( _pc+Vec3D(_r,0) ); } 00644 00647 virtual Vec3D end( void ) const { return( _pc+Vec3D(_r,0) ); } 00648 00651 virtual void set_start( const Vec3D &s ) {} 00652 00655 virtual void set_end( const Vec3D &e ) {} 00656 00665 virtual int ray_cross( double x, double y ) const; 00666 00672 bool geom_same( const MyDXFCircle &circle, double eps = 1.0e-6 ) const; 00673 00681 virtual void plot( const class MyDXFFile *dxf, cairo_t *cairo, 00682 const Transformation *t, const double range[4] ) const; 00683 00686 virtual void get_bbox( Vec3D &min, Vec3D &max, 00687 const class MyDXFFile *dxf, const Transformation *t ) const; 00688 00691 virtual void scale( class MyDXFFile *dxf, double s ); 00692 }; 00693 00694 00695 #define ATTACHMENT_POINT_TOP_LEFT 1 00696 #define ATTACHMENT_POINT_TOP_CENTER 2 00697 #define ATTACHMENT_POINT_TOP_RIGHT 3 00698 #define ATTACHMENT_POINT_MIDDLE_LEFT 4 00699 #define ATTACHMENT_POINT_MIDDLE_CENTER 5 00700 #define ATTACHMENT_POINT_MIDDLE_RIGHT 6 00701 #define ATTACHMENT_POINT_BOTTOM_LEFT 7 00702 #define ATTACHMENT_POINT_BOTTOM_CENTER 8 00703 #define ATTACHMENT_POINT_BOTTOM_RIGHT 9 00704 00705 #define DRAWING_DIRECTION_LEFT_TO_RIGHT 1 00706 #define DRAWING_DIRECTION_TOP_TO_BOTTOM 3 00707 #define DRAWING_DIRECTION_BY_STYLE 5 00708 00709 00714 class MyDXFMText : public MyDXFEntity 00715 { 00716 00717 std::string _text; 00718 Vec3D _p; 00719 double _text_height; 00720 double _rect_width; 00721 int16_t _attachment_point; 00722 int16_t _drawing_direction; 00723 00724 virtual void debug_print( std::ostream &os ) const; 00725 00726 public: 00727 00730 MyDXFMText() : _text_height(1.0), _rect_width(1.0), 00731 _attachment_point(ATTACHMENT_POINT_TOP_LEFT), 00732 _drawing_direction(DRAWING_DIRECTION_LEFT_TO_RIGHT) {}; 00733 00736 MyDXFMText( class MyDXFFile *dxf ); 00737 00740 virtual ~MyDXFMText() {} 00741 00744 virtual MyDXFMText *copy( void ) const { return( new MyDXFMText( *this ) ); } 00745 00752 virtual void explode( class MyDXFEntities *ent, MyDXFFile *dxf, const Transformation *t ) const; 00753 00756 virtual void write( class MyDXFFile *dxf, std::ofstream &ostr ); 00757 00760 virtual EntityType get_type( void ) const { return( ENTITY_MTEXT ); } 00761 00769 virtual void plot( const class MyDXFFile *dxf, cairo_t *cairo, 00770 const Transformation *t, const double range[4] ) const; 00771 00774 virtual void get_bbox( Vec3D &min, Vec3D &max, 00775 const class MyDXFFile *dxf, const Transformation *t ) const; 00776 00779 virtual void scale( class MyDXFFile *dxf, double s ); 00780 }; 00781 00782 00783 00788 class MyDXFInsert : public MyDXFEntity 00789 { 00790 00791 std::string _block_name; 00792 00793 Vec3D _p; // Insertion point 00794 Vec3D _scale; 00795 00796 double _rotation; 00797 00798 int16_t _col_count; 00799 int16_t _row_count; 00800 00801 double _col_spacing; 00802 double _row_spacing; 00803 00804 virtual void debug_print( std::ostream &os ) const; 00805 00806 public: 00807 00810 MyDXFInsert(); 00811 00814 MyDXFInsert( class MyDXFFile *dxf ); 00815 00818 virtual ~MyDXFInsert() {} 00819 00822 virtual MyDXFInsert *copy( void ) const { return( new MyDXFInsert( *this ) ); } 00823 00830 virtual void explode( class MyDXFEntities *ent, MyDXFFile *dxf, const Transformation *t ) const; 00831 00834 virtual void write( class MyDXFFile *dxf, std::ofstream &ostr ); 00835 00838 virtual EntityType get_type( void ) const { return( ENTITY_INSERT ); } 00839 00847 virtual void plot( const class MyDXFFile *dxf, cairo_t *cairo, 00848 const Transformation *t, const double range[4] ) const; 00849 00852 virtual void get_bbox( Vec3D &min, Vec3D &max, 00853 const class MyDXFFile *dxf, const Transformation *t ) const; 00854 00857 virtual void scale( class MyDXFFile *dxf, double s ); 00858 00861 const std::string &block_name( void ) const { return( _block_name ); } 00862 }; 00863 00864 00865 00871 class MyDXFEntitySelection 00872 { 00873 00874 std::vector<uint32_t> _selection; 00875 00876 public: 00877 00880 MyDXFEntitySelection() {} 00881 00884 ~MyDXFEntitySelection() {} 00885 00888 uint32_t size() const { return( _selection.size() ); } 00889 00892 void add_entity( uint32_t a ) { _selection.push_back( a ); } 00893 00896 const uint32_t &operator()( int a ) const { 00897 if( a < 0 || a >= (int)_selection.size() ) 00898 throw( Error( ERROR_LOCATION, "index out of range" ) ); 00899 return( _selection[a] ); 00900 } 00901 00904 uint32_t &operator()( int a ) { 00905 if( a < 0 || a >= (int)_selection.size() ) 00906 throw( Error( ERROR_LOCATION, "index out of range" ) ); 00907 return( _selection[a] ); 00908 } 00909 00910 friend std::ostream &operator<<( std::ostream &os, const MyDXFEntitySelection &sel ); 00911 }; 00912 00913 00920 class MyDXFEntities 00921 { 00922 00923 std::vector<MyDXFEntity *> _entities; 00924 00925 public: 00926 00927 00930 MyDXFEntities() {} 00931 00934 MyDXFEntities( MyDXFEntities *ent, MyDXFEntitySelection *sel ); 00935 00941 MyDXFEntities( class MyDXFFile *dxf, bool reading_blocks = false ); 00942 00945 ~MyDXFEntities(); 00946 00947 00950 void write( class MyDXFFile *dxf, std::ofstream &ostr ); 00951 00957 void write_entities( class MyDXFFile *dxf, std::ofstream &ostr ); 00958 00961 uint32_t size() const { return( _entities.size() ); } 00962 00965 const MyDXFEntity *get_entity( uint32_t a ) const { return( _entities[a] ); } 00966 00969 MyDXFEntity *get_entity( uint32_t a ) { return( _entities[a] ); } 00970 00971 00972 00973 00978 void add_entity( MyDXFEntity *e ) { _entities.push_back( e ); } 00979 00980 00983 MyDXFEntitySelection *selection_all( void ) const; 00984 00987 MyDXFEntitySelection *selection_layer( const std::string &layername ) const; 00988 00991 MyDXFEntitySelection *selection_type( EntityType type ) const; 00992 01001 MyDXFEntitySelection *selection_path_loop( MyDXFEntitySelection *selection, 01002 double eps = 1.0e-6 ); 01003 01004 01005 01006 01007 01013 bool geom_same( uint32_t a, uint32_t b, double eps = 1.0e-6 ) const; 01014 01015 /* ! \brief Check if point is inside a loop defined by a selection 01016 * of entities. 01017 * 01018 * The check is done assuming a 2D drawing in xy-plane. The 01019 * check is done using ray shooting algorithm. If exact crossing 01020 * happens perturbation algorithm is used. New test is performed 01021 * at eps distance from the first. 01022 */ 01023 bool inside_loop( MyDXFEntitySelection *selection, double x, double y, double eps = 1.0e-6 ); 01024 01034 void plot( const MyDXFEntitySelection *selection, const class MyDXFFile *dxf, 01035 cairo_t *cairo, const Transformation *t, const double range[4] ) const; 01036 01039 void get_bbox( const MyDXFEntitySelection *selection, Vec3D &min, Vec3D &max, 01040 const class MyDXFFile *dxf, const Transformation *t ) const; 01041 01042 01043 01044 /* 01045 void translate( MyDXFEntitySelection *selection, double dx, double dy, double dz ); 01046 void rotate_x( MyDXFEntitySelection *selection, double y, double z, double ang ); 01047 void rotate_y( MyDXFEntitySelection *selection, double x, double z, double ang ); 01048 void rotate_z( MyDXFEntitySelection *selection, double x, double y, double ang ); 01049 */ 01050 01055 void scale( MyDXFEntitySelection *selection, class MyDXFFile *dxf, double s ); 01056 01057 01065 void remove( MyDXFEntitySelection *selection ); 01066 01067 01074 void explode( MyDXFEntitySelection *selection, class MyDXFFile *dxf ); 01075 01080 void explode( MyDXFEntities *ent, class MyDXFFile *dxf, const Transformation *t ) const; 01081 01082 01085 void debug_print( std::ostream &os ) const; 01086 01087 01088 }; 01089 01090 01091 01092 01093 01094 #endif 01095 01096 01097