mirror of
https://gitlab.com/kicad/code/kicad.git
synced 2025-09-14 10:13:19 +02:00
Fix a bunch more bugs in bezier approximation.
(cherry picked from commit e8e7282fe1eed4f2a633fea9c7bdb0e81be53f9b)
This commit is contained in:
parent
29d0cdb546
commit
d7a0555780
@ -303,7 +303,7 @@ bool EDA_SHAPE::Deserialize( const google::protobuf::Any &aContainer )
|
|||||||
SetBezierC1( UnpackVector2( shape.bezier().control1() ) );
|
SetBezierC1( UnpackVector2( shape.bezier().control1() ) );
|
||||||
SetBezierC2( UnpackVector2( shape.bezier().control2() ) );
|
SetBezierC2( UnpackVector2( shape.bezier().control2() ) );
|
||||||
SetEnd( UnpackVector2( shape.bezier().end() ) );
|
SetEnd( UnpackVector2( shape.bezier().end() ) );
|
||||||
RebuildBezierToSegmentsPointsList( ARC_HIGH_DEF );
|
RebuildBezierToSegmentsPointsList( getMaxError() );
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
@ -623,7 +623,7 @@ void EDA_SHAPE::scale( double aScale )
|
|||||||
scalePt( m_end );
|
scalePt( m_end );
|
||||||
scalePt( m_bezierC1 );
|
scalePt( m_bezierC1 );
|
||||||
scalePt( m_bezierC2 );
|
scalePt( m_bezierC2 );
|
||||||
RebuildBezierToSegmentsPointsList( m_stroke.GetWidth() / 2 );
|
RebuildBezierToSegmentsPointsList( getMaxError() );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -727,7 +727,7 @@ void EDA_SHAPE::flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
|
|||||||
MIRROR( m_bezierC1, aCentre, aFlipDirection );
|
MIRROR( m_bezierC1, aCentre, aFlipDirection );
|
||||||
MIRROR( m_bezierC2, aCentre, aFlipDirection );
|
MIRROR( m_bezierC2, aCentre, aFlipDirection );
|
||||||
|
|
||||||
RebuildBezierToSegmentsPointsList( m_stroke.GetWidth() / 2 );
|
RebuildBezierToSegmentsPointsList( getMaxError() );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -1742,7 +1742,7 @@ void EDA_SHAPE::beginEdit( const VECTOR2I& aPosition )
|
|||||||
SetBezierC2( aPosition );
|
SetBezierC2( aPosition );
|
||||||
m_editState = 1;
|
m_editState = 1;
|
||||||
|
|
||||||
RebuildBezierToSegmentsPointsList( GetWidth() / 2 );
|
RebuildBezierToSegmentsPointsList( getMaxError() );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHAPE_T::POLY:
|
case SHAPE_T::POLY:
|
||||||
@ -1824,7 +1824,7 @@ void EDA_SHAPE::calcEdit( const VECTOR2I& aPosition )
|
|||||||
case 3: SetBezierC2( aPosition ); break;
|
case 3: SetBezierC2( aPosition ); break;
|
||||||
}
|
}
|
||||||
|
|
||||||
RebuildBezierToSegmentsPointsList( GetWidth() / 2 );
|
RebuildBezierToSegmentsPointsList( getMaxError() );
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -228,7 +228,7 @@ void EDA_BEZIER_POINT_EDIT_BEHAVIOR::UpdateItem( const EDIT_POINT& aEditedPoint,
|
|||||||
m_bezier.SetEnd( aPoints.Point( BEZIER_END ).GetPosition() );
|
m_bezier.SetEnd( aPoints.Point( BEZIER_END ).GetPosition() );
|
||||||
}
|
}
|
||||||
|
|
||||||
m_bezier.RebuildBezierToSegmentsPointsList( ARC_HIGH_DEF );
|
m_bezier.RebuildBezierToSegmentsPointsList( m_maxError );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -217,7 +217,7 @@ void GRAPHICS_IMPORTER_LIB_SYMBOL::AddSpline( const VECTOR2D& aStart,
|
|||||||
spline->SetBezierC1( MapCoordinate( aBezierControl1 ) );
|
spline->SetBezierC1( MapCoordinate( aBezierControl1 ) );
|
||||||
spline->SetBezierC2( MapCoordinate( aBezierControl2 ) );
|
spline->SetBezierC2( MapCoordinate( aBezierControl2 ) );
|
||||||
spline->SetEnd( MapCoordinate( aEnd ) );
|
spline->SetEnd( MapCoordinate( aEnd ) );
|
||||||
spline->RebuildBezierToSegmentsPointsList( aStroke.GetWidth() / 2 );
|
spline->RebuildBezierToSegmentsPointsList( schIUScale.mmToIU( ARC_LOW_DEF_MM ) );
|
||||||
|
|
||||||
// If the spline is degenerated (i.e. a segment) add it as segment or discard it if
|
// If the spline is degenerated (i.e. a segment) add it as segment or discard it if
|
||||||
// null (i.e. very small) length
|
// null (i.e. very small) length
|
||||||
|
@ -2276,7 +2276,7 @@ void SCH_IO_ALTIUM::ParseBezier( const std::map<wxString, wxString>& aProperties
|
|||||||
}
|
}
|
||||||
|
|
||||||
bezier->SetStroke( STROKE_PARAMS( elem.LineWidth, LINE_STYLE::SOLID ) );
|
bezier->SetStroke( STROKE_PARAMS( elem.LineWidth, LINE_STYLE::SOLID ) );
|
||||||
bezier->RebuildBezierToSegmentsPointsList( bezier->GetWidth() / 2 );
|
bezier->RebuildBezierToSegmentsPointsList( schIUScale.mmToIU( ARC_LOW_DEF_MM ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2680,7 +2680,7 @@ void SCH_IO_ALTIUM::ParseEllipticalArc( const std::map<wxString, wxString>& aPro
|
|||||||
schbezier->SetBezierC2( bezier.C2 );
|
schbezier->SetBezierC2( bezier.C2 );
|
||||||
schbezier->SetEnd( bezier.End );
|
schbezier->SetEnd( bezier.End );
|
||||||
schbezier->SetStroke( STROKE_PARAMS( elem.LineWidth, LINE_STYLE::SOLID ) );
|
schbezier->SetStroke( STROKE_PARAMS( elem.LineWidth, LINE_STYLE::SOLID ) );
|
||||||
schbezier->RebuildBezierToSegmentsPointsList( elem.LineWidth / 2 );
|
schbezier->RebuildBezierToSegmentsPointsList( schIUScale.mmToIU( ARC_LOW_DEF_MM ) );
|
||||||
|
|
||||||
currentScreen->Append( schbezier );
|
currentScreen->Append( schbezier );
|
||||||
}
|
}
|
||||||
@ -2743,7 +2743,7 @@ void SCH_IO_ALTIUM::ParseEllipticalArc( const std::map<wxString, wxString>& aPro
|
|||||||
}
|
}
|
||||||
|
|
||||||
SetLibShapeLine( elem, schbezier, ALTIUM_SCH_RECORD::ELLIPTICAL_ARC );
|
SetLibShapeLine( elem, schbezier, ALTIUM_SCH_RECORD::ELLIPTICAL_ARC );
|
||||||
schbezier->RebuildBezierToSegmentsPointsList( elem.LineWidth / 2 );
|
schbezier->RebuildBezierToSegmentsPointsList( schIUScale.mmToIU( ARC_LOW_DEF_MM ) );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2877,7 +2877,7 @@ void SCH_IO_ALTIUM::ParseEllipse( const std::map<wxString, wxString>& aPropertie
|
|||||||
schbezier->SetFillColor( fillColor );
|
schbezier->SetFillColor( fillColor );
|
||||||
schbezier->SetFillMode( fillMode );
|
schbezier->SetFillMode( fillMode );
|
||||||
|
|
||||||
schbezier->RebuildBezierToSegmentsPointsList( schbezier->GetWidth() / 2 );
|
schbezier->RebuildBezierToSegmentsPointsList( schIUScale.mmToIU( ARC_LOW_DEF_MM ) );
|
||||||
screen->Append( schbezier );
|
screen->Append( schbezier );
|
||||||
|
|
||||||
polyPoints.push_back( bezier.Start );
|
polyPoints.push_back( bezier.Start );
|
||||||
@ -2953,7 +2953,7 @@ void SCH_IO_ALTIUM::ParseEllipse( const std::map<wxString, wxString>& aPropertie
|
|||||||
|
|
||||||
SetLibShapeLine( elem, libbezier, ALTIUM_SCH_RECORD::ELLIPSE );
|
SetLibShapeLine( elem, libbezier, ALTIUM_SCH_RECORD::ELLIPSE );
|
||||||
SetLibShapeFillAndColor( elem, libbezier, ALTIUM_SCH_RECORD::ELLIPSE, elem.Color );
|
SetLibShapeFillAndColor( elem, libbezier, ALTIUM_SCH_RECORD::ELLIPSE, elem.Color );
|
||||||
libbezier->RebuildBezierToSegmentsPointsList( libbezier->GetWidth() / 2 );
|
libbezier->RebuildBezierToSegmentsPointsList( schIUScale.mmToIU( ARC_LOW_DEF_MM ) );
|
||||||
|
|
||||||
polyPoints.push_back( libbezier->GetStart() );
|
polyPoints.push_back( libbezier->GetStart() );
|
||||||
}
|
}
|
||||||
|
@ -1403,7 +1403,7 @@ SCH_SHAPE* SCH_IO_KICAD_LEGACY_LIB_CACHE::loadBezier( LINE_READER& aReader )
|
|||||||
pt.y = -schIUScale.MilsToIU( parseInt( aReader, line, &line ) );
|
pt.y = -schIUScale.MilsToIU( parseInt( aReader, line, &line ) );
|
||||||
bezier->SetEnd( pt );
|
bezier->SetEnd( pt );
|
||||||
|
|
||||||
bezier->RebuildBezierToSegmentsPointsList( bezier->GetWidth() / 2 );
|
bezier->RebuildBezierToSegmentsPointsList( schIUScale.mmToIU( ARC_LOW_DEF_MM ) );
|
||||||
|
|
||||||
if( *line != 0 )
|
if( *line != 0 )
|
||||||
bezier->SetFillMode( parseFillMode( aReader, line, &line ) );
|
bezier->SetFillMode( parseFillMode( aReader, line, &line ) );
|
||||||
|
@ -85,7 +85,8 @@ SCH_IO_KICAD_SEXPR_PARSER::SCH_IO_KICAD_SEXPR_PARSER( LINE_READER* aLineReader,
|
|||||||
m_lineReader( aLineReader ),
|
m_lineReader( aLineReader ),
|
||||||
m_lastProgressLine( 0 ),
|
m_lastProgressLine( 0 ),
|
||||||
m_lineCount( aLineCount ),
|
m_lineCount( aLineCount ),
|
||||||
m_rootSheet( aRootSheet )
|
m_rootSheet( aRootSheet ),
|
||||||
|
m_maxError( ARC_LOW_DEF_MM * schIUScale.IU_PER_MM )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1432,7 +1433,7 @@ SCH_SHAPE* SCH_IO_KICAD_SEXPR_PARSER::parseSymbolBezier()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bezier->RebuildBezierToSegmentsPointsList( bezier->GetPenWidth() / 2 );
|
bezier->RebuildBezierToSegmentsPointsList( m_maxError );
|
||||||
|
|
||||||
return bezier.release();
|
return bezier.release();
|
||||||
}
|
}
|
||||||
@ -2604,6 +2605,9 @@ void SCH_IO_KICAD_SEXPR_PARSER::ParseSchematic( SCH_SHEET* aSheet, bool aIsCopya
|
|||||||
|
|
||||||
wxCHECK( screen != nullptr, /* void */ );
|
wxCHECK( screen != nullptr, /* void */ );
|
||||||
|
|
||||||
|
if( SCHEMATIC* schematic = dynamic_cast<SCHEMATIC*>( screen->GetParent() ) )
|
||||||
|
m_maxError = schematic->Settings().m_MaxError;
|
||||||
|
|
||||||
if( aIsCopyableOnly )
|
if( aIsCopyableOnly )
|
||||||
m_requiredVersion = aFileVersion;
|
m_requiredVersion = aFileVersion;
|
||||||
|
|
||||||
@ -4246,7 +4250,7 @@ SCH_SHAPE* SCH_IO_KICAD_SEXPR_PARSER::parseSchBezier()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bezier->RebuildBezierToSegmentsPointsList( bezier->GetPenWidth() / 2 );
|
bezier->RebuildBezierToSegmentsPointsList( m_maxError );
|
||||||
|
|
||||||
return bezier.release();
|
return bezier.release();
|
||||||
}
|
}
|
||||||
|
@ -254,6 +254,9 @@ private:
|
|||||||
|
|
||||||
/// The rootsheet for full project loads or null for importing a schematic.
|
/// The rootsheet for full project loads or null for importing a schematic.
|
||||||
SCH_SHEET* m_rootSheet;
|
SCH_SHEET* m_rootSheet;
|
||||||
|
|
||||||
|
/// Max deviation allowed when approximating bezier curves
|
||||||
|
int m_maxError;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // SCH_IO_KICAD_SEXPR_PARSER_H_
|
#endif // SCH_IO_KICAD_SEXPR_PARSER_H_
|
||||||
|
@ -27,6 +27,7 @@
|
|||||||
|
|
||||||
#include <sch_item.h>
|
#include <sch_item.h>
|
||||||
#include <eda_shape.h>
|
#include <eda_shape.h>
|
||||||
|
#include <schematic.h>
|
||||||
|
|
||||||
|
|
||||||
class SCH_SHAPE : public SCH_ITEM, public EDA_SHAPE
|
class SCH_SHAPE : public SCH_ITEM, public EDA_SHAPE
|
||||||
@ -139,7 +140,10 @@ protected:
|
|||||||
|
|
||||||
int getMaxError() const override
|
int getMaxError() const override
|
||||||
{
|
{
|
||||||
return schIUScale.mmToIU( ARC_HIGH_DEF_MM );
|
if( SCHEMATIC* schematic = Schematic() )
|
||||||
|
return schematic->Settings().m_MaxError;
|
||||||
|
else
|
||||||
|
return schIUScale.mmToIU( ARC_LOW_DEF_MM );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -64,13 +64,13 @@ SCHEMATIC_SETTINGS::SCHEMATIC_SETTINGS( JSON_SETTINGS* aParent, const std::strin
|
|||||||
m_SpiceSaveAllDissipations( false ),
|
m_SpiceSaveAllDissipations( false ),
|
||||||
m_SpiceSaveAllEvents( true ),
|
m_SpiceSaveAllEvents( true ),
|
||||||
m_SpiceModelCurSheetAsRoot( true ),
|
m_SpiceModelCurSheetAsRoot( true ),
|
||||||
|
m_MaxError( ARC_LOW_DEF_MM * schIUScale.IU_PER_MM ),
|
||||||
m_NgspiceSettings( nullptr )
|
m_NgspiceSettings( nullptr )
|
||||||
{
|
{
|
||||||
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
|
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
|
||||||
EESCHEMA_SETTINGS* cfg = mgr.GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" );
|
EESCHEMA_SETTINGS* cfg = mgr.GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" );
|
||||||
|
|
||||||
int defaultLineThickness =
|
int defaultLineThickness = cfg ? cfg->m_Drawing.default_line_thickness : DEFAULT_LINE_WIDTH_MILS;
|
||||||
cfg ? cfg->m_Drawing.default_line_thickness : DEFAULT_LINE_WIDTH_MILS;
|
|
||||||
int defaultTextSize = cfg ? cfg->m_Drawing.default_text_size : DEFAULT_TEXT_SIZE;
|
int defaultTextSize = cfg ? cfg->m_Drawing.default_text_size : DEFAULT_TEXT_SIZE;
|
||||||
int defaultPinSymbolSize = cfg ? cfg->m_Drawing.pin_symbol_size : DEFAULT_TEXT_SIZE / 2;
|
int defaultPinSymbolSize = cfg ? cfg->m_Drawing.pin_symbol_size : DEFAULT_TEXT_SIZE / 2;
|
||||||
int defaultJunctionSizeChoice = cfg ? cfg->m_Drawing.junction_size_choice : 3;
|
int defaultJunctionSizeChoice = cfg ? cfg->m_Drawing.junction_size_choice : 3;
|
||||||
|
@ -114,6 +114,9 @@ public:
|
|||||||
|
|
||||||
KIFONT::METRICS m_FontMetrics;
|
KIFONT::METRICS m_FontMetrics;
|
||||||
|
|
||||||
|
/// Max deviation allowable when approximating circles and curves (in IU).
|
||||||
|
int m_MaxError;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ngspice simulator settings.
|
* Ngspice simulator settings.
|
||||||
*/
|
*/
|
||||||
|
@ -918,8 +918,15 @@ void SCH_POINT_EDITOR::makePointsAndBehavior( EDA_ITEM* aItem )
|
|||||||
m_editBehavior = std::make_unique<EDA_POLYGON_POINT_EDIT_BEHAVIOR>( *shape );
|
m_editBehavior = std::make_unique<EDA_POLYGON_POINT_EDIT_BEHAVIOR>( *shape );
|
||||||
break;
|
break;
|
||||||
case SHAPE_T::BEZIER:
|
case SHAPE_T::BEZIER:
|
||||||
m_editBehavior = std::make_unique<EDA_BEZIER_POINT_EDIT_BEHAVIOR>( *shape );
|
{
|
||||||
|
int maxError = schIUScale.mmToIU( ARC_LOW_DEF_MM );
|
||||||
|
|
||||||
|
if( SCHEMATIC* schematic = shape->Schematic() )
|
||||||
|
maxError = schematic->Settings().m_MaxError;
|
||||||
|
|
||||||
|
m_editBehavior = std::make_unique<EDA_BEZIER_POINT_EDIT_BEHAVIOR>( *shape, maxError );
|
||||||
break;
|
break;
|
||||||
|
}
|
||||||
default:
|
default:
|
||||||
UNIMPLEMENTED_FOR( shape->SHAPE_T_asString() );
|
UNIMPLEMENTED_FOR( shape->SHAPE_T_asString() );
|
||||||
}
|
}
|
||||||
|
@ -79,7 +79,9 @@ struct EDA_IU_SCALE
|
|||||||
|
|
||||||
|
|
||||||
constexpr EDA_IU_SCALE( double aIUPerMM ) :
|
constexpr EDA_IU_SCALE( double aIUPerMM ) :
|
||||||
IU_PER_MM( aIUPerMM ), IU_PER_MILS( aIUPerMM * 0.0254 ), MM_PER_IU( 1 / IU_PER_MM )
|
IU_PER_MM( aIUPerMM ),
|
||||||
|
IU_PER_MILS( aIUPerMM * 0.0254 ),
|
||||||
|
MM_PER_IU( 1 / IU_PER_MM )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -110,14 +112,19 @@ constexpr EDA_IU_SCALE drawSheetIUScale = EDA_IU_SCALE( PL_IU_PER_MM );
|
|||||||
constexpr EDA_IU_SCALE schIUScale = EDA_IU_SCALE( SCH_IU_PER_MM );
|
constexpr EDA_IU_SCALE schIUScale = EDA_IU_SCALE( SCH_IU_PER_MM );
|
||||||
constexpr EDA_IU_SCALE unityScale = EDA_IU_SCALE( 1 );
|
constexpr EDA_IU_SCALE unityScale = EDA_IU_SCALE( 1 );
|
||||||
|
|
||||||
|
// Allowed error to approximate an arg by segments, in millimeters
|
||||||
|
constexpr double ARC_LOW_DEF_MM = 0.02;
|
||||||
|
constexpr double ARC_HIGH_DEF_MM = 0.005;
|
||||||
|
|
||||||
#ifndef SWIG
|
#ifndef SWIG
|
||||||
// The max error is the distance between the middle of a segment, and the circle
|
// The max error is the distance between the middle of a segment, and the circle
|
||||||
// for circle/arc to segment approximation.
|
// for circle/arc to segment approximation.
|
||||||
// Warning: too small values can create very long calculation time in zone filling
|
// Warning: too small values can create very long calculation time in zone filling
|
||||||
// 0.05 to 0.005 mm are reasonable values
|
// 0.05 to 0.005 mm are reasonable values
|
||||||
|
|
||||||
constexpr int ARC_LOW_DEF = pcbIUScale.mmToIU( 0.02 );
|
// Allowed error to approximate an arg by segments, in Pcbnew IU
|
||||||
constexpr int ARC_HIGH_DEF = pcbIUScale.mmToIU( 0.005 );
|
constexpr int ARC_LOW_DEF = pcbIUScale.mmToIU( ARC_LOW_DEF_MM );
|
||||||
|
constexpr int ARC_HIGH_DEF = pcbIUScale.mmToIU( ARC_HIGH_DEF_MM );
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif // _BASE_UNITS_H_
|
#endif // _BASE_UNITS_H_
|
||||||
|
@ -128,7 +128,9 @@ protected:
|
|||||||
class POLYGON_POINT_EDIT_BEHAVIOR : public POINT_EDIT_BEHAVIOR
|
class POLYGON_POINT_EDIT_BEHAVIOR : public POINT_EDIT_BEHAVIOR
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
POLYGON_POINT_EDIT_BEHAVIOR( SHAPE_POLY_SET& aPolygon ) : m_polygon( aPolygon ) {}
|
POLYGON_POINT_EDIT_BEHAVIOR( SHAPE_POLY_SET& aPolygon ) :
|
||||||
|
m_polygon( aPolygon )
|
||||||
|
{}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build the edit points for the given polygon outline.
|
* Build the edit points for the given polygon outline.
|
||||||
@ -193,7 +195,8 @@ public:
|
|||||||
class EDA_SEGMENT_POINT_EDIT_BEHAVIOR : public POINT_EDIT_BEHAVIOR
|
class EDA_SEGMENT_POINT_EDIT_BEHAVIOR : public POINT_EDIT_BEHAVIOR
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EDA_SEGMENT_POINT_EDIT_BEHAVIOR( EDA_SHAPE& aSegment ) : m_segment( aSegment )
|
EDA_SEGMENT_POINT_EDIT_BEHAVIOR( EDA_SHAPE& aSegment ) :
|
||||||
|
m_segment( aSegment )
|
||||||
{
|
{
|
||||||
wxASSERT( aSegment.GetShape() == SHAPE_T::SEGMENT );
|
wxASSERT( aSegment.GetShape() == SHAPE_T::SEGMENT );
|
||||||
}
|
}
|
||||||
@ -228,7 +231,8 @@ private:
|
|||||||
class EDA_CIRCLE_POINT_EDIT_BEHAVIOR : public POINT_EDIT_BEHAVIOR
|
class EDA_CIRCLE_POINT_EDIT_BEHAVIOR : public POINT_EDIT_BEHAVIOR
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EDA_CIRCLE_POINT_EDIT_BEHAVIOR( EDA_SHAPE& aCircle ) : m_circle( aCircle )
|
EDA_CIRCLE_POINT_EDIT_BEHAVIOR( EDA_SHAPE& aCircle ) :
|
||||||
|
m_circle( aCircle )
|
||||||
{
|
{
|
||||||
wxASSERT( aCircle.GetShape() == SHAPE_T::CIRCLE );
|
wxASSERT( aCircle.GetShape() == SHAPE_T::CIRCLE );
|
||||||
}
|
}
|
||||||
@ -263,7 +267,9 @@ private:
|
|||||||
class EDA_BEZIER_POINT_EDIT_BEHAVIOR : public POINT_EDIT_BEHAVIOR
|
class EDA_BEZIER_POINT_EDIT_BEHAVIOR : public POINT_EDIT_BEHAVIOR
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EDA_BEZIER_POINT_EDIT_BEHAVIOR( EDA_SHAPE& aBezier ) : m_bezier( aBezier )
|
EDA_BEZIER_POINT_EDIT_BEHAVIOR( EDA_SHAPE& aBezier, int aMaxError ) :
|
||||||
|
m_bezier( aBezier ),
|
||||||
|
m_maxError( aMaxError )
|
||||||
{
|
{
|
||||||
wxASSERT( aBezier.GetShape() == SHAPE_T::BEZIER );
|
wxASSERT( aBezier.GetShape() == SHAPE_T::BEZIER );
|
||||||
}
|
}
|
||||||
@ -288,6 +294,7 @@ protected:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
EDA_SHAPE& m_bezier;
|
EDA_SHAPE& m_bezier;
|
||||||
|
int m_maxError;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -398,7 +398,7 @@ bool doConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Ensure the approximated Bezier shape is built
|
// Ensure the approximated Bezier shape is built
|
||||||
graphic->RebuildBezierToSegmentsPointsList( ARC_HIGH_DEF );
|
graphic->RebuildBezierToSegmentsPointsList( aErrorMax );
|
||||||
|
|
||||||
if( reverse )
|
if( reverse )
|
||||||
{
|
{
|
||||||
|
@ -37,7 +37,7 @@
|
|||||||
#include <pcb_shape.h>
|
#include <pcb_shape.h>
|
||||||
#include <macros.h>
|
#include <macros.h>
|
||||||
#include <widgets/unit_binder.h>
|
#include <widgets/unit_binder.h>
|
||||||
|
#include <board_design_settings.h>
|
||||||
#include <dialog_shape_properties_base.h>
|
#include <dialog_shape_properties_base.h>
|
||||||
#include <tools/drawing_tool.h>
|
#include <tools/drawing_tool.h>
|
||||||
|
|
||||||
@ -1166,7 +1166,7 @@ bool DIALOG_SHAPE_PROPERTIES::TransferDataFromWindow()
|
|||||||
else
|
else
|
||||||
m_item->SetLocalSolderMaskMargin( m_solderMaskMargin.GetIntValue() );
|
m_item->SetLocalSolderMaskMargin( m_solderMaskMargin.GetIntValue() );
|
||||||
|
|
||||||
m_item->RebuildBezierToSegmentsPointsList( ARC_HIGH_DEF );
|
m_item->RebuildBezierToSegmentsPointsList( m_parent->GetDesignSettings().m_MaxError );
|
||||||
|
|
||||||
if( m_item->IsOnCopperLayer() )
|
if( m_item->IsOnCopperLayer() )
|
||||||
m_item->SetNetCode( m_netSelector->GetSelectedNetcode() );
|
m_item->SetNetCode( m_netSelector->GetSelectedNetcode() );
|
||||||
|
@ -312,7 +312,7 @@ bool DRC_TEST_PROVIDER_PHYSICAL_CLEARANCE::Run()
|
|||||||
{
|
{
|
||||||
SHAPE_LINE_CHAIN asPoly;
|
SHAPE_LINE_CHAIN asPoly;
|
||||||
|
|
||||||
shape->RebuildBezierToSegmentsPointsList( ARC_HIGH_DEF );
|
shape->RebuildBezierToSegmentsPointsList( errorMax );
|
||||||
|
|
||||||
for( const VECTOR2I& pt : shape->GetBezierPoints() )
|
for( const VECTOR2I& pt : shape->GetBezierPoints() )
|
||||||
asPoly.Append( pt );
|
asPoly.Append( pt );
|
||||||
|
@ -43,7 +43,8 @@ GRAPHICS_CLEANER::GRAPHICS_CLEANER( const DRAWINGS& aDrawings, FOOTPRINT* aParen
|
|||||||
m_commit( aCommit ),
|
m_commit( aCommit ),
|
||||||
m_toolMgr( aToolMgr ),
|
m_toolMgr( aToolMgr ),
|
||||||
m_dryRun( true ),
|
m_dryRun( true ),
|
||||||
m_epsilon( 0 ),
|
m_epsilon( 1 ),
|
||||||
|
m_maxError( ARC_HIGH_DEF ),
|
||||||
m_outlinesTolerance( 0 ),
|
m_outlinesTolerance( 0 ),
|
||||||
m_itemsList( nullptr )
|
m_itemsList( nullptr )
|
||||||
{
|
{
|
||||||
@ -59,7 +60,8 @@ void GRAPHICS_CLEANER::CleanupBoard( bool
|
|||||||
m_itemsList = aItemsList;
|
m_itemsList = aItemsList;
|
||||||
m_outlinesTolerance = aTolerance;
|
m_outlinesTolerance = aTolerance;
|
||||||
|
|
||||||
m_epsilon = m_commit.GetBoard()->GetDesignSettings().m_MaxError;
|
m_epsilon = m_commit.GetBoard()->GetDesignSettings().GetDRCEpsilon();
|
||||||
|
m_maxError = m_commit.GetBoard()->GetDesignSettings().m_MaxError;
|
||||||
|
|
||||||
// Clear the flag used to mark some shapes as deleted, in dry run:
|
// Clear the flag used to mark some shapes as deleted, in dry run:
|
||||||
for( BOARD_ITEM* drawing : m_drawings )
|
for( BOARD_ITEM* drawing : m_drawings )
|
||||||
@ -105,7 +107,7 @@ bool GRAPHICS_CLEANER::isNullShape( PCB_SHAPE* aShape )
|
|||||||
return aShape->GetPointCount() == 0;
|
return aShape->GetPointCount() == 0;
|
||||||
|
|
||||||
case SHAPE_T::BEZIER:
|
case SHAPE_T::BEZIER:
|
||||||
aShape->RebuildBezierToSegmentsPointsList( ARC_HIGH_DEF );
|
aShape->RebuildBezierToSegmentsPointsList( m_maxError );
|
||||||
|
|
||||||
// If the Bezier points list contains 2 points, it is equivalent to a segment
|
// If the Bezier points list contains 2 points, it is equivalent to a segment
|
||||||
if( aShape->GetBezierPoints().size() == 2 )
|
if( aShape->GetBezierPoints().size() == 2 )
|
||||||
|
@ -61,12 +61,13 @@ private:
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const DRAWINGS& m_drawings;
|
const DRAWINGS& m_drawings;
|
||||||
FOOTPRINT* m_parentFootprint; // nullptr if not in Footprint Editor
|
FOOTPRINT* m_parentFootprint; // nullptr if not in Footprint Editor
|
||||||
BOARD_COMMIT& m_commit;
|
BOARD_COMMIT& m_commit;
|
||||||
TOOL_MANAGER* m_toolMgr;
|
TOOL_MANAGER* m_toolMgr;
|
||||||
bool m_dryRun;
|
bool m_dryRun;
|
||||||
int m_epsilon;
|
int m_epsilon;
|
||||||
int m_outlinesTolerance;
|
int m_maxError;
|
||||||
|
int m_outlinesTolerance;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<CLEANUP_ITEM>>* m_itemsList;
|
std::vector<std::shared_ptr<CLEANUP_ITEM>>* m_itemsList;
|
||||||
};
|
};
|
||||||
|
@ -2937,7 +2937,7 @@ PCB_SHAPE* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_SHAPE( BOARD_ITEM* aParent )
|
|||||||
shape->SetBezierC1( parseXY());
|
shape->SetBezierC1( parseXY());
|
||||||
shape->SetBezierC2( parseXY());
|
shape->SetBezierC2( parseXY());
|
||||||
shape->SetEnd( parseXY() );
|
shape->SetEnd( parseXY() );
|
||||||
shape->RebuildBezierToSegmentsPointsList( ARC_HIGH_DEF );
|
shape->RebuildBezierToSegmentsPointsList( m_board->GetDesignSettings().m_MaxError );
|
||||||
NeedRIGHT();
|
NeedRIGHT();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -500,37 +500,7 @@ void PCB_SHAPE::Flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
|
|||||||
|
|
||||||
void PCB_SHAPE::Mirror( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
|
void PCB_SHAPE::Mirror( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
|
||||||
{
|
{
|
||||||
// Mirror an edge of the footprint. the layer is not modified
|
flip( aCentre, aFlipDirection );
|
||||||
// This is a footprint shape modification.
|
|
||||||
|
|
||||||
switch( GetShape() )
|
|
||||||
{
|
|
||||||
case SHAPE_T::ARC:
|
|
||||||
case SHAPE_T::SEGMENT:
|
|
||||||
case SHAPE_T::RECTANGLE:
|
|
||||||
case SHAPE_T::CIRCLE:
|
|
||||||
case SHAPE_T::BEZIER:
|
|
||||||
MIRROR( m_start, aCentre, aFlipDirection );
|
|
||||||
MIRROR( m_end, aCentre, aFlipDirection );
|
|
||||||
MIRROR( m_arcCenter, aCentre, aFlipDirection );
|
|
||||||
MIRROR( m_bezierC1, aCentre, aFlipDirection );
|
|
||||||
MIRROR( m_bezierC2, aCentre, aFlipDirection );
|
|
||||||
|
|
||||||
if( GetShape() == SHAPE_T::ARC )
|
|
||||||
std::swap( m_start, m_end );
|
|
||||||
|
|
||||||
if( GetShape() == SHAPE_T::BEZIER )
|
|
||||||
RebuildBezierToSegmentsPointsList( ARC_HIGH_DEF );
|
|
||||||
|
|
||||||
break;
|
|
||||||
|
|
||||||
case SHAPE_T::POLY:
|
|
||||||
m_poly.Mirror( aCentre, aFlipDirection );
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
UNIMPLEMENTED_FOR( SHAPE_T_asString() );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -2827,29 +2827,13 @@ bool DRAWING_TOOL::drawArc( const TOOL_EVENT& aTool, PCB_SHAPE** aGraphic,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Update a bezier PCB_SHAPE from the current state of a Bezier Geometry Manager.
|
|
||||||
*/
|
|
||||||
static void updateBezierFromConstructionMgr( const KIGFX::PREVIEW::BEZIER_GEOM_MANAGER& aMgr,
|
|
||||||
PCB_SHAPE& aBezier )
|
|
||||||
{
|
|
||||||
VECTOR2I vec = aMgr.GetStart();
|
|
||||||
|
|
||||||
aBezier.SetStart( vec );
|
|
||||||
aBezier.SetBezierC1( aMgr.GetControlC1() );
|
|
||||||
aBezier.SetEnd( aMgr.GetEnd() );
|
|
||||||
aBezier.SetBezierC2( aMgr.GetControlC2() );
|
|
||||||
|
|
||||||
// Need this for the length preview to work
|
|
||||||
aBezier.RebuildBezierToSegmentsPointsList( ARC_HIGH_DEF );
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
std::unique_ptr<PCB_SHAPE> DRAWING_TOOL::drawOneBezier( const TOOL_EVENT& aTool,
|
std::unique_ptr<PCB_SHAPE> DRAWING_TOOL::drawOneBezier( const TOOL_EVENT& aTool,
|
||||||
const OPT_VECTOR2I& aStartingPoint,
|
const OPT_VECTOR2I& aStartingPoint,
|
||||||
const OPT_VECTOR2I& aStartingControl1Point,
|
const OPT_VECTOR2I& aStartingControl1Point,
|
||||||
DRAW_ONE_RESULT& aResult )
|
DRAW_ONE_RESULT& aResult )
|
||||||
{
|
{
|
||||||
|
int maxError = board()->GetDesignSettings().m_MaxError;
|
||||||
|
|
||||||
std::unique_ptr<PCB_SHAPE> bezier = std::make_unique<PCB_SHAPE>( m_frame->GetModel() );
|
std::unique_ptr<PCB_SHAPE> bezier = std::make_unique<PCB_SHAPE>( m_frame->GetModel() );
|
||||||
bezier->SetShape( SHAPE_T::BEZIER );
|
bezier->SetShape( SHAPE_T::BEZIER );
|
||||||
bezier->SetFlags( IS_NEW );
|
bezier->SetFlags( IS_NEW );
|
||||||
@ -2875,26 +2859,29 @@ std::unique_ptr<PCB_SHAPE> DRAWING_TOOL::drawOneBezier( const TOOL_EVENT& aToo
|
|||||||
m_view->Add( &bezierAsst );
|
m_view->Add( &bezierAsst );
|
||||||
PCB_GRID_HELPER grid( m_toolMgr, m_frame->GetMagneticItemsSettings() );
|
PCB_GRID_HELPER grid( m_toolMgr, m_frame->GetMagneticItemsSettings() );
|
||||||
|
|
||||||
const auto setCursor = [&]()
|
const auto setCursor =
|
||||||
{
|
[&]()
|
||||||
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
|
{
|
||||||
};
|
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
|
||||||
|
};
|
||||||
|
|
||||||
const auto resetProgress = [&]()
|
const auto resetProgress =
|
||||||
{
|
[&]()
|
||||||
preview.Clear();
|
{
|
||||||
bezier.reset();
|
preview.Clear();
|
||||||
};
|
bezier.reset();
|
||||||
|
};
|
||||||
|
|
||||||
m_controls->ShowCursor( true );
|
m_controls->ShowCursor( true );
|
||||||
m_controls->ForceCursorPosition( false );
|
m_controls->ForceCursorPosition( false );
|
||||||
// Set initial cursor
|
// Set initial cursor
|
||||||
setCursor();
|
setCursor();
|
||||||
|
|
||||||
const auto started = [&]()
|
const auto started =
|
||||||
{
|
[&]()
|
||||||
return bezierManager.GetStep() > KIGFX::PREVIEW::BEZIER_GEOM_MANAGER::SET_START;
|
{
|
||||||
};
|
return bezierManager.GetStep() > KIGFX::PREVIEW::BEZIER_GEOM_MANAGER::SET_START;
|
||||||
|
};
|
||||||
|
|
||||||
aResult = DRAW_ONE_RESULT::ACCEPTED;
|
aResult = DRAW_ONE_RESULT::ACCEPTED;
|
||||||
bool priming = false;
|
bool priming = false;
|
||||||
@ -3010,15 +2997,11 @@ std::unique_ptr<PCB_SHAPE> DRAWING_TOOL::drawOneBezier( const TOOL_EVENT& aToo
|
|||||||
{
|
{
|
||||||
// Use the current point for all remaining points
|
// Use the current point for all remaining points
|
||||||
while( bezierManager.GetStep() < KIGFX::PREVIEW::BEZIER_GEOM_MANAGER::SET_END )
|
while( bezierManager.GetStep() < KIGFX::PREVIEW::BEZIER_GEOM_MANAGER::SET_END )
|
||||||
{
|
|
||||||
bezierManager.AddPoint( cursorPos, true );
|
bezierManager.AddPoint( cursorPos, true );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if( bezierManager.GetStep() == KIGFX::PREVIEW::BEZIER_GEOM_MANAGER::SET_END )
|
if( bezierManager.GetStep() == KIGFX::PREVIEW::BEZIER_GEOM_MANAGER::SET_END )
|
||||||
{
|
|
||||||
preview.Add( bezier.get() );
|
preview.Add( bezier.get() );
|
||||||
}
|
|
||||||
|
|
||||||
// Return to the caller for a reset
|
// Return to the caller for a reset
|
||||||
if( doubleClick )
|
if( doubleClick )
|
||||||
@ -3033,9 +3016,7 @@ std::unique_ptr<PCB_SHAPE> DRAWING_TOOL::drawOneBezier( const TOOL_EVENT& aToo
|
|||||||
bezierManager.RemoveLastPoint();
|
bezierManager.RemoveLastPoint();
|
||||||
|
|
||||||
if( bezierManager.GetStep() < KIGFX::PREVIEW::BEZIER_GEOM_MANAGER::SET_END )
|
if( bezierManager.GetStep() < KIGFX::PREVIEW::BEZIER_GEOM_MANAGER::SET_END )
|
||||||
{
|
|
||||||
preview.Remove( bezier.get() );
|
preview.Remove( bezier.get() );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else if( evt->IsMotion() )
|
else if( evt->IsMotion() )
|
||||||
{
|
{
|
||||||
@ -3126,9 +3107,8 @@ std::unique_ptr<PCB_SHAPE> DRAWING_TOOL::drawOneBezier( const TOOL_EVENT& aToo
|
|||||||
m_view->Update( &bezierAsst );
|
m_view->Update( &bezierAsst );
|
||||||
evt->SetPassEvent();
|
evt->SetPassEvent();
|
||||||
}
|
}
|
||||||
else if( started()
|
else if( started() && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
|
||||||
&& ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
|
|| evt->IsAction( &ACTIONS::redo ) ) )
|
||||||
|| evt->IsAction( &ACTIONS::redo ) ) )
|
|
||||||
{
|
{
|
||||||
wxBell();
|
wxBell();
|
||||||
}
|
}
|
||||||
@ -3143,7 +3123,12 @@ std::unique_ptr<PCB_SHAPE> DRAWING_TOOL::drawOneBezier( const TOOL_EVENT& aToo
|
|||||||
}
|
}
|
||||||
else if( bezierManager.HasGeometryChanged() )
|
else if( bezierManager.HasGeometryChanged() )
|
||||||
{
|
{
|
||||||
updateBezierFromConstructionMgr( bezierManager, *bezier );
|
bezier->SetStart( bezierManager.GetStart() );
|
||||||
|
bezier->SetBezierC1( bezierManager.GetControlC1() );
|
||||||
|
bezier->SetEnd( bezierManager.GetEnd() );
|
||||||
|
bezier->SetBezierC2( bezierManager.GetControlC2() );
|
||||||
|
bezier->RebuildBezierToSegmentsPointsList( maxError );
|
||||||
|
|
||||||
m_view->Update( &preview );
|
m_view->Update( &preview );
|
||||||
m_view->Update( &bezierAsst );
|
m_view->Update( &bezierAsst );
|
||||||
|
|
||||||
|
@ -2008,9 +2008,11 @@ std::shared_ptr<EDIT_POINTS> PCB_POINT_EDITOR::makePoints( EDA_ITEM* aItem )
|
|||||||
case SHAPE_T::SEGMENT:
|
case SHAPE_T::SEGMENT:
|
||||||
m_editorBehavior = std::make_unique<EDA_SEGMENT_POINT_EDIT_BEHAVIOR>( *shape );
|
m_editorBehavior = std::make_unique<EDA_SEGMENT_POINT_EDIT_BEHAVIOR>( *shape );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHAPE_T::RECTANGLE:
|
case SHAPE_T::RECTANGLE:
|
||||||
m_editorBehavior = std::make_unique<RECTANGLE_POINT_EDIT_BEHAVIOR>( *shape );
|
m_editorBehavior = std::make_unique<RECTANGLE_POINT_EDIT_BEHAVIOR>( *shape );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SHAPE_T::ARC:
|
case SHAPE_T::ARC:
|
||||||
m_editorBehavior = std::make_unique<ARC_POINT_EDIT_BEHAVIOR>( *shape, m_arcEditMode,
|
m_editorBehavior = std::make_unique<ARC_POINT_EDIT_BEHAVIOR>( *shape, m_arcEditMode,
|
||||||
*getViewControls() );
|
*getViewControls() );
|
||||||
@ -2025,7 +2027,8 @@ std::shared_ptr<EDIT_POINTS> PCB_POINT_EDITOR::makePoints( EDA_ITEM* aItem )
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case SHAPE_T::BEZIER:
|
case SHAPE_T::BEZIER:
|
||||||
m_editorBehavior = std::make_unique<EDA_BEZIER_POINT_EDIT_BEHAVIOR>( *shape );
|
m_editorBehavior = std::make_unique<EDA_BEZIER_POINT_EDIT_BEHAVIOR>(
|
||||||
|
*shape, board()->GetDesignSettings().m_MaxError );
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: // suppress warnings
|
default: // suppress warnings
|
||||||
|
Loading…
x
Reference in New Issue
Block a user