Move SHAPE_POLY_SET::Inflate's error spec from a seg-count to a max-deviation.
1) Also reorders parameters to make sure the compiler helps out. 2) This also makes it harder to mess up the discrepency between BOX2I/wxRECT/etc::Inflate() and SHAPE_POLY_SET::Inflate. 3) Also fixes a couple of bugs where the corner strategy was passed in as a segCount. 4) Also fixes a couple of bugs where the error wasn't forced to the outside to match the ERROR_LOCATION. 5) Also fixes a couple of bugs where the seg count was specified without regard to an already passed-in max deviation
This commit is contained in:
parent
7f250870fe
commit
65e53b8ecd
|
@ -438,7 +438,7 @@ void BOARD_ADAPTER::createPadWithMargin( const PAD* aPad, CONTAINER_2D_BASE* aCo
|
||||||
if( !poly.IsEmpty() )
|
if( !poly.IsEmpty() )
|
||||||
{
|
{
|
||||||
if( clearance.x )
|
if( clearance.x )
|
||||||
poly.Inflate( clearance.x, 32 );
|
poly.Inflate( clearance.x, SHAPE_POLY_SET::ROUND_ALL_CORNERS, maxError );
|
||||||
|
|
||||||
// Add the PAD polygon
|
// Add the PAD polygon
|
||||||
ConvertPolygonToTriangles( poly, *aContainer, m_biuTo3Dunits, *aPad );
|
ConvertPolygonToTriangles( poly, *aContainer, m_biuTo3Dunits, *aPad );
|
||||||
|
|
|
@ -1002,19 +1002,19 @@ public:
|
||||||
* the outline.
|
* the outline.
|
||||||
*
|
*
|
||||||
* @param aAmount is the number of units to offset edges.
|
* @param aAmount is the number of units to offset edges.
|
||||||
* @param aCircleSegCount is the number of segments per 360 degrees to use in curve approx
|
|
||||||
* @param aCornerStrategy #ALLOW_ACUTE_CORNERS to preserve all angles,
|
* @param aCornerStrategy #ALLOW_ACUTE_CORNERS to preserve all angles,
|
||||||
* #CHAMFER_ACUTE_CORNERS to chop angles less than 90°,
|
* #CHAMFER_ACUTE_CORNERS to chop angles less than 90°,
|
||||||
* #ROUND_ACUTE_CORNERS to round off angles less than 90°,
|
* #ROUND_ACUTE_CORNERS to round off angles less than 90°,
|
||||||
* #ROUND_ALL_CORNERS to round regardless of angles
|
* #ROUND_ALL_CORNERS to round regardless of angles
|
||||||
|
* @param aMaxError is the allowable deviation when rounding corners with an approximated
|
||||||
|
* polygon
|
||||||
*/
|
*/
|
||||||
void Inflate( int aAmount, int aCircleSegCount,
|
void Inflate( int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError,
|
||||||
CORNER_STRATEGY aCornerStrategy = ROUND_ALL_CORNERS, bool aSimplify = false );
|
bool aSimplify = false );
|
||||||
|
|
||||||
void Deflate( int aAmount, int aCircleSegmentsCount,
|
void Deflate( int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError )
|
||||||
CORNER_STRATEGY aCornerStrategy = CHAMFER_ALL_CORNERS )
|
|
||||||
{
|
{
|
||||||
Inflate( -aAmount, aCircleSegmentsCount, aCornerStrategy );
|
Inflate( -aAmount, aCornerStrategy, aMaxError );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -1096,13 +1096,15 @@ void SHAPE_POLY_SET::inflate2( int aAmount, int aCircleSegCount, CORNER_STRATEGY
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void SHAPE_POLY_SET::Inflate( int aAmount, int aCircleSegCount, CORNER_STRATEGY aCornerStrategy,
|
void SHAPE_POLY_SET::Inflate( int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError,
|
||||||
bool aSimplify )
|
bool aSimplify )
|
||||||
{
|
{
|
||||||
|
int segCount = GetArcToSegmentCount( aAmount, aMaxError, FULL_CIRCLE );
|
||||||
|
|
||||||
if( ADVANCED_CFG::GetCfg().m_UseClipper2 )
|
if( ADVANCED_CFG::GetCfg().m_UseClipper2 )
|
||||||
inflate2( aAmount, aCircleSegCount, aCornerStrategy, aSimplify );
|
inflate2( aAmount, segCount, aCornerStrategy, aSimplify );
|
||||||
else
|
else
|
||||||
inflate1( aAmount, aCircleSegCount, aCornerStrategy );
|
inflate1( aAmount, segCount, aCornerStrategy );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -190,8 +190,9 @@ bool DRC_TEST_PROVIDER_TEXT_DIMS::Run()
|
||||||
if( glyphArea == 0 )
|
if( glyphArea == 0 )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
poly.Inflate( constraint.Value().Min() / 2, 16 );
|
poly.Inflate( constraint.Value().Min() / 2,
|
||||||
poly.Simplify( SHAPE_POLY_SET::PM_FAST );
|
SHAPE_POLY_SET::CHAMFER_ALL_CORNERS, ARC_LOW_DEF, true );
|
||||||
|
|
||||||
double resultingGlyphArea = poly.Area();
|
double resultingGlyphArea = poly.Area();
|
||||||
|
|
||||||
if( ( std::abs( resultingGlyphArea - glyphArea ) / glyphArea ) > 0.1 )
|
if( ( std::abs( resultingGlyphArea - glyphArea ) / glyphArea ) > 0.1 )
|
||||||
|
|
|
@ -1952,13 +1952,13 @@ double FOOTPRINT::GetCoverageArea( const BOARD_ITEM* aItem, const GENERAL_COLLEC
|
||||||
{
|
{
|
||||||
const PCB_TEXT* text = static_cast<const PCB_TEXT*>( aItem );
|
const PCB_TEXT* text = static_cast<const PCB_TEXT*>( aItem );
|
||||||
|
|
||||||
text->TransformTextToPolySet( poly, textMargin, ARC_LOW_DEF, ERROR_OUTSIDE );
|
text->TransformTextToPolySet( poly, textMargin, ARC_LOW_DEF, ERROR_INSIDE );
|
||||||
}
|
}
|
||||||
else if( aItem->Type() == PCB_TEXTBOX_T )
|
else if( aItem->Type() == PCB_TEXTBOX_T )
|
||||||
{
|
{
|
||||||
const PCB_TEXTBOX* tb = static_cast<const PCB_TEXTBOX*>( aItem );
|
const PCB_TEXTBOX* tb = static_cast<const PCB_TEXTBOX*>( aItem );
|
||||||
|
|
||||||
tb->TransformTextToPolySet( poly, textMargin, ARC_LOW_DEF, ERROR_OUTSIDE );
|
tb->TransformTextToPolySet( poly, textMargin, ARC_LOW_DEF, ERROR_INSIDE );
|
||||||
}
|
}
|
||||||
else if( aItem->Type() == PCB_SHAPE_T )
|
else if( aItem->Type() == PCB_SHAPE_T )
|
||||||
{
|
{
|
||||||
|
@ -2138,14 +2138,14 @@ void FOOTPRINT::BuildCourtyardCaches( OUTLINE_ERROR_HANDLER* aErrorHandler )
|
||||||
if( !list_front.size() && !list_back.size() )
|
if( !list_front.size() && !list_back.size() )
|
||||||
return;
|
return;
|
||||||
|
|
||||||
int errorMax = pcbIUScale.mmToIU( 0.02 ); // max error for polygonization
|
int maxError = pcbIUScale.mmToIU( 0.02 ); // max error for polygonization
|
||||||
int chainingEpsilon = pcbIUScale.mmToIU( 0.02 ); // max dist from one endPt to next startPt
|
int chainingEpsilon = pcbIUScale.mmToIU( 0.02 ); // max dist from one endPt to next startPt
|
||||||
|
|
||||||
if( ConvertOutlineToPolygon( list_front, m_courtyard_cache_front, errorMax, chainingEpsilon,
|
if( ConvertOutlineToPolygon( list_front, m_courtyard_cache_front, maxError, chainingEpsilon,
|
||||||
true, aErrorHandler ) )
|
true, aErrorHandler ) )
|
||||||
{
|
{
|
||||||
// Touching courtyards, or courtyards -at- the clearance distance are legal.
|
// Touching courtyards, or courtyards -at- the clearance distance are legal.
|
||||||
m_courtyard_cache_front.Inflate( -1, SHAPE_POLY_SET::CHAMFER_ACUTE_CORNERS );
|
m_courtyard_cache_front.Inflate( -1, SHAPE_POLY_SET::CHAMFER_ACUTE_CORNERS, maxError );
|
||||||
|
|
||||||
m_courtyard_cache_front.CacheTriangulation( false );
|
m_courtyard_cache_front.CacheTriangulation( false );
|
||||||
}
|
}
|
||||||
|
@ -2154,11 +2154,11 @@ void FOOTPRINT::BuildCourtyardCaches( OUTLINE_ERROR_HANDLER* aErrorHandler )
|
||||||
SetFlags( MALFORMED_F_COURTYARD );
|
SetFlags( MALFORMED_F_COURTYARD );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( ConvertOutlineToPolygon( list_back, m_courtyard_cache_back, errorMax, chainingEpsilon,
|
if( ConvertOutlineToPolygon( list_back, m_courtyard_cache_back, maxError, chainingEpsilon,
|
||||||
true, aErrorHandler ) )
|
true, aErrorHandler ) )
|
||||||
{
|
{
|
||||||
// Touching courtyards, or courtyards -at- the clearance distance are legal.
|
// Touching courtyards, or courtyards -at- the clearance distance are legal.
|
||||||
m_courtyard_cache_back.Inflate( -1, SHAPE_POLY_SET::CHAMFER_ACUTE_CORNERS );
|
m_courtyard_cache_back.Inflate( -1, SHAPE_POLY_SET::CHAMFER_ACUTE_CORNERS, maxError );
|
||||||
|
|
||||||
m_courtyard_cache_back.CacheTriangulation( false );
|
m_courtyard_cache_back.CacheTriangulation( false );
|
||||||
}
|
}
|
||||||
|
|
|
@ -1592,7 +1592,7 @@ bool PAD::TransformHoleToPolygon( SHAPE_POLY_SET& aBuffer, int aClearance, int a
|
||||||
|
|
||||||
|
|
||||||
void PAD::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
|
void PAD::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
|
||||||
int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth ) const
|
int aMaxError, ERROR_LOC aErrorLoc, bool ignoreLineWidth ) const
|
||||||
{
|
{
|
||||||
wxASSERT_MSG( !ignoreLineWidth, wxT( "IgnoreLineWidth has no meaning for pads." ) );
|
wxASSERT_MSG( !ignoreLineWidth, wxT( "IgnoreLineWidth has no meaning for pads." ) );
|
||||||
|
|
||||||
|
@ -1613,7 +1613,7 @@ void PAD::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
|
||||||
// Note: dx == dy is not guaranteed for circle pads in legacy boards
|
// Note: dx == dy is not guaranteed for circle pads in legacy boards
|
||||||
if( dx == dy || ( GetShape() == PAD_SHAPE::CIRCLE ) )
|
if( dx == dy || ( GetShape() == PAD_SHAPE::CIRCLE ) )
|
||||||
{
|
{
|
||||||
TransformCircleToPolygon( aBuffer, padShapePos, dx + aClearance, aError, aErrorLoc,
|
TransformCircleToPolygon( aBuffer, padShapePos, dx + aClearance, aMaxError, aErrorLoc,
|
||||||
pad_min_seg_per_circle_count );
|
pad_min_seg_per_circle_count );
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -1624,7 +1624,7 @@ void PAD::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
|
||||||
RotatePoint( delta, m_orient );
|
RotatePoint( delta, m_orient );
|
||||||
|
|
||||||
TransformOvalToPolygon( aBuffer, padShapePos - delta, padShapePos + delta,
|
TransformOvalToPolygon( aBuffer, padShapePos - delta, padShapePos + delta,
|
||||||
( half_width + aClearance ) * 2, aError, aErrorLoc,
|
( half_width + aClearance ) * 2, aMaxError, aErrorLoc,
|
||||||
pad_min_seg_per_circle_count );
|
pad_min_seg_per_circle_count );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1638,7 +1638,7 @@ void PAD::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
|
||||||
|
|
||||||
SHAPE_POLY_SET outline;
|
SHAPE_POLY_SET outline;
|
||||||
TransformTrapezoidToPolygon( outline, padShapePos, m_size, m_orient, ddx, ddy, aClearance,
|
TransformTrapezoidToPolygon( outline, padShapePos, m_size, m_orient, ddx, ddy, aClearance,
|
||||||
aError, aErrorLoc );
|
aMaxError, aErrorLoc );
|
||||||
aBuffer.Append( outline );
|
aBuffer.Append( outline );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1653,7 +1653,7 @@ void PAD::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
|
||||||
GetRoundRectCornerRadius(),
|
GetRoundRectCornerRadius(),
|
||||||
doChamfer ? GetChamferRectRatio() : 0,
|
doChamfer ? GetChamferRectRatio() : 0,
|
||||||
doChamfer ? GetChamferPositions() : 0,
|
doChamfer ? GetChamferPositions() : 0,
|
||||||
aClearance, aError, aErrorLoc );
|
aClearance, aMaxError, aErrorLoc );
|
||||||
aBuffer.Append( outline );
|
aBuffer.Append( outline );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1665,19 +1665,12 @@ void PAD::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
|
||||||
outline.Rotate( m_orient );
|
outline.Rotate( m_orient );
|
||||||
outline.Move( VECTOR2I( m_pos ) );
|
outline.Move( VECTOR2I( m_pos ) );
|
||||||
|
|
||||||
if( aClearance )
|
if( aClearance > 0 || aErrorLoc == ERROR_OUTSIDE )
|
||||||
{
|
{
|
||||||
int numSegs = std::max( GetArcToSegmentCount( aClearance, aError, FULL_CIRCLE ),
|
|
||||||
pad_min_seg_per_circle_count );
|
|
||||||
int clearance = aClearance;
|
|
||||||
|
|
||||||
if( aErrorLoc == ERROR_OUTSIDE )
|
if( aErrorLoc == ERROR_OUTSIDE )
|
||||||
{
|
aClearance += aMaxError;
|
||||||
int actual_error = CircleToEndSegmentDeltaRadius( clearance, numSegs );
|
|
||||||
clearance += GetCircleToPolyCorrection( actual_error );
|
|
||||||
}
|
|
||||||
|
|
||||||
outline.Inflate( clearance, numSegs );
|
outline.Inflate( aClearance, SHAPE_POLY_SET::ROUND_ALL_CORNERS, aMaxError );
|
||||||
outline.Fracture( SHAPE_POLY_SET::PM_FAST );
|
outline.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -466,7 +466,7 @@ void PCB_TEXT::buildBoundingHull( SHAPE_POLY_SET* aBuffer, const SHAPE_POLY_SET&
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PCB_TEXT::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance, int aError,
|
void PCB_TEXT::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance, int aMaxError,
|
||||||
ERROR_LOC aErrorLoc ) const
|
ERROR_LOC aErrorLoc ) const
|
||||||
{
|
{
|
||||||
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
|
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
|
||||||
|
@ -485,7 +485,7 @@ void PCB_TEXT::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance,
|
||||||
// Stroke callback
|
// Stroke callback
|
||||||
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
|
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
|
||||||
{
|
{
|
||||||
TransformOvalToPolygon( textShape, aPt1, aPt2, penWidth, aError, aErrorLoc );
|
TransformOvalToPolygon( textShape, aPt1, aPt2, penWidth, aMaxError, aErrorLoc );
|
||||||
},
|
},
|
||||||
// Triangulation callback
|
// Triangulation callback
|
||||||
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 )
|
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 )
|
||||||
|
@ -511,11 +511,12 @@ void PCB_TEXT::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance,
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if( aClearance > 0 )
|
if( aClearance > 0 || aErrorLoc == ERROR_OUTSIDE )
|
||||||
{
|
{
|
||||||
// Number of segments to approximate a circle when inflating a polygon
|
if( aErrorLoc == ERROR_OUTSIDE )
|
||||||
const int circleSegmentsCount = 16;
|
aClearance += aMaxError;
|
||||||
textShape.Inflate( aClearance, circleSegmentsCount );
|
|
||||||
|
textShape.Inflate( aClearance, SHAPE_POLY_SET::ROUND_ALL_CORNERS, aMaxError );
|
||||||
}
|
}
|
||||||
|
|
||||||
aBuffer.Append( textShape );
|
aBuffer.Append( textShape );
|
||||||
|
@ -524,12 +525,12 @@ void PCB_TEXT::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance,
|
||||||
|
|
||||||
|
|
||||||
void PCB_TEXT::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
|
void PCB_TEXT::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
|
||||||
int aClearance, int aError, ERROR_LOC aErrorLoc,
|
int aClearance, int aMaxError, ERROR_LOC aErrorLoc,
|
||||||
bool aIgnoreLineWidth ) const
|
bool aIgnoreLineWidth ) const
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET poly;
|
SHAPE_POLY_SET poly;
|
||||||
|
|
||||||
TransformTextToPolySet( poly, 0, GetBoard()->GetDesignSettings().m_MaxError, ERROR_INSIDE );
|
TransformTextToPolySet( poly, 0, aMaxError, aErrorLoc );
|
||||||
|
|
||||||
buildBoundingHull( &aBuffer, poly, aClearance );
|
buildBoundingHull( &aBuffer, poly, aClearance );
|
||||||
}
|
}
|
||||||
|
|
|
@ -137,13 +137,13 @@ public:
|
||||||
* Circles and arcs are approximated by segments.
|
* Circles and arcs are approximated by segments.
|
||||||
* @param aBuffer SHAPE_POLY_SET to store the polygon corners
|
* @param aBuffer SHAPE_POLY_SET to store the polygon corners
|
||||||
* @param aClearance the clearance around the text
|
* @param aClearance the clearance around the text
|
||||||
* @param aError the maximum error to allow when approximating curves
|
* @param aMaxError the maximum error to allow when approximating curves
|
||||||
*/
|
*/
|
||||||
void TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance, int aError,
|
void TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance, int aMaxError,
|
||||||
ERROR_LOC aErrorLoc ) const;
|
ERROR_LOC aErrorLoc ) const;
|
||||||
|
|
||||||
void TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
|
void TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
|
||||||
int aError, ERROR_LOC aErrorLoc,
|
int aMaxError, ERROR_LOC aErrorLoc,
|
||||||
bool aIgnoreLineWidth = false ) const override;
|
bool aIgnoreLineWidth = false ) const override;
|
||||||
|
|
||||||
// @copydoc BOARD_ITEM::GetEffectiveShape
|
// @copydoc BOARD_ITEM::GetEffectiveShape
|
||||||
|
|
|
@ -447,7 +447,7 @@ std::shared_ptr<SHAPE> PCB_TEXTBOX::GetEffectiveShape( PCB_LAYER_ID aLayer, FLAS
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PCB_TEXTBOX::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance, int aError,
|
void PCB_TEXTBOX::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance, int aMaxError,
|
||||||
ERROR_LOC aErrorLoc ) const
|
ERROR_LOC aErrorLoc ) const
|
||||||
{
|
{
|
||||||
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
|
KIGFX::GAL_DISPLAY_OPTIONS empty_opts;
|
||||||
|
@ -465,7 +465,7 @@ void PCB_TEXTBOX::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearanc
|
||||||
// Stroke callback
|
// Stroke callback
|
||||||
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
|
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2 )
|
||||||
{
|
{
|
||||||
TransformOvalToPolygon( buffer, aPt1, aPt2, penWidth, aError, aErrorLoc );
|
TransformOvalToPolygon( buffer, aPt1, aPt2, penWidth, aMaxError, aErrorLoc );
|
||||||
},
|
},
|
||||||
// Triangulation callback
|
// Triangulation callback
|
||||||
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 )
|
[&]( const VECTOR2I& aPt1, const VECTOR2I& aPt2, const VECTOR2I& aPt3 )
|
||||||
|
@ -478,17 +478,24 @@ void PCB_TEXTBOX::TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearanc
|
||||||
|
|
||||||
font->Draw( &callback_gal, GetShownText( true ), GetDrawPos(), GetAttributes() );
|
font->Draw( &callback_gal, GetShownText( true ), GetDrawPos(), GetAttributes() );
|
||||||
|
|
||||||
if( aClearance > 0 )
|
if( aClearance > 0 || aErrorLoc == ERROR_OUTSIDE )
|
||||||
buffer.Inflate( aClearance, aClearance );
|
{
|
||||||
|
if( aErrorLoc == ERROR_OUTSIDE )
|
||||||
|
aClearance += aMaxError;
|
||||||
|
|
||||||
|
buffer.Inflate( aClearance, SHAPE_POLY_SET::ROUND_ALL_CORNERS, aMaxError, true );
|
||||||
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
buffer.Simplify( SHAPE_POLY_SET::PM_FAST );
|
buffer.Simplify( SHAPE_POLY_SET::PM_FAST );
|
||||||
|
}
|
||||||
|
|
||||||
aBuffer.Append( buffer );
|
aBuffer.Append( buffer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void PCB_TEXTBOX::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
|
void PCB_TEXTBOX::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer,
|
||||||
int aClearance, int aError, ERROR_LOC aErrorLoc,
|
int aClearance, int aMaxError, ERROR_LOC aErrorLoc,
|
||||||
bool aIgnoreLineWidth ) const
|
bool aIgnoreLineWidth ) const
|
||||||
{
|
{
|
||||||
// Don't use PCB_SHAPE::TransformShapeToPolygon. We want to treat the textbox as filled even
|
// Don't use PCB_SHAPE::TransformShapeToPolygon. We want to treat the textbox as filled even
|
||||||
|
@ -508,10 +515,10 @@ void PCB_TEXTBOX::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID
|
||||||
if( width > 0 )
|
if( width > 0 )
|
||||||
{
|
{
|
||||||
// Add in segments
|
// Add in segments
|
||||||
TransformOvalToPolygon( aBuffer, pts[0], pts[1], width, aError, aErrorLoc );
|
TransformOvalToPolygon( aBuffer, pts[0], pts[1], width, aMaxError, aErrorLoc );
|
||||||
TransformOvalToPolygon( aBuffer, pts[1], pts[2], width, aError, aErrorLoc );
|
TransformOvalToPolygon( aBuffer, pts[1], pts[2], width, aMaxError, aErrorLoc );
|
||||||
TransformOvalToPolygon( aBuffer, pts[2], pts[3], width, aError, aErrorLoc );
|
TransformOvalToPolygon( aBuffer, pts[2], pts[3], width, aMaxError, aErrorLoc );
|
||||||
TransformOvalToPolygon( aBuffer, pts[3], pts[0], width, aError, aErrorLoc );
|
TransformOvalToPolygon( aBuffer, pts[3], pts[0], width, aMaxError, aErrorLoc );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if( GetShape() == SHAPE_T::POLY ) // Non-cardinally-rotated rect
|
else if( GetShape() == SHAPE_T::POLY ) // Non-cardinally-rotated rect
|
||||||
|
@ -528,7 +535,7 @@ void PCB_TEXTBOX::TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID
|
||||||
for( int ii = 0; ii < poly.SegmentCount(); ++ii )
|
for( int ii = 0; ii < poly.SegmentCount(); ++ii )
|
||||||
{
|
{
|
||||||
const SEG& seg = poly.GetSegment( ii );
|
const SEG& seg = poly.GetSegment( ii );
|
||||||
TransformOvalToPolygon( aBuffer, seg.A, seg.B, width, aError, aErrorLoc );
|
TransformOvalToPolygon( aBuffer, seg.A, seg.B, width, aMaxError, aErrorLoc );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -114,11 +114,11 @@ public:
|
||||||
* @param aClearance = the clearance around the text
|
* @param aClearance = the clearance around the text
|
||||||
* @param aError = the maximum error to allow when approximating curves
|
* @param aError = the maximum error to allow when approximating curves
|
||||||
*/
|
*/
|
||||||
void TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance, int aError,
|
void TransformTextToPolySet( SHAPE_POLY_SET& aBuffer, int aClearance, int aMaxError,
|
||||||
ERROR_LOC aErrorLoc ) const;
|
ERROR_LOC aErrorLoc ) const;
|
||||||
|
|
||||||
void TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
|
void TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
|
||||||
int aError, ERROR_LOC aErrorLoc,
|
int aMaxError, ERROR_LOC aErrorLoc,
|
||||||
bool aIgnoreLineWidth = false ) const override;
|
bool aIgnoreLineWidth = false ) const override;
|
||||||
|
|
||||||
// @copydoc BOARD_ITEM::GetEffectiveShape
|
// @copydoc BOARD_ITEM::GetEffectiveShape
|
||||||
|
|
|
@ -2139,7 +2139,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadCoppers()
|
||||||
{
|
{
|
||||||
fill = getPolySetFromCadstarShape( csCopper.Shape, -1 );
|
fill = getPolySetFromCadstarShape( csCopper.Shape, -1 );
|
||||||
fill.ClearArcs();
|
fill.ClearArcs();
|
||||||
fill.Inflate( copperWidth / 2, 32 );
|
fill.Inflate( copperWidth / 2, SHAPE_POLY_SET::ROUND_ALL_CORNERS, ARC_HIGH_DEF );
|
||||||
}
|
}
|
||||||
|
|
||||||
if( pouredZone->HasFilledPolysForLayer( getKiCadLayer( csCopper.LayerID ) ) )
|
if( pouredZone->HasFilledPolysForLayer( getKiCadLayer( csCopper.LayerID ) ) )
|
||||||
|
@ -3033,10 +3033,7 @@ SHAPE_POLY_SET CADSTAR_PCB_ARCHIVE_LOADER::getPolySetFromCadstarShape( const SHA
|
||||||
polySet.ClearArcs();
|
polySet.ClearArcs();
|
||||||
|
|
||||||
if( aLineThickness > 0 )
|
if( aLineThickness > 0 )
|
||||||
{
|
polySet.Inflate( aLineThickness / 2, SHAPE_POLY_SET::ROUND_ALL_CORNERS, ARC_HIGH_DEF );
|
||||||
polySet.Inflate( aLineThickness / 2, 32,
|
|
||||||
SHAPE_POLY_SET::CORNER_STRATEGY::ROUND_ALL_CORNERS );
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
for( int i = 0; i < polySet.OutlineCount(); ++i )
|
for( int i = 0; i < polySet.OutlineCount(); ++i )
|
||||||
|
@ -3730,7 +3727,8 @@ bool CADSTAR_PCB_ARCHIVE_LOADER::calculateZonePriorities( PCB_LAYER_ID& aLayer )
|
||||||
[&]( ZONE* aLowerZone, ZONE* aHigherZone ) -> double
|
[&]( ZONE* aLowerZone, ZONE* aHigherZone ) -> double
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET intersectShape( *aHigherZone->Outline() );
|
SHAPE_POLY_SET intersectShape( *aHigherZone->Outline() );
|
||||||
intersectShape.Inflate( inflateValue( aLowerZone, aHigherZone ) , 32 );
|
intersectShape.Inflate( inflateValue( aLowerZone, aHigherZone ),
|
||||||
|
SHAPE_POLY_SET::ROUND_ALL_CORNERS, ARC_HIGH_DEF );
|
||||||
|
|
||||||
SHAPE_POLY_SET lowerZoneFill( *aLowerZone->GetFilledPolysList( aLayer ) );
|
SHAPE_POLY_SET lowerZoneFill( *aLowerZone->GetFilledPolysList( aLayer ) );
|
||||||
SHAPE_POLY_SET lowerZoneOutline( *aLowerZone->Outline() );
|
SHAPE_POLY_SET lowerZoneOutline( *aLowerZone->Outline() );
|
||||||
|
@ -3748,10 +3746,12 @@ bool CADSTAR_PCB_ARCHIVE_LOADER::calculateZonePriorities( PCB_LAYER_ID& aLayer )
|
||||||
[&]( ZONE* aZoneA, ZONE* aZoneB ) -> double
|
[&]( ZONE* aZoneA, ZONE* aZoneB ) -> double
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET outLineA( *aZoneA->Outline() );
|
SHAPE_POLY_SET outLineA( *aZoneA->Outline() );
|
||||||
outLineA.Inflate( inflateValue( aZoneA, aZoneB ), 32 );
|
outLineA.Inflate( inflateValue( aZoneA, aZoneB ), SHAPE_POLY_SET::ROUND_ALL_CORNERS,
|
||||||
|
ARC_HIGH_DEF );
|
||||||
|
|
||||||
SHAPE_POLY_SET outLineB( *aZoneA->Outline() );
|
SHAPE_POLY_SET outLineB( *aZoneA->Outline() );
|
||||||
outLineB.Inflate( inflateValue( aZoneA, aZoneB ), 32 );
|
outLineB.Inflate( inflateValue( aZoneA, aZoneB ), SHAPE_POLY_SET::ROUND_ALL_CORNERS,
|
||||||
|
ARC_HIGH_DEF );
|
||||||
|
|
||||||
outLineA.BooleanIntersection( outLineB, SHAPE_POLY_SET::PM_FAST );
|
outLineA.BooleanIntersection( outLineB, SHAPE_POLY_SET::PM_FAST );
|
||||||
|
|
||||||
|
|
|
@ -1492,7 +1492,8 @@ ZONE* EAGLE_PLUGIN::loadPolygon( wxXmlNode* aPolyNode )
|
||||||
// We trace the zone such that the copper is completely inside.
|
// We trace the zone such that the copper is completely inside.
|
||||||
if( p.width.ToPcbUnits() > 0 )
|
if( p.width.ToPcbUnits() > 0 )
|
||||||
{
|
{
|
||||||
polygon.Inflate( p.width.ToPcbUnits() / 2, 32, SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS );
|
polygon.Inflate( p.width.ToPcbUnits() / 2, SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS,
|
||||||
|
ARC_HIGH_DEF );
|
||||||
polygon.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
polygon.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2233,8 +2234,8 @@ void EAGLE_PLUGIN::packagePolygon( FOOTPRINT* aFootprint, wxXmlNode* aTree ) con
|
||||||
dwg->SetPolyPoints( pts );
|
dwg->SetPolyPoints( pts );
|
||||||
dwg->Rotate( { 0, 0 }, aFootprint->GetOrientation() );
|
dwg->Rotate( { 0, 0 }, aFootprint->GetOrientation() );
|
||||||
dwg->Move( aFootprint->GetPosition() );
|
dwg->Move( aFootprint->GetPosition() );
|
||||||
dwg->GetPolyShape().Inflate( p.width.ToPcbUnits() / 2, 32,
|
dwg->GetPolyShape().Inflate( p.width.ToPcbUnits() / 2,
|
||||||
SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS );
|
SHAPE_POLY_SET::ALLOW_ACUTE_CORNERS, ARC_HIGH_DEF );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1231,7 +1231,7 @@ bool ZONE::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly, PCB_LAYER_ID aLayer
|
||||||
if( aSmoothedPolyWithApron )
|
if( aSmoothedPolyWithApron )
|
||||||
{
|
{
|
||||||
SHAPE_POLY_SET poly = maxExtents->CloneDropTriangulation();
|
SHAPE_POLY_SET poly = maxExtents->CloneDropTriangulation();
|
||||||
poly.Inflate( m_ZoneMinThickness, 64 );
|
poly.Inflate( m_ZoneMinThickness, SHAPE_POLY_SET::ROUND_ALL_CORNERS, maxError );
|
||||||
*aSmoothedPolyWithApron = aSmoothedPoly;
|
*aSmoothedPolyWithApron = aSmoothedPoly;
|
||||||
aSmoothedPolyWithApron->BooleanIntersection( poly, SHAPE_POLY_SET::PM_FAST );
|
aSmoothedPolyWithApron->BooleanIntersection( poly, SHAPE_POLY_SET::PM_FAST );
|
||||||
}
|
}
|
||||||
|
@ -1292,12 +1292,10 @@ void ZONE::TransformSmoothedOutlineToPolygon( SHAPE_POLY_SET& aBuffer, int aClea
|
||||||
if( board )
|
if( board )
|
||||||
maxError = board->GetDesignSettings().m_MaxError;
|
maxError = board->GetDesignSettings().m_MaxError;
|
||||||
|
|
||||||
int segCount = GetArcToSegmentCount( aClearance, maxError, FULL_CIRCLE );
|
|
||||||
|
|
||||||
if( aErrorLoc == ERROR_OUTSIDE )
|
if( aErrorLoc == ERROR_OUTSIDE )
|
||||||
aClearance += aMaxError;
|
aClearance += maxError;
|
||||||
|
|
||||||
polybuffer.Inflate( aClearance, segCount );
|
polybuffer.Inflate( aClearance, SHAPE_POLY_SET::ROUND_ALL_CORNERS, maxError );
|
||||||
}
|
}
|
||||||
|
|
||||||
polybuffer.Fracture( SHAPE_POLY_SET::PM_FAST );
|
polybuffer.Fracture( SHAPE_POLY_SET::PM_FAST );
|
||||||
|
|
|
@ -1391,7 +1391,6 @@ bool ZONE_FILLER::fillCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, PCB_LA
|
||||||
// deflating/inflating.
|
// deflating/inflating.
|
||||||
int half_min_width = aZone->GetMinThickness() / 2;
|
int half_min_width = aZone->GetMinThickness() / 2;
|
||||||
int epsilon = pcbIUScale.mmToIU( 0.001 );
|
int epsilon = pcbIUScale.mmToIU( 0.001 );
|
||||||
int numSegs = GetArcToSegmentCount( half_min_width, m_maxError, FULL_CIRCLE );
|
|
||||||
|
|
||||||
// Solid polygons are deflated and inflated during calculations. Deflating doesn't cause
|
// Solid polygons are deflated and inflated during calculations. Deflating doesn't cause
|
||||||
// issues, but inflate is tricky as it can create excessively long and narrow spikes for
|
// issues, but inflate is tricky as it can create excessively long and narrow spikes for
|
||||||
|
@ -1456,10 +1455,10 @@ bool ZONE_FILLER::fillCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, PCB_LA
|
||||||
// Prune features that don't meet minimum-width criteria
|
// Prune features that don't meet minimum-width criteria
|
||||||
if( half_min_width - epsilon > epsilon )
|
if( half_min_width - epsilon > epsilon )
|
||||||
{
|
{
|
||||||
testAreas.Deflate( half_min_width - epsilon, numSegs, fastCornerStrategy );
|
testAreas.Deflate( half_min_width - epsilon, fastCornerStrategy, m_maxError );
|
||||||
DUMP_POLYS_TO_COPPER_LAYER( testAreas, In5_Cu, wxT( "spoke-test-deflated" ) );
|
DUMP_POLYS_TO_COPPER_LAYER( testAreas, In5_Cu, wxT( "spoke-test-deflated" ) );
|
||||||
|
|
||||||
testAreas.Inflate( half_min_width - epsilon, numSegs, fastCornerStrategy );
|
testAreas.Inflate( half_min_width - epsilon, fastCornerStrategy, m_maxError );
|
||||||
DUMP_POLYS_TO_COPPER_LAYER( testAreas, In6_Cu, wxT( "spoke-test-reinflated" ) );
|
DUMP_POLYS_TO_COPPER_LAYER( testAreas, In6_Cu, wxT( "spoke-test-reinflated" ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1526,7 +1525,7 @@ bool ZONE_FILLER::fillCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, PCB_LA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if( half_min_width - epsilon > epsilon )
|
if( half_min_width - epsilon > epsilon )
|
||||||
aFillPolys.Deflate( half_min_width - epsilon, numSegs, fastCornerStrategy );
|
aFillPolys.Deflate( half_min_width - epsilon, fastCornerStrategy, m_maxError );
|
||||||
|
|
||||||
// Min-thickness is the web thickness. On the other hand, a blob min-thickness by
|
// Min-thickness is the web thickness. On the other hand, a blob min-thickness by
|
||||||
// min-thickness is not useful. Since there's no obvious definition of web vs. blob, we
|
// min-thickness is not useful. Since there's no obvious definition of web vs. blob, we
|
||||||
|
@ -1563,7 +1562,7 @@ bool ZONE_FILLER::fillCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer, PCB_LA
|
||||||
*/
|
*/
|
||||||
|
|
||||||
if( half_min_width - epsilon > epsilon )
|
if( half_min_width - epsilon > epsilon )
|
||||||
aFillPolys.Inflate( half_min_width - epsilon, numSegs, cornerStrategy, true );
|
aFillPolys.Inflate( half_min_width - epsilon, cornerStrategy, m_maxError, true );
|
||||||
|
|
||||||
DUMP_POLYS_TO_COPPER_LAYER( aFillPolys, In15_Cu, wxT( "after-reinflating" ) );
|
DUMP_POLYS_TO_COPPER_LAYER( aFillPolys, In15_Cu, wxT( "after-reinflating" ) );
|
||||||
|
|
||||||
|
@ -1663,7 +1662,7 @@ bool ZONE_FILLER::fillNonCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer,
|
||||||
int epsilon = pcbIUScale.mmToIU( 0.001 );
|
int epsilon = pcbIUScale.mmToIU( 0.001 );
|
||||||
int numSegs = GetArcToSegmentCount( half_min_width, m_maxError, FULL_CIRCLE );
|
int numSegs = GetArcToSegmentCount( half_min_width, m_maxError, FULL_CIRCLE );
|
||||||
|
|
||||||
aFillPolys.Deflate( half_min_width - epsilon, numSegs );
|
aFillPolys.Deflate( half_min_width - epsilon, SHAPE_POLY_SET::CHAMFER_ALL_CORNERS, m_maxError );
|
||||||
|
|
||||||
// Remove the non filled areas due to the hatch pattern
|
// Remove the non filled areas due to the hatch pattern
|
||||||
if( aZone->GetFillMode() == ZONE_FILL_MODE::HATCH_PATTERN )
|
if( aZone->GetFillMode() == ZONE_FILL_MODE::HATCH_PATTERN )
|
||||||
|
@ -1674,7 +1673,7 @@ bool ZONE_FILLER::fillNonCopperZone( const ZONE* aZone, PCB_LAYER_ID aLayer,
|
||||||
|
|
||||||
// Re-inflate after pruning of areas that don't meet minimum-width criteria
|
// Re-inflate after pruning of areas that don't meet minimum-width criteria
|
||||||
if( half_min_width - epsilon > epsilon )
|
if( half_min_width - epsilon > epsilon )
|
||||||
aFillPolys.Inflate( half_min_width - epsilon, numSegs );
|
aFillPolys.Inflate( half_min_width - epsilon, SHAPE_POLY_SET::ROUND_ALL_CORNERS, m_maxError );
|
||||||
|
|
||||||
aFillPolys.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
aFillPolys.Fracture( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE );
|
||||||
return true;
|
return true;
|
||||||
|
|
Loading…
Reference in New Issue