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 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.
|
||||
|
@ -93,225 +113,68 @@ static wxDC* s_DC_lastDC = NULL;
|
|||
*
|
||||
* @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 ) )
|
||||
return false;
|
||||
// Stock Cohen-Sutherland algorithm; check *any* CG book for details
|
||||
int outcode1 = clipOutCode( aClipBox, x1, y1 );
|
||||
int outcode2 = clipOutCode( aClipBox, x2, y2 );
|
||||
|
||||
wxRect rect = *aClipBox;
|
||||
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 ) )
|
||||
while( outcode1 || outcode2 )
|
||||
{
|
||||
if( x1 == x2 ) /* Vertical line, clip Y. */
|
||||
{
|
||||
if( y2 < minY )
|
||||
{
|
||||
y2 = minY;
|
||||
return false;
|
||||
}
|
||||
// Fast reject
|
||||
if( outcode1 & outcode2 )
|
||||
return true;
|
||||
|
||||
if( y2 > maxY )
|
||||
{
|
||||
y2 = maxY;
|
||||
return false;
|
||||
}
|
||||
// Choose a side to clip
|
||||
int thisoutcode, x, y;
|
||||
if( outcode1 )
|
||||
thisoutcode = outcode1;
|
||||
else
|
||||
thisoutcode = outcode2;
|
||||
|
||||
/* One clip round
|
||||
* Since we use the full range of 32 bit ints, the proportion
|
||||
* computation has to be done in 64 bits to avoid horrible
|
||||
* results */
|
||||
if( thisoutcode & 1 ) // Clip the bottom
|
||||
{
|
||||
y = aClipBox->GetBottom();
|
||||
x = x1 + (x2 - x1) * int64_t(y - y1) / (y2 - y1);
|
||||
}
|
||||
else if( y1 == y2 ) /* Horizontal line, clip X. */
|
||||
else if( thisoutcode & 2 ) // Clip the top
|
||||
{
|
||||
if( x2 < minX )
|
||||
{
|
||||
x2 = minX;
|
||||
return false;
|
||||
}
|
||||
|
||||
if( x2 > maxX )
|
||||
{
|
||||
x2 = maxX;
|
||||
return false;
|
||||
}
|
||||
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( thisoutcode & 4), obviously, clip the left
|
||||
{
|
||||
x = aClipBox->GetX();
|
||||
y = y1 + (y2 - y1) * int64_t(x - x1) / (x2 - x1);
|
||||
}
|
||||
|
||||
/* If we're here, it's a diagonal line. */
|
||||
|
||||
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 */
|
||||
// Put the result back and update the boundary code
|
||||
// No ambiguity, otherwise it would have been a fast reject
|
||||
if( thisoutcode == outcode1 )
|
||||
{
|
||||
if( x2 != clippedX )
|
||||
x2 = clippedX;
|
||||
if( y2 != clippedY )
|
||||
y2 = clippedY;
|
||||
return false;
|
||||
x1 = x;
|
||||
y1 = y;
|
||||
outcode1 = clipOutCode( aClipBox, x1, y1 );
|
||||
}
|
||||
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 ) )
|
||||
{
|
||||
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;
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static void WinClipAndDrawLine( EDA_RECT* ClipBox, wxDC* DC, int x1, int y1, int x2, int y2,
|
||||
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 )
|
||||
{
|
||||
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
|
||||
{
|
||||
NETCLASSPTR myclass = GetNetClass();
|
||||
|
|
|
@ -32,8 +32,8 @@
|
|||
#define BOARD_CONNECTED_ITEM_H
|
||||
|
||||
#include <class_board_item.h>
|
||||
#include <class_netinfo.h>
|
||||
|
||||
class NETINFO_ITEM;
|
||||
class NETCLASS;
|
||||
class TRACK;
|
||||
class D_PAD;
|
||||
|
@ -77,7 +77,10 @@ public:
|
|||
* Function GetNetCode
|
||||
* @return int - the net code.
|
||||
*/
|
||||
int GetNetCode() const;
|
||||
int GetNetCode() const
|
||||
{
|
||||
return m_netinfo->GetNet();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function SetNetCode
|
||||
|
@ -119,13 +122,19 @@ public:
|
|||
* Function GetNetname
|
||||
* @return wxString - the full netname
|
||||
*/
|
||||
const wxString& GetNetname() const;
|
||||
const wxString& GetNetname() const
|
||||
{
|
||||
return m_netinfo->GetNetname();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetShortNetname
|
||||
* @return wxString - the short netname
|
||||
*/
|
||||
const wxString& GetShortNetname() const;
|
||||
const wxString& GetShortNetname() const
|
||||
{
|
||||
return m_netinfo->GetShortNetname();
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetClearance
|
||||
|
|
Loading…
Reference in New Issue