53 virtual bool Run()
override;
55 virtual const wxString
GetName()
const override {
return wxT(
"sliver checker" ); };
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() )
122 fill = zone->GetFill( layer )->CloneDropTriangulation();
152 std::vector<std::future<size_t>> returns;
154 returns.reserve( copperLayers.size() );
156 for(
size_t ii = 0; ii < copperLayers.size(); ++ii )
157 returns.emplace_back(
tp.submit( build_layer_polys, ii ) );
159 for(
const std::future<size_t>& ret : returns )
161 std::future_status status = ret.wait_for( std::chrono::milliseconds( 250 ) );
163 while( status != std::future_status::ready )
166 status = ret.wait_for( std::chrono::milliseconds( 250 ) );
170 for(
int ii = 0; ii < layerCount; ++ii )
188 int ptCount = pts.size();
197 auto isLocallyInside = [&](
int aA,
int aB ) ->
bool
199 int prev = ( ptCount + aA - 1 ) % ptCount;
200 int next = ( aA + 1 ) % ptCount;
202 if( area( pts[prev], pts[aA], pts[
next] ) < 0 )
203 return area( pts[aA], pts[aB], pts[
next] ) >= 0 && area( pts[aA], pts[prev], pts[aB] ) >= 0;
205 return area( pts[aA], pts[aB], pts[prev] ) < 0 || area( pts[aA], pts[
next], pts[aB] ) < 0;
211 for(
int kk = 0; kk < ptCount; kk += offset )
213 int prior_index = ( ptCount + kk - 1 ) % ptCount;
214 int next_index = ( kk + 1 ) % ptCount;
216 VECTOR2I ptPrior = pts[ prior_index ];
218 int forward_offset = 1;
223 && offset < ptCount )
225 pt = pts[ ( kk + offset++ ) % ptCount ];
226 vPrior = ( ptPrior - pt );
229 if( offset >= ptCount )
232 VECTOR2I ptAfter = pts[ next_index ];
236 && forward_offset < ptCount )
238 next_index = ( kk + forward_offset++ ) % ptCount;
239 ptAfter = pts[ next_index ];
240 vAfter = ( ptAfter - pt );
243 if( offset >= ptCount )
247 if( vPrior.
Dot( vAfter ) <= 0 )
250 if( !isLocallyInside( prior_index, next_index ) )
253 VECTOR2I vIncluded = ptAfter - ptPrior;
258 double cos_ang =
std::abs( ( opp - arm1 - arm2 ) / ( std::sqrt( arm1 ) * std::sqrt( arm2 ) ) );
260 if( cos_ang > cosangleTol && 2.0 - cos_ang > std::numeric_limits<float>::epsilon() && opp > squared_width )
263 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.
const ZONES & Zones() const
int GetCopperLayerCount() 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 ~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()
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)
virtual void reportViolation(std::shared_ptr< DRC_ITEM > &item, const VECTOR2I &aMarkerPos, int aMarkerLayer, DRC_CUSTOM_MARKER_HANDLER *aCustomHandler=nullptr)
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 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.
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.
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
thread_pool & GetKiCadThreadPool()
Get a reference to the current thread pool.
BS::thread_pool thread_pool
double DEG2RAD(double deg)