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
This commit is contained in:
jean-pierre charras 2023-02-28 16:34:07 +01:00
parent a1ceb585c7
commit 7256a51e8e
6 changed files with 54 additions and 11 deletions

View File

@ -2,7 +2,7 @@
* This program source code file is part of KiCad, a free EDA CAD application.
*
* Copyright (C) 2015-2022 Mario Luzeiro <mrluzeiro@ua.pt>
* 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,

View File

@ -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 );

View File

@ -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;
@ -651,6 +655,16 @@ public:
bool GetBoardPolygonOutlines( SHAPE_POLY_SET& aOutlines,
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

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2017 Jean-Pierre Charras, jp.charras at wanadoo.fr
* Copyright (C) 2015 SoftPLC Corporation, Dick Hollenbeck <dick@softplc.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
@ -400,11 +400,21 @@ bool ConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& 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<PCB_SHAPE*>& 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;

View File

@ -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 ) )

View File

@ -3,7 +3,7 @@
*
* Copyright (C) 2022 Mark Roszko <mark.roszko@gmail.com>
* Copyright (C) 2016 Cirilo Bernardo <cirilo.bernardo@gmail.com>
* 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" ) );