Added EC_CONVERGING for zone areas modification.
This commit is contained in:
parent
f8a0869314
commit
d19f57b0d5
|
@ -26,8 +26,7 @@
|
||||||
|
|
||||||
#include "edit_points.h"
|
#include "edit_points.h"
|
||||||
#include <gal/graphics_abstraction_layer.h>
|
#include <gal/graphics_abstraction_layer.h>
|
||||||
|
#include <geometry/seg.h>
|
||||||
#include <class_drawsegment.h>
|
|
||||||
|
|
||||||
bool EDIT_POINT::WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const
|
bool EDIT_POINT::WithinPoint( const VECTOR2I& aPoint, unsigned int aSize ) const
|
||||||
{
|
{
|
||||||
|
@ -205,3 +204,89 @@ void EC_CIRCLE::Apply()
|
||||||
|
|
||||||
m_constrained.SetPosition( m_center.GetPosition() + newLine );
|
m_constrained.SetPosition( m_center.GetPosition() + newLine );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EC_CONVERGING::EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ) :
|
||||||
|
EDIT_CONSTRAINT<EDIT_POINT>( aLine.GetEnd() ),
|
||||||
|
/*m_end( aLine.GetEnd() ), m_origin( aLine.GetOrigin() ),*/ m_line( aLine ),
|
||||||
|
m_editPoints( aPoints )
|
||||||
|
{
|
||||||
|
// Dragged segment endings
|
||||||
|
EDIT_POINT& origin = aLine.GetOrigin();
|
||||||
|
EDIT_POINT& end = aLine.GetEnd();
|
||||||
|
|
||||||
|
// Add constraint to the line origin, so it moves only along it current line
|
||||||
|
EDIT_POINT& prevOrigin = *aPoints.Previous( origin );
|
||||||
|
EDIT_POINT& nextEnd = *aPoints.Next( end );
|
||||||
|
|
||||||
|
// Constraints for segments adjacent to the dragged one
|
||||||
|
m_originSideConstraint = new EC_LINE( origin, prevOrigin );
|
||||||
|
m_endSideConstraint = new EC_LINE( end, nextEnd );
|
||||||
|
|
||||||
|
// Compute dragged segment slope
|
||||||
|
VECTOR2D delta = m_line.GetPosition() - end.GetPosition();
|
||||||
|
m_coefA = delta.y / delta.x;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
EC_CONVERGING::~EC_CONVERGING()
|
||||||
|
{
|
||||||
|
delete m_originSideConstraint;
|
||||||
|
delete m_endSideConstraint;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void EC_CONVERGING::Apply()
|
||||||
|
{
|
||||||
|
EDIT_POINT& origin = m_line.GetOrigin();
|
||||||
|
EDIT_POINT& end = m_line.GetEnd();
|
||||||
|
|
||||||
|
// Do not allow points on the adjacent segments move freely
|
||||||
|
m_originSideConstraint->Apply();
|
||||||
|
m_endSideConstraint->Apply();
|
||||||
|
|
||||||
|
// Find points that make adjacent segments
|
||||||
|
EDIT_POINT& prevOrigin = *m_editPoints.Previous( origin ); // point previous to origin
|
||||||
|
EDIT_POINT& nextEnd = *m_editPoints.Next( end ); // point next to end
|
||||||
|
|
||||||
|
// Two segments adjacent to the dragged segment
|
||||||
|
SEG originSide( origin.GetPosition(), prevOrigin.GetPosition() );
|
||||||
|
SEG endSide( end.GetPosition(), nextEnd.GetPosition() );
|
||||||
|
|
||||||
|
VECTOR2I draggedCenter; // center point of the dragged segment
|
||||||
|
|
||||||
|
// Check if adjacent segments intersect (did we dragged the line to the point that it may
|
||||||
|
// create a selfintersecting polygon?)
|
||||||
|
if( OPT_VECTOR2I originEndIntersect = endSide.Intersect( originSide ) )
|
||||||
|
draggedCenter = *originEndIntersect;
|
||||||
|
else
|
||||||
|
draggedCenter = m_line.GetPosition();
|
||||||
|
|
||||||
|
// Line B coefficient (y=Ax+B) for the dragged segment (A coefficient is computed up on the
|
||||||
|
// the construction of EC_CONVERGING
|
||||||
|
double coefB = draggedCenter.y - m_coefA * draggedCenter.x;
|
||||||
|
VECTOR2D draggedEnd = draggedCenter + 10000;
|
||||||
|
|
||||||
|
if( std::isfinite( m_coefA ) )
|
||||||
|
{
|
||||||
|
if( std::abs( m_coefA ) < 1 )
|
||||||
|
draggedEnd.y = m_coefA * draggedEnd.x + coefB;
|
||||||
|
else
|
||||||
|
draggedEnd.x = ( draggedEnd.y - coefB ) / m_coefA;
|
||||||
|
}
|
||||||
|
else // vertical line
|
||||||
|
{
|
||||||
|
draggedEnd.x = draggedCenter.x;
|
||||||
|
draggedEnd.y = draggedEnd.x + coefB;
|
||||||
|
}
|
||||||
|
|
||||||
|
SEG dragged( draggedCenter, draggedEnd ); // the dragged segment
|
||||||
|
|
||||||
|
// First intersection point (dragged segment against origin side)
|
||||||
|
if( OPT_VECTOR2I originIntersect = dragged.IntersectLines( originSide ) )
|
||||||
|
origin.SetPosition( *originIntersect );
|
||||||
|
|
||||||
|
// Second intersection point (dragged segment against end side)
|
||||||
|
if( OPT_VECTOR2I endIntersect = dragged.IntersectLines( endSide ) )
|
||||||
|
end.SetPosition( *endIntersect );
|
||||||
|
}
|
||||||
|
|
|
@ -579,4 +579,29 @@ private:
|
||||||
const EDIT_POINT& m_end;
|
const EDIT_POINT& m_end;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class EC_CONVERGING
|
||||||
|
*
|
||||||
|
* EDIT_CONSTRAINT for 3 segment: dragged and two adjacent ones, enforcing to keep their slopes
|
||||||
|
* and allows only to change ending points. Applied to zones.
|
||||||
|
*/
|
||||||
|
class EC_CONVERGING : public EDIT_CONSTRAINT<EDIT_POINT>
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints );
|
||||||
|
|
||||||
|
virtual ~EC_CONVERGING();
|
||||||
|
|
||||||
|
///> @copydoc EDIT_CONSTRAINT::Apply()
|
||||||
|
virtual void Apply();
|
||||||
|
|
||||||
|
private:
|
||||||
|
EC_LINE* m_originSideConstraint; ///< Constraint for origin side segment
|
||||||
|
EC_LINE* m_endSideConstraint; ///< Constraint for end side segment
|
||||||
|
EDIT_LINE& m_line; ///< Dragged segment
|
||||||
|
EDIT_POINTS& m_editPoints; ///< EDIT_POINT instance storing modified lines
|
||||||
|
double m_coefA; ///< Original dragged segment A coefficient (y = Ax + B)
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* EDIT_POINTS_H_ */
|
#endif /* EDIT_POINTS_H_ */
|
||||||
|
|
|
@ -135,7 +135,7 @@ private:
|
||||||
|
|
||||||
POINT_EDITOR::POINT_EDITOR() :
|
POINT_EDITOR::POINT_EDITOR() :
|
||||||
TOOL_INTERACTIVE( "pcbnew.PointEditor" ), m_selectionTool( NULL ), m_dragPoint( NULL ),
|
TOOL_INTERACTIVE( "pcbnew.PointEditor" ), m_selectionTool( NULL ), m_dragPoint( NULL ),
|
||||||
m_original( VECTOR2I( 0, 0 ) )
|
m_original( VECTOR2I( 0, 0 ) ), m_altConstrainer( VECTOR2I( 0, 0 ) )
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -143,6 +143,7 @@ POINT_EDITOR::POINT_EDITOR() :
|
||||||
void POINT_EDITOR::Reset( RESET_REASON aReason )
|
void POINT_EDITOR::Reset( RESET_REASON aReason )
|
||||||
{
|
{
|
||||||
m_editPoints.reset();
|
m_editPoints.reset();
|
||||||
|
m_altConstraint.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -175,8 +176,6 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent )
|
||||||
KIGFX::VIEW* view = getView();
|
KIGFX::VIEW* view = getView();
|
||||||
PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
|
PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
|
||||||
EDA_ITEM* item = selection.items.GetPickedItem( 0 );
|
EDA_ITEM* item = selection.items.GetPickedItem( 0 );
|
||||||
EDIT_POINT constrainer( VECTOR2I( 0, 0 ) );
|
|
||||||
boost::shared_ptr<EDIT_CONSTRAINT<EDIT_POINT> > degree45Constraint;
|
|
||||||
|
|
||||||
m_editPoints = EDIT_POINTS_FACTORY::Make( item );
|
m_editPoints = EDIT_POINTS_FACTORY::Make( item );
|
||||||
if( !m_editPoints )
|
if( !m_editPoints )
|
||||||
|
@ -237,24 +236,14 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent )
|
||||||
modified = true;
|
modified = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if( !!evt->Modifier( MD_CTRL ) != (bool) degree45Constraint ) // 45 degrees mode
|
bool enableAltConstraint = !!evt->Modifier( MD_CTRL );
|
||||||
{
|
if( enableAltConstraint != (bool) m_altConstraint ) // alternative constraint
|
||||||
if( !degree45Constraint )
|
setAltConstraint( enableAltConstraint );
|
||||||
{
|
|
||||||
// Find a proper constraining point for 45 degrees mode
|
|
||||||
constrainer = get45DegConstrainer();
|
|
||||||
degree45Constraint.reset( new EC_45DEGREE( *m_dragPoint, constrainer ) );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
degree45Constraint.reset();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
m_dragPoint->SetPosition( controls->GetCursorPosition() );
|
m_dragPoint->SetPosition( controls->GetCursorPosition() );
|
||||||
|
|
||||||
if( degree45Constraint )
|
if( m_altConstraint )
|
||||||
degree45Constraint->Apply();
|
m_altConstraint->Apply();
|
||||||
else
|
else
|
||||||
m_dragPoint->ApplyConstraint();
|
m_dragPoint->ApplyConstraint();
|
||||||
|
|
||||||
|
@ -271,7 +260,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent )
|
||||||
|
|
||||||
else if( evt->IsMouseUp( BUT_LEFT ) )
|
else if( evt->IsMouseUp( BUT_LEFT ) )
|
||||||
{
|
{
|
||||||
degree45Constraint.reset();
|
setAltConstraint( false );
|
||||||
modified = false;
|
modified = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -540,6 +529,32 @@ void POINT_EDITOR::updatePoints() const
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void POINT_EDITOR::setAltConstraint( bool aEnabled )
|
||||||
|
{
|
||||||
|
if( aEnabled )
|
||||||
|
{
|
||||||
|
EDIT_LINE* line = dynamic_cast<EDIT_LINE*>( m_dragPoint );
|
||||||
|
if( line )
|
||||||
|
{
|
||||||
|
if( m_editPoints->GetParent()->Type() == PCB_ZONE_AREA_T )
|
||||||
|
{
|
||||||
|
m_altConstraint.reset( new EC_CONVERGING( *line, *m_editPoints ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Find a proper constraining point for 45 degrees mode
|
||||||
|
m_altConstrainer = get45DegConstrainer();
|
||||||
|
m_altConstraint.reset( new EC_45DEGREE( *m_dragPoint, m_altConstrainer ) );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_altConstraint.reset();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
EDIT_POINT POINT_EDITOR::get45DegConstrainer() const
|
EDIT_POINT POINT_EDITOR::get45DegConstrainer() const
|
||||||
{
|
{
|
||||||
EDA_ITEM* item = m_editPoints->GetParent();
|
EDA_ITEM* item = m_editPoints->GetParent();
|
||||||
|
|
|
@ -68,6 +68,12 @@ private:
|
||||||
///> Currently available edit points.
|
///> Currently available edit points.
|
||||||
boost::shared_ptr<EDIT_POINTS> m_editPoints;
|
boost::shared_ptr<EDIT_POINTS> m_editPoints;
|
||||||
|
|
||||||
|
// Alternative constraint, enabled while a modifier key is held
|
||||||
|
boost::shared_ptr<EDIT_CONSTRAINT<EDIT_POINT> > m_altConstraint;
|
||||||
|
|
||||||
|
// EDIT_POINT for alternative constraint mode
|
||||||
|
EDIT_POINT m_altConstrainer;
|
||||||
|
|
||||||
///> Updates item's points with edit points.
|
///> Updates item's points with edit points.
|
||||||
void updateItem() const;
|
void updateItem() const;
|
||||||
|
|
||||||
|
@ -83,6 +89,9 @@ private:
|
||||||
return m_dragPoint == &aPoint;
|
return m_dragPoint == &aPoint;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
///> Sets up an alternative constraint (typically enabled upon a modifier key being pressed).
|
||||||
|
void setAltConstraint( bool aEnabled );
|
||||||
|
|
||||||
///> Returns a point that should be used as a constrainer for 45 degrees mode.
|
///> Returns a point that should be used as a constrainer for 45 degrees mode.
|
||||||
EDIT_POINT get45DegConstrainer() const;
|
EDIT_POINT get45DegConstrainer() const;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue