KiCad PCB EDA Suite
Loading...
Searching...
No Matches
sch_io_ltspice_parser.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
26
29#include <schematic.h>
30#include <sch_line.h>
31#include <sch_label.h>
32#include <sch_edit_frame.h>
33#include <sch_shape.h>
34#include <sch_bus_entry.h>
35
36
38 std::vector<LTSPICE_SCHEMATIC::LT_ASC>& outLT_ASCs,
39 const std::vector<wxString>& aAsyFileNames )
40{
41 // Center created objects in Kicad page
42 BOX2I bbox;
43
44 for( const LTSPICE_SCHEMATIC::LT_ASC& asc : outLT_ASCs )
45 bbox.Merge( asc.BoundingBox );
46
47 m_originOffset = { 0, 0 };
48 bbox.SetOrigin( ToKicadCoords( bbox.GetOrigin() ) );
49 bbox.SetSize( ToKicadCoords( bbox.GetSize() ) );
50
51 VECTOR2I pageSize = aSheet->LastScreen()->GetPageSettings().GetSizeIU( schIUScale.IU_PER_MILS );
52 int grid = schIUScale.MilsToIU( 50 );
53 int margin = grid * 10;
54
55 m_originOffset = ( pageSize / 2 ) - bbox.GetCenter();
56
57 if( bbox.GetWidth() > pageSize.x - margin )
58 m_originOffset.x = margin - bbox.GetLeft();
59
60 if( bbox.GetHeight() > pageSize.y - margin )
61 m_originOffset.y = margin - bbox.GetTop();
62
64
65 readIncludes( outLT_ASCs );
66 CreateKicadSYMBOLs( aSheet, outLT_ASCs, aAsyFileNames );
67 CreateKicadSCH_ITEMs( aSheet, outLT_ASCs );
68}
69
70
71void SCH_IO_LTSPICE_PARSER::readIncludes( std::vector<LTSPICE_SCHEMATIC::LT_ASC>& outLT_ASCs )
72{
73 wxFileName ltSubDir( m_lt_schematic->GetLTspiceDataDir().GetFullPath(), wxEmptyString );
74 ltSubDir.AppendDir( wxS( "sub" ) );
75
76 for( const LTSPICE_SCHEMATIC::LT_ASC& asc : outLT_ASCs )
77 {
78 for( const LTSPICE_SCHEMATIC::TEXT& lt_text : asc.Texts )
79 {
80 for( wxString& line : wxSplit( lt_text.Value, '\n' ) )
81 {
82 if( line.StartsWith( wxS( ".include " ) ) || line.StartsWith( wxS( ".inc " ) )
83 || line.StartsWith( wxS( ".lib " ) ) )
84 {
85 wxString path = line.AfterFirst( ' ' );
86
87 path.Replace( '\\', '/' );
88 wxFileName fileName( path );
89
90 if( fileName.IsAbsolute() )
91 {
92 m_includes[fileName.GetName()] = fileName.GetFullPath();
93 }
94 else
95 {
96 fileName.MakeAbsolute( ltSubDir.GetFullPath() );
97 m_includes[fileName.GetName()] = fileName.GetFullPath();
98 }
99 }
100 }
101 }
102 }
103}
104
105
108 int aIndex, SCH_SHAPE* shape )
109{
110 LTSPICE_SCHEMATIC::LINE& lt_line = aLTSymbol.Lines[aIndex];
111
112 shape->AddPoint( ToKicadCoords( lt_line.End ) );
113 shape->AddPoint( ToKicadCoords( lt_line.Start ) );
114 shape->SetStroke( getStroke( lt_line.LineWidth, lt_line.LineStyle ) );
115}
116
117
119 SCH_SHEET_PATH* aSheet )
120{
121 LTSPICE_SCHEMATIC::LINE& lt_line = aLTSymbol.Lines[aIndex];
122 SCH_SHAPE* shape = new SCH_SHAPE( SHAPE_T::POLY );
123
124 shape->AddPoint( ToKicadCoords( lt_line.End ) );
125 shape->AddPoint( ToKicadCoords( lt_line.Start ) );
126 shape->SetStroke( getStroke( lt_line.LineWidth, lt_line.LineStyle ) );
127
128 shape->Move( ToKicadCoords( aLTSymbol.Offset ) + m_originOffset );
129 RotateMirrorShape( aLTSymbol, shape );
130
131 aSheet->LastScreen()->Append( shape );
132}
133
134
136 std::vector<LTSPICE_SCHEMATIC::LT_ASC>& outLT_ASCs,
137 const std::vector<wxString>& aAsyFiles )
138{
139 for( LTSPICE_SCHEMATIC::LT_ASC& lt_asc : outLT_ASCs )
140 {
141 std::vector<LTSPICE_SCHEMATIC::LT_SYMBOL> symbols = lt_asc.Symbols;
142 std::map<wxString, LIB_SYMBOL*> existingSymbol;
143 std::map<wxString, SCH_SYMBOL*> existingSchematicSymbol;
144
145 for( LTSPICE_SCHEMATIC::LT_SYMBOL& lt_symbol : symbols )
146 {
147 if( !alg::contains( aAsyFiles, lt_symbol.Name ) )
148 {
149 LIB_SYMBOL* lib_symbol;
150
151 if( existingSymbol.count( lt_symbol.Name ) == 0 )
152 {
153 lib_symbol = new LIB_SYMBOL( lt_symbol.Name );
154
155 CreateSymbol( lt_symbol, lib_symbol );
156
157 existingSymbol.emplace( lt_symbol.Name, lib_symbol );
158 }
159 else
160 {
161 lib_symbol = existingSymbol[lt_symbol.Name];
162 }
163
164 LIB_ID libId( wxS( "ltspice" ), lt_symbol.Name );
165 SCH_SYMBOL* sch_symbol = new SCH_SYMBOL( *lib_symbol, libId, aSheet, 1 );
166
167 CreateFields( lt_symbol, sch_symbol, aSheet );
168
169 for( int j = 0; j < (int) lt_symbol.Wires.size(); j++ )
170 CreateWires( lt_symbol, j, aSheet );
171
172 sch_symbol->Move( ToKicadCoords( lt_symbol.Offset ) + m_originOffset );
173 RotateMirror( lt_symbol, sch_symbol );
174
175 aSheet->LastScreen()->Append( sch_symbol );
176 }
177 else
178 {
179 for( int j = 0; j < (int) lt_symbol.Lines.size(); j++ )
180 CreateLines( lt_symbol, j, aSheet );
181
182 for( int j = 0; j < (int) lt_symbol.Circles.size(); j++ )
183 CreateCircle( lt_symbol, j, aSheet );
184
185 for( int j = 0; j < (int) lt_symbol.Arcs.size(); j++ )
186 CreateArc( lt_symbol, j, aSheet );
187
188 for( int j = 0; j < (int) lt_symbol.Rectangles.size(); j++ )
189 CreateRect( lt_symbol, j, aSheet );
190
191 // Calculating bounding box
192 BOX2I bbox;
193
195 LTSPICE_FILE tempAsyFile( lt_symbol.Name + ".asy", { 0, 0 } );
197
198 tempSymbol = m_lt_schematic->SymbolBuilder( lt_symbol.Name, dummyAsc );
199
200 LIB_SYMBOL* tempLibSymbol = new LIB_SYMBOL( lt_symbol.Name );
201 CreateSymbol( tempSymbol, tempLibSymbol );
202
203 bbox = tempLibSymbol->GetBoundingBox();
204
205 int topLeftX = lt_symbol.Offset.x + ToLtSpiceCoords( bbox.GetOrigin().x );
206 int topLeftY = lt_symbol.Offset.y + ToLtSpiceCoords( bbox.GetOrigin().y );
207 int botRightX = lt_symbol.Offset.x
208 + ToLtSpiceCoords( bbox.GetOrigin().x )
209 + ToLtSpiceCoords( bbox.GetSize().x );
210 int botRightY = lt_symbol.Offset.y
211 + ToLtSpiceCoords( bbox.GetOrigin().y )
212 + ToLtSpiceCoords( bbox.GetSize().y );
213
214 for( LTSPICE_SCHEMATIC::LT_PIN& pin : lt_symbol.Pins )
215 {
216 VECTOR2I pinPos = pin.PinLocation;
217
218 for( LTSPICE_SCHEMATIC::WIRE& wire : lt_asc.Wires )
219 {
220 if( wire.Start == ( pinPos + lt_symbol.Offset ) )
221 {
222 //wire is vertical
223 if( wire.End.x == ( pinPos + lt_symbol.Offset ).x )
224 {
225 if( wire.End.y <= topLeftY )
226 wire.Start = VECTOR2I( wire.Start.x, topLeftY + 3 );
227 else if( wire.End.y >= botRightY )
228 wire.Start = VECTOR2I( wire.Start.x, botRightY );
229 else if( wire.End.y < botRightY && wire.End.y > topLeftY )
230 wire.Start = VECTOR2I( topLeftX, wire.Start.y );
231 }
232 //wire is horizontal
233 else if( wire.End.y == ( pinPos + lt_symbol.Offset ).y )
234 {
235 if( wire.End.x <= topLeftX )
236 wire.Start = VECTOR2I( topLeftX, wire.Start.y );
237 else if( wire.End.x >= botRightX )
238 wire.Start = VECTOR2I( botRightX, wire.Start.y );
239 else if( wire.End.x < botRightX && wire.End.x > topLeftX )
240 wire.Start = VECTOR2I( botRightX, wire.Start.y );
241 }
242 }
243 else if( wire.End == ( pinPos + lt_symbol.Offset ) )
244 {
245 //wire is Vertical
246 if( wire.Start.x == ( pinPos + lt_symbol.Offset ).x )
247 {
248 if( wire.Start.y <= topLeftY )
249 wire.End = VECTOR2I( wire.End.x, topLeftY );
250 else if( wire.Start.y > botRightY )
251 wire.End = VECTOR2I( wire.End.x, botRightY );
252 else if( wire.Start.y < botRightY && wire.End.y > topLeftY )
253 wire.End = VECTOR2I( wire.End.x, botRightY );
254 }
255 //wire is Horizontal
256 else if( wire.Start.y == ( pinPos + lt_symbol.Offset ).y )
257 {
258 if( wire.Start.x <= topLeftX )
259 wire.End = VECTOR2I( topLeftX, wire.End.y );
260 else if( wire.Start.x >= botRightX )
261 wire.End = VECTOR2I( botRightX, wire.End.y );
262 else if( wire.Start.x < botRightX && wire.Start.x > topLeftX )
263 wire.End = VECTOR2I( botRightX, wire.End.y );
264 }
265 }
266 }
267 }
268 }
269 }
270 }
271}
272
273
275 LIB_SYMBOL* aLibSymbol )
276{
277 for( int j = 0; j < (int) aLtSymbol.Lines.size(); j++ )
278 {
280
281 CreateLines( aLibSymbol, aLtSymbol, j, line );
282 aLibSymbol->AddDrawItem( line );
283 }
284
285 for( int j = 0; j < (int) aLtSymbol.Circles.size(); j++ )
286 {
288
289 CreateCircle( aLtSymbol, j, circle );
290 aLibSymbol->AddDrawItem( circle );
291 }
292
293 for( int j = 0; j < (int) aLtSymbol.Arcs.size(); j++ )
294 {
296
297 CreateArc( aLtSymbol, j, arc );
298 aLibSymbol->AddDrawItem( arc );
299 }
300
301 for( int j = 0; j < (int) aLtSymbol.Rectangles.size(); j++ )
302 {
304
305 CreateRect( aLtSymbol, j, rectangle );
306 aLibSymbol->AddDrawItem( rectangle );
307 }
308
309 for( int j = 0; j < (int) aLtSymbol.Pins.size(); j++ )
310 {
311 SCH_PIN* pin = new SCH_PIN( aLibSymbol );
312
313 CreatePin( aLtSymbol, j, pin );
314 aLibSymbol->AddDrawItem( pin );
315 }
316
317 aLibSymbol->SetShowPinNumbers( false );
318}
319
320
322{
323 return schIUScale.MilsToIU( rescale( 50, aCoordinate, 16 ) );
324}
325
326
328{
329 return VECTOR2I( ToKicadCoords( aPos.x ), ToKicadCoords( aPos.y ) );
330}
331
332
334{
335 auto MILS_SIZE =
336 []( int mils )
337 {
338 return VECTOR2I( schIUScale.MilsToIU( mils ), schIUScale.MilsToIU( mils ) );
339 };
340
341 if( aLTFontSize == 1 ) return MILS_SIZE( 36 );
342 else if( aLTFontSize == 2 ) return MILS_SIZE( 42 );
343 else if( aLTFontSize == 3 ) return MILS_SIZE( 50 );
344 else if( aLTFontSize == 4 ) return MILS_SIZE( 60 );
345 else if( aLTFontSize == 5 ) return MILS_SIZE( 72 );
346 else if( aLTFontSize == 6 ) return MILS_SIZE( 88 );
347 else if( aLTFontSize == 7 ) return MILS_SIZE( 108 );
348 else return ToKicadFontSize( 2 );
349}
350
351
353{
354 return schIUScale.IUToMils( rescale( 16, aCoordinate, 50 ) );
355}
356
357
359 SCH_SHAPE* aShape )
360{
362 {
363 aShape->Rotate( VECTOR2I(), true );
364 }
366 {
367 aShape->Rotate( VECTOR2I(), false );
368 aShape->Rotate( VECTOR2I(), false );
369 }
371 {
372 aShape->Rotate( VECTOR2I(), false );
373 }
375 {
376 aShape->MirrorVertically( 0 );
377 }
379 {
380 aShape->MirrorVertically( 0 );
381 aShape->Rotate( VECTOR2I(), false );
382 }
384 {
385 aShape->MirrorHorizontally( 0 );
386 }
388 {
389 aShape->MirrorVertically( 0 );
390 aShape->Rotate( VECTOR2I(), true );
391 }
392}
393
394
396 SCH_SYMBOL* aSchSymbol )
397{
399 {
400 aSchSymbol->SetOrientation( SYM_ORIENT_0 );
401 }
403 {
404 aSchSymbol->SetOrientation( SYM_ORIENT_180 );
406 }
408 {
409 aSchSymbol->SetOrientation( SYM_ORIENT_180 );
410 }
412 {
414 }
416 {
417 aSchSymbol->SetOrientation( SYM_MIRROR_Y );
418 }
420 {
421 aSchSymbol->SetOrientation( SYM_MIRROR_Y );
423 }
425 {
426 aSchSymbol->SetOrientation( SYM_MIRROR_X );
427 }
429 {
430 aSchSymbol->SetOrientation( SYM_MIRROR_Y );
432 }
433}
434
435
437 SCH_SHEET_PATH* aSheet )
438{
439 SCH_LINE* segment = new SCH_LINE();
440
443
444 segment->SetStartPoint( aLTSymbol.Wires[aIndex].Start );
445 segment->SetEndPoint( aLTSymbol.Wires[aIndex].End );
446
447 aSheet->LastScreen()->Append( segment );
448}
449
450
452 std::vector<LTSPICE_SCHEMATIC::LT_ASC>& outLT_ASCs )
453{
454 SCH_SCREEN* screen = aSheet->LastScreen();
455
456 for( LTSPICE_SCHEMATIC::LT_ASC& lt_asc : outLT_ASCs )
457 {
458 for( int j = 0; j < (int) lt_asc.Lines.size(); j++ )
459 CreateLine( lt_asc, j, aSheet );
460
461 for( int j = 0; j < (int) lt_asc.Circles.size(); j++ )
462 CreateCircle( lt_asc, j, aSheet );
463
464 for( int j = 0; j < (int) lt_asc.Arcs.size(); j++ )
465 CreateArc( lt_asc, j, aSheet );
466
467 for( int j = 0; j < (int) lt_asc.Rectangles.size(); j++ )
468 CreateRect( lt_asc, j, aSheet );
469
470 for( int j = 0; j < (int) lt_asc.Bustap.size(); j++ )
471 CreateBusEntry( lt_asc, j, aSheet );
472
491
492 for( int j = 0; j < (int) lt_asc.Wires.size(); j++ )
493 CreateWire( lt_asc, j, aSheet, SCH_LAYER_ID::LAYER_WIRE );
494
495 for( int j = 0; j < (int) lt_asc.Iopins.size(); j++ )
496 CreatePin( lt_asc, j, aSheet );
497
498 for( const LTSPICE_SCHEMATIC::FLAG& lt_flag : lt_asc.Flags )
499 {
500 if( lt_flag.Value == wxS( "0" ) )
501 {
502 screen->Append( CreatePowerSymbol( lt_flag.Offset, lt_flag.Value, lt_flag.FontSize,
503 aSheet, lt_asc.Wires ) );
504 }
505 else
506 {
507 screen->Append( CreateSCH_LABEL( SCH_GLOBAL_LABEL_T, lt_flag.Offset, lt_flag.Value,
508 lt_flag.FontSize, lt_asc.Wires ) );
509 }
510 }
511
512 for( const LTSPICE_SCHEMATIC::TEXT& lt_text : lt_asc.Texts )
513 {
514 wxString textVal = lt_text.Value;
515
516 // Includes are already handled through Sim.Library, comment them out
517 if( textVal.StartsWith( ".include " ) || textVal.StartsWith( ".inc " )
518 || textVal.StartsWith( ".lib " ) )
519 {
520 textVal = wxS( "* " ) + textVal;
521 }
522
523 screen->Append( CreateSCH_TEXT( lt_text.Offset, textVal, lt_text.FontSize,
524 lt_text.Justification ) );
525 }
526
527 for( const LTSPICE_SCHEMATIC::DATAFLAG& lt_flag : lt_asc.DataFlags )
528 {
530 lt_flag.Expression, lt_flag.FontSize, lt_asc.Wires ) );
531 }
532 }
533}
534
535
537 SCH_SHEET_PATH* aSheet )
538{
539 LTSPICE_SCHEMATIC::BUSTAP& bustap = aAscfile.Bustap[aIndex];
540
541 for( int k = 0; k < (int) aAscfile.Wires.size(); k++ )
542 {
543 if( ( aAscfile.Wires[k].Start == bustap.Start )
544 || ( aAscfile.Wires[k].End == bustap.Start ) )
545 {
546 CreateWire( aAscfile, k, aSheet, SCH_LAYER_ID::LAYER_BUS );
547 aAscfile.Wires.erase( aAscfile.Wires.begin() + k );
548 }
549 }
550
551 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( ToKicadCoords( { bustap.Start.x,
552 bustap.Start.y - 16 } ) );
553
554 busEntry->SetSize( { ToKicadCoords( 16 ), ToKicadCoords( 16 ) } );
555
556 aSheet->LastScreen()->Append( busEntry );
557}
558
559
569
570
572 SCH_SHEET_PATH* aSheet )
573{
574 LTSPICE_SCHEMATIC::IOPIN& iopin = aAscfile.Iopins[aIndex];
575 wxString ioPinName;
576
577 for( unsigned int k = 0; k < aAscfile.Flags.size(); k++ )
578 {
579 if( ( aAscfile.Flags[k].Offset.x == iopin.Location.x )
580 && ( aAscfile.Flags[k].Offset.y == iopin.Location.y ) )
581 {
582 ioPinName = aAscfile.Flags[k].Value;
583 aAscfile.Flags.erase( aAscfile.Flags.begin() + k );
584 }
585 }
586
587 SCH_HIERLABEL* sheetPin =
588 new SCH_HIERLABEL( ToKicadCoords( iopin.Location ), ioPinName, SCH_HIER_LABEL_T );
589
590 sheetPin->Move( m_originOffset );
591
592 sheetPin->SetShape( getLabelShape( iopin.Polarity ) );
593 aSheet->LastScreen()->Append( sheetPin );
594}
595
596
598 SCH_SHEET_PATH* aSheet )
599{
600 LTSPICE_SCHEMATIC::LINE& lt_line = aAscfile.Lines[aIndex];
602
603 line->SetEndPoint( ToKicadCoords( lt_line.End ) );
604 line->SetStroke( getStroke( lt_line.LineWidth, lt_line.LineStyle ) );
605 line->Move( m_originOffset );
606
607 aSheet->LastScreen()->Append( line );
608}
609
610
612 SCH_SHEET_PATH* aSheet )
613{
614 LTSPICE_SCHEMATIC::CIRCLE& lt_circle = aAscfile.Circles[aIndex];
616
617 VECTOR2I c = ( lt_circle.TopLeft + lt_circle.BotRight ) / 2;
618 int r = ( lt_circle.TopLeft.x - lt_circle.BotRight.x ) / 2;
619
620 circle->SetPosition( ToKicadCoords( c ) );
621 circle->SetEnd( ToKicadCoords( c ) + VECTOR2I( abs( ToKicadCoords( r ) ), 0 ) );
622 circle->SetStroke( getStroke( lt_circle.LineWidth, lt_circle.LineStyle ) );
623 circle->Move( m_originOffset );
624
625 aSheet->LastScreen()->Append( circle );
626}
627
628
630 SCH_SHEET_PATH* aSheet )
631{
632 LTSPICE_SCHEMATIC::ARC& lt_arc = aAscfile.Arcs[aIndex];
633 SCH_SHAPE* arc = new SCH_SHAPE( SHAPE_T::ARC );
634
635 arc->SetCenter( ToKicadCoords( ( lt_arc.TopLeft + lt_arc.BotRight ) / 2 ) );
636 arc->SetEnd( ToKicadCoords( lt_arc.ArcEnd ) );
637 arc->SetStart( ToKicadCoords( lt_arc.ArcStart ) );
638 arc->SetStroke( getStroke( lt_arc.LineWidth, lt_arc.LineStyle ) );
639 arc->Move( m_originOffset );
640
641 aSheet->LastScreen()->Append( arc );
642}
643
644
646 SCH_SHEET_PATH* aSheet )
647{
648 LTSPICE_SCHEMATIC::RECTANGLE& lt_rect = aAscfile.Rectangles[aIndex];
649 SCH_SHAPE* rectangle = new SCH_SHAPE( SHAPE_T::RECTANGLE );
650
651 rectangle->SetPosition( ToKicadCoords( lt_rect.TopLeft ) );
652 rectangle->SetEnd( ToKicadCoords( lt_rect.BotRight ) );
653 rectangle->SetStroke( getStroke( lt_rect.LineWidth, lt_rect.LineStyle ) );
654 rectangle->Move( m_originOffset );
655
656 aSheet->LastScreen()->Append( rectangle );
657}
658
659
661{
662 if( aLineWidth == LTSPICE_SCHEMATIC::LINEWIDTH::Normal )
663 return schIUScale.MilsToIU( 6 );
664 else if( aLineWidth == LTSPICE_SCHEMATIC::LINEWIDTH::Wide )
665 return schIUScale.MilsToIU( 12 );
666 else
667 return schIUScale.MilsToIU( 6 );
668}
669
670
683
684
686 const LTSPICE_SCHEMATIC::LINESTYLE& aLineStyle )
687{
688 return STROKE_PARAMS( getLineWidth( aLineWidth ), getLineStyle( aLineStyle ) );
689}
690
691
693 LTSPICE_SCHEMATIC::JUSTIFICATION aJustification )
694{
695 switch( aJustification )
696 {
698 aText->SetVisible( false );
699 break;
700
705 break;
706
711 break;
712
717 break;
718
723 break;
724
729 break;
730
731 default: break;
732 }
733
734 switch( aJustification )
735 {
742 break;
743
750 break;
751
752 default: break;
753 }
754
755 // Center, Left, Right aligns by first line in multiline text
756 if( wxSplit( aText->GetText(), '\n', '\0' ).size() > 1 )
757 {
758 switch( aJustification )
759 {
764 aText->Offset( VECTOR2I( 0, -aText->GetTextHeight() / 2 ) );
765 break;
766
771 aText->Offset( VECTOR2I( -aText->GetTextHeight() / 2, 0 ) );
772 break;
773
774 default: break;
775 }
776 }
777}
778
779
780SCH_TEXT* SCH_IO_LTSPICE_PARSER::CreateSCH_TEXT( const VECTOR2I& aOffset, const wxString& aText,
781 int aFontSize,
782 LTSPICE_SCHEMATIC::JUSTIFICATION aJustification )
783{
784 VECTOR2I pos = ToKicadCoords( aOffset ) + m_originOffset;
785 SCH_TEXT* textItem = new SCH_TEXT( pos, aText );
786
787 textItem->SetTextSize( ToKicadFontSize( aFontSize ) );
788 textItem->SetVisible( true );
789 textItem->SetMultilineAllowed( true );
790
791 setTextJustification( textItem, aJustification );
792
793 return textItem;
794}
795
796
798 SCH_SHEET_PATH* aSheet, SCH_LAYER_ID aLayer )
799{
800 SCH_LINE* segment = new SCH_LINE();
801
804 segment->SetLayer( aLayer );
805
806 segment->SetStartPoint( ToKicadCoords( aAscfile.Wires[aIndex].Start ) + m_originOffset );
807 segment->SetEndPoint( ToKicadCoords( aAscfile.Wires[aIndex].End ) + m_originOffset );
808
809 aSheet->LastScreen()->Append( segment );
810}
811
812
814 const wxString& aValue,
815 int aFontSize, SCH_SHEET_PATH* aSheet,
816 std::vector<LTSPICE_SCHEMATIC::WIRE>& aWires )
817{
818 LIB_SYMBOL* lib_symbol = new LIB_SYMBOL( wxS( "GND" ) );
820
821 shape->AddPoint( ToKicadCoords( { 16, 0 } ) );
822 shape->AddPoint( ToKicadCoords( { -16, 0 } ) );
823 shape->AddPoint( ToKicadCoords( { 0, 15 } ) );
824 shape->AddPoint( ToKicadCoords( { 16, 0 } ) );
825 shape->AddPoint( ToKicadCoords( { -16, 0 } ) );
826 shape->AddPoint( ToKicadCoords( { 0, 15 } ) );
827
830
831 lib_symbol->AddDrawItem( shape );
832 lib_symbol->SetGlobalPower();
833
834 SCH_PIN* pin = new SCH_PIN( lib_symbol );
835
837 pin->SetPosition( ToKicadCoords( { 0, 0 } ) );
838 pin->SetLength( 5 );
839 pin->SetShape( GRAPHIC_PINSHAPE::LINE );
840 lib_symbol->AddDrawItem( pin );
841
842 LIB_ID libId( wxS( "ltspice" ), wxS( "GND" ) );
843 SCH_SYMBOL* sch_symbol = new SCH_SYMBOL( *lib_symbol, libId, aSheet, 1 );
844
845 sch_symbol->SetRef( aSheet, wxString::Format( wxS( "#GND%03d" ), m_powerSymbolIndex++ ) );
846 sch_symbol->GetField( FIELD_T::REFERENCE )->SetVisible( false );
847 sch_symbol->SetValueFieldText( wxS( "0" ) );
848 sch_symbol->GetField( FIELD_T::VALUE )->SetTextSize( ToKicadFontSize( aFontSize ) );
849 sch_symbol->GetField( FIELD_T::VALUE )->SetVisible( false );
850
851 sch_symbol->Move( ToKicadCoords( aOffset ) + m_originOffset );
852
853 for( LTSPICE_SCHEMATIC::WIRE& wire : aWires )
854 {
855 if( aOffset == wire.Start )
856 {
857 if( wire.Start.x == wire.End.x )
858 {
859 if( wire.Start.y < wire.End.y )
860 {
863 }
864 }
865 else
866 {
867 if( wire.Start.x < wire.End.x )
869 else if( wire.Start.x > wire.End.x )
871 }
872 }
873 else if( aOffset == wire.End )
874 {
875 if( wire.Start.x == wire.End.x )
876 {
877 if( wire.Start.y > wire.End.y )
878 {
881 }
882 }
883 else
884 {
885 if( wire.Start.x < wire.End.x )
887 else if( wire.Start.x > wire.End.x )
889 }
890 }
891 }
892
893 return sch_symbol;
894}
895
896
899 const wxString& aValue, int aFontSize,
900 std::vector<LTSPICE_SCHEMATIC::WIRE>& aWires )
901{
902 SCH_LABEL_BASE* label = nullptr;
903
904 if( aType == SCH_GLOBAL_LABEL_T )
905 {
906 label = new SCH_GLOBALLABEL();
907
908 label->SetText( aValue );
909 label->SetTextSize( ToKicadFontSize( aFontSize ) );
911 }
912 else if( aType == SCH_DIRECTIVE_LABEL_T )
913 {
914 label = new SCH_DIRECTIVE_LABEL();
915
917
918 SCH_FIELD field( label, FIELD_T::USER, wxS( "DATAFLAG" ) );
919 field.SetText( aValue );
920 field.SetTextSize( ToKicadFontSize( aFontSize ) );
921 field.SetVisible( true );
922
923 label->AddField( field );
924 label->AutoplaceFields( nullptr, AUTOPLACE_AUTO );
925 }
926 else
927 {
928 UNIMPLEMENTED_FOR( wxString::Format( wxT( "Type not supported %d" ), (int)aType ) );
929 }
930
931 if( label )
932 {
933 label->SetPosition( ToKicadCoords( aOffset ) + m_originOffset );
934 label->SetVisible( true );
935 }
936
937 std::vector<SPIN_STYLE> preferredSpins;
938
939 for( LTSPICE_SCHEMATIC::WIRE& wire : aWires )
940 {
941 if( aOffset == wire.Start )
942 {
943 if( wire.Start.x == wire.End.x )
944 {
945 if( wire.Start.y < wire.End.y )
946 preferredSpins.emplace_back( SPIN_STYLE::UP );
947 else if( wire.Start.y > wire.End.y )
948 preferredSpins.emplace_back( SPIN_STYLE::BOTTOM );
949 }
950 else
951 {
952 if( wire.Start.x < wire.End.x )
953 preferredSpins.emplace_back( SPIN_STYLE::LEFT );
954 else if( wire.Start.x > wire.End.x )
955 preferredSpins.emplace_back( SPIN_STYLE::RIGHT );
956 }
957 }
958 else if( aOffset == wire.End )
959 {
960 if( wire.Start.x == wire.End.x )
961 {
962 if( wire.Start.y > wire.End.y )
963 preferredSpins.emplace_back( SPIN_STYLE::UP );
964 else if( wire.Start.y < wire.End.y )
965 preferredSpins.emplace_back( SPIN_STYLE::BOTTOM );
966 }
967 else
968 {
969 if( wire.Start.x > wire.End.x )
970 preferredSpins.emplace_back( SPIN_STYLE::LEFT );
971 else if( wire.Start.x < wire.End.x )
972 preferredSpins.emplace_back( SPIN_STYLE::RIGHT );
973 }
974 }
975 }
976
977 if( preferredSpins.size() == 1 )
978 label->SetSpinStyle( preferredSpins.front() );
979
980 return label;
981}
982
983
985 SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aSheet )
986{
987 wxString libPath = m_lt_schematic->GetLTspiceDataDir().GetFullPath();
988 wxString symbolName = aLTSymbol.Name.Upper();
989 wxString type = aLTSymbol.SymAttributes[wxS( "TYPE" )].Upper();
990 wxString prefix = aLTSymbol.SymAttributes[wxS( "PREFIX" )].Upper();
991 wxString instName = aLTSymbol.SymAttributes[wxS( "INSTNAME" )].Upper();
992 wxString value = aLTSymbol.SymAttributes[wxS( "VALUE" )];
993 wxString value2 = aLTSymbol.SymAttributes[wxS( "VALUE2" )];
994
995 if( value.IsEmpty() )
996 {
997 value = value2;
998 value2 = wxEmptyString;
999 }
1000
1001 auto addField =
1002 [&]( const wxString& aFieldName, const wxString& aFieldValue )
1003 {
1004 SCH_FIELD newField( aSymbol, FIELD_T::USER, aFieldName );
1005 newField.SetVisible( false );
1006 newField.SetText( aFieldValue );
1007 aSymbol->AddField( newField );
1008 };
1009
1010 aSymbol->SetRef( aSheet, instName );
1011 aSymbol->SetValueFieldText( value );
1012
1013 if( !value2.IsEmpty() )
1014 addField( wxS( "Value2" ), value2 );
1015
1016 auto setupNonInferredPassive =
1017 [&]( const wxString& aDevice, const wxString& aValueKey )
1018 {
1019 addField( wxS( "Sim.Device" ), aDevice );
1020 addField( wxS( "Sim.Params" ), aValueKey + wxS( "=${VALUE}" ) );
1021 };
1022
1023 auto setupBehavioral =
1024 [&]( const wxString& aDevice, const wxString& aType )
1025 {
1026 aSymbol->SetValueFieldText( wxS( "${Sim.Params}" ) );
1027
1028 addField( wxS( "Sim.Device" ), aDevice );
1029 addField( wxS( "Sim.Type" ), aType );
1030 addField( wxS( "Sim.Params" ), value );
1031 };
1032
1033 static const std::set<wxString> prefixWithGain = { wxS( "E" ), wxS( "F" ), wxS( "G" ), wxS( "H" ) };
1034
1035 if( prefix == wxS( "R" ) )
1036 {
1037 setupNonInferredPassive( prefix, wxS( "R" ) );
1038 }
1039 else if( prefix == wxS( "C" ) )
1040 {
1041 setupNonInferredPassive( prefix, wxS( "C" ) );
1042 }
1043 else if( prefix == wxS( "L" ) )
1044 {
1045 setupNonInferredPassive( prefix, wxS( "L" ) );
1046 }
1047 else if( prefixWithGain.count( prefix ) > 0 )
1048 {
1049 setupNonInferredPassive( prefix, wxS( "gain" ) );
1050 }
1051 else if( prefix == wxS( "B" ) )
1052 {
1053 if( symbolName.StartsWith( wxS( "BV" ) ) )
1054 setupBehavioral( wxS( "V" ), wxS( "=" ) );
1055 else if( symbolName.StartsWith( wxS( "BI" ) ) )
1056 setupBehavioral( wxS( "I" ), wxS( "=" ) );
1057 }
1058 else if( prefix == wxS( "T" ) )
1059 {
1060 aSymbol->SetValueFieldText( wxS( "${Sim.Params}" ) );
1061
1062 addField( wxS( "Sim.Device" ), wxS( "TLINE" ) );
1063 addField( wxS( "Sim.Params" ), value );
1064 }
1065 else if( prefix == wxS( "V" ) || symbolName == wxS( "I" ) )
1066 {
1067 addField( wxS( "Sim.Device" ), wxS( "SPICE" ) );
1068
1069 wxString simParams;
1070 simParams << "type=" << '"' << prefix << '"' << ' ';
1071
1072 if( value2.IsEmpty() )
1073 simParams << "model=" << '"' << "${VALUE}" << '"' << ' ';
1074 else
1075 simParams << "model=" << '"' << "${VALUE} ${VALUE2}" << '"' << ' ';
1076
1077 addField( wxS( "Sim.Params" ), simParams );
1078 }
1079 else
1080 {
1081 wxString libFile = aLTSymbol.SymAttributes[wxS( "MODELFILE" )];
1082
1083 if( prefix == wxS( "X" ) )
1084 {
1085 // A prefix of X overrides the simulation model for other symbols (npn, etc.)
1086 type = wxS( "X" );
1087 }
1088 else if( libFile.IsEmpty() )
1089 {
1090 if( type.IsEmpty() )
1091 type = symbolName;
1092
1093 if( value == "DIODE" )
1094 libFile = libPath + wxS( "cmp/standard.dio" );
1095 else if( value == "NPN" || value == "PNP" )
1096 libFile = libPath + wxS( "cmp/standard.bjt" );
1097 else if( value == "NJF" || value == "PJF" )
1098 libFile = libPath + wxS( "cmp/standard.jft" );
1099 else if( value == "NMOS" || value == "PMOS" )
1100 libFile = libPath + wxS( "cmp/standard.mos" );
1101 }
1102
1103 if( libFile.IsEmpty() )
1104 libFile = m_includes[value];
1105
1106 if( !libFile.IsEmpty() )
1107 {
1108 addField( wxS( "Sim.Library" ), libFile );
1109 addField( wxS( "Sim.Name" ), symbolName );
1110 }
1111
1112 wxString spiceLine = aLTSymbol.SymAttributes[wxS( "SPICELINE" )];
1113
1114 if( type == wxS( "X" ) )
1115 {
1116 addField( wxS( "Sim.Device" ), wxS( "SUBCKT" ) );
1117
1118 if( !spiceLine.IsEmpty() )
1119 addField( wxS( "Sim.Params" ), spiceLine );
1120 }
1121 else
1122 {
1123 addField( wxS( "Sim.Device" ), wxS( "SPICE" ) );
1124
1125 if( !spiceLine.IsEmpty() )
1126 addField( wxS( "Sim.Params" ), spiceLine );
1127 else
1128 addField( wxS( "Sim.Params" ), "model=\"" + value + "\"" );
1129 }
1130 }
1131
1132 for( LTSPICE_SCHEMATIC::LT_WINDOW& lt_window : aLTSymbol.Windows )
1133 {
1134 SCH_FIELD* field = nullptr;
1135
1136 switch( lt_window.WindowNumber )
1137 {
1138 case -1: /* PartNum */ break;
1139 case 0: /* InstName */ field = aSymbol->GetField( FIELD_T::REFERENCE ); break;
1140 case 1: /* Type */ break;
1141 case 2: /* RefName */ break;
1142 case 3: /* Value */ field = aSymbol->GetField( FIELD_T::VALUE ); break;
1143
1144 case 5: /* QArea */ break;
1145
1146 case 8: /* Width */ break;
1147 case 9: /* Length */ break;
1148 case 10: /* Multi */ break;
1149
1150 case 16: /* Nec */ break;
1151
1152 case 38: /* SpiceModel */ field = aSymbol->GetField( wxS( "Sim.Name" ) ); break;
1153 case 39: /* SpiceLine */ field = aSymbol->GetField( wxS( "Sim.Params" ) ); break;
1154 case 40: /* SpiceLine2 */ break;
1155
1156 /*
1157 47 Def_Sub
1158
1159 50 Digital_Timing_Model
1160 51 Digital_Extracts
1161 52 Digital_IO_Model
1162 53 Digital_Line
1163 54 Digital_Primitive
1164 55 Digital_MNTYMXDLY
1165 56 Digital_IO_LEVEL
1166 57 Digital_StdCell
1167 58 Digital_File
1168
1169 105 Cell
1170 106 W/L
1171 107 PSIZE
1172 108 NSIZE
1173 109 sheets
1174 110 sh#
1175 111 Em_Scale
1176 112 Epi
1177 113 Sinker
1178 114 Multi5
1179
1180 118 AQ
1181 119 AQSUB
1182 120 ZSIZE
1183 121 ESR
1184 123 Value2
1185 124 COUPLE
1186 125 Voltage
1187 126 Area1
1188 127 Area2
1189 128 Area3
1190 129 Area4
1191 130 Multi1
1192 131 Multi2
1193 132 Multi3
1194 133 Multi4
1195 134 DArea
1196 135 DPerim
1197 136 CArea
1198 137 CPerim
1199 138 Shrink
1200 139 Gate_Resize
1201
1202 142 BP
1203 143 BN
1204 144 Sim_Level
1205
1206 146 G_Voltage
1207
1208 150 SpiceLine3
1209
1210 153 D_VOLTAGES
1211
1212 156 Version
1213 157 Comment
1214 158 XDef_Sub
1215 159 LVS_Area
1216
1217 162 User1
1218 163 User2
1219 164 User3
1220 165 User4
1221 166 User5
1222 167 Root
1223 168 Class
1224 169 Geometry
1225 170 WL_Delimiter
1226
1227 175 T1
1228 176 T2
1229
1230 184 DsgnName
1231 185 Designer
1232
1233 190 RTN
1234 191 PWR
1235 192 BW
1236
1237 201 CAPROWS
1238 202 CAPCOLS
1239 203 NF
1240 204 SLICES
1241 205 CUR
1242 206 TEMPRISE
1243 207 STRIPS
1244 208 WEM
1245 209 LEM
1246 210 BASES
1247 211 COLS
1248 212 XDef_Tub
1249 */
1250 default: break;
1251 }
1252
1253 if( field )
1254 {
1255 field->SetPosition( ToKicadCoords( lt_window.Position ) );
1256 field->SetTextSize( ToKicadFontSize( lt_window.FontSize ) );
1257
1258 if( lt_window.FontSize == 0 )
1259 field->SetVisible( false );
1260
1261 setTextJustification( field, lt_window.Justification );
1262 }
1263 }
1264}
1265
1266
1268 SCH_SHAPE* aRectangle )
1269{
1270 LTSPICE_SCHEMATIC::RECTANGLE& lt_rect = aLTSymbol.Rectangles[aIndex];
1271
1272 aRectangle->SetPosition( ToKicadCoords( lt_rect.BotRight ) );
1273 aRectangle->SetEnd( ToKicadCoords( lt_rect.TopLeft ) );
1274 aRectangle->SetStroke( getStroke( lt_rect.LineWidth, lt_rect.LineStyle ) );
1275
1276 if( aLTSymbol.SymAttributes[wxS( "Prefix" )] == wxS( "X" ) )
1278}
1279
1280
1282 SCH_SHEET_PATH* aSheet )
1283{
1284 LTSPICE_SCHEMATIC::RECTANGLE& lt_rect = aLTSymbol.Rectangles[aIndex];
1285 SCH_SHAPE* rectangle = new SCH_SHAPE( SHAPE_T::RECTANGLE );
1286
1287 rectangle->SetPosition( ToKicadCoords( lt_rect.BotRight ) );
1288 rectangle->SetEnd( ToKicadCoords( lt_rect.TopLeft ) );
1289 rectangle->SetStroke( getStroke( lt_rect.LineWidth, lt_rect.LineStyle ) );
1290
1291 rectangle->Move( aLTSymbol.Offset );
1292 RotateMirrorShape( aLTSymbol, rectangle );
1293
1294 aSheet->LastScreen()->Append( rectangle );
1295}
1296
1297
1299 SCH_PIN* aPin )
1300{
1301 LTSPICE_SCHEMATIC::LT_PIN& lt_pin = aLTSymbol.Pins[aIndex];
1302 wxString device = aLTSymbol.Name.Lower();
1303
1304 if( aLTSymbol.Pins.size() == 2 && ( device == wxS( "res" )
1305 || device == wxS( "cap" )
1306 || device == wxS( "ind" ) ) )
1307 {
1308 // drop A/B pin names from simple LRCs as they're not terribly useful (and prevent
1309 // other pin names on the net from driving the net name).
1310 }
1311 else
1312 {
1313 aPin->SetName( lt_pin.PinAttribute[ wxS( "PinName" ) ] );
1314
1316 aPin->SetNameTextSize( 0 );
1317 }
1318
1319 aPin->SetNumber( wxString::Format( wxS( "%d" ), aIndex + 1 ) );
1321 aPin->SetPosition( ToKicadCoords( lt_pin.PinLocation ) );
1322 aPin->SetLength( 5 );
1324
1325 switch( lt_pin.PinJustification )
1326 {
1330 break;
1331
1335 break;
1336
1340 break;
1341
1345 break;
1346
1347 default: break;
1348 }
1349}
1350
1351
1353 SCH_SHAPE* aArc )
1354{
1355 LTSPICE_SCHEMATIC::ARC& lt_arc = aLTSymbol.Arcs[aIndex];
1356
1357 aArc->SetCenter( ToKicadCoords( ( lt_arc.TopLeft + lt_arc.BotRight ) / 2 ) );
1358 aArc->SetStart( ToKicadCoords( lt_arc.ArcEnd ) );
1359 aArc->SetEnd( ToKicadCoords( lt_arc.ArcStart ) );
1360 aArc->SetStroke( getStroke( lt_arc.LineWidth, lt_arc.LineStyle ) );
1361}
1362
1363
1365 SCH_SHEET_PATH* aSheet )
1366{
1367 LTSPICE_SCHEMATIC::ARC& lt_arc = aLTSymbol.Arcs[aIndex];
1368 SCH_SHAPE* arc = new SCH_SHAPE( SHAPE_T::ARC );
1369
1370 arc->SetCenter( ToKicadCoords( ( lt_arc.TopLeft + lt_arc.BotRight ) / 2 ) );
1371 arc->SetStart( ToKicadCoords( lt_arc.ArcEnd ) );
1372 arc->SetEnd( ToKicadCoords( lt_arc.ArcStart ) );
1373 arc->SetStroke( getStroke( lt_arc.LineWidth, lt_arc.LineStyle ) );
1374
1375 arc->Move( ToKicadCoords( aLTSymbol.Offset ) + m_originOffset );
1376 RotateMirrorShape( aLTSymbol, arc );
1377
1378 aSheet->LastScreen()->Append( arc );
1379}
1380
1381
1383 SCH_SHEET_PATH* aSheet )
1384{
1385 LTSPICE_SCHEMATIC::CIRCLE& lt_circle = aLTSymbol.Circles[aIndex];
1387
1388 VECTOR2I c = ( lt_circle.TopLeft + lt_circle.BotRight ) / 2;
1389 int r = ( lt_circle.TopLeft.x - lt_circle.BotRight.x ) / 2;
1390
1391 circle->SetPosition( ToKicadCoords( c ) );
1392 circle->SetEnd( ToKicadCoords( c ) + VECTOR2I( abs( ToKicadCoords( r ) ), 0 ) );
1393 circle->SetStroke( getStroke( lt_circle.LineWidth, lt_circle.LineStyle ) );
1394
1395 circle->Move( aLTSymbol.Offset );
1396 RotateMirrorShape( aLTSymbol, circle );
1397
1398 aSheet->LastScreen()->Append( circle );
1399}
1400
1401
1403 SCH_SHAPE* aCircle )
1404{
1405 LTSPICE_SCHEMATIC::CIRCLE& lt_circle = aLTSymbol.Circles[aIndex];
1406
1407 VECTOR2I c = ( lt_circle.TopLeft + lt_circle.BotRight ) / 2;
1408 int r = ( lt_circle.TopLeft.x - lt_circle.BotRight.x ) / 2;
1409
1410 aCircle->SetPosition( ToKicadCoords( c ) );
1411 aCircle->SetEnd( ToKicadCoords( c ) + VECTOR2I( abs( ToKicadCoords( r ) ), 0 ) );
1412 aCircle->SetStroke( getStroke( lt_circle.LineWidth, lt_circle.LineStyle ) );
1413}
1414
1415
constexpr EDA_IU_SCALE schIUScale
Definition base_units.h:114
BOX2< VECTOR2I > BOX2I
Definition box2.h:922
constexpr void SetOrigin(const Vec &pos)
Definition box2.h:237
constexpr size_type GetWidth() const
Definition box2.h:214
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 GetCenter() const
Definition box2.h:230
constexpr void SetSize(const SizeVec &size)
Definition box2.h:248
constexpr size_type GetHeight() const
Definition box2.h:215
constexpr coord_type GetLeft() const
Definition box2.h:228
constexpr const Vec & GetOrigin() const
Definition box2.h:210
constexpr const SizeVec & GetSize() const
Definition box2.h:206
constexpr coord_type GetTop() const
Definition box2.h:229
constexpr void Offset(coord_type dx, coord_type dy)
Definition box2.h:259
void SetCenter(const VECTOR2I &aCenter)
void SetStart(const VECTOR2I &aStart)
Definition eda_shape.h:178
void SetEnd(const VECTOR2I &aEnd)
Definition eda_shape.h:220
void SetFillMode(FILL_T aFill)
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition eda_text.h:80
int GetTextHeight() const
Definition eda_text.h:267
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition eda_text.cpp:541
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition eda_text.h:98
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition eda_text.cpp:426
void Offset(const VECTOR2I &aOffset)
Definition eda_text.cpp:603
virtual void SetVisible(bool aVisible)
Definition eda_text.cpp:395
virtual void SetText(const wxString &aText)
Definition eda_text.cpp:279
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition eda_text.cpp:308
void SetMultilineAllowed(bool aAllow)
Definition eda_text.cpp:410
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition eda_text.cpp:418
A logical library item identifier and consists of various portions much like a URI.
Definition lib_id.h:49
Define a library symbol object.
Definition lib_symbol.h:83
void SetGlobalPower()
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition lib_symbol.h:241
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
POLARITY
Polarity enum represents polarity of pin.
JUSTIFICATION
Defines in what ways the PIN or TEXT can be justified.
const VECTOR2D GetSizeIU(double aIUScale) const
Gets the page size in internal units.
Definition page_info.h:177
void SetSize(const VECTOR2I &aSize)
Class for a wire to bus entry.
void SetPosition(const VECTOR2I &aPosition) override
void SetText(const wxString &aText) override
int ToLtSpiceCoords(int aCoordinate)
Method converts kicad coordinate(i.e scale) to ltspice coordinates.
void CreateCircle(LTSPICE_SCHEMATIC::LT_ASC &aAscfile, int aIndex, SCH_SHEET_PATH *aSheet)
Method for plotting circle from Asc files.
void setTextJustification(EDA_TEXT *aText, LTSPICE_SCHEMATIC::JUSTIFICATION aJustification)
SCH_TEXT * CreateSCH_TEXT(const VECTOR2I &aOffset, const wxString &aText, int aFontSize, LTSPICE_SCHEMATIC::JUSTIFICATION aJustification)
Create schematic text.
void CreateWires(LTSPICE_SCHEMATIC::LT_SYMBOL &aLTSymbol, int aIndex, SCH_SHEET_PATH *aSheet)
Method for plotting wires.
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.
STROKE_PARAMS getStroke(const LTSPICE_SCHEMATIC::LINEWIDTH &aLineWidth, const LTSPICE_SCHEMATIC::LINESTYLE &aLineStyle)
void CreateKicadSYMBOLs(SCH_SHEET_PATH *aSheet, std::vector< LTSPICE_SCHEMATIC::LT_ASC > &outLT_ASCs, const std::vector< wxString > &aAsyFiles)
Main Method for loading indermediate data to kicacd object from asy files.
SCH_SYMBOL * CreatePowerSymbol(const VECTOR2I &aOffset, const wxString &aValue, int aFontSize, SCH_SHEET_PATH *aSheet, std::vector< LTSPICE_SCHEMATIC::WIRE > &aWires)
Create a power symbol.
std::map< wxString, wxString > m_includes
void CreateLine(LTSPICE_SCHEMATIC::LT_ASC &aAscfile, int aIndex, SCH_SHEET_PATH *aSheet)
Method for plotting Line from Asc files.
int getLineWidth(const LTSPICE_SCHEMATIC::LINEWIDTH &aLineWidth)
void RotateMirror(LTSPICE_SCHEMATIC::LT_SYMBOL &aLTSymbol, SCH_SYMBOL *aSchSymbol)
Methods for rotating and mirroring objects.
void CreateBusEntry(LTSPICE_SCHEMATIC::LT_ASC &aAscfile, int aIndex, SCH_SHEET_PATH *aSheet)
Method for plotting Bustap from Asc files.
void CreateRect(LTSPICE_SCHEMATIC::LT_ASC &aAscfile, int aIndex, SCH_SHEET_PATH *aSheet)
Method for plotting rectangle from Asc files.
void CreateWire(LTSPICE_SCHEMATIC::LT_ASC &aAscfile, int aIndex, SCH_SHEET_PATH *aSheet, SCH_LAYER_ID aLayer)
Create a schematic wire.
void CreateLines(LIB_SYMBOL *aSymbol, LTSPICE_SCHEMATIC::LT_SYMBOL &aLTSymbol, int aIndex, SCH_SHAPE *aShape)
Method for plotting Lines from Asy files.
void CreatePin(LTSPICE_SCHEMATIC::LT_ASC &aAscfile, int aIndex, SCH_SHEET_PATH *aSheet)
Method for plotting Iopin from Asc files.
void CreateArc(LTSPICE_SCHEMATIC::LT_ASC &aAscfile, int aIndex, SCH_SHEET_PATH *aSheet)
Method for plotting Arc from Asc files.
void readIncludes(std::vector< LTSPICE_SCHEMATIC::LT_ASC > &outLT_ASCs)
LINE_STYLE getLineStyle(const LTSPICE_SCHEMATIC::LINESTYLE &aLineStyle)
LTSPICE_SCHEMATIC * m_lt_schematic
int ToKicadCoords(int aCoordinate)
Method converts ltspice coordinate(i.e scale) to kicad coordinates.
void CreateFields(LTSPICE_SCHEMATIC::LT_SYMBOL &aLTSymbol, SCH_SYMBOL *aSymbol, SCH_SHEET_PATH *aSheet)
void RotateMirrorShape(LTSPICE_SCHEMATIC::LT_SYMBOL &aLTSymbol, SCH_SHAPE *aShape)
SCH_LABEL_BASE * CreateSCH_LABEL(KICAD_T aType, const VECTOR2I &aOffset, const wxString &aValue, int aFontSize, std::vector< LTSPICE_SCHEMATIC::WIRE > &aWires)
Create a label.
void CreateKicadSCH_ITEMs(SCH_SHEET_PATH *aSheet, std::vector< LTSPICE_SCHEMATIC::LT_ASC > &outLT_ASCs)
Main method for loading intermediate data structure from Asc file to kicad.
VECTOR2I ToKicadFontSize(int aLTFontSize)
void CreateSymbol(LTSPICE_SCHEMATIC::LT_SYMBOL &aLtSymbol, LIB_SYMBOL *aLibSymbol)
void SetLayer(SCH_LAYER_ID aLayer)
Definition sch_item.h:341
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
void AddField(const SCH_FIELD &aField)
Definition sch_label.h:230
void SetShape(LABEL_FLAG_SHAPE aShape)
Definition sch_label.h:181
void SetPosition(const VECTOR2I &aPosition) override
void AutoplaceFields(SCH_SCREEN *aScreen, AUTOPLACE_ALGO aAlgo) override
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
Segment description base class to describe items which have 2 end points (track, wire,...
Definition sch_line.h:42
void SetStartPoint(const VECTOR2I &aPosition)
Definition sch_line.h:140
void SetLineWidth(const int aSize)
Definition sch_line.cpp:346
void SetLineStyle(const LINE_STYLE aStyle)
Definition sch_line.cpp:317
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition sch_line.cpp:165
virtual void SetStroke(const STROKE_PARAMS &aStroke) override
Definition sch_line.h:202
void SetEndPoint(const VECTOR2I &aPosition)
Definition sch_line.h:149
void SetNumber(const wxString &aNumber)
Definition sch_pin.cpp:642
void SetOrientation(PIN_ORIENTATION aOrientation)
Definition sch_pin.h:93
void SetName(const wxString &aName)
Definition sch_pin.cpp:419
void SetPosition(const VECTOR2I &aPos) override
Definition sch_pin.h:251
void SetLength(int aLength)
Definition sch_pin.h:99
void SetShape(GRAPHIC_PINSHAPE aShape)
Definition sch_pin.h:96
void SetType(ELECTRICAL_PINTYPE aType)
Definition sch_pin.cpp:333
void SetNameTextSize(int aSize)
Definition sch_pin.cpp:669
const PAGE_INFO & GetPageSettings() const
Definition sch_screen.h:140
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
void SetPosition(const VECTOR2I &aPos) override
Definition sch_shape.h:86
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
void Move(const VECTOR2I &aOffset) override
Move the item by aMoveVector to a new position.
Definition sch_shape.cpp:78
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition sch_shape.cpp:61
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
void AddPoint(const VECTOR2I &aPosition)
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
SCH_SCREEN * LastScreen()
Schematic symbol object.
Definition sch_symbol.h:76
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition sch_symbol.h:770
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
void SetOrientation(int aOrientation)
Compute the new transform matrix based on aOrientation for the symbol which is applied to the current...
void SetValueFieldText(const wxString &aValue, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString)
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a field to the symbol.
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
Simple container to manage line stroke parameters.
virtual void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
Definition symbol.h:174
static constexpr EDA_ANGLE ANGLE_VERTICAL
Definition eda_angle.h:408
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition eda_angle.h:407
@ RECTANGLE
Use RECTANGLE instead of RECT to avoid collision in a Windows header.
Definition eda_shape.h:46
@ FILLED_WITH_BG_BODYCOLOR
Definition eda_shape.h:59
SCH_LAYER_ID
Eeschema drawing layers.
Definition layer_ids.h:449
@ LAYER_DEVICE
Definition layer_ids.h:466
@ LAYER_WIRE
Definition layer_ids.h:452
@ LAYER_NOTES
Definition layer_ids.h:467
@ LAYER_BUS
Definition layer_ids.h:453
#define UNIMPLEMENTED_FOR(type)
Definition macros.h:96
bool contains(const _Container &__container, _Value __value)
Returns true if the container contains the given value.
Definition kicad_algo.h:100
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
Definition pin_type.h:46
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin.
Definition pin_type.h:43
@ PIN_UP
The pin extends upwards from the connection point: Probably on the bottom side of the symbol.
Definition pin_type.h:127
@ PIN_RIGHT
The pin extends rightwards from the connection point.
Definition pin_type.h:111
@ PIN_LEFT
The pin extends leftwards from the connection point: Probably on the right side of the symbol.
Definition pin_type.h:118
@ PIN_DOWN
The pin extends downwards from the connection: Probably on the top side of the symbol.
Definition pin_type.h:135
LABEL_FLAG_SHAPE getLabelShape(LTSPICE_SCHEMATIC::POLARITY aPolarity)
@ AUTOPLACE_AUTO
Definition sch_item.h:70
LABEL_FLAG_SHAPE
Definition sch_label.h:99
@ L_BIDI
Definition sch_label.h:102
@ L_OUTPUT
Definition sch_label.h:101
@ L_INPUT
Definition sch_label.h:100
LINE_STYLE
Dashed line types.
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< RECTANGLE > Rectangles
std::map< wxString, wxString > PinAttribute
A struct to hold SYMBOL definition.
std::map< wxString, wxString > SymAttributes
std::vector< RECTANGLE > Rectangles
std::vector< LT_WINDOW > Windows
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.
@ SYM_ROTATE_CLOCKWISE
Definition symbol.h:37
@ SYM_ROTATE_COUNTERCLOCKWISE
Definition symbol.h:38
@ SYM_MIRROR_Y
Definition symbol.h:44
@ SYM_ORIENT_180
Definition symbol.h:41
@ SYM_MIRROR_X
Definition symbol.h:43
@ SYM_ORIENT_0
Definition symbol.h:39
@ USER
The field ID hasn't been set yet; field is invalid.
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
std::string path
KIBIS_PIN * pin
SHAPE_CIRCLE circle(c.m_circle_center, c.m_circle_radius)
@ GR_TEXT_H_ALIGN_CENTER
@ GR_TEXT_H_ALIGN_RIGHT
@ GR_TEXT_H_ALIGN_LEFT
@ GR_TEXT_V_ALIGN_BOTTOM
@ GR_TEXT_V_ALIGN_CENTER
@ GR_TEXT_V_ALIGN_TOP
KICAD_T
The set of class identification values stored in EDA_ITEM::m_structType.
Definition typeinfo.h:78
@ SCH_DIRECTIVE_LABEL_T
Definition typeinfo.h:175
@ SCH_HIER_LABEL_T
Definition typeinfo.h:173
@ SCH_GLOBAL_LABEL_T
Definition typeinfo.h:172
T rescale(T aNumerator, T aValue, T aDenominator)
Scale a number (value) by rational (numerator/denominator).
Definition util.h:139
VECTOR2< int32_t > VECTOR2I
Definition vector2d.h:695