Commit 1a97b31d authored by Marco Mattila's avatar Marco Mattila

Combine DRAWSEGMENT and EDGE_MOD code in pcbnew.

parent e414f8da
...@@ -168,51 +168,6 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon( ...@@ -168,51 +168,6 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon(
} }
} }
/**
* Function TransformShapeWithClearanceToPolygon
* Convert the track shape to a closed polygon
* Used in filling zones calculations
* Circles and arcs are approximated by segments
* @param aCornerBuffer = a buffer to store the polygon
* @param aClearanceValue = the clearance around the pad
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aCorrectionFactor = the correction to apply to circles radius to keep
* clearance when the circle is approxiamted by segment bigger or equal
* to the real clearance value (usually near from 1.0)
*/
void EDGE_MODULE::TransformShapeWithClearanceToPolygon(
std::vector <CPolyPt>& aCornerBuffer,
int aClearanceValue,
int aCircleToSegmentsCount,
double aCorrectionFactor )
{
switch( m_Shape )
{
case S_CIRCLE:
TransformArcToPolygon( aCornerBuffer, m_Start, // Circle centre
m_End, 3600,
aCircleToSegmentsCount,
m_Width + (2 * aClearanceValue) );
break;
case S_ARC:
TransformArcToPolygon( aCornerBuffer, m_Start,
m_End, m_Angle,
aCircleToSegmentsCount,
m_Width + (2 * aClearanceValue) );
break;
case S_SEGMENT:
TransformRoundedEndsSegmentToPolygon(
aCornerBuffer, m_Start, m_End,
aCircleToSegmentsCount, m_Width + (2 * aClearanceValue) );
break;
default:
break;
}
}
/** /**
* Function TransformShapeWithClearanceToPolygon * Function TransformShapeWithClearanceToPolygon
......
...@@ -18,24 +18,24 @@ ...@@ -18,24 +18,24 @@
#include "protos.h" #include "protos.h"
#include "richio.h" #include "richio.h"
/* DRAWSEGMENT: constructor */
DRAWSEGMENT::DRAWSEGMENT( BOARD_ITEM* aParent, KICAD_T idtype ) : DRAWSEGMENT::DRAWSEGMENT( BOARD_ITEM* aParent, KICAD_T idtype ) :
BOARD_ITEM( aParent, idtype ) BOARD_ITEM( aParent, idtype )
{ {
m_Width = m_Flags = m_Shape = m_Type = m_Angle = 0; m_Width = m_Flags = m_Type = m_Angle = 0;
m_Shape = S_SEGMENT;
} }
/* destructor */
DRAWSEGMENT:: ~DRAWSEGMENT() DRAWSEGMENT:: ~DRAWSEGMENT()
{ {
} }
/*******************************************/
void DRAWSEGMENT::Copy( DRAWSEGMENT* source ) void DRAWSEGMENT::Copy( DRAWSEGMENT* source )
/*******************************************/
{ {
if( source == NULL )
return;
m_Type = source->m_Type; m_Type = source->m_Type;
m_Layer = source->m_Layer; m_Layer = source->m_Layer;
m_Width = source->m_Width; m_Width = source->m_Width;
...@@ -46,26 +46,18 @@ void DRAWSEGMENT::Copy( DRAWSEGMENT* source ) ...@@ -46,26 +46,18 @@ void DRAWSEGMENT::Copy( DRAWSEGMENT* source )
m_TimeStamp = source->m_TimeStamp; m_TimeStamp = source->m_TimeStamp;
m_BezierC1 = source->m_BezierC1; m_BezierC1 = source->m_BezierC1;
m_BezierC2 = source->m_BezierC1; m_BezierC2 = source->m_BezierC1;
m_BezierPoints = source->m_BezierPoints;
} }
/**
* Function Rotate void DRAWSEGMENT::Rotate( const wxPoint& aRotCentre, int aAngle )
* Rotate this object.
* @param aRotCentre - the rotation point.
* @param aAngle - the rotation angle in 0.1 degree.
*/
void DRAWSEGMENT::Rotate(const wxPoint& aRotCentre, int aAngle)
{ {
RotatePoint( &m_Start, aRotCentre, aAngle ); RotatePoint( &m_Start, aRotCentre, aAngle );
RotatePoint( &m_End, aRotCentre, aAngle ); RotatePoint( &m_End, aRotCentre, aAngle );
} }
/**
* Function Flip void DRAWSEGMENT::Flip( const wxPoint& aCentre )
* Flip this object, i.e. change the board side for this object
* @param aCentre - the rotation point.
*/
void DRAWSEGMENT::Flip(const wxPoint& aCentre )
{ {
m_Start.y = aCentre.y - (m_Start.y - aCentre.y); m_Start.y = aCentre.y - (m_Start.y - aCentre.y);
m_End.y = aCentre.y - (m_End.y - aCentre.y); m_End.y = aCentre.y - (m_End.y - aCentre.y);
...@@ -79,20 +71,22 @@ void DRAWSEGMENT::Flip(const wxPoint& aCentre ) ...@@ -79,20 +71,22 @@ void DRAWSEGMENT::Flip(const wxPoint& aCentre )
bool DRAWSEGMENT::Save( FILE* aFile ) const bool DRAWSEGMENT::Save( FILE* aFile ) const
{ {
bool rc = false;
if( fprintf( aFile, "$DRAWSEGMENT\n" ) != sizeof("$DRAWSEGMENT\n") - 1 ) if( fprintf( aFile, "$DRAWSEGMENT\n" ) != sizeof("$DRAWSEGMENT\n") - 1 )
goto out; return false;
fprintf( aFile, "Po %d %d %d %d %d %d\n", fprintf( aFile, "Po %d %d %d %d %d %d\n",
m_Shape, m_Shape,
m_Start.x, m_Start.y, m_Start.x, m_Start.y,
m_End.x, m_End.y, m_Width ); m_End.x, m_End.y, m_Width );
if( m_Type != S_CURVE) {
if( m_Type != S_CURVE )
{
fprintf( aFile, "De %d %d %d %lX %X\n", fprintf( aFile, "De %d %d %d %lX %X\n",
m_Layer, m_Type, m_Angle, m_Layer, m_Type, m_Angle,
m_TimeStamp, ReturnStatus() ); m_TimeStamp, ReturnStatus() );
} else { }
else
{
fprintf( aFile, "De %d %d %d %lX %X %d %d %d %d\n", fprintf( aFile, "De %d %d %d %lX %X %d %d %d %d\n",
m_Layer, m_Type, m_Angle, m_Layer, m_Type, m_Angle,
m_TimeStamp, ReturnStatus(), m_TimeStamp, ReturnStatus(),
...@@ -101,34 +95,29 @@ bool DRAWSEGMENT::Save( FILE* aFile ) const ...@@ -101,34 +95,29 @@ bool DRAWSEGMENT::Save( FILE* aFile ) const
} }
if( fprintf( aFile, "$EndDRAWSEGMENT\n" ) != sizeof("$EndDRAWSEGMENT\n") - 1 ) if( fprintf( aFile, "$EndDRAWSEGMENT\n" ) != sizeof("$EndDRAWSEGMENT\n") - 1 )
goto out; return false;
rc = true;
out: return true;
return rc;
} }
/******************************************************************/
bool DRAWSEGMENT::ReadDrawSegmentDescr( LINE_READER* aReader ) bool DRAWSEGMENT::ReadDrawSegmentDescr( LINE_READER* aReader )
/******************************************************************/
/* Read a DRAWSEGMENT from a file
*/
{ {
char* Line; char* Line;
while( aReader->ReadLine() ) while( aReader->ReadLine() )
{ {
Line = aReader->Line(); Line = aReader->Line();
if( strnicmp( Line, "$End", 4 ) == 0 ) if( strnicmp( Line, "$End", 4 ) == 0 )
return TRUE; /* End of description */ return TRUE; /* End of description */
if( Line[0] == 'P' ) if( Line[0] == 'P' )
{ {
sscanf( Line + 2, " %d %d %d %d %d %d", sscanf( Line + 2, " %d %d %d %d %d %d",
&m_Shape, &m_Start.x, &m_Start.y, &m_Shape, &m_Start.x, &m_Start.y,
&m_End.x, &m_End.y, &m_Width ); &m_End.x, &m_End.y, &m_Width );
if( m_Width < 0 ) if( m_Width < 0 )
m_Width = 0; m_Width = 0;
} }
...@@ -136,39 +125,41 @@ bool DRAWSEGMENT::ReadDrawSegmentDescr( LINE_READER* aReader ) ...@@ -136,39 +125,41 @@ bool DRAWSEGMENT::ReadDrawSegmentDescr( LINE_READER* aReader )
if( Line[0] == 'D' ) if( Line[0] == 'D' )
{ {
int status; int status;
char* token=0; char* token = 0;
token = strtok(Line," "); token = strtok( Line," " );
for(int i=0; (token = strtok(NULL," ")) != NULL; i++){ for( int i = 0; (token = strtok( NULL," " )) != NULL; i++ )
switch(i){ {
switch( i )
{
case 0: case 0:
sscanf(token,"%d",&m_Layer); sscanf( token,"%d",&m_Layer );
break; break;
case 1: case 1:
sscanf(token,"%d",&m_Type); sscanf( token,"%d",&m_Type );
break; break;
case 2: case 2:
sscanf(token,"%d",&m_Angle); sscanf( token,"%d",&m_Angle );
break; break;
case 3: case 3:
sscanf(token,"%lX",&m_TimeStamp); sscanf( token,"%lX",&m_TimeStamp );
break; break;
case 4: case 4:
sscanf(token,"%X",&status); sscanf( token,"%X",&status );
break; break;
/* Bezier Control Points*/ /* Bezier Control Points*/
case 5: case 5:
sscanf(token,"%d",&m_BezierC1.x); sscanf( token,"%d",&m_BezierC1.x );
break; break;
case 6: case 6:
sscanf(token,"%d",&m_BezierC1.y); sscanf( token,"%d",&m_BezierC1.y );
break; break;
case 7: case 7:
sscanf(token,"%d",&m_BezierC2.x); sscanf( token,"%d",&m_BezierC2.x );
break; break;
case 8: case 8:
sscanf(token,"%d",&m_BezierC2.y); sscanf( token,"%d",&m_BezierC2.y );
break; break;
default: default:
break; break;
...@@ -177,6 +168,7 @@ bool DRAWSEGMENT::ReadDrawSegmentDescr( LINE_READER* aReader ) ...@@ -177,6 +168,7 @@ bool DRAWSEGMENT::ReadDrawSegmentDescr( LINE_READER* aReader )
if( m_Layer < FIRST_NO_COPPER_LAYER ) if( m_Layer < FIRST_NO_COPPER_LAYER )
m_Layer = FIRST_NO_COPPER_LAYER; m_Layer = FIRST_NO_COPPER_LAYER;
if( m_Layer > LAST_NO_COPPER_LAYER ) if( m_Layer > LAST_NO_COPPER_LAYER )
m_Layer = LAST_NO_COPPER_LAYER; m_Layer = LAST_NO_COPPER_LAYER;
...@@ -224,6 +216,14 @@ wxPoint DRAWSEGMENT::GetEnd() const ...@@ -224,6 +216,14 @@ wxPoint DRAWSEGMENT::GetEnd() const
} }
MODULE* DRAWSEGMENT::GetParentModule() const
{
if( m_Parent->Type() != TYPE_MODULE )
return NULL;
return (MODULE*) m_Parent;
}
void DRAWSEGMENT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int draw_mode, const wxPoint& aOffset ) void DRAWSEGMENT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int draw_mode, const wxPoint& aOffset )
{ {
...@@ -233,10 +233,11 @@ void DRAWSEGMENT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int draw_mode, const wx ...@@ -233,10 +233,11 @@ void DRAWSEGMENT::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int draw_mode, const wx
int rayon; int rayon;
BOARD * brd = GetBoard( ); BOARD * brd = GetBoard( );
if( brd->IsLayerVisible( GetLayer() ) == false ) if( brd->IsLayerVisible( GetLayer() ) == false )
return; return;
color = brd->GetLayerColor(GetLayer()); color = brd->GetLayerColor( GetLayer() );
GRSetDrawMode( DC, draw_mode ); GRSetDrawMode( DC, draw_mode );
l_piste = m_Width >> 1; /* half trace width */ l_piste = m_Width >> 1; /* half trace width */
...@@ -404,18 +405,69 @@ void DRAWSEGMENT::DisplayInfo( EDA_DRAW_FRAME* frame ) ...@@ -404,18 +405,69 @@ void DRAWSEGMENT::DisplayInfo( EDA_DRAW_FRAME* frame )
} }
/** EDA_RECT DRAWSEGMENT::GetBoundingBox() const
* Function HitTest {
* tests if the given wxPoint is within the bounds of this object. EDA_RECT bbox;
* @param aRefPos A wxPoint to test
* @return bool - true if a hit, else false bbox.SetOrigin( m_Start );
*/
switch( m_Shape )
{
case S_SEGMENT:
bbox.SetEnd( m_End );
bbox.Inflate( (m_Width / 2) + 1 );
break;
case S_CIRCLE:
bbox.Inflate( GetRadius() + 1 );
break;
case S_ARC:
{
bbox.Inflate( GetRadius() + 1 );
}
break;
case S_POLYGON:
{
wxPoint p_end;
MODULE* module = GetParentModule();
for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
{
wxPoint pt = m_PolyPoints[ii];
if( module ) // Transform, if we belong to a module
{
RotatePoint( &pt, module->m_Orient );
pt += module->m_Pos;
}
if( ii == 0 )
p_end = pt;
bbox.m_Pos.x = MIN( bbox.m_Pos.x, pt.x );
bbox.m_Pos.y = MIN( bbox.m_Pos.y, pt.y );
p_end.x = MAX( p_end.x, pt.x );
p_end.y = MAX( p_end.y, pt.y );
}
bbox.SetEnd(p_end);
bbox.Inflate( 1 );
break;
}
}
bbox.Inflate( (m_Width+1) / 2 );
return bbox;
}
bool DRAWSEGMENT::HitTest( const wxPoint& aRefPos ) bool DRAWSEGMENT::HitTest( const wxPoint& aRefPos )
{ {
/* Calculate coordinates to test relative to segment origin. */ /* Calculate coordinates to test relative to segment origin. */
wxPoint relPos = aRefPos - m_Start; wxPoint relPos = aRefPos - m_Start;
switch(m_Shape) switch( m_Shape )
{ {
case S_CIRCLE: case S_CIRCLE:
case S_ARC: case S_ARC:
...@@ -453,32 +505,30 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aRefPos ) ...@@ -453,32 +505,30 @@ bool DRAWSEGMENT::HitTest( const wxPoint& aRefPos )
} }
break; break;
default: case S_SEGMENT:
if( TestSegmentHit( aRefPos, m_Start, m_End, m_Width / 2 ) ) if( TestSegmentHit( aRefPos, m_Start, m_End, m_Width / 2 ) )
return true; return true;
break;
default:
wxASSERT( 0 );
break;
} }
return false; return false;
} }
/**
* Function HitTest (overlayed)
* tests if the given EDA_RECT intersect this object.
* For now, for arcs and segments, an ending point must be inside this rect.
* @param refArea : the given EDA_RECT
* @return bool - true if a hit, else false
*/
bool DRAWSEGMENT::HitTest( EDA_RECT& refArea ) bool DRAWSEGMENT::HitTest( EDA_RECT& refArea )
{ {
switch(m_Shape) switch( m_Shape )
{ {
case S_CIRCLE: case S_CIRCLE:
{ {
int radius = GetRadius(); int radius = GetRadius();
// Text if area intersects the circle: // Text if area intersects the circle:
EDA_RECT area = refArea; EDA_RECT area = refArea;
area.Inflate(radius); area.Inflate( radius );
if( area.Contains(m_Start) ) if( area.Contains( m_Start ) )
return true; return true;
} }
break; break;
...@@ -501,7 +551,7 @@ wxString DRAWSEGMENT::GetSelectMenuText() const ...@@ -501,7 +551,7 @@ wxString DRAWSEGMENT::GetSelectMenuText() const
wxString temp; wxString temp;
text << _( "Pcb Graphic" ) << wxT(": ") << ShowShape( (Track_Shapes)m_Shape ) text << _( "Pcb Graphic" ) << wxT(": ") << ShowShape( (Track_Shapes)m_Shape )
<< wxChar(' ') << _("Length:") << valeur_param( GetLength(), temp ) << wxChar(' ') << _( "Length:" ) << valeur_param( GetLength(), temp )
<< _( " on " ) << GetLayerName(); << _( " on " ) << GetLayerName();
return text; return text;
......
...@@ -22,7 +22,10 @@ public: ...@@ -22,7 +22,10 @@ public:
wxPoint m_BezierC1; // Bezier Control Point 1 wxPoint m_BezierC1; // Bezier Control Point 1
wxPoint m_BezierC2; // Bezier Control Point 1 wxPoint m_BezierC2; // Bezier Control Point 1
protected:
std::vector<wxPoint> m_BezierPoints; std::vector<wxPoint> m_BezierPoints;
std::vector<wxPoint> m_PolyPoints;
public: public:
DRAWSEGMENT( BOARD_ITEM* aParent, KICAD_T idtype = TYPE_DRAWSEGMENT ); DRAWSEGMENT( BOARD_ITEM* aParent, KICAD_T idtype = TYPE_DRAWSEGMENT );
~DRAWSEGMENT(); ~DRAWSEGMENT();
...@@ -41,7 +44,6 @@ public: ...@@ -41,7 +44,6 @@ public:
return m_Start; return m_Start;
} }
/** /**
* Function GetStart * Function GetStart
* returns the starting point of the graphic * returns the starting point of the graphic
...@@ -65,6 +67,17 @@ public: ...@@ -65,6 +67,17 @@ public:
return wxRound( radius ); return wxRound( radius );
} }
/**
* Function GetParentModule
* returns a pointer to the parent module, or NULL if DRAWSEGMENT does not
* belong to a module.
* @return MODULE* - pointer to the parent module or NULL.
*/
MODULE* GetParentModule() const;
std::vector<wxPoint>& GetBezierPoints() { return m_BezierPoints; };
std::vector<wxPoint>& GetPolyPoints() { return m_PolyPoints; };
/** /**
* Function Save * Function Save
* writes the data structures for this object out to a FILE in "*.brd" format. * writes the data structures for this object out to a FILE in "*.brd" format.
...@@ -91,6 +104,16 @@ public: ...@@ -91,6 +104,16 @@ public:
virtual void DisplayInfo( EDA_DRAW_FRAME* frame ); virtual void DisplayInfo( EDA_DRAW_FRAME* frame );
/**
* Function GetBoundingBox
* returns the orthogonal, bounding box of this object for display purposes.
* This box should be an enclosing perimeter for visible components of this
* object, and the units should be in the pcb or schematic coordinate system.
* It is OK to overestimate the size by a few counts.
*/
virtual EDA_RECT GetBoundingBox() const;
/** /**
* Function HitTest * Function HitTest
* tests if the given wxPoint is within the bounds of this object. * tests if the given wxPoint is within the bounds of this object.
......
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
/*********************/ /*********************/
EDGE_MODULE::EDGE_MODULE( MODULE* parent ) : EDGE_MODULE::EDGE_MODULE( MODULE* parent ) :
BOARD_ITEM( parent, TYPE_EDGE_MODULE ) DRAWSEGMENT( parent, TYPE_EDGE_MODULE )
{ {
m_Shape = S_SEGMENT; m_Shape = S_SEGMENT;
m_Angle = 0; m_Angle = 0;
...@@ -42,85 +42,15 @@ void EDGE_MODULE::Copy( EDGE_MODULE* source ) ...@@ -42,85 +42,15 @@ void EDGE_MODULE::Copy( EDGE_MODULE* source )
if( source == NULL ) if( source == NULL )
return; return;
m_Start = source->m_Start; DRAWSEGMENT::Copy( source );
m_End = source->m_End;
m_Shape = source->m_Shape;
m_Start0 = source->m_Start0; m_Start0 = source->m_Start0;
m_End0 = source->m_End0; m_End0 = source->m_End0;
m_Angle = source->m_Angle;
m_Layer = source->m_Layer;
m_Width = source->m_Width;
m_PolyPoints = source->m_PolyPoints; // std::vector copy m_PolyPoints = source->m_PolyPoints; // std::vector copy
} }
/**
* Function GetBoundingBox
* returns the orthogonal, bounding box of this object for display purposes.
* This box should be an enclosing perimeter for visible components of this
* object, and the units should be in the pcb or schematic coordinate system.
* It is OK to overestimate the size by a few counts.
*/
EDA_RECT EDGE_MODULE::GetBoundingBox() const
{
EDA_RECT bbox;
bbox.SetOrigin( m_Start );
switch( m_Shape )
{
case S_SEGMENT:
bbox.SetEnd( m_End );
bbox.Inflate( (m_Width / 2) + 1 );
break;
case S_CIRCLE:
bbox.Inflate( GetRadius() + 1 );
break;
case S_ARC:
{
bbox.Inflate( GetRadius() + 1 );
}
break;
case S_POLYGON:
{
// We must compute true coordinates from m_PolyPoints
// which are relative to module position, orientation 0
wxPoint p_end;
MODULE* Module = (MODULE*) m_Parent;
for( unsigned ii = 0; ii < m_PolyPoints.size(); ii++ )
{
wxPoint pt = m_PolyPoints[ii];
if( Module )
{
RotatePoint( &pt, Module->m_Orient );
pt += Module->m_Pos;
}
if( ii == 0 )
p_end = pt;
bbox.m_Pos.x = MIN( bbox.m_Pos.x, pt.x );
bbox.m_Pos.y = MIN( bbox.m_Pos.y, pt.y );
p_end.x = MAX( p_end.x, pt.x );
p_end.y = MAX( p_end.y, pt.y );
}
bbox.SetEnd(p_end);
bbox.Inflate( 1 );
break;
}
}
bbox.Inflate( (m_Width+1) / 2 );
return bbox;
}
void EDGE_MODULE::SetDrawCoord() void EDGE_MODULE::SetDrawCoord()
{ {
MODULE* Module = (MODULE*) m_Parent; MODULE* Module = (MODULE*) m_Parent;
...@@ -158,10 +88,11 @@ void EDGE_MODULE::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int draw_mode, const wx ...@@ -158,10 +88,11 @@ void EDGE_MODULE::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int draw_mode, const wx
return; return;
BOARD * brd = GetBoard( ); BOARD * brd = GetBoard( );
if( brd->IsLayerVisible( m_Layer ) == false ) if( brd->IsLayerVisible( m_Layer ) == false )
return; return;
color = brd->GetLayerColor(m_Layer); color = brd->GetLayerColor( m_Layer );
frame = (PCB_BASE_FRAME*) panel->GetParent(); frame = (PCB_BASE_FRAME*) panel->GetParent();
...@@ -481,127 +412,6 @@ int EDGE_MODULE::ReadDescr( LINE_READER* aReader ) ...@@ -481,127 +412,6 @@ int EDGE_MODULE::ReadDescr( LINE_READER* aReader )
} }
wxPoint EDGE_MODULE::GetStart() const
{
switch( m_Shape )
{
case S_ARC:
return m_End; // the start of the arc is held in field m_End, center point is in m_Start.
case S_SEGMENT:
default:
return m_Start;
}
}
wxPoint EDGE_MODULE::GetEnd() const
{
wxPoint endPoint; // start of arc
switch( m_Shape )
{
case S_ARC:
// rotate the starting point of the arc, given by m_End, through the
// angle m_Angle to get the ending point of the arc.
// m_Start is the arc centre
endPoint = m_End; // m_End = start point of arc
RotatePoint( &endPoint, m_Start, -m_Angle );
return endPoint; // after rotation, the end of the arc.
break;
case S_SEGMENT:
default:
return m_End;
}
}
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param refPos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool EDGE_MODULE::HitTest( const wxPoint& refPos )
{
int rayon, dist;
switch( m_Shape )
{
case S_SEGMENT:
if( TestSegmentHit( refPos, m_Start, m_End, m_Width / 2 ) )
return true;
break;
case S_CIRCLE:
rayon = GetRadius();
dist = (int) hypot( (double) (refPos.x - m_Start.x), (double) (refPos.y - m_Start.y) );
if( abs( rayon - dist ) <= (m_Width/2) )
return true;
break;
case S_ARC:
rayon = GetRadius();
dist = (int) hypot( (double) (refPos.x - m_Start.x), (double) (refPos.y - m_Start.y) );
if( abs( rayon - dist ) > (m_Width/2) )
break;
int mouseAngle = ArcTangente( refPos.y - m_Start.y, refPos.x - m_Start.x );
int stAngle = ArcTangente( m_End.y - m_Start.y, m_End.x - m_Start.x );
int endAngle = stAngle + m_Angle;
if( endAngle > 3600 )
{
stAngle -= 3600;
endAngle -= 3600;
}
if( (mouseAngle >= stAngle) && (mouseAngle <= endAngle) )
return true;
break;
}
return false; // an unknown m_Shape also returns false
}
/**
* Function HitTest (overlayed)
* tests if the given EDA_RECT intersect this object.
* For now, for arcs and segments, an ending point must be inside this rect.
* @param refArea : the given EDA_RECT
* @return bool - true if a hit, else false
*/
bool EDGE_MODULE::HitTest( EDA_RECT& refArea )
{
switch(m_Shape)
{
case S_CIRCLE:
{
int radius = GetRadius();
// Test if area intersects the circle:
EDA_RECT area = refArea;
area.Inflate(radius);
if( area.Contains(m_Start) )
return true;
}
break;
case S_ARC:
case S_SEGMENT:
if( refArea.Contains( GetStart() ) )
return true;
if( refArea.Contains( GetEnd() ) )
return true;
break;
}
return false;
}
wxString EDGE_MODULE::GetSelectMenuText() const wxString EDGE_MODULE::GetSelectMenuText() const
{ {
wxString text; wxString text;
......
...@@ -2,32 +2,21 @@ ...@@ -2,32 +2,21 @@
/* class_edge_module.h : EDGE_MODULE class definition. */ /* class_edge_module.h : EDGE_MODULE class definition. */
/*******************************************************/ /*******************************************************/
#ifndef CLASS_DRAWSEGMENT_H #ifndef _CLASS_EDGE_MOD_H_
#define _CLASS_EDGE_MOD_H_ #define _CLASS_EDGE_MOD_H_
#include "class_drawsegment.h"
#include "richio.h" #include "richio.h"
class Pcb3D_GLCanvas; class Pcb3D_GLCanvas;
class EDGE_MODULE : public BOARD_ITEM class EDGE_MODULE : public DRAWSEGMENT
{ {
public: public:
int m_Width; // 0 = line, > 0 = tracks, bus ...
wxPoint m_Start; // Line start point and circle and arc center
wxPoint m_End; // Line end point and circle and arc starting point
int m_Shape; // enum Track_Shapes
wxPoint m_Start0; // Start point or centre, relative to module origin, orient 0. wxPoint m_Start0; // Start point or centre, relative to module origin, orient 0.
wxPoint m_End0; // End point, relative to module origin, orient 0. wxPoint m_End0; // End point, relative to module origin, orient 0.
int m_Angle; // Arcs: angle in 0.1 degrees
std::vector<wxPoint> m_PolyPoints; /* For polygons: number of points (> 2)
* Coord are relative to Origin, orient 0
* m_Start0 and m_End0 are not used for polygons
*/
public: public:
EDGE_MODULE( MODULE* parent ); EDGE_MODULE( MODULE* parent );
EDGE_MODULE( EDGE_MODULE* edge ); EDGE_MODULE( EDGE_MODULE* edge );
...@@ -36,40 +25,6 @@ public: ...@@ -36,40 +25,6 @@ public:
EDGE_MODULE* Next() const { return (EDGE_MODULE*) Pnext; } EDGE_MODULE* Next() const { return (EDGE_MODULE*) Pnext; }
EDGE_MODULE* Back() const { return (EDGE_MODULE*) Pback; } EDGE_MODULE* Back() const { return (EDGE_MODULE*) Pback; }
/**
* Function GetPosition
* returns the position of this object.
* @return const wxPoint& - The position of this object.
*/
wxPoint& GetPosition()
{
return m_Start;
}
/**
* Function GetStart
* returns the starting point of the graphic
*/
wxPoint GetStart() const;
/**
* Function GetEnd
* returns the ending point of the graphic
*/
wxPoint GetEnd() const;
/**
* Function GetRadius
* returns the radius of this item
* Has meaning only for arc and circle
*/
int GetRadius() const
{
double radius = hypot( (double) (m_End.x - m_Start.x), (double) (m_End.y - m_Start.y) );
return wxRound( radius );
}
void Copy( EDGE_MODULE* source ); // copy structure void Copy( EDGE_MODULE* source ); // copy structure
/** /**
...@@ -100,32 +55,6 @@ public: ...@@ -100,32 +55,6 @@ public:
void DisplayInfo( EDA_DRAW_FRAME* frame ); void DisplayInfo( EDA_DRAW_FRAME* frame );
/**
* Function GetBoundingBox
* returns the orthogonal, bounding box of this object for display purposes.
* This box should be an enclosing perimeter for visible components of this
* object, and the units should be in the pcb or schematic coordinate system.
* It is OK to overestimate the size by a few counts.
*/
virtual EDA_RECT GetBoundingBox() const;
/**
* Function HitTest
* tests if the given wxPoint is within the bounds of this object.
* @param refPos A wxPoint to test
* @return bool - true if a hit, else false
*/
bool HitTest( const wxPoint& refPos );
/**
* Function HitTest (overlayed)
* tests if the given EDA_RECT intersect this object.
* For now, for segments and arcs, an ending point must be inside this rect.
* @param refArea the given EDA_RECT to test
* @return bool - true if a hit, else false
*/
bool HitTest( EDA_RECT& refArea );
/** /**
* Function GetClass * Function GetClass
* returns the class name. * returns the class name.
...@@ -138,24 +67,6 @@ public: ...@@ -138,24 +67,6 @@ public:
// return wxT( "EDGE" ); ? // return wxT( "EDGE" ); ?
} }
/**
* Function TransformShapeWithClearanceToPolygon
* Convert the track shape to a closed polygon
* Used in filling zones calculations
* Circles and arcs are approximated by segments
* @param aCornerBuffer = a buffer to store the polygon
* @param aClearanceValue = the clearance around the pad
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aCorrectionFactor = the correction to apply to circles radius to keep
* clearance when the circle is approximated by segment bigger or equal
* to the real clearance value (usually near from 1.0)
*/
void TransformShapeWithClearanceToPolygon( std::vector <CPolyPt>& aCornerBuffer,
int aClearanceValue,
int aCircleToSegmentsCount,
double aCorrectionFactor );
virtual wxString GetSelectMenuText() const; virtual wxString GetSelectMenuText() const;
virtual const char** GetMenuImage() const { return (const char**) show_mod_edge_xpm; } virtual const char** GetMenuImage() const { return (const char**) show_mod_edge_xpm; }
......
...@@ -677,18 +677,20 @@ void MODULE::Set_Rectangle_Encadrement() ...@@ -677,18 +677,20 @@ void MODULE::Set_Rectangle_Encadrement()
break; break;
case S_POLYGON: case S_POLYGON:
for( unsigned ii = 0; ii < edge->m_PolyPoints.size(); ii++ )
{ {
wxPoint pt = edge->m_PolyPoints[ii]; std::vector<wxPoint> polyPoints = edge->GetPolyPoints();
for( unsigned ii = 0; ii < polyPoints.size(); ii++ )
{
wxPoint pt = polyPoints[ii];
xmin = MIN( xmin, (pt.x - width) ); xmin = MIN( xmin, (pt.x - width) );
ymin = MIN( ymin, (pt.y - width) ); ymin = MIN( ymin, (pt.y - width) );
xmax = MAX( xmax, (pt.x + width) ); xmax = MAX( xmax, (pt.x + width) );
ymax = MAX( ymax, (pt.y + width) ); ymax = MAX( ymax, (pt.y + width) );
} }
break; break;
} }
} }
}
/* Pads: find the min and max coordinates and update the bounding box. /* Pads: find the min and max coordinates and update the bounding box.
*/ */
......
...@@ -674,11 +674,12 @@ MODULE* PCB_EDIT_FRAME::Create_MuWaveComponent( int shape_type ) ...@@ -674,11 +674,12 @@ MODULE* PCB_EDIT_FRAME::Create_MuWaveComponent( int shape_type )
edge->SetLayer( LAYER_N_FRONT ); edge->SetLayer( LAYER_N_FRONT );
int numPoints = angle / 50 + 3; // Note: angles are in 0.1 degrees int numPoints = angle / 50 + 3; // Note: angles are in 0.1 degrees
edge->m_PolyPoints.reserve( numPoints ); std::vector<wxPoint> polyPoints = edge->GetPolyPoints();
polyPoints.reserve( numPoints );
edge->m_Start0.y = -pad->m_Size.y / 2; edge->m_Start0.y = -pad->m_Size.y / 2;
edge->m_PolyPoints.push_back( wxPoint( 0, 0 ) ); polyPoints.push_back( wxPoint( 0, 0 ) );
int theta = -angle / 2; int theta = -angle / 2;
for( int ii = 1; ii<numPoints - 1; ii++ ) for( int ii = 1; ii<numPoints - 1; ii++ )
...@@ -687,7 +688,7 @@ MODULE* PCB_EDIT_FRAME::Create_MuWaveComponent( int shape_type ) ...@@ -687,7 +688,7 @@ MODULE* PCB_EDIT_FRAME::Create_MuWaveComponent( int shape_type )
RotatePoint( &pt.x, &pt.y, theta ); RotatePoint( &pt.x, &pt.y, theta );
edge->m_PolyPoints.push_back( pt ); polyPoints.push_back( pt );
theta += 50; theta += 50;
if( theta > angle / 2 ) if( theta > angle / 2 )
...@@ -695,7 +696,7 @@ MODULE* PCB_EDIT_FRAME::Create_MuWaveComponent( int shape_type ) ...@@ -695,7 +696,7 @@ MODULE* PCB_EDIT_FRAME::Create_MuWaveComponent( int shape_type )
} }
// Close the polygon: // Close the polygon:
edge->m_PolyPoints.push_back( edge->m_PolyPoints[0] ); polyPoints.push_back( polyPoints[0] );
} }
break; break;
...@@ -996,10 +997,11 @@ MODULE* PCB_EDIT_FRAME::Create_MuWavePolygonShape() ...@@ -996,10 +997,11 @@ MODULE* PCB_EDIT_FRAME::Create_MuWavePolygonShape()
edge->SetLayer( LAYER_N_FRONT ); edge->SetLayer( LAYER_N_FRONT );
npoints = PolyEdgesCount; npoints = PolyEdgesCount;
edge->m_PolyPoints.reserve( 2 * PolyEdgesCount + 2 ); std::vector<wxPoint> polyPoints = edge->GetPolyPoints();
polyPoints.reserve( 2 * PolyEdgesCount + 2 );
// Init start point coord: // Init start point coord:
edge->m_PolyPoints.push_back( wxPoint( pad1->m_Pos0.x, 0 ) ); polyPoints.push_back( wxPoint( pad1->m_Pos0.x, 0 ) );
double* dptr = PolyEdges; double* dptr = PolyEdges;
wxPoint first_coordinate, last_coordinate; wxPoint first_coordinate, last_coordinate;
...@@ -1007,10 +1009,10 @@ MODULE* PCB_EDIT_FRAME::Create_MuWavePolygonShape() ...@@ -1007,10 +1009,10 @@ MODULE* PCB_EDIT_FRAME::Create_MuWavePolygonShape()
{ {
last_coordinate.x = wxRound( *dptr++ *ShapeScaleX ) + pad1->m_Pos0.x; last_coordinate.x = wxRound( *dptr++ *ShapeScaleX ) + pad1->m_Pos0.x;
last_coordinate.y = -wxRound( *dptr++ *ShapeScaleY ); last_coordinate.y = -wxRound( *dptr++ *ShapeScaleY );
edge->m_PolyPoints.push_back( last_coordinate ); polyPoints.push_back( last_coordinate );
} }
first_coordinate.y = edge->m_PolyPoints[1].y; first_coordinate.y = polyPoints[1].y;
switch( PolyShapeType ) switch( PolyShapeType )
{ {
...@@ -1018,7 +1020,7 @@ MODULE* PCB_EDIT_FRAME::Create_MuWavePolygonShape() ...@@ -1018,7 +1020,7 @@ MODULE* PCB_EDIT_FRAME::Create_MuWavePolygonShape()
case 2: // Single mirrored case 2: // Single mirrored
// Init end point coord: // Init end point coord:
pad2->m_Pos0.x = last_coordinate.x; pad2->m_Pos0.x = last_coordinate.x;
edge->m_PolyPoints.push_back( wxPoint( last_coordinate.x, 0 ) ); polyPoints.push_back( wxPoint( last_coordinate.x, 0 ) );
pad1->m_Size.x = pad1->m_Size.y = ABS( first_coordinate.y ); pad1->m_Size.x = pad1->m_Size.y = ABS( first_coordinate.y );
pad2->m_Size.x = pad2->m_Size.y = ABS( last_coordinate.y ); pad2->m_Size.x = pad2->m_Size.y = ABS( last_coordinate.y );
...@@ -1029,13 +1031,13 @@ MODULE* PCB_EDIT_FRAME::Create_MuWavePolygonShape() ...@@ -1029,13 +1031,13 @@ MODULE* PCB_EDIT_FRAME::Create_MuWavePolygonShape()
break; break;
case 1: // Symmetric case 1: // Symmetric
for( int ndx = edge->m_PolyPoints.size() - 1; ndx>=0; --ndx ) for( int ndx = polyPoints.size() - 1; ndx>=0; --ndx )
{ {
wxPoint pt = edge->m_PolyPoints[ndx]; wxPoint pt = polyPoints[ndx];
pt.y = -pt.y; // mirror about X axis pt.y = -pt.y; // mirror about X axis
edge->m_PolyPoints.push_back( pt ); polyPoints.push_back( pt );
} }
pad1->m_Size.x = pad1->m_Size.y = 2 * ABS( first_coordinate.y ); pad1->m_Size.x = pad1->m_Size.y = 2 * ABS( first_coordinate.y );
......
...@@ -430,26 +430,25 @@ void Plot_1_EdgeModule( PLOTTER* plotter, EDGE_MODULE* PtEdge, ...@@ -430,26 +430,25 @@ void Plot_1_EdgeModule( PLOTTER* plotter, EDGE_MODULE* PtEdge,
case S_POLYGON: case S_POLYGON:
{ {
if( PtEdge->m_PolyPoints.size() <= 1 ) // Malformed polygon std::vector<wxPoint> polyPoints = PtEdge->GetPolyPoints();
if( polyPoints.size() <= 1 ) // Malformed polygon
break; break;
// We must compute true coordinates from m_PolyList // We must compute true coordinates from m_PolyList
// which are relative to module position, orientation 0 // which are relative to module position, orientation 0
MODULE* Module = NULL; MODULE* module = PtEdge->GetParentModule();
if( PtEdge->GetParent() && (PtEdge->GetParent()->Type() == TYPE_MODULE) )
Module = (MODULE*) PtEdge->GetParent();
static std::vector< wxPoint > cornerList; static std::vector< wxPoint > cornerList;
cornerList.clear(); cornerList.clear();
for( unsigned ii = 0; ii < PtEdge->m_PolyPoints.size(); ii++ ) for( unsigned ii = 0; ii < polyPoints.size(); ii++ )
{ {
wxPoint corner = PtEdge->m_PolyPoints[ii]; wxPoint corner = polyPoints[ii];
if( Module ) if( module )
{ {
RotatePoint( &corner, Module->m_Orient ); RotatePoint( &corner, module->m_Orient );
corner += Module->m_Pos; corner += module->m_Pos;
} }
cornerList.push_back( corner ); cornerList.push_back( corner );
...@@ -639,13 +638,15 @@ void PlotDrawSegment( PLOTTER* plotter, DRAWSEGMENT* pt_segm, int masque_layer, ...@@ -639,13 +638,15 @@ void PlotDrawSegment( PLOTTER* plotter, DRAWSEGMENT* pt_segm, int masque_layer,
break; break;
case S_CURVE: case S_CURVE:
for( unsigned i = 1; i < pt_segm->m_BezierPoints.size(); i++ ) {
plotter->thick_segment( pt_segm->m_BezierPoints[i - 1], std::vector<wxPoint> bezierPoints = pt_segm->GetBezierPoints();
pt_segm->m_BezierPoints[i], for( unsigned i = 1; i < bezierPoints.size(); i++ )
plotter->thick_segment( bezierPoints[i - 1],
bezierPoints[i],
thickness, thickness,
trace_mode ); trace_mode );
break; break;
}
default: default:
plotter->thick_segment( start, end, thickness, trace_mode ); plotter->thick_segment( start, end, thickness, trace_mode );
......
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