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
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, 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
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 ) );
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 {
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
803 segment->SetLineStyle( LINE_STYLE::SOLID );
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" ) );
819 SCH_SHAPE* shape = new SCH_SHAPE( SHAPE_T::POLY,LAYER_DEVICE );
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
829 LINE_STYLE::SOLID ) );
830
831 lib_symbol->AddDrawItem( shape );
832 lib_symbol->SetGlobalPower();
833
834 SCH_PIN* pin = new SCH_PIN( lib_symbol );
835
836 pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN );
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( 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( "V" ) || symbolName == wxS( "I" ) )
1059 {
1060 addField( wxS( "Sim.Device" ), wxS( "SPICE" ) );
1061
1062 wxString simParams;
1063 simParams << "type=" << '"' << prefix << '"' << ' ';
1064
1065 if( value2.IsEmpty() )
1066 simParams << "model=" << '"' << "${VALUE}" << '"' << ' ';
1067 else
1068 simParams << "model=" << '"' << "${VALUE} ${VALUE2}" << '"' << ' ';
1069
1070 addField( wxS( "Sim.Params" ), simParams );
1071 }
1072 else
1073 {
1074 wxString libFile = aLTSymbol.SymAttributes[wxS( "MODELFILE" )];
1075
1076 if( prefix == wxS( "X" ) )
1077 {
1078 // A prefix of X overrides the simulation model for other symbols (npn, etc.)
1079 type = wxS( "X" );
1080 }
1081 else if( libFile.IsEmpty() )
1082 {
1083 if( type.IsEmpty() )
1084 type = symbolName;
1085
1086 if( value == "DIODE" )
1087 libFile = libPath + wxS( "cmp/standard.dio" );
1088 else if( value == "NPN" || value == "PNP" )
1089 libFile = libPath + wxS( "cmp/standard.bjt" );
1090 else if( value == "NJF" || value == "PJF" )
1091 libFile = libPath + wxS( "cmp/standard.jft" );
1092 else if( value == "NMOS" || value == "PMOS" )
1093 libFile = libPath + wxS( "cmp/standard.mos" );
1094 }
1095
1096 if( libFile.IsEmpty() )
1097 libFile = m_includes[value];
1098
1099 if( !libFile.IsEmpty() )
1100 addField( wxS( "Sim.Library" ), libFile );
1101
1102 if( type == wxS( "X" ) )
1103 addField( wxS( "Sim.Device" ), wxS( "SUBCKT" ) );
1104 else
1105 addField( wxS( "Sim.Device" ), wxS( "SPICE" ) );
1106
1107 wxString spiceLine = aLTSymbol.SymAttributes[wxS( "SPICELINE" )];
1108
1109 if( !spiceLine.IsEmpty() )
1110 {
1111 // TODO: append value
1112 addField( wxS( "Sim.Params" ), spiceLine );
1113 }
1114 else
1115 {
1116 addField( wxS( "Sim.Params" ), "model=\"" + value + "\"" );
1117 }
1118 }
1119
1120 for( LTSPICE_SCHEMATIC::LT_WINDOW& lt_window : aLTSymbol.Windows )
1121 {
1122 SCH_FIELD* field = nullptr;
1123
1124 switch( lt_window.WindowNumber )
1125 {
1126 case -1: /* PartNum */ break;
1127 case 0: /* InstName */ field = aSymbol->GetField( FIELD_T::REFERENCE ); break;
1128 case 1: /* Type */ break;
1129 case 2: /* RefName */ break;
1130 case 3: /* Value */ field = aSymbol->GetField( FIELD_T::VALUE ); break;
1131
1132 case 5: /* QArea */ break;
1133
1134 case 8: /* Width */ break;
1135 case 9: /* Length */ break;
1136 case 10: /* Multi */ break;
1137
1138 case 16: /* Nec */ break;
1139
1140 case 38: /* SpiceModel */ field = aSymbol->GetField( wxS( "Sim.Name" ) ); break;
1141 case 39: /* SpiceLine */ field = aSymbol->GetField( wxS( "Sim.Params" ) ); break;
1142 case 40: /* SpiceLine2 */ break;
1143
1144 /*
1145 47 Def_Sub
1146
1147 50 Digital_Timing_Model
1148 51 Digital_Extracts
1149 52 Digital_IO_Model
1150 53 Digital_Line
1151 54 Digital_Primitive
1152 55 Digital_MNTYMXDLY
1153 56 Digital_IO_LEVEL
1154 57 Digital_StdCell
1155 58 Digital_File
1156
1157 105 Cell
1158 106 W/L
1159 107 PSIZE
1160 108 NSIZE
1161 109 sheets
1162 110 sh#
1163 111 Em_Scale
1164 112 Epi
1165 113 Sinker
1166 114 Multi5
1167
1168 118 AQ
1169 119 AQSUB
1170 120 ZSIZE
1171 121 ESR
1172 123 Value2
1173 124 COUPLE
1174 125 Voltage
1175 126 Area1
1176 127 Area2
1177 128 Area3
1178 129 Area4
1179 130 Multi1
1180 131 Multi2
1181 132 Multi3
1182 133 Multi4
1183 134 DArea
1184 135 DPerim
1185 136 CArea
1186 137 CPerim
1187 138 Shrink
1188 139 Gate_Resize
1189
1190 142 BP
1191 143 BN
1192 144 Sim_Level
1193
1194 146 G_Voltage
1195
1196 150 SpiceLine3
1197
1198 153 D_VOLTAGES
1199
1200 156 Version
1201 157 Comment
1202 158 XDef_Sub
1203 159 LVS_Area
1204
1205 162 User1
1206 163 User2
1207 164 User3
1208 165 User4
1209 166 User5
1210 167 Root
1211 168 Class
1212 169 Geometry
1213 170 WL_Delimiter
1214
1215 175 T1
1216 176 T2
1217
1218 184 DsgnName
1219 185 Designer
1220
1221 190 RTN
1222 191 PWR
1223 192 BW
1224
1225 201 CAPROWS
1226 202 CAPCOLS
1227 203 NF
1228 204 SLICES
1229 205 CUR
1230 206 TEMPRISE
1231 207 STRIPS
1232 208 WEM
1233 209 LEM
1234 210 BASES
1235 211 COLS
1236 212 XDef_Tub
1237 */
1238 default: break;
1239 }
1240
1241 if( field )
1242 {
1243 field->SetPosition( ToKicadCoords( lt_window.Position ) );
1244 field->SetTextSize( ToKicadFontSize( lt_window.FontSize ) );
1245
1246 if( lt_window.FontSize == 0 )
1247 field->SetVisible( false );
1248
1249 setTextJustification( field, lt_window.Justification );
1250 }
1251 }
1252}
1253
1254
1256 SCH_SHAPE* aRectangle )
1257{
1258 LTSPICE_SCHEMATIC::RECTANGLE& lt_rect = aLTSymbol.Rectangles[aIndex];
1259
1260 aRectangle->SetPosition( ToKicadCoords( lt_rect.BotRight ) );
1261 aRectangle->SetEnd( ToKicadCoords( lt_rect.TopLeft ) );
1262 aRectangle->SetStroke( getStroke( lt_rect.LineWidth, lt_rect.LineStyle ) );
1263
1264 if( aLTSymbol.SymAttributes[wxS( "Prefix" )] == wxS( "X" ) )
1265 aRectangle->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
1266}
1267
1268
1270 SCH_SHEET_PATH* aSheet )
1271{
1272 LTSPICE_SCHEMATIC::RECTANGLE& lt_rect = aLTSymbol.Rectangles[aIndex];
1273 SCH_SHAPE* rectangle = new SCH_SHAPE( SHAPE_T::RECTANGLE );
1274
1275 rectangle->SetPosition( ToKicadCoords( lt_rect.BotRight ) );
1276 rectangle->SetEnd( ToKicadCoords( lt_rect.TopLeft ) );
1277 rectangle->SetStroke( getStroke( lt_rect.LineWidth, lt_rect.LineStyle ) );
1278
1279 rectangle->Move( aLTSymbol.Offset );
1280 RotateMirrorShape( aLTSymbol, rectangle );
1281
1282 aSheet->LastScreen()->Append( rectangle );
1283}
1284
1285
1287 SCH_PIN* aPin )
1288{
1289 LTSPICE_SCHEMATIC::LT_PIN& lt_pin = aLTSymbol.Pins[aIndex];
1290 wxString device = aLTSymbol.Name.Lower();
1291
1292 if( aLTSymbol.Pins.size() == 2 && ( device == wxS( "res" )
1293 || device == wxS( "cap" )
1294 || device == wxS( "ind" ) ) )
1295 {
1296 // drop A/B pin names from simple LRCs as they're not terribly useful (and prevent
1297 // other pin names on the net from driving the net name).
1298 }
1299 else
1300 {
1301 aPin->SetName( lt_pin.PinAttribute[ wxS( "PinName" ) ] );
1302
1304 aPin->SetNameTextSize( 0 );
1305 }
1306
1307 aPin->SetNumber( wxString::Format( wxS( "%d" ), aIndex + 1 ) );
1308 aPin->SetType( ELECTRICAL_PINTYPE::PT_PASSIVE );
1309 aPin->SetPosition( ToKicadCoords( lt_pin.PinLocation ) );
1310 aPin->SetLength( 5 );
1311 aPin->SetShape( GRAPHIC_PINSHAPE::LINE );
1312
1313 switch( lt_pin.PinJustification )
1314 {
1317 aPin->SetOrientation( PIN_ORIENTATION::PIN_RIGHT );
1318 break;
1319
1322 aPin->SetOrientation( PIN_ORIENTATION::PIN_LEFT );
1323 break;
1324
1327 aPin->SetOrientation( PIN_ORIENTATION::PIN_UP );
1328 break;
1329
1332 aPin->SetOrientation( PIN_ORIENTATION::PIN_DOWN );
1333 break;
1334
1335 default: break;
1336 }
1337}
1338
1339
1341 SCH_SHAPE* aArc )
1342{
1343 LTSPICE_SCHEMATIC::ARC& lt_arc = aLTSymbol.Arcs[aIndex];
1344
1345 aArc->SetCenter( ToKicadCoords( ( lt_arc.TopLeft + lt_arc.BotRight ) / 2 ) );
1346 aArc->SetStart( ToKicadCoords( lt_arc.ArcEnd ) );
1347 aArc->SetEnd( ToKicadCoords( lt_arc.ArcStart ) );
1348 aArc->SetStroke( getStroke( lt_arc.LineWidth, lt_arc.LineStyle ) );
1349}
1350
1351
1353 SCH_SHEET_PATH* aSheet )
1354{
1355 LTSPICE_SCHEMATIC::ARC& lt_arc = aLTSymbol.Arcs[aIndex];
1356 SCH_SHAPE* arc = new SCH_SHAPE( SHAPE_T::ARC );
1357
1358 arc->SetCenter( ToKicadCoords( ( lt_arc.TopLeft + lt_arc.BotRight ) / 2 ) );
1359 arc->SetStart( ToKicadCoords( lt_arc.ArcEnd ) );
1360 arc->SetEnd( ToKicadCoords( lt_arc.ArcStart ) );
1361 arc->SetStroke( getStroke( lt_arc.LineWidth, lt_arc.LineStyle ) );
1362
1363 arc->Move( ToKicadCoords( aLTSymbol.Offset ) + m_originOffset );
1364 RotateMirrorShape( aLTSymbol, arc );
1365
1366 aSheet->LastScreen()->Append( arc );
1367}
1368
1369
1371 SCH_SHEET_PATH* aSheet )
1372{
1373 LTSPICE_SCHEMATIC::CIRCLE& lt_circle = aLTSymbol.Circles[aIndex];
1374 SCH_SHAPE* circle = new SCH_SHAPE( SHAPE_T::CIRCLE );
1375
1376 VECTOR2I c = ( lt_circle.TopLeft + lt_circle.BotRight ) / 2;
1377 int r = ( lt_circle.TopLeft.x - lt_circle.BotRight.x ) / 2;
1378
1379 circle->SetPosition( ToKicadCoords( c ) );
1380 circle->SetEnd( ToKicadCoords( c ) + VECTOR2I( abs( ToKicadCoords( r ) ), 0 ) );
1381 circle->SetStroke( getStroke( lt_circle.LineWidth, lt_circle.LineStyle ) );
1382
1383 circle->Move( aLTSymbol.Offset );
1384 RotateMirrorShape( aLTSymbol, circle );
1385
1386 aSheet->LastScreen()->Append( circle );
1387}
1388
1389
1391 SCH_SHAPE* aCircle )
1392{
1393 LTSPICE_SCHEMATIC::CIRCLE& lt_circle = aLTSymbol.Circles[aIndex];
1394
1395 VECTOR2I c = ( lt_circle.TopLeft + lt_circle.BotRight ) / 2;
1396 int r = ( lt_circle.TopLeft.x - lt_circle.BotRight.x ) / 2;
1397
1398 aCircle->SetPosition( ToKicadCoords( c ) );
1399 aCircle->SetEnd( ToKicadCoords( c ) + VECTOR2I( abs( ToKicadCoords( r ) ), 0 ) );
1400 aCircle->SetStroke( getStroke( lt_circle.LineWidth, lt_circle.LineStyle ) );
1401}
1402
1403
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:114
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:955
void SetStart(const VECTOR2I &aStart)
Definition: eda_shape.h:177
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:219
void SetFillMode(FILL_T aFill)
Definition: eda_shape.cpp:539
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:79
int GetTextHeight() const
Definition: eda_text.h:264
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:533
virtual const wxString & GetText() const
Return the string associated with the text object.
Definition: eda_text.h:97
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
Definition: eda_text.cpp:417
void Offset(const VECTOR2I &aOffset)
Definition: eda_text.cpp:596
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:386
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:270
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:299
void SetMultilineAllowed(bool aAllow)
Definition: eda_text.cpp:401
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:409
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:85
void SetGlobalPower()
Definition: lib_symbol.cpp:476
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
Definition: lib_symbol.h:242
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:786
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.
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_field.cpp:1324
void SetText(const wxString &aText) override
Definition: sch_field.cpp:1092
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:310
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_label.cpp:384
void AddField(const SCH_FIELD &aField)
Definition: sch_label.h:223
void SetShape(LABEL_FLAG_SHAPE aShape)
Definition: sch_label.h:177
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_label.cpp:377
void AutoplaceFields(SCH_SCREEN *aScreen, AUTOPLACE_ALGO aAlgo) override
Definition: sch_label.cpp:567
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
Definition: sch_label.cpp:303
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:315
void SetLineStyle(const LINE_STYLE aStyle)
Definition: sch_line.cpp:286
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_line.cpp:162
virtual void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: sch_line.h:194
void SetEndPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:145
void SetNumber(const wxString &aNumber)
Definition: sch_pin.cpp:554
void SetOrientation(PIN_ORIENTATION aOrientation)
Definition: sch_pin.h:92
void SetName(const wxString &aName)
Definition: sch_pin.cpp:405
void SetPosition(const VECTOR2I &aPos) override
Definition: sch_pin.h:224
void SetLength(int aLength)
Definition: sch_pin.h:98
void SetShape(GRAPHIC_PINSHAPE aShape)
Definition: sch_pin.h:95
void SetType(ELECTRICAL_PINTYPE aType)
Definition: sch_pin.cpp:315
void SetNameTextSize(int aSize)
Definition: sch_pin.cpp:581
const PAGE_INFO & GetPageSettings() const
Definition: sch_screen.h:134
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Definition: sch_screen.cpp:160
void SetPosition(const VECTOR2I &aPos) override
Definition: sch_shape.h:85
void MirrorHorizontally(int aCenter) override
Mirror item horizontally about aCenter.
Definition: sch_shape.cpp:105
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.
Definition: sch_shape.cpp:111
void AddPoint(const VECTOR2I &aPosition)
Definition: sch_shape.cpp:403
void Rotate(const VECTOR2I &aCenter, bool aRotateCCW) override
Rotate the item around aCenter 90 degrees in the clockwise direction.
Definition: sch_shape.cpp:117
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:75
void SetValueFieldText(const wxString &aValue)
Definition: sch_symbol.cpp:730
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_symbol.h:693
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:592
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.
Definition: sch_symbol.cpp:807
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:752
void Move(const VECTOR2I &aVector) override
Definition: shape_circle.h:133
Simple container to manage line stroke parameters.
Definition: stroke_params.h:94
virtual void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
Definition: symbol.h:164
static constexpr EDA_ANGLE ANGLE_VERTICAL
Definition: eda_angle.h:408
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition: eda_angle.h:407
SCH_LAYER_ID
Eeschema drawing layers.
Definition: layer_ids.h:439
@ LAYER_DEVICE
Definition: layer_ids.h:456
#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)
@ AUTOPLACE_AUTO
Definition: sch_item.h:71
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.
Definition: stroke_params.h:46
constexpr int IUToMils(int iu) const
Definition: base_units.h:103
const double IU_PER_MILS
Definition: base_units.h:77
constexpr int MilsToIU(int mils) const
Definition: base_units.h:97
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.
@ 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
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:172
@ SCH_HIER_LABEL_T
Definition: typeinfo.h:170
@ SCH_GLOBAL_LABEL_T
Definition: typeinfo.h:169
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:695