53 virtual bool Run()
override;
55 virtual const wxString
GetName()
const override {
return wxT(
"sliver checker" ); };
64 return wxString::Format( wxT(
"(%s)" ),
m_drcEngine->GetBoard()->GetLayerName( aLayer ) );
73 if( !
reportPhase(
_(
"Running sliver detection on copper layers..." ) ) )
77 int64_t squared_width = widthTolerance * widthTolerance;
80 double cosangleTol = 2.0 * cos(
DEG2RAD( angleTolerance ) );
82 int layerCount = copperLayers.size();
85 int zoneLayerCount = 0;
86 std::atomic<size_t> done( 1 );
92 if( !zone->GetIsRuleArea() && zone->IsOnLayer( layer ) )
102 std::vector<SHAPE_POLY_SET> layerPolys( layerCount );
104 auto build_layer_polys =
105 [&](
int layerIdx ) ->
size_t
118 if(
ZONE* zone =
dynamic_cast<ZONE*
>( item) )
120 if( !zone->GetIsRuleArea() )
153 auto returns =
tp.submit_loop( 0, copperLayers.size(), build_layer_polys );
155 for(
auto& ret : returns )
157 std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
159 while( status != std::future_status::ready )
162 status = ret.wait_for( std::chrono::milliseconds( 250 ) );
166 for(
int ii = 0; ii < layerCount; ++ii )
184 int ptCount = pts.size();
193 auto isLocallyInside = [&](
int aA,
int aB ) ->
bool
195 int prev = ( ptCount + aA - 1 ) % ptCount;
196 int next = ( aA + 1 ) % ptCount;
198 if( area( pts[prev], pts[aA], pts[
next] ) < 0 )
199 return area( pts[aA], pts[aB], pts[
next] ) >= 0 && area( pts[aA], pts[prev], pts[aB] ) >= 0;
201 return area( pts[aA], pts[aB], pts[prev] ) < 0 || area( pts[aA], pts[
next], pts[aB] ) < 0;
207 for(
int kk = 0; kk < ptCount; kk += offset )
209 int prior_index = ( ptCount + kk - 1 ) % ptCount;
210 int next_index = ( kk + 1 ) % ptCount;
212 VECTOR2I ptPrior = pts[ prior_index ];
214 int forward_offset = 1;
219 && offset < ptCount )
221 pt = pts[ ( kk + offset++ ) % ptCount ];
222 vPrior = ( ptPrior - pt );
225 if( offset >= ptCount )
228 VECTOR2I ptAfter = pts[ next_index ];
232 && forward_offset < ptCount )
234 next_index = ( kk + forward_offset++ ) % ptCount;
235 ptAfter = pts[ next_index ];
236 vAfter = ( ptAfter - pt );
239 if( offset >= ptCount )
243 if( vPrior.
Dot( vAfter ) <= 0 )
246 if( !isLocallyInside( prior_index, next_index ) )
249 VECTOR2I vIncluded = ptAfter - ptPrior;
254 double cos_ang =
std::abs( ( opp - arm1 - arm2 ) / ( std::sqrt( arm1 ) * std::sqrt( arm2 ) ) );
256 if( cos_ang > cosangleTol && 2.0 - cos_ang > std::numeric_limits<float>::epsilon() && opp > squared_width )
259 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.
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 ~DRC_TEST_PROVIDER_SLIVER_CHECKER()=default
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()
virtual bool reportPhase(const wxString &aStageName)
int forEachGeometryItem(const std::vector< KICAD_T > &aTypes, const LSET &aLayers, const std::function< bool(BOARD_ITEM *)> &aFunc)
static std::vector< KICAD_T > s_allBasicItems
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, const VECTOR2I &aMarkerPos, int aMarkerLayer, const std::vector< PCB_SHAPE > &aShapes={})
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.
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
static LSET AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
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.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)
void Simplify()
Simplify the polyset (merges overlapping polys, eliminates degeneracy/self-intersections)
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.
SHAPE_POLY_SET CloneDropTriangulation() const
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)
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::thread_pool< 0 > thread_pool
double DEG2RAD(double deg)
VECTOR2< int32_t > VECTOR2I