1 /* 2 * This program source code file is part of KiCad, a free EDA CAD application. 3 * 4 * Copyright (C) 2020-2021 Roberto Fernandez Bautista <roberto.fer.bau@gmail.com> 5 * Copyright (C) 2020-2021 KiCad Developers, see AUTHORS.txt for contributors. 6 * 7 * This program is free software: you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation, either version 3 of the License, or (at your 10 * option) any later version. 11 * 12 * This program is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * You should have received a copy of the GNU General Public License along 18 * with this program. If not, see <http://www.gnu.org/licenses/>. 19 */ 20 21 /** 22 * @file cadstar_sch_archive_loader.h 23 * @brief Loads a csa file into a KiCad SCHEMATIC object 24 */ 25 26 #ifndef CADSTAR_SCH_ARCHIVE_LOADER_H_ 27 #define CADSTAR_SCH_ARCHIVE_LOADER_H_ 28 29 #include <sch_plugins/cadstar/cadstar_sch_archive_parser.h> 30 31 #include <layer_ids.h> // SCH_LAYER_ID 32 #include <plotters/plotter.h> // PLOT_DASH_TYPE 33 #include <pin_type.h> // ELECTRICAL_PINTYPE 34 #include <sch_io_mgr.h> 35 #include <wx/filename.h> 36 37 class BUS_ALIAS; 38 class EDA_TEXT; 39 class LABEL_SPIN_STYLE; 40 class LIB_FIELD; 41 class LIB_SYMBOL; 42 class SCH_SYMBOL; 43 class SCH_ITEM; 44 class SCH_FIELD; 45 class SCH_GLOBALLABEL; 46 class SCH_HIERLABEL; 47 class SCH_SHEET; 48 class SCH_SHEET_PATH; 49 class SCH_TEXT; 50 class SCHEMATIC; 51 52 class CADSTAR_SCH_ARCHIVE_LOADER : public CADSTAR_SCH_ARCHIVE_PARSER 53 { 54 public: 55 // Size of tiny net labels when none present in original design 56 const int SMALL_LABEL_SIZE = KiROUND( (double) SCH_IU_PER_MM * 0.4 ); 57 CADSTAR_SCH_ARCHIVE_LOADER(wxString aFilename,REPORTER * aReporter,PROGRESS_REPORTER * aProgressReporter)58 explicit CADSTAR_SCH_ARCHIVE_LOADER( wxString aFilename, REPORTER* aReporter, 59 PROGRESS_REPORTER* aProgressReporter ) : 60 CADSTAR_SCH_ARCHIVE_PARSER( aFilename ) 61 { 62 m_schematic = nullptr; 63 m_rootSheet = nullptr; 64 m_plugin = nullptr; 65 m_designCenter.x = 0; 66 m_designCenter.y = 0; 67 m_reporter = aReporter; 68 m_progressReporter = aProgressReporter; 69 } 70 71 ~CADSTAR_SCH_ARCHIVE_LOADER()72 ~CADSTAR_SCH_ARCHIVE_LOADER() 73 { 74 } 75 76 /** 77 * @brief Loads a CADSTAR PCB Archive file into the KiCad BOARD object given 78 * @param aSchematic Schematic to add the design onto 79 * @param aRootSheet Root sheet to add the design onto 80 */ 81 void Load( SCHEMATIC* aSchematic, SCH_SHEET* aRootSheet, 82 SCH_PLUGIN::SCH_PLUGIN_RELEASER* aSchPlugin, const wxFileName& aLibraryFileName ); 83 84 85 private: 86 typedef std::pair<BLOCK_ID, TERMINAL_ID> BLOCK_PIN_ID; 87 typedef std::pair<PART_ID, GATE_ID> PART_GATE_ID; 88 89 /** 90 * Map between a terminal ID in a symbol definition to the pin number that should 91 * be imported into KiCad. 92 */ 93 typedef std::map<TERMINAL_ID, wxString> TERMINAL_TO_PINNUM_MAP; 94 95 REPORTER* m_reporter; 96 SCHEMATIC* m_schematic; 97 SCH_SHEET* m_rootSheet; 98 SCH_PLUGIN::SCH_PLUGIN_RELEASER* m_plugin; 99 wxFileName m_libraryFileName; 100 wxPoint m_designCenter; ///< Used for calculating the required 101 ///< offset to apply to the Cadstar design 102 ///< so that it fits in KiCad canvas 103 std::map<LAYER_ID, SCH_SHEET*> m_sheetMap; ///< Map between Cadstar and KiCad Sheets 104 std::map<BLOCK_PIN_ID, SCH_HIERLABEL*> 105 m_sheetPinMap; ///< Map between Cadstar and KiCad Sheets Pins 106 std::map<PART_ID, LIB_SYMBOL*> m_partMap; ///< Map between Cadstar and KiCad Parts 107 std::map<PART_GATE_ID, SYMDEF_ID> m_partSymbolsMap; ///< Map holding the symbols loaded so far 108 /// for a particular PART_ID and GATE_ID 109 std::map<PART_ID, TERMINAL_TO_PINNUM_MAP> m_pinNumsMap; ///< Map of pin numbers in CADSTAR parts 110 std::map<wxString, LIB_SYMBOL*> m_powerSymLibMap; ///< Map of KiCad Power Symbol Library items 111 std::map<SYMBOL_ID, SCH_SYMBOL*> 112 m_powerSymMap; ///< Map between Cadstar and KiCad Power Symbols 113 std::map<SYMBOL_ID, SCH_GLOBALLABEL*> 114 m_globalLabelsMap; ///< Map between Cadstar and KiCad Global Labels 115 std::map<BUS_ID, std::shared_ptr<BUS_ALIAS>> m_busesMap; ///< Map of Cadstar and KiCad Buses 116 117 void loadSheets(); 118 void loadHierarchicalSheetPins(); 119 void loadPartsLibrary(); 120 void loadSchematicSymbolInstances(); 121 void loadBusses(); 122 void loadNets(); 123 void loadFigures(); 124 void loadTexts(); 125 void loadDocumentationSymbols(); 126 void loadTextVariables(); 127 128 //Helper Functions for loading sheets 129 void loadSheetAndChildSheets( LAYER_ID aCadstarSheetID, const wxPoint& aPosition, 130 wxSize aSheetSize, const SCH_SHEET_PATH& aParentSheet ); 131 132 void loadChildSheets( LAYER_ID aCadstarSheetID, const SCH_SHEET_PATH& aSheet ); 133 134 std::vector<LAYER_ID> findOrphanSheets(); 135 136 int getSheetNumber( LAYER_ID aCadstarSheetID ); 137 138 void loadItemOntoKiCadSheet( LAYER_ID aCadstarSheetID, SCH_ITEM* aItem ); 139 140 //Helper Functions for loading library items 141 void loadSymDefIntoLibrary( const SYMDEF_ID& aSymdefID, const PART* aCadstarPart, 142 const GATE_ID& aGateID, LIB_SYMBOL* aSymbol ); 143 144 void loadLibrarySymbolShapeVertices( const std::vector<VERTEX>& aCadstarVertices, 145 wxPoint aSymbolOrigin, LIB_SYMBOL* aSymbol, 146 int aGateNumber, int aLineThickness ); 147 148 void applyToLibraryFieldAttribute( const ATTRIBUTE_LOCATION& aCadstarAttrLoc, 149 wxPoint aSymbolOrigin, LIB_FIELD* aKiCadField ); 150 151 //Helper Functions for loading symbols in schematic 152 SCH_SYMBOL* loadSchematicSymbol( const SYMBOL& aCadstarSymbol, const LIB_SYMBOL& aKiCadPart, 153 double& aComponentOrientationDeciDeg ); 154 155 void loadSymbolFieldAttribute( const ATTRIBUTE_LOCATION& aCadstarAttrLoc, 156 const double& aComponentOrientationDeciDeg, bool aIsMirrored, 157 SCH_FIELD* aKiCadField ); 158 159 int getComponentOrientation( double aOrientAngleDeciDeg, double& aReturnedOrientationDeciDeg ); 160 161 //Helper functions for loading nets 162 POINT getLocationOfNetElement( const NET_SCH& aNet, const NETELEMENT_ID& aNetElementID ); 163 164 wxString getNetName( const NET_SCH& aNet ); 165 166 //Helper functions for loading figures / graphical items 167 void loadGraphicStaightSegment( const wxPoint& aStartPoint, const wxPoint& aEndPoint, 168 const LINECODE_ID& aCadstarLineCodeID, const LAYER_ID& aCadstarSheetID, 169 const SCH_LAYER_ID& aKiCadSchLayerID, const wxPoint& aMoveVector = { 0, 0 }, 170 const double& aRotationAngleDeciDeg = 0.0, const double& aScalingFactor = 1.0, 171 const wxPoint& aTransformCentre = { 0, 0 }, const bool& aMirrorInvert = false ); 172 173 void loadShapeVertices( const std::vector<VERTEX>& aCadstarVertices, 174 LINECODE_ID aCadstarLineCodeID, LAYER_ID aCadstarSheetID, SCH_LAYER_ID aKiCadSchLayerID, 175 const wxPoint& aMoveVector = { 0, 0 }, const double& aRotationAngleDeciDeg = 0.0, 176 const double& aScalingFactor = 1.0, const wxPoint& aTransformCentre = { 0, 0 }, 177 const bool& aMirrorInvert = false ); 178 179 void loadFigure( const FIGURE& aCadstarFigure, const LAYER_ID& aCadstarSheetIDOverride, 180 SCH_LAYER_ID aKiCadSchLayerID, const wxPoint& aMoveVector = { 0, 0 }, 181 const double& aRotationAngleDeciDeg = 0.0, const double& aScalingFactor = 1.0, 182 const wxPoint& aTransformCentre = { 0, 0 }, const bool& aMirrorInvert = false ); 183 184 //Helper functions for loading text elements 185 void applyTextSettings( EDA_TEXT* aKiCadTextItem, 186 const TEXTCODE_ID& aCadstarTextCodeID, 187 const ALIGNMENT& aCadstarAlignment, 188 const JUSTIFICATION& aCadstarJustification, 189 const long long aCadstarOrientAngle = 0, 190 bool aMirrored = false ); 191 192 SCH_TEXT* getKiCadSchText( const TEXT& aCadstarTextElement ); 193 194 195 //Helper Functions for obtaining CADSTAR elements from the parsed structures 196 SYMDEF_ID getSymDefFromName( const wxString& aSymdefName, const wxString& aSymDefAlternate ); 197 bool isAttributeVisible( const ATTRIBUTE_ID& aCadstarAttributeID ); 198 199 int getLineThickness( const LINECODE_ID& aCadstarLineCodeID ); 200 PLOT_DASH_TYPE getLineStyle( const LINECODE_ID& aCadstarLineCodeID ); 201 PART getPart( const PART_ID& aCadstarPartID ); 202 ROUTECODE getRouteCode( const ROUTECODE_ID& aCadstarRouteCodeID ); 203 TEXTCODE getTextCode( const TEXTCODE_ID& aCadstarTextCodeID ); 204 int getTextHeightFromTextCode( const TEXTCODE_ID& aCadstarTextCodeID ); 205 wxString getAttributeName( const ATTRIBUTE_ID& aCadstarAttributeID ); 206 207 PART::DEFINITION::PIN getPartDefinitionPin( 208 const PART& aCadstarPart, const GATE_ID& aGateID, const TERMINAL_ID& aTerminalID ); 209 210 //Helper Functions for obtaining individual elements as KiCad elements: 211 ELECTRICAL_PINTYPE getKiCadPinType( const PART::PIN_TYPE& aPinType ); 212 213 int getKiCadUnitNumberFromGate( const GATE_ID& aCadstarGateID ); 214 LABEL_SPIN_STYLE getSpinStyle( const long long& aCadstarOrientation, bool aMirror ); 215 LABEL_SPIN_STYLE getSpinStyleDeciDeg( const double& aOrientationDeciDeg ); 216 ALIGNMENT mirrorX( const ALIGNMENT& aCadstarAlignment ); 217 ALIGNMENT rotate180( const ALIGNMENT& aCadstarAlignment ); 218 219 //General Graphical manipulation functions 220 221 LIB_SYMBOL* getScaledLibPart( const LIB_SYMBOL* aSymbol, long long aScalingFactorNumerator, 222 long long aScalingFactorDenominator ); 223 224 void fixUpLibraryPins( LIB_SYMBOL* aSymbolToFix, int aGateNumber ); 225 226 std::pair<wxPoint, wxSize> getFigureExtentsKiCad( const FIGURE& aCadstarFigure ); 227 228 wxPoint getKiCadPoint( const wxPoint& aCadstarPoint ); 229 230 wxPoint getKiCadLibraryPoint( const wxPoint& aCadstarPoint, const wxPoint& aCadstarCentre ); 231 232 wxPoint applyTransform( const wxPoint& aPoint, const wxPoint& aMoveVector = { 0, 0 }, 233 const double& aRotationAngleDeciDeg = 0.0, const double& aScalingFactor = 1.0, 234 const wxPoint& aTransformCentre = { 0, 0 }, const bool& aMirrorInvert = false ); 235 getKiCadLength(long long aCadstarLength)236 int getKiCadLength( long long aCadstarLength ) 237 { 238 int mod = aCadstarLength % KiCadUnitDivider; 239 int absmod = sign( mod ) * mod; 240 int offset = 0; 241 242 // Round half-way cases away from zero 243 if( absmod >= KiCadUnitDivider / 2 ) 244 offset = sign( aCadstarLength ); 245 246 return ( aCadstarLength / KiCadUnitDivider ) + offset; 247 } 248 249 /** 250 * @brief 251 * @param aCadstarAngle 252 * @return 253 */ getAngleTenthDegree(const long long & aCadstarAngle)254 double getAngleTenthDegree( const long long& aCadstarAngle ) 255 { 256 // CADSTAR v6 (which outputted Schematic Format Version 8) and earlier used 1/10 degree 257 // as the unit for angles/orientations. It is assumed that CADSTAR version 7 (i.e. Schematic 258 // Format Version 9 and later) is the version that introduced 1/1000 degree for angles. 259 if( Header.Format.Version > 8 ) 260 { 261 return (double) aCadstarAngle / 100.0; 262 } 263 else 264 { 265 return (double) aCadstarAngle; 266 } 267 } 268 269 /** 270 * @brief 271 * @param aCadstarAngle 272 * @return 273 */ getAngleDegrees(const long long & aCadstarAngle)274 double getAngleDegrees( const long long& aCadstarAngle ) 275 { 276 return getAngleTenthDegree( aCadstarAngle ) / 10.0; 277 } 278 279 getCadstarAngle(const double & aAngleTenthDegree)280 long long getCadstarAngle( const double& aAngleTenthDegree ) 281 { 282 return KiROUND( ( aAngleTenthDegree / getAngleTenthDegree( aAngleTenthDegree ) ) 283 * aAngleTenthDegree ); 284 } 285 286 /** 287 * @brief 288 * @param aPoint 289 * @return Angle in decidegrees of the polar representation of the point, scaled 0..360 290 */ 291 double getPolarAngle( const wxPoint& aPoint ); 292 293 /** 294 * @brief 295 * @param aPoint 296 * @return Radius of polar representation of the point 297 */ 298 double getPolarRadius( const wxPoint& aPoint ); 299 300 }; // CADSTAR_SCH_ARCHIVE_LOADER 301 302 303 #endif // CADSTAR_SCH_ARCHIVE_LOADER_H_ 304