Move all common CADSTAR Importer Parser code
Move all common code from CADSTAR_PCB_ARCHIVE_PARSER (pcbnew) to CADSTAR_ARCHIVE_PARSER (common)
This commit is contained in:
parent
c5c6b97c8b
commit
1b20a2910a
File diff suppressed because it is too large
Load Diff
|
@ -50,14 +50,210 @@
|
|||
#define THROW_PARSING_IO_ERROR( param, location ) \
|
||||
THROW_IO_ERROR( wxString::Format( _( "Unable to parse '%s' in '%s'" ), param, location ) )
|
||||
|
||||
//=================================
|
||||
// MACRO DEFINITIONS
|
||||
//=================================
|
||||
#define UNDEFINED_LAYER_ID ( LAYER_ID ) wxEmptyString
|
||||
|
||||
|
||||
/**
|
||||
* Component Name Attribute ID - typically used for placement of designators on silk screen.
|
||||
*/
|
||||
#define COMPONENT_NAME_ATTRID ( ATTRIBUTE_ID ) wxT( "__COMPONENT_NAME__" )
|
||||
|
||||
/**
|
||||
* Component Name 2 Attribute ID - typically used for indicating the placement of designators in
|
||||
* placement drawings.
|
||||
*/
|
||||
#define COMPONENT_NAME_2_ATTRID ( ATTRIBUTE_ID ) wxT( "__COMPONENT_NAME_2__" )
|
||||
#define PART_NAME_ATTRID ( ATTRIBUTE_ID ) wxT( "__PART_NAME__" )
|
||||
|
||||
|
||||
/**
|
||||
* @brief Helper functions and common structures for CADSTAR PCB and Schematic archive files.
|
||||
*/
|
||||
class CADSTAR_ARCHIVE_PARSER
|
||||
{
|
||||
public:
|
||||
typedef wxString LINECODE_ID;
|
||||
typedef wxString HATCHCODE_ID;
|
||||
typedef wxString ROUTECODE_ID;
|
||||
typedef wxString NETCLASS_ID;
|
||||
typedef wxString SPACING_CLASS_ID;
|
||||
typedef wxString TEXTCODE_ID;
|
||||
typedef wxString LAYER_ID; ///< ID of a Sheet (if schematic) or board Layer (if PCB)
|
||||
typedef wxString VARIANT_ID;
|
||||
typedef wxString ATTRIBUTE_ID;
|
||||
typedef wxString SYMDEF_ID;
|
||||
typedef wxString PART_ID;
|
||||
typedef wxString GATE_ID;
|
||||
typedef long TERMINAL_ID; ///< Terminal is the pin identifier in the schematic
|
||||
typedef long PART_DEFINITION_PIN_ID; ///< Pin identifier in the part definition
|
||||
typedef long PART_PIN_ID; ///< Pin identifier in the part
|
||||
typedef wxString TEXT_ID;
|
||||
typedef wxString FIGURE_ID;
|
||||
typedef wxString GROUP_ID;
|
||||
typedef wxString REUSEBLOCK_ID;
|
||||
typedef wxString NET_ID;
|
||||
typedef wxString NETELEMENT_ID;
|
||||
typedef wxString DOCUMENTATION_SYMBOL_ID;
|
||||
|
||||
static const long UNDEFINED_VALUE = -1;
|
||||
|
||||
|
||||
struct FORMAT
|
||||
{
|
||||
wxString Type;
|
||||
long SomeInt; ///< It is unclear what this parameter is used for
|
||||
long Version; ///< Archive version number (e.g. for PCB: 19=> CADSTAR 17.0 archive,
|
||||
///< 20=> CADSTAR 18.0 archive, 21 => CADSTAR 2018.0 / 2019.0 / 2020.0,
|
||||
///< etc.)
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct TIMESTAMP
|
||||
{
|
||||
long Year;
|
||||
long Month;
|
||||
long Day;
|
||||
long Hour;
|
||||
long Minute;
|
||||
long Second;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
//Note: there are possibly several other resolutions, but HUNDREDTH MICRON is only one known
|
||||
enum class RESOLUTION
|
||||
{
|
||||
HUNDREDTH_MICRON
|
||||
};
|
||||
|
||||
|
||||
struct HEADER
|
||||
{
|
||||
FORMAT Format;
|
||||
wxString JobFile;
|
||||
wxString JobTitle;
|
||||
wxString Generator;
|
||||
RESOLUTION Resolution;
|
||||
TIMESTAMP Timestamp;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct VARIANT ///< Nodename = "VARIANT" or "VMASTER" (master variant
|
||||
{
|
||||
VARIANT_ID ID = wxEmptyString;
|
||||
VARIANT_ID ParentID = wxEmptyString; ///< if empty, then this one is the master
|
||||
wxString Name = wxEmptyString;
|
||||
wxString Description = wxEmptyString;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct VARIANT_HIERARCHY
|
||||
{
|
||||
std::map<VARIANT_ID, VARIANT> Variants;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
enum class LINESTYLE
|
||||
{
|
||||
SOLID,
|
||||
DASH,
|
||||
DASHDOT,
|
||||
DASHDOTDOT,
|
||||
DOT
|
||||
};
|
||||
|
||||
|
||||
struct LINECODE
|
||||
{
|
||||
LINECODE_ID ID;
|
||||
wxString Name;
|
||||
long Width;
|
||||
LINESTYLE Style;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct HATCH
|
||||
{
|
||||
long Step;
|
||||
long LineWidth;
|
||||
long OrientAngle; ///< 1/1000 of a Degree
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct HATCHCODE
|
||||
{
|
||||
HATCHCODE_ID ID;
|
||||
wxString Name;
|
||||
std::vector<HATCH> Hatches;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
static const long FONT_NORMAL = 400;
|
||||
static const long FONT_BOLD = 700;
|
||||
|
||||
|
||||
struct FONT
|
||||
{
|
||||
wxString Name = wxT( "CADSTAR" );
|
||||
long Modifier1 = FONT_NORMAL; ///< It seems this is related to weight. 400=Normal, 700=Bold.
|
||||
long Modifier2 = 0; ///< It seems this is always 0 regardless of settings
|
||||
bool KerningPairs =
|
||||
false; ///< From CADSTAR Help: "Kerning Pairs is for causing the system to
|
||||
///< automatically reduce the spacing between certain pairs of
|
||||
///< characters in order to improve the appearance of the text"
|
||||
bool Italic = false;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct TEXTCODE
|
||||
{
|
||||
TEXTCODE_ID ID;
|
||||
wxString Name;
|
||||
long LineWidth;
|
||||
long Height;
|
||||
long Width; ///< Defaults to 0 if using system fonts or, if using CADSTAR font, default to
|
||||
///< equal height (1:1 aspect ratio). Allows for system fonts to be rendered in
|
||||
///< a different aspect ratio.
|
||||
FONT Font;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct ROUTECODE
|
||||
{
|
||||
//TODO: Generalise this so it can also be used with CSA files
|
||||
// (CSA files use "SROUTEWIDTH" subnode, instead of attribute)
|
||||
|
||||
ROUTECODE_ID ID;
|
||||
wxString Name;
|
||||
long OptimalWidth;
|
||||
long MinWidth;
|
||||
long MaxWidth;
|
||||
long NeckedWidth;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Represents a floating value in E notation
|
||||
*/
|
||||
|
@ -147,6 +343,755 @@ public:
|
|||
};
|
||||
|
||||
|
||||
enum class UNITS
|
||||
{
|
||||
DESIGN, ///< Inherits from design units (assumed Assignments->Technology->Units)
|
||||
THOU,
|
||||
INCH,
|
||||
MICROMETRE,
|
||||
MM,
|
||||
CENTIMETER,
|
||||
METER
|
||||
};
|
||||
|
||||
|
||||
static UNITS ParseUnits( XNODE* aNode );
|
||||
|
||||
|
||||
enum class ANGUNITS
|
||||
{
|
||||
DEGREES,
|
||||
RADIANS
|
||||
};
|
||||
|
||||
|
||||
static ANGUNITS ParseAngunits( XNODE* aNode );
|
||||
|
||||
|
||||
enum class GRID_TYPE
|
||||
{
|
||||
FRACTIONALGRID, ///< Param1 = Units, Param2 = Divisor. The grid is equal in X and Y
|
||||
///< dimensions with a step size equal to Param1/Param2
|
||||
STEPGRID ///< Param1 = X Step, Param2 = Y Step. A standard x,y grid.
|
||||
};
|
||||
|
||||
|
||||
struct GRID
|
||||
{
|
||||
GRID_TYPE Type;
|
||||
wxString Name;
|
||||
long Param1; ///< Either Units or X step, depending on Type (see GRID_TYPE for
|
||||
///< more details)
|
||||
long Param2; ///< Either Divisor or Y step, depending on Type (see GRID_TYPE for
|
||||
///< more details)
|
||||
|
||||
static bool IsGrid( XNODE* aNode );
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct GRIDS
|
||||
{
|
||||
GRID WorkingGrid;
|
||||
GRID ScreenGrid; ///< From CADSTAR Help: "There is one Screen Grid, which is
|
||||
///< visible as dots on the screen. You cannot specify your
|
||||
///< own name for the Screen Grid. The visibility and colour
|
||||
///< of the dots representing the Screen Grid is set up by
|
||||
///< the Highlight category on the Colours dialog.
|
||||
///<
|
||||
///< The type of Screen grid displayed(Lined or Points) is
|
||||
///< set up on the Display dialog within Options(File menu)."
|
||||
std::vector<GRID> UserGrids; ///< List of predefined grids created by the user
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct SETTINGS
|
||||
{
|
||||
UNITS Units; ///< Units to display for linear dimensions
|
||||
long UnitDisplPrecision; ///< Number of decimal points to display for linear dimensions
|
||||
long InterlineGap; ///< For CADSTAR font only, distance between lines of text,
|
||||
///< expressed as a percentage of the text height (accepted
|
||||
///< values are 0-100)
|
||||
long BarlineGap; ///< For CADSTAR font only, distance between top bar and
|
||||
///< character, expressed as a percentage of the text height
|
||||
///< (accepted values are 0-100)
|
||||
bool AllowBarredText = false; ///< Specifies if barring is allowed in the design
|
||||
long AngularPrecision; ///< Number of decimal points to display for angular dimensions
|
||||
|
||||
LONGPOINT DesignOrigin;
|
||||
std::pair<POINT, POINT> DesignArea;
|
||||
LONGPOINT DesignRef; ///< Appears to be 0,0 always
|
||||
LONGPOINT DesignLimit;
|
||||
|
||||
bool ParseSubNode( XNODE* aChildNode );
|
||||
virtual void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief From CADSTAR Help: "Text Alignment enables you to define the position of an alignment
|
||||
* origin for all text items in CADSTAR. The alignment origin is a point on or within the text
|
||||
* boundary and defines how the text is displayed.
|
||||
*
|
||||
* For example, with an alignment of bottom-right the origin will be positioned at the bottom
|
||||
* right of the text boundary. This makes it easier to right-align several text items
|
||||
* regardless of the length of text displayed.
|
||||
*
|
||||
* Text Alignment applies to all CADSTAR text. [...]
|
||||
*
|
||||
* Note: Unaligned text operates in the way CADSTAR text always has. In most cases this behaves
|
||||
* as Bottom Left alignment, but there are a few exceptions, e.g. pin names. Also unaligned
|
||||
* multiline text has an origin Bottom Left of the first line."
|
||||
*
|
||||
* See also JUSTIFICATION
|
||||
*/
|
||||
enum class ALIGNMENT
|
||||
{
|
||||
NO_ALIGNMENT, ///< NO_ALIGNMENT has different meaning depending on the object type
|
||||
TOPLEFT,
|
||||
TOPCENTER,
|
||||
TOPRIGHT,
|
||||
CENTERLEFT,
|
||||
CENTERCENTER,
|
||||
CENTERRIGHT,
|
||||
BOTTOMLEFT,
|
||||
BOTTOMCENTER,
|
||||
BOTTOMRIGHT
|
||||
};
|
||||
|
||||
|
||||
static ALIGNMENT ParseAlignment( XNODE* aNode );
|
||||
|
||||
/**
|
||||
* @brief From CADSTAR Help: "Multi Line Text can also be justified as Left, Centre or Right.
|
||||
* This does not affect the text alignment. Note: Justification of single line text has no
|
||||
* effect."
|
||||
*
|
||||
* This only affects multiline text
|
||||
*
|
||||
* See also ALIGNMENT
|
||||
*/
|
||||
enum class JUSTIFICATION
|
||||
{
|
||||
LEFT,
|
||||
CENTER,
|
||||
RIGHT
|
||||
};
|
||||
|
||||
|
||||
static JUSTIFICATION ParseJustification( XNODE* aNode );
|
||||
|
||||
/**
|
||||
* @brief Sets the readibility direction of text. From CADSTAR Help: "Horizontal text will
|
||||
* always be displayed from left to right (i.e. never upside down). Vertical text can be set as
|
||||
* readable from either the left or right edge of the design."
|
||||
*
|
||||
* I.e. Vertical text can either be rotated 90 degrees clockwise or 90 degrees anticlockwise from
|
||||
* horizontal. This does not impact vertical text
|
||||
*/
|
||||
enum class READABILITY
|
||||
{
|
||||
BOTTOM_TO_TOP, ///< When text is vertical, show it rotated 90 degrees anticlockwise
|
||||
TOP_TO_BOTTOM ///< When text is vertical, show it rotated 90 degrees clockwise
|
||||
};
|
||||
|
||||
|
||||
static READABILITY ParseReadability( XNODE* aNode );
|
||||
|
||||
|
||||
enum class ATTROWNER
|
||||
{
|
||||
ALL_ITEMS,
|
||||
AREA,
|
||||
BOARD,
|
||||
COMPONENT,
|
||||
CONNECTION,
|
||||
COPPER,
|
||||
DOCSYMBOL,
|
||||
FIGURE,
|
||||
NET,
|
||||
NETCLASS,
|
||||
PART, ///< Only library Attributes
|
||||
PART_DEFINITION, ///< Only library Attributes
|
||||
PIN,
|
||||
SYMDEF,
|
||||
TEMPLATE,
|
||||
TESTPOINT
|
||||
};
|
||||
|
||||
|
||||
enum class ATTRUSAGE
|
||||
{
|
||||
BOTH, ///< From CADSTAR Help: Assigned to both Schematic symbols and PCB components,
|
||||
///< and displayed on Schematic and PCB designs.
|
||||
COMPONENT, ///< From CADSTAR Help: Assigned to PCB components and displayed on PCB designs
|
||||
PART_DEFINITION, ///< From CADSTAR Help: Assigned to Parts library Definitions and displayed
|
||||
///< by the Library searcher
|
||||
PART_LIBRARY, ///< From CADSTAR Help: Only used by non-Cadstar applications
|
||||
SYMBOL, ///< From CADSTAR Help: Assigned to Schematic Symbols and displayed on
|
||||
///< Schematic Designs
|
||||
UNDEFINED ///< Note: It seems that some attribute have no "ATTRUSAGE" defined. It appears
|
||||
///< that the attributes that fall under this category arethe ones associated
|
||||
///< with the design itself (i.e. not inherited from the library)
|
||||
};
|
||||
|
||||
struct ATTRIBUTE_LOCATION
|
||||
{
|
||||
TEXTCODE_ID TextCodeID;
|
||||
LAYER_ID LayerID;
|
||||
POINT Position;
|
||||
long OrientAngle = 0;
|
||||
bool Mirror = false;
|
||||
bool Fixed = false;
|
||||
JUSTIFICATION Justification =
|
||||
JUSTIFICATION::LEFT; ///< Note: Justification has no effect on single lines of text
|
||||
ALIGNMENT Alignment = ALIGNMENT::
|
||||
NO_ALIGNMENT; ///< In CADSTAR The default alignment for a TEXT object (when
|
||||
///< "(No Alignment()" is selected) Bottom Left of the *first line*.
|
||||
///< Note that this is different from BOTTOM_LEFT (which is bottom
|
||||
///< left of the whole text block)
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief NOTE from CADSTAR help: To convert a Part Definition Attribute into a hyperlink, prefix
|
||||
* the attribute name with "Link "
|
||||
*/
|
||||
struct ATTRNAME
|
||||
{
|
||||
struct COLUMNORDER
|
||||
{
|
||||
long ID;
|
||||
long Order;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct COLUMNWIDTH
|
||||
{
|
||||
long ID;
|
||||
long Width;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
ATTRIBUTE_ID ID;
|
||||
wxString Name; ///< Parenthesis aren't permitted in user attributes in CADSTAR. Any
|
||||
///< Attributes in Parenthesis indicate an internal CADSTAR attribute
|
||||
///< Examples: "(PartDescription)" "(PartDefinitionNameStem)",etc.
|
||||
///TODO: create a list of all CADSTAR internal attribute names.
|
||||
ATTROWNER AttributeOwner = ATTROWNER::ALL_ITEMS;
|
||||
ATTRUSAGE AttributeUsage = ATTRUSAGE::UNDEFINED;
|
||||
bool NoTransfer = false; ///< True="All Design Types", False="Current Design Type"
|
||||
///< "All Design Types" Description from CADSTAR Help:
|
||||
///< "The selected attribute name will beavailable when
|
||||
///< any design is displayed"
|
||||
///< "Current Design Type" From CADSTAR Help: This
|
||||
///< restricts the availability of the selected attribute
|
||||
///< name to the current design.
|
||||
std::vector<COLUMNORDER> ColumnOrders;
|
||||
std::vector<COLUMNWIDTH> ColumnWidths;
|
||||
bool ColumnInvisible = false;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct ATTRIBUTE_VALUE
|
||||
{
|
||||
ATTRIBUTE_ID AttributeID;
|
||||
wxString Value;
|
||||
bool ReadOnly = false;
|
||||
bool HasLocation = false; ///< Flag to know if this ATTRIBUTE_VALUE has a location
|
||||
///< i.e. is displayed
|
||||
ATTRIBUTE_LOCATION AttributeLocation;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief Corresponds to CADSTAR "origin". This is used for setting a location of an attribute
|
||||
* e.g. Designator (called Component Name in CADSTAR), Part Name (name of component in the
|
||||
* library), etc. The atom identifier is "TEXTLOC"
|
||||
*/
|
||||
struct TEXT_LOCATION : ATTRIBUTE_LOCATION
|
||||
{
|
||||
TEXT_LOCATION()
|
||||
{
|
||||
// The default alignment for TEXT_LOCATION (when "NO_ALIGNMENT" is selected) is
|
||||
// Bottom left, matching CADSTAR's default behaviour
|
||||
Alignment = ALIGNMENT::BOTTOMLEFT;
|
||||
}
|
||||
ATTRIBUTE_ID AttributeID;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct NETCLASS
|
||||
{
|
||||
NETCLASS_ID ID;
|
||||
wxString Name;
|
||||
std::vector<ATTRIBUTE_VALUE> Attributes;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct SPCCLASSNAME
|
||||
{
|
||||
SPACING_CLASS_ID ID;
|
||||
wxString Name;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct CODEDEFS
|
||||
{
|
||||
std::map<LINECODE_ID, LINECODE> LineCodes;
|
||||
std::map<HATCHCODE_ID, HATCHCODE> HatchCodes;
|
||||
std::map<TEXTCODE_ID, TEXTCODE> TextCodes;
|
||||
std::map<ROUTECODE_ID, ROUTECODE> RouteCodes;
|
||||
std::map<ATTRIBUTE_ID, ATTRNAME> AttributeNames;
|
||||
std::map<NETCLASS_ID, NETCLASS> NetClasses;
|
||||
std::map<SPACING_CLASS_ID, SPCCLASSNAME> SpacingClassNames;
|
||||
|
||||
bool ParseSubNode( XNODE* aChildNode );
|
||||
virtual void Parse( XNODE* aNode ) = 0;
|
||||
};
|
||||
|
||||
/**
|
||||
* @brief Corresponds to "Display when" Item property. From CADSTAR
|
||||
* Help: "This parameter enables you to make the visibility of
|
||||
* a component outline/area (or an area of component copper, or
|
||||
* a string of component text) dependent on the current mirror
|
||||
* status of the component.
|
||||
*
|
||||
* For example, you may require a string of component text to
|
||||
* be displayed only when the component is mirrored."
|
||||
*/
|
||||
enum class SWAP_RULE
|
||||
{
|
||||
NO_SWAP, ///< Display when Unmirrored
|
||||
USE_SWAP_LAYER, ///< Display when Mirrored
|
||||
BOTH ///< Always display (Mirrored and Unmirrored)
|
||||
};
|
||||
|
||||
|
||||
static SWAP_RULE ParseSwapRule( XNODE* aNode );
|
||||
|
||||
|
||||
struct REUSEBLOCK
|
||||
{
|
||||
REUSEBLOCK_ID ID;
|
||||
wxString Name;
|
||||
wxString FileName; ///< Filename of the reuse block (usually a .pcb). Used for reloading
|
||||
bool Mirror = false;
|
||||
long OrientAngle = 0;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* @brief References an element from a design reuse block
|
||||
*/
|
||||
struct REUSEBLOCKREF
|
||||
{
|
||||
REUSEBLOCK_ID ReuseBlockID = wxEmptyString;
|
||||
wxString ItemReference = wxEmptyString; ///< For Components, this references the designator
|
||||
///< in the reuse file.
|
||||
///< For net elements (such as vias, routes, etc.),
|
||||
///< coppers and templates, this parameter is blank.
|
||||
|
||||
bool IsEmpty(); ///< Determines if this is empty (i.e. no design reuse associated)
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct GROUP
|
||||
{
|
||||
GROUP_ID ID;
|
||||
wxString Name;
|
||||
bool Fixed = false;
|
||||
GROUP_ID GroupID = wxEmptyString; ///< If not empty, this GROUP
|
||||
///< is part of another GROUP
|
||||
REUSEBLOCKREF ReuseBlockRef;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct FIGURE
|
||||
{
|
||||
FIGURE_ID ID;
|
||||
LINECODE_ID LineCodeID;
|
||||
LAYER_ID LayerID;
|
||||
SHAPE Shape; //< Uses the component's coordinate frame if within a component
|
||||
//< definition, otherwise uses the design's coordinate frame.
|
||||
GROUP_ID GroupID = wxEmptyString; ///< If not empty, this FIGURE is part of a group
|
||||
REUSEBLOCKREF ReuseBlockRef;
|
||||
SWAP_RULE SwapRule = SWAP_RULE::BOTH; ///< Only applicable to Figures in Components
|
||||
bool Fixed = false;
|
||||
std::map<ATTRIBUTE_ID, ATTRIBUTE_VALUE> AttributeValues;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct TEXT
|
||||
{
|
||||
TEXT_ID ID;
|
||||
wxString Text; //TODO: Need to lex/parse to identify design fields and hyperlinks
|
||||
TEXTCODE_ID TextCodeID;
|
||||
LAYER_ID LayerID;
|
||||
POINT Position;
|
||||
long OrientAngle = 0;
|
||||
bool Mirror = false;
|
||||
bool Fixed = false;
|
||||
SWAP_RULE SwapRule = SWAP_RULE::BOTH;
|
||||
JUSTIFICATION Justification =
|
||||
JUSTIFICATION::LEFT; ///< Note: Justification has no effect on single lines of text
|
||||
ALIGNMENT Alignment = ALIGNMENT::
|
||||
NO_ALIGNMENT; ///< In CADSTAR The default alignment for a TEXT object (when
|
||||
///< "(No Alignment()" is selected) Bottom Left of the *first line*.
|
||||
///< Note that this is different from BOTTOM_LEFT (which is bottom
|
||||
///< left of the whole text block)
|
||||
GROUP_ID GroupID = wxEmptyString; ///< If not empty, this FIGURE is part of a group
|
||||
REUSEBLOCKREF ReuseBlockRef;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct SYMDEF
|
||||
{
|
||||
SYMDEF_ID ID;
|
||||
wxString ReferenceName; ///< This is the name which identifies the symbol in the library
|
||||
///< Multiple components may exist with the same ReferenceName.
|
||||
wxString Alternate; ///< This is in addition to ReferenceName. It allows defining
|
||||
///< different versions, views etc. of the same basic symbol.
|
||||
POINT Origin; ///< Origin of the component (this is used as the reference point
|
||||
///< when placing the component in the design)
|
||||
bool Stub = false; ///< When the CADSTAR Archive file is exported without the
|
||||
///< component library, if components on the board are still
|
||||
///< exported, the Reference and Alternate names will still be
|
||||
///< exported but the content is replaced with a "STUB" atom,
|
||||
///< requiring access to the original library for component
|
||||
///< definition.
|
||||
long Version = UNDEFINED_VALUE; ///< Version is a sequential integer number to identify
|
||||
///< discrepancies between the library and the design.
|
||||
|
||||
std::map<FIGURE_ID, FIGURE> Figures;
|
||||
std::map<TEXT_ID, TEXT> Texts;
|
||||
std::map<ATTRIBUTE_ID, TEXT_LOCATION> TextLocations; ///< This contains location of
|
||||
///< any attributes, including
|
||||
///< designator position
|
||||
std::map<ATTRIBUTE_ID, ATTRIBUTE_VALUE> AttributeValues; ///< These attributes might also
|
||||
///< have a location
|
||||
|
||||
void ParseIdentifiers( XNODE* aNode );
|
||||
bool ParseSubNode( XNODE* aChildNode );
|
||||
virtual void Parse( XNODE* aNode ) = 0;
|
||||
};
|
||||
|
||||
|
||||
struct PART
|
||||
{
|
||||
enum class PIN_TYPE
|
||||
{
|
||||
UNCOMMITTED, ///< Uncomitted pin (default)
|
||||
INPUT, ///< Input pin
|
||||
OUTPUT_OR, ///< Output pin OR tieable
|
||||
OUTPUT_NOT_OR, ///< Output pin not OR tieable
|
||||
OUTPUT_NOT_NORM_OR, ///< Output pin not normally OR tieable
|
||||
POWER, ///< Power pin
|
||||
GROUND, ///< Ground pin
|
||||
TRISTATE_BIDIR, ///< Tristate bi-directional driver pin
|
||||
TRISTATE_INPUT, ///< Tristate input pin
|
||||
TRISTATE_DRIVER ///< Tristate output pin
|
||||
};
|
||||
|
||||
|
||||
static PIN_TYPE GetPinType( XNODE* aNode );
|
||||
|
||||
|
||||
struct DEFINITION ///< "PARTDEFINITION" node name
|
||||
{
|
||||
struct GATE ///< "GATEDEFINITION" node name
|
||||
{
|
||||
GATE_ID ID; ///< Usually "A", "B", "C", etc.
|
||||
wxString Name; ///< Symbol name in the symbol library
|
||||
wxString Alternate; ///< Symbol alternate name in the symbol library
|
||||
long PinCount; ///< Number of pins (terminals) in the symbol
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct PIN ///< "PARTDEFINITIONPIN" node name
|
||||
{
|
||||
/**
|
||||
* @brief Positioning of pin names can be in one of four quadrants
|
||||
*/
|
||||
enum class POSITION
|
||||
{
|
||||
TOP_RIGHT = 0, ///< Default
|
||||
TOP_LEFT = 1,
|
||||
BOTTOM_LEFT = 2,
|
||||
BOTTOM_RIGHT = 3
|
||||
};
|
||||
|
||||
PART_DEFINITION_PIN_ID ID;
|
||||
wxString Name = wxEmptyString; ///< Can be empty. If empty the pin name
|
||||
///< displayed wil be Identifier
|
||||
///< (subnode="PINNAME")
|
||||
wxString Label = wxEmptyString; ///< This Can be empty (subnode=
|
||||
///< "PINLABEL")
|
||||
///< From CADSTAR Help: "Pin
|
||||
///< Labels are an optional replacement
|
||||
///< for the free text sometimes placed
|
||||
///< in schematic symbols. Using Pin
|
||||
///< Labels instead has the advantage of
|
||||
///< associating each piece of label
|
||||
///< text with a particular pin. This
|
||||
///< means that the text remains
|
||||
///< correctly placed after any Gate and
|
||||
///< Pin Swaps are Back Annotated to the
|
||||
///< Schematic design."
|
||||
wxString Signal = wxEmptyString; ///< Usually for Power/Ground pins,
|
||||
///< (subnode="PINSIGNAL")
|
||||
GATE_ID TerminalGate; ///< (subnode="PINTERM", param0)
|
||||
TERMINAL_ID TerminalPin; ///< (subnode="PINTERM", param1)
|
||||
PIN_TYPE Type = PIN_TYPE::UNCOMMITTED; ///< subnode="PINTYPE"
|
||||
long Load = UNDEFINED_VALUE; ///< The electrical current expected on
|
||||
///< the pin (It is unclear what the units
|
||||
///< are, but only accepted values are
|
||||
///< integers) subnode ="PINLOAD"
|
||||
POSITION Position =
|
||||
POSITION::TOP_RIGHT; ///< The pin names will use these positions when
|
||||
///< the symbol is added to a schematic design
|
||||
///< subnode="PINPOSITION"
|
||||
|
||||
wxString Identifier =
|
||||
wxEmptyString; ///< This should match a pad identifier in the component
|
||||
///< footprint subnode="PINIDENTIFIER". It is assumed that
|
||||
///< this could be empty in earlier versions of CADSTAR
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct PIN_EQUIVALENCE ///< "PINEQUIVALENCE" Node name (represents "Equivalence")
|
||||
{
|
||||
std::vector<PART_DEFINITION_PIN_ID> PinIDs; ///< All the pins in this vector are
|
||||
///< equivalent and can be swapped with
|
||||
///< each other
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct SWAP_GATE ///< "SWAPGATE" Node name (represents an "Element")
|
||||
{
|
||||
std::vector<PART_DEFINITION_PIN_ID> PinIDs; ///< The pins in this vector
|
||||
///< describe a "gate"
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct SWAP_GROUP
|
||||
{
|
||||
wxString GateName =
|
||||
wxEmptyString; ///< Optional. If not empty, should match the Name
|
||||
///< attribute of one of the gates defined in the
|
||||
///< part definition
|
||||
|
||||
bool External = false; ///< Determines if this swap group is external (and internal)
|
||||
///< or internal only. External Gate swapping allows Gates on
|
||||
///< different components with the same Part Definition to
|
||||
///< swap with one another.
|
||||
///<
|
||||
///< The external swapping groups must be at the root level
|
||||
///< (i.e. they cannot be contained by other swapping groups)
|
||||
|
||||
std::vector<SWAP_GATE> SwapGates; ///< Each of the elements in this vector can be
|
||||
///< swapped with each other - i.e. *all* of the
|
||||
///< pins in each swap gate can be swapped with
|
||||
///< *all* in another swap gate defined in this
|
||||
///< vector
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
wxString Name; ///< This name can be different to the PART name
|
||||
bool HidePinNames; ///< Specifies whether to display the pin names/indentifier in
|
||||
///< the schematic symbol or not. E.g. it is useful to display
|
||||
///< pin name information for integrated circuits but less so
|
||||
///< for resistors and capacitors. (subnode HIDEPINNAMES)
|
||||
|
||||
long MaxPinCount =
|
||||
UNDEFINED_VALUE; ///< Optional parameter which is used for specifying the number
|
||||
///< of electrical pins on the PCB component symbol to be
|
||||
///< used in the part definition (this should not include
|
||||
///< mechanical pins for fixing etc.). This value must be less
|
||||
///< than or equal to than the number of pins on the PCB
|
||||
///< Component symbol.
|
||||
|
||||
std::map<GATE_ID, GATE> GateSymbols;
|
||||
std::map<PART_DEFINITION_PIN_ID, PIN> Pins;
|
||||
std::map<ATTRIBUTE_ID, ATTRIBUTE_VALUE> AttributeValues; ///< Some attributes are
|
||||
///< defined within the part
|
||||
///< definition, whilst others
|
||||
///< are defined in the part
|
||||
std::vector<PIN_EQUIVALENCE> PinEquivalences;
|
||||
std::vector<SWAP_GROUP> SwapGroups;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct PART_PIN ///< "PARTPIN" node name
|
||||
{
|
||||
PART_PIN_ID ID;
|
||||
wxString Name = wxEmptyString;
|
||||
PIN_TYPE Type = PIN_TYPE::UNCOMMITTED;
|
||||
wxString Identifier = wxEmptyString;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
PART_ID ID;
|
||||
wxString Name;
|
||||
long Version;
|
||||
DEFINITION Definition;
|
||||
std::map<PART_PIN_ID, PART_PIN> PartPins; ///< It is unclear why there are two "Pin"
|
||||
///< structures in CPA files... PART_PIN seems to
|
||||
///< be a reduced version of PART::DEFINITION::PIN
|
||||
///< Therefore, PART_PIN is only included for
|
||||
///< completeness of the parser, but won't be used
|
||||
|
||||
|
||||
std::map<ATTRIBUTE_ID, ATTRIBUTE_VALUE> AttributeValues; ///< Some attributes are defined
|
||||
///< within the part definition,
|
||||
///< whilst others are defined in
|
||||
///< the part itself
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct PARTS
|
||||
{
|
||||
std::map<PART_ID, PART> PartDefinitions;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct NET
|
||||
{
|
||||
struct JUNCTION ///< "JPT" nodename.
|
||||
{
|
||||
NETELEMENT_ID ID; ///< First character is "J"
|
||||
LAYER_ID LayerID;
|
||||
POINT Location;
|
||||
GROUP_ID GroupID = wxEmptyString; ///< If not empty, this JUCTION is part of a
|
||||
///< group
|
||||
REUSEBLOCKREF ReuseBlockRef;
|
||||
bool Fixed = false;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
struct CONNECTION ///< "CONN" nodename
|
||||
{
|
||||
NETELEMENT_ID StartNode;
|
||||
NETELEMENT_ID EndNode;
|
||||
ROUTECODE_ID RouteCodeID;
|
||||
|
||||
bool Fixed = false;
|
||||
bool Hidden = false;
|
||||
GROUP_ID GroupID = wxEmptyString; ///< If not empty, this connection is part of a group
|
||||
REUSEBLOCKREF ReuseBlockRef;
|
||||
|
||||
std::map<ATTRIBUTE_ID, ATTRIBUTE_VALUE> AttributeValues; ///< It is possible to add
|
||||
///< attributes solely to a
|
||||
///< particular connection
|
||||
void ParseIdentifiers( XNODE* aNode );
|
||||
bool ParseSubNode( XNODE* aChildNode );
|
||||
virtual void Parse( XNODE* aNode ) = 0;
|
||||
};
|
||||
|
||||
NET_ID ID;
|
||||
ROUTECODE_ID RouteCodeID = wxEmptyString; ///< "NETCODE" subnode
|
||||
long SignalNum = UNDEFINED_VALUE; ///< This is undefined if the net has been
|
||||
///< given a name. "SIGNUM" subnode.
|
||||
wxString Name = wxEmptyString; ///< This is undefined (wxEmptyString) if the net
|
||||
///< is unnamed. "SIGNAME" subnode
|
||||
bool Highlight = false;
|
||||
|
||||
std::map<NETELEMENT_ID, JUNCTION> Junctions;
|
||||
std::map<ATTRIBUTE_ID, ATTRIBUTE_VALUE> AttributeValues;
|
||||
|
||||
NETCLASS_ID NetClassID =
|
||||
wxEmptyString; ///< The net might not have a net class, in which case it will be
|
||||
///< wxEmptyString ("NETCLASSREF" subnode)
|
||||
SPACING_CLASS_ID SpacingClassID =
|
||||
wxEmptyString; ///< The net might not have a spacing class, in which case it will
|
||||
///< be wxEmptyString ("SPACINGCLASS" subnode)
|
||||
|
||||
void ParseIdentifiers( XNODE* aNode );
|
||||
bool ParseSubNode( XNODE* aChildNode );
|
||||
virtual void Parse( XNODE* aNode ) = 0;
|
||||
};
|
||||
|
||||
|
||||
struct DOCUMENTATION_SYMBOL
|
||||
{
|
||||
DOCUMENTATION_SYMBOL_ID ID;
|
||||
|
||||
SYMDEF_ID SymdefID; ///< Normally documentation symbols only have TEXT, FIGURE and
|
||||
///< TEXT_LOCATION objects which are all drawn on the "(Undefined)"
|
||||
///< Layer. When used in the design, the user has to specify which
|
||||
///< layer to draw it on.
|
||||
LAYER_ID LayerID; ///< Move all objects in the Symdef to this layer.
|
||||
POINT Origin; ///< Origin of the component (this is used as the reference point
|
||||
///< when placing the component in the design)
|
||||
|
||||
GROUP_ID GroupID = wxEmptyString; ///< If not empty, this component is part of a group
|
||||
REUSEBLOCKREF ReuseBlockRef;
|
||||
long OrientAngle = 0;
|
||||
bool Mirror = false;
|
||||
bool Fixed = false;
|
||||
READABILITY Readability = READABILITY::BOTTOM_TO_TOP;
|
||||
|
||||
long ScaleRatioNumerator = 1; ///< Documentation symbols can be arbitrarily scaled when
|
||||
///< added to a design
|
||||
long ScaleRatioDenominator = 1; ///< Documentation symbols can be arbitrarily scaled when
|
||||
///< added to a design
|
||||
|
||||
std::map<ATTRIBUTE_ID, ATTRIBUTE_VALUE> AttributeValues;
|
||||
|
||||
void Parse( XNODE* aNode );
|
||||
};
|
||||
|
||||
|
||||
///////////////////////
|
||||
// HELPER FUNCTIONS: //
|
||||
///////////////////////
|
||||
|
||||
|
||||
static void InsertAttributeAtEnd( XNODE* aNode, wxString aValue );
|
||||
|
||||
/**
|
||||
|
@ -172,7 +1117,7 @@ public:
|
|||
* @brief
|
||||
* @param aNode
|
||||
* @param aID
|
||||
* @return returns the value of attribute "attrX" in aNode where 'X' is aID
|
||||
* @return returns the value (wxString) of attribute "attrX" in aNode where 'X' is aID
|
||||
* @throws IO_ERROR if attribute does not exist
|
||||
*/
|
||||
static wxString GetXmlAttributeIDString( XNODE* aNode, unsigned int aID );
|
||||
|
@ -181,7 +1126,7 @@ public:
|
|||
* @brief
|
||||
* @param aNode
|
||||
* @param aID
|
||||
* @return returns the value of attribute "attrX" in aNode where 'X' is aID
|
||||
* @return returns the value (long) of attribute "attrX" in aNode where 'X' is aID
|
||||
* @throws IO_ERROR if attribute does not exist
|
||||
*/
|
||||
static long GetXmlAttributeIDLong( XNODE* aNode, unsigned int aID );
|
||||
|
|
|
@ -48,8 +48,8 @@ void CADSTAR_PCB_ARCHIVE_LOADER::Load( ::BOARD* aBoard )
|
|||
LONGPOINT designLimit = Assignments.Technology.DesignLimit;
|
||||
|
||||
//Note: can't use getKiCadPoint() due wxPoint being int - need long long to make the check
|
||||
long long designSizeXkicad = (long long) designLimit.x * KiCadUnitMultiplier;
|
||||
long long designSizeYkicad = (long long) designLimit.y * KiCadUnitMultiplier;
|
||||
long long designSizeXkicad = (long long) designLimit.x * KiCadUnitMultiplier;
|
||||
long long designSizeYkicad = (long long) designLimit.y * KiCadUnitMultiplier;
|
||||
|
||||
// Max size limited by the positive dimension of wxPoint (which is an int)
|
||||
long long maxDesignSizekicad = std::numeric_limits<int>::max();
|
||||
|
@ -92,7 +92,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::Load( ::BOARD* aBoard )
|
|||
loadCoppers();
|
||||
loadNets();
|
||||
|
||||
if( Layout.VariantHierarchy.size() > 0 )
|
||||
if( Layout.VariantHierarchy.Variants.size() > 0 )
|
||||
wxLogWarning(
|
||||
_( "The CADSTAR design contains variants which has no KiCad equivalent. All "
|
||||
"components have been loaded on top of each other. " ) );
|
||||
|
@ -402,8 +402,8 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadBoardStackup()
|
|||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadDesignRules()
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS& ds = mBoard->GetDesignSettings();
|
||||
std::map<SPACINGCODE_ID, SPACINGCODE>& spacingCodes = Assignments.Codedefs.SpacingCodes;
|
||||
BOARD_DESIGN_SETTINGS& ds = mBoard->GetDesignSettings();
|
||||
std::map<SPACINGCODE_ID, SPACINGCODE>& spacingCodes = Assignments.Codedefs.SpacingCodes;
|
||||
|
||||
auto applyRule =
|
||||
[&]( wxString aID, int* aVal )
|
||||
|
@ -438,16 +438,20 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadDesignRules()
|
|||
wxLogWarning( _( "KiCad design rules are different from CADSTAR ones. Only the compatible "
|
||||
"design rules were imported. It is recommended that you review the design "
|
||||
"rules that have been applied." ) );
|
||||
wxLogWarning(
|
||||
_( "KiCad design rules are different from CADSTAR ones. Only the compatible "
|
||||
"design rules were imported. It is recommended that you review the design "
|
||||
"rules that have been applied." ) );
|
||||
}
|
||||
|
||||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadComponentLibrary()
|
||||
{
|
||||
for( std::pair<SYMDEF_ID, SYMDEF> symPair : Library.ComponentDefinitions )
|
||||
for( std::pair<SYMDEF_ID, SYMDEF_PCB> symPair : Library.ComponentDefinitions )
|
||||
{
|
||||
SYMDEF_ID key = symPair.first;
|
||||
SYMDEF component = symPair.second;
|
||||
wxString moduleName = component.ReferenceName
|
||||
SYMDEF_ID key = symPair.first;
|
||||
SYMDEF_PCB component = symPair.second;
|
||||
wxString moduleName = component.ReferenceName
|
||||
+ ( ( component.Alternate.size() > 0 ) ?
|
||||
( wxT( " (" ) + component.Alternate + wxT( ")" ) ) :
|
||||
wxT( "" ) );
|
||||
|
@ -468,7 +472,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadComponentLibrary()
|
|||
}
|
||||
|
||||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryFigures( const SYMDEF& aComponent, MODULE* aModule )
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryFigures( const SYMDEF_PCB& aComponent, MODULE* aModule )
|
||||
{
|
||||
for( std::pair<FIGURE_ID, FIGURE> figPair : aComponent.Figures )
|
||||
{
|
||||
|
@ -482,7 +486,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryFigures( const SYMDEF& aComponent, M
|
|||
}
|
||||
|
||||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryCoppers( const SYMDEF& aComponent, MODULE* aModule )
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryCoppers( const SYMDEF_PCB& aComponent, MODULE* aModule )
|
||||
{
|
||||
for( COMPONENT_COPPER compCopper : aComponent.ComponentCoppers )
|
||||
{
|
||||
|
@ -496,7 +500,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryCoppers( const SYMDEF& aComponent, M
|
|||
}
|
||||
|
||||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryAreas( const SYMDEF& aComponent, MODULE* aModule )
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryAreas( const SYMDEF_PCB& aComponent, MODULE* aModule )
|
||||
{
|
||||
for( std::pair<COMP_AREA_ID, COMPONENT_AREA> areaPair : aComponent.ComponentAreas )
|
||||
{
|
||||
|
@ -504,8 +508,8 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryAreas( const SYMDEF& aComponent, MOD
|
|||
|
||||
if( area.NoVias || area.NoTracks )
|
||||
{
|
||||
ZONE_CONTAINER* zone =
|
||||
getZoneFromCadstarShape( area.Shape, getLineThickness( area.LineCodeID ), aModule );
|
||||
ZONE_CONTAINER* zone = getZoneFromCadstarShape(
|
||||
area.Shape, getLineThickness( area.LineCodeID ), aModule );
|
||||
|
||||
aModule->Add( zone, ADD_MODE::APPEND );
|
||||
|
||||
|
@ -541,7 +545,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryAreas( const SYMDEF& aComponent, MOD
|
|||
}
|
||||
|
||||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryPads( const SYMDEF& aComponent, MODULE* aModule )
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryPads( const SYMDEF_PCB& aComponent, MODULE* aModule )
|
||||
{
|
||||
for( std::pair<PAD_ID, PAD> padPair : aComponent.Pads )
|
||||
{
|
||||
|
@ -549,8 +553,9 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryPads( const SYMDEF& aComponent, MODU
|
|||
PADCODE csPadcode = getPadCode( csPad.PadCodeID );
|
||||
|
||||
D_PAD* pad = new D_PAD( aModule );
|
||||
aModule->Add( pad, ADD_MODE::INSERT ); // insert so that we get correct behaviour when finding pads
|
||||
// in the module by PAD_ID - see loadNets()
|
||||
aModule->Add( pad,
|
||||
ADD_MODE::INSERT ); // insert so that we get correct behaviour when finding pads
|
||||
// in the module by PAD_ID - see loadNets()
|
||||
|
||||
switch( csPad.Side )
|
||||
{
|
||||
|
@ -673,7 +678,8 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadLibraryPads( const SYMDEF& aComponent, MODU
|
|||
if( csPadcode.ReliefWidth != UNDEFINED_VALUE )
|
||||
pad->SetThermalSpokeWidth( getKiCadLength( csPadcode.ReliefWidth ) );
|
||||
|
||||
pad->SetOrientation( pad->GetOrientation() + getAngleTenthDegree( csPadcode.Shape.OrientAngle ) );
|
||||
pad->SetOrientation(
|
||||
pad->GetOrientation() + getAngleTenthDegree( csPadcode.Shape.OrientAngle ) );
|
||||
|
||||
if( csPadcode.DrillDiameter != UNDEFINED_VALUE )
|
||||
{
|
||||
|
@ -732,7 +738,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadGroups()
|
|||
}
|
||||
else
|
||||
{
|
||||
PCB_GROUP* kiCadGroup = mGroupMap.at( csGroup.ID );
|
||||
PCB_GROUP* kiCadGroup = mGroupMap.at( csGroup.ID );
|
||||
PCB_GROUP* parentGroup = mGroupMap.at( csGroup.GroupID );
|
||||
parentGroup->AddItem( kiCadGroup );
|
||||
}
|
||||
|
@ -745,7 +751,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadBoards()
|
|||
{
|
||||
for( std::pair<BOARD_ID, BOARD> boardPair : Layout.Boards )
|
||||
{
|
||||
BOARD& board = boardPair.second;
|
||||
BOARD& board = boardPair.second;
|
||||
GROUP_ID boardGroup = createUniqueGroupID( wxT( "Board" ) );
|
||||
drawCadstarShape( board.Shape, PCB_LAYER_ID::Edge_Cuts,
|
||||
getLineThickness( board.LineCodeID ), wxString::Format( "BOARD %s", board.ID ),
|
||||
|
@ -969,12 +975,12 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadDocumentationSymbols()
|
|||
docSymInstance.SymdefID ) );
|
||||
}
|
||||
|
||||
SYMDEF& docSymDefinition = ( *docSymIter ).second;
|
||||
wxPoint moveVector =
|
||||
SYMDEF_PCB& docSymDefinition = ( *docSymIter ).second;
|
||||
wxPoint moveVector =
|
||||
getKiCadPoint( docSymInstance.Origin ) - getKiCadPoint( docSymDefinition.Origin );
|
||||
double rotationAngle = getAngleTenthDegree( docSymInstance.OrientAngle );
|
||||
double scalingFactor =
|
||||
(double) docSymInstance.ScaleRatioNumerator / (double) docSymInstance.ScaleRatioDenominator;
|
||||
double rotationAngle = getAngleTenthDegree( docSymInstance.OrientAngle );
|
||||
double scalingFactor = (double) docSymInstance.ScaleRatioNumerator
|
||||
/ (double) docSymInstance.ScaleRatioDenominator;
|
||||
wxPoint centreOfTransform = getKiCadPoint( docSymDefinition.Origin );
|
||||
bool mirrorInvert = docSymInstance.Mirror;
|
||||
|
||||
|
@ -1004,8 +1010,8 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadDocumentationSymbols()
|
|||
for( std::pair<TEXT_ID, TEXT> textPair : docSymDefinition.Texts )
|
||||
{
|
||||
TEXT txt = textPair.second;
|
||||
drawCadstarText( txt, mBoard, groupID, docSymInstance.LayerID, moveVector, rotationAngle,
|
||||
scalingFactor, centreOfTransform, mirrorInvert );
|
||||
drawCadstarText( txt, mBoard, groupID, docSymInstance.LayerID, moveVector,
|
||||
rotationAngle, scalingFactor, centreOfTransform, mirrorInvert );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1025,7 +1031,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadTemplates()
|
|||
zone->SetZoneName( csTemplate.Name );
|
||||
zone->SetLayer( getKiCadLayer( csTemplate.LayerID ) );
|
||||
|
||||
if( !(csTemplate.NetID.IsEmpty() || csTemplate.NetID == wxT("NONE") ) )
|
||||
if( !( csTemplate.NetID.IsEmpty() || csTemplate.NetID == wxT( "NONE" ) ) )
|
||||
zone->SetNet( getKiCadNet( csTemplate.NetID ) );
|
||||
|
||||
if( csTemplate.Pouring.AllowInNoRouting )
|
||||
|
@ -1109,15 +1115,16 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadTemplates()
|
|||
//Now create power plane layers:
|
||||
for( LAYER_ID layer : mPowerPlaneLayers )
|
||||
{
|
||||
wxASSERT( Assignments.Layerdefs.Layers.find( layer ) != Assignments.Layerdefs.Layers.end() );
|
||||
wxASSERT(
|
||||
Assignments.Layerdefs.Layers.find( layer ) != Assignments.Layerdefs.Layers.end() );
|
||||
|
||||
//The net name will equal the layer name
|
||||
wxString powerPlaneLayerName = Assignments.Layerdefs.Layers.at( layer ).Name;
|
||||
NET_ID netid = wxEmptyString;
|
||||
NET_ID netid = wxEmptyString;
|
||||
|
||||
for( std::pair<NET_ID, NET> netPair : Layout.Nets )
|
||||
for( std::pair<NET_ID, NET_PCB> netPair : Layout.Nets )
|
||||
{
|
||||
NET net = netPair.second;
|
||||
NET_PCB net = netPair.second;
|
||||
|
||||
if( net.Name == powerPlaneLayerName )
|
||||
{
|
||||
|
@ -1155,11 +1162,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadTemplates()
|
|||
zone->SetNet( getKiCadNet( netid ) );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
@ -1193,7 +1196,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadCoppers()
|
|||
getDrawSegmentsFromVertices( csCopper.Shape.Vertices );
|
||||
|
||||
std::vector<TRACK*> outlineTracks = makeTracksFromDrawsegments( outlineSegments, mBoard,
|
||||
getKiCadNet(csCopper.NetRef.NetID) , getKiCadLayer( csCopper.LayerID ),
|
||||
getKiCadNet( csCopper.NetRef.NetID ), getKiCadLayer( csCopper.LayerID ),
|
||||
getKiCadLength( getCopperCode( csCopper.CopperCodeID ).CopperWidth ) );
|
||||
|
||||
//cleanup
|
||||
|
@ -1251,15 +1254,15 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadCoppers()
|
|||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadNets()
|
||||
{
|
||||
for( std::pair<NET_ID, NET> netPair : Layout.Nets )
|
||||
for( std::pair<NET_ID, NET_PCB> netPair : Layout.Nets )
|
||||
{
|
||||
NET net = netPair.second;
|
||||
NET_PCB net = netPair.second;
|
||||
wxString netnameForErrorReporting = net.Name;
|
||||
|
||||
if( netnameForErrorReporting.IsEmpty() )
|
||||
netnameForErrorReporting = wxString::Format( "$%ld", net.SignalNum );
|
||||
|
||||
for( NET::CONNECTION connection : net.Connections )
|
||||
for( NET_PCB::CONNECTION_PCB connection : net.Connections )
|
||||
{
|
||||
if( !connection.Unrouted )
|
||||
loadNetTracks( net.ID, connection.Route );
|
||||
|
@ -1267,16 +1270,16 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadNets()
|
|||
//TODO: all other elements
|
||||
}
|
||||
|
||||
for( std::pair<NETELEMENT_ID, NET::VIA> viaPair : net.Vias )
|
||||
for( std::pair<NETELEMENT_ID, NET_PCB::VIA> viaPair : net.Vias )
|
||||
{
|
||||
NET::VIA via = viaPair.second;
|
||||
NET_PCB::VIA via = viaPair.second;
|
||||
loadNetVia( net.ID, via );
|
||||
}
|
||||
|
||||
for( std::pair<NETELEMENT_ID, NET::PIN> pinPair : net.Pins )
|
||||
for( std::pair<NETELEMENT_ID, NET_PCB::PIN> pinPair : net.Pins )
|
||||
{
|
||||
NET::PIN pin = pinPair.second;
|
||||
MODULE* m = getModuleFromCadstarID( pin.ComponentID );
|
||||
NET_PCB::PIN pin = pinPair.second;
|
||||
MODULE* m = getModuleFromCadstarID( pin.ComponentID );
|
||||
|
||||
if( m == nullptr )
|
||||
{
|
||||
|
@ -1340,13 +1343,13 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadComponentAttributes(
|
|||
|
||||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadNetTracks(
|
||||
const NET_ID& aCadstarNetID, const NET::ROUTE& aCadstarRoute )
|
||||
const NET_ID& aCadstarNetID, const NET_PCB::ROUTE& aCadstarRoute )
|
||||
{
|
||||
std::vector<DRAWSEGMENT*> dsVector;
|
||||
|
||||
POINT prevEnd = aCadstarRoute.StartPoint;
|
||||
|
||||
for( const NET::ROUTE_VERTEX& v : aCadstarRoute.RouteVertices )
|
||||
for( const NET_PCB::ROUTE_VERTEX& v : aCadstarRoute.RouteVertices )
|
||||
{
|
||||
DRAWSEGMENT* ds = getDrawSegmentFromVertex( prevEnd, v.Vertex );
|
||||
ds->SetLayer( getKiCadLayer( aCadstarRoute.LayerID ) );
|
||||
|
@ -1369,7 +1372,7 @@ void CADSTAR_PCB_ARCHIVE_LOADER::loadNetTracks(
|
|||
|
||||
|
||||
void CADSTAR_PCB_ARCHIVE_LOADER::loadNetVia(
|
||||
const NET_ID& aCadstarNetID, const NET::VIA& aCadstarVia )
|
||||
const NET_ID& aCadstarNetID, const NET_PCB::VIA& aCadstarVia )
|
||||
{
|
||||
VIA* via = new VIA( mBoard );
|
||||
mBoard->Add( via, ADD_MODE::APPEND );
|
||||
|
@ -1770,8 +1773,8 @@ DRAWSEGMENT* CADSTAR_PCB_ARCHIVE_LOADER::getDrawSegmentFromVertex( const POINT&
|
|||
}
|
||||
|
||||
|
||||
ZONE_CONTAINER* CADSTAR_PCB_ARCHIVE_LOADER::getZoneFromCadstarShape(
|
||||
const SHAPE& aCadstarShape, const int& aLineThickness, BOARD_ITEM_CONTAINER* aParentContainer )
|
||||
ZONE_CONTAINER* CADSTAR_PCB_ARCHIVE_LOADER::getZoneFromCadstarShape( const SHAPE& aCadstarShape,
|
||||
const int& aLineThickness, BOARD_ITEM_CONTAINER* aParentContainer )
|
||||
{
|
||||
ZONE_CONTAINER* zone = new ZONE_CONTAINER( aParentContainer, isModule( aParentContainer ) );
|
||||
|
||||
|
@ -2026,7 +2029,8 @@ void CADSTAR_PCB_ARCHIVE_LOADER::addAttribute( const ATTRIBUTE_LOCATION& aCadsta
|
|||
txt->SetPos0( rotatedTextPos );
|
||||
txt->SetLayer( getKiCadLayer( aCadstarAttrLoc.LayerID ) );
|
||||
txt->SetMirrored( aCadstarAttrLoc.Mirror );
|
||||
txt->SetTextAngle( getAngleTenthDegree( aCadstarAttrLoc.OrientAngle ) - aModule->GetOrientation() );
|
||||
txt->SetTextAngle(
|
||||
getAngleTenthDegree( aCadstarAttrLoc.OrientAngle ) - aModule->GetOrientation() );
|
||||
|
||||
TEXTCODE tc = getTextCode( aCadstarAttrLoc.TextCodeID );
|
||||
|
||||
|
@ -2205,7 +2209,8 @@ CADSTAR_PCB_ARCHIVE_LOADER::HATCHCODE CADSTAR_PCB_ARCHIVE_LOADER::getHatchCode(
|
|||
}
|
||||
|
||||
|
||||
double CADSTAR_PCB_ARCHIVE_LOADER::getHatchCodeAngleDegrees( const HATCHCODE_ID& aCadstarHatchcodeID )
|
||||
double CADSTAR_PCB_ARCHIVE_LOADER::getHatchCodeAngleDegrees(
|
||||
const HATCHCODE_ID& aCadstarHatchcodeID )
|
||||
{
|
||||
checkAndLogHatchCode( aCadstarHatchcodeID );
|
||||
HATCHCODE hcode = getHatchCode( aCadstarHatchcodeID );
|
||||
|
@ -2278,7 +2283,8 @@ void CADSTAR_PCB_ARCHIVE_LOADER::checkAndLogHatchCode( const HATCHCODE_ID& aCads
|
|||
"hatching uses the width defined in the first hatch definition, i.e. "
|
||||
"%.2f mm." ),
|
||||
hcode.Name,
|
||||
(double) ((double) getKiCadLength( hcode.Hatches.at( 0 ).LineWidth ) ) / 1E6 ) );
|
||||
(double) ( (double) getKiCadLength( hcode.Hatches.at( 0 ).LineWidth ) )
|
||||
/ 1E6 ) );
|
||||
}
|
||||
|
||||
if( hcode.Hatches.at( 0 ).Step != hcode.Hatches.at( 1 ).Step )
|
||||
|
@ -2347,13 +2353,13 @@ NETINFO_ITEM* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadNet( const NET_ID& aCadstarNet
|
|||
return nullptr;
|
||||
else if( mNetMap.find( aCadstarNetID ) != mNetMap.end() )
|
||||
{
|
||||
return mNetMap.at(aCadstarNetID);
|
||||
return mNetMap.at( aCadstarNetID );
|
||||
}
|
||||
else
|
||||
{
|
||||
wxCHECK( Layout.Nets.find( aCadstarNetID ) != Layout.Nets.end(), nullptr );
|
||||
|
||||
NET csNet = Layout.Nets.at( aCadstarNetID );
|
||||
NET_PCB csNet = Layout.Nets.at( aCadstarNetID );
|
||||
wxString newName = csNet.Name;
|
||||
|
||||
if( csNet.Name.IsEmpty() )
|
||||
|
@ -2362,12 +2368,12 @@ NETINFO_ITEM* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadNet( const NET_ID& aCadstarNet
|
|||
{
|
||||
// Create default KiCad net naming:
|
||||
|
||||
NET::PIN firstPin = (*csNet.Pins.begin()).second;
|
||||
NET_PCB::PIN firstPin = ( *csNet.Pins.begin() ).second;
|
||||
//we should have already loaded the component with loadComponents() :
|
||||
MODULE* m = getModuleFromCadstarID( firstPin.ComponentID );
|
||||
newName = wxT( "Net-(" );
|
||||
newName << m->Reference().GetText();
|
||||
newName << "-Pad" << wxString::Format( "%i", firstPin.PadID) << ")";
|
||||
newName << "-Pad" << wxString::Format( "%i", firstPin.PadID ) << ")";
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2380,11 +2386,11 @@ NETINFO_ITEM* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadNet( const NET_ID& aCadstarNet
|
|||
if( !mDoneNetClassWarning && !csNet.NetClassID.IsEmpty()
|
||||
&& csNet.NetClassID != wxT( "NONE" ) )
|
||||
{
|
||||
wxLogMessage( _(
|
||||
"The CADSTAR design contains nets with a 'Net Class' assigned. KiCad does "
|
||||
"not have an equivalent to CADSTAR's Net Class so these elements were not "
|
||||
"imported. Note: KiCad's version of 'Net Class' is closer to CADSTAR's "
|
||||
"'Net Route Code' (which has been imported for all nets)." ) );
|
||||
wxLogMessage(
|
||||
_( "The CADSTAR design contains nets with a 'Net Class' assigned. KiCad does "
|
||||
"not have an equivalent to CADSTAR's Net Class so these elements were not "
|
||||
"imported. Note: KiCad's version of 'Net Class' is closer to CADSTAR's "
|
||||
"'Net Route Code' (which has been imported for all nets)." ) );
|
||||
mDoneNetClassWarning = true;
|
||||
}
|
||||
|
||||
|
@ -2426,7 +2432,7 @@ NETINFO_ITEM* CADSTAR_PCB_ARCHIVE_LOADER::getKiCadNet( const NET_ID& aCadstarNet
|
|||
|
||||
PCB_LAYER_ID CADSTAR_PCB_ARCHIVE_LOADER::getKiCadCopperLayerID( unsigned int aLayerNum )
|
||||
{
|
||||
if(aLayerNum == Assignments.Technology.MaxPhysicalLayer)
|
||||
if( aLayerNum == Assignments.Technology.MaxPhysicalLayer )
|
||||
return PCB_LAYER_ID::B_Cu;
|
||||
|
||||
switch( aLayerNum )
|
||||
|
@ -2503,7 +2509,7 @@ PCB_LAYER_ID CADSTAR_PCB_ARCHIVE_LOADER::getKiCadLayer( const LAYER_ID& aCadstar
|
|||
|
||||
wxCHECK( mLayermap.find( aCadstarLayerID ) != mLayermap.end(), PCB_LAYER_ID::UNDEFINED_LAYER );
|
||||
|
||||
return mLayermap.at(aCadstarLayerID);
|
||||
return mLayermap.at( aCadstarLayerID );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -86,8 +86,8 @@ private:
|
|||
std::map<ROUTECODE_ID, NETCLASSPTR> mNetClassMap; ///< Map between Cadstar and KiCad classes
|
||||
std::map<PHYSICAL_LAYER_ID, LAYER_ID> mCopperLayers; ///< Map of CADSTAR Physical layers to
|
||||
///< CADSTAR Layer IDs
|
||||
std::vector<LAYER_ID> mPowerPlaneLayers; ///< List of layers that are marked as
|
||||
///< power plane in CADSTAR. This is used
|
||||
std::vector<LAYER_ID> mPowerPlaneLayers; ///< List of layers that are marked as
|
||||
///< power plane in CADSTAR. This is used
|
||||
///< by "loadtemplates"
|
||||
wxPoint mDesignCenter; ///< Used for calculating the required
|
||||
///< offset to apply to the Cadstar design
|
||||
|
@ -100,7 +100,7 @@ private:
|
|||
///< multiple duplicate warnings
|
||||
bool mDoneNetClassWarning; ///< Used by getKiCadNet() to avoid
|
||||
///< multiple duplicate warnings
|
||||
int mNumNets; ///< Number of nets loaded so far
|
||||
int mNumNets; ///< Number of nets loaded so far
|
||||
|
||||
|
||||
// Functions for loading individual elements:
|
||||
|
@ -122,13 +122,13 @@ private:
|
|||
// Helper functions for element loading:
|
||||
void logBoardStackupWarning(
|
||||
const wxString& aCadstarLayerName, const PCB_LAYER_ID& aKiCadLayer );
|
||||
void loadLibraryFigures( const SYMDEF& aComponent, MODULE* aModule );
|
||||
void loadLibraryCoppers( const SYMDEF& aComponent, MODULE* aModule );
|
||||
void loadLibraryAreas( const SYMDEF& aComponent, MODULE* aModule );
|
||||
void loadLibraryPads( const SYMDEF& aComponent, MODULE* aModule );
|
||||
void loadLibraryFigures( const SYMDEF_PCB& aComponent, MODULE* aModule );
|
||||
void loadLibraryCoppers( const SYMDEF_PCB& aComponent, MODULE* aModule );
|
||||
void loadLibraryAreas( const SYMDEF_PCB& aComponent, MODULE* aModule );
|
||||
void loadLibraryPads( const SYMDEF_PCB& aComponent, MODULE* aModule );
|
||||
void loadComponentAttributes( const COMPONENT& aComponent, MODULE* aModule );
|
||||
void loadNetTracks( const NET_ID& aCadstarNetID, const NET::ROUTE& aCadstarRoute );
|
||||
void loadNetVia( const NET_ID& aCadstarNetID, const NET::VIA& aCadstarVia );
|
||||
void loadNetTracks( const NET_ID& aCadstarNetID, const NET_PCB::ROUTE& aCadstarRoute );
|
||||
void loadNetVia( const NET_ID& aCadstarNetID, const NET_PCB::VIA& aCadstarVia );
|
||||
void checkAndLogHatchCode( const HATCHCODE_ID& aCadstarHatchcodeID );
|
||||
|
||||
//Helper functions for drawing /loading objects onto screen:
|
||||
|
@ -323,8 +323,8 @@ private:
|
|||
TEXTCODE getTextCode( const TEXTCODE_ID& aCadstarTextCodeID );
|
||||
VIACODE getViaCode( const VIACODE_ID& aCadstarViaCodeID );
|
||||
wxString getAttributeName( const ATTRIBUTE_ID& aCadstarAttributeID );
|
||||
wxString getAttributeValue( const ATTRIBUTE_ID& aCadstarAttributeID,
|
||||
const std::map<ATTRIBUTE_ID, ATTRIBUTE_VALUE>& aCadstarAttributeMap );
|
||||
wxString getAttributeValue( const ATTRIBUTE_ID& aCadstarAttributeID,
|
||||
const std::map<ATTRIBUTE_ID, ATTRIBUTE_VALUE>& aCadstarAttributeMap );
|
||||
|
||||
// Helper Functions for obtaining individual elements as KiCad elements:
|
||||
double getHatchCodeAngleDegrees( const HATCHCODE_ID& aCadstarHatchcodeID );
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue