Move 3D polygon approximation to absolute-error algorithm.
Also inflates via and pad hole polygons to bisect their circles. Fixes: lp:1758137 * https://bugs.launchpad.net/kicad/+bug/1758137
This commit is contained in:
parent
fbf10e941b
commit
cd0cd242d1
|
@ -33,6 +33,7 @@
|
|||
#include <class_board.h>
|
||||
#include <3d_math.h>
|
||||
#include "3d_fastmath.h"
|
||||
#include <geometry/geometry_utils.h>
|
||||
|
||||
/**
|
||||
* Trace mask used to enable or disable the trace output of this class.
|
||||
|
@ -243,37 +244,19 @@ int CINFO3D_VISU::GetCopperThicknessBIU() const
|
|||
return COPPER_THICKNESS;
|
||||
}
|
||||
|
||||
// Constant factors used for number of segments approximation calcs
|
||||
#define MIN_SEG_PER_CIRCLE 12
|
||||
#define MAX_SEG_PER_CIRCLE 48
|
||||
|
||||
#define SEG_MIN_FACTOR_BIU ( 0.10f * IU_PER_MM )
|
||||
#define SEG_MAX_FACTOR_BIU ( 6.00f * IU_PER_MM )
|
||||
|
||||
|
||||
unsigned int CINFO3D_VISU::GetNrSegmentsCircle( float aDiameter3DU ) const
|
||||
{
|
||||
wxASSERT( aDiameter3DU > 0.0f );
|
||||
|
||||
unsigned int result = mapf( aDiameter3DU,
|
||||
m_calc_seg_min_factor3DU, m_calc_seg_max_factor3DU,
|
||||
(float)MIN_SEG_PER_CIRCLE, (float)MAX_SEG_PER_CIRCLE );
|
||||
wxASSERT( result > 1 );
|
||||
|
||||
return result;
|
||||
return GetNrSegmentsCircle( (int)( aDiameter3DU / m_biuTo3Dunits ) );
|
||||
}
|
||||
|
||||
|
||||
unsigned int CINFO3D_VISU::GetNrSegmentsCircle( int aDiameterBUI ) const
|
||||
unsigned int CINFO3D_VISU::GetNrSegmentsCircle( int aDiameterBIU ) const
|
||||
{
|
||||
wxASSERT( aDiameterBUI > 0 );
|
||||
wxASSERT( aDiameterBIU > 0 );
|
||||
|
||||
unsigned int result = mapf( (float)aDiameterBUI,
|
||||
(float)SEG_MIN_FACTOR_BIU, (float)SEG_MAX_FACTOR_BIU,
|
||||
(float)MIN_SEG_PER_CIRCLE, (float)MAX_SEG_PER_CIRCLE );
|
||||
wxASSERT( result > 1 );
|
||||
|
||||
return result;
|
||||
return GetArcToSegmentCount( aDiameterBIU / 2, ARC_HIGH_DEF, 360.0 );
|
||||
}
|
||||
|
||||
|
||||
|
@ -281,7 +264,7 @@ double CINFO3D_VISU::GetCircleCorrectionFactor( int aNrSides ) const
|
|||
{
|
||||
wxASSERT( aNrSides >= 3 );
|
||||
|
||||
return 1.0 / cos( M_PI / ( (double)aNrSides * 2.0 ) );
|
||||
return GetCircletoPolyCorrectionFactor( aNrSides );
|
||||
}
|
||||
|
||||
|
||||
|
@ -318,10 +301,6 @@ void CINFO3D_VISU::InitSettings( REPORTER *aStatusTextReporter )
|
|||
// Calculate the convertion to apply to all positions.
|
||||
m_biuTo3Dunits = RANGE_SCALE_3D / std::max( m_boardSize.x, m_boardSize.y );
|
||||
|
||||
// Calculate factors for cicle segment approximation
|
||||
m_calc_seg_min_factor3DU = (float)( SEG_MIN_FACTOR_BIU * m_biuTo3Dunits );
|
||||
m_calc_seg_max_factor3DU = (float)( SEG_MAX_FACTOR_BIU * m_biuTo3Dunits );
|
||||
|
||||
m_epoxyThickness3DU = m_board->GetDesignSettings().GetBoardThickness() *
|
||||
m_biuTo3Dunits;
|
||||
|
||||
|
|
|
@ -394,10 +394,10 @@ class CINFO3D_VISU
|
|||
|
||||
/**
|
||||
* @brief GetNrSegmentsCircle
|
||||
* @param aDiameterBUI: diameter in board unities
|
||||
* @param aDiameterBIU: diameter in board internal units
|
||||
* @return number of sides that should be used in that circle
|
||||
*/
|
||||
unsigned int GetNrSegmentsCircle( int aDiameterBUI ) const;
|
||||
unsigned int GetNrSegmentsCircle( int aDiameterBIU ) const;
|
||||
|
||||
/**
|
||||
* @brief GetCircleCorrectionFactor - computes a angle correction
|
||||
|
|
|
@ -768,9 +768,11 @@ void C3D_RENDER_OGL_LEGACY::generate_3D_Vias_and_Pads()
|
|||
{
|
||||
const VIA *via = static_cast<const VIA*>(track);
|
||||
|
||||
const float holediameter = via->GetDrillValue() * m_settings.BiuTo3Dunits();
|
||||
const float thickness = m_settings.GetCopperThickness3DU();
|
||||
const float hole_inner_radius = ( holediameter / 2.0f );
|
||||
const float holediameter = via->GetDrillValue() * m_settings.BiuTo3Dunits();
|
||||
const float thickness = m_settings.GetCopperThickness3DU();
|
||||
const int nrSegments = m_settings.GetNrSegmentsCircle( via->GetDrillValue() );
|
||||
const double correctionFactor = m_settings.GetCircleCorrectionFactor( nrSegments );
|
||||
const float hole_inner_radius = ( holediameter / 2.0f ) * correctionFactor;
|
||||
|
||||
const SFVEC2F via_center( via->GetStart().x * m_settings.BiuTo3Dunits(),
|
||||
-via->GetStart().y * m_settings.BiuTo3Dunits() );
|
||||
|
@ -790,7 +792,7 @@ void C3D_RENDER_OGL_LEGACY::generate_3D_Vias_and_Pads()
|
|||
hole_inner_radius + thickness,
|
||||
ztop,
|
||||
zbot,
|
||||
m_settings.GetNrSegmentsCircle( via->GetDrillValue() ),
|
||||
nrSegments,
|
||||
layerTriangleVIA );
|
||||
}
|
||||
}
|
||||
|
@ -829,20 +831,20 @@ void C3D_RENDER_OGL_LEGACY::generate_3D_Vias_and_Pads()
|
|||
|
||||
// we use the hole diameter to calculate the seg count.
|
||||
// for round holes, drillsize.x == drillsize.y
|
||||
// for oblong holes, the diameter is the smaller of
|
||||
// (drillsize.x, drillsize.y)
|
||||
const int diam = std::min( drillsize.x, drillsize.y ) +
|
||||
m_settings.GetCopperThicknessBIU() * 2;
|
||||
|
||||
const int segmentsPerCircle = m_settings.GetNrSegmentsCircle( diam );
|
||||
// for slots, the diameter is the smaller of (drillsize.x, drillsize.y)
|
||||
int copperThickness = m_settings.GetCopperThicknessBIU();
|
||||
int radius = std::min( drillsize.x, drillsize.y ) / 2 + copperThickness;
|
||||
int nrSegments = m_settings.GetNrSegmentsCircle( radius * 2 );
|
||||
double correctionFactor = m_settings.GetCircleCorrectionFactor( nrSegments );
|
||||
int correction = radius * ( correctionFactor - 1 );
|
||||
|
||||
pad->BuildPadDrillShapePolygon( tht_outer_holes_poly,
|
||||
m_settings.GetCopperThicknessBIU(),
|
||||
segmentsPerCircle );
|
||||
copperThickness + correction,
|
||||
nrSegments );
|
||||
|
||||
pad->BuildPadDrillShapePolygon( tht_inner_holes_poly,
|
||||
0,
|
||||
segmentsPerCircle );
|
||||
correction,
|
||||
nrSegments );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue