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 (C) 2022-2024 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
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
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 {
279 SCH_SHAPE* line = new SCH_SHAPE( SHAPE_T::POLY, LAYER_DEVICE );
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 {
287 SCH_SHAPE* circle = new SCH_SHAPE( SHAPE_T::CIRCLE, LAYER_DEVICE );
288
289 CreateCircle( aLtSymbol, j, circle );
290 aLibSymbol->AddDrawItem( circle );
291 }
292
293 for( int j = 0; j < (int) aLtSymbol.Arcs.size(); j++ )
294 {
295 SCH_SHAPE* arc = new SCH_SHAPE( SHAPE_T::ARC, LAYER_DEVICE );
296
297 CreateArc( aLtSymbol, j, arc );
298 aLibSymbol->AddDrawItem( arc );
299 }
300
301 for( int j = 0; j < (int) aLtSymbol.Rectangles.size(); j++ )
302 {
303 SCH_SHAPE* rectangle = new SCH_SHAPE( SHAPE_T::RECTANGLE, LAYER_DEVICE );
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
442 segment->SetLineStyle( LINE_STYLE::SOLID );
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
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 ) );
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 ) );
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
561{
562 if( aPolarity == LTSPICE_SCHEMATIC::POLARITY::INPUT )
564 else if( aPolarity == LTSPICE_SCHEMATIC::POLARITY::OUTPUT )
566 else
568}
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];
601 SCH_LINE* line = new SCH_LINE( ToKicadCoords( lt_line.Start ), SCH_LAYER_ID::LAYER_NOTES );
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];
615 SCH_SHAPE* circle = new SCH_SHAPE( SHAPE_T::CIRCLE );
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
672{
673 switch( aLineStyle )
674 {
675 case LTSPICE_SCHEMATIC::LINESTYLE::SOLID: return LINE_STYLE::SOLID;
676 case LTSPICE_SCHEMATIC::LINESTYLE::DOT: return LINE_STYLE::DOT;
677 case LTSPICE_SCHEMATIC::LINESTYLE::DASHDOTDOT: return LINE_STYLE::DASHDOTDOT;
678 case LTSPICE_SCHEMATIC::LINESTYLE::DASHDOT: return LINE_STYLE::DASHDOT;
679 case LTSPICE_SCHEMATIC::LINESTYLE::DASH: return LINE_STYLE::DASH;
680 default: return LINE_STYLE::SOLID;
681 }
682}
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 {
701 break;
702
707 break;
708
713 break;
714
719 break;
720
725 break;
726
727 default: break;
728 }
729
730 switch( aJustification )
731 {
738 break;
739
746 break;
747
748 default: break;
749 }
750
751 // Center, Left, Right aligns by first line in multiline text
752 if( wxSplit( aText->GetText(), '\n', '\0' ).size() > 1 )
753 {
754 switch( aJustification )
755 {
760 aText->Offset( VECTOR2I( 0, -aText->GetTextHeight() / 2 ) );
761 break;
762
767 aText->Offset( VECTOR2I( -aText->GetTextHeight() / 2, 0 ) );
768 break;
769
770 default: break;
771 }
772 }
773}
774
775
776SCH_TEXT* SCH_IO_LTSPICE_PARSER::CreateSCH_TEXT( const VECTOR2I& aOffset, const wxString& aText,
777 int aFontSize,
778 LTSPICE_SCHEMATIC::JUSTIFICATION aJustification )
779{
780 VECTOR2I pos = ToKicadCoords( aOffset ) + m_originOffset;
781 SCH_TEXT* textItem = new SCH_TEXT( pos, aText );
782
783 textItem->SetTextSize( ToKicadFontSize( aFontSize ) );
784 textItem->SetVisible( true );
785 textItem->SetMultilineAllowed( true );
786
787 setTextJustification( textItem, aJustification );
788
789 return textItem;
790}
791
792
794 SCH_SHEET_PATH* aSheet, SCH_LAYER_ID aLayer )
795{
796 SCH_LINE* segment = new SCH_LINE();
797
799 segment->SetLineStyle( LINE_STYLE::SOLID );
800 segment->SetLayer( aLayer );
801
802 segment->SetStartPoint( ToKicadCoords( aAscfile.Wires[aIndex].Start ) + m_originOffset );
803 segment->SetEndPoint( ToKicadCoords( aAscfile.Wires[aIndex].End ) + m_originOffset );
804
805 aSheet->LastScreen()->Append( segment );
806}
807
808
810 const wxString& aValue,
811 int aFontSize, SCH_SHEET_PATH* aSheet,
812 std::vector<LTSPICE_SCHEMATIC::WIRE>& aWires )
813{
814 LIB_SYMBOL* lib_symbol = new LIB_SYMBOL( wxS( "GND" ) );
815 SCH_SHAPE* shape = new SCH_SHAPE( SHAPE_T::POLY,LAYER_DEVICE );
816
817 shape->AddPoint( ToKicadCoords( { 16, 0 } ) );
818 shape->AddPoint( ToKicadCoords( { -16, 0 } ) );
819 shape->AddPoint( ToKicadCoords( { 0, 15 } ) );
820 shape->AddPoint( ToKicadCoords( { 16, 0 } ) );
821 shape->AddPoint( ToKicadCoords( { -16, 0 } ) );
822 shape->AddPoint( ToKicadCoords( { 0, 15 } ) );
823
825 LINE_STYLE::SOLID ) );
826
827 lib_symbol->AddDrawItem( shape );
828 lib_symbol->SetPower();
829
830 SCH_PIN* pin = new SCH_PIN( lib_symbol );
831
832 pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN );
833 pin->SetPosition( ToKicadCoords( { 0, 0 } ) );
834 pin->SetLength( 5 );
835 pin->SetShape( GRAPHIC_PINSHAPE::LINE );
836 lib_symbol->AddDrawItem( pin );
837
838 LIB_ID libId( wxS( "ltspice" ), wxS( "GND" ) );
839 SCH_SYMBOL* sch_symbol = new SCH_SYMBOL( *lib_symbol, libId, aSheet, 1 );
840
841 sch_symbol->SetRef( aSheet, wxString::Format( wxS( "#GND%03d" ), m_powerSymbolIndex++ ) );
842 sch_symbol->GetField( REFERENCE_FIELD )->SetVisible( false );
843 sch_symbol->SetValueFieldText( wxS( "0" ) );
844 sch_symbol->GetField( VALUE_FIELD )->SetTextSize( ToKicadFontSize( aFontSize ) );
845 sch_symbol->GetField( VALUE_FIELD )->SetVisible( false );
846
847 sch_symbol->Move( ToKicadCoords( aOffset ) + m_originOffset );
848
849 for( LTSPICE_SCHEMATIC::WIRE& wire : aWires )
850 {
851 if( aOffset == wire.Start )
852 {
853 if( wire.Start.x == wire.End.x )
854 {
855 if( wire.Start.y < wire.End.y )
856 {
859 }
860 }
861 else
862 {
863 if( wire.Start.x < wire.End.x )
865 else if( wire.Start.x > wire.End.x )
867 }
868 }
869 else if( aOffset == wire.End )
870 {
871 if( wire.Start.x == wire.End.x )
872 {
873 if( wire.Start.y > wire.End.y )
874 {
877 }
878 }
879 else
880 {
881 if( wire.Start.x < wire.End.x )
883 else if( wire.Start.x > wire.End.x )
885 }
886 }
887 }
888
889 return sch_symbol;
890}
891
892
894 const wxString& aValue, int aFontSize )
895{
896 SCH_LABEL_BASE* label = nullptr;
897
898 if( aType == SCH_GLOBAL_LABEL_T )
899 {
900 label = new SCH_GLOBALLABEL();
901
902 label->SetText( aValue );
903 label->SetTextSize( ToKicadFontSize( aFontSize ) );
905 }
906 else if( aType == SCH_DIRECTIVE_LABEL_T )
907 {
908 label = new SCH_DIRECTIVE_LABEL();
909
911
912 SCH_FIELD field( { 0, 0 }, -1, label, wxS( "DATAFLAG" ) );
913 field.SetText( aValue );
914 field.SetTextSize( ToKicadFontSize( aFontSize ) );
915 field.SetVisible( true );
916
917 label->AddField( field );
918 label->AutoplaceFields( nullptr, false );
919 }
920 else
921 {
922 UNIMPLEMENTED_FOR( aType );
923 }
924
925 if( label )
926 {
927 label->SetPosition( ToKicadCoords( aOffset ) + m_originOffset );
928 label->SetVisible( true );
929 }
930
931 return label;
932}
933
934
936 SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aSheet )
937{
938 wxString libPath = m_lt_schematic->GetLTspiceDataDir().GetFullPath();
939 wxString symbolName = aLTSymbol.Name.Upper();
940 wxString type = aLTSymbol.SymAttributes[wxS( "TYPE" )].Upper();
941 wxString prefix = aLTSymbol.SymAttributes[wxS( "PREFIX" )].Upper();
942 wxString instName = aLTSymbol.SymAttributes[wxS( "INSTNAME" )].Upper();
943 wxString value = aLTSymbol.SymAttributes[wxS( "VALUE" )];
944 wxString value2 = aLTSymbol.SymAttributes[wxS( "VALUE2" )];
945
946 if( value.IsEmpty() )
947 {
948 value = value2;
949 value2 = wxEmptyString;
950 }
951
952 aSymbol->SetRef( aSheet, instName );
953 aSymbol->SetValueFieldText( value );
954
955 if( !value2.IsEmpty() )
956 {
957 SCH_FIELD paramsField( { 0, 0 }, -1, aSymbol, wxS( "Value2" ) );
958 paramsField.SetText( value2 );
959 aSymbol->AddField( paramsField );
960 }
961
962 auto setupNonInferredPassive = [&]( const wxString& aDevice, const wxString& aValueKey )
963 {
964 SCH_FIELD deviceField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Device" ) );
965 deviceField.SetText( aDevice );
966 aSymbol->AddField( deviceField );
967
968 SCH_FIELD paramsField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Params" ) );
969 paramsField.SetText( aValueKey + wxS( "=${VALUE}" ) );
970 aSymbol->AddField( paramsField );
971 };
972
973 auto setupBehavioral = [&]( const wxString& aDevice, const wxString& aType )
974 {
975 aSymbol->SetValueFieldText( wxS( "${Sim.Params}" ) );
976
977 SCH_FIELD deviceField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Device" ) );
978 deviceField.SetText( aDevice );
979 aSymbol->AddField( deviceField );
980
981 SCH_FIELD typeField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Type" ) );
982 typeField.SetText( aType );
983 aSymbol->AddField( typeField );
984
985 SCH_FIELD paramsField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Params" ) );
986 paramsField.SetText( value );
987 aSymbol->AddField( paramsField );
988 };
989
990 static const std::set<wxString> prefixWithGain = { wxS( "E" ), wxS( "F" ), wxS( "G" ),
991 wxS( "H" ) };
992
993 if( prefix == wxS( "R" ) )
994 {
995 setupNonInferredPassive( prefix, wxS( "R" ) );
996 }
997 else if( prefix == wxS( "C" ) )
998 {
999 setupNonInferredPassive( prefix, wxS( "C" ) );
1000 }
1001 else if( prefix == wxS( "L" ) )
1002 {
1003 setupNonInferredPassive( prefix, wxS( "L" ) );
1004 }
1005 else if( prefixWithGain.count( prefix ) > 0 )
1006 {
1007 setupNonInferredPassive( prefix, wxS( "gain" ) );
1008 }
1009 else if( prefix == wxS( "B" ) )
1010 {
1011 if( symbolName.StartsWith( wxS( "BV" ) ) )
1012 {
1013 setupBehavioral( wxS( "V" ), wxS( "=" ) );
1014 }
1015 else if( symbolName.StartsWith( wxS( "BI" ) ) )
1016 {
1017 setupBehavioral( wxS( "I" ), wxS( "=" ) );
1018 }
1019 }
1020 else if( prefix == wxS( "V" ) || symbolName == wxS( "I" ) )
1021 {
1022 SCH_FIELD deviceField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Device" ) );
1023 deviceField.SetText( wxS( "SPICE" ) );
1024 aSymbol->AddField( deviceField );
1025
1026 wxString simParams;
1027 simParams << "type=" << '"' << prefix << '"' << ' ';
1028
1029 if( value2.IsEmpty() )
1030 simParams << "model=" << '"' << "${VALUE}" << '"' << ' ';
1031 else
1032 simParams << "model=" << '"' << "${VALUE} ${VALUE2}" << '"' << ' ';
1033
1034 SCH_FIELD paramsField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Params" ) );
1035 paramsField.SetText( simParams );
1036 aSymbol->AddField( paramsField );
1037 }
1038 else
1039 {
1040 wxString libFile = aLTSymbol.SymAttributes[wxS( "MODELFILE" )];
1041
1042 if( prefix == wxS( "X" ) )
1043 {
1044 // A prefix of X overrides the simulation model for other symbols (npn, etc.)
1045 type = wxS( "X" );
1046 }
1047 else if( libFile.IsEmpty() )
1048 {
1049 if( type.IsEmpty() )
1050 type = symbolName;
1051
1052 if( value == "DIODE" )
1053 libFile = libPath + wxS( "cmp/standard.dio" );
1054 else if( value == "NPN" || value == "PNP" )
1055 libFile = libPath + wxS( "cmp/standard.bjt" );
1056 else if( value == "NJF" || value == "PJF" )
1057 libFile = libPath + wxS( "cmp/standard.jft" );
1058 else if( value == "NMOS" || value == "PMOS" )
1059 libFile = libPath + wxS( "cmp/standard.mos" );
1060 }
1061
1062 if( libFile.IsEmpty() )
1063 libFile = m_includes[value];
1064
1065 if( !libFile.IsEmpty() )
1066 {
1067 SCH_FIELD libField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Library" ) );
1068 libField.SetText( libFile );
1069 aSymbol->AddField( libField );
1070 }
1071
1072 if( type == wxS( "X" ) )
1073 {
1074 SCH_FIELD deviceField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Device" ) );
1075 deviceField.SetText( wxS( "SUBCKT" ) );
1076 aSymbol->AddField( deviceField );
1077 }
1078 else
1079 {
1080 SCH_FIELD deviceField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Device" ) );
1081 deviceField.SetText( wxS( "SPICE" ) );
1082 aSymbol->AddField( deviceField );
1083 }
1084
1085 wxString spiceLine = aLTSymbol.SymAttributes[wxS( "SPICELINE" )];
1086
1087 if( !spiceLine.IsEmpty() )
1088 {
1089 // TODO: append value
1090 SCH_FIELD paramsField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Params" ) );
1091 paramsField.SetText( spiceLine );
1092 aSymbol->AddField( paramsField );
1093 }
1094 else
1095 {
1096 SCH_FIELD modelField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Params" ) );
1097 modelField.SetText( "model=\"" + value + "\"" );
1098 aSymbol->AddField( modelField );
1099 }
1100 }
1101
1102 for( LTSPICE_SCHEMATIC::LT_WINDOW& lt_window : aLTSymbol.Windows )
1103 {
1104 SCH_FIELD* field = nullptr;
1105
1106 switch( lt_window.WindowNumber )
1107 {
1108 case -1: /* PartNum */ break;
1109 case 0: /* InstName */ field = aSymbol->GetField( REFERENCE_FIELD ); break;
1110 case 1: /* Type */ break;
1111 case 2: /* RefName */ break;
1112 case 3: /* Value */ field = aSymbol->GetField( VALUE_FIELD ); break;
1113
1114 case 5: /* QArea */ break;
1115
1116 case 8: /* Width */ break;
1117 case 9: /* Length */ break;
1118 case 10: /* Multi */ break;
1119
1120 case 16: /* Nec */ break;
1121
1122 case 38: /* SpiceModel */ field = aSymbol->FindField( wxS( "Sim.Name" ) ); break;
1123 case 39: /* SpiceLine */ field = aSymbol->FindField( wxS( "Sim.Params" ) ); break;
1124 case 40: /* SpiceLine2 */ break;
1125
1126 /*
1127 47 Def_Sub
1128
1129 50 Digital_Timing_Model
1130 51 Digital_Extracts
1131 52 Digital_IO_Model
1132 53 Digital_Line
1133 54 Digital_Primitive
1134 55 Digital_MNTYMXDLY
1135 56 Digital_IO_LEVEL
1136 57 Digital_StdCell
1137 58 Digital_File
1138
1139 105 Cell
1140 106 W/L
1141 107 PSIZE
1142 108 NSIZE
1143 109 sheets
1144 110 sh#
1145 111 Em_Scale
1146 112 Epi
1147 113 Sinker
1148 114 Multi5
1149
1150 118 AQ
1151 119 AQSUB
1152 120 ZSIZE
1153 121 ESR
1154 123 Value2
1155 124 COUPLE
1156 125 Voltage
1157 126 Area1
1158 127 Area2
1159 128 Area3
1160 129 Area4
1161 130 Multi1
1162 131 Multi2
1163 132 Multi3
1164 133 Multi4
1165 134 DArea
1166 135 DPerim
1167 136 CArea
1168 137 CPerim
1169 138 Shrink
1170 139 Gate_Resize
1171
1172 142 BP
1173 143 BN
1174 144 Sim_Level
1175
1176 146 G_Voltage
1177
1178 150 SpiceLine3
1179
1180 153 D_VOLTAGES
1181
1182 156 Version
1183 157 Comment
1184 158 XDef_Sub
1185 159 LVS_Area
1186
1187 162 User1
1188 163 User2
1189 164 User3
1190 165 User4
1191 166 User5
1192 167 Root
1193 168 Class
1194 169 Geometry
1195 170 WL_Delimiter
1196
1197 175 T1
1198 176 T2
1199
1200 184 DsgnName
1201 185 Designer
1202
1203 190 RTN
1204 191 PWR
1205 192 BW
1206
1207 201 CAPROWS
1208 202 CAPCOLS
1209 203 NF
1210 204 SLICES
1211 205 CUR
1212 206 TEMPRISE
1213 207 STRIPS
1214 208 WEM
1215 209 LEM
1216 210 BASES
1217 211 COLS
1218 212 XDef_Tub
1219 */
1220 default: break;
1221 }
1222
1223 if( field )
1224 {
1225 field->SetPosition( ToKicadCoords( lt_window.Position ) );
1226 field->SetTextSize( ToKicadFontSize( lt_window.FontSize ) );
1227
1228 if( lt_window.FontSize == 0 )
1229 field->SetVisible( false );
1230
1231 setTextJustification( field, lt_window.Justification );
1232 }
1233 }
1234}
1235
1236
1238 SCH_SHAPE* aRectangle )
1239{
1240 LTSPICE_SCHEMATIC::RECTANGLE& lt_rect = aLTSymbol.Rectangles[aIndex];
1241
1242 aRectangle->SetPosition( ToKicadCoords( lt_rect.BotRight ) );
1243 aRectangle->SetEnd( ToKicadCoords( lt_rect.TopLeft ) );
1244 aRectangle->SetStroke( getStroke( lt_rect.LineWidth, lt_rect.LineStyle ) );
1245
1246 if( aLTSymbol.SymAttributes[wxS( "Prefix" )] == wxS( "X" ) )
1247 aRectangle->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
1248}
1249
1250
1252 SCH_SHEET_PATH* aSheet )
1253{
1254 LTSPICE_SCHEMATIC::RECTANGLE& lt_rect = aLTSymbol.Rectangles[aIndex];
1255 SCH_SHAPE* rectangle = new SCH_SHAPE( SHAPE_T::RECTANGLE );
1256
1257 rectangle->SetPosition( ToKicadCoords( lt_rect.BotRight ) );
1258 rectangle->SetEnd( ToKicadCoords( lt_rect.TopLeft ) );
1259 rectangle->SetStroke( getStroke( lt_rect.LineWidth, lt_rect.LineStyle ) );
1260
1261 rectangle->Move( aLTSymbol.Offset );
1262 RotateMirrorShape( aLTSymbol, rectangle );
1263
1264 aSheet->LastScreen()->Append( rectangle );
1265}
1266
1267
1269 SCH_PIN* aPin )
1270{
1271 LTSPICE_SCHEMATIC::LT_PIN& lt_pin = aLTSymbol.Pins[aIndex];
1272 wxString device = aLTSymbol.Name.Lower();
1273
1274 if( aLTSymbol.Pins.size() == 2 && ( device == wxS( "res" )
1275 || device == wxS( "cap" )
1276 || device == wxS( "ind" ) ) )
1277 {
1278 // drop A/B pin names from simple LRCs as they're not terribly useful (and prevent
1279 // other pin names on the net from driving the net name).
1280 }
1281 else
1282 {
1283 aPin->SetName( lt_pin.PinAttribute[ wxS( "PinName" ) ] );
1284
1286 aPin->SetNameTextSize( 0 );
1287 }
1288
1289 aPin->SetNumber( wxString::Format( wxS( "%d" ), aIndex + 1 ) );
1290 aPin->SetType( ELECTRICAL_PINTYPE::PT_PASSIVE );
1291 aPin->SetPosition( ToKicadCoords( lt_pin.PinLocation ) );
1292 aPin->SetLength( 5 );
1293 aPin->SetShape( GRAPHIC_PINSHAPE::LINE );
1294
1295 switch( lt_pin.PinJustification )
1296 {
1299 aPin->SetOrientation( PIN_ORIENTATION::PIN_RIGHT );
1300 break;
1301
1304 aPin->SetOrientation( PIN_ORIENTATION::PIN_LEFT );
1305 break;
1306
1309 aPin->SetOrientation( PIN_ORIENTATION::PIN_UP );
1310 break;
1311
1314 aPin->SetOrientation( PIN_ORIENTATION::PIN_DOWN );
1315 break;
1316
1317 default: break;
1318 }
1319}
1320
1321
1323 SCH_SHAPE* aArc )
1324{
1325 LTSPICE_SCHEMATIC::ARC& lt_arc = aLTSymbol.Arcs[aIndex];
1326
1327 aArc->SetCenter( ToKicadCoords( ( lt_arc.TopLeft + lt_arc.BotRight ) / 2 ) );
1328 aArc->SetEnd( ToKicadCoords( lt_arc.ArcEnd ) );
1329 aArc->SetStart( ToKicadCoords( lt_arc.ArcStart ) );
1330 aArc->SetStroke( getStroke( lt_arc.LineWidth, lt_arc.LineStyle ) );
1331}
1332
1333
1335 SCH_SHEET_PATH* aSheet )
1336{
1337 LTSPICE_SCHEMATIC::ARC& lt_arc = aLTSymbol.Arcs[aIndex];
1338 SCH_SHAPE* arc = new SCH_SHAPE( SHAPE_T::ARC );
1339
1340 arc->SetCenter( ToKicadCoords( ( lt_arc.TopLeft + lt_arc.BotRight ) / 2 ) );
1341 arc->SetEnd( ToKicadCoords( lt_arc.ArcEnd ) );
1342 arc->SetStart( ToKicadCoords( lt_arc.ArcStart ) );
1343 arc->SetStroke( getStroke( lt_arc.LineWidth, lt_arc.LineStyle ) );
1344
1345 arc->Move( ToKicadCoords( aLTSymbol.Offset ) + m_originOffset );
1346 RotateMirrorShape( aLTSymbol, arc );
1347
1348 aSheet->LastScreen()->Append( arc );
1349}
1350
1351
1353 SCH_SHEET_PATH* aSheet )
1354{
1355 LTSPICE_SCHEMATIC::CIRCLE& lt_circle = aLTSymbol.Circles[aIndex];
1356 SCH_SHAPE* circle = new SCH_SHAPE( SHAPE_T::CIRCLE );
1357
1358 VECTOR2I c = ( lt_circle.TopLeft + lt_circle.BotRight ) / 2;
1359 int r = ( lt_circle.TopLeft.x - lt_circle.BotRight.x ) / 2;
1360
1361 circle->SetPosition( ToKicadCoords( c ) );
1362 circle->SetEnd( ToKicadCoords( c ) + VECTOR2I( abs( ToKicadCoords( r ) ), 0 ) );
1363 circle->SetStroke( getStroke( lt_circle.LineWidth, lt_circle.LineStyle ) );
1364
1365 circle->Move( aLTSymbol.Offset );
1366 RotateMirrorShape( aLTSymbol, circle );
1367
1368 aSheet->LastScreen()->Append( circle );
1369}
1370
1371
1373 SCH_SHAPE* aCircle )
1374{
1375 LTSPICE_SCHEMATIC::CIRCLE& lt_circle = aLTSymbol.Circles[aIndex];
1376
1377 VECTOR2I c = ( lt_circle.TopLeft + lt_circle.BotRight ) / 2;
1378 int r = ( lt_circle.TopLeft.x - lt_circle.BotRight.x ) / 2;
1379
1380 aCircle->SetPosition( ToKicadCoords( c ) );
1381 aCircle->SetEnd( ToKicadCoords( c ) + VECTOR2I( abs( ToKicadCoords( r ) ), 0 ) );
1382 aCircle->SetStroke( getStroke( lt_circle.LineWidth, lt_circle.LineStyle ) );
1383}
1384
1385
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
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)
Definition: eda_shape.cpp:778
void SetStart(const VECTOR2I &aStart)
Definition: eda_shape.h:141
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:178
void SetFillMode(FILL_T aFill)
Definition: eda_shape.h:113
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:251
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:506
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:408
void Offset(const VECTOR2I &aOffset)
Definition: eda_text.cpp:569
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:377
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:269
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:291
void SetMultilineAllowed(bool aAllow)
Definition: eda_text.cpp:392
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:400
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:78
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: lib_symbol.h:243
void SetPower()
Definition: lib_symbol.cpp:405
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
Definition: lib_symbol.cpp:808
LT_SYMBOL SymbolBuilder(const wxString &aAscFileName, LT_ASC &aAscFile)
POLARITY
Polarity enum represents polarity of pin.
const wxFileName & GetLTspiceDataDir()
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:171
void SetSize(const VECTOR2I &aSize)
Definition: sch_bus_entry.h:74
Class for a wire to bus entry.
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
Definition: sch_field.h:51
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_field.cpp:1463
void SetText(const wxString &aText) override
Definition: sch_field.cpp:1210
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
SCH_LABEL_BASE * CreateSCH_LABEL(KICAD_T aType, const VECTOR2I &aOffset, const wxString &aValue, int aFontSize)
Create a label.
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)
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:282
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_label.cpp:378
void AddField(const SCH_FIELD &aField)
Definition: sch_label.h:219
void SetShape(LABEL_FLAG_SHAPE aShape)
Definition: sch_label.h:178
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_label.cpp:371
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Definition: sch_label.cpp:563
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
Definition: sch_label.cpp:297
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:41
void SetStartPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:137
void SetLineWidth(const int aSize)
Definition: sch_line.cpp:317
void SetLineStyle(const LINE_STYLE aStyle)
Definition: sch_line.cpp:288
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_line.cpp:155
virtual void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: sch_line.h:185
void SetEndPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:142
void SetNumber(const wxString &aNumber)
Definition: sch_pin.cpp:514
void SetOrientation(PIN_ORIENTATION aOrientation)
Definition: sch_pin.h:86
void SetName(const wxString &aName)
Definition: sch_pin.cpp:393
void SetPosition(const VECTOR2I &aPos) override
Definition: sch_pin.h:203
void SetLength(int aLength)
Definition: sch_pin.h:92
void SetShape(GRAPHIC_PINSHAPE aShape)
Definition: sch_pin.h:89
void SetType(ELECTRICAL_PINTYPE aType)
Definition: sch_pin.cpp:324
void SetNameTextSize(int aSize)
Definition: sch_pin.cpp:542
const PAGE_INFO & GetPageSettings() const
Definition: sch_screen.h:130
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Definition: sch_screen.cpp:153
void SetPosition(const VECTOR2I &aPos) override
Definition: sch_shape.h:71
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_shape.cpp:96
void Move(const VECTOR2I &aOffset) override
Move the item by aMoveVector to a new position.
Definition: sch_shape.cpp:69
void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: sch_shape.cpp:63
void MirrorVertically(int aCenter) override
Mirror item vertically about aCenter.
Definition: sch_shape.cpp:102
void AddPoint(const VECTOR2I &aPosition)
Definition: sch_shape.cpp:579
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_shape.cpp:108
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:104
void SetValueFieldText(const wxString &aValue)
Definition: sch_symbol.cpp:917
SCH_FIELD * FindField(const wxString &aFieldName, bool aIncludeDefaultFields=true, bool aCaseInsensitive=false)
Search for a SCH_FIELD with aFieldName.
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_symbol.h:723
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:939
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
Definition: sch_symbol.cpp:779
void SetOrientation(int aOrientation)
Compute the new transform matrix based on aOrientation for the symbol which is applied to the current...
SCH_FIELD * AddField(const SCH_FIELD &aField)
Add a field to the symbol.
Simple container to manage line stroke parameters.
Definition: stroke_params.h:79
virtual void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
Definition: symbol.h:129
static constexpr EDA_ANGLE ANGLE_VERTICAL
Definition: eda_angle.h:398
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition: eda_angle.h:397
SCH_LAYER_ID
Eeschema drawing layers.
Definition: layer_ids.h:353
@ LAYER_DEVICE
Definition: layer_ids.h:370
#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
LABEL_FLAG_SHAPE getLabelShape(LTSPICE_SCHEMATIC::POLARITY aPolarity)
LABEL_FLAG_SHAPE
Definition: sch_label.h:98
@ L_BIDI
Definition: sch_label.h:101
@ L_OUTPUT
Definition: sch_label.h:100
@ L_INPUT
Definition: sch_label.h:99
@ SYM_ROTATE_CLOCKWISE
Definition: sch_symbol.h:78
@ SYM_ROTATE_COUNTERCLOCKWISE
Definition: sch_symbol.h:79
@ SYM_MIRROR_Y
Definition: sch_symbol.h:85
@ SYM_ORIENT_180
Definition: sch_symbol.h:82
@ SYM_MIRROR_X
Definition: sch_symbol.h:84
@ SYM_ORIENT_0
Definition: sch_symbol.h:80
LINE_STYLE
Dashed line types.
Definition: stroke_params.h:46
constexpr int IUToMils(int iu) const
Definition: base_units.h:99
const double IU_PER_MILS
Definition: base_units.h:77
constexpr int MilsToIU(int mils) const
Definition: base_units.h:93
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< LINE > Lines
std::vector< WIRE > Wires
std::vector< RECTANGLE > Rectangles
std::vector< FLAG > Flags
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< 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.
@ VALUE_FIELD
Field Value of part, i.e. "3.3K".
@ REFERENCE_FIELD
Field Reference of part, i.e. "IC21".
@ 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:171
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:169
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:168
T rescale(T aNumerator, T aValue, T aDenominator)
Scale a number (value) by rational (numerator/denominator).
Definition: util.h:153
VECTOR2< int32_t > VECTOR2I
Definition: vector2d.h:691