Commit 07877f90 authored by Lorenzo Marcantonio's avatar Lorenzo Marcantonio

Replaced the display line clipper with the way simpler (and faster) Cohen-Sutherland one.

A couple of trivial accessors made inline
parent f7c1372d
...@@ -79,6 +79,26 @@ static EDA_COLOR_T s_DC_lastbrushcolor = UNSPECIFIED_COLOR; ...@@ -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; ...@@ -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;
if( y2 > maxY ) else
{ thisoutcode = outcode2;
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 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 */
{
if( x2 != clippedX )
x2 = clippedX;
if( y2 != clippedY )
y2 = clippedY;
return false;
}
/* If we're here, something has gone terribly wrong. */ /* One clip round
#if DEBUG_DUMP_CLIP_ERROR_COORDS * Since we use the full range of 32 bit ints, the proportion
wxLogDebug( wxT( "Line (%d,%d):(%d,%d) in rectangle (%d,%d,%d,%d) clipped to (%d,%d,%d,%d)" ), * computation has to be done in 64 bits to avoid horrible
tmpX1, tmpY1, tmpX2, tmpY2, minX, minY, maxX, maxY, x1, y1, x2, y2 ); * results */
#endif if( thisoutcode & 1 ) // Clip the bottom
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 ) y = aClipBox->GetBottom();
{ x = x1 + (x2 - x1) * int64_t(y - y1) / (y2 - y1);
x2 = minX; }
return false; else if( thisoutcode & 2 ) // Clip the top
}
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 ) y = aClipBox->GetY();
x1 = clippedX; x = x1 + (x2 - x1) * int64_t(y - y1) / (y2 - y1);
if( y1 != clippedY ) }
y1 = clippedY; else if( thisoutcode & 8 ) // Clip the right
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; x = aClipBox->GetRight();
intersectY = &intersectY2; y = y1 + (y2 - y1) * int64_t(x - x1) / (x2 - x1);
haveFirstPoint = true;
} }
else // if( thisoutcode & 4), obviously, clip the left
/* Top clip rectangle line. */
if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, minY, maxX, minY,
intersectX, intersectY ) )
{ {
intersectX = &intersectX2; x = aClipBox->GetX();
intersectY = &intersectY2; y = y1 + (y2 - y1) * int64_t(x - x1) / (x2 - x1);
if( haveFirstPoint )
{
x1 = intersectX1;
y1 = intersectY1;
x2 = intersectX2;
y2 = intersectY2;
return false;
}
haveFirstPoint = true;
} }
/* Right clip rectangle line. */ // Put the result back and update the boundary code
if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, maxX, minY, maxX, maxY, // No ambiguity, otherwise it would have been a fast reject
intersectX, intersectY ) ) if( thisoutcode == outcode1 )
{ {
intersectX = &intersectX2; x1 = x;
intersectY = &intersectY2; y1 = y;
if( haveFirstPoint ) outcode1 = clipOutCode( aClipBox, x1, y1 );
{
x1 = intersectX1;
y1 = intersectY1;
x2 = intersectX2;
y2 = intersectY2;
return false;
}
haveFirstPoint = true;
} }
else
/* Bottom clip rectangle line. */
if( TestForIntersectionOfStraightLineSegments( x1, y1, x2, y2, minX, maxY, maxX, maxY,
intersectX, intersectY ) )
{ {
intersectX = &intersectX2; x2 = x;
intersectY = &intersectY2; y2 = y;
if( haveFirstPoint ) outcode2 = clipOutCode( aClipBox, x2, y2 );
{
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
} }
return false;
/* 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 ) ...@@ -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 ) ...@@ -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 @@ ...@@ -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: ...@@ -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: ...@@ -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
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment