Don't depend on a global MaxError value.

It can't handle multiple IUScales.
This commit is contained in:
Jeff Young
2025-10-23 17:43:29 +01:00
parent 0159dc644f
commit ce6d6cd5b2
13 changed files with 65 additions and 67 deletions
@@ -677,9 +677,9 @@ void BOARD_ADAPTER::addShape( const PCB_SHAPE* aShape, CONTAINER_2D_BASE* aConta
ROUNDRECT rr( SHAPE_RECT( aShape->GetPosition(),
aShape->GetRectangleWidth(),
aShape->GetRectangleHeight() ),
aShape->GetCornerRadius() );
aShape->GetCornerRadius() );
SHAPE_POLY_SET poly;
rr.TransformToPolygon( poly );
rr.TransformToPolygon( poly, aShape->GetMaxError() );
SHAPE_LINE_CHAIN& r_outline = poly.Outline( 0 );
r_outline.SetClosed( true );
+7 -5
View File
@@ -607,7 +607,7 @@ void EDA_SHAPE::UpdateHatching() const
{
ROUNDRECT rr( SHAPE_RECT( getPosition(), GetRectangleWidth(), GetRectangleHeight() ),
GetCornerRadius() );
rr.TransformToPolygon( shapeBuffer );
rr.TransformToPolygon( shapeBuffer, getMaxError() );
}
break;
@@ -824,7 +824,7 @@ void EDA_SHAPE::rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle )
// Convert non-cardinally-rotated rect to a diamond
ROUNDRECT rr( SHAPE_RECT( GetStart(), GetRectangleWidth(), GetRectangleHeight() ), m_cornerRadius );
m_shape = SHAPE_T::POLY;
rr.TransformToPolygon( m_poly );
rr.TransformToPolygon( m_poly, getMaxError() );
m_poly.Rotate( aAngle, aRotCentre );
}
@@ -1360,7 +1360,7 @@ bool EDA_SHAPE::hitTest( const VECTOR2I& aPosition, int aAccuracy ) const
{
ROUNDRECT rr( SHAPE_RECT( GetStart(), GetRectangleWidth(), GetRectangleHeight() ), m_cornerRadius );
SHAPE_POLY_SET poly;
rr.TransformToPolygon( poly );
rr.TransformToPolygon( poly, getMaxError() );
if( poly.CollideEdge( aPosition, nullptr, maxdist ) )
return true;
@@ -1508,7 +1508,7 @@ bool EDA_SHAPE::hitTest( const BOX2I& aRect, bool aContained, int aAccuracy ) co
{
ROUNDRECT rr( SHAPE_RECT( GetStart(), GetRectangleWidth(), GetRectangleHeight() ), m_cornerRadius );
SHAPE_POLY_SET poly;
rr.TransformToPolygon( poly );
rr.TransformToPolygon( poly, getMaxError() );
// Account for the width of the line
arect.Inflate( GetWidth() / 2 );
@@ -1838,7 +1838,7 @@ std::vector<SHAPE*> EDA_SHAPE::makeEffectiveShapes( bool aEdgeOnly, bool aLineCh
{
ROUNDRECT rr( SHAPE_RECT( GetStart(), GetRectangleWidth(), GetRectangleHeight() ), m_cornerRadius );
SHAPE_POLY_SET poly;
rr.TransformToPolygon( poly );
rr.TransformToPolygon( poly, getMaxError() );
SHAPE_LINE_CHAIN outline = poly.Outline( 0 );
if( solidFill )
@@ -1846,6 +1846,8 @@ std::vector<SHAPE*> EDA_SHAPE::makeEffectiveShapes( bool aEdgeOnly, bool aLineCh
if( width > 0 || !solidFill )
{
// TODO: need to handle arcs in outline!
for( int i = 0; i < outline.PointCount() - 1; ++i )
{
effectiveShapes.emplace_back( new SHAPE_SEGMENT( outline.CPoint( i ), outline.CPoint( i + 1 ),
+9
View File
@@ -613,6 +613,15 @@ int SCH_ITEM::compare( const SCH_ITEM& aOther, int aCompareFlags ) const
}
int SCH_ITEM::GetMaxError() const
{
if( SCHEMATIC* schematic = Schematic() )
return schematic->Settings().m_MaxError;
else
return schIUScale.mmToIU( ARC_LOW_DEF_MM );
}
const wxString& SCH_ITEM::GetDefaultFont( const RENDER_SETTINGS* aSettings ) const
{
static wxString defaultName = KICAD_FONT_NAME;
+2
View File
@@ -326,6 +326,8 @@ public:
*/
std::vector<int> ViewGetLayers() const override;
int GetMaxError() const;
/**
* @return the size of the "pen" that be used to draw or plot this item
*/
+3 -4
View File
@@ -2045,9 +2045,9 @@ void SCH_PAINTER::draw( const SCH_SHAPE* aShape, int aLayer, bool aDimmed )
ROUNDRECT rr( SHAPE_RECT( shape->GetPosition(),
shape->GetRectangleWidth(),
shape->GetRectangleHeight() ),
shape->GetCornerRadius(), true /* normalize */ );
shape->GetCornerRadius(), true /* normalize */ );
SHAPE_POLY_SET poly;
rr.TransformToPolygon( poly );
rr.TransformToPolygon( poly, shape->GetMaxError() );
m_gal->DrawPolygon( poly );
}
else
@@ -2067,8 +2067,7 @@ void SCH_PAINTER::draw( const SCH_SHAPE* aShape, int aLayer, bool aDimmed )
for( SHAPE* polySegment : polySegments )
pts.push_back( static_cast<SHAPE_SEGMENT*>( polySegment )->GetSeg().A );
pts.push_back(
static_cast<SHAPE_SEGMENT*>( polySegments.back() )->GetSeg().B );
pts.push_back( static_cast<SHAPE_SEGMENT*>( polySegments.back() )->GetSeg().B );
for( SHAPE* polySegment : polySegments )
delete polySegment;
+1 -7
View File
@@ -145,13 +145,7 @@ protected:
bool isMoving() const override { return IsMoving(); }
int getMaxError() const override
{
if( SCHEMATIC* schematic = Schematic() )
return schematic->Settings().m_MaxError;
else
return schIUScale.mmToIU( ARC_LOW_DEF_MM );
}
int getMaxError() const override { return GetMaxError(); }
/**
* @copydoc SCH_ITEM::compare()
+1 -1
View File
@@ -83,7 +83,7 @@ public:
/**
* Get the polygonal representation of the roundrect.
*/
void TransformToPolygon( SHAPE_POLY_SET& aBuffer ) const;
void TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aMaxError ) const;
private:
SHAPE_RECT m_rect;
+14 -10
View File
@@ -78,8 +78,12 @@ ROUNDRECT ROUNDRECT::GetInflated( int aOutset ) const
}
void ROUNDRECT::TransformToPolygon( SHAPE_POLY_SET& aBuffer ) const
void ROUNDRECT::TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aMaxError ) const
{
// Roundrects won't have a gazillion points, so we use a higher definition than the
// typical maxError.
int maxError = aMaxError / 5;
const int idx = aBuffer.NewOutline();
SHAPE_LINE_CHAIN& outline = aBuffer.Outline( idx );
@@ -107,7 +111,7 @@ void ROUNDRECT::TransformToPolygon( SHAPE_POLY_SET& aBuffer ) const
{
// It's a circle
outline.Append( SHAPE_ARC( m_p0 + VECTOR2I( m_radius, m_radius ),
m_p0 + VECTOR2I( -m_radius, 0 ), ANGLE_360 ) );
m_p0 + VECTOR2I( -m_radius, 0 ), ANGLE_360 ), maxError );
}
else
{
@@ -125,13 +129,13 @@ void ROUNDRECT::TransformToPolygon( SHAPE_POLY_SET& aBuffer ) const
if( y_edge > 0 )
{
outline.Append( MakeCornerArcCw90( inner_rect, m_radius, DIRECTION_45::NE ) );
outline.Append( MakeCornerArcCw90( inner_rect, m_radius, DIRECTION_45::NE ), maxError );
outline.Append( m_p0 + VECTOR2I( w, m_radius + y_edge ) );
outline.Append( MakeCornerArcCw90( inner_rect, m_radius, DIRECTION_45::SE ) );
outline.Append( MakeCornerArcCw90( inner_rect, m_radius, DIRECTION_45::SE ), maxError );
}
else
{
outline.Append( MakeSideArcCw180( inner_rect, m_radius, DIRECTION_45::E ) );
outline.Append( MakeSideArcCw180( inner_rect, m_radius, DIRECTION_45::E ), maxError );
}
// Bottom side
@@ -139,22 +143,22 @@ void ROUNDRECT::TransformToPolygon( SHAPE_POLY_SET& aBuffer ) const
if( y_edge > 0 )
{
outline.Append( MakeCornerArcCw90( inner_rect, m_radius, DIRECTION_45::SW ) );
outline.Append( MakeCornerArcCw90( inner_rect, m_radius, DIRECTION_45::SW ), maxError );
outline.Append( m_p0 + VECTOR2I( 0, m_radius ) );
outline.Append( MakeCornerArcCw90( inner_rect, m_radius, DIRECTION_45::NW ) );
outline.Append( MakeCornerArcCw90( inner_rect, m_radius, DIRECTION_45::NW ), maxError );
}
else
{
outline.Append( MakeSideArcCw180( inner_rect, m_radius, DIRECTION_45::W ) );
outline.Append( MakeSideArcCw180( inner_rect, m_radius, DIRECTION_45::W ), maxError );
}
}
else
{
// x_edge is 0 but y_edge is not, so it's an oval the other way up
outline.Append( m_p0 + VECTOR2I( 0, m_radius ) );
outline.Append( MakeSideArcCw180( inner_rect, m_radius, DIRECTION_45::N ) );
outline.Append( MakeSideArcCw180( inner_rect, m_radius, DIRECTION_45::N ), maxError );
outline.Append( m_p0 + VECTOR2I( w, m_radius + y_edge ) );
outline.Append( MakeSideArcCw180( inner_rect, m_radius, DIRECTION_45::S ) );
outline.Append( MakeSideArcCw180( inner_rect, m_radius, DIRECTION_45::S ), maxError );
}
}
+9 -18
View File
@@ -123,13 +123,12 @@ const std::string SHAPE_RECT::Format( bool aCplusPlus ) const
}
void SHAPE_RECT::TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
ERROR_LOC aErrorLoc ) const
void SHAPE_RECT::TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError, ERROR_LOC aErrorLoc ) const
{
if( m_radius > 0 )
{
ROUNDRECT rr( *this, m_radius );
rr.TransformToPolygon( aBuffer );
rr.TransformToPolygon( aBuffer, aError );
return;
}
@@ -143,24 +142,16 @@ void SHAPE_RECT::TransformToPolygon( SHAPE_POLY_SET& aBuffer, int aError,
outline.SetClosed( true );
}
const SHAPE_LINE_CHAIN SHAPE_RECT::Outline() const
{
if( m_radius > 0 )
{
SHAPE_POLY_SET poly;
ROUNDRECT rr( *this, m_radius );
rr.TransformToPolygon( poly );
return poly.Outline( 0 );
}
// TODO: we're DEPENDING on clients of this routine to use the actual arcs (if any)
// inserted into the SHAPE_LINE_CHAIN. They must NOT use the approximated segments
// because we don't know what IUScale to generate them in.
SHAPE_LINE_CHAIN rv;
rv.Append( m_p0 );
rv.Append( m_p0.x, m_p0.y + m_h );
rv.Append( m_p0.x + m_w, m_p0.y + m_h );
rv.Append( m_p0.x + m_w, m_p0.y );
rv.Append( m_p0 );
rv.SetClosed( true );
return rv;
SHAPE_POLY_SET buffer;
TransformToPolygon( buffer, SHAPE_ARC::DefaultAccuracyForPCB(), ERROR_INSIDE );
return std::move( buffer.Outline( 0 ) );
}
+2 -2
View File
@@ -225,9 +225,9 @@ static void processClosedShape( PCB_SHAPE* aShape, SHAPE_LINE_CHAIN& aContour,
if( aShape->GetCornerRadius() > 0 )
{
ROUNDRECT rr( SHAPE_RECT( aShape->GetStart(), aShape->GetRectangleWidth(), aShape->GetRectangleHeight() ),
aShape->GetCornerRadius() );
aShape->GetCornerRadius(), true /* normalize */ );
SHAPE_POLY_SET poly;
rr.TransformToPolygon( poly );
rr.TransformToPolygon( poly, aShape->GetMaxError() );
aContour.Append( poly.Outline( 0 ) );
for( int ii = 1; ii < aContour.PointCount(); ++ii )
+1 -1
View File
@@ -1998,7 +1998,7 @@ void PCB_PAINTER::draw( const PCB_SHAPE* aShape, int aLayer )
aShape->GetRectangleHeight() ),
aShape->GetCornerRadius(), true /* normalize */ );
SHAPE_POLY_SET poly;
rr.TransformToPolygon( poly );
rr.TransformToPolygon( poly, aShape->GetMaxError() );
SHAPE_LINE_CHAIN outline = poly.Outline( 0 );
if( aShape->IsProxyItem() )
+1 -1
View File
@@ -1190,7 +1190,7 @@ int CONVERT_TOOL::CreateLines( const TOOL_EVENT& aEvent )
ROUNDRECT rrect( rect, graphic->GetCornerRadius(), true );
SHAPE_POLY_SET poly;
rrect.TransformToPolygon( poly );
rrect.TransformToPolygon( poly, graphic->GetMaxError() );
processPolySet( poly, itemWidth );
break;
}
+13 -16
View File
@@ -945,7 +945,7 @@ void OUTSET_ROUTINE::ProcessItem( BOARD_ITEM& aItem )
// No point doing a SHAPE_RECT as we may need to rotate it
ROUNDRECT rrect( box, radius );
SHAPE_POLY_SET poly;
rrect.TransformToPolygon( poly );
rrect.TransformToPolygon( poly, pad.GetMaxError() );
poly.Rotate( pad.GetOrientation(), pad.GetPosition() );
addPoly( poly );
@@ -986,29 +986,26 @@ void OUTSET_ROUTINE::ProcessItem( BOARD_ITEM& aItem )
box.Normalize();
SHAPE_RECT rect( box );
int cornerRadius = pcb_shape.GetCornerRadius();
if( m_params.roundCorners )
{
if( m_params.gridRounding.has_value() )
rect = GetRectRoundedToGridOutwards( rect, *m_params.gridRounding );
cornerRadius += m_params.outsetDistance;
try
{
int cornerRadius = pcb_shape.GetCornerRadius() + m_params.outsetDistance;
ROUNDRECT rrect( rect, cornerRadius );
SHAPE_POLY_SET poly;
rrect.TransformToPolygon( poly );
addPoly( poly );
}
catch( ... )
{
DisplayErrorMessage( nullptr, _( "Cannot create rectangle outset" ) );
}
if( m_params.gridRounding.has_value() )
rect = GetRectRoundedToGridOutwards( rect, *m_params.gridRounding );
if( cornerRadius > 0 )
{
ROUNDRECT rrect( rect, cornerRadius );
SHAPE_POLY_SET poly;
rrect.TransformToPolygon( poly, pcb_shape.GetMaxError() );
addChain( poly.Outline( 0 ) );
}
else
{
addRect( rect );
}
AddSuccess();
break;
}