コード例 #1
0
// The helper function for D_CODE::ConvertShapeToPolygon().
// Add a hole to a polygon
static void addHoleToPolygon( SHAPE_POLY_SET*       aPolygon,
                              APERTURE_DEF_HOLETYPE aHoleShape,
                              wxSize                aSize,
                              wxPoint               aAnchorPos )
{
    wxPoint currpos;
    SHAPE_POLY_SET holeBuffer;

    if( aHoleShape == APT_DEF_ROUND_HOLE )
    {
        TransformCircleToPolygon( holeBuffer, wxPoint( 0, 0 ), aSize.x / 2, SEGS_CNT );
    }
    else if( aHoleShape == APT_DEF_RECT_HOLE )
    {
        holeBuffer.NewOutline();
        currpos.x = aSize.x / 2;
        currpos.y = aSize.y / 2;
        holeBuffer.Append( VECTOR2I( currpos ) );       // link to hole and begin hole
        currpos.x -= aSize.x;
        holeBuffer.Append( VECTOR2I( currpos ) );
        currpos.y -= aSize.y;
        holeBuffer.Append( VECTOR2I( currpos ) );
        currpos.x += aSize.x;
        holeBuffer.Append( VECTOR2I( currpos ) );
        currpos.y += aSize.y;
        holeBuffer.Append( VECTOR2I( currpos ) );       // close hole
    }

    aPolygon->BooleanSubtract( holeBuffer, SHAPE_POLY_SET::PM_FAST );

    // Needed for legacy canvas only
    aPolygon->Fracture( SHAPE_POLY_SET::PM_FAST );
}
コード例 #2
0
bool SHAPE_RECT::Collide( const SEG& aSeg, int aClearance ) const
{
    //VECTOR2I pmin = VECTOR2I( std::min( aSeg.a.x, aSeg.b.x ), std::min( aSeg.a.y, aSeg.b.y ) );
    //VECTOR2I pmax = VECTOR2I( std::max( aSeg.a.x, aSeg.b.x ), std::max( aSeg.a.y, aSeg.b.y ));
    //BOX2I r( pmin, VECTOR2I( pmax.x - pmin.x, pmax.y - pmin.y ) );

    //if( BBox( 0 ).SquaredDistance( r ) > aClearance * aClearance )
    //    return false;

    if( BBox( 0 ).Contains( aSeg.A ) || BBox( 0 ).Contains( aSeg.B ) )
        return true;

    VECTOR2I vts[] = { VECTOR2I( m_p0.x, m_p0.y ),
                        VECTOR2I( m_p0.x, m_p0.y + m_h ),
                        VECTOR2I( m_p0.x + m_w, m_p0.y + m_h ),
                        VECTOR2I( m_p0.x + m_w, m_p0.y ),
                        VECTOR2I( m_p0.x, m_p0.y ) };

    for( int i = 0; i < 4; i++ )
    {
        SEG s( vts[i], vts[i + 1], i );

        if( s.Distance( aSeg ) < aClearance )
            return true;
    }

    return false;
}
コード例 #3
0
const SHAPE_LINE_CHAIN PNS_SOLID::Hull( int aClearance, int aWalkaroundThickness ) const
{
    int cl = aClearance + aWalkaroundThickness / 2;

    switch( m_shape->Type() )
    {
    case SH_RECT:
    {
        SHAPE_RECT* rect = static_cast<SHAPE_RECT*>( m_shape );
        return OctagonalHull( rect->GetPosition(), rect->GetSize(), cl + 1, 0.2 * cl );
    }

    case SH_CIRCLE:
    {
        SHAPE_CIRCLE* circle = static_cast<SHAPE_CIRCLE*>( m_shape );
        int r = circle->GetRadius();
        return OctagonalHull( circle->GetCenter() - VECTOR2I( r, r ), VECTOR2I( 2 * r, 2 * r ),
                              cl + 1, 0.52 * ( r + cl ) );
    }

    case SH_SEGMENT:
    {
        SHAPE_SEGMENT* seg = static_cast<SHAPE_SEGMENT*> ( m_shape );
        return SegmentHull( *seg, aClearance, aWalkaroundThickness );
    }

    default:
        break;
    }

    return SHAPE_LINE_CHAIN();
}
コード例 #4
0
const BOX2I DIMENSION::ViewBBox() const
{
    BOX2I dimBBox = BOX2I( VECTOR2I( GetBoundingBox().GetPosition() ),
                           VECTOR2I( GetBoundingBox().GetSize() ) );
    dimBBox.Merge( m_Text.ViewBBox() );

    return dimBBox;
}
コード例 #5
0
ファイル: pns_diff_pair.cpp プロジェクト: OpenEE/micad
static void drawGw( VECTOR2I p, int color )
{
    SHAPE_LINE_CHAIN l;

    l.Append( p - VECTOR2I( -50000, -50000 ) );
    l.Append( p + VECTOR2I( -50000, -50000 ) );

    l.Clear();
    l.Append( p - VECTOR2I( 50000, -50000 ) );
    l.Append( p + VECTOR2I( 50000, -50000 ) );
}
コード例 #6
0
void SCH_VIEW::ShowSelectionArea( bool aShow )
{
    if( aShow )
    {
        // Reset seleciton area so the previous one doesn't flash before the first
        // mouse move updates it
        m_selectionArea->SetOrigin( VECTOR2I() );
        m_selectionArea->SetEnd( VECTOR2I() );
    }

    SetVisible( m_selectionArea.get(), aShow );
}
コード例 #7
0
ファイル: grid_helper.cpp プロジェクト: JOE-JOE-NGIGI/kicad
VECTOR2I GRID_HELPER::BestSnapAnchor( const VECTOR2I& aOrigin, BOARD_ITEM* aDraggedItem )
{
    double worldScale = m_frame->GetGalCanvas()->GetGAL()->GetWorldScale();
    int snapRange = (int) ( 100.0 / worldScale );

    BOX2I bb( VECTOR2I( aOrigin.x - snapRange / 2, aOrigin.y - snapRange / 2 ), VECTOR2I( snapRange, snapRange ) );

    clearAnchors();

    BOOST_FOREACH( BOARD_ITEM* item, queryVisible( bb ) )
    {
        computeAnchors( item, aOrigin );
    }
コード例 #8
0
const BOX2I LIB_EDIT_FRAME::GetDocumentExtents() const
{
    LIB_PART*  part = GetCurPart();

    if( !part )
    {
        return BOX2I( VECTOR2I(-100, -100), VECTOR2I( 200, 200 ) );
    }
    else
    {
        EDA_RECT boundingBox = part->GetUnitBoundingBox( m_unit, m_convert );
        return BOX2I( boundingBox.GetOrigin(), VECTOR2I( boundingBox.GetWidth(), boundingBox.GetHeight() ) );
    }
}
コード例 #9
0
const BOX2I D_PAD::ViewBBox() const
{
    // Bounding box includes soldermask too
    int solderMaskMargin       = GetSolderMaskMargin();
    VECTOR2I solderPasteMargin = VECTOR2D( GetSolderPasteMargin() );
    EDA_RECT bbox              = GetBoundingBox();

    // Look for the biggest possible bounding box
    int xMargin = std::max( solderMaskMargin, solderPasteMargin.x );
    int yMargin = std::max( solderMaskMargin, solderPasteMargin.y );

    return BOX2I( VECTOR2I( bbox.GetOrigin() ) - VECTOR2I( xMargin, yMargin ),
                  VECTOR2I( bbox.GetSize() ) + VECTOR2I( 2 * xMargin, 2 * yMargin ) );
}
コード例 #10
0
ファイル: pns_router.cpp プロジェクト: chgans/kicad
    void AddDirections( VECTOR2D aP, int aMask, int aColor )
    {
        BOX2I b( aP - VECTOR2I( 10000, 10000 ), VECTOR2I( 20000, 20000 ) );

        AddBox( b, aColor );
        for( int i = 0; i < 8; i++ )
        {
            if( ( 1 << i ) & aMask )
            {
                VECTOR2I v = DIRECTION_45( ( DIRECTION_45::Directions ) i ).ToVector() * 100000;
                AddSegment( SEG( aP, aP + v ), aColor );
            }
        }
    }
コード例 #11
0
ファイル: pns_router.cpp プロジェクト: chgans/kicad
    void AddPoint( VECTOR2I aP, int aColor )
    {
        SHAPE_LINE_CHAIN l;

        l.Append( aP - VECTOR2I( -50000, -50000 ) );
        l.Append( aP + VECTOR2I( -50000, -50000 ) );

        AddLine ( l, aColor, 10000 );

        l.Clear();
        l.Append( aP - VECTOR2I( 50000, -50000 ) );
        l.Append( aP + VECTOR2I( 50000, -50000 ) );

        AddLine( l, aColor, 10000 );
    }
コード例 #12
0
ファイル: pns_utils.cpp プロジェクト: cpavlina/kicad
void DrawDebugPoint( VECTOR2I aP, int aColor )
{
    SHAPE_LINE_CHAIN l;

    l.Append( aP - VECTOR2I( -50000, -50000 ) );
    l.Append( aP + VECTOR2I( -50000, -50000 ) );

    ROUTER::GetInstance()->DisplayDebugLine ( l, aColor, 10000 );

    l.Clear();
    l.Append( aP - VECTOR2I( 50000, -50000 ) );
    l.Append( aP + VECTOR2I( 50000, -50000 ) );

    ROUTER::GetInstance()->DisplayDebugLine( l, aColor, 10000 );
}
コード例 #13
0
void POINT_EDITOR::removeCorner( EDIT_POINT* aPoint )
{
    EDA_ITEM* item = m_editPoints->GetParent();

    if( item->Type() == PCB_ZONE_AREA_T )
    {
        const SELECTION& selection = m_selectionTool->GetSelection();
        PCB_BASE_FRAME* frame = getEditFrame<PCB_BASE_FRAME>();

        ZONE_CONTAINER* zone = static_cast<ZONE_CONTAINER*>( item );
        CPolyLine* outline = zone->Outline();

        for( int i = 0; i < outline->GetCornersCount(); ++i )
        {
            if( VECTOR2I( outline->GetPos( i ) ) == aPoint->GetPosition() )
            {
                frame->OnModify();
                frame->SaveCopyInUndoList( selection.items, UR_CHANGED );
                outline->DeleteCorner( i );
                setEditedPoint( NULL );
                break;
            }
        }
    }
}
コード例 #14
0
ファイル: viewlib_frame.cpp プロジェクト: johnbeard/kicad
const BOX2I LIB_VIEW_FRAME::GetDocumentExtents() const
{
    LIB_ALIAS*  alias = getSelectedAlias();
    LIB_PART*   part = alias ? alias->GetPart() : nullptr;

    if( !part )
    {
        return BOX2I( VECTOR2I(-200, -200), VECTOR2I( 400, 400 ) );
    }
    else
    {
        EDA_RECT bbox = part->GetUnitBoundingBox( m_unit, m_convert );
        return BOX2I( bbox.GetOrigin(), VECTOR2I( bbox.GetWidth(), bbox.GetHeight() ) );

    }
}
コード例 #15
0
/**
 * Function TestLineChainEqualCPolyLine
 * tests the equality between a SHAPE_LINE_CHAIN polygon and a polygon inside a
 * CPolyLine object using Boost test suite.
 * @param lineChain is a SHAPE_LINE_CHAIN polygon object.
 * @param polyLine  is a CPolyLine polygon object.
 * @param contourIdx is the index of the contour inside polyLine that has to be tested
 *                   against lineChain.
 */
void TestLineChainEqualCPolyLine(SHAPE_LINE_CHAIN& lineChain, CPolyLine& polyLine,
                                 int contourIdx = 0)
{
    // Arrays to store the polygon points lexicographically ordered
    std::vector<VECTOR2I> chainPoints;
    std::vector<VECTOR2I> polyPoints;

    // Populate the array storing the new data with the lineChain corners
    for (int pointIdx = 0; pointIdx < lineChain.PointCount(); pointIdx++) {
        chainPoints.push_back(lineChain.Point(pointIdx));
    }

    int start = polyLine.GetContourStart(contourIdx);
    int end = polyLine.GetContourEnd(contourIdx);

    // Populate the array storing the legacy data with the polyLine corners
    for (int pointIdx = start; pointIdx <= end; pointIdx++) {
        polyPoints.push_back( VECTOR2I(polyLine.GetX(pointIdx), polyLine.GetY(pointIdx)) );
    }

    // Order the vectors in a lexicographic way
    std::sort(chainPoints.begin(), chainPoints.end(), lexicographicOrder);
    std::sort(polyPoints.begin(), polyPoints.end(), lexicographicOrder);

    // Compare every point coordinate to check the equality
    BOOST_CHECK_EQUAL_COLLECTIONS(chainPoints.begin(), chainPoints.end(),
                                  polyPoints.begin(), polyPoints.end());
}
コード例 #16
0
ファイル: grid_helper.cpp プロジェクト: JOE-JOE-NGIGI/kicad
VECTOR2I GRID_HELPER::GetGrid() const
{
    PCB_SCREEN* screen = m_frame->GetScreen();

    const wxRealPoint& size = screen->GetGridSize();

    return VECTOR2I( KiROUND( size.x ), KiROUND( size.y ) );
}
コード例 #17
0
ファイル: RectList.cpp プロジェクト: FlorianPO/SpriteEditor
void RectList::use() {
	if (INPUT->again(Qt::LeftButton)) {
		sf::IntRect rect = findRect(INPUT->getPixel() - VECTOR2I(LAYER->getPosition()), LAYER->getImage());
		if (rect.width > 0) {
			layer = LAYER;
			findRectList(rect, LAYER->getImage());
		}	
	}
}
コード例 #18
0
static bool Rect2Circle( VECTOR2I rp0, VECTOR2I rsize, VECTOR2I cc, int cr, VECTOR2I& force )
{
    VECTOR2I vts[] =
    {
        VECTOR2I( rp0.x,           rp0.y ),
        VECTOR2I( rp0.x,           rp0.y + rsize.y ),
        VECTOR2I( rp0.x + rsize.x, rp0.y + rsize.y ),
        VECTOR2I( rp0.x + rsize.x, rp0.y ),
        VECTOR2I( rp0.x,           rp0.y )
    };

    int dist = INT_MAX;
    VECTOR2I nearest;

    for( int i = 0; i < 4; i++ )
    {
        SEG s( vts[i], vts[i + 1] );

        VECTOR2I pn = s.NearestPoint( cc );

        int d = (pn - cc).EuclideanNorm();

        if( d < dist )
        {
            nearest = pn;
            dist = d;
        }
    }

    bool inside = cc.x >= rp0.x && cc.x <= (rp0.x + rsize.x)
                  && cc.y >= rp0.y && cc.y <= (rp0.y + rsize.y);

    VECTOR2I delta = cc - nearest;

    if( dist >= cr && !inside )
        return false;

    if( inside )
        force = -delta.Resize( abs( cr + dist ) + 1 );
    else
        force = delta.Resize( abs( cr - dist ) + 1 );

    return true;
};
コード例 #19
0
void SelectionController::sumSelection(const sf::IntRect& rect, const sf::Image* image, bool add) {
	float min_x = std::min(rect.left, cadre.left);
	float min_y = std::min(rect.top, cadre.top);

	sf::Texture texture = *sprite_selec.getTexture();
	sf::Sprite spr(texture);

	sprite_selec.setPosition(min_x - 1, min_y - 1);
	renderTexture_selec.create(std::max(rect.left + rect.width, cadre.left + cadre.width) - min_x + 2,
							   std::max(rect.top + rect.height, cadre.top + cadre.height) - min_y + 2);

	if (!inverted)
		renderTexture_selec.clear(ident_color);
	else
		renderTexture_selec.clear(blend_color);

	spr.setPosition(cadre.left - min_x, cadre.top - min_y);
	renderTexture_selec.draw(spr, sf::BlendNone);

	renderTexture_selec.display();

	if (image == NULL) {
		sf::Image img;
		if (add)
			img.create(rect.width, rect.height, blend_color);
		else
			img.create(rect.width, rect.height, ident_color);
		texture.loadFromImage(img);

		spr.setTexture(texture, true); spr.setPosition(rect.left - min_x + 1, rect.top - min_y + 1);
		renderTexture_selec.draw(spr, sf::BlendNone);
	}
	else {
		if (add)
			RES->getShader(nRer::update).setParameter("mode", 1.f); //Add
		else
			RES->getShader(nRer::update).setParameter("mode", 2.f); //Sub
		RES->getShader(nRer::update).setParameter("offset", sprite_selec.getPosition());
		RES->getShader(nRer::update).setParameter("texture", renderTexture_selec.getTexture());

		texture.loadFromImage(*image, sf::IntRect(sf::Vector2i(rect.left, rect.top) - VECTOR2I(LAYER->getPosition()),
			sf::Vector2i(rect.width, rect.height)));

		sf::Vector2f vect = sf::Vector2f(rect.left, rect.top);
		spr.setTexture(texture, true); spr.setPosition(vect - sprite_selec.getPosition());
		RES->getShader(nRer::update).setParameter("brosse", texture);
		RES->getShader(nRer::update).setParameter("pos_brosse", vect);

		renderTexture_selec.draw(spr, RES->getRender(nRer::update));
	}
	renderTexture_selec.display();

	sprite_selec.setTexture(renderTexture_selec.getTexture(), true);
	image_selec = new sf::Image(renderTexture_selec.getTexture().copyToImage());
}
コード例 #20
0
bool PNS_MEANDER_SKEW_PLACER::Start( const VECTOR2I& aP, PNS_ITEM* aStartItem )
{
    VECTOR2I p;

    if( !aStartItem || !aStartItem->OfKind( PNS_ITEM::SEGMENT ) )
    {
        Router()->SetFailureReason( _( "Please select a differential pair trace you want to tune." ) );
        return false;
    }

    m_initialSegment = static_cast<PNS_SEGMENT*>( aStartItem );

    p = m_initialSegment->Seg().NearestPoint( aP );

    m_originLine = NULL;
    m_currentNode = NULL;
    m_currentStart = p;

    m_world = Router()->GetWorld( )->Branch();
    m_originLine = m_world->AssembleLine( m_initialSegment );

    PNS_TOPOLOGY topo( m_world );
    m_tunedPath = topo.AssembleTrivialPath( m_initialSegment );

    if( !topo.AssembleDiffPair ( m_initialSegment, m_originPair ) )
    {
        Router()->SetFailureReason( _( "Unable to find complementary differential pair "
                                       "net for skew tuning. Make sure the names of the nets belonging "
                                       "to a differential pair end with either _N/_P or +/-." ) );
        return false;
    }

    if( m_originPair.Gap() < 0 )
        m_originPair.SetGap( Router()->Sizes().DiffPairGap() );

    if( !m_originPair.PLine().SegmentCount() ||
        !m_originPair.NLine().SegmentCount() )
        return false;

    m_tunedPathP = topo.AssembleTrivialPath( m_originPair.PLine().GetLink( 0 ) );
    m_tunedPathN = topo.AssembleTrivialPath( m_originPair.NLine().GetLink( 0 ) );

    m_world->Remove( m_originLine );

    m_currentWidth = m_originLine->Width( );
    m_currentEnd = VECTOR2I( 0, 0 );

    if ( m_originPair.PLine().Net () == m_originLine->Net() )
        m_coupledLength = itemsetLength( m_tunedPathN );
    else
        m_coupledLength = itemsetLength( m_tunedPathP );

    return true;
}
コード例 #21
0
void DIALOG_CREATE_ARRAY::calculateCircularArrayProperties()
{
    wxPoint centre;

    centre.x = DoubleValueFromString( g_UserUnit, m_entryCentreX->GetValue() );
    centre.y = DoubleValueFromString( g_UserUnit, m_entryCentreY->GetValue() );

    // Find the radius, etc of the circle
    centre -= m_originalItemPosition;

    const double radius = VECTOR2I(centre.x, centre.y).EuclideanNorm();
    m_labelCircRadiusValue->SetLabelText( StringFromValue( g_UserUnit, int(radius), true ) );
}
コード例 #22
0
bool PL_SELECTION_TOOL::selectionContains( const VECTOR2I& aPoint ) const
{
    const unsigned GRIP_MARGIN = 20;
    VECTOR2I margin = getView()->ToWorld( VECTOR2I( GRIP_MARGIN, GRIP_MARGIN ), false );

    // Check if the point is located within any of the currently selected items bounding boxes
    for( auto item : m_selection )
    {
        BOX2I itemBox = item->ViewBBox();
        itemBox.Inflate( margin.x, margin.y );    // Give some margin for gripping an item

        if( itemBox.Contains( aPoint ) )
            return true;
    }

    return false;
}
コード例 #23
0
void ZONE_CONTAINER::Move( const wxPoint& offset )
{
    /* move outlines */
    for( unsigned ii = 0; ii < m_Poly->m_CornersList.GetCornersCount(); ii++ )
    {
        SetCornerPosition( ii, GetCornerPosition( ii ) + offset );
    }

    m_Poly->Hatch();

    m_FilledPolysList.Move( VECTOR2I( offset.x, offset.y ) );

    for( unsigned ic = 0; ic < m_FillSegmList.size(); ic++ )
    {
        m_FillSegmList[ic].m_Start += offset;
        m_FillSegmList[ic].m_End   += offset;
    }
}
コード例 #24
0
ファイル: class_edge_mod.cpp プロジェクト: cpavlina/kicad
void EDGE_MODULE::Move( const wxPoint& aMoveVector )
{
    // Move an edge of the footprint.
    // This is a footprint shape modification.
    m_Start0 += aMoveVector;
    m_End0   += aMoveVector;

    switch( GetShape() )
    {
    default:
        break;

    case S_POLYGON:
        // polygon corners coordinates are always relative to the
        // footprint position, orientation 0
        for( auto iter = m_Poly.Iterate(); iter; iter++ )
            *iter += VECTOR2I( aMoveVector );
    }

    SetDrawCoord();
}
コード例 #25
0
bool SHAPE_LINE_CHAIN::Parse( std::stringstream& aStream )
{
    int n_pts;

    m_points.clear();
    aStream >> n_pts;

    // Rough sanity check, just make sure the loop bounds aren't absolutely outlandish
    if( n_pts < 0 || n_pts > int( aStream.str().size() ) )
        return false;

    aStream >> m_closed;

    for( int i = 0; i < n_pts; i++ )
    {
        int x, y;
        aStream >> x;
        aStream >> y;
        m_points.push_back( VECTOR2I( x, y ) );
    }

    return true;
}
コード例 #26
0
void SelectionController::createSelection(const sf::IntRect& rect, const sf::Image* image) {
	renderTexture_selec.create(rect.width + 2, rect.height + 2);
	renderTexture_selec.clear(ident_color);
	sprite_selec.setPosition(rect.left - 1, rect.top - 1);

	sf::Texture texture;
	if (image == NULL) {
		sf::Image img;
		img.create(rect.width, rect.height, blend_color);
		texture.loadFromImage(img);
	}
	else {
		texture.loadFromImage(*image, sf::IntRect(sf::Vector2i(rect.left, rect.top) - VECTOR2I(LAYER->getPosition()),
			sf::Vector2i(rect.width, rect.height)));
	}

	sf::Sprite spr(texture); spr.setPosition(1, 1);
	renderTexture_selec.draw(spr, sf::BlendNone);
	renderTexture_selec.display();
	
	sprite_selec.setTexture(renderTexture_selec.getTexture(), true);
	image_selec = new sf::Image(renderTexture_selec.getTexture().copyToImage());
}
コード例 #27
0
ファイル: pns_router.cpp プロジェクト: chgans/kicad
PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad )
{
    PNS_LAYERSET layers( 0, MAX_CU_LAYERS - 1 );

    // ignore non-copper pads
    if ( (aPad->GetLayerSet() & LSET::AllCuMask()).none() )
        return NULL;

    switch( aPad->GetAttribute() )
    {
    case PAD_ATTRIB_STANDARD:
        break;

    case PAD_ATTRIB_SMD:
    case PAD_ATTRIB_HOLE_NOT_PLATED:
    case PAD_ATTRIB_CONN:
        {
            LSET lmsk = aPad->GetLayerSet();
            bool is_copper = false;

            for( int i = 0; i < MAX_CU_LAYERS; i++ )
            {
                if( lmsk[i] )
                {
                    is_copper = true;
                    if( aPad->GetAttribute() != PAD_ATTRIB_HOLE_NOT_PLATED )
                        layers = PNS_LAYERSET( i );
                    break;
                }
            }

            if( !is_copper )
                return NULL;
        }
        break;

    default:
        TRACE( 0, "unsupported pad type 0x%x", aPad->GetAttribute() );
        return NULL;
    }

    PNS_SOLID* solid = new PNS_SOLID;

    solid->SetLayers( layers );
    solid->SetNet( aPad->GetNetCode() );
    solid->SetParent( aPad );

    wxPoint wx_c = aPad->ShapePos();
    wxSize  wx_sz = aPad->GetSize();
    wxPoint offset = aPad->GetOffset();

    VECTOR2I c( wx_c.x, wx_c.y );
    VECTOR2I sz( wx_sz.x, wx_sz.y );

    RotatePoint( &offset, aPad->GetOrientation() );

    solid->SetPos( VECTOR2I( c.x - offset.x, c.y - offset.y ) );
    solid->SetOffset ( VECTOR2I ( offset.x, offset.y ) );

    double orient = aPad->GetOrientation() / 10.0;

    if( aPad->GetShape() == PAD_SHAPE_CIRCLE )
    {
        solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
    }
    else
    {
        if( orient == 0.0 || orient == 90.0 || orient == 180.0 || orient == 270.0 )
        {
            if( orient == 90.0 || orient == 270.0 )
                sz = VECTOR2I( sz.y, sz.x );

            switch( aPad->GetShape() )
            {
            case PAD_SHAPE_OVAL:
                if( sz.x == sz.y )
                    solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
                else
                {
                    VECTOR2I delta;

                    if( sz.x > sz.y )
                        delta = VECTOR2I( ( sz.x - sz.y ) / 2, 0 );
                    else
                        delta = VECTOR2I( 0, ( sz.y - sz.x ) / 2 );

                    SHAPE_SEGMENT* shape = new SHAPE_SEGMENT( c - delta, c + delta,
                                                              std::min( sz.x, sz.y ) );
                    solid->SetShape( shape );
                }
                break;

            case PAD_SHAPE_RECT:
                solid->SetShape( new SHAPE_RECT( c - sz / 2, sz.x, sz.y ) );
                break;

            case PAD_SHAPE_TRAPEZOID:
            {
                wxPoint coords[4];
                aPad->BuildPadPolygon( coords, wxSize( 0, 0 ), aPad->GetOrientation() );
                SHAPE_CONVEX* shape = new SHAPE_CONVEX();

                for( int ii = 0; ii < 4; ii++ )
                {
                    shape->Append( wx_c + coords[ii] );
                }

                solid->SetShape( shape );
                break;
            }

            default:
                TRACEn( 0, "unsupported pad shape" );
                delete solid;
                return NULL;
            }
        }
        else
        {
            switch( aPad->GetShape() )
            {
            // PAD_SHAPE_CIRCLE already handled above

            case PAD_SHAPE_OVAL:
                if( sz.x == sz.y )
                    solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) );
                else
                {
                    wxPoint start;
                    wxPoint end;
                    wxPoint corner;

                    SHAPE_CONVEX* shape = new SHAPE_CONVEX();

                    int w = aPad->BuildSegmentFromOvalShape( start, end, 0.0, wxSize( 0, 0 ) );

                    if( start.y == 0 )
                        corner = wxPoint( start.x, -( w / 2 ) );
                    else
                        corner = wxPoint( w / 2, start.y );

                    RotatePoint( &start, aPad->GetOrientation() );
                    RotatePoint( &corner, aPad->GetOrientation() );
                    shape->Append( wx_c + corner );

                    for( int rot = 100; rot <= 1800; rot += 100 )
                    {
                        wxPoint p( corner );
                        RotatePoint( &p, start, rot );
                        shape->Append( wx_c + p );
                    }

                    if( end.y == 0 )
                        corner = wxPoint( end.x, w / 2 );
                    else
                        corner = wxPoint( -( w / 2 ), end.y );

                    RotatePoint( &end, aPad->GetOrientation() );
                    RotatePoint( &corner, aPad->GetOrientation() );
                    shape->Append( wx_c + corner );

                    for( int rot = 100; rot <= 1800; rot += 100 )
                    {
                        wxPoint p( corner );
                        RotatePoint( &p, end, rot );
                        shape->Append( wx_c + p );
                    }

                    solid->SetShape( shape );
                }
                break;

            case PAD_SHAPE_RECT:
            case PAD_SHAPE_TRAPEZOID:
            {
                wxPoint coords[4];
                aPad->BuildPadPolygon( coords, wxSize( 0, 0 ), aPad->GetOrientation() );

                SHAPE_CONVEX* shape = new SHAPE_CONVEX();
                for( int ii = 0; ii < 4; ii++ )
                {
                    shape->Append( wx_c + coords[ii] );
                }

                solid->SetShape( shape );
                break;
            }

            default:
                TRACEn( 0, "unsupported pad shape" );
                delete solid;

                return NULL;
            }
        }
    }
    return solid;
}
コード例 #28
0
void D_CODE::ConvertShapeToPolygon()
{
    wxPoint initialpos;
    wxPoint currpos;

    m_Polygon.RemoveAllContours();

    switch( m_Shape )
    {
    case APT_CIRCLE:        // creates only a circle with rectangular hole
        TransformCircleToPolygon( m_Polygon, initialpos, m_Size.x >> 1, SEGS_CNT );
        addHoleToPolygon( &m_Polygon, m_DrillShape, m_Drill, initialpos );
        break;

    case APT_RECT:
        m_Polygon.NewOutline();
        currpos.x  = m_Size.x / 2;
        currpos.y  = m_Size.y / 2;
        initialpos = currpos;
        m_Polygon.Append( VECTOR2I( currpos ) );
        currpos.x -= m_Size.x;
        m_Polygon.Append( VECTOR2I( currpos ) );
        currpos.y -= m_Size.y;
        m_Polygon.Append( VECTOR2I( currpos ) );
        currpos.x += m_Size.x;
        m_Polygon.Append( VECTOR2I( currpos ) );
        currpos.y += m_Size.y;
        m_Polygon.Append( VECTOR2I( currpos ) );    // close polygon
        m_Polygon.Append( VECTOR2I( initialpos ) );

        addHoleToPolygon( &m_Polygon, m_DrillShape, m_Drill, initialpos );
        break;

    case APT_OVAL:
    {
        m_Polygon.NewOutline();
        int delta, radius;

        // we create an horizontal oval shape. then rotate if needed
        if( m_Size.x > m_Size.y )   // horizontal oval
        {
            delta  = (m_Size.x - m_Size.y) / 2;
            radius = m_Size.y / 2;
        }
        else   // vertical oval
        {
            delta  = (m_Size.y - m_Size.x) / 2;
            radius = m_Size.x / 2;
        }

        currpos.y  = radius;
        initialpos = currpos;
        m_Polygon.Append( VECTOR2I( currpos ) );

        // build the right arc of the shape
        unsigned ii = 0;

        for( ; ii <= SEGS_CNT / 2; ii++ )
        {
            currpos = initialpos;
            RotatePoint( &currpos, ii * 3600.0 / SEGS_CNT );
            currpos.x += delta;
            m_Polygon.Append( VECTOR2I( currpos ) );
        }

        // build the left arc of the shape
        for( ii = SEGS_CNT / 2; ii <= SEGS_CNT; ii++ )
        {
            currpos = initialpos;
            RotatePoint( &currpos, ii * 3600.0 / SEGS_CNT );
            currpos.x -= delta;
            m_Polygon.Append( VECTOR2I( currpos ) );
        }

        m_Polygon.Append( VECTOR2I( initialpos ) );      // close outline

        if( m_Size.y > m_Size.x )                   // vertical oval, rotate polygon.
        {
            for( auto it = m_Polygon.Iterate( 0 ); it; ++it )
                it->Rotate( -M_PI / 2 );
        }

        addHoleToPolygon( &m_Polygon, m_DrillShape, m_Drill, initialpos );
    }
    break;

    case APT_POLYGON:
        m_Polygon.NewOutline();
        currpos.x  = m_Size.x >> 1;     // first point is on X axis
        initialpos = currpos;

        // rs274x said: m_EdgesCount = 3 ... 12
        if( m_EdgesCount < 3 )
            m_EdgesCount = 3;

        if( m_EdgesCount > 12 )
            m_EdgesCount = 12;

        for( int ii = 0; ii < m_EdgesCount; ii++ )
        {
            currpos = initialpos;
            RotatePoint( &currpos, ii * 3600.0 / m_EdgesCount );
            m_Polygon.Append( VECTOR2I( currpos ) );
        }

        addHoleToPolygon( &m_Polygon, m_DrillShape, m_Drill, initialpos );

        if( m_Rotation )                   // vertical oval, rotate polygon.
        {
            int angle = KiROUND( m_Rotation * 10 );

            for( auto it = m_Polygon.Iterate( 0 ); it; ++it )
                it->Rotate( -angle );
        }

        break;

    case APT_MACRO:

        // TODO
        break;
    }
}
コード例 #29
0
ファイル: edit_tool.cpp プロジェクト: OpenEE/micad
int EDIT_TOOL::Main( const TOOL_EVENT& aEvent )
{
    KIGFX::VIEW_CONTROLS* controls = getViewControls();
    PCB_BASE_EDIT_FRAME* editFrame = getEditFrame<PCB_BASE_EDIT_FRAME>();

    VECTOR2I originalCursorPos = controls->GetCursorPosition();
    const SELECTION& selection = m_selectionTool->GetSelection();

    // Shall the selection be cleared at the end?
    bool unselect = selection.Empty();

    // Be sure that there is at least one item that we can modify. If nothing was selected before,
    // try looking for the stuff under mouse cursor (i.e. Kicad old-style hover selection)
    if( !hoverSelection( selection ) )
        return 0;

    Activate();

    m_dragging = false;         // Are selected items being dragged?
    bool restore = false;       // Should items' state be restored when finishing the tool?
    bool lockOverride = false;

    // By default, modified items need to update their geometry
    m_updateFlag = KIGFX::VIEW_ITEM::GEOMETRY;

    controls->ShowCursor( true );

    // cumulative translation
    wxPoint totalMovement( 0, 0 );

    GRID_HELPER grid( editFrame );
    OPT_TOOL_EVENT evt = aEvent;

    // Main loop: keep receiving events
    do
    {
        if( evt->IsCancel() )
        {
            restore = true; // Cancelling the tool means that items have to be restored
            break;          // Finish
        }

        else if( evt->Action() == TA_UNDO_REDO )
        {
            unselect = true;
            break;
        }

        else if( evt->IsAction( &COMMON_ACTIONS::editActivate )
                 || evt->IsMotion() || evt->IsDrag( BUT_LEFT ) )
        {
            BOARD_ITEM* item = selection.Item<BOARD_ITEM>( 0 );

            if( m_dragging && evt->Category() == TC_MOUSE )
            {
                m_cursor = grid.BestSnapAnchor( evt->Position(), item );
                controls->ForceCursorPosition( true, m_cursor );

                wxPoint movement = wxPoint( m_cursor.x, m_cursor.y ) - item->GetPosition();
                totalMovement += movement;

                // Drag items to the current cursor position
                for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
                    selection.Item<BOARD_ITEM>( i )->Move( movement + m_offset );

                updateRatsnest( true );
            }
            else if( !m_dragging )    // Prepare to start dragging
            {
                if( !invokeInlineRouter() )
                {
                    m_selectionTool->SanitizeSelection();

                    if( selection.Empty() )
                        break;

                    // deal with locked items (override lock or abort the operation)
                    SELECTION_LOCK_FLAGS lockFlags = m_selectionTool->CheckLock();

                    if( lockFlags == SELECTION_LOCKED )
                        break;
                    else if( lockFlags == SELECTION_LOCK_OVERRIDE )
                        lockOverride = true;

                    // Save items, so changes can be undone
                    if( !isUndoInhibited() )
                    {
                        editFrame->OnModify();
                        editFrame->SaveCopyInUndoList( selection.items, UR_CHANGED );
                    }

                    m_cursor = controls->GetCursorPosition();

                    if( selection.Size() == 1 )
                    {
                        // Set the current cursor position to the first dragged item origin, so the
                        // movement vector could be computed later
                        m_cursor = grid.BestDragOrigin( originalCursorPos, item );
                        grid.SetAuxAxes( true, m_cursor );
                    }
                    else
                    {
                        m_cursor = grid.Align( m_cursor );
                    }

                    controls->ForceCursorPosition( true, m_cursor );
                    controls->WarpCursor( m_cursor, true );

                    VECTOR2I o = VECTOR2I( item->GetPosition() );
                    m_offset.x = o.x - m_cursor.x;
                    m_offset.y = o.y - m_cursor.y;

                    controls->SetAutoPan( true );
                    m_dragging = true;
                    incUndoInhibit();
                }
            }

            selection.group->ViewUpdate( KIGFX::VIEW_ITEM::GEOMETRY );
            m_toolMgr->RunAction( COMMON_ACTIONS::pointEditorUpdate, true );
        }

        // Dispatch TOOL_ACTIONs
        else if( evt->Category() == TC_COMMAND )
        {
            if( evt->IsAction( &COMMON_ACTIONS::rotate ) )
            {
                Rotate( aEvent );
            }
            else if( evt->IsAction( &COMMON_ACTIONS::flip ) )
            {
                Flip( aEvent );

                // Flip causes change of layers
                enableUpdateFlag( KIGFX::VIEW_ITEM::LAYERS );
            }
            else if( evt->IsAction( &COMMON_ACTIONS::remove ) )
            {
                Remove( aEvent );

                break;       // exit the loop, as there is no further processing for removed items
            }
            else if( evt->IsAction( &COMMON_ACTIONS::duplicate ) )
            {
                // On duplicate, stop moving this item
                // The duplicate tool should then select the new item and start
                // a new move procedure
                break;
            }
            else if( evt->IsAction( &COMMON_ACTIONS::moveExact ) )
            {
                // Can't do this, because the selection will then contain
                // stale pointers and it will all go horribly wrong...
                //editFrame->RestoreCopyFromUndoList( dummy );
                //
                // So, instead, reset the position manually
                for( unsigned int i = 0; i < selection.items.GetCount(); ++i )
                {
                    BOARD_ITEM* item = selection.Item<BOARD_ITEM>( i );
                    item->SetPosition( item->GetPosition() - totalMovement );

                    // And what about flipping and rotation?
                    // for now, they won't be undone, but maybe that is how
                    // it should be, so you can flip and move exact in the
                    // same action?
                }

                // This causes a double event, so we will get the dialogue
                // correctly, somehow - why does Rotate not?
                //MoveExact( aEvent );
                break;      // exit the loop - we move exactly, so we have finished moving
            }
        }

        else if( evt->IsMouseUp( BUT_LEFT ) || evt->IsClick( BUT_LEFT ) )
        {
            if( !lockOverride )
                break; // Finish

            lockOverride = false;
        }
    } while( evt = Wait() );

    if( m_dragging )
        decUndoInhibit();

    m_dragging = false;
    m_offset.x = 0;
    m_offset.y = 0;

    if( restore )
    {
        // Modifications have to be rollbacked, so restore the previous state of items
        wxCommandEvent dummy;
        editFrame->RestoreCopyFromUndoList( dummy );
    }
    else
    {
        // Changes are applied, so update the items
        selection.group->ItemsViewUpdate( m_updateFlag );
    }

    if( unselect )
        m_toolMgr->RunAction( COMMON_ACTIONS::selectionClear, true );

    RN_DATA* ratsnest = getModel<BOARD>()->GetRatsnest();
    ratsnest->ClearSimple();
    ratsnest->Recalculate();

    controls->ShowCursor( false );
    controls->SetAutoPan( false );

    return 0;
}
コード例 #30
0
const BOX2I MODULE::ViewBBox() const
{
    EDA_RECT fpRect = GetFootprintRect();

    return BOX2I( VECTOR2I( fpRect.GetOrigin() ), VECTOR2I( fpRect.GetSize() ) );
}