Allow deletion of zone cutout areas
ADDED: Ability to delete zone cutout areas Fixes https://gitlab.com/kicad/code/kicad/issues/4188
This commit is contained in:
parent
7068b6453e
commit
37a4dd927b
|
@ -437,6 +437,13 @@ class SHAPE_POLY_SET : public SHAPE
|
|||
|
||||
SHAPE_POLY_SET();
|
||||
|
||||
/**
|
||||
* Construct a SHAPE_POLY_SET with the first outline given by aOutline.
|
||||
*
|
||||
* @param aOutline is a closed outline
|
||||
*/
|
||||
SHAPE_POLY_SET( const SHAPE_LINE_CHAIN& aOutline );
|
||||
|
||||
/**
|
||||
* Copy constructor SHAPE_POLY_SET
|
||||
* Performs a deep copy of \p aOther into \p this.
|
||||
|
|
|
@ -60,6 +60,13 @@ SHAPE_POLY_SET::SHAPE_POLY_SET() :
|
|||
}
|
||||
|
||||
|
||||
SHAPE_POLY_SET::SHAPE_POLY_SET( const SHAPE_LINE_CHAIN& aOutline ) :
|
||||
SHAPE( SH_POLY_SET )
|
||||
{
|
||||
AddOutline( aOutline );
|
||||
}
|
||||
|
||||
|
||||
SHAPE_POLY_SET::SHAPE_POLY_SET( const SHAPE_POLY_SET& aOther, bool aDeepCopy ) :
|
||||
SHAPE( SH_POLY_SET ), m_polys( aOther.m_polys )
|
||||
{
|
||||
|
|
|
@ -689,6 +689,31 @@ bool ZONE_CONTAINER::HitTestFilledArea( const wxPoint& aRefPos ) const
|
|||
}
|
||||
|
||||
|
||||
bool ZONE_CONTAINER::HitTestCutout( const VECTOR2I& aRefPos, int* aOutlineIdx, int* aHoleIdx ) const
|
||||
{
|
||||
// Iterate over each outline polygon in the zone and then iterate over
|
||||
// each hole it has to see if the point is in it.
|
||||
for( int i = 0; i < m_Poly->OutlineCount(); i++ )
|
||||
{
|
||||
for( int j = 0; j < m_Poly->HoleCount( i ); j++ )
|
||||
{
|
||||
if( m_Poly->Hole( i, j ).PointInside( aRefPos ) )
|
||||
{
|
||||
if( aOutlineIdx )
|
||||
*aOutlineIdx = i;
|
||||
|
||||
if( aHoleIdx )
|
||||
*aHoleIdx = j;
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void ZONE_CONTAINER::GetMsgPanelInfo( EDA_UNITS aUnits, std::vector<MSG_PANEL_ITEM>& aList )
|
||||
{
|
||||
wxString msg;
|
||||
|
@ -887,6 +912,21 @@ ZONE_CONNECTION ZONE_CONTAINER::GetPadConnection( D_PAD* aPad ) const
|
|||
}
|
||||
|
||||
|
||||
void ZONE_CONTAINER::RemoveCutout( int aOutlineIdx, int aHoleIdx )
|
||||
{
|
||||
// Ensure the requested cutout is valid
|
||||
if( m_Poly->OutlineCount() < aOutlineIdx || m_Poly->HoleCount( aOutlineIdx ) < aHoleIdx )
|
||||
return;
|
||||
|
||||
SHAPE_POLY_SET cutPoly( m_Poly->Hole( aOutlineIdx, aHoleIdx ) );
|
||||
|
||||
// Add the cutout back to the zone
|
||||
m_Poly->BooleanAdd( cutPoly, SHAPE_POLY_SET::PM_FAST );
|
||||
|
||||
SetNeedRefill( true );
|
||||
}
|
||||
|
||||
|
||||
void ZONE_CONTAINER::AddPolygon( const SHAPE_LINE_CHAIN& aPolygon )
|
||||
{
|
||||
wxASSERT( aPolygon.IsClosed() );
|
||||
|
|
|
@ -283,6 +283,24 @@ public:
|
|||
*/
|
||||
bool HitTestFilledArea( const wxPoint& aRefPos ) const;
|
||||
|
||||
/**
|
||||
* Tests if the given point is contained within a cutout of the zone.
|
||||
*
|
||||
* @param aRefPos is the point to test
|
||||
* @param aOutlineIdx is the index of the outline containing the cutout
|
||||
* @param aHoleIdx is the index of the hole
|
||||
* @return true if aRefPos is inside a zone cutout
|
||||
*/
|
||||
bool HitTestCutout( const VECTOR2I& aRefPos, int* aOutlineIdx = nullptr,
|
||||
int* aHoleIdx = nullptr ) const;
|
||||
|
||||
bool HitTestCutout( const wxPoint& aRefPos, int* aOutlineIdx = nullptr,
|
||||
int* aHoleIdx = nullptr ) const
|
||||
{
|
||||
return HitTestCutout( VECTOR2I( aRefPos.x, aRefPos.y ), aOutlineIdx, aHoleIdx );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Some intersecting zones, despite being on the same layer with the same net, cannot be
|
||||
* merged due to other parameters such as fillet radius. The copper pour will end up
|
||||
|
@ -618,6 +636,14 @@ public:
|
|||
void SetFilledPolysUseThickness( bool aOption ) { m_FilledPolysUseThickness = aOption; }
|
||||
|
||||
|
||||
/**
|
||||
* Remove a cutout from the zone.
|
||||
*
|
||||
* @param aOutlineIdx is the zone outline the hole belongs to
|
||||
* @param aHoleIdx is the hole in the outline to remove
|
||||
*/
|
||||
void RemoveCutout( int aOutlineIdx, int aHoleIdx );
|
||||
|
||||
/**
|
||||
* add a polygon to the zone outline
|
||||
* if the zone outline is empty, this is the main outline
|
||||
|
|
|
@ -55,6 +55,7 @@ using namespace std::placeholders;
|
|||
#include <dialogs/dialog_track_via_properties.h>
|
||||
#include <preview_items/ruler_item.h>
|
||||
#include <board_commit.h>
|
||||
#include <zone_filler.h>
|
||||
|
||||
|
||||
void EditToolSelectionFilter( GENERAL_COLLECTOR& aCollector, int aFlags )
|
||||
|
@ -925,6 +926,48 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
|
|||
}
|
||||
break;
|
||||
|
||||
case PCB_ZONE_AREA_T:
|
||||
// We process the zones special so that cutouts can be deleted when the delete tool
|
||||
// is called from inside a cutout when the zone is selected.
|
||||
{
|
||||
// Only interact with cutouts when deleting and a single item is selected
|
||||
if( !isCut && selectionCopy.GetSize() == 1 )
|
||||
{
|
||||
VECTOR2I curPos = getViewControls()->GetCursorPosition();
|
||||
auto zone = static_cast<ZONE_CONTAINER*>( item );
|
||||
|
||||
int outlineIdx, holeIdx;
|
||||
|
||||
if( zone->HitTestCutout( curPos, &outlineIdx, &holeIdx ) )
|
||||
{
|
||||
// Remove the cutout
|
||||
m_commit->Modify( zone );
|
||||
zone->RemoveCutout( outlineIdx, holeIdx );
|
||||
|
||||
std::vector<ZONE_CONTAINER*> toFill;
|
||||
toFill.emplace_back( zone );
|
||||
|
||||
// Fill the modified zone
|
||||
ZONE_FILLER filler( board() );
|
||||
filler.InstallNewProgressReporter( frame(), _( "Fill Zone" ), 4 );
|
||||
filler.Fill( toFill );
|
||||
|
||||
// Update the display
|
||||
zone->Hatch();
|
||||
canvas()->Refresh();
|
||||
|
||||
// Restore the selection on the original zone
|
||||
m_toolMgr->RunAction( PCB_ACTIONS::selectItem, true, zone );
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Remove the entire zone otherwise
|
||||
m_commit->Remove( item );
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
m_commit->Remove( item );
|
||||
break;
|
||||
|
|
Loading…
Reference in New Issue