25#ifndef ORCAD_CONVERTER_H_
26#define ORCAD_CONVERTER_H_
111 { 0, 0, 0, 0, 1, 0, 0, 1 }, { 90, 0, 0, 1, 0, 1, -1, 0 }, { 180, 0, 1, 2, -1, 0, 0, -1 },
112 { 270, 0, 2, 0, 0, -1, 1, 0 }, { 0,
'y', 1, 0, -1, 0, 0, 1 }, { 90,
'x', 0, 0, 0, 1, 1, 0 },
113 { 0,
'x', 0, 2, 1, 0, 0, -1 }, { 270,
'x', 2, 1, 0, -1, -1, 0 }
120 return ( aRotation & 3 ) | ( aMirror ? 0x4 : 0 );
126 return aSelector == 1 ? aWidth : aSelector == 2 ? aHeight : 0;
144 return VECTOR2I( aBaseX + t.
x + e.
a * aPx + e.
b * aPy, aBaseY + t.
y + e.
c * aPx + e.
d * aPy );
165 static constexpr const char*
LIB_NICK =
"orcad_import";
207 using PKG_KEY = std::tuple<std::string, std::string, int, std::string>;
232 void warn(
const wxString& aMsg );
235 void note(
const wxString& aMsg );
252 const std::vector<const ORCAD_PLACED_INSTANCE*>& aInstances )
const;
262 const PKG_KEY** aSourceUnit =
nullptr );
272 std::string
powerLibFor(
const std::string& aSymbolName,
const std::string& aNetName );
279 int aOffsetX = 0,
int aOffsetY = 0 );
287 bool aPower,
const std::string& aNameOverride,
bool aNameVisible,
bool aShowPinNumbers,
288 bool aNumberVisible,
const BOX2I* aBodyBox,
bool aHidden =
false,
289 bool aExplicitNet =
false );
304 int aOrient,
const std::string& aValue,
const std::string& aFootprint );
321 int textBaselineOffset(
int aTextSize,
int aFontIdx,
bool aTemplateFont =
true )
const;
327 int fontHeightDbu(
int aFontIdx,
bool aTemplateFont =
true )
const;
330 int textSizeIU(
int aFontIdx,
bool aTemplateFont =
true )
const;
335 void applyFont(
EDA_TEXT* aText,
int aFontIdx,
bool aTemplateFont =
true )
const;
339 static std::string
SymbolId(
const std::string& aName );
343 bool aContainerPage =
false,
bool aSharedFolderPage =
false );
345 const std::string& aChildFolder );
358 static wxString
MakePageFileName(
int aPageIndex,
const std::string& aPageName );
394 const std::string& aNetName )
const;
407 bool aNestedHierarchy,
bool aSharedFolderPage );
414 const std::string& aText,
SCH_SCREEN* aScreen );
428 bool* aUsedEmbeddedEmf =
nullptr );
434 SCH_SCREEN* aScreen,
double aTextScaleX = 1.0,
double aTextScaleY = 1.0,
435 bool aUseGenericTextBaseline =
false,
436 const std::string& aTextFaceOverride = {} );
504 const std::vector<SEG>& aSourceWires );
524 std::map<std::tuple<SCH_SCREEN*, const ORCAD_PLACED_INSTANCE*, size_t>, std::pair<uint32_t, std::string>>
m_wirelessNetNames;
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
A color representation with 4 components: red, green, blue, alpha.
Define a library symbol object.
void placePowerSymbol(ORCAD_RAW_PAGE &aPage, const ORCAD_GRAPHIC_INST &aInst, const std::string &aNet, SCH_SCREEN *aScreen, const SCH_SHEET_PATH &aSheetPath)
void placePageFrame(const ORCAD_RAW_PAGE &aPage, SCH_SCREEN *aScreen)
void placeJunctions(const ORCAD_RAW_PAGE &aPage, SCH_SCREEN *aScreen)
Append computed junctions as SCH_JUNCTION items.
bool displayUsesTemplateFont(const ORCAD_DISPLAY_PROP &aProp) const
std::map< std::string, std::string > m_currentInterfaceNetAliases
std::vector< VECTOR2I > computeJunctions(const ORCAD_RAW_PAGE &aPage) const
Use both geometry and net IDs; a crossing alone does not create a junction.
void computeFontBaseline()
int displayFontId(const ORCAD_DISPLAY_PROP &aProp) const
std::vector< OFFPAGE_NET > offpageNets(const ORCAD_RAW_PAGE &aPage) const
Resolve every off-page connector on the page to (index, net, pin position).
const std::map< uint32_t, std::string > * m_currentOccUnitRefs
std::string netAt(const ORCAD_RAW_PAGE &aPage, int aX, int aY) const
Prefer endpoint nets, then intersecting wires, then endpoint aliases.
static constexpr int MARGIN_B_DBU
PROGRESS_REPORTER * m_progressReporter
SCH_SHEET * Convert(SCH_SHEET *aRootSheet)
aRootSheet must have a screen and be registered on the schematic.
void assignPageItemUuids(size_t aPageOrdinal)
void buildNetLookup(const ORCAD_RAW_PAGE &aPage)
Rebuild m_wireEndpoints for a page (both endpoints of every wire).
std::map< SCH_LABEL_BASE *, std::pair< SCH_SCREEN *, uint32_t > > m_labelSourceNets
std::map< SCH_SYMBOL *, std::vector< SOURCE_PIN_IDENTITY > > m_sourcePinIdentities
std::set< const ORCAD_PIN_INST * > m_currentImplicitPowerPins
std::vector< int > placedStackedPinOffsets(const ORCAD_PLACED_INSTANCE &aInstance) const
void rememberInterfaceLabelSource(SCH_SCREEN *aScreen, SCH_LABEL_BASE *aLabel, const std::vector< SEG > &aSourceWires)
static constexpr int PIN_LEN_DBU
– constants (calibrated; do not change) -------------------------------------—
static constexpr int MARGIN_R_DBU
std::map< SCH_SCREEN *, std::vector< wxString > > m_sourceOccurrences
std::pair< const ORCAD_SYMBOL_DEF *, int > pickVariant(const ORCAD_PLACED_INSTANCE &aInst) const
Match cached variants to placed pin positions; use the first entry if none matches.
std::map< SCH_SCREEN *, const ORCAD_RAW_PAGE * > m_sourcePages
std::set< std::string > m_currentConnectorInterfaceNetAliases
std::map< SCH_SYMBOL *, const ORCAD_PLACED_INSTANCE * > m_sourceInstances
void placeDefinitionVectors(const ORCAD_SYMBOL_DEF &aDefinition, int aBaseX, int aBaseY, int aOrient, SCH_SCREEN *aScreen, double aTextScaleX=1.0, double aTextScaleY=1.0, bool aUseGenericTextBaseline=false, const std::string &aTextFaceOverride={})
const std::map< uint32_t, std::string > * m_currentOccRefs
Per-page occurrence references distinguish repeated child schematics.
bool isOffpageNetName(const std::string &aName) const
void placeBitmap(const ORCAD_PRIMITIVE &aPrim, SCH_SCREEN *aScreen, int aOrient=0, bool *aUsedEmbeddedEmf=nullptr)
Skip undecodable images with a warning.
VECTOR2I graphicPinPos(const ORCAD_GRAPHIC_INST &aInst) const
Use the transformed cache pin position, or the instance anchor if no pin is available.
const ORCAD_PACKAGE * packageFor(const ORCAD_PLACED_INSTANCE &aInst) const
The cache package backing a placement, or nullptr when the design has none.
std::map< std::string, std::vector< UNIT_INFO > > m_preparedLibUnits
void applyPageSettings(ORCAD_RAW_PAGE &aPage, SCH_SCREEN *aScreen)
Shift content on the 10-DBU grid to preserve connectivity.
const std::map< uint32_t, std::map< std::string, std::string > > * m_currentOccProps
std::map< std::string, std::string > m_currentOccurrenceNetAliases
ORCAD_CONVERTER(ORCAD_DESIGN &aDesign, SCHEMATIC *aSchematic, REPORTER *aReporter, PROGRESS_REPORTER *aProgressReporter=nullptr)
aDesign is mutated and must outlive the converter.
static bool onSegment(int aX, int aY, const ORCAD_WIRE &aWire)
True when the point lies strictly INSIDE (not at an endpoint of) an H/V wire.
std::map< std::tuple< SCH_SCREEN *, const ORCAD_PLACED_INSTANCE *, size_t >, std::pair< uint32_t, std::string > > m_wirelessNetNames
~ORCAD_CONVERTER()
Out-of-line: LIB_ENTRY holds LIB_SYMBOL by unique_ptr.
void placeGraphicDisplayText(const ORCAD_GRAPHIC_INST &aGraphic, const ORCAD_DISPLAY_PROP &aDisplay, const std::string &aText, SCH_SCREEN *aScreen)
One displayed property attached to a placed page symbol, preserving source text geometry.
int resolveFontIndex(int aFontIdx) const
Resolve a Design Template font ID to its 1-based LOGFONT index.
void addSymbolPin(LIB_SYMBOL *aSymbol, const ORCAD_SYMBOL_PIN &aPin, const wxString &aNumber, int aUnit, bool aPower, const std::string &aNameOverride, bool aNameVisible, bool aShowPinNumbers, bool aNumberVisible, const BOX2I *aBodyBox, bool aHidden=false, bool aExplicitNet=false)
VECTOR2I namedGraphicPinPos(const ORCAD_RAW_PAGE &aPage, const ORCAD_GRAPHIC_INST &aInst) const
Graphic-symbol connection point, corrected to a nearby endpoint of its named wire.
static wxString MakePageFileName(int aPageIndex, const std::string &aPageName)
LIB_SYMBOL * kicadSymbolFor(const std::string &aLibName)
static BOX2I pageExtentDbu(const ORCAD_RAW_PAGE &aPage)
Free graphics use nested primitive bounds; their outer boxes do not describe page coordinates.
std::map< PKG_KEY, std::pair< std::string, int > > m_pkgToLib
void appendPageItem(SCH_SCREEN *aScreen, SCH_ITEM *aItem)
void note(const wxString &aMsg)
Fact about the source design (not a conversion problem): RPT_SEVERITY_INFO.
void placeInstance(ORCAD_RAW_PAGE &aPage, const ORCAD_PLACED_INSTANCE &aInst, SCH_SCREEN *aScreen, const SCH_SHEET_PATH &aSheetPath)
std::vector< NET_LABEL_INTENT > m_netLabelIntents
int textBaselineOffset(int aTextSize, int aFontIdx, bool aTemplateFont=true) const
int m_fontBaselineDbu
dominant text height; 0 = none
void placeSymbolFields(SCH_SYMBOL *aSymbol, const ORCAD_PLACED_INSTANCE &aInst, const ORCAD_SYMBOL_DEF &aDef, int aOrient, const std::string &aValue, const std::string &aFootprint)
std::set< wxString > m_usedSheetNames
Lower-cased sheet names already emitted, to keep sibling sheet names unique.
void addSymbolArc(LIB_SYMBOL *aSymbol, const ORCAD_PRIMITIVE &aPrim, int aUnit, int aColor, int aOffsetX=0, int aOffsetY=0)
Polyline approximation of an arc primitive.
std::vector< INTERFACE_LABEL_SOURCE > m_interfaceLabelSources
SCH_SCREEN * m_pageItemScreen
void prepareGlobalNetNames()
Capture net names ignore case; KiCad net names do not.
std::map< std::string, LIB_ENTRY > m_libSymbols
keyed by emitted lib name
std::map< std::string, size_t > m_occurrenceNetNameScopeCounts
static int toKicadOrientation(int aOrient)
int m_powerCount
"#PWR%04d" counter
void convertUnreferencedPages()
void convertPage(ORCAD_RAW_PAGE &aPage, SCH_SCREEN *aScreen, const SCH_SHEET_PATH &aSheetPath, bool aContainerPage=false, bool aSharedFolderPage=false)
VECTOR2I powerPinPos(const ORCAD_RAW_PAGE &aPage, const ORCAD_GRAPHIC_INST &aInst) const
Power-symbol connection point, corrected to a nearby endpoint of its named wire.
KIID deterministicUuid(const std::string &aRole, size_t aOrdinal) const
std::set< std::string > m_offpageNetNames
bool m_scopeNamedFlatNets
void applyTitleBlock(const ORCAD_RAW_PAGE &aPage, SCH_SCREEN *aScreen)
void finalizeNativePowerPackages()
void finishConversion()
Run the shared finalization sequence that ends every conversion entry point.
std::map< std::pair< SCH_SCREEN *, uint32_t >, std::vector< SCH_ITEM * > > m_sourceNetItems
void placeDefinitionImages(const ORCAD_SYMBOL_DEF &aDefinition, int aBaseX, int aBaseY, int aOrient, SCH_SCREEN *aScreen)
wxString resolveReference(const ORCAD_PLACED_INSTANCE &aInst) const
Use the occurrence reference when the instance has an unannotated template.
std::string occurrenceElectricalNetName(uint32_t aOccurrenceId, const std::string &aName) const
std::map< std::pair< SCH_SCREEN *, uint32_t >, std::string > m_sourceGeneratedNetNames
void applyFont(EDA_TEXT *aText, int aFontIdx, bool aTemplateFont=true) const
std::map< std::pair< SCH_SCREEN *, uint32_t >, std::set< std::string > > m_sourceNetNames
std::pair< std::string, int > libForInstance(const ORCAD_PLACED_INSTANCE &aInst, const PKG_KEY **aSourceUnit=nullptr)
Returns the registered library name and unit number.
static void offsetPage(ORCAD_RAW_PAGE &aPage, int aDx, int aDy)
aDx and aDy must be multiples of the 10-DBU grid.
VECTOR2I textSize(int aFontIdx, bool aTemplateFont=true) const
Preserve an explicit LOGFONT width while retaining natural font aspect when it is zero.
std::string unitLetter(const ORCAD_PLACED_INSTANCE &aInst) const
The unit key includes a non-Normal view so DeMorgan graphics remain distinct.
static std::string SymbolId(const std::string &aName)
LIB_ID-safe symbol name: ':', '"', '/' and whitespace runs -> '_'; "SYM" if empty.
bool isPowerNetName(const std::string &aName) const
bool hasImplicitPowerPinName(const ORCAD_PLACED_INSTANCE &aInstance, size_t aPinIndex, const std::string &aNetName) const
std::map< PKG_KEY, std::pair< std::string, int > > m_preparedPkgToLib
std::string m_currentFlatNetSuffix
void addSymbolPrimitive(LIB_SYMBOL *aSymbol, const ORCAD_PRIMITIVE &aPrim, int aUnit, int aColor, int aOffsetX=0, int aOffsetY=0)
bool m_scopeGeneratedFlatNets
std::vector< PLACED_PACKAGE_UNIT > m_placedPackageUnits
ORCAD_SYMBOL_DEF synthesizeSymbol(const std::string &aPkgName, const std::vector< const ORCAD_PLACED_INSTANCE * > &aInstances) const
Use placed pin positions to keep uncached symbols connected.
std::tuple< std::string, std::string, int, std::string > PKG_KEY
(sourcePackage-or-pkgName, pkgName, variant index, unit discriminator) -> (lib name,...
static constexpr int MARGIN_T_DBU
void placeHierarchicalBlockFields(SCH_SHEET *aSheet, const ORCAD_DRAWN_INSTANCE &aBlock, const std::string &aChildFolder)
void placeGraphics(const ORCAD_RAW_PAGE &aPage, SCH_SCREEN *aScreen)
const std::map< uint32_t, std::string > * m_currentOccNetNames
std::string powerLibFor(const std::string &aSymbolName, const std::string &aNetName)
Key power symbols by net name because users can rename their ports.
void placeHierarchicalBlockPinFill(SCH_SCREEN *aScreen, SCH_SHEET_PIN *aPin)
std::vector< SCH_ITEM * > m_pageItems
void placeWires(const ORCAD_RAW_PAGE &aPage, SCH_SCREEN *aScreen, bool aHierarchical, bool aNestedHierarchy, bool aSharedFolderPage)
int textSizeIU(int aFontIdx, bool aTemplateFont=true) const
std::map< std::string, std::map< std::string, std::string > > m_hierBusNamesByScreen
void warn(const wxString &aMsg)
– reporting [orcad_converter_sheet.cpp] ---------------------------------------—
std::map< std::string, std::string > m_globalNetAliases
std::map< std::string, std::string > m_currentUnconnectedInterfaceNetNames
std::string canonicalGlobalNetName(const std::string &aName) const
Return the design-wide spelling selected by prepareGlobalNetNames().
void applyMultilineSpacing(SCH_TEXT *aText, int aFontIdx, bool aTemplateFont=true) const
std::map< std::string, size_t > m_occurrenceNetNameMinDepth
std::vector< LIB_SYMBOL * > BuildSymbolLibrary()
The caller owns the returned library symbols.
void placePorts(const ORCAD_RAW_PAGE &aPage, SCH_SCREEN *aScreen, bool aHierarchical)
static constexpr const char * LIB_NICK
Symbol library nickname used in every emitted LIB_ID.
int wireAliasFontId(const ORCAD_ALIAS &aAlias) const
static VECTOR2I snapToWire(int aX, int aY, const ORCAD_WIRE &aWire)
Closest point (DBU) on a wire segment to (aX, aY); exact for H/V wires.
static constexpr int MARGIN_L_DBU
Page margins in DBU leave room for the KiCad frame and title block.
std::set< std::string > m_connectedBlockInterfaceNames
VECTOR2I placedPinElectricalPosition(const ORCAD_PLACED_INSTANCE &aInstance, size_t aPinIndex) const
std::string powerNet(const ORCAD_RAW_PAGE &aPage, const ORCAD_GRAPHIC_INST &aInst) const
std::map< std::pair< int, int >, std::vector< const ORCAD_WIRE * > > m_wireEndpoints
Per-page wire lookup: endpoint -> wires ending there.
void placeBusEntries(const ORCAD_RAW_PAGE &aPage, SCH_SCREEN *aScreen)
SCH_BUS_WIRE_ENTRY per bus entry (position x1,y1; size x2-x1, y2-y1).
std::set< std::string > m_nativePowerFamilies
std::optional< uint32_t > occurrenceNetIdFor(const std::string *aName) const
Return the occurrence net id owning aName, which the table identifies by address.
static wxString SanitizeFileName(const std::string &aName)
std::map< std::string, std::string > m_globalNetNames
int fontHeightDbu(int aFontIdx, bool aTemplateFont=true) const
|lfHeight| of a Design Template font ID; ID 0 selects the template default.
void appendNetIntent(SCH_SCREEN *aScreen, SCH_LABEL *aLabel, bool aExplicitName, uint32_t aNetId=0)
std::set< std::string > m_powerNetNames
std::string effectiveInterfaceNetName(const std::string &aName) const
std::map< std::string, std::string > effectiveProps(const ORCAD_PLACED_INSTANCE &aInst, const ORCAD_SYMBOL_DEF &aDef) const
Empty package and placement values must not clear a library property.
void placeOffpageConnectors(const ORCAD_RAW_PAGE &aPage, SCH_SCREEN *aScreen, const SCH_SHEET_PATH &aSheetPath, bool aHierarchical)
Keep computed intersheet references hidden; display the stored OrCAD IREF text.
A progress reporter interface for use in multi-threaded environments.
A pure virtual class used to derive REPORTER objects from.
Holds all the data relating to one schematic.
Base class for any item which can be embedded within the SCHEMATIC container class,...
Segment description base class to describe items which have 2 end points (track, wire,...
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Define a sheet pin (label) used in sheets to create hierarchical schematics.
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
constexpr ORCAD_ORIENT_ENTRY ORCAD_ORIENT_TABLE[8]
Indexed by orientation bits: angle, mirror, offset selectors, then matrix coefficients.
int OrcadDisplayType(const ORCAD_DISPLAY_PROP &aProp)
VECTOR2I OrcadDbuToIu(int aX, int aY)
bool OrcadDisplayPropShowsName(const ORCAD_DISPLAY_PROP &aProp)
FILL_T OrcadFillType(int aFillStyle, int aHatchStyle)
VECTOR2I OrcadTransformPoint(int aOrient, int aWidth, int aHeight, int aBaseX, int aBaseY, int aPx, int aPy)
Parts use the instance anchor as the base.
int OrcadOrientDim(int aSelector, int aWidth, int aHeight)
int OrcadLineWidthIu(int aWidth)
std::pair< double, double > OrcadDashRatios(int aFormatVersionMajor)
int OrcadTextBaselineOffset(int aTextSize)
std::vector< SEG > OrcadHatchLines(const EDA_SHAPE &aShape, int aHatchStyle, int aPitch)
int OrcadPageOrder(wxString &aName)
Return a numeric page prefix (or -1); strip only the "N - title" convention.
int OrcadHatchPitchIu(uint32_t aModifyTimestamp)
bool OrcadDisplayPropShowsValue(const ORCAD_DISPLAY_PROP &aProp)
int OrcadHatchLineWidthIu(uint32_t aModifyTimestamp)
KIGFX::COLOR4D OrcadColor(int aColorIndex)
int OrcadOrientOf(int aRotation, bool aMirror)
Compose the 3-bit orientation code from the rotation bits and mirror bit.
int OrcadDisplayFontId(const ORCAD_DISPLAY_PROP &aProp)
wxString OrcadPinNameMarkup(const wxString &aName)
constexpr int ORCAD_IU_PER_DBU
Schematic internal units per OrCAD DBU: 10 mil * 254 IU/mil.
bool OrcadDisplayPropVisible(const ORCAD_DISPLAY_PROP &aProp)
LINE_STYLE OrcadLineStyle(int aStyle)
VECTOR2I OrcadOrientOffset(int aOrient, int aWidth, int aHeight)
Bbox re-anchoring offset for the given orientation and body size (DBU).
int OrcadPageGraphicLineWidthIu(int aWidth)
VECTOR2I OrcadStretchedImageSize(int aWidth, int aHeight, int aBoxWidth, int aBoxHeight)
LINE_STYLE
Dashed line types.
The owning wire defines the connection.
std::vector< SCH_LINE * > wires
One emitted KiCad lib symbol (possibly multi-unit).
std::string name
lib item name (no nickname)
std::unique_ptr< LIB_SYMBOL > kicadSymbol
built lazily by kicadSymbolFor()
std::vector< UNIT_INFO > units
sorted by letter; unit numbers are 1-based indices
std::string powerNet
power symbols are keyed by NET name
One resolved off-page connector: index into page.offpage, net, pin position.
const PKG_KEY * sourceUnit
std::optional< KIID > libraryPin
– shared bookkeeping types ------------------------------------------------—
std::vector< int > pinOffsets
hidden duplicate-pin electrical offsets, DBU
std::vector< bool > pinIgnore
package pins suppressed for this unit
const ORCAD_SYMBOL_DEF * symbol
std::vector< bool > explicitPinNets
placed pins whose source net overrides implicit power naming
std::vector< std::string > pinNumbers
device pin-number map for this unit
std::string letter
unit discriminator, e.g. "A", "-16", "B:Convert"
bool operator==(const UNIT_INFO &) const =default
std::vector< bool > pinNumberVisible
nonblank source package pin numbers
Child-folder pages are instantiated for each occurrence, with that occurrence's references.
Display positions use symbol coordinates; rotFont combines the font index and quarter turns.
The inline LibraryPart defines the block interface; placed pin records supply absolute positions.
Free graphics use nested primitive coordinates.
OrCAD rotates about the bounding box; KiCad rotates about the anchor.
char mirror
0 = none, 'x' or 'y' = KiCad mirror axis
int8_t tySel
Y offset selector.
int angle
KiCad placement angle in degrees (0/90/180/270, CCW)
int8_t txSel
X offset selector.
The placed box includes displayed text.
Primitive byte lengths can include or exclude the eight-byte size envelope.
Wire IDs refer to netmap, which supplies the source net names.
The bounding box occupies the final eight bytes before the next prefix stop.
Pin coordinates use symbol space with Y down.
The wire ID refers to the page net table.
VECTOR2< int32_t > VECTOR2I