pns_via.cpp 2.62 KB
Newer Older
1 2 3
/*
 * KiRouter - a push-and-(sometimes-)shove PCB router
 *
4
 * Copyright (C) 2013-2014 CERN
5
 * Author: Tomasz Wlostowski <tomasz.wlostowski@cern.ch>
6
 *
7 8 9 10
 * This program is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 3 of the License, or (at your
 * option) any later version.
11
 *
12 13 14 15
 * This program is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * General Public License for more details.
16
 *
17
 * You should have received a copy of the GNU General Public License along
18
 * with this program.  If not, see <http://www.gnu.org/licenses/>.
19 20 21 22 23
 */

#include "pns_via.h"
#include "pns_node.h"
#include "pns_utils.h"
24
#include "pns_router.h"
25 26 27

#include <geometry/shape_rect.h>

28 29
bool PNS_VIA::PushoutForce( PNS_NODE* aNode, const VECTOR2I& aDirection, VECTOR2I& aForce,
                            bool aSolidsOnly, int aMaxIterations )
30
{
31 32
    int iter = 0;
    PNS_VIA mv( *this );
33 34
    VECTOR2I force, totalForce, force2;

35 36
    while( iter < aMaxIterations )
    {
37 38
        PNS_NODE::OPT_OBSTACLE obs = aNode->CheckColliding( &mv,
                aSolidsOnly ? PNS_ITEM::SOLID : PNS_ITEM::ANY );
39

40 41
        if( !obs )
            break;
42

43
        int clearance = aNode->GetClearance( obs->m_item, &mv );
44

45
        if( iter > aMaxIterations / 2 )
46
        {
47
            VECTOR2I l = aDirection.Resize( m_diameter / 2 );
48
            totalForce += l;
49
            mv.SetPos( mv.Pos() + l );
50
        }
51

52
        bool col = CollideShapes( obs->m_item->Shape(), mv.Shape(), clearance, true, force2 );
53

54
        if( col ) {
55 56
            totalForce += force2;
            mv.SetPos( mv.Pos() + force2 );
57
        }
58

59 60
        iter++;
    }
61

62 63 64 65
    if( iter == aMaxIterations )
        return false;

    aForce = totalForce;
66

67
    return true;
68 69
}

70 71

const SHAPE_LINE_CHAIN PNS_VIA::Hull( int aClearance, int aWalkaroundThickness ) const
72
{
73
    int cl = ( aClearance + aWalkaroundThickness / 2 );
74

75
    return OctagonalHull( m_pos -
76 77
            VECTOR2I( m_diameter / 2, m_diameter / 2 ), VECTOR2I( m_diameter, m_diameter ),
            cl + 1, ( 2 * cl + m_diameter ) * 0.26 );
78 79
}

80

81 82 83 84 85 86 87 88 89 90 91 92 93
PNS_VIA* PNS_VIA::Clone ( ) const
{
    PNS_VIA* v = new PNS_VIA();

    v->SetNet( Net() );
    v->SetLayers( Layers() );
    v->m_pos = m_pos;
    v->m_diameter = m_diameter;
    v->m_drill = m_drill;
    v->m_owner = NULL;
    v->m_shape = SHAPE_CIRCLE( m_pos, m_diameter / 2 );
    v->m_rank = m_rank;
    v->m_marker = m_marker;
94
    v->m_viaType = m_viaType;
95 96

    return v;
97
}