Commit 19a87ac7 authored by Maciej Suminski's avatar Maciej Suminski
Browse files

Added EC_CONVERGING for zone areas modification.

parent d6c1670c
Loading
Loading
Loading
Loading
+87 −2
Original line number Diff line number Diff line
@@ -26,8 +26,7 @@

#include "edit_points.h"
#include <gal/graphics_abstraction_layer.h>

#include <class_drawsegment.h>
#include <geometry/seg.h>

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 );
}


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 );
}
+25 −0
Original line number Diff line number Diff line
@@ -579,4 +579,29 @@ private:
    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_ */
+34 −19
Original line number Diff line number Diff line
@@ -135,7 +135,7 @@ private:

POINT_EDITOR::POINT_EDITOR() :
    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 )
{
    m_editPoints.reset();
    m_altConstraint.reset();
}


@@ -175,8 +176,6 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent )
        KIGFX::VIEW* view = getView();
        PCB_EDIT_FRAME* editFrame = getEditFrame<PCB_EDIT_FRAME>();
        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 );
        if( !m_editPoints )
@@ -237,24 +236,14 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent )
                    modified = true;
                }

                if( !!evt->Modifier( MD_CTRL ) != (bool) degree45Constraint )      // 45 degrees mode
                {
                    if( !degree45Constraint )
                    {
                        // Find a proper constraining point for 45 degrees mode
                        constrainer = get45DegConstrainer();
                        degree45Constraint.reset( new EC_45DEGREE( *m_dragPoint, constrainer ) );
                    }
                    else
                    {
                        degree45Constraint.reset();
                    }
                }
                bool enableAltConstraint = !!evt->Modifier( MD_CTRL );
                if( enableAltConstraint != (bool) m_altConstraint )  // alternative constraint
                    setAltConstraint( enableAltConstraint );

                m_dragPoint->SetPosition( controls->GetCursorPosition() );

                if( degree45Constraint )
                    degree45Constraint->Apply();
                if( m_altConstraint )
                    m_altConstraint->Apply();
                else
                    m_dragPoint->ApplyConstraint();

@@ -271,7 +260,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent )

            else if( evt->IsMouseUp( BUT_LEFT ) )
            {
                degree45Constraint.reset();
                setAltConstraint( 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
{
    EDA_ITEM* item = m_editPoints->GetParent();
+9 −0
Original line number Diff line number Diff line
@@ -68,6 +68,12 @@ private:
    ///> Currently available edit points.
    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.
    void updateItem() const;

@@ -83,6 +89,9 @@ private:
        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.
    EDIT_POINT get45DegConstrainer() const;