Replaced the display line clipper with the way simpler (and faster) Cohen-Sutherland one.
A couple of trivial accessors made inline
This commit is contained in:
parent
f7c1372d58
commit
07877f9044
|
@ -79,6 +79,26 @@ static EDA_COLOR_T s_DC_lastbrushcolor = UNSPECIFIED_COLOR;
|
||||||
static bool s_DC_lastbrushfill = false;
|
static bool s_DC_lastbrushfill = false;
|
||||||
static wxDC* s_DC_lastDC = NULL;
|
static wxDC* s_DC_lastDC = NULL;
|
||||||
|
|
||||||
|
/***
|
||||||
|
* Utility for the line clipping code, returns the boundary code of
|
||||||
|
* a point. Bit allocation is arbitrary
|
||||||
|
*/
|
||||||
|
static inline int clipOutCode( const EDA_RECT *aClipBox, int x, int y )
|
||||||
|
{
|
||||||
|
int code;
|
||||||
|
if( y < aClipBox->GetY() )
|
||||||
|
code = 2;
|
||||||
|
else if( y > aClipBox->GetBottom() )
|
||||||
|
code = 1;
|
||||||
|
else
|
||||||
|
code = 0;
|
||||||
|
if( x < aClipBox->GetX() )
|
||||||
|
code |= 4;
|
||||||
|
else if( x > aClipBox->GetRight() )
|
||||||
|
code |= 8;
|
||||||
|
return code;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Test if any part of a line falls within the bounds of a rectangle.
|
* Test if any part of a line falls within the bounds of a rectangle.
|
||||||
|
@ -93,225 +113,68 @@ static wxDC* s_DC_lastDC = NULL;
|
||||||
*
|
*
|
||||||
* @return - False if any part of the line lies within the rectangle.
|
* @return - False if any part of the line lies within the rectangle.
|
||||||
*/
|
*/
|
||||||
static bool clipLine( EDA_RECT* aClipBox, int& x1, int& y1, int& x2, int& y2 )
|
static bool clipLine( const EDA_RECT *aClipBox, int &x1, int &y1, int &x2, int &y2 )
|
||||||
{
|
{
|
||||||
if( aClipBox->Contains( x1, y1 ) && aClipBox->Contains( x2, y2 ) )
|
// Stock Cohen-Sutherland algorithm; check *any* CG book for details
|
||||||
return false;
|
int outcode1 = clipOutCode( aClipBox, x1, y1 );
|
||||||
|
int outcode2 = clipOutCode( aClipBox, x2, y2 );
|
||||||
|
|
||||||
wxRect rect = *aClipBox;
|
while( outcode1 || outcode2 )
|
||||||
int minX = rect.GetLeft();
|
|
||||||
int maxX = rect.GetRight();
|
|
||||||
int minY = rect.GetTop();
|
|
||||||
int maxY = rect.GetBottom();
|
|
||||||
int clippedX, clippedY;
|
|
||||||
|
|
||||||
#if DEBUG_DUMP_CLIP_COORDS
|
|
||||||
int tmpX1, tmpY1, tmpX2, tmpY2;
|
|
||||||
tmpX1 = x1;
|
|
||||||
tmpY1 = y1;
|
|
||||||
tmpX2 = x2;
|
|
||||||
tmpY2 = y2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if( aClipBox->Contains( x1, y1 ) )
|
|
||||||
{
|
{
|
||||||
if( x1 == x2 ) /* Vertical line, clip Y. */
|
// Fast reject
|
||||||
{
|
if( outcode1 & outcode2 )
|
||||||
if( y2 < minY )
|
return true;
|
||||||
{
|
|
||||||
y2 = minY;
|
// Choose a side to clip
|
||||||
return false;
|
int thisoutcode, x, y;
|
||||||
}
|
if( outcode1 )
|
||||||
|
thisoutcode = outcode1;
|
||||||
|
else
|
||||||
|
thisoutcode = outcode2;
|
||||||
|
|
||||||
if( y2 > maxY )
|
/* One clip round
|
||||||
{
|
* Since we use the full range of 32 bit ints, the proportion
|
||||||
y2 = maxY;
|
* computation has to be done in 64 bits to avoid horrible
|
||||||
return false;
|
* results */
|
||||||
}
|
if( thisoutcode & 1 ) // Clip the bottom
|
||||||
|
{
|
||||||
|
y = aClipBox->GetBottom();
|
||||||
|
x = x1 + (x2 - x1) * int64_t(y - y1) / (y2 - y1);
|
||||||
|
}
|
||||||
|
else if( thisoutcode & 2 ) // Clip the top
|
||||||
|
{
|
||||||
|
y = aClipBox->GetY();
|
||||||
|
x = x1 + (x2 - x1) * int64_t(y - y1) / (y2 - y1);
|
||||||
|
}
|
||||||
|
else if( thisoutcode & 8 ) // Clip the right
|
||||||
|
{
|
||||||
|
x = aClipBox->GetRight();
|
||||||
|
y = y1 + (y2 - y1) * int64_t(x - x1) / (x2 - x1);
|
||||||
}
|
}
|
||||||
else if( y1 == y2 ) /* Horizontal line, clip X. */
|
else // if( thisoutcode & 4), obviously, clip the left
|
||||||
{
|
{
|
||||||
if( x2 < minX )
|
x = aClipBox->GetX();
|
||||||
{
|
y = y1 + (y2 - y1) * int64_t(x - x1) / (x2 - x1);
|
||||||
x2 = minX;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( x2 > maxX )
|
|
||||||
{
|
|
||||||
x2 = maxX;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're here, it's a diagonal line. */
|
// Put the result back and update the boundary code
|
||||||
|
// No ambiguity, otherwise it would have been a fast reject
|
||||||
if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, minX, maxY,
|
if( thisoutcode == outcode1 )
|
||||||
&clippedX, &clippedY ) /* Left */
|
|
||||||
|| TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, maxX, minY,
|
|
||||||
&clippedX, &clippedY ) /* Top */
|
|
||||||
|| TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, maxX, minY, maxX, maxY,
|
|
||||||
&clippedX, &clippedY ) /* Right */
|
|
||||||
|| TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, maxY, maxX, maxY,
|
|
||||||
&clippedX, &clippedY ) ) /* Bottom */
|
|
||||||
{
|
{
|
||||||
if( x2 != clippedX )
|
x1 = x;
|
||||||
x2 = clippedX;
|
y1 = y;
|
||||||
if( y2 != clippedY )
|
outcode1 = clipOutCode( aClipBox, x1, y1 );
|
||||||
y2 = clippedY;
|
}
|
||||||
return false;
|
else
|
||||||
|
{
|
||||||
|
x2 = x;
|
||||||
|
y2 = y;
|
||||||
|
outcode2 = clipOutCode( aClipBox, x2, y2 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If we're here, something has gone terribly wrong. */
|
|
||||||
#if DEBUG_DUMP_CLIP_ERROR_COORDS
|
|
||||||
wxLogDebug( wxT( "Line (%d,%d):(%d,%d) in rectangle (%d,%d,%d,%d) clipped to (%d,%d,%d,%d)" ),
|
|
||||||
tmpX1, tmpY1, tmpX2, tmpY2, minX, minY, maxX, maxY, x1, y1, x2, y2 );
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
else if( aClipBox->Contains( x2, y2 ) )
|
return false;
|
||||||
{
|
|
||||||
if( x1 == x2 ) /* Vertical line, clip Y. */
|
|
||||||
{
|
|
||||||
if( y2 < minY )
|
|
||||||
{
|
|
||||||
y2 = minY;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( y2 > maxY )
|
|
||||||
{
|
|
||||||
y2 = maxY;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if( y1 == y2 ) /* Horizontal line, clip X. */
|
|
||||||
{
|
|
||||||
if( x2 < minX )
|
|
||||||
{
|
|
||||||
x2 = minX;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if( x2 > maxX )
|
|
||||||
{
|
|
||||||
x2 = maxX;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, minX, maxY,
|
|
||||||
&clippedX, &clippedY ) /* Left */
|
|
||||||
|| TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, maxX, minY,
|
|
||||||
&clippedX, &clippedY ) /* Top */
|
|
||||||
|| TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, maxX, minY, maxX, maxY,
|
|
||||||
&clippedX, &clippedY ) /* Right */
|
|
||||||
|| TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, maxY, maxX, maxY,
|
|
||||||
&clippedX, &clippedY ) ) /* Bottom */
|
|
||||||
{
|
|
||||||
if( x1 != clippedX )
|
|
||||||
x1 = clippedX;
|
|
||||||
if( y1 != clippedY )
|
|
||||||
y1 = clippedY;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we're here, something has gone terribly wrong. */
|
|
||||||
#if DEBUG_DUMP_CLIP_ERROR_COORDS
|
|
||||||
wxLogDebug( wxT( "Line (%d,%d):(%d,%d) in rectangle (%d,%d,%d,%d) clipped to (%d,%d,%d,%d)" ),
|
|
||||||
tmpX1, tmpY1, tmpX2, tmpY2, minX, minY, maxX, maxY, x1, y1, x2, y2 );
|
|
||||||
#endif
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
int* intersectX;
|
|
||||||
int* intersectY;
|
|
||||||
int intersectX1, intersectY1, intersectX2, intersectY2;
|
|
||||||
bool haveFirstPoint = false;
|
|
||||||
|
|
||||||
intersectX = &intersectX1;
|
|
||||||
intersectY = &intersectY1;
|
|
||||||
|
|
||||||
/* Left clip rectangle line. */
|
|
||||||
if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, minX, maxY,
|
|
||||||
intersectX, intersectY ) )
|
|
||||||
{
|
|
||||||
intersectX = &intersectX2;
|
|
||||||
intersectY = &intersectY2;
|
|
||||||
haveFirstPoint = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Top clip rectangle line. */
|
|
||||||
if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, maxX, minY,
|
|
||||||
intersectX, intersectY ) )
|
|
||||||
{
|
|
||||||
intersectX = &intersectX2;
|
|
||||||
intersectY = &intersectY2;
|
|
||||||
if( haveFirstPoint )
|
|
||||||
{
|
|
||||||
x1 = intersectX1;
|
|
||||||
y1 = intersectY1;
|
|
||||||
x2 = intersectX2;
|
|
||||||
y2 = intersectY2;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
haveFirstPoint = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Right clip rectangle line. */
|
|
||||||
if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, maxX, minY, maxX, maxY,
|
|
||||||
intersectX, intersectY ) )
|
|
||||||
{
|
|
||||||
intersectX = &intersectX2;
|
|
||||||
intersectY = &intersectY2;
|
|
||||||
if( haveFirstPoint )
|
|
||||||
{
|
|
||||||
x1 = intersectX1;
|
|
||||||
y1 = intersectY1;
|
|
||||||
x2 = intersectX2;
|
|
||||||
y2 = intersectY2;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
haveFirstPoint = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Bottom clip rectangle line. */
|
|
||||||
if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, maxY, maxX, maxY,
|
|
||||||
intersectX, intersectY ) )
|
|
||||||
{
|
|
||||||
intersectX = &intersectX2;
|
|
||||||
intersectY = &intersectY2;
|
|
||||||
if( haveFirstPoint )
|
|
||||||
{
|
|
||||||
x1 = intersectX1;
|
|
||||||
y1 = intersectY1;
|
|
||||||
x2 = intersectX2;
|
|
||||||
y2 = intersectY2;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we're here and only one line of the clip box has been intersected,
|
|
||||||
* something has gone terribly wrong. */
|
|
||||||
#if DEBUG_DUMP_CLIP_ERROR_COORDS
|
|
||||||
if( haveFirstPoint )
|
|
||||||
wxLogDebug( wxT( "Line (%d,%d):(%d,%d) in rectangle (%d,%d,%d,%d) clipped to (%d,%d,%d,%d)" ),
|
|
||||||
tmpX1, tmpY1, tmpX2, tmpY2, minX, minY, maxX, maxY, x1, y1, x2, y2 );
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Set this to one to verify that diagonal lines get clipped properly. */
|
|
||||||
#if DEBUG_DUMP_CLIP_COORDS
|
|
||||||
if( !( x1 == x2 || y1 == y2 ) )
|
|
||||||
wxLogDebug( wxT( "Clipped line (%d,%d):(%d,%d) from rectangle (%d,%d,%d,%d)" ),
|
|
||||||
tmpX1, tmpY1, tmpX2, tmpY2, minX, minY, maxX, maxY );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static void WinClipAndDrawLine( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
|
static void WinClipAndDrawLine( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
|
||||||
EDA_COLOR_T Color, int width = 1 )
|
EDA_COLOR_T Color, int width = 1 )
|
||||||
{
|
{
|
||||||
|
|
|
@ -50,12 +50,6 @@ BOARD_CONNECTED_ITEM::BOARD_CONNECTED_ITEM( const BOARD_CONNECTED_ITEM& aItem )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int BOARD_CONNECTED_ITEM::GetNetCode() const
|
|
||||||
{
|
|
||||||
return m_netinfo->GetNet();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
void BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode )
|
void BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode )
|
||||||
{
|
{
|
||||||
BOARD* board = GetBoard();
|
BOARD* board = GetBoard();
|
||||||
|
@ -75,18 +69,6 @@ void BOARD_CONNECTED_ITEM::SetNetCode( int aNetCode )
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
const wxString& BOARD_CONNECTED_ITEM::GetNetname() const
|
|
||||||
{
|
|
||||||
return m_netinfo->GetNetname();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const wxString& BOARD_CONNECTED_ITEM::GetShortNetname() const
|
|
||||||
{
|
|
||||||
return m_netinfo->GetShortNetname();
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int BOARD_CONNECTED_ITEM::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const
|
int BOARD_CONNECTED_ITEM::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const
|
||||||
{
|
{
|
||||||
NETCLASSPTR myclass = GetNetClass();
|
NETCLASSPTR myclass = GetNetClass();
|
||||||
|
|
|
@ -32,8 +32,8 @@
|
||||||
#define BOARD_CONNECTED_ITEM_H
|
#define BOARD_CONNECTED_ITEM_H
|
||||||
|
|
||||||
#include <class_board_item.h>
|
#include <class_board_item.h>
|
||||||
|
#include <class_netinfo.h>
|
||||||
|
|
||||||
class NETINFO_ITEM;
|
|
||||||
class NETCLASS;
|
class NETCLASS;
|
||||||
class TRACK;
|
class TRACK;
|
||||||
class D_PAD;
|
class D_PAD;
|
||||||
|
@ -77,7 +77,10 @@ public:
|
||||||
* Function GetNetCode
|
* Function GetNetCode
|
||||||
* @return int - the net code.
|
* @return int - the net code.
|
||||||
*/
|
*/
|
||||||
int GetNetCode() const;
|
int GetNetCode() const
|
||||||
|
{
|
||||||
|
return m_netinfo->GetNet();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function SetNetCode
|
* Function SetNetCode
|
||||||
|
@ -119,13 +122,19 @@ public:
|
||||||
* Function GetNetname
|
* Function GetNetname
|
||||||
* @return wxString - the full netname
|
* @return wxString - the full netname
|
||||||
*/
|
*/
|
||||||
const wxString& GetNetname() const;
|
const wxString& GetNetname() const
|
||||||
|
{
|
||||||
|
return m_netinfo->GetNetname();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetShortNetname
|
* Function GetShortNetname
|
||||||
* @return wxString - the short netname
|
* @return wxString - the short netname
|
||||||
*/
|
*/
|
||||||
const wxString& GetShortNetname() const;
|
const wxString& GetShortNetname() const
|
||||||
|
{
|
||||||
|
return m_netinfo->GetShortNetname();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetClearance
|
* Function GetClearance
|
||||||
|
|
Loading…
Reference in New Issue