Fix some issues with rotated oval pads.
This commit is contained in:
parent
5c8d712a56
commit
874f13e29e
|
@ -590,7 +590,7 @@ COBJECT2D *BOARD_ADAPTER::createNewPadDrill( const D_PAD* aPad, int aInflateValu
|
||||||
wxPoint start, end;
|
wxPoint start, end;
|
||||||
int width;
|
int width;
|
||||||
|
|
||||||
aPad->GetOblongDrillGeometry( start, end, width );
|
aPad->GetOblongGeometry( aPad->GetDrillSize(), &start, &end, &width );
|
||||||
|
|
||||||
width += aInflateValue * 2;
|
width += aInflateValue * 2;
|
||||||
start += aPad->GetPosition();
|
start += aPad->GetPosition();
|
||||||
|
|
|
@ -360,20 +360,8 @@ void SCH_BASE_FRAME::FocusOnItem( SCH_ITEM* aItem )
|
||||||
RefreshItem( aItem );
|
RefreshItem( aItem );
|
||||||
lastBrightenedItemID = aItem->m_Uuid;
|
lastBrightenedItemID = aItem->m_Uuid;
|
||||||
|
|
||||||
wxPoint position = aItem->GetPosition();
|
// JEY TODO: test this with pins and fields (and with rotated symbols) ....
|
||||||
|
FocusOnLocation( aItem->GetFocusPosition() );
|
||||||
if( aItem->GetParent() && aItem->GetParent()->Type() == SCH_COMPONENT_T )
|
|
||||||
{
|
|
||||||
SCH_COMPONENT* comp = static_cast<SCH_COMPONENT*>( aItem->GetParent() );
|
|
||||||
|
|
||||||
// for a pin, GetPosition() is relative to the symbol, not rotated, not mirrored
|
|
||||||
// calculate the physical position:
|
|
||||||
wxPoint delta;
|
|
||||||
delta = comp->GetTransform().TransformCoordinate( position );
|
|
||||||
position = delta + comp->GetPosition();
|
|
||||||
}
|
|
||||||
|
|
||||||
FocusOnLocation( position );
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -342,6 +342,13 @@ public:
|
||||||
|
|
||||||
virtual const wxPoint GetPosition() const { return wxPoint(); }
|
virtual const wxPoint GetPosition() const { return wxPoint(); }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Function GetFocusPosition
|
||||||
|
* similar to GetPosition, but allows items to return their visual center rather
|
||||||
|
* than their anchor.
|
||||||
|
*/
|
||||||
|
virtual const wxPoint GetFocusPosition() const { return GetPosition(); }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function Clone
|
* Function Clone
|
||||||
* creates a duplicate of this item with linked list members set to NULL.
|
* creates a duplicate of this item with linked list members set to NULL.
|
||||||
|
|
|
@ -679,8 +679,8 @@ void D_PAD::BuildPadShapePolygon( SHAPE_POLY_SET& aCornerBuffer, wxSize aInflate
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
bool D_PAD::BuildPadDrillShapePolygon(
|
bool D_PAD::BuildPadDrillShapePolygon( SHAPE_POLY_SET& aCornerBuffer, int aInflateValue,
|
||||||
SHAPE_POLY_SET& aCornerBuffer, int aInflateValue, int aError ) const
|
int aError ) const
|
||||||
{
|
{
|
||||||
wxSize drillsize = GetDrillSize();
|
wxSize drillsize = GetDrillSize();
|
||||||
|
|
||||||
|
@ -697,7 +697,7 @@ bool D_PAD::BuildPadDrillShapePolygon(
|
||||||
wxPoint start, end;
|
wxPoint start, end;
|
||||||
int width;
|
int width;
|
||||||
|
|
||||||
GetOblongDrillGeometry( start, end, width );
|
GetOblongGeometry( GetDrillSize(), &start, &end, &width );
|
||||||
|
|
||||||
start += GetPosition();
|
start += GetPosition();
|
||||||
end += GetPosition();
|
end += GetPosition();
|
||||||
|
|
|
@ -1047,37 +1047,36 @@ void D_PAD::GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void D_PAD::GetOblongDrillGeometry( wxPoint& aStartPoint,
|
void D_PAD::GetOblongGeometry( const wxSize& aDrillOrPadSize,
|
||||||
wxPoint& aEndPoint, int& aWidth ) const
|
wxPoint* aStartPoint, wxPoint* aEndPoint, int* aWidth ) const
|
||||||
{
|
{
|
||||||
// calculates the start point, end point and width
|
// calculates the start point, end point and width
|
||||||
// of an equivalent segment which have the same position and width as the hole
|
// of an equivalent segment which have the same position and width as the pad or hole
|
||||||
int delta_cx, delta_cy;
|
int delta_cx, delta_cy;
|
||||||
|
|
||||||
wxSize halfsize = GetDrillSize();
|
wxSize halfsize = aDrillOrPadSize / 2;
|
||||||
halfsize.x /= 2;
|
wxPoint offset;
|
||||||
halfsize.y /= 2;
|
|
||||||
|
|
||||||
if( m_Drill.x > m_Drill.y ) // horizontal
|
if( aDrillOrPadSize.x > aDrillOrPadSize.y ) // horizontal
|
||||||
{
|
{
|
||||||
delta_cx = halfsize.x - halfsize.y;
|
delta_cx = halfsize.x - halfsize.y;
|
||||||
delta_cy = 0;
|
delta_cy = 0;
|
||||||
aWidth = m_Drill.y;
|
*aWidth = aDrillOrPadSize.y;
|
||||||
}
|
}
|
||||||
else // vertical
|
else // vertical
|
||||||
{
|
{
|
||||||
delta_cx = 0;
|
delta_cx = 0;
|
||||||
delta_cy = halfsize.y - halfsize.x;
|
delta_cy = halfsize.y - halfsize.x;
|
||||||
aWidth = m_Drill.x;
|
*aWidth = aDrillOrPadSize.x;
|
||||||
}
|
}
|
||||||
|
|
||||||
RotatePoint( &delta_cx, &delta_cy, m_Orient );
|
RotatePoint( &delta_cx, &delta_cy, m_Orient );
|
||||||
|
|
||||||
aStartPoint.x = delta_cx;
|
aStartPoint->x = delta_cx + offset.x;
|
||||||
aStartPoint.y = delta_cy;
|
aStartPoint->y = delta_cy + offset.y;
|
||||||
|
|
||||||
aEndPoint.x = - delta_cx;
|
aEndPoint->x = - delta_cx + offset.x;
|
||||||
aEndPoint.y = - delta_cy;
|
aEndPoint->y = - delta_cy + offset.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -408,15 +408,19 @@ public:
|
||||||
PAD_DRILL_SHAPE_T GetDrillShape() const { return m_drillShape; }
|
PAD_DRILL_SHAPE_T GetDrillShape() const { return m_drillShape; }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Function GetOblongDrillGeometry calculates the start point, end point and width
|
* Function GetOblongGeometry calculates the start point, end point and width of an
|
||||||
* of an equivalent segment which have the same position and width as the hole
|
* equivalent segment which have the same position and width as the pad (for circular
|
||||||
* Usefull to plot/draw oblong holes like segments with rounded ends
|
* of oval pads) or hole
|
||||||
* used in draw and plot functions
|
*
|
||||||
|
* NB: points returned are RELATIVE to the PAD POSITION. For board coordinates holes
|
||||||
|
* will need to be offset by GetPosition() and pads by ShapePos().
|
||||||
|
*
|
||||||
* @param aStartPoint = first point of the equivalent segment, relative to the pad position.
|
* @param aStartPoint = first point of the equivalent segment, relative to the pad position.
|
||||||
* @param aEndPoint = second point of the equivalent segment, relative to the pad position.
|
* @param aEndPoint = second point of the equivalent segment, relative to the pad position.
|
||||||
* @param aWidth = width equivalent segment.
|
* @param aWidth = width equivalent segment.
|
||||||
*/
|
*/
|
||||||
void GetOblongDrillGeometry( wxPoint& aStartPoint, wxPoint& aEndPoint, int& aWidth ) const;
|
void GetOblongGeometry( const wxSize& aDrillOrPadSize,
|
||||||
|
wxPoint* aStartPoint, wxPoint* aEndPoint, int* aWidth ) const;
|
||||||
|
|
||||||
void SetLayerSet( LSET aLayerMask ) { m_layerMask = aLayerMask; }
|
void SetLayerSet( LSET aLayerMask ) { m_layerMask = aLayerMask; }
|
||||||
LSET GetLayerSet() const override { return m_layerMask; }
|
LSET GetLayerSet() const override { return m_layerMask; }
|
||||||
|
|
|
@ -100,6 +100,7 @@ public:
|
||||||
|
|
||||||
void SetPosition( const wxPoint& aPos ) override { m_Start = aPos; }
|
void SetPosition( const wxPoint& aPos ) override { m_Start = aPos; }
|
||||||
const wxPoint GetPosition() const override { return m_Start; }
|
const wxPoint GetPosition() const override { return m_Start; }
|
||||||
|
const wxPoint GetFocusPosition() const override { return ( m_Start + m_End ) / 2; }
|
||||||
|
|
||||||
void SetWidth( int aWidth ) { m_Width = aWidth; }
|
void SetWidth( int aWidth ) { m_Width = aWidth; }
|
||||||
int GetWidth() const { return m_Width; }
|
int GetWidth() const { return m_Width; }
|
||||||
|
|
|
@ -338,21 +338,23 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
||||||
|
|
||||||
if( pad->GetDrillSize().x > 0 )
|
if( pad->GetDrillSize().x > 0 )
|
||||||
{
|
{
|
||||||
|
wxString clearanceSource;
|
||||||
|
int minClearance = aRefSeg->GetClearance( nullptr, &clearanceSource );
|
||||||
|
|
||||||
/* Treat an oval hole as a line segment along the hole's major axis,
|
/* Treat an oval hole as a line segment along the hole's major axis,
|
||||||
* shortened by half its minor axis.
|
* shortened by half its minor axis.
|
||||||
* A circular hole is just a degenerate case of an oval hole.
|
* A circular hole is just a degenerate case of an oval hole.
|
||||||
*/
|
*/
|
||||||
wxPoint slotStart;
|
wxPoint slotStart, slotEnd;
|
||||||
wxPoint slotEnd;
|
|
||||||
int slotWidth;
|
int slotWidth;
|
||||||
|
|
||||||
pad->GetOblongDrillGeometry( slotStart, slotEnd, slotWidth );
|
pad->GetOblongGeometry( pad->GetDrillSize(), &slotStart, &slotEnd, &slotWidth );
|
||||||
|
slotStart += pad->GetPosition();
|
||||||
|
slotEnd += pad->GetPosition();
|
||||||
|
|
||||||
wxString clearanceSource;
|
SEG slotSeg( slotStart, slotEnd );
|
||||||
int minClearance = aRefSeg->GetClearance( nullptr, &clearanceSource );
|
int widths = ( slotWidth + refSegWidth ) / 2;
|
||||||
SEG slotSeg( slotStart, slotEnd );
|
int center2centerAllowed = minClearance + widths;
|
||||||
int widths = ( slotWidth + refSegWidth ) / 2;
|
|
||||||
int center2centerAllowed = minClearance + widths;
|
|
||||||
|
|
||||||
// Avoid square-roots if possible (for performance)
|
// Avoid square-roots if possible (for performance)
|
||||||
SEG::ecoord center2center_squared = refSeg.SquaredDistance( slotSeg );
|
SEG::ecoord center2center_squared = refSeg.SquaredDistance( slotSeg );
|
||||||
|
@ -387,11 +389,11 @@ void DRC::doTrackDrc( TRACK* aRefSeg, TRACKS::iterator aStartIt, TRACKS::iterato
|
||||||
|
|
||||||
wxString clearanceSource;
|
wxString clearanceSource;
|
||||||
int minClearance = aRefSeg->GetClearance( pad, &clearanceSource );
|
int minClearance = aRefSeg->GetClearance( pad, &clearanceSource );
|
||||||
SEG padSeg( pad->GetPosition(), pad->GetPosition() );
|
|
||||||
int actual;
|
int actual;
|
||||||
|
|
||||||
if( !checkClearanceSegmToPad( refSeg, refSegWidth, pad, minClearance, &actual ) )
|
if( !checkClearanceSegmToPad( refSeg, refSegWidth, pad, minClearance, &actual ) )
|
||||||
{
|
{
|
||||||
|
SEG padSeg( pad->GetPosition(), pad->GetPosition() );
|
||||||
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_NEAR_PAD );
|
DRC_ITEM* drcItem = new DRC_ITEM( DRCE_TRACK_NEAR_PAD );
|
||||||
|
|
||||||
msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
|
msg.Printf( drcItem->GetErrorText() + _( " (%s %s; actual %s)" ),
|
||||||
|
@ -666,22 +668,12 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, int aMinClearance
|
||||||
* shortened by half its minor axis.
|
* shortened by half its minor axis.
|
||||||
* A circular pad is just a degenerate case of an oval hole.
|
* A circular pad is just a degenerate case of an oval hole.
|
||||||
*/
|
*/
|
||||||
wxPoint refPadStart = aRefPad->GetPosition() + aRefPad->GetOffset();
|
wxPoint refPadStart, refPadEnd;
|
||||||
wxPoint refPadEnd = aRefPad->GetPosition() + aRefPad->GetOffset();
|
|
||||||
int refPadWidth;
|
int refPadWidth;
|
||||||
|
|
||||||
if( aRefPad->GetSize().x > aRefPad->GetSize().y )
|
aRefPad->GetOblongGeometry( aRefPad->GetSize(), &refPadStart, &refPadEnd, &refPadWidth );
|
||||||
{
|
refPadStart += aRefPad->ShapePos();
|
||||||
refPadWidth = aRefPad->GetSize().y;
|
refPadEnd += aRefPad->ShapePos();
|
||||||
refPadStart.x -= ( aRefPad->GetSize().x - refPadWidth ) / 2;
|
|
||||||
refPadEnd.x += ( aRefPad->GetSize().x - refPadWidth ) / 2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
refPadWidth = aRefPad->GetSize().x;
|
|
||||||
refPadStart.y -= ( aRefPad->GetSize().y - refPadWidth ) / 2;
|
|
||||||
refPadEnd.y += ( aRefPad->GetSize().y - refPadWidth ) / 2;
|
|
||||||
}
|
|
||||||
|
|
||||||
SEG refPadSeg( refPadStart, refPadEnd );
|
SEG refPadSeg( refPadStart, refPadEnd );
|
||||||
diag = checkClearanceSegmToPad( refPadSeg, refPadWidth, aPad, aMinClearance, aActual );
|
diag = checkClearanceSegmToPad( refPadSeg, refPadWidth, aPad, aMinClearance, aActual );
|
||||||
|
@ -694,14 +686,6 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, int aMinClearance
|
||||||
wxPoint polyref[4];
|
wxPoint polyref[4];
|
||||||
// corners of aRefPad (used only for custom pad)
|
// corners of aRefPad (used only for custom pad)
|
||||||
SHAPE_POLY_SET polysetref;
|
SHAPE_POLY_SET polysetref;
|
||||||
// corners of aPad (used only for rect/roundrect/trap pad)
|
|
||||||
wxPoint polycompare[4];
|
|
||||||
// corners of aPad (used only custom pad)
|
|
||||||
SHAPE_POLY_SET polysetcompare;
|
|
||||||
|
|
||||||
// pad_angle = pad orient relative to the aRefPad orient
|
|
||||||
double pad_angle = aRefPad->GetOrientation() + aPad->GetOrientation();
|
|
||||||
NORMALIZE_ANGLE_POS( pad_angle );
|
|
||||||
|
|
||||||
if( aRefPad->GetShape() == PAD_SHAPE_ROUNDRECT )
|
if( aRefPad->GetShape() == PAD_SHAPE_ROUNDRECT )
|
||||||
{
|
{
|
||||||
|
@ -739,6 +723,11 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, int aMinClearance
|
||||||
aRefPad->BuildPadPolygon( polyref, wxSize( 0, 0 ), aRefPad->GetOrientation() );
|
aRefPad->BuildPadPolygon( polyref, wxSize( 0, 0 ), aRefPad->GetOrientation() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// corners of aPad (used only for rect/roundrect/trap pad)
|
||||||
|
wxPoint polycompare[4];
|
||||||
|
// corners of aPad (used only custom pad)
|
||||||
|
SHAPE_POLY_SET polysetcompare;
|
||||||
|
|
||||||
switch( aPad->GetShape() )
|
switch( aPad->GetShape() )
|
||||||
{
|
{
|
||||||
case PAD_SHAPE_ROUNDRECT:
|
case PAD_SHAPE_ROUNDRECT:
|
||||||
|
@ -784,6 +773,7 @@ bool DRC::checkClearancePadToPad( D_PAD* aRefPad, D_PAD* aPad, int aMinClearance
|
||||||
for( int ii = 0; ii < 4; ii++ )
|
for( int ii = 0; ii < 4; ii++ )
|
||||||
polycompare[ii] += relativePadPos;
|
polycompare[ii] += relativePadPos;
|
||||||
}
|
}
|
||||||
|
|
||||||
// And now test polygons: We have 3 cases:
|
// And now test polygons: We have 3 cases:
|
||||||
// one poly is complex and the other is basic (has only 4 corners)
|
// one poly is complex and the other is basic (has only 4 corners)
|
||||||
// both polys are complex
|
// both polys are complex
|
||||||
|
@ -857,25 +847,15 @@ bool DRC::checkClearanceSegmToPad( const SEG& refSeg, int refSegWidth, const D_P
|
||||||
* shortened by half its minor axis.
|
* shortened by half its minor axis.
|
||||||
* A circular pad is just a degenerate case of an oval hole.
|
* A circular pad is just a degenerate case of an oval hole.
|
||||||
*/
|
*/
|
||||||
wxPoint padStart = pad->GetPosition() + pad->GetOffset(); // JEY TODO: needs to handle rotation....
|
wxPoint padStart, padEnd;
|
||||||
wxPoint padEnd = pad->GetPosition() + pad->GetOffset();
|
int padWidth;
|
||||||
int padHalfWidth;
|
|
||||||
|
|
||||||
if( pad->GetSize().x > pad->GetSize().y )
|
pad->GetOblongGeometry( pad->GetSize(), &padStart, &padEnd, &padWidth );
|
||||||
{
|
padStart += pad->ShapePos();
|
||||||
padHalfWidth = pad->GetSize().y / 2;
|
padEnd += pad->ShapePos();
|
||||||
padStart.x -= ( pad->GetSize().x / 2 ) - padHalfWidth;
|
|
||||||
padEnd.x += ( pad->GetSize().x / 2 ) - padHalfWidth;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
padHalfWidth = pad->GetSize().x / 2;
|
|
||||||
padStart.y -= ( pad->GetSize().y / 2 ) - padHalfWidth;
|
|
||||||
padEnd.y += ( pad->GetSize().y / 2 ) - padHalfWidth;
|
|
||||||
}
|
|
||||||
|
|
||||||
SEG padSeg( padStart, padEnd );
|
SEG padSeg( padStart, padEnd );
|
||||||
int widths = padHalfWidth + ( refSegWidth / 2 );
|
int widths = ( padWidth + refSegWidth ) / 2;
|
||||||
int center2centerAllowed = minClearance + widths;
|
int center2centerAllowed = minClearance + widths;
|
||||||
|
|
||||||
// Avoid square-roots if possible (for performance)
|
// Avoid square-roots if possible (for performance)
|
||||||
|
|
|
@ -230,7 +230,7 @@ void PCB_BASE_FRAME::FocusOnItem( BOARD_ITEM* aItem )
|
||||||
|
|
||||||
GetCanvas()->GetView()->Update( aItem );
|
GetCanvas()->GetView()->Update( aItem );
|
||||||
lastBrightenedItemID = aItem->m_Uuid;
|
lastBrightenedItemID = aItem->m_Uuid;
|
||||||
FocusOnLocation( aItem->GetPosition() );
|
FocusOnLocation( aItem->GetFocusPosition() );
|
||||||
GetCanvas()->Refresh();
|
GetCanvas()->Refresh();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -779,7 +779,8 @@ void PlotLayerOutlines( BOARD* aBoard, PLOTTER* aPlotter, LSET aLayerMask,
|
||||||
// Note: small drill marks have no significance when applied to slots
|
// Note: small drill marks have no significance when applied to slots
|
||||||
wxPoint drl_start, drl_end;
|
wxPoint drl_start, drl_end;
|
||||||
int width;
|
int width;
|
||||||
pad->GetOblongDrillGeometry( drl_start, drl_end, width );
|
|
||||||
|
pad->GetOblongGeometry( pad->GetDrillSize(), &drl_start, &drl_end, &width );
|
||||||
aPlotter->ThickSegment( pad->GetPosition() + drl_start,
|
aPlotter->ThickSegment( pad->GetPosition() + drl_start,
|
||||||
pad->GetPosition() + drl_end, width, SKETCH, NULL );
|
pad->GetPosition() + drl_end, width, SKETCH, NULL );
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue