/* Move marked items, at new position = old position + offset
 */
void MoveMarkedItems( MODULE* module, wxPoint offset )
{
    EDA_ITEM* item;

    if( module == NULL )
        return;

    if( module->Reference().IsSelected() )
        module->Reference().Move( offset );

    if( module->Value().IsSelected() )
        module->Value().Move( offset );

    D_PAD* pad = module->Pads();

    for( ; pad != NULL; pad = pad->Next() )
    {
        if( !pad->IsSelected() )
            continue;

        pad->SetPosition( pad->GetPosition() + offset );
        pad->SetPos0( pad->GetPos0() + offset );
    }

    item = module->GraphicalItems();

    for( ; item != NULL; item = item->Next() )
    {
        if( !item->IsSelected() )
            continue;

        switch( item->Type() )
        {
        case PCB_MODULE_TEXT_T:
            static_cast<TEXTE_MODULE*>( item )->Move( offset );
            break;

        case PCB_MODULE_EDGE_T:
        {
            EDGE_MODULE* em = (EDGE_MODULE*) item;
            em->SetStart( em->GetStart() + offset );
            em->SetEnd( em->GetEnd() + offset );
            em->SetStart0( em->GetStart0() + offset );
            em->SetEnd0( em->GetEnd0() + offset );
        }
        break;

        default:
            ;
        }
    }

    ClearMarkItems( module );
}
/* Move marked items, at new position = old position + offset
 */
void MoveMarkedItems( MODULE* module, wxPoint offset )
{
    EDA_ITEM* item;

    if( module == NULL )
        return;

    D_PAD* pad = module->Pads();

    for( ; pad != NULL; pad = pad->Next() )
    {
        if( !pad->IsSelected() )
            continue;

        pad->SetPosition( pad->GetPosition() + offset );
        pad->SetPos0( pad->GetPos0() + offset );
    }

    item = module->GraphicalItems();

    for( ; item != NULL; item = item->Next() )
    {
        if( !item->IsSelected() )
            continue;

        switch( item->Type() )
        {
        case PCB_MODULE_TEXT_T:
        {
            TEXTE_MODULE* tm = (TEXTE_MODULE*) item;
            tm->Offset( offset );
            tm->SetPos0( tm->GetPos0() + offset );
        }
        break;

        case PCB_MODULE_EDGE_T:
        {
            EDGE_MODULE* em = (EDGE_MODULE*) item;
            em->SetStart( em->GetStart() + offset );
            em->SetEnd( em->GetEnd() + offset );
            em->SetStart0( em->GetStart0() + offset );
            em->SetEnd0( em->GetEnd0() + offset );
        }
        break;

        default:
            ;
        }

        item->ClearFlags();
    }
}
/** Mirror marked items, refer to a Vertical axis at position offset
 * Note: because this function is used in global transform,
 * if force_all is true, all items will be mirrored
 */
void MirrorMarkedItems( MODULE* module, wxPoint offset, bool force_all )
{
#define SETMIRROR( z ) (z) -= offset.x; (z) = -(z); (z) += offset.x;
    wxPoint     tmp;
    wxSize      tmpz;

    if( module == NULL )
        return;

    for( D_PAD* pad = module->Pads();  pad;  pad = pad->Next() )
    {
        // Skip pads not selected, i.e. not inside the block to mirror:
        if( !pad->IsSelected() && !force_all )
            continue;

        tmp = pad->GetPosition();
        SETMIRROR( tmp.x );
        pad->SetPosition( tmp );

        pad->SetX0( pad->GetPosition().x );

        tmp = pad->GetOffset();
        NEGATE( tmp.x );
        pad->SetOffset( tmp );

        tmpz = pad->GetDelta();
        NEGATE( tmpz.x );
        pad->SetDelta( tmpz );

        pad->SetOrientation( 1800 - pad->GetOrientation() );
    }

    for( EDA_ITEM* item = module->GraphicalItems();  item;  item = item->Next() )
    {
        // Skip items not selected, i.e. not inside the block to mirror:
        if( !item->IsSelected() && !force_all )
            continue;

        switch( item->Type() )
        {
        case PCB_MODULE_EDGE_T:
            {
                EDGE_MODULE* em = (EDGE_MODULE*) item;

                tmp = em->GetStart0();
                SETMIRROR( tmp.x );
                em->SetStart0( tmp );
                em->SetStartX( tmp.x );

                tmp = em->GetEnd0();
                SETMIRROR( tmp.x );
                em->SetEnd0( tmp );
                em->SetEndX( tmp.x );

                em->SetAngle( -em->GetAngle() );
            }
            break;

        case PCB_MODULE_TEXT_T:
            {
                TEXTE_MODULE* tm = (TEXTE_MODULE*) item;
                tmp = tm->GetTextPosition();
                SETMIRROR( tmp.x );
                tm->SetTextPosition( tmp );
                tmp.y = tm->GetPos0().y;
                tm->SetPos0( tmp );
            }
            break;

        default:
            break;
        }

        item->ClearFlags();
    }
}
Пример #4
0
/* Creates the shape of a footprint (section SHAPE)
 *  The shape is always given "normal" (Orient 0, not mirrored)
 * It's almost guaranteed that the silk layer will be imported wrong but
 * the shape also contains the pads!
 */
static void FootprintWriteShape( FILE* aFile, MODULE* module )
{
    EDGE_MODULE* PtEdge;
    EDA_ITEM*    PtStruct;

    // Control Y axis change sign for flipped modules
    int          Yaxis_sign = -1;

    // Flip for bottom side components
    if( module->GetFlag() )
        Yaxis_sign = 1;

    /* creates header: */
    fprintf( aFile, "\nSHAPE %s\n", TO_UTF8( module->GetReference() ) );

    if( module->GetAttributes() & MOD_VIRTUAL )
    {
        fprintf( aFile, "INSERT SMD\n" );
    }
    else
    {
        if( module->GetAttributes() & MOD_CMS )
        {
            fprintf( aFile, "INSERT SMD\n" );
        }
        else
        {
            fprintf( aFile, "INSERT TH\n" );
        }
    }

#if 0 /* ATTRIBUTE name and value is unspecified and the original exporter
       * got the syntax wrong, so CAM350 rejected the whole shape! */

    if( module->m_Attributs != MOD_DEFAULT )
    {
        fprintf( aFile, "ATTRIBUTE" );

        if( module->m_Attributs & MOD_CMS )
            fprintf( aFile, " PAD_SMD" );

        if( module->m_Attributs & MOD_VIRTUAL )
            fprintf( aFile, " VIRTUAL" );

        fprintf( aFile, "\n" );
    }
#endif

    // Silk outline; wildly interpreted by various importers:
    // CAM350 read it right but only closed shapes
    // ProntoPlace double-flip it (at least the pads are correct)
    // GerberTool usually get it right...
    for( PtStruct = module->GraphicalItems(); PtStruct; PtStruct = PtStruct->Next() )
    {
        switch( PtStruct->Type() )
        {
        case PCB_MODULE_TEXT_T:

            // If we wanted to export text, this is not the correct section
            break;

        case PCB_MODULE_EDGE_T:
            PtEdge = (EDGE_MODULE*) PtStruct;
            if( PtEdge->GetLayer() == F_SilkS
                || PtEdge->GetLayer() == B_SilkS )
            {
                switch( PtEdge->GetShape() )
                {
                case S_SEGMENT:
                    fprintf( aFile, "LINE %g %g %g %g\n",
                             (PtEdge->m_Start0.x) / SCALE_FACTOR,
                             (Yaxis_sign * PtEdge->m_Start0.y) / SCALE_FACTOR,
                             (PtEdge->m_End0.x) / SCALE_FACTOR,
                             (Yaxis_sign * PtEdge->m_End0.y ) / SCALE_FACTOR );
                    break;

                case S_CIRCLE:
                {
                    int radius = KiROUND( GetLineLength( PtEdge->m_End0,
                                                         PtEdge->m_Start0 ) );
                    fprintf( aFile, "CIRCLE %g %g %g\n",
                             PtEdge->m_Start0.x / SCALE_FACTOR,
                             Yaxis_sign * PtEdge->m_Start0.y / SCALE_FACTOR,
                             radius / SCALE_FACTOR );
                    break;
                }

                case S_ARC:
                {
                    int arcendx, arcendy;
                    arcendx = PtEdge->m_End0.x - PtEdge->m_Start0.x;
                    arcendy = PtEdge->m_End0.y - PtEdge->m_Start0.y;
                    RotatePoint( &arcendx, &arcendy, -PtEdge->GetAngle() );
                    arcendx += PtEdge->GetStart0().x;
                    arcendy += PtEdge->GetStart0().y;
                    if( Yaxis_sign == -1 )
                    {
                        // Flipping Y flips the arc direction too
                        fprintf( aFile, "ARC %g %g %g %g %g %g\n",
                                 (arcendx) / SCALE_FACTOR,
                                 (Yaxis_sign * arcendy) / SCALE_FACTOR,
                                 (PtEdge->m_End0.x) / SCALE_FACTOR,
                                 (Yaxis_sign * PtEdge->GetEnd0().y) / SCALE_FACTOR,
                                 (PtEdge->GetStart0().x) / SCALE_FACTOR,
                                 (Yaxis_sign * PtEdge->GetStart0().y) / SCALE_FACTOR );
                    }
                    else
                    {
                        fprintf( aFile, "ARC %g %g %g %g %g %g\n",
                                 (PtEdge->GetEnd0().x) / SCALE_FACTOR,
                                 (Yaxis_sign * PtEdge->GetEnd0().y) / SCALE_FACTOR,
                                 (arcendx) / SCALE_FACTOR,
                                 (Yaxis_sign * arcendy) / SCALE_FACTOR,
                                 (PtEdge->GetStart0().x) / SCALE_FACTOR,
                                 (Yaxis_sign * PtEdge->GetStart0().y) / SCALE_FACTOR );
                    }
                    break;
                }

                default:
                    DisplayError( NULL, wxT( "Type Edge Module invalid." ) );
                    break;
                }
            }
            break;

        default:
            break;
        }
    }
}