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( ToInvertedKicadCoords( lt_line.End ) );
113 shape->AddPoint( ToInvertedKicadCoords( 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 LIB_PIN* pin = new LIB_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 return VECTOR2I( ToKicadCoords( aPos.x ), -ToKicadCoords( aPos.y ) );
336}
337
338
340{
341 auto MILS_SIZE =
342 []( int mils )
343 {
344 return VECTOR2I( schIUScale.MilsToIU( mils ), schIUScale.MilsToIU( mils ) );
345 };
346
347 if( aLTFontSize == 1 ) return MILS_SIZE( 36 );
348 else if( aLTFontSize == 2 ) return MILS_SIZE( 42 );
349 else if( aLTFontSize == 3 ) return MILS_SIZE( 50 );
350 else if( aLTFontSize == 4 ) return MILS_SIZE( 60 );
351 else if( aLTFontSize == 5 ) return MILS_SIZE( 72 );
352 else if( aLTFontSize == 6 ) return MILS_SIZE( 88 );
353 else if( aLTFontSize == 7 ) return MILS_SIZE( 108 );
354 else return ToKicadFontSize( 2 );
355}
356
357
359{
360 return schIUScale.IUToMils( rescale( 16, aCoordinate, 50 ) );
361}
362
363
365 SCH_SHAPE* aShape )
366{
368 {
369 aShape->Rotate( VECTOR2I(), true );
370 }
372 {
373 aShape->Rotate( VECTOR2I(), false );
374 aShape->Rotate( VECTOR2I(), false );
375 }
377 {
378 aShape->Rotate( VECTOR2I(), false );
379 }
381 {
382 aShape->MirrorVertically( 0 );
383 }
385 {
386 aShape->MirrorVertically( 0 );
387 aShape->Rotate( VECTOR2I(), false );
388 }
390 {
391 aShape->MirrorHorizontally( 0 );
392 }
394 {
395 aShape->MirrorVertically( 0 );
396 aShape->Rotate( VECTOR2I(), true );
397 }
398}
399
400
402 SCH_SYMBOL* aSchSymbol )
403{
405 {
406 aSchSymbol->SetOrientation( SYM_ORIENT_0 );
407 }
409 {
410 aSchSymbol->SetOrientation( SYM_ORIENT_180 );
412 }
414 {
415 aSchSymbol->SetOrientation( SYM_ORIENT_180 );
416 }
418 {
420 }
422 {
423 aSchSymbol->SetOrientation( SYM_MIRROR_Y );
424 }
426 {
427 aSchSymbol->SetOrientation( SYM_MIRROR_Y );
429 }
431 {
432 aSchSymbol->SetOrientation( SYM_MIRROR_X );
433 }
435 {
436 aSchSymbol->SetOrientation( SYM_MIRROR_Y );
438 }
439}
440
441
443 SCH_SHEET_PATH* aSheet )
444{
445 SCH_LINE* segment = new SCH_LINE();
446
448 segment->SetLineStyle( LINE_STYLE::SOLID );
449
450 segment->SetStartPoint( aLTSymbol.Wires[aIndex].Start );
451 segment->SetEndPoint( aLTSymbol.Wires[aIndex].End );
452
453 aSheet->LastScreen()->Append( segment );
454}
455
456
458 std::vector<LTSPICE_SCHEMATIC::LT_ASC>& outLT_ASCs )
459{
460 SCH_SCREEN* screen = aSheet->LastScreen();
461
462 for( LTSPICE_SCHEMATIC::LT_ASC& lt_asc : outLT_ASCs )
463 {
464 for( int j = 0; j < (int) lt_asc.Lines.size(); j++ )
465 CreateLine( lt_asc, j, aSheet );
466
467 for( int j = 0; j < (int) lt_asc.Circles.size(); j++ )
468 CreateCircle( lt_asc, j, aSheet );
469
470 for( int j = 0; j < (int) lt_asc.Arcs.size(); j++ )
471 CreateArc( lt_asc, j, aSheet );
472
473 for( int j = 0; j < (int) lt_asc.Rectangles.size(); j++ )
474 CreateRect( lt_asc, j, aSheet );
475
476 for( int j = 0; j < (int) lt_asc.Bustap.size(); j++ )
477 CreateBusEntry( lt_asc, j, aSheet );
478
498 for( int j = 0; j < (int) lt_asc.Wires.size(); j++ )
499 CreateWire( lt_asc, j, aSheet, SCH_LAYER_ID::LAYER_WIRE );
500
501 for( int j = 0; j < (int) lt_asc.Iopins.size(); j++ )
502 CreatePin( lt_asc, j, aSheet );
503
504 for( const LTSPICE_SCHEMATIC::FLAG& lt_flag : lt_asc.Flags )
505 {
506 if( lt_flag.Value == wxS( "0" ) )
507 {
508 screen->Append( CreatePowerSymbol( lt_flag.Offset, lt_flag.Value, lt_flag.FontSize,
509 aSheet, lt_asc.Wires ) );
510 }
511 else
512 {
513 screen->Append( CreateSCH_LABEL( SCH_GLOBAL_LABEL_T, lt_flag.Offset, lt_flag.Value,
514 lt_flag.FontSize ) );
515 }
516 }
517
518 for( const LTSPICE_SCHEMATIC::TEXT& lt_text : lt_asc.Texts )
519 {
520 wxString textVal = lt_text.Value;
521
522 // Includes are already handled through Sim.Library, comment them out
523 if( textVal.StartsWith( ".include " ) || textVal.StartsWith( ".inc " )
524 || textVal.StartsWith( ".lib " ) )
525 {
526 textVal = wxS( "* " ) + textVal;
527 }
528
529 screen->Append( CreateSCH_TEXT( lt_text.Offset, textVal, lt_text.FontSize,
530 lt_text.Justification ) );
531 }
532
533 for( const LTSPICE_SCHEMATIC::DATAFLAG& lt_flag : lt_asc.DataFlags )
534 {
536 lt_flag.Expression, lt_flag.FontSize ) );
537 }
538 }
539}
540
541
543 SCH_SHEET_PATH* aSheet )
544{
545 LTSPICE_SCHEMATIC::BUSTAP& bustap = aAscfile.Bustap[aIndex];
546
547 for( int k = 0; k < (int) aAscfile.Wires.size(); k++ )
548 {
549 if( ( aAscfile.Wires[k].Start == bustap.Start )
550 || ( aAscfile.Wires[k].End == bustap.Start ) )
551 {
552 CreateWire( aAscfile, k, aSheet, SCH_LAYER_ID::LAYER_BUS );
553 aAscfile.Wires.erase( aAscfile.Wires.begin() + k );
554 }
555 }
556
557 SCH_BUS_WIRE_ENTRY* busEntry = new SCH_BUS_WIRE_ENTRY( ToKicadCoords( { bustap.Start.x,
558 bustap.Start.y - 16 } ) );
559
560 busEntry->SetSize( { ToKicadCoords( 16 ), ToKicadCoords( 16 ) } );
561
562 aSheet->LastScreen()->Append( busEntry );
563}
564
565
567{
568 if( aPolarity == LTSPICE_SCHEMATIC::POLARITY::INPUT )
570 else if( aPolarity == LTSPICE_SCHEMATIC::POLARITY::OUTPUT )
572 else
574}
575
576
578 SCH_SHEET_PATH* aSheet )
579{
580 LTSPICE_SCHEMATIC::IOPIN& iopin = aAscfile.Iopins[aIndex];
581 wxString ioPinName;
582
583 for( unsigned int k = 0; k < aAscfile.Flags.size(); k++ )
584 {
585 if( ( aAscfile.Flags[k].Offset.x == iopin.Location.x )
586 && ( aAscfile.Flags[k].Offset.y == iopin.Location.y ) )
587 {
588 ioPinName = aAscfile.Flags[k].Value;
589 aAscfile.Flags.erase( aAscfile.Flags.begin() + k );
590 }
591 }
592
593 SCH_HIERLABEL* sheetPin =
594 new SCH_HIERLABEL( ToKicadCoords( iopin.Location ), ioPinName, SCH_HIER_LABEL_T );
595
596 sheetPin->Move( m_originOffset );
597
598 sheetPin->SetShape( getLabelShape( iopin.Polarity ) );
599 aSheet->LastScreen()->Append( sheetPin );
600}
601
602
604 SCH_SHEET_PATH* aSheet )
605{
606 LTSPICE_SCHEMATIC::LINE& lt_line = aAscfile.Lines[aIndex];
607 SCH_LINE* line = new SCH_LINE( ToKicadCoords( lt_line.Start ), SCH_LAYER_ID::LAYER_NOTES );
608
609 line->SetEndPoint( ToKicadCoords( lt_line.End ) );
610 line->SetStroke( getStroke( lt_line.LineWidth, lt_line.LineStyle ) );
611 line->Move( m_originOffset );
612
613 aSheet->LastScreen()->Append( line );
614}
615
616
618 SCH_SHEET_PATH* aSheet )
619{
620 LTSPICE_SCHEMATIC::CIRCLE& lt_circle = aAscfile.Circles[aIndex];
621 SCH_SHAPE* circle = new SCH_SHAPE( SHAPE_T::CIRCLE );
622
623 VECTOR2I c = ( lt_circle.TopLeft + lt_circle.BotRight ) / 2;
624 int r = ( lt_circle.TopLeft.x - lt_circle.BotRight.x ) / 2;
625
626 circle->SetPosition( ToKicadCoords( c ) );
627 circle->SetEnd( ToKicadCoords( c ) + VECTOR2I( abs( ToKicadCoords( r ) ), 0 ) );
628 circle->SetStroke( getStroke( lt_circle.LineWidth, lt_circle.LineStyle ) );
629 circle->Move( m_originOffset );
630
631 aSheet->LastScreen()->Append( circle );
632}
633
634
636 SCH_SHEET_PATH* aSheet )
637{
638 LTSPICE_SCHEMATIC::ARC& lt_arc = aAscfile.Arcs[aIndex];
639 SCH_SHAPE* arc = new SCH_SHAPE( SHAPE_T::ARC );
640
641 arc->SetCenter( ToKicadCoords( ( lt_arc.TopLeft + lt_arc.BotRight ) / 2 ) );
642 arc->SetEnd( ToKicadCoords( lt_arc.ArcEnd ) );
643 arc->SetStart( ToKicadCoords( lt_arc.ArcStart ) );
644 arc->SetStroke( getStroke( lt_arc.LineWidth, lt_arc.LineStyle ) );
645 arc->Move( m_originOffset );
646
647 aSheet->LastScreen()->Append( arc );
648}
649
650
652 SCH_SHEET_PATH* aSheet )
653{
654 LTSPICE_SCHEMATIC::RECTANGLE& lt_rect = aAscfile.Rectangles[aIndex];
655 SCH_SHAPE* rectangle = new SCH_SHAPE( SHAPE_T::RECTANGLE );
656
657 rectangle->SetPosition( ToKicadCoords( lt_rect.TopLeft ) );
658 rectangle->SetEnd( ToKicadCoords( lt_rect.BotRight ) );
659 rectangle->SetStroke( getStroke( lt_rect.LineWidth, lt_rect.LineStyle ) );
660 rectangle->Move( m_originOffset );
661
662 aSheet->LastScreen()->Append( rectangle );
663}
664
665
667{
668 if( aLineWidth == LTSPICE_SCHEMATIC::LINEWIDTH::Normal )
669 return schIUScale.MilsToIU( 6 );
670 else if( aLineWidth == LTSPICE_SCHEMATIC::LINEWIDTH::Wide )
671 return schIUScale.MilsToIU( 12 );
672 else
673 return schIUScale.MilsToIU( 6 );
674}
675
676
678{
679 switch( aLineStyle )
680 {
681 case LTSPICE_SCHEMATIC::LINESTYLE::SOLID: return LINE_STYLE::SOLID;
682 case LTSPICE_SCHEMATIC::LINESTYLE::DOT: return LINE_STYLE::DOT;
683 case LTSPICE_SCHEMATIC::LINESTYLE::DASHDOTDOT: return LINE_STYLE::DASHDOTDOT;
684 case LTSPICE_SCHEMATIC::LINESTYLE::DASHDOT: return LINE_STYLE::DASHDOT;
685 case LTSPICE_SCHEMATIC::LINESTYLE::DASH: return LINE_STYLE::DASH;
686 default: return LINE_STYLE::SOLID;
687 }
688}
689
690
692 const LTSPICE_SCHEMATIC::LINESTYLE& aLineStyle )
693{
694 return STROKE_PARAMS( getLineWidth( aLineWidth ), getLineStyle( aLineStyle ) );
695}
696
697
699 LTSPICE_SCHEMATIC::JUSTIFICATION aJustification )
700{
701 switch( aJustification )
702 {
707 break;
708
713 break;
714
719 break;
720
725 break;
726
731 break;
732
733 default: break;
734 }
735
736 switch( aJustification )
737 {
744 break;
745
752 break;
753
754 default: break;
755 }
756
757 // Center, Left, Right aligns by first line in multiline text
758 if( wxSplit( aText->GetText(), '\n', '\0' ).size() > 1 )
759 {
760 switch( aJustification )
761 {
766 aText->Offset( VECTOR2I( 0, -aText->GetTextHeight() / 2 ) );
767 break;
768
773 aText->Offset( VECTOR2I( -aText->GetTextHeight() / 2, 0 ) );
774 break;
775
776 default: break;
777 }
778 }
779}
780
781
783 int aFontSize,
784 LTSPICE_SCHEMATIC::JUSTIFICATION aJustification )
785{
786 VECTOR2I pos = ToKicadCoords( aOffset ) + m_originOffset;
787 SCH_TEXT* textItem = new SCH_TEXT( pos, aText );
788
789 textItem->SetTextSize( ToKicadFontSize( aFontSize ) );
790 textItem->SetVisible( true );
791 textItem->SetMultilineAllowed( true );
792
793 setTextJustification( textItem, aJustification );
794
795 return textItem;
796}
797
798
800 SCH_SHEET_PATH* aSheet, SCH_LAYER_ID aLayer )
801{
802 SCH_LINE* segment = new SCH_LINE();
803
805 segment->SetLineStyle( LINE_STYLE::SOLID );
806 segment->SetLayer( aLayer );
807
808 segment->SetStartPoint( ToKicadCoords( aAscfile.Wires[aIndex].Start ) + m_originOffset );
809 segment->SetEndPoint( ToKicadCoords( aAscfile.Wires[aIndex].End ) + m_originOffset );
810
811 aSheet->LastScreen()->Append( segment );
812}
813
814
816 const wxString& aValue,
817 int aFontSize, SCH_SHEET_PATH* aSheet,
818 std::vector<LTSPICE_SCHEMATIC::WIRE>& aWires )
819{
820 LIB_SYMBOL* lib_symbol = new LIB_SYMBOL( wxS( "GND" ) );
821 SCH_SHAPE* shape = new SCH_SHAPE( SHAPE_T::POLY,LAYER_DEVICE );
822
823 shape->AddPoint( ToInvertedKicadCoords( { 16, 0 } ) );
824 shape->AddPoint( ToInvertedKicadCoords( { -16, 0 } ) );
825 shape->AddPoint( ToInvertedKicadCoords( { 0, 15 } ) );
826 shape->AddPoint( ToInvertedKicadCoords( { 16, 0 } ) );
827 shape->AddPoint( ToInvertedKicadCoords( { -16, 0 } ) );
828 shape->AddPoint( ToInvertedKicadCoords( { 0, 15 } ) );
829
831 LINE_STYLE::SOLID ) );
832
833 lib_symbol->AddDrawItem( shape );
834 lib_symbol->SetPower();
835
836 LIB_PIN* pin = new LIB_PIN( lib_symbol );
837
838 pin->SetType( ELECTRICAL_PINTYPE::PT_POWER_IN );
839 pin->SetPosition( ToInvertedKicadCoords( { 0, 0 } ) );
840 pin->SetLength( 5 );
841 pin->SetShape( GRAPHIC_PINSHAPE::LINE );
842 lib_symbol->AddDrawItem( pin );
843
844 LIB_ID libId( wxS( "ltspice" ), wxS( "GND" ) );
845 SCH_SYMBOL* sch_symbol = new SCH_SYMBOL( *lib_symbol, libId, aSheet, 1 );
846
847 sch_symbol->SetRef( aSheet, wxString::Format( wxS( "#GND%03d" ), m_powerSymbolIndex++ ) );
848 sch_symbol->GetField( REFERENCE_FIELD )->SetVisible( false );
849 sch_symbol->SetValueFieldText( wxS( "0" ) );
850 sch_symbol->GetField( VALUE_FIELD )->SetTextSize( ToKicadFontSize( aFontSize ) );
851 sch_symbol->GetField( VALUE_FIELD )->SetVisible( false );
852
853 sch_symbol->Move( ToKicadCoords( aOffset ) + m_originOffset );
854
855 for( LTSPICE_SCHEMATIC::WIRE& wire : aWires )
856 {
857 if( aOffset == wire.Start )
858 {
859 if( wire.Start.x == wire.End.x )
860 {
861 if( wire.Start.y < wire.End.y )
862 {
865 }
866 }
867 else
868 {
869 if( wire.Start.x < wire.End.x )
871 else if( wire.Start.x > wire.End.x )
873 }
874 }
875 else if( aOffset == wire.End )
876 {
877 if( wire.Start.x == wire.End.x )
878 {
879 if( wire.Start.y > wire.End.y )
880 {
883 }
884 }
885 else
886 {
887 if( wire.Start.x < wire.End.x )
889 else if( wire.Start.x > wire.End.x )
891 }
892 }
893 }
894
895 return sch_symbol;
896}
897
898
900 const wxString& aValue, int aFontSize )
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( { 0, 0 }, -1, label, wxS( "DATAFLAG" ) );
919 field.SetText( aValue );
920 field.SetTextSize( ToKicadFontSize( aFontSize ) );
921 field.SetVisible( true );
922
923 label->AddField( field );
924 label->AutoplaceFields( nullptr, false );
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 return label;
938}
939
940
942 SCH_SYMBOL* aSymbol, SCH_SHEET_PATH* aSheet )
943{
944 wxString libPath = m_lt_schematic->GetLTspiceDataDir().GetFullPath();
945 wxString symbolName = aLTSymbol.Name.Upper();
946 wxString type = aLTSymbol.SymAttributes[wxS( "TYPE" )].Upper();
947 wxString prefix = aLTSymbol.SymAttributes[wxS( "PREFIX" )].Upper();
948 wxString instName = aLTSymbol.SymAttributes[wxS( "INSTNAME" )].Upper();
949 wxString value = aLTSymbol.SymAttributes[wxS( "VALUE" )];
950 wxString value2 = aLTSymbol.SymAttributes[wxS( "VALUE2" )];
951
952 if( value.IsEmpty() )
953 {
954 value = value2;
955 value2 = wxEmptyString;
956 }
957
958 aSymbol->SetRef( aSheet, instName );
959 aSymbol->SetValueFieldText( value );
960
961 if( !value2.IsEmpty() )
962 {
963 SCH_FIELD paramsField( { 0, 0 }, -1, aSymbol, wxS( "Value2" ) );
964 paramsField.SetText( value2 );
965 aSymbol->AddField( paramsField );
966 }
967
968 auto setupNonInferredPassive = [&]( const wxString& aDevice, const wxString& aValueKey )
969 {
970 SCH_FIELD deviceField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Device" ) );
971 deviceField.SetText( aDevice );
972 aSymbol->AddField( deviceField );
973
974 SCH_FIELD paramsField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Params" ) );
975 paramsField.SetText( aValueKey + wxS( "=${VALUE}" ) );
976 aSymbol->AddField( paramsField );
977 };
978
979 auto setupBehavioral = [&]( const wxString& aDevice, const wxString& aType )
980 {
981 aSymbol->SetValueFieldText( wxS( "${Sim.Params}" ) );
982
983 SCH_FIELD deviceField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Device" ) );
984 deviceField.SetText( aDevice );
985 aSymbol->AddField( deviceField );
986
987 SCH_FIELD typeField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Type" ) );
988 typeField.SetText( aType );
989 aSymbol->AddField( typeField );
990
991 SCH_FIELD paramsField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Params" ) );
992 paramsField.SetText( value );
993 aSymbol->AddField( paramsField );
994 };
995
996 static const std::set<wxString> prefixWithGain = { wxS( "E" ), wxS( "F" ), wxS( "G" ),
997 wxS( "H" ) };
998
999 if( prefix == wxS( "R" ) )
1000 {
1001 setupNonInferredPassive( prefix, wxS( "R" ) );
1002 }
1003 else if( prefix == wxS( "C" ) )
1004 {
1005 setupNonInferredPassive( prefix, wxS( "C" ) );
1006 }
1007 else if( prefix == wxS( "L" ) )
1008 {
1009 setupNonInferredPassive( prefix, wxS( "L" ) );
1010 }
1011 else if( prefixWithGain.count( prefix ) > 0 )
1012 {
1013 setupNonInferredPassive( prefix, wxS( "gain" ) );
1014 }
1015 else if( prefix == wxS( "B" ) )
1016 {
1017 if( symbolName.StartsWith( wxS( "BV" ) ) )
1018 {
1019 setupBehavioral( wxS( "V" ), wxS( "=" ) );
1020 }
1021 else if( symbolName.StartsWith( wxS( "BI" ) ) )
1022 {
1023 setupBehavioral( wxS( "I" ), wxS( "=" ) );
1024 }
1025 }
1026 else if( prefix == wxS( "V" ) || symbolName == wxS( "I" ) )
1027 {
1028 SCH_FIELD deviceField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Device" ) );
1029 deviceField.SetText( wxS( "SPICE" ) );
1030 aSymbol->AddField( deviceField );
1031
1032 wxString simParams;
1033 simParams << "type=" << '"' << prefix << '"' << ' ';
1034
1035 if( value2.IsEmpty() )
1036 simParams << "model=" << '"' << "${VALUE}" << '"' << ' ';
1037 else
1038 simParams << "model=" << '"' << "${VALUE} ${VALUE2}" << '"' << ' ';
1039
1040 SCH_FIELD paramsField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Params" ) );
1041 paramsField.SetText( simParams );
1042 aSymbol->AddField( paramsField );
1043 }
1044 else
1045 {
1046 wxString libFile = aLTSymbol.SymAttributes[wxS( "MODELFILE" )];
1047
1048 if( prefix == wxS( "X" ) )
1049 {
1050 // A prefix of X overrides the simulation model for other symbols (npn, etc.)
1051 type = wxS( "X" );
1052 }
1053 else if( libFile.IsEmpty() )
1054 {
1055 if( type.IsEmpty() )
1056 type = symbolName;
1057
1058 if( value == "DIODE" )
1059 libFile = libPath + wxS( "cmp/standard.dio" );
1060 else if( value == "NPN" || value == "PNP" )
1061 libFile = libPath + wxS( "cmp/standard.bjt" );
1062 else if( value == "NJF" || value == "PJF" )
1063 libFile = libPath + wxS( "cmp/standard.jft" );
1064 else if( value == "NMOS" || value == "PMOS" )
1065 libFile = libPath + wxS( "cmp/standard.mos" );
1066 }
1067
1068 if( libFile.IsEmpty() )
1069 libFile = m_includes[value];
1070
1071 if( !libFile.IsEmpty() )
1072 {
1073 SCH_FIELD libField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Library" ) );
1074 libField.SetText( libFile );
1075 aSymbol->AddField( libField );
1076 }
1077
1078 if( type == wxS( "X" ) )
1079 {
1080 SCH_FIELD deviceField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Device" ) );
1081 deviceField.SetText( wxS( "SUBCKT" ) );
1082 aSymbol->AddField( deviceField );
1083 }
1084 else
1085 {
1086 SCH_FIELD deviceField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Device" ) );
1087 deviceField.SetText( wxS( "SPICE" ) );
1088 aSymbol->AddField( deviceField );
1089 }
1090
1091 wxString spiceLine = aLTSymbol.SymAttributes[wxS( "SPICELINE" )];
1092
1093 if( !spiceLine.IsEmpty() )
1094 {
1095 // TODO: append value
1096 SCH_FIELD paramsField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Params" ) );
1097 paramsField.SetText( spiceLine );
1098 aSymbol->AddField( paramsField );
1099 }
1100 else
1101 {
1102 SCH_FIELD modelField( { 0, 0 }, -1, aSymbol, wxS( "Sim.Params" ) );
1103 modelField.SetText( "model=\"" + value + "\"" );
1104 aSymbol->AddField( modelField );
1105 }
1106 }
1107
1108 for( LTSPICE_SCHEMATIC::LT_WINDOW& lt_window : aLTSymbol.Windows )
1109 {
1110 SCH_FIELD* field = nullptr;
1111
1112 switch( lt_window.WindowNumber )
1113 {
1114 case -1: /* PartNum */ break;
1115 case 0: /* InstName */ field = aSymbol->GetField( REFERENCE_FIELD ); break;
1116 case 1: /* Type */ break;
1117 case 2: /* RefName */ break;
1118 case 3: /* Value */ field = aSymbol->GetField( VALUE_FIELD ); break;
1119
1120 case 5: /* QArea */ break;
1121
1122 case 8: /* Width */ break;
1123 case 9: /* Length */ break;
1124 case 10: /* Multi */ break;
1125
1126 case 16: /* Nec */ break;
1127
1128 case 38: /* SpiceModel */ field = aSymbol->FindField( wxS( "Sim.Name" ) ); break;
1129 case 39: /* SpiceLine */ field = aSymbol->FindField( wxS( "Sim.Params" ) ); break;
1130 case 40: /* SpiceLine2 */ break;
1131
1132 /*
1133 47 Def_Sub
1134
1135 50 Digital_Timing_Model
1136 51 Digital_Extracts
1137 52 Digital_IO_Model
1138 53 Digital_Line
1139 54 Digital_Primitive
1140 55 Digital_MNTYMXDLY
1141 56 Digital_IO_LEVEL
1142 57 Digital_StdCell
1143 58 Digital_File
1144
1145 105 Cell
1146 106 W/L
1147 107 PSIZE
1148 108 NSIZE
1149 109 sheets
1150 110 sh#
1151 111 Em_Scale
1152 112 Epi
1153 113 Sinker
1154 114 Multi5
1155
1156 118 AQ
1157 119 AQSUB
1158 120 ZSIZE
1159 121 ESR
1160 123 Value2
1161 124 COUPLE
1162 125 Voltage
1163 126 Area1
1164 127 Area2
1165 128 Area3
1166 129 Area4
1167 130 Multi1
1168 131 Multi2
1169 132 Multi3
1170 133 Multi4
1171 134 DArea
1172 135 DPerim
1173 136 CArea
1174 137 CPerim
1175 138 Shrink
1176 139 Gate_Resize
1177
1178 142 BP
1179 143 BN
1180 144 Sim_Level
1181
1182 146 G_Voltage
1183
1184 150 SpiceLine3
1185
1186 153 D_VOLTAGES
1187
1188 156 Version
1189 157 Comment
1190 158 XDef_Sub
1191 159 LVS_Area
1192
1193 162 User1
1194 163 User2
1195 164 User3
1196 165 User4
1197 166 User5
1198 167 Root
1199 168 Class
1200 169 Geometry
1201 170 WL_Delimiter
1202
1203 175 T1
1204 176 T2
1205
1206 184 DsgnName
1207 185 Designer
1208
1209 190 RTN
1210 191 PWR
1211 192 BW
1212
1213 201 CAPROWS
1214 202 CAPCOLS
1215 203 NF
1216 204 SLICES
1217 205 CUR
1218 206 TEMPRISE
1219 207 STRIPS
1220 208 WEM
1221 209 LEM
1222 210 BASES
1223 211 COLS
1224 212 XDef_Tub
1225 */
1226 default: break;
1227 }
1228
1229 if( field )
1230 {
1231 field->SetPosition( ToKicadCoords( lt_window.Position ) );
1232 field->SetTextSize( ToKicadFontSize( lt_window.FontSize ) );
1233
1234 if( lt_window.FontSize == 0 )
1235 field->SetVisible( false );
1236
1237 setTextJustification( field, lt_window.Justification );
1238 }
1239 }
1240}
1241
1242
1244 SCH_SHAPE* aRectangle )
1245{
1246 LTSPICE_SCHEMATIC::RECTANGLE& lt_rect = aLTSymbol.Rectangles[aIndex];
1247
1248 aRectangle->SetPosition( ToInvertedKicadCoords( lt_rect.BotRight ) );
1249 aRectangle->SetEnd( ToInvertedKicadCoords( lt_rect.TopLeft ) );
1250 aRectangle->SetStroke( getStroke( lt_rect.LineWidth, lt_rect.LineStyle ) );
1251
1252 if( aLTSymbol.SymAttributes[wxS( "Prefix" )] == wxS( "X" ) )
1253 aRectangle->SetFillMode( FILL_T::FILLED_WITH_BG_BODYCOLOR );
1254}
1255
1256
1258 SCH_SHEET_PATH* aSheet )
1259{
1260 LTSPICE_SCHEMATIC::RECTANGLE& lt_rect = aLTSymbol.Rectangles[aIndex];
1261 SCH_SHAPE* rectangle = new SCH_SHAPE( SHAPE_T::RECTANGLE );
1262
1263 rectangle->SetPosition( ToInvertedKicadCoords( lt_rect.BotRight ) );
1264 rectangle->SetEnd( ToInvertedKicadCoords( lt_rect.TopLeft ) );
1265 rectangle->SetStroke( getStroke( lt_rect.LineWidth, lt_rect.LineStyle ) );
1266
1267 rectangle->Move( aLTSymbol.Offset );
1268 RotateMirrorShape( aLTSymbol, rectangle );
1269
1270 aSheet->LastScreen()->Append( rectangle );
1271}
1272
1273
1275 LIB_PIN* aPin )
1276{
1277 LTSPICE_SCHEMATIC::LT_PIN& lt_pin = aLTSymbol.Pins[aIndex];
1278 wxString device = aLTSymbol.Name.Lower();
1279
1280 if( aLTSymbol.Pins.size() == 2 && ( device == wxS( "res" )
1281 || device == wxS( "cap" )
1282 || device == wxS( "ind" ) ) )
1283 {
1284 // drop A/B pin names from simple LRCs as they're not terribly useful (and prevent
1285 // other pin names on the net from driving the net name).
1286 }
1287 else
1288 {
1289 aPin->SetName( lt_pin.PinAttribute[ wxS( "PinName" ) ] );
1290
1292 aPin->SetNameTextSize( 0 );
1293 }
1294
1295 aPin->SetNumber( wxString::Format( wxS( "%d" ), aIndex + 1 ) );
1296 aPin->SetType( ELECTRICAL_PINTYPE::PT_PASSIVE );
1298 aPin->SetLength( 5 );
1299 aPin->SetShape( GRAPHIC_PINSHAPE::LINE );
1300
1301 switch( lt_pin.PinJustification )
1302 {
1305 aPin->SetOrientation( PIN_ORIENTATION::PIN_RIGHT );
1306 break;
1307
1310 aPin->SetOrientation( PIN_ORIENTATION::PIN_LEFT );
1311 break;
1312
1315 aPin->SetOrientation( PIN_ORIENTATION::PIN_UP );
1316 break;
1317
1320 aPin->SetOrientation( PIN_ORIENTATION::PIN_DOWN );
1321 break;
1322
1323 default: break;
1324 }
1325}
1326
1327
1329 SCH_SHAPE* aArc )
1330{
1331 LTSPICE_SCHEMATIC::ARC& lt_arc = aLTSymbol.Arcs[aIndex];
1332
1333 aArc->SetCenter( ToInvertedKicadCoords( ( lt_arc.TopLeft + lt_arc.BotRight ) / 2 ) );
1334 aArc->SetEnd( ToInvertedKicadCoords( lt_arc.ArcEnd ) );
1335 aArc->SetStart( ToInvertedKicadCoords( lt_arc.ArcStart ) );
1336 aArc->SetStroke( getStroke( lt_arc.LineWidth, lt_arc.LineStyle ) );
1337}
1338
1339
1341 SCH_SHEET_PATH* aSheet )
1342{
1343 LTSPICE_SCHEMATIC::ARC& lt_arc = aLTSymbol.Arcs[aIndex];
1344 SCH_SHAPE* arc = new SCH_SHAPE( SHAPE_T::ARC );
1345
1346 arc->SetCenter( ToInvertedKicadCoords( ( lt_arc.TopLeft + lt_arc.BotRight ) / 2 ) );
1347 arc->SetEnd( ToInvertedKicadCoords( lt_arc.ArcEnd ) );
1348 arc->SetStart( ToInvertedKicadCoords( lt_arc.ArcStart ) );
1349 arc->SetStroke( getStroke( lt_arc.LineWidth, lt_arc.LineStyle ) );
1350
1351 arc->Move( ToKicadCoords( aLTSymbol.Offset ) + m_originOffset );
1352 RotateMirrorShape( aLTSymbol, arc );
1353
1354 aSheet->LastScreen()->Append( arc );
1355}
1356
1357
1359 SCH_SHEET_PATH* aSheet )
1360{
1361 LTSPICE_SCHEMATIC::CIRCLE& lt_circle = aLTSymbol.Circles[aIndex];
1362 SCH_SHAPE* circle = new SCH_SHAPE( SHAPE_T::CIRCLE );
1363
1364 VECTOR2I c = ( lt_circle.TopLeft + lt_circle.BotRight ) / 2;
1365 int r = ( lt_circle.TopLeft.x - lt_circle.BotRight.x ) / 2;
1366
1367 circle->SetPosition( ToInvertedKicadCoords( c ) );
1368 circle->SetEnd( ToInvertedKicadCoords( c ) + VECTOR2I( abs( ToKicadCoords( r ) ), 0 ) );
1369 circle->SetStroke( getStroke( lt_circle.LineWidth, lt_circle.LineStyle ) );
1370
1371 circle->Move( aLTSymbol.Offset );
1372 RotateMirrorShape( aLTSymbol, circle );
1373
1374 aSheet->LastScreen()->Append( circle );
1375}
1376
1377
1379 SCH_SHAPE* aCircle )
1380{
1381 LTSPICE_SCHEMATIC::CIRCLE& lt_circle = aLTSymbol.Circles[aIndex];
1382
1383 VECTOR2I c = ( lt_circle.TopLeft + lt_circle.BotRight ) / 2;
1384 int r = ( lt_circle.TopLeft.x - lt_circle.BotRight.x ) / 2;
1385
1386 aCircle->SetPosition( ToInvertedKicadCoords( c ) );
1387 aCircle->SetEnd( ToInvertedKicadCoords( c ) + VECTOR2I( abs( ToKicadCoords( r ) ), 0 ) );
1388 aCircle->SetStroke( getStroke( lt_circle.LineWidth, lt_circle.LineStyle ) );
1389}
1390
1391
constexpr EDA_IU_SCALE schIUScale
Definition: base_units.h:110
void SetOrigin(const Vec &pos)
Definition: box2.h:203
const Vec & GetOrigin() const
Definition: box2.h:184
void Offset(coord_type dx, coord_type dy)
Definition: box2.h:225
const Vec GetCenter() const
Definition: box2.h:196
coord_type GetTop() const
Definition: box2.h:195
coord_type GetHeight() const
Definition: box2.h:189
coord_type GetWidth() const
Definition: box2.h:188
void SetSize(const Vec &size)
Definition: box2.h:214
coord_type GetLeft() const
Definition: box2.h:194
const Vec & GetSize() const
Definition: box2.h:180
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:589
void SetCenter(const VECTOR2I &aCenter)
Definition: eda_shape.cpp:543
void SetStart(const VECTOR2I &aStart)
Definition: eda_shape.h:129
void SetEnd(const VECTOR2I &aEnd)
Definition: eda_shape.h:154
void SetFillMode(FILL_T aFill)
Definition: eda_shape.h:101
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
Definition: eda_text.h:83
int GetTextHeight() const
Definition: eda_text.h:228
void SetTextSize(VECTOR2I aNewSize, bool aEnforceMinTextSize=true)
Definition: eda_text.cpp:374
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:276
void Offset(const VECTOR2I &aOffset)
Definition: eda_text.cpp:437
virtual void SetVisible(bool aVisible)
Definition: eda_text.cpp:245
virtual void SetText(const wxString &aText)
Definition: eda_text.cpp:183
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
Definition: eda_text.cpp:205
void SetMultilineAllowed(bool aAllow)
Definition: eda_text.cpp:260
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
Definition: eda_text.cpp:268
A logical library item identifier and consists of various portions much like a URI.
Definition: lib_id.h:49
void SetShape(GRAPHIC_PINSHAPE aShape)
Definition: lib_pin.h:79
void SetPosition(const VECTOR2I &aPos) override
Definition: lib_pin.h:208
void SetName(const wxString &aName)
Definition: lib_pin.h:115
void SetNameTextSize(int aSize)
Definition: lib_pin.h:136
void SetType(ELECTRICAL_PINTYPE aType)
Definition: lib_pin.h:92
void SetOrientation(PIN_ORIENTATION aOrientation)
Definition: lib_pin.h:76
void SetNumber(const wxString &aNumber)
Definition: lib_pin.h:126
void SetLength(int aLength)
Definition: lib_pin.h:82
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:680
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:970
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:1368
void SetText(const wxString &aText) override
Definition: sch_field.cpp:1119
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)
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.
VECTOR2I ToInvertedKicadCoords(const VECTOR2I &aPos)
SCH_TEXT * CreateSCH_TEXT(VECTOR2I aOffset, const wxString &aText, int aFontSize, LTSPICE_SCHEMATIC::JUSTIFICATION aJustification)
Create schematic text.
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:288
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_label.cpp:419
void AddField(const SCH_FIELD &aField)
Definition: sch_label.h:212
void SetShape(LABEL_FLAG_SHAPE aShape)
Definition: sch_label.h:171
void SetPosition(const VECTOR2I &aPosition) override
Definition: sch_label.cpp:412
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Definition: sch_label.cpp:639
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
Definition: sch_label.cpp:338
Segment description base class to describe items which have 2 end points (track, wire,...
Definition: sch_line.h:40
void SetStartPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:136
void SetLineWidth(const int aSize)
Definition: sch_line.cpp:321
void SetLineStyle(const LINE_STYLE aStyle)
Definition: sch_line.cpp:292
void Move(const VECTOR2I &aMoveVector) override
Move the item by aMoveVector to a new position.
Definition: sch_line.cpp:156
virtual void SetStroke(const STROKE_PARAMS &aStroke) override
Definition: sch_line.h:176
void SetEndPoint(const VECTOR2I &aPosition)
Definition: sch_line.h:141
const PAGE_INFO & GetPageSettings() const
Definition: sch_screen.h:131
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
Definition: sch_screen.cpp:150
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:637
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:108
void SetValueFieldText(const wxString &aValue)
Definition: sch_symbol.cpp:898
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:688
SCH_FIELD * GetField(MANDATORY_FIELD_T aFieldType)
Return a mandatory field in this symbol.
Definition: sch_symbol.cpp:920
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:760
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:983
Simple container to manage line stroke parameters.
Definition: stroke_params.h:81
void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
Definition: symbol.h:134
static constexpr EDA_ANGLE ANGLE_VERTICAL
Definition: eda_angle.h:432
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
Definition: eda_angle.h:431
SCH_LAYER_ID
Eeschema drawing layers.
Definition: layer_ids.h:353
@ LAYER_DEVICE
Definition: layer_ids.h:369
#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:91
@ L_BIDI
Definition: sch_label.h:94
@ L_OUTPUT
Definition: sch_label.h:93
@ L_INPUT
Definition: sch_label.h:92
@ SYM_ROTATE_CLOCKWISE
Definition: sch_symbol.h:82
@ SYM_ROTATE_COUNTERCLOCKWISE
Definition: sch_symbol.h:83
@ SYM_MIRROR_Y
Definition: sch_symbol.h:89
@ SYM_ORIENT_180
Definition: sch_symbol.h:86
@ SYM_MIRROR_X
Definition: sch_symbol.h:88
@ SYM_ORIENT_0
Definition: sch_symbol.h:84
LINE_STYLE
Dashed line types.
Definition: stroke_params.h:48
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:170
@ 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:129
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588