Separate creation of polygons for open and closed shapes.
This allows us to create a bounding hull from an open shape-line-chain, which is useful for defining milled slots.
This commit is contained in:
parent
740e193871
commit
ec9c6a8053
|
@ -138,6 +138,38 @@ double EDA_SHAPE::GetLength() const
|
|||
}
|
||||
|
||||
|
||||
bool EDA_SHAPE::IsClosed() const
|
||||
{
|
||||
switch( m_shape )
|
||||
{
|
||||
case SHAPE_T::CIRCLE:
|
||||
case SHAPE_T::RECT:
|
||||
return true;
|
||||
|
||||
case SHAPE_T::ARC:
|
||||
case SHAPE_T::SEGMENT:
|
||||
return false;
|
||||
|
||||
case SHAPE_T::POLY:
|
||||
if( m_poly.IsEmpty() )
|
||||
return false;
|
||||
else
|
||||
return m_poly.Outline( 0 ).IsClosed();
|
||||
|
||||
case SHAPE_T::BEZIER:
|
||||
if( m_bezierPoints.size() < 3 )
|
||||
return false;
|
||||
else
|
||||
return m_bezierPoints[0] == m_bezierPoints[ m_bezierPoints.size() - 1 ];
|
||||
|
||||
default:
|
||||
UNIMPLEMENTED_FOR( SHAPE_T_asString() );
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
void EDA_SHAPE::move( const VECTOR2I& aMoveVector )
|
||||
{
|
||||
switch ( m_shape )
|
||||
|
|
|
@ -100,6 +100,8 @@ public:
|
|||
void SetFillMode( FILL_T aFill ) { m_fill = aFill; }
|
||||
FILL_T GetFillMode() const { return m_fill; }
|
||||
|
||||
bool IsClosed() const;
|
||||
|
||||
COLOR4D GetFillColor() const { return m_fillColor; }
|
||||
void SetFillColor( const COLOR4D& aColor ) { m_fillColor = aColor; }
|
||||
|
||||
|
|
|
@ -34,6 +34,7 @@ namespace PNS
|
|||
// Settings for the CONVERT_TOOL.
|
||||
struct CONVERT_SETTINGS
|
||||
{
|
||||
bool m_StrokeHulls;
|
||||
bool m_IgnoreLineWidths;
|
||||
bool m_DeleteOriginals;
|
||||
};
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include <tools/pcb_actions.h>
|
||||
#include <tools/pcb_selection_tool.h>
|
||||
#include <trigo.h>
|
||||
#include <macros.h>
|
||||
#include <zone.h>
|
||||
|
||||
#include "convert_tool.h"
|
||||
|
@ -203,7 +204,6 @@ int CONVERT_TOOL::CreatePolys( const TOOL_EVENT& aEvent )
|
|||
PCB_LAYER_ID destLayer = m_frame->GetActiveLayer();
|
||||
FOOTPRINT* parentFootprint = nullptr;
|
||||
bool foundChainedSegs = false;
|
||||
bool foundFilledShape = false;
|
||||
|
||||
PCB_SELECTION& selection = m_selectionTool->RequestSelection(
|
||||
[]( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, PCB_SELECTION_TOOL* sTool )
|
||||
|
@ -219,23 +219,28 @@ int CONVERT_TOOL::CreatePolys( const TOOL_EVENT& aEvent )
|
|||
polys.clear();
|
||||
|
||||
for( EDA_ITEM* item : selection )
|
||||
{
|
||||
item->ClearTempFlags();
|
||||
|
||||
if( item->Type() == PCB_SHAPE_T || item->Type() == PCB_FP_SHAPE_T )
|
||||
foundFilledShape = static_cast<PCB_SHAPE*>( item )->IsFilled();
|
||||
}
|
||||
|
||||
SHAPE_POLY_SET polySet;
|
||||
SHAPE_POLY_SET temp;
|
||||
|
||||
if( convertSettings.m_IgnoreLineWidths )
|
||||
polySet.Append( makePolysFromClosedGraphics( selection.GetItems(),
|
||||
convertSettings.m_IgnoreLineWidths ) );
|
||||
|
||||
temp = makePolysFromChainedSegs( selection.GetItems() );
|
||||
|
||||
if( !temp.IsEmpty() )
|
||||
{
|
||||
polySet.Append( makePolysFromChainedSegs( selection.GetItems() ) );
|
||||
foundChainedSegs = polySet.OutlineCount() > 0;
|
||||
polySet.Append( temp );
|
||||
foundChainedSegs = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
for( EDA_ITEM* item : selection )
|
||||
item->ClearTempFlags();
|
||||
}
|
||||
|
||||
polySet.Append( makePolysFromGraphics( selection.GetItems(),
|
||||
convertSettings.m_IgnoreLineWidths ) );
|
||||
polySet.Append( makePolysFromOpenGraphics( selection.GetItems() ) );
|
||||
|
||||
if( polySet.IsEmpty() )
|
||||
return false;
|
||||
|
@ -257,8 +262,8 @@ int CONVERT_TOOL::CreatePolys( const TOOL_EVENT& aEvent )
|
|||
// to true.
|
||||
// We also use the pre-flight to keep from putting up any of the dialogs if there's nothing
|
||||
// to convert.
|
||||
convertSettings.m_IgnoreLineWidths = true;
|
||||
convertSettings.m_DeleteOriginals = false;
|
||||
convertSettings.m_IgnoreLineWidths = false;
|
||||
convertSettings.m_DeleteOriginals = true;
|
||||
|
||||
if( !getPolys() )
|
||||
return 0;
|
||||
|
@ -294,7 +299,6 @@ int CONVERT_TOOL::CreatePolys( const TOOL_EVENT& aEvent )
|
|||
PCB_SHAPE* graphic = isFootprint ? new FP_SHAPE( parentFootprint ) : new PCB_SHAPE;
|
||||
|
||||
graphic->SetShape( SHAPE_T::POLY );
|
||||
graphic->SetFilled( !convertSettings.m_IgnoreLineWidths || foundFilledShape );
|
||||
graphic->SetStroke( STROKE_PARAMS( 0, PLOT_DASH_TYPE::SOLID, COLOR4D::UNSPECIFIED ) );
|
||||
graphic->SetLayer( destLayer );
|
||||
graphic->SetPolyShape( poly );
|
||||
|
@ -572,7 +576,42 @@ SHAPE_POLY_SET CONVERT_TOOL::makePolysFromChainedSegs( const std::deque<EDA_ITEM
|
|||
}
|
||||
|
||||
|
||||
SHAPE_POLY_SET CONVERT_TOOL::makePolysFromGraphics( const std::deque<EDA_ITEM*>& aItems,
|
||||
SHAPE_POLY_SET CONVERT_TOOL::makePolysFromOpenGraphics( const std::deque<EDA_ITEM*>& aItems )
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS& bds = m_frame->GetBoard()->GetDesignSettings();
|
||||
SHAPE_POLY_SET poly;
|
||||
|
||||
for( EDA_ITEM* item : aItems )
|
||||
{
|
||||
if( item->GetFlags() & SKIP_STRUCT )
|
||||
continue;
|
||||
|
||||
switch( item->Type() )
|
||||
{
|
||||
case PCB_SHAPE_T:
|
||||
case PCB_FP_SHAPE_T:
|
||||
{
|
||||
PCB_SHAPE* temp = static_cast<PCB_SHAPE*>( item->Clone() );
|
||||
|
||||
if( temp->IsClosed() )
|
||||
continue;
|
||||
|
||||
temp->TransformShapeToPolygon( poly, UNDEFINED_LAYER, 0, bds.m_MaxError, ERROR_INSIDE,
|
||||
false );
|
||||
item->SetFlags( SKIP_STRUCT );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
return poly;
|
||||
}
|
||||
|
||||
|
||||
SHAPE_POLY_SET CONVERT_TOOL::makePolysFromClosedGraphics( const std::deque<EDA_ITEM*>& aItems,
|
||||
bool aIgnoreLineWidths )
|
||||
{
|
||||
BOARD_DESIGN_SETTINGS& bds = m_frame->GetBoard()->GetDesignSettings();
|
||||
|
@ -590,9 +629,10 @@ SHAPE_POLY_SET CONVERT_TOOL::makePolysFromGraphics( const std::deque<EDA_ITEM*>&
|
|||
{
|
||||
PCB_SHAPE* temp = static_cast<PCB_SHAPE*>( item->Clone() );
|
||||
|
||||
if( aIgnoreLineWidths )
|
||||
temp->SetFilled( true );
|
||||
if( !temp->IsClosed() )
|
||||
continue;
|
||||
|
||||
temp->SetFilled( true );
|
||||
temp->TransformShapeToPolygon( poly, UNDEFINED_LAYER, 0, bds.m_MaxError, ERROR_INSIDE,
|
||||
aIgnoreLineWidths );
|
||||
item->SetFlags( SKIP_STRUCT );
|
||||
|
|
|
@ -90,7 +90,8 @@ private:
|
|||
* @param aItems is a list of items to process.
|
||||
* @return a #SHAPE_POLY_SET containing any polygons that were created.
|
||||
*/
|
||||
SHAPE_POLY_SET makePolysFromGraphics( const std::deque<EDA_ITEM*>& aItems,
|
||||
SHAPE_POLY_SET makePolysFromOpenGraphics( const std::deque<EDA_ITEM*>& aItems );
|
||||
SHAPE_POLY_SET makePolysFromClosedGraphics( const std::deque<EDA_ITEM*>& aItems,
|
||||
bool aIgnoreLineWidths );
|
||||
|
||||
PCB_SELECTION_TOOL* m_selectionTool;
|
||||
|
|
Loading…
Reference in New Issue