KiCad PCB EDA Suite
convert_tool.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) 1992-2020 KiCad Developers, see AUTHORS.txt for contributors.
5  * @author Jon Evans <jon@craftyjon.com>
6  *
7  * This program is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU General Public License
9  * as published by the Free Software Foundation; either version 2
10  * of the License, or (at your option) any later version.
11  *
12  * This program is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with this program; if not, you may find one here:
19  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
20  * or you may search the http://www.gnu.org website for the version 2 license,
21  * or you may write to the Free Software Foundation, Inc.,
22  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
23  */
24 
25 #include <bitmaps.h>
26 #include <board_commit.h>
27 #include <class_board.h>
28 #include <pcb_shape.h>
29 #include <fp_shape.h>
30 #include <class_track.h>
31 #include <class_zone.h>
32 #include <collectors.h>
33 #include <confirm.h>
34 #include <menus_helpers.h>
35 #include <pcb_edit_frame.h>
36 #include <footprint_edit_frame.h>
37 #include <trigo.h>
38 #include <tool/tool_manager.h>
39 #include <tools/edit_tool.h>
40 #include <tools/pcb_actions.h>
41 #include <tools/selection_tool.h>
42 
43 #include "convert_tool.h"
44 
45 
47  TOOL_INTERACTIVE( "pcbnew.Convert" ), m_selectionTool( NULL ),
48  m_menu( NULL ), m_frame( NULL )
49 {
50 }
51 
53 {
54  delete m_menu;
55 }
56 
57 
60 
61 
63 {
65  m_frame = getEditFrame<PCB_BASE_FRAME>();
66 
67  // Create a context menu and make it available through selection tool
68  m_menu = new CONDITIONAL_MENU( this );
70  m_menu->SetTitle( _( "Convert..." ) );
71 
72  static KICAD_T convertableTracks[] = { PCB_TRACE_T, PCB_ARC_T, EOT };
73  static KICAD_T convertableZones[] = { PCB_ZONE_AREA_T, PCB_FP_ZONE_AREA_T, EOT };
74 
75  auto graphicLines = P_S_C::OnlyGraphicShapeTypes( { S_SEGMENT, S_RECT } ) && P_S_C::SameLayer();
76 
77  auto trackLines = S_C::MoreThan( 1 ) &&
78  S_C::OnlyTypes( convertableTracks ) && P_S_C::SameLayer();
79 
80  auto anyLines = graphicLines || trackLines;
81 
82  auto anyPolys = ( S_C::OnlyTypes( convertableZones ) ||
84 
85  auto lineToArc = S_C::Count( 1 ) && ( P_S_C::OnlyGraphicShapeTypes( { S_SEGMENT } ) ||
87 
88  auto showConvert = anyPolys || anyLines || lineToArc;
89 
91 
94 
97 
99 
100  // Currently the code exists, but tracks are not really existing in footprints
101  // only segments on copper layers
104 
106 
107  for( std::shared_ptr<ACTION_MENU>& subMenu : m_selectionTool->GetToolMenu().GetSubMenus() )
108  {
109  if( dynamic_cast<SPECIAL_TOOLS_CONTEXT_MENU*>( subMenu.get() ) )
110  static_cast<CONDITIONAL_MENU*>( subMenu.get() )->AddMenu( m_menu, SELECTION_CONDITIONS::ShowAlways );
111  }
112 
113  return true;
114 }
115 
116 
118 {
119  MODULE* mod = nullptr;
120 
121  auto& selection = m_selectionTool->RequestSelection(
122  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, SELECTION_TOOL* sTool )
123  {
124  EditToolSelectionFilter( aCollector,
126 
127  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
128  {
129  BOARD_ITEM* item = aCollector[i];
130 
131  switch( item->Type() )
132  {
133  case PCB_SHAPE_T:
134  case PCB_FP_SHAPE_T:
135  switch( static_cast<PCB_SHAPE*>( item )->GetShape() )
136  {
137  case S_SEGMENT:
138  case S_RECT:
139  // case S_ARC: // Not yet
140  break;
141 
142  default:
143  aCollector.Remove( item );
144  }
145 
146  break;
147 
148  case PCB_TRACE_T:
149  // case PCB_ARC_T: // Not yet
150  break;
151 
152  default:
153  aCollector.Remove( item );
154  }
155  }
156  } );
157 
158  if( selection.Empty() )
159  return 0;
160 
161  // TODO(JE) From a context menu, the selection condition enforces that the items are on
162  // a single layer. But, you can still trigger this with items on multiple layer selected.
163  // Technically we should make this work if each contiguous poly shares a layer
164  PCB_LAYER_ID destLayer = static_cast<BOARD_ITEM*>( selection.Front() )->GetLayer();
165 
166  SHAPE_POLY_SET polySet = makePolysFromSegs( selection.GetItems() );
167 
168  polySet.Append( makePolysFromRects( selection.GetItems() ) );
169 
170  if( polySet.IsEmpty() )
171  return 0;
172 
173  bool isFootprint = m_frame->IsType( FRAME_FOOTPRINT_EDITOR );
174 
175  if( FP_SHAPE* graphic = dynamic_cast<FP_SHAPE*>( selection.Front() ) )
176  mod = graphic->GetParentModule();
177 
178  BOARD_COMMIT commit( m_frame );
179 
180  // For now, we convert each outline in the returned shape to its own polygon
181  std::vector<SHAPE_POLY_SET> polys;
182 
183  for( int i = 0; i < polySet.OutlineCount(); i++ )
184  polys.emplace_back( SHAPE_POLY_SET( polySet.COutline( i ) ) );
185 
186  if( aEvent.IsAction( &PCB_ACTIONS::convertToPoly ) )
187  {
188  for( const SHAPE_POLY_SET& poly : polys )
189  {
190  PCB_SHAPE* graphic = isFootprint ? new FP_SHAPE( mod ) : new PCB_SHAPE;
191 
192  graphic->SetShape( S_POLYGON );
193  graphic->SetLayer( destLayer );
194  graphic->SetPolyShape( poly );
195 
196  commit.Add( graphic );
197  }
198 
199  commit.Push( _( "Convert shapes to polygon" ) );
200  }
201  else
202  {
203  // Creating zone or keepout
204  PCB_BASE_EDIT_FRAME* frame = getEditFrame<PCB_BASE_EDIT_FRAME>();
205  BOARD_ITEM_CONTAINER* parent = frame->GetModel();
206  ZONE_SETTINGS zoneInfo = frame->GetZoneSettings();
207 
208  int ret;
209 
210  if( aEvent.IsAction( &PCB_ACTIONS::convertToKeepout ) )
211  ret = InvokeRuleAreaEditor( frame, &zoneInfo );
212  else
213  ret = InvokeCopperZonesEditor( frame, &zoneInfo );
214 
215  if( ret == wxID_CANCEL )
216  return 0;
217 
218  for( const SHAPE_POLY_SET& poly : polys )
219  {
220  ZONE_CONTAINER* zone = isFootprint ? new MODULE_ZONE_CONTAINER( parent )
221  : new ZONE_CONTAINER( parent );
222 
223  *zone->Outline() = poly;
224  zone->HatchBorder();
225 
226  zoneInfo.ExportSetting( *zone );
227 
228  commit.Add( zone );
229  }
230 
231  commit.Push( _( "Convert shapes to zone" ) );
232  }
233 
234  return 0;
235 }
236 
237 
238 SHAPE_POLY_SET CONVERT_TOOL::makePolysFromSegs( const std::deque<EDA_ITEM*>& aItems )
239 {
240  SHAPE_POLY_SET poly;
241 
242  std::map<VECTOR2I, std::vector<EDA_ITEM*>> connections;
243  std::set<EDA_ITEM*> used;
244  std::deque<EDA_ITEM*> toCheck;
245 
246  for( EDA_ITEM* item : aItems )
247  {
248  if( OPT<SEG> seg = getStartEndPoints( item ) )
249  {
250  toCheck.push_back( item );
251  connections[seg->A].emplace_back( item );
252  connections[seg->B].emplace_back( item );
253  }
254  }
255 
256  while( !toCheck.empty() )
257  {
258  EDA_ITEM* candidate = toCheck.front();
259  toCheck.pop_front();
260 
261  if( used.count( candidate ) )
262  continue;
263 
264  OPT<SEG> seg = getStartEndPoints( candidate );
265  wxASSERT( seg );
266 
267  SHAPE_LINE_CHAIN outline;
268  std::deque<VECTOR2I> points;
269 
270  // aDirection == true for walking "right" and appending to the end of points
271  // false for walking "left" and prepending to the beginning
272  std::function<void( EDA_ITEM*, bool )> process =
273  [&]( EDA_ITEM* aItem, bool aDirection )
274  {
275  if( used.count( aItem ) )
276  return;
277 
278  used.insert( aItem );
279 
280  OPT<SEG> nextSeg = getStartEndPoints( aItem );
281  wxASSERT( nextSeg );
282 
283  // The reference point, i.e. last added point in the direction we're headed
284  VECTOR2I& ref = aDirection ? points.back() : points.front();
285 
286  // The next point, i.e. the other point on this segment
287  VECTOR2I& next = ( ref == nextSeg->A ) ? nextSeg->B : nextSeg->A;
288 
289  if( aDirection )
290  points.push_back( next );
291  else
292  points.push_front( next );
293 
294  for( EDA_ITEM* neighbor : connections[next] )
295  process( neighbor, aDirection );
296  };
297 
298  // Start with just one point and walk one direction
299  points.push_back( seg->A );
300  process( candidate, true );
301 
302  // check for any candidates on the "left"
303  EDA_ITEM* left = nullptr;
304 
305  for( EDA_ITEM* possibleLeft : connections[seg->A] )
306  {
307  if( possibleLeft != candidate )
308  {
309  left = possibleLeft;
310  break;
311  }
312  }
313 
314  if( left )
315  process( left, false );
316 
317  if( points.size() < 3 )
318  continue;
319 
320  for( const VECTOR2I& point : points )
321  outline.Append( point );
322 
323  outline.SetClosed( true );
324 
325  poly.AddOutline( outline );
326  }
327 
328  return poly;
329 }
330 
331 
332 SHAPE_POLY_SET CONVERT_TOOL::makePolysFromRects( const std::deque<EDA_ITEM*>& aItems )
333 {
334  SHAPE_POLY_SET poly;
335 
336  for( EDA_ITEM* item : aItems )
337  {
338  if( item->Type() != PCB_SHAPE_T && item->Type() != PCB_FP_SHAPE_T )
339  continue;
340 
341  PCB_SHAPE* graphic = static_cast<PCB_SHAPE*>( item );
342 
343  if( graphic->GetShape() != S_RECT )
344  continue;
345 
346  SHAPE_LINE_CHAIN outline;
347  VECTOR2I start( graphic->GetStart() );
348  VECTOR2I end( graphic->GetEnd() );
349 
350  outline.Append( start );
351  outline.Append( VECTOR2I( end.x, start.y ) );
352  outline.Append( end );
353  outline.Append( VECTOR2I( start.x, end.y ) );
354  outline.SetClosed( true );
355 
356  poly.AddOutline( outline );
357  }
358 
359  return poly;
360 }
361 
362 
364 {
365  auto& selection = m_selectionTool->RequestSelection(
366  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, SELECTION_TOOL* sTool )
367  {
368  EditToolSelectionFilter( aCollector,
370 
371  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
372  {
373  BOARD_ITEM* item = aCollector[i];
374 
375  switch( item->Type() )
376  {
377  case PCB_SHAPE_T:
378  case PCB_FP_SHAPE_T:
379  switch( static_cast<PCB_SHAPE*>( item )->GetShape() )
380  {
381  case S_POLYGON:
382  break;
383 
384  case S_RECT:
385  break;
386 
387  default:
388  aCollector.Remove( item );
389  }
390 
391  break;
392 
393  case PCB_ZONE_AREA_T:
394  case PCB_FP_ZONE_AREA_T:
395  break;
396 
397  default:
398  aCollector.Remove( item );
399  }
400  }
401  } );
402 
403  if( selection.Empty() )
404  return 0;
405 
406  auto getPolySet =
407  []( EDA_ITEM* aItem )
408  {
409  SHAPE_POLY_SET set;
410 
411  switch( aItem->Type() )
412  {
413  case PCB_ZONE_AREA_T:
414  case PCB_FP_ZONE_AREA_T:
415  set = *static_cast<ZONE_CONTAINER*>( aItem )->Outline();
416  break;
417 
418  case PCB_SHAPE_T:
419  case PCB_FP_SHAPE_T:
420  {
421  PCB_SHAPE* graphic = static_cast<PCB_SHAPE*>( aItem );
422 
423  if( graphic->GetShape() == S_POLYGON )
424  {
425  set = graphic->GetPolyShape();
426  }
427  else if( graphic->GetShape() == S_RECT )
428  {
429  SHAPE_LINE_CHAIN outline;
430  VECTOR2I start( graphic->GetStart() );
431  VECTOR2I end( graphic->GetEnd() );
432 
433  outline.Append( start );
434  outline.Append( VECTOR2I( end.x, start.y ) );
435  outline.Append( end );
436  outline.Append( VECTOR2I( start.x, end.y ) );
437  outline.SetClosed( true );
438 
439  set.AddOutline( outline );
440  }
441  else
442  {
443  wxFAIL_MSG( "Unhandled graphic shape type in PolyToLines - getPolySet" );
444  }
445  break;
446  }
447 
448  default:
449  wxFAIL_MSG( "Unhandled type in PolyToLines - getPolySet" );
450  break;
451  }
452 
453  return set;
454  };
455 
456  auto getSegList =
457  []( SHAPE_POLY_SET& aPoly )
458  {
459  std::vector<SEG> segs;
460 
461  // Our input should be valid polys, so OK to assert here
462  wxASSERT( aPoly.VertexCount() >= 2 );
463 
464  for( int i = 1; i < aPoly.VertexCount(); i++ )
465  segs.emplace_back( SEG( aPoly.CVertex( i - 1 ), aPoly.CVertex( i ) ) );
466 
467  segs.emplace_back( SEG( aPoly.CVertex( aPoly.VertexCount() - 1 ),
468  aPoly.CVertex( 0 ) ) );
469 
470  return segs;
471  };
472 
473  BOARD_COMMIT commit( m_frame );
474  FOOTPRINT_EDIT_FRAME* fpEditor = dynamic_cast<FOOTPRINT_EDIT_FRAME*>( m_frame );
475 
476  MODULE* footprint = nullptr;
477 
478  if( fpEditor )
479  footprint = fpEditor->GetBoard()->GetFirstModule();
480 
481  for( EDA_ITEM* item : selection )
482  {
483  PCB_LAYER_ID layer = static_cast<BOARD_ITEM*>( item )->GetLayer();
484  SHAPE_POLY_SET polySet = getPolySet( item );
485  std::vector<SEG> segs = getSegList( polySet );
486 
487  if( aEvent.IsAction( &PCB_ACTIONS::convertToLines ) )
488  {
489  for( SEG& seg : segs )
490  {
491  if( fpEditor )
492  {
493  FP_SHAPE* graphic = new FP_SHAPE( footprint, S_SEGMENT );
494 
495  graphic->SetLayer( layer );
496  graphic->SetStart( wxPoint( seg.A ) );
497  graphic->SetStart0( wxPoint( seg.A ) );
498  graphic->SetEnd( wxPoint( seg.B ) );
499  graphic->SetEnd0( wxPoint( seg.B ) );
500  commit.Add( graphic );
501  }
502  else
503  {
504  PCB_SHAPE* graphic = new PCB_SHAPE;
505 
506  graphic->SetShape( S_SEGMENT );
507  graphic->SetLayer( layer );
508  graphic->SetStart( wxPoint( seg.A ) );
509  graphic->SetEnd( wxPoint( seg.B ) );
510  commit.Add( graphic );
511  }
512  }
513  }
514  else
515  {
516  PCB_BASE_EDIT_FRAME* frame = getEditFrame<PCB_BASE_EDIT_FRAME>();
517  BOARD_ITEM_CONTAINER* parent = frame->GetModel();
518 
519  if( !IsCopperLayer( layer ) )
520  layer = frame->SelectLayer( F_Cu, LSET::AllNonCuMask() );
521 
522  // I am really unsure converting a polygon to "tracks" (i.e. segments on
523  // copper layers) make sense for footprints, but anyway this code exists
524  if( fpEditor )
525  {
526  // Creating segments on copper layer
527  for( SEG& seg : segs )
528  {
529  FP_SHAPE* graphic = new FP_SHAPE( footprint, S_SEGMENT );
530  graphic->SetLayer( layer );
531  graphic->SetStart( wxPoint( seg.A ) );
532  graphic->SetStart0( wxPoint( seg.A ) );
533  graphic->SetEnd( wxPoint( seg.B ) );
534  graphic->SetEnd0( wxPoint( seg.B ) );
535  commit.Add( graphic );
536  }
537  }
538  else
539  {
540  // Creating tracks
541  for( SEG& seg : segs )
542  {
543  TRACK* track = new TRACK( parent );
544 
545  track->SetLayer( layer );
546  track->SetStart( wxPoint( seg.A ) );
547  track->SetEnd( wxPoint( seg.B ) );
548  commit.Add( track );
549  }
550  }
551  }
552  }
553 
554  commit.Push( _( "Convert polygons to lines" ) );
555 
556  return 0;
557 }
558 
559 
561 {
562  auto& selection = m_selectionTool->RequestSelection(
563  []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, SELECTION_TOOL* sTool )
564  {
565  EditToolSelectionFilter( aCollector,
567 
568  for( int i = aCollector.GetCount() - 1; i >= 0; --i )
569  {
570  BOARD_ITEM* item = aCollector[i];
571 
572  if( !( item->Type() == PCB_SHAPE_T ||
573  item->Type() == PCB_TRACE_T ||
574  item->Type() == PCB_FP_SHAPE_T ) )
575  aCollector.Remove( item );
576  }
577  } );
578 
579  EDA_ITEM* source = selection.Front();
580  VECTOR2I start, end, mid;
581 
582  // Offset the midpoint along the normal a little bit so that it's more obviously an arc
583  const double offsetRatio = 0.1;
584 
585  if( OPT<SEG> seg = getStartEndPoints( source ) )
586  {
587  start = seg->A;
588  end = seg->B;
589 
590  VECTOR2I normal = ( seg->B - seg->A ).Perpendicular().Resize( offsetRatio * seg->Length() );
591  mid = seg->Center() + normal;
592  }
593  else
594  return -1;
595 
596  PCB_BASE_EDIT_FRAME* frame = getEditFrame<PCB_BASE_EDIT_FRAME>();
597  BOARD_ITEM_CONTAINER* parent = frame->GetModel();
598 
599  BOARD_ITEM* boardItem = dynamic_cast<BOARD_ITEM*>( source );
600 
601  // Don't continue processing if we don't actually have a board item
602  if( !boardItem )
603  return 0;
604 
605  PCB_LAYER_ID layer = boardItem->GetLayer();
606 
607  BOARD_COMMIT commit( m_frame );
608 
609  if( source->Type() == PCB_SHAPE_T || source->Type() == PCB_FP_SHAPE_T )
610  {
611  PCB_SHAPE* line = static_cast<PCB_SHAPE*>( source );
612  PCB_SHAPE* arc = new PCB_SHAPE( parent );
613 
614  VECTOR2I center = GetArcCenter( start, mid, end );
615 
616  arc->SetShape( S_ARC );
617  arc->SetLayer( layer );
618  arc->SetWidth( line->GetWidth() );
619 
620  arc->SetCenter( wxPoint( center ) );
621  arc->SetArcStart( wxPoint( start ) );
622  arc->SetAngle( GetArcAngle( start, mid, end ) );
623 
624  arc->SetArcEnd( wxPoint( end ) );
625  commit.Add( arc );
626  }
627  else
628  {
629  wxASSERT( source->Type() == PCB_TRACE_T );
630  TRACK* line = static_cast<TRACK*>( source );
631  ARC* arc = new ARC( parent );
632 
633  arc->SetLayer( layer );
634  arc->SetWidth( line->GetWidth() );
635  arc->SetStart( wxPoint( start ) );
636  arc->SetMid( wxPoint( mid ) );
637  arc->SetEnd( wxPoint( end ) );
638 
639  commit.Add( arc );
640  }
641 
642  commit.Push( _( "Create arc from line segment" ) );
643 
644  return 0;
645 }
646 
647 
649 {
650  switch( aItem->Type() )
651  {
652  case PCB_SHAPE_T:
653  case PCB_FP_SHAPE_T:
654  {
655  PCB_SHAPE* line = static_cast<PCB_SHAPE*>( aItem );
656  return boost::make_optional<SEG>( { VECTOR2I( line->GetStart() ),
657  VECTOR2I( line->GetEnd() ) } );
658  }
659 
660  case PCB_TRACE_T:
661  {
662  TRACK* line = static_cast<TRACK*>( aItem );
663  return boost::make_optional<SEG>( { VECTOR2I( line->GetStart() ),
664  VECTOR2I( line->GetEnd() ) } );
665  }
666 
667  case PCB_ARC_T:
668  {
669  ARC* arc = static_cast<ARC*>( aItem );
670  return boost::make_optional<SEG>( { VECTOR2I( arc->GetStart() ),
671  VECTOR2I( arc->GetEnd() ) } );
672  }
673 
674  default:
675  return NULLOPT;
676  }
677 }
678 
679 
681 {
688 }
CITER next(CITER it)
Definition: ptree.cpp:126
static bool ShowAlways(const SELECTION &aSelection)
The default condition function (always returns true).
usual segment : line with rounded ends
ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:61
void HatchBorder()
Function HatchBorder computes the hatch lines depending on the hatch parameters and stores it in the ...
Definition: class_zone.cpp:919
class ZONE_CONTAINER, managed by a footprint
Definition: typeinfo.h:95
int OutlineCount() const
Returns the number of outlines in the set
void SetEnd0(const wxPoint &aPoint)
Definition: fp_shape.h:108
double GetArcAngle(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Returns the subtended angle for a given arc.
Definition: trigo.cpp:472
static TOOL_ACTION convertToTracks
Definition: pcb_actions.h:468
static OPT< SEG > getStartEndPoints(EDA_ITEM *aItem)
Retrieves the start and end points for a generic item.
SHAPE_POLY_SET & GetPolyShape()
Definition: pcb_shape.h:243
void EditToolSelectionFilter(GENERAL_COLLECTOR &aCollector, int aFlags, SELECTION_TOOL *selectionTool)
Definition: edit_tool.cpp:64
static TOOL_ACTION convertToLines
Definition: pcb_actions.h:466
const wxPoint & GetEnd() const
Function GetEnd returns the ending point of the graphic.
Definition: pcb_shape.h:140
virtual void SetLayer(PCB_LAYER_ID aLayer)
Function SetLayer sets the layer this item is on.
This file is part of the common library.
BOARD_ITEM is a base class for any item which can be embedded within the BOARD container class,...
void SetEnd(const wxPoint &aEnd)
Definition: class_track.h:112
static SELECTION_CONDITION MoreThan(int aNumber)
Creates a functor that tests if the number of selected items is greater than the value given as param...
COMMIT & Add(EDA_ITEM *aItem)
Adds a new item to the model
Definition: commit.h:78
const wxPoint & GetStart() const
Definition: class_track.h:116
static SELECTION_CONDITION OnlyTypes(const KICAD_T aTypes[])
Creates a functor that tests if the selected items are only of given types.
SELECTION_TOOL.
TOOL_MANAGER * m_toolMgr
Definition: tool_base.h:219
bool IsEmpty() const
Returns true if the set is empty (no polygons at all)
int GetWidth() const
Definition: pcb_shape.h:100
static LSET AllNonCuMask()
Return a mask holding all layer minus CU layers.
Definition: lset.cpp:772
static SELECTION_CONDITION OnlyGraphicShapeTypes(const std::set< PCB_SHAPE_TYPE_T > aTypes)
Creates a functor that tests if the selection contains PCB_SHAPE* items of certain shapes This implic...
class ZONE_CONTAINER, a zone area
Definition: typeinfo.h:106
SELECTION_TOOL * m_selectionTool
Definition: convert_tool.h:92
SHAPE_POLY_SET * Outline()
Definition: class_zone.h:300
TOOL_MENU & GetToolMenu()
class ARC, an arc track segment on a copper layer
Definition: typeinfo.h:98
Class that groups generic conditions for selected items.
class FP_SHAPE, a footprint edge
Definition: typeinfo.h:94
static SELECTION_CONDITION Count(int aNumber)
Creates a functor that tests if the number of selected items is equal to the value given as parameter...
VECTOR2< int > VECTOR2I
Definition: vector2d.h:594
Arcs (with rounded ends)
static SELECTION_CONDITION SameLayer()
Function SameLayer Creates a functor that tests if selection contains items that belong exclusively t...
static SHAPE_POLY_SET makePolysFromRects(const std::deque< EDA_ITEM * > &aItems)
Tries to make polygons from rects.
void Go(int(T::*aStateFunc)(const TOOL_EVENT &), const TOOL_EVENT_LIST &aConditions=TOOL_EVENT(TC_ANY, TA_ANY))
Function Go()
void Remove(int aIndex)
Function Remove removes the item at aIndex (first position is 0);.
Definition: collector.h:133
search types array terminator (End Of Types)
Definition: typeinfo.h:82
KICAD_T
Enum KICAD_T is the set of class identification values, stored in EDA_ITEM::m_StructType.
Definition: typeinfo.h:78
A single base class (TRACK) represents both tracks and vias, with subclasses for curved tracks (ARC) ...
class TRACK, a track segment (segment on a copper layer)
Definition: typeinfo.h:96
void Append(int aX, int aY, bool aAllowDuplication=false)
Function Append()
void SetWidth(int aWidth)
Definition: class_track.h:109
bool IsAction(const TOOL_ACTION *aAction) const
Function IsAction() Tests if the event contains an action issued upon activation of the given TOOL_AC...
Definition: tool_event.cpp:67
virtual ~CONVERT_TOOL()
int LinesToPoly(const TOOL_EVENT &aEvent)
Converts selected lines to a polygon, if possible.
int GetCount() const
Function GetCount returns the number of objects in the list.
Definition: collector.h:104
void SetClosed(bool aClosed)
Function SetClosed()
PCB_LAYER_ID
A quick note on layer IDs:
segment with non rounded ends
const auto NULLOPT
Definition: optional.h:9
#define NULL
void SetShape(PCB_SHAPE_TYPE_T aShape)
Definition: pcb_shape.h:113
SHAPE_POLY_SET.
SHAPE_LINE_CHAIN & Outline(int aIndex)
Returns the reference to aIndex-th outline in the set
void SetIcon(const BITMAP_OPAQUE *aIcon)
Assigns an icon for the entry.
Definition: action_menu.cpp:71
const ZONE_SETTINGS & GetZoneSettings() const
TOOL_EVENT.
Definition: tool_event.h:171
const wxPoint & GetStart() const
Function GetStart returns the starting point of the graphic.
Definition: pcb_shape.h:129
MODULE * GetFirstModule() const
Gets the first module in the list (used in footprint viewer/editor) or NULL if none.
Definition: class_board.h:347
static TOOL_ACTION convertToZone
Definition: pcb_actions.h:464
static TOOL_ACTION convertToKeepout
Definition: pcb_actions.h:465
void SetCenter(const wxPoint &aCenterPoint)
For arcs and circles:
Definition: pcb_shape.h:213
void ExportSetting(ZONE_CONTAINER &aTarget, bool aFullExport=true) const
Function ExportSetting copy settings to a given zone.
void SetMid(const wxPoint &aMid)
Definition: class_track.h:301
void SetStart0(const wxPoint &aPoint)
Definition: fp_shape.h:105
int InvokeRuleAreaEditor(PCB_BASE_FRAME *aCaller, ZONE_SETTINGS *aSettings)
Function InvokeRuleAreaEditor invokes up a modal dialog window for copper zone editing.
#define EXCLUDE_TRANSIENTS
Definition: edit_tool.h:55
const BITMAP_OPAQUE refresh_xpm[1]
Definition: refresh.cpp:28
ZONE_SETTINGS handles zones parameters.
Definition: zone_settings.h:67
virtual BOARD_ITEM_CONTAINER * GetModel() const =0
Function GetModel()
Definition: seg.h:39
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index
PCB_BASE_FRAME * m_frame
Definition: convert_tool.h:94
VECTOR2< T > Resize(T aNewLength) const
Function Resize returns a vector of the same direction, but length specified in aNewLength.
Definition: vector2d.h:392
static TOOL_ACTION convertToArc
Definition: pcb_actions.h:467
std::vector< std::shared_ptr< ACTION_MENU > > & GetSubMenus()
Definition: tool_menu.h:95
CONDITIONAL_MENU * m_menu
Definition: convert_tool.h:93
bool Init() override
Function Init() Init() is called once upon a registration of the tool.
void SetTitle(const wxString &aTitle) override
Sets title for the menu.
Definition: action_menu.cpp:89
PCBNEW_SELECTION & RequestSelection(CLIENT_SELECTION_FILTER aClientFilter, std::vector< BOARD_ITEM * > *aFiltered=nullptr, bool aConfirmLockedItems=false)
Function RequestSelection()
bool IsType(FRAME_T aType) const
Common, abstract interface for edit frames.
void SetStart(const wxPoint &aStart)
Definition: pcb_shape.h:132
void setTransitions() override
polygon (not yet used for tracks, but could be in microwave apps)
#define _(s)
Definition: 3d_actions.cpp:33
SHAPE_LINE_CHAIN.
Used when the right click button is pressed, or when the select tool is in effect.
Definition: collectors.h:240
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
static SELECTION_CONDITION OnlyType(KICAD_T aType)
Creates a functor that tests if the selected items are only of given type.
void process(const BOARD_CONNECTED_ITEM *item, int net)
void SetWidth(int aWidth)
Definition: pcb_shape.h:99
EDA_ITEM is a base class for most all the KiCad significant classes, used in schematics and boards.
Definition: eda_item.h:148
MODULE_ZONE_CONTAINER is the same item as ZONE_CONTAINER, but with a specific type id ZONE_CONTAINER ...
Definition: class_zone.h:957
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Executes the changes.
const wxPoint & GetEnd() const
Definition: class_track.h:113
void SetArcEnd(const wxPoint &aArcEndPoint)
Initialize the end arc point.
Definition: pcb_shape.h:206
boost::optional< T > OPT
Definition: optional.h:7
static bool GetLayer(MODEL_VRML &aModel, LAYER_NUM layer, VRML_LAYER **vlayer)
bool IsCopperLayer(LAYER_NUM aLayerId)
Tests whether a layer is a copper layer.
int InvokeCopperZonesEditor(PCB_BASE_FRAME *aCaller, ZONE_SETTINGS *aSettings)
Function InvokeCopperZonesEditor invokes up a modal dialog window for copper zone editing.
void SetStart(const wxPoint &aStart)
Definition: class_track.h:115
static TOOL_ACTION convertToPoly
Definition: pcb_actions.h:463
void SetPolyShape(const SHAPE_POLY_SET &aShape)
Definition: pcb_shape.h:251
int PolyToLines(const TOOL_EVENT &aEvent)
Converts selected polygon-like object to graphic lines, if possible.
#define EXCLUDE_LOCKED
Function EditToolSelectionFilter.
Definition: edit_tool.h:53
static SHAPE_POLY_SET makePolysFromSegs(const std::deque< EDA_ITEM * > &aItems)
Tries to make polygons from segments in the selected items.
PCB_SHAPE_TYPE_T GetShape() const
Definition: pcb_shape.h:114
Abstract interface for BOARD_ITEMs capable of storing other items inside.
BOARD * GetBoard() const
const VECTOR2I GetArcCenter(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Determine the center of an arc or circle given three points on its circumference.
Definition: trigo.cpp:430
virtual void SetAngle(double aAngle, bool aUpdateEnd=true)
Function SetAngle sets the angle for arcs, and normalizes it within the range 0 - 360 degrees.
Definition: pcb_shape.cpp:435
class PCB_SHAPE, a segment not on copper layers
Definition: typeinfo.h:91
void AddItem(const TOOL_ACTION &aAction, const SELECTION_CONDITION &aCondition, int aOrder=ANY_ORDER)
Adds a menu entry to run a TOOL_ACTION on selected items.
virtual PCB_LAYER_ID GetLayer() const
Function GetLayer returns the primary layer this item is on.
PCB_LAYER_ID SelectLayer(PCB_LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask=LSET(), wxPoint aDlgPosition=wxDefaultPosition)
Install the dialog box for layer selection.
Definition: sel_layer.cpp:204
void SetEnd(const wxPoint &aEnd)
Definition: pcb_shape.h:143
void SetArcStart(const wxPoint &aArcStartPoint)
Initialize the start arc point.
Definition: pcb_shape.h:197
KICAD_T Type() const
Function Type()
Definition: eda_item.h:182
int SegmentToArc(const TOOL_EVENT &aEvent)
Converts selected segment (graphic or track) to an arc of the same type.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Appends a vertex at the end of the given outline/hole (default: the last outline)