53#include <boost/range/adaptor/reversed.hpp>
67#define FIELD_PADDING schIUScale.MilsToIU( 15 )
68#define WIRE_V_SPACING schIUScale.MilsToIU( 100 )
69#define HPADDING schIUScale.MilsToIU( 25 )
70#define VPADDING schIUScale.MilsToIU( 15 )
75template<
typename T> T
round_n(
const T& value,
const T& n,
bool aRoundUp )
78 return n * (value / n + (aRoundUp ? 1 : 0));
137 bool forceWireSpacing =
false;
147 int last_y_coord = field_box.
GetTop();
149 for(
unsigned field_idx = 0; field_idx <
m_fields.size(); ++field_idx )
158 if( sideandpins.
pins > 0 )
172 fieldVPlacement( field, field_box, &last_y_coord, !forceWireSpacing ) );
176 if( abs( field_side.
x ) > 0 )
179 if( abs( field_side.
y ) > 0 )
194 int max_field_width = 0;
195 int total_height = 0;
197 std::vector<SCH_FIELD*> visibleFields;
201 if( field->IsVisible() )
202 visibleFields.push_back( field );
207 if( field->CanAutoplace() )
215 BOX2I bbox = field->GetBoundingBox();
219 max_field_width = std::max( max_field_width, field_width );
229 return VECTOR2I( max_field_width, total_height );
241 case PIN_ORIENTATION::PIN_RIGHT:
return SIDE_LEFT;
242 case PIN_ORIENTATION::PIN_LEFT:
return SIDE_RIGHT;
244 case PIN_ORIENTATION::PIN_DOWN:
return SIDE_TOP;
246 wxFAIL_MSG( wxS(
"Invalid pin orientation" ) );
256 unsigned pin_count = 0;
276 wxCHECK_RET(
m_screen, wxS(
"getPossibleCollisions() with null m_screen" ) );
284 box.
Merge( symbolBox );
293 std::vector<SCH_FIELD*> fields;
294 candidate->GetFields( fields,
true );
297 aItems.push_back( field );
300 aItems.push_back( item );
311 std::vector<SCH_ITEM*> filtered;
318 item_box = item_comp->GetBodyAndPinsBoundingBox();
320 item_box = item->GetBoundingBox();
323 filtered.push_back( item );
341 std::vector<SIDE_AND_NPINS> sides( sides_init, sides_init +
arrayDim( sides_init ) );
344 int orient_angle = orient & 0xff;
356 switch( orient_angle )
359 std::swap( sides[0], sides[1] );
360 std::swap( sides[1], sides[3] );
364 std::swap( sides[0], sides[2] );
365 std::swap( sides[1], sides[2] );
369 std::swap( sides[0], sides[3] );
373 std::swap( sides[1], sides[2] );
383 std::swap( sides[0], sides[2] );
389 std::swap( sides[0], sides[1] );
390 std::swap( sides[1], sides[3] );
403 std::vector<SIDE> sides( sides_init, sides_init +
arrayDim( sides_init ) );
404 std::vector<SIDE_AND_COLL> colliding;
407 for(
SIDE side : sides )
410 sideandpins.
side = side;
421 if( line && !side.x )
437 colliding.push_back( { side, collision } );
448 const std::vector<SIDE_AND_COLL>& aCollidingSides,
454 std::vector<SIDE_AND_NPINS>::iterator it = aSides.begin();
456 while( it != aSides.end() )
462 if( collision.side == it->side && collision.collision == aCollision )
472 if( it->pins <= sel.
pins )
478 it = aSides.erase( it );
494 std::reverse( sides.begin(), sides.end() );
497 if( aAvoidCollisions )
504 for(
SIDE_AND_NPINS& each_side : sides | boost::adaptors::reversed )
506 if( !each_side.pins )
return each_side;
511 if( each_side.pins <= side.
pins )
513 side.
pins = each_side.pins;
514 side.
side = each_side.side;
544 if( aFieldSideAndPins.
side.
x != 0 )
546 else if( aFieldSideAndPins.
side.
y != 0 )
549 fbox_center.
x += aFieldSideAndPins.
side.
x * offs_x;
550 fbox_center.
y += aFieldSideAndPins.
side.
y * offs_y;
566 pinsBox.
Merge( each_pin->GetBoundingBox() );
572 if( aFieldSideAndPins.
pins > 0 )
574 BOX2I pinsBox = getPinsBox( aFieldSideAndPins.
side );
600 if( colliders.empty() )
615 if( start.
y != end.y )
621 offset = this_offset;
622 else if( offset != this_offset )
656 switch( field_hjust )
659 field_xcoord = aFieldBox.
GetLeft();
662 field_xcoord = aFieldBox.
Centre().
x;
665 field_xcoord = aFieldBox.
GetRight();
668 wxFAIL_MSG( wxS(
"Unexpected value for SCH_FIELD::GetHorizJustify()" ) );
669 field_xcoord = aFieldBox.
Centre().
x;
708 int placement = *aAccumulatedPosition + padding / 2 + field_height / 2;
710 *aAccumulatedPosition += padding + field_height;
737 wxASSERT_MSG( aScreen, wxS(
"A SCH_SCREEN pointer must be given for manual autoplacement" ) );
constexpr std::size_t arrayDim(T const (&)[N]) noexcept
Returns # of elements in an array.
T round_n(const T &value, const T &n, bool aRoundUp)
Round up/down to the nearest multiple of n.
constexpr EDA_IU_SCALE schIUScale
KIFACE_BASE & Kiface()
Global KIFACE_BASE "get" accessor.
VECTOR2I computeFBoxSize(bool aDynamic)
Compute and return the size of the fields' bounding box.
VECTOR2I fieldBoxPlacement(SIDE_AND_NPINS aFieldSideAndPins)
Return the position of the field bounding box.
SIDE getPinSide(SCH_PIN *aPin)
Return the side that a pin is on.
int fieldVPlacement(SCH_FIELD *aField, const BOX2I &aFieldBox, int *aAccumulatedPosition, bool aDynamic)
Place a field vertically.
void getPossibleCollisions(std::vector< SCH_ITEM * > &aItems)
Populate a list of all drawing items that may collide with the fields.
void DoAutoplace(bool aManual)
Do the actual autoplacement.
static const SIDE SIDE_TOP
static const SIDE SIDE_BOTTOM
unsigned pinsOnSide(SIDE aSide)
Count the number of pins on a side of the symbol.
std::vector< SCH_FIELD * > m_fields
SIDE_AND_NPINS chooseSideForFields(bool aAvoidCollisions)
Look where a symbol's pins are to pick a side to put the fields on.
AUTOPLACER(SCH_SYMBOL *aSymbol, SCH_SCREEN *aScreen)
bool fitFieldsBetweenWires(BOX2I *aBox, SIDE aSide)
Shift a field box up or down a bit to make the fields fit between some wires.
int fieldHPlacement(SCH_FIELD *aField, const BOX2I &aFieldBox)
Place a field horizontally, taking into account the field width and justification.
std::vector< SCH_ITEM * > m_colliders
static const SIDE SIDE_RIGHT
std::vector< SCH_ITEM * > filterCollisions(const BOX2I &aRect)
Filter a list of possible colliders to include only those that actually collide with a given rectangl...
std::vector< SIDE_AND_NPINS > getPreferredSides()
Return a list with the preferred field sides for the symbol, in decreasing order of preference.
std::vector< SIDE_AND_COLL > getCollidingSides()
Return a list of the sides where a field set would collide with another item.
static const SIDE SIDE_LEFT
SIDE_AND_NPINS chooseSideFiltered(std::vector< SIDE_AND_NPINS > &aSides, const std::vector< SIDE_AND_COLL > &aCollidingSides, COLLISION aCollision, SIDE_AND_NPINS aLastSelection)
Choose a side for the fields, filtered on only one side collision type.
void justifyField(SCH_FIELD *aField, SIDE aFieldSide)
Set the justification of a field based on the side it's supposed to be on, taking into account whethe...
void SetOrigin(const Vec &pos)
const Vec & GetPosition() const
bool Intersects(const BOX2< Vec > &aRect) const
coord_type GetTop() const
coord_type GetHeight() const
coord_type GetWidth() const
coord_type GetRight() const
coord_type GetLeft() const
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
virtual bool IsVisible() const
void SetVertJustify(GR_TEXT_V_ALIGN_T aType)
GR_TEXT_H_ALIGN_T GetHorizJustify() const
void SetHorizJustify(GR_TEXT_H_ALIGN_T aType)
EE_TYPE Overlapping(const BOX2I &aRect) const
APP_SETTINGS_BASE * KifaceSettings() const
PIN_ORIENTATION PinDrawOrient(const TRANSFORM &aTransform) const
Return the pin real orientation (PIN_UP, PIN_DOWN, PIN_RIGHT, PIN_LEFT), according to its orientation...
Instances are attached to a symbol or sheet and provide a place for the symbol's value,...
const BOX2I GetBoundingBox() const override
Return the orthogonal bounding box of this object for display purposes.
bool IsHorizJustifyFlipped() const
Return whether the field will be rendered with the horizontal justification inverted due to rotation ...
void SetPosition(const VECTOR2I &aPosition) override
bool CanAutoplace() const
Base class for any item which can be embedded within the SCHEMATIC container class,...
FIELDS_AUTOPLACED m_fieldsAutoplaced
Segment description base class to describe items which have 2 end points (track, wire,...
VECTOR2I GetEndPoint() const
VECTOR2I GetStartPoint() const
LIB_PIN * GetLibPin() const
EE_RTREE & Items()
Gets the full RTree, usually for iterating.
void AutoplaceFields(SCH_SCREEN *aScreen, bool aManual) override
Automatically orient all the fields in the symbol.
std::vector< SCH_PIN * > GetPins(const SCH_SHEET_PATH *aSheet=nullptr) const
Retrieve a list of the SCH_PINs for the given sheet path.
TRANSFORM & GetTransform()
int GetOrientation() const
Get the display symbol orientation.
BOX2I GetBodyAndPinsBoundingBox() const
Return a bounding box for the symbol body and pins but not the fields.
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Populate a std::vector with SCH_FIELDs.
BOX2I GetBodyBoundingBox() const
Return a bounding box for the symbol body but not the pins or fields.
static constexpr EDA_ANGLE & ANGLE_HORIZONTAL
static constexpr EDA_ANGLE & ANGLE_VERTICAL
PIN_ORIENTATION
The symbol library pin object orientations.
@ FIELDS_AUTOPLACED_MANUAL
bool collide(T aObject, U aAnotherObject, int aMinDistance)
Used by SHAPE_INDEX to implement Query().
constexpr int MilsToIU(int mils) const