Jon Evans 11 months ago
parent
commit
69fe1368f1
  1. 2
      pcbnew/dialogs/dialog_multichannel_repeat_layout.cpp
  2. 159
      pcbnew/dialogs/dialog_multichannel_repeat_layout.fbp
  3. 9
      pcbnew/dialogs/dialog_multichannel_repeat_layout_base.cpp
  4. 4
      pcbnew/dialogs/dialog_multichannel_repeat_layout_base.h
  5. 136
      pcbnew/tools/multichannel_tool.cpp
  6. 2
      pcbnew/tools/multichannel_tool.h

2
pcbnew/dialogs/dialog_multichannel_repeat_layout.cpp

@ -88,6 +88,7 @@ DIALOG_MULTICHANNEL_REPEAT_LAYOUT::DIALOG_MULTICHANNEL_REPEAT_LAYOUT (
m_cbCopyPlacement->SetValue( data->m_options.m_copyPlacement );
m_cbCopyRouting->SetValue( data->m_options.m_copyRouting );
m_cbGroupItems->SetValue( data->m_options.m_groupItems );
m_cbCopyOtherItems->SetValue( data->m_options.m_copyOtherItems );
m_cbIncludeLockedComponents->SetValue( data->m_options.m_includeLockedItems );
m_cbIncludeOffRAComponents->SetValue( data->m_options.m_moveOffRAComponents );
@ -111,6 +112,7 @@ bool DIALOG_MULTICHANNEL_REPEAT_LAYOUT::TransferDataFromWindow()
data->m_options.m_copyPlacement = m_cbCopyPlacement->GetValue();
data->m_options.m_copyRouting = m_cbCopyRouting->GetValue();
data->m_options.m_copyOtherItems = m_cbCopyOtherItems->GetValue();
data->m_options.m_groupItems = m_cbGroupItems->GetValue();
data->m_options.m_includeLockedItems = m_cbIncludeLockedComponents->GetValue();
data->m_options.m_moveOffRAComponents = m_cbIncludeOffRAComponents->GetValue();

159
pcbnew/dialogs/dialog_multichannel_repeat_layout.fbp

@ -1,34 +1,36 @@
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<wxFormBuilder_Project>
<FileVersion major="1" minor="17"/>
<FileVersion major="1" minor="18"/>
<object class="Project" expanded="true">
<property name="class_decoration"></property>
<property name="code_generation">C++</property>
<property name="disconnect_events">1</property>
<property name="disconnect_mode">source_name</property>
<property name="disconnect_php_events">0</property>
<property name="disconnect_python_events">0</property>
<property name="cpp_class_decoration"></property>
<property name="cpp_disconnect_events">1</property>
<property name="cpp_event_generation">connect</property>
<property name="cpp_help_provider">none</property>
<property name="cpp_namespace"></property>
<property name="cpp_precompiled_header"></property>
<property name="cpp_use_array_enum">0</property>
<property name="cpp_use_enum">0</property>
<property name="embedded_files_path">res</property>
<property name="encoding">UTF-8</property>
<property name="event_generation">connect</property>
<property name="file">dialog_multichannel_repeat_layout_base</property>
<property name="first_id">1000</property>
<property name="help_provider">none</property>
<property name="image_path_wrapper_function_name"></property>
<property name="indent_with_spaces"></property>
<property name="internationalize">1</property>
<property name="lua_skip_events">1</property>
<property name="lua_ui_table">UI</property>
<property name="name">dialog_multichannel_repeat_layout</property>
<property name="namespace"></property>
<property name="path">.</property>
<property name="precompiled_header"></property>
<property name="php_disconnect_events">0</property>
<property name="php_disconnect_mode">source_name</property>
<property name="php_skip_events">1</property>
<property name="python_disconnect_events">0</property>
<property name="python_disconnect_mode">source_name</property>
<property name="python_image_path_wrapper_function_name"></property>
<property name="python_indent_with_spaces"></property>
<property name="python_skip_events">1</property>
<property name="relative_path">1</property>
<property name="skip_lua_events">1</property>
<property name="skip_php_events">1</property>
<property name="skip_python_events">1</property>
<property name="ui_table">UI</property>
<property name="use_array_enum">0</property>
<property name="use_enum">0</property>
<property name="use_microsoft_bom">0</property>
<property name="use_native_eol">0</property>
<object class="Dialog" expanded="true">
<property name="aui_managed">0</property>
<property name="aui_manager_style">wxAUI_MGR_DEFAULT</property>
@ -89,10 +91,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
@ -151,10 +153,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="autosize_cols">1</property>
<property name="autosize_rows">1</property>
<property name="best_size"></property>
@ -249,10 +251,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
@ -311,10 +313,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
@ -384,10 +386,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
@ -409,7 +411,7 @@
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Copy placement</property>
<property name="label">Copy footprint placement</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
@ -449,10 +451,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
@ -505,6 +507,71 @@
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="true">
<property name="border">5</property>
<property name="flag">wxALL</property>
<property name="proportion">0</property>
<object class="wxCheckBox" expanded="true">
<property name="BottomDockable">1</property>
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
<property name="caption_visible">1</property>
<property name="center_pane">0</property>
<property name="checked">0</property>
<property name="close_button">1</property>
<property name="context_help"></property>
<property name="context_menu">1</property>
<property name="default_pane">0</property>
<property name="dock">Dock</property>
<property name="dock_fixed">0</property>
<property name="docking">Left</property>
<property name="drag_accept_files">0</property>
<property name="enabled">1</property>
<property name="fg"></property>
<property name="floatable">1</property>
<property name="font"></property>
<property name="gripper">0</property>
<property name="hidden">0</property>
<property name="id">wxID_ANY</property>
<property name="label">Copy other items</property>
<property name="max_size"></property>
<property name="maximize_button">0</property>
<property name="maximum_size"></property>
<property name="min_size"></property>
<property name="minimize_button">0</property>
<property name="minimum_size"></property>
<property name="moveable">1</property>
<property name="name">m_cbCopyOtherItems</property>
<property name="pane_border">1</property>
<property name="pane_position"></property>
<property name="pane_size"></property>
<property name="permission">protected</property>
<property name="pin_button">1</property>
<property name="pos"></property>
<property name="resize">Resizable</property>
<property name="show">1</property>
<property name="size"></property>
<property name="style"></property>
<property name="subclass">; ; forward_declare</property>
<property name="toolbar_pane">0</property>
<property name="tooltip">Copy text, shapes, zones, and other items inside the source rule area</property>
<property name="validator_data_type"></property>
<property name="validator_style">wxFILTER_NONE</property>
<property name="validator_type">wxDefaultValidator</property>
<property name="validator_variable"></property>
<property name="window_extra_style"></property>
<property name="window_name"></property>
<property name="window_style"></property>
</object>
</object>
<object class="sizeritem" expanded="false">
<property name="border">5</property>
<property name="flag">wxALL</property>
@ -514,10 +581,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
@ -579,10 +646,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>
@ -644,10 +711,10 @@
<property name="LeftDockable">1</property>
<property name="RightDockable">1</property>
<property name="TopDockable">1</property>
<property name="aui_layer"></property>
<property name="aui_layer">0</property>
<property name="aui_name"></property>
<property name="aui_position"></property>
<property name="aui_row"></property>
<property name="aui_position">0</property>
<property name="aui_row">0</property>
<property name="best_size"></property>
<property name="bg"></property>
<property name="caption"></property>

9
pcbnew/dialogs/dialog_multichannel_repeat_layout_base.cpp

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -74,12 +74,17 @@ DIALOG_MULTICHANNEL_REPEAT_LAYOUT_BASE::DIALOG_MULTICHANNEL_REPEAT_LAYOUT_BASE(
wxBoxSizer* bSizer13;
bSizer13 = new wxBoxSizer( wxVERTICAL );
m_cbCopyPlacement = new wxCheckBox( this, wxID_ANY, _("Copy placement"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbCopyPlacement = new wxCheckBox( this, wxID_ANY, _("Copy footprint placement"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer13->Add( m_cbCopyPlacement, 0, wxALL, 5 );
m_cbCopyRouting = new wxCheckBox( this, wxID_ANY, _("Copy routing"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer13->Add( m_cbCopyRouting, 0, wxALL, 5 );
m_cbCopyOtherItems = new wxCheckBox( this, wxID_ANY, _("Copy other items"), wxDefaultPosition, wxDefaultSize, 0 );
m_cbCopyOtherItems->SetToolTip( _("Copy text, shapes, zones, and other items inside the source rule area") );
bSizer13->Add( m_cbCopyOtherItems, 0, wxALL, 5 );
m_cbGroupItems = new wxCheckBox( this, wxID_ANY, _("Group components with their placement rule areas"), wxDefaultPosition, wxDefaultSize, 0 );
bSizer13->Add( m_cbGroupItems, 0, wxALL, 5 );

4
pcbnew/dialogs/dialog_multichannel_repeat_layout_base.h

@ -1,5 +1,5 @@
///////////////////////////////////////////////////////////////////////////
// C++ code generated with wxFormBuilder (version 4.0.0-0-g0efcecf)
// C++ code generated with wxFormBuilder (version 4.2.1-0-g80c4cb6)
// http://www.wxformbuilder.org/
//
// PLEASE DO *NOT* EDIT THIS FILE!
@ -25,7 +25,6 @@
///////////////////////////////////////////////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
/// Class DIALOG_MULTICHANNEL_REPEAT_LAYOUT_BASE
///////////////////////////////////////////////////////////////////////////////
@ -41,6 +40,7 @@ class DIALOG_MULTICHANNEL_REPEAT_LAYOUT_BASE : public DIALOG_SHIM
wxStaticText* m_refRAName;
wxCheckBox* m_cbCopyPlacement;
wxCheckBox* m_cbCopyRouting;
wxCheckBox* m_cbCopyOtherItems;
wxCheckBox* m_cbGroupItems;
wxCheckBox* m_cbIncludeLockedComponents;
wxCheckBox* m_cbIncludeOffRAComponents;

136
pcbnew/tools/multichannel_tool.cpp

@ -129,6 +129,91 @@ bool MULTICHANNEL_TOOL::identifyComponentsInRuleArea( ZONE* aRul
}
bool MULTICHANNEL_TOOL::findOtherItemsInRuleArea( ZONE* aRuleArea, std::set<BOARD_ITEM*>& aItems )
{
std::vector<BOARD_ITEM*> result;
PCBEXPR_COMPILER compiler( new PCBEXPR_UNIT_RESOLVER );
PCBEXPR_UCODE ucode;
PCBEXPR_CONTEXT ctx, preflightCtx;
auto reportError = [&]( const wxString& aMessage, int aOffset )
{
wxLogTrace( traceMultichannelTool, wxT( "ERROR: %s"), aMessage );
};
ctx.SetErrorCallback( reportError );
preflightCtx.SetErrorCallback( reportError );
compiler.SetErrorCallback( reportError );
bool restoreBlankName = false;
if( aRuleArea->GetZoneName().IsEmpty() )
{
restoreBlankName = true;
aRuleArea->SetZoneName( aRuleArea->m_Uuid.AsString() );
}
wxString ruleText = wxString::Format( wxT( "A.enclosedByArea('%s')" ), aRuleArea->GetZoneName() );
if( !compiler.Compile( ruleText, &ucode, &preflightCtx ) )
{
if( restoreBlankName )
aRuleArea->SetZoneName( wxEmptyString );
return false;
}
auto testAndAdd =
[&]( BOARD_ITEM* aItem )
{
ctx.SetItems( aItem, aItem );
auto val = ucode.Run( &ctx );
if( val->AsDouble() != 0.0 )
aItems.insert( aItem );
};
for( ZONE* zone : board()->Zones() )
{
if( zone == aRuleArea )
continue;
testAndAdd( zone );
}
for( BOARD_ITEM* drawing : board()->Drawings() )
testAndAdd( drawing );
for( PCB_GROUP* group : board()->Groups() )
{
// A group is cloned in its entirety if *all* children are contained
bool addGroup = true;
group->RunOnDescendants(
[&]( BOARD_ITEM* aItem )
{
if( aItem->IsType( { PCB_ZONE_T, PCB_SHAPE_T, PCB_DIMENSION_T } ) )
{
ctx.SetItems( aItem, aItem );
auto val = ucode.Run( &ctx );
if( val->AsDouble() == 0.0 )
addGroup = false;
}
} );
if( addGroup )
aItems.insert( group );
}
if( restoreBlankName )
aRuleArea->SetZoneName( wxEmptyString );
return true;
}
std::set<FOOTPRINT*> MULTICHANNEL_TOOL::queryComponentsInSheet( wxString aSheetName ) const
{
std::set<FOOTPRINT*> rv;
@ -583,17 +668,68 @@ bool MULTICHANNEL_TOOL::copyRuleAreaContents( TMATCH::COMPONENT_MATCHES& aMatche
{
if( !aRefArea->m_area->GetLayerSet().Contains( item->GetLayer() ) )
continue;
if( !aTargetArea->m_area->GetLayerSet().Contains( item->GetLayer() ) )
continue;
BOARD_ITEM* copied = static_cast<BOARD_ITEM*>( item->Clone() );
copied->Move( disp );
copied->SetParentGroup( nullptr );
aGroupableItems.insert( copied );
aCommit->Add( copied );
}
}
if( aOpts.m_copyOtherItems )
{
std::set<BOARD_ITEM*> sourceItems;
findOtherItemsInRuleArea( aRefArea->m_area, sourceItems );
for( BOARD_ITEM* item : sourceItems )
{
if( !aRefArea->m_area->GetLayerSet().Contains( item->GetLayer() ) )
continue;
if( !aTargetArea->m_area->GetLayerSet().Contains( item->GetLayer() ) )
continue;
// Groups that are fully-contained within the area are added themselves; copy their
// items as part of DeepClone rather than explicitly
if( item->GetParentGroup() && sourceItems.contains( item->GetParentGroup() ) )
continue;
BOARD_ITEM* copied;
if( item->Type() == PCB_GROUP_T )
{
copied = static_cast<PCB_GROUP*>( item )->DeepClone();
}
else
{
copied = static_cast<BOARD_ITEM*>( item->Clone() );
}
copied->ClearFlags();
copied->SetParentGroup( nullptr );
copied->Move( disp );
aGroupableItems.insert( copied );
aCommit->Add( copied );
getView()->Query( copied->GetBoundingBox(),
[&]( KIGFX::VIEW_ITEM* viewItem ) -> bool
{
BOARD_ITEM* existingItem = static_cast<BOARD_ITEM*>( viewItem );
if( existingItem && existingItem->Similarity( *copied ) == 1.0 )
aCommit->Remove( existingItem );
return true;
} );
}
}
aTargetArea->m_area->RemoveAllContours();
aTargetArea->m_area->AddPolygon( newTargetOutline );
aTargetArea->m_area->UnHatchBorder();

2
pcbnew/tools/multichannel_tool.h

@ -48,6 +48,7 @@ struct REPEAT_LAYOUT_OPTIONS
{
bool m_copyRouting = true;
bool m_copyPlacement = true;
bool m_copyOtherItems = true;
bool m_groupItems = false;
bool m_moveOffRAComponents = true;
bool m_includeLockedItems = true;
@ -123,6 +124,7 @@ private:
wxString stripComponentIndex( const wxString& aRef ) const;
bool identifyComponentsInRuleArea( ZONE* aRuleArea, std::set<FOOTPRINT*>& aComponents );
bool findOtherItemsInRuleArea( ZONE* aRuleArea, std::set<BOARD_ITEM*>& aItems );
const SHAPE_LINE_CHAIN buildRAOutline( std::set<FOOTPRINT*>& aFootprints, int aMargin );
std::set<FOOTPRINT*> queryComponentsInSheet( wxString aSheetName ) const;
std::set<FOOTPRINT*>

Loading…
Cancel
Save