/* Mark items inside rect.
 *  Items are inside rect when an end point is inside rect
 */
int MarkItemsInBloc( MODULE* module, EDA_RECT& Rect )
{
    EDA_ITEM* item;
    int       ItemsCount = 0;
    wxPoint   pos;
    D_PAD*    pad;

    if( module == NULL )
        return 0;

    pad = module->Pads();

    for( ; pad != NULL; pad = pad->Next() )
    {
        pad->ClearFlags( SELECTED );
        pos = pad->GetPosition();

        if( Rect.Contains( pos ) )
        {
            pad->SetFlags( SELECTED );
            ItemsCount++;
        }
    }

    item = module->GraphicalItems();

    for( ; item != NULL; item = item->Next() )
    {
        item->ClearFlags( SELECTED );

        switch( item->Type() )
        {
        case PCB_MODULE_EDGE_T:
            if( ((EDGE_MODULE*)item )->HitTest( Rect ) )
            {
                item->SetFlags( SELECTED );
                ItemsCount++;
            }

            break;

        case PCB_MODULE_TEXT_T:
            pos = ( (TEXTE_MODULE*) item )->GetTextPosition();

            if( Rect.Contains( pos ) )
            {
                item->SetFlags( SELECTED );
                ItemsCount++;
            }

            break;

        default:
            break;
        }
    }

    return ItemsCount;
}
bool ZONE_CONTAINER::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
    EDA_RECT arect = aRect;
    arect.Inflate( aAccuracy );
    CRect rect = m_Poly->GetBoundingBox();
    EDA_RECT bbox;

    bbox.SetOrigin( rect.left,  rect.bottom );
    bbox.SetEnd(    rect.right, rect.top    );

    if( aContained )
         return arect.Contains( bbox );
    else    // Test for intersection between aRect and the polygon
            // For a polygon, using its bounding box has no sense here
    {
        // Fast test: if aRect is outside the polygon bounding box,
        // rectangles cannot intersect
        if( ! bbox.Intersects( arect ) )
            return false;

        // aRect is inside the polygon bounding box,
        // and can intersect the polygon: use a fine test.
        // aRect intersects the polygon if at least one aRect corner
        // is inside the polygon
        wxPoint corner = arect.GetOrigin();

        if( HitTestInsideZone( corner ) )
            return true;

        corner.x = arect.GetEnd().x;

        if( HitTestInsideZone( corner ) )
            return true;

        corner = arect.GetEnd();

        if( HitTestInsideZone( corner ) )
            return true;

        corner.x = arect.GetOrigin().x;

        if( HitTestInsideZone( corner ) )
            return true;

        // No corner inside arect, but outlines can intersect arect
        // if one of outline corners is inside arect
        int count = m_Poly->GetCornersCount();
        for( int ii =0; ii < count; ii++ )
        {
            if( arect.Contains( m_Poly->GetPos( ii ) ) )
                return true;
        }

        return false;
    }
}
bool TRACK::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
    EDA_RECT arect = aRect;
    arect.Inflate( aAccuracy );

    if( aContained )
        /* Tracks are a special case:
         * they are considered inside the rect if one end is inside the rect */
        return arect.Contains( GetStart() ) || arect.Contains( GetEnd() );
    else
        return arect.Intersects( GetStart(), GetEnd() );
}
bool GERBER_DRAW_ITEM::HitTest( const EDA_RECT& aRefArea ) const
{
    wxPoint pos = GetABPosition( m_Start );

    if( aRefArea.Contains( pos ) )
        return true;

    pos = GetABPosition( m_End );

    if( aRefArea.Contains( pos ) )
        return true;

    return false;
}
Example #5
0
bool PCB_TARGET::HitTest( const EDA_RECT& aRect ) const
{
    if( aRect.Contains( m_Pos ) )
        return true;

    return false;
}
bool LIB_CIRCLE::Inside( EDA_RECT& aRect ) const
{
    /*
     * FIXME: This fails to take into account the radius around the center
     *        point.
     */
    return aRect.Contains( m_Pos.x, -m_Pos.y );
}
bool LIB_FIELD::Inside( EDA_RECT& rect ) const
{
    /*
     * FIXME: This fails to take into account the size and/or orientation of
     *        the text.
     */
    return rect.Contains( m_Pos.x, -m_Pos.y );
}
Example #8
0
bool SCH_JUNCTION::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
    EDA_RECT rect = GetBoundingBox();

    rect.Inflate( aAccuracy );

    return rect.Contains( aPosition );
}
Example #9
0
bool SCH_SHEET_PIN::HitTest( const wxPoint& aPoint, int aAccuracy ) const
{
    EDA_RECT rect = GetBoundingBox();

    rect.Inflate( aAccuracy );

    return rect.Contains( aPoint );
}
Example #10
0
bool LIB_TEXT::Inside( EDA_RECT& rect ) const
{
    /*
     * FIXME: This should calculate the text size and justification and
     *        use rectangle intersect.
     */
    return rect.Contains( m_Pos.x, -m_Pos.y );
}
bool MODULE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
    EDA_RECT arect = aRect;
    arect.Inflate( aAccuracy );

    if( aContained )
        return arect.Contains( m_BoundaryBox );
    else
        return m_BoundaryBox.Intersects( arect );
}
Example #12
0
bool SCH_TEXT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
    EDA_RECT bBox = GetBoundingBox();
    bBox.Inflate( aAccuracy );

    if( aContained )
        return aRect.Contains( bBox );

    return aRect.Intersects( bBox );
}
Example #13
0
bool PCB_TARGET::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
    EDA_RECT arect = aRect;
    arect.Inflate( aAccuracy );

    if( aContained )
        return arect.Contains( GetBoundingBox() );
    else
        return GetBoundingBox().Intersects( arect );
}
Example #14
0
bool EDA_TEXT::TextHitTest( const wxPoint& aPoint, int aAccuracy ) const
{
    EDA_RECT rect = GetTextBox( -1 );   // Get the full text area.
    wxPoint location = aPoint;

    rect.Inflate( aAccuracy );
    RotatePoint( &location, m_Pos, -m_Orient );

    return rect.Contains( location );
}
Example #15
0
bool LIB_POLYLINE::Inside( EDA_RECT& aRect ) const
{
    for( size_t i = 0; i < m_PolyPoints.size(); i++ )
    {
        if( aRect.Contains( m_PolyPoints[i].x, -m_PolyPoints[i].y ) )
            return true;
    }

    return false;
}
bool TEXTE_MODULE::TextHitTest( const wxPoint& aPoint, int aAccuracy ) const
{
    EDA_RECT rect = GetTextBox( -1 );
    wxPoint location = aPoint;

    rect.Inflate( aAccuracy );

    RotatePoint( &location, GetTextPos(), -GetDrawRotation() );

    return rect.Contains( location );
}
Example #17
0
bool EDA_TEXT::TextHitTest( const EDA_RECT& aRect, bool aContains, int aAccuracy ) const
{
    EDA_RECT rect = aRect;

    rect.Inflate( aAccuracy );

    if( aContains )
        return rect.Contains( GetTextBox( -1 ) );

    return rect.Intersects( GetTextBox( -1 ) );
}
Example #18
0
bool SCH_BUS_ENTRY_BASE::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
    EDA_RECT rect = aRect;

    rect.Inflate( aAccuracy );

    if( aContained )
        return rect.Contains( GetBoundingBox() );

    return rect.Intersects( GetBoundingBox() );
}
Example #19
0
bool SCH_FIELD::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
    // Do not hit test hidden or empty fields.
    if( !IsVisible() || IsVoid() )
        return false;

    EDA_RECT rect = GetBoundingBox();

    rect.Inflate( aAccuracy );

    return rect.Contains( aPosition );
}
bool VIA::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
    EDA_RECT box;
    EDA_RECT arect = aRect;
    arect.Inflate( aAccuracy );

    box.SetOrigin( GetStart() );
    box.Inflate( GetWidth() / 2 );

    if( aContained )
        return arect.Contains( box );
    else
        return arect.Intersects( box );
}
Example #21
0
bool SCH_JUNCTION::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
    if( m_Flags & STRUCT_DELETED || m_Flags & SKIP_STRUCT )
        return false;

    EDA_RECT rect = aRect;

    rect.Inflate( aAccuracy );

    if( aContained )
        return rect.Contains( GetBoundingBox() );

    return rect.Intersects( GetBoundingBox() );
}
bool DIMENSION::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
    EDA_RECT arect = aRect;
    arect.Inflate( aAccuracy );

    EDA_RECT rect = GetBoundingBox();
    if( aAccuracy )
        rect.Inflate( aAccuracy );

    if( aContained )
        return arect.Contains( rect );

    return arect.Intersects( rect );
}
bool TEXTE_MODULE::TextHitTest( const EDA_RECT& aRect, bool aContains, int aAccuracy ) const
{
    EDA_RECT rect = aRect;

    rect.Inflate( aAccuracy );

    if( aContains )
    {
        return rect.Contains( GetBoundingBox() );
    }
    else
    {
        return rect.Intersects( GetTextBox( -1 ), GetDrawRotation() );
    }
}
Example #24
0
bool SCH_FIELD::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
    // Do not hit test hidden fields.
    if( !IsVisible() || IsVoid() )
        return false;

    EDA_RECT rect = aRect;

    rect.Inflate( aAccuracy );

    if( aContained )
        return rect.Contains( GetBoundingBox() );

    return rect.Intersects( GetBoundingBox() );
}
bool TEXTE_MODULE::HitTest( const wxPoint& aPosition ) const
{
    wxPoint  rel_pos;
    EDA_RECT area = GetTextBox( -1, -1 );

    /* Rotate refPos to - angle to test if refPos is within area (which
     * is relative to an horizontal text)
     */
    rel_pos = aPosition;
    RotatePoint( &rel_pos, m_Pos, -GetDrawRotation() );

    if( area.Contains( rel_pos ) )
        return true;

    return false;
}
bool DRAWSEGMENT::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
    wxPoint p1, p2;
    int radius;
    float theta;
    EDA_RECT arect = aRect;
    arect.Inflate( aAccuracy );

    switch( m_Shape )
    {
    case S_CIRCLE:
        // Test if area intersects or contains the circle:
        if( aContained )
            return arect.Contains( GetBoundingBox() );
        else
            return arect.Intersects( GetBoundingBox() );
        break;

    case S_ARC:
        radius = hypot( (double)( GetEnd().x - GetStart().x ),
                        (double)( GetEnd().y - GetStart().y ) );
        theta  = std::atan2( GetEnd().y - GetStart().y , GetEnd().x - GetStart().x );

        //Approximate the arc with two lines. This should be accurate enough for selection.
        p1.x   = radius * std::cos( theta + M_PI/4 ) + GetStart().x;
        p1.y   = radius * std::sin( theta + M_PI/4 ) + GetStart().y;
        p2.x   = radius * std::cos( theta + M_PI/2 ) + GetStart().x;
        p2.y   = radius * std::sin( theta + M_PI/2 ) + GetStart().y;

        if( aContained )
            return arect.Contains( GetEnd() ) && aRect.Contains( p1 ) && aRect.Contains( p2 );
        else
            return arect.Intersects( GetEnd(), p1 ) || aRect.Intersects( p1, p2 );

        break;

    case S_SEGMENT:
        if( aContained )
            return arect.Contains( GetStart() ) && aRect.Contains( GetEnd() );
        else
            return arect.Intersects( GetStart(), GetEnd() );

        break;

    default:
        ;
    }
    return false;
}
Example #27
0
bool LIB_RECTANGLE::Inside( EDA_RECT& aRect ) const
{
    return aRect.Contains( m_Pos.x, -m_Pos.y ) || aRect.Contains( m_End.x, -m_End.y );
}
Example #28
0
bool SCH_TEXT::HitTest( const wxPoint& aPosition, int aAccuracy ) const
{
    EDA_RECT bBox = GetBoundingBox();
    bBox.Inflate( aAccuracy );
    return bBox.Contains( aPosition );
}
/* Function to move components in a rectangular area format 4 / 3,
 * starting from the mouse cursor.
 * Footprints are grouped by sheet.
 * Components with the LOCKED status set are not moved
 */
void PCB_EDIT_FRAME::SpreadFootprints( std::vector<MODULE*>* aFootprints,
                                       bool aMoveFootprintsOutsideBoardOnly,
                                       bool aCheckForBoardEdges,
                                       wxPoint aSpreadAreaPosition,
                                       bool aPrepareUndoCommand )
{
    EDA_RECT bbox = GetBoard()->GetBoardEdgesBoundingBox();
    bool     edgesExist = bbox.GetWidth() || bbox.GetHeight();
    // if aFootprintsOutsideBoardOnly is true, and if board outline exists,
    // we have to filter footprints to move:
    bool outsideBrdFilter = aMoveFootprintsOutsideBoardOnly && edgesExist;

    // no edges exist
    if( aMoveFootprintsOutsideBoardOnly && !edgesExist )
    {
        DisplayError( this,
                      _( "Could not automatically place footprints. No board outlines detected." ) );
        return;
    }


    // Build candidate list
    // calculate also the area needed by these footprints
    std::vector <MODULE*> footprintList;

    for( MODULE* footprint : *aFootprints )
    {
        footprint->CalculateBoundingBox();

        if( outsideBrdFilter )
        {
            if( bbox.Contains( footprint->GetPosition() ) )
                continue;
        }

        if( footprint->IsLocked() )
            continue;

        footprintList.push_back( footprint );
    }

    if( footprintList.empty() )
        return;

    // sort footprints by sheet path. we group them later by sheet
    sort( footprintList.begin(), footprintList.end(), sortFootprintsbySheetPath );

    // Undo command: init undo list. If aPrepareUndoCommand == false
    // no undo command will be initialized.
    // Useful when a undo command is already initialized by the caller
    PICKED_ITEMS_LIST  undoList;

    if( aPrepareUndoCommand )
    {
        undoList.m_Status = UR_CHANGED;
        ITEM_PICKER        picker( NULL, UR_CHANGED );

        for( MODULE* footprint : footprintList )
        {
            // Undo: add copy of the footprint to undo list
            picker.SetItem( footprint );
            picker.SetLink( footprint->Clone() );
            undoList.PushItem( picker );
        }
    }

    // Extract and place footprints by sheet
    std::vector <MODULE*> footprintListBySheet;
    std::vector <EDA_RECT> placementSheetAreas;
    double subsurface;
    double placementsurface = 0.0;

    // put the placement area position on mouse cursor.
    // this position will be adjusted later
    wxPoint placementAreaPosition = aSpreadAreaPosition;

    // We sometimes do not want to move footprints inside an existing board.
    // Therefore, move the placement area position outside the board bounding box
    // to the left of the board
    if( aCheckForBoardEdges && edgesExist )
    {
        if( placementAreaPosition.x < bbox.GetEnd().x &&
            placementAreaPosition.y < bbox.GetEnd().y )
        {
            // the placement area could overlap the board
            // move its position to a safe location
            placementAreaPosition.x = bbox.GetEnd().x;
            placementAreaPosition.y = bbox.GetOrigin().y;
        }
    }

    // The placement uses 2 passes:
    // the first pass creates the rectangular areas to place footprints
    // each sheet in schematic creates one rectangular area.
    // the second pass moves footprints inside these areas
    MODULE* footprint;
    for( int pass = 0; pass < 2; pass++ )
    {
        int subareaIdx = 0;
        footprintListBySheet.clear();
        subsurface = 0.0;

        for( unsigned ii = 0; ii < footprintList.size(); ii++ )
        {
            footprint = footprintList[ii];
            bool islastItem = false;

            if( ii == footprintList.size() - 1 ||
                ( footprintList[ii]->GetPath().BeforeLast( '/' ) !=
                  footprintList[ii+1]->GetPath().BeforeLast( '/' ) ) )
                islastItem = true;

            footprintListBySheet.push_back( footprint );
            subsurface += footprint->GetArea( PADDING );

            if( islastItem )
            {
                // end of the footprint sublist relative to the same sheet path
                // calculate placement of the current sublist
                EDA_RECT freeArea;
                int Xsize_allowed = (int) ( sqrt( subsurface ) * 4.0 / 3.0 );
                int Ysize_allowed = (int) ( subsurface / Xsize_allowed );

                freeArea.SetWidth( Xsize_allowed );
                freeArea.SetHeight( Ysize_allowed );
                CRectPlacement placementArea;

                if( pass == 1 )
                {
                    wxPoint areapos = placementSheetAreas[subareaIdx].GetOrigin()
                                      + placementAreaPosition;
                    freeArea.SetOrigin( areapos );
                }

                bool findAreaOnly = pass == 0;
                moveFootprintsInArea( placementArea, footprintListBySheet,
                                      freeArea, findAreaOnly );

                if( pass == 0 )
                {
                    // Populate sheet placement areas list
                    EDA_RECT sub_area;
                    sub_area.SetWidth( placementArea.GetW()*scale );
                    sub_area.SetHeight( placementArea.GetH()*scale );
                    // Add a margin around the sheet placement area:
                    sub_area.Inflate( Millimeter2iu( 1.5 ) );

                    placementSheetAreas.push_back( sub_area );

                    placementsurface += (double) sub_area.GetWidth()*
                                        sub_area.GetHeight();
                }

                // Prepare buffers for next sheet
                subsurface  = 0.0;
                footprintListBySheet.clear();
                subareaIdx++;
            }
        }

        // End of pass:
        // At the end of the first pass, we have to find position of each sheet
        // placement area
        if( pass == 0 )
        {
            int Xsize_allowed = (int) ( sqrt( placementsurface ) * 4.0 / 3.0 );
            int Ysize_allowed = (int) ( placementsurface / Xsize_allowed );
            CRectPlacement placementArea;
            CSubRectArray  vecSubRects;

            fillRectList( vecSubRects, placementSheetAreas );
            spreadRectangles( placementArea, vecSubRects, Xsize_allowed, Ysize_allowed );

            for( unsigned it = 0; it < vecSubRects.size(); ++it )
            {
                TSubRect& srect = vecSubRects[it];
                wxPoint pos( srect.x*scale, srect.y*scale );
                wxSize size( srect.w*scale, srect.h*scale );
                placementSheetAreas[srect.n].SetOrigin( pos );
                placementSheetAreas[srect.n].SetSize( size );
            }
        }
    }   // End pass

    // Undo: commit list
    if( aPrepareUndoCommand )
        SaveCopyInUndoList( undoList, UR_CHANGED );

    OnModify();

    m_canvas->Refresh();
}
Example #30
0
bool D_PAD::HitTest( const EDA_RECT& aRect, bool aContained, int aAccuracy ) const
{
    EDA_RECT arect = aRect;
    arect.Normalize();
    arect.Inflate( aAccuracy );

    wxPoint shapePos = ShapePos();

    EDA_RECT shapeRect;

    int r;

    EDA_RECT bb = GetBoundingBox();

    wxPoint endCenter;
    int radius;

    if( !arect.Intersects( bb ) )
        return false;

    // This covers total containment for all test cases
    if( arect.Contains( bb ) )
        return true;

    switch( GetShape() )
    {
    case PAD_SHAPE_CIRCLE:
        return arect.IntersectsCircle( GetPosition(), GetBoundingRadius() );
    case PAD_SHAPE_RECT:
        shapeRect.SetOrigin( shapePos );
        shapeRect.Inflate( m_Size.x / 2, m_Size.y / 2 );
        return arect.Intersects( shapeRect, m_Orient );
    case PAD_SHAPE_OVAL:

        // Circlular test if dimensions are equal
        if( m_Size.x == m_Size.y )
            return arect.IntersectsCircle( shapePos, GetBoundingRadius() );

        shapeRect.SetOrigin( shapePos );

        // Horizontal dimension is greater
        if( m_Size.x > m_Size.y )
        {
            radius = m_Size.y / 2;

            shapeRect.Inflate( m_Size.x / 2 - radius, radius );

            endCenter = wxPoint( m_Size.x / 2 - radius, 0 );
            RotatePoint( &endCenter, m_Orient );

            // Test circular ends
            if( arect.IntersectsCircle( shapePos + endCenter, radius ) ||
                arect.IntersectsCircle( shapePos - endCenter, radius ) )
            {
                return true;
            }
        }
        else
        {
            radius = m_Size.x / 2;

            shapeRect.Inflate( radius, m_Size.y / 2 - radius );

            endCenter = wxPoint( 0, m_Size.y / 2 - radius );
            RotatePoint( &endCenter, m_Orient );

            // Test circular ends
            if( arect.IntersectsCircle( shapePos + endCenter, radius ) ||
                arect.IntersectsCircle( shapePos - endCenter, radius ) )
            {
                return true;
            }
        }

        // Test rectangular portion between rounded ends
        if( arect.Intersects( shapeRect, m_Orient ) )
        {
            return true;
        }

        break;
    case PAD_SHAPE_TRAPEZOID:
        /* Trapezoid intersection tests:
         * A) Any points of rect inside trapezoid
         * B) Any points of trapezoid inside rect
         * C) Any sides of trapezoid cross rect
         */
        {

        wxPoint poly[4];
        BuildPadPolygon( poly, wxSize( 0, 0 ), 0 );

        wxPoint corners[4];

        corners[0] = wxPoint( arect.GetLeft(),  arect.GetTop() );
        corners[1] = wxPoint( arect.GetRight(), arect.GetTop() );
        corners[2] = wxPoint( arect.GetRight(), arect.GetBottom() );
        corners[3] = wxPoint( arect.GetLeft(),  arect.GetBottom() );

        for( int i=0; i<4; i++ )
        {
            RotatePoint( &poly[i], m_Orient );
            poly[i] += shapePos;
        }

        for( int ii=0; ii<4; ii++ )
        {
            if( TestPointInsidePolygon( poly, 4, corners[ii] ) )
            {
                return true;
            }

            if( arect.Contains( poly[ii] ) )
            {
                return true;
            }

            if( arect.Intersects( poly[ii], poly[(ii+1) % 4] ) )
            {
                return true;
            }
        }

        return false;

        }
    case PAD_SHAPE_ROUNDRECT:
        /* RoundRect intersection can be broken up into simple tests:
         * a) Test intersection of horizontal rect
         * b) Test intersection of vertical rect
         * c) Test intersection of each corner
         */


        r = GetRoundRectCornerRadius();

        /* Test A - intersection of horizontal rect */
        shapeRect.SetSize( 0, 0 );
        shapeRect.SetOrigin( shapePos );
        shapeRect.Inflate( m_Size.x / 2, m_Size.y / 2 - r );

        // Short-circuit test for zero width or height
        if( shapeRect.GetWidth() > 0 && shapeRect.GetHeight() > 0 &&
            arect.Intersects( shapeRect, m_Orient ) )
        {
            return true;
        }

        /* Test B - intersection of vertical rect */
        shapeRect.SetSize( 0, 0 );
        shapeRect.SetOrigin( shapePos );
        shapeRect.Inflate( m_Size.x / 2 - r, m_Size.y / 2 );

        // Short-circuit test for zero width or height
        if( shapeRect.GetWidth() > 0 && shapeRect.GetHeight() > 0 &&
            arect.Intersects( shapeRect, m_Orient ) )
        {
            return true;
        }

        /* Test C - intersection of each corner */

        endCenter = wxPoint( m_Size.x / 2 - r, m_Size.y / 2 - r );
        RotatePoint( &endCenter, m_Orient );

        if( arect.IntersectsCircle( shapePos + endCenter, r ) ||
            arect.IntersectsCircle( shapePos - endCenter, r ) )
        {
            return true;
        }

        endCenter = wxPoint( m_Size.x / 2 - r, -m_Size.y / 2 + r );
        RotatePoint( &endCenter, m_Orient );

        if( arect.IntersectsCircle( shapePos + endCenter, r ) ||
            arect.IntersectsCircle( shapePos - endCenter, r ) )
        {
            return true;
        }

        break;
    default:
        break;
    }

    return false;
}