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