KiCad PCB EDA Suite
Loading...
Searching...
No Matches
ltspice_schematic.cpp
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2022 Chetan Subhash Shinde<[email protected]>
5 * Copyright (C) 2023 CERN
6 * Copyright The KiCad Developers, see AUTHORS.txt for contributors.
7 *
8 * This program is free software: you can redistribute it and/or modify it
9 * under the terms of the GNU General Public License as published by the
10 * Free Software Foundation, either version 3 of the License, or (at your
11 * option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program. If not, see <http://www.gnu.org/licenses/>.
20 */
21
27
29#include <sch_screen.h>
30#include <wx/log.h>
31#include <wx/dir.h>
33#include <sch_sheet.h>
34#include <schematic.h>
35#include <project.h>
36#include <richio.h>
37
38
39void LTSPICE_SCHEMATIC::Load( SCHEMATIC* aSchematic, SCH_SHEET* aRootSheet,
40 const wxFileName& aLibraryFileName, REPORTER* aReporter )
41{
42 std::map<wxString, wxString> mapOfAscFiles;
43 std::map<wxString, wxString> mapOfAsyFiles;
44
45 // Library paths to search (Give highest priority to files contained in same directory)
46 GetAscAndAsyFilePaths( aLibraryFileName.GetPath(), false, mapOfAscFiles, mapOfAsyFiles );
47
48 // TODO: Custom paths go here (non-recursive)
49
50 // Default LTspice libs
51 GetAscAndAsyFilePaths( m_ltspiceDataDir.GetPathWithSep() + wxS( "sub" ), true, mapOfAscFiles,
52 mapOfAsyFiles );
53
54 GetAscAndAsyFilePaths( m_ltspiceDataDir.GetPathWithSep() + wxS( "sym" ), true, mapOfAscFiles,
55 mapOfAsyFiles );
56
57 m_schematic = aSchematic;
58
59 std::queue<wxString> ascFileQueue;
60 ascFileQueue.push( aLibraryFileName.GetName().Lower() );
61
62 LTSPICE_FILE rootAscFile( ascFileQueue.front(), { 0, 0 } );
63
64 rootAscFile.Sheet = aRootSheet;
65 rootAscFile.Screen = new SCH_SCREEN();
66
67 int parentSheetIndex = 0;
68
69 // Asc files who are subschematic in nature
70 std::vector<LTSPICE_FILE> ascFiles;
71
72 ascFiles.push_back( rootAscFile );
73
74 while( !ascFileQueue.empty() )
75 {
76 SCH_SCREEN* screen = nullptr;
77
78 // Reading the .asc file
79 wxString ascFilePath = mapOfAscFiles[ ascFileQueue.front() ];
80 wxString buffer = SafeReadFile( ascFilePath, "r" );
81
82 std::vector<LTSPICE_FILE> newSubSchematicElements = GetSchematicElements( buffer );
83
84 alg::delete_if( newSubSchematicElements,
85 [&mapOfAscFiles]( const LTSPICE_FILE& ii )
86 {
87 return mapOfAscFiles[ii.ElementName].IsEmpty();
88 } );
89
90 for( LTSPICE_FILE& newSubSchematicElement : newSubSchematicElements )
91 {
92 wxString asyName = newSubSchematicElement.ElementName;
93 auto it = mapOfAsyFiles.find( asyName );
94
95 if( it == mapOfAsyFiles.end() )
96 continue;
97
98 wxString asyBuffer = SafeReadFile( it->second, "r" );
99
100 if( IsAsySubsheet( asyBuffer ) )
101 {
102 if( !screen )
103 screen = new SCH_SCREEN( m_schematic );
104
105 newSubSchematicElement.ParentIndex = parentSheetIndex;
106 newSubSchematicElement.Screen = screen;
107 newSubSchematicElement.Sheet = new SCH_SHEET();
108
109 ascFileQueue.push( newSubSchematicElement.ElementName );
110 ascFiles.push_back( newSubSchematicElement );
111 }
112 }
113
114 ascFileQueue.pop();
115
116 parentSheetIndex++;
117 }
118
119 for( unsigned int i = 0; i < ascFiles.size(); i++ )
120 {
121 // Reading the .asc file
122 wxString buffer = SafeReadFile( mapOfAscFiles[ascFiles[i].ElementName], wxS( "r" ) );
123
124 // Getting the keywords to read
125 {
126 std::vector<LTSPICE_FILE> sourceFiles = GetSchematicElements( buffer );
127
128 m_fileCache[ wxS( "asyFiles" ) ] = ReadAsyFiles( sourceFiles, mapOfAsyFiles );
129 m_fileCache[ wxS( "ascFiles" ) ][ wxS( "parentFile" ) ] = buffer;
130
131 for( const LTSPICE_FILE& file : sourceFiles )
132 wxASSERT( file.Sheet == nullptr && file.Screen == nullptr );
133 }
134
135 SCH_SHEET_PATH curSheetPath;
136 SCH_IO_LTSPICE_PARSER parser( this );
137
138 if( i > 0 )
139 {
140 SCH_SHEET* curSheet = ascFiles[i].Sheet;
141 std::map tempAsyMap = ReadAsyFile( ascFiles[i], mapOfAsyFiles );
142 wxString ascFileName = ascFiles[i].ElementName;
143 LT_ASC dummyAsc;
144 LT_SYMBOL tempSymbol = SymbolBuilder( ascFileName, tempAsyMap[ascFileName], dummyAsc );
145 LIB_SYMBOL tempLibSymbol( ascFiles[i].ElementName );
146
147 parser.CreateSymbol( tempSymbol, &tempLibSymbol );
148
149 BOX2I bbox = tempLibSymbol.GetBoundingBox();
150
151 curSheet->SetSize( bbox.GetSize() );
152 curSheet->SetPosition( parser.ToKicadCoords( ascFiles[i].Offset ) + bbox.GetOrigin() );
153 curSheet->SetParent( ascFiles[ascFiles[i].ParentIndex].Sheet );
154
155 SCH_FIELD* sheetNameField = curSheet->GetField( FIELD_T::SHEET_NAME );
156 SCH_FIELD* fileNameSheet = curSheet->GetField( FIELD_T::SHEET_FILENAME );
157 wxString sheetName = wxString::Format( wxS( "%s-subsheet-%d" ),
158 ascFiles[i].ElementName,
159 i );
160
161 sheetNameField->SetText( sheetName );
162 fileNameSheet->SetText( sheetName + ".kicad_sch" );
163
164 curSheet->SetScreen( ascFiles[i].Screen );
165
166 curSheetPath = ascFiles[ascFiles[i].ParentIndex].SheetPath;
167 curSheetPath.push_back( curSheet );
168
169 ascFiles[i].SheetPath = curSheetPath;
170
171 ascFiles[ascFiles[i].ParentIndex].Sheet->GetScreen()->Append( curSheet );
172
173 curSheet->GetScreen()->SetFileName( m_schematic->Prj().GetProjectPath() + sheetName
174 + ".kicad_sch" );
175 }
176 else
177 {
178 SCH_SHEET* curSheet = ascFiles[i].Sheet;
179
180 ascFiles[i].SheetPath.push_back( curSheet );
181 curSheetPath = ascFiles[i].SheetPath;
182 }
183
184 std::vector<wxString> subSchematicAsyFiles;
185
186 for( const LTSPICE_FILE& ascFile : ascFiles )
187 subSchematicAsyFiles.push_back( ascFile.ElementName );
188
189 try
190 {
191 std::vector<LTSPICE_SCHEMATIC::LT_ASC> lt_ascs = StructureBuilder();
192 parser.Parse( &curSheetPath, lt_ascs, subSchematicAsyFiles );
193 }
194 catch( IO_ERROR& e )
195 {
196 aReporter->Report( e.What(), RPT_SEVERITY_ERROR );
197 }
198 }
199}
200
201
202void LTSPICE_SCHEMATIC::GetAscAndAsyFilePaths( const wxDir& aDir, bool aRecursive,
203 std::map<wxString, wxString>& aMapOfAscFiles,
204 std::map<wxString, wxString>& aMapOfAsyFiles,
205 const std::vector<wxString>& aBaseDirs )
206{
207 wxString filename;
208
209 {
210 bool cont = aDir.GetFirst( &filename, wxEmptyString, wxDIR_FILES | wxDIR_HIDDEN );
211
212 while( cont )
213 {
214 wxFileName path( aDir.GetName(), filename );
215
216 auto logToMap = [&]( std::map<wxString, wxString>& aMapToLogTo, const wxString& aKey )
217 {
218 if( aMapToLogTo.count( aKey ) )
219 {
220 if( m_reporter )
221 {
222 m_reporter->Report( wxString::Format(
223 _( "File at '%s' was ignored. Using previously found "
224 "file at '%s' instead." ),
225 path.GetFullPath(), aMapToLogTo.at( aKey ) ) );
226 }
227 }
228 else
229 {
230 aMapToLogTo.emplace( aKey, path.GetFullPath() );
231 }
232 };
233
234 // Add dir1/dir2/cmp, dir2/cmp, cmp
235 wxString extension = path.GetExt().Lower();
236
237 for( size_t i = 0; i < aBaseDirs.size() + 1; i++ )
238 {
239 wxString alias;
240
241 for( size_t j = i; j < aBaseDirs.size(); j++ )
242 alias << aBaseDirs[j].Lower() << '/';
243
244 alias << path.GetName().Lower();
245
246 if( extension == wxS( "asc" ) )
247 logToMap( aMapOfAscFiles, alias );
248 else if( extension == wxS( "asy" ) )
249 logToMap( aMapOfAsyFiles, alias );
250 }
251
252 cont = aDir.GetNext( &filename );
253 }
254 }
255
256 if( aRecursive )
257 {
258 bool cont = aDir.GetFirst( &filename, wxEmptyString, wxDIR_DIRS | wxDIR_HIDDEN );
259
260 while( cont )
261 {
262 wxFileName path( aDir.GetName(), filename );
263 wxDir subDir( path.GetFullPath() );
264
265 std::vector<wxString> newBase = aBaseDirs;
266 newBase.push_back( filename );
267
268 GetAscAndAsyFilePaths( subDir, true, aMapOfAscFiles, aMapOfAsyFiles, newBase );
269
270 cont = aDir.GetNext( &filename );
271 }
272 }
273}
274
275
276std::map<wxString, wxString>
278 const std::map<wxString, wxString>& aAsyFileMap )
279{
280 std::map<wxString, wxString> resultantMap;
281
282 wxString fileName = aSourceFile.ElementName;
283
284 if( aAsyFileMap.count( fileName ) )
285 resultantMap[fileName] = SafeReadFile( aAsyFileMap.at( fileName ), wxS( "r" ) );
286
287 return resultantMap;
288}
289
290
291std::map<wxString, wxString>
292LTSPICE_SCHEMATIC::ReadAsyFiles( const std::vector<LTSPICE_FILE>& aSourceFiles,
293 const std::map<wxString, wxString>& aAsyFileMap )
294{
295 std::map<wxString, wxString> resultantMap;
296
297 for( const LTSPICE_FILE& source : aSourceFiles )
298 {
299 wxString fileName = source.ElementName;
300
301 if( aAsyFileMap.count( fileName ) )
302 resultantMap[fileName] = SafeReadFile( aAsyFileMap.at( fileName ), wxS( "r" ) );
303 }
304
305 return resultantMap;
306}
307
308
309std::vector<LTSPICE_FILE> LTSPICE_SCHEMATIC::GetSchematicElements( const wxString& aAscFile )
310{
311 std::vector<LTSPICE_FILE> resultantArray;
312 wxArrayString lines = wxSplit( aAscFile, '\n' );
313
314 for( const wxString& line : lines )
315 {
316 wxArrayString tokens = wxSplit( line, ' ' );
317
318 if( !tokens.IsEmpty() && tokens[0].Upper() == wxS( "SYMBOL" ) )
319 {
320 wxString elementName( tokens[1] );
321 long posX, posY;
322
323 tokens[2].ToLong( &posX );
324 tokens[3].ToLong( &posY );
325
326 elementName.Replace( '\\', '/' );
327
328 LTSPICE_FILE asyFile( elementName, VECTOR2I( (int) posX, (int) posY ) );
329
330 resultantArray.push_back( asyFile );
331 }
332 }
333
334 return resultantArray;
335}
336
337
338bool LTSPICE_SCHEMATIC::IsAsySubsheet( const wxString& aAsyFile )
339{
340 wxStringTokenizer lines( aAsyFile, "\n" );
341
342 while( lines.HasMoreTokens() )
343 {
344 wxStringTokenizer parts( lines.GetNextToken(), " " );
345
346 if( parts.GetNextToken().IsSameAs( wxS( "SYMATTR" ), false )
347 && parts.GetNextToken().IsSameAs( wxS( "Prefix" ), false ) )
348 {
349 return false;
350 }
351 }
352
353 return true;
354}
355
356
357int LTSPICE_SCHEMATIC::integerCheck( const wxString& aToken, int aLineNumber,
358 const wxString& aFileName )
359{
360 long result;
361
362 if( !aToken.ToLong( &result ) )
363 {
364 THROW_IO_ERROR( wxString::Format( _( "Expecting integer at line %d in file %s" ),
365 aLineNumber,
366 aFileName ) );
367 }
368
369 return (int) result;
370}
371
372
373VECTOR2I LTSPICE_SCHEMATIC::pointCheck( const wxString& aTokenX, const wxString& aTokenY,
374 int aLineNumber, const wxString& aFileName )
375{
376 return VECTOR2I( integerCheck( aTokenX, aLineNumber, aFileName ),
377 integerCheck( aTokenY, aLineNumber, aFileName ) );
378}
379
380
381void LTSPICE_SCHEMATIC::tokensSizeRangeCheck( size_t aActualSize, int aExpectedMin,
382 int aExpectedMax, int aLineNumber,
383 const wxString& aFileName )
384{
385 if( (int) aActualSize < aExpectedMin )
386 {
387 THROW_IO_ERROR( wxString::Format( _( "Expected data missing on line %d in file %s" ),
388 aLineNumber,
389 aFileName ) );
390 }
391 else if( (int) aActualSize > aExpectedMax )
392 {
393 THROW_IO_ERROR( wxString::Format( _( "Extra data found on line %d in file %s" ),
394 aLineNumber,
395 aFileName ) );
396 }
397}
398
399
400void LTSPICE_SCHEMATIC::aggregateAttributeValue( wxArrayString& aTokens, int aIndex )
401{
402 // Merges a value which is across multiple tokens into one token with spaces in between.
403 for( int i = aIndex + 1; i < (int) aTokens.GetCount(); i++ )
404 aTokens[ aIndex ] += " " + aTokens[i];
405}
406
407
409{
410 std::map<int, LINESTYLE> lineStyleMap;
411
412 lineStyleMap[0] = LINESTYLE::SOLID;
413 lineStyleMap[1] = LINESTYLE::DASH;
414 lineStyleMap[2] = LINESTYLE::DOT;
415 lineStyleMap[3] = LINESTYLE::DASHDOT;
416 lineStyleMap[4] = LINESTYLE::DASHDOTDOT;
417
418 if( lineStyleMap.find( aValue ) == lineStyleMap.end() )
419 THROW_IO_ERROR( _( "Expecting 0, 1, 2, 3 or 4" ) );
420
421 return lineStyleMap[ aValue ];
422}
423
424
426{
427 std::map<wxString, LINEWIDTH> lineWidthMap;
428
429 lineWidthMap["NORMAL"] = LINEWIDTH::Normal;
430 lineWidthMap["WIDE"] = LINEWIDTH::Wide;
431
432 if( lineWidthMap.find( aValue.Upper() ) == lineWidthMap.end() )
433 THROW_IO_ERROR( _( "Expecting NORMAL or WIDE" ) );
434
435 return lineWidthMap[ aValue.Upper() ];
436}
437
438
440{
441 std::map<wxString, POLARITY> polarityMap;
442
443 polarityMap["I"] = POLARITY::INPUT;
444 polarityMap["O"] = POLARITY::OUTPUT;
445 polarityMap["B"] = POLARITY::BIDIR;
446 polarityMap["IN"] = POLARITY::INPUT;
447 polarityMap["OUT"] = POLARITY::OUTPUT;
448 polarityMap["BIDIR"] = POLARITY::BIDIR;
449
450 if( polarityMap.find( aValue.Upper() ) == polarityMap.end() )
451 THROW_IO_ERROR( _( "Expecting I, O, B, IN, OUT or BIDIR" ) );
452
453 return polarityMap[ aValue.Upper() ];
454}
455
456
458{
459 std::map<wxString, ORIENTATION> rotationMirrorMap;
460
461 rotationMirrorMap["R0"] = ORIENTATION::R0;
462 rotationMirrorMap["R90"] = ORIENTATION::R90;
463 rotationMirrorMap["R180"] = ORIENTATION::R180;
464 rotationMirrorMap["R270"] = ORIENTATION::R270;
465
466 rotationMirrorMap["M0"] = ORIENTATION::M0;
467 rotationMirrorMap["M90"] = ORIENTATION::M90;
468 rotationMirrorMap["M180"] = ORIENTATION::M180;
469 rotationMirrorMap["M270"] = ORIENTATION::M270;
470
471 if( rotationMirrorMap.find( aValue.Upper() ) == rotationMirrorMap.end() )
472 THROW_IO_ERROR( _( "Expecting R0, R90, R18, R270, M0, M90, M180 or M270" ) );
473
474 return rotationMirrorMap[ aValue.Upper() ];
475}
476
477
479{
480 std::map<wxString, JUSTIFICATION> justificationMap;
481
482 justificationMap["LEFT"] = JUSTIFICATION::LEFT;
483 justificationMap["CENTER"] = JUSTIFICATION::CENTER;
484 justificationMap["RIGHT"] = JUSTIFICATION::RIGHT;
485 justificationMap["VLEFT"] = JUSTIFICATION::VLEFT;
486 justificationMap["VRIGHT"] = JUSTIFICATION::VRIGHT;
487 justificationMap["VCENTER"] = JUSTIFICATION::VCENTER;
488 justificationMap["BOTTOM"] = JUSTIFICATION::BOTTOM;
489 justificationMap["TOP"] = JUSTIFICATION::TOP;
490 justificationMap["VBOTTOM"] = JUSTIFICATION::VBOTTOM;
491 justificationMap["VTOP"] = JUSTIFICATION::VTOP;
492 justificationMap["INVISIBLE"] = JUSTIFICATION::INVISIBLE;
493
494 if( justificationMap.find( aValue.Upper() ) == justificationMap.end() )
495 THROW_IO_ERROR( _( "Expecting LEFT, CENTER, RIGHT, TOP, BOTTOM, VLEFT, VRIGHT, VCENTER, "
496 "VTOP, VBOTTOM or INVISIBLE" ) );
497
498 return justificationMap[ aValue.Upper() ];
499}
500
501
503{
504 std::map<wxString, JUSTIFICATION> pinJustificationMap;
505
506 pinJustificationMap["BOTTOM"] = JUSTIFICATION::BOTTOM;
507 pinJustificationMap["NONE"] = JUSTIFICATION::NONE;
508 pinJustificationMap["LEFT"] = JUSTIFICATION::LEFT;
509 pinJustificationMap["RIGHT"] = JUSTIFICATION::RIGHT;
510 pinJustificationMap["TOP"] = JUSTIFICATION::TOP;
511 pinJustificationMap["VBOTTOM"] = JUSTIFICATION::VBOTTOM;
512 pinJustificationMap["VLEFT"] = JUSTIFICATION::VLEFT;
513 pinJustificationMap["VRIGHT"] = JUSTIFICATION::VRIGHT;
514 pinJustificationMap["VCENTER"] = JUSTIFICATION::VCENTER;
515 pinJustificationMap["VTOP"] = JUSTIFICATION::VTOP;
516
517 if( pinJustificationMap.find( aValue.Upper() ) == pinJustificationMap.end() )
518 THROW_IO_ERROR( _( "Expecting NONE, BOTTOM, TOP, LEFT, RIGHT, VBOTTOM, VTOP, VCENTER, VLEFT or VRIGHT" ) );
519
520 return pinJustificationMap[ aValue.Upper() ];
521}
522
523
525{
526 std::map<wxString, SYMBOLTYPE> symbolTypeMap;
527
528 symbolTypeMap["CELL"] = SYMBOLTYPE::CELL;
529 symbolTypeMap["BLOCK"] = SYMBOLTYPE::BLOCK;
530
531 if( symbolTypeMap.find( aValue.Upper() ) == symbolTypeMap.end() )
532 THROW_IO_ERROR( _( "Expecting CELL or BLOCK" ) );
533
534 return symbolTypeMap[ aValue.Upper() ];
535}
536
537
538void LTSPICE_SCHEMATIC::removeCarriageReturn( wxString& elementFromLine )
539{
540 if( elementFromLine.EndsWith( '\r' ) )
541 elementFromLine = elementFromLine.BeforeLast( '\r' );
542}
543
544
546 LT_ASC& aAscFile )
547{
548 const std::map<wxString, wxString>& asyFiles = m_fileCache[ wxS( "asyFiles" ) ];
549
550 if( !asyFiles.count( aAscFileName.Lower() ) )
551 THROW_IO_ERROR( wxString::Format( _( "Symbol '%s.asy' not found" ), aAscFileName ) );
552
553 return SymbolBuilder( aAscFileName, asyFiles.at( aAscFileName.Lower() ), aAscFile );
554}
555
557 const wxString& aAsyFileContent,
558 LT_ASC& aAscFile )
559{
560 LT_SYMBOL lt_symbol;
561 int lineNumber = 1;
562
563 lt_symbol.Name = aAscFileName;
566
567 for( wxString line : wxSplit( aAsyFileContent, '\n' ) )
568 {
569 removeCarriageReturn( line );
570
571 wxArrayString tokens = wxSplit( line, ' ' );
572
573 if( tokens.IsEmpty() )
574 continue;
575
576 wxString element = tokens[0].Upper();
577
578 if( element == "LINE" )
579 {
580 tokensSizeRangeCheck( tokens.size(), 6, 7, lineNumber, aAscFileName );
581
582 wxString lineWidth = tokens[1];
583 wxString startPointX = tokens[2];
584 wxString startPointY = tokens[3];
585 wxString endPointX = tokens[4];
586 wxString endPointY = tokens[5];
587
588 LINE lt_line;
589 lt_line.LineWidth = getLineWidth( lineWidth );
590 lt_line.Start = pointCheck( startPointX, startPointY, lineNumber, aAscFileName );
591 lt_line.End = pointCheck( endPointX, endPointY, lineNumber, aAscFileName );
592
593 int lineStyleNumber = 0; // default
594
595 if( tokens.size() == 7 )
596 {
597 wxString lineStyle = tokens[6];
598 lineStyleNumber = integerCheck( lineStyle, lineNumber, aAscFileName );
599 }
600
601 lt_line.LineStyle = getLineStyle( lineStyleNumber );
602
603 lt_symbol.Lines.push_back( lt_line );
604 }
605 else if( element == "RECTANGLE" )
606 {
607 tokensSizeRangeCheck( tokens.size(), 6, 7, lineNumber, aAscFileName );
608
609 wxString lineWidth = tokens[1];
610 wxString botRightX = tokens[2];
611 wxString botRightY = tokens[3];
612 wxString topLeftX = tokens[4];
613 wxString topRightY = tokens[5];
614
615 RECTANGLE rect;
616 rect.LineWidth = getLineWidth( lineWidth );
617 rect.BotRight = pointCheck( botRightX, botRightY, lineNumber, aAscFileName );
618 rect.TopLeft = pointCheck( topLeftX, topRightY, lineNumber, aAscFileName );
619
620 int lineStyleNumber = 0; // default
621
622 if( tokens.size() == 7 )
623 {
624 wxString lineStyle = tokens[6];
625 lineStyleNumber = integerCheck( lineStyle, lineNumber, aAscFileName );
626 }
627
628 rect.LineStyle = getLineStyle( lineStyleNumber );
629
630 lt_symbol.Rectangles.push_back( rect );
631 }
632 else if( element == "CIRCLE" )
633 {
638 tokensSizeRangeCheck( tokens.size(), 6, 7, lineNumber, aAscFileName );
639
640 wxString lineWidth = tokens[1];
641 wxString botRightX = tokens[2];
642 wxString botRightY = tokens[3];
643 wxString topLeftX = tokens[4];
644 wxString topRightY = tokens[5];
645
647 circle.LineWidth = getLineWidth( lineWidth );
648 circle.BotRight = pointCheck( botRightX, botRightY, lineNumber, aAscFileName );
649 circle.TopLeft = pointCheck( topLeftX, topRightY, lineNumber, aAscFileName );
650
651 int lineStyleNumber = 0; // default
652
653 if( tokens.size() == 7 )
654 {
655 wxString lineStyle = tokens[6];
656 lineStyleNumber = integerCheck( lineStyle, lineNumber, aAscFileName );
657 }
658
659 circle.LineStyle = getLineStyle( lineStyleNumber );
660
661 lt_symbol.Circles.push_back( circle );
662 }
663 else if( element == "ARC" )
664 {
670 tokensSizeRangeCheck( tokens.size(), 10, 11, lineNumber, aAscFileName );
671
672 wxString lineWidth = tokens[1];
673 wxString botRightX = tokens[2];
674 wxString botRightY = tokens[3];
675 wxString topLeftX = tokens[4];
676 wxString topRightY = tokens[5];
677 wxString arcStartPointX = tokens[6];
678 wxString arcStartPointY = tokens[7];
679 wxString arcEndPointX = tokens[8];
680 wxString arcEndPointY = tokens[9];
681
682 ARC arc;
683 arc.LineWidth = getLineWidth( lineWidth );
684 arc.BotRight = pointCheck( botRightX, botRightY, lineNumber, aAscFileName );
685 arc.TopLeft = pointCheck( topLeftX, topRightY, lineNumber, aAscFileName );
686 arc.ArcStart = pointCheck( arcStartPointX, arcStartPointY, lineNumber, aAscFileName );
687 arc.ArcEnd = pointCheck( arcEndPointX, arcEndPointY, lineNumber, aAscFileName );
688
689 int lineStyleNumber = 0; // default
690
691 if( tokens.size() == 11 )
692 {
693 wxString lineStyle = tokens[10];
694 lineStyleNumber = integerCheck( lineStyle, lineNumber, aAscFileName );
695 }
696
697 arc.LineStyle = getLineStyle( lineStyleNumber );
698
699 lt_symbol.Arcs.push_back( arc );
700 }
701 else if( element == "WINDOW" )
702 {
703 tokensSizeRangeCheck( tokens.size(), 6, 6, lineNumber, aAscFileName );
704
705 wxString number = tokens[1];
706 wxString windowPosX = tokens[2];
707 wxString windowPosY = tokens[3];
708 wxString justification = tokens[4];
709 wxString fontSize = tokens[5];
710
711 LT_WINDOW window;
712 window.WindowNumber = integerCheck( number, lineNumber, aAscFileName );
713 window.Position = pointCheck( windowPosX, windowPosY, lineNumber, aAscFileName );
714 window.Justification = getTextJustification( justification );
715 window.FontSize = integerCheck( fontSize, lineNumber, aAscFileName );
716
717 // LTSpice appears to ignore hidden property from .asy files
718 if( window.FontSize == 0 )
719 window.FontSize = 2;
720
721 lt_symbol.Windows.push_back( window );
722 }
723 else if( element == "SYMATTR" )
724 {
725 aggregateAttributeValue( tokens, 2 );
726
727 tokensSizeRangeCheck( tokens.size(), 3, INT_MAX, lineNumber, aAscFileName );
728
729 wxString key = tokens[1];
730 wxString value = tokens[2];
731
732 if( value == wxS( "\"\"" ) )
733 value = wxEmptyString;
734
735 lt_symbol.SymAttributes[ key.Upper() ] = value;
736 }
737 else if( element == "PIN" )
738 {
739 tokensSizeRangeCheck( tokens.size(), 5, 5, lineNumber, aAscFileName );
740
741 wxString pinLocationX = tokens[1];
742 wxString pinLocationY = tokens[2];
743 wxString Justification = tokens[3];
744 wxString nameOffSet = tokens[4];
745
746 LT_PIN pin;
747 pin.PinLocation = pointCheck( pinLocationX, pinLocationY, lineNumber,aAscFileName );
748 pin.PinJustification = getPinJustification( Justification );
749 pin.NameOffSet = integerCheck( nameOffSet, lineNumber, aAscFileName );
750
751 lt_symbol.Pins.push_back( pin );
752 }
753 else if( element == "PINATTR" )
754 {
755 aggregateAttributeValue( tokens, 2 );
756
757 tokensSizeRangeCheck( tokens.size(), 3, INT_MAX, lineNumber, aAscFileName );
758
759 wxString name = tokens[1];
760 wxString Value = tokens[2];
761
762 lt_symbol.Pins.back().PinAttribute.insert( { name, Value } );
763 }
764 else if( element == "SYMBOLTYPE" )
765 {
766 tokensSizeRangeCheck( tokens.size(), 2, 2, lineNumber, aAscFileName );
767
768 wxString symbolType = tokens[1];
769
770 lt_symbol.SymbolType = getSymbolType( symbolType );
771 }
772
773 lineNumber++;
774 }
775
776 return lt_symbol;
777}
778
779
781{
782 LT_SYMBOL lt_symbol;
783
784 lt_symbol.Name = aAscFileName;
787
788 RECTANGLE rect;
789 rect.LineWidth = getLineWidth( "NORMAL" );
791 rect.BotRight = VECTOR2I( 20, 20 );
792 rect.TopLeft = VECTOR2I( -20, -20 );
793
794 lt_symbol.Rectangles.push_back( rect );
795
796 return lt_symbol;
797}
798
799
800std::vector<LTSPICE_SCHEMATIC::LT_ASC> LTSPICE_SCHEMATIC::StructureBuilder()
801{
802 // Initialising Symbol Struct
803
804 std::vector<LT_ASC> ascFiles;
805
806 for( const auto& [ fileName, contents ] : m_fileCache[ wxS( "ascFiles" ) ] )
807 {
808 LT_ASC ascFile;
809 std::vector<LT_SYMBOL> symbolArray;
810
811 ascFile.SheetSize = VECTOR2I( 0, 0 );
812 ascFile.Symbols = symbolArray;
813 ascFile.Version = 0;
814 ascFile.VersionMinor = 0;
815 ascFile.SheetNumber = 0;
816
817 int lineNumber = 1;
818
819 for( wxString line : wxSplit( contents, '\n' ) )
820 {
821 removeCarriageReturn( line );
822
823 wxArrayString tokens = wxSplit( line, ' ' );
824
825 if( tokens.IsEmpty() )
826 continue;
827
828 wxString element = tokens[0].Upper();
829
830 if( element == "SHEET" )
831 {
832 tokensSizeRangeCheck( tokens.size(), 4, 4, lineNumber, fileName );
833
834 wxString sheetNumber = tokens[1];
835 wxString sheetWidth = tokens[2];
836 wxString sheetHeight = tokens[3];
837
838 ascFile.SheetNumber = integerCheck( sheetNumber, lineNumber, fileName );
839 ascFile.SheetSize = pointCheck( sheetWidth, sheetHeight, lineNumber, fileName );
840 }
841 else if( element == "SYMBOL" )
842 {
843 tokensSizeRangeCheck( tokens.size(), 5, 5, lineNumber, fileName );
844
845 wxString symbolName = tokens[1];
846 wxString posX = tokens[2];
847 wxString posY = tokens[3];
848 wxString rotate_mirror_option = tokens[4];
849
850 symbolName.Replace( '\\', '/' );
851
852 try
853 {
854 LT_SYMBOL lt_symbol = SymbolBuilder( symbolName, ascFile );
855 lt_symbol.Offset = pointCheck( posX, posY, lineNumber, fileName );
856 lt_symbol.SymbolOrientation = getSymbolRotationOrMirror( rotate_mirror_option );
857
858 ascFile.Symbols.push_back( lt_symbol );
859 ascFile.BoundingBox.Merge( lt_symbol.Offset );
860 }
861 catch( IO_ERROR& e )
862 {
863 if( m_reporter )
865
866 // Use dummy symbol
867 LT_SYMBOL lt_symbol = MakeDummySymbol( symbolName );
868 lt_symbol.Offset = pointCheck( posX, posY, lineNumber, fileName );
869 lt_symbol.SymbolOrientation = getSymbolRotationOrMirror( rotate_mirror_option );
870
871 ascFile.Symbols.push_back( lt_symbol );
872 ascFile.BoundingBox.Merge( lt_symbol.Offset );
873 }
874 }
875 else if( element == "WIRE" )
876 {
877 tokensSizeRangeCheck( tokens.size(), 5, 5, lineNumber, fileName );
878
879 wxString startPointX = tokens[1];
880 wxString startPointY = tokens[2];
881 wxString endPointX = tokens[3];
882 wxString endPointY = tokens[4];
883
884 WIRE wire;
885 wire.Start = pointCheck( startPointX, startPointY, lineNumber, fileName );
886 wire.End = pointCheck( endPointX, endPointY, lineNumber, fileName );
887
888 ascFile.Wires.push_back( wire );
889 ascFile.BoundingBox.Merge( wire.Start );
890 ascFile.BoundingBox.Merge( wire.End );
891 }
892 else if( element == "FLAG" )
893 {
894 tokensSizeRangeCheck( tokens.size(), 4, 4, lineNumber, fileName );
895
896 wxString posX = tokens[1];
897 wxString posY = tokens[2];
898 wxString name = tokens[3];
899
900 FLAG flag;
901 flag.Offset = pointCheck( posX, posY, lineNumber, fileName );
902 flag.Value = name;
903 flag.FontSize = 2;
904
905 ascFile.Flags.push_back( flag );
906 ascFile.BoundingBox.Merge( flag.Offset );
907 }
908 else if( element == "DATAFLAG" )
909 {
910 tokensSizeRangeCheck( tokens.size(), 4, 4, lineNumber, fileName );
911
912 wxString posX = tokens[1];
913 wxString posY = tokens[2];
914 wxString expression = tokens[3];
915
917 flag.Offset = pointCheck( posX, posY, lineNumber, fileName );
918 flag.Expression = expression;
919 flag.FontSize = 2;
920
921 ascFile.DataFlags.push_back( flag );
922 ascFile.BoundingBox.Merge( flag.Offset );
923 }
924 else if( element == "WINDOW" )
925 {
926 tokensSizeRangeCheck( tokens.size(), 6, 6, lineNumber, fileName );
927
928 wxString number = tokens[1];
929 wxString windowPosX = tokens[2];
930 wxString windowPosY = tokens[3];
931 wxString justification = tokens[4];
932 wxString fontSize = tokens[5];
933
934 int windowNumber = integerCheck( number, lineNumber, fileName );
935 LT_WINDOW* window = nullptr;
936
937 // Overwrite an existing window from the symbol definition
938 for( LT_WINDOW& candidate : ascFile.Symbols.back().Windows )
939 {
940 if( candidate.WindowNumber == windowNumber )
941 {
942 window = &candidate;
943 break;
944 }
945 }
946
947 if( !window )
948 {
949 ascFile.Symbols.back().Windows.emplace_back( LT_WINDOW() );
950 window = &ascFile.Symbols.back().Windows.back();
951 }
952
953 window->WindowNumber = windowNumber;
954 window->Position = pointCheck( windowPosX, windowPosY, lineNumber, fileName );
955 window->Justification = getTextJustification( justification );
956 window->FontSize = integerCheck( fontSize, lineNumber, fileName );
957
958 ascFile.BoundingBox.Merge( window->Position );
959 }
960 else if( element == "SYMATTR" )
961 {
962 tokensSizeRangeCheck( tokens.size(), 3, INT_MAX, lineNumber, fileName );
963
964 aggregateAttributeValue( tokens, 2 );
965
966 wxString name = tokens[1];
967 wxString value = tokens[2];
968
969 if( value == wxS( "\"\"" ) )
970 value = wxEmptyString;
971
972 ascFile.Symbols.back().SymAttributes[ name.Upper() ] = value;
973 }
974 else if( element == "LINE" )
975 {
976 tokensSizeRangeCheck( tokens.size(), 6, 7, lineNumber, fileName );
977
978 wxString lineWidth = tokens[1];
979 wxString startPointX = tokens[2];
980 wxString startPointY = tokens[3];
981 wxString endPointX = tokens[4];
982 wxString endPointY = tokens[5];
983
984 LINE lt_line;
985 lt_line.LineWidth = getLineWidth( lineWidth );
986 lt_line.Start = pointCheck( startPointX, startPointY, lineNumber, fileName );
987 lt_line.End = pointCheck( endPointX, endPointY, lineNumber, fileName );
988
989 int lineStyleNumber = 0; // default
990
991 if( tokens.size() == 7 )
992 {
993 wxString lineStyle = tokens[6];
994 lineStyleNumber = integerCheck( lineStyle, lineNumber, fileName );
995 }
996
997 lt_line.LineStyle = getLineStyle( lineStyleNumber );
998
999 ascFile.Lines.push_back( lt_line );
1000 ascFile.BoundingBox.Merge( lt_line.Start );
1001 ascFile.BoundingBox.Merge( lt_line.End );
1002 }
1003 else if( element == "RECTANGLE" )
1004 {
1005 tokensSizeRangeCheck( tokens.size(), 6, 7, lineNumber, fileName );
1006
1007 wxString lineWidth = tokens[1];
1008 wxString botRightX = tokens[2];
1009 wxString botRightY = tokens[3];
1010 wxString topLeftX = tokens[4];
1011 wxString topRightY = tokens[5];
1012
1013 RECTANGLE rect;
1014 rect.LineWidth = getLineWidth( tokens[1] );
1015 rect.BotRight = pointCheck( botRightX, botRightY, lineNumber, fileName );
1016 rect.TopLeft = pointCheck( topLeftX, topRightY, lineNumber, fileName );
1017
1018 int lineStyleNumber = 0; // default
1019
1020 if( tokens.size() == 7 )
1021 {
1022 wxString lineStyle = tokens[6];
1023 lineStyleNumber = integerCheck( lineStyle, lineNumber, fileName );
1024 }
1025
1026 rect.LineStyle = getLineStyle( lineStyleNumber );
1027
1028 ascFile.Rectangles.push_back( rect );
1029 ascFile.BoundingBox.Merge( rect.TopLeft );
1030 ascFile.BoundingBox.Merge( rect.BotRight );
1031 }
1032 else if( element == "CIRCLE" )
1033 {
1034 tokensSizeRangeCheck( tokens.size(), 6, 7, lineNumber, fileName );
1035
1036 wxString lineWidth = tokens[1];
1037 wxString botRightX = tokens[2];
1038 wxString botRightY = tokens[3];
1039 wxString topLeftX = tokens[4];
1040 wxString topRightY = tokens[5];
1041
1042 CIRCLE circle;
1043 circle.LineWidth = getLineWidth( lineWidth );
1044 circle.BotRight = pointCheck( botRightX, botRightY, lineNumber, fileName );
1045 circle.TopLeft = pointCheck( topLeftX, topRightY, lineNumber, fileName );
1046
1047 int lineStyleNumber = 0; // default
1048
1049 if( tokens.size() == 7 )
1050 {
1051 wxString lineStyle = tokens[6];
1052 lineStyleNumber = integerCheck( lineStyle, lineNumber, fileName );
1053 }
1054
1055 circle.LineStyle = getLineStyle( lineStyleNumber );
1056
1057 ascFile.Circles.push_back( circle );
1058 ascFile.BoundingBox.Merge( circle.TopLeft );
1059 ascFile.BoundingBox.Merge( circle.BotRight );
1060 }
1061 else if( element == "ARC" )
1062 {
1068 tokensSizeRangeCheck( tokens.size(), 10, 11, lineNumber, fileName );
1069
1070 wxString lineWidth = tokens[1];
1071 wxString botRightX = tokens[2];
1072 wxString botRightY = tokens[3];
1073 wxString topLeftX = tokens[4];
1074 wxString topRightY = tokens[5];
1075 wxString arcStartPointX = tokens[6];
1076 wxString arcStartPointY = tokens[7];
1077 wxString arcEndPointX = tokens[8];
1078 wxString arcEndPointY = tokens[9];
1079
1080 ARC arc;
1081 arc.LineWidth = getLineWidth( lineWidth );
1082 arc.BotRight = pointCheck( botRightX, botRightY, lineNumber, fileName );
1083 arc.TopLeft = pointCheck( topLeftX, topRightY, lineNumber, fileName );
1084 arc.ArcEnd = pointCheck( arcStartPointX, arcStartPointY, lineNumber, fileName );
1085 arc.ArcStart = pointCheck( arcEndPointX, arcEndPointY, lineNumber, fileName );
1086
1087 int lineStyleNumber = 0; // default
1088
1089 if( tokens.size() == 11 )
1090 {
1091 wxString lineStyle = tokens[10];
1092 lineStyleNumber = integerCheck( lineStyle, lineNumber, fileName );
1093 }
1094
1095 arc.LineStyle = getLineStyle( lineStyleNumber );
1096
1097 ascFile.Arcs.push_back( arc );
1098 ascFile.BoundingBox.Merge( arc.TopLeft );
1099 ascFile.BoundingBox.Merge( arc.BotRight );
1100 }
1101 else if( element == "IOPIN" )
1102 {
1103 tokensSizeRangeCheck( tokens.size(), 4, 4, lineNumber, fileName );
1104
1105 wxString pinLocationX = tokens[1];
1106 wxString pinLocationY = tokens[2];
1107 wxString pinPolarity = tokens[3];
1108
1109 IOPIN iopin;
1110 iopin.Location = pointCheck( pinLocationX, pinLocationY, lineNumber, fileName );
1111 iopin.Polarity = getPolarity( pinPolarity );
1112
1113 ascFile.Iopins.push_back( iopin );
1114 ascFile.BoundingBox.Merge( iopin.Location );
1115 }
1116 else if( element == "TEXT" )
1117 {
1118 aggregateAttributeValue( tokens, 5 );
1119
1120 tokensSizeRangeCheck( tokens.size(), 6, INT_MAX, lineNumber, fileName );
1121
1122 wxString positionX = tokens[1];
1123 wxString positionY = tokens[2];
1124 wxString justification = tokens[3];
1125 wxString fontSize = tokens[4];
1126 wxString value = tokens[5];
1127
1128 TEXT text;
1129 text.Offset = pointCheck( positionX, positionY, lineNumber, fileName );
1130 text.Justification = getTextJustification( justification );
1131 text.FontSize = integerCheck( fontSize, lineNumber, fileName );
1132
1133 if( value.StartsWith( wxS( "!" ), &text.Value ) )
1134 text.Value.Replace( wxS( "! " ), wxS( "\n" ) ); // replace subsequent ! with \n
1135 else if( value.StartsWith( wxS( ";" ), &text.Value ) )
1136 text.Value.Replace( wxS( "; " ), wxS( "\n" ) ); // replace subsequent ; with \n
1137 else
1138 text.Value = value;
1139
1140 text.Value.Replace( wxS( "\\n" ), wxS( "\n" ) );
1141
1142 ascFile.Texts.push_back( text );
1143 ascFile.BoundingBox.Merge( text.Offset );
1144 }
1145 else if( element == "BUSTAP" )
1146 {
1147 tokensSizeRangeCheck( tokens.size(), 5, 5, lineNumber, fileName );
1148
1149 wxString startPointX = tokens[1];
1150 wxString startPointY = tokens[2];
1151 wxString endPointX = tokens[3];
1152 wxString endPointY = tokens[4];
1153
1154 BUSTAP bustap;
1155 bustap.Start = pointCheck( startPointX, startPointY, lineNumber, fileName );
1156 bustap.End = pointCheck( endPointX, endPointY, lineNumber, fileName );
1157
1158 ascFile.Bustap.push_back( bustap );
1159 ascFile.BoundingBox.Merge( bustap.Start );
1160 ascFile.BoundingBox.Merge( bustap.End );
1161 }
1162 else if( element == "VERSION" )
1163 {
1164 wxString versionNumber = tokens[1];
1165 if( versionNumber.Contains( '.' ) )
1166 {
1167 wxString majorStr = versionNumber.BeforeFirst( '.' );
1168 wxString minorStr = versionNumber.AfterFirst( '.' );
1169 ascFile.Version = integerCheck( majorStr, lineNumber, fileName );
1170 ascFile.VersionMinor = integerCheck( minorStr, lineNumber, fileName );
1171 }
1172 else
1173 {
1174 ascFile.Version = integerCheck( versionNumber, lineNumber, fileName );
1175 }
1176 }
1177
1178 lineNumber++;
1179 }
1180
1181 ascFiles.push_back( ascFile );
1182 }
1183
1184 return ascFiles;
1185}
1186
1187
const char * name
Definition: DXF_plotter.cpp:62
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:658
constexpr const Vec & GetOrigin() const
Definition: box2.h:210
constexpr const SizeVec & GetSize() const
Definition: box2.h:206
virtual void SetParent(EDA_ITEM *aParent)
Definition: eda_item.h:111
Hold an error message and may be used when throwing exceptions containing meaningful error messages.
Definition: ki_exception.h:77
virtual const wxString What() const
A composite of Problem() and Where()
Definition: exceptions.cpp:30
Define a library symbol object.
Definition: lib_symbol.h:85
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: lib_symbol.h:242
static VECTOR2I pointCheck(const wxString &aTokenX, const wxString &aTokenY, int aLineNumber, const wxString &aFileName)
LT_SYMBOL MakeDummySymbol(const wxString &aAscFileName)
static SYMBOLTYPE getSymbolType(const wxString &aValue)
std::vector< LT_ASC > StructureBuilder()
Build Intermediate data structure.
std::vector< LTSPICE_FILE > GetSchematicElements(const wxString &aAscFile)
Used to get symbols list present in asc file.
LT_SYMBOL SymbolBuilder(const wxString &aAscFileName, LT_ASC &aAscFile)
POLARITY
Polarity enum represents polarity of pin.
JUSTIFICATION
Defines in what ways the PIN or TEXT can be justified.
static ORIENTATION getSymbolRotationOrMirror(const wxString &aValue)
bool IsAsySubsheet(const wxString &aAsyFile)
Check if the asy file content indicates that we need to load subsheet.
static POLARITY getPolarity(const wxString &aValue)
static void tokensSizeRangeCheck(size_t aActualSize, int aExpectedMin, int aExpectedMax, int aLineNumber, const wxString &aFileName)
Used to check size of the token generated from split function.
static LINEWIDTH getLineWidth(const wxString &aValue)
ORIENTATION
Defines different types or rotation and mirror operation can be applied to a LT_SYMBOL.
static void aggregateAttributeValue(wxArrayString &aTokens, int aIndex)
Join value present across multiple tokens into one.
void GetAscAndAsyFilePaths(const wxDir &aDir, bool aRecursive, std::map< wxString, wxString > &aMapOfAscFiles, std::map< wxString, wxString > &aMapOfAsyFiles, const std::vector< wxString > &aBaseDirs={})
Used to get file path for Asc and Asy files.
void Load(SCHEMATIC *aSchematic, SCH_SHEET *aRootSheet, const wxFileName &aLibraryFileName, REPORTER *aReporter)
The main function responsible for loading the .asc and .asy files.
static int integerCheck(const wxString &aToken, int aLineNumber, const wxString &aFileName)
Used to check if the given token in integer or not.
wxFileName m_ltspiceDataDir
std::map< wxString, std::map< wxString, wxString > > m_fileCache
static JUSTIFICATION getTextJustification(const wxString &aValue)
static JUSTIFICATION getPinJustification(const wxString &aValue)
std::map< wxString, wxString > ReadAsyFile(const LTSPICE_FILE &aSourceFile, const std::map< wxString, wxString > &aAsyFileMap)
SYMBOLTYPE
Type of Symbol loaded from asc and asy file.
std::map< wxString, wxString > ReadAsyFiles(const std::vector< LTSPICE_FILE > &aSourceFiles, const std::map< wxString, wxString > &aAsyFileMap)
The function returns a map.
static void removeCarriageReturn(wxString &elementFromLine)
static LINESTYLE getLineStyle(int aValue)
virtual const wxString GetProjectPath() const
Return the full path of the project.
Definition: project.cpp:146
A pure virtual class used to derive REPORTER objects from.
Definition: reporter.h:73
virtual REPORTER & Report(const wxString &aText, SEVERITY aSeverity=RPT_SEVERITY_UNDEFINED)
Report a string with a given severity.
Definition: reporter.h:102
Holds all the data relating to one schematic.
Definition: schematic.h:69
PROJECT & Prj() const
Return a reference to the project this schematic is part of.
Definition: schematic.h:84
void SetText(const wxString &aText) override
Definition: sch_field.cpp:1095
The class is been used for loading the asc and asy files in intermediate data structure.
void Parse(SCH_SHEET_PATH *aSheet, std::vector< LTSPICE_SCHEMATIC::LT_ASC > &outLT_ASCs, const std::vector< wxString > &aAsyFileNames)
Function responsible for loading the .asc and .asy files in intermediate data structure.
int ToKicadCoords(int aCoordinate)
Method converts ltspice coordinate(i.e scale) to kicad coordinates.
void CreateSymbol(LTSPICE_SCHEMATIC::LT_SYMBOL &aLtSymbol, LIB_SYMBOL *aLibSymbol)
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
Definition: sch_screen.cpp:121
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
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.
Definition: sch_sheet.h:47
void SetSize(const VECTOR2I &aSize)
Definition: sch_sheet.h:119
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this sheet.
Definition: sch_sheet.cpp:369
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_sheet.cpp:988
SCH_SCREEN * GetScreen() const
Definition: sch_sheet.h:116
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
Definition: sch_sheet.cpp:137
#define _(s)
#define THROW_IO_ERROR(msg)
Definition: ki_exception.h:39
void delete_if(_Container &__c, _Function &&__f)
Deletes all values from __c for which __f returns true.
Definition: kicad_algo.h:174
@ RPT_SEVERITY_ERROR
wxString SafeReadFile(const wxString &aFilePath, const wxString &aReadType)
Nominally opens a file and reads it into a string.
Definition: richio.cpp:96
SCH_SCREEN * Screen
SCH_SHEET * Sheet
wxString ElementName
The ARC is represented inside a rectangle whose opposite site are given.
The CIRCLE is represented in Ltpsice inside a rectangle whose two opposite points and line style are ...
IOPIN is special contact on symbol used for IO operations.
A struct to hold .asc file definition.
std::vector< CIRCLE > Circles
std::vector< IOPIN > Iopins
std::vector< BUSTAP > Bustap
std::vector< LT_SYMBOL > Symbols
std::vector< TEXT > Texts
std::vector< DATAFLAG > DataFlags
std::vector< LINE > Lines
std::vector< WIRE > Wires
std::vector< RECTANGLE > Rectangles
std::vector< FLAG > Flags
A struct to hold SYMBOL definition.
std::map< wxString, wxString > SymAttributes
std::vector< RECTANGLE > Rectangles
std::vector< LT_WINDOW > Windows
std::vector< LT_PIN > Pins
std::vector< CIRCLE > Circles
A 4-sided polygon with opposite equal sides, used in representing shapes.
A metallic connection, used for transfer, between two points or pin.
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:695
Definition of file extensions used in Kicad.