26#include <wx/filename.h>
28#include <wx/mstream.h>
63constexpr int PLACEMENT_GRID = 12700;
66constexpr int BUS_SIGNAL = 65502;
69constexpr int SIGNAL_GAP = 254;
72constexpr int MAX_DIAGONAL_STEPS = 8;
75constexpr int NEAR_MISS = 1000;
78constexpr int LABEL_REACH = 50800;
80const wxString LIB_NAME = wxS(
"target3001" );
85 int quadrant = ( (int) std::lround( aDirection / 90.0f ) % 4 + 4 ) % 4;
147int textQuadrant(
float aDirection )
149 return ( (
int) std::lround( aDirection / 90.0f ) % 4 + 4 ) % 4;
154bool isHiddenText(
const ELEMENT& aElem )
161bool isUnplacedGate(
const ELEMENT& aGate )
220 if( dir.
Cross( c - a ) || dir.
Cross( d - a ) )
223 auto along = [&](
const VECTOR2I& aPos )
225 return dir.
Dot( aPos - a );
228 return std::min( std::max( along( a ), along( b ) ), std::max( along( c ), along( d ) ) )
229 > std::max( std::min( along( a ), along( b ) ), std::min( along( c ), along( d ) ) );
240 bool aUseRightEnd =
true )
244 aFonts.
Apply( aText, aElem, 100 );
246 int quadrant = textQuadrant( src.
direction );
247 bool upsideDown = quadrant >= 2;
248 bool fromEnd = upsideDown != ( src.
mirrored != 0 );
256 if(
end && aUseRightEnd )
289 return KiROUND( aLength / 100.0 );
315 if( !isUnplacedGate( s ) )
323 if( e.
type == ELEMENT_TYPE::SIGNAL && e.
signal )
335 for(
int sheet : used )
346 if( e.
type == ELEMENT_TYPE::SIGNAL && e.
signal )
353 for(
const auto& [sheet, items] :
m_netItems )
374 it->second.
Merge( bbox );
388 case ELEMENT_TYPE::LINE:
408 case ELEMENT_TYPE::RECTANGLE:
419 VECTOR2D corners[4] = { { 0.0, 0.0 }, { double( r.
width ), 0.0 },
432 case ELEMENT_TYPE::TRIANGLE:
443 case ELEMENT_TYPE::DISC:
451 case ELEMENT_TYPE::ARC:
458 if(
sweep >= 360.0 - 1e-6 )
466 auto at = [&](
double aDeg )
478 case ELEMENT_TYPE::TEXT:
480 if( isHiddenText( aElem ) )
486 std::pair<int32_t, int32_t> pos = configureText(
text, aElem,
m_fonts );
499 if( aElem.
type != ELEMENT_TYPE::RECTANGLE )
507 if( data.empty() || size.
x == 0 || size.
y == 0 )
510 wxMemoryInputStream stream( data.data(), data.size() );
512 if( !
image.LoadFile( stream, wxBITMAP_TYPE_ANY ) )
516 int w =
image.GetWidth();
517 int h =
image.GetHeight();
518 int stretchedW = std::max( w,
KiROUND(
double( h ) * size.
x / size.
y ) );
519 int stretchedH = std::max( h,
KiROUND(
double( w ) * size.
y / size.
x ) );
521 if( stretchedW > w + 1 || stretchedH > h + 1 )
522 image.Rescale( stretchedW, stretchedH, wxIMAGE_QUALITY_HIGH );
553 std::vector<const ELEMENT*> gates;
558 gates.push_back( &s );
564 std::stable_sort( gates.begin(), gates.end(),
567 return a->symbol->gateOrdinal < b->symbol->gateOrdinal;
570 bool hasPackage = std::any_of(
comp.packageItems.begin(),
comp.packageItems.end(),
571 [](
const ELEMENT& e ) { return e.type == ELEMENT_TYPE::PACKAGE; } );
572 bool allSupply =
true;
573 int supplySignal = 0;
575 for(
const ELEMENT* gate : gates )
579 if( child.
type != ELEMENT_TYPE::PIN )
584 else if( !supplySignal )
589 bool isPower = !hasPackage && allSupply && supplySignal;
591 wxString reference =
ToWx(
comp.prefix ).Trim().Trim(
false );
592 uint16_t number =
comp.referenceExtension.value_or(
comp.referenceNumber );
595 reference = wxString::Format( wxS(
"#PWR%03d" ), ++
m_powerCount );
599 wxString value =
ToWx(
comp.value );
601 const ELEMENT* sig = isPower ?
m_project.FindSignal( supplySignal ) :
nullptr;
603 if( sig && !sig->
signal->name.empty() )
607 wxString symName =
ToWx(
comp.name );
609 if( symName.IsEmpty() )
612 symName = wxString::Format( wxS(
"%s_%d" ), symName,
int( aComponent.
base.
component ) );
614 symName.Replace( wxS(
"/" ), wxS(
"_" ) );
625 std::map<uint16_t, wxString> padNumbers;
629 if( item.
type == ELEMENT_TYPE::PAD )
630 padNumbers.emplace( item.
pad.
number, PadNumber( item ) );
635 for(
size_t g = 0; g < gates.size(); g++ )
637 const ELEMENT& gate = *gates[g];
639 if( isUnplacedGate( gate ) )
652 if( !
comp.package.empty() )
655 bool refShown =
false;
656 bool valueShown =
false;
660 if( child.
type != ELEMENT_TYPE::TEXT )
665 if( child.
text.
function == uint8_t( TEXT_FUNCTION::REFERENCE ) )
667 else if( child.
text.
function == uint8_t( TEXT_FUNCTION::VALUE ) )
673 std::pair<int32_t, int32_t> pos = configureText( field, child,
m_fonts );
696 if( child.
type == ELEMENT_TYPE::PIN )
715 bool aFieldTexts,
const std::map<uint16_t, wxString>& aPadNumbers )
const
717 bool showNumbers =
false;
718 bool showNames =
false;
719 std::vector<SCH_PIN*> hiddenNames;
721 for(
size_t g = 0; g < aGates.size(); g++ )
723 const ELEMENT& gate = *aGates[g];
725 int unit = int( g ) + 1;
729 if( child.
type == ELEMENT_TYPE::PIN )
734 bool nameShown =
false;
738 if( pc.
type == ELEMENT_TYPE::TEXT && pc.
text.
function == uint8_t( TEXT_FUNCTION::PIN_NAME ) )
741 nameShown = !isHiddenText( pc ) && !
name.IsEmpty();
746 m_fonts.Apply( &probe, pc, 100 );
755 pin->SetType( pinType( child ) );
756 pin->SetShape( pinShape( src ) );
757 pin->SetName(
name.IsEmpty() ? wxString( wxS(
"~" ) ) :
name );
758 pin->SetUnit( unit );
762 const std::string* padName = child.
base.
FindProp(
"PADNAME" );
764 if(
pad != aPadNumbers.end() )
765 pin->SetNumber(
pad->second );
766 else if( padName && !padName->empty() )
767 pin->SetNumber(
ToWx( *padName ) );
769 pin->SetNumber( wxString::Format( wxS(
"%u" ), src.
pinNumber ) );
771 if( !nameShown && !
name.IsEmpty() )
772 hiddenNames.push_back(
pin );
776 showNames |= nameShown;
781 if( aFieldTexts && child.
type == ELEMENT_TYPE::TEXT
782 && ( child.
text.
function == uint8_t( TEXT_FUNCTION::REFERENCE )
783 || child.
text.
function == uint8_t( TEXT_FUNCTION::VALUE ) ) )
789 if( child.
type == ELEMENT_TYPE::RECTANGLE && child.
base.
FindProp(
"JPEG_PICTURE" ) )
794 item->SetUnit( unit );
804 pin->SetName( wxS(
"~" ) );
816 bool isBus = aSignal.
base.
signal == BUS_SIGNAL;
833 case ELEMENT_TYPE::LINE:
841 case ELEMENT_TYPE::DISC:
846 case ELEMENT_TYPE::TEXT:
848 bool signalName = e.
text.
function == uint8_t( TEXT_FUNCTION::SIGNAL_NAME );
851 if( isHiddenText( e ) && !signalName )
855 std::optional<VECTOR2I>
anchor;
869 configureText( label, e,
m_fonts,
false );
890 if( aSignal.
signal->name.empty() )
897 std::set<int> sheets;
908 sheets.insert(
pin.sheet );
911 return sheets.size() > 1;
918 std::optional<VECTOR2I> best;
920 auto consider = [&](
const VECTOR2I& aCandidate )
922 SEG::ecoord dist = ( aCandidate - aPos ).SquaredEuclideanNorm();
924 if( dist <=
SEG::Square( LABEL_REACH ) && ( !best || dist < ( *best - aPos ).SquaredEuclideanNorm() ) )
930 if( e.
type != ELEMENT_TYPE::LINE ||
sheetOf( e ) != aSheet )
937 if( ( nearest - wire.
A ).Cross( wire.
B - wire.
A ) != 0 )
952 if(
pin.sheet == aSheet )
963 std::map<int, std::map<int, std::vector<SCH_ITEM*>>> bySignal;
965 for(
const auto& [sheet, items] :
m_netItems )
967 for(
const auto& [item, signal] : items )
968 bySignal[signal][sheet].push_back( item );
971 for(
const auto& [signal, pins] :
m_pinEnds )
973 if( signal != BUS_SIGNAL )
981 const std::vector<PIN_END>& pins =
m_pinEnds.at( aSignal );
983 bool anyNamed =
false;
984 std::set<int> sheets;
990 std::vector<std::pair<VECTOR2I, VECTOR2I>> ends;
993 std::vector<PIECE> unnamed;
997 sheets.insert(
pin.sheet );
999 auto isFree = [&](
int aSheet,
const VECTOR2I& aPos )
1001 for(
const auto& [pos, pinSignal] :
m_pinSignals[aSheet] )
1003 if( pos == aPos && pinSignal != aSignal )
1007 for(
const auto& [item, itemSignal] :
m_netItems[aSheet] )
1009 if( itemSignal == aSignal )
1014 if( item->GetPosition() == aPos )
1029 for(
int sheet : sheets )
1031 std::vector<SEG> wires;
1032 std::vector<VECTOR2I> points;
1033 std::set<VECTOR2I> names;
1034 std::set<VECTOR2I> pinPoints;
1036 if(
auto it = aItems.find( sheet ); it != aItems.end() )
1058 if(
pin.sheet == sheet )
1059 pinPoints.insert(
pin.pos );
1062 std::map<VECTOR2I, int>
index;
1063 std::vector<int> parent;
1065 auto node = [&](
const VECTOR2I& aPos )
1067 auto [it, inserted] =
index.emplace( aPos,
int( parent.size() ) );
1070 parent.push_back( it->second );
1075 auto find = [&](
int aNode )
1077 while( parent[aNode] != aNode )
1078 aNode = parent[aNode] = parent[parent[aNode]];
1083 auto unite = [&](
int aFirst,
int aSecond )
1085 parent[
find( aFirst )] =
find( aSecond );
1088 std::vector<VECTOR2I> ends( pinPoints.begin(), pinPoints.end() );
1090 for(
const SEG& wire : wires )
1092 int start = node( wire.A );
1093 unite( start, node( wire.B ) );
1094 ends.push_back( wire.A );
1095 ends.push_back( wire.B );
1098 for(
const VECTOR2I& pos : points )
1104 for(
const VECTOR2I& pos : pinPoints )
1108 for(
const auto& [pos,
id] :
index )
1110 for(
const SEG& wire : wires )
1113 unite(
id,
index.at( wire.A ) );
1117 std::sort( ends.begin(), ends.end(),
1120 return a.x < b.x || ( a.x == b.x && a.y < b.y );
1123 ends.erase( std::unique( ends.begin(), ends.end() ), ends.end() );
1125 for(
size_t i = 0; i < ends.size(); i++ )
1127 for(
size_t j = i + 1; j < ends.size() && ends[j].x - ends[i].x < NEAR_MISS; j++ )
1129 int first =
index.at( ends[i] );
1130 int second =
index.at( ends[j] );
1132 if( ( ends[j] - ends[i] ).EuclideanNorm() >= NEAR_MISS ||
find( first ) ==
find( second ) )
1138 unite( first, second );
1142 std::set<int> named;
1145 named.insert(
find(
index.at( pos ) ) );
1149 if( global &&
pin.power &&
pin.sheet == sheet )
1153 std::map<VECTOR2I, int> endCount;
1154 std::map<VECTOR2I, VECTOR2I> outward;
1156 for(
const SEG& wire : wires )
1160 outward[wire.A] = wire.A - wire.B;
1161 outward[wire.B] = wire.B - wire.A;
1168 if(
pin.sheet != sheet )
1173 if( named.count( root ) )
1179 if( !seen.insert( root ).second )
1182 PIECE piece{ &
pin, {} };
1184 for(
const auto& [pos, count] : endCount )
1186 if( count == 1 && !pinPoints.count( pos ) &&
find(
index.at( pos ) ) == root )
1187 piece.ends.emplace_back( pos, outward.at( pos ) );
1190 unnamed.push_back( std::move( piece ) );
1196 if( unnamed.size() + ( anyNamed ? 1 : 0 ) < 2 || !sig || sig->
signal->name.empty() )
1208 for(
const PIECE& piece : unnamed )
1210 int sheet = piece.pin->sheet;
1215 switch( pinOrientation( piece.pin->direction ) )
1223 for(
const auto& [
end, dir] : piece.ends )
1225 if( isFree( sheet,
end ) )
1228 spin = spinAlong( dir );
1249 m_netItems[aSheet].emplace_back( aItem, aSignal );
1255 std::vector<std::pair<SCH_LINE*, int>> wires;
1256 std::vector<SCH_LINE*> buses;
1257 std::vector<std::pair<SCH_ITEM*, int>> points;
1259 for(
const auto& [item, signal] :
m_netItems[aSheet] )
1262 points.emplace_back( item, signal );
1263 else if( signal == BUS_SIGNAL )
1264 buses.push_back(
static_cast<SCH_LINE*
>( item ) );
1266 wires.emplace_back(
static_cast<SCH_LINE*
>( item ), signal );
1270 for(
const auto& [wire, signal] : wires )
1272 for(
int end : { 0, 1 } )
1277 bool onBus = std::any_of( buses.begin(), buses.end(),
1280 return IsPointOnSegment( bus->GetStartPoint(), bus->GetEndPoint(), pos );
1283 if( !onBus ||
moved == pos )
1287 bool labeled =
false;
1289 for(
const auto& [item, itemSignal] : points )
1291 if( itemSignal != signal )
1294 if( item->GetPosition() == pos )
1295 item->SetPosition(
moved );
1298 &&
IsPointOnSegment( wire->GetStartPoint(), wire->GetEndPoint(), item->GetPosition() );
1303 if( labeled || !sig || sig->
signal->name.empty() )
1318 points.emplace_back( label, signal );
1323 auto hasBranch = [&](
const std::pair<SCH_LINE*, int>& aWire )
1325 return std::any_of( points.begin(), points.end(),
1326 [&](
const std::pair<SCH_ITEM*, int>& aPoint )
1328 return aPoint.second == aWire.second
1329 && passesThrough( aWire.first, aPoint.first->GetPosition() );
1335 size_t drawn = wires.size();
1337 for(
size_t i = 0; i < drawn; i++ )
1339 for(
size_t j = i + 1; j < drawn; j++ )
1341 if( wires[i].second == wires[j].second || !overlaps( wires[i].first, wires[j].first ) )
1344 bool firstShorter = wires[i].first->GetLength() <= wires[j].first->GetLength();
1345 std::pair<SCH_LINE*, int> pick = firstShorter ? wires[i] : wires[j];
1347 if( hasBranch( pick ) )
1348 pick = firstShorter ? wires[j] : wires[i];
1352 if( hasBranch( pick ) || wire->
GetLength() <= 2 * SIGNAL_GAP )
1360 for(
const auto& [from, to] : { std::pair( start, start + side ), std::pair(
end + side,
end ) } )
1366 wires.emplace_back( stub, pick.second );
1384 std::map<VECTOR2I, std::vector<MEMBER>> at;
1385 std::set<VECTOR2I> busEnds;
1387 for(
const auto& [wire, signal] : wires )
1389 for(
int end : { 0, 1 } )
1390 at[wireEnd( wire,
end )].push_back( { signal, wire,
end,
false } );
1393 for(
const auto& [pos, signal] :
m_pinSignals[aSheet] )
1394 at[pos].push_back( { signal,
nullptr, -1,
true } );
1396 for(
const auto& [item, signal] : points )
1397 at[item->GetPosition()].push_back( { signal, item, -1,
false } );
1401 busEnds.insert( bus->GetStartPoint() );
1402 busEnds.insert( bus->GetEndPoint() );
1405 for(
auto& [pos, members] : at )
1408 bool joinsBus = std::any_of( members.begin(), members.end(),
1409 [](
const MEMBER& m )
1414 if( joinsBus && busEnds.count( pos ) )
1415 members.push_back( { BUS_SIGNAL,
nullptr, -1,
true } );
1417 for(
const auto& [wire, signal] : wires )
1419 if( passesThrough( wire, pos ) )
1420 members.push_back( { signal, wire, -1,
true } );
1425 if( joinsBus && passesThrough( bus, pos ) )
1426 members.push_back( { BUS_SIGNAL, bus, -1,
true } );
1431 auto isFree = [&](
const VECTOR2I& aPos )
1433 auto onLine = [&](
SCH_LINE* aLine )
1438 return !at.count( aPos ) && std::none_of( buses.begin(), buses.end(), onLine )
1439 && std::none_of( wires.begin(), wires.end(),
1440 [&](
const std::pair<SCH_LINE*, int>& aWire )
1442 return onLine( aWire.first );
1447 auto endAt = [&](
const MEMBER* aMember,
const VECTOR2I& aPos ) -> std::pair<SCH_LINE*, int>
1451 if( wireEnd( line, aMember->end ) == aPos )
1452 return { line, aMember->end };
1454 for(
const auto& [wire, signal] : wires )
1456 for(
int end : { 0, 1 } )
1458 if( signal == aMember->signal && wireEnd( wire,
end ) == aPos )
1459 return { wire,
end };
1463 return { line, aMember->end };
1466 for(
const auto& [pos, members] : at )
1468 std::map<int, std::vector<const MEMBER*>> groups;
1469 std::set<int> fixed;
1470 std::set<int> pinned;
1472 for(
const MEMBER& m : members )
1474 groups[m.signal].push_back( &m );
1477 fixed.insert( m.signal );
1479 if( m.fixed && !m.item )
1480 pinned.insert( m.signal );
1484 if( groups.size() < 2 || pinned.size() > 1 )
1487 int keeper = groups.begin()->first;
1489 for(
const auto& [signal,
group] : groups )
1491 if( fixed.count( signal ) > fixed.count( keeper )
1492 || ( fixed.count( signal ) == fixed.count( keeper ) &&
group.size() > groups.at( keeper ).size() ) )
1498 if( !pinned.empty() )
1499 keeper = *pinned.begin();
1503 for(
const auto& [signal,
group] : groups )
1505 if( signal == keeper )
1510 if( fixed.count( signal ) )
1513 std::optional<VECTOR2I> side =
bendAround( aSheet, signal, pos, wires, isFree );
1518 moved = pos + *side;
1524 [](
const MEMBER* m )
1529 bool oneEnd = std::count_if(
group.begin(),
group.end(),
1530 [](
const MEMBER* m )
1538 auto [line, lineEnd] = endAt( *
end, pos );
1539 moved = stepIn( line, lineEnd );
1548 moved = pos +
VECTOR2I( step * SIGNAL_GAP, step * SIGNAL_GAP );
1549 }
while( !isFree(
moved ) && step < MAX_DIAGONAL_STEPS );
1553 for(
const MEMBER* m :
group )
1557 auto [line, lineEnd] = endAt( m, pos );
1558 setWireEnd( line, lineEnd,
moved );
1560 else if( !m->fixed )
1562 m->item->SetPosition(
moved );
1571 std::vector<std::pair<SCH_LINE*, int>>& aWires,
1572 const std::function<
bool(
const VECTOR2I& )>& aIsFree )
1574 std::vector<SCH_LINE*> lines;
1576 for(
const auto& [wire, signal] : aWires )
1578 if( signal == aSignal && passesThrough( wire, aPos ) )
1579 lines.push_back( wire );
1583 return std::nullopt;
1585 VECTOR2I dir = lines[0]->GetEndPoint() - lines[0]->GetStartPoint();
1589 VECTOR2I span = line->GetEndPoint() - line->GetStartPoint();
1592 if( span.
Cross( dir ) || ( aPos - line->GetStartPoint() ).EuclideanNorm() <= 2 * SIGNAL_GAP
1593 || ( line->GetEndPoint() - aPos ).EuclideanNorm() <= 2 * SIGNAL_GAP )
1595 return std::nullopt;
1602 for(
int k : { 1, -1, 2, -2, 3, -3 } )
1604 if( aIsFree( aPos +
normal * k ) )
1613 VECTOR2I along = ( line->GetEndPoint() - line->GetStartPoint() ).Resize( SIGNAL_GAP );
1618 line->SetEndPoint( before );
1620 for(
const auto& [from, to] : { std::pair( before, before + side ), std::pair( before + side, after + side ),
1621 std::pair( after + side, after ), std::pair( after,
end ) } )
1627 aWires.emplace_back( piece, aSignal );
1642 if( aElem.
type == ELEMENT_TYPE::SYMBOL && aElem.
symbol )
1689 return it->second->GetScreen();
1704 fn.SetName( fn.GetName() + wxString::Format( wxS(
"_%d" ), aSheet ) );
1714 if( aSheet - 1 <
int(
m_project.settings.sheetNames.size() ) )
1717 if(
name.IsEmpty() )
1718 name = wxString::Format( wxS(
"Sheet %d" ), aSheet );
1730 const int margin =
schIUScale.mmToIU( PAGE_MARGIN_MM );
1738 auto snap = [](
int v )
1740 return KiROUND(
double( v ) / PLACEMENT_GRID ) * PLACEMENT_GRID;
1752 item->Move( offset );
1759 std::vector<SCH_SHEET*> sheets;
1761 for(
const auto& [number, sheet] :
m_sheets )
1762 sheets.push_back( sheet );
1769 for(
const auto& [number, sheet] :
m_sheets )
1770 sheet->GetScreen()->SetPageNumber( wxString::Format( wxS(
"%d" ), page++ ) );
constexpr EDA_IU_SCALE schIUScale
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
void SetImageType(wxBitmapType aType)
Set the bitmap type (png, jpeg, etc.)
constexpr size_type GetWidth() const
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
constexpr size_type GetHeight() const
constexpr coord_type GetLeft() const
constexpr coord_type GetTop() const
virtual VECTOR2I GetPosition() const
virtual const BOX2I GetBoundingBox() const
Return the orthogonal bounding box of this object for display purposes.
KICAD_T Type() const
Returns the type of object.
virtual void SetEnd(const VECTOR2I &aEnd)
virtual void SetCenter(const VECTOR2I &aCenter)
virtual void SetArcGeometry(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Set the three controlling points for an arc.
A mix-in class (via multiple inheritance) that handles texts such as labels, parts,...
virtual int GetTextHeight() const
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
virtual void SetVisible(bool aVisible)
virtual void SetTextAngle(const EDA_ANGLE &aAngle)
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
A logical library item identifier and consists of various portions much like a URI.
static UTF8 FixIllegalChars(const UTF8 &aLibItemName, bool aLib)
Replace illegal LIB_ID item name characters with underscores '_'.
Define a library symbol object.
const LIB_ID & GetLibId() const override
LIB_ITEMS_CONTAINER & GetDrawItems()
Return a reference to the draw item list.
void SetUnitCount(int aCount, bool aDuplicateDrawItems)
Set the units per symbol count.
SCH_FIELD & GetValueField()
void SetLibId(const LIB_ID &aLibId)
void AddDrawItem(SCH_ITEM *aItem, bool aSort=true)
Add a new draw aItem to the draw object list and sort according to aSort.
SCH_FIELD & GetReferenceField()
Describe the page size and margins of a paper page on which to eventually print or plot.
void SetWidthMM(double aWidthInMM)
void SetHeightMM(double aHeightInMM)
A REFERENCE_IMAGE is a wrapper around a BITMAP_IMAGE that is displayed in an editor as a reference fo...
BITMAP_BASE & MutableImage() const
Only use this if you really need to modify the underlying image.
void Rotate(const VECTOR2I &aCenter, const EDA_ANGLE &aAngle)
bool SetImage(const wxImage &aImage)
Set the image from an existing wxImage.
void SetPosition(const VECTOR2I &aPos)
void SetWidth(int aWidth)
A pure virtual class used to derive REPORTER objects from.
Holds all the data relating to one schematic.
Object to handle a bitmap image that can be inserted in a schematic.
REFERENCE_IMAGE & GetReferenceImage()
void SetPosition(const VECTOR2I &aPosition) override
void SetText(const wxString &aText) override
Base class for any item which can be embedded within the SCHEMATIC container class,...
virtual void SetSpinStyle(SPIN_STYLE aSpinStyle)
Segment description base class to describe items which have 2 end points (track, wire,...
void SetStartPoint(const VECTOR2I &aPosition)
VECTOR2I GetEndPoint() const
VECTOR2I GetStartPoint() const
virtual void SetStroke(const STROKE_PARAMS &aStroke) override
bool IsEndPoint(const VECTOR2I &aPoint) const override
Test if aPt is an end point of this schematic object.
void SetEndPoint(const VECTOR2I &aPosition)
void Append(SCH_ITEM *aItem, bool aUpdateLibSymbol=true)
void SetPageSettings(const PAGE_INFO &aPageSettings)
void SetFileName(const wxString &aFileName)
Set the file name for this screen to aFileName.
void SetStroke(const STROKE_PARAMS &aStroke) override
void AddPoint(const VECTOR2I &aPosition)
Handle access to a stack of flattened SCH_SHEET objects by way of a path for creating a flattened sch...
Sheet symbol placed in a schematic, and is the entry point for a sub schematic.
void SetFileName(const wxString &aFilename)
void SetName(const wxString &aName)
SCH_SCREEN * GetScreen() const
void SetScreen(SCH_SCREEN *aScreen)
Set the SCH_SCREEN associated with this sheet to aScreen.
void SetExcludedFromSim(bool aEnable, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
Set or clear the exclude from simulation flag.
void SetRef(const SCH_SHEET_PATH *aSheet, const wxString &aReference)
Set the reference for the given sheet path for this symbol.
void SetFootprintFieldText(const wxString &aFootprint)
void SetExcludedFromBOM(bool aEnable, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
Set or clear the exclude from schematic bill of materials flag.
void SetLibSymbol(LIB_SYMBOL *aLibSymbol)
Set this schematic symbol library symbol reference to aLibSymbol.
void SetExcludedFromBoard(bool aEnable, const SCH_SHEET_PATH *aInstance=nullptr, const wxString &aVariantName=wxEmptyString) override
SCH_FIELD * GetField(FIELD_T aFieldType)
Return a mandatory field in this symbol.
VECTOR2I::extended_type ecoord
const VECTOR2I NearestPoint(const VECTOR2I &aP) const
Compute a point on the segment (this) that is closest to point aP.
static SEG::ecoord Square(int a)
Spin style for labels of all kinds on schematics.
Simple container to manage line stroke parameters.
virtual void SetShowPinNumbers(bool aShow)
Set or clear the pin number visibility flag.
virtual void SetShowPinNames(bool aShow)
Set or clear the pin name visibility flag.
static VECTOR2I BaselineShift(const EDA_TEXT &aText)
Offset in text units that moves aText so the baseline-left point of its first glyph lies on its posit...
void Apply(EDA_TEXT *aText, const ELEMENT &aElem, int aUnit)
Give aText the font, style, size and stroke width of text aElem.
void addNetItem(int aSheet, SCH_ITEM *aItem, int aSignal)
Add a wire, junction or label of signal aSignal; separateSignals() keeps it apart from other signals.
const TARGET3001::PROJECT & m_project
TARGET3001_SCH_BUILDER(SCHEMATIC *aSchematic, SCH_SHEET *aRootSheet, const TARGET3001::PROJECT &aProject, const wxString &aFileName, REPORTER *aReporter)
void addToSheet(int aSheet, SCH_ITEM *aItem)
void addFreeItem(const TARGET3001::ELEMENT &aElem)
bool joinsGlobally(const TARGET3001::ELEMENT &aSignal) const
True when the signal's labels must be global: it reaches several sheets or meets supply symbols.
static VECTOR2I toSch(int32_t aX, int32_t aY)
Sheet position in KiCad units, before the per-sheet page offset is applied.
std::map< int, std::vector< PIN_END > > m_pinEnds
placed pins of each signal, by signal ID
SCH_BITMAP * makePicture(const TARGET3001::ELEMENT &aElem) const
Image a rectangle shows instead of its fill, or nullptr when it has none.
std::map< int, std::set< int > > m_powerSheets
sheets holding a power symbol, by signal ID
void joinSignalPieces()
Join the pieces of every signal as separateSignals() left them; see joinPieces()
SCH_ITEM * makeGraphic(const TARGET3001::ELEMENT &aElem, const VECTOR2I &aOrigin, bool aInSymbol) const
Add graphics shared by free items and symbol bodies; returns nullptr for unsupported items.
std::map< int, BOX2I > m_extents
drawn extent of each sheet
void addFreeSymbol(const TARGET3001::ELEMENT &aSymbol)
void joinPieces(int aSignal, const std::map< int, std::vector< SCH_ITEM * > > &aItems)
Join the pieces of signal aSignal that KiCad would see apart, since the file joins a signal's items b...
std::map< int, std::vector< std::pair< SCH_ITEM *, int > > > m_netItems
items and their signal, by sheet
std::map< int, std::vector< std::pair< VECTOR2I, int > > > m_pinSignals
pin points and signal, by sheet
TARGET3001::FONTS m_fonts
lookup cache, filled while drawing
std::optional< VECTOR2I > labelAnchor(const TARGET3001::ELEMENT &aSignal, int aSheet, const VECTOR2I &aPos) const
Point on the signal's own wires or pins nearest a name drawn at aPos, if it is close enough to name t...
std::optional< VECTOR2I > bendAround(int aSheet, int aSignal, const VECTOR2I &aPos, std::vector< std::pair< SCH_LINE *, int > > &aWires, const std::function< bool(const VECTOR2I &)> &aIsFree)
Bend the wires of aSignal that pass through aPos around it, one gap aside on a side aIsFree accepts,...
void addGateBodies(LIB_SYMBOL *aLib, const std::vector< const TARGET3001::ELEMENT * > &aGates, bool aFieldTexts, const std::map< uint16_t, wxString > &aPadNumbers={}) const
Draw each gate's body as one unit of aLib; aFieldTexts leaves reference and value texts to fields.
void addComponent(const TARGET3001::ELEMENT &aComponent)
void addConnections(const TARGET3001::ELEMENT &aSignal)
std::map< int, std::vector< SCH_ITEM * > > m_pending
std::set< int > m_globalSignals
signals joined by global labels
void separateSignals(int aSheet)
Move apart items of different signals that touch where KiCad would join them, since the file connects...
SCH_SCREEN * screen(int aSheet)
Screen for a 1-based sheet number, created on first use.
std::map< int, SCH_SHEET * > m_sheets
by 1-based sheet number
static int sheetOf(const TARGET3001::ELEMENT &aElem)
Sheet number of a schematic element, or 0 for board elements.
constexpr extended_type Cross(const VECTOR2< T > &aVector) const
Compute cross product of self with aVector.
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
constexpr extended_type Dot(const VECTOR2< T > &aVector) const
Compute dot product of self with aVector.
VECTOR2< T > Resize(T aNewLength) const
Return a vector of the same direction, but length specified in aNewLength.
static constexpr EDA_ANGLE ANGLE_VERTICAL
static constexpr EDA_ANGLE ANGLE_HORIZONTAL
@ FILLED_SHAPE
Fill with object color.
static const std::string KiCadSchematicFileExtension
SCH_LAYER_ID
Eeschema drawing layers.
constexpr double PAGE_MARGIN_MM
Margin added on every side of the drawn extents before choosing a page, in millimetres.
constexpr int SCHEMATIC_SHEET_COUNT
Sheets occupy layers 101 to 200.
wxString ToWx(const std::string &aRaw)
Convert a stored ANSI string to a wxString.
ELEMENT_TYPE
Element class tags as stored in the file.
constexpr int SCHEMATIC_LAYER_BASE
First layer number used for schematic sheets; sheet N (1-based) is layer 100 + N.
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
ELECTRICAL_PINTYPE
The symbol library pin object electrical types used in ERC tests.
@ PT_INPUT
usual pin input: must be connected
@ PT_NC
not connected (must be left open)
@ PT_TRISTATE
tri state bus pin
@ PT_NIC
not internally connected (may be connected to anything)
@ PT_BIDI
input or output (like port for a microprocessor)
@ PT_OPENCOLLECTOR
pin type open collector
@ PT_POWER_IN
power input (GND, VCC for ICs). Must be connected to a power output.
@ PT_UNSPECIFIED
unknown electrical properties: creates always a warning when connected
@ PT_PASSIVE
pin for passive symbols: must be connected, and can be connected to any pin.
PIN_ORIENTATION
The symbol library pin object orientations.
@ PIN_UP
The pin extends upwards from the connection point: Probably on the bottom side of the symbol.
@ PIN_RIGHT
The pin extends rightwards from the connection point.
@ PIN_LEFT
The pin extends leftwards from the connection point: Probably on the right side of the symbol.
@ PIN_DOWN
The pin extends downwards from the connection: Probably on the top side of the symbol.
Definition of the SCH_SHEET_PATH and SCH_SHEET_LIST classes for Eeschema.
LINE_STYLE
Dashed line types.
Stroked arc or circle. The base position is the start point.
double Sweep() const
Counter-clockwise sweep in (0, 360]; equal angles give a full circle.
float startAngle
degrees, counter-clockwise from +X
Fields shared by every drawable element.
std::vector< uint8_t > Picture() const
Encoded image a rectangle shows stretched over its area instead of its fill, empty for none.
uint16_t component
ID of the owning component (a component stores its own), 0 for none.
uint16_t signal
ID of the owning signal (a signal stores its own), 0 for none.
std::optional< std::pair< int32_t, int32_t > > TextRightEnd() const
Right end of right-aligned text from its ARXY property, in file coordinates.
const std::string * FindProp(const std::string &aKey) const
Return the value of the first property named aKey, if any.
One element of any class.
std::shared_ptr< COMPONENT > component
std::shared_ptr< SYMBOL > symbol
std::shared_ptr< SIGNAL > signal
std::vector< ELEMENT > children
Children of a pin (its number text).
uint8_t dashStyle
0 solid, 1 long dash, 2 dash-dot, 3 other, 4 short dash
Schematic pin. The base position is the connection point; the pin extends along direction.
Filled rectangle anchored at a corner (the base position); sizes are signed.
Filled triangle given by three absolute corners (the first is the base position).
wxString ToWx(const std::string &aRaw)
Convert a stored ANSI string to a wxString.
FIELD_T
The set of all field indices assuming an array like sequence that a SCH_COMPONENT or LIB_PART can hol...
@ REFERENCE
Field Reference of part, i.e. "IC21".
@ VALUE
Field Value of part, i.e. "3.3K".
static double sweep(float aStart, float aEnd)
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Calculate the new point of coord coord pX, pY, for a rotation center 0, 0.
bool IsPointOnSegment(const VECTOR2I &aSegStart, const VECTOR2I &aSegEnd, const VECTOR2I &aTestPoint)
Test if aTestPoint is on line defined by aSegStart and aSegEnd.
double DEG2RAD(double deg)
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D
Definition of file extensions used in Kicad.