Move remaining hard-coded segment counts

This removes the remaining hard-coded segments counts and replaces them
with the relative error calculation where the segments per arc is
determined by the maximum error we allow (smaller arcs = fewer segments)
This commit is contained in:
Seth Hillbrand 2019-05-14 05:39:34 -07:00
parent 8378f97a78
commit ddc6079ceb
34 changed files with 404 additions and 692 deletions

View File

@ -836,12 +836,9 @@ void CINFO3D_VISU::AddShapeWithClearanceToContainer( const DRAWSEGMENT* aDrawSeg
case S_CURVE:
case S_POLYGON:
{
const int segcountforcircle = ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF;
const double correctionFactor = GetCircleCorrectionFactor( segcountforcircle );
SHAPE_POLY_SET polyList;
aDrawSegment->TransformShapeWithClearanceToPolygon( polyList, aClearanceValue,
segcountforcircle, correctionFactor );
aDrawSegment->TransformShapeWithClearanceToPolygon( polyList, aClearanceValue );
polyList.Simplify( SHAPE_POLY_SET::PM_FAST );
@ -967,15 +964,7 @@ void CINFO3D_VISU::buildPadShapeThickOutlineAsSegments( const D_PAD* aPad,
// For other shapes, draw polygon outlines
SHAPE_POLY_SET corners;
const int segcountforcircle = GetNrSegmentsCircle( glm::min( aPad->GetSize().x,
aPad->GetSize().y) );
const double correctionFactor = GetCircleCorrectionFactor( segcountforcircle );
aPad->BuildPadShapePolygon( corners, wxSize( 0, 0 ),
// This two factors are only expected to be used if render an oval
segcountforcircle, correctionFactor );
aPad->BuildPadShapePolygon( corners, wxSize( 0, 0 ) );
// Add outlines as thick segments in polygon buffer
@ -992,15 +981,13 @@ void CINFO3D_VISU::buildPadShapeThickOutlineAsSegments( const D_PAD* aPad,
if( Is_segment_a_circle( start3DU, end3DU ) )
{
aDstContainer->Add( new CFILLEDCIRCLE2D( start3DU,
(aWidth / 2) * m_biuTo3Dunits,
*aPad ) );
aDstContainer->Add(
new CFILLEDCIRCLE2D( start3DU, ( aWidth / 2 ) * m_biuTo3Dunits, *aPad ) );
}
else
{
aDstContainer->Add( new CROUNDSEGMENT2D( start3DU, end3DU,
aWidth * m_biuTo3Dunits,
*aPad ) );
aDstContainer->Add(
new CROUNDSEGMENT2D( start3DU, end3DU, aWidth * m_biuTo3Dunits, *aPad ) );
}
}
}

View File

@ -140,17 +140,6 @@ void CINFO3D_VISU::destroyLayers()
void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
{
// Number of segments to draw a circle using segments (used on countour zones
// and text copper elements )
const int segcountforcircle = 12;
const double correctionFactor = GetCircleCorrectionFactor( segcountforcircle );
// segments to draw a circle to build texts. Is is used only to build
// the shape of each segment of the stroke font, therefore no need to have
// many segments per circle.
const int segcountInStrokeFont = 12;
const double correctionFactorStroke = GetCircleCorrectionFactor( segcountInStrokeFont );
destroyLayers();
// Build Copper layers
@ -563,28 +552,16 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
// The hole in the body is inflated by copper thickness.
const int inflate = GetCopperThicknessBIU();
// we use the hole diameter to calculate the seg count.
// for round holes, padHole.x == padHole.y
// for oblong holes, the diameter is the smaller of (padHole.x, padHole.y)
const int diam = std::min( padHole.x, padHole.y );
if( pad->GetAttribute () != PAD_ATTRIB_HOLE_NOT_PLATED )
{
pad->BuildPadDrillShapePolygon( m_through_outer_holes_poly,
inflate,
GetNrSegmentsCircle( diam ) );
pad->BuildPadDrillShapePolygon( m_through_outer_holes_poly, inflate );
pad->BuildPadDrillShapePolygon( m_through_inner_holes_poly,
0,
GetNrSegmentsCircle( diam ) );
pad->BuildPadDrillShapePolygon( m_through_inner_holes_poly, 0 );
}
else
{
// If not plated, no copper.
pad->BuildPadDrillShapePolygon( m_through_outer_holes_poly_NPTH,
inflate,
GetNrSegmentsCircle( diam ) );
pad->BuildPadDrillShapePolygon( m_through_outer_holes_poly_NPTH, inflate );
}
}
}
@ -656,11 +633,8 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
true );
// Micro-wave modules may have items on copper layers
module->TransformGraphicTextWithClearanceToPolygonSet( curr_layer_id,
*layerPoly,
0,
segcountforcircle,
correctionFactor );
module->TransformGraphicTextWithClearanceToPolygonSet(
curr_layer_id, *layerPoly, 0 );
transformGraphicModuleEdgeToPolygonSet( module, curr_layer_id, *layerPoly );
}
@ -749,31 +723,17 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
switch( item->Type() )
{
case PCB_LINE_T:
{
const int nrSegments =
GetNrSegmentsCircle( item->GetBoundingBox().GetSizeMax() );
( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon(
*layerPoly,
0,
nrSegments,
GetCircleCorrectionFactor( nrSegments ) );
}
break;
( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon( *layerPoly, 0 );
break;
case PCB_TEXT_T:
( (TEXTE_PCB*) item )->TransformShapeWithClearanceToPolygonSet(
*layerPoly,
0,
segcountforcircle,
correctionFactor );
break;
( (TEXTE_PCB*) item )->TransformShapeWithClearanceToPolygonSet( *layerPoly, 0 );
break;
default:
wxLogTrace( m_logTrace,
wxT( "createLayers: item type: %d not implemented" ),
item->Type() );
break;
wxLogTrace( m_logTrace, wxT( "createLayers: item type: %d not implemented" ),
item->Type() );
break;
}
}
}
@ -846,7 +806,7 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
auto layerContainer = m_layers_poly.find( zone->GetLayer() );
if( layerContainer != m_layers_poly.end() )
zone->TransformSolidAreasShapesToPolygonSet( *layerContainer->second, segcountforcircle, correctionFactor );
zone->TransformSolidAreasShapesToPolygonSet( *layerContainer->second );
}
}
@ -1034,22 +994,11 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
switch( item->Type() )
{
case PCB_LINE_T:
{
const unsigned int nr_segments =
GetNrSegmentsCircle( item->GetBoundingBox().GetSizeMax() );
((DRAWSEGMENT*) item)->TransformShapeWithClearanceToPolygon( *layerPoly,
0,
nr_segments,
0.0 );
}
( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon( *layerPoly, 0 );
break;
case PCB_TEXT_T:
((TEXTE_PCB*) item)->TransformShapeWithClearanceToPolygonSet( *layerPoly,
0,
segcountInStrokeFont,
1.0 );
( (TEXTE_PCB*) item )->TransformShapeWithClearanceToPolygonSet( *layerPoly, 0 );
break;
default:
@ -1072,24 +1021,16 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
if( !pad->IsOnLayer( curr_layer_id ) )
continue;
buildPadShapeThickOutlineAsSegments( pad,
layerContainer,
linewidth );
buildPadShapeThickOutlineAsSegments( pad, layerContainer, linewidth );
}
}
else
{
AddPadsShapesWithClearanceToContainer( module,
layerContainer,
curr_layer_id,
0,
false );
AddPadsShapesWithClearanceToContainer(
module, layerContainer, curr_layer_id, 0, false );
}
AddGraphicsShapesWithClearanceToContainer( module,
layerContainer,
curr_layer_id,
0 );
AddGraphicsShapesWithClearanceToContainer( module, layerContainer, curr_layer_id, 0 );
}
@ -1112,20 +1053,12 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
}
else
{
transformPadsShapesWithClearanceToPolygon( module->PadsList(),
curr_layer_id,
*layerPoly,
0,
false );
transformPadsShapesWithClearanceToPolygon(
module->PadsList(), curr_layer_id, *layerPoly, 0, false );
}
// On tech layers, use a poor circle approximation, only for texts (stroke font)
module->TransformGraphicTextWithClearanceToPolygonSet( curr_layer_id,
*layerPoly,
0,
segcountInStrokeFont,
correctionFactorStroke,
segcountInStrokeFont );
module->TransformGraphicTextWithClearanceToPolygonSet( curr_layer_id, *layerPoly, 0 );
// Add the remaining things with dynamic seg count for circles
transformGraphicModuleEdgeToPolygonSet( module, curr_layer_id, *layerPoly );
@ -1155,10 +1088,7 @@ void CINFO3D_VISU::createLayers( REPORTER *aStatusTextReporter )
if( !zone->IsOnLayer( curr_layer_id ) )
continue;
zone->TransformSolidAreasShapesToPolygonSet( *layerPoly,
// Use the same segcount as stroke font
segcountInStrokeFont,
correctionFactorStroke );
zone->TransformSolidAreasShapesToPolygonSet( *layerPoly );
}
}

View File

@ -823,13 +823,10 @@ void C3D_RENDER_OGL_LEGACY::generate_3D_Vias_and_Pads()
double correctionFactor = m_settings.GetCircleCorrectionFactor( nrSegments );
int correction = radius * ( correctionFactor - 1 );
pad->BuildPadDrillShapePolygon( tht_outer_holes_poly,
copperThickness + correction,
nrSegments );
pad->BuildPadDrillShapePolygon(
tht_outer_holes_poly, copperThickness + correction );
pad->BuildPadDrillShapePolygon( tht_inner_holes_poly,
correction,
nrSegments );
pad->BuildPadDrillShapePolygon( tht_inner_holes_poly, correction );
}
}
}

View File

@ -34,7 +34,6 @@ set( GAL_SRCS
draw_panel_gal.cpp
gl_context_mgr.cpp
newstroke_font.cpp
origin_viewitem.cpp
painter.cpp
text_utils.cpp
worksheet_viewitem.cpp
@ -322,7 +321,6 @@ set( COMMON_SRCS
getrunningmicrosecs.cpp
gr_basic.cpp
grid_tricks.cpp
hash_eda.cpp
hotkey_store.cpp
hotkeys_basic.cpp
html_messagebox.cpp
@ -444,7 +442,9 @@ set( PCB_COMMON_SRCS
base_screen.cpp
eda_text.cpp
fp_lib_table.cpp
hash_eda.cpp
lset.cpp
origin_viewitem.cpp
page_info.cpp
pcb_keywords.cpp
pcb_plot_params_keywords.cpp

View File

@ -28,7 +28,6 @@
* and their documentation (comments and keywords)
*/
#include <class_module.h>
#include <common.h>
#include <fctsys.h>
#include <footprint_info.h>

View File

@ -45,7 +45,6 @@
#include <algorithm>
#include <fstream>
#include <limits>
#include <board_connected_item.h>
#include <memory>
using namespace hed;

View File

@ -24,7 +24,6 @@
#include <preview_items/bright_box.h>
#include <gal/graphics_abstraction_layer.h>
#include <class_track.h>
using namespace KIGFX;

View File

@ -25,7 +25,8 @@
#include <tool/tool_event.h>
#include <tool/tool_manager.h>
#include <pcb_edit_frame.h>
#include <draw_frame.h>
#include <eda_base_frame.h>
bool TOOL_BASE::IsToolActive() const
{
@ -94,9 +95,8 @@ wxConfigBase* TOOL_SETTINGS::getConfigBase() const
if( !m_tool )
return NULL;
// fixme: make independent of pcbnew (post-stable)
if( PCB_EDIT_FRAME* frame = m_tool->getEditFrame<PCB_EDIT_FRAME>() )
return frame->GetSettings();
if( EDA_BASE_FRAME* frame = m_tool->getEditFrame<EDA_BASE_FRAME>() )
return frame->config();
return NULL;
}

View File

@ -23,7 +23,7 @@
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
*/
#include <pcb_edit_frame.h>
#include <macros.h>
#include <trace_helpers.h>
#include <tool/tool_manager.h>
@ -33,6 +33,7 @@
#include <view/wx_view_controls.h>
#include <class_draw_panel_gal.h>
#include <draw_frame.h>
#include <pcbnew_id.h>
#include <core/optional.h>
@ -319,10 +320,10 @@ void TOOL_DISPATCHER::DispatchWxEvent( wxEvent& aEvent )
// Sometimes there is no window that has the focus (it happens when another PCB_BASE_FRAME
// is opened and is iconized on Windows).
// In this case, gives the focus to the parent PCB_BASE_FRAME (for an obscure reason,
// In this case, gives the focus to the parent frame (for an obscure reason,
// when happens, the GAL canvas itself does not accept the focus)
if( wxWindow::FindFocus() == nullptr )
static_cast<PCB_BASE_FRAME*>( m_toolMgr->GetEditFrame() )->SetFocus();
m_toolMgr->GetEditFrame()->SetFocus();
// Mouse handling
// Note: wxEVT_LEFT_DOWN event must always be skipped.

View File

@ -41,8 +41,8 @@
#include <tool/coroutine.h>
#include <tool/action_manager.h>
#include <pcb_edit_frame.h>
#include <class_draw_panel_gal.h>
#include <draw_frame.h>
/// Struct describing the current execution state of a TOOL
struct TOOL_MANAGER::TOOL_STATE

View File

@ -17,15 +17,15 @@
* with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <pcb_edit_frame.h>
#include <class_draw_panel_gal.h>
#include <view/view_controls.h>
#include <view/view.h>
#include <tool/tool_manager.h>
#include <tool/actions.h>
#include <tool/zoom_tool.h>
#include <draw_frame.h>
#include <id.h>
#include <preview_items/selection_area.h>
#include <tool/actions.h>
#include <tool/tool_manager.h>
#include <tool/zoom_tool.h>
#include <view/view.h>
#include <view/view_controls.h>
ZOOM_TOOL::ZOOM_TOOL() :

View File

@ -32,6 +32,7 @@
#include <base_struct.h>
#include <convert_to_biu.h>
#include <gr_basic.h>
#include <layers_id_colors_and_visibility.h>
@ -295,18 +296,12 @@ public:
* Circles and arcs are approximated by segments
* @param aCornerBuffer = a buffer to store the polygon
* @param aClearanceValue = the clearance around the pad
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aCorrectionFactor = the correction to apply to circles radius to keep
* clearance when the circle is approximated by segment bigger or equal
* to the real clearance value (usually near from 1.0)
* @param aError = the maximum deviation from true circle
* @param ignoreLineWidth = used for edge cut items where the line width is only
* for visualization
*/
virtual void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
int aClearanceValue,
int aCircleToSegmentsCount,
double aCorrectionFactor,
bool ignoreLineWidth = false ) const;
int aClearanceValue, int aError = ARC_LOW_DEF, bool ignoreLineWidth = false ) const;
};
#endif /* BOARD_ITEM_STRUCT_H */

View File

@ -181,13 +181,6 @@ protected:
*/
virtual bool doAutoSave();
/**
* Return the wxConfigBase used in SaveSettings().
*
* This is overloaded in #KICAD_MANAGER_FRAME
*/
virtual wxConfigBase* config();
/**
* Return a SEARCH_STACK pertaining to entire program.
*
@ -230,8 +223,14 @@ public:
void PrintMsg( const wxString& text );
/**
* Returns the wxConfigBase used in SaveSettings(), and is overloaded in
* KICAD_MANAGER_FRAME
*/
virtual wxConfigBase* config();
/**
* Function InstallPreferences
* Allow a frame to load its preference panels (if any) into the preferences dialog.
*
* @param aParent a paged dialog into which the preference panels should be installed
*/
virtual void InstallPreferences( PAGED_DIALOG* aParent ) { }

View File

@ -31,6 +31,8 @@
#ifndef ID_H_
#define ID_H_
#include <wx/defs.h>
/**
* Common command IDs shared by more than one of the KiCad applications.
*

View File

@ -61,12 +61,6 @@ struct TSEGM_2_POLY_PRMS {
};
TSEGM_2_POLY_PRMS prms;
// The max error is the distance between the middle of a segment, and the circle
// for circle/arc to segment approximation.
// Warning: too small values can create very long calculation time in zone filling
// 0.05 to 0.01 mm is a reasonable value
double s_error_max = Millimeter2iu( 0.02 );
// This is a call back function, used by DrawGraphicText to draw the 3D text shape:
static void addTextSegmToPoly( int x0, int y0, int xf, int yf, void* aData )
{
@ -79,29 +73,22 @@ static void addTextSegmToPoly( int x0, int y0, int xf, int yf, void* aData )
void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer, SHAPE_POLY_SET& aOutlines )
{
// Number of segments to convert a circle to a polygon
const int segcountforcircle = ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF;
double correctionFactor = GetCircletoPolyCorrectionFactor( segcountforcircle );
// convert tracks and vias:
for( TRACK* track = m_Track; track != NULL; track = track->Next() )
{
if( !track->IsOnLayer( aLayer ) )
continue;
track->TransformShapeWithClearanceToPolygon( aOutlines,
0, segcountforcircle, correctionFactor );
track->TransformShapeWithClearanceToPolygon( aOutlines, 0 );
}
// convert pads
for( MODULE* module = m_Modules; module != NULL; module = module->Next() )
{
module->TransformPadsShapesWithClearanceToPolygon( aLayer,
aOutlines, 0, segcountforcircle, correctionFactor );
module->TransformPadsShapesWithClearanceToPolygon( aLayer, aOutlines, 0 );
// Micro-wave modules may have items on copper layers
module->TransformGraphicShapesWithClearanceToPolygonSet( aLayer,
aOutlines, 0, segcountforcircle, correctionFactor );
module->TransformGraphicShapesWithClearanceToPolygonSet( aLayer, aOutlines, 0 );
}
// convert copper zones
@ -111,8 +98,7 @@ void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer, SHAPE_POLY_
PCB_LAYER_ID zonelayer = zone->GetLayer();
if( zonelayer == aLayer )
zone->TransformSolidAreasShapesToPolygonSet(
aOutlines, segcountforcircle, correctionFactor );
zone->TransformSolidAreasShapesToPolygonSet( aOutlines );
}
// convert graphic items on copper layers (texts)
@ -124,13 +110,11 @@ void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer, SHAPE_POLY_
switch( item->Type() )
{
case PCB_LINE_T:
( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon(
aOutlines, 0, segcountforcircle, correctionFactor );
( (DRAWSEGMENT*) item )->TransformShapeWithClearanceToPolygon( aOutlines, 0 );
break;
case PCB_TEXT_T:
( (TEXTE_PCB*) item )->TransformShapeWithClearanceToPolygonSet(
aOutlines, 0, segcountforcircle, correctionFactor );
( (TEXTE_PCB*) item )->TransformShapeWithClearanceToPolygonSet( aOutlines, 0 );
break;
default:
@ -141,11 +125,8 @@ void BOARD::ConvertBrdLayerToPolygonalContours( PCB_LAYER_ID aLayer, SHAPE_POLY_
void MODULE::TransformPadsShapesWithClearanceToPolygon( PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aCornerBuffer,
int aInflateValue,
int aCircleToSegmentsCount,
double aCorrectionFactor,
bool aSkipNPTHPadsWihNoCopper ) const
SHAPE_POLY_SET& aCornerBuffer, int aInflateValue, int aMaxError,
bool aSkipNPTHPadsWihNoCopper ) const
{
D_PAD* pad = PadsList();
@ -198,8 +179,7 @@ void MODULE::TransformPadsShapesWithClearanceToPolygon( PCB_LAYER_ID aLayer,
break;
}
pad->BuildPadShapePolygon( aCornerBuffer, margin,
aCircleToSegmentsCount, aCorrectionFactor );
pad->BuildPadShapePolygon( aCornerBuffer, margin );
}
}
@ -214,14 +194,8 @@ void MODULE::TransformPadsShapesWithClearanceToPolygon( PCB_LAYER_ID aLayer,
* the radius of circle approximated by segments is
* initial radius * aCorrectionFactor
*/
void MODULE::TransformGraphicShapesWithClearanceToPolygonSet(
PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aCornerBuffer,
int aInflateValue,
int aCircleToSegmentsCount,
double aCorrectionFactor,
int aCircleToSegmentsCountForTexts,
bool aIncludeText ) const
void MODULE::TransformGraphicShapesWithClearanceToPolygonSet( PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aCornerBuffer, int aInflateValue, int aError, bool aIncludeText ) const
{
std::vector<TEXTE_MODULE *> texts; // List of TEXTE_MODULE to convert
EDGE_MODULE* outline;
@ -231,15 +205,14 @@ void MODULE::TransformGraphicShapesWithClearanceToPolygonSet(
switch( item->Type() )
{
case PCB_MODULE_TEXT_T:
{
TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
{
TEXTE_MODULE* text = static_cast<TEXTE_MODULE*>( item );
if( ( aLayer != UNDEFINED_LAYER && text->GetLayer() == aLayer )
&& text->IsVisible() )
texts.push_back( text );
if( ( aLayer != UNDEFINED_LAYER && text->GetLayer() == aLayer ) && text->IsVisible() )
texts.push_back( text );
break;
}
break;
}
case PCB_MODULE_EDGE_T:
outline = (EDGE_MODULE*) item;
@ -247,12 +220,11 @@ void MODULE::TransformGraphicShapesWithClearanceToPolygonSet(
if( aLayer != UNDEFINED_LAYER && outline->GetLayer() != aLayer )
break;
outline->TransformShapeWithClearanceToPolygon( aCornerBuffer, 0,
aCircleToSegmentsCount, aCorrectionFactor );
outline->TransformShapeWithClearanceToPolygon( aCornerBuffer, 0, aError );
break;
default:
break;
default:
break;
}
}
@ -268,16 +240,12 @@ void MODULE::TransformGraphicShapesWithClearanceToPolygonSet(
prms.m_cornerBuffer = &aCornerBuffer;
// To allow optimization of circles approximated by segments,
// aCircleToSegmentsCountForTexts, when not 0, is used.
// if 0 (default value) the aCircleToSegmentsCount is used
prms.m_textCircle2SegmentCount = aCircleToSegmentsCountForTexts ?
aCircleToSegmentsCountForTexts : aCircleToSegmentsCount;
for( unsigned ii = 0; ii < texts.size(); ii++ )
{
TEXTE_MODULE *textmod = texts[ii];
prms.m_textWidth = textmod->GetThickness() + ( 2 * aInflateValue );
prms.m_textCircle2SegmentCount =
std::max( GetArcToSegmentCount( prms.m_textWidth / 2, aError, 360.0 ), 6 );
wxSize size = textmod->GetTextSize();
if( textmod->IsMirrored() )
@ -296,12 +264,7 @@ void MODULE::TransformGraphicShapesWithClearanceToPolygonSet(
// Same as function TransformGraphicShapesWithClearanceToPolygonSet but
// this only render text
void MODULE::TransformGraphicTextWithClearanceToPolygonSet(
PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aCornerBuffer,
int aInflateValue,
int aCircleToSegmentsCount,
double aCorrectionFactor,
int aCircleToSegmentsCountForTexts ) const
PCB_LAYER_ID aLayer, SHAPE_POLY_SET& aCornerBuffer, int aInflateValue, int aError ) const
{
std::vector<TEXTE_MODULE *> texts; // List of TEXTE_MODULE to convert
@ -337,16 +300,12 @@ void MODULE::TransformGraphicTextWithClearanceToPolygonSet(
prms.m_cornerBuffer = &aCornerBuffer;
// To allow optimization of circles approximated by segments,
// aCircleToSegmentsCountForTexts, when not 0, is used.
// if 0 (default value) the aCircleToSegmentsCount is used
prms.m_textCircle2SegmentCount = aCircleToSegmentsCountForTexts ?
aCircleToSegmentsCountForTexts : aCircleToSegmentsCount;
for( unsigned ii = 0; ii < texts.size(); ii++ )
{
TEXTE_MODULE *textmod = texts[ii];
prms.m_textWidth = textmod->GetThickness() + ( 2 * aInflateValue );
prms.m_textCircle2SegmentCount =
std::max( GetArcToSegmentCount( prms.m_textWidth / 2, aError, 360.0 ), 6 );
wxSize size = textmod->GetTextSize();
if( textmod->IsMirrored() )
@ -361,24 +320,15 @@ void MODULE::TransformGraphicTextWithClearanceToPolygonSet(
}
/* Function TransformSolidAreasShapesToPolygonSet
* Convert solid areas full shapes to polygon set
* (the full shape is the polygon area with a thick outline)
* Used in 3D view
* Arcs (ends of segments) are approximated by segments
* aCornerBuffer = a buffer to store the polygons
* aCircleToSegmentsCount = the number of segments to approximate a circle
* aCorrectionFactor = the correction to apply to arcs radius to roughly
* keep arc radius when approximated by segments
*/
void ZONE_CONTAINER::TransformSolidAreasShapesToPolygonSet(
SHAPE_POLY_SET& aCornerBuffer,
int aCircleToSegmentsCount,
double aCorrectionFactor ) const
SHAPE_POLY_SET& aCornerBuffer, int aError ) const
{
if( GetFilledPolysList().IsEmpty() )
return;
int numSegs = std::max( GetArcToSegmentCount( GetMinThickness() / 2, aError, 360.0 ), 6 );
// add filled areas polygons
aCornerBuffer.Append( m_FilledPolysList );
@ -392,24 +342,15 @@ void ZONE_CONTAINER::TransformSolidAreasShapesToPolygonSet(
const VECTOR2I& a = path.CPoint( j );
const VECTOR2I& b = path.CPoint( j + 1 );
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, wxPoint( a.x, a.y ), wxPoint( b.x, b.y ),
aCircleToSegmentsCount,
GetMinThickness() );
TransformRoundedEndsSegmentToPolygon( aCornerBuffer, wxPoint( a.x, a.y ),
wxPoint( b.x, b.y ), numSegs, GetMinThickness() );
}
}
}
/**
* Function TransformBoundingBoxWithClearanceToPolygon
* Convert the text bounding box to a rectangular polygon
* Used in filling zones calculations
* Circles and arcs are approximated by segments
* @param aCornerBuffer = a buffer to store the polygon
* @param aClearanceValue = the clearance around the text bounding box
*/
void EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon(
SHAPE_POLY_SET* aCornerBuffer,
int aClearanceValue ) const
SHAPE_POLY_SET* aCornerBuffer, int aClearanceValue ) const
{
// Oh dear. When in UTF-8 mode, wxString puts string iterators in a linked list, and
// that linked list is not thread-safe.
@ -455,10 +396,7 @@ void EDA_TEXT::TransformBoundingBoxWithClearanceToPolygon(
*/
void TEXTE_PCB::TransformShapeWithClearanceToPolygonSet(
SHAPE_POLY_SET& aCornerBuffer,
int aClearanceValue,
int aCircleToSegmentsCount,
double aCorrectionFactor ) const
SHAPE_POLY_SET& aCornerBuffer, int aClearanceValue, int aError ) const
{
wxSize size = GetTextSize();
@ -466,8 +404,9 @@ void TEXTE_PCB::TransformShapeWithClearanceToPolygonSet(
size.x = -size.x;
prms.m_cornerBuffer = &aCornerBuffer;
prms.m_textWidth = GetThickness() + ( 2 * aClearanceValue );
prms.m_textCircle2SegmentCount = aCircleToSegmentsCount;
prms.m_textWidth = GetThickness() + ( 2 * aClearanceValue );
prms.m_textCircle2SegmentCount =
std::max( GetArcToSegmentCount( prms.m_textWidth / 2, aError, 360.0 ), 6 );
COLOR4D color = COLOR4D::BLACK; // not actually used, but needed by DrawGraphicText
if( IsMultilineAllowed() )
@ -499,61 +438,39 @@ void TEXTE_PCB::TransformShapeWithClearanceToPolygonSet(
}
/**
* Function TransformShapeWithClearanceToPolygon
* Convert the track shape to a closed polygon
* Used in filling zones calculations
* Circles and arcs are approximated by segments
* @param aCornerBuffer = a buffer to store the polygon
* @param aClearanceValue = the clearance around the pad
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aCorrectionFactor = the correction to apply to circles radius to keep
* clearance when the circle is approxiamted by segment bigger or equal
* to the real clearance value (usually near from 1.0)
* @param ignoreLineWidth = used for edge cut items where the line width is only
* for visualization
*/
void DRAWSEGMENT::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
int aClearanceValue,
int aCircleToSegmentsCount,
double aCorrectionFactor,
bool ignoreLineWidth ) const
void DRAWSEGMENT::TransformShapeWithClearanceToPolygon(
SHAPE_POLY_SET& aCornerBuffer, int aClearanceValue, int aError, bool ignoreLineWidth ) const
{
// The full width of the lines to create:
int linewidth = ignoreLineWidth ? 0 : m_Width;
linewidth += 2 * aClearanceValue;
int numSegs = std::max( GetArcToSegmentCount( linewidth / 2, aError, 360.0 ), 6 );
double correction = GetCircletoPolyCorrectionFactor( numSegs );
// Creating a reliable clearance shape for circles and arcs is not so easy, due to
// the error created by segment approximation.
// for a cicle this is not so hard: create a polygon from a circle slightly bigger:
// for a circle this is not so hard: create a polygon from a circle slightly bigger:
// thickness = linewidth + s_error_max, and radius = initial radius + s_error_max/2
// giving a shape with a suitable internal radius and external radius
// For an arc this is more tricky: TODO
if( m_Shape == S_CIRCLE || m_Shape == S_ARC )
{
int segCount = GetArcToSegmentCount( GetRadius(), s_error_max, 360.0 );
if( segCount > aCircleToSegmentsCount )
aCircleToSegmentsCount = segCount;
}
switch( m_Shape )
{
case S_CIRCLE:
TransformRingToPolygon( aCornerBuffer, GetCenter(), GetRadius() + (s_error_max/2),
aCircleToSegmentsCount, linewidth + s_error_max ) ;
TransformRingToPolygon(
aCornerBuffer, GetCenter(), GetRadius(), numSegs, correction * linewidth );
break;
case S_ARC:
TransformArcToPolygon( aCornerBuffer, GetCenter(),
GetArcStart(), m_Angle,
aCircleToSegmentsCount, linewidth );
TransformArcToPolygon(
aCornerBuffer, GetCenter(), GetArcStart(), m_Angle, numSegs, linewidth );
break;
case S_SEGMENT:
TransformOvalClearanceToPolygon( aCornerBuffer, m_Start, m_End, linewidth,
aCircleToSegmentsCount, aCorrectionFactor );
TransformOvalClearanceToPolygon(
aCornerBuffer, m_Start, m_End, linewidth, numSegs, correction );
break;
case S_POLYGON:
@ -583,12 +500,12 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerB
{
for( size_t ii = 1; ii < poly.size(); ii++ )
{
TransformOvalClearanceToPolygon( aCornerBuffer, poly[ii - 1], poly[ii],
linewidth, aCircleToSegmentsCount, aCorrectionFactor );
TransformOvalClearanceToPolygon(
aCornerBuffer, poly[ii - 1], poly[ii], linewidth, numSegs, correction );
}
TransformOvalClearanceToPolygon( aCornerBuffer, poly.back(), poly.front(),
linewidth, aCircleToSegmentsCount, aCorrectionFactor );
TransformOvalClearanceToPolygon(
aCornerBuffer, poly.back(), poly.front(), linewidth, numSegs, correction );
break;
}
@ -612,8 +529,8 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerB
if( corner2 != corner1 )
{
TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
corner1, corner2, aCircleToSegmentsCount, linewidth );
TransformRoundedEndsSegmentToPolygon(
aCornerBuffer, corner1, corner2, numSegs, linewidth );
}
corner1 = corner2;
@ -631,8 +548,8 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerB
for( unsigned ii = 1; ii < poly.size(); ii++ )
{
TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
poly[ii-1], poly[ii], aCircleToSegmentsCount, linewidth );
TransformRoundedEndsSegmentToPolygon(
aCornerBuffer, poly[ii - 1], poly[ii], numSegs, linewidth );
}
}
break;
@ -643,66 +560,34 @@ void DRAWSEGMENT::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerB
}
/**
* Function TransformShapeWithClearanceToPolygon
* Convert the track shape to a closed polygon
* Used in filling zones calculations
* Circles (vias) and arcs (ends of tracks) are approximated by segments
* @param aCornerBuffer = a buffer to store the polygon
* @param aClearanceValue = the clearance around the pad
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aCorrectionFactor = the correction to apply to circles radius to keep
* clearance when the circle is approximated by segment bigger or equal
* to the real clearance value (usually near from 1.0)
* @param ignoreLineWidth = used for edge cut items where the line width is only
* for visualization
*/
void TRACK::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
int aClearanceValue,
int aCircleToSegmentsCount,
double aCorrectionFactor,
bool ignoreLineWidth ) const
void TRACK::TransformShapeWithClearanceToPolygon(
SHAPE_POLY_SET& aCornerBuffer, int aClearanceValue, int aError, bool ignoreLineWidth ) const
{
wxASSERT_MSG( !ignoreLineWidth, "IgnoreLineWidth has no meaning for tracks." );
int radius = ( m_Width / 2 ) + aClearanceValue;
int numSegs = std::max( GetArcToSegmentCount( radius, aError, 360.0 ), 6 );
double correction = GetCircletoPolyCorrectionFactor( numSegs );
switch( Type() )
{
case PCB_VIA_T:
{
int radius = (m_Width / 2) + aClearanceValue;
radius = KiROUND( radius * aCorrectionFactor );
TransformCircleToPolygon( aCornerBuffer, m_Start, radius, aCircleToSegmentsCount );
radius = KiROUND( radius * correction );
TransformCircleToPolygon( aCornerBuffer, m_Start, radius, numSegs );
}
break;
default:
TransformOvalClearanceToPolygon( aCornerBuffer, m_Start, m_End,
m_Width + ( 2 * aClearanceValue),
aCircleToSegmentsCount,
aCorrectionFactor );
m_Width + ( 2 * aClearanceValue ), numSegs, correction );
break;
}
}
/* Function TransformShapeWithClearanceToPolygon
* Convert the pad shape to a closed polygon
* Used in filling zones calculations and 3D view generation
* Circles and arcs are approximated by segments
* aCornerBuffer = a SHAPE_POLY_SET to store the polygon corners
* aClearanceValue = the clearance around the pad
* aCircleToSegmentsCount = the number of segments to approximate a circle
* aCorrectionFactor = the correction to apply to circles radius to keep
* clearance when the circle is approximated by segment bigger or equal
* to the real clearance value (usually near from 1.0)
* @param ignoreLineWidth = used for edge cut items where the line width is only
* for visualization
*/
void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
int aClearanceValue,
int aCircleToSegmentsCount,
double aCorrectionFactor,
bool ignoreLineWidth ) const
void D_PAD::TransformShapeWithClearanceToPolygon(
SHAPE_POLY_SET& aCornerBuffer, int aClearanceValue, int aError, bool ignoreLineWidth ) const
{
wxASSERT_MSG( !ignoreLineWidth, "IgnoreLineWidth has no meaning for pads." );
@ -716,9 +601,12 @@ void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
switch( GetShape() )
{
case PAD_SHAPE_CIRCLE:
dx = KiROUND( dx * aCorrectionFactor );
TransformCircleToPolygon( aCornerBuffer, padShapePos, dx,
aCircleToSegmentsCount );
{
int numSegs = std::max( GetArcToSegmentCount( dx, aError, 360.0 ), 6 );
double correction = GetCircletoPolyCorrectionFactor( numSegs );
dx = KiROUND( dx * correction );
TransformCircleToPolygon( aCornerBuffer, padShapePos, dx, numSegs );
}
break;
case PAD_SHAPE_OVAL:
@ -737,11 +625,13 @@ void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
width = dy * 2;
}
int numSegs = std::max( GetArcToSegmentCount( width / 2, aError, 360.0 ), 6 );
double correction = GetCircletoPolyCorrectionFactor( numSegs );
RotatePoint( &shape_offset, angle );
wxPoint start = padShapePos - shape_offset;
wxPoint end = padShapePos + shape_offset;
TransformOvalClearanceToPolygon( aCornerBuffer, start, end, width,
aCircleToSegmentsCount, aCorrectionFactor );
TransformOvalClearanceToPolygon( aCornerBuffer, start, end, width, numSegs, correction );
}
break;
@ -760,8 +650,11 @@ void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
outline.Append( corners[ii].x, corners[ii].y );
}
int rounding_radius = int( aClearanceValue * aCorrectionFactor );
outline.Inflate( rounding_radius, aCircleToSegmentsCount );
int numSegs = std::max( GetArcToSegmentCount( aClearanceValue, aError, 360.0 ), 6 );
double correction = GetCircletoPolyCorrectionFactor( numSegs );
int rounding_radius = KiROUND( aClearanceValue * correction );
outline.Inflate( rounding_radius, numSegs );
aCornerBuffer.Append( outline );
}
@ -771,18 +664,20 @@ void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
case PAD_SHAPE_ROUNDRECT:
{
SHAPE_POLY_SET outline;
int clearance = int( aClearanceValue * aCorrectionFactor );
int rounding_radius = GetRoundRectCornerRadius() + clearance;
wxSize shapesize( m_Size );
int radius = GetRoundRectCornerRadius() + aClearanceValue;
int numSegs = std::max( GetArcToSegmentCount( radius, aError, 360.0 ), 6 );
double correction = GetCircletoPolyCorrectionFactor( numSegs );
int clearance = KiROUND( aClearanceValue * correction );
int rounding_radius = GetRoundRectCornerRadius() + clearance;
wxSize shapesize( m_Size );
shapesize.x += clearance*2;
shapesize.y += clearance*2;
bool doChamfer = GetShape() == PAD_SHAPE_CHAMFERED_RECT;
TransformRoundChamferedRectToPolygon( outline, padShapePos, shapesize, angle,
rounding_radius,
doChamfer ? GetChamferRectRatio() : 0.0,
doChamfer ? GetChamferPositions() : 0,
aCircleToSegmentsCount );
rounding_radius, doChamfer ? GetChamferRectRatio() : 0.0,
doChamfer ? GetChamferPositions() : 0, numSegs );
aCornerBuffer.Append( outline );
}
@ -790,12 +685,14 @@ void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
case PAD_SHAPE_CUSTOM:
{
int clearance = KiROUND( aClearanceValue * aCorrectionFactor );
int numSegs = std::max( GetArcToSegmentCount( aClearanceValue, aError, 360.0 ), 6 );
double correction = GetCircletoPolyCorrectionFactor( numSegs );
int clearance = KiROUND( aClearanceValue * correction );
SHAPE_POLY_SET outline; // Will contain the corners in board coordinates
outline.Append( m_customShapeAsPolygon );
CustomShapeAsPolygonToBoardPosition( &outline, GetPosition(), GetOrientation() );
outline.Simplify( SHAPE_POLY_SET::PM_FAST );
outline.Inflate( clearance, aCircleToSegmentsCount );
outline.Inflate( clearance, numSegs );
outline.Fracture( SHAPE_POLY_SET::PM_FAST );
aCornerBuffer.Append( outline );
}
@ -812,9 +709,8 @@ void D_PAD::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
* Note: for Round and oval pads this function is equivalent to
* TransformShapeWithClearanceToPolygon, but not for other shapes
*/
void D_PAD::BuildPadShapePolygon( SHAPE_POLY_SET& aCornerBuffer,
wxSize aInflateValue, int aSegmentsPerCircle,
double aCorrectionFactor ) const
void D_PAD::BuildPadShapePolygon(
SHAPE_POLY_SET& aCornerBuffer, wxSize aInflateValue, int aError ) const
{
wxPoint corners[4];
wxPoint padShapePos = ShapePos(); /* Note: for pad having a shape offset,
@ -834,8 +730,7 @@ void D_PAD::BuildPadShapePolygon( SHAPE_POLY_SET& aCornerBuffer,
// a wxSize to inflate the pad size
D_PAD dummy( *this );
dummy.SetSize( GetSize() + aInflateValue + aInflateValue );
dummy.TransformShapeWithClearanceToPolygon( aCornerBuffer, 0,
aSegmentsPerCircle, aCorrectionFactor );
dummy.TransformShapeWithClearanceToPolygon( aCornerBuffer, 0 );
}
break;
@ -856,21 +751,15 @@ void D_PAD::BuildPadShapePolygon( SHAPE_POLY_SET& aCornerBuffer,
// for a custom shape, that is in fact a polygon (with holes), we can use only a inflate value.
// so use ( aInflateValue.x + aInflateValue.y ) / 2 as polygon inflate value.
// (different values for aInflateValue.x and aInflateValue.y has no sense for a custom pad)
TransformShapeWithClearanceToPolygon( aCornerBuffer,
( aInflateValue.x + aInflateValue.y ) / 2,
aSegmentsPerCircle, aCorrectionFactor );
TransformShapeWithClearanceToPolygon(
aCornerBuffer, ( aInflateValue.x + aInflateValue.y ) / 2 );
break;
}
}
/*
* Function BuildPadDrillShapePolygon
* Build the Corner list of the polygonal drill shape,
* depending on shape pad hole and orientation
* return false if the pad has no hole, true otherwise
*/
bool D_PAD::BuildPadDrillShapePolygon( SHAPE_POLY_SET& aCornerBuffer,
int aInflateValue, int aSegmentsPerCircle ) const
bool D_PAD::BuildPadDrillShapePolygon(
SHAPE_POLY_SET& aCornerBuffer, int aInflateValue, int aError ) const
{
wxSize drillsize = GetDrillSize();
@ -879,8 +768,9 @@ bool D_PAD::BuildPadDrillShapePolygon( SHAPE_POLY_SET& aCornerBuffer,
if( drillsize.x == drillsize.y ) // usual round hole
{
TransformCircleToPolygon( aCornerBuffer, GetPosition(),
(drillsize.x / 2) + aInflateValue, aSegmentsPerCircle );
int radius = ( drillsize.x / 2 ) + aInflateValue;
int numSegs = std::max( GetArcToSegmentCount( radius, aError, 360.0 ), 6 );
TransformCircleToPolygon( aCornerBuffer, GetPosition(), radius, numSegs );
}
else // Oblong hole
{
@ -890,9 +780,10 @@ bool D_PAD::BuildPadDrillShapePolygon( SHAPE_POLY_SET& aCornerBuffer,
GetOblongDrillGeometry( start, end, width );
width += aInflateValue * 2;
int numSegs = std::max( GetArcToSegmentCount( width / 2, aError, 360.0 ), 6 );
TransformRoundedEndsSegmentToPolygon( aCornerBuffer,
GetPosition() + start, GetPosition() + end, aSegmentsPerCircle, width );
TransformRoundedEndsSegmentToPolygon(
aCornerBuffer, GetPosition() + start, GetPosition() + end, numSegs, width );
}
return true;
@ -907,8 +798,7 @@ bool D_PAD::BuildPadDrillShapePolygon( SHAPE_POLY_SET& aCornerBuffer,
* @param aThermalGap = gap in thermal shape
* @param aCopperThickness = stubs thickness in thermal shape
* @param aMinThicknessValue = min copper thickness allowed
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aCorrectionFactor = the correction to apply to circles radius to keep
* @param aError = maximum error allowed when approximating arcs
* @param aThermalRot = for rond pads the rotation of thermal stubs (450 usually for 45 deg.)
*/
@ -926,21 +816,18 @@ bool D_PAD::BuildPadDrillShapePolygon( SHAPE_POLY_SET& aCornerBuffer,
* and are used in microwave applications and they *DO NOT* have a thermal relief that
* change the shape by creating stubs and destroy their properties.
*/
void CreateThermalReliefPadPolygon( SHAPE_POLY_SET& aCornerBuffer,
const D_PAD& aPad,
int aThermalGap,
int aCopperThickness,
int aMinThicknessValue,
int aCircleToSegmentsCount,
double aCorrectionFactor,
double aThermalRot )
void CreateThermalReliefPadPolygon( SHAPE_POLY_SET& aCornerBuffer,
const D_PAD& aPad,
int aThermalGap,
int aCopperThickness,
int aMinThicknessValue,
int aError,
double aThermalRot )
{
wxPoint corner, corner_end;
wxSize copper_thickness;
wxPoint padShapePos = aPad.ShapePos(); // Note: for pad having a shape offset,
// the pad position is NOT the shape position
wxSize copper_thickness;
double delta = 3600.0 / aCircleToSegmentsCount; // rot angle in 0.1 degree
/* Keep in account the polygon outline thickness
* aThermalGap must be increased by aMinThicknessValue/2 because drawing external outline
@ -984,8 +871,12 @@ void CreateThermalReliefPadPolygon( SHAPE_POLY_SET& aCornerBuffer,
// The pattern roughtly is a 90 deg arc pie
std::vector <wxPoint> corners_buffer;
int numSegs = std::max( GetArcToSegmentCount( dx + aThermalGap, aError, 360.0 ), 6 );
double correction = GetCircletoPolyCorrectionFactor( numSegs );
double delta = 3600.0 / numSegs;
// Radius of outer arcs of the shape corrected for arc approximation by lines
int outer_radius = KiROUND( (dx + aThermalGap) * aCorrectionFactor );
int outer_radius = KiROUND( ( dx + aThermalGap ) * correction );
// Crosspoint of thermal spoke sides, the first point of polygon buffer
corners_buffer.push_back( wxPoint( copper_thickness.x / 2, copper_thickness.y / 2 ) );
@ -1006,7 +897,7 @@ void CreateThermalReliefPadPolygon( SHAPE_POLY_SET& aCornerBuffer,
( (double) corner.x * corner.x ) ) );
RotatePoint( &corner, 90 ); // 9 degrees is the spoke fillet size
// calculate the ending point of the outter arc
// calculate the ending point of the outer arc
corner_end.x = corner.y;
corner_end.y = corner.x;
@ -1074,6 +965,10 @@ void CreateThermalReliefPadPolygon( SHAPE_POLY_SET& aCornerBuffer,
// Radius of outer arcs of the shape:
int outer_radius = dy; // The radius of the outer arc is radius end + aThermalGap
int numSegs = std::max( GetArcToSegmentCount( outer_radius, aError, 360.0 ), 6 );
double delta = 3600.0 / numSegs;
// Some coordinate fiddling, depending on the shape offset direction
shape_offset = wxPoint( deltasize, 0 );
@ -1236,11 +1131,13 @@ void CreateThermalReliefPadPolygon( SHAPE_POLY_SET& aCornerBuffer,
wxPoint arc_start_point( -(aThermalGap / 4 + copper_thickness.x / 2) , -dy );
corners_buffer.push_back( arc_start_point );
int rounding_radius = KiROUND( aThermalGap * aCorrectionFactor ); // Corner rounding radius
int numSegs = std::max( GetArcToSegmentCount( aThermalGap, aError, 360.0 ), 6 );
double correction = GetCircletoPolyCorrectionFactor( numSegs );
int rounding_radius = KiROUND( aThermalGap * correction ); // Corner rounding radius
// Calculate arc angle parameters.
// the start angle id near 900 decidegrees, the final angle is near 1800.0 decidegrees.
double arc_increment = 3600.0 / aCircleToSegmentsCount;
double arc_increment = 3600.0 / numSegs;
// the arc_angle_start is 900.0 or slighly more, depending on the actual arc starting point
double arc_angle_start = atan2( -arc_start_point.y -corner_origin_pos.y, arc_start_point.x - corner_origin_pos.x ) * 1800/M_PI;
@ -1319,8 +1216,7 @@ void CreateThermalReliefPadPolygon( SHAPE_POLY_SET& aCornerBuffer,
EDA_RECT bbox = aPad.GetBoundingBox();
int stub_len = std::max( bbox.GetWidth(), bbox.GetHeight() );
aPad.TransformShapeWithClearanceToPolygon( antipad, aThermalGap,
aCircleToSegmentsCount, aCorrectionFactor );
aPad.TransformShapeWithClearanceToPolygon( antipad, aThermalGap );
SHAPE_POLY_SET stub; // A basic stub ( a rectangle)
SHAPE_POLY_SET stubs; // the full stubs shape
@ -1388,11 +1284,8 @@ void CreateThermalReliefPadPolygon( SHAPE_POLY_SET& aCornerBuffer,
}
}
void ZONE_CONTAINER::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
int aClearanceValue,
int aCircleToSegmentsCount,
double aCorrectionFactor,
bool ignoreLineWidth ) const
void ZONE_CONTAINER::TransformShapeWithClearanceToPolygon(
SHAPE_POLY_SET& aCornerBuffer, int aClearanceValue, int aError, bool ignoreLineWidth ) const
{
wxASSERT_MSG( !ignoreLineWidth, "IgnoreLineWidth has no meaning for zones." );

View File

@ -140,11 +140,8 @@ void BOARD_ITEM::SwapData( BOARD_ITEM* aImage )
}
void BOARD_ITEM::TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
int aClearanceValue,
int aCircleToSegmentsCount,
double aCorrectionFactor,
bool ignoreLineWidth ) const
void BOARD_ITEM::TransformShapeWithClearanceToPolygon(
SHAPE_POLY_SET& aCornerBuffer, int aClearanceValue, int aError, bool ignoreLineWidth ) const
{
wxASSERT_MSG( false, "Called TransformShapeWithClearanceToPolygon() on unsupported BOARD_ITEM." );
};

View File

@ -31,9 +31,10 @@
#define CLASS_DRAWSEGMENT_H_
#include <class_board_item.h>
#include <common.h>
#include <convert_to_biu.h>
#include <math_for_graphics.h>
#include <trigo.h>
#include <common.h>
#include <geometry/shape_poly_set.h>
@ -246,18 +247,12 @@ public:
* Circles and arcs are approximated by segments
* @param aCornerBuffer = a buffer to store the polygon
* @param aClearanceValue = the clearance around the pad
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aCorrectionFactor = the correction to apply to circles radius to keep
* clearance when the circle is approximated by segment bigger or equal
* to the real clearance value (usually near from 1.0)
* @param aError = the maximum deviation from a true arc
* @param ignoreLineWidth = used for edge cut items where the line width is only
* for visualization
*/
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
int aClearanceValue,
int aCircleToSegmentsCount,
double aCorrectionFactor,
bool ignoreLineWidth = false ) const override;
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, int aClearanceValue,
int aError = ARC_HIGH_DEF, bool ignoreLineWidth = false ) const override;
virtual wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override;

View File

@ -32,13 +32,14 @@
#define MODULE_H_
#include <list>
#include <dlist.h>
#include <layers_id_colors_and_visibility.h> // ALL_LAYERS definition.
#include <class_board_item.h>
#include <board_item_container.h>
#include <class_board_item.h>
#include <collectors.h>
#include <convert_to_biu.h>
#include <dlist.h>
#include <layers_id_colors_and_visibility.h> // ALL_LAYERS definition.
#include <lib_id.h>
#include <list>
#include <class_text_mod.h>
#include "zones.h"
@ -351,12 +352,7 @@ public:
* @param aCornerBuffer = the buffer to store polygons
* @param aInflateValue = an additionnal size to add to pad shapes
* aInflateValue = 0 to have the exact pad size
* @param aCircleToSegmentsCount = number of segments to generate a circle
* @param aCorrectionFactor = the correction to apply to a circle radius
* to approximate a circle by the polygon.
* if aCorrectionFactor = 1.0, the polygon is inside the circle
* the radius of circle approximated by segments is
* initial radius * aCorrectionFactor
* @param aMaxError = Maximum deviation from true for arcs
* @param aSkipNPTHPadsWihNoCopper = if true, do not add a NPTH pad shape,
* if the shape has same size and position as the hole. Usually, these
* pads are not drawn on copper layers, because there is actually no copper
@ -365,10 +361,7 @@ public:
* default = false
*/
void TransformPadsShapesWithClearanceToPolygon( PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aCornerBuffer,
int aInflateValue,
int aCircleToSegmentsCount,
double aCorrectionFactor,
SHAPE_POLY_SET& aCornerBuffer, int aInflateValue, int aMaxError = ARC_HIGH_DEF,
bool aSkipNPTHPadsWihNoCopper = false ) const;
/**
@ -381,41 +374,25 @@ public:
* @param aCornerBuffer = the buffer to store polygons
* @param aInflateValue = a value to inflate shapes
* aInflateValue = 0 to have the exact shape size
* @param aCircleToSegmentsCount = number of segments to generate a circle
* @param aCorrectionFactor = the correction to apply to a circle radius
* to approximate a circle by the polygon.
* if aCorrectionFactor = 1.0, the polygon is inside the circle
* the radius of circle approximated by segments is
* initial radius * aCorrectionFactor
* @param aCircleToSegmentsCountForTexts = number of segments to generate
* a circle when building the texts polygonal shapes of the stroke font
* if 0, use the aCircleToSegmentsCount value
* @param aError = Maximum error between true arc and polygon approx
* @param aIncludeText = True to transform text shapes
*/
void TransformGraphicShapesWithClearanceToPolygonSet( PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aCornerBuffer,
int aInflateValue,
int aCircleToSegmentsCount,
double aCorrectionFactor,
int aCircleToSegmentsCountForTexts = 0,
SHAPE_POLY_SET& aCornerBuffer, int aInflateValue, int aError = ARC_HIGH_DEF,
bool aIncludeText = true ) const;
/**
* @brief TransformGraphicTextWithClearanceToPolygonSet
* This function is the same as TransformGraphicShapesWithClearanceToPolygonSet
* but only generate text
* @param aLayer
* @param aCornerBuffer
* @param aInflateValue
* @param aCircleToSegmentsCount
* @param aCorrectionFactor
* @param aCircleToSegmentsCountForTexts
* @param aLayer = the layer to consider, or UNDEFINED_LAYER to consider all
* @param aCornerBuffer = the buffer to store polygons
* @param aInflateValue = a value to inflate shapes
* aInflateValue = 0 to have the exact shape size
* @param aError = Maximum error between true arc and polygon approx
*/
void TransformGraphicTextWithClearanceToPolygonSet( PCB_LAYER_ID aLayer,
SHAPE_POLY_SET& aCornerBuffer,
int aInflateValue,
int aCircleToSegmentsCount,
double aCorrectionFactor,
int aCircleToSegmentsCountForTexts = 0 ) const;
SHAPE_POLY_SET& aCornerBuffer, int aInflateValue, int aError = ARC_HIGH_DEF ) const;
/**
* Function DrawEdgesOnly

View File

@ -35,8 +35,9 @@
#include <base_units.h>
#include <bitmaps.h>
#include <view/view.h>
#include <geometry/geometry_utils.h>
#include <pcbnew.h>
#include <view/view.h>
#include <class_board.h>
#include <class_module.h>
@ -936,7 +937,8 @@ bool D_PAD::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
// Check for hit in polygon
SHAPE_POLY_SET outline;
const int segmentToCircleCount = ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF;
int segmentToCircleCount = std::max<int>(
GetArcToSegmentCount( GetRoundRectCornerRadius(), ARC_HIGH_DEF, 360.0 ), 3 );
bool doChamfer = GetShape() == PAD_SHAPE_CHAMFERED_RECT;
TransformRoundChamferedRectToPolygon( outline, wxPoint(0,0), GetSize(), m_Orient,

View File

@ -30,13 +30,14 @@
#ifndef PAD_H_
#define PAD_H_
#include <pcbnew.h>
#include <class_board_item.h>
#include <board_connected_item.h>
#include <pad_shapes.h>
#include <geometry/shape_poly_set.h>
#include <config_params.h> // PARAM_CFG_ARRAY
#include "zones.h"
#include <board_connected_item.h>
#include <class_board_item.h>
#include <config_params.h> // PARAM_CFG_ARRAY
#include <convert_to_biu.h>
#include <geometry/shape_poly_set.h>
#include <pad_shapes.h>
#include <pcbnew.h>
class DRAWSEGMENT;
@ -312,8 +313,7 @@ public:
* (default = 32)
* Note: The corners coordinates are relative to the pad position, orientation 0,
*/
bool MergePrimitivesAsPolygon( SHAPE_POLY_SET * aMergedPolygon = NULL,
int aCircleToSegmentsCount = ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF );
bool MergePrimitivesAsPolygon( SHAPE_POLY_SET* aMergedPolygon = NULL );
/**
* clear the basic shapes list
@ -443,18 +443,12 @@ public:
* Circles and arcs are approximated by segments
* @param aCornerBuffer = a buffer to store the polygon
* @param aClearanceValue = the clearance around the pad
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aCorrectionFactor = the correction to apply to circles radius to keep
* clearance when the circle is approximated by segment bigger or equal
* to the real clearance value (usually near from 1.0)
* @param aMaxError = Maximum error from true when converting arcs
* @param ignoreLineWidth = used for edge cut items where the line width is only
* for visualization
*/
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
int aClearanceValue,
int aCircleToSegmentsCount,
double aCorrectionFactor,
bool ignoreLineWidth = false ) const override;
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, int aClearanceValue,
int aMaxError = ARC_HIGH_DEF, bool ignoreLineWidth = false ) const override;
/**
* Function GetClearance
@ -576,14 +570,10 @@ public:
* value > 0: inflate, < 0 deflate, = 0 : no change
* the clearance can have different values for x and y directions
* (relative to the pad)
* @param aSegmentsPerCircle = number of segments to approximate a circle
* (used for round and oblong shapes only (16 to 32 is a good value)
* @param aCorrectionFactor = the correction to apply to circles radius to keep
* the pad size/clearance when the arcs are approximated by segments
* @param aError = Maximum deviation of an arc from the polygon segment
*/
void BuildPadShapePolygon( SHAPE_POLY_SET& aCornerBuffer,
wxSize aInflateValue, int aSegmentsPerCircle,
double aCorrectionFactor ) const;
void BuildPadShapePolygon(
SHAPE_POLY_SET& aCornerBuffer, wxSize aInflateValue, int aError = ARC_HIGH_DEF ) const;
/**
* Function BuildPadDrillShapePolygon
@ -592,12 +582,11 @@ public:
* @param aCornerBuffer = a buffer to fill.
* @param aInflateValue = the clearance or margin value.
* value > 0: inflate, < 0 deflate, = 0 : no change
* @param aSegmentsPerCircle = number of segments to approximate a circle
* (used for round and oblong shapes only(16 to 32 is a good value)
* @param aError = Maximum deviation of an arc from the polygon approximation
* @return false if the pad has no hole, true otherwise
*/
bool BuildPadDrillShapePolygon( SHAPE_POLY_SET& aCornerBuffer,
int aInflateValue, int aSegmentsPerCircle ) const;
bool BuildPadDrillShapePolygon(
SHAPE_POLY_SET& aCornerBuffer, int aInflateValue, int aError = ARC_HIGH_DEF ) const;
/**
* Function BuildSegmentFromOvalShape
@ -832,8 +821,7 @@ private:
*/
int boundingRadius() const;
bool buildCustomPadPolygon( SHAPE_POLY_SET* aMergedPolygon,
int aCircleToSegmentsCount );
bool buildCustomPadPolygon( SHAPE_POLY_SET* aMergedPolygon, int aError );
private: // Private variable members:

View File

@ -105,15 +105,10 @@ public:
* Circles and arcs are approximated by segments
* @param aCornerBuffer = a buffer to store the polygon
* @param aClearanceValue = the clearance around the text
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aCorrectionFactor = the correction to apply to circles radius to keep
* clearance when the circle is approximated by segment bigger or equal
* to the real clearance value (usually near from 1.0)
* @param aError = deviation from true arc position to segment approx
*/
void TransformShapeWithClearanceToPolygonSet( SHAPE_POLY_SET& aCornerBuffer,
int aClearanceValue,
int aCircleToSegmentsCount,
double aCorrectionFactor ) const;
void TransformShapeWithClearanceToPolygonSet(
SHAPE_POLY_SET& aCornerBuffer, int aClearanceValue, int aError = ARC_HIGH_DEF ) const;
wxString GetSelectMenuText( EDA_UNITS_T aUnits ) const override;

View File

@ -31,10 +31,11 @@
#define CLASS_TRACK_H
#include <pcbnew.h>
#include <class_board_item.h>
#include <board_connected_item.h>
#include <class_board_item.h>
#include <convert_to_biu.h>
#include <pcb_display_options.h>
#include <pcbnew.h>
#include <trigo.h>
@ -199,18 +200,12 @@ public:
* Circles (vias) and arcs (ends of tracks) are approximated by segments
* @param aCornerBuffer = a buffer to store the polygon
* @param aClearanceValue = the clearance around the pad
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aCorrectionFactor = the correction to apply to circles radius to keep
* clearance when the circle is approximated by segment bigger or equal
* to the real clearance value (usually near from 1.0)
* @param aError = the maximum deviation from true circle
* @param ignoreLineWidth = used for edge cut items where the line width is only
* for visualization
*/
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
int aClearanceValue,
int aCircleToSegmentsCount,
double aCorrectionFactor,
bool ignoreLineWidth = false ) const override;
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, int aClearanceValue,
int aError = ARC_HIGH_DEF, bool ignoreLineWidth = false ) const override;
/**
* Function IsPointOnEnds
* returns STARTPOINT if point if near (dist = min_dist) start point, ENDPOINT if

View File

@ -28,16 +28,17 @@
* @brief Implementation of class to handle copper zones.
*/
#include <fctsys.h>
#include <trigo.h>
#include <pcb_screen.h>
#include <class_drawpanel.h>
#include <kicad_string.h>
#include <richio.h>
#include <macros.h>
#include <pcb_base_frame.h>
#include <msgpanel.h>
#include <bitmaps.h>
#include <class_drawpanel.h>
#include <fctsys.h>
#include <geometry/geometry_utils.h>
#include <kicad_string.h>
#include <macros.h>
#include <msgpanel.h>
#include <pcb_base_frame.h>
#include <pcb_screen.h>
#include <richio.h>
#include <trigo.h>
#include <convert_to_biu.h>
#include <class_board.h>
@ -1304,12 +1305,7 @@ bool ZONE_CONTAINER::BuildSmoothedPoly( SHAPE_POLY_SET& aSmoothedPoly ) const
break;
case ZONE_SETTINGS::SMOOTHING_FILLET:
// Note: we're now using m_ArcToSegmentsCount only as a hint to determine accuracy
// vs. speed.
if( m_ArcToSegmentsCount > SEGMENT_COUNT_CROSSOVER )
aSmoothedPoly = m_Poly->Fillet( m_cornerRadius, ARC_HIGH_DEF );
else
aSmoothedPoly = m_Poly->Fillet( m_cornerRadius, ARC_LOW_DEF );
aSmoothedPoly = m_Poly->Fillet( m_cornerRadius, ARC_HIGH_DEF );
break;
default:
@ -1353,8 +1349,10 @@ void ZONE_CONTAINER::TransformOutlinesShapeWithClearanceToPolygon(
// Calculate the polygon with clearance
// holes are linked to the main outline, so only one polygon is created.
if( clearance )
polybuffer.Inflate( clearance, ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF );
{
int segCount = std::max( GetArcToSegmentCount( clearance, ARC_HIGH_DEF, 360.0 ), 3 );
polybuffer.Inflate( clearance, segCount );
}
polybuffer.Fracture( SHAPE_POLY_SET::PM_FAST );
aCornerBuffer.Append( polybuffer );
}

View File

@ -290,22 +290,19 @@ public:
*/
bool HitTestFilledArea( const wxPoint& aRefPos ) const;
/**
/**
* Function TransformSolidAreasShapesToPolygonSet
* Convert solid areas full shapes to polygon set
* (the full shape is the polygon area with a thick outline)
* Used in 3D view
* Arcs (ends of segments) are approximated by segments
* @param aCornerBuffer = a buffer to store the polygons
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aCorrectionFactor = the correction to apply to arcs radius to roughly
* keep arc radius when approximated by segments
* @param aError = Maximum error allowed between true arc and polygon approx
*/
void TransformSolidAreasShapesToPolygonSet( SHAPE_POLY_SET& aCornerBuffer,
int aCircleToSegmentsCount,
double aCorrectionFactor ) const;
void TransformSolidAreasShapesToPolygonSet(
SHAPE_POLY_SET& aCornerBuffer, int aError = ARC_HIGH_DEF ) const;
/**
/**
* Function TransformOutlinesShapeWithClearanceToPolygon
* Convert the outlines shape to a polygon with no holes
* inflated (optional) by max( aClearanceValue, the zone clearance)
@ -330,18 +327,12 @@ public:
* Circles and arcs are approximated by segments
* @param aCornerBuffer = a buffer to store the polygon
* @param aClearanceValue = the clearance around the pad
* @param aCircleToSegmentsCount = the number of segments to approximate a circle
* @param aCorrectionFactor = the correction to apply to circles radius to keep
* clearance when the circle is approximated by segment bigger or equal
* to the real clearance value (usually near from 1.0)
* @param aError = the maximum deviation from true circle
* @param ignoreLineWidth = used for edge cut items where the line width is only
* for visualization
*/
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer,
int aClearanceValue,
int aCircleToSegmentsCount,
double aCorrectionFactor,
bool ignoreLineWidth = false ) const override;
void TransformShapeWithClearanceToPolygon( SHAPE_POLY_SET& aCornerBuffer, int aClearanceValue,
int aError = ARC_HIGH_DEF, bool ignoreLineWidth = false ) const override;
/**
* Function HitTestForCorner

View File

@ -1136,13 +1136,8 @@ void DRC::testCopperDrawItem( DRAWSEGMENT* aItem )
if( pad->GetParent() == aItem->GetParent() )
continue;
const int segmentCount = ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF;
double correctionFactor = GetCircletoPolyCorrectionFactor( segmentCount );
SHAPE_POLY_SET padOutline;
// We incorporate "minDist" into the pad's outline
pad->TransformShapeWithClearanceToPolygon( padOutline, pad->GetClearance( NULL ),
segmentCount, correctionFactor );
pad->TransformShapeWithClearanceToPolygon( padOutline, pad->GetClearance( NULL ) );
for( const auto& itemSeg : itemShape )
{
@ -1219,13 +1214,10 @@ void DRC::testCopperTextItem( BOARD_ITEM* aTextItem )
if( !rect_area.Collide( SEG( shape_pos, shape_pos ), bb_radius ) )
continue;
const int segmentCount = ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF;
double correctionFactor = GetCircletoPolyCorrectionFactor( segmentCount );
SHAPE_POLY_SET padOutline;
int minDist = textWidth/2 + pad->GetClearance( NULL );
pad->TransformShapeWithClearanceToPolygon( padOutline, 0,
segmentCount, correctionFactor );
pad->TransformShapeWithClearanceToPolygon( padOutline, 0 );
for( unsigned jj = 0; jj < textShape.size(); jj += 2 )
{

View File

@ -1142,9 +1142,8 @@ static void export_vrml_padshape( MODEL_VRML& aModel, VRML_LAYER* aTinLayer, D_P
case PAD_SHAPE_CUSTOM:
{
SHAPE_POLY_SET polySet;
int segmentToCircleCount = ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF;
std::vector< wxRealPoint > cornerList;
aPad->MergePrimitivesAsPolygon( &polySet, segmentToCircleCount );
aPad->MergePrimitivesAsPolygon( &polySet );
for( int cnt = 0; cnt < polySet.OutlineCount(); ++cnt )
{

View File

@ -200,8 +200,7 @@ void D_PAD::DeletePrimitivesList()
}
bool D_PAD::buildCustomPadPolygon( SHAPE_POLY_SET* aMergedPolygon,
int aCircleToSegmentsCount )
bool D_PAD::buildCustomPadPolygon( SHAPE_POLY_SET* aMergedPolygon, int aError )
{
SHAPE_POLY_SET aux_polyset;
@ -221,33 +220,42 @@ bool D_PAD::buildCustomPadPolygon( SHAPE_POLY_SET* aMergedPolygon,
for( unsigned ii = 1; ii < poly.size(); ii++ )
{
TransformRoundedEndsSegmentToPolygon( aux_polyset,
poly[ii-1], poly[ii], aCircleToSegmentsCount, bshape.m_Thickness );
int numSegs = std::max(
GetArcToSegmentCount( bshape.m_Thickness / 2, aError, 360.0 ), 6 );
TransformRoundedEndsSegmentToPolygon(
aux_polyset, poly[ii - 1], poly[ii], numSegs, bshape.m_Thickness );
}
break;
}
case S_SEGMENT: // usual segment : line with rounded ends
TransformRoundedEndsSegmentToPolygon( aux_polyset,
bshape.m_Start, bshape.m_End, aCircleToSegmentsCount, bshape.m_Thickness );
{
int numSegs =
std::max( GetArcToSegmentCount( bshape.m_Thickness / 2, aError, 360.0 ), 6 );
TransformRoundedEndsSegmentToPolygon(
aux_polyset, bshape.m_Start, bshape.m_End, numSegs, bshape.m_Thickness );
break;
}
case S_ARC: // Arc with rounded ends
TransformArcToPolygon( aux_polyset,
bshape.m_Start, bshape.m_End, bshape.m_ArcAngle,
aCircleToSegmentsCount, bshape.m_Thickness );
{
int radius = KiROUND( EuclideanNorm( ( bshape.m_Start - bshape.m_End ) ) );
int numSegs = std::max( GetArcToSegmentCount( radius, aError, 360.0 ), 6 );
TransformArcToPolygon( aux_polyset, bshape.m_Start, bshape.m_End, bshape.m_ArcAngle,
numSegs, bshape.m_Thickness );
break;
}
case S_CIRCLE: // ring or circle
{
int numSegs = std::max( GetArcToSegmentCount( bshape.m_Radius, aError, 360.0 ), 6 );
if( bshape.m_Thickness ) // ring
TransformRingToPolygon( aux_polyset,
bshape.m_Start, bshape.m_Radius,
aCircleToSegmentsCount, bshape.m_Thickness ) ;
TransformRingToPolygon(
aux_polyset, bshape.m_Start, bshape.m_Radius, numSegs, bshape.m_Thickness );
else // Filled circle
TransformCircleToPolygon( aux_polyset,
bshape.m_Start, bshape.m_Radius,
aCircleToSegmentsCount ) ;
TransformCircleToPolygon( aux_polyset, bshape.m_Start, bshape.m_Radius, numSegs );
break;
}
case S_POLYGON: // polygon
if( bshape.m_Poly.size() < 2 )
@ -268,7 +276,9 @@ bool D_PAD::buildCustomPadPolygon( SHAPE_POLY_SET* aMergedPolygon,
polyset.Append( poly[ii].x, poly[ii].y );
}
polyset.Inflate( bshape.m_Thickness/2, ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF );
int numSegs = std::max(
GetArcToSegmentCount( bshape.m_Thickness / 2, aError, 360.0 ), 6 );
polyset.Inflate( bshape.m_Thickness / 2, numSegs );
aux_polyset.Append( polyset );
}
@ -300,8 +310,7 @@ bool D_PAD::buildCustomPadPolygon( SHAPE_POLY_SET* aMergedPolygon,
* return true if OK, false in there is more than one polygon
* in aMergedPolygon
*/
bool D_PAD::MergePrimitivesAsPolygon( SHAPE_POLY_SET* aMergedPolygon,
int aCircleToSegmentsCount )
bool D_PAD::MergePrimitivesAsPolygon( SHAPE_POLY_SET* aMergedPolygon )
{
// if aMergedPolygon == NULL, use m_customShapeAsPolygon as target
@ -316,19 +325,23 @@ bool D_PAD::MergePrimitivesAsPolygon( SHAPE_POLY_SET* aMergedPolygon,
{
default:
case PAD_SHAPE_CIRCLE:
TransformCircleToPolygon( *aMergedPolygon, wxPoint( 0,0 ), GetSize().x/2,
aCircleToSegmentsCount );
break;
{
int numSegs = std::max( GetArcToSegmentCount( GetSize().x / 2, ARC_HIGH_DEF, 360.0 ), 6 );
TransformCircleToPolygon( *aMergedPolygon, wxPoint( 0, 0 ), GetSize().x / 2, numSegs );
case PAD_SHAPE_RECT:
{
SHAPE_RECT rect( -GetSize().x/2, -GetSize().y/2, GetSize().x, GetSize().y );
aMergedPolygon->AddOutline( rect.Outline() );
}
break;
}
if ( !buildCustomPadPolygon( aMergedPolygon, aCircleToSegmentsCount ) )
case PAD_SHAPE_RECT:
{
SHAPE_RECT rect( -GetSize().x / 2, -GetSize().y / 2, GetSize().x, GetSize().y );
aMergedPolygon->AddOutline( rect.Outline() );
break;
}
}
if( !buildCustomPadPolygon( aMergedPolygon, ARC_HIGH_DEF ) )
return false;
m_boundingRadius = -1; // The current bouding radius is no more valid.
@ -364,7 +377,7 @@ bool D_PAD::GetBestAnchorPosition( VECTOR2I& aPos )
{
SHAPE_POLY_SET poly;
if ( !buildCustomPadPolygon( &poly, ARC_APPROX_SEGMENTS_COUNT_LOW_DEF ) )
if( !buildCustomPadPolygon( &poly, ARC_LOW_DEF ) )
return false;
const int minSteps = 10;

View File

@ -28,20 +28,20 @@
* @file class_pad_draw_functions.cpp
*/
#include <fctsys.h>
#include <gr_basic.h>
#include <common.h>
#include <trigo.h>
#include <pcb_screen.h>
#include <class_board.h>
#include <class_drawpanel.h>
#include <common.h>
#include <convert_basic_shapes_to_polygon.h>
#include <draw_graphic_text.h>
#include <fctsys.h>
#include <geometry/geometry_utils.h>
#include <gr_basic.h>
#include <layers_id_colors_and_visibility.h>
#include <pcb_edit_frame.h>
#include <pcbnew_id.h> // ID_TRACK_BUTT
#include <pcb_screen.h>
#include <pcbnew.h>
#include <class_board.h>
#include <convert_basic_shapes_to_polygon.h>
#include <pcbnew_id.h> // ID_TRACK_BUTT
#include <trigo.h>
/* uncomment this line to show this pad with its specfic size and color
@ -420,7 +420,7 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
if( aDrawInfo.m_PadClearance )
{
SHAPE_POLY_SET outline;
TransformShapeWithClearanceToPolygon( outline, aDrawInfo.m_PadClearance, ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF, 1.0 );
TransformShapeWithClearanceToPolygon( outline, aDrawInfo.m_PadClearance );
// Draw the polygon: Inflate creates only one convex polygon
if( outline.OutlineCount() > 0 )
@ -527,11 +527,12 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
CustomShapeAsPolygonToBoardPosition( &outline, pad_pos, GetOrientation() );
SHAPE_LINE_CHAIN* poly;
const int segmentToCircleCount = ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF;
if( aDrawInfo.m_Mask_margin.x )
outline.InflateWithLinkedHoles( aDrawInfo.m_Mask_margin.x,
segmentToCircleCount, SHAPE_POLY_SET::PM_FAST );
{
int numSegs = GetArcToSegmentCount( aDrawInfo.m_Mask_margin.x, ARC_HIGH_DEF, 360.0 );
outline.InflateWithLinkedHoles(
aDrawInfo.m_Mask_margin.x, numSegs, SHAPE_POLY_SET::PM_FAST );
}
// Draw the polygon: only one polygon is expected
// However we provide a multi polygon shape drawing
@ -550,8 +551,9 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
SHAPE_POLY_SET clearance_outline;
clearance_outline.Append( outline );
clearance_outline.InflateWithLinkedHoles( aDrawInfo.m_PadClearance,
segmentToCircleCount, SHAPE_POLY_SET::PM_FAST );
int numSegs = GetArcToSegmentCount( aDrawInfo.m_PadClearance, ARC_HIGH_DEF, 360.0 );
clearance_outline.InflateWithLinkedHoles(
aDrawInfo.m_PadClearance, numSegs, SHAPE_POLY_SET::PM_FAST );
for( int jj = 0; jj < clearance_outline.OutlineCount(); ++jj )
{
@ -565,6 +567,7 @@ void D_PAD::DrawShape( EDA_RECT* aClipBox, wxDC* aDC, PAD_DRAWINFO& aDrawInfo )
}
}
}
break;
}
}

View File

@ -40,8 +40,9 @@
#include <pcb_painter.h>
#include <pcb_display_options.h>
#include <gal/graphics_abstraction_layer.h>
#include <convert_basic_shapes_to_polygon.h>
#include <gal/graphics_abstraction_layer.h>
#include <geometry/geometry_utils.h>
#include <geometry/shape_line_chain.h>
using namespace KIGFX;
@ -845,11 +846,11 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
{
SHAPE_POLY_SET outline;
outline.Append( aPad->GetCustomShapeAsPolygon() );
const int segmentToCircleCount = ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF;
// outline polygon can have holes linked to the main outline.
// So use InflateWithLinkedHoles(), not Inflate() that can create
// bad shapes if custom_margin is < 0
outline.InflateWithLinkedHoles( custom_margin, segmentToCircleCount, SHAPE_POLY_SET::PM_FAST );
int numSegs = std::max( GetArcToSegmentCount( custom_margin, ARC_HIGH_DEF, 360.0 ), 6 );
outline.InflateWithLinkedHoles( custom_margin, numSegs, SHAPE_POLY_SET::PM_FAST );
m_gal->DrawPolygon( outline );
}
else
@ -900,8 +901,7 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
|| aLayer == LAYER_PADS_TH ) )
{
SHAPE_POLY_SET polySet;
constexpr int SEGCOUNT = 64;
aPad->TransformShapeWithClearanceToPolygon( polySet, aPad->GetClearance(), SEGCOUNT, 1.0 );
aPad->TransformShapeWithClearanceToPolygon( polySet, aPad->GetClearance() );
m_gal->SetLineWidth( m_pcbSettings.m_outlineWidth );
m_gal->SetIsStroke( true );
m_gal->SetIsFill( false );

View File

@ -450,12 +450,12 @@ void PlotStandardLayer( BOARD *aBoard, PLOTTER* aPlotter,
D_PAD dummy( *pad );
SHAPE_POLY_SET shape;
pad->MergePrimitivesAsPolygon( &shape, 64 );
pad->MergePrimitivesAsPolygon( &shape );
// shape polygon can have holes linked to the main outline.
// So use InflateWithLinkedHoles(), not Inflate() that can create
// bad shapes if margin.x is < 0
shape.InflateWithLinkedHoles( margin.x, ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF,
SHAPE_POLY_SET::PM_FAST );
int numSegs = std::max( GetArcToSegmentCount( margin.x, ARC_HIGH_DEF, 360.0 ), 6 );
shape.InflateWithLinkedHoles( margin.x, numSegs, SHAPE_POLY_SET::PM_FAST );
dummy.DeletePrimitivesList();
dummy.AddPrimitive( shape, 0 );
dummy.MergePrimitivesAsPolygon();
@ -801,21 +801,13 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
SHAPE_POLY_SET areas; // Contains shapes to plot
SHAPE_POLY_SET initialPolys; // Contains exact shapes to plot
/* calculates the coeff to compensate radius reduction of holes clearance
* due to the segment approx ( 1 /cos( PI/circleToSegmentsCount )
*/
int circleToSegmentsCount = ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF;
double correction = GetCircletoPolyCorrectionFactor( circleToSegmentsCount );
// Plot pads
for( MODULE* module = aBoard->m_Modules; module; module = module->Next() )
{
// add shapes with exact size
module->TransformPadsShapesWithClearanceToPolygon( layer,
initialPolys, 0, circleToSegmentsCount, correction );
module->TransformPadsShapesWithClearanceToPolygon( layer, initialPolys, 0 );
// add shapes inflated by aMinThickness/2
module->TransformPadsShapesWithClearanceToPolygon( layer,
areas, inflate, circleToSegmentsCount, correction );
module->TransformPadsShapesWithClearanceToPolygon( layer, areas, inflate );
}
// Plot vias on solder masks, if aPlotOpt.GetPlotViaOnMaskLayer() is true,
@ -846,12 +838,8 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
if( !( via_set & aLayerMask ).any() )
continue;
via->TransformShapeWithClearanceToPolygon( areas, via_margin,
circleToSegmentsCount,
correction );
via->TransformShapeWithClearanceToPolygon( initialPolys, via_clearance,
circleToSegmentsCount,
correction );
via->TransformShapeWithClearanceToPolygon( areas, via_margin );
via->TransformShapeWithClearanceToPolygon( initialPolys, via_clearance );
}
}
@ -869,10 +857,8 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
if( zone->GetLayer() != layer )
continue;
zone->TransformOutlinesShapeWithClearanceToPolygon( areas,
inflate+zone_margin, false );
zone->TransformOutlinesShapeWithClearanceToPolygon( initialPolys,
zone_margin, false );
zone->TransformOutlinesShapeWithClearanceToPolygon( areas, inflate + zone_margin, false );
zone->TransformOutlinesShapeWithClearanceToPolygon( initialPolys, zone_margin, false );
}
// To avoid a lot of code, use a ZONE_CONTAINER
@ -885,9 +871,10 @@ void PlotSolderMaskLayer( BOARD *aBoard, PLOTTER* aPlotter,
zone.SetArcSegmentCount( ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF );
zone.SetMinThickness( 0 ); // trace polygons only
zone.SetLayer ( layer );
int numSegs = std::max( GetArcToSegmentCount( inflate, ARC_HIGH_DEF, 360.0 ), 6 );
areas.BooleanAdd( initialPolys, SHAPE_POLY_SET::PM_FAST );
areas.Inflate( -inflate, circleToSegmentsCount );
areas.Inflate( -inflate, numSegs );
// Combine the current areas to initial areas. This is mandatory because
// inflate/deflate transform is not perfect, and we want the initial areas perfectly kept

View File

@ -201,7 +201,7 @@ void BRDITEMS_PLOTTER::PlotPad( D_PAD* aPad, COLOR4D aColor, EDA_DRAW_MODE_T aPl
case PAD_SHAPE_CUSTOM:
{
SHAPE_POLY_SET polygons;
aPad->MergePrimitivesAsPolygon(&polygons, 64 );
aPad->MergePrimitivesAsPolygon( &polygons );
if( polygons.OutlineCount() == 0 )
break;

View File

@ -616,9 +616,7 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE::syncPad( D_PAD* aPad )
case PAD_SHAPE_ROUNDRECT:
{
SHAPE_POLY_SET outline;
const int segmentToCircleCount = 64;
aPad->BuildPadShapePolygon( outline, wxSize( 0, 0 ), segmentToCircleCount, 1.0 );
aPad->BuildPadShapePolygon( outline, wxSize( 0, 0 ) );
// TransformRoundRectToPolygon creates only one convex polygon
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );
@ -711,9 +709,7 @@ std::unique_ptr<PNS::SOLID> PNS_KICAD_IFACE::syncPad( D_PAD* aPad )
case PAD_SHAPE_ROUNDRECT:
{
SHAPE_POLY_SET outline;
const int segmentToCircleCount = ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF;
aPad->BuildPadShapePolygon( outline, wxSize( 0, 0 ),
segmentToCircleCount, 1.0 );
aPad->BuildPadShapePolygon( outline, wxSize( 0, 0 ) );
// TransformRoundRectToPolygon creates only one convex polygon
SHAPE_LINE_CHAIN& poly = outline.Outline( 0 );

View File

@ -74,10 +74,9 @@ private:
};
extern void CreateThermalReliefPadPolygon( SHAPE_POLY_SET& aCornerBuffer,
const D_PAD& aPad, int aThermalGap, int aCopperThickness,
int aMinThicknessValue, int aCircleToSegmentsCount,
double aCorrectionFactor, double aThermalRot );
extern void CreateThermalReliefPadPolygon( SHAPE_POLY_SET& aCornerBuffer, const D_PAD& aPad,
int aThermalGap, int aCopperThickness, int aMinThicknessValue, int aError,
double aThermalRot );
static double s_thermalRot = 450; // angle of stubs in thermal reliefs for round pads
static const bool s_DumpZonesWhenFilling = false;
@ -138,7 +137,8 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE_CONTAINER*>& aZones, bool aCheck
}
std::atomic<size_t> nextItem( 0 );
size_t parallelThreadCount = std::min<size_t>( std::thread::hardware_concurrency(), toFill.size() );
size_t parallelThreadCount =
std::min<size_t>( std::thread::hardware_concurrency(), aZones.size() );
std::vector<std::future<size_t>> returns( parallelThreadCount );
auto fill_lambda = [&] ( PROGRESS_REPORTER* aReporter ) -> size_t
@ -218,12 +218,18 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE_CONTAINER*>& aZones, bool aCheck
}
}
// Zones with no net can have areas outside the board cutouts.
// Please, use only this clipping for no-net zones: this is a very time consumming
// calculation (x 5 in a test case if made for all zones), mainly due to poly.Fracture
// By definition, the island has all points outside the outline, so we only
// need to check one point for each island
else if( clip_to_brd_outlines )
{
poly.BooleanIntersection( boardOutline, SHAPE_POLY_SET::PM_FAST );
poly.Fracture( SHAPE_POLY_SET::PM_FAST );
for( auto idx : zone.m_islands )
{
if( poly.Polygon( idx ).empty()
|| !boardOutline.Contains( poly.Polygon( idx ).front().CPoint( 0 ) ) )
{
poly.DeletePolygon( idx );
}
}
}
zone.m_zone->SetFilledPolysList( poly );
@ -326,20 +332,6 @@ bool ZONE_FILLER::Fill( const std::vector<ZONE_CONTAINER*>& aZones, bool aCheck
void ZONE_FILLER::buildZoneFeatureHoleList( const ZONE_CONTAINER* aZone,
SHAPE_POLY_SET& aFeatures ) const
{
// Set the number of segments in arc approximations
// Since we can no longer edit the segment count in pcbnew, we set
// the fill to our high-def count to avoid jagged knock-outs
// However, if the user has edited their zone to increase the segment count,
// we keep this preference
int segsPerCircle = std::max( aZone->GetArcSegmentCount(), ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF );
/* calculates the coeff to compensate radius reduction of holes clearance
* due to the segment approx.
* For a circle the min radius is radius * cos( 2PI / segsPerCircle / 2)
* correctionFactor is 1 /cos( PI/segsPerCircle )
*/
double correctionFactor = GetCircletoPolyCorrectionFactor( segsPerCircle );
aFeatures.RemoveAllContours();
int zone_clearance = aZone->GetClearance();
@ -428,9 +420,12 @@ void ZONE_FILLER::buildZoneFeatureHoleList( const ZONE_CONTAINER* aZone,
// the pad shape in zone can be its convex hull or
// the shape itself
SHAPE_POLY_SET outline( pad->GetCustomShapeAsPolygon() );
outline.Inflate( KiROUND( clearance * correctionFactor ), segsPerCircle );
pad->CustomShapeAsPolygonToBoardPosition( &outline,
pad->GetPosition(), pad->GetOrientation() );
int numSegs = std::max(
GetArcToSegmentCount( clearance, ARC_HIGH_DEF, 360.0 ), 6 );
double correction = GetCircletoPolyCorrectionFactor( numSegs );
outline.Inflate( KiROUND( clearance * correction ), numSegs );
pad->CustomShapeAsPolygonToBoardPosition(
&outline, pad->GetPosition(), pad->GetOrientation() );
if( pad->GetCustomShapeInZoneOpt() == CUST_PAD_SHAPE_IN_ZONE_CONVEXHULL )
{
@ -446,10 +441,7 @@ void ZONE_FILLER::buildZoneFeatureHoleList( const ZONE_CONTAINER* aZone,
aFeatures.Append( outline );
}
else
pad->TransformShapeWithClearanceToPolygon( aFeatures,
clearance,
segsPerCircle,
correctionFactor );
pad->TransformShapeWithClearanceToPolygon( aFeatures, clearance );
}
continue;
@ -477,10 +469,13 @@ void ZONE_FILLER::buildZoneFeatureHoleList( const ZONE_CONTAINER* aZone,
{
// the pad shape in zone can be its convex hull or
// the shape itself
int numSegs =
std::max( GetArcToSegmentCount( gap, ARC_HIGH_DEF, 360.0 ), 6 );
double correction = GetCircletoPolyCorrectionFactor( numSegs );
SHAPE_POLY_SET outline( pad->GetCustomShapeAsPolygon() );
outline.Inflate( KiROUND( gap * correctionFactor ), segsPerCircle );
pad->CustomShapeAsPolygonToBoardPosition( &outline,
pad->GetPosition(), pad->GetOrientation() );
outline.Inflate( KiROUND( gap * correction ), numSegs );
pad->CustomShapeAsPolygonToBoardPosition(
&outline, pad->GetPosition(), pad->GetOrientation() );
std::vector<wxPoint> convex_hull;
BuildConvexHull( convex_hull, outline );
@ -491,8 +486,7 @@ void ZONE_FILLER::buildZoneFeatureHoleList( const ZONE_CONTAINER* aZone,
aFeatures.Append( convex_hull[ii] );
}
else
pad->TransformShapeWithClearanceToPolygon( aFeatures,
gap, segsPerCircle, correctionFactor );
pad->TransformShapeWithClearanceToPolygon( aFeatures, gap );
}
}
}
@ -515,8 +509,7 @@ void ZONE_FILLER::buildZoneFeatureHoleList( const ZONE_CONTAINER* aZone,
if( item_boundingbox.Intersects( zone_boundingbox ) )
{
int clearance = std::max( zone_clearance, item_clearance );
track->TransformShapeWithClearanceToPolygon( aFeatures,
clearance, segsPerCircle, correctionFactor );
track->TransformShapeWithClearanceToPolygon( aFeatures, clearance );
}
}
@ -549,7 +542,7 @@ void ZONE_FILLER::buildZoneFeatureHoleList( const ZONE_CONTAINER* aZone,
{
case PCB_LINE_T:
static_cast<DRAWSEGMENT*>( aItem )->TransformShapeWithClearanceToPolygon(
aFeatures, zclearance, segsPerCircle, correctionFactor, ignoreLineWidth );
aFeatures, zclearance, ARC_HIGH_DEF, ignoreLineWidth );
break;
case PCB_TEXT_T:
@ -559,7 +552,7 @@ void ZONE_FILLER::buildZoneFeatureHoleList( const ZONE_CONTAINER* aZone,
case PCB_MODULE_EDGE_T:
static_cast<EDGE_MODULE*>( aItem )->TransformShapeWithClearanceToPolygon(
aFeatures, zclearance, segsPerCircle, correctionFactor, ignoreLineWidth );
aFeatures, zclearance, ARC_HIGH_DEF, ignoreLineWidth );
break;
case PCB_MODULE_TEXT_T:
@ -667,12 +660,9 @@ void ZONE_FILLER::buildZoneFeatureHoleList( const ZONE_CONTAINER* aZone,
if( item_boundingbox.Intersects( zone_boundingbox ) )
{
CreateThermalReliefPadPolygon( aFeatures,
*pad, thermalGap,
aZone->GetThermalReliefCopperBridge( pad ),
aZone->GetMinThickness(),
segsPerCircle,
correctionFactor, s_thermalRot );
CreateThermalReliefPadPolygon( aFeatures, *pad, thermalGap,
aZone->GetThermalReliefCopperBridge( pad ), aZone->GetMinThickness(),
ARC_HIGH_DEF, s_thermalRot );
}
}
}
@ -717,19 +707,16 @@ void ZONE_FILLER::computeRawFilledAreas( const ZONE_CONTAINER* aZone,
std::unique_ptr<SHAPE_FILE_IO> dumper( new SHAPE_FILE_IO(
s_DumpZonesWhenFilling ? "zones_dump.txt" : "", SHAPE_FILE_IO::IOM_APPEND ) );
// Set the number of segments in arc approximations
int segsPerCircle = std::max( aZone->GetArcSegmentCount(), ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF );
/* calculates the coeff to compensate radius reduction of holes clearance
*/
double correctionFactor = GetCircletoPolyCorrectionFactor( segsPerCircle );
if( s_DumpZonesWhenFilling )
dumper->BeginGroup( "clipper-zone" );
SHAPE_POLY_SET solidAreas = aSmoothedOutline;
solidAreas.Inflate( -outline_half_thickness, segsPerCircle );
int numSegs =
std::max( GetArcToSegmentCount( outline_half_thickness, ARC_HIGH_DEF, 360.0 ), 6 );
double correction = GetCircletoPolyCorrectionFactor( numSegs );
solidAreas.Inflate( -outline_half_thickness, numSegs );
solidAreas.Simplify( SHAPE_POLY_SET::PM_FAST );
SHAPE_POLY_SET holes;
@ -788,9 +775,8 @@ void ZONE_FILLER::computeRawFilledAreas( const ZONE_CONTAINER* aZone,
if( aZone->GetNetCode() > 0 )
{
buildUnconnectedThermalStubsPolygonList( thermalHoles, aZone, solidAreas,
correctionFactor, s_thermalRot );
buildUnconnectedThermalStubsPolygonList(
thermalHoles, aZone, solidAreas, correction, s_thermalRot );
}
// remove copper areas corresponding to not connected stubs
@ -853,7 +839,9 @@ bool ZONE_FILLER::fillSingleZone( ZONE_CONTAINER* aZone, SHAPE_POLY_SET& aRawPol
}
else
{
aFinalPolys.Inflate( -aZone->GetMinThickness() / 2, ARC_APPROX_SEGMENTS_COUNT_HIGH_DEF );
int numSegs = std::max(
GetArcToSegmentCount( aZone->GetMinThickness() / 2, ARC_HIGH_DEF, 360.0 ), 6 );
aFinalPolys.Inflate( -aZone->GetMinThickness() / 2, numSegs );
// Remove the non filled areas due to the hatch pattern
if( aZone->GetFillMode() == ZFM_HATCH_PATTERN )

View File

@ -46,12 +46,7 @@ void process( const BOARD_CONNECTED_ITEM* item, int net )
SHAPE_POLY_SET pset;
const int segsPerCircle = 64;
double correctionFactor = 1.0 / cos( M_PI / (double) segsPerCircle );
item->TransformShapeWithClearanceToPolygon( pset, 1, segsPerCircle, correctionFactor );
item->TransformShapeWithClearanceToPolygon( pset, 1, ARC_HIGH_DEF );
SHAPE_FILE_IO shapeIo; // default = stdout
shapeIo.Write( &pset );
@ -114,4 +109,4 @@ KI_TEST::UTILITY_PROGRAM polygon_generator_tool = {
"polygon_generator",
"Dump board geometry as a set of polygons",
polygon_gererator_main,
};
};