KiCad PCB EDA Suite
zone_create_helper.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  * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors.
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, you may find one here:
17  * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
18  * or you may search the http://www.gnu.org website for the version 2 license,
19  * or you may write to the Free Software Foundation, Inc.,
20  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
21  */
22 
24 
25 #include <view/view.h>
26 #include <tool/tool_manager.h>
27 #include <class_zone.h>
28 #include <class_drawsegment.h>
29 #include <class_edge_mod.h>
30 #include <class_pad.h>
31 #include <board_commit.h>
32 #include <pcb_painter.h>
33 
34 #include <tools/pcb_actions.h>
35 #include <tools/selection_tool.h>
36 
37 #include <zone_filler.h>
38 
40  m_tool( aTool ),
41  m_params( aParams ),
42  m_parentView( *aTool.getView() )
43 {
45 }
46 
47 
49 {
50  // remove the preview from the view
53 }
54 
55 
56 std::unique_ptr<ZONE_CONTAINER> ZONE_CREATE_HELPER::createNewZone( bool aKeepout )
57 {
58  auto& frame = *m_tool.getEditFrame<PCB_BASE_EDIT_FRAME>();
59  auto& board = *m_tool.getModel<BOARD>();
61 
62  // Get the current default settings for zones
63  ZONE_SETTINGS zoneInfo = frame.GetZoneSettings();
65  zoneInfo.m_NetcodeSelection = board.GetHighLightNetCode();
66  zoneInfo.SetIsKeepout( m_params.m_keepout );
67 
69  {
70  // Get the current default settings for zones
71 
72  // Show options dialog
73  int dialogResult;
74 
75  if( m_params.m_keepout )
76  dialogResult = InvokeKeepoutAreaEditor( &frame, &zoneInfo );
77  else
78  {
79  if( IsCopperLayer( zoneInfo.m_CurrentZone_Layer ) )
80  dialogResult = InvokeCopperZonesEditor( &frame, &zoneInfo );
81  else
82  dialogResult = InvokeNonCopperZonesEditor( &frame, &zoneInfo );
83  }
84 
85  if( dialogResult == wxID_CANCEL )
86  return nullptr;
87 
88  controls->WarpCursor( controls->GetCursorPosition(), true );
89  }
90 
91  auto newZone = std::make_unique<ZONE_CONTAINER>( &board );
92 
93  // Apply the selected settings
94  zoneInfo.ExportSetting( *newZone );
95 
96  return newZone;
97 }
98 
99 
100 std::unique_ptr<ZONE_CONTAINER> ZONE_CREATE_HELPER::createZoneFromExisting(
101  const ZONE_CONTAINER& aSrcZone )
102 {
103  auto& board = *m_tool.getModel<BOARD>();
104 
105  auto newZone = std::make_unique<ZONE_CONTAINER>( &board );
106 
107  ZONE_SETTINGS zoneSettings;
108  zoneSettings << aSrcZone;
109 
110  zoneSettings.ExportSetting( *newZone );
111 
112  return newZone;
113 }
114 
115 
117 {
118  BOARD_COMMIT commit( &m_tool );
119  BOARD* board = m_tool.getModel<BOARD>();
120  std::vector<ZONE_CONTAINER*> newZones;
121 
122  SHAPE_POLY_SET originalOutline( *aZone.Outline() );
123  originalOutline.BooleanSubtract( *aCutout.Outline(), SHAPE_POLY_SET::PM_FAST );
124 
125  for( int i = 0; i < originalOutline.OutlineCount(); i++ )
126  {
127  auto newZoneOutline = new SHAPE_POLY_SET;
128  newZoneOutline->AddOutline( originalOutline.Outline( i ) );
129 
130  for (int j = 0; j < originalOutline.HoleCount(i) ; j++ )
131  {
132  newZoneOutline->AddHole( originalOutline.CHole(i, j), i );
133  }
134 
135  auto newZone = new ZONE_CONTAINER( aZone );
136  newZone->SetOutline( newZoneOutline );
137  newZone->SetLocalFlags( 1 );
138  newZone->Hatch();
139  newZones.push_back( newZone );
140  commit.Add( newZone );
141  }
142 
143  commit.Remove( &aZone );
144  commit.Push( _( "Add a zone cutout" ) );
145 
146  ZONE_FILLER filler( board );
147  filler.Fill( newZones );
148 
149  auto toolMgr = m_tool.GetManager();
150 
151  toolMgr->RunAction( PCB_ACTIONS::selectionClear, true );
152  toolMgr->RunAction( PCB_ACTIONS::selectItem, true, newZones[0] );
153 }
154 
155 
156 void ZONE_CREATE_HELPER::commitZone( std::unique_ptr<ZONE_CONTAINER> aZone )
157 {
158  auto& frame = *m_tool.getEditFrame<PCB_EDIT_FRAME>();
159  auto board = m_tool.getModel<BOARD>();
160 
161  switch ( m_params.m_mode )
162  {
164  // For cutouts, subtract from the source
166  break;
167 
170  {
171  BOARD_COMMIT bCommit( &m_tool );
172 
173  aZone->Hatch();
174 
175  if( !m_params.m_keepout )
176  {
177  ZONE_FILLER filler( board );
178  filler.Fill( { aZone.get() } );
179  }
180 
181  bCommit.Add( aZone.release() );
182  bCommit.Push( _( "Add a zone" ) );
183  break;
184  }
185 
187  {
188  BOARD_COMMIT bCommit( &m_tool );
189  BOARD_ITEM_CONTAINER* parent = frame.GetModel();
190  auto poly = m_tool.m_editModules ? new EDGE_MODULE( (MODULE *) parent ) : new DRAWSEGMENT();
191 
192  poly->SetShape ( S_POLYGON );
193  poly->SetLayer( m_tool.getDrawingLayer() );
194  poly->SetPolyShape ( *aZone->Outline() );
195 
196  bCommit.Add( poly );
197  bCommit.Push( _( "Add a graphical polygon" ) );
198 
199  break;
200  }
201  }
202 }
203 
204 
206 {
207  // if we don't have a zone, create one
208  // the user's choice here can affect things like the colour
209  // of the preview
210  if( !m_zone )
211  {
212  if( m_params.m_sourceZone )
214  else
216 
217  if( m_zone )
218  {
219  // set up poperties from zone
220  const auto& settings = *m_parentView.GetPainter()->GetSettings();
221  COLOR4D color = settings.GetColor( nullptr, m_zone->GetLayer() );
222 
224  m_previewItem.SetFillColor( color.WithAlpha( 0.2 ) );
225 
227 
228  aMgr.SetLeaderMode( m_zone.get()->GetHV45()
231  }
232  }
233 
234  if( !m_zone )
235  {
236  return false;
237  }
238 
239  return true;
240 }
241 
242 
244 {
245  // send the points to the preview item
248 }
249 
250 
252 {
253  auto& finalPoints = aMgr.GetLockedInPoints();
254 
255  if( finalPoints.PointCount() < 3 )
256  {
257  // just scrap the zone in progress
258  m_zone = nullptr;
259  }
260  else
261  {
262  // if m_params.m_mode == DRAWING_TOOL::ZONE_MODE::CUTOUT, m_zone
263  // will be merged to the existing zone as a new hole.
264  m_zone->Outline()->NewOutline();
265  auto* outline = m_zone->Outline();
266 
267  for( int i = 0; i < finalPoints.PointCount(); ++i )
268  {
269  outline->Append( finalPoints.CPoint( i ) );
270  }
271 
272  outline->Outline( 0 ).SetClosed( true );
273  outline->RemoveNullSegments();
274 
275  // hand the zone over to the committer
276  commitZone( std::move( m_zone ) );
277  }
278 
280 }
static TOOL_ACTION selectionClear
Clears the current selection.
Definition: pcb_actions.h:53
const SHAPE_LINE_CHAIN & GetLockedInPoints() const
Get the "locked-in" points that describe the polygon itself.
Class ZONE_CONTAINER handles a list of polygons defining a copper zone.
Definition: class_zone.h:60
std::unique_ptr< ZONE_CONTAINER > createZoneFromExisting(const ZONE_CONTAINER &aSrcZone)
Function createZoneFromExisting.
void OnComplete(const POLYGON_GEOM_MANAGER &aMgr) override
Called when the polygon is complete
int InvokeKeepoutAreaEditor(PCB_BASE_FRAME *aCaller, ZONE_SETTINGS *aSettings)
Function InvokeKeepoutAreaEditor invokes up a modal dialog window for copper zone editing...
void SetStrokeColor(const COLOR4D &aNewColor)
Set the stroke colour to set before drawing preview
COMMIT & Add(EDA_ITEM *aItem)
Adds a new item to the model
Definition: commit.h:78
int InvokeNonCopperZonesEditor(PCB_BASE_FRAME *aParent, ZONE_SETTINGS *aSettings)
Function InvokeNonCopperZonesEditor invokes up a modal dialog window for non-copper zone editing...
int color
Definition: DXF_plotter.cpp:62
polygon (not yet used for tracks, but could be in microwave apps)
virtual void Remove(VIEW_ITEM *aItem)
Function Remove() Removes a VIEW_ITEM from the view.
Definition: view.cpp:374
SHAPE_POLY_SET * Outline()
Definition: class_zone.h:242
PCB_LAYER_ID m_layer
Layer to begin drawing
bool RunAction(const std::string &aActionName, bool aNow=false, T aParam=NULL)
Function RunAction() Runs the specified action.
Definition: tool_manager.h:125
void commitZone(std::unique_ptr< ZONE_CONTAINER > aZone)
Commit the current zone-in-progress to the BOARD.
Classes to handle copper zones.
std::unique_ptr< ZONE_CONTAINER > m_zone
The zone-in-progress
KIGFX::PREVIEW::POLYGON_ITEM m_previewItem
The preview item to display
Parameters used to fully describe a zone creation process.
void SetLeaderMode(LEADER_MODE aMode)
Set the leader mode to use when calculating the leader/returner lines.
Add a new zone with the same settings as an existing one.
void ExportSetting(ZONE_CONTAINER &aTarget, bool aFullExport=true) const
Function ExportSetting copy settings to a given zone.
KIGFX::VIEW_CONTROLS * GetViewControls() const
Definition: tool_manager.h:257
int m_NetcodeSelection
Net code selection for the current zone.
Definition: zone_settings.h:65
void performZoneCutout(ZONE_CONTAINER &aZone, ZONE_CONTAINER &aCutout)
Function performZoneCutout()
Unconstrained point-to-point
T * getModel() const
Function getModel()
Definition: tool_base.h:199
Class DRAWING_TOOL.
Definition: drawing_tool.h:49
Class SHAPE_POLY_SET.
ZONE_CONTAINER * m_sourceZone
Zone settings source (for similar and cutout zones)
KIGFX::VIEW & m_parentView
view that show the preview item
bool Fill(std::vector< ZONE_CONTAINER * > aZones, bool aCheck=false)
Definition: zone_filler.cpp:83
COLOR4D WithAlpha(double aAlpha) const
Function WithAlpha Returns a colour with the same colour, but the given alpha.
Definition: color4d.h:233
Class VIEW_CONTROLS is an interface for classes handling user events controlling the view behaviour (...
void SetIsKeepout(bool aEnable)
bool OnFirstPoint(POLYGON_GEOM_MANAGER &aMgr) override
Called before the first point is added - clients can do initialisation here, and can veto the start o...
COMMIT & Remove(EDA_ITEM *aItem)
Removes a new item from the model
Definition: commit.h:90
PAINTER * GetPainter() const
Function GetPainter() Returns the painter object used by the view for drawing VIEW_ITEMS.
Definition: view.h:199
void SetFillColor(const COLOR4D &aNewColor)
Set the fill colour to set before drawing preview
const SHAPE_LINE_CHAIN & GetLeaderLinePoints() const
Get the points comprising the leader line (the line from the last locked-in point to the current curs...
virtual void Update(VIEW_ITEM *aItem, int aUpdateFlags)
For dynamic VIEWs, informs the associated VIEW that the graphical representation of this item has cha...
Definition: view.cpp:1530
Pad object description.
DRAWING_TOOL::ZONE_MODE m_mode
The zone mode to operate in
bool m_editModules
Definition: pcb_tool.h:150
Class ZONE_SETTINGS handles zones parameters.
Definition: zone_settings.h:48
ZONE_CREATE_HELPER(DRAWING_TOOL &aTool, const PARAMS &aParams)
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new outline to the set and returns its index
const PARAMS & m_params
Parameters of the zone to be drawn
PCB_LAYER_ID getDrawingLayer() const
Selects a non-copper layer for drawing
virtual RENDER_SETTINGS * GetSettings()=0
Function GetSettings Returns pointer to current settings that are going to be used when drawing items...
void OnGeometryChange(const POLYGON_GEOM_MANAGER &aMgr) override
Sent when the polygon geometry changes
std::unique_ptr< ZONE_CONTAINER > createNewZone(bool aKeepout)
Function createNewZone()
Class to handle a graphic segment.
Common, abstract interface for edit frames.
Class BOARD holds information pertinent to a Pcbnew printed circuit board.
Definition: class_board.h:170
size_t i
Definition: json11.cpp:597
static TOOL_ACTION selectItem
Selects an item (specified as the event parameter).
Definition: pcb_actions.h:56
Class PCB_EDIT_FRAME is the main frame for Pcbnew.
virtual void Push(const wxString &aMessage=wxT("A commit"), bool aCreateUndoEntry=true, bool aSetDirtyBit=true) override
Executes the changes.
Definition: colors.h:49
void SetPoints(const SHAPE_LINE_CHAIN &aLockedInPts, const SHAPE_LINE_CHAIN &aLeaderPts)
Set the polygon points.
TOOL_MANAGER * GetManager() const
Function GetManager() Returns the instance of TOOL_MANAGER that takes care of the tool...
Definition: tool_base.h:144
bool IsCopperLayer(LAYER_NUM aLayerId)
Function IsCopperLayer 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 SetVisible(VIEW_ITEM *aItem, bool aIsVisible=true)
Sets the item visibility.
Definition: view.cpp:1476
virtual void Add(VIEW_ITEM *aItem, int aDrawPriority=-1)
Function Add() Adds a VIEW_ITEM to the view.
Definition: view.cpp:344
void BooleanSubtract(const SHAPE_POLY_SET &b, POLYGON_MODE aFastMode)
Performs boolean polyset difference For aFastMode meaning, see function booleanOp ...
Abstract interface for BOARD_ITEMs capable of storing other items inside.
bool m_keepout
Should create a keepout zone?
EDGE_MODULE class definition.
Add a new zone/keepout with fresh settings.
Make a cutout to an existing zone.
PCB_LAYER_ID m_CurrentZone_Layer
Layer used to create the current zone.
Definition: zone_settings.h:69
Class that handles the drawing of a polygon, including management of last corner deletion and drawing...
Color has changed.
Definition: view_item.h:57
T * getEditFrame() const
Function getEditFrame()
Definition: tool_base.h:188
Class COLOR4D is the color representation with 4 components: red, green, blue, alpha.
Definition: color4d.h:39