29#include <wx/filename.h>
66 if( aOutlines.empty() )
69 double minX = std::numeric_limits<double>::max();
70 double maxX = std::numeric_limits<double>::lowest();
71 double minY = std::numeric_limits<double>::max();
72 double maxY = std::numeric_limits<double>::lowest();
78 minX = std::min( minX, pt.
x );
79 maxX = std::max( maxX, pt.
x );
80 minY = std::min( minY, pt.
y );
81 maxY = std::max( maxY, pt.
y );
85 if( minX >= maxX || minY >= maxY )
99 return static_cast<int>( std::clamp<int64_t>( nm, INT_MIN, INT_MAX ) );
120 auto convertLayerType =
149 info.padsLayerNum = padsInfo.number;
150 info.name = padsInfo.name;
155 info.type = convertLayerType( padsInfo.layer_type );
157 std::string lowerName = padsInfo.name;
158 std::transform( lowerName.begin(), lowerName.end(), lowerName.begin(),
159 [](
unsigned char c )
161 return std::tolower( c );
164 bool isBottom = lowerName.find(
"bottom" ) != std::string::npos
165 || lowerName.find(
"bot" ) != std::string::npos;
177 if( padsInfo.number == 1 )
179 else if( padsInfo.number == aPadsLayerCount )
196 info.required = padsInfo.required;
202 if( aMappingHandler )
208 int requested = std::max( aPadsLayerCount, 2 );
219 m_reporter->Report( wxString::Format(
_(
"The PADS file declares %d copper layers; KiCad supports "
220 "%d, so the layers past that share the last inner layer." ),
233 if(
info.padsLayerNum == aPadsLayer )
250 std::vector<const PADS_IO::LAYER_INFO*> copperLayerInfos;
255 copperLayerInfos.push_back( &li );
258 bool hasStackupData =
false;
262 if( li->layer_thickness > 0.0 || li->dielectric_constant > 0.0 )
264 hasStackupData =
true;
269 if( !hasStackupData )
278 std::map<PCB_LAYER_ID, const PADS_IO::LAYER_INFO*> copperInfoMap;
285 copperInfoMap[kicadLayer] = li;
295 auto it = copperInfoMap.find( item->GetBrdLayerId() );
297 if( it != copperInfoMap.end() )
299 prevCopperInfo = it->second;
301 if( it->second->copper_thickness > 0.0 )
302 item->SetThickness(
ScaleSize( it->second->copper_thickness ) );
318 item->SetColor( wxT(
"White" ) );
322 item->SetColor( wxT(
"Green" ) );
333 if( aNetName.empty() )
338 if(
m_board->FindNet( wxName ) ==
nullptr )
352 if( aPts.size() == 1 && aPts[0].is_arc &&
std::abs( aPts[0].arc.delta_angle ) >= 359.0 )
357 constexpr int NUM_SEGS = 36;
359 for(
int i = 0; i < NUM_SEGS; i++ )
361 double angle = 2.0 *
M_PI * i / NUM_SEGS;
371 for(
size_t i = 1; i < aPts.size(); i++ )
380 for(
int j = 1; j < arcPoly.
PointCount(); j++ )
405 double dx = aCurr.
x - aPrev.
x;
406 double dy = aCurr.
y - aPrev.
y;
411 midX = ( aPrev.
x + aCurr.
x ) / 2.0 - dy / 2.0;
412 midY = ( aPrev.
y + aCurr.
y ) / 2.0 + dx / 2.0;
417 midX = ( aPrev.
x + aCurr.
x ) / 2.0 + dy / 2.0;
418 midY = ( aPrev.
y + aCurr.
y ) / 2.0 - dx / 2.0;
426 double startAngleRad = atan2( aPrev.
y - aCurr.
arc.
cy, aPrev.
x - aCurr.
arc.
cx );
447 m_reporter->Report( wxString::Format(
_(
"Text on unmapped layer %d assigned to Comments layer" ),
460 int scaledSize =
ScaleSize( padsText.height );
465 if( padsText.width > 0 )
469 text->SetTextAngle( textAngle );
476 text->SetPosition( pos + textShift );
478 if( padsText.hjust ==
"LEFT" )
480 else if( padsText.hjust ==
"RIGHT" )
485 if( padsText.vjust ==
"UP" )
487 else if( padsText.vjust ==
"DOWN" )
492 text->SetKeepUpright(
false );
493 text->SetLayer( textLayer );
496 text->SetMirrored( padsText.mirrored );
505 int keepoutIndex = 0;
509 if( ko.outline.size() < 3 )
515 if( ko.layers.empty() )
519 else if( ko.layers.size() == 1 )
527 m_reporter->Report( wxString::Format(
_(
"Skipping keepout on unmapped layer %d" ), ko.layers[0] ),
541 for(
int layer : ko.layers )
546 layerSet.
set( mappedLayer );
549 if( layerSet.none() )
578 zone->
SetZoneName( wxString::Format( wxT(
"%s_%d" ), typeName, ++keepoutIndex ) );
584 if( ko.outline.size() > 2 )
606 if( dim.points.size() < 2 )
618 if( dim.is_horizontal )
628 if( dim.is_horizontal )
642 if( dim.text_height > 0 )
644 int scaledSize =
ScaleSize( dim.text_height );
649 if( dim.text_width > 0 )
653 if( !dim.text.empty() )
663 if( dim.rotation != 0.0 )
683 aZone->
SetZoneName( wxString::Format( wxT(
"Cutout_%s" ),
708 const std::vector<PADS_IO::DIFF_PAIR_DEF>& aDiffPairs )
710 if( aDiffPairs.empty() )
715 auto isSerializable =
716 [](
const wxString& aName )
718 return !aName.EndsWith( wxS(
"\\" ) );
724 [](
const wxString& aName )
726 wxString out = aName;
728 out.Replace( wxS(
"'" ), wxS(
"\\'" ) );
729 out.Replace( wxS(
"\\" ), wxS(
"\\\\" ) );
730 out.Replace( wxS(
"\"" ), wxS(
"\\\"" ) );
731 out.Replace( wxS(
"\r" ), wxS(
"\\r" ) );
732 out.Replace( wxS(
"\n" ), wxS(
"\\n" ) );
738 [](
const wxString& aName )
740 wxString out = aName;
742 out.Replace( wxS(
"\\" ), wxS(
"\\\\" ) );
743 out.Replace( wxS(
"\"" ), wxS(
"\\\"" ) );
744 out.Replace( wxS(
"\r" ), wxS(
"\\r" ) );
745 out.Replace( wxS(
"\n" ), wxS(
"\\n" ) );
750 wxString customRules = wxT(
"(version 2)\n" );
751 bool hasAnyRule =
false;
755 if( dp.name.empty() || dp.gap <= 0 || dp.positive_net.empty() || dp.negative_net.empty() )
763 if( !isSerializable( posNet ) || !isSerializable( negNet ) )
767 m_reporter->Report( wxString::Format(
_(
"Skipped design rule for differential pair "
768 "'%s'; a net name ends with a backslash." ),
777 wxString gapStr = wxString::FromUTF8(
FormatDouble2Str( gapMm ) ) + wxT(
"mm" );
779 customRules += wxString::Format( wxT(
"\n(rule \"%s_gap\"\n" )
780 wxT(
" (condition \"A.NetName == '%s' && B.NetName == '%s'\")\n" )
781 wxT(
" (constraint clearance (min %s)))\n" ),
782 escapeSymbol( ruleName ), escapeOperand( posNet ),
783 escapeOperand( negNet ), gapStr );
791 wxFileName fn( aFileName );
792 fn.SetExt( wxT(
"kicad_dru" ) );
796 wxFile rulesFile( fn.GetFullPath(), wxFile::write_excl );
798 if( !rulesFile.IsOpened() )
802 wxString msg = fn.FileExists() ?
_(
"Design rules for the imported differential pairs were not "
803 "written; '%s' already exists." )
804 :
_(
"Could not write design rules to '%s'." );
812 bool written = rulesFile.Write( customRules );
814 if( !rulesFile.Close() )
821 wxRemoveFile( fn.GetFullPath() );
825 m_reporter->Report( wxString::Format(
_(
"Could not write design rules to '%s'." ),
838 size_t trackCount = 0;
849 m_reporter->Report( wxString::Format(
_(
"Imported %zu footprints, %d nets, %zu tracks, %zu vias, %zu zones" ),
850 m_board->Footprints().size(),
m_board->GetNetCount(), trackCount, viaCount,
constexpr EDA_IU_SCALE pcbIUScale
@ BS_ITEM_TYPE_SILKSCREEN
@ BS_ITEM_TYPE_DIELECTRIC
@ BS_ITEM_TYPE_SOLDERMASK
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
BASE_SET & set(size_t pos)
Container for design settings for a BOARD object.
BOARD_STACKUP & GetStackupDescriptor()
void SetBoardThickness(int aThickness)
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
Manage one layer needed to make a physical board.
Manage layers needed to make a physical board.
void RemoveAll()
Delete all items in list and clear the list.
const std::vector< BOARD_STACKUP_ITEM * > & GetList() const
int BuildBoardThicknessFromStackup() const
void BuildDefaultStackupList(const BOARD_DESIGN_SETTINGS *aSettings, int aActiveCopperLayersCount=0)
Create a default stackup, according to the current BOARD_DESIGN_SETTINGS settings.
Information pertinent to a Pcbnew printed circuit board.
LSET is a set of PCB_LAYER_IDs.
static LSET AllCuMask(int aCuLayerCount)
Return a mask holding the requested number of Cu PCB_LAYER_IDs.
Handle the data for a net.
PADS_LAYER_MAPPER m_layerMapper
void AppendArcPoints(SHAPE_LINE_CHAIN &aChain, const std::vector< PADS_IO::ARC_POINT > &aPts) const
Append PADS vertices to a chain, converting arc entries to polylines and expanding a lone full-circle...
VECTOR2I ScalePoint(double aX, double aY) const
PADS_UNIT_CONVERTER m_unitConverter
void WriteDiffPairRules(const wxString &aFileName, const std::vector< PADS_IO::DIFF_PAIR_DEF > &aDiffPairs)
Write a .kicad_dru beside aFileName carrying one clearance rule per differential pair with a gap.
bool SetOriginFromOutlines(const std::vector< PADS_IO::POLYLINE > &aOutlines)
Move the origin to the center of the board outline bounding box, which places the imported board near...
PCB_LAYER_ID GetMappedLayer(int aPadsLayer) const
std::map< wxString, PCB_LAYER_ID > m_layerMap
PADS_PCB_CONVERTER(BOARD *aBoard, REPORTER *aReporter)
void SetupLayers(const std::vector< PADS_IO::LAYER_INFO > &aPadsLayers, int aPadsLayerCount, const LAYER_MAPPING_HANDLER &aMappingHandler, bool aResolveUnknownTypeByName)
Resolve the PADS layer table to KiCad layers and apply the copper layer count to the board.
void EnsureNet(const std::string &aNetName)
SHAPE_ARC MakeMidpointArc(const PADS_IO::ARC_POINT &aPrev, const PADS_IO::ARC_POINT &aCurr, int aWidth) const
Build a SHAPE_ARC from two consecutive PADS points.
void LoadTexts(const std::vector< PADS_IO::TEXT > &aTexts)
void LoadDimensions(const std::vector< PADS_IO::DIMENSION > &aDimensions)
void ApplyPourSettings(ZONE *aZone, const PADS_IO::POUR &aPour, int aMaxPriority, const PADS_IO::PARAMETERS &aParams)
Apply the cutout or fill settings of aPour to a zone whose outline the caller has already built.
void LoadKeepouts(const std::vector< PADS_IO::KEEPOUT > &aKeepouts)
void SetOrigin(double aX, double aY)
std::vector< PADS_LAYER_INFO > m_layerInfos
int ScaleSize(double aVal) const
int ScaleCoord(double aVal, bool aIsX) const
void BuildStackup(const std::vector< PADS_IO::LAYER_INFO > &aPadsLayers)
Build the board stackup from the PADS physical layer data, if that data carries real thicknesses or d...
static constexpr double MM_TO_NM
void Update()
Update the dimension's cached text and geometry.
virtual void SetEnd(const VECTOR2I &aPoint)
virtual void SetStart(const VECTOR2I &aPoint)
void SetOverrideTextEnabled(bool aOverride)
void SetLineThickness(int aWidth)
void SetOverrideText(const wxString &aValue)
For better understanding of the points that make a dimension:
void SetHeight(int aHeight)
Set the distance from the feature points to the crossbar line.
void SetTextThickness(int aWidth) override
The TextThickness is that set by the user.
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true) override
void SetTextAngle(const EDA_ANGLE &aAngle) override
A pure virtual class used to derive REPORTER objects from.
const SHAPE_LINE_CHAIN ConvertToPolyline(int aMaxError=DefaultAccuracyForPCB(), int *aActualError=nullptr) const
Construct a SHAPE_LINE_CHAIN of segments from a given arc.
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
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.
const VECTOR2I & CPoint(int aIndex) const
Return a reference to a given point in the line chain.
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index.
Handle a list of polygons defining a copper zone.
void SetDoNotAllowPads(bool aEnable)
void SetMinThickness(int aMinThickness)
void SetThermalReliefSpokeWidth(int aThermalReliefSpokeWidth)
virtual void SetLayer(PCB_LAYER_ID aLayer) override
Set the layer this item is on.
SHAPE_POLY_SET * Outline()
void SetIsRuleArea(bool aEnable)
void SetDoNotAllowTracks(bool aEnable)
void SetLayerSet(const LSET &aLayerSet) override
void SetDoNotAllowVias(bool aEnable)
void SetNet(NETINFO_ITEM *aNetInfo) override
Override that drops aNetInfo when this zone is in copper-thieving fill mode.
void SetThermalReliefGap(int aThermalReliefGap)
void SetDoNotAllowFootprints(bool aEnable)
void SetDoNotAllowZoneFills(bool aEnable)
void SetAssignedPriority(unsigned aPriority)
void SetPadConnection(ZONE_CONNECTION aPadConnection)
void SetZoneName(const wxString &aName)
static int GetDefaultHatchPitch()
void SetBorderDisplayStyle(ZONE_BORDER_DISPLAY_STYLE aBorderHatchStyle, int aBorderHatchPitch, bool aRebuilBorderHatch)
Set all hatch parameters for the zone.
double m_PadsPcbTextWidthScale
PADS text width scale factor for PCB imports.
double m_PadsPcbTextHeightScale
PADS text height scale factor for PCB imports.
bool IsCopperLayer(int aLayerId)
Test whether a layer is a copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
int PadsScaleCoord(double aVal, bool aIsX, double aOriginX, double aOriginY, double aScaleFactor)
Map a PADS board coordinate to a KiCad internal coordinate.
wxString ConvertText(const std::string &aText)
Decode text from a PADS file, which uses an 8-bit codepage rather than UTF-8.
wxString ConvertInvertedNetName(const std::string &aNetName)
Convert a PADS net name to KiCad notation.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
PADS_LAYER_TYPE
Functional categories of PADS layers, independent of specific layer numbers.
std::function< std::map< wxString, PCB_LAYER_ID >(const std::vector< INPUT_LAYER_DESC > &)> LAYER_MAPPING_HANDLER
Pointer to a function that takes a map of source and KiCad layers and returns a re-mapped version.
std::string FormatDouble2Str(double aValue)
Print a float number without using scientific notation and no trailing 0 This function is intended in...
A polyline point that may instead be an arc segment.
ARC arc
Only valid when is_arc is true.
double layer_thickness
Dielectric, BASIC units.
double dielectric_constant
Er.
double thermal_line_width
THERLINEWID, THT.
double thermal_min_clearance
STMINCLEAR.
A polyline that may contain arc segments, used for board outlines and graphics.
bool is_cutout
POCUT piece.
std::string owner_pour
Parent pour, 7th header field.
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_DIM_ALIGNED_T
class PCB_DIM_ALIGNED, a linear dimension (graphic item)
VECTOR2< int32_t > VECTOR2I
@ FULL
pads are covered by copper