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();
|
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
|
* Copy constructor SHAPE_POLY_SET
|
||||||
* Performs a deep copy of \p aOther into \p this.
|
* 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_POLY_SET::SHAPE_POLY_SET( const SHAPE_POLY_SET& aOther, bool aDeepCopy ) :
|
||||||
SHAPE( SH_POLY_SET ), m_polys( aOther.m_polys )
|
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 )
|
void ZONE_CONTAINER::GetMsgPanelInfo( EDA_UNITS aUnits, std::vector<MSG_PANEL_ITEM>& aList )
|
||||||
{
|
{
|
||||||
wxString msg;
|
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 )
|
void ZONE_CONTAINER::AddPolygon( const SHAPE_LINE_CHAIN& aPolygon )
|
||||||
{
|
{
|
||||||
wxASSERT( aPolygon.IsClosed() );
|
wxASSERT( aPolygon.IsClosed() );
|
||||||
|
|
|
@ -283,6 +283,24 @@ public:
|
||||||
*/
|
*/
|
||||||
bool HitTestFilledArea( const wxPoint& aRefPos ) const;
|
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
|
* 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
|
* 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; }
|
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
|
* add a polygon to the zone outline
|
||||||
* if the zone outline is empty, this is the main 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 <dialogs/dialog_track_via_properties.h>
|
||||||
#include <preview_items/ruler_item.h>
|
#include <preview_items/ruler_item.h>
|
||||||
#include <board_commit.h>
|
#include <board_commit.h>
|
||||||
|
#include <zone_filler.h>
|
||||||
|
|
||||||
|
|
||||||
void EditToolSelectionFilter( GENERAL_COLLECTOR& aCollector, int aFlags )
|
void EditToolSelectionFilter( GENERAL_COLLECTOR& aCollector, int aFlags )
|
||||||
|
@ -925,6 +926,48 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent )
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
m_commit->Remove( item );
|
m_commit->Remove( item );
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in New Issue