/* 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(); } }
/* 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; } } }