2012-01-14 19:50:32 +00:00
|
|
|
/*
|
|
|
|
* This program source code file is part of KiCad, a free EDA CAD application.
|
|
|
|
*
|
|
|
|
* Copyright (C) 2004 Jean-Pierre Charras, jaen-pierre.charras@gipsa-lab.inpg.com
|
2023-03-04 23:15:43 +00:00
|
|
|
* Copyright (C) 1992-2023 KiCad Developers, see AUTHORS.txt for contributors.
|
2012-01-14 19:50:32 +00:00
|
|
|
*
|
|
|
|
* 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
|
|
|
|
*/
|
|
|
|
|
2021-06-11 16:59:28 +00:00
|
|
|
#ifndef PCB_DIMENSION_H
|
|
|
|
#define PCB_DIMENSION_H
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2011-09-23 13:57:12 +00:00
|
|
|
|
2020-11-14 18:11:28 +00:00
|
|
|
#include <board_item.h>
|
2020-10-04 23:34:59 +00:00
|
|
|
#include <pcb_text.h>
|
2020-09-12 20:09:40 +00:00
|
|
|
#include <geometry/shape.h>
|
2021-03-05 23:10:18 +00:00
|
|
|
#include <geometry/circle.h>
|
2011-09-20 15:07:52 +00:00
|
|
|
|
2011-09-23 13:57:12 +00:00
|
|
|
class LINE_READER;
|
2013-01-12 17:32:24 +00:00
|
|
|
class MSG_PANEL_ITEM;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2011-08-01 15:29:27 +00:00
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
/// How to display the units in a dimension's text
|
|
|
|
enum class DIM_UNITS_FORMAT
|
|
|
|
{
|
|
|
|
NO_SUFFIX, // 1234.0
|
|
|
|
BARE_SUFFIX, // 1234.0 mm
|
|
|
|
PAREN_SUFFIX // 1234.0 (mm)
|
|
|
|
};
|
|
|
|
|
2023-03-05 13:27:22 +00:00
|
|
|
enum class DIM_PRECISION
|
|
|
|
{
|
|
|
|
X = 0, // 0
|
|
|
|
X_X, // 0.0
|
|
|
|
X_XX, // 0.00
|
|
|
|
X_XXX, // 0.000
|
|
|
|
X_XXXX, // 0.0000
|
|
|
|
X_XXXXX, // 0.00000
|
|
|
|
V_VV, // 0.00 / 0 / 0.0
|
|
|
|
V_VVV, // 0.000 / 0 / 0.00
|
|
|
|
V_VVVV, // 0.0000 / 0.0 / 0.000
|
|
|
|
V_VVVVV // 0.00000 / 0.00 / 0.0000
|
|
|
|
};
|
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
/// Where to place the text on a dimension
|
|
|
|
enum class DIM_TEXT_POSITION
|
|
|
|
{
|
|
|
|
OUTSIDE, ///< Text appears outside the dimension line (default)
|
|
|
|
INLINE, ///< Text appears in line with the dimension line
|
|
|
|
MANUAL ///< Text placement is manually set by the user
|
|
|
|
};
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Used for storing the units selection in the file because EDA_UNITS alone doesn't cut it
|
|
|
|
*/
|
|
|
|
enum class DIM_UNITS_MODE
|
|
|
|
{
|
|
|
|
INCHES,
|
|
|
|
MILS,
|
|
|
|
MILLIMETRES,
|
|
|
|
AUTOMATIC
|
|
|
|
};
|
|
|
|
|
2020-09-12 20:09:40 +00:00
|
|
|
/**
|
|
|
|
* Frame to show around dimension text
|
|
|
|
*/
|
2021-07-13 18:46:33 +00:00
|
|
|
enum class DIM_TEXT_BORDER
|
2020-09-12 20:09:40 +00:00
|
|
|
{
|
|
|
|
NONE,
|
2020-09-16 18:26:34 +00:00
|
|
|
RECTANGLE,
|
2020-09-12 20:09:40 +00:00
|
|
|
CIRCLE,
|
|
|
|
ROUNDRECT
|
|
|
|
};
|
|
|
|
|
2014-02-11 12:22:30 +00:00
|
|
|
/**
|
2020-09-09 03:17:08 +00:00
|
|
|
* Abstract dimension API
|
2014-02-11 12:22:30 +00:00
|
|
|
*
|
2020-09-09 03:17:08 +00:00
|
|
|
* Some notes about dimension nomenclature:
|
|
|
|
*
|
|
|
|
* - "feature points" are the points being measured by the dimension. For an example, the start
|
|
|
|
* and end points of a line to be measured. These are the first points picked when drawing a
|
|
|
|
* new dimension. Dimensions can have one or more feature points: linear dimensions (the only
|
|
|
|
* type supported in KiCad 5 and earlier) have two feature points; leader dimensions have one;
|
|
|
|
* and ordinate dimensions can have in theory an unlimited number of feature points.
|
|
|
|
*
|
|
|
|
* - "feature lines" are lines that coincide with feature points. Not all dimension types have
|
|
|
|
* feature lines. The actual start and end of feature lines is calculated from dimension style
|
|
|
|
* properties (offset from feature point to start of feature line, height of crossbar, and height
|
|
|
|
* of feature line past crossbar, for example in linear dimensions)
|
2014-02-11 12:22:30 +00:00
|
|
|
*
|
2020-09-09 03:17:08 +00:00
|
|
|
* - "crossbar" refers to the perpendicular line (usually with arrows at each end) between feature
|
|
|
|
* lines on linear dimensions
|
2014-02-11 12:22:30 +00:00
|
|
|
*/
|
2023-03-04 23:15:43 +00:00
|
|
|
class PCB_DIMENSION_BASE : public PCB_TEXT
|
2007-06-05 12:10:51 +00:00
|
|
|
{
|
2013-03-13 18:53:58 +00:00
|
|
|
public:
|
2021-06-11 16:59:28 +00:00
|
|
|
PCB_DIMENSION_BASE( BOARD_ITEM* aParent, KICAD_T aType = PCB_DIMENSION_T );
|
2020-09-12 20:09:40 +00:00
|
|
|
|
2022-08-21 19:54:07 +00:00
|
|
|
bool IsType( const std::vector<KICAD_T>& aScanTypes ) const override
|
2020-09-12 20:09:40 +00:00
|
|
|
{
|
|
|
|
if( BOARD_ITEM::IsType( aScanTypes ) )
|
|
|
|
return true;
|
|
|
|
|
2022-08-20 09:27:35 +00:00
|
|
|
for( KICAD_T scanType : aScanTypes )
|
2020-09-12 20:09:40 +00:00
|
|
|
{
|
2022-08-20 09:27:35 +00:00
|
|
|
if( scanType == PCB_LOCATE_GRAPHIC_T )
|
2020-09-12 20:09:40 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
|
|
|
}
|
2012-01-14 19:50:32 +00:00
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
/**
|
|
|
|
* The dimension's origin is the first feature point for the dimension. Every dimension has
|
|
|
|
* one or more feature points, so every dimension has at least an origin.
|
|
|
|
* @return the origin point of this dimension
|
|
|
|
*/
|
2022-01-01 06:04:08 +00:00
|
|
|
virtual const VECTOR2I& GetStart() const { return m_start; }
|
|
|
|
virtual void SetStart( const VECTOR2I& aPoint ) { m_start = aPoint; }
|
2012-01-14 19:50:32 +00:00
|
|
|
|
2022-01-01 06:04:08 +00:00
|
|
|
virtual const VECTOR2I& GetEnd() const { return m_end; }
|
|
|
|
virtual void SetEnd( const VECTOR2I& aPoint ) { m_end = aPoint; }
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2022-01-01 06:04:08 +00:00
|
|
|
VECTOR2I GetPosition() const override { return m_start; }
|
|
|
|
void SetPosition( const VECTOR2I& aPos ) override { m_start = aPos; }
|
2020-09-09 03:17:08 +00:00
|
|
|
|
2020-09-11 23:52:45 +00:00
|
|
|
bool GetOverrideTextEnabled() const { return m_overrideTextEnabled; }
|
|
|
|
void SetOverrideTextEnabled( bool aOverride ) { m_overrideTextEnabled = aOverride; }
|
|
|
|
|
|
|
|
wxString GetOverrideText() const { return m_valueString; }
|
|
|
|
void SetOverrideText( const wxString& aValue ) { m_valueString = aValue; }
|
2020-09-09 03:17:08 +00:00
|
|
|
|
2023-03-04 23:15:43 +00:00
|
|
|
void ChangeOverrideText( const wxString& aValue )
|
|
|
|
{
|
|
|
|
SetOverrideTextEnabled( true );
|
|
|
|
SetOverrideText( aValue );
|
|
|
|
updateText();
|
|
|
|
}
|
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
int GetMeasuredValue() const { return m_measuredValue; }
|
|
|
|
|
2021-07-24 13:23:55 +00:00
|
|
|
// KiCad normally calculates the measured value but some importers need to set it.
|
|
|
|
void SetMeasuredValue( int aValue ) { m_measuredValue = aValue; }
|
|
|
|
|
2020-09-11 02:38:30 +00:00
|
|
|
/**
|
2020-09-11 23:52:45 +00:00
|
|
|
* @return the dimension value, rendered with precision / zero suppression but no units, etc
|
2020-09-11 02:38:30 +00:00
|
|
|
*/
|
2020-09-11 23:52:45 +00:00
|
|
|
wxString GetValueText() const;
|
|
|
|
|
|
|
|
/**
|
2021-06-04 13:04:30 +00:00
|
|
|
* Update the dimension's cached text and geometry.
|
2020-09-11 23:52:45 +00:00
|
|
|
*/
|
|
|
|
void Update()
|
|
|
|
{
|
|
|
|
updateGeometry();
|
|
|
|
updateText();
|
|
|
|
}
|
2018-08-28 20:14:47 +00:00
|
|
|
|
2023-03-05 13:27:22 +00:00
|
|
|
void UpdateUnits()
|
|
|
|
{
|
|
|
|
SetUnitsMode( GetUnitsMode() );
|
|
|
|
updateText();
|
|
|
|
}
|
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
wxString GetPrefix() const { return m_prefix; }
|
2020-09-11 23:52:45 +00:00
|
|
|
void SetPrefix( const wxString& aPrefix );
|
2020-05-15 23:25:33 +00:00
|
|
|
|
2023-03-04 23:15:43 +00:00
|
|
|
void ChangePrefix( const wxString& aPrefix )
|
|
|
|
{
|
|
|
|
SetPrefix( aPrefix );
|
|
|
|
updateText();
|
|
|
|
}
|
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
wxString GetSuffix() const { return m_suffix; }
|
2020-09-11 23:52:45 +00:00
|
|
|
void SetSuffix( const wxString& aSuffix );
|
2020-05-15 23:25:33 +00:00
|
|
|
|
2023-03-04 23:15:43 +00:00
|
|
|
void ChangeSuffix( const wxString& aSuffix )
|
|
|
|
{
|
|
|
|
SetSuffix( aSuffix );
|
|
|
|
updateText();
|
|
|
|
}
|
|
|
|
|
2022-09-19 16:09:59 +00:00
|
|
|
EDA_UNITS GetUnits() const { return m_units; }
|
2020-10-02 20:51:24 +00:00
|
|
|
void SetUnits( EDA_UNITS aUnits );
|
2013-03-13 18:53:58 +00:00
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
DIM_UNITS_MODE GetUnitsMode() const;
|
|
|
|
void SetUnitsMode( DIM_UNITS_MODE aMode );
|
2013-03-13 18:53:58 +00:00
|
|
|
|
2023-03-04 23:15:43 +00:00
|
|
|
void ChangeUnitsMode( DIM_UNITS_MODE aMode )
|
|
|
|
{
|
|
|
|
SetUnitsMode( aMode );
|
|
|
|
updateText();
|
|
|
|
}
|
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
void SetAutoUnits( bool aAuto = true ) { m_autoUnits = aAuto; }
|
2011-11-30 21:15:56 +00:00
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
DIM_UNITS_FORMAT GetUnitsFormat() const { return m_unitsFormat; }
|
|
|
|
void SetUnitsFormat( const DIM_UNITS_FORMAT aFormat ) { m_unitsFormat = aFormat; }
|
2011-11-30 21:15:56 +00:00
|
|
|
|
2023-03-04 23:15:43 +00:00
|
|
|
void ChangeUnitsFormat( const DIM_UNITS_FORMAT aFormat )
|
|
|
|
{
|
|
|
|
SetUnitsFormat( aFormat );
|
|
|
|
updateText();
|
|
|
|
}
|
|
|
|
|
2023-03-05 13:27:22 +00:00
|
|
|
DIM_PRECISION GetPrecision() const { return m_precision; }
|
|
|
|
void SetPrecision( DIM_PRECISION aPrecision ) { m_precision = aPrecision; }
|
2008-04-01 05:21:50 +00:00
|
|
|
|
2023-03-05 13:27:22 +00:00
|
|
|
void ChangePrecision( DIM_PRECISION aPrecision )
|
2023-03-04 23:15:43 +00:00
|
|
|
{
|
|
|
|
SetPrecision( aPrecision );
|
|
|
|
updateText();
|
|
|
|
}
|
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
bool GetSuppressZeroes() const { return m_suppressZeroes; }
|
|
|
|
void SetSuppressZeroes( bool aSuppress ) { m_suppressZeroes = aSuppress; }
|
2009-08-03 07:55:08 +00:00
|
|
|
|
2023-03-04 23:15:43 +00:00
|
|
|
void ChangeSuppressZeroes( bool aSuppress )
|
|
|
|
{
|
|
|
|
SetSuppressZeroes( aSuppress );
|
|
|
|
updateText();
|
|
|
|
}
|
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
bool GetKeepTextAligned() const { return m_keepTextAligned; }
|
|
|
|
void SetKeepTextAligned( bool aKeepAligned ) { m_keepTextAligned = aKeepAligned; }
|
2011-12-14 04:29:25 +00:00
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
void SetTextPositionMode( DIM_TEXT_POSITION aMode ) { m_textPosition = aMode; }
|
|
|
|
DIM_TEXT_POSITION GetTextPositionMode() const { return m_textPosition; }
|
2011-12-14 04:29:25 +00:00
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
int GetArrowLength() const { return m_arrowLength; }
|
|
|
|
void SetArrowLength( int aLength ) { m_arrowLength = aLength; }
|
2014-02-11 12:22:30 +00:00
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
void SetExtensionOffset( int aOffset ) { m_extensionOffset = aOffset; }
|
|
|
|
int GetExtensionOffset() const { return m_extensionOffset; }
|
2014-02-11 12:22:30 +00:00
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
int GetLineThickness() const { return m_lineThickness; }
|
|
|
|
void SetLineThickness( int aWidth ) { m_lineThickness = aWidth; }
|
2014-02-11 12:22:30 +00:00
|
|
|
|
|
|
|
/**
|
2021-06-04 13:04:30 +00:00
|
|
|
* @return a list of line segments that make up this dimension (for drawing, plotting, etc).
|
2014-02-11 12:22:30 +00:00
|
|
|
*/
|
2020-09-12 20:09:40 +00:00
|
|
|
const std::vector<std::shared_ptr<SHAPE>>& GetShapes() const { return m_shapes; }
|
2020-09-09 03:17:08 +00:00
|
|
|
|
|
|
|
// BOARD_ITEM overrides
|
|
|
|
|
2022-01-01 06:04:08 +00:00
|
|
|
void Move( const VECTOR2I& offset ) override;
|
2022-01-13 19:32:00 +00:00
|
|
|
void Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle ) override;
|
2022-01-01 06:04:08 +00:00
|
|
|
void Flip( const VECTOR2I& aCentre, bool aFlipLeftRight ) override;
|
2014-03-12 09:46:11 +00:00
|
|
|
|
|
|
|
/**
|
2021-06-04 13:04:30 +00:00
|
|
|
* Mirror the dimension relative to a given horizontal axis.
|
|
|
|
*
|
|
|
|
* The text is not mirrored. Only its position (and angle) is mirrored. The layer is not
|
|
|
|
* changed.
|
|
|
|
*
|
|
|
|
* @param axis_pos is the vertical axis position to mirror around.
|
2014-03-12 09:46:11 +00:00
|
|
|
*/
|
2022-06-20 20:15:21 +00:00
|
|
|
virtual void Mirror( const VECTOR2I& axis_pos, bool aMirrorLeftRight = false );
|
2020-09-09 03:17:08 +00:00
|
|
|
|
|
|
|
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
|
|
|
|
|
2022-01-01 06:04:08 +00:00
|
|
|
bool HitTest( const VECTOR2I& aPosition, int aAccuracy ) const override;
|
2022-08-31 09:33:46 +00:00
|
|
|
bool HitTest( const BOX2I& aRect, bool aContained, int aAccuracy = 0 ) const override;
|
2020-09-09 03:17:08 +00:00
|
|
|
|
2022-08-31 09:15:42 +00:00
|
|
|
const BOX2I GetBoundingBox() const override;
|
2020-09-09 03:17:08 +00:00
|
|
|
|
2022-03-16 23:48:24 +00:00
|
|
|
std::shared_ptr<SHAPE> GetEffectiveShape( PCB_LAYER_ID aLayer,
|
|
|
|
FLASHING aFlash = FLASHING::DEFAULT ) const override;
|
2020-09-19 11:47:43 +00:00
|
|
|
|
2023-01-12 03:27:44 +00:00
|
|
|
wxString GetItemDescription( UNITS_PROVIDER* aUnitsProvider ) const override;
|
2020-09-09 03:17:08 +00:00
|
|
|
|
2020-09-17 00:54:58 +00:00
|
|
|
const BOX2I ViewBBox() const override;
|
2020-09-09 03:17:08 +00:00
|
|
|
|
2023-03-04 23:15:43 +00:00
|
|
|
void ClearRenderCache() override;
|
|
|
|
|
2022-10-21 12:48:45 +00:00
|
|
|
void TransformShapeToPolygon( SHAPE_POLY_SET& aBuffer, PCB_LAYER_ID aLayer, int aClearance,
|
|
|
|
int aError, ERROR_LOC aErrorLoc,
|
|
|
|
bool aIgnoreLineWidth = false ) const override;
|
2021-02-03 23:33:36 +00:00
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
#if defined(DEBUG)
|
|
|
|
virtual void Show( int nestLevel, std::ostream& os ) const override { ShowDummy( os ); }
|
|
|
|
#endif
|
|
|
|
|
|
|
|
protected:
|
2014-03-12 09:46:11 +00:00
|
|
|
|
|
|
|
/**
|
2021-06-04 13:04:30 +00:00
|
|
|
* Update the cached geometry of the dimension after changing any of its properties.
|
2014-03-12 09:46:11 +00:00
|
|
|
*/
|
2020-09-09 03:17:08 +00:00
|
|
|
virtual void updateGeometry() = 0;
|
2014-02-11 12:22:30 +00:00
|
|
|
|
|
|
|
/**
|
2021-06-04 13:04:30 +00:00
|
|
|
* Update the text field value from the current geometry (called by updateGeometry normally).
|
2014-02-11 12:22:30 +00:00
|
|
|
*/
|
2020-09-11 23:52:45 +00:00
|
|
|
virtual void updateText();
|
2020-09-09 03:17:08 +00:00
|
|
|
|
2020-09-12 20:09:40 +00:00
|
|
|
template<typename ShapeType>
|
2020-10-01 19:11:35 +00:00
|
|
|
void addShape( const ShapeType& aShape );
|
2020-09-12 20:09:40 +00:00
|
|
|
|
|
|
|
/**
|
2021-06-04 13:04:30 +00:00
|
|
|
* Find the intersection between a given segment and polygon outline.
|
|
|
|
*
|
|
|
|
* @param aPoly is the polygon to collide.
|
|
|
|
* @param aSeg is the segment to collide.
|
|
|
|
* @param aStart if true will start from aSeg.A, otherwise aSeg.B.
|
|
|
|
* @return a point on aSeg that collides with aPoly closest to the start, if one exists.
|
2020-09-12 20:09:40 +00:00
|
|
|
*/
|
2021-06-04 13:04:30 +00:00
|
|
|
static OPT_VECTOR2I segPolyIntersection( const SHAPE_POLY_SET& aPoly, const SEG& aSeg,
|
|
|
|
bool aStart = true );
|
2021-03-05 23:10:18 +00:00
|
|
|
static OPT_VECTOR2I segCircleIntersection( CIRCLE& aCircle, SEG& aSeg, bool aStart = true );
|
2021-06-04 13:04:30 +00:00
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
// Value format
|
2020-09-11 23:52:45 +00:00
|
|
|
bool m_overrideTextEnabled; ///< Manually specify the displayed measurement value
|
|
|
|
wxString m_valueString; ///< Displayed value when m_overrideValue = true
|
2020-09-09 03:17:08 +00:00
|
|
|
wxString m_prefix; ///< String prepended to the value
|
|
|
|
wxString m_suffix; ///< String appended to the value
|
|
|
|
EDA_UNITS m_units; ///< 0 = inches, 1 = mm
|
|
|
|
bool m_autoUnits; ///< If true, follow the currently selected UI units
|
|
|
|
DIM_UNITS_FORMAT m_unitsFormat; ///< How to render the units suffix
|
2023-03-05 13:27:22 +00:00
|
|
|
DIM_PRECISION m_precision; ///< Number of digits to display after decimal
|
2020-09-09 03:17:08 +00:00
|
|
|
bool m_suppressZeroes; ///< Suppress trailing zeroes
|
|
|
|
|
|
|
|
// Geometry
|
|
|
|
int m_lineThickness; ///< Thickness used for all graphics in the dimension
|
|
|
|
int m_arrowLength; ///< Length of arrow shapes
|
|
|
|
int m_extensionOffset; ///< Distance from feature points to extension line start
|
|
|
|
DIM_TEXT_POSITION m_textPosition; ///< How to position the text
|
|
|
|
bool m_keepTextAligned; ///< Calculate text orientation to match dimension
|
|
|
|
|
|
|
|
// Internal
|
|
|
|
int m_measuredValue; ///< value of PCB dimensions
|
2022-01-01 06:04:08 +00:00
|
|
|
VECTOR2I m_start;
|
|
|
|
VECTOR2I m_end;
|
2020-09-09 03:17:08 +00:00
|
|
|
|
2020-09-12 20:09:40 +00:00
|
|
|
///< Internal cache of drawn shapes
|
|
|
|
std::vector<std::shared_ptr<SHAPE>> m_shapes;
|
2023-03-04 23:15:43 +00:00
|
|
|
|
|
|
|
bool m_inClearRenderCache; ///< re-entrancy guard
|
2020-09-09 03:17:08 +00:00
|
|
|
};
|
2014-02-11 12:22:30 +00:00
|
|
|
|
2021-06-04 13:04:30 +00:00
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
/**
|
|
|
|
* For better understanding of the points that make a dimension:
|
|
|
|
*
|
|
|
|
* Note: historically KiCad called extension lines "feature lines", and also note that what we
|
|
|
|
* call the "crossbar line" here is more commonly called the "dimension line"
|
|
|
|
*
|
|
|
|
* Start (feature point 1) End (feature point 2)
|
|
|
|
* | |
|
|
|
|
* | <-- extension lines --> |
|
|
|
|
* | |
|
|
|
|
* | m_arrowG2F m_arrowD2F |
|
|
|
|
* | / \ |
|
|
|
|
* Crossbar start |/_______crossbar line________\| Crossbar end
|
|
|
|
* |\ m_text /|
|
|
|
|
* | \ / |
|
|
|
|
* | m_arrowG1F m_arrowD1F |
|
|
|
|
* | |
|
|
|
|
* m_featureLineGF m_featureLineDF
|
|
|
|
*/
|
2014-02-11 12:22:30 +00:00
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
/**
|
|
|
|
* An aligned dimension measures the distance between two feature points. It has a crossbar
|
|
|
|
* (dimension line) that stays parallel with the vector between the feature points.
|
|
|
|
*
|
|
|
|
* The height (distance from features to crossbar) can be set directly, or set by manipulating the
|
|
|
|
* crossbar start or end point (with the point editor).
|
|
|
|
*/
|
2021-06-11 16:59:28 +00:00
|
|
|
class PCB_DIM_ALIGNED : public PCB_DIMENSION_BASE
|
2020-09-09 03:17:08 +00:00
|
|
|
{
|
|
|
|
public:
|
2021-12-04 23:52:00 +00:00
|
|
|
PCB_DIM_ALIGNED( BOARD_ITEM* aParent, KICAD_T aType );
|
2020-09-09 03:17:08 +00:00
|
|
|
|
|
|
|
// Do not create a copy constructor & operator=.
|
|
|
|
// The ones generated by the compiler are adequate.
|
|
|
|
|
2021-06-11 16:59:28 +00:00
|
|
|
~PCB_DIM_ALIGNED() = default;
|
2020-09-09 03:17:08 +00:00
|
|
|
|
|
|
|
static inline bool ClassOf( const EDA_ITEM* aItem )
|
2018-07-21 12:49:19 +00:00
|
|
|
{
|
2021-12-04 23:52:00 +00:00
|
|
|
return aItem && ( aItem->Type() == PCB_DIM_ALIGNED_T
|
|
|
|
|| aItem->Type() == PCB_FP_DIM_ALIGNED_T );
|
2018-07-21 12:49:19 +00:00
|
|
|
}
|
2010-04-23 09:54:40 +00:00
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
EDA_ITEM* Clone() const override;
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2022-06-20 20:15:21 +00:00
|
|
|
void Mirror( const VECTOR2I& axis_pos, bool aMirrorLeftRight = false ) override;
|
|
|
|
|
2021-03-08 02:59:07 +00:00
|
|
|
BITMAPS GetMenuImage() const override;
|
2020-09-12 20:09:40 +00:00
|
|
|
|
2022-01-01 06:04:08 +00:00
|
|
|
const VECTOR2I& GetCrossbarStart() const { return m_crossBarStart; }
|
2020-09-09 03:17:08 +00:00
|
|
|
|
2022-01-01 06:04:08 +00:00
|
|
|
const VECTOR2I& GetCrossbarEnd() const { return m_crossBarEnd; }
|
2013-03-13 18:53:58 +00:00
|
|
|
|
2008-04-01 05:21:50 +00:00
|
|
|
/**
|
2021-06-04 13:04:30 +00:00
|
|
|
* Set the distance from the feature points to the crossbar line.
|
|
|
|
*
|
2020-09-09 03:17:08 +00:00
|
|
|
* @param aHeight is the new height.
|
2008-04-01 05:21:50 +00:00
|
|
|
*/
|
2021-01-19 16:08:37 +00:00
|
|
|
void SetHeight( int aHeight ) { m_height = aHeight; }
|
2020-09-09 03:17:08 +00:00
|
|
|
int GetHeight() const { return m_height; }
|
2008-04-01 05:21:50 +00:00
|
|
|
|
2023-03-04 23:15:43 +00:00
|
|
|
void ChangeHeight( int aHeight )
|
|
|
|
{
|
|
|
|
SetHeight( aHeight );
|
|
|
|
updateGeometry();
|
|
|
|
}
|
|
|
|
|
2008-04-01 05:21:50 +00:00
|
|
|
/**
|
2021-06-04 13:04:30 +00:00
|
|
|
* Update the stored height basing on points coordinates.
|
|
|
|
*
|
|
|
|
* @param aCrossbarStart is the start point of the crossbar.
|
2008-04-01 05:21:50 +00:00
|
|
|
*/
|
2022-01-01 06:04:08 +00:00
|
|
|
void UpdateHeight( const VECTOR2I& aCrossbarStart, const VECTOR2I& aCrossbarEnd );
|
2007-06-05 12:10:51 +00:00
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
void SetExtensionHeight( int aHeight ) { m_extensionHeight = aHeight; }
|
|
|
|
int GetExtensionHeight() const { return m_extensionHeight; }
|
2008-04-01 05:21:50 +00:00
|
|
|
|
2023-03-04 23:15:43 +00:00
|
|
|
void ChangeExtensionHeight( int aHeight )
|
|
|
|
{
|
|
|
|
SetExtensionHeight( aHeight );
|
|
|
|
updateGeometry();
|
|
|
|
}
|
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
/**
|
2021-06-04 13:04:30 +00:00
|
|
|
* Return the angle of the crossbar.
|
|
|
|
*
|
2020-09-09 03:17:08 +00:00
|
|
|
* @return Angle of the crossbar line expressed in radians.
|
|
|
|
*/
|
|
|
|
double GetAngle() const
|
|
|
|
{
|
2022-01-11 00:49:49 +00:00
|
|
|
VECTOR2I delta( m_end - m_start );
|
2020-09-09 03:17:08 +00:00
|
|
|
|
|
|
|
return atan2( (double)delta.y, (double)delta.x );
|
|
|
|
}
|
2008-01-06 12:43:57 +00:00
|
|
|
|
2016-09-24 18:53:15 +00:00
|
|
|
wxString GetClass() const override
|
2007-08-08 20:51:08 +00:00
|
|
|
{
|
2021-06-11 16:59:28 +00:00
|
|
|
return wxT( "PCB_DIM_ALIGNED" );
|
2007-08-08 20:51:08 +00:00
|
|
|
}
|
2011-02-25 16:23:24 +00:00
|
|
|
|
2021-01-19 16:08:37 +00:00
|
|
|
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
|
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
protected:
|
2022-11-11 17:09:25 +00:00
|
|
|
virtual void swapData( BOARD_ITEM* aImage ) override;
|
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
void updateGeometry() override;
|
2011-08-01 15:29:27 +00:00
|
|
|
|
2020-09-09 03:17:08 +00:00
|
|
|
void updateText() override;
|
2021-06-04 13:04:30 +00:00
|
|
|
|
|
|
|
// Geometry
|
|
|
|
int m_height; ///< Perpendicular distance from features to crossbar
|
|
|
|
int m_extensionHeight; ///< Length of extension lines past the crossbar
|
|
|
|
|
2022-01-01 06:04:08 +00:00
|
|
|
VECTOR2I m_crossBarStart; ///< Crossbar start control point
|
|
|
|
VECTOR2I m_crossBarEnd; ///< Crossbar end control point
|
2021-06-04 13:04:30 +00:00
|
|
|
|
2007-06-05 12:10:51 +00:00
|
|
|
};
|
|
|
|
|
2020-09-12 20:09:40 +00:00
|
|
|
|
2020-09-22 02:32:40 +00:00
|
|
|
/**
|
|
|
|
* An orthogonal dimension is like an aligned dimension, but the extension lines are locked to the
|
|
|
|
* X or Y axes, and the measurement is only taken in the X or Y direction.
|
|
|
|
*/
|
2021-06-11 16:59:28 +00:00
|
|
|
class PCB_DIM_ORTHOGONAL : public PCB_DIM_ALIGNED
|
2020-09-22 02:32:40 +00:00
|
|
|
{
|
|
|
|
public:
|
|
|
|
enum class DIR
|
|
|
|
{
|
|
|
|
HORIZONTAL, // Aligned with x-axis
|
|
|
|
VERTICAL // Aligned with y-axis
|
|
|
|
};
|
|
|
|
|
2021-12-04 23:52:00 +00:00
|
|
|
PCB_DIM_ORTHOGONAL( BOARD_ITEM* aParent, bool aInFP = false );
|
2020-09-22 02:32:40 +00:00
|
|
|
|
2021-06-11 16:59:28 +00:00
|
|
|
~PCB_DIM_ORTHOGONAL() = default;
|
2020-09-22 02:32:40 +00:00
|
|
|
|
|
|
|
static inline bool ClassOf( const EDA_ITEM* aItem )
|
|
|
|
{
|
2021-12-04 23:52:00 +00:00
|
|
|
return aItem && ( aItem->Type() == PCB_DIM_ORTHOGONAL_T
|
|
|
|
|| aItem->Type() == PCB_FP_DIM_ORTHOGONAL_T );
|
2020-09-22 02:32:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
EDA_ITEM* Clone() const override;
|
|
|
|
|
2021-03-08 02:59:07 +00:00
|
|
|
BITMAPS GetMenuImage() const override;
|
2020-09-22 02:32:40 +00:00
|
|
|
|
|
|
|
/**
|
2021-06-04 13:04:30 +00:00
|
|
|
* Set the orientation of the dimension line (so, perpendicular to the feature lines).
|
|
|
|
*
|
|
|
|
* @param aOrientation is the orientation the dimension should take.
|
2020-09-22 02:32:40 +00:00
|
|
|
*/
|
|
|
|
void SetOrientation( DIR aOrientation ) { m_orientation = aOrientation; }
|
|
|
|
DIR GetOrientation() const { return m_orientation; }
|
|
|
|
|
|
|
|
wxString GetClass() const override
|
|
|
|
{
|
2021-06-11 16:59:28 +00:00
|
|
|
return wxT( "PCB_DIM_ORTHOGONAL" );
|
2020-09-22 02:32:40 +00:00
|
|
|
}
|
2022-01-13 19:32:00 +00:00
|
|
|
void Rotate( const VECTOR2I& aRotCentre, const EDA_ANGLE& aAngle ) override;
|
2020-09-22 02:32:40 +00:00
|
|
|
|
|
|
|
protected:
|
2022-11-11 17:09:25 +00:00
|
|
|
void swapData( BOARD_ITEM* aImage ) override;
|
|
|
|
|
2020-09-22 02:32:40 +00:00
|
|
|
void updateGeometry() override;
|
|
|
|
|
|
|
|
void updateText() override;
|
2021-06-04 13:04:30 +00:00
|
|
|
|
|
|
|
private:
|
|
|
|
// Geometry
|
|
|
|
DIR m_orientation; ///< What axis to lock the dimension line to.
|
|
|
|
|
2020-09-22 02:32:40 +00:00
|
|
|
};
|
|
|
|
|
|
|
|
|
2021-07-13 18:46:33 +00:00
|
|
|
/**
|
|
|
|
* A radial dimension indicates either the radius or diameter of an arc or circle.
|
|
|
|
*
|
|
|
|
* A guide to the geometry of a circle dimension:
|
|
|
|
*
|
|
|
|
* |
|
|
|
|
* --a--
|
|
|
|
* |
|
|
|
|
*
|
|
|
|
*
|
|
|
|
* b_
|
|
|
|
* |\
|
|
|
|
* \
|
|
|
|
* c---d TEXT
|
|
|
|
*
|
|
|
|
* Point a (the center of the arc or circle) is m_start, point b (a point on the arc or circle)
|
|
|
|
* is m_end, point c is m_leaderLength away from b on the a-b vector, and point d is the end of
|
|
|
|
* the "text line". The c-d line is drawn from c to the text center, and clipped on the text
|
|
|
|
* bounding box.
|
|
|
|
*/
|
|
|
|
class PCB_DIM_RADIAL : public PCB_DIMENSION_BASE
|
|
|
|
{
|
|
|
|
public:
|
2021-12-04 23:52:00 +00:00
|
|
|
PCB_DIM_RADIAL( BOARD_ITEM* aParent, bool aInFP = false );
|
2021-07-13 18:46:33 +00:00
|
|
|
|
|
|
|
static inline bool ClassOf( const EDA_ITEM* aItem )
|
|
|
|
{
|
2021-12-04 23:52:00 +00:00
|
|
|
return aItem && ( aItem->Type() == PCB_DIM_RADIAL_T
|
|
|
|
|| aItem->Type() == PCB_FP_DIM_RADIAL_T );
|
2021-07-13 18:46:33 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
EDA_ITEM* Clone() const override;
|
|
|
|
|
|
|
|
void SetLeaderLength( int aLength ) { m_leaderLength = aLength; }
|
|
|
|
int GetLeaderLength() const { return m_leaderLength; }
|
|
|
|
|
2023-03-04 23:15:43 +00:00
|
|
|
void ChangeLeaderLength( int aLength )
|
|
|
|
{
|
|
|
|
SetLeaderLength( aLength );
|
|
|
|
updateGeometry();
|
|
|
|
}
|
|
|
|
|
2021-07-13 18:46:33 +00:00
|
|
|
// Returns the point (c).
|
2022-01-01 06:04:08 +00:00
|
|
|
VECTOR2I GetKnee() const;
|
2021-07-13 18:46:33 +00:00
|
|
|
|
|
|
|
BITMAPS GetMenuImage() const override;
|
|
|
|
|
|
|
|
wxString GetClass() const override
|
|
|
|
{
|
|
|
|
return wxT( "PCB_DIM_RADIAL" );
|
|
|
|
}
|
|
|
|
|
|
|
|
protected:
|
2022-11-11 17:09:25 +00:00
|
|
|
virtual void swapData( BOARD_ITEM* aImage ) override;
|
|
|
|
|
2021-07-13 18:46:33 +00:00
|
|
|
void updateText() override;
|
|
|
|
void updateGeometry() override;
|
|
|
|
|
|
|
|
private:
|
|
|
|
bool m_isDiameter;
|
|
|
|
int m_leaderLength;
|
|
|
|
};
|
|
|
|
|
|
|
|
|
2020-09-12 20:09:40 +00:00
|
|
|
/**
|
|
|
|
* A leader is a dimension-like object pointing to a specific point.
|
|
|
|
*
|
|
|
|
* A guide to the geometry of a leader:
|
|
|
|
*
|
2021-07-13 18:46:33 +00:00
|
|
|
* a_
|
|
|
|
* |\
|
|
|
|
* \
|
|
|
|
* b---c TEXT
|
2020-09-12 20:09:40 +00:00
|
|
|
*
|
|
|
|
* Point (a) is m_start, point (b) is m_end, point (c) is the end of the "text line"
|
|
|
|
* The b-c line is drawn from b to the text center, and clipped on the text bounding box.
|
|
|
|
*/
|
2021-06-11 16:59:28 +00:00
|
|
|
class PCB_DIM_LEADER : public PCB_DIMENSION_BASE
|
2020-09-12 20:09:40 +00:00
|
|
|
{
|
|
|
|
public:
|
2021-12-04 23:52:00 +00:00
|
|
|
PCB_DIM_LEADER( BOARD_ITEM* aParent, bool aInFP = false );
|
2020-09-12 20:09:40 +00:00
|
|
|
|
|
|
|
static inline bool ClassOf( const EDA_ITEM* aItem )
|
|
|
|
{
|
2021-12-04 23:52:00 +00:00
|
|
|
return aItem && ( aItem->Type() == PCB_DIM_LEADER_T
|
|
|
|
|| aItem->Type() == PCB_FP_DIM_LEADER_T );
|
2020-09-12 20:09:40 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
EDA_ITEM* Clone() const override;
|
|
|
|
|
2021-03-08 02:59:07 +00:00
|
|
|
BITMAPS GetMenuImage() const override;
|
2020-09-12 20:09:40 +00:00
|
|
|
|
|
|
|
wxString GetClass() const override
|
|
|
|
{
|
2021-06-11 16:59:28 +00:00
|
|
|
return wxT( "PCB_DIM_LEADER" );
|
2020-09-12 20:09:40 +00:00
|
|
|
}
|
|
|
|
|
2023-03-04 23:15:43 +00:00
|
|
|
void SetTextBorder( DIM_TEXT_BORDER aBorder ) { m_textBorder = aBorder; }
|
2021-07-13 18:46:33 +00:00
|
|
|
DIM_TEXT_BORDER GetTextBorder() const { return m_textBorder; }
|
2020-09-12 20:09:40 +00:00
|
|
|
|
2023-03-04 23:15:43 +00:00
|
|
|
void ChangeTextBorder( DIM_TEXT_BORDER aBorder )
|
|
|
|
{
|
|
|
|
SetTextBorder( aBorder );
|
|
|
|
updateGeometry();
|
|
|
|
}
|
|
|
|
|
2020-09-24 21:23:16 +00:00
|
|
|
void GetMsgPanelInfo( EDA_DRAW_FRAME* aFrame, std::vector<MSG_PANEL_ITEM>& aList ) override;
|
|
|
|
|
2020-09-12 20:09:40 +00:00
|
|
|
protected:
|
2022-11-11 17:09:25 +00:00
|
|
|
virtual void swapData( BOARD_ITEM* aImage ) override;
|
|
|
|
|
2023-03-05 13:27:22 +00:00
|
|
|
void updateText() override;
|
2020-09-12 20:09:40 +00:00
|
|
|
void updateGeometry() override;
|
2021-06-04 13:04:30 +00:00
|
|
|
|
|
|
|
private:
|
2021-07-13 18:46:33 +00:00
|
|
|
DIM_TEXT_BORDER m_textBorder;
|
2020-09-12 20:09:40 +00:00
|
|
|
};
|
|
|
|
|
2020-09-17 00:54:58 +00:00
|
|
|
|
|
|
|
/**
|
2021-06-04 13:04:30 +00:00
|
|
|
* Mark the center of a circle or arc with a cross shape.
|
|
|
|
*
|
2020-09-17 00:54:58 +00:00
|
|
|
* The size and orientation of the cross is adjustable.
|
|
|
|
* m_start always marks the center being measured; m_end marks the end of one leg of the cross.
|
|
|
|
*/
|
2021-06-11 16:59:28 +00:00
|
|
|
class PCB_DIM_CENTER : public PCB_DIMENSION_BASE
|
2020-09-17 00:54:58 +00:00
|
|
|
{
|
|
|
|
public:
|
2021-12-04 23:52:00 +00:00
|
|
|
PCB_DIM_CENTER( BOARD_ITEM* aParent, bool aInFP = false );
|
2020-09-17 00:54:58 +00:00
|
|
|
|
|
|
|
static inline bool ClassOf( const EDA_ITEM* aItem )
|
|
|
|
{
|
2021-12-04 23:52:00 +00:00
|
|
|
return aItem && ( aItem->Type() == PCB_DIM_CENTER_T
|
|
|
|
|| aItem->Type() == PCB_FP_DIM_CENTER_T );
|
2020-09-17 00:54:58 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
EDA_ITEM* Clone() const override;
|
|
|
|
|
2021-03-08 02:59:07 +00:00
|
|
|
BITMAPS GetMenuImage() const override;
|
2020-09-17 00:54:58 +00:00
|
|
|
|
|
|
|
wxString GetClass() const override
|
|
|
|
{
|
2021-06-11 16:59:28 +00:00
|
|
|
return wxT( "PCB_DIM_CENTER" );
|
2020-09-17 00:54:58 +00:00
|
|
|
}
|
|
|
|
|
2022-08-31 09:15:42 +00:00
|
|
|
const BOX2I GetBoundingBox() const override;
|
2020-09-17 00:54:58 +00:00
|
|
|
|
|
|
|
const BOX2I ViewBBox() const override;
|
|
|
|
|
|
|
|
protected:
|
2022-11-11 17:09:25 +00:00
|
|
|
virtual void swapData( BOARD_ITEM* aImage ) override;
|
|
|
|
|
2020-09-17 00:54:58 +00:00
|
|
|
void updateGeometry() override;
|
|
|
|
};
|
|
|
|
|
2020-11-11 23:05:59 +00:00
|
|
|
#endif // DIMENSION_H
|