Loading common/drawpanel_gal.cpp +0 −11 Original line number Diff line number Diff line Loading @@ -121,11 +121,6 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) ) m_pendingRefresh = false; m_lastRefresh = wxGetLocalTimeMillis(); #ifdef __WXDEBUG__ prof_counter time; prof_start( &time, false ); #endif /* __WXDEBUG__ */ m_gal->BeginDrawing(); m_gal->SetBackgroundColor( KiGfx::COLOR4D( 0.0, 0.0, 0.0, 1.0 ) ); m_gal->ClearScreen(); Loading @@ -138,12 +133,6 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) ) m_gal->DrawCursor( m_viewControls->GetCursorPosition() ); m_gal->EndDrawing(); #ifdef __WXDEBUG__ prof_end( &time ); wxLogDebug( wxT( "EDA_DRAW_PANEL_GAL::Refresh: %.0f ms (%.0f fps)" ), static_cast<double>( time.value ) / 1000.0, 1000000.0 / static_cast<double>( time.value ) ); #endif /* __WXDEBUG__ */ } Loading common/geometry/seg.cpp +63 −61 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ template <typename T> int sgn(T val) { return ( T( 0 ) < val ) - ( val < T( 0 ) ); } bool SEG::PointCloserThan( const VECTOR2I& aP, int dist ) const { VECTOR2I d = b - a; Loading @@ -37,13 +38,11 @@ bool SEG::PointCloserThan (const VECTOR2I& aP, int dist) const SEG::ecoord l_squared = d.Dot( d ); SEG::ecoord t = d.Dot( aP - a ); if( t <= 0 || !l_squared ) return ( aP - a ).SquaredEuclideanNorm() < dist_sq; else if( t >= l_squared ) return ( aP - b ).SquaredEuclideanNorm() < dist_sq; int dxdy = abs( d.x ) - abs( d.y ); if( ( dxdy >= -1 && dxdy <= 1 ) || abs( d.x ) <= 1 || abs( d.y ) <= 1 ) Loading Loading @@ -71,6 +70,7 @@ bool SEG::PointCloserThan (const VECTOR2I& aP, int dist) const return ( nearest - aP ).SquaredEuclideanNorm() <= dist_sq; } SEG::ecoord SEG::SquaredDistance( const SEG& aSeg ) const { // fixme: rather inefficient.... Loading @@ -88,9 +88,11 @@ SEG::ecoord SEG::SquaredDistance( const SEG& aSeg ) const ecoord m = VECTOR2I::ECOORD_MAX; for( int i = 0; i < 4; i++ ) m = std::min( m, pts[i].SquaredEuclideanNorm() ); return m; } OPT_VECTOR2I SEG::Intersect( const SEG& aSeg, bool aIgnoreEndpoints, bool aLines ) const { const VECTOR2I e ( b - a ); Loading @@ -110,7 +112,6 @@ OPT_VECTOR2I SEG::Intersect( const SEG& aSeg, bool aIgnoreEndpoints, bool aLines if ( !aLines && aIgnoreEndpoints && ( q == 0 || q == d ) && ( p == 0 || p == d ) ) return OPT_VECTOR2I(); VECTOR2I ip( aSeg.a.x + rescale( q, (ecoord)f.x, d ), aSeg.a.y + rescale( q, (ecoord)f.y, d ) ); Loading @@ -123,11 +124,13 @@ bool SEG::ccw ( const VECTOR2I& a, const VECTOR2I& b, const VECTOR2I &c ) const return (ecoord)( c.y - a.y ) * ( b.x - a.x ) > (ecoord)( b.y - a.y ) * ( c.x - a.x ); } bool SEG::Collide( const SEG& aSeg, int aClearance ) const { // check for intersection // fixme: move to a method if( ccw(a,aSeg.a,aSeg.b) != ccw(b,aSeg.a,aSeg.b) && ccw(a,b,aSeg.a) != ccw(a,b,aSeg.b) ) if( ccw( a, aSeg.a, aSeg.b ) != ccw( b, aSeg.a, aSeg.b ) && ccw( a, b, aSeg.a ) != ccw( a, b, aSeg.b ) ) return true; #define CHK(_seg, _pt) \ Loading @@ -137,14 +140,13 @@ bool SEG::Collide( const SEG& aSeg, int aClearance ) const CHK( *this, aSeg.b ); CHK( aSeg, a ); CHK( aSeg, b ); #undef CHK return false; } bool SEG::Contains( const VECTOR2I& aP ) const { return PointCloserThan( aP, 1 ); } common/geometry/shape_collisions.cpp +71 −48 Original line number Diff line number Diff line Loading @@ -31,7 +31,8 @@ typedef VECTOR2I::extended_type ecoord; static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_CIRCLE& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_CIRCLE& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { ecoord min_dist = clearance + a.GetRadius() + b.GetRadius(); ecoord min_dist_sq = min_dist * min_dist; Loading @@ -49,7 +50,8 @@ static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_CIRCLE& b, int cl return true; } static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { const VECTOR2I c = b.GetCenter(); const VECTOR2I p0 = a.GetPosition(); Loading Loading @@ -82,7 +84,6 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle const SEG seg( vts[i], vts[i+1] ); ecoord dist_sq = seg.SquaredDistance( c ); if( dist_sq < min_dist_sq ) { if( !needMTV ) Loading Loading @@ -112,7 +113,9 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle return true; } static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { for( int s = 0; s < b.SegmentCount(); s++ ) { Loading @@ -123,7 +126,9 @@ static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_LINE_CHAIN& b, i return false; } static inline bool Collide( const SHAPE_LINE_CHAIN& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_LINE_CHAIN& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { for( int i = 0; i < b.SegmentCount(); i++ ) if( a.Collide( b.CSegment(i), clearance ) ) Loading @@ -132,7 +137,8 @@ static inline bool Collide( const SHAPE_LINE_CHAIN& a, const SHAPE_LINE_CHAIN& b } static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { for( int s = 0; s < b.SegmentCount(); s++ ) { Loading @@ -145,7 +151,6 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int } bool CollideShapes( const SHAPE* a, const SHAPE* b, int clearance, bool needMTV, VECTOR2I& aMTV ) { switch( a->Type() ) Loading @@ -154,9 +159,13 @@ bool CollideShapes ( const SHAPE *a, const SHAPE *b, int clearance, bool needMTV switch( b->Type() ) { case SH_CIRCLE: return Collide( *static_cast<const SHAPE_RECT *> (a), *static_cast<const SHAPE_CIRCLE *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_RECT*>( a ), *static_cast<const SHAPE_CIRCLE*>( b ), clearance, needMTV, aMTV ); case SH_LINE_CHAIN: return Collide( *static_cast<const SHAPE_RECT *> (a), *static_cast<const SHAPE_LINE_CHAIN *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_RECT*>( a ), *static_cast<const SHAPE_LINE_CHAIN*>( b ), clearance, needMTV, aMTV ); default: break; } Loading @@ -165,11 +174,17 @@ bool CollideShapes ( const SHAPE *a, const SHAPE *b, int clearance, bool needMTV switch( b->Type() ) { case SH_RECT: return Collide( *static_cast<const SHAPE_RECT *> (b), *static_cast<const SHAPE_CIRCLE *> (a), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_RECT*>( b ), *static_cast<const SHAPE_CIRCLE*>( a ), clearance, needMTV, aMTV ); case SH_CIRCLE: return Collide( *static_cast<const SHAPE_CIRCLE *> (a), *static_cast<const SHAPE_CIRCLE *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_CIRCLE*>( a ), *static_cast<const SHAPE_CIRCLE*>( b ), clearance, needMTV, aMTV ); case SH_LINE_CHAIN: return Collide( *static_cast<const SHAPE_CIRCLE *> (a), *static_cast<const SHAPE_LINE_CHAIN *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_CIRCLE*>( a ), *static_cast<const SHAPE_LINE_CHAIN *>( b ), clearance, needMTV, aMTV ); default: break; } Loading @@ -178,14 +193,21 @@ bool CollideShapes ( const SHAPE *a, const SHAPE *b, int clearance, bool needMTV switch( b->Type() ) { case SH_RECT: return Collide( *static_cast<const SHAPE_RECT *> (b), *static_cast<const SHAPE_LINE_CHAIN *> (a), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_RECT*>( b ), *static_cast<const SHAPE_LINE_CHAIN*>( a ), clearance, needMTV, aMTV ); case SH_CIRCLE: return Collide( *static_cast<const SHAPE_CIRCLE *> (b), *static_cast<const SHAPE_LINE_CHAIN *> (a), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_CIRCLE*>( b ), *static_cast<const SHAPE_LINE_CHAIN*>( a ), clearance, needMTV, aMTV ); case SH_LINE_CHAIN: return Collide( *static_cast<const SHAPE_LINE_CHAIN *> (a), *static_cast<const SHAPE_LINE_CHAIN *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_LINE_CHAIN*>( a ), *static_cast<const SHAPE_LINE_CHAIN*>( b ), clearance, needMTV, aMTV ); default: break; } default: break; } Loading @@ -193,6 +215,7 @@ bool CollideShapes ( const SHAPE *a, const SHAPE *b, int clearance, bool needMTV bool unsupported_collision = true; assert( unsupported_collision == false ); return false; } Loading @@ -202,9 +225,9 @@ bool SHAPE::Collide ( const SHAPE *aShape, int aClerance, VECTOR2I& aMTV ) const return CollideShapes( this, aShape, aClerance, true, aMTV); } bool SHAPE::Collide ( const SHAPE* aShape, int aClerance ) const { VECTOR2I dummy; return CollideShapes( this, aShape, aClerance, false, dummy ); } common/geometry/shape_index.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -30,4 +30,3 @@ const SHAPE* shapeFunctor( SHAPE* aItem ) { return aItem; } common/geometry/shape_line_chain.cpp +225 −170 Original line number Diff line number Diff line Loading @@ -34,12 +34,14 @@ bool SHAPE_LINE_CHAIN::Collide ( const VECTOR2I& aP, int aClearance ) const return false; } bool SHAPE_LINE_CHAIN::Collide( const BOX2I& aBox, int aClearance ) const { assert( false ); return false; } bool SHAPE_LINE_CHAIN::Collide( const SEG& aSeg, int aClearance ) const { BOX2I box_a( aSeg.a, aSeg.b - aSeg.a ); Loading @@ -58,6 +60,7 @@ bool SHAPE_LINE_CHAIN::Collide ( const SEG& aSeg, int aClearance ) const return true; } } return false; } Loading @@ -76,53 +79,61 @@ int SHAPE_LINE_CHAIN::Length() const int l = 0; for( int i = 0; i < SegmentCount(); i++ ) l += CSegment( i ).Length(); return l; } void SHAPE_LINE_CHAIN::Replace( int start_index, int end_index, const VECTOR2I& aP) void SHAPE_LINE_CHAIN::Replace( int aStartIndex, int aEndIndex, const VECTOR2I& aP ) { if(end_index < 0) end_index += PointCount(); if(start_index < 0) start_index += PointCount(); if( aEndIndex < 0 ) aEndIndex += PointCount(); if( aStartIndex < 0 ) aStartIndex += PointCount(); if (start_index == end_index) m_points [start_index] = aP; else { m_points.erase (m_points.begin() + start_index + 1, m_points.begin() + end_index + 1); m_points [start_index] = aP; if( aStartIndex == aEndIndex ) m_points [aStartIndex] = aP; else { m_points.erase( m_points.begin() + aStartIndex + 1, m_points.begin() + aEndIndex + 1 ); m_points[aStartIndex] = aP; } } void SHAPE_LINE_CHAIN::Replace( int start_index, int end_index, const SHAPE_LINE_CHAIN& aLine) void SHAPE_LINE_CHAIN::Replace( int aStartIndex, int aEndIndex, const SHAPE_LINE_CHAIN& aLine ) { if(end_index < 0) end_index += PointCount(); if(start_index < 0) start_index += PointCount(); if( aEndIndex < 0 ) aEndIndex += PointCount(); if( aStartIndex < 0 ) aStartIndex += PointCount(); m_points.erase (m_points.begin() + start_index, m_points.begin() + end_index + 1); m_points.insert (m_points.begin() + start_index, aLine.m_points.begin(), aLine.m_points.end()); m_points.erase( m_points.begin() + aStartIndex, m_points.begin() + aEndIndex + 1 ); m_points.insert( m_points.begin() + aStartIndex, aLine.m_points.begin(), aLine.m_points.end() ); } void SHAPE_LINE_CHAIN::Remove( int start_index, int end_index) void SHAPE_LINE_CHAIN::Remove( int aStartIndex, int aEndIndex ) { if(end_index < 0) end_index += PointCount(); if(start_index < 0) start_index += PointCount(); if(aEndIndex < 0) aEndIndex += PointCount(); if(aStartIndex < 0) aStartIndex += PointCount(); m_points.erase (m_points.begin() + start_index, m_points.begin() + end_index + 1); m_points.erase( m_points.begin() + aStartIndex, m_points.begin() + aEndIndex + 1 ); } int SHAPE_LINE_CHAIN::Distance( const VECTOR2I& aP ) const { int d = INT_MAX; for( int s = 0; s < SegmentCount(); s++ ) d = min( d, CSegment( s ).Distance( aP ) ); return d; } int SHAPE_LINE_CHAIN::Split( const VECTOR2I& aP ) { int ii = -1; Loading Loading @@ -150,41 +161,49 @@ int SHAPE_LINE_CHAIN::Split( const VECTOR2I & aP ) if( ii >= 0 ) { m_points.insert( m_points.begin() + ii + 1, aP ); return ii + 1; } return -1; } int SHAPE_LINE_CHAIN::Find( const VECTOR2I& aP ) const { for( int s = 0; s< PointCount(); s++ ) if( CPoint( s ) == aP ) return s; return -1; } const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Slice( int start_index, int end_index ) const const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Slice( int aStartIndex, int aEndIndex ) const { SHAPE_LINE_CHAIN rv; if(end_index < 0) end_index += PointCount(); if(start_index < 0) start_index += PointCount(); if( aEndIndex < 0 ) aEndIndex += PointCount(); if( aStartIndex < 0 ) aStartIndex += PointCount(); for(int i = start_index; i<= end_index; i++) for( int i = aStartIndex; i <= aEndIndex; i++ ) rv.Append( m_points[i] ); return rv; } struct compareOriginDistance { struct compareOriginDistance { compareOriginDistance( VECTOR2I& aOrigin ): m_origin( aOrigin ) {}; bool operator()(const SHAPE_LINE_CHAIN::Intersection &a, const SHAPE_LINE_CHAIN::Intersection& b) bool operator()( const SHAPE_LINE_CHAIN::Intersection& aA, const SHAPE_LINE_CHAIN::Intersection& aB ) { return (m_origin - a.p).EuclideanNorm() < (m_origin - b.p).EuclideanNorm(); return ( m_origin - aA.p ).EuclideanNorm() < ( m_origin - aB.p ).EuclideanNorm(); } VECTOR2I m_origin; Loading @@ -208,8 +227,10 @@ int SHAPE_LINE_CHAIN::Intersect ( const SEG& aSeg, Intersections& aIp ) const compareOriginDistance comp( aSeg.a ); sort( aIp.begin(), aIp.end(), comp ); return aIp.size(); }; } int SHAPE_LINE_CHAIN::Intersect( const SHAPE_LINE_CHAIN& aChain, Intersections& aIp ) const { Loading @@ -228,14 +249,15 @@ BOX2I bb_other = aChain.BBox(); const SEG& b = aChain.CSegment( s2 ); Intersection is; if( a.Collinear( b ) ) { if( a.Contains( b.a ) ) { is.p = b.a; aIp.push_back( is ); } if( a.Contains( b.b ) ) { is.p = b.b; aIp.push_back( is ); } if( b.Contains( a.a ) ) { is.p = a.a; aIp.push_back( is ); } if( b.Contains( a.b ) ) { is.p = a.b; aIp.push_back( is ); } } else { } else { OPT_VECTOR2I p = a.Intersect( b ); if( p ) Loading @@ -252,6 +274,7 @@ BOX2I bb_other = aChain.BBox(); return aIp.size(); for( int s1 = 0; s1 < SegmentCount(); s1++ ) { for( int s2 = 0; s2 < aChain.SegmentCount(); s2++ ) { const SEG& a = CSegment( s1 ); Loading @@ -265,7 +288,8 @@ BOX2I bb_other = aChain.BBox(); is.our = a; is.their = b; aIp.push_back( is ); } else if (a.Collinear(b)) } else if( a.Collinear( b ) ) { if( a.a != b.a && a.a != b.b && b.Contains( a.a ) ) { Loading @@ -284,9 +308,12 @@ BOX2I bb_other = aChain.BBox(); } } } return aIp.size(); } int SHAPE_LINE_CHAIN::PathLength( const VECTOR2I& aP ) const { int sum = 0; Loading @@ -294,6 +321,7 @@ int SHAPE_LINE_CHAIN::PathLength (const VECTOR2I& aP ) const { const SEG seg = CSegment( i ); int d = seg.Distance( aP ); if( d <= 1 ) { sum += ( aP - seg.a ).EuclideanNorm(); Loading @@ -302,29 +330,36 @@ int SHAPE_LINE_CHAIN::PathLength (const VECTOR2I& aP ) const else sum += seg.Length(); } return -1; } bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aP ) const { if( !m_closed || SegmentCount() < 3 ) return false; int cur = CSegment(0).Side( aP ); if( cur == 0 ) return false; for( int i = 1; i < SegmentCount(); i++ ) { const SEG s = CSegment( i ); if( aP == s.a || aP == s.b ) // edge does not belong to the interior! return false; if( s.Side(aP) != cur ) return false; } return true; } bool SHAPE_LINE_CHAIN::PointOnEdge( const VECTOR2I& aP ) const { if( SegmentCount() < 1 ) Loading @@ -333,18 +368,22 @@ bool SHAPE_LINE_CHAIN::PointOnEdge( const VECTOR2I& aP) const for( int i = 1; i < SegmentCount(); i++ ) { const SEG s = CSegment( i ); if( s.a == aP || s.b == aP ) return true; if( s.Distance(aP) <= 1 ) return true; } return false; } const optional<SHAPE_LINE_CHAIN::Intersection> SHAPE_LINE_CHAIN::SelfIntersecting() const { for( int s1 = 0; s1 < SegmentCount(); s1++ ) { for( int s2 = s1 + 1; s2 < SegmentCount(); s2++ ) { const VECTOR2I s2a = CSegment( s2 ).a, s2b = CSegment( s2 ).b; Loading @@ -355,14 +394,17 @@ const optional<SHAPE_LINE_CHAIN::Intersection> SHAPE_LINE_CHAIN::SelfIntersectin is.their = CSegment( s2 ); is.p = s2a; return is; } else if (CSegment(s1).Contains(s2b)) { } else if( CSegment( s1 ).Contains(s2b ) ) { Intersection is; is.our = CSegment( s1 ); is.their = CSegment( s2 ); is.p = s2b; return is; } else { } else { OPT_VECTOR2I p = CSegment( s1 ).Intersect( CSegment( s2 ), true ); if( p ) Loading @@ -375,6 +417,8 @@ const optional<SHAPE_LINE_CHAIN::Intersection> SHAPE_LINE_CHAIN::SelfIntersectin } } } } return optional<Intersection>(); } Loading @@ -386,9 +430,12 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify() if( PointCount() < 2 ) { return *this; } else if (PointCount() == 2) { } else if( PointCount() == 2 ) { if( m_points[0] == m_points[1] ) m_points.erase( m_points.end() ); return *this; } Loading @@ -401,6 +448,7 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify() int j = i + 1; while( j < np && CPoint(i) == CPoint( j ) ) j++; pts_unique.push_back( CPoint( i ) ); i = j; } Loading @@ -415,27 +463,32 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify() const VECTOR2I p0 = pts_unique[i]; const VECTOR2I p1 = pts_unique[i+1]; int n = i; while( n < np - 2 && SEG( p0, p1 ).LineDistance( pts_unique[n + 2] ) <= 1 ) n++; m_points.push_back( p0 ); if( n > i ) i = n; if( n == np ) { m_points.push_back( pts_unique[n - 1] ); return *this; } i++; } if( np > 1 ) m_points.push_back( pts_unique[np - 2] ); m_points.push_back( pts_unique[np - 1] ); return *this; } const VECTOR2I SHAPE_LINE_CHAIN::NearestPoint( const VECTOR2I& aP ) const { int min_d = INT_MAX; Loading @@ -449,9 +502,11 @@ const VECTOR2I SHAPE_LINE_CHAIN::NearestPoint(const VECTOR2I& aP) const nearest = i; } } return CSegment( nearest ).NearestPoint( aP ); } const string SHAPE_LINE_CHAIN::Format() const { stringstream ss; Loading Loading
common/drawpanel_gal.cpp +0 −11 Original line number Diff line number Diff line Loading @@ -121,11 +121,6 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) ) m_pendingRefresh = false; m_lastRefresh = wxGetLocalTimeMillis(); #ifdef __WXDEBUG__ prof_counter time; prof_start( &time, false ); #endif /* __WXDEBUG__ */ m_gal->BeginDrawing(); m_gal->SetBackgroundColor( KiGfx::COLOR4D( 0.0, 0.0, 0.0, 1.0 ) ); m_gal->ClearScreen(); Loading @@ -138,12 +133,6 @@ void EDA_DRAW_PANEL_GAL::onPaint( wxPaintEvent& WXUNUSED( aEvent ) ) m_gal->DrawCursor( m_viewControls->GetCursorPosition() ); m_gal->EndDrawing(); #ifdef __WXDEBUG__ prof_end( &time ); wxLogDebug( wxT( "EDA_DRAW_PANEL_GAL::Refresh: %.0f ms (%.0f fps)" ), static_cast<double>( time.value ) / 1000.0, 1000000.0 / static_cast<double>( time.value ) ); #endif /* __WXDEBUG__ */ } Loading
common/geometry/seg.cpp +63 −61 Original line number Diff line number Diff line Loading @@ -29,6 +29,7 @@ template <typename T> int sgn(T val) { return ( T( 0 ) < val ) - ( val < T( 0 ) ); } bool SEG::PointCloserThan( const VECTOR2I& aP, int dist ) const { VECTOR2I d = b - a; Loading @@ -37,13 +38,11 @@ bool SEG::PointCloserThan (const VECTOR2I& aP, int dist) const SEG::ecoord l_squared = d.Dot( d ); SEG::ecoord t = d.Dot( aP - a ); if( t <= 0 || !l_squared ) return ( aP - a ).SquaredEuclideanNorm() < dist_sq; else if( t >= l_squared ) return ( aP - b ).SquaredEuclideanNorm() < dist_sq; int dxdy = abs( d.x ) - abs( d.y ); if( ( dxdy >= -1 && dxdy <= 1 ) || abs( d.x ) <= 1 || abs( d.y ) <= 1 ) Loading Loading @@ -71,6 +70,7 @@ bool SEG::PointCloserThan (const VECTOR2I& aP, int dist) const return ( nearest - aP ).SquaredEuclideanNorm() <= dist_sq; } SEG::ecoord SEG::SquaredDistance( const SEG& aSeg ) const { // fixme: rather inefficient.... Loading @@ -88,9 +88,11 @@ SEG::ecoord SEG::SquaredDistance( const SEG& aSeg ) const ecoord m = VECTOR2I::ECOORD_MAX; for( int i = 0; i < 4; i++ ) m = std::min( m, pts[i].SquaredEuclideanNorm() ); return m; } OPT_VECTOR2I SEG::Intersect( const SEG& aSeg, bool aIgnoreEndpoints, bool aLines ) const { const VECTOR2I e ( b - a ); Loading @@ -110,7 +112,6 @@ OPT_VECTOR2I SEG::Intersect( const SEG& aSeg, bool aIgnoreEndpoints, bool aLines if ( !aLines && aIgnoreEndpoints && ( q == 0 || q == d ) && ( p == 0 || p == d ) ) return OPT_VECTOR2I(); VECTOR2I ip( aSeg.a.x + rescale( q, (ecoord)f.x, d ), aSeg.a.y + rescale( q, (ecoord)f.y, d ) ); Loading @@ -123,11 +124,13 @@ bool SEG::ccw ( const VECTOR2I& a, const VECTOR2I& b, const VECTOR2I &c ) const return (ecoord)( c.y - a.y ) * ( b.x - a.x ) > (ecoord)( b.y - a.y ) * ( c.x - a.x ); } bool SEG::Collide( const SEG& aSeg, int aClearance ) const { // check for intersection // fixme: move to a method if( ccw(a,aSeg.a,aSeg.b) != ccw(b,aSeg.a,aSeg.b) && ccw(a,b,aSeg.a) != ccw(a,b,aSeg.b) ) if( ccw( a, aSeg.a, aSeg.b ) != ccw( b, aSeg.a, aSeg.b ) && ccw( a, b, aSeg.a ) != ccw( a, b, aSeg.b ) ) return true; #define CHK(_seg, _pt) \ Loading @@ -137,14 +140,13 @@ bool SEG::Collide( const SEG& aSeg, int aClearance ) const CHK( *this, aSeg.b ); CHK( aSeg, a ); CHK( aSeg, b ); #undef CHK return false; } bool SEG::Contains( const VECTOR2I& aP ) const { return PointCloserThan( aP, 1 ); }
common/geometry/shape_collisions.cpp +71 −48 Original line number Diff line number Diff line Loading @@ -31,7 +31,8 @@ typedef VECTOR2I::extended_type ecoord; static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_CIRCLE& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_CIRCLE& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { ecoord min_dist = clearance + a.GetRadius() + b.GetRadius(); ecoord min_dist_sq = min_dist * min_dist; Loading @@ -49,7 +50,8 @@ static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_CIRCLE& b, int cl return true; } static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { const VECTOR2I c = b.GetCenter(); const VECTOR2I p0 = a.GetPosition(); Loading Loading @@ -82,7 +84,6 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle const SEG seg( vts[i], vts[i+1] ); ecoord dist_sq = seg.SquaredDistance( c ); if( dist_sq < min_dist_sq ) { if( !needMTV ) Loading Loading @@ -112,7 +113,9 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_CIRCLE& b, int cle return true; } static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { for( int s = 0; s < b.SegmentCount(); s++ ) { Loading @@ -123,7 +126,9 @@ static inline bool Collide( const SHAPE_CIRCLE& a, const SHAPE_LINE_CHAIN& b, i return false; } static inline bool Collide( const SHAPE_LINE_CHAIN& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_LINE_CHAIN& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { for( int i = 0; i < b.SegmentCount(); i++ ) if( a.Collide( b.CSegment(i), clearance ) ) Loading @@ -132,7 +137,8 @@ static inline bool Collide( const SHAPE_LINE_CHAIN& a, const SHAPE_LINE_CHAIN& b } static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int clearance, bool needMTV, VECTOR2I& aMTV ) { for( int s = 0; s < b.SegmentCount(); s++ ) { Loading @@ -145,7 +151,6 @@ static inline bool Collide( const SHAPE_RECT& a, const SHAPE_LINE_CHAIN& b, int } bool CollideShapes( const SHAPE* a, const SHAPE* b, int clearance, bool needMTV, VECTOR2I& aMTV ) { switch( a->Type() ) Loading @@ -154,9 +159,13 @@ bool CollideShapes ( const SHAPE *a, const SHAPE *b, int clearance, bool needMTV switch( b->Type() ) { case SH_CIRCLE: return Collide( *static_cast<const SHAPE_RECT *> (a), *static_cast<const SHAPE_CIRCLE *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_RECT*>( a ), *static_cast<const SHAPE_CIRCLE*>( b ), clearance, needMTV, aMTV ); case SH_LINE_CHAIN: return Collide( *static_cast<const SHAPE_RECT *> (a), *static_cast<const SHAPE_LINE_CHAIN *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_RECT*>( a ), *static_cast<const SHAPE_LINE_CHAIN*>( b ), clearance, needMTV, aMTV ); default: break; } Loading @@ -165,11 +174,17 @@ bool CollideShapes ( const SHAPE *a, const SHAPE *b, int clearance, bool needMTV switch( b->Type() ) { case SH_RECT: return Collide( *static_cast<const SHAPE_RECT *> (b), *static_cast<const SHAPE_CIRCLE *> (a), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_RECT*>( b ), *static_cast<const SHAPE_CIRCLE*>( a ), clearance, needMTV, aMTV ); case SH_CIRCLE: return Collide( *static_cast<const SHAPE_CIRCLE *> (a), *static_cast<const SHAPE_CIRCLE *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_CIRCLE*>( a ), *static_cast<const SHAPE_CIRCLE*>( b ), clearance, needMTV, aMTV ); case SH_LINE_CHAIN: return Collide( *static_cast<const SHAPE_CIRCLE *> (a), *static_cast<const SHAPE_LINE_CHAIN *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_CIRCLE*>( a ), *static_cast<const SHAPE_LINE_CHAIN *>( b ), clearance, needMTV, aMTV ); default: break; } Loading @@ -178,14 +193,21 @@ bool CollideShapes ( const SHAPE *a, const SHAPE *b, int clearance, bool needMTV switch( b->Type() ) { case SH_RECT: return Collide( *static_cast<const SHAPE_RECT *> (b), *static_cast<const SHAPE_LINE_CHAIN *> (a), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_RECT*>( b ), *static_cast<const SHAPE_LINE_CHAIN*>( a ), clearance, needMTV, aMTV ); case SH_CIRCLE: return Collide( *static_cast<const SHAPE_CIRCLE *> (b), *static_cast<const SHAPE_LINE_CHAIN *> (a), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_CIRCLE*>( b ), *static_cast<const SHAPE_LINE_CHAIN*>( a ), clearance, needMTV, aMTV ); case SH_LINE_CHAIN: return Collide( *static_cast<const SHAPE_LINE_CHAIN *> (a), *static_cast<const SHAPE_LINE_CHAIN *> (b), clearance, needMTV, aMTV ); return Collide( *static_cast<const SHAPE_LINE_CHAIN*>( a ), *static_cast<const SHAPE_LINE_CHAIN*>( b ), clearance, needMTV, aMTV ); default: break; } default: break; } Loading @@ -193,6 +215,7 @@ bool CollideShapes ( const SHAPE *a, const SHAPE *b, int clearance, bool needMTV bool unsupported_collision = true; assert( unsupported_collision == false ); return false; } Loading @@ -202,9 +225,9 @@ bool SHAPE::Collide ( const SHAPE *aShape, int aClerance, VECTOR2I& aMTV ) const return CollideShapes( this, aShape, aClerance, true, aMTV); } bool SHAPE::Collide ( const SHAPE* aShape, int aClerance ) const { VECTOR2I dummy; return CollideShapes( this, aShape, aClerance, false, dummy ); }
common/geometry/shape_index.cpp +0 −1 Original line number Diff line number Diff line Loading @@ -30,4 +30,3 @@ const SHAPE* shapeFunctor( SHAPE* aItem ) { return aItem; }
common/geometry/shape_line_chain.cpp +225 −170 Original line number Diff line number Diff line Loading @@ -34,12 +34,14 @@ bool SHAPE_LINE_CHAIN::Collide ( const VECTOR2I& aP, int aClearance ) const return false; } bool SHAPE_LINE_CHAIN::Collide( const BOX2I& aBox, int aClearance ) const { assert( false ); return false; } bool SHAPE_LINE_CHAIN::Collide( const SEG& aSeg, int aClearance ) const { BOX2I box_a( aSeg.a, aSeg.b - aSeg.a ); Loading @@ -58,6 +60,7 @@ bool SHAPE_LINE_CHAIN::Collide ( const SEG& aSeg, int aClearance ) const return true; } } return false; } Loading @@ -76,53 +79,61 @@ int SHAPE_LINE_CHAIN::Length() const int l = 0; for( int i = 0; i < SegmentCount(); i++ ) l += CSegment( i ).Length(); return l; } void SHAPE_LINE_CHAIN::Replace( int start_index, int end_index, const VECTOR2I& aP) void SHAPE_LINE_CHAIN::Replace( int aStartIndex, int aEndIndex, const VECTOR2I& aP ) { if(end_index < 0) end_index += PointCount(); if(start_index < 0) start_index += PointCount(); if( aEndIndex < 0 ) aEndIndex += PointCount(); if( aStartIndex < 0 ) aStartIndex += PointCount(); if (start_index == end_index) m_points [start_index] = aP; else { m_points.erase (m_points.begin() + start_index + 1, m_points.begin() + end_index + 1); m_points [start_index] = aP; if( aStartIndex == aEndIndex ) m_points [aStartIndex] = aP; else { m_points.erase( m_points.begin() + aStartIndex + 1, m_points.begin() + aEndIndex + 1 ); m_points[aStartIndex] = aP; } } void SHAPE_LINE_CHAIN::Replace( int start_index, int end_index, const SHAPE_LINE_CHAIN& aLine) void SHAPE_LINE_CHAIN::Replace( int aStartIndex, int aEndIndex, const SHAPE_LINE_CHAIN& aLine ) { if(end_index < 0) end_index += PointCount(); if(start_index < 0) start_index += PointCount(); if( aEndIndex < 0 ) aEndIndex += PointCount(); if( aStartIndex < 0 ) aStartIndex += PointCount(); m_points.erase (m_points.begin() + start_index, m_points.begin() + end_index + 1); m_points.insert (m_points.begin() + start_index, aLine.m_points.begin(), aLine.m_points.end()); m_points.erase( m_points.begin() + aStartIndex, m_points.begin() + aEndIndex + 1 ); m_points.insert( m_points.begin() + aStartIndex, aLine.m_points.begin(), aLine.m_points.end() ); } void SHAPE_LINE_CHAIN::Remove( int start_index, int end_index) void SHAPE_LINE_CHAIN::Remove( int aStartIndex, int aEndIndex ) { if(end_index < 0) end_index += PointCount(); if(start_index < 0) start_index += PointCount(); if(aEndIndex < 0) aEndIndex += PointCount(); if(aStartIndex < 0) aStartIndex += PointCount(); m_points.erase (m_points.begin() + start_index, m_points.begin() + end_index + 1); m_points.erase( m_points.begin() + aStartIndex, m_points.begin() + aEndIndex + 1 ); } int SHAPE_LINE_CHAIN::Distance( const VECTOR2I& aP ) const { int d = INT_MAX; for( int s = 0; s < SegmentCount(); s++ ) d = min( d, CSegment( s ).Distance( aP ) ); return d; } int SHAPE_LINE_CHAIN::Split( const VECTOR2I& aP ) { int ii = -1; Loading Loading @@ -150,41 +161,49 @@ int SHAPE_LINE_CHAIN::Split( const VECTOR2I & aP ) if( ii >= 0 ) { m_points.insert( m_points.begin() + ii + 1, aP ); return ii + 1; } return -1; } int SHAPE_LINE_CHAIN::Find( const VECTOR2I& aP ) const { for( int s = 0; s< PointCount(); s++ ) if( CPoint( s ) == aP ) return s; return -1; } const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Slice( int start_index, int end_index ) const const SHAPE_LINE_CHAIN SHAPE_LINE_CHAIN::Slice( int aStartIndex, int aEndIndex ) const { SHAPE_LINE_CHAIN rv; if(end_index < 0) end_index += PointCount(); if(start_index < 0) start_index += PointCount(); if( aEndIndex < 0 ) aEndIndex += PointCount(); if( aStartIndex < 0 ) aStartIndex += PointCount(); for(int i = start_index; i<= end_index; i++) for( int i = aStartIndex; i <= aEndIndex; i++ ) rv.Append( m_points[i] ); return rv; } struct compareOriginDistance { struct compareOriginDistance { compareOriginDistance( VECTOR2I& aOrigin ): m_origin( aOrigin ) {}; bool operator()(const SHAPE_LINE_CHAIN::Intersection &a, const SHAPE_LINE_CHAIN::Intersection& b) bool operator()( const SHAPE_LINE_CHAIN::Intersection& aA, const SHAPE_LINE_CHAIN::Intersection& aB ) { return (m_origin - a.p).EuclideanNorm() < (m_origin - b.p).EuclideanNorm(); return ( m_origin - aA.p ).EuclideanNorm() < ( m_origin - aB.p ).EuclideanNorm(); } VECTOR2I m_origin; Loading @@ -208,8 +227,10 @@ int SHAPE_LINE_CHAIN::Intersect ( const SEG& aSeg, Intersections& aIp ) const compareOriginDistance comp( aSeg.a ); sort( aIp.begin(), aIp.end(), comp ); return aIp.size(); }; } int SHAPE_LINE_CHAIN::Intersect( const SHAPE_LINE_CHAIN& aChain, Intersections& aIp ) const { Loading @@ -228,14 +249,15 @@ BOX2I bb_other = aChain.BBox(); const SEG& b = aChain.CSegment( s2 ); Intersection is; if( a.Collinear( b ) ) { if( a.Contains( b.a ) ) { is.p = b.a; aIp.push_back( is ); } if( a.Contains( b.b ) ) { is.p = b.b; aIp.push_back( is ); } if( b.Contains( a.a ) ) { is.p = a.a; aIp.push_back( is ); } if( b.Contains( a.b ) ) { is.p = a.b; aIp.push_back( is ); } } else { } else { OPT_VECTOR2I p = a.Intersect( b ); if( p ) Loading @@ -252,6 +274,7 @@ BOX2I bb_other = aChain.BBox(); return aIp.size(); for( int s1 = 0; s1 < SegmentCount(); s1++ ) { for( int s2 = 0; s2 < aChain.SegmentCount(); s2++ ) { const SEG& a = CSegment( s1 ); Loading @@ -265,7 +288,8 @@ BOX2I bb_other = aChain.BBox(); is.our = a; is.their = b; aIp.push_back( is ); } else if (a.Collinear(b)) } else if( a.Collinear( b ) ) { if( a.a != b.a && a.a != b.b && b.Contains( a.a ) ) { Loading @@ -284,9 +308,12 @@ BOX2I bb_other = aChain.BBox(); } } } return aIp.size(); } int SHAPE_LINE_CHAIN::PathLength( const VECTOR2I& aP ) const { int sum = 0; Loading @@ -294,6 +321,7 @@ int SHAPE_LINE_CHAIN::PathLength (const VECTOR2I& aP ) const { const SEG seg = CSegment( i ); int d = seg.Distance( aP ); if( d <= 1 ) { sum += ( aP - seg.a ).EuclideanNorm(); Loading @@ -302,29 +330,36 @@ int SHAPE_LINE_CHAIN::PathLength (const VECTOR2I& aP ) const else sum += seg.Length(); } return -1; } bool SHAPE_LINE_CHAIN::PointInside( const VECTOR2I& aP ) const { if( !m_closed || SegmentCount() < 3 ) return false; int cur = CSegment(0).Side( aP ); if( cur == 0 ) return false; for( int i = 1; i < SegmentCount(); i++ ) { const SEG s = CSegment( i ); if( aP == s.a || aP == s.b ) // edge does not belong to the interior! return false; if( s.Side(aP) != cur ) return false; } return true; } bool SHAPE_LINE_CHAIN::PointOnEdge( const VECTOR2I& aP ) const { if( SegmentCount() < 1 ) Loading @@ -333,18 +368,22 @@ bool SHAPE_LINE_CHAIN::PointOnEdge( const VECTOR2I& aP) const for( int i = 1; i < SegmentCount(); i++ ) { const SEG s = CSegment( i ); if( s.a == aP || s.b == aP ) return true; if( s.Distance(aP) <= 1 ) return true; } return false; } const optional<SHAPE_LINE_CHAIN::Intersection> SHAPE_LINE_CHAIN::SelfIntersecting() const { for( int s1 = 0; s1 < SegmentCount(); s1++ ) { for( int s2 = s1 + 1; s2 < SegmentCount(); s2++ ) { const VECTOR2I s2a = CSegment( s2 ).a, s2b = CSegment( s2 ).b; Loading @@ -355,14 +394,17 @@ const optional<SHAPE_LINE_CHAIN::Intersection> SHAPE_LINE_CHAIN::SelfIntersectin is.their = CSegment( s2 ); is.p = s2a; return is; } else if (CSegment(s1).Contains(s2b)) { } else if( CSegment( s1 ).Contains(s2b ) ) { Intersection is; is.our = CSegment( s1 ); is.their = CSegment( s2 ); is.p = s2b; return is; } else { } else { OPT_VECTOR2I p = CSegment( s1 ).Intersect( CSegment( s2 ), true ); if( p ) Loading @@ -375,6 +417,8 @@ const optional<SHAPE_LINE_CHAIN::Intersection> SHAPE_LINE_CHAIN::SelfIntersectin } } } } return optional<Intersection>(); } Loading @@ -386,9 +430,12 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify() if( PointCount() < 2 ) { return *this; } else if (PointCount() == 2) { } else if( PointCount() == 2 ) { if( m_points[0] == m_points[1] ) m_points.erase( m_points.end() ); return *this; } Loading @@ -401,6 +448,7 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify() int j = i + 1; while( j < np && CPoint(i) == CPoint( j ) ) j++; pts_unique.push_back( CPoint( i ) ); i = j; } Loading @@ -415,27 +463,32 @@ SHAPE_LINE_CHAIN& SHAPE_LINE_CHAIN::Simplify() const VECTOR2I p0 = pts_unique[i]; const VECTOR2I p1 = pts_unique[i+1]; int n = i; while( n < np - 2 && SEG( p0, p1 ).LineDistance( pts_unique[n + 2] ) <= 1 ) n++; m_points.push_back( p0 ); if( n > i ) i = n; if( n == np ) { m_points.push_back( pts_unique[n - 1] ); return *this; } i++; } if( np > 1 ) m_points.push_back( pts_unique[np - 2] ); m_points.push_back( pts_unique[np - 1] ); return *this; } const VECTOR2I SHAPE_LINE_CHAIN::NearestPoint( const VECTOR2I& aP ) const { int min_d = INT_MAX; Loading @@ -449,9 +502,11 @@ const VECTOR2I SHAPE_LINE_CHAIN::NearestPoint(const VECTOR2I& aP) const nearest = i; } } return CSegment( nearest ).NearestPoint( aP ); } const string SHAPE_LINE_CHAIN::Format() const { stringstream ss; Loading