From bee0d118f0798c4939a5a013ba8fa0906d5849ef Mon Sep 17 00:00:00 2001 From: charras Date: Sun, 3 Jan 2010 16:47:46 +0000 Subject: [PATCH] fixed a potential bug in fill zone. Tried to fix a problem under Vista and Window 7 in fill zone: sometimes Pcbnew crashes. Could be a bug in Kbool (see changelog). --- CHANGELOG.txt | 21 ++++++++++++++++++ include/kicad_device_context.h | 2 +- .../zones_convert_brd_items_to_polygons.cpp | 22 +++++++++---------- polygon/math_for_graphics.cpp | 16 ++++++++++++++ 4 files changed, 49 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 24c312f77d..ece0f344fb 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -3,6 +3,27 @@ KiCad ChangeLog 2009 Please add newer entries at the top, list the date and your name with email address. +2010-Jan-03 UPDATE Jean-Pierre Charras +================================================================================ +++pcbnew + - fixed a potential bug in a fill zone function: AddClearanceAreasPolygonsToPolysList() + - Try to fix a problem with AddClearanceAreasPolygonsToPolysList() in Window Vista a Window 7 + This is perhaps a problem in kbool library + (a bug in Bool_Engine destructor ? + Its happens when: + - a lot of polygon corners are added in group A + - nothing in group B + - No operation asked in kbool engine ( that also has a bug if an operation is asked + with no polygon in group B) + - and call the Bool_Engine destructor. + Could be a stack error or overflow, very hard to locate and debug. + - Under Vista seems create always a crash. + - Under Window 7 sometimes create a crash. + - No problem under XP and Linux. + -Workaround: + Leave the group A void if group B is void. + I am not sure this fix the problem. + Just its solves this problem with 2 samples boards that crash Pcbnew without this change. 2010-Jan-01 UPDATE Jean-Pierre Charras ================================================================================ diff --git a/include/kicad_device_context.h b/include/kicad_device_context.h index cf306b40d0..d1610e8ee2 100644 --- a/include/kicad_device_context.h +++ b/include/kicad_device_context.h @@ -8,7 +8,7 @@ // Comment this line to use the standard wxClientDC // and uncomment to use buffered DC -// #define KICAD_USE_BUFFERED_DC // Currently for tests +// #define KICAD_USE_BUFFERED_DC // Currently under test #ifdef KICAD_USE_BUFFERED_DC #include diff --git a/pcbnew/zones_convert_brd_items_to_polygons.cpp b/pcbnew/zones_convert_brd_items_to_polygons.cpp index 5fff03eb23..5644b41cb7 100644 --- a/pcbnew/zones_convert_brd_items_to_polygons.cpp +++ b/pcbnew/zones_convert_brd_items_to_polygons.cpp @@ -177,11 +177,6 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) booleng = new Bool_Engine(); ArmBoolEng( booleng, true ); - /* Add the main corrected polygon (i.e. the filled area using only one outline) - * in GroupA in Bool_Engine - */ - CopyPolygonsFromFilledPolysListToBoolengine( booleng, GROUP_A ); - /* Calculates the clearance value that meet DRC requirements * from m_ZoneClearance and clearance from the corresponding netclass * We have a "local" clearance in zones because most of time @@ -218,6 +213,7 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) */ int item_clearance; have_poly_to_substract = false; + for( MODULE* module = aPcb->m_Modules; module; module = module->Next() ) { for( D_PAD* pad = module->m_Pads; pad != NULL; pad = pad->Next() ) @@ -254,8 +250,6 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) } } - have_poly_to_substract = false; - /* Add holes (i.e. tracks and pads areas as polygons outlines) * in GroupB in Bool_Engine * Next : Add tracks and vias @@ -371,6 +365,11 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) if( have_poly_to_substract ) { + /* Add the main corrected polygon (i.e. the filled area using only one outline) + * in GroupA in Bool_Engine + */ + CopyPolygonsFromFilledPolysListToBoolengine( booleng, GROUP_A ); + booleng->Do_Operation( BOOL_A_SUB_B ); /* put these areas in m_FilledPolysList */ @@ -461,10 +460,6 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) booleng = new Bool_Engine(); ArmBoolEng( booleng, true ); -/* Add the main corrected polygon (i.e. the filled area using only one outline) - * in GroupA in Bool_Engine - */ - CopyPolygonsFromFilledPolysListToBoolengine( booleng, GROUP_A ); /* * Test and add polygons to remove thermal stubs. @@ -586,6 +581,11 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) /* compute copper areas */ if( have_poly_to_substract ) { + /* Add the main corrected polygon (i.e. the filled area using only one outline) + * in GroupA in Bool_Engine + */ + CopyPolygonsFromFilledPolysListToBoolengine( booleng, GROUP_A ); + booleng->Do_Operation( BOOL_A_SUB_B ); /* put these areas in m_FilledPolysList */ diff --git a/polygon/math_for_graphics.cpp b/polygon/math_for_graphics.cpp index 7e047c7f68..25398948d2 100644 --- a/polygon/math_for_graphics.cpp +++ b/polygon/math_for_graphics.cpp @@ -813,9 +813,13 @@ int GetClearanceBetweenSegments( int x1i, int y1i, int x1f, int y1f, int style1, const int NSTEPS = 32; if( el1.theta2 > el1.theta1 ) + { wxASSERT(0); + } if( bArcs && el2.theta2 > el2.theta1 ) + { wxASSERT(0); + } // test multiple points in both segments double th1; @@ -1012,7 +1016,9 @@ double Distance( int x1, int y1, int x2, int y2 ) double d; d = sqrt( (double)(x1-x2)*(x1-x2) + (double)(y1-y2)*(y1-y2) ); if( d > INT_MAX || d < INT_MIN ) + { wxASSERT(0); + } return (int)d; } @@ -1023,9 +1029,13 @@ int GetArcIntersections( EllipseKH * el1, EllipseKH * el2, double * x1, double * y1, double * x2, double * y2 ) { if( el1->theta2 > el1->theta1 ) + { wxASSERT(0); + } if( el2->theta2 > el2->theta1 ) + { wxASSERT(0); + } const int NSTEPS = 32; double xret[2], yret[2]; @@ -1079,7 +1089,9 @@ int GetArcIntersections( EllipseKH * el1, EllipseKH * el2, yret[n] = y*el1->yrad + el1->Center.Y; n++; if( n > 2 ) + { wxASSERT(0); + } } } } @@ -1106,9 +1118,13 @@ double GetArcClearance( EllipseKH * el1, EllipseKH * el2, const int NSTEPS = 32; if( el1->theta2 > el1->theta1 ) + { wxASSERT(0); + } if( el2->theta2 > el2->theta1 ) + { wxASSERT(0); + } // test multiple positions in both arcs, moving clockwise (ie. decreasing theta) double th_start = el1->theta1;