62 size_t sepPos = aRef.rfind(
'-' );
64 if( sepPos == std::string::npos )
65 sepPos = aRef.rfind(
'.' );
67 if( sepPos != std::string::npos && sepPos + 1 < aRef.size()
68 && std::isalpha(
static_cast<unsigned char>( aRef[sepPos + 1] ) ) )
70 return aRef.substr( 0, sepPos );
84 int charHeight =
static_cast<int>( scaledSize
86 int charWidth =
static_cast<int>( scaledSize
106 else if( justVal >= 2 )
148 const std::vector<PADS_SCH::SCH_SIGNAL>& aSignals,
149 const VECTOR2I& aOpcPos,
bool aPinUp,
int aPageHeightIU )
152 std::string opcRef =
"@@@O" + aOpcId;
156 for(
const auto& signal : aSignals )
158 for(
const auto& wire : signal.wires )
160 if( wire.vertices.size() < 2 )
163 if( wire.endpoint_a == opcRef )
173 if( wire.endpoint_b == opcRef )
175 size_t last = wire.vertices.size() - 1;
180 KiROUND( wire.vertices[last - 1].y ) ) );
194 int dx = adjPos.
x - aOpcPos.
x;
195 int dy = adjPos.
y - aOpcPos.
y;
267 const std::map<std::string, UTF8>* aProperties )
269 wxCHECK( !aFileName.IsEmpty() && aSchematic,
nullptr );
277 wxCHECK_MSG( aSchematic->
IsValid(),
nullptr,
"Can't append to a schematic with no root!" );
278 rootSheet = aAppendToMe;
300 wxCHECK( rootScreen,
nullptr );
311 std::string filename( aFileName.ToUTF8() );
313 if( !parser.
Parse( filename ) )
315 THROW_IO_ERROR( wxString::Format( wxT(
"Failed to parse PADS file: %s" ), aFileName ) );
328 const std::string& ref = part.reference;
329 size_t dashPos = ref.rfind(
'-' );
330 size_t dotPos = ref.rfind(
'.' );
331 size_t sepPos = std::string::npos;
333 if( dashPos != std::string::npos )
335 else if( dotPos != std::string::npos )
338 if( sepPos != std::string::npos && sepPos + 1 < ref.size()
339 && std::isalpha(
static_cast<unsigned char>( ref[sepPos + 1] ) ) )
364 if( sheetNumbers.empty() )
365 sheetNumbers.insert( 1 );
367 bool isSingleSheet = ( sheetNumbers.size() == 1 );
377 std::map<int, SheetContext> sheetContexts;
381 int sheetNum = *sheetNumbers.begin();
383 ctx.sheet = rootSheet;
384 ctx.screen = rootScreen;
386 ctx.screen->SetPageSettings( pageInfo );
387 sheetContexts[sheetNum] = ctx;
392 int totalSheets =
static_cast<int>( sheetNumbers.size() );
394 for(
int sheetNum : sheetNumbers )
397 sheetNum, totalSheets, rootSheet, aFileName );
405 if( hdr.sheet_num == sheetNum && !hdr.sheet_name.empty() )
408 wxString::FromUTF8( hdr.sheet_name ) );
418 wxString pageNo = wxString::Format( wxT(
"%d" ), sheetNum );
427 ctx.sheet = subSheet;
430 ctx.screen->SetPageSettings( pageInfo );
431 sheetContexts[sheetNum] = ctx;
439 for(
auto& [sheetNum, ctx] : sheetContexts )
441 std::vector<PADS_SCH::PART_PLACEMENT> parts = parser.
GetPartsOnSheet( sheetNum );
445 auto ptIt = parser.
GetPartTypes().find( part.part_type );
448 bool isMultiGate =
false;
449 bool isPower =
false;
450 std::string libItemName;
456 if( ptDef.
gates.size() > 1 )
461 libItemName = ptDef.
name;
464 else if( !ptDef.
gates.empty() )
468 int idx = std::max( 0, part.gate_index );
469 std::string decalName;
471 if( idx <
static_cast<int>( gate.
decal_names.size() ) )
481 libItemName = decalName;
487 int idx = std::max( 0, part.gate_index );
488 idx = std::min( idx,
static_cast<int>( ptDef.
special_variants.size() ) - 1 );
496 libItemName = decalName;
512 wxString::Format( wxT(
"PADS Import: symbol '%s' not found,"
513 " part '%s' skipped" ),
514 wxString::FromUTF8( part.symbol_name ),
515 wxString::FromUTF8( part.reference ) ),
521 libItemName = symDef->
name;
527 if( ptIt != parser.
GetPartTypes().end() && !ptIt->second.sigpins.empty() )
536 std::string powerStyle;
539 && !ptIt->second.special_variants.empty() )
541 int varIdx = std::max( 0, part.gate_index );
544 static_cast<int>( ptIt->second.special_variants.size() ) - 1 );
545 const auto& variant = ptIt->second.special_variants[varIdx];
548 variant.decal_name, variant.pin_type );
551 if( isPower && powerStyle.empty() )
553 std::string rawNetName = part.power_net_name.empty()
555 : part.power_net_name;
561 powerStyle = std::string( powerLibId->GetLibItemName().c_str() );
564 auto symbolPtr = std::make_unique<SCH_SYMBOL>();
568 if( isPower && !powerStyle.empty() )
584 instanceSymbol =
new LIB_SYMBOL( *libSymbol );
597 if( part.rotation == 90.0 )
599 else if( part.rotation == 180.0 )
601 else if( part.rotation == 270.0 )
604 if( part.mirror_flags & 1 )
607 if( part.mirror_flags & 2 )
613 symbol->
SetUnit( part.gate_index + 1 );
620 if( !isPower && ( !isMultiGate || part.gate_index == 0 ) )
628 symbol->
SetRef( &ctx.path, wxString::FromUTF8( part.reference ) );
638 const std::string& cat = ptIt->second.category;
640 if( cat ==
"CAP" || cat ==
"RES" || cat ==
"IND" )
642 auto valIt = part.attr_overrides.find(
"VALUE1" );
644 if( valIt != part.attr_overrides.end() && !valIt->second.empty() )
648 for(
const auto& attr : part.attributes )
650 if( attr.name ==
"VALUE1" || attr.name ==
"Value1" )
655 if( part.mirror_flags & 1 )
660 KiROUND( attr.position.y ) ) );
663 int fieldTextSize =
schIUScale.MilsToIU( 50 );
665 VECTOR2I( fieldTextSize, fieldTextSize ) );
679 wxString netName = part.power_net_name.empty()
680 ? wxString::FromUTF8( part.symbol_name )
681 : wxString::FromUTF8( part.power_net_name );
683 if( netName.StartsWith( wxT(
"/" ) ) )
684 netName = wxT(
"~{" ) + netName.Mid( 1 ) + wxT(
"}" );
691 wxString::FromUTF8( part.reference ),
695 ctx.screen->Append( symbolPtr.release() );
702 std::set<std::string> powerSignalNames;
706 if( opc.signal_name.empty() )
709 auto ptIt = parser.
GetPartTypes().find( opc.symbol_lib );
712 && !ptIt->second.special_keyword.empty() && ptIt->second.special_keyword !=
"OFF"
713 && !ptIt->second.special_variants.empty() )
715 int idx = std::max( 0, opc.flags2 );
717 static_cast<int>( ptIt->second.special_variants.size() ) - 1 );
718 const auto& variant = ptIt->second.special_variants[idx];
721 variant.decal_name, variant.pin_type ).empty() )
723 powerSignalNames.insert( opc.signal_name );
731 std::set<std::string> signalOpcIds;
735 if( opc.signal_name.empty() || powerSignalNames.count( opc.signal_name ) )
738 signalOpcIds.insert(
"@@@O" + std::to_string( opc.id ) );
742 for(
auto& [sheetNum, ctx] : sheetContexts )
744 std::vector<PADS_SCH::SCH_SIGNAL> sheetSignals = parser.
GetSignalsOnSheet( sheetNum );
755 for(
size_t v = 0; v + 1 < wire.
vertices.size(); v++ )
772 ctx.screen->Append( line );
780 if( dot.sheet_number != sheetNum )
787 ctx.screen->Append( junction );
800 if( opc.source_sheet != sheetNum )
803 if( opc.signal_name.empty() )
811 std::string powerStyle;
812 auto opcPtIt = parser.
GetPartTypes().find( opc.symbol_lib );
815 && !opcPtIt->second.special_keyword.empty() && opcPtIt->second.special_keyword !=
"OFF"
816 && !opcPtIt->second.special_variants.empty() )
818 int idx = std::max( 0, opc.flags2 );
821 opcPtIt->second.special_variants.size() ) - 1 );
822 const auto& variant = opcPtIt->second.special_variants[idx];
825 variant.decal_name, variant.pin_type );
828 if( !powerStyle.empty() )
834 auto symbolPtr = std::make_unique<SCH_SYMBOL>();
847 bool pinUp = ( powerStyle ==
"VCC" || powerStyle ==
"PWR_TRIANGLE" );
849 std::to_string( opc.id ), sheetSignals, pos, pinUp,
854 wxString netName = wxString::FromUTF8( opc.signal_name );
856 if( netName.StartsWith( wxT(
"/" ) ) )
857 netName = wxT(
"~{" ) + netName.Mid( 1 ) + wxT(
"}" );
862 wxString pwrRef = wxString::Format( wxT(
"#PWR%03d" ), pwrIndex++ );
863 symbol->
SetRef( &ctx.path, pwrRef );
867 ctx.screen->Append( symbolPtr.release() );
879 if( !sheetContexts.empty() )
881 SCH_SCREEN* textScreen = sheetContexts.begin()->second.screen;
885 if( textItem.content.empty() )
897 if( !sheetContexts.empty() )
899 SCH_SCREEN* linesScreen = sheetContexts.begin()->second.screen;
906 double ox = linesItem.origin.x;
907 double oy = linesItem.origin.y;
936 && prim.
points.size() == 2 )
957 linesScreen->
Append( rect );
959 else if( prim.
points.size() >= 2 )
961 for(
size_t p = 0; p + 1 < prim.
points.size(); p++ )
979 if( prim.
points[p].arc.has_value() )
989 double sx = start.
x -
center.x;
990 double sy = start.
y -
center.y;
993 double radius = std::sqrt( sx * sx + sy * sy );
997 double mlen = std::sqrt( mx * mx + my * my );
1004 +
static_cast<int>(
radius * mx / mlen );
1006 +
static_cast<int>(
radius * my / mlen );
1011 +
static_cast<int>( -sy *
radius
1012 / std::max(
radius, 1.0 ) );
1014 +
static_cast<int>( sx *
radius
1015 / std::max(
radius, 1.0 ) );
1031 linesScreen->
Append( arc );
1039 linesScreen->
Append( line );
1048 if( textItem.
content.empty() )
1085 std::ifstream file( aFileName.fn_str() );
1087 if( !file.is_open() )
1092 if( std::getline( file, line ) )
1094 if( line.find(
"*PADS-POWERLOGIC" ) != std::string::npos )
1097 if( line.find(
"*PADS-LOGIC" ) != std::string::npos )
constexpr EDA_IU_SCALE schIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
static const ADVANCED_CFG & GetCfg()
Get the singleton instance's config, which is shared by all consumers.
void ClearFlags(EDA_ITEM_FLAGS aMask=EDA_ITEM_ALL_FLAGS)
void SetEnd(const VECTOR2I &aEnd)
void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
void SetFillMode(FILL_T aFill)
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
void SetTextThickness(int aWidth)
The TextThickness is that set by the user.
void SetTextAngleDegrees(double aOrientation)
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
REPORTER * m_reporter
Reporter to log errors/warnings to, may be nullptr.
PROGRESS_REPORTER * m_progressReporter
Progress reporter to track the progress of the operation, may be nullptr.
virtual bool CanReadLibrary(const wxString &aFileName) const
Checks if this IO object can read the specified library file/directory.
A logical library item identifier and consists of various portions much like a URI.
int SetLibItemName(const UTF8 &aLibItemName)
Override the library item name portion of the LIB_ID to aLibItemName.
int SetLibNickname(const UTF8 &aLibNickname)
Override the logical library name portion of the LIB_ID to aLibNickname.
Define a library symbol object.
Instantiate the current locale within a scope in which you are expecting exceptions to be thrown.
Parser for PADS Logic schematic design export files.
const std::vector< TEXT_ITEM > & GetTextItems() const
const std::vector< TIED_DOT > & GetTiedDots() const
const std::vector< OFF_PAGE_CONNECTOR > & GetOffPageConnectors() const
bool Parse(const std::string &aFileName)
const std::vector< SHEET_HEADER > & GetSheetHeaders() const
const std::vector< LINES_ITEM > & GetLinesItems() const
std::vector< SCH_SIGNAL > GetSignalsOnSheet(int aSheetNumber) const
std::set< int > GetSheetNumbers() const
const std::vector< SYMBOL_DEF > & GetSymbolDefs() const
const std::vector< PART_PLACEMENT > & GetPartPlacements() const
const std::map< std::string, PARTTYPE_DEF > & GetPartTypes() const
std::vector< PART_PLACEMENT > GetPartsOnSheet(int aSheetNumber) const
const SYMBOL_DEF * GetSymbolDef(const std::string &aName) const
const PARAMETERS & GetParameters() const
Builder class to create KiCad schematic elements from parsed PADS data.
int CreateNetLabels(const std::vector< SCH_SIGNAL > &aSignals, SCH_SCREEN *aScreen, const std::set< std::string > &aSignalOpcIds, const std::set< std::string > &aSkipSignals={})
Create net labels for named signals.
void ApplyPartAttributes(SCH_SYMBOL *aSymbol, const PART_PLACEMENT &aPlacement)
Apply part attributes to a symbol instance.
void CreateTitleBlock(SCH_SCREEN *aScreen)
Create title block from parsed PADS parameters.
int CreateCustomFields(SCH_SYMBOL *aSymbol, const PART_PLACEMENT &aPlacement)
Create custom fields from non-standard PADS attributes.
SCH_SHEET * CreateHierarchicalSheet(int aSheetNumber, int aTotalSheets, SCH_SHEET *aParentSheet, const wxString &aBaseFilename)
Create hierarchical sheet for a sub-schematic page.
Builder class to convert PADS symbol definitions to KiCad LIB_SYMBOL objects.
void AddHiddenPowerPins(LIB_SYMBOL *aSymbol, const std::vector< PARTTYPE_DEF::SIGPIN > &aSigpins)
Add hidden power pins from PARTTYPE SIGPIN entries to an existing symbol.
LIB_SYMBOL * GetOrCreateMultiUnitSymbol(const PARTTYPE_DEF &aPartType, const std::vector< SYMBOL_DEF > &aSymbolDefs)
Get or create a multi-unit symbol for the given PARTTYPE.
static std::optional< LIB_ID > GetKiCadPowerSymbolId(const std::string &aPadsName)
Get KiCad power library symbol ID for a PADS power symbol.
LIB_SYMBOL * BuildKiCadPowerSymbol(const std::string &aKiCadName)
Build a power symbol using hard-coded KiCad-standard graphics.
static bool IsPowerSymbol(const std::string &aName)
Check if a symbol name indicates a power symbol.
static std::string GetPowerStyleFromVariant(const std::string &aDecalName, const std::string &aPinType)
Map a PADS special_variant to a power symbol style name.
LIB_SYMBOL * GetOrCreateSymbol(const SYMBOL_DEF &aSymbolDef)
Get or create a symbol for the given definition.
LIB_SYMBOL * GetOrCreatePartTypeSymbol(const PARTTYPE_DEF &aPartType, const SYMBOL_DEF &aSymbolDef)
Get or create a single-gate symbol with PARTTYPE-specific pin remapping.
Describe the page size and margins of a paper page on which to eventually print or plot.
int GetHeightIU(double aIUScale) const
Gets the page height in IU.
bool SetType(PAGE_SIZE_TYPE aPageSize, bool aIsPortrait=false)
Set the name of the page type and also the sizes and margins commonly associated with that type name.
Holds all the data relating to one schematic.
SCHEMATIC_SETTINGS & Settings() const
bool IsValid() const
A simple test if the schematic is loaded, not a complete one.
void SetTopLevelSheets(const std::vector< SCH_SHEET * > &aSheets)
void SetPosition(const VECTOR2I &aPosition) override
void SetText(const wxString &aText) override
bool CanReadLibrary(const wxString &aFileName) const override
Checks if this IO object can read the specified library file/directory.
bool checkFileHeader(const wxString &aFileName) const
Check if the file header indicates a PADS Logic schematic file.
bool CanReadSchematicFile(const wxString &aFileName) const override
Checks if this SCH_IO can read the specified schematic file.
std::unordered_map< wxString, SEVERITY > m_errorMessages
SCH_SHEET * LoadSchematicFile(const wxString &aFileName, SCHEMATIC *aSchematic, SCH_SHEET *aAppendToMe=nullptr, const std::map< std::string, UTF8 > *aProperties=nullptr) override
Load information from some input file format that this SCH_IO implementation knows about,...
virtual bool CanReadSchematicFile(const wxString &aFileName) const
Checks if this SCH_IO can read the specified schematic file.
SCH_IO(const wxString &aName)
void SetConnectivityDirty(bool aDirty=true)
virtual void SetUnit(int aUnit)
Segment description base class to describe items which have 2 end points (track, wire,...
virtual void SetStroke(const STROKE_PARAMS &aStroke) override
void SetEndPoint(const VECTOR2I &aPosition)
Container class that holds multiple SCH_SCREEN objects in a hierarchy.
void UpdateSymbolLinks(REPORTER *aReporter=nullptr)
Initialize the LIB_SYMBOL reference for each SCH_SYMBOL found in the full schematic.
std::vector< SCH_SHEET_INSTANCE > m_sheetInstances
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
const KIID & GetUuid() const
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
void SetPosition(const VECTOR2I &aPos) override
void SetStroke(const STROKE_PARAMS &aStroke) override
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
KIID_PATH Path() const
Get the sheet path as an KIID_PATH.
void SetPageNumber(const wxString &aPageNumber)
Set the sheet instance user definable page number.
void push_back(SCH_SHEET *aSheet)
Forwarded method from std::vector.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
void SetFileName(const wxString &aFilename)
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this sheet.
SCH_SCREEN * GetScreen() const
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
void SetLibId(const LIB_ID &aName)
void SetPosition(const VECTOR2I &aPosition) override
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
void SetOrientation(int aOrientation)
Compute the new transform matrix based on aOrientation for the symbol which is applied to the current...
void AddHierarchicalReference(const KIID_PATH &aPath, const wxString &aRef, int aUnit)
Add a full hierarchical reference to this symbol.
VECTOR2I GetPosition() const override
void SetValueFieldText(const wxString &aValue, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString)
void SetLibSymbol(LIB_SYMBOL *aLibSymbol)
Set this schematic symbol library symbol reference to aLibSymbol.
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
Simple container to manage line stroke parameters.
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
@ FILLED_SHAPE
Fill with object color.
double m_PadsSchTextWidthScale
PADS text width scale factor for schematic imports.
double m_PadsSchTextHeightScale
PADS text height scale factor for schematic imports.
#define THROW_IO_ERROR(msg)
macro which captures the "call site" values of FILE_, __FUNCTION & LINE
LINE_STYLE PadsLineStyleToKiCad(int aPadsStyle)
Convert a PADS line style integer to a KiCad LINE_STYLE enum value.
KIID GenerateDeterministicUuid(const std::string &aIdentifier)
Generate a deterministic KIID from a PADS component identifier.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Common utilities and types for parsing PADS file formats.
static int computePowerOrientation(const std::string &aOpcId, const std::vector< PADS_SCH::SCH_SIGNAL > &aSignals, const VECTOR2I &aOpcPos, bool aPinUp, int aPageHeightIU)
Determine the orientation for a power symbol at an OPC position based on the wire direction at that p...
static SCH_TEXT * createSchText(const PADS_SCH::TEXT_ITEM &aText, const VECTOR2I &aPos)
static std::string stripGateSuffix(const std::string &aRef)
Strip any alphabetic gate suffix (e.g.
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
LINE_STYLE
Dashed line types.
Gate definition within a PARTTYPE.
std::vector< std::string > decal_names
Graphical line/shape item from LINES section.
Off-page reference from OFFPAGE REFS section.
General schematic parameters from SCH and FIELDS sections.
std::string border_template
Part type definition from PARTTYPE section.
std::vector< GATE_DEF > gates
std::vector< SPECIAL_VARIANT > special_variants
std::string special_keyword
Part instance from PART section.
Signal (net) definition from CONNECTION and SIGNAL sections.
Symbol definition from CAEDECAL section.
Graphic primitive from CAEDECAL or LINES sections (OPEN, CLOSED, CIRCLE, COPCLS).
std::vector< GRAPHIC_POINT > points
Free text item from TEXT section.
Junction dot from TIEDOTS section.
Wire segment connecting two endpoints through coordinate vertices.
std::vector< POINT > vertices
A simple container for sheet instance information.
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
VECTOR2< int32_t > VECTOR2I
Definition of file extensions used in Kicad.