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