Browse Source
Pcbnew: add bezier editing tool
Pcbnew: add bezier editing tool
Adds the initial implementation of bezier overlay (assistant) and geometry manager. This is only implemented in Pcbnew - the code is common, but eeschema doesn't currently use it for any shape. Relates-To: https://gitlab.com/kicad/code/kicad/-/issues/8828jobs
14 changed files with 796 additions and 2 deletions
-
2common/CMakeLists.txt
-
110common/preview_items/bezier_assistant.cpp
-
98common/preview_items/bezier_geom_manager.cpp
-
71include/preview_items/bezier_assistant.h
-
102include/preview_items/bezier_geom_manager.h
-
1pcbnew/menubar_footprint_editor.cpp
-
1pcbnew/menubar_pcb_editor.cpp
-
1pcbnew/pcb_edit_frame.cpp
-
3pcbnew/toolbars_footprint_editor.cpp
-
3pcbnew/toolbars_pcb_editor.cpp
-
373pcbnew/tools/drawing_tool.cpp
-
24pcbnew/tools/drawing_tool.h
-
8pcbnew/tools/pcb_actions.cpp
-
1pcbnew/tools/pcb_actions.h
@ -0,0 +1,110 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2017-2022 Kicad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
#include "preview_items/bezier_assistant.h"
|
|||
|
|||
#include <preview_items/draw_context.h>
|
|||
#include <preview_items/preview_utils.h>
|
|||
|
|||
#include <gal/graphics_abstraction_layer.h>
|
|||
#include <view/view.h>
|
|||
|
|||
#include <base_units.h>
|
|||
#include <trigo.h>
|
|||
|
|||
using namespace KIGFX::PREVIEW; |
|||
|
|||
BEZIER_ASSISTANT::BEZIER_ASSISTANT( const BEZIER_GEOM_MANAGER& aManager, |
|||
const EDA_IU_SCALE& aIuScale, EDA_UNITS aUnits ) : |
|||
EDA_ITEM( NOT_USED ), m_constructMan( aManager ), m_iuScale( aIuScale ), m_units( aUnits ) |
|||
{ |
|||
} |
|||
|
|||
|
|||
const BOX2I BEZIER_ASSISTANT::ViewBBox() const |
|||
{ |
|||
BOX2I tmp; |
|||
|
|||
// no bounding box when no graphic shown
|
|||
if( m_constructMan.IsReset() ) |
|||
return tmp; |
|||
|
|||
// this is an edit-time artefact; no reason to try and be smart with the bounding box
|
|||
// (besides, we can't tell the text extents without a view to know what the scale is)
|
|||
tmp.SetMaximum(); |
|||
return tmp; |
|||
} |
|||
|
|||
|
|||
void BEZIER_ASSISTANT::ViewDraw( int aLayer, KIGFX::VIEW* aView ) const |
|||
{ |
|||
KIGFX::GAL& gal = *aView->GetGAL(); |
|||
|
|||
// not in a position to draw anything
|
|||
if( m_constructMan.IsReset() ) |
|||
return; |
|||
|
|||
gal.ResetTextAttributes(); |
|||
|
|||
const VECTOR2I start = m_constructMan.GetStart(); |
|||
const BEZIER_GEOM_MANAGER::BEZIER_STEPS step = m_constructMan.GetStep(); |
|||
|
|||
KIGFX::PREVIEW::DRAW_CONTEXT preview_ctx( *aView ); |
|||
|
|||
int dashSize = KiROUND( aView->ToWorld( 12 ) ); |
|||
|
|||
if( step >= BEZIER_GEOM_MANAGER::BEZIER_STEPS::SET_CONTROL1 ) |
|||
{ |
|||
// Draw the first control point control line
|
|||
preview_ctx.DrawLineDashed( start, m_constructMan.GetControlC1(), dashSize, dashSize / 2, |
|||
false ); |
|||
} |
|||
|
|||
if( step >= BEZIER_GEOM_MANAGER::BEZIER_STEPS::SET_CONTROL2 ) |
|||
{ |
|||
const VECTOR2I c2vec = m_constructMan.GetControlC2() - m_constructMan.GetEnd(); |
|||
// Draw the second control point control line as a double length line
|
|||
// centred on the end point
|
|||
preview_ctx.DrawLineDashed( m_constructMan.GetEnd() - c2vec, m_constructMan.GetControlC2(), |
|||
dashSize, dashSize / 2, false ); |
|||
} |
|||
|
|||
std::vector<wxString> cursorStrings; |
|||
|
|||
if( step >= BEZIER_GEOM_MANAGER::BEZIER_STEPS::SET_END ) |
|||
{ |
|||
// Going to need a better way to get a length here
|
|||
// const int length = m_constructMan.GetBezierLength();
|
|||
// Have enough points to report a bezier length
|
|||
// cursorStrings.push_back( DimensionLabel( wxString::FromUTF8( "L" ), 12300000,
|
|||
// m_iuScale, m_units ) );
|
|||
} |
|||
|
|||
if( !cursorStrings.empty() ) |
|||
{ |
|||
// place the text next to cursor, on opposite side from radius
|
|||
DrawTextNextToCursor( aView, m_constructMan.GetLastPoint(), |
|||
start - m_constructMan.GetLastPoint(), cursorStrings, |
|||
aLayer == LAYER_SELECT_OVERLAY ); |
|||
} |
|||
} |
@ -0,0 +1,98 @@ |
|||
/*
|
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2024 Kicad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
|
|||
* or you may search the http://www.gnu.org website for the version 2 license,
|
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
#include "preview_items/bezier_geom_manager.h"
|
|||
|
|||
using namespace KIGFX::PREVIEW; |
|||
|
|||
|
|||
bool BEZIER_GEOM_MANAGER::acceptPoint( const VECTOR2I& aPt ) |
|||
{ |
|||
switch( getStep() ) |
|||
{ |
|||
case SET_START: return setStart( aPt ); |
|||
case SET_CONTROL1: return setControlC1( aPt ); |
|||
case SET_END: return setEnd( aPt ); |
|||
case SET_CONTROL2: return setControlC2( aPt ); |
|||
case COMPLETE: return false; |
|||
} |
|||
|
|||
return false; |
|||
} |
|||
|
|||
|
|||
VECTOR2I BEZIER_GEOM_MANAGER::GetStart() const |
|||
{ |
|||
return m_start; |
|||
} |
|||
|
|||
VECTOR2I BEZIER_GEOM_MANAGER::GetControlC1() const |
|||
{ |
|||
return m_controlC1; |
|||
} |
|||
|
|||
VECTOR2I BEZIER_GEOM_MANAGER::GetEnd() const |
|||
{ |
|||
return m_end; |
|||
} |
|||
|
|||
VECTOR2I BEZIER_GEOM_MANAGER::GetControlC2() const |
|||
{ |
|||
// The actual bezier C2 point is the reflection over the end point
|
|||
// so that the cursor will be on the C1 point of the next bezier.
|
|||
return m_end - ( m_controlC2 - m_end ); |
|||
} |
|||
|
|||
bool BEZIER_GEOM_MANAGER::setStart( const VECTOR2I& aStart ) |
|||
{ |
|||
m_start = aStart; |
|||
// Prevents wierd-looking loops if the control points aren't initialized
|
|||
m_end = aStart; |
|||
m_controlC1 = aStart; |
|||
m_controlC2 = aStart; |
|||
return true; |
|||
} |
|||
|
|||
|
|||
bool BEZIER_GEOM_MANAGER::setControlC1( const VECTOR2I& aControlC1 ) |
|||
{ |
|||
m_controlC1 = aControlC1; |
|||
m_end = m_controlC1; |
|||
m_controlC2 = m_controlC1; |
|||
// It's possible to set the control 1 point to the same as the start point
|
|||
return true; |
|||
} |
|||
|
|||
bool BEZIER_GEOM_MANAGER::setEnd( const VECTOR2I& aEnd ) |
|||
{ |
|||
m_end = aEnd; |
|||
m_controlC2 = m_end; |
|||
return m_end != m_start; |
|||
} |
|||
|
|||
bool BEZIER_GEOM_MANAGER::setControlC2( const VECTOR2I& aControlC2 ) |
|||
{ |
|||
m_controlC2 = aControlC2; |
|||
// It's possible to set the control 2 point to the same as the end point
|
|||
return true; |
|||
} |
@ -0,0 +1,71 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2024 Kicad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
|||
* or you may search the http://www.gnu.org website for the version 2 license, |
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <eda_item.h> |
|||
#include <preview_items/bezier_geom_manager.h> |
|||
#include <layer_ids.h> |
|||
|
|||
namespace KIGFX |
|||
{ |
|||
namespace PREVIEW |
|||
{ |
|||
/** |
|||
* Represents an assistant draw when interactively drawing a bezier on a canvas. |
|||
*/ |
|||
class BEZIER_ASSISTANT : public EDA_ITEM |
|||
{ |
|||
public: |
|||
BEZIER_ASSISTANT( const BEZIER_GEOM_MANAGER& aManager, const EDA_IU_SCALE& aIuScale, |
|||
EDA_UNITS aUnits ); |
|||
|
|||
const BOX2I ViewBBox() const override; |
|||
|
|||
void ViewGetLayers( int aLayers[], int& aCount ) const override |
|||
{ |
|||
aLayers[0] = LAYER_SELECT_OVERLAY; // Assistant graphics |
|||
aLayers[1] = LAYER_GP_OVERLAY; // Drop shadows |
|||
aCount = 2; |
|||
} |
|||
|
|||
/** |
|||
* Draw the assistance (with reference to the construction manager |
|||
*/ |
|||
void ViewDraw( int aLayer, KIGFX::VIEW* aView ) const override final; |
|||
|
|||
#if defined( DEBUG ) |
|||
void Show( int x, std::ostream& st ) const override {} |
|||
#endif |
|||
|
|||
wxString GetClass() const override { return "BEZIER_ASSISTANT"; } |
|||
|
|||
void SetUnits( EDA_UNITS aUnits ) { m_units = aUnits; } |
|||
|
|||
private: |
|||
const BEZIER_GEOM_MANAGER& m_constructMan; |
|||
const EDA_IU_SCALE& m_iuScale; |
|||
EDA_UNITS m_units; |
|||
}; |
|||
} // namespace PREVIEW |
|||
} // namespace KIGFX |
@ -0,0 +1,102 @@ |
|||
/* |
|||
* This program source code file is part of KiCad, a free EDA CAD application. |
|||
* |
|||
* Copyright (C) 2024 Kicad Developers, see AUTHORS.txt for contributors. |
|||
* |
|||
* This program is free software; you can redistribute it and/or |
|||
* modify it under the terms of the GNU General Public License |
|||
* as published by the Free Software Foundation; either version 2 |
|||
* of the License, or (at your option) any later version. |
|||
* |
|||
* This program is distributed in the hope that it will be useful, |
|||
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
|||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
|||
* GNU General Public License for more details. |
|||
* |
|||
* You should have received a copy of the GNU General Public License |
|||
* along with this program; if not, you may find one here: |
|||
* http://www.gnu.org/licenses/old-licenses/gpl-2.0.html |
|||
* or you may search the http://www.gnu.org website for the version 2 license, |
|||
* or you may write to the Free Software Foundation, Inc., |
|||
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA |
|||
*/ |
|||
|
|||
#pragma once |
|||
|
|||
#include <preview_items/multistep_geom_manager.h> |
|||
#include <geometry/eda_angle.h> |
|||
#include <geometry/seg.h> |
|||
|
|||
namespace KIGFX |
|||
{ |
|||
namespace PREVIEW |
|||
{ |
|||
|
|||
|
|||
/** |
|||
* Manage the construction of a bezier through a series of steps. |
|||
* |
|||
* See also @ref KIGFX::PREVIEW::ARC_GEOM_MANAGER. |
|||
* |
|||
* Interfaces are provided to return both arc geometry (can be used to set up real beziers on |
|||
* PCBs, for example) as well as important control points for informational overlays. |
|||
*/ |
|||
class BEZIER_GEOM_MANAGER : public MULTISTEP_GEOM_MANAGER |
|||
{ |
|||
public: |
|||
BEZIER_GEOM_MANAGER() {} |
|||
|
|||
enum BEZIER_STEPS |
|||
{ |
|||
SET_START = 0, ///< Waiting to lock in the start point |
|||
SET_CONTROL1, ///< Waiting to lock in the first control point |
|||
SET_END, ///< Waiting to lock in the end point |
|||
SET_CONTROL2, ///< Waiting to lock in the second control point |
|||
COMPLETE |
|||
}; |
|||
|
|||
int getMaxStep() const override { return COMPLETE; } |
|||
|
|||
/** |
|||
* Get the current step the manager is on (useful when drawing |
|||
* something depends on the current state) |
|||
*/ |
|||
BEZIER_STEPS GetStep() const { return static_cast<BEZIER_STEPS>( getStep() ); } |
|||
|
|||
bool acceptPoint( const VECTOR2I& aPt ) override; |
|||
|
|||
/* |
|||
* Geometry query interface - used by clients of the manager |
|||
*/ |
|||
|
|||
///< Get the center point of the arc (valid when state > SET_ORIGIN) |
|||
VECTOR2I GetStart() const; |
|||
|
|||
///< Get the coordinates of the arc start |
|||
VECTOR2I GetControlC1() const; |
|||
VECTOR2I GetControlC2() const; |
|||
|
|||
///< Get the coordinates of the arc end point |
|||
VECTOR2I GetEnd() const; |
|||
|
|||
private: |
|||
/* |
|||
* Point acceptor functions |
|||
*/ |
|||
|
|||
///< Set the center point of the arc |
|||
bool setStart( const VECTOR2I& aOrigin ); |
|||
bool setControlC1( const VECTOR2I& aControl ); |
|||
bool setEnd( const VECTOR2I& aCursor ); |
|||
bool setControlC2( const VECTOR2I& aControl ); |
|||
|
|||
/* |
|||
* Bezier geometry |
|||
*/ |
|||
VECTOR2I m_start; |
|||
VECTOR2I m_controlC1; |
|||
VECTOR2I m_end; |
|||
VECTOR2I m_controlC2; |
|||
}; |
|||
} // namespace PREVIEW |
|||
} // namespace KIGFX |
Write
Preview
Loading…
Cancel
Save
Reference in new issue