59#include <api/board/board_types.pb.h>
63#include <magic_enum.hpp>
128static int scaleLength(
int aLength,
double aFactor )
130 return KiROUND( aLength * aFactor );
135static void scaleInChildFrame(
double aSx,
double aSy,
const EDA_ANGLE& aRelOrient,
double& aLocalSx,
double& aLocalSy )
137 const double c = aRelOrient.
Cos();
138 const double s = aRelOrient.
Sin();
139 aLocalSx = aSx * c * c + aSy * s * s;
140 aLocalSy = aSx * s * s + aSy * c * c;
153 const double uniform = ( sx + sy ) * 0.5;
154 return { scaleLength( aLibSize.
x, uniform ), scaleLength( aLibSize.
y, uniform ) };
158 double localSx, localSy;
159 scaleInChildFrame( sx, sy, aRelOrient, localSx, localSy );
160 return { scaleLength( aLibSize.
x, localSx ), scaleLength( aLibSize.
y, localSy ) };
173 const double uniform = ( sx + sy ) * 0.5;
174 return { scaleLength( aBoardSize.
x, 1.0 / uniform ), scaleLength( aBoardSize.
y, 1.0 / uniform ) };
177 double localSx, localSy;
178 scaleInChildFrame( sx, sy, aRelOrient, localSx, localSy );
179 return { scaleLength( aBoardSize.
x, 1.0 / localSx ), scaleLength( aBoardSize.
y, 1.0 / localSy ) };
192 const double uniform = ( sx + sy ) * 0.5;
193 return { scaleLength( aLibDrill.
x, uniform ), scaleLength( aLibDrill.
y, uniform ) };
197 double localSx, localSy;
198 scaleInChildFrame( sx, sy, aRelOrient, localSx, localSy );
199 return { scaleLength( aLibDrill.
x, localSx ), scaleLength( aLibDrill.
y, localSy ) };
212 const double uniform = ( sx + sy ) * 0.5;
213 return { scaleLength( aBoardDrill.
x, 1.0 / uniform ), scaleLength( aBoardDrill.
y, 1.0 / uniform ) };
216 double localSx, localSy;
217 scaleInChildFrame( sx, sy, aRelOrient, localSx, localSy );
218 return { scaleLength( aBoardDrill.
x, 1.0 / localSx ), scaleLength( aBoardDrill.
y, 1.0 / localSy ) };
226 double localSx, localSy;
228 return { scaleLength( aLibOffset.
x, localSx ), scaleLength( aLibOffset.
y, localSy ) };
236 double localSx, localSy;
238 return { scaleLength( aBoardOffset.
x, 1.0 / localSx ), scaleLength( aBoardOffset.
y, 1.0 / localSy ) };
247 m_libPos = fp->GetTransform().InverseApply( aPos );
258 return fp->GetTransform().Apply(
m_libPos );
300 return derivePadBoardSize(
m_padStack.Size( aLayer ),
GetShape( aLayer ), fp->GetTransform(),
369 *
this = *
static_cast<const PAD*
>( aOther );
374std::optional<std::pair<ELECTRICAL_PINTYPE, bool>>
parsePinType(
const wxString& aPinTypeString )
377 static std::map<wxString, ELECTRICAL_PINTYPE> map = {
392 bool hasNoConnect = aPinTypeString.EndsWith( wxT(
"+no_connect" ) );
394 if(
auto it = map.find( aPinTypeString.BeforeFirst(
'+' ) ); it != map.end() )
395 return std::make_pair( it->second, hasNoConnect );
407 pad.mutable_id()->set_value(
m_Uuid.AsStdString() );
409 pad.set_locked(
IsLocked() ? LockedState::LS_LOCKED
410 : LockedState::LS_UNLOCKED );
427 pad.mutable_symbol_pin()->set_no_connect( pt->second );
434 pad.mutable_parent()->set_value( parent->m_Uuid.AsStdString() );
444 aContainer.PackFrom(
pad );
450 kiapi::board::types::Pad
pad;
452 if( !aContainer.UnpackTo( &
pad ) )
458 SetLocked(
pad.locked() == kiapi::common::types::LockedState::LS_LOCKED );
466 google::protobuf::Any padStackWrapper;
467 padStackWrapper.PackFrom(
pad.pad_stack() );
473 if(
pad.has_copper_clearance_override() )
480 if(
pad.symbol_pin().type() != kiapi::common::types::EPT_UNKNOWN )
485 if(
pad.symbol_pin().no_connect() )
489 if(
pad.has_teardrop() )
509 std::unique_lock<std::mutex> cacheLock(
m_dataMutex );
518 std::unique_lock<std::mutex> cacheLock(
m_dataMutex );
528 std::unique_lock<std::mutex> cacheLock(
m_dataMutex );
552 bool hasCopper =
false;
593 int thisNetTieGroup = padToNetTieGroupMap[
GetNumber() ];
594 int otherNetTieGroup = padToNetTieGroupMap[ aOther->
GetNumber() ];
596 return thisNetTieGroup >= 0 && thisNetTieGroup == otherNetTieGroup;
605 return m_pinType.Contains( wxT(
"no_connect" ) );
753 else if( aOnlyCheckIfPermitted )
763 return board->GetConnectivity()->IsConnectedOnLayer(
this, aLayer, nonZoneTypes );
888 int startOrdinal =
board->IsLayerEnabled( secondaryDrill.
start )
890 : secondaryDrill.
start / 2 + 1 )
891 : secondaryDrill.
start / 2
893 int endOrdinal =
board->IsLayerEnabled( secondaryDrill.
end )
895 : secondaryDrill.
end / 2 + 1 )
896 : secondaryDrill.
end / 2
898 int layerOrdinal =
board->IsLayerEnabled( aLayer )
900 : aLayer ==
B_Cu ?
board->GetCopperLayerCount() - 1
905 if( layerOrdinal >= 0 && startOrdinal >= 0 && endOrdinal >= 0 )
907 if( startOrdinal > endOrdinal )
908 std::swap( startOrdinal, endOrdinal );
910 if( layerOrdinal >= startOrdinal && layerOrdinal <= endOrdinal )
920 int startOrdinal =
board->IsLayerEnabled( tertiaryDrill.
start )
922 : tertiaryDrill.
start / 2 + 1 )
923 : tertiaryDrill.
start / 2
925 int endOrdinal =
board->IsLayerEnabled( tertiaryDrill.
end )
927 : tertiaryDrill.
end / 2 + 1 )
928 : tertiaryDrill.
end / 2
930 int layerOrdinal =
board->IsLayerEnabled( aLayer )
932 : aLayer ==
B_Cu ?
board->GetCopperLayerCount() - 1
937 if( layerOrdinal >= 0 && startOrdinal >= 0 && endOrdinal >= 0 )
939 if( startOrdinal > endOrdinal )
940 std::swap( startOrdinal, endOrdinal );
942 if( layerOrdinal >= startOrdinal && layerOrdinal <= endOrdinal )
973 int pmDepth = frontPM.
depth;
976 if( pmDepth <= 0 && *frontPM.mode == PAD_DRILL_POST_MACHINING_MODE::COUNTERSINK && frontPM.angle > 0 )
978 double halfAngleRad = ( frontPM.
angle / 10.0 ) *
M_PI / 180.0 / 2.0;
979 pmDepth =
static_cast<int>( ( frontPM.
size / 2.0 ) / tan( halfAngleRad ) );
987 if( layerDist < pmDepth )
992 double halfAngleRad = ( frontPM.
angle / 10.0 ) *
M_PI / 180.0 / 2.0;
993 int diameterAtLayer = frontPM.
size -
static_cast<int>( 2.0 * layerDist * tan( halfAngleRad ) );
994 return std::max( 0, diameterAtLayer );
1011 int pmDepth = backPM.
depth;
1014 if( pmDepth <= 0 && *backPM.mode == PAD_DRILL_POST_MACHINING_MODE::COUNTERSINK && backPM.angle > 0 )
1016 double halfAngleRad = ( backPM.
angle / 10.0 ) *
M_PI / 180.0 / 2.0;
1017 pmDepth =
static_cast<int>( ( backPM.
size / 2.0 ) / tan( halfAngleRad ) );
1025 if( layerDist < pmDepth )
1030 double halfAngleRad = ( backPM.
angle / 10.0 ) *
M_PI / 180.0 / 2.0;
1031 int diameterAtLayer = backPM.
size -
static_cast<int>( 2.0 * layerDist * tan( halfAngleRad ) );
1032 return std::max( 0, diameterAtLayer );
1189 m_padStack.SetRoundRectRadius( aRadius, aLayer );
1195 m_padStack.SetRoundRectRadiusRatio( std::clamp( aRadiusScale, 0.0, 0.5 ), aLayer );
1204 "Set front radius only meaningful for normal padstacks" );
1206 m_padStack.SetRoundRectRadiusRatio( std::clamp( aRadiusScale, 0.0, 0.5 ),
F_Cu );
1214 const int minSize = std::min( size.
x, size.
y );
1215 const double newRatio = aRadius / double(
minSize );
1224 const int minSize = std::min( size.
x, size.
y );
1233 m_padStack.SetChamferRatio( aChamferScale, aLayer );
1256 std::shared_ptr<SHAPE_COMPOUND> effective_compound = std::make_shared<SHAPE_COMPOUND>();
1261 return effective_compound;
1265 effective_compound->AddShape( std::make_shared<SHAPE_NULL>() );
1266 return effective_compound;
1273 std::shared_ptr<SHAPE_COMPOUND> effective_compund = std::make_shared<SHAPE_COMPOUND>();
1287 return effective_compund;
1291 effective_compund->AddShape( std::make_shared<SHAPE_NULL>() );
1292 return effective_compund;
1307 wxString::Format( wxT(
"Missing shape in PAD::GetEffectiveShape for layer %s." ),
1308 magic_enum::enum_name( effectiveLayer ) ) );
1310 wxString::Format( wxT(
"Null shape in PAD::GetEffectiveShape for layer %s." ),
1311 magic_enum::enum_name( effectiveLayer ) ) );
1313 std::shared_ptr<SHAPE> shape = drawCache.
m_effectiveShapes.at( effectiveLayer );
1325 std::shared_ptr<SHAPE_COMPOUND> effective_compound = std::make_shared<SHAPE_COMPOUND>();
1326 effective_compound->AddShape( shape );
1328 return effective_compound;
1341 if( it !=
m_maskShapes.end() && it->second.first == aExpansion )
1342 return it->second.second;
1349 std::shared_ptr<SHAPE_COMPOUND> shape = std::make_shared<SHAPE_COMPOUND>();
1375 if( maxHoleSize >
getDrawCache().m_effectiveHoleShape->GetWidth() )
1395 m_drawCache = std::make_unique<PAD_DRAW_CACHE_DATA>();
1403 std::lock_guard<std::mutex> RAII_lock(
m_dataMutex );
1436 half_width = half_size.
x;
1440 half_width = std::min( half_size.
x, half_size.
y );
1441 half_len =
VECTOR2I( half_size.
x - half_width, half_size.
y - half_width );
1447 drawCache.
m_effectiveHoleShape = std::make_shared<SHAPE_SEGMENT>( pos - half_len, pos + half_len, half_width * 2 );
1468 auto add = [
this, aLayer](
SHAPE* aShape )
1480 switch( effectiveShape )
1487 if( size.
x == size.
y )
1494 int half_width = std::min( half_size.
x, half_size.
y );
1495 VECTOR2I half_len( half_size.
x - half_width, half_size.
y - half_width );
1497 add(
new SHAPE_SEGMENT( shapePos - half_len, shapePos + half_len, half_width * 2 ) );
1507 VECTOR2I half_size( size.
x / 2, size.
y / 2 );
1516 const int min_len =
pcbIUScale.mmToIU( 0.0001 );
1518 if( half_size.
x < min_len && half_size.
y < min_len )
1526 trap_delta =
m_padStack.TrapezoidDeltaSize( aLayer ) / 2;
1531 corners.
Append( -half_size.
x - trap_delta.
y, half_size.
y + trap_delta.
x );
1532 corners.
Append( half_size.
x + trap_delta.
y, half_size.
y - trap_delta.
x );
1533 corners.
Append( half_size.
x - trap_delta.
y, -half_size.
y + trap_delta.
x );
1534 corners.
Append( -half_size.
x + trap_delta.
y, -half_size.
y - trap_delta.
x );
1537 corners.
Move( shapePos );
1592 wxFAIL_MSG( wxT(
"PAD::buildEffectiveShapes: Unsupported pad shape: PAD_SHAPE::" )
1593 + wxString( std::string( magic_enum::enum_name( effectiveShape ) ) ) );
1599 for(
const std::shared_ptr<PCB_SHAPE>& primitive :
m_padStack.Primitives( aLayer ) )
1601 if( !primitive->IsProxyItem() )
1603 for(
SHAPE* shape : primitive->MakeEffectiveShapes() )
1606 shape->Move( shapePos );
1619 std::lock_guard<std::mutex> RAII_lock(
m_dataMutex );
1635 std::shared_ptr<SHAPE_POLY_SET>& effectivePolygon =
1638 effectivePolygon = std::make_shared<SHAPE_POLY_SET>();
1642 if( doBoundingRadius )
1649 std::shared_ptr<SHAPE_POLY_SET>& effectivePolygon =
1652 for(
int cnt = 0; cnt < effectivePolygon->OutlineCount(); ++cnt )
1656 for(
int ii = 0; ii < poly.
PointCount(); ++ii )
1697 switch( aAttribute )
1710 if( copperLayers.count() > 1 )
1712 layerMask &=
~LSET::AllCuMask();
1714 if( copperLayers.test(
B_Cu ) )
1717 layerMask.
set( copperLayers.
Seq().front() );
1752 if( !wasRoundable && isRoundable )
1787 m_padStack.SetOrientation( aAngle + parentFP->GetOrientation() );
1818 VECTOR2I libCentre = fp->GetTransform().InverseApply( aCentre );
1824 MIRROR( newPos, aCentre, aFlipDirection );
1837 auto mirrorBitFlags = [](
int& aBitfield,
int a,
int b )
1839 bool temp = aBitfield & a;
1893 for( std::shared_ptr<PCB_SHAPE>& primitive :
m_padStack.Primitives( aLayer ) )
1897 primitive->SetParent(
this);
1898 primitive->Flip(
VECTOR2I( 0, 0 ), aFlipDirection );
1911 if( loc_offset.
x == 0 && loc_offset.
y == 0 )
1916 return pos + loc_offset;
1922 wxCHECK( aLhs && aRhs, );
1924 LSET uniqueLayerUnion;
1929 uniqueLayerUnion.
set( layer );
1935 uniqueLayerUnion.
set( layer );
1938 std::map<PCB_LAYER_ID, std::pair<VECTOR2I, VECTOR2I>> positions;
1951 positions[layer].first = rhsShapePos - lhsOffset;
1952 positions[layer].second = lhsShapePos - rhsOffset;
1975 bool hasAnnularRing =
true;
1986 hasAnnularRing =
false;
1996 hasAnnularRing =
false;
2008 if( !hasAnnularRing )
2018 if(
m_padStack.Clearance().has_value() && aSource )
2019 *aSource =
_(
"pad" );
2031 return parentFootprint->GetClearanceOverrides( aSource );
2033 return std::optional<int>();
2045 auto seq = aLayers.
Seq();
2082 std::optional<int> margin;
2097 margin =
m_padStack.SolderMaskMargin( aLayer );
2099 if( !margin.has_value() )
2102 margin = parentFootprint->GetLocalSolderMaskMargin();
2105 if( !margin.has_value() )
2108 margin = brd->GetDesignSettings().m_SolderMaskExpansion;
2112 int marginValue = margin.value_or( 0 );
2117 if( marginValue < 0 )
2121 if( marginValue < minsize )
2122 marginValue = minsize;
2144 std::optional<int> margin;
2145 std::optional<double> mratio;
2147 std::shared_ptr<DRC_ENGINE> drcEngine;
2152 bool hasAbsRules = drcEngine
2154 bool hasRelRules = drcEngine
2157 if( hasAbsRules || hasRelRules )
2180 if( !margin.has_value() )
2182 margin =
m_padStack.SolderPasteMargin( aLayer );
2184 if( !margin.has_value() )
2187 margin = parentFootprint->GetLocalSolderPasteMargin();
2190 if( !margin.has_value() )
2193 margin = brd->GetDesignSettings().m_SolderPasteMargin;
2197 if( !mratio.has_value() )
2199 mratio =
m_padStack.SolderPasteMarginRatio( aLayer );
2201 if( !mratio.has_value() )
2204 mratio = parentFootprint->GetLocalSolderPasteMarginRatio();
2207 if( !mratio.has_value() )
2210 mratio = brd->GetDesignSettings().m_SolderPasteMarginRatio;
2218 pad_margin.
x = margin.value_or( 0 ) +
KiROUND( padSize.
x * mratio.value_or( 0 ) );
2219 pad_margin.
y = margin.value_or( 0 ) +
KiROUND( padSize.
y * mratio.value_or( 0 ) );
2224 if( pad_margin.
x < -padSize.
x / 2 )
2225 pad_margin.
x = -padSize.
x / 2;
2227 if( pad_margin.
y < -padSize.
y / 2 )
2228 pad_margin.
y = -padSize.
y / 2;
2242 *aSource =
_(
"pad" );
2248 connection = parentFootprint->GetZoneConnectionOverrides( aSource );
2257 if(
m_padStack.ThermalSpokeWidth().has_value() && aSource )
2258 *aSource =
_(
"pad" );
2260 return m_padStack.ThermalSpokeWidth().value_or( 0 );
2266 if(
m_padStack.ThermalGap().has_value() && aSource )
2267 *aSource =
_(
"pad" );
2280 if( parentFootprint )
2281 aList.emplace_back(
_(
"Footprint" ), parentFootprint->
GetReference() );
2284 aList.emplace_back(
_(
"Pad" ),
m_number );
2290 aList.emplace_back(
_(
"Pin Type" ),
GetPinType() );
2298 const wxString& chainName = netInfo->GetNetChain();
2300 if( !chainName.IsEmpty() )
2304 aList.emplace_back(
_(
"Resolved Netclass" ),
2308 aList.emplace_back(
_(
"Status" ),
_(
"Locked" ) );
2320 double area = poly->Area();
2345 std::set<bool> circles;
2346 std::set<PAD_SHAPE> shapes;
2347 std::set<int> widths;
2348 std::set<int> heights;
2357 shapes.insert( shape );
2358 widths.insert( size.
x );
2359 heights.insert( size.
y );
2362 aList.emplace_back( shapes.size() == 1 ?
ShowPadShape( *shapes.begin() ) :
_(
"(mixed shapes)" ), props );
2364 if( circles.size() == 1 && *circles.begin() )
2366 aList.emplace_back(
_(
"Diameter" ), widths.size() == 1 ? aFrame->
MessageTextFromValue( *widths.begin() )
2371 aList.emplace_back(
_(
"Width" ), widths.size() == 1 ? aFrame->
MessageTextFromValue( *widths.begin() )
2373 aList.emplace_back(
_(
"Height" ), heights.size() == 1 ? aFrame->
MessageTextFromValue( *heights.begin() )
2381 if( !fp_orient.
IsZero() )
2386 aList.emplace_back(
_(
"Rotation" ), msg );
2393 if( drill.
x > 0 || drill.
y > 0 )
2397 aList.emplace_back(
_(
"Hole" ),
2398 wxString::Format( wxT(
"%s" ),
2403 aList.emplace_back(
_(
"Hole X / Y" ),
2404 wxString::Format( wxT(
"%s / %s" ),
2415 aList.emplace_back( wxString::Format(
_(
"Min Clearance: %s" ),
2417 wxString::Format(
_(
"(from %s)" ),
2422 aList.emplace_back( wxT(
"UUID" ),
m_Uuid.AsString() );
2452 bool contains =
false;
2472 BOX2I arect = aRect;
2499 int count = poly->TotalVertices();
2501 for(
int ii = 0; ii < count; ii++ )
2503 VECTOR2I vertex = poly->CVertex( ii );
2504 VECTOR2I vertexNext = poly->CVertex( ( ii + 1 ) % count );
2555 if( ( diff =
static_cast<int>( aPadRef->
m_attribute ) -
static_cast<int>( aPadCmp->
m_attribute ) ) != 0 )
2591 double localSx, localSy;
2607 for(
const std::shared_ptr<PCB_SHAPE>& prim :
Padstack().Primitives( aLayer ) )
2620 parentOrient = fp->GetOrientation();
2638 default:
return wxT(
"???" );
2660 default:
return wxT(
"???" );
2673 default:
return wxT(
"???" );
2689 return wxString::Format(
_(
"NPTH pad of %s" ), parentFP->
GetReference() );
2691 return _(
"NPTH pad" );
2699 return wxString::Format(
_(
"Pad %s of %s on %s" ),
2706 return wxString::Format(
_(
"Pad on %s" ),
2714 return wxString::Format(
_(
"PTH pad %s of %s" ),
2720 return _(
"PTH pad" );
2730 return wxString::Format(
_(
"Pad %s %s of %s on %s" ),
2738 return wxString::Format(
_(
"Pad %s on %s" ),
2747 return wxString::Format(
_(
"PTH pad %s %s of %s" ),
2754 return wxString::Format(
_(
"PTH pad %s" ),
2770 PAD* cloned =
new PAD( *
this );
2777 primitive->SetParent( cloned );
2786 std::vector<int> layers;
2787 layers.reserve( 64 );
2795 for(
PCB_LAYER_ID mapLayer : drillBoard->DrillSymbolLayers().Seq() )
2818 cuLayers &=
board->GetEnabledLayers();
2820 if( cuLayers.count() > 1 )
2855 else if( cuLayers.count() == 1 )
2872 layers.push_back( each_layer );
2907 if( onFront && !onBack && !frVis )
2910 if( onBack && !onFront && !bkVis )
2913 if( onFront && onBack && !frVis && !bkVis )
2922 if( !drawnRegardless )
2941 LSET visiblePhysical =
board->GetVisibleLayers();
2942 visiblePhysical &=
board->GetEnabledLayers();
2945 if( !visiblePhysical.any() )
2958 LSET visible =
board->GetVisibleLayers();
2959 visible &=
board->GetEnabledLayers();
2973 int64_t minSide = std::min( padSize.
x, padSize.
y );
2985 int solderMaskMargin = 0;
2993 solderPasteMargin.
x = std::max( solderPasteMargin.
x, layerMargin.
x );
2994 solderPasteMargin.
y = std::max( solderPasteMargin.
y, layerMargin.
y );
3003 if( cfg && cfg->m_Display.m_PadClearance &&
GetBoard() )
3008 int xMargin = std::max( solderMaskMargin, solderPasteMargin.
x ) +
clearance;
3009 int yMargin = std::max( solderMaskMargin, solderPasteMargin.
y ) +
clearance;
3099 std::swap( *
this, *
static_cast<PAD*
>( aImage ) );
3108 if( !drillsize.
x || !drillsize.
y )
3114 aError, aErrorLoc );
3137 int aMaxError,
ERROR_LOC aErrorLoc,
bool ignoreLineWidth )
const
3140 wxT(
"UNDEFINED_LAYER is no longer allowed for PAD::TransformShapeToPolygon" ) );
3145 const int pad_min_seg_per_circle_count = 16;
3147 int dx = padSize.
x / 2;
3148 int dy = padSize.
y / 2;
3161 pad_min_seg_per_circle_count );
3165 int half_width = std::min( dx, dy );
3171 ( half_width + aClearance ) * 2, aMaxError, aErrorLoc,
3172 pad_min_seg_per_circle_count );
3187 aBuffer.
Append( outline );
3200 aClearance, aMaxError, aErrorLoc );
3201 aBuffer.
Append( outline );
3215 aClearance += aMaxError;
3220 else if( aClearance < 0 )
3230 aBuffer.
Append( outline );
3235 wxFAIL_MSG( wxT(
"PAD::TransformShapeToPolygon no implementation for " )
3236 + wxString( std::string( magic_enum::enum_name( shape ) ) ) );
3280 [&](
PCB_SHAPE* aShape ) -> std::vector<PCB_SHAPE*>
3282 std::vector<PCB_SHAPE*> matching;
3298 if( aShape->GetLayer() != other->
GetLayer() )
3302 if( aShape->Compare( other ) == 0 )
3303 matching.push_back( other );
3309 std::vector<PCB_SHAPE*> mergedShapes;
3335 existingOutline.
NearestPoints( &originSeg, nearestPoint, dummyPoint );
3336 int radius = ( nearestPoint - origin ).EuclideanNorm();
3356 mergedShapes.push_back( fpShape );
3364 group->RemoveItem( fpShape );
3381 for(
PCB_SHAPE* other : findMatching( fpShape ) )
3384 mergedShapes.push_back( other );
3398 recombine( aLayer, aLayer );
3408 return mergedShapes;
3420 const PAD& other =
static_cast<const PAD&
>( aBoardItem );
3422 return *
this == other;
3449 const PAD& other =
static_cast<const PAD&
>( aOther );
3451 double similarity = 1.0;
3470 poly_no_hole.
Append( aPoly );
3477 for(
int ii = 0; ii < poly_no_hole.
OutlineCount(); ++ii )
3510 if( aPrimitivesList.size() )
3520 for(
const std::shared_ptr<PCB_SHAPE>& prim : aPrimitivesList )
3546 m_padStack.AddPrimitive( aPrimitive, aLayer );
3584 SHAPE_RECT rect( -padSize.
x / 2, -padSize.
y / 2, padSize.
x, padSize.
y );
3597 for(
const std::shared_ptr<PCB_SHAPE>& primitive :
m_padStack.Primitives( aLayer ) )
3599 if( !primitive->IsProxyItem() )
3659 if( pmMap.
Choices().GetCount() == 0 )
3672 if( bdMap.
Choices().GetCount() == 0 )
3684 if( zcMap.
Choices().GetCount() == 0 )
3716 if(
PAD*
pad =
dynamic_cast<PAD*
>( aItem ) )
3722 auto padCanHaveHole =
3725 if(
PAD*
pad =
dynamic_cast<PAD*
>( aItem ) )
3731 auto hasNormalPadstack =
3734 if(
PAD*
pad =
dynamic_cast<PAD*
>( aItem ) )
3745 const wxString groupPad =
_HKI(
"Pad Properties" );
3746 const wxString groupPostMachining =
_HKI(
"Post-machining Properties" );
3747 const wxString groupBackdrill =
_HKI(
"Backdrill Properties" );
3774 wxPGChoices choices;
3795 if(
PAD*
pad =
dynamic_cast<PAD*
>( aItem ) )
3808 const auto hasRoundRadius =
3811 if(
PAD*
pad =
dynamic_cast<PAD*
>( aItem ) )
3851 if(
PAD*
pad =
dynamic_cast<PAD*
>( aItem ) )
3859 groupPostMachining )
3863 if(
PAD*
pad =
dynamic_cast<PAD*
>( aItem ) )
3871 groupPostMachining )
3876 if(
PAD*
pad =
dynamic_cast<PAD*
>( aItem ) )
3881 std::optional<PAD_DRILL_POST_MACHINING_MODE> mode =
pad->GetFrontPostMachining();
3882 return mode.has_value()
3892 groupPostMachining )
3897 if(
PAD*
pad =
dynamic_cast<PAD*
>( aItem ) )
3902 std::optional<PAD_DRILL_POST_MACHINING_MODE> mode =
pad->GetFrontPostMachining();
3911 groupPostMachining )
3916 if(
PAD*
pad =
dynamic_cast<PAD*
>( aItem ) )
3921 std::optional<PAD_DRILL_POST_MACHINING_MODE> mode =
pad->GetFrontPostMachining();
3930 groupPostMachining )
3934 if(
PAD*
pad =
dynamic_cast<PAD*
>( aItem ) )
3942 groupPostMachining )
3947 if(
PAD*
pad =
dynamic_cast<PAD*
>( aItem ) )
3952 std::optional<PAD_DRILL_POST_MACHINING_MODE> mode =
pad->GetBackPostMachining();
3953 return mode.has_value()
3963 groupPostMachining )
3968 if(
PAD*
pad =
dynamic_cast<PAD*
>( aItem ) )
3973 std::optional<PAD_DRILL_POST_MACHINING_MODE> mode =
pad->GetBackPostMachining();
3982 groupPostMachining )
3987 if(
PAD*
pad =
dynamic_cast<PAD*
>( aItem ) )
3992 std::optional<PAD_DRILL_POST_MACHINING_MODE> mode =
pad->GetBackPostMachining();
4009 if(
PAD*
pad =
dynamic_cast<PAD*
>( aItem ) )
4028 if(
PAD*
pad =
dynamic_cast<PAD*
>( aItem ) )
4047 if(
PAD*
pad =
dynamic_cast<PAD*
>( aItem ) )
4065 if(
PAD*
pad =
dynamic_cast<PAD*
>( aItem ) )
4096 const wxString groupOverrides =
_HKI(
"Overrides" );
KICOMMON_API types::KiCadObjectType ToProtoEnum(KICAD_T aValue)
KICOMMON_API KICAD_T FromProtoEnum(types::KiCadObjectType aValue)
ERROR_LOC
When approximating an arc or circle, should the error be placed on the outside or inside of the curve...
constexpr EDA_IU_SCALE pcbIUScale
constexpr int ARC_LOW_DEF
BITMAPS
A list of all bitmap identifiers.
ZONE_LAYER_OVERRIDE
Conditionally flashed vias and pads that interact with zones of different priority can be very squirr...
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
BASE_SET & set(size_t pos)
A base class derived from BOARD_ITEM for items that can be connected and have a net,...
wxString GetNetnameMsg() const
virtual NETCLASS * GetEffectiveNetClass() const
Return the NETCLASS for this item.
virtual bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
wxString GetNetname() const
BOARD_CONNECTED_ITEM(BOARD_ITEM *aParent, KICAD_T idtype)
void PackNet(kiapi::board::types::Net *aProto) const
TEARDROP_PARAMETERS m_teardropParams
Not all BOARD_CONNECTED_ITEMs support teardrops, but we want those that do to share a single section ...
void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
NETINFO_ITEM * GetNet() const
Return NETINFO_ITEM object for a given item.
const wxString & GetShortNetname() const
virtual int GetOwnClearance(PCB_LAYER_ID aLayer, wxString *aSource=nullptr) const
Return an item's "own" clearance in internal units.
void UnpackNet(const kiapi::board::types::Net &aProto)
Assigns a net to this item from an API message.
TEARDROP_PARAMETERS & GetTeardropParams()
void SetTeardropsEnabled(bool aEnable)
std::shared_ptr< DRC_ENGINE > m_DRCEngine
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
BOARD_ITEM(BOARD_ITEM *aParent, KICAD_T idtype, PCB_LAYER_ID aLayer=F_Cu)
void SetUuidDirect(const KIID &aUuid)
Raw UUID assignment.
void SetLocked(bool aLocked) override
PCB_LAYER_ID GetFlippedLayer(PCB_LAYER_ID aLayer) const
Return the layer paired with aLayer on the opposite side of the board.
static double polygonArea(SHAPE_POLY_SET &aPolySet)
Area of aPolySet with every contour closed first, holes subtracted.
bool IsLocked() const override
virtual const BOARD * GetBoard() const
Return the BOARD in which this BOARD_ITEM resides, or NULL if none.
FOOTPRINT * GetParentFootprint() const
virtual wxString LayerMaskDescribe() const
Return a string (to be shown to the user) describing a layer mask.
BOARD_ITEM & operator=(const BOARD_ITEM &aOther)
BOARD_ITEM_CONTAINER * GetParent() const
virtual int BoardCopperLayerCount() const
Return the total number of copper layers for the board that this item resides on.
Manage layers needed to make a physical board.
int GetLayerDistance(PCB_LAYER_ID aFirstLayer, PCB_LAYER_ID aSecondLayer) const
Calculate the distance (height) between the two given copper layers.
Information pertinent to a Pcbnew printed circuit board.
int GetMaxClearanceValue() const
Returns the maximum clearance value for any object on the board.
BOX2I ExpandBoundingBoxForDrillSymbols(const BOX2I &aBoundingBox) const
Include every displaced copy of a hole-owned drill symbol in its view bounds.
BOARD_DESIGN_SETTINGS & GetDesignSettings()
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
constexpr BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
static constexpr BOX2< VECTOR2I > ByCenter(const VECTOR2I &aCenter, const SizeVec &aSize)
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr bool Contains(const Vec &aPoint) const
constexpr const Vec & GetOrigin() const
constexpr const SizeVec & GetSize() const
constexpr bool Intersects(const BOX2< Vec > &aRect) const
Design Rule Checker object that performs all the DRC tests.
DRC_CONSTRAINT EvalRules(DRC_CONSTRAINT_T aConstraintType, const BOARD_ITEM *a, const BOARD_ITEM *b, PCB_LAYER_ID aLayer, REPORTER *aReporter=nullptr)
EDA_ANGLE Normalized() const
The base class for create windows for drawing purpose.
A set of EDA_ITEMs (i.e., without duplicates).
KICAD_T Type() const
Returns the type of object.
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
virtual void SetParent(EDA_ITEM *aParent)
EDA_ITEM * m_parent
Owner.
EDA_ITEM_FLAGS GetFlags() const
EDA_ITEM(EDA_ITEM *parent, KICAD_T idType, bool isSCH_ITEM=false, bool isBOARD_ITEM=false)
const VECTOR2I & GetBezierC2() const
SHAPE_POLY_SET & GetPolyShape()
virtual void SetFilled(bool aFlag)
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
const VECTOR2I & GetBezierC1() const
void SetPolyPoints(const std::vector< VECTOR2I > &aPoints)
void SetFillMode(FILL_T aFill)
VECTOR2I GetArcMid() const
ENUM_MAP & Map(T aValue, const wxString &aName)
static ENUM_MAP< T > & Instance()
ENUM_MAP & Undefined(T aValue)
Class that other classes need to inherit from, in order to be inspectable.
Contains methods for drawing PCB-specific items.
virtual PCB_RENDER_SETTINGS * GetSettings() override
Return a pointer to current settings that are going to be used when drawing items.
PCB specific render settings.
const std::set< int > & GetHighlightNetCodes() const
Return the netcode of currently highlighted net.
PCB_LAYER_ID GetPrimaryHighContrastLayer() const
Return the board layer which is in high-contrast mode.
bool IsHighlightEnabled() const
Return current highlight setting.
bool GetHighContrast() const
static double lodScaleForThreshold(const KIGFX::VIEW *aView, int aWhatIu, int aThresholdIu)
Get the scale at which aWhatIu would be drawn at the same size as aThresholdIu on screen.
static constexpr double LOD_HIDE
Return this constant from ViewGetLOD() to hide the item unconditionally.
static constexpr double LOD_SHOW
Return this constant from ViewGetLOD() to show the item unconditionally.
Hold a (potentially large) number of VIEW_ITEMs and renders them on a graphics device provided by the...
bool IsLayerVisibleCached(int aLayer) const
bool IsLayerVisible(int aLayer) const
Return information about visibility of a particular layer.
PAINTER * GetPainter() const
Return the painter object used by the view for drawing VIEW_ITEM objects.
LSET is a set of PCB_LAYER_IDs.
static const LSET & FrontMask()
Return a mask holding all technical layers and the external CU layer on front side.
static const LSET & AllCuMask()
return AllCuMask( MAX_CU_LAYERS );
static const LSET & FrontBoardTechMask()
Return a mask holding technical layers used in a board fabrication (no CU layer) on front side.
static const LSET & BackMask()
Return a mask holding all technical layers and the external CU layer on back side.
LSEQ Seq(const LSEQ &aSequence) const
Return an LSEQ from the union of this LSET and a desired sequence.
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
static const LSET & PhysicalLayersMask()
Return a mask holding all layers which are physically realized.
static const LSET & BackBoardTechMask()
Return a mask holding technical layers used in a board fabrication (no CU layer) on Back side.
Handle the data for a net.
static const int UNCONNECTED
Constant that holds the "unconnected net" number (typically 0) all items "connected" to this net are ...
double Similarity(const PADSTACK &aOther) const
Return a measure of how likely the other object is to represent the same object.
int GetMaxHoleSize() const
void ForEachUniqueLayer(const std::function< void(PCB_LAYER_ID)> &aMethod) const
Runs the given callable for each active unique copper layer in this padstack, meaning F_Cu for MODE::...
PCB_LAYER_ID EffectiveLayerFor(PCB_LAYER_ID aLayer) const
Determines which geometry layer should be used for the given input layer.
static int Compare(const PADSTACK *aPadstackRef, const PADSTACK *aPadstackCmp)
Compare two padstacks and return 0 if they are equal.
@ NORMAL
Shape is the same on all layers.
void SetOrientation(const EDA_ANGLE &aAngle)
static constexpr PCB_LAYER_ID ALL_LAYERS
! The layer identifier to use for the single defintion on normal padstacks
static constexpr PCB_LAYER_ID TEMP_ALL_LAYERS
! Temporary layer identifier to identify code that is not padstack-aware
std::vector< std::shared_ptr< PCB_SHAPE > > & Primitives(PCB_LAYER_ID aLayer)
VECTOR2I GetPrimaryDrillSize() const
void SetFrontPostMachiningSize(int aSize)
int GetBackPostMachiningSize() const
void SetAnchorPadShape(PCB_LAYER_ID aLayer, PAD_SHAPE aShape)
Set the shape of the anchor pad for custom shaped pads.
bool IsAperturePad() const
void SetAttribute(PAD_ATTRIB aAttribute)
int GetOwnClearance(PCB_LAYER_ID aLayer, wxString *aSource=nullptr) const override
Return the pad's "own" clearance in internal units.
virtual void swapData(BOARD_ITEM *aImage) override
PAD_PROP GetProperty() const
void SetFrontPostMachiningAngle(int aAngle)
void OnFootprintTransformed() override
Hook for items inside a footprint to refresh after the FP transform changes (translate,...
void SetPrimaryDrillFilledFlag(bool aFilled)
void Serialize(google::protobuf::Any &aContainer) const override
Serializes this object to the given Any message.
double GetFrontRoundRectRadiusRatio() const
static wxString ShowPadShape(PAD_SHAPE aShape)
std::optional< int > GetClearanceOverrides(wxString *aSource) const override
Return any clearance overrides set in the "classic" (ie: pre-rule) system.
void SetPinType(const wxString &aType)
Set the pad electrical type.
LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
const ZONE_LAYER_OVERRIDE & GetZoneLayerOverride(PCB_LAYER_ID aLayer) const
void MergePrimitivesAsPolygon(PCB_LAYER_ID aLayer, SHAPE_POLY_SET *aMergedPolygon, ERROR_LOC aErrorLoc=ERROR_INSIDE) const
Merge all basic shapes to a SHAPE_POLY_SET.
int GetRoundRectCornerRadius(PCB_LAYER_ID aLayer) const
void rebakePrimitiveToFootprint(PCB_SHAPE *aPrimitive) const
bool FlashLayer(int aLayer, bool aOnlyCheckIfPermitted=false) const
Check to see whether the pad should be flashed on the specific layer.
void SetLocalThermalGapOverride(const std::optional< int > &aOverride)
std::shared_ptr< SHAPE_SEGMENT > GetEffectiveHoleShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, DRC_CONSTRAINT_T aUsage=NULL_CONSTRAINT) const override
Return a SHAPE_SEGMENT object representing the pad's hole.
double GetCoverageArea(int aTextMargin) const override
Return the board area this item covers, used to rank candidates under the cursor so a click on a smal...
void SetPrimaryDrillSize(const VECTOR2I &aSize)
std::mutex m_maskShapeMutex
void GetMsgPanelInfo(EDA_DRAW_FRAME *aFrame, std::vector< MSG_PANEL_ITEM > &aList) override
Populate aList of MSG_PANEL_ITEM objects with it's internal state for display purposes.
const BOX2I GetBoundingBox() const override
The bounding box is cached, so this will be efficient most of the time.
void SetTertiaryDrillStartLayer(PCB_LAYER_ID aLayer)
bool IsOnLayer(PCB_LAYER_ID aLayer) const override
Test to see if this object is on the given layer.
void AddPrimitivePoly(PCB_LAYER_ID aLayer, const SHAPE_POLY_SET &aPoly, int aThickness, bool aFilled)
Has meaning only for custom shape pads.
std::optional< double > GetLocalSolderPasteMarginRatio() const
void SetFrontPostMachiningDepth(int aDepth)
void SetFrontShape(PAD_SHAPE aShape)
void SetTopBackdrillLayer(PCB_LAYER_ID aLayer)
const wxString & GetPinType() const
void SetZoneLayerOverride(PCB_LAYER_ID aLayer, ZONE_LAYER_OVERRIDE aOverride)
void SetSecondaryDrillSize(const VECTOR2I &aSize)
void SetPrimaryDrillFilled(const std::optional< bool > &aFilled)
PAD_ATTRIB GetAttribute() const
static LSET PTHMask()
layer set for a through hole pad
int GetDrillSizeYProp() const
static int Compare(const PAD *aPadRef, const PAD *aPadCmp)
Compare two pads and return 0 if they are equal.
const wxString & GetPinFunction() const
bool CanHaveNumber() const
Indicates whether or not the pad can have a number.
void SetThermalSpokeAngle(const EDA_ANGLE &aAngle)
The orientation of the thermal spokes.
std::optional< int > GetBottomBackdrillSize() const
bool Deserialize(const google::protobuf::Any &aContainer) override
Deserializes the given protobuf message into this object.
const wxString & GetNumber() const
double ViewGetLOD(int aLayer, const KIGFX::VIEW *aView) const override
Return the level of detail (LOD) of the item.
void SetSecondaryDrillSizeX(int aX)
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aMaxError, ERROR_LOC aErrorLoc=ERROR_INSIDE, bool aIgnoreLineWidth=false) const override
Convert the pad shape to a closed polygon.
void SetFrontRoundRectRadiusRatio(double aRadiusScale)
void SetPrimaryDrillSizeX(int aX)
PAD_DRAW_CACHE_DATA & getDrawCache() const
void BuildEffectiveShapes() const
Rebuild the effective shape cache (and bounding box and radius) for the pad and clears the dirty bit.
void SetPrimaryDrillEndLayer(PCB_LAYER_ID aLayer)
void SetSimElectricalType(PAD_SIM_ELECTRICAL_TYPE aType)
PAD_SHAPE GetFrontShape() const
void SetFrontPostMachiningMode(PAD_DRILL_POST_MACHINING_MODE aMode)
void CopyFrom(const BOARD_ITEM *aOther) override
void SetLocalSolderPasteMarginRatio(std::optional< double > aRatio)
PAD & operator=(const PAD &aOther)
void SetLocalThermalSpokeWidthOverride(std::optional< int > aWidth)
Set the width of the thermal spokes connecting the pad to a zone.
void SetShape(PCB_LAYER_ID aLayer, PAD_SHAPE aShape)
Set the new shape of this pad.
void SetSecondaryDrillStartLayer(PCB_LAYER_ID aLayer)
bool IsLocked() const override
wxString ShowLegacyPadShape(PCB_LAYER_ID aLayer) const
An older version still used by place file writer.
void SetSizeXProp(int aX)
void OnFootprintRescaled(double aRatioX, double aRatioY, double aLinearFactor, const VECTOR2I &aAnchor, const EDA_ANGLE &aParentRotate) override
Apply a parent footprint scale to this item.
VECTOR2I GetPosition() const override
void SetProperty(PAD_PROP aProperty)
void SetThermalSpokeAngleDegrees(double aAngle)
void SetPrimaryDrillSizeY(int aY)
EDA_ANGLE GetThermalSpokeAngle() const
std::map< PCB_LAYER_ID, ZONE_LAYER_OVERRIDE > m_zoneLayerOverrides
void Flip(const VECTOR2I &VECTOR2I, FLIP_DIRECTION aFlipDirection) override
Flip this object, i.e.
int GetDrillSizeXProp() const
void SetBackPostMachiningSize(int aSize)
std::vector< PCB_SHAPE * > Recombine(bool aIsDryRun, int aMaxError)
Recombines the pad with other graphical shapes in the footprint.
PCB_LAYER_ID GetPrincipalLayer() const
void ClearTertiaryDrillSize()
PAD_DRILL_SHAPE GetTertiaryDrillShape() const
static LSET UnplatedHoleMask()
layer set for a mechanical unplated through hole pad
void SetBottomBackdrillLayer(PCB_LAYER_ID aLayer)
EDA_ITEM * Clone() const override
Create a duplicate of this item with linked list members set to NULL.
void SetTertiaryDrillShape(PAD_DRILL_SHAPE aShape)
VECTOR2I GetOffset(PCB_LAYER_ID aLayer) const
double GetOrientationDegrees() const
void SetBackdrillMode(BACKDRILL_MODE aMode)
VECTOR2I GetDrillSize() const
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
int GetBackPostMachiningAngle() const
void SetPadToDieDelay(int aDelay)
void FlipPrimitives(FLIP_DIRECTION aFlipDirection)
Flip (mirror) the primitives left to right or top to bottom, around the anchor position in custom pad...
bool IsNoConnectPad() const
int GetFrontPostMachiningSize() const
void SetTertiaryDrillSizeX(int aX)
void DeletePrimitivesList(PCB_LAYER_ID aLayer=UNDEFINED_LAYER)
Clear the basic shapes list.
void SetUnconnectedLayerMode(UNCONNECTED_LAYER_MODE aMode)
PAD_SHAPE GetShape(PCB_LAYER_ID aLayer) const
void SetNumber(const wxString &aNumber)
Set the pad number (note that it can be alphanumeric, such as the array reference "AA12").
BACKDRILL_MODE GetBackdrillMode() const
void SetTertiaryDrillSize(const VECTOR2I &aSize)
void SetFrontRoundRectRadiusSize(int aRadius)
wxString ShowPadAttr() const
void SetSecondaryDrillEndLayer(PCB_LAYER_ID aLayer)
void AddPrimitive(PCB_LAYER_ID aLayer, PCB_SHAPE *aPrimitive)
Add item to the custom shape primitives list.
int GetFrontPostMachiningDepth() const
void SetDrillShape(PAD_DRILL_SHAPE aShape)
int m_effectiveBoundingRadius
void SetDrillSizeXProp(int aX)
void SetLocalSolderMaskMargin(std::optional< int > aMargin)
void SetBackPostMachiningMode(PAD_DRILL_POST_MACHINING_MODE aMode)
void SetOffset(PCB_LAYER_ID aLayer, const VECTOR2I &aOffset)
void SetCustomShapeInZoneOpt(CUSTOM_SHAPE_ZONE_MODE aOption)
Set the option for the custom pad shape to use as clearance area in copper zones.
void SetLocalZoneConnection(ZONE_CONNECTION aType)
void SetChamferRectRatio(PCB_LAYER_ID aLayer, double aChamferScale)
Has meaning only for chamfered rectangular pads.
void SetPrimaryDrillCappedFlag(bool aCapped)
int GetSolderMaskExpansion(PCB_LAYER_ID aLayer) const
VECTOR2I GetSize(PCB_LAYER_ID aLayer) const
int GetPadToDieDelay() const
std::optional< int > GetLocalClearance() const override
Return any local clearances set in the "classic" (ie: pre-rule) system.
void ImportSettingsFrom(const PAD &aMasterPad)
Import the pad settings from aMasterPad.
double Similarity(const BOARD_ITEM &aOther) const override
Return a measure of how likely the other object is to represent the same object.
std::unique_ptr< PAD_DRAW_CACHE_DATA > m_drawCache
bool IsOnCopperLayer() const override
void SetTertiaryDrillEndLayer(PCB_LAYER_ID aLayer)
void SetPadstack(const PADSTACK &aPadstack)
void SetPosition(const VECTOR2I &aPos) override
const SHAPE_COMPOUND & buildEffectiveShape(PCB_LAYER_ID aLayer) const
void SetPrimaryDrillShape(PAD_DRILL_SHAPE aShape)
const PADSTACK & Padstack() const
PAD_DRILL_SHAPE GetSecondaryDrillShape() const
void BuildEffectivePolygon(ERROR_LOC aErrorLoc=ERROR_INSIDE) const
static LSET ConnSMDMask()
layer set for a SMD pad on Front layer used for edge board connectors
PAD_DRILL_POST_MACHINING_MODE GetBackPostMachiningMode() const
int GetFrontPostMachiningAngle() const
void SetLibOffset(PCB_LAYER_ID aLayer, const VECTOR2I &aOffset)
PAD_DRILL_POST_MACHINING_MODE GetFrontPostMachiningMode() const
bool IsNPTHWithNoCopper() const
void SetLibSize(PCB_LAYER_ID aLayer, const VECTOR2I &aSize)
EDA_ANGLE GetOrientation() const
Return the rotation angle of the pad.
void SetSize(PCB_LAYER_ID aLayer, const VECTOR2I &aSize)
PAD_DRILL_SHAPE GetDrillShape() const
void SetSecondaryDrillShape(PAD_DRILL_SHAPE aShape)
void ReplacePrimitives(PCB_LAYER_ID aLayer, const std::vector< std::shared_ptr< PCB_SHAPE > > &aPrimitivesList)
Clear the current custom shape primitives list and import a new list.
int GetChamferPositions(PCB_LAYER_ID aLayer) const
static LSET ApertureMask()
layer set for an aperture pad
virtual const BOX2I ViewBBox() const override
Return the bounding box of the item covering all its layers.
UNCONNECTED_LAYER_MODE GetUnconnectedLayerMode() const
void SetRoundRectCornerRadius(PCB_LAYER_ID aLayer, double aRadius)
void SetDrillSizeYProp(int aY)
static LSET SMDMask()
layer set for a SMD pad on Front layer
std::optional< int > GetLocalSolderPasteMargin() const
int GetFrontRoundRectRadiusSize() const
const std::shared_ptr< SHAPE_POLY_SET > & GetEffectivePolygon(PCB_LAYER_ID aLayer, ERROR_LOC aErrorLoc=ERROR_INSIDE) const
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT, DRC_CONSTRAINT_T aUsage=NULL_CONSTRAINT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
int GetBackPostMachiningDepth() const
PAD_SIM_ELECTRICAL_TYPE GetSimElectricalType() const
std::optional< int > GetLocalSolderMaskMargin() const
void SetLocalSolderPasteMargin(std::optional< int > aMargin)
std::optional< int > GetLocalThermalGapOverride() const
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
void GetPrimitiveLibScale(double &aScaleX, double &aScaleY) const
wxString GetItemDescription(UNITS_PROVIDER *aUnitsProvider, bool aFull) const override
Return a user-visible description string of this item.
void SetPinFunction(const wxString &aName)
Set the pad function (pin name in schematic)
EDA_ANGLE GetFPRelativeOrientation() const
double GetChamferRectRatio(PCB_LAYER_ID aLayer) const
bool HitTest(const VECTOR2I &aPosition, int aAccuracy=0) const override
Test if aPosition is inside or on the boundary of this item.
void SetFPRelativeOrientation(const EDA_ANGLE &aAngle)
int GetPostMachiningKnockout(PCB_LAYER_ID aLayer) const
Get the knockout diameter for a layer affected by post-machining.
int GetBoundingRadius() const
Return the radius of a minimum sized circle which fully encloses this pad.
std::optional< int > GetTopBackdrillSize() const
void ClearZoneLayerOverrides()
void SetOrientation(const EDA_ANGLE &aAngle)
Set the rotation angle of the pad.
std::optional< int > GetLocalThermalSpokeWidthOverride() const
PAD_DRILL_SHAPE GetPrimaryDrillShape() const
bool IsBackdrilledOrPostMachined(PCB_LAYER_ID aLayer) const
Check if a layer is affected by backdrilling or post-machining operations.
void SetSizeYProp(int aY)
VECTOR2I GetSolderPasteMargin(PCB_LAYER_ID aLayer) const
Usually < 0 (mask shape smaller than pad)because the margin can be dependent on the pad size,...
void SetTopBackdrillSize(std::optional< int > aSize)
BITMAPS GetMenuImage() const override
Return a pointer to an image to be used in menus.
void AppendPrimitives(PCB_LAYER_ID aLayer, const std::vector< std::shared_ptr< PCB_SHAPE > > &aPrimitivesList)
Import a custom shape primitive list (composed of basic shapes) and add items to the current list.
static void SwapShapePositions(PAD *aLhs, PAD *aRhs)
Swap the visible shape positions of two pads, preserving each pad's own shape offset.
std::map< PCB_LAYER_ID, std::pair< int, std::shared_ptr< SHAPE_COMPOUND > > > m_maskShapes
void SetPrimaryDrillStartLayer(PCB_LAYER_ID aLayer)
void SetBackPostMachiningDepth(int aDepth)
void SetPrimaryDrillCapped(const std::optional< bool > &aCapped)
void SetLibDrillSize(const VECTOR2I &aSize)
PCB_LAYER_ID GetBottomBackdrillLayer() const
void SetLocalClearance(std::optional< int > aClearance)
int GetSubRatsnest() const
ZONE_CONNECTION GetLocalZoneConnection() const
void SetTertiaryDrillSizeY(int aY)
bool HasHole() const override
double GetThermalSpokeAngleDegrees() const
CUSTOM_SHAPE_ZONE_MODE GetCustomShapeInZoneOpt() const
VECTOR2I ShapePos(PCB_LAYER_ID aLayer) const
void SetSecondaryDrillSizeY(int aY)
PCB_LAYER_ID GetTopBackdrillLayer() const
EDA_ORIENTATION m_libOrientation
void SetOrientationDegrees(double aOrientation)
ZONE_CONNECTION GetZoneConnectionOverrides(wxString *aSource=nullptr) const
int GetLocalThermalGapOverride(wxString *aSource) const
void SetLayerSet(const LSET &aLayers) override
bool SharesNetTieGroup(const PAD *aOther) const
PAD_SHAPE GetAnchorPadShape(PCB_LAYER_ID aLayer) const
void SetBottomBackdrillSize(std::optional< int > aSize)
void SetRoundRectRadiusRatio(PCB_LAYER_ID aLayer, double aRadiusScale)
Has meaning only for rounded rectangle pads.
void ClearSecondaryDrillSize()
void SetSubRatsnest(int aSubRatsnest)
int GetLocalSpokeWidthOverride(wxString *aSource=nullptr) const
std::shared_ptr< SHAPE_COMPOUND > getMaskShape(PCB_LAYER_ID aLayer, int aExpansion) const
bool TransformHoleToPolygon(SHAPE_POLY_SET &aBuffer, int aClearance, int aError, ERROR_LOC aErrorLoc=ERROR_INSIDE) const
Build the corner list of the polygonal drill shape in the board coordinate system.
void SetPadToDieLength(int aLength)
bool operator==(const PAD &aOther) const
int GetPadToDieLength() const
void SetBackPostMachiningAngle(int aAngle)
virtual std::vector< int > ViewGetLayers() const override
Return the all the layers within the VIEW the object is painted on.
void Rotate(const VECTOR2I &aRotCentre, const EDA_ANGLE &aAngle) override
Rotate this object.
void OverrideLibPoly(const SHAPE_POLY_SET &aPoly)
void OverrideLibBezier(const VECTOR2I &aC1, const VECTOR2I &aC2)
void SetShape(SHAPE_T aShape) override
void SetPolyShape(const SHAPE_POLY_SET &aShape) override
bool IsProxyItem() const override
void OverrideLibCoords(const VECTOR2I &aStart, const VECTOR2I &aEnd, const VECTOR2I &aArcMid=VECTOR2I(0, 0))
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the shape to a closed polygon.
void RebakeWithScale(double aScaleX, double aScaleY)
void Move(const VECTOR2I &aMoveVector) override
Move this object.
void SetStroke(const STROKE_PARAMS &aStroke) override
PCB_LAYER_ID GetLayer() const override
Return the primary layer this item is on.
PROPERTY_BASE & SetChoicesFunc(std::function< wxPGChoices(INSPECTABLE *)> aFunc)
PROPERTY_BASE & SetAvailableFunc(std::function< bool(INSPECTABLE *)> aFunc)
Set a callback function to determine whether an object provides this property.
PROPERTY_BASE & SetWriteableFunc(std::function< bool(INSPECTABLE *)> aFunc)
PROPERTY_BASE & SetValidator(PROPERTY_VALIDATOR_FN &&aValidator)
PROPERTY_BASE & SetIsCopyable(bool aIsCopyable=true)
PROPERTY_BASE & SetIsHiddenFromLibraryEditors(bool aIsHidden=true)
void InheritsAfter(TYPE_ID aDerived, TYPE_ID aBase)
Declare an inheritance relationship between types.
void Mask(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName)
Sets a base class property as masked in a derived class.
static PROPERTY_MANAGER & Instance()
PROPERTY_BASE & AddProperty(PROPERTY_BASE *aProperty, const wxString &aGroup=wxEmptyString)
Register a property.
void OverrideAvailability(TYPE_ID aDerived, TYPE_ID aBase, const wxString &aName, std::function< bool(INSPECTABLE *)> aFunc)
Sets an override availability functor for a base class property of a given derived class.
void AddTypeCast(TYPE_CAST_BASE *aCast)
Register a type converter.
static VALIDATOR_RESULT PositiveIntValidator(const wxAny &&aValue, EDA_ITEM *aItem)
static VALIDATOR_RESULT RangeIntValidator(const wxAny &&aValue, EDA_ITEM *aItem)
static SEG::ecoord Square(int a)
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
void AddShape(SHAPE *aShape)
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void Move(const VECTOR2I &aVector) override
int PointCount() const
Return the number of points (vertices) in this line chain.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
void Rotate(const EDA_ANGLE &aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Rotate all vertices by a given angle.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
Represent a set of closed polygons.
void Rotate(const EDA_ANGLE &aAngle, const VECTOR2I &aCenter={ 0, 0 }) override
Rotate all vertices by a given angle.
void RemoveAllContours()
Remove all outlines & holes (clears) the polygon set.
bool HasHoles() const
Return true if the polygon set has any holes.
void BooleanAdd(const SHAPE_POLY_SET &b)
Perform boolean polyset union.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
bool IsEmpty() const
Return true if the set is empty (no polygons at all)
void Inflate(int aAmount, CORNER_STRATEGY aCornerStrategy, int aMaxError, bool aSimplify=false)
Perform outline inflation/deflation.
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)
void BooleanIntersection(const SHAPE_POLY_SET &b)
Perform boolean polyset intersection.
int OutlineCount() const
Return the number of outlines in the set.
void Move(const VECTOR2I &aVector) override
void Fracture(bool aSimplify=true)
Convert a set of polygons with holes to a single outline with "slits"/"fractures" connecting the oute...
bool Contains(const VECTOR2I &aP, int aSubpolyIndex=-1, int aAccuracy=0, bool aUseBBoxCaches=false) const
Return true if a given subpolygon contains the point aP.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
const SHAPE_LINE_CHAIN Outline() const
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
bool Collide(const SHAPE *aShape, int aClearance, VECTOR2I *aMTV) const override
Check if the boundary of shape (this) lies closer to the shape aShape than aClearance,...
Represent a simple polygon consisting of a zero-thickness closed chain of connected line segments.
An abstract shape on 2D plane.
bool NearestPoints(const SHAPE *aOther, VECTOR2I &aPtThis, VECTOR2I &aPtOther) const
Return the two points that mark the closest distance between this shape and aOther.
Simple container to manage line stroke parameters.
wxString MessageTextFromValue(double aValue, bool aAddUnitLabel=true, EDA_DATA_TYPE aType=EDA_DATA_TYPE::DISTANCE) const
A lower-precision version of StringFromValue().
A type-safe container of any type.
void TransformCircleToPolygon(SHAPE_LINE_CHAIN &aBuffer, const VECTOR2I &aCenter, int aRadius, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a circle to a polygon, using multiple straight lines.
void TransformRoundChamferedRectToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aPosition, const VECTOR2I &aSize, const EDA_ANGLE &aRotation, int aCornerRadius, double aChamferRatio, int aChamferCorners, int aInflate, int aError, ERROR_LOC aErrorLoc)
Convert a rectangle with rounded corners and/or chamfered corners to a polygon.
void TransformOvalToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aStart, const VECTOR2I &aEnd, int aWidth, int aError, ERROR_LOC aErrorLoc, int aMinSegCount=0)
Convert a oblong shape to a polygon, using multiple segments.
void TransformTrapezoidToPolygon(SHAPE_POLY_SET &aBuffer, const VECTOR2I &aPosition, const VECTOR2I &aSize, const EDA_ANGLE &aRotation, int aDeltaX, int aDeltaY, int aInflate, int aError, ERROR_LOC aErrorLoc)
Convert a rectangle or trapezoid to a polygon.
@ RECT_CHAMFER_BOTTOM_RIGHT
@ RECT_CHAMFER_BOTTOM_LEFT
@ ROUND_ALL_CORNERS
All angles are rounded.
@ ALLOW_ACUTE_CORNERS
just inflate the polygon. Acute angles create spikes
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
const int minSize
Push and Shove router track width and via size dialog.
@ ANNULAR_WIDTH_CONSTRAINT
@ SILK_CLEARANCE_CONSTRAINT
@ HOLE_CLEARANCE_CONSTRAINT
@ SOLDER_PASTE_ABS_MARGIN_CONSTRAINT
@ SOLDER_MASK_EXPANSION_CONSTRAINT
@ PHYSICAL_CLEARANCE_CONSTRAINT
@ SOLDER_PASTE_REL_MARGIN_CONSTRAINT
@ HOLE_TO_HOLE_CONSTRAINT
static constexpr EDA_ANGLE ANGLE_0
#define FOOTPRINT_EDIT_FRAME_NAME
#define PCB_EDIT_FRAME_NAME
@ FILLED_SHAPE
Fill with object color.
#define IGNORE_PARENT_GROUP
#define ROUTER_TRANSIENT
transient items that should NOT be cached
#define ENTERED
indicates a group has been entered
#define SKIP_STRUCT
flag indicating that the structure should be ignored
static PCB_SHAPE * findNext(PCB_SHAPE *aShape, const VECTOR2I &aPoint, const KDTree &kdTree, const PCB_SHAPE_ENDPOINTS_ADAPTOR &adaptor, double aChainingEpsilon)
Searches for a PCB_SHAPE matching a given end point or start point in a list.
a few functions useful in geometry calculations.
Some functions to handle hotkeys in KiCad.
bool IsSolderMaskLayer(int aLayer)
@ LAYER_PAD_FR_NETNAMES
Additional netnames layers (not associated with a PCB layer).
bool IsDrillSymbolLayer(int aLayer)
bool IsPadCopperLayer(int aLayer)
bool IsFrontLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a front layer.
FLASHING
Enum used during connectivity building to ensure we do not query connectivity while building the data...
@ NEVER_FLASHED
Never flashed for connectivity.
@ ALWAYS_FLASHED
Always flashed for connectivity.
bool IsBackLayer(PCB_LAYER_ID aLayerId)
Layer classification: check if it's a back layer.
bool IsClearanceLayer(int aLayer)
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
@ LAYER_DRILL_SYMBOL_START
Drill symbols, one channel per board layer.
@ LAYER_LOCKED_ITEM_SHADOW
Shadow layer for locked items.
@ LAYER_PAD_COPPER_START
Virtual layers for pad copper on a given copper layer.
@ LAYER_FOOTPRINTS_FR
Show footprints on front.
@ LAYER_NON_PLATEDHOLES
Draw usual through hole vias.
@ LAYER_PADS
Meta control for all pads opacity/visibility (color ignored).
@ LAYER_PAD_PLATEDHOLES
to draw pad holes (plated)
@ LAYER_CLEARANCE_START
Virtual layers for pad/via/track clearance outlines for a given copper layer.
@ LAYER_FOOTPRINTS_BK
Show footprints on back.
#define DRILL_SYMBOL_LAYER_FOR(boardLayer)
bool IsNetnameLayer(int aLayer)
Test whether a layer is a netname layer.
bool IsHoleLayer(int aLayer)
bool IsExternalCopperLayer(int aLayerId)
Test whether a layer is an external (F_Cu or B_Cu) copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
PCB_LAYER_ID ToLAYER_ID(int aLayer)
This file contains miscellaneous commonly used macros and functions.
constexpr void MIRROR(T &aPoint, const T &aMirrorRef)
Updates aPoint with the mirror of aPoint relative to the aMirrorRef.
@ LEFT_RIGHT
Flip left to right (around the Y axis)
Message panel definition file.
constexpr int Mils2IU(const EDA_IU_SCALE &aIuScale, int mils)
bool ShapeHitTest(const SHAPE_LINE_CHAIN &aHitter, const SHAPE &aHittee, bool aHitteeContained)
Perform a shape-to-shape hit test.
bool PadHasMeaningfulRoundingRadius(const PAD &aPad, PCB_LAYER_ID aLayer)
Returns true if the pad's rounding ratio is valid (i.e.
void RemoveAllDrillsFromPadstack(PADSTACK &aPadstack)
Remove the primary drill, the secondary and tertiary drills, and any post-machining operations from a...
double GetDefaultIpcRoundingRatio(const PAD &aPad, PCB_LAYER_ID aLayer)
Get a sensible default for a rounded rectangle pad's rounding ratio.
void PackZoneLayerOverrides(google::protobuf::RepeatedPtrField< types::ZoneLayerOverrideEntry > *aOutput, const std::map< PCB_LAYER_ID, ZONE_LAYER_OVERRIDE > &aInput)
void UnpackTeardropSettings(TEARDROP_PARAMETERS &aOutput, const types::PadTeardropSettings &aProto)
void UnpackZoneLayerOverrides(std::map< PCB_LAYER_ID, ZONE_LAYER_OVERRIDE > &aOutput, const google::protobuf::RepeatedPtrField< types::ZoneLayerOverrideEntry > &aInput)
void PackTeardropSettings(types::PadTeardropSettings &aOutput, const TEARDROP_PARAMETERS &aParams)
KICOMMON_API void PackCustomProperties(google::protobuf::RepeatedPtrField< types::CustomProperty > *aOutput, const EDA_ITEM &aItem)
KICOMMON_API VECTOR2I UnpackVector2(const types::Vector2 &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void PackVector2(types::Vector2 &aOutput, const VECTOR2I &aInput, const EDA_IU_SCALE &aScale)
KICOMMON_API void UnpackCustomProperties(const google::protobuf::RepeatedPtrField< types::CustomProperty > &aInput, EDA_ITEM &aItem)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
std::optional< std::pair< ELECTRICAL_PINTYPE, bool > > parsePinType(const wxString &aPinTypeString)
static struct PAD_DESC _PAD_DESC
PAD_SIM_ELECTRICAL_TYPE
The electrical type of a pad.
PAD_DRILL_SHAPE
The set of pad drill shapes, used with PAD::{Set,Get}DrillShape()
PAD_ATTRIB
The set of pad shapes, used with PAD::{Set,Get}Attribute().
@ NPTH
like PAD_PTH, but not plated mechanical use only, no connection allowed
@ SMD
Smd pad, appears on the solder paste layer (default)
@ PTH
Plated through hole pad.
@ CONN
Like smd, does not appear on the solder paste layer (default) Note: also has a special attribute in G...
PAD_SHAPE
The set of pad shapes, used with PAD::{Set,Get}Shape()
PAD_PROP
The set of pad properties used in Gerber files (Draw files, and P&P files) to define some properties ...
@ FIDUCIAL_LOCAL
a fiducial (usually a smd) local to the parent footprint
@ FIDUCIAL_GLBL
a fiducial (usually a smd) for the full board
@ MECHANICAL
a pad used for mechanical support
@ PRESSFIT
a PTH with a hole diameter with tight tolerances for press fit pin
@ HEATSINK
a pad used as heat sink, usually in SMD footprints
@ NONE
no special fabrication property
@ TESTPOINT
a test point pad
@ CASTELLATED
a pad with a castellated through hole
@ BGA
Smd pad, used in BGA footprints.
@ REMOVE_EXCEPT_START_AND_END
Class to handle a set of BOARD_ITEMs.
PCBNEW_SETTINGS * pcbconfig()
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
@ PT_INPUT
usual pin input: must be connected
@ PT_NC
not connected (must be left open)
@ PT_TRISTATE
tri state bus pin
@ PT_NIC
not internally connected (may be connected to anything)
@ PT_BIDI
input or output (like port for a microprocessor)
@ PT_OPENEMITTER
pin type open emitter
@ PT_POWER_OUT
output of a regulator: intended to be connected to power input pins
@ PT_OPENCOLLECTOR
pin type open collector
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
@ PT_UNSPECIFIED
unknown electrical properties: creates always a warning when connected
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin.
wxString GetCanonicalElectricalTypeName(ELECTRICAL_PINTYPE aType)
#define ELECTRICAL_PINTYPES_TOTAL
#define TYPE_HASH(x)
Macro to generate unique identifier for a type.
#define ENUM_TO_WXANY(type)
@ PT_DEGREE
Angle expressed in degrees.
@ PT_DECIDEGREE
Angle expressed in decidegrees.
@ PT_SIZE
Size expressed in distance units (mm/inch)
@ PT_TIME
Time expressed in ps.
#define REGISTER_TYPE(x)
Helper macro to map type hashes to names.
wxString UnescapeString(const wxString &aSource)
The properties of a padstack drill.
VECTOR2I size
Drill diameter (x == y) or slot dimensions (x != y)
std::optional< PAD_DRILL_POST_MACHINING_MODE > mode
LAYER_POLYGON_MAP m_effectivePolygons
LAYER_SHAPE_MAP m_effectiveShapes
std::shared_ptr< SHAPE_SEGMENT > m_effectiveHoleShape
BOX2I m_effectiveBoundingBox
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_PAD_T
class PAD, a pad in a footprint
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
VECTOR2< int32_t > VECTOR2I
VECTOR2< int64_t > VECTOR2L
ZONE_CONNECTION
How pads are covered by copper in zone.
@ THERMAL
Use thermal relief for pads.
@ THT_THERMAL
Thermal relief only for THT pads.
@ NONE
Pads are not covered.
@ FULL
pads are covered by copper
#define ZONE_THICKNESS_MIN_VALUE_MM