Added new constraint for EDIT_POINTs (EPC_LINE).
Dimensions have EDIT_POINTs. Different handling of 45 degree mode in POINT_EDITOR.
This commit is contained in:
parent
66fcb84f92
commit
e6571f6862
|
@ -47,13 +47,9 @@
|
|||
|
||||
DIMENSION::DIMENSION( BOARD_ITEM* aParent ) :
|
||||
BOARD_ITEM( aParent, PCB_DIMENSION_T ),
|
||||
m_Text( this )
|
||||
m_Width( Millimeter2iu( 0.2 ) ), m_Unit( INCHES ), m_Value( 0 ), m_Height( 0 ), m_Text( this )
|
||||
{
|
||||
m_Layer = DRAW_N;
|
||||
m_Width = Millimeter2iu( 0.2 );
|
||||
m_Value = 0;
|
||||
m_Shape = 0;
|
||||
m_Unit = INCHES;
|
||||
}
|
||||
|
||||
|
||||
|
@ -99,6 +95,7 @@ void DIMENSION::Copy( DIMENSION* source )
|
|||
SetLayer( source->GetLayer() );
|
||||
m_Width = source->m_Width;
|
||||
m_Shape = source->m_Shape;
|
||||
m_Height = source->m_Height;
|
||||
m_Unit = source->m_Unit;
|
||||
SetTimeStamp( GetNewTimeStamp() );
|
||||
m_Text.Copy( &source->m_Text );
|
||||
|
@ -195,7 +192,6 @@ void DIMENSION::Mirror( const wxPoint& axis_pos )
|
|||
|
||||
void DIMENSION::SetOrigin( const wxPoint& aOrigin )
|
||||
{
|
||||
m_crossBarO = aOrigin;
|
||||
m_featureLineGO = aOrigin;
|
||||
|
||||
AdjustDimensionDetails();
|
||||
|
@ -204,29 +200,32 @@ void DIMENSION::SetOrigin( const wxPoint& aOrigin )
|
|||
|
||||
void DIMENSION::SetEnd( const wxPoint& aEnd )
|
||||
{
|
||||
m_crossBarF = aEnd;
|
||||
m_featureLineDO = aEnd;
|
||||
|
||||
AdjustDimensionDetails();
|
||||
}
|
||||
|
||||
|
||||
void DIMENSION::SetHeight( double aHeight )
|
||||
void DIMENSION::SetHeight( int aHeight )
|
||||
{
|
||||
/* Calculating the direction of travel perpendicular to the selected axis. */
|
||||
double angle = GetAngle() + ( M_PI / 2 );
|
||||
|
||||
int dx = KiROUND( aHeight * cos( angle ) );
|
||||
int dy = KiROUND( aHeight * sin( angle ) );
|
||||
m_crossBarO.x = m_featureLineGO.x + dx;
|
||||
m_crossBarO.y = m_featureLineGO.y + dy;
|
||||
m_crossBarF.x = m_featureLineDO.x + dx;
|
||||
m_crossBarF.y = m_featureLineDO.y + dy;
|
||||
m_Height = aHeight;
|
||||
|
||||
AdjustDimensionDetails();
|
||||
}
|
||||
|
||||
|
||||
void DIMENSION::UpdateHeight()
|
||||
{
|
||||
VECTOR2D featureLine( m_crossBarO - m_featureLineGO );
|
||||
VECTOR2D crossBar( m_featureLineDO - m_featureLineGO );
|
||||
|
||||
if( featureLine.Cross( crossBar ) > 0 )
|
||||
m_Height = -featureLine.EuclideanNorm();
|
||||
else
|
||||
m_Height = featureLine.EuclideanNorm();
|
||||
}
|
||||
|
||||
|
||||
void DIMENSION::AdjustDimensionDetails( bool aDoNotChangeText )
|
||||
{
|
||||
const int arrowz = DMils2iu( 500 ); // size of arrows
|
||||
|
@ -281,6 +280,13 @@ void DIMENSION::AdjustDimensionDetails( bool aDoNotChangeText )
|
|||
arrow_dw_Y = wxRound( arrowz * sin( angle_f ) );
|
||||
}
|
||||
|
||||
int dx = KiROUND( m_Height * cos( angle + M_PI / 2 ) );
|
||||
int dy = KiROUND( m_Height * sin( angle + M_PI / 2 ) );
|
||||
m_crossBarO.x = m_featureLineGO.x + dx;
|
||||
m_crossBarO.y = m_featureLineGO.y + dy;
|
||||
m_crossBarF.x = m_featureLineDO.x + dx;
|
||||
m_crossBarF.y = m_featureLineDO.y + dy;
|
||||
|
||||
m_arrowG1F.x = m_crossBarO.x + arrow_up_X;
|
||||
m_arrowG1F.y = m_crossBarO.y + arrow_up_Y;
|
||||
|
||||
|
|
|
@ -61,14 +61,13 @@ class MSG_PANEL_ITEM;
|
|||
*/
|
||||
class DIMENSION : public BOARD_ITEM
|
||||
{
|
||||
int m_Width;
|
||||
int m_Shape; // / Currently always 0.
|
||||
int m_Unit; // / 0 = inches, 1 = mm
|
||||
int m_Value; // / value of PCB dimensions.
|
||||
|
||||
int m_Width; ///< Line width
|
||||
int m_Shape; ///< Currently always 0.
|
||||
EDA_UNITS_T m_Unit; ///< 0 = inches, 1 = mm
|
||||
int m_Value; ///< value of PCB dimensions.
|
||||
int m_Height; ///< length of feature lines
|
||||
TEXTE_PCB m_Text;
|
||||
|
||||
|
||||
public:
|
||||
// TODO private: These member should be private. they are public only due to legacy code
|
||||
wxPoint m_crossBarO, m_crossBarF;
|
||||
|
@ -117,7 +116,7 @@ public:
|
|||
*/
|
||||
const wxPoint& GetOrigin() const
|
||||
{
|
||||
return m_crossBarO;
|
||||
return m_featureLineGO;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -133,7 +132,7 @@ public:
|
|||
*/
|
||||
const wxPoint& GetEnd()
|
||||
{
|
||||
return m_crossBarF;
|
||||
return m_featureLineDO;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -141,12 +140,27 @@ public:
|
|||
* Sets the length of feature lines.
|
||||
* @param aHeight is the new height.
|
||||
*/
|
||||
void SetHeight( double aHeight );
|
||||
void SetHeight( int aHeight );
|
||||
|
||||
/**
|
||||
* Function GetHeight
|
||||
* Returns the length of feature lines.
|
||||
*/
|
||||
int GetHeight() const
|
||||
{
|
||||
return m_Height;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function UpdateHeight
|
||||
* Updates stored height basing on points coordinates.
|
||||
*/
|
||||
void UpdateHeight();
|
||||
|
||||
/**
|
||||
* Function GetAngle
|
||||
* Returns angle of the crossbar.
|
||||
* @return Angle of the crossbar line.
|
||||
* @return Angle of the crossbar line expressed in radians.
|
||||
*/
|
||||
double GetAngle() const
|
||||
{
|
||||
|
|
|
@ -1438,6 +1438,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR )
|
|||
|
||||
parseXY( &dimension->m_featureLineDO.x, &dimension->m_featureLineDO.y );
|
||||
parseXY( &dimension->m_featureLineDF.x, &dimension->m_featureLineDF.y );
|
||||
dimension->UpdateHeight();
|
||||
NeedRIGHT();
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
@ -1451,6 +1452,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR )
|
|||
|
||||
parseXY( &dimension->m_featureLineGO.x, &dimension->m_featureLineGO.y );
|
||||
parseXY( &dimension->m_featureLineGF.x, &dimension->m_featureLineGF.y );
|
||||
dimension->UpdateHeight();
|
||||
NeedRIGHT();
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
@ -1465,6 +1467,7 @@ DIMENSION* PCB_PARSER::parseDIMENSION() throw( IO_ERROR, PARSE_ERROR )
|
|||
|
||||
parseXY( &dimension->m_crossBarO.x, &dimension->m_crossBarO.y );
|
||||
parseXY( &dimension->m_crossBarF.x, &dimension->m_crossBarF.y );
|
||||
dimension->UpdateHeight();
|
||||
NeedRIGHT();
|
||||
NeedRIGHT();
|
||||
break;
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
bool EDIT_POINT::WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const
|
||||
{
|
||||
// Corners of the square
|
||||
// Corners of the EDIT_POINT square
|
||||
VECTOR2I topLeft = GetPosition() - aSize;
|
||||
VECTOR2I bottomRight = GetPosition() + aSize;
|
||||
|
||||
|
@ -162,6 +162,42 @@ void EPC_45DEGREE::Apply()
|
|||
}
|
||||
|
||||
|
||||
EPC_LINE::EPC_LINE( EDIT_POINT& aConstrained, EDIT_POINT& aConstrainer ) :
|
||||
EDIT_POINT_CONSTRAINT( aConstrained ), m_constrainer( aConstrainer )
|
||||
{
|
||||
Update();
|
||||
}
|
||||
|
||||
|
||||
void EPC_LINE::Apply()
|
||||
{
|
||||
VECTOR2I position = m_constrained.GetPosition();
|
||||
|
||||
if( std::isfinite( m_coefA ) )
|
||||
{
|
||||
if( abs( m_coefA ) < 1 )
|
||||
position.y = m_coefA * position.x + m_coefB;
|
||||
else
|
||||
position.x = ( position.y - m_coefB ) / m_coefA;
|
||||
}
|
||||
else // vertical line
|
||||
{
|
||||
position.x = m_constrainer.GetX();
|
||||
}
|
||||
|
||||
m_constrained.SetPosition( position );
|
||||
}
|
||||
|
||||
|
||||
void EPC_LINE::Update()
|
||||
{
|
||||
// Compute line coefficients
|
||||
VECTOR2D delta = m_constrainer.GetPosition() - m_constrained.GetPosition();
|
||||
m_coefA = delta.y / delta.x;
|
||||
m_coefB = m_constrainer.GetY() - m_coefA * m_constrainer.GetX();
|
||||
}
|
||||
|
||||
|
||||
void EPC_CIRCLE::Apply()
|
||||
{
|
||||
VECTOR2I centerToEnd = m_end.GetPosition() - m_center.GetPosition();
|
||||
|
|
|
@ -97,6 +97,26 @@ public:
|
|||
return m_position;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetX()
|
||||
*
|
||||
* Returns X coordinate of an EDIT_POINT.
|
||||
*/
|
||||
int GetX() const
|
||||
{
|
||||
return GetPosition().x;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetX()
|
||||
*
|
||||
* Returns Y coordinate of an EDIT_POINT.
|
||||
*/
|
||||
int GetY() const
|
||||
{
|
||||
return GetPosition().y;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function SetPosition()
|
||||
*
|
||||
|
@ -132,6 +152,17 @@ public:
|
|||
m_constraint = aConstraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function GetConstraint()
|
||||
*
|
||||
* Returns the constraint imposed on an EDIT_POINT. If there are no constraints, NULL is
|
||||
* returned.
|
||||
*/
|
||||
EDIT_POINT_CONSTRAINT* GetConstraint() const
|
||||
{
|
||||
return m_constraint;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function ClearConstraint()
|
||||
*
|
||||
|
@ -468,6 +499,32 @@ private:
|
|||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class EPC_LINE
|
||||
*
|
||||
* EDIT_POINT_CONSTRAINT that imposes a constraint that a point has to lie on a line (determined
|
||||
* by 2 points).
|
||||
*/
|
||||
class EPC_LINE : public EDIT_POINT_CONSTRAINT
|
||||
{
|
||||
public:
|
||||
EPC_LINE( EDIT_POINT& aConstrained, EDIT_POINT& aConstrainer );
|
||||
|
||||
///> @copydoc EDIT_POINT_CONSTRAINT::Apply()
|
||||
virtual void Apply();
|
||||
|
||||
/**
|
||||
* Function Update()
|
||||
* Updates line coefficients that make the constraining line.
|
||||
*/
|
||||
void Update();
|
||||
|
||||
private:
|
||||
EDIT_POINT& m_constrainer; ///< Point that imposes the constraint.
|
||||
double m_coefA, m_coefB;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Class EPC_CIRCLE.
|
||||
*
|
||||
|
|
|
@ -35,6 +35,7 @@
|
|||
|
||||
#include <wxPcbStruct.h>
|
||||
#include <class_drawsegment.h>
|
||||
#include <class_dimension.h>
|
||||
#include <class_zone.h>
|
||||
|
||||
/**
|
||||
|
@ -60,8 +61,8 @@ public:
|
|||
switch( segment->GetShape() )
|
||||
{
|
||||
case S_SEGMENT:
|
||||
points->AddPoint( segment->GetStart() );
|
||||
points->AddPoint( segment->GetEnd() );
|
||||
points->AddPoint( segment->GetStart() ); // points[0]
|
||||
points->AddPoint( segment->GetEnd() ); // points[1]
|
||||
break;
|
||||
|
||||
case S_ARC:
|
||||
|
@ -75,8 +76,8 @@ public:
|
|||
break;
|
||||
|
||||
case S_CIRCLE:
|
||||
points->AddPoint( segment->GetCenter() );
|
||||
points->AddPoint( segment->GetEnd() );
|
||||
points->AddPoint( segment->GetCenter() ); // points[0]
|
||||
points->AddPoint( segment->GetEnd() ); // points[1]
|
||||
break;
|
||||
|
||||
default: // suppress warnings
|
||||
|
@ -98,8 +99,23 @@ public:
|
|||
for( int i = 0; i < cornersCount - 1; ++i )
|
||||
points->AddLine( (*points)[i], (*points)[i + 1] );
|
||||
|
||||
// The one missing line
|
||||
// The last missing line, connecting the last and the first polygon point
|
||||
points->AddLine( (*points)[cornersCount - 1], (*points)[0] );
|
||||
break;
|
||||
}
|
||||
|
||||
case PCB_DIMENSION_T:
|
||||
{
|
||||
const DIMENSION* dimension = static_cast<const DIMENSION*>( aItem );
|
||||
|
||||
points->AddPoint( dimension->m_featureLineGO );
|
||||
points->AddPoint( dimension->m_featureLineDO );
|
||||
points->AddPoint( dimension->m_crossBarO );
|
||||
points->AddPoint( dimension->m_crossBarF );
|
||||
|
||||
// Dimension height setting - edit points should move only along the feature lines
|
||||
(*points)[2].SetConstraint( new EPC_LINE( (*points)[2], (*points)[0] ) );
|
||||
(*points)[3].SetConstraint( new EPC_LINE( (*points)[3], (*points)[1] ) );
|
||||
|
||||
break;
|
||||
}
|
||||
|
@ -118,7 +134,7 @@ private:
|
|||
|
||||
|
||||
POINT_EDITOR::POINT_EDITOR() :
|
||||
TOOL_INTERACTIVE( "pcbnew.PointEditor" ), m_selectionTool( NULL )
|
||||
TOOL_INTERACTIVE( "pcbnew.PointEditor" ), m_selectionTool( NULL ), m_dragPoint( NULL )
|
||||
{
|
||||
}
|
||||
|
||||
|
@ -159,6 +175,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent )
|
|||
PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
|
||||
EDA_ITEM* item = selection.items.GetPickedItem( 0 );
|
||||
EDIT_POINT constrainer( VECTOR2I( 0, 0 ) );
|
||||
bool degree45 = false; // 45 degree mode
|
||||
|
||||
m_editPoints = EDIT_POINTS_FACTORY::Make( item );
|
||||
if( !m_editPoints )
|
||||
|
@ -218,18 +235,20 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent )
|
|||
modified = true;
|
||||
}
|
||||
|
||||
if( evt->Modifier( MD_CTRL ) ) // 45 degrees mode
|
||||
if( evt->Modifier( MD_CTRL ) != degree45 ) // 45 degrees mode
|
||||
{
|
||||
if( !m_dragPoint->IsConstrained() )
|
||||
degree45 = evt->Modifier( MD_CTRL );
|
||||
|
||||
if( degree45 )
|
||||
{
|
||||
// Find a proper constraining point for 45 degrees mode
|
||||
constrainer = get45DegConstrainer();
|
||||
m_dragPoint->SetConstraint( new EPC_45DEGREE( *m_dragPoint, constrainer ) );
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
m_dragPoint->ClearConstraint();
|
||||
else
|
||||
{
|
||||
m_dragPoint->ClearConstraint();
|
||||
}
|
||||
}
|
||||
|
||||
m_dragPoint->SetPosition( controls->GetCursorPosition() );
|
||||
|
@ -387,6 +406,47 @@ void POINT_EDITOR::updateItem() const
|
|||
break;
|
||||
}
|
||||
|
||||
case PCB_DIMENSION_T:
|
||||
{
|
||||
DIMENSION* dimension = static_cast<DIMENSION*>( item );
|
||||
|
||||
// Check which point is currently modified and updated dimension's points respectively
|
||||
if( isModified( (*m_editPoints)[0] ) )
|
||||
{
|
||||
dimension->SetOrigin( wxPoint( m_dragPoint->GetPosition().x, m_dragPoint->GetPosition().y ) );
|
||||
static_cast<EPC_LINE*>( (*m_editPoints)[2].GetConstraint() )->Update();
|
||||
static_cast<EPC_LINE*>( (*m_editPoints)[3].GetConstraint() )->Update();
|
||||
}
|
||||
else if( isModified( (*m_editPoints)[1] ) )
|
||||
{
|
||||
dimension->SetEnd( wxPoint( m_dragPoint->GetPosition().x, m_dragPoint->GetPosition().y ) );
|
||||
static_cast<EPC_LINE*>( (*m_editPoints)[2].GetConstraint() )->Update();
|
||||
static_cast<EPC_LINE*>( (*m_editPoints)[3].GetConstraint() )->Update();
|
||||
}
|
||||
else if( isModified( (*m_editPoints)[2] ) )
|
||||
{
|
||||
VECTOR2D featureLine( m_dragPoint->GetPosition() - dimension->GetOrigin() );
|
||||
VECTOR2D crossBar( dimension->GetEnd() - dimension->GetOrigin() );
|
||||
|
||||
if( featureLine.Cross( crossBar ) > 0 )
|
||||
dimension->SetHeight( -featureLine.EuclideanNorm() );
|
||||
else
|
||||
dimension->SetHeight( featureLine.EuclideanNorm() );
|
||||
}
|
||||
else if( isModified( (*m_editPoints)[3] ) )
|
||||
{
|
||||
VECTOR2D featureLine( m_dragPoint->GetPosition() - dimension->GetEnd() );
|
||||
VECTOR2D crossBar( dimension->GetEnd() - dimension->GetOrigin() );
|
||||
|
||||
if( featureLine.Cross( crossBar ) > 0 )
|
||||
dimension->SetHeight( -featureLine.EuclideanNorm() );
|
||||
else
|
||||
dimension->SetHeight( featureLine.EuclideanNorm() );
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -454,6 +514,17 @@ void POINT_EDITOR::updatePoints() const
|
|||
break;
|
||||
}
|
||||
|
||||
case PCB_DIMENSION_T:
|
||||
{
|
||||
const DIMENSION* dimension = static_cast<const DIMENSION*>( item );
|
||||
|
||||
(*m_editPoints)[0].SetPosition( dimension->m_featureLineGO );
|
||||
(*m_editPoints)[1].SetPosition( dimension->m_featureLineDO );
|
||||
(*m_editPoints)[2].SetPosition( dimension->m_crossBarO );
|
||||
(*m_editPoints)[3].SetPosition( dimension->m_crossBarF );
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -482,6 +553,14 @@ EDIT_POINT POINT_EDITOR::get45DegConstrainer() const
|
|||
}
|
||||
}
|
||||
}
|
||||
else if( item->Type() == PCB_DIMENSION_T )
|
||||
{
|
||||
// Constraint for crossbar
|
||||
if( isModified( (*m_editPoints)[0] ) )
|
||||
return (*m_editPoints)[1];
|
||||
else if( isModified( (*m_editPoints)[1] ) )
|
||||
return (*m_editPoints)[0];
|
||||
}
|
||||
|
||||
// In any other case we may align item to the current cursor position.
|
||||
return EDIT_POINT( getViewControls()->GetCursorPosition() );
|
||||
|
|
Loading…
Reference in New Issue