diff --git a/pcbnew/exporters/export_vrml.cpp b/pcbnew/exporters/export_vrml.cpp index 2aac14c892..6aa8451353 100644 --- a/pcbnew/exporters/export_vrml.cpp +++ b/pcbnew/exporters/export_vrml.cpp @@ -51,7 +51,7 @@ #include #include - +#include #include // minimum width (mm) of a VRML line @@ -315,10 +315,10 @@ static bool GetLayer( MODEL_VRML& aModel, LAYER_NUM layer, VRML_LAYER** vlayer ) } static void create_vrml_shell( IFSG_TRANSFORM& PcbOutput, VRML_COLOR_INDEX colorID, - VRML_LAYER* layer, double top_z, double bottom_z ); + VRML_LAYER* layer, double top_z, double bottom_z ); static void create_vrml_plane( IFSG_TRANSFORM& PcbOutput, VRML_COLOR_INDEX colorID, - VRML_LAYER* layer, double aHeight, bool aTopPlane ); + VRML_LAYER* layer, double aHeight, bool aTopPlane ); static void write_triangle_bag( std::ostream& aOut_file, VRML_COLOR& aColor, VRML_LAYER* aLayer, bool aPlane, bool aTop, @@ -420,8 +420,8 @@ static void write_triangle_bag( std::ostream& aOut_file, VRML_COLOR& aColor, } -static void write_layers( MODEL_VRML& aModel, BOARD* aPcb, - const char* aFileName, OSTREAM* aOutputFile ) +static void write_layers( MODEL_VRML& aModel, BOARD* aPcb, const char* aFileName, + OSTREAM* aOutputFile ) { // VRML_LAYER board; aModel.m_board.Tesselate( &aModel.m_holes ); @@ -452,8 +452,8 @@ static void write_layers( MODEL_VRML& aModel, BOARD* aPcb, if( USE_INLINES ) { write_triangle_bag( *aOutputFile, aModel.GetColor( VRML_COLOR_TRACK ), - &aModel.m_top_copper, true, true, - aModel.GetLayerZ( F_Cu ), 0 ); + &aModel.m_top_copper, true, true, + aModel.GetLayerZ( F_Cu ), 0 ); } else { @@ -923,7 +923,7 @@ static void export_round_padstack( MODEL_VRML& aModel, BOARD* pcb, if( aModel.m_plainPCB ) return; - while( 1 ) + while( true ) { if( layer == B_Cu ) { @@ -1016,9 +1016,8 @@ static void export_vrml_tracks( MODEL_VRML& aModel, BOARD* pcb ) } -static void export_vrml_zones( MODEL_VRML& aModel, BOARD* aPcb ) +static void export_vrml_zones( MODEL_VRML& aModel, BOARD* aPcb, COMMIT* aCommit ) { - for( int ii = 0; ii < aPcb->GetAreaCount(); ii++ ) { ZONE_CONTAINER* zone = aPcb->GetArea( ii ); @@ -1030,11 +1029,9 @@ static void export_vrml_zones( MODEL_VRML& aModel, BOARD* aPcb ) if( !GetLayer( aModel, layer, &vl ) ) continue; - // fixme: this modifies the board where it shouldn't, but I don't have the time - // to clean this up - TW if( !zone->IsFilled() ) { - ZONE_FILLER filler( aPcb ); + ZONE_FILLER filler( aPcb, aCommit ); zone->SetFillMode( ZONE_FILL_MODE::POLYGONS ); // use filled polygons filler.Fill( { zone } ); } @@ -1586,6 +1583,8 @@ bool PCB_EDIT_FRAME::ExportVRML_File( const wxString& aFullFileName, double aMMt { BOARD* pcb = GetBoard(); bool ok = true; + BOARD_COMMIT commit( this ); // We may need to modify the board (for instance to + // fill zones), so make sure we can revert. USE_INLINES = aExport3DFiles; USE_DEFS = true; @@ -1630,7 +1629,7 @@ bool PCB_EDIT_FRAME::ExportVRML_File( const wxString& aFullFileName, double aMMt // Export zone fills if( !aUsePlainPCB ) - export_vrml_zones( model3d, pcb); + export_vrml_zones( model3d, pcb, &commit ); if( USE_INLINES ) { @@ -1699,6 +1698,7 @@ bool PCB_EDIT_FRAME::ExportVRML_File( const wxString& aFullFileName, double aMMt ok = false; } + commit.Revert(); return ok; } diff --git a/pcbnew/tools/edit_tool.cpp b/pcbnew/tools/edit_tool.cpp index a09fed41e8..19f1474eba 100644 --- a/pcbnew/tools/edit_tool.cpp +++ b/pcbnew/tools/edit_tool.cpp @@ -477,9 +477,11 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference ) // If moving a group, record position of all the descendants for undo if( item->Type() == PCB_GROUP_T ) { - static_cast( item )->RunOnDescendants( [&]( BOARD_ITEM* bItem ) { - m_commit->Modify( bItem ); - }); + static_cast( item )->RunOnDescendants( + [&]( BOARD_ITEM* bItem ) + { + m_commit->Modify( bItem ); + }); } } } @@ -634,7 +636,8 @@ int EDIT_TOOL::doMoveSelection( const TOOL_EVENT& aEvent, bool aPickReference ) int EDIT_TOOL::ChangeTrackWidth( const TOOL_EVENT& aEvent ) { const auto& selection = m_selectionTool->RequestSelection( - []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, SELECTION_TOOL* sTool ) { + []( const VECTOR2I& aPt, GENERAL_COLLECTOR& aCollector, SELECTION_TOOL* sTool ) + { EditToolSelectionFilter( aCollector, EXCLUDE_TRANSIENTS, sTool ); } ); @@ -649,7 +652,7 @@ int EDIT_TOOL::ChangeTrackWidth( const TOOL_EVENT& aEvent ) if( via->GetViaType() == VIATYPE::MICROVIA ) { - auto net = via->GetNet(); + NETINFO_ITEM* net = via->GetNet(); new_width = net->GetMicroViaSize(); new_drill = net->GetMicroViaDrillSize(); @@ -663,7 +666,7 @@ int EDIT_TOOL::ChangeTrackWidth( const TOOL_EVENT& aEvent ) via->SetDrill( new_drill ); via->SetWidth( new_width ); } - else if ( auto track = dyn_cast( item ) ) + else if ( TRACK* track = dyn_cast( item ) ) { m_commit->Modify( item ); @@ -770,9 +773,10 @@ int EDIT_TOOL::Rotate( const TOOL_EVENT& aEvent ) // If rotating a group, record position of all the descendants for undo if( item->Type() == PCB_GROUP_T ) { - static_cast( item )->RunOnDescendants( [&]( BOARD_ITEM* bItem ) { - m_commit->Modify( bItem ); - }); + static_cast( item )->RunOnDescendants( [&]( BOARD_ITEM* bItem ) + { + m_commit->Modify( bItem ); + }); } } @@ -883,29 +887,29 @@ int EDIT_TOOL::Mirror( const TOOL_EVENT& aEvent ) { case PCB_MODULE_EDGE_T: { - auto& edge = static_cast( *item ); - edge.Mirror( mirrorPoint, false ); + EDGE_MODULE* edge = static_cast( item ); + edge->Mirror( mirrorPoint, false ); break; } case PCB_MODULE_ZONE_AREA_T: { - auto& zone = static_cast( *item ); - zone.Mirror( mirrorPoint, false ); + MODULE_ZONE_CONTAINER* zone = static_cast( item ); + zone->Mirror( mirrorPoint, false ); break; } case PCB_MODULE_TEXT_T: { - auto& modText = static_cast( *item ); - modText.Mirror( mirrorPoint, false ); + TEXTE_MODULE* modText = static_cast( item ); + modText->Mirror( mirrorPoint, false ); break; } case PCB_PAD_T: { - auto& pad = static_cast( *item ); - mirrorPadX( pad, mirrorPoint ); + D_PAD* pad = static_cast( item ); + mirrorPadX( *pad, mirrorPoint ); break; } @@ -973,9 +977,10 @@ int EDIT_TOOL::Flip( const TOOL_EVENT& aEvent ) if( item->Type() == PCB_GROUP_T ) { - static_cast( item )->RunOnDescendants( [&]( BOARD_ITEM* bItem ) { - m_commit->Modify( bItem ); - }); + static_cast( item )->RunOnDescendants( [&]( BOARD_ITEM* bItem ) + { + m_commit->Modify( bItem ); + }); } static_cast( item )->Flip( modPoint, leftRight ); @@ -1004,12 +1009,6 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) return 0; } - ROUTER_TOOL* routerTool = m_toolMgr->GetTool(); - - // Do not delete items while actively routing. - if( routerTool && routerTool->Router() && routerTool->Router()->RoutingInProgress() ) - return 1; - std::vector lockedItems; Activate(); @@ -1078,8 +1077,8 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) { case PCB_MODULE_TEXT_T: { - auto text = static_cast( item ); - auto parent = static_cast( item->GetParent() ); + TEXTE_MODULE* text = static_cast( item ); + MODULE* parent = static_cast( item->GetParent() ); if( text->GetType() == TEXTE_MODULE::TEXT_is_DIVERS ) { @@ -1092,8 +1091,8 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) case PCB_PAD_T: { - auto pad = static_cast( item ); - auto parent = static_cast( item->GetParent() ); + D_PAD* pad = static_cast( item ); + MODULE* parent = static_cast( item->GetParent() ); m_commit->Modify( parent ); getView()->Remove( pad ); @@ -1103,8 +1102,8 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) case PCB_MODULE_ZONE_AREA_T: { - auto zone = static_cast( item ); - auto parent = static_cast( item->GetParent() ); + MODULE_ZONE_CONTAINER* zone = static_cast( item ); + MODULE* parent = static_cast( item->GetParent() ); m_commit->Modify( parent ); getView()->Remove( zone ); @@ -1119,8 +1118,8 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) // 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( item ); + VECTOR2I curPos = getViewControls()->GetCursorPosition(); + ZONE_CONTAINER* zone = static_cast( item ); int outlineIdx, holeIdx; @@ -1134,9 +1133,14 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) toFill.emplace_back( zone ); // Fill the modified zone - ZONE_FILLER filler( board() ); + ZONE_FILLER filler( board(), m_commit.get() ); filler.InstallNewProgressReporter( frame(), _( "Fill Zone" ), 4 ); - filler.Fill( toFill ); + + if( !filler.Fill( toFill ) ) + { + m_commit->Revert(); + return 1; + } // Update the display zone->HatchBorder(); @@ -1160,9 +1164,10 @@ int EDIT_TOOL::Remove( const TOOL_EVENT& aEvent ) m_commit->Remove( item ); removed.Add( item ); - static_cast( item )->RunOnDescendants( [&]( BOARD_ITEM* bItem ) { - m_commit->Remove( bItem ); - }); + static_cast( item )->RunOnDescendants( [&]( BOARD_ITEM* bItem ) + { + m_commit->Remove( bItem ); + }); } break; @@ -1280,9 +1285,11 @@ int EDIT_TOOL::MoveExact( const TOOL_EVENT& aEvent ) if( item->Type() == PCB_GROUP_T ) { - static_cast( item )->RunOnDescendants( [&]( BOARD_ITEM* bItem ) { - m_commit->Modify( bItem ); - }); + static_cast( item )->RunOnDescendants( + [&]( BOARD_ITEM* bItem ) + { + m_commit->Modify( bItem ); + }); } } @@ -1411,9 +1418,10 @@ int EDIT_TOOL::Duplicate( const TOOL_EVENT& aEvent ) { if( dupe_item->Type() == PCB_GROUP_T ) { - static_cast( dupe_item )->RunOnDescendants( [&]( BOARD_ITEM* bItem ) { - m_commit->Add( bItem ); - }); + static_cast( dupe_item )->RunOnDescendants( [&]( BOARD_ITEM* bItem ) + { + m_commit->Add( bItem ); + }); } // Clear the selection flag here, otherwise the SELECTION_TOOL diff --git a/pcbnew/tools/zone_create_helper.cpp b/pcbnew/tools/zone_create_helper.cpp index e29f8b98bd..ae8fe170cb 100644 --- a/pcbnew/tools/zone_create_helper.cpp +++ b/pcbnew/tools/zone_create_helper.cpp @@ -166,10 +166,15 @@ void ZONE_CREATE_HELPER::performZoneCutout( ZONE_CONTAINER& aZone, ZONE_CONTAINE } commit.Remove( &aZone ); - commit.Push( _( "Add a zone cutout" ) ); - ZONE_FILLER filler( board ); - filler.Fill( newZones ); + ZONE_FILLER filler( board, &commit ); + if( !filler.Fill( newZones ) ) + { + commit.Revert(); + return; + } + + commit.Push( _( "Add a zone cutout" ) ); // Select the new zone and set it as the source for the next cutout toolMgr->RunAction( PCB_ACTIONS::selectItem, true, newZones[0] ); @@ -193,14 +198,19 @@ void ZONE_CREATE_HELPER::commitZone( std::unique_ptr aZone ) BOARD_COMMIT bCommit( &m_tool ); aZone->HatchBorder(); + bCommit.Add( aZone.get() ); if( !m_params.m_keepout ) { - ZONE_FILLER filler( m_tool.getModel() ); - filler.Fill( { aZone.get() } ); + ZONE_FILLER filler( m_tool.getModel(), &bCommit ); + + if( !filler.Fill( { aZone.get() } ) ) + { + bCommit.Revert(); + break; + } } - bCommit.Add( aZone.get() ); bCommit.Push( _( "Add a zone" ) ); m_tool.GetManager()->RunAction( PCB_ACTIONS::selectItem, true, aZone.release() ); break; diff --git a/pcbnew/tools/zone_filler_tool.cpp b/pcbnew/tools/zone_filler_tool.cpp index 69c0833fec..192dbef6c0 100644 --- a/pcbnew/tools/zone_filler_tool.cpp +++ b/pcbnew/tools/zone_filler_tool.cpp @@ -70,9 +70,15 @@ void ZONE_FILLER_TOOL::CheckAllZones( wxWindow* aCaller ) if( filler.Fill( toFill, true ) ) { + commit.Push( _( "Fill Zone(s)" ), false ); getEditFrame()->m_ZoneFillsDirty = false; - canvas()->Refresh(); } + else + { + commit.Revert(); + } + + canvas()->Refresh(); } @@ -96,7 +102,14 @@ void ZONE_FILLER_TOOL::FillAllZones( wxWindow* aCaller ) filler.InstallNewProgressReporter( aCaller, _( "Fill All Zones" ), 4 ); if( filler.Fill( toFill ) ) + { + commit.Push( _( "Fill Zone(s)" ), false ); getEditFrame()->m_ZoneFillsDirty = false; + } + else + { + commit.Revert(); + } canvas()->Refresh(); @@ -128,7 +141,11 @@ int ZONE_FILLER_TOOL::ZoneFill( const TOOL_EVENT& aEvent ) ZONE_FILLER filler( board(), &commit ); filler.InstallNewProgressReporter( frame(), _( "Fill Zone" ), 4 ); - filler.Fill( toFill ); + + if( filler.Fill( toFill ) ) + commit.Push( _( "Fill Zone(s)" ), false ); + else + commit.Revert(); canvas()->Refresh(); return 0; diff --git a/pcbnew/zone_filler.cpp b/pcbnew/zone_filler.cpp index 99eab40082..cbc7b448ba 100644 --- a/pcbnew/zone_filler.cpp +++ b/pcbnew/zone_filler.cpp @@ -141,8 +141,7 @@ bool ZONE_FILLER::Fill( const std::vector& aZones, bool aCheck if( zone->GetIsKeepout() ) continue; - if( m_commit ) - m_commit->Modify( zone ); + m_commit->Modify( zone ); // calculate the hash value for filled areas. it will be used later // to know if the current filled areas are up to date @@ -161,16 +160,6 @@ bool ZONE_FILLER::Fill( const std::vector& aZones, bool aCheck zone->UnFill(); } - auto cleanupAfterCancel = - [&]() - { - if( m_commit ) - m_commit->Revert(); - - for( ZONE_CONTAINER* zone : aZones ) - zone->UnFill(); - }; - std::atomic nextItem( 0 ); size_t parallelThreadCount = std::min( std::thread::hardware_concurrency(), aZones.size() ); @@ -236,10 +225,7 @@ bool ZONE_FILLER::Fill( const std::vector& aZones, bool aCheck if( m_progressReporter ) { if( m_progressReporter->IsCancelled() ) - { - cleanupAfterCancel(); return false; - } m_progressReporter->AdvancePhase(); m_progressReporter->Report( _( "Removing insulated copper islands..." ) ); @@ -251,10 +237,7 @@ bool ZONE_FILLER::Fill( const std::vector& aZones, bool aCheck connectivity->SetProgressReporter( nullptr ); if( m_progressReporter && m_progressReporter->IsCancelled() ) - { - cleanupAfterCancel(); return false; - } // Now remove insulated copper islands and islands outside the board edge bool outOfDate = false; @@ -319,10 +302,7 @@ bool ZONE_FILLER::Fill( const std::vector& aZones, bool aCheck outOfDate = true; if( m_progressReporter && m_progressReporter->IsCancelled() ) - { - cleanupAfterCancel(); return false; - } } } @@ -336,10 +316,7 @@ bool ZONE_FILLER::Fill( const std::vector& aZones, bool aCheck dlg.DoNotShowCheckbox( __FILE__, __LINE__ ); if( dlg.ShowModal() == wxID_CANCEL ) - { - cleanupAfterCancel(); return false; - } } if( m_progressReporter ) @@ -402,10 +379,7 @@ bool ZONE_FILLER::Fill( const std::vector& aZones, bool aCheck if( m_progressReporter ) { if( m_progressReporter->IsCancelled() ) - { - cleanupAfterCancel(); return false; - } m_progressReporter->AdvancePhase(); m_progressReporter->Report( _( "Committing changes..." ) ); @@ -413,19 +387,6 @@ bool ZONE_FILLER::Fill( const std::vector& aZones, bool aCheck } connectivity->SetProgressReporter( nullptr ); - - if( m_commit ) - { - m_commit->Push( _( "Fill Zone(s)" ), false ); - } - else - { - for( auto& i : toFill ) - connectivity->Update( i.first ); - - connectivity->RecalculateRatsnest(); - } - return true; } diff --git a/pcbnew/zone_filler.h b/pcbnew/zone_filler.h index 2427c38924..d26bd6a6ec 100644 --- a/pcbnew/zone_filler.h +++ b/pcbnew/zone_filler.h @@ -39,7 +39,7 @@ class SHAPE_LINE_CHAIN; class ZONE_FILLER { public: - ZONE_FILLER( BOARD* aBoard, COMMIT* aCommit = nullptr ); + ZONE_FILLER( BOARD* aBoard, COMMIT* aCommit ); ~ZONE_FILLER(); void InstallNewProgressReporter( wxWindow* aParent, const wxString& aTitle, int aNumPhases ); diff --git a/pcbnew/zones_by_polygon.cpp b/pcbnew/zones_by_polygon.cpp index f6c86c350a..70dbe619dd 100644 --- a/pcbnew/zones_by_polygon.cpp +++ b/pcbnew/zones_by_polygon.cpp @@ -134,15 +134,21 @@ void PCB_EDIT_FRAME::Edit_Zone_Params( ZONE_CONTAINER* aZone ) zones_to_refill.push_back( zone ); } + commit.Stage( s_PickedList ); + if( zones_to_refill.size() ) { - ZONE_FILLER filler( GetBoard() ); + ZONE_FILLER filler( GetBoard(), &commit ); wxString title = wxString::Format( _( "Refill %d Zones" ), (int) zones_to_refill.size() ); filler.InstallNewProgressReporter( this, title, 4 ); - filler.Fill( zones_to_refill ); + + if( !filler.Fill( zones_to_refill ) ) + { + commit.Revert(); + return; + } } - commit.Stage( s_PickedList ); commit.Push( _( "Modify zone properties" ) ); GetBoard()->GetConnectivity()->RecalculateRatsnest();