pcbnew: first working version of the Repeat Layout feature (MULTICHANNEL_TOOL)
This commit is contained in:
@@ -244,10 +244,18 @@ void MULTICHANNEL_TOOL::findExistingRuleAreas()
|
||||
FP_WITH_CONNECTIONS fpc;
|
||||
fpc.fp = fp;
|
||||
area.m_raFootprints.push_back( fpc );
|
||||
|
||||
for ( auto pad : fp->Pads() )
|
||||
{
|
||||
area.m_fpPads[ pad ] = fp;
|
||||
}
|
||||
|
||||
}
|
||||
area.m_ruleName = zone->GetZoneName();
|
||||
area.m_center = zone->Outline()->COutline(0).Centre();
|
||||
|
||||
|
||||
|
||||
m_areas.m_areas.push_back( area );
|
||||
}
|
||||
}
|
||||
@@ -285,8 +293,6 @@ int MULTICHANNEL_TOOL::repeatLayout( const TOOL_EVENT& aEvent )
|
||||
}
|
||||
}
|
||||
|
||||
printf("refRAs: %d\n", refRAs.size() );
|
||||
|
||||
if( refRAs.size() != 1 )
|
||||
{
|
||||
frame()->ShowInfoBarError(
|
||||
@@ -297,36 +303,57 @@ int MULTICHANNEL_TOOL::repeatLayout( const TOOL_EVENT& aEvent )
|
||||
|
||||
findExistingRuleAreas();
|
||||
|
||||
m_areas.m_refRA = nullptr;
|
||||
|
||||
for( auto& ra : m_areas.m_areas )
|
||||
{
|
||||
if( ra.m_area == refRAs.front() )
|
||||
{
|
||||
m_areas.m_refRA = &ra;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if( !m_areas.m_refRA )
|
||||
return -1;
|
||||
|
||||
for( auto& ra : m_areas.m_areas )
|
||||
{
|
||||
if( ra.m_area == m_areas.m_refRA->m_area )
|
||||
continue;
|
||||
|
||||
m_areas.m_compatMap[ &ra ] = RULE_AREA_COMPAT_DATA();
|
||||
|
||||
resolveConnectionTopology( m_areas.m_refRA, &ra, m_areas.m_compatMap[ &ra ] );
|
||||
}
|
||||
|
||||
DIALOG_MULTICHANNEL_REPEAT_LAYOUT dialog( frame(), this );
|
||||
int ret = dialog.ShowModal();
|
||||
|
||||
if( ret != wxID_OK )
|
||||
return 0;
|
||||
|
||||
auto refArea = findRAByName( wxT( "r1" ) );
|
||||
auto targetArea = findRAByName( wxT( "r2" ) );
|
||||
//auto targetArea = findRAByName( wxT( "auto-placement-area-/io_drivers_fp/bank2/io56/" ) );
|
||||
|
||||
|
||||
MULTICHANNEL_TOOL::FP_PAIRS pairs;
|
||||
|
||||
BOARD_COMMIT commit( frame()->GetToolManager(), true ); //<PNS_LOG_VIEWER_FRAME>()->GetToolManager(), true );
|
||||
|
||||
REPEAT_LAYOUT_OPTIONS opts;
|
||||
|
||||
if( ! resolveConnectionTopology( refArea, targetArea, pairs ) )
|
||||
for( auto& targetArea : m_areas.m_compatMap )
|
||||
{
|
||||
m_reporter->Report( wxString::Format( wxT( "Can't fit connection topologies between %s and %s"),
|
||||
refArea->m_area->GetZoneName(),
|
||||
targetArea->m_area->GetZoneName() ) );
|
||||
}
|
||||
if( !targetArea.second.m_isOk )
|
||||
continue;
|
||||
|
||||
if( copyRuleAreaContents( pairs, &commit, refArea, targetArea, opts ) )
|
||||
{
|
||||
printf("Committing\n");
|
||||
commit.Push( wxT("Repeat layout"));
|
||||
if( !copyRuleAreaContents( targetArea.second.m_matchingFootprints, &commit, m_areas.m_refRA, targetArea.first, m_areas.m_options ) )
|
||||
{
|
||||
auto errMsg = wxString::Format( _( "Copy Rule Area contents failed between rule areas '%s' and '%s'."),
|
||||
m_areas.m_refRA->m_area->GetZoneName(),
|
||||
targetArea.first->m_area->GetZoneName() );
|
||||
|
||||
commit.Revert();
|
||||
frame()->ShowInfoBarError( errMsg, true );
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
commit.Push( _("Repeat layout"));
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -350,103 +377,156 @@ wxString MULTICHANNEL_TOOL::stripComponentIndex( wxString aRef ) const
|
||||
return rv;
|
||||
}
|
||||
|
||||
const std::set<BOARD_ITEM*> findRoutedConnections( std::shared_ptr<CONNECTIVITY_DATA> aConnectivity,
|
||||
const SHAPE_POLY_SET& aRAPoly, RULE_AREA* aRA,
|
||||
FOOTPRINT* aFp,
|
||||
const REPEAT_LAYOUT_OPTIONS& aOpts )
|
||||
{
|
||||
std::set<BOARD_ITEM*> rv;
|
||||
|
||||
for( auto pad : aFp->Pads() )
|
||||
{
|
||||
auto connItems = aConnectivity->GetConnectedItems(
|
||||
pad, { PCB_PAD_T, PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T }, true );
|
||||
|
||||
printf( "pad [%p] %s-%s: %d items\n", pad, aFp->GetReference().c_str().AsChar(),
|
||||
pad->GetNumber().c_str().AsChar(), connItems.size() );
|
||||
|
||||
for( auto item : connItems )
|
||||
{
|
||||
// fixme: respect layer sets assigned to each RA
|
||||
|
||||
if( item->Type() == PCB_PAD_T )
|
||||
continue;
|
||||
|
||||
auto effShape = item->GetEffectiveShape( item->GetLayer() );
|
||||
|
||||
if( effShape->Collide( &aRAPoly, 0 ) )
|
||||
{
|
||||
rv.insert( item );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
bool MULTICHANNEL_TOOL::copyRuleAreaContents( FP_PAIRS& aMatches, BOARD_COMMIT* aCommit, RULE_AREA* aRefArea, RULE_AREA* aTargetArea, REPEAT_LAYOUT_OPTIONS aOpts )
|
||||
{
|
||||
// copy shapes
|
||||
|
||||
printf("ref : %p z: %p\n", aRefArea, aRefArea->m_area );
|
||||
printf("tgt : %p z: %p\n", aTargetArea, aTargetArea->m_area );
|
||||
// copy RA shapes first
|
||||
|
||||
SHAPE_LINE_CHAIN refOutline = aRefArea->m_area->Outline()->COutline(0);
|
||||
SHAPE_LINE_CHAIN targetOutline = aTargetArea->m_area->Outline()->COutline(0);
|
||||
|
||||
printf("RefOutlVtx: %d closed %d\n", refOutline.PointCount(), refOutline.IsClosed() ? 1: 0);
|
||||
VECTOR2I disp = aTargetArea->m_center - aRefArea->m_center;
|
||||
|
||||
|
||||
SHAPE_POLY_SET refPoly;
|
||||
refPoly.AddOutline( refOutline );
|
||||
refPoly.CacheTriangulation( false );
|
||||
|
||||
SHAPE_LINE_CHAIN targetOutline( refOutline );
|
||||
|
||||
targetOutline.Move( disp );
|
||||
SHAPE_POLY_SET targetPoly;
|
||||
|
||||
SHAPE_LINE_CHAIN newTargetOutline( refOutline );
|
||||
newTargetOutline.Move( disp );
|
||||
targetPoly.AddOutline( newTargetOutline );
|
||||
targetPoly.CacheTriangulation( false );
|
||||
|
||||
auto connectivity = board()->GetConnectivity();
|
||||
|
||||
if( aOpts.m_copyRouting )
|
||||
{
|
||||
|
||||
for( auto& fpPair : aMatches )
|
||||
{
|
||||
auto refFP = fpPair.first;
|
||||
|
||||
for( auto pad : refFP->Pads() )
|
||||
for( auto& fpPair : aMatches )
|
||||
{
|
||||
auto connItems = connectivity->GetConnectedItems( pad, { PCB_PAD_T, PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T }, true );
|
||||
auto refRouting = findRoutedConnections( connectivity, refPoly, aRefArea, fpPair.first, aOpts );
|
||||
auto targetRouting = findRoutedConnections( connectivity, targetPoly, aTargetArea, fpPair.second, aOpts );
|
||||
|
||||
printf("pad [%p] %s-%s: %d items\n", pad, refFP->GetReference().c_str().AsChar(), pad->GetNumber().c_str().AsChar(), connItems.size() );
|
||||
|
||||
for( auto item : connItems )
|
||||
for( auto item : targetRouting )
|
||||
{
|
||||
if( item->IsLocked() && !aOpts.m_includeLockedItems )
|
||||
continue;
|
||||
|
||||
aCommit->Remove( item );
|
||||
}
|
||||
|
||||
for( auto item : refRouting )
|
||||
{
|
||||
auto copied = static_cast<BOARD_ITEM*>( item->Clone() );
|
||||
copied->Move( disp );
|
||||
aCommit->Add( copied );
|
||||
}
|
||||
|
||||
#if 0
|
||||
for( auto pad : refFP->Pads() )
|
||||
{
|
||||
auto connItems = connectivity->GetConnectedItems( pad, { PCB_PAD_T, PCB_TRACE_T, PCB_ARC_T, PCB_VIA_T }, true );
|
||||
|
||||
printf("pad [%p] %s-%s: %d items\n", pad, refFP->GetReference().c_str().AsChar(), pad->GetNumber().c_str().AsChar(), connItems.size() );
|
||||
|
||||
for( auto item : connItems )
|
||||
{
|
||||
|
||||
|
||||
//if( ! ( item->GetLayerSet(). aRefArea->m_area->GetLayerSet() ) )
|
||||
// continue;
|
||||
|
||||
printf("process conn: type %\n", item->Type() );
|
||||
//if( ! ( item->GetLayerSet(). aRefArea->m_area->GetLayerSet() ) )
|
||||
// continue;
|
||||
|
||||
printf("process conn: type %\n", item->Type() );
|
||||
|
||||
auto effShape = item->GetEffectiveShape( item->GetLayer() );
|
||||
auto bb =effShape->BBox();
|
||||
auto effShape = item->GetEffectiveShape( item->GetLayer() );
|
||||
auto bb =effShape->BBox();
|
||||
|
||||
printf("Effshape: %s bbox %d %d %d %d\n",
|
||||
effShape->TypeName().c_str().AsChar(),
|
||||
bb.GetLeft(), bb.GetTop(),
|
||||
bb.GetRight(), bb.GetBottom()
|
||||
);
|
||||
|
||||
|
||||
//overlay->SetIsFill( true );
|
||||
//overlay->SetFillColor( GREEN );
|
||||
//overlay->Rectangle( bb.GetOrigin(), bb.GetEnd() );
|
||||
|
||||
auto rbb = refPoly.BBox();
|
||||
printf("ref: bbox %d %d %d %d tris %d\n",
|
||||
rbb.GetLeft(), rbb.GetTop(),
|
||||
rbb.GetRight(), rbb.GetBottom()
|
||||
printf("Effshape: %s bbox %d %d %d %d\n",
|
||||
effShape->TypeName().c_str().AsChar(),
|
||||
bb.GetLeft(), bb.GetTop(),
|
||||
bb.GetRight(), bb.GetBottom()
|
||||
);
|
||||
|
||||
//overlay->SetIsFill( true );
|
||||
//overlay->SetFillColor( RED );
|
||||
//overlay->Rectangle( rbb.GetOrigin(), rbb.GetEnd() );
|
||||
|
||||
//overlay->SetIsFill( true );
|
||||
//overlay->SetFillColor( GREEN );
|
||||
//overlay->Rectangle( bb.GetOrigin(), bb.GetEnd() );
|
||||
|
||||
auto rbb = refPoly.BBox();
|
||||
printf("ref: bbox %d %d %d %d tris %d\n",
|
||||
rbb.GetLeft(), rbb.GetTop(),
|
||||
rbb.GetRight(), rbb.GetBottom()
|
||||
);
|
||||
|
||||
//overlay->SetIsFill( true );
|
||||
//overlay->SetFillColor( RED );
|
||||
//overlay->Rectangle( rbb.GetOrigin(), rbb.GetEnd() );
|
||||
|
||||
|
||||
if( rbb.Intersects( bb ) )
|
||||
printf("Possible collision\n");
|
||||
if( rbb.Intersects( bb ) )
|
||||
printf("Possible collision\n");
|
||||
|
||||
if( effShape->Collide( &refPoly, 0 ) )
|
||||
{
|
||||
//printf("Coll : %p\n", item );
|
||||
if( effShape->Collide( &refPoly, 0 ) )
|
||||
{
|
||||
//printf("Coll : %p\n", item );
|
||||
|
||||
auto ni = static_cast<BOARD_ITEM*>( item->Clone() );
|
||||
ni->Move( disp );
|
||||
aCommit->Add( ni );
|
||||
auto ni = static_cast<BOARD_ITEM*>( item->Clone() );
|
||||
ni->Move( disp );
|
||||
aCommit->Add( ni );
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
aCommit->Modify( aTargetArea->m_area );
|
||||
|
||||
aTargetArea->m_area->RemoveAllContours();
|
||||
aTargetArea->m_area->AddPolygon( targetOutline );
|
||||
aTargetArea->m_area->AddPolygon( newTargetOutline );
|
||||
|
||||
if( aOpts.m_copyPlacement )
|
||||
{
|
||||
for( auto& fpPair : aMatches )
|
||||
{
|
||||
auto refFP = fpPair.first;
|
||||
auto targetFP = fpPair.second;
|
||||
|
||||
printf("ref-ls: %s\n", aRefArea->m_area->GetLayerSet().FmtHex().c_str() );
|
||||
printf("target-ls: %s\n", aRefArea->m_area->GetLayerSet().FmtHex().c_str() );
|
||||
// printf("ref-ls: %s\n", aRefArea->m_area->GetLayerSet().FmtHex().c_str() );
|
||||
// printf("target-ls: %s\n", aRefArea->m_area->GetLayerSet().FmtHex().c_str() );
|
||||
|
||||
#if 0
|
||||
if( ! aRefArea->m_area->GetLayerSet().Contains( refFP->GetLayer() ) );
|
||||
@@ -460,6 +540,9 @@ bool MULTICHANNEL_TOOL::copyRuleAreaContents( FP_PAIRS& aMatches, BOARD_COMMIT*
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if( targetFP->IsLocked() && !aOpts.m_includeLockedItems )
|
||||
continue;
|
||||
|
||||
aCommit->Modify( targetFP );
|
||||
|
||||
targetFP->SetOrientation( refFP->GetOrientation() );
|
||||
@@ -471,15 +554,21 @@ bool MULTICHANNEL_TOOL::copyRuleAreaContents( FP_PAIRS& aMatches, BOARD_COMMIT*
|
||||
targetFP->Value().SetTextAngle( refFP->Value().GetTextAngle() );
|
||||
targetFP->Value().SetPosition( refFP->Value().GetPosition() );
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool MULTICHANNEL_TOOL::resolveConnectionTopology( RULE_AREA* aRefArea, RULE_AREA* aTargetArea, MULTICHANNEL_TOOL::FP_PAIRS& aMatches )
|
||||
bool MULTICHANNEL_TOOL::resolveConnectionTopology( RULE_AREA* aRefArea, RULE_AREA* aTargetArea, RULE_AREA_COMPAT_DATA& aMatches )
|
||||
{
|
||||
std::map<NETINFO_ITEM*, std::vector<PAD* > > allPads;
|
||||
|
||||
PROF_TIMER totalMatch("total-match");
|
||||
|
||||
{
|
||||
//PROF_TIMER tmr1("buldPads");
|
||||
|
||||
for( auto fp : board()->Footprints() )
|
||||
for( auto pad : fp->Pads() )
|
||||
{
|
||||
@@ -490,17 +579,16 @@ bool MULTICHANNEL_TOOL::resolveConnectionTopology( RULE_AREA* aRefArea, RULE_ARE
|
||||
else
|
||||
allPads[ pad->GetNet() ].push_back( pad );
|
||||
}
|
||||
//tmr1.Show();
|
||||
}
|
||||
|
||||
auto belongsToRAFootprint = [] ( RULE_AREA* ra, PAD *aPad ) -> FOOTPRINT*
|
||||
{
|
||||
for( auto fp : ra->m_raFootprints )
|
||||
for ( auto pad : fp.fp->Pads() )
|
||||
{
|
||||
if (aPad == pad)
|
||||
return fp.fp;
|
||||
}
|
||||
auto iter = ra->m_fpPads.find( aPad );
|
||||
if ( iter == ra->m_fpPads.end() )
|
||||
return nullptr;
|
||||
|
||||
return nullptr;
|
||||
return iter->second;
|
||||
};
|
||||
|
||||
auto findPadConnectionsWithinRA = [&] ( RULE_AREA* ra, PAD *aPad ) -> std::vector<PAD_PREFIX_ENTRY>
|
||||
@@ -596,13 +684,21 @@ bool MULTICHANNEL_TOOL::resolveConnectionTopology( RULE_AREA* aRefArea, RULE_ARE
|
||||
|
||||
if( aRefArea->m_raFootprints.size() != aTargetArea->m_raFootprints.size() )
|
||||
{
|
||||
m_reporter->Report( wxString::Format( wxT("component count mismatch, ref=%d, target=%d\n"),
|
||||
aMatches.m_isOk = false;
|
||||
aMatches.m_errorMsg = wxString::Format( wxT("Component count mismatch (reference area has %d, target area has %d)"),
|
||||
(int) aRefArea->m_raFootprints.size(),
|
||||
(int) aTargetArea->m_raFootprints.size() ) );
|
||||
(int) aTargetArea->m_raFootprints.size() );
|
||||
|
||||
m_reporter->Report( aMatches.m_errorMsg );
|
||||
}
|
||||
|
||||
{
|
||||
//PROF_TIMER tmr1("buldPadCons");
|
||||
|
||||
buildPadConnectionsWithinRA( aRefArea );
|
||||
buildPadConnectionsWithinRA( aTargetArea );
|
||||
//tmr1.Show();
|
||||
}
|
||||
|
||||
for( auto& refFP : aRefArea->m_raFootprints )
|
||||
{
|
||||
@@ -618,6 +714,8 @@ bool MULTICHANNEL_TOOL::resolveConnectionTopology( RULE_AREA* aRefArea, RULE_ARE
|
||||
|
||||
int targetsRemaining = aTargetArea->m_raFootprints.size();
|
||||
|
||||
{
|
||||
//PROF_TIMER tmr1("matchTopo");
|
||||
for( auto& refFP : aRefArea->m_raFootprints )
|
||||
{
|
||||
//int tid = random() % targetsRemaining;
|
||||
@@ -640,12 +738,12 @@ bool MULTICHANNEL_TOOL::resolveConnectionTopology( RULE_AREA* aRefArea, RULE_ARE
|
||||
|
||||
if( matches )
|
||||
{
|
||||
printf("%s: matches %s\n", refFP.fp->GetReference().c_str().AsChar(), targetFP.fp->GetReference().c_str().AsChar() );
|
||||
// printf("%s: matches %s\n", refFP.fp->GetReference().c_str().AsChar(), targetFP.fp->GetReference().c_str().AsChar() );
|
||||
//refFP.processed = true;
|
||||
//targetFP.processed = true;
|
||||
anyMatchesFound = true;
|
||||
targetFP.processed = true;
|
||||
aMatches.push_back( { refFP.fp, targetFP.fp } );
|
||||
aMatches.m_matchingFootprints.push_back( { refFP.fp, targetFP.fp } );
|
||||
break;
|
||||
}
|
||||
//else
|
||||
@@ -662,13 +760,22 @@ bool MULTICHANNEL_TOOL::resolveConnectionTopology( RULE_AREA* aRefArea, RULE_ARE
|
||||
|
||||
if( !anyMatchesFound )
|
||||
{
|
||||
printf("%s: no match\n", refFP.fp->GetReference().c_str().AsChar() );
|
||||
aMatches.m_errorMsg = wxString::Format( wxT("Topology mismatch (no counterpart found for component %s)"),
|
||||
refFP.fp->GetReference() );
|
||||
|
||||
aMatches.m_isOk = false;
|
||||
printf("%s: no match\n", refFP.fp->GetReference().c_str().AsChar() );
|
||||
return false;
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
||||
//tmr1.Show();
|
||||
}
|
||||
|
||||
printf("match done\n");
|
||||
|
||||
/*for( auto refPad : refFP->Pads() )
|
||||
{
|
||||
@@ -679,6 +786,10 @@ bool MULTICHANNEL_TOOL::resolveConnectionTopology( RULE_AREA* aRefArea, RULE_ARE
|
||||
}*/
|
||||
//}
|
||||
|
||||
aMatches.m_isOk = true;
|
||||
|
||||
totalMatch.Show();
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,6 +34,27 @@
|
||||
#include <pad.h>
|
||||
#include <footprint.h>
|
||||
#include <reporter.h>
|
||||
#include <core/profile.h>
|
||||
|
||||
typedef std::vector<std::pair<FOOTPRINT*, FOOTPRINT*> > FP_PAIRS;
|
||||
|
||||
enum class REPEAT_LAYOUT_EDGE_MODE
|
||||
{
|
||||
INSIDE = 0,
|
||||
TOUCHING,
|
||||
CLIP
|
||||
};
|
||||
|
||||
struct REPEAT_LAYOUT_OPTIONS
|
||||
{
|
||||
bool m_copyRouting = true;
|
||||
bool m_copyPlacement = true;
|
||||
bool m_groupItems = false;
|
||||
bool m_moveOffRAComponents = true;
|
||||
bool m_includeLockedItems = true;
|
||||
bool m_keepOldRouting = false;
|
||||
REPEAT_LAYOUT_EDGE_MODE m_edgeMode;
|
||||
};
|
||||
|
||||
struct PAD_PREFIX_ENTRY
|
||||
{
|
||||
@@ -90,30 +111,32 @@ struct FP_WITH_CONNECTIONS
|
||||
}
|
||||
};
|
||||
|
||||
struct RULE_AREA;
|
||||
|
||||
struct RULE_AREA_COMPAT_DATA
|
||||
{
|
||||
RULE_AREA* m_refArea;
|
||||
bool m_isOk;
|
||||
bool m_doCopy;
|
||||
wxString m_errorMsg;
|
||||
std::vector< std::pair<FOOTPRINT*, FOOTPRINT*> > m_matchingFootprints;
|
||||
};
|
||||
|
||||
struct RULE_AREA
|
||||
{
|
||||
ZONE* m_area;
|
||||
std::vector<FP_WITH_CONNECTIONS> m_raFootprints;
|
||||
std::set<FOOTPRINT*> m_sheetComponents;
|
||||
std::map<PAD*, FOOTPRINT*> m_fpPads;
|
||||
bool m_existsAlready;
|
||||
bool m_generateEnabled;
|
||||
wxString m_sheetPath;
|
||||
wxString m_sheetName;
|
||||
wxString m_ruleName;
|
||||
VECTOR2I m_center;
|
||||
std::unordered_set<BOARD_ITEM*> m_clonableItems;
|
||||
};
|
||||
|
||||
|
||||
struct RULE_AREA_COMPAT_DATA
|
||||
{
|
||||
RULE_AREA* m_refArea;
|
||||
bool m_componentCountError;
|
||||
bool m_topologyError;
|
||||
bool m_componentTypeError;
|
||||
std::vector< std::pair<FOOTPRINT*, FOOTPRINT*> > m_matchingFootprints;
|
||||
};
|
||||
|
||||
struct RA_SHEET
|
||||
{
|
||||
bool m_generateEnabled;
|
||||
@@ -126,28 +149,15 @@ struct RULE_AREAS_DATA
|
||||
{
|
||||
bool m_replaceExisting;
|
||||
bool m_groupItems;
|
||||
RULE_AREA* m_refRA;
|
||||
REPEAT_LAYOUT_OPTIONS m_options;
|
||||
|
||||
std::vector<RULE_AREA> m_areas;
|
||||
std::unordered_map<RULE_AREA*, RULE_AREA_COMPAT_DATA> m_compatMap;
|
||||
|
||||
};
|
||||
|
||||
enum class REPEAT_LAYOUT_EDGE_MODE
|
||||
{
|
||||
INSIDE = 0,
|
||||
TOUCHING,
|
||||
CLIP
|
||||
};
|
||||
|
||||
struct REPEAT_LAYOUT_OPTIONS
|
||||
{
|
||||
bool m_copyRouting = true;
|
||||
bool m_copyPlacement = true;
|
||||
bool m_groupItems = false;
|
||||
bool m_moveOffRAComponents = true;
|
||||
bool m_includeLockedItems = true;
|
||||
REPEAT_LAYOUT_EDGE_MODE m_edgeMode;
|
||||
};
|
||||
|
||||
class MULTICHANNEL_TOOL : public PCB_TOOL_BASE
|
||||
{
|
||||
@@ -158,8 +168,6 @@ class MULTICHANNEL_TOOL : public PCB_TOOL_BASE
|
||||
RULE_AREAS_DATA* GetData() { return &m_areas; }
|
||||
|
||||
private:
|
||||
typedef std::vector<std::pair<FOOTPRINT*, FOOTPRINT*> > FP_PAIRS;
|
||||
|
||||
void setTransitions() override;
|
||||
int autogenerateRuleAreas( const TOOL_EVENT& aEvent );
|
||||
int repeatLayout( const TOOL_EVENT& aEvent );
|
||||
@@ -171,7 +179,7 @@ class MULTICHANNEL_TOOL : public PCB_TOOL_BASE
|
||||
void querySheets();
|
||||
|
||||
RULE_AREA* findRAByName( const wxString& aName );
|
||||
bool resolveConnectionTopology( RULE_AREA* aRefArea, RULE_AREA* aTargetArea, FP_PAIRS& aMatches );
|
||||
bool resolveConnectionTopology( RULE_AREA* aRefArea, RULE_AREA* aTargetArea, RULE_AREA_COMPAT_DATA& aMatches );
|
||||
bool copyRuleAreaContents( FP_PAIRS& aMatches, BOARD_COMMIT* aCommit, RULE_AREA* aRefArea, RULE_AREA* aTargetArea, REPEAT_LAYOUT_OPTIONS aOpts );
|
||||
|
||||
std::unique_ptr<REPORTER> m_reporter;
|
||||
|
||||
Reference in New Issue
Block a user