KiCad PCB EDA Suite
AUTOPLACER Class Reference

Classes

struct  SIDE_AND_COLL
 
struct  SIDE_AND_NPINS
 

Public Types

enum  COLLISION { COLLIDE_NONE, COLLIDE_OBJECTS, COLLIDE_H_WIRES }
 
typedef wxPoint SIDE
 

Public Member Functions

 AUTOPLACER (SCH_COMPONENT *aComponent, SCH_SCREEN *aScreen)
 
void DoAutoplace (bool aManual)
 Do the actual autoplacement. More...
 

Static Public Attributes

static const SIDE SIDE_TOP
 
static const SIDE SIDE_BOTTOM
 
static const SIDE SIDE_LEFT
 
static const SIDE SIDE_RIGHT
 

Protected Member Functions

wxSize ComputeFBoxSize (bool aDynamic)
 Compute and return the size of the fields' bounding box. More...
 
SIDE get_pin_side (LIB_PIN *aPin)
 Function get_pin_side Return the side that a pin is on. More...
 
unsigned pins_on_side (SIDE aSide)
 Function pins_on_side Count the number of pins on a side of the component. More...
 
void get_possible_colliders (std::vector< SCH_ITEM * > &aItems)
 Function get_possible_colliders Populate a list of all drawing items that may collide with the fields. More...
 
std::vector< SCH_ITEM * > filtered_colliders (const EDA_RECT &aRect)
 Function filtered_colliders Filter a list of possible colliders to include only those that actually collide with a given rectangle. More...
 
std::vector< SIDE_AND_NPINSget_preferred_sides ()
 Function get_preferred_sides Return a list with the preferred field sides for the component, in decreasing order of preference. More...
 
std::vector< SIDE_AND_COLLget_colliding_sides ()
 Function get_colliding_sides Return a list of the sides where a field set would collide with another item. More...
 
SIDE_AND_NPINS choose_side_filtered (std::vector< SIDE_AND_NPINS > &aSides, const std::vector< SIDE_AND_COLL > &aCollidingSides, COLLISION aCollision, SIDE_AND_NPINS aLastSelection)
 Function choose_side_filtered Choose a side for the fields, filtered on only one side collision type. More...
 
SIDE choose_side_for_fields (bool aAvoidCollisions)
 Function choose_side_for_fields Look where a component's pins are to pick a side to put the fields on. More...
 
void justify_field (SCH_FIELD *aField, SIDE aFieldSide)
 Function justify_field Set the justification of a field based on the side it's supposed to be on, taking into account whether the field will be displayed with flipped justification due to mirroring. More...
 
wxPoint field_box_placement (SIDE aFieldSide)
 Function field_box_placement Returns the position of the field bounding box. More...
 
bool fit_fields_between_wires (EDA_RECT *aBox, SIDE aSide)
 Function fit_fields_between_wires Shift a field box up or down a bit to make the fields fit between some wires. More...
 
int field_horiz_placement (SCH_FIELD *aField, const EDA_RECT &aFieldBox)
 Function field_horiz_placement Place a field horizontally, taking into account the field width and justification. More...
 
int field_vert_placement (SCH_FIELD *aField, const EDA_RECT &aFieldBox, int *aPosAccum, bool aDynamic)
 Function field_vert_placement Place a field vertically. More...
 
int get_field_padding ()
 Function get_field_padding Return the desired padding between fields. More...
 

Private Attributes

SCH_SCREENm_screen
 
SCH_COMPONENTm_component
 
std::vector< SCH_FIELD * > m_fields
 
std::vector< SCH_ITEM * > m_colliders
 
EDA_RECT m_comp_bbox
 
wxSize m_fbox_size
 
bool m_allow_rejustify
 
bool m_align_to_grid
 
bool m_power_symbol
 

Detailed Description

Definition at line 96 of file autoplace_fields.cpp.

Member Typedef Documentation

Definition at line 108 of file autoplace_fields.cpp.

Member Enumeration Documentation

Constructor & Destructor Documentation

AUTOPLACER::AUTOPLACER ( SCH_COMPONENT aComponent,
SCH_SCREEN aScreen 
)
inline

Definition at line 125 of file autoplace_fields.cpp.

References AutoplaceAlignEntry, AutoplaceJustifyEntry, ComputeFBoxSize(), get_possible_colliders(), SCH_COMPONENT::GetBodyBoundingBox(), SCH_COMPONENT::GetFields(), SCH_COMPONENT::IsInNetlist(), Kiface(), and KIFACE_I::KifaceSettings().

126  :m_screen( aScreen ), m_component( aComponent )
127  {
128  m_component->GetFields( m_fields, /* aVisibleOnly */ true );
131 
133  m_fbox_size = ComputeFBoxSize( /* aDynamic */ true );
134 
136 
137  if( aScreen )
139  }
wxSize ComputeFBoxSize(bool aDynamic)
Compute and return the size of the fields' bounding box.
std::vector< SCH_FIELD * > m_fields
SCH_COMPONENT * m_component
EDA_RECT GetBodyBoundingBox() const
Function GetBodyBoundingBox Return a bounding box for the component body but not the fields...
KIFACE_I & Kiface()
Global KIFACE_I "get" accessor.
Definition: kicad.cpp:52
void GetFields(std::vector< SCH_FIELD * > &aVector, bool aVisibleOnly)
Function GetFields populates a std::vector with SCH_FIELDs.
SCH_SCREEN * m_screen
const wxChar AutoplaceAlignEntry[]
std::vector< SCH_ITEM * > m_colliders
wxConfigBase * KifaceSettings() const
Definition: kiface_i.h:103
bool IsInNetlist() const
EDA_RECT m_comp_bbox
void get_possible_colliders(std::vector< SCH_ITEM * > &aItems)
Function get_possible_colliders Populate a list of all drawing items that may collide with the fields...
const wxChar AutoplaceJustifyEntry[]

Member Function Documentation

SIDE_AND_NPINS AUTOPLACER::choose_side_filtered ( std::vector< SIDE_AND_NPINS > &  aSides,
const std::vector< SIDE_AND_COLL > &  aCollidingSides,
COLLISION  aCollision,
SIDE_AND_NPINS  aLastSelection 
)
inlineprotected

Function choose_side_filtered Choose a side for the fields, filtered on only one side collision type.

Removes the sides matching the filter from the list.

Definition at line 426 of file autoplace_fields.cpp.

References collide(), AUTOPLACER::SIDE_AND_NPINS::pins, and AUTOPLACER::SIDE_AND_NPINS::side.

Referenced by choose_side_for_fields().

429  {
430  SIDE_AND_NPINS sel = aLastSelection;
431 
432  std::vector<SIDE_AND_NPINS>::iterator it = aSides.begin();
433  while( it != aSides.end() )
434  {
435  bool collide = false;
436  for( SIDE_AND_COLL collision : aCollidingSides )
437  {
438  if( collision.side == it->side && collision.collision == aCollision )
439  collide = true;
440  }
441  if( !collide )
442  ++it;
443  else
444  {
445  if( it->pins <= sel.pins )
446  {
447  sel.pins = it->pins;
448  sel.side = it->side;
449  }
450  it = aSides.erase( it );
451  }
452  }
453  return sel;
454  }
bool collide(T aObject, U aAnotherObject, int aMinDistance)
collide template method
Definition: shape_index.h:91
SIDE AUTOPLACER::choose_side_for_fields ( bool  aAvoidCollisions)
inlineprotected

Function choose_side_for_fields Look where a component's pins are to pick a side to put the fields on.

Parameters
aAvoidCollisions- if true, pick last the sides where the label will collide with other items.

Definition at line 463 of file autoplace_fields.cpp.

References choose_side_filtered(), COLLIDE_H_WIRES, COLLIDE_OBJECTS, get_colliding_sides(), get_preferred_sides(), and reverse().

Referenced by DoAutoplace().

464  {
465  std::vector<SIDE_AND_NPINS> sides = get_preferred_sides();
466 
467  std::reverse( sides.begin(), sides.end() );
468  SIDE_AND_NPINS side = { wxPoint( 1, 0 ), UINT_MAX };
469 
470  if( aAvoidCollisions )
471  {
472  std::vector<SIDE_AND_COLL> colliding_sides = get_colliding_sides();
473  side = choose_side_filtered( sides, colliding_sides, COLLIDE_OBJECTS, side );
474  side = choose_side_filtered( sides, colliding_sides, COLLIDE_H_WIRES, side );
475  }
476 
477  for( SIDE_AND_NPINS& each_side : sides | boost::adaptors::reversed )
478  {
479  if( !each_side.pins ) return each_side.side;
480  }
481 
482  for( SIDE_AND_NPINS& each_side : sides )
483  {
484  if( each_side.pins <= side.pins )
485  {
486  side.pins = each_side.pins;
487  side.side = each_side.side;
488  }
489  }
490 
491  return side.side;
492  }
std::vector< SIDE_AND_COLL > get_colliding_sides()
Function get_colliding_sides Return a list of the sides where a field set would collide with another ...
SIDE_AND_NPINS choose_side_filtered(std::vector< SIDE_AND_NPINS > &aSides, const std::vector< SIDE_AND_COLL > &aCollidingSides, COLLISION aCollision, SIDE_AND_NPINS aLastSelection)
Function choose_side_filtered Choose a side for the fields, filtered on only one side collision type...
static void reverse(privcurve_t *curve)
Definition: trace.cpp:1020
std::vector< SIDE_AND_NPINS > get_preferred_sides()
Function get_preferred_sides Return a list with the preferred field sides for the component...
wxSize AUTOPLACER::ComputeFBoxSize ( bool  aDynamic)
inlineprotected

Compute and return the size of the fields' bounding box.

Parameters
aDynamic- if true, use dynamic spacing

Definition at line 186 of file autoplace_fields.cpp.

References get_field_padding(), SCH_COMPONENT::GetTransform(), max, TEXT_ANGLE_HORIZ, TEXT_ANGLE_VERT, WIRE_V_SPACING, and TRANSFORM::y1.

Referenced by AUTOPLACER(), and fit_fields_between_wires().

187  {
188  int max_field_width = 0;
189  int total_height = 0;
190 
191  for( SCH_FIELD* field : m_fields )
192  {
193  int field_width;
194  int field_height;
195 
196  if( m_component->GetTransform().y1 )
197  {
198  field->SetTextAngle( TEXT_ANGLE_VERT );
199  }
200  else
201  {
202  field->SetTextAngle( TEXT_ANGLE_HORIZ );
203  }
204 
205  field_width = field->GetBoundingBox().GetWidth();
206  field_height = field->GetBoundingBox().GetHeight();
207 
208  max_field_width = std::max( max_field_width, field_width );
209 
210  if( aDynamic )
211  total_height += field_height + get_field_padding();
212  else
213  total_height += WIRE_V_SPACING;
214 
215  }
216 
217  return wxSize( max_field_width, total_height );
218  }
#define TEXT_ANGLE_HORIZ
Frequent text rotations, used with {Set,Get}TextAngle(), in 0.1 degrees for now, hoping to migrate to...
Definition: common.h:91
Class SCH_FIELD instances are attached to a component and provide a place for the component's value...
Definition: sch_field.h:56
std::vector< SCH_FIELD * > m_fields
TRANSFORM & GetTransform() const
SCH_COMPONENT * m_component
#define TEXT_ANGLE_VERT
Definition: common.h:92
#define WIRE_V_SPACING
int y1
Definition: transform.h:49
#define max(a, b)
Definition: auxiliary.h:86
int get_field_padding()
Function get_field_padding Return the desired padding between fields.
void AUTOPLACER::DoAutoplace ( bool  aManual)
inline

Do the actual autoplacement.

Parameters
aManual- if true, use extra heuristics for smarter placement when manually called up.

Definition at line 147 of file autoplace_fields.cpp.

References choose_side_for_fields(), field_box_placement(), field_horiz_placement(), field_vert_placement(), fit_fields_between_wires(), EDA_RECT::GetTop(), justify_field(), round_n(), SCH_FIELD::SetPosition(), wxPoint::x, and wxPoint::y.

Referenced by SCH_COMPONENT::AutoplaceFields().

148  {
149  bool force_wire_spacing = false;
150  SIDE field_side = choose_side_for_fields( aManual );
151  wxPoint fbox_pos = field_box_placement( field_side );
152  EDA_RECT field_box( fbox_pos, m_fbox_size );
153 
154  if( aManual )
155  force_wire_spacing = fit_fields_between_wires( &field_box, field_side );
156 
157  // Move the fields
158  int last_y_coord = field_box.GetTop();
159  for( unsigned field_idx = 0; field_idx < m_fields.size(); ++field_idx )
160  {
161  SCH_FIELD* field = m_fields[field_idx];
162 
163  if( m_allow_rejustify )
164  justify_field( field, field_side );
165 
166  wxPoint pos(
167  field_horiz_placement( field, field_box ),
168  field_vert_placement( field, field_box, &last_y_coord, !force_wire_spacing ) );
169 
170  if( m_align_to_grid )
171  {
172  pos.x = round_n( pos.x, 50, field_side.x >= 0 );
173  pos.y = round_n( pos.y, 50, field_side.y == 1 );
174  }
175 
176  field->SetPosition( pos );
177  }
178  }
void justify_field(SCH_FIELD *aField, SIDE aFieldSide)
Function justify_field Set the justification of a field based on the side it's supposed to be on...
Class SCH_FIELD instances are attached to a component and provide a place for the component's value...
Definition: sch_field.h:56
std::vector< SCH_FIELD * > m_fields
wxPoint field_box_placement(SIDE aFieldSide)
Function field_box_placement Returns the position of the field bounding box.
T round_n(const T &value, const T &n, bool aRoundUp)
Function round_n Round up/down to the nearest multiple of n.
bool fit_fields_between_wires(EDA_RECT *aBox, SIDE aSide)
Function fit_fields_between_wires Shift a field box up or down a bit to make the fields fit between s...
int field_horiz_placement(SCH_FIELD *aField, const EDA_RECT &aFieldBox)
Function field_horiz_placement Place a field horizontally, taking into account the field width and ju...
int field_vert_placement(SCH_FIELD *aField, const EDA_RECT &aFieldBox, int *aPosAccum, bool aDynamic)
Function field_vert_placement Place a field vertically.
Class EDA_RECT handles the component boundary box.
SIDE choose_side_for_fields(bool aAvoidCollisions)
Function choose_side_for_fields Look where a component's pins are to pick a side to put the fields on...
void SetPosition(const wxPoint &aPosition) override
Function SetPosition set the schematic item position to aPosition.
Definition: sch_field.cpp:581
wxPoint AUTOPLACER::field_box_placement ( SIDE  aFieldSide)
inlineprotected

Function field_box_placement Returns the position of the field bounding box.

Definition at line 515 of file autoplace_fields.cpp.

References EDA_RECT::Centre(), EDA_RECT::GetHeight(), EDA_RECT::GetWidth(), HPADDING, VPADDING, wxPoint::x, and wxPoint::y.

Referenced by DoAutoplace(), and get_colliding_sides().

516  {
517  wxPoint fbox_center = m_comp_bbox.Centre();
518  int offs_x = ( m_comp_bbox.GetWidth() + m_fbox_size.GetWidth() ) / 2 + HPADDING;
519  int offs_y = ( m_comp_bbox.GetHeight() + m_fbox_size.GetHeight() ) / 2 + VPADDING;
520 
521  fbox_center.x += aFieldSide.x * offs_x;
522  fbox_center.y += aFieldSide.y * offs_y;
523 
524  wxPoint fbox_pos(
525  fbox_center.x - m_fbox_size.GetWidth() / 2,
526  fbox_center.y - m_fbox_size.GetHeight() / 2 );
527 
528  return fbox_pos;
529  }
#define VPADDING
#define HPADDING
int GetHeight() const
wxPoint Centre() const
EDA_RECT m_comp_bbox
int GetWidth() const
int AUTOPLACER::field_horiz_placement ( SCH_FIELD aField,
const EDA_RECT aFieldBox 
)
inlineprotected

Function field_horiz_placement Place a field horizontally, taking into account the field width and justification.

Parameters
aField- the field to place.
aFieldBox- box in which fields will be placed
Returns
Correct field horizontal position

Definition at line 598 of file autoplace_fields.cpp.

References EDA_RECT::Centre(), EDA_TEXT::GetHorizJustify(), EDA_RECT::GetLeft(), EDA_RECT::GetRight(), GR_TEXT_HJUSTIFY_CENTER, GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_HJUSTIFY_RIGHT, SCH_FIELD::IsHorizJustifyFlipped(), and wxPoint::x.

Referenced by DoAutoplace().

599  {
600  int field_hjust;
601  int field_xcoord;
602 
603  if( aField->IsHorizJustifyFlipped() )
604  field_hjust = -aField->GetHorizJustify();
605  else
606  field_hjust = aField->GetHorizJustify();
607 
608  switch( field_hjust )
609  {
611  field_xcoord = aFieldBox.GetLeft();
612  break;
614  field_xcoord = aFieldBox.Centre().x;
615  break;
617  field_xcoord = aFieldBox.GetRight();
618  break;
619  default:
620  wxFAIL_MSG( "Unexpected value for SCH_FIELD::GetHorizJustify()" );
621  field_xcoord = aFieldBox.Centre().x; // Most are centered
622  }
623 
624  return field_xcoord;
625  }
int GetLeft() const
EDA_TEXT_HJUSTIFY_T GetHorizJustify() const
Definition: eda_text.h:190
wxPoint Centre() const
int GetRight() const
bool IsHorizJustifyFlipped() const
Function IsHorizJustifyFlipped Returns whether the field will be rendered with the horizontal justifi...
Definition: sch_field.cpp:297
int AUTOPLACER::field_vert_placement ( SCH_FIELD aField,
const EDA_RECT aFieldBox,
int *  aPosAccum,
bool  aDynamic 
)
inlineprotected

Function field_vert_placement Place a field vertically.

Because field vertical placements accumulate, this takes a pointer to a vertical position accumulator.

Parameters
aField- the field to place.
aFieldBox- box in which fields will be placed.
aPosAccum- pointer to a position accumulator
aDynamic- use dynamic spacing
Returns
Correct field vertical position

Definition at line 639 of file autoplace_fields.cpp.

References get_field_padding(), SCH_FIELD::GetBoundingBox(), EDA_RECT::GetHeight(), and WIRE_V_SPACING.

Referenced by DoAutoplace().

641  {
642  int field_height;
643  int padding;
644 
645  if( aDynamic )
646  {
647  field_height = aField->GetBoundingBox().GetHeight();
648 
649  padding = get_field_padding();
650  }
651  else
652  {
653  field_height = WIRE_V_SPACING / 2;
654  padding = WIRE_V_SPACING / 2;
655  }
656 
657  int placement = *aPosAccum + padding / 2 + field_height / 2;
658 
659  *aPosAccum += padding + field_height;
660 
661  return placement;
662  }
int GetHeight() const
#define WIRE_V_SPACING
const EDA_RECT GetBoundingBox() const override
Function GetBoundingBox returns the orthogonal, bounding box of this object for display purposes...
Definition: sch_field.cpp:251
int get_field_padding()
Function get_field_padding Return the desired padding between fields.
std::vector<SCH_ITEM*> AUTOPLACER::filtered_colliders ( const EDA_RECT aRect)
inlineprotected

Function filtered_colliders Filter a list of possible colliders to include only those that actually collide with a given rectangle.

Returns the new vector.

Definition at line 294 of file autoplace_fields.cpp.

References EDA_RECT::Intersects().

Referenced by fit_fields_between_wires(), and get_colliding_sides().

295  {
296  std::vector<SCH_ITEM*> filtered;
297  for( SCH_ITEM* item : m_colliders )
298  {
299  EDA_RECT item_box;
300  if( SCH_COMPONENT* item_comp = dynamic_cast<SCH_COMPONENT*>( item ) )
301  item_box = item_comp->GetBodyBoundingBox();
302  else
303  item_box = item->GetBoundingBox();
304 
305  if( item_box.Intersects( aRect ) )
306  filtered.push_back( item );
307  }
308  return filtered;
309  }
std::vector< SCH_ITEM * > m_colliders
bool Intersects(const EDA_RECT &aRect) const
Function Intersects tests for a common area between rectangles.
Class EDA_RECT handles the component boundary box.
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:69
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
bool AUTOPLACER::fit_fields_between_wires ( EDA_RECT aBox,
SIDE  aSide 
)
inlineprotected

Function fit_fields_between_wires Shift a field box up or down a bit to make the fields fit between some wires.

Returns true if a shift was made.

Definition at line 537 of file autoplace_fields.cpp.

References ComputeFBoxSize(), filtered_colliders(), get_field_padding(), EDA_RECT::GetBottom(), SCH_LINE::GetEndPoint(), EDA_RECT::GetPosition(), SCH_LINE::GetStartPoint(), EDA_RECT::GetTop(), round_n(), EDA_RECT::SetOrigin(), WIRE_V_SPACING, and wxPoint::y.

Referenced by DoAutoplace().

538  {
539  if( aSide != SIDE_TOP && aSide != SIDE_BOTTOM )
540  return false;
541 
542  std::vector<SCH_ITEM*> colliders = filtered_colliders( *aBox );
543  if( colliders.empty() )
544  return false;
545 
546  // Find the offset of the wires for proper positioning
547  int offset = 0;
548 
549  for( SCH_ITEM* item : colliders )
550  {
551  SCH_LINE* line = dynamic_cast<SCH_LINE*>( item );
552  if( !line )
553  return false;
554  wxPoint start = line->GetStartPoint(), end = line->GetEndPoint();
555  if( start.y != end.y )
556  return false;
557 
558  int this_offset = (3 * WIRE_V_SPACING / 2) - ( start.y % WIRE_V_SPACING );
559  if( offset == 0 )
560  offset = this_offset;
561  else if( offset != this_offset )
562  return false;
563  }
564 
565  // At this point we are recomputing the field box size. Do not
566  // return false after this point.
567  m_fbox_size = ComputeFBoxSize( /* aDynamic */ false );
568 
569  wxPoint pos = aBox->GetPosition();
570 
571  // Remove the existing padding to get a bit more space to work with
572  if( aSide == SIDE_BOTTOM )
573  {
575  }
576  else
577  {
579  }
580 
581  pos.y = round_n( pos.y, WIRE_V_SPACING, aSide == SIDE_BOTTOM );
582 
583  aBox->SetOrigin( pos );
584  return true;
585  }
wxSize ComputeFBoxSize(bool aDynamic)
Compute and return the size of the fields' bounding box.
void SetOrigin(const wxPoint &pos)
wxPoint GetEndPoint() const
Definition: sch_line.h:75
#define WIRE_V_SPACING
T round_n(const T &value, const T &n, bool aRoundUp)
Function round_n Round up/down to the nearest multiple of n.
wxPoint GetStartPoint() const
Definition: sch_line.h:71
int GetBottom() const
EDA_RECT m_comp_bbox
const wxPoint & GetPosition() const
Class SCH_LINE is a segment description base class to describe items which have 2 end points (track...
Definition: sch_line.h:42
static const SIDE SIDE_BOTTOM
int get_field_padding()
Function get_field_padding Return the desired padding between fields.
static const SIDE SIDE_TOP
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
std::vector< SCH_ITEM * > filtered_colliders(const EDA_RECT &aRect)
Function filtered_colliders Filter a list of possible colliders to include only those that actually c...
int GetTop() const
std::vector<SIDE_AND_COLL> AUTOPLACER::get_colliding_sides ( )
inlineprotected

Function get_colliding_sides Return a list of the sides where a field set would collide with another item.

Definition at line 386 of file autoplace_fields.cpp.

References COLLIDE_H_WIRES, COLLIDE_NONE, COLLIDE_OBJECTS, DIM, field_box_placement(), filtered_colliders(), SCH_LINE::GetEndPoint(), SCH_LINE::GetStartPoint(), SIDE_LEFT, SIDE_RIGHT, SIDE_TOP, and wxPoint::y.

Referenced by choose_side_for_fields().

387  {
388  SIDE sides_init[] = { SIDE_RIGHT, SIDE_TOP, SIDE_LEFT, SIDE_BOTTOM };
389  std::vector<SIDE> sides( sides_init, sides_init + DIM( sides_init ) );
390  std::vector<SIDE_AND_COLL> colliding;
391 
392  // Iterate over all sides and find the ones that collide
393  for( SIDE side : sides )
394  {
395  EDA_RECT box( field_box_placement( side ), m_fbox_size );
396 
397  COLLISION collision = COLLIDE_NONE;
398  for( SCH_ITEM* collider : filtered_colliders( box ) )
399  {
400  SCH_LINE* line = dynamic_cast<SCH_LINE*>( collider );
401  if( line && !side.x )
402  {
403  wxPoint start = line->GetStartPoint(), end = line->GetEndPoint();
404  if( start.y == end.y && collision != COLLIDE_OBJECTS )
405  collision = COLLIDE_H_WIRES;
406  else
407  collision = COLLIDE_OBJECTS;
408  }
409  else
410  collision = COLLIDE_OBJECTS;
411  }
412 
413  if( collision != COLLIDE_NONE )
414  colliding.push_back( { side, collision } );
415  }
416 
417  return colliding;
418  }
#define DIM(x)
of elements in an array
Definition: macros.h:98
wxPoint field_box_placement(SIDE aFieldSide)
Function field_box_placement Returns the position of the field bounding box.
wxPoint GetEndPoint() const
Definition: sch_line.h:75
wxPoint GetStartPoint() const
Definition: sch_line.h:71
static const SIDE SIDE_LEFT
static const SIDE SIDE_RIGHT
Class SCH_LINE is a segment description base class to describe items which have 2 end points (track...
Definition: sch_line.h:42
static const SIDE SIDE_BOTTOM
Class EDA_RECT handles the component boundary box.
static const SIDE SIDE_TOP
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
std::vector< SCH_ITEM * > filtered_colliders(const EDA_RECT &aRect)
Function filtered_colliders Filter a list of possible colliders to include only those that actually c...
int AUTOPLACER::get_field_padding ( )
inlineprotected

Function get_field_padding Return the desired padding between fields.

Definition at line 668 of file autoplace_fields.cpp.

References FIELD_PADDING, and FIELD_PADDING_ALIGNED.

Referenced by ComputeFBoxSize(), field_vert_placement(), and fit_fields_between_wires().

669  {
670  if( m_align_to_grid )
671  return FIELD_PADDING_ALIGNED;
672  else
673  return FIELD_PADDING;
674  }
#define FIELD_PADDING_ALIGNED
#define FIELD_PADDING
SIDE AUTOPLACER::get_pin_side ( LIB_PIN aPin)
inlineprotected

Function get_pin_side Return the side that a pin is on.

Definition at line 225 of file autoplace_fields.cpp.

References SCH_COMPONENT::GetTransform(), PIN_DOWN, PIN_LEFT, PIN_RIGHT, PIN_UP, LIB_PIN::PinDrawOrient(), SIDE_BOTTOM, SIDE_LEFT, SIDE_RIGHT, and SIDE_TOP.

Referenced by pins_on_side().

226  {
227  int pin_orient = aPin->PinDrawOrient( m_component->GetTransform() );
228  switch( pin_orient )
229  {
230  case PIN_RIGHT: return SIDE_LEFT;
231  case PIN_LEFT: return SIDE_RIGHT;
232  case PIN_UP: return SIDE_BOTTOM;
233  case PIN_DOWN: return SIDE_TOP;
234  default:
235  wxFAIL_MSG( "Invalid pin orientation" );
236  return SIDE_LEFT;
237  }
238  }
TRANSFORM & GetTransform() const
SCH_COMPONENT * m_component
Definition: lib_pin.h:54
static const SIDE SIDE_LEFT
static const SIDE SIDE_RIGHT
static const SIDE SIDE_BOTTOM
static const SIDE SIDE_TOP
int PinDrawOrient(const TRANSFORM &aTransform) const
Function PinDrawOrient returns the pin real orientation (PIN_UP, PIN_DOWN, PIN_RIGHT, PIN_LEFT), according to its orientation and the matrix transform (rot, mirror) aTransform.
Definition: lib_pin.cpp:1841
void AUTOPLACER::get_possible_colliders ( std::vector< SCH_ITEM * > &  aItems)
inlineprotected

Function get_possible_colliders Populate a list of all drawing items that may collide with the fields.

That is, all drawing items, including other fields, that are not the current component or its own fields.

Definition at line 270 of file autoplace_fields.cpp.

References SCH_SCREEN::GetDrawItems(), and SCH_ITEM::Next().

Referenced by AUTOPLACER().

271  {
272  wxASSERT_MSG( m_screen, "get_possible_colliders() with null m_screen" );
273  for( SCH_ITEM* item = m_screen->GetDrawItems(); item; item = item->Next() )
274  {
275  if( SCH_COMPONENT* comp = dynamic_cast<SCH_COMPONENT*>( item ) )
276  {
277  if( comp == m_component ) continue;
278 
279  std::vector<SCH_FIELD*> fields;
280  comp->GetFields( fields, /* aVisibleOnly */ true );
281  for( SCH_FIELD* field : fields )
282  aItems.push_back( field );
283  }
284  aItems.push_back( item );
285  }
286  }
Class SCH_FIELD instances are attached to a component and provide a place for the component's value...
Definition: sch_field.h:56
SCH_COMPONENT * m_component
SCH_ITEM * Next() const
SCH_SCREEN * m_screen
SCH_ITEM * GetDrawItems() const
Function GetDrawItems().
Class SCH_COMPONENT describes a real schematic component.
Definition: sch_component.h:69
Class SCH_ITEM is a base class for any item which can be embedded within the SCHEMATIC container clas...
std::vector<SIDE_AND_NPINS> AUTOPLACER::get_preferred_sides ( )
inlineprotected

Function get_preferred_sides Return a list with the preferred field sides for the component, in decreasing order of preference.

Definition at line 317 of file autoplace_fields.cpp.

References CMP_MIRROR_X, CMP_ORIENT_0, CMP_ORIENT_180, CMP_ORIENT_270, CMP_ORIENT_90, DIM, EDA_RECT::GetHeight(), SCH_COMPONENT::GetOrientation(), EDA_RECT::GetWidth(), pins_on_side(), SIDE_BOTTOM, SIDE_LEFT, SIDE_RIGHT, and SIDE_TOP.

Referenced by choose_side_for_fields().

318  {
319  SIDE_AND_NPINS sides_init[] = {
324  };
325  std::vector<SIDE_AND_NPINS> sides( sides_init, sides_init + DIM( sides_init ) );
326 
327  int orient = m_component->GetOrientation();
328  int orient_angle = orient & 0xff; // enum is a bitmask
329  bool h_mirrored = ( ( orient & CMP_MIRROR_X )
330  && ( orient_angle == CMP_ORIENT_0 || orient_angle == CMP_ORIENT_180 ) );
331  double w = double( m_comp_bbox.GetWidth() );
332  double h = double( m_comp_bbox.GetHeight() );
333 
334  // The preferred-sides heuristics are a bit magical. These were determined mostly
335  // by trial and error.
336 
337  if( m_power_symbol )
338  {
339  // For power symbols, we generally want the label at the top first.
340  switch( orient_angle )
341  {
342  case CMP_ORIENT_0:
343  std::swap( sides[0], sides[1] );
344  std::swap( sides[1], sides[3] );
345  // TOP, BOTTOM, RIGHT, LEFT
346  break;
347  case CMP_ORIENT_90:
348  std::swap( sides[0], sides[2] );
349  std::swap( sides[1], sides[2] );
350  // LEFT, RIGHT, TOP, BOTTOM
351  break;
352  case CMP_ORIENT_180:
353  std::swap( sides[0], sides[3] );
354  // BOTTOM, TOP, LEFT, RIGHT
355  break;
356  case CMP_ORIENT_270:
357  std::swap( sides[1], sides[2] );
358  // RIGHT, LEFT, TOP, BOTTOM
359  break;
360  }
361  }
362  else
363  {
364  // If the component is horizontally mirrored, swap left and right
365  if( h_mirrored )
366  {
367  std::swap( sides[0], sides[2] );
368  }
369 
370  // If the component is very long or is a power symbol, swap H and V
371  if( w/h > 3.0 )
372  {
373  std::swap( sides[0], sides[1] );
374  std::swap( sides[1], sides[3] );
375  }
376  }
377 
378  return sides;
379  }
#define DIM(x)
of elements in an array
Definition: macros.h:98
unsigned pins_on_side(SIDE aSide)
Function pins_on_side Count the number of pins on a side of the component.
int GetOrientation()
Function GetOrientation Used to display component orientation (in dialog editor or info) ...
SCH_COMPONENT * m_component
int GetHeight() const
static const SIDE SIDE_LEFT
EDA_RECT m_comp_bbox
static const SIDE SIDE_RIGHT
static const SIDE SIDE_BOTTOM
int GetWidth() const
static const SIDE SIDE_TOP
void AUTOPLACER::justify_field ( SCH_FIELD aField,
SIDE  aFieldSide 
)
inlineprotected

Function justify_field Set the justification of a field based on the side it's supposed to be on, taking into account whether the field will be displayed with flipped justification due to mirroring.

Definition at line 501 of file autoplace_fields.cpp.

References GR_TEXT_VJUSTIFY_CENTER, SCH_FIELD::IsHorizJustifyFlipped(), EDA_TEXT::SetHorizJustify(), EDA_TEXT::SetVertJustify(), TO_HJUSTIFY(), and wxPoint::x.

Referenced by DoAutoplace().

502  {
503  // Justification is set twice to allow IsHorizJustifyFlipped() to work correctly.
504  aField->SetHorizJustify( TO_HJUSTIFY( -aFieldSide.x ) );
505  aField->SetHorizJustify( TO_HJUSTIFY( -aFieldSide.x *
506  ( aField->IsHorizJustifyFlipped() ? -1 : 1 ) ) );
508  }
void SetVertJustify(EDA_TEXT_VJUSTIFY_T aType)
Definition: eda_text.h:194
EDA_TEXT_HJUSTIFY_T TO_HJUSTIFY(int x)
Function TO_HJUSTIFY Converts an integer to a horizontal justification; neg=L zero=C pos=R...
void SetHorizJustify(EDA_TEXT_HJUSTIFY_T aType)
Definition: eda_text.h:193
bool IsHorizJustifyFlipped() const
Function IsHorizJustifyFlipped Returns whether the field will be rendered with the horizontal justifi...
Definition: sch_field.cpp:297
unsigned AUTOPLACER::pins_on_side ( SIDE  aSide)
inlineprotected

Function pins_on_side Count the number of pins on a side of the component.

Definition at line 245 of file autoplace_fields.cpp.

References get_pin_side(), SCH_COMPONENT::GetPins(), and m_power_symbol.

Referenced by get_preferred_sides().

246  {
247  unsigned pin_count = 0;
248 
249  std::vector<LIB_PIN*> pins;
250  m_component->GetPins( pins );
251 
252  for( LIB_PIN* each_pin : pins )
253  {
254  if( !each_pin->IsVisible() && !m_power_symbol )
255  continue;
256  if( get_pin_side( each_pin ) == aSide )
257  ++pin_count;
258  }
259 
260  return pin_count;
261  }
SCH_COMPONENT * m_component
SIDE get_pin_side(LIB_PIN *aPin)
Function get_pin_side Return the side that a pin is on.
void GetPins(std::vector< LIB_PIN * > &aPinsList)
Function GetPins populate a vector with all the pins.

Member Data Documentation

bool AUTOPLACER::m_align_to_grid
private

Definition at line 104 of file autoplace_fields.cpp.

bool AUTOPLACER::m_allow_rejustify
private

Definition at line 104 of file autoplace_fields.cpp.

std::vector<SCH_ITEM*> AUTOPLACER::m_colliders
private

Definition at line 101 of file autoplace_fields.cpp.

EDA_RECT AUTOPLACER::m_comp_bbox
private

Definition at line 102 of file autoplace_fields.cpp.

SCH_COMPONENT* AUTOPLACER::m_component
private

Definition at line 99 of file autoplace_fields.cpp.

wxSize AUTOPLACER::m_fbox_size
private

Definition at line 103 of file autoplace_fields.cpp.

std::vector<SCH_FIELD*> AUTOPLACER::m_fields
private

Definition at line 100 of file autoplace_fields.cpp.

bool AUTOPLACER::m_power_symbol
private

Definition at line 105 of file autoplace_fields.cpp.

Referenced by pins_on_side().

SCH_SCREEN* AUTOPLACER::m_screen
private

Definition at line 98 of file autoplace_fields.cpp.

const AUTOPLACER::SIDE AUTOPLACER::SIDE_BOTTOM
static

Definition at line 109 of file autoplace_fields.cpp.

Referenced by get_pin_side(), and get_preferred_sides().

const AUTOPLACER::SIDE AUTOPLACER::SIDE_LEFT
static

Definition at line 109 of file autoplace_fields.cpp.

Referenced by get_colliding_sides(), get_pin_side(), and get_preferred_sides().

const AUTOPLACER::SIDE AUTOPLACER::SIDE_RIGHT
static

Definition at line 109 of file autoplace_fields.cpp.

Referenced by get_colliding_sides(), get_pin_side(), and get_preferred_sides().

const AUTOPLACER::SIDE AUTOPLACER::SIDE_TOP
static

Definition at line 109 of file autoplace_fields.cpp.

Referenced by get_colliding_sides(), get_pin_side(), and get_preferred_sides().


The documentation for this class was generated from the following file: