27#include <wx/statline.h>
28#include <wx/checkbox.h>
30#include <wx/radiobut.h>
60 DIALOG_SHIM( aParent, wxID_ANY,
_(
"Conversion Settings" ), wxDefaultPosition,
61 wxDefaultSize, wxDEFAULT_DIALOG_STYLE | wxRESIZE_BORDER ),
64 wxBoxSizer* mainSizer =
new wxBoxSizer( wxVERTICAL );
65 wxBoxSizer* topSizer =
new wxBoxSizer( wxVERTICAL );
66 SetSizer( mainSizer );
68 m_rbMimicLineWidth =
new wxRadioButton(
this, wxID_ANY,
_(
"Copy line width of first object" ) );
71 topSizer->AddSpacer( 6 );
72 m_rbCenterline =
new wxRadioButton(
this, wxID_ANY,
_(
"Use centerlines" ) );
75 topSizer->AddSpacer( 6 );
76 m_rbEnvelope =
new wxRadioButton(
this, wxID_ANY,
_(
"Create bounding hull" ) );
79 m_gapLabel =
new wxStaticText(
this, wxID_ANY,
_(
"Gap:" ) );
80 m_gapCtrl =
new wxTextCtrl(
this, wxID_ANY );
81 m_gapUnits =
new wxStaticText(
this, wxID_ANY,
_(
"mm" ) );
84 m_widthLabel =
new wxStaticText(
this, wxID_ANY,
_(
"Line width:" ) );
89 wxBoxSizer* hullParamsSizer =
new wxBoxSizer( wxHORIZONTAL );
90 hullParamsSizer->Add(
m_gapLabel, 0, wxALIGN_CENTRE_VERTICAL, 5 );
91 hullParamsSizer->Add(
m_gapCtrl, 1, wxALIGN_CENTRE_VERTICAL|wxLEFT|wxRIGHT, 3 );
92 hullParamsSizer->Add(
m_gapUnits, 0, wxALIGN_CENTRE_VERTICAL, 5 );
93 hullParamsSizer->AddSpacer( 18 );
94 hullParamsSizer->Add(
m_widthLabel, 0, wxALIGN_CENTRE_VERTICAL, 5 );
95 hullParamsSizer->Add(
m_widthCtrl, 1, wxALIGN_CENTRE_VERTICAL|wxLEFT|wxRIGHT, 3 );
96 hullParamsSizer->Add(
m_widthUnits, 0, wxALIGN_CENTRE_VERTICAL, 5 );
98 topSizer->AddSpacer( 2 );
99 topSizer->Add( hullParamsSizer, 0, wxLEFT, 26 );
101 topSizer->AddSpacer( 15 );
102 m_cbDeleteOriginals =
new wxCheckBox(
this, wxID_ANY,
_(
"Delete source objects after conversion" ) );
105 wxStaticLine* line =
new wxStaticLine(
this, wxID_ANY, wxDefaultPosition, wxDefaultSize,
107 topSizer->Add( line, 0, wxLEFT|wxRIGHT|wxTOP|wxEXPAND, 5 );
109 mainSizer->Add( topSizer, 1, wxALL|wxEXPAND, 10 );
111 wxBoxSizer* buttonsSizer =
new wxBoxSizer( wxHORIZONTAL );
112 buttonsSizer->AddStretchSpacer();
114 wxStdDialogButtonSizer* sdbSizer =
new wxStdDialogButtonSizer();
115 wxButton* sdbSizerOK =
new wxButton(
this, wxID_OK );
116 sdbSizer->AddButton( sdbSizerOK );
117 wxButton* sdbSizerCancel =
new wxButton(
this, wxID_CANCEL );
118 sdbSizer->AddButton( sdbSizerCancel );
121 buttonsSizer->Add( sdbSizer, 1, 0, 5 );
122 mainSizer->Add( buttonsSizer, 0, wxLEFT|wxRIGHT|wxBOTTOM|wxEXPAND, 5 );
132 m_rbEnvelope->Connect( wxEVT_COMMAND_RADIOBUTTON_SELECTED,
206 m_selectionTool( nullptr ),
230 m_frame = getEditFrame<PCB_BASE_FRAME>();
253 auto canCreatePolyType = graphicLines || anyPolys || anyTracks;
254 auto canCreateLines = anyPolys;
255 auto canCreateTracks = anyPolys || graphicToTrack;
256 auto canCreate = canCreatePolyType
266 m_menu->AppendSeparator();
275 m_menu->AppendSeparator();
287 std::vector<SHAPE_POLY_SET> polys;
296 if( selection.
Empty() )
305 item->ClearTempFlags();
329 for(
int jj = 0; jj < polySet.
HoleCount( ii ); ++jj )
330 polys.back().AddHole( polySet.
Hole( ii, jj ) );
340 if( !getPolys( preflightSettings ) )
350 parentFootprint =
static_cast<FOOTPRINT*
>( zone->GetParent() );
352 wxFAIL_MSG( wxT(
"Unimplemented footprint parent in CONVERT_TOOL::CreatePolys" ) );
363 if( dlg.ShowModal() != wxID_OK )
373 if( resolvedSettings.
m_Gap > 0 )
377 if( !getPolys( resolvedSettings ) )
393 if( candidate->HasLineStroke() )
395 pos = candidate->GetPosition();
402 topLeftItem = candidate;
412 COLOR4D::UNSPECIFIED ) );
416 commit.
Add( graphic );
427 zoneInfo.
m_Layers.reset().set( destLayer );
452 if( ret == wxID_CANCEL )
476 for(
EDA_ITEM* item : selectionCopy )
484 commit.
Push(
_(
"Convert shapes to polygon" ) );
486 commit.
Push(
_(
"Convert shapes to zone" ) );
502 int chainingEpsilon = 100;
508 std::map<VECTOR2I, std::vector<std::pair<int, EDA_ITEM*>>> connections;
509 std::deque<EDA_ITEM*> toCheck;
514 return ( aLeft - aRight ).SquaredEuclideanNorm() <=
SEG::Square( aLimit );
517 auto findInsertionPoint =
520 if( connections.count( aPoint ) )
523 for(
const auto& candidatePair : connections )
525 if( closeEnough( aPoint, candidatePair.first, chainingEpsilon ) )
526 return candidatePair.first;
536 toCheck.push_back( item );
537 connections[findInsertionPoint( seg->A )].emplace_back( std::make_pair( 0, item ) );
538 connections[findInsertionPoint( seg->B )].emplace_back( std::make_pair( 1, item ) );
542 while( !toCheck.empty() )
544 std::vector<BOARD_ITEM*> insertedItems;
546 EDA_ITEM* candidate = toCheck.front();
580 insertedItems.push_back(
static_cast<BOARD_ITEM*
>( aItem ) );
582 else if( aItem->
IsType( { PCB_SHAPE_LOCATE_BEZIER_T } ) )
586 if( aAnchor == graphic->
GetStart() )
612 insertedItems.push_back(
static_cast<BOARD_ITEM*
>( aItem ) );
616 VECTOR2I& point = ( aAnchor == nextSeg->A ) ? nextSeg->B : nextSeg->A;
621 outline.
Insert( 0, point );
623 insertedItems.push_back(
static_cast<BOARD_ITEM*
>( aItem ) );
637 insert( aItem, aAnchor, aDirection );
642 VECTOR2I nextAnchor = ( aAnchor == anchors->A ) ? anchors->B : anchors->A;
644 for( std::pair<int, EDA_ITEM*> pair : connections[nextAnchor] )
646 if( pair.second == aItem )
649 process( pair.second, nextAnchor, aDirection );
663 insert( candidate, anchors->A,
true );
666 process( candidate, anchors->B,
true );
671 for( std::pair<int, EDA_ITEM*> possibleLeft : connections[anchors->A] )
673 if( possibleLeft.second != candidate )
675 left = possibleLeft.second;
684 || !closeEnough( outline.
GetPoint( 0 ), outline.
GetPoint( -1 ), chainingEpsilon ) )
686 for(
EDA_ITEM* item : insertedItems )
705 insertedItems.clear();
723 switch( item->Type() )
773 switch( item->Type() )
813 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
815 BOARD_ITEM* item = aCollector[i];
817 switch( item->Type() )
821 switch( static_cast<PCB_SHAPE*>( item )->GetShape() )
823 case SHAPE_T::SEGMENT:
830 aCollector.Remove( item );
840 aCollector.Remove( item );
845 if( selection.Empty() )
853 switch( aItem->Type() )
857 set = *
static_cast<ZONE*
>( aItem )->Outline();
885 wxFAIL_MSG( wxT(
"Unhandled graphic shape type in PolyToLines - getPolySet" ) );
891 wxFAIL_MSG( wxT(
"Unhandled type in PolyToLines - getPolySet" ) );
901 std::vector<SEG> segs;
904 wxASSERT( aPoly.VertexCount() >= 2 );
906 for(
int i = 1; i < aPoly.VertexCount(); i++ )
907 segs.emplace_back(
SEG( aPoly.CVertex( i - 1 ), aPoly.CVertex( i ) ) );
909 segs.emplace_back(
SEG( aPoly.CVertex( aPoly.VertexCount() - 1 ),
910 aPoly.CVertex( 0 ) ) );
925 auto handleGraphicSeg =
975 if( handleGraphicSeg( item ) )
979 std::vector<SEG> segs = getSegList( polySet );
983 for(
SEG& seg : segs )
994 commit.Add( graphic );
1003 commit.Add( graphic );
1014 for(
SEG& seg : segs )
1022 commit.Add( graphic );
1028 for(
SEG& seg : segs )
1035 commit.Add( track );
1041 commit.Push(
_(
"Convert polygons to lines" ) );
1052 for(
int i = aCollector.
GetCount() - 1; i >= 0; --i )
1054 BOARD_ITEM* item = aCollector[i];
1056 if( !( item->Type() == PCB_SHAPE_T ||
1057 item->Type() == PCB_TRACE_T ||
1058 item->Type() == PCB_FP_SHAPE_T ) )
1060 aCollector.Remove( item );
1065 EDA_ITEM* source = selection.Front();
1069 const double offsetRatio = 0.1;
1071 if( std::optional<SEG> seg = getStartEndPoints( source ) )
1076 VECTOR2I normal = ( seg->B - seg->A ).Perpendicular().Resize( offsetRatio * seg->Length() );
1077 mid = seg->Center() +
normal;
1129 commit.Push(
_(
"Create arc from line segment" ) );
1137 switch( aItem->
Type() )
1151 return std::nullopt;
1157 return std::nullopt;
1174 return std::nullopt;
virtual void Push(const wxString &aMessage=wxT("A commit"), int aCommitFlags=0) override
Revert the commit by restoring the modified items state.
Container for design settings for a BOARD object.
int GetLayerClass(PCB_LAYER_ID aLayer) const
int m_LineThickness[LAYER_CLASS_COUNT]
Abstract interface for BOARD_ITEMs capable of storing other items inside.
A base class for any item which can be embedded within the BOARD container class, and therefore insta...
virtual PCB_LAYER_ID GetLayer() const
Return the primary layer this item is on.
virtual STROKE_PARAMS GetStroke() const
virtual void SetLayer(PCB_LAYER_ID aLayer)
Set the layer this item is on.
BOARD_ITEM_CONTAINER * GetParentFootprint() const
FOOTPRINT * GetFirstFootprint() const
Get the first footprint on the board or nullptr.
BOARD_DESIGN_SETTINGS & GetDesignSettings() const
int GetCount() const
Return the number of objects in the list.
COMMIT & Remove(EDA_ITEM *aItem)
Notify observers that aItem has been removed.
COMMIT & Add(EDA_ITEM *aItem)
Notify observers that aItem has been added.
wxRadioButton * m_rbEnvelope
CONVERT_SETTINGS * m_settings
bool TransferDataToWindow() override
CONVERT_SETTINGS_DIALOG(EDA_DRAW_FRAME *aParent, CONVERT_SETTINGS *aSettings)
wxStaticText * m_gapLabel
wxRadioButton * m_rbMimicLineWidth
wxRadioButton * m_rbCenterline
void onRadioButton(wxCommandEvent &aEvent)
wxStaticText * m_gapUnits
bool TransferDataFromWindow() override
wxCheckBox * m_cbDeleteOriginals
wxStaticText * m_widthLabel
~CONVERT_SETTINGS_DIALOG()
wxStaticText * m_widthUnits
Dialog helper object to sit in the inheritance tree between wxDialog and any class written by wxFormB...
void SetupStandardButtons(std::map< int, wxString > aLabels={})
void finishDialogSettings()
In all dialogs, we must call the same functions to fix minimal dlg size, the default position and per...
bool IsType(FRAME_T aType) const
The base class for create windows for drawing purpose.
A base class for most all the KiCad significant classes used in schematics and boards.
virtual VECTOR2I GetPosition() const
void SetFlags(EDA_ITEM_FLAGS aMask)
KICAD_T Type() const
Returns the type of object.
virtual bool IsType(const std::vector< KICAD_T > &aScanTypes) const
Check whether the item is one of the listed types.
EDA_ITEM_FLAGS GetFlags() const
void SetCenter(const VECTOR2I &aCenter)
FILL_T GetFillMode() const
SHAPE_POLY_SET & GetPolyShape()
void SetFilled(bool aFlag)
void SetPolyShape(const SHAPE_POLY_SET &aShape)
const VECTOR2I & GetEnd() const
Return the ending point of the graphic.
void SetStart(const VECTOR2I &aStart)
const VECTOR2I & GetStart() const
Return the starting point of the graphic.
void SetShape(SHAPE_T aShape)
const std::vector< VECTOR2I > & GetBezierPoints() const
void SetEnd(const VECTOR2I &aEnd)
void SetFillMode(FILL_T aFill)
VECTOR2I GetArcMid() const
void SetEnd0(const VECTOR2I &aPoint)
void SetStart0(const VECTOR2I &aPoint)
A specialization of ZONE for use in footprints.
Used when the right click button is pressed, or when the select tool is in effect.
static LSET AllNonCuMask()
Return a mask holding all layer minus CU layers.
static TOOL_ACTION convertToKeepout
static TOOL_ACTION convertToTracks
static TOOL_ACTION convertToLines
static TOOL_ACTION convertToZone
static TOOL_ACTION convertToPoly
static TOOL_ACTION convertToArc
static TOOL_ACTION createArray
Tool for creating an array of objects.
void SetMid(const VECTOR2I &aMid)
std::shared_ptr< SHAPE > GetEffectiveShape(PCB_LAYER_ID aLayer=UNDEFINED_LAYER, FLASHING aFlash=FLASHING::DEFAULT) const override
Some pad shapes can be complex (rounded/chamfered rectangle), even without considering custom shapes.
Common, abstract interface for edit frames.
PCB_LAYER_ID SelectOneLayer(PCB_LAYER_ID aDefaultLayer, LSET aNotAllowedLayersMask=LSET(), wxPoint aDlgPosition=wxDefaultPosition)
Show the dialog box for a layer selection.
virtual PCB_LAYER_ID GetActiveLayer() const
const ZONE_SETTINGS & GetZoneSettings() const
virtual BOARD_ITEM_CONTAINER * GetModel() const =0
static SELECTION_CONDITION SameLayer()
Creates a functor that tests if selection contains items that belong exclusively to the same layer.
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Convert the shape to a closed polygon.
STROKE_PARAMS GetStroke() const override
void SetStroke(const STROKE_PARAMS &aStroke) override
void SetWidth(int aWidth)
void SetEnd(const VECTOR2I &aEnd)
void SetStart(const VECTOR2I &aStart)
void TransformShapeToPolygon(SHAPE_POLY_SET &aBuffer, PCB_LAYER_ID aLayer, int aClearance, int aError, ERROR_LOC aErrorLoc, bool ignoreLineWidth=false) const override
Function TransformShapeToPolygon Convert the track shape to a closed polygon Used in filling zones ca...
const VECTOR2I & GetStart() const
const VECTOR2I & GetEnd() const
static SEG::ecoord Square(int a)
Class that groups generic conditions for selected items.
static SELECTION_CONDITION MoreThan(int aNumber)
Create a functor that tests if the number of selected items is greater than the value given as parame...
static SELECTION_CONDITION Count(int aNumber)
Create a functor that tests if the number of selected items is equal to the value given as parameter.
static SELECTION_CONDITION OnlyTypes(std::vector< KICAD_T > aTypes)
Create a functor that tests if the selected items are only of given types.
bool Empty() const
Checks if there is anything selected.
SHAPE_ARC Reversed() const
const VECTOR2I & GetP0() const
Represent a polyline containing arcs as well as line segments: A chain of connected line and/or arc s...
virtual const VECTOR2I GetPoint(int aIndex) const override
void SetClosed(bool aClosed)
Mark the line chain as closed (i.e.
int PointCount() const
Return the number of points (vertices) in this line chain.
void Append(int aX, int aY, bool aAllowDuplication=false)
Append a new point at the end of the line chain.
void Insert(size_t aVertex, const VECTOR2I &aP)
Represent a set of closed polygons.
void ClearArcs()
Appends a vertex at the end of the given outline/hole (default: the last outline)
int AddOutline(const SHAPE_LINE_CHAIN &aOutline)
Adds a new hole to the given outline (default: last) and returns its index.
int HoleCount(int aOutline) const
Return the reference to aIndex-th outline in the set.
int Append(int x, int y, int aOutline=-1, int aHole=-1, bool aAllowDuplication=false)
Add a new vertex to the contour indexed by aOutline and aHole (defaults to the outline of the last po...
void Simplify(POLYGON_MODE aFastMode)
SHAPE_LINE_CHAIN & Hole(int aOutline, int aHole)
Return the aIndex-th subpolygon in the set.
int OutlineCount() const
Return the number of vertices in a given outline/hole.
const SHAPE_LINE_CHAIN & COutline(int aIndex) const
Simple container to manage line stroke parameters.
virtual long long int GetValue()
Return the current value in Internal Units.
void Enable(bool aEnable)
Enable/disable the label, widget and units label.
virtual void SetValue(long long int aValue)
Set new value (in Internal Units) for the text field, taking care of units conversion.
ZONE_SETTINGS handles zones parameters.
void SetIsRuleArea(bool aEnable)
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.
void HatchBorder()
Compute the hatch lines depending on the hatch parameters and stores it in the zone's attribute m_bor...
SHAPE_POLY_SET * Outline()
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 SKIP_STRUCT
flag indicating that the structure should be ignored
bool IsNonCopperLayer(int aLayerId)
Test whether a layer is a non copper layer.
bool IsCopperLayer(int aLayerId)
Tests whether a layer is a copper layer.
PCB_LAYER_ID
A quick note on layer IDs:
This file contains miscellaneous commonly used macros and functions.
void process(const BOARD_CONNECTED_ITEM *item, int net)
CONVERT_STRATEGY m_Strategy
const VECTOR2I CalcArcCenter(const VECTOR2I &aStart, const VECTOR2I &aMid, const VECTOR2I &aEnd)
Determine the center of an arc or circle given three points on its circumference.
@ PCB_SHAPE_T
class PCB_SHAPE, a segment not on copper layers
@ PCB_FP_SHAPE_T
class FP_SHAPE, a footprint edge
@ PCB_VIA_T
class PCB_VIA, a via (like a track segment on a copper layer)
@ PCB_ZONE_T
class ZONE, a copper pour area
@ PCB_SHAPE_LOCATE_CIRCLE_T
@ PCB_SHAPE_LOCATE_SEGMENT_T
@ PCB_SHAPE_LOCATE_RECT_T
@ PCB_SHAPE_LOCATE_BEZIER_T
@ PCB_FP_ZONE_T
class ZONE, managed by a footprint
@ PCB_SHAPE_LOCATE_POLY_T
@ PCB_ARC_T
class PCB_ARC, an arc track segment on a copper layer
@ PCB_TRACE_T
class PCB_TRACK, a track segment (segment on a copper layer)
constexpr ret_type KiROUND(fp_type v)
Round a floating point number to an integer using "round halfway cases away from zero".