Commit 92a8f8f1 authored by Maciej Suminski's avatar Maciej Suminski

Support for zone cut-outs in the point editor (GAL).

parent 7ec906a3
...@@ -98,8 +98,8 @@ EC_CONVERGING::EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ) : ...@@ -98,8 +98,8 @@ EC_CONVERGING::EC_CONVERGING( EDIT_LINE& aLine, EDIT_POINTS& aPoints ) :
EDIT_POINT& end = aLine.GetEnd(); EDIT_POINT& end = aLine.GetEnd();
// Previous and next points, to make constraining lines (adjacent to the dragged line) // Previous and next points, to make constraining lines (adjacent to the dragged line)
EDIT_POINT& prevOrigin = *aPoints.Previous( origin ); EDIT_POINT& prevOrigin = *aPoints.Previous( origin, false );
EDIT_POINT& nextEnd = *aPoints.Next( end ); EDIT_POINT& nextEnd = *aPoints.Next( end, false );
// Constraints for segments adjacent to the dragged one // Constraints for segments adjacent to the dragged one
m_originSideConstraint = new EC_LINE( origin, prevOrigin ); m_originSideConstraint = new EC_LINE( origin, prevOrigin );
...@@ -147,8 +147,8 @@ void EC_CONVERGING::Apply( EDIT_LINE& aHandle ) ...@@ -147,8 +147,8 @@ void EC_CONVERGING::Apply( EDIT_LINE& aHandle )
m_originSideConstraint->Apply(); m_originSideConstraint->Apply();
m_endSideConstraint->Apply(); m_endSideConstraint->Apply();
EDIT_POINT& prevOrigin = *m_editPoints.Previous( origin ); EDIT_POINT& prevOrigin = *m_editPoints.Previous( origin, false );
EDIT_POINT& nextEnd = *m_editPoints.Next( end ); EDIT_POINT& nextEnd = *m_editPoints.Next( end, false );
// Two segments adjacent to the dragged segment // Two segments adjacent to the dragged segment
SEG originSide = SEG( origin.GetPosition(), prevOrigin.GetPosition() ); SEG originSide = SEG( origin.GetPosition(), prevOrigin.GetPosition() );
......
...@@ -60,22 +60,86 @@ EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation ) ...@@ -60,22 +60,86 @@ EDIT_POINT* EDIT_POINTS::FindPoint( const VECTOR2I& aLocation )
std::deque<EDIT_LINE>::iterator lit, litEnd; std::deque<EDIT_LINE>::iterator lit, litEnd;
for( lit = m_lines.begin(), litEnd = m_lines.end(); lit != litEnd; ++lit ) for( lit = m_lines.begin(), litEnd = m_lines.end(); lit != litEnd; ++lit )
{ {
EDIT_LINE& point = *lit; EDIT_LINE& line = *lit;
if( point.WithinPoint( aLocation, size ) ) if( line.WithinPoint( aLocation, size ) )
return &point; return &line;
} }
return NULL; return NULL;
} }
EDIT_POINT* EDIT_POINTS::Previous( const EDIT_POINT& aPoint ) int EDIT_POINTS::GetContourStartIdx( int aPointIdx ) const
{
int lastIdx = 0;
BOOST_FOREACH( int idx, m_contours )
{
if( idx >= aPointIdx )
return lastIdx;
lastIdx = idx + 1;
}
return lastIdx;
}
int EDIT_POINTS::GetContourEndIdx( int aPointIdx ) const
{
BOOST_FOREACH( int idx, m_contours )
{
if( idx >= aPointIdx )
return idx;
}
return m_points.size() - 1;
}
bool EDIT_POINTS::IsContourStart( int aPointIdx ) const
{
BOOST_FOREACH( int idx, m_contours )
{
if( idx + 1 == aPointIdx )
return true;
// the list is sorted, so we cannot expect it any further
if( idx > aPointIdx )
break;
}
return ( aPointIdx == 0 );
}
bool EDIT_POINTS::IsContourEnd( int aPointIdx ) const
{
BOOST_FOREACH( int idx, m_contours )
{
if( idx == aPointIdx )
return true;
// the list is sorted, so we cannot expect it any further
if( idx > aPointIdx )
break;
}
// the end of the list surely is the end of a contour
return ( aPointIdx == (int) m_points.size() - 1 );
}
EDIT_POINT* EDIT_POINTS::Previous( const EDIT_POINT& aPoint, bool aTraverseContours )
{ {
for( unsigned int i = 0; i < m_points.size(); ++i ) for( unsigned int i = 0; i < m_points.size(); ++i )
{ {
if( m_points[i] == aPoint ) if( m_points[i] == aPoint )
{ {
if( !aTraverseContours && IsContourStart( i ) )
return &m_points[GetContourEndIdx( i )];
if( i == 0 ) if( i == 0 )
return &m_points[m_points.size() - 1]; return &m_points[m_points.size() - 1];
else else
...@@ -104,12 +168,15 @@ EDIT_LINE* EDIT_POINTS::Previous( const EDIT_LINE& aLine ) ...@@ -104,12 +168,15 @@ EDIT_LINE* EDIT_POINTS::Previous( const EDIT_LINE& aLine )
} }
EDIT_POINT* EDIT_POINTS::Next( const EDIT_POINT& aPoint ) EDIT_POINT* EDIT_POINTS::Next( const EDIT_POINT& aPoint, bool aTraverseContours )
{ {
for( unsigned int i = 0; i < m_points.size(); ++i ) for( unsigned int i = 0; i < m_points.size(); ++i )
{ {
if( m_points[i] == aPoint ) if( m_points[i] == aPoint )
{ {
if( !aTraverseContours && IsContourEnd( i ) )
return &m_points[GetContourStartIdx( i )];
if( i == m_points.size() - 1 ) if( i == m_points.size() - 1 )
return &m_points[0]; return &m_points[0];
else else
...@@ -152,7 +219,9 @@ void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const ...@@ -152,7 +219,9 @@ void EDIT_POINTS::ViewDraw( int aLayer, KIGFX::GAL* aGal ) const
aGal->DrawRectangle( point.GetPosition() - size / 2, point.GetPosition() + size / 2 ); aGal->DrawRectangle( point.GetPosition() - size / 2, point.GetPosition() + size / 2 );
BOOST_FOREACH( const EDIT_LINE& line, m_lines ) BOOST_FOREACH( const EDIT_LINE& line, m_lines )
{
aGal->DrawCircle( line.GetPosition(), size / 2 ); aGal->DrawCircle( line.GetPosition(), size / 2 );
}
aGal->PopDepth(); aGal->PopDepth();
} }
...@@ -243,7 +243,6 @@ public: ...@@ -243,7 +243,6 @@ public:
return m_constraint.get(); return m_constraint.get();
} }
/** /**
* Function GetOrigin() * Function GetOrigin()
* *
...@@ -371,16 +370,65 @@ public: ...@@ -371,16 +370,65 @@ public:
m_lines.push_back( EDIT_LINE( aOrigin, aEnd ) ); m_lines.push_back( EDIT_LINE( aOrigin, aEnd ) );
} }
/**
* Function AddBreak()
*
* Adds a break, indicating the end of a contour.
*/
void AddBreak()
{
assert( m_points.size() > 0 );
m_contours.push_back( m_points.size() - 1 );
}
/**
* Function GetContourStartIdx()
*
* Returns index of the contour origin for a point with given index.
* @param aPointIdx is the index of point for which the contour origin is searched.
* @return Index of the contour origin point.
*/
int GetContourStartIdx( int aPointIdx ) const;
/**
* Function GetContourEndIdx()
*
* Returns index of the contour finish for a point with given index.
* @param aPointIdx is the index of point for which the contour finish is searched.
* @return Index of the contour finish point.
*/
int GetContourEndIdx( int aPointIdx ) const;
/**
* Function IsContourStart()
*
* Checks is a point with given index is a contour origin.
* @param aPointIdx is the index of the point to be checked.
* @return True if the point is an origin of a contour.
*/
bool IsContourStart( int aPointIdx ) const;
/**
* Function IsContourEnd()
*
* Checks is a point with given index is a contour finish.
* @param aPointIdx is the index of the point to be checked.
* @return True if the point is a finish of a contour.
*/
bool IsContourEnd( int aPointIdx ) const;
/** /**
* Function Previous() * Function Previous()
* *
* Returns the point that is after the given point in the list. * Returns the point that is after the given point in the list.
* @param aPoint is the point that is supposed to be preceding the searched point. * @param aPoint is the point that is supposed to be preceding the searched point.
* @param aTraverseContours decides if in case of breaks should we return to the origin
* of contour or continue with the next contour.
* @return The point following aPoint in the list. If aPoint is the first in * @return The point following aPoint in the list. If aPoint is the first in
* the list, the last from the list will be returned. If there are no points at all, NULL * the list, the last from the list will be returned. If there are no points at all, NULL
* is returned. * is returned.
*/ */
EDIT_POINT* Previous( const EDIT_POINT& aPoint ); EDIT_POINT* Previous( const EDIT_POINT& aPoint, bool aTraverseContours = true );
EDIT_LINE* Previous( const EDIT_LINE& aLine ); EDIT_LINE* Previous( const EDIT_LINE& aLine );
...@@ -389,11 +437,13 @@ public: ...@@ -389,11 +437,13 @@ public:
* *
* Returns the point that is before the given point in the list. * Returns the point that is before the given point in the list.
* @param aPoint is the point that is supposed to be following the searched point. * @param aPoint is the point that is supposed to be following the searched point.
* @param aTraverseContours decides if in case of breaks should we return to the origin
* of contour or continue with the next contour.
* @return The point preceding aPoint in the list. If aPoint is the last in * @return The point preceding aPoint in the list. If aPoint is the last in
* the list, the first point from the list will be returned. If there are no points at all, * the list, the first point from the list will be returned. If there are no points at all,
* NULL is returned. * NULL is returned.
*/ */
EDIT_POINT* Next( const EDIT_POINT& aPoint ); EDIT_POINT* Next( const EDIT_POINT& aPoint, bool aTraverseContours = true );
EDIT_LINE* Next( const EDIT_LINE& aLine ); EDIT_LINE* Next( const EDIT_LINE& aLine );
...@@ -461,6 +511,7 @@ private: ...@@ -461,6 +511,7 @@ private:
EDA_ITEM* m_parent; ///< Parent of the EDIT_POINTs EDA_ITEM* m_parent; ///< Parent of the EDIT_POINTs
std::deque<EDIT_POINT> m_points; ///< EDIT_POINTs for modifying m_parent std::deque<EDIT_POINT> m_points; ///< EDIT_POINTs for modifying m_parent
std::deque<EDIT_LINE> m_lines; ///< EDIT_LINEs for modifying m_parent std::deque<EDIT_LINE> m_lines; ///< EDIT_LINEs for modifying m_parent
std::list<int> m_contours; ///< Indices of end contour points
}; };
#endif /* EDIT_POINTS_H_ */ #endif /* EDIT_POINTS_H_ */
...@@ -119,20 +119,35 @@ public: ...@@ -119,20 +119,35 @@ public:
int cornersCount = outline->GetCornersCount(); int cornersCount = outline->GetCornersCount();
for( int i = 0; i < cornersCount; ++i ) for( int i = 0; i < cornersCount; ++i )
{
points->AddPoint( outline->GetPos( i ) ); points->AddPoint( outline->GetPos( i ) );
if( outline->IsEndContour( i ) )
points->AddBreak();
}
// Lines have to be added after creating edit points, // Lines have to be added after creating edit points,
// as they use EDIT_POINT references // as they use EDIT_POINT references
for( int i = 0; i < cornersCount - 1; ++i ) for( int i = 0; i < cornersCount - 1; ++i )
{ {
points->AddLine( points->Point( i ), points->Point( i + 1 ) ); if( points->IsContourEnd( i ) )
points->Line( i ).SetConstraint( {
new EC_SNAPLINE( points->Line( i ), points->AddLine( points->Point( i ),
points->Point( points->GetContourStartIdx( i ) ) );
}
else
{
points->AddLine( points->Point( i ), points->Point( i + 1 ) );
}
points->Line( i ).SetConstraint( new EC_SNAPLINE( points->Line( i ),
boost::bind( &KIGFX::GAL::GetGridPoint, aGal, _1 ) ) ); boost::bind( &KIGFX::GAL::GetGridPoint, aGal, _1 ) ) );
} }
// The last missing line, connecting the last and the first polygon point // The last missing line, connecting the last and the first polygon point
points->AddLine( points->Point( cornersCount - 1 ), points->Point( 0 ) ); points->AddLine( points->Point( cornersCount - 1 ),
points->Point( points->GetContourStartIdx( cornersCount - 1 ) ) );
points->Line( points->LinesSize() - 1 ).SetConstraint( points->Line( points->LinesSize() - 1 ).SetConstraint(
new EC_SNAPLINE( points->Line( points->LinesSize() - 1 ), new EC_SNAPLINE( points->Line( points->LinesSize() - 1 ),
boost::bind( &KIGFX::GAL::GetGridPoint, aGal, _1 ) ) ); boost::bind( &KIGFX::GAL::GetGridPoint, aGal, _1 ) ) );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment