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(
}
}
/**
* 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
......
This diff is collapsed.
......@@ -22,7 +22,10 @@ public:
wxPoint m_BezierC1; // Bezier Control Point 1
wxPoint m_BezierC2; // Bezier Control Point 1
protected:
std::vector<wxPoint> m_BezierPoints;
std::vector<wxPoint> m_PolyPoints;
public:
DRAWSEGMENT( BOARD_ITEM* aParent, KICAD_T idtype = TYPE_DRAWSEGMENT );
~DRAWSEGMENT();
......@@ -41,7 +44,6 @@ public:
return m_Start;
}
/**
* Function GetStart
* returns the starting point of the graphic
......@@ -65,6 +67,17 @@ public:
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
* writes the data structures for this object out to a FILE in "*.brd" format.
......@@ -91,6 +104,16 @@ public:
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
* tests if the given wxPoint is within the bounds of this object.
......
......@@ -24,7 +24,7 @@
/*********************/
EDGE_MODULE::EDGE_MODULE( MODULE* parent ) :
BOARD_ITEM( parent, TYPE_EDGE_MODULE )
DRAWSEGMENT( parent, TYPE_EDGE_MODULE )
{
m_Shape = S_SEGMENT;
m_Angle = 0;
......@@ -42,85 +42,15 @@ void EDGE_MODULE::Copy( EDGE_MODULE* source )
if( source == NULL )
return;
m_Start = source->m_Start;
m_End = source->m_End;
m_Shape = source->m_Shape;
DRAWSEGMENT::Copy( source );
m_Start0 = source->m_Start0;
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
}
/**
* 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()
{
MODULE* Module = (MODULE*) m_Parent;
......@@ -158,10 +88,11 @@ void EDGE_MODULE::Draw( EDA_DRAW_PANEL* panel, wxDC* DC, int draw_mode, const wx
return;
BOARD * brd = GetBoard( );
if( brd->IsLayerVisible( m_Layer ) == false )
return;
color = brd->GetLayerColor(m_Layer);
color = brd->GetLayerColor( m_Layer );
frame = (PCB_BASE_FRAME*) panel->GetParent();
......@@ -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 text;
......
......@@ -2,32 +2,21 @@
/* class_edge_module.h : EDGE_MODULE class definition. */
/*******************************************************/
#ifndef CLASS_DRAWSEGMENT_H
#ifndef _CLASS_EDGE_MOD_H_
#define _CLASS_EDGE_MOD_H_
#include "class_drawsegment.h"
#include "richio.h"
class Pcb3D_GLCanvas;
class EDGE_MODULE : public BOARD_ITEM
class EDGE_MODULE : public DRAWSEGMENT
{
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_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:
EDGE_MODULE( MODULE* parent );
EDGE_MODULE( EDGE_MODULE* edge );
......@@ -36,40 +25,6 @@ public:
EDGE_MODULE* Next() const { return (EDGE_MODULE*) Pnext; }
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
/**
......@@ -100,32 +55,6 @@ public:
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
* returns the class name.
......@@ -138,24 +67,6 @@ public:
// 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 const char** GetMenuImage() const { return (const char**) show_mod_edge_xpm; }
......
......@@ -677,17 +677,19 @@ void MODULE::Set_Rectangle_Encadrement()
break;
case S_POLYGON:
for( unsigned ii = 0; ii < edge->m_PolyPoints.size(); ii++ )
{
std::vector<wxPoint> polyPoints = edge->GetPolyPoints();
for( unsigned ii = 0; ii < polyPoints.size(); ii++ )
{
wxPoint pt = edge->m_PolyPoints[ii];
wxPoint pt = polyPoints[ii];
xmin = MIN( xmin, (pt.x - width) );
ymin = MIN( ymin, (pt.y - width) );
xmax = MAX( xmax, (pt.x + width) );
ymax = MAX( ymax, (pt.y + width) );
}
break;
}
}
}
/* 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 )
edge->SetLayer( LAYER_N_FRONT );
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_PolyPoints.push_back( wxPoint( 0, 0 ) );
polyPoints.push_back( wxPoint( 0, 0 ) );
int theta = -angle / 2;
for( int ii = 1; ii<numPoints - 1; ii++ )
......@@ -687,7 +688,7 @@ MODULE* PCB_EDIT_FRAME::Create_MuWaveComponent( int shape_type )
RotatePoint( &pt.x, &pt.y, theta );
edge->m_PolyPoints.push_back( pt );
polyPoints.push_back( pt );
theta += 50;
if( theta > angle / 2 )
......@@ -695,7 +696,7 @@ MODULE* PCB_EDIT_FRAME::Create_MuWaveComponent( int shape_type )
}
// Close the polygon:
edge->m_PolyPoints.push_back( edge->m_PolyPoints[0] );
polyPoints.push_back( polyPoints[0] );
}
break;
......@@ -996,10 +997,11 @@ MODULE* PCB_EDIT_FRAME::Create_MuWavePolygonShape()
edge->SetLayer( LAYER_N_FRONT );
npoints = PolyEdgesCount;
edge->m_PolyPoints.reserve( 2 * PolyEdgesCount + 2 );
std::vector<wxPoint> polyPoints = edge->GetPolyPoints();
polyPoints.reserve( 2 * PolyEdgesCount + 2 );
// 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;
wxPoint first_coordinate, last_coordinate;
......@@ -1007,10 +1009,10 @@ MODULE* PCB_EDIT_FRAME::Create_MuWavePolygonShape()
{
last_coordinate.x = wxRound( *dptr++ *ShapeScaleX ) + pad1->m_Pos0.x;
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 )
{
......@@ -1018,7 +1020,7 @@ MODULE* PCB_EDIT_FRAME::Create_MuWavePolygonShape()
case 2: // Single mirrored
// Init end point coord:
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 );
pad2->m_Size.x = pad2->m_Size.y = ABS( last_coordinate.y );
......@@ -1029,13 +1031,13 @@ MODULE* PCB_EDIT_FRAME::Create_MuWavePolygonShape()
break;
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
edge->m_PolyPoints.push_back( pt );
polyPoints.push_back( pt );
}
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,
case S_POLYGON:
{
if( PtEdge->m_PolyPoints.size() <= 1 ) // Malformed polygon
std::vector<wxPoint> polyPoints = PtEdge->GetPolyPoints();
if( polyPoints.size() <= 1 ) // Malformed polygon
break;
// We must compute true coordinates from m_PolyList
// which are relative to module position, orientation 0
MODULE* Module = NULL;
if( PtEdge->GetParent() && (PtEdge->GetParent()->Type() == TYPE_MODULE) )
Module = (MODULE*) PtEdge->GetParent();
MODULE* module = PtEdge->GetParentModule();
static std::vector< wxPoint > cornerList;
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 );
corner += Module->m_Pos;
RotatePoint( &corner, module->m_Orient );
corner += module->m_Pos;
}
cornerList.push_back( corner );
......@@ -639,13 +638,15 @@ void PlotDrawSegment( PLOTTER* plotter, DRAWSEGMENT* pt_segm, int masque_layer,
break;
case S_CURVE:
for( unsigned i = 1; i < pt_segm->m_BezierPoints.size(); i++ )
plotter->thick_segment( pt_segm->m_BezierPoints[i - 1],
pt_segm->m_BezierPoints[i],
{
std::vector<wxPoint> bezierPoints = pt_segm->GetBezierPoints();
for( unsigned i = 1; i < bezierPoints.size(); i++ )
plotter->thick_segment( bezierPoints[i - 1],
bezierPoints[i],
thickness,
trace_mode );
break;
}
default:
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