KiCad PCB EDA Suite
edit_zone_helpers.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) 2012 Jean-Pierre Charras, [email protected]
5 * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * Some code comes from FreePCB.
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#include <kiface_base.h>
28#include <confirm.h>
29#include <pcb_edit_frame.h>
30#include <pcbnew_settings.h>
31#include <board_commit.h>
32#include <tool/tool_manager.h>
33#include <tool/actions.h>
34#include <zone.h>
35#include <zones.h>
38
39
41{
42 int dialogResult;
43 ZONE_SETTINGS zoneInfo = GetZoneSettings();
44 PICKED_ITEMS_LIST pickedList; // zones for undo/redo command
45 PICKED_ITEMS_LIST deletedList; // zones that have been deleted when combined
46 BOARD_COMMIT commit( this );
47
48 // Save initial zones configuration, for undo/redo, before adding new zone
49 // note the net name and the layer can be changed, so we must save all zones
50 SaveCopyOfZones( pickedList, GetBoard() );
51
52 if( aZone->GetIsRuleArea() )
53 {
54 // edit a rule area on a copper layer
55 zoneInfo << *aZone;
56 dialogResult = InvokeRuleAreaEditor( this, &zoneInfo );
57 }
58 else if( IsCopperLayer( aZone->GetFirstLayer() ) )
59 {
60 // edit a zone on a copper layer
61 zoneInfo << *aZone;
62 dialogResult = InvokeCopperZonesEditor( this, &zoneInfo );
63 }
64 else
65 {
66 zoneInfo << *aZone;
67 dialogResult = InvokeNonCopperZonesEditor( this, &zoneInfo );
68 }
69
70 if( dialogResult == wxID_CANCEL )
71 {
72 ClearListAndDeleteItems( &deletedList );
73 ClearListAndDeleteItems( &pickedList );
74 return;
75 }
76
77 SetZoneSettings( zoneInfo );
78 OnModify();
79
80 if( dialogResult == ZONE_EXPORT_VALUES )
81 {
82 UpdateCopyOfZonesList( pickedList, deletedList, GetBoard() );
83 commit.Stage( pickedList );
84 commit.Push( _( "Modify zone properties" ) );
85 pickedList.ClearItemsList(); // s_ItemsListPicker is no more owner of picked items
86 return;
87 }
88
89 wxBusyCursor dummy;
90
91 // Undraw old zone outlines
92 for( ZONE* zone : GetBoard()->Zones() )
93 GetCanvas()->GetView()->Update( zone );
94
95 zoneInfo.ExportSetting( *aZone );
96
97 NETINFO_ITEM* net = GetBoard()->FindNet( zoneInfo.m_NetcodeSelection );
98
99 if( net ) // net == NULL should not occur
100 aZone->SetNetCode( net->GetNetCode() );
101
102 UpdateCopyOfZonesList( pickedList, deletedList, GetBoard() );
103
104 commit.Stage( pickedList );
105
106 commit.Push( _( "Modify zone properties" ), SKIP_CONNECTIVITY );
108
109 pickedList.ClearItemsList(); // s_ItemsListPicker is no longer owner of picked items
110}
111
112
113bool BOARD::TestZoneIntersection( ZONE* aZone1, ZONE* aZone2 )
114{
115 // see if areas are on same layer
116 if( !( aZone1->GetLayerSet() & aZone2->GetLayerSet() ).any() )
117 return false;
118
119 SHAPE_POLY_SET* poly1 = aZone1->Outline();
120 SHAPE_POLY_SET* poly2 = aZone2->Outline();
121
122 // test bounding rects
123 BOX2I b1 = poly1->BBox();
124 BOX2I b2 = poly2->BBox();
125
126 if( ! b1.Intersects( b2 ) )
127 return false;
128
129 // Now test for intersecting segments
130 for( auto segIterator1 = poly1->IterateSegmentsWithHoles(); segIterator1; segIterator1++ )
131 {
132 // Build segment
133 SEG firstSegment = *segIterator1;
134
135 for( auto segIterator2 = poly2->IterateSegmentsWithHoles(); segIterator2; segIterator2++ )
136 {
137 // Build second segment
138 SEG secondSegment = *segIterator2;
139
140 // Check whether the two segments built collide
141 if( firstSegment.Collide( secondSegment, 0 ) )
142 return true;
143 }
144 }
145
146 // If a contour is inside another contour, no segments intersects, but the zones
147 // can be combined if a corner is inside an outline (only one corner is enough)
148 for( auto iter = poly2->IterateWithHoles(); iter; iter++ )
149 {
150 if( poly1->Contains( *iter ) )
151 return true;
152 }
153
154 for( auto iter = poly1->IterateWithHoles(); iter; iter++ )
155 {
156 if( poly2->Contains( *iter ) )
157 return true;
158 }
159
160 return false;
161}
162
163
164
#define SKIP_CONNECTIVITY
Definition: board_commit.h:42
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
COMMIT & Stage(EDA_ITEM *aItem, CHANGE_TYPE aChangeType) override
bool SetNetCode(int aNetCode, bool aNoAssert)
Set net using a net code.
NETINFO_ITEM * FindNet(int aNetcode) const
Search for a net with the given netcode.
Definition: board.cpp:1417
bool TestZoneIntersection(ZONE *aZone1, ZONE *aZone2)
Test for intersection of 2 copper areas.
bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:269
virtual void Update(const VIEW_ITEM *aItem, int aUpdateFlags) const override
For dynamic VIEWs, inform the associated VIEW that the graphical representation of this item has chan...
Definition: pcb_view.cpp:92
Handle the data for a net.
Definition: netinfo.h:66
int GetNetCode() const
Definition: netinfo.h:113
void ClearListAndDeleteItems(PICKED_ITEMS_LIST *aList)
Definition: undo_redo.cpp:587
PCB_DRAW_PANEL_GAL * GetCanvas() const override
Return a pointer to GAL-based canvas of given EDA draw frame.
const ZONE_SETTINGS & GetZoneSettings() const
void SetZoneSettings(const ZONE_SETTINGS &aSettings)
BOARD * GetBoard() const
virtual KIGFX::PCB_VIEW * GetView() const override
Return a pointer to the #VIEW instance used in the panel.
void OnModify() override
Must be called after a board change to set the modified flag.
void Edit_Zone_Params(ZONE *zone_container)
Edit params (layer, clearance, ...) for a zone outline.
A holder to handle information on schematic or board items.
void ClearItemsList()
Delete only the list of pickers NOT the picked data itself.
Definition: seg.h:42
bool Collide(const SEG &aSeg, int aClearance, int *aActual=nullptr) const
Definition: seg.cpp:223
Represent a set of closed polygons.
ITERATOR IterateWithHoles(int aOutline)
bool Contains(const VECTOR2I &aP, int aSubpolyIndex=-1, int aAccuracy=0, bool aUseBBoxCaches=false) const
Return true if a given subpolygon contains the point aP.
SEGMENT_ITERATOR IterateSegmentsWithHoles()
Return an iterator object, for the aOutline-th outline in the set (with holes).
const BOX2I BBox(int aClearance=0) const override
Compute a bounding box of the shape, with a margin of aClearance a collision.
ZONE_SETTINGS handles zones parameters.
Definition: zone_settings.h:70
int m_NetcodeSelection
Definition: zone_settings.h:95
void ExportSetting(ZONE &aTarget, bool aFullExport=true) const
Function ExportSetting copy settings to a given zone.
Handle a list of polygons defining a copper zone.
Definition: zone.h:57
bool GetIsRuleArea() const
Accessors to parameters used in Rule Area zones:
Definition: zone.h:697
SHAPE_POLY_SET * Outline()
Definition: zone.h:312
virtual LSET GetLayerSet() const override
Return a std::bitset of all layers on which the item physically resides.
Definition: zone.h:122
PCB_LAYER_ID GetFirstLayer() const
Definition: zone.cpp:242
This file is part of the common library.
int InvokeCopperZonesEditor(PCB_BASE_FRAME *aCaller, ZONE_SETTINGS *aSettings, CONVERT_SETTINGS *aConvertSettings)
Function InvokeCopperZonesEditor invokes up a modal dialog window for copper zone editing.
int InvokeNonCopperZonesEditor(PCB_BASE_FRAME *aParent, ZONE_SETTINGS *aSettings, CONVERT_SETTINGS *aConvertSettings)
Function InvokeNonCopperZonesEditor invokes up a modal dialog window for non-copper zone editing.
int InvokeRuleAreaEditor(PCB_BASE_FRAME *aCaller, ZONE_SETTINGS *aZoneSettings, CONVERT_SETTINGS *aConvertSettings)
Function InvokeRuleAreaEditor invokes up a modal dialog window for copper zone editing.
#define _(s)
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
Definition: layer_ids.h:825
std::vector< FAB_LAYER_COLOR > dummy
#define ZONE_EXPORT_VALUES
Definition: zones.h:44
void UpdateCopyOfZonesList(PICKED_ITEMS_LIST &aPickList, PICKED_ITEMS_LIST &aAuxiliaryList, BOARD *aPcb)
Function UpdateCopyOfZonesList Check a pick list to remove zones identical to their copies and set th...
void SaveCopyOfZones(PICKED_ITEMS_LIST &aPickList, BOARD *aPcb)
Function SaveCopyOfZones creates a copy of zones having a given netcode on a given layer,...