Loading pcbnew/tools/edit_points.cpp +87 −2 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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 ); } pcbnew/tools/edit_points.h +25 −0 Original line number Diff line number Diff line Loading @@ -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_ */ pcbnew/tools/point_editor.cpp +34 −19 Original line number Diff line number Diff line Loading @@ -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 ) ) { } Loading @@ -143,6 +143,7 @@ POINT_EDITOR::POINT_EDITOR() : void POINT_EDITOR::Reset( RESET_REASON aReason ) { m_editPoints.reset(); m_altConstraint.reset(); } Loading Loading @@ -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 ) Loading Loading @@ -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(); Loading @@ -271,7 +260,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) else if( evt->IsMouseUp( BUT_LEFT ) ) { degree45Constraint.reset(); setAltConstraint( false ); modified = false; } Loading Loading @@ -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(); Loading pcbnew/tools/point_editor.h +9 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading Loading
pcbnew/tools/edit_points.cpp +87 −2 Original line number Diff line number Diff line Loading @@ -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 { Loading Loading @@ -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 ); }
pcbnew/tools/edit_points.h +25 −0 Original line number Diff line number Diff line Loading @@ -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_ */
pcbnew/tools/point_editor.cpp +34 −19 Original line number Diff line number Diff line Loading @@ -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 ) ) { } Loading @@ -143,6 +143,7 @@ POINT_EDITOR::POINT_EDITOR() : void POINT_EDITOR::Reset( RESET_REASON aReason ) { m_editPoints.reset(); m_altConstraint.reset(); } Loading Loading @@ -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 ) Loading Loading @@ -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(); Loading @@ -271,7 +260,7 @@ int POINT_EDITOR::OnSelectionChange( TOOL_EVENT& aEvent ) else if( evt->IsMouseUp( BUT_LEFT ) ) { degree45Constraint.reset(); setAltConstraint( false ); modified = false; } Loading Loading @@ -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(); Loading
pcbnew/tools/point_editor.h +9 −0 Original line number Diff line number Diff line Loading @@ -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; Loading @@ -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; Loading