diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 962bc85996..9307fcd490 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -4,6 +4,17 @@ KiCad ChangeLog 2010 Please add newer entries at the top, list the date and your name with email address. +2010-oct-15, UPDATE Jean-Pierre Charras +================================================================================ +PolyLine.cpp: + remove unused method CPolyLine::TestPointInsideContour() which was a duplicate of + TestPointInsidePolygon(). + In CPolyLine::TestPointInside(); replace curious algo (which have a problem) + to test a point inside a polygon by TestPointInsidePolygon() +++Pcbnew: + fix a bug in Drc and clearance calculations when using a dummy pad + ( in zones calcualtions and to test holes ot tracks and holes to pads DRC). + 2010-oct-26 UPDATE Wayne Stambaugh ================================================================================ ++EESchema diff --git a/cvpcb/CMakeLists.txt b/cvpcb/CMakeLists.txt index f9adde7d2f..e10ac4e4c4 100644 --- a/cvpcb/CMakeLists.txt +++ b/cvpcb/CMakeLists.txt @@ -4,6 +4,7 @@ add_definitions(-DCVPCB) # Includes ### include_directories(${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/dialogs ${Boost_INCLUDE_DIR} ../3d-viewer ../pcbnew @@ -13,6 +14,13 @@ include_directories(${CMAKE_CURRENT_SOURCE_DIR} ### # Sources ### +set(CVPCB_DIALOGS + dialogs/dialog_cvpcb_config.cpp + dialogs/dialog_cvpcb_config_fbp.cpp + dialogs/dialog_display_options.cpp + dialogs/dialog_display_options_base.cpp + ) + set(CVPCB_SRCS autosel.cpp cfg.cpp @@ -22,10 +30,6 @@ set(CVPCB_SRCS class_footprints_listbox.cpp cvframe.cpp cvpcb.cpp - dialog_cvpcb_config.cpp - dialog_cvpcb_config_fbp.cpp - dialog_display_options.cpp - dialog_display_options_base.cpp dummy_functions.cpp genequiv.cpp init.cpp @@ -69,6 +73,7 @@ endif(APPLE) ### add_executable(cvpcb WIN32 MACOSX_BUNDLE ${CVPCB_SRCS} + ${CVPCB_DIALOGS} ${CVPCB_RESOURCES}) ### diff --git a/cvpcb/dialog_cvpcb_config.cpp b/cvpcb/dialogs/dialog_cvpcb_config.cpp similarity index 100% rename from cvpcb/dialog_cvpcb_config.cpp rename to cvpcb/dialogs/dialog_cvpcb_config.cpp diff --git a/cvpcb/dialog_cvpcb_config.h b/cvpcb/dialogs/dialog_cvpcb_config.h similarity index 100% rename from cvpcb/dialog_cvpcb_config.h rename to cvpcb/dialogs/dialog_cvpcb_config.h diff --git a/cvpcb/dialog_cvpcb_config_fbp.cpp b/cvpcb/dialogs/dialog_cvpcb_config_fbp.cpp similarity index 100% rename from cvpcb/dialog_cvpcb_config_fbp.cpp rename to cvpcb/dialogs/dialog_cvpcb_config_fbp.cpp diff --git a/cvpcb/dialog_cvpcb_config_fbp.fbp b/cvpcb/dialogs/dialog_cvpcb_config_fbp.fbp similarity index 100% rename from cvpcb/dialog_cvpcb_config_fbp.fbp rename to cvpcb/dialogs/dialog_cvpcb_config_fbp.fbp diff --git a/cvpcb/dialog_cvpcb_config_fbp.h b/cvpcb/dialogs/dialog_cvpcb_config_fbp.h similarity index 100% rename from cvpcb/dialog_cvpcb_config_fbp.h rename to cvpcb/dialogs/dialog_cvpcb_config_fbp.h diff --git a/cvpcb/dialog_display_options.cpp b/cvpcb/dialogs/dialog_display_options.cpp similarity index 100% rename from cvpcb/dialog_display_options.cpp rename to cvpcb/dialogs/dialog_display_options.cpp diff --git a/cvpcb/dialog_display_options.h b/cvpcb/dialogs/dialog_display_options.h similarity index 100% rename from cvpcb/dialog_display_options.h rename to cvpcb/dialogs/dialog_display_options.h diff --git a/cvpcb/dialog_display_options_base.cpp b/cvpcb/dialogs/dialog_display_options_base.cpp similarity index 100% rename from cvpcb/dialog_display_options_base.cpp rename to cvpcb/dialogs/dialog_display_options_base.cpp diff --git a/cvpcb/dialog_display_options_base.fbp b/cvpcb/dialogs/dialog_display_options_base.fbp similarity index 100% rename from cvpcb/dialog_display_options_base.fbp rename to cvpcb/dialogs/dialog_display_options_base.fbp diff --git a/cvpcb/dialog_display_options_base.h b/cvpcb/dialogs/dialog_display_options_base.h similarity index 100% rename from cvpcb/dialog_display_options_base.h rename to cvpcb/dialogs/dialog_display_options_base.h diff --git a/eeschema/CMakeLists.txt b/eeschema/CMakeLists.txt index 34fc194889..e94d771730 100644 --- a/eeschema/CMakeLists.txt +++ b/eeschema/CMakeLists.txt @@ -1,8 +1,8 @@ add_definitions(-DEESCHEMA) include_directories(${CMAKE_CURRENT_SOURCE_DIR} + ${CMAKE_CURRENT_SOURCE_DIR}/dialogs ${CMAKE_SOURCE_DIR}/common - ${CMAKE_SOURCE_DIR}/dialogs ${Boost_INCLUDE_DIR} ) diff --git a/pcbnew/class_board_connected_item.cpp b/pcbnew/class_board_connected_item.cpp index b9315ed2c6..162373e31f 100644 --- a/pcbnew/class_board_connected_item.cpp +++ b/pcbnew/class_board_connected_item.cpp @@ -93,7 +93,7 @@ int BOARD_CONNECTED_ITEM::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const else { #ifdef __WXDEBUG__ - wxLogWarning(wxT("BOARD_CONNECTED_ITEM::GetClearance(): NULL netclass") ); + wxLogWarning(wxT("BOARD_CONNECTED_ITEM::GetClearance():NULL netclass,type %d"), Type() ); #endif } @@ -116,7 +116,7 @@ NETCLASS* BOARD_CONNECTED_ITEM::GetNetClass() const if( board == NULL ) // Should not occurs { #ifdef __WXDEBUG__ - wxLogWarning(wxT("BOARD_CONNECTED_ITEM::GetNetClass(): NULL board, type %d"), Type() ); + wxLogWarning(wxT("BOARD_CONNECTED_ITEM::GetNetClass():NULL board,type %d"), Type() ); #endif return NULL; } @@ -129,7 +129,7 @@ NETCLASS* BOARD_CONNECTED_ITEM::GetNetClass() const #ifdef __WXDEBUG__ if( netclass == NULL ) { - wxLogWarning(wxT("BOARD_CONNECTED_ITEM::GetNetClass(): NULL netclass") ); + wxLogWarning(wxT("BOARD_CONNECTED_ITEM::GetNetClass():NULL netclass,type %d"), Type()); } #endif } diff --git a/pcbnew/class_pad.cpp b/pcbnew/class_pad.cpp index 6db2778247..227b05a71f 100644 --- a/pcbnew/class_pad.cpp +++ b/pcbnew/class_pad.cpp @@ -213,8 +213,8 @@ void D_PAD::Copy( D_PAD* source ) * returns the clearance in internal units. If \a aItem is not NULL then the * returned clearance is the greater of this object's clearance and * aItem's clearance. If \a aItem is NULL, then this objects - * clearance - * is returned. + * clearance is returned. + * note also if the pad is not on copper layers, just ist local clearance is returned * @param aItem is another BOARD_CONNECTED_ITEM or NULL * @return int - the clearance in internal units. */ @@ -224,16 +224,24 @@ int D_PAD::GetClearance( BOARD_CONNECTED_ITEM* aItem ) const // overrides its NETCLASS clearance value int clearance = m_LocalClearance; - if( clearance == 0 ) - { // If local clearance is 0, use the parent footprint clearance value - if( GetParent() && ( (MODULE*) GetParent() )->m_LocalClearance ) - clearance = ( (MODULE*) GetParent() )->m_LocalClearance; + // if not on copper layers, this pad has no netclass, + // So return just use its local clearance + // Old versions of pcbnew allow a hole in a pad which is not on copper layers + // (this is obviously a mistake, but we must support it) + // else see other clearance values + if( (m_Masque_Layer & ALL_CU_LAYERS) != 0 ) + { + if( clearance == 0 ) + { // If local clearance is 0, use the parent footprint clearance value + if( GetParent() && ( (MODULE*) GetParent() )->m_LocalClearance ) + clearance = ( (MODULE*) GetParent() )->m_LocalClearance; + } + + if( clearance == 0 ) // If the parent footprint clearance value = 0, use NETCLASS value + return BOARD_CONNECTED_ITEM::GetClearance( aItem ); } - if( clearance == 0 ) // If the parent footprint clearance value = 0, use NETCLASS value - return BOARD_CONNECTED_ITEM::GetClearance( aItem ); - - // We have a specific clearance. + // We have a specific clearance or a pad with no netclass (not on copper layers). // if aItem, return the biggest clearance if( aItem ) { diff --git a/pcbnew/drc.cpp b/pcbnew/drc.cpp index 1c32d7a345..bae993e9fc 100644 --- a/pcbnew/drc.cpp +++ b/pcbnew/drc.cpp @@ -556,10 +556,14 @@ bool DRC::doPadToPadsDrc( D_PAD* aRefPad, LISTE_PAD* aStart, LISTE_PAD* aEnd, { int layerMask = aRefPad->m_Masque_Layer & ALL_CU_LAYERS; - // used to test DRC pad to holes: this dummypad is a pad hole to test - // pad to pad hole DRC, using pad to pad DRC test. - // this dummy pad is a circle or an oval. - static D_PAD dummypad( (MODULE*) NULL ); + /* used to test DRC pad to holes: this dummy pad has the size and shape of the hole + * to test pad to pad hole DRC, using the pad to pad DRC test function. + * Therefore, this dummy pad is a circle or an oval. + * A pad must have a parent because some functions expect a non null parent + * to find the parent board, and some other data + */ + MODULE dummymodule( m_pcb ); // Creates a dummy parent + D_PAD dummypad( &dummymodule ); dummypad.m_Masque_Layer |= ALL_CU_LAYERS; // Ensure the hole is on all copper layers dummypad.m_LocalClearance = 1; /* Use the minimal local clerance value for the dummy pad * the clearance of the active pad will be used diff --git a/pcbnew/drc_clearance_test_functions.cpp b/pcbnew/drc_clearance_test_functions.cpp index cfe7e97092..7e31e09c35 100644 --- a/pcbnew/drc_clearance_test_functions.cpp +++ b/pcbnew/drc_clearance_test_functions.cpp @@ -264,9 +264,16 @@ bool DRC::doTrackDrc( TRACK* aRefSeg, TRACK* aStart, bool testPads ) /* Phase 1 : test DRC track to pads : */ /******************************************/ - // Use a dummy pad to test DRC tracks versus holes, for pads not on all copper layers - // but having a hole - D_PAD dummypad( (MODULE*) NULL ); // construct this once outside following loop + /* Use a dummy pad to test DRC tracks versus holes, for pads not on all copper layers + * but having a hole + * This dummy pad has the size and shape of the hole + * to test tracks to pad hole DRC, using checkClearanceSegmToPad test function. + * Therefore, this dummy pad is a circle or an oval. + * A pad must have a parent because some functions expect a non null parent + * to find the parent board, and some other data + */ + MODULE dummymodule( m_pcb ); // Creates a dummy parent + D_PAD dummypad( &dummymodule ); dummypad.m_Masque_Layer = ALL_CU_LAYERS; // Ensure the hole is on all layers // Compute the min distance to pads diff --git a/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp b/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp index 1348661f07..fd0b9b45cd 100644 --- a/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp +++ b/pcbnew/zones_convert_brd_items_to_polygons_with_Boost.cpp @@ -173,7 +173,15 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) static std::vector cornerBufferPolysToSubstract; cornerBufferPolysToSubstract.clear(); - D_PAD dummyPad( (MODULE*) NULL ); + /* Use a dummy pad to calculate hole clerance when a pad is not on all copper layers + * and this pad has a hole + * This dummy pad has the size and shape of the hole + * Therefore, this dummy pad is a circle or an oval. + * A pad must have a parent because some functions expect a non null parent + * to find the parent board, and some other data + */ + MODULE dummymodule( aPcb ); // Creates a dummy parent + D_PAD dummypad( &dummymodule ); D_PAD* nextpad; for( MODULE* module = aPcb->m_Modules; module; module = module->Next() ) { @@ -190,11 +198,11 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) continue; // Use a dummy pad to calculate a hole shape that have the same dimension as the pad hole - dummyPad.m_Size = pad->m_Drill; - dummyPad.m_Orient = pad->m_Orient; - dummyPad.m_PadShape = pad->m_DrillShape; - dummyPad.m_Pos = pad->m_Pos; - pad = &dummyPad; + dummypad.m_Size = pad->m_Drill; + dummypad.m_Orient = pad->m_Orient; + dummypad.m_PadShape = pad->m_DrillShape; + dummypad.m_Pos = pad->m_Pos; + pad = &dummypad; } if( pad->GetNet() != GetNet() ) diff --git a/pcbnew/zones_convert_brd_items_to_polygons_with_Kbool.cpp b/pcbnew/zones_convert_brd_items_to_polygons_with_Kbool.cpp index aeeee6fc73..33ea1d7465 100644 --- a/pcbnew/zones_convert_brd_items_to_polygons_with_Kbool.cpp +++ b/pcbnew/zones_convert_brd_items_to_polygons_with_Kbool.cpp @@ -209,7 +209,15 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) static std::vector cornerBufferPolysToSubstract; cornerBufferPolysToSubstract.clear(); - D_PAD dummyPad( (MODULE*) NULL ); + /* Use a dummy pad to calculate hole clerance when a pad is not on all copper layers + * and this pad has a hole + * This dummy pad has the size and shape of the hole + * Therefore, this dummy pad is a circle or an oval. + * A pad must have a parent because some functions expect a non null parent + * to find the parent board, and some other data + */ + MODULE dummymodule( aPcb ); // Creates a dummy parent + D_PAD dummypad( &dummymodule ); D_PAD* nextpad; for( MODULE* module = aPcb->m_Modules; module; module = module->Next() ) { @@ -226,11 +234,11 @@ void ZONE_CONTAINER::AddClearanceAreasPolygonsToPolysList( BOARD* aPcb ) continue; // Use a dummy pad to calculate a hole shape that have the same dimension as the pad hole - dummyPad.m_Size = pad->m_Drill; - dummyPad.m_Orient = pad->m_Orient; - dummyPad.m_PadShape = pad->m_DrillShape; - dummyPad.m_Pos = pad->m_Pos; - pad = &dummyPad; + dummypad.m_Size = pad->m_Drill; + dummypad.m_Orient = pad->m_Orient; + dummypad.m_PadShape = pad->m_DrillShape; + dummypad.m_Pos = pad->m_Pos; + pad = &dummypad; } if( pad->GetNet() != GetNet() ) diff --git a/polygon/PolyLine.cpp b/polygon/PolyLine.cpp index 573993d39b..6ecd29386d 100644 --- a/polygon/PolyLine.cpp +++ b/polygon/PolyLine.cpp @@ -11,6 +11,7 @@ #include "PolyLine.h" #include "gr_basic.h" #include "bezier_curves.h" +#include "polygon_test_point_inside.h" using namespace std; @@ -1366,150 +1367,25 @@ bool CPolyLine::TestPointInside( int px, int py ) wxASSERT( 0 ); } - // define line passing through (x,y), with slope = 2/3; - // get intersection points - int xx, yy; - double slope = (double) 2.0 / 3.0; - double a = py - slope * px; - int nloops = 0; - int npts; - bool inside = false; - - // make this a loop so if my homebrew algorithm screws up, we try it again - do + // Test all polygons. + // Since the first is the main outline, and other are hole, + // if the tested point is inside only one contour, it is inside the whole polygon + // (in fact inside the main outline, and outside all holes). + // if inside 2 contours (the main outline + an hole), it is outside the poly. + int polycount = GetNumContours(); + bool inside = false; + for( int icont = 0; icont < polycount; icont++ ) { - // now find all intersection points of line with polyline sides - npts = 0; - inside = false; - for( int icont = 0; icont px ) - inside = not inside; - npts++; - } - if( ok == 2 ) - { - xx = (int) x2; - yy = (int) y2; - if( xx == px && yy == py ) - return FALSE; // (x,y) is on a side, call it outside - else if( xx > px ) - inside = not inside; - npts++; - } - } - } - - nloops++; - a += PCBU_PER_MIL / 100; - } while( npts % 2 != 0 && nloops < 3 ); - - wxASSERT( npts % 2==0 ); // odd number of intersection points, error - - return inside; -} - - -// test to see if a point is inside polyline contour -// -bool CPolyLine::TestPointInsideContour( int icont, int px, int py ) -{ - if( icont >= GetNumContours() ) - return FALSE; - if( !GetClosed() ) - { - wxASSERT( 0 ); - } - -// define line passing through (x,y), with slope = 2/3; -// get intersection points - int xx, yy; - double slope = (double) 2.0 / 3.0; - double a = py - slope * px; - int nloops = 0; - int npts; - bool inside = false; - -// make this a loop so if my homebrew algorithm screws up, we try it again - do - { - // now find all intersection points of line with polyline sides - npts = 0; - inside = false; int istart = GetContourStart( icont ); int iend = GetContourEnd( icont ); - for( int ic = istart; ic<=iend; ic++ ) - { - double x, y, x2, y2; - int ok; - if( ic == istart ) - ok = FindLineSegmentIntersection( a, slope, - corner[iend].x, corner[iend].y, - corner[istart].x, corner[istart].y, - side_style[iend], - &x, &y, &x2, &y2 ); - else - ok = FindLineSegmentIntersection( a, slope, - corner[ic - 1].x, corner[ic - 1].y, - corner[ic].x, corner[ic].y, - side_style[ic - 1], - &x, &y, &x2, &y2 ); - if( ok ) - { - xx = (int) x; - yy = (int) y; - npts++; - if( xx == px && yy == py ) - return FALSE; // (x,y) is on a side, call it outside - else if( xx > px ) - inside = not inside; - } - if( ok == 2 ) - { - xx = (int) x2; - yy = (int) y2; - npts++; - if( xx == px && yy == py ) - return FALSE; // (x,y) is on a side, call it outside - else if( xx > px ) - inside = not inside; - } - } - - nloops++; - a += PCBU_PER_MIL / 100; - } while( npts % 2 != 0 && nloops < 3 ); - - wxASSERT( npts % 2==0 ); // odd number of intersection points, error + // Test this polygon: + if( TestPointInsidePolygon( corner, istart, iend, px, py) ) // test point inside the current polygon + inside = not inside; + } return inside; } - // copy data from another poly, but don't draw it // void CPolyLine::Copy( CPolyLine* src ) diff --git a/polygon/PolyLine.h b/polygon/PolyLine.h index c4a4e1284b..1a1785ff71 100644 --- a/polygon/PolyLine.h +++ b/polygon/PolyLine.h @@ -145,7 +145,6 @@ public: CRect GetCornerBounds( int icont ); void Copy( CPolyLine* src ); bool TestPointInside( int x, int y ); - bool TestPointInsideContour( int icont, int x, int y ); bool IsCutoutContour( int icont ); void AppendArc( int xi, int yi, int xf, int yf, int xc, int yc, int num ); diff --git a/polygon/polygon_test_point_inside.cpp b/polygon/polygon_test_point_inside.cpp index cf3ffec628..a389b5bbe4 100644 --- a/polygon/polygon_test_point_inside.cpp +++ b/polygon/polygon_test_point_inside.cpp @@ -17,7 +17,7 @@ * Because the starting point of a segment is also the ending point of the previous, only one must be used. * And we do no use twice the same segment, so we do NOT use both starting and ending points of these 2 segments. * So we must use only one ending point of each segment when calculating intersections - * but it cannot be always the starting or the endind point. This depend on relative position of 2 consectutive segments + * but it cannot be always the starting or the ending point. This depend on relative position of 2 consectutive segments * Here, the ending point above the Y reference position is used * and the ending point below or equal the Y reference position is NOT used * Obviously, others cases are irrelevant because there is not intersection. @@ -35,10 +35,9 @@ bool TestPointInsidePolygon( std::vector aPolysList, /** Function TestPointInsidePolygon * test if a point is inside or outside a polygon. * the polygon must have only lines (not arcs) for outlines. - * Use TestPointInside or TestPointInsideContour for more complex polygons * @param aPolysList: the list of polygons * @param aIdxstart: the starting point of a given polygon in m_FilledPolysList. - * @param aIdxend: the ending point of the polygon in m_FilledPolysList. + * @param aIdxend: the ending point of this polygon in m_FilledPolysList. * @param aRefx, aRefy: the point coordinate to test * @return true if the point is inside, false for outside */