56 virtual bool Run()
override;
58 virtual const wxString
GetName()
const override
60 return wxT(
"sliver checker" );
65 return wxT(
"Checks copper layers for slivers" );
84 if( !
reportPhase(
_(
"Running sliver detection on copper layers..." ) ) )
88 int64_t squared_width = widthTolerance * widthTolerance;
91 double cosangleTol = 2.0 * cos(
DEG2RAD( angleTolerance ) );
93 LSEQ copperLayers = copperLayerSet.
Seq();
94 int layerCount = copperLayers.size();
97 int zoneLayerCount = 0;
98 std::atomic<size_t> done( 1 );
104 if( !zone->GetIsRuleArea() && zone->IsOnLayer( layer ) )
114 std::vector<SHAPE_POLY_SET> layerPolys( layerCount );
116 auto build_layer_polys =
117 [&](
int layerIdx ) ->
size_t
130 if(
ZONE* zone =
dynamic_cast<ZONE*
>( item) )
132 if( !zone->GetIsRuleArea() )
134 fill = zone->GetFill( layer )->CloneDropTriangulation();
164 std::vector<std::future<size_t>> returns;
166 returns.reserve( copperLayers.size() );
168 for(
size_t ii = 0; ii < copperLayers.size(); ++ii )
169 returns.emplace_back(
tp.submit( build_layer_polys, ii ) );
171 for(
const std::future<size_t>& ret : returns )
173 std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
175 while( status != std::future_status::ready )
178 status = ret.wait_for( std::chrono::milliseconds( 250 ) );
182 for(
int ii = 0; ii < layerCount; ++ii )
200 int ptCount = pts.size();
209 auto isLocallyInside = [&](
int aA,
int aB ) ->
bool
211 int prev = ( ptCount + aA - 1 ) % ptCount;
212 int next = ( aA + 1 ) % ptCount;
214 if( area( pts[prev], pts[aA], pts[
next] ) < 0 )
215 return area( pts[aA], pts[aB], pts[
next] ) >= 0 && area( pts[aA], pts[prev], pts[aB] ) >= 0;
217 return area( pts[aA], pts[aB], pts[prev] ) < 0 || area( pts[aA], pts[
next], pts[aB] ) < 0;
223 for(
int kk = 0; kk < ptCount; kk += offset )
225 int prior_index = ( ptCount + kk - 1 ) % ptCount;
226 int next_index = ( kk + 1 ) % ptCount;
228 VECTOR2I ptPrior = pts[ prior_index ];
230 int forward_offset = 1;
235 && offset < ptCount )
237 pt = pts[ ( kk + offset++ ) % ptCount ];
238 vPrior = ( ptPrior - pt );
241 if( offset >= ptCount )
244 VECTOR2I ptAfter = pts[ next_index ];
248 && forward_offset < ptCount )
250 next_index = ( kk + forward_offset++ ) % ptCount;
251 ptAfter = pts[ next_index ];
252 vAfter = ( ptAfter - pt );
255 if( offset >= ptCount )
259 if( vPrior.
Dot( vAfter ) <= 0 )
262 if( !isLocallyInside( prior_index, next_index ) )
265 VECTOR2I vIncluded = ptAfter - ptPrior;
270 double cos_ang =
std::abs( ( opp - arm1 - arm2 ) / ( std::sqrt( arm1 ) * std::sqrt( arm2 ) ) );
272 if( cos_ang > cosangleTol && 2.0 - cos_ang > std::numeric_limits<float>::epsilon() && opp > squared_width )
275 drce->SetErrorMessage( drce->GetErrorText() + wxS(
" " ) +
layerDesc( layer ) );
constexpr EDA_IU_SCALE pcbIUScale
constexpr int ARC_LOW_DEF
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const
Convert the item shape to a closed polygon.
LSET GetEnabledLayers() const
A proxy function that calls the corresponding function in m_BoardSettings.
const ZONES & Zones() const
const wxString GetLayerName(PCB_LAYER_ID aLayer) const
Return the name of a aLayer.
bool IsErrorLimitExceeded(int error_code)
PROGRESS_REPORTER * GetProgressReporter() const
static std::shared_ptr< DRC_ITEM > Create(int aErrorCode)
Constructs a DRC_ITEM for the given error code.
wxString layerDesc(PCB_LAYER_ID aLayer)
virtual const wxString GetDescription() const override
virtual ~DRC_TEST_PROVIDER_SLIVER_CHECKER()
virtual const wxString GetName() const override
virtual bool Run() override
Run this provider against the given PCB with configured options (if any).
DRC_TEST_PROVIDER_SLIVER_CHECKER()
Represent a DRC "provider" which runs some DRC functions over a BOARD and spits out DRC_ITEM and posi...
virtual bool reportPhase(const wxString &aStageName)
int forEachGeometryItem(const std::vector< KICAD_T > &aTypes, LSET aLayers, const std::function< bool(BOARD_ITEM *)> &aFunc)
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, const VECTOR2I &aMarkerPos, int aMarkerLayer)
static std::vector< KICAD_T > s_allBasicItems
virtual bool reportProgress(size_t aCount, size_t aSize, size_t aDelta=1)
LSEQ is a sequence (and therefore also a set) of PCB_LAYER_IDs.
LSET is a set of PCB_LAYER_IDs.
static LSET AllCuMask(int aCuLayerCount=MAX_CU_LAYERS)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
A progress reporter interface for use in multi-threaded environments.
virtual bool IsCancelled() const =0
const std::vector< VECTOR2I > & CPoints() const
Represent a set of closed polygons.
void Simplify(POLYGON_MODE aFastMode)
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections) For aFastMo...
SHAPE_LINE_CHAIN & Outline(int aIndex)
Return the reference to aIndex-th outline in the set.
int OutlineCount() const
Return the number of outlines in the set.
constexpr extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
VECTOR2_TRAITS< int32_t >::extended_type extended_type
constexpr extended_type Dot(const VECTOR2< T > &aVector) const
Compute dot product of self with aVector.
Handle a list of polygons defining a copper zone.
double m_SliverAngleTolerance
Sliver angle to tolerance for DRC.
PCB_LAYER_ID
A quick note on layer IDs:
static DRC_REGISTER_TEST_PROVIDER< DRC_TEST_PROVIDER_ANNULAR_WIDTH > dummy
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
constexpr int mmToIU(double mm) const
BS::thread_pool thread_pool
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
double DEG2RAD(double deg)