00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015 #ifndef __WXWIRE_H__
00016 #define __WXWIRE_H__
00017
00018 #ifndef WX_PRECOMP
00019 #include "wx/wx.h"
00020 #endif
00021
00022 #include "wx/artbase/afmatrix.h"
00023 #include "wx/geometry.h"
00024 #include "wx/artbase/bbox.h"
00025
00026 #include "wx/canvas/canobj.h"
00027 #include "wx/canvas/canprim.h"
00028 #include "wx/canvas/polygon.h"
00029
00030 class A2DCANVASDLLEXP a2dWirePolylineL;
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 class A2DCANVASDLLEXP a2dRouteData : public a2dObject
00058 {
00059 public:
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069
00070
00071
00072 a2dRouteData( a2dCanvasObject *showobject, bool final );
00073
00074
00075 ~a2dRouteData();
00076
00077
00078 static void SetRaster( double raster ) { m_raster = raster; }
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100 bool RerouteWire( a2dWirePolylineL *wire, a2dPin *dispin, a2dPin *startpin, bool startisbegin, bool final );
00101
00102
00103 enum RoutePointFlag
00104 {
00105 flag_original = 0x01,
00106 flag_targetwire = 0x02,
00107 flag_targetpin = 0x04,
00108 flag_targetapprox = 0x08,
00109 flag_reachable = 0x10,
00110 flag_final = 0x20
00111 };
00112
00113 enum RoutePointDirection
00114 {
00115 dir_xminus = 0,
00116 dir_xplus = 1,
00117 dir_yminus = 2,
00118 dir_yplus = 3,
00119
00120
00121 dir_start = 4,
00122
00123
00124 dir_min = 0,
00125
00126 dir_max = 3,
00127
00128 dir_count = 4,
00129
00130 dir_invxor = 1
00131 };
00132
00133
00134
00135
00136
00137
00138
00139 struct RoutePoint
00140 {
00141
00142 unsigned int m_cost;
00143
00144 unsigned short m_flags;
00145
00146 unsigned char m_direction;
00147
00148 unsigned char m_prevdir;
00149
00150 unsigned short m_x, m_y;
00151 };
00152
00153
00154
00155
00156
00157 struct BorderPoint
00158 {
00159
00160 unsigned int m_cost;
00161
00162 unsigned char m_direction;
00163
00164 unsigned char m_prevdir;
00165
00166 unsigned short m_x, m_y;
00167
00168 BorderPoint *m_next;
00169 };
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180 class BorderQueue
00181 {
00182 public:
00183
00184 BorderQueue();
00185
00186 ~BorderQueue();
00187
00188 void Add( const BorderPoint &brdr );
00189
00190 const BorderPoint &GetBest()
00191 {
00192 wxASSERT( m_costring[ m_mincostindex ] );
00193 return *m_costring[ m_mincostindex ];
00194 }
00195
00196 void RmvBest();
00197
00198 bool IsNotEmpty()
00199 {
00200 return m_costring[ m_mincostindex ] != 0;
00201 }
00202
00203 protected:
00204
00205 enum {
00206
00207 m_ncost = 1024,
00208
00209 m_costmask = 1023,
00210 };
00211
00212
00213 struct AllocBlock
00214 {
00215 enum {
00216
00217 m_pointsperblock = 1024
00218 };
00219 BorderPoint m_memory[m_pointsperblock];
00220 AllocBlock *m_next;
00221 };
00222
00223
00224 unsigned m_mincostindex;
00225
00226 BorderPoint *m_costring[m_ncost];
00227
00228 BorderPoint *m_freelist;
00229
00230 AllocBlock *m_memory;
00231
00232 int m_freememory;
00233
00234 public:
00235 #ifdef _DEBUG
00236 unsigned m_mincost;
00237 #endif
00238 #ifdef PRFL_ENBL
00239 int m_count;
00240 #endif
00241 };
00242
00243 protected:
00244
00245
00246 unsigned short &GetVerticalOccupation( int x, int y ) {
00247 wxASSERT( x>=0 && x<=m_width );
00248 wxASSERT( y>=0 && y<=m_height );
00249 return m_verticaloccupation[ m_widthp1 * y + x ];
00250 }
00251
00252
00253 unsigned short &GetHorizontalOccupation( int x, int y ) {
00254 wxASSERT( x>=0 && x<=m_width );
00255 wxASSERT( y>=0 && y<=m_height );
00256 return m_horizontaloccupation[ m_widthp1 * y + x ];
00257 }
00258
00259
00260 bool IsVerticalOccupied( int x, int y )
00261 {
00262 wxASSERT( x>=0 && x<=m_width );
00263 wxASSERT( y>=0 && y<=m_height );
00264 return m_verticaloccupation[ m_widthp1 * y + x ] > 0;
00265 }
00266
00267
00268 bool IsHorizontalOccupied( int x, int y )
00269 {
00270 wxASSERT( x>=0 && x<=m_width );
00271 wxASSERT( y>=0 && y<=m_height );
00272 return m_horizontaloccupation[ m_widthp1 * y + x ] > 0;
00273 }
00274
00275
00276 RoutePoint &GetRoutePoint( int x, int y, int dir ) {
00277 wxASSERT( x>=0 && x<=m_width );
00278 wxASSERT( y>=0 && y<=m_height );
00279 wxASSERT( dir>=dir_min && dir<=dir_max );
00280 return m_routepoints[ ( m_widthp1 * y + x ) * (int) dir_count + ( dir - dir_min ) ];
00281 }
00282
00283
00284
00285
00286
00287
00288 void AddOccupationRect( const a2dBoundingBox &bbox, short incr );
00289
00290
00291
00292
00293
00294
00295 void AddOccupationPolyline( const a2dVertexList *points, const a2dAffineMatrix &trns, short incr );
00296
00297
00298 void SetFlagRect( const a2dBoundingBox &bbox, RoutePointFlag flag );
00299
00300
00301
00302
00303
00304
00305 void SetFlagPolyline( const a2dVertexList *points, const a2dAffineMatrix &trns, RoutePointFlag flag );
00306
00307
00308 void SetFlagRoutePointAllDirs( int x, int y, RoutePointFlag flag )
00309 {
00310 RoutePoint *routepoints = &GetRoutePoint( x, y, dir_min );
00311 routepoints[0].m_flags |= flag;
00312 routepoints[1].m_flags |= flag;
00313 routepoints[2].m_flags |= flag;
00314 routepoints[3].m_flags |= flag;
00315 }
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328 inline void AddBorderPoint(
00329 BorderQueue *queue, RoutePoint *current,
00330 int nextx, int nexty,
00331 int dir, int prevdir
00332 );
00333
00334
00335
00336
00337
00338
00339 a2dBoundingBox CalculateRoutingBbox( a2dCanvasObject *object );
00340
00341
00342 void DumpOccupation( FILE *file );
00343 void DumpCost();
00344 void DumpVertexList( a2dVertexList *list );
00345
00346
00347 bool m_ok;
00348
00349 a2dCanvasObject *m_showobject;
00350
00351 int m_width;
00352
00353 int m_widthp1;
00354
00355 int m_height;
00356
00357 int m_heightp1;
00358
00359 static double m_raster;
00360
00361 double m_rasterinv;
00362
00363 int m_rasterminx, m_rastermaxx, m_rasterminy, m_rastermaxy;
00364
00365 double m_rasterborder;
00366
00367
00368 unsigned short *m_verticaloccupation;
00369
00370 unsigned short *m_horizontaloccupation;
00371
00372 RoutePoint *m_routepoints;
00373
00374
00375 #ifdef DUMP_FINAL
00376 FILE *m_dump;
00377 #endif
00378
00379
00380 DECLARE_CLASS( a2dRouteData )
00381
00382
00383 virtual a2dObject* Clone( CloneOptions WXUNUSED(options) ) const
00384 {
00385 wxASSERT(0); return 0;
00386 }
00387 #if wxART2D_USE_CVGIO
00388
00389 virtual void DoSave( wxObject* WXUNUSED(parent), a2dIOHandlerXmlSerOut &WXUNUSED(out), a2dXmlSer_flag WXUNUSED(xmlparts), a2dObjectList* WXUNUSED(towrite) ) {
00390 wxASSERT( 0 ); }
00391 virtual void DoLoad( wxObject* WXUNUSED(parent), a2dIOHandlerXmlSerIn& WXUNUSED(parser), a2dXmlSer_flag WXUNUSED(xmlparts) ) {
00392 wxASSERT( 0 ); }
00393
00394 #endif //wxART2D_USE_CVGIO
00395 };
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406 class A2DCANVASDLLEXP a2dWirePolylineL: public a2dPolylineL
00407 {
00408 A2D_DECLARE_EVENT_TABLE()
00409 public:
00410
00411 a2dWirePolylineL();
00412 a2dWirePolylineL(a2dVertexList* points, bool spline = false );
00413 a2dWirePolylineL( const a2dWirePolylineL& poly, CloneOptions options );
00414 ~a2dWirePolylineL();
00415
00416 void SetConnectionInfo(
00417 bool inverted,
00418 a2dPinClass* objBegin,
00419 a2dPinClass* objEnd
00420 );
00421
00422 a2dPinClass* GetStartPinClass() const { return m_wireBegin; }
00423 void SetStartPinClass( a2dPinClass* startPinClass ) { m_wireBegin = startPinClass; }
00424
00425 a2dPinClass* GetEndPinClass() const { return m_wireEnd; }
00426 void SetEndPinClass( a2dPinClass* endPinClass ) { m_wireEnd = endPinClass; }
00427
00428 virtual a2dObject* Clone( CloneOptions options ) const;
00429
00430
00431 void SetRouteOneLine( bool oneLine ) { m_oneLine = oneLine; }
00432
00433
00434 bool GetRouteOneLine() { return m_oneLine; }
00435
00436 virtual bool IsConnect() const;
00437 virtual bool NeedsUpdateWhenConnected() const;
00438 virtual void DoUpdateImmediate( a2dDoUpdateImmediateData *data );
00439
00440
00441
00442
00443
00444 virtual bool AdjustAfterChange( bool final );
00445
00446 #if wxART2D_USE_CVGIO
00447 virtual void DoLoad( wxObject* parent, a2dIOHandlerXmlSerIn& parser, a2dXmlSer_flag xmlparts );
00448 virtual void DoSave( wxObject* parent, a2dIOHandlerXmlSerOut &out, a2dXmlSer_flag xmlparts , a2dObjectList* towrite );
00449 #endif //wxART2D_USE_CVGIO
00450
00451
00452 void SetEndPoint( int iEnd, int iNext, double x, double y, bool final );
00453
00454
00455 bool IsDislocated();
00456
00457 DECLARE_CLASS(a2dWirePolylineL)
00458
00459 protected:
00460
00461 virtual void EditFeedback( a2dIterC& ic, const a2dFeedbackId *id, a2dCanvasObject *currentEdit=0, int depth=INT_MAX, a2dCanvasObjectFlagsMask flags=0, double x=0, double y=0 );
00462
00463 virtual bool GeneratePins( a2dPinClass* toConnectTo, a2dConnectTask task, double x, double y );
00464
00465
00466 bool m_wasVertical;
00467
00468 bool m_inverted;
00469
00470 a2dPinClass *m_objBegin;
00471 a2dPinClass *m_objEnd;
00472
00473 a2dPinClass *m_wireBegin;
00474 a2dPinClass *m_wireEnd;
00475
00476 bool m_oneLine;
00477
00478 public:
00479
00480 static a2dPropertyIdBool* PROPID_Reroute;
00481
00482 static a2dPropertyIdBool* PROPID_Rerouteadded;
00483
00484 DECLARE_PROPERTIES()
00485
00486 private:
00487
00488 a2dWirePolylineL( const a2dWirePolylineL &other );
00489 };
00490
00491
00492
00493
00494
00495
00496
00497
00498 class A2DCANVASDLLEXP a2dWireEnd: public a2dCanvasObject
00499 {
00500 DECLARE_CLASS(a2dWireEnd)
00501
00502 public:
00503
00504 a2dWireEnd( double x = 0 , double y = 0);
00505 a2dWireEnd( const a2dWireEnd& obj, CloneOptions options );
00506 virtual a2dObject* Clone( CloneOptions options ) const;
00507
00508 private:
00509
00510 a2dWireEnd( const a2dWireEnd &other );
00511 };
00512
00513 #endif