diff --git a/3d-viewer/3d_canvas/board_adapter.cpp b/3d-viewer/3d_canvas/board_adapter.cpp index dcc64899a4..7f59629f33 100644 --- a/3d-viewer/3d_canvas/board_adapter.cpp +++ b/3d-viewer/3d_canvas/board_adapter.cpp @@ -898,7 +898,7 @@ bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg ) } else { - success = m_board->GetBoardPolygonOutlines( m_board_poly ); + success = m_board->GetBoardPolygonOutlines( m_board_poly, nullptr, false, true ); if( !success && aErrorMsg ) *aErrorMsg = _( "Board outline is missing or malformed. Run DRC for a full analysis." ); diff --git a/pcbnew/board.cpp b/pcbnew/board.cpp index 4b2ab1e0cf..a84a4d7ce9 100644 --- a/pcbnew/board.cpp +++ b/pcbnew/board.cpp @@ -2200,13 +2200,46 @@ ZONE* BOARD::AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode, PCB_LAYER_ bool BOARD::GetBoardPolygonOutlines( SHAPE_POLY_SET& aOutlines, OUTLINE_ERROR_HANDLER* aErrorHandler, - bool aAllowUseArcsInPolygons ) + bool aAllowUseArcsInPolygons, + bool aIncludeNPTHAsOutlines ) { // max dist from one endPt to next startPt: use the current value int chainingEpsilon = GetOutlinesChainingEpsilon(); bool success = BuildBoardPolygonOutlines( this, aOutlines, GetDesignSettings().m_MaxError, - chainingEpsilon, aErrorHandler, aAllowUseArcsInPolygons ); + chainingEpsilon, aErrorHandler, + aAllowUseArcsInPolygons ); + + // Now add NPTH oval holes as holes in outlines if required + if( aIncludeNPTHAsOutlines ) + { + for( FOOTPRINT* fp : Footprints() ) + { + for( PAD* pad : fp->Pads() ) + { + if( pad->GetAttribute () != PAD_ATTRIB::NPTH ) + continue; + + SHAPE_POLY_SET hole; + pad->TransformHoleToPolygon( hole, 0, GetDesignSettings().m_MaxError, ERROR_INSIDE ); + + // Add this pad hole to the main outline + // But we can have more than one main outline (i.e. more than one board), so + // search the right main outline i.e. the outline that contains the pad hole + SHAPE_LINE_CHAIN& pad_hole = hole.Outline( 0 ); + const VECTOR2I holePt = pad_hole.CPoint( 0 ); + + for( int jj = 0; jj < aOutlines.OutlineCount(); ++jj ) + { + if( aOutlines.Outline( jj ).PointInside( holePt ) ) + { + aOutlines.AddHole( pad_hole, jj ); + break; + } + } + } + } + } // Make polygon strictly simple to avoid issues (especially in 3D viewer) aOutlines.Simplify( SHAPE_POLY_SET::PM_STRICTLY_SIMPLE ); diff --git a/pcbnew/board.h b/pcbnew/board.h index 1f4b3104b9..898c4e6599 100644 --- a/pcbnew/board.h +++ b/pcbnew/board.h @@ -679,11 +679,15 @@ public: * @param aAllowUseArcsInPolygons = an optional option to allow adding arcs in * SHAPE_LINE_CHAIN polylines/polygons when building outlines from aShapeList * This is mainly for export to STEP files + * @param aIncludeNPTHAsOutlines = an optional option to include NPTH pad holes + * in board outlines. These holes can be seen like holes created by closed shapes + * drawn on edge cut layer inside the board main outline. * @return true if success, false if a contour is not valid */ bool GetBoardPolygonOutlines( SHAPE_POLY_SET& aOutlines, OUTLINE_ERROR_HANDLER* aErrorHandler = nullptr, - bool aAllowUseArcsInPolygons = false ); + bool aAllowUseArcsInPolygons = false, + bool aIncludeNPTHAsOutlines = false ); /** * @return a epsilon value that is the max distance between 2 points to see them