From 7256a51e8ec1349a95006983d3e5e669c10a781f Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Tue, 28 Feb 2023 16:34:07 +0100 Subject: [PATCH] Fixes in build board outlines as polygon and convert_shape_list_to_polygon: - Ensure Bezier curves have their polygon build before use it. - When building board outlines as polygon the same chaining epsilon value for DRC, export step and 3D view (default 0.01mm). Fixes #14115 https://gitlab.com/kicad/code/kicad/issues/14115 Fixes #14009 https://gitlab.com/kicad/code/kicad/issues/14009 --- 3d-viewer/3d_canvas/board_adapter.cpp | 5 +++-- pcbnew/board.cpp | 7 ++++++- pcbnew/board.h | 20 +++++++++++++++++++- pcbnew/convert_shape_list_to_polygon.cpp | 15 ++++++++++++++- pcbnew/drc/drc_test_provider_misc.cpp | 6 +++--- pcbnew/exporters/step/exporter_step.cpp | 12 +++++++++--- 6 files changed, 54 insertions(+), 11 deletions(-) diff --git a/3d-viewer/3d_canvas/board_adapter.cpp b/3d-viewer/3d_canvas/board_adapter.cpp index 74be552d3b..c9a232dc57 100644 --- a/3d-viewer/3d_canvas/board_adapter.cpp +++ b/3d-viewer/3d_canvas/board_adapter.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2015-2022 Mario Luzeiro - * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -671,7 +671,8 @@ bool BOARD_ADAPTER::createBoardPolygon( wxString* aErrorMsg ) return false; } - int chainingEpsilon = pcbIUScale.mmToIU( 0.02 ); // max dist from one endPt to next startPt + // max dist from one endPt to next startPt + int chainingEpsilon = m_board->GetOutlinesChainingEpsilon(); success = BuildFootprintPolygonOutlines( m_board, m_board_poly, m_board->GetDesignSettings().m_MaxError, diff --git a/pcbnew/board.cpp b/pcbnew/board.cpp index edd5b5e987..52ee8b6dbd 100644 --- a/pcbnew/board.cpp +++ b/pcbnew/board.cpp @@ -78,6 +78,10 @@ BOARD::BOARD() : m_designSettings( new BOARD_DESIGN_SETTINGS( nullptr, "board.design_settings" ) ), m_NetInfo( this ) { + // A too small value do not allow connecting 2 shapes (i.e. segments) not exactly connected + // A too large value do not allow safely connecting 2 shapes like very short segments. + m_outlinesChainingEpsilon = pcbIUScale.mmToIU( DEFAULT_CHAINING_EPSILON_MM ); + // we have not loaded a board yet, assume latest until then. m_fileFormatVersionAtLoad = LEGACY_BOARD_FILE_VERSION; @@ -1968,7 +1972,8 @@ ZONE* BOARD::AddArea( PICKED_ITEMS_LIST* aNewZonesList, int aNetcode, PCB_LAYER_ bool BOARD::GetBoardPolygonOutlines( SHAPE_POLY_SET& aOutlines, OUTLINE_ERROR_HANDLER* aErrorHandler ) { - int chainingEpsilon = pcbIUScale.mmToIU( 0.02 ); // max dist from one endPt to next startPt + // 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 ); diff --git a/pcbnew/board.h b/pcbnew/board.h index e84a5b6ea7..48f4750f19 100644 --- a/pcbnew/board.h +++ b/pcbnew/board.h @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2007 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com - * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -61,6 +61,10 @@ class COMPONENT; class PROJECT; class PROGRESS_REPORTER; +// The default value for m_outlinesChainingEpsilon to convert a board outlines to polygons +// It is the max dist between 2 end points to see them connected +#define DEFAULT_CHAINING_EPSILON_MM 0.01 + // Forward declare endpoint from class_track.h enum ENDPOINT_T : int; @@ -652,6 +656,16 @@ public: OUTLINE_ERROR_HANDLER* aErrorHandler = nullptr ); /** + * @return a epsilon value that is the max distance between 2 points to see them + * at the same coordinate when building the board outlines and tray to connect 2 end points + * when buildind the outlines of the board + * Too small value do not allow connecting 2 shapes (i.e. segments) not exactly connected + * Too large value do not allow safely connecting 2 shapes like very short segments. + */ + int GetOutlinesChainingEpsilon() { return( m_outlinesChainingEpsilon ); } + void SetOutlinesChainingEpsilon( int aValue) { m_outlinesChainingEpsilon = aValue; } + + /** * Build a set of polygons which are the outlines of copper items (pads, tracks, vias, texts, * zones). * @@ -1171,6 +1185,10 @@ private: friend class PCB_EDIT_FRAME; + + /// the max distance between 2 end point to see them connected when building the board outlines + int m_outlinesChainingEpsilon; + /// What is this board being used for BOARD_USE m_boardUse; int m_timeStamp; // actually a modification counter diff --git a/pcbnew/convert_shape_list_to_polygon.cpp b/pcbnew/convert_shape_list_to_polygon.cpp index d07ea3f609..ad973f0d76 100644 --- a/pcbnew/convert_shape_list_to_polygon.cpp +++ b/pcbnew/convert_shape_list_to_polygon.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr * Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck - * Copyright (C) 1992-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -400,11 +400,21 @@ bool ConvertOutlineToPolygon( std::vector& aShapeList, SHAPE_POLY_SE reverse = true; } + // Ensure the approximated Bezier shape is built + // a good value is between (Bezier curve width / 2) and (Bezier curve width) + // ( and at least 0.05 mm to avoid very small segments) + int min_segm_lenght = std::max( pcbIUScale.mmToIU( 0.05 ), graphic->GetWidth() ); + graphic->RebuildBezierToSegmentsPointsList( min_segm_lenght ); + if( reverse ) { for( int jj = graphic->GetBezierPoints().size()-1; jj >= 0; jj-- ) { const VECTOR2I& pt = graphic->GetBezierPoints()[jj]; + + if( prevPt == pt ) + continue; + currContour.Append( pt ); shapeOwners[ std::make_pair( prevPt, pt ) ] = graphic; prevPt = pt; @@ -414,6 +424,9 @@ bool ConvertOutlineToPolygon( std::vector& aShapeList, SHAPE_POLY_SE { for( const VECTOR2I& pt : graphic->GetBezierPoints() ) { + if( prevPt == pt ) + continue; + currContour.Append( pt ); shapeOwners[ std::make_pair( prevPt, pt ) ] = graphic; prevPt = pt; diff --git a/pcbnew/drc/drc_test_provider_misc.cpp b/pcbnew/drc/drc_test_provider_misc.cpp index e5424536ed..30e7d1d3db 100644 --- a/pcbnew/drc/drc_test_provider_misc.cpp +++ b/pcbnew/drc/drc_test_provider_misc.cpp @@ -1,7 +1,7 @@ /* * This program source code file is part of KiCad, a free EDA CAD application. * - * Copyright (C) 2004-2022 KiCad Developers. + * Copyright (C) 2004-2023 KiCad Developers. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -94,9 +94,9 @@ void DRC_TEST_PROVIDER_MISC::testOutline() errorHandled = true; }; - // Use a really tight chaining epsilon here so that we report errors that might affect + // Use the standard chaining epsilon here so that we report errors that might affect // other tools (such as STEP export). - constexpr int chainingEpsilon = pcbIUScale.mmToIU( 0.02 ) / 100; + int chainingEpsilon = m_board->GetOutlinesChainingEpsilon(); if( !BuildBoardPolygonOutlines( m_board, dummyOutline, m_board->GetDesignSettings().m_MaxError, chainingEpsilon, &errorHandler ) ) diff --git a/pcbnew/exporters/step/exporter_step.cpp b/pcbnew/exporters/step/exporter_step.cpp index 6b5272f8c2..e4e0631fb9 100644 --- a/pcbnew/exporters/step/exporter_step.cpp +++ b/pcbnew/exporters/step/exporter_step.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 2022 Mark Roszko * Copyright (C) 2016 Cirilo Bernardo - * Copyright (C) 2016-2022 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2016-2023 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -263,8 +263,10 @@ bool EXPORTER_STEP::composePCB() m_pcbModel->SetBoardColor( m_solderMaskColor.r, m_solderMaskColor.g, m_solderMaskColor.b ); m_pcbModel->SetPCBThickness( m_boardThickness ); - m_pcbModel->SetMinDistance( - std::max( m_params.m_minDistance, STEPEXPORT_MIN_ACCEPTABLE_DISTANCE ) ); + + // Set the min distance betewenn 2 points for OCC to see these 2 points as merged + double minDistmm = std::max( m_params.m_minDistance, STEPEXPORT_MIN_ACCEPTABLE_DISTANCE ); + m_pcbModel->SetMinDistance( minDistmm ); m_pcbModel->SetMaxError( m_board->GetDesignSettings().m_MaxError ); @@ -273,6 +275,10 @@ bool EXPORTER_STEP::composePCB() ReportMessage( wxT( "Create PCB solid model\n" ) ); + wxString msg; + msg.Printf( wxT( "Board outline: find %d initial points\n" ), pcbOutlines.FullPointCount() ); + ReportMessage( msg ); + if( !m_pcbModel->CreatePCB( pcbOutlines, origin ) ) { ReportMessage( wxT( "could not create PCB solid model\n" ) );