Fix a bunch more bugs in bezier approximation.

This commit is contained in:
Jeff Young 2025-05-26 17:30:37 +01:00
parent e44c5a7fcd
commit e8e7282fe1
24 changed files with 105 additions and 148 deletions

View File

@ -305,7 +305,7 @@ bool EDA_SHAPE::Deserialize( const google::protobuf::Any &aContainer )
SetBezierC1( UnpackVector2( shape.bezier().control1() ) );
SetBezierC2( UnpackVector2( shape.bezier().control2() ) );
SetEnd( UnpackVector2( shape.bezier().end() ) );
RebuildBezierToSegmentsPointsList( ARC_HIGH_DEF );
RebuildBezierToSegmentsPointsList( getMaxError() );
}
return true;
@ -356,15 +356,6 @@ wxString EDA_SHAPE::SHAPE_T_asString() const
}
int EDA_SHAPE::GetArcToSegMaxErrorIU( bool aHighDefinition ) const
{
// Returning ARC_HIGH_DEF or ARC_LOW_DEF is suitable only for
// Pcbnew calculations
// For other cases a GetArcToSegMaxErrorIU() must be probably override this one
return aHighDefinition ? ARC_HIGH_DEF : ARC_LOW_DEF;
}
void EDA_SHAPE::setPosition( const VECTOR2I& aPos )
{
move( aPos - getPosition() );
@ -620,8 +611,7 @@ void EDA_SHAPE::UpdateHatching() const
break;
case SHAPE_T::CIRCLE:
TransformCircleToPolygon( shapeBuffer, getCenter(), GetRadius(),
GetArcToSegMaxErrorIU(), ERROR_INSIDE );
TransformCircleToPolygon( shapeBuffer, getCenter(), GetRadius(), getMaxError(), ERROR_INSIDE );
break;
case SHAPE_T::POLY:
@ -789,7 +779,7 @@ void EDA_SHAPE::scale( double aScale )
scalePt( m_end );
scalePt( m_bezierC1 );
scalePt( m_bezierC2 );
RebuildBezierToSegmentsPointsList( m_stroke.GetWidth() / 2 );
RebuildBezierToSegmentsPointsList( getMaxError() );
break;
default:
@ -897,7 +887,7 @@ void EDA_SHAPE::flip( const VECTOR2I& aCentre, FLIP_DIRECTION aFlipDirection )
MIRROR( m_bezierC1, aCentre, aFlipDirection );
MIRROR( m_bezierC2, aCentre, aFlipDirection );
RebuildBezierToSegmentsPointsList( m_stroke.GetWidth() / 2 );
RebuildBezierToSegmentsPointsList( getMaxError() );
break;
default:
@ -1934,7 +1924,7 @@ void EDA_SHAPE::beginEdit( const VECTOR2I& aPosition )
SetBezierC2( aPosition );
m_editState = 1;
RebuildBezierToSegmentsPointsList( GetWidth() / 2 );
RebuildBezierToSegmentsPointsList( getMaxError() );
break;
case SHAPE_T::POLY:
@ -2016,7 +2006,7 @@ void EDA_SHAPE::calcEdit( const VECTOR2I& aPosition )
case 3: SetBezierC2( aPosition ); break;
}
RebuildBezierToSegmentsPointsList( GetWidth() / 2 );
RebuildBezierToSegmentsPointsList( getMaxError() );
}
break;

View File

@ -229,7 +229,7 @@ void EDA_BEZIER_POINT_EDIT_BEHAVIOR::UpdateItem( const EDIT_POINT& aEditedPoint,
m_bezier.SetEnd( aPoints.Point( BEZIER_END ).GetPosition() );
}
m_bezier.RebuildBezierToSegmentsPointsList( ARC_HIGH_DEF );
m_bezier.RebuildBezierToSegmentsPointsList( m_maxError );
}

View File

@ -217,7 +217,7 @@ void GRAPHICS_IMPORTER_LIB_SYMBOL::AddSpline( const VECTOR2D& aStart,
spline->SetBezierC1( MapCoordinate( aBezierControl1 ) );
spline->SetBezierC2( MapCoordinate( aBezierControl2 ) );
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
// null (i.e. very small) length

View File

@ -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->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->SetEnd( bezier.End );
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 );
}
@ -2743,7 +2743,7 @@ void SCH_IO_ALTIUM::ParseEllipticalArc( const std::map<wxString, wxString>& aPro
}
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->SetFillMode( fillMode );
schbezier->RebuildBezierToSegmentsPointsList( schbezier->GetWidth() / 2 );
schbezier->RebuildBezierToSegmentsPointsList( schIUScale.mmToIU( ARC_LOW_DEF_MM ) );
screen->Append( schbezier );
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 );
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() );
}

View File

@ -1400,7 +1400,7 @@ SCH_SHAPE* SCH_IO_KICAD_LEGACY_LIB_CACHE::loadBezier( LINE_READER& aReader )
pt.y = -schIUScale.MilsToIU( parseInt( aReader, line, &line ) );
bezier->SetEnd( pt );
bezier->RebuildBezierToSegmentsPointsList( bezier->GetWidth() / 2 );
bezier->RebuildBezierToSegmentsPointsList( schIUScale.mmToIU( ARC_LOW_DEF_MM ) );
if( *line != 0 )
bezier->SetFillMode( parseFillMode( aReader, line, &line ) );

View File

@ -86,7 +86,8 @@ SCH_IO_KICAD_SEXPR_PARSER::SCH_IO_KICAD_SEXPR_PARSER( LINE_READER* aLineReader,
m_lineReader( aLineReader ),
m_lastProgressLine( 0 ),
m_lineCount( aLineCount ),
m_rootSheet( aRootSheet )
m_rootSheet( aRootSheet ),
m_maxError( ARC_LOW_DEF_MM * schIUScale.IU_PER_MM )
{
}
@ -1458,7 +1459,7 @@ SCH_SHAPE* SCH_IO_KICAD_SEXPR_PARSER::parseSymbolBezier()
}
}
bezier->RebuildBezierToSegmentsPointsList( bezier->GetPenWidth() / 2 );
bezier->RebuildBezierToSegmentsPointsList( m_maxError );
return bezier.release();
}
@ -2653,6 +2654,9 @@ void SCH_IO_KICAD_SEXPR_PARSER::ParseSchematic( SCH_SHEET* aSheet, bool aIsCopya
wxCHECK( screen != nullptr, /* void */ );
if( SCHEMATIC* schematic = dynamic_cast<SCHEMATIC*>( screen->GetParent() ) )
m_maxError = schematic->Settings().m_MaxError;
if( aIsCopyableOnly )
m_requiredVersion = aFileVersion;
@ -4293,7 +4297,7 @@ SCH_SHAPE* SCH_IO_KICAD_SEXPR_PARSER::parseSchBezier()
}
}
bezier->RebuildBezierToSegmentsPointsList( bezier->GetPenWidth() / 2 );
bezier->RebuildBezierToSegmentsPointsList( m_maxError );
return bezier.release();
}

View File

@ -271,6 +271,9 @@ private:
/// The rootsheet for full project loads or null for importing a schematic.
SCH_SHEET* m_rootSheet;
/// Max deviation allowed when approximating bezier curves
int m_maxError;
std::vector<GROUP_INFO> m_groupInfos;
};

View File

@ -49,14 +49,6 @@ EDA_ITEM* SCH_SHAPE::Clone() const
}
int SCH_SHAPE::GetArcToSegMaxErrorIU( bool aHighDefinition ) const
{
// Returns the equivalent of ARC_HIGH_DEF or ARC_LOW_DEF in eeschema IU
return aHighDefinition ?
schIUScale.mmToIU( ARC_HIGH_DEF_MM ) : schIUScale.mmToIU( ARC_LOW_DEF_MM );
}
void SCH_SHAPE::swapData( SCH_ITEM* aItem )
{
SCH_SHAPE* shape = static_cast<SCH_SHAPE*>( aItem );

View File

@ -27,6 +27,7 @@
#include <sch_item.h>
#include <eda_shape.h>
#include <schematic.h>
class SCH_SHAPE : public SCH_ITEM, public EDA_SHAPE
@ -76,14 +77,6 @@ public:
return GetHatchLineWidth() * 40;
}
/**
* @return a suitable value for error approximation when converting arc/circle to segments
* this value is in internal units
* @param aHightDef = true for high definition
* high def = similar to ARC_HIGH_DEF but in Eeschema IU, low def = similar to ARC_LOW_DEF
*/
int GetArcToSegMaxErrorIU( bool aHighDefinition = true ) const override;
void SetFilled( bool aFilled ) override;
const BOX2I GetBoundingBox() const override;
@ -153,7 +146,10 @@ protected:
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 );
}
/**

View File

@ -64,13 +64,13 @@ SCHEMATIC_SETTINGS::SCHEMATIC_SETTINGS( JSON_SETTINGS* aParent, const std::strin
m_SpiceSaveAllDissipations( false ),
m_SpiceSaveAllEvents( true ),
m_SpiceModelCurSheetAsRoot( true ),
m_MaxError( ARC_LOW_DEF_MM * schIUScale.IU_PER_MM ),
m_NgspiceSettings( nullptr )
{
SETTINGS_MANAGER& mgr = Pgm().GetSettingsManager();
EESCHEMA_SETTINGS* cfg = mgr.GetAppSettings<EESCHEMA_SETTINGS>( "eeschema" );
int defaultLineThickness =
cfg ? cfg->m_Drawing.default_line_thickness : DEFAULT_LINE_WIDTH_MILS;
int defaultLineThickness = cfg ? cfg->m_Drawing.default_line_thickness : DEFAULT_LINE_WIDTH_MILS;
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 defaultJunctionSizeChoice = cfg ? cfg->m_Drawing.junction_size_choice : 3;

View File

@ -114,6 +114,9 @@ public:
KIFONT::METRICS m_FontMetrics;
/// Max deviation allowable when approximating circles and curves (in IU).
int m_MaxError;
/**
* Ngspice simulator settings.
*/

View File

@ -862,8 +862,15 @@ void SCH_POINT_EDITOR::makePointsAndBehavior( EDA_ITEM* aItem )
m_editBehavior = std::make_unique<EDA_POLYGON_POINT_EDIT_BEHAVIOR>( *shape );
break;
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;
}
default:
UNIMPLEMENTED_FOR( shape->SHAPE_T_asString() );
}

View File

@ -81,7 +81,9 @@ struct EDA_IU_SCALE
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 )
{
}

View File

@ -381,14 +381,6 @@ public:
return makeEffectiveShapes( aEdgeOnly );
}
/**
* @return a suitable value for error approximation when converting arc/circle to segments
* this value is in internal units
* @param aHightDef = true for high definition
* for boards, high def = ARC_HIGH_DEF, low def = ARC_LOW_DEF
*/
virtual int GetArcToSegMaxErrorIU( bool aHighDefinition = true ) const;
void ShapeGetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList );
void SetLength( const double& aLength );

View File

@ -130,7 +130,9 @@ protected:
class POLYGON_POINT_EDIT_BEHAVIOR : public POINT_EDIT_BEHAVIOR
{
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.
@ -201,7 +203,8 @@ public:
class EDA_SEGMENT_POINT_EDIT_BEHAVIOR : public POINT_EDIT_BEHAVIOR
{
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 );
}
@ -236,7 +239,8 @@ private:
class EDA_CIRCLE_POINT_EDIT_BEHAVIOR : public POINT_EDIT_BEHAVIOR
{
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 );
}
@ -271,7 +275,9 @@ private:
class EDA_BEZIER_POINT_EDIT_BEHAVIOR : public POINT_EDIT_BEHAVIOR
{
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 );
}
@ -296,6 +302,7 @@ protected:
private:
EDA_SHAPE& m_bezier;
int m_maxError;
};

View File

@ -398,7 +398,7 @@ bool doConvertOutlineToPolygon( std::vector<PCB_SHAPE*>& aShapeList, SHAPE_POLY_
}
// Ensure the approximated Bezier shape is built
graphic->RebuildBezierToSegmentsPointsList( ARC_HIGH_DEF );
graphic->RebuildBezierToSegmentsPointsList( aErrorMax );
if( reverse )
{

View File

@ -1158,7 +1158,7 @@ bool DIALOG_SHAPE_PROPERTIES::TransferDataFromWindow()
else
m_item->SetLocalSolderMaskMargin( m_solderMaskMargin.GetIntValue() );
m_item->RebuildBezierToSegmentsPointsList( ARC_HIGH_DEF );
m_item->RebuildBezierToSegmentsPointsList( m_parent->GetDesignSettings().m_MaxError );
if( m_item->IsOnCopperLayer() )
m_item->SetNetCode( m_netSelector->GetSelectedNetcode() );

View File

@ -312,7 +312,7 @@ bool DRC_TEST_PROVIDER_PHYSICAL_CLEARANCE::Run()
{
SHAPE_LINE_CHAIN asPoly;
shape->RebuildBezierToSegmentsPointsList( ARC_HIGH_DEF );
shape->RebuildBezierToSegmentsPointsList( errorMax );
for( const VECTOR2I& pt : shape->GetBezierPoints() )
asPoly.Append( pt );

View File

@ -43,7 +43,8 @@ GRAPHICS_CLEANER::GRAPHICS_CLEANER( const DRAWINGS& aDrawings, FOOTPRINT* aParen
m_commit( aCommit ),
m_toolMgr( aToolMgr ),
m_dryRun( true ),
m_epsilon( 0 ),
m_epsilon( 1 ),
m_maxError( ARC_HIGH_DEF ),
m_outlinesTolerance( 0 ),
m_itemsList( nullptr )
{
@ -59,7 +60,8 @@ void GRAPHICS_CLEANER::CleanupBoard( bool
m_itemsList = aItemsList;
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:
for( BOARD_ITEM* drawing : m_drawings )
@ -105,7 +107,7 @@ bool GRAPHICS_CLEANER::isNullShape( PCB_SHAPE* aShape )
return aShape->GetPointCount() == 0;
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( aShape->GetBezierPoints().size() == 2 )

View File

@ -61,12 +61,13 @@ private:
private:
const DRAWINGS& m_drawings;
FOOTPRINT* m_parentFootprint; // nullptr if not in Footprint Editor
BOARD_COMMIT& m_commit;
TOOL_MANAGER* m_toolMgr;
bool m_dryRun;
int m_epsilon;
int m_outlinesTolerance;
FOOTPRINT* m_parentFootprint; // nullptr if not in Footprint Editor
BOARD_COMMIT& m_commit;
TOOL_MANAGER* m_toolMgr;
bool m_dryRun;
int m_epsilon;
int m_maxError;
int m_outlinesTolerance;
std::vector<std::shared_ptr<CLEANUP_ITEM>>* m_itemsList;
};

View File

@ -3020,7 +3020,7 @@ PCB_SHAPE* PCB_IO_KICAD_SEXPR_PARSER::parsePCB_SHAPE( BOARD_ITEM* aParent )
shape->SetBezierC1( parseXY());
shape->SetBezierC2( parseXY());
shape->SetEnd( parseXY() );
shape->RebuildBezierToSegmentsPointsList( ARC_HIGH_DEF );
shape->RebuildBezierToSegmentsPointsList( m_board->GetDesignSettings().m_MaxError );
NeedRIGHT();
break;

View File

@ -572,37 +572,7 @@ void PCB_SHAPE::Flip( 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
// 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() );
}
flip( aCentre, aFlipDirection );
}

View File

@ -2812,29 +2812,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,
const OPT_VECTOR2I& aStartingPoint,
const OPT_VECTOR2I& aStartingControl1Point,
DRAW_ONE_RESULT& aResult )
{
int maxError = board()->GetDesignSettings().m_MaxError;
std::unique_ptr<PCB_SHAPE> bezier = std::make_unique<PCB_SHAPE>( m_frame->GetModel() );
bezier->SetShape( SHAPE_T::BEZIER );
bezier->SetFlags( IS_NEW );
@ -2860,26 +2844,29 @@ std::unique_ptr<PCB_SHAPE> DRAWING_TOOL::drawOneBezier( const TOOL_EVENT& aToo
m_view->Add( &bezierAsst );
PCB_GRID_HELPER grid( m_toolMgr, m_frame->GetMagneticItemsSettings() );
const auto setCursor = [&]()
{
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
};
const auto setCursor =
[&]()
{
m_frame->GetCanvas()->SetCurrentCursor( KICURSOR::PENCIL );
};
const auto resetProgress = [&]()
{
preview.Clear();
bezier.reset();
};
const auto resetProgress =
[&]()
{
preview.Clear();
bezier.reset();
};
m_controls->ShowCursor( true );
m_controls->ForceCursorPosition( false );
// Set initial cursor
setCursor();
const auto started = [&]()
{
return bezierManager.GetStep() > KIGFX::PREVIEW::BEZIER_GEOM_MANAGER::SET_START;
};
const auto started =
[&]()
{
return bezierManager.GetStep() > KIGFX::PREVIEW::BEZIER_GEOM_MANAGER::SET_START;
};
aResult = DRAW_ONE_RESULT::ACCEPTED;
bool priming = false;
@ -2995,15 +2982,11 @@ std::unique_ptr<PCB_SHAPE> DRAWING_TOOL::drawOneBezier( const TOOL_EVENT& aToo
{
// Use the current point for all remaining points
while( bezierManager.GetStep() < KIGFX::PREVIEW::BEZIER_GEOM_MANAGER::SET_END )
{
bezierManager.AddPoint( cursorPos, true );
}
}
if( bezierManager.GetStep() == KIGFX::PREVIEW::BEZIER_GEOM_MANAGER::SET_END )
{
preview.Add( bezier.get() );
}
// Return to the caller for a reset
if( doubleClick )
@ -3018,9 +3001,7 @@ std::unique_ptr<PCB_SHAPE> DRAWING_TOOL::drawOneBezier( const TOOL_EVENT& aToo
bezierManager.RemoveLastPoint();
if( bezierManager.GetStep() < KIGFX::PREVIEW::BEZIER_GEOM_MANAGER::SET_END )
{
preview.Remove( bezier.get() );
}
}
else if( evt->IsMotion() )
{
@ -3111,9 +3092,8 @@ std::unique_ptr<PCB_SHAPE> DRAWING_TOOL::drawOneBezier( const TOOL_EVENT& aToo
m_view->Update( &bezierAsst );
evt->SetPassEvent();
}
else if( started()
&& ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
|| evt->IsAction( &ACTIONS::redo ) ) )
else if( started() && ( ZONE_FILLER_TOOL::IsZoneFillAction( evt )
|| evt->IsAction( &ACTIONS::redo ) ) )
{
wxBell();
}
@ -3128,7 +3108,12 @@ std::unique_ptr<PCB_SHAPE> DRAWING_TOOL::drawOneBezier( const TOOL_EVENT& aToo
}
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( &bezierAsst );

View File

@ -1611,12 +1611,14 @@ std::shared_ptr<EDIT_POINTS> PCB_POINT_EDITOR::makePoints( EDA_ITEM* aItem )
case SHAPE_T::SEGMENT:
m_editorBehavior = std::make_unique<EDA_SEGMENT_POINT_EDIT_BEHAVIOR>( *shape );
break;
case SHAPE_T::RECTANGLE:
m_editorBehavior = std::make_unique<RECTANGLE_POINT_EDIT_BEHAVIOR>( *shape );
break;
case SHAPE_T::ARC:
m_editorBehavior =
std::make_unique<EDA_ARC_POINT_EDIT_BEHAVIOR>( *shape, m_arcEditMode, *getViewControls() );
m_editorBehavior = std::make_unique<EDA_ARC_POINT_EDIT_BEHAVIOR>(
*shape, m_arcEditMode, *getViewControls() );
break;
case SHAPE_T::CIRCLE:
@ -1628,7 +1630,8 @@ std::shared_ptr<EDIT_POINTS> PCB_POINT_EDITOR::makePoints( EDA_ITEM* aItem )
break;
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;
default: // suppress warnings