void WinEDA_BasePcbFrame::Rotate_Module(wxDC * DC, MODULE * module, int angle, bool incremental) /***********************************************************************/ /* Fait tourner l'empreinte de angle degres, dans le sens < 0. Si incremental == TRUE, la rotation est faite a partir de la derniere orientation, sinon le module est mis dans l'orientation absolue angle. Si DC == NULL, le composant n'est pas redessine. Sinon, il est efface, tourne et redessine */ { if ( module == NULL ) return; m_CurrentScreen->SetModify(); /* efface ancienne position */ if( !(module->m_Flags & IS_MOVED) ) /* Rotation simple */ { if ( DC ) { module->Draw(DrawPanel, DC, wxPoint(0,0), GR_XOR); /* Reaffichage chevelu general si necessaire */ if(g_Show_Ratsnest) DrawGeneralRatsnest(DC); } } else { /* reaffiche module en mouvement */ if ( DC ) { DrawModuleOutlines(DrawPanel, DC, module); Dessine_Segments_Dragges(DrawPanel, DC); } } m_Pcb->m_Status_Pcb &= ~(LISTE_CHEVELU_OK | CONNEXION_OK); if ( incremental ) module->SetOrientation(module->m_Orient + angle); else module->SetOrientation(angle); module->Display_Infos(this); if ( DC ) { if( !(module->m_Flags & IS_MOVED) ) /* Rotation simple */ { module->Draw(DrawPanel, DC, wxPoint(0,0), GR_OR); /* Reaffichage chevelu general si necessaire */ ReCompile_Ratsnest_After_Changes( DC ); } else { /* reaffiche module en mouvement */ DrawModuleOutlines(DrawPanel, DC, module); Dessine_Segments_Dragges(DrawPanel, DC); } } }
void Montre_Position_Empreinte(WinEDA_DrawPanel * panel, wxDC * DC, bool erase) /**********************************************************************************/ /* redessin du contour de l'empreinte lors des deplacements de la souris */ { MODULE * module = (MODULE *) panel->m_Parent->m_CurrentScreen->m_CurrentItem; if ( module == NULL ) return; /* efface ancienne position */ if( erase ) { DrawModuleOutlines(panel, DC, module); } /* Redessine le module a la nouvelle place */ g_Offset_Module.x = module->m_Pos.x - panel->m_Parent->m_CurrentScreen->m_Curseur.x; g_Offset_Module.y = module->m_Pos.y - panel->m_Parent->m_CurrentScreen->m_Curseur.y; DrawModuleOutlines(panel, DC, module); Dessine_Segments_Dragges(panel, DC); }
static void drawPickedItems( EDA_DRAW_PANEL* aPanel, wxDC* aDC, wxPoint aOffset ) { PICKED_ITEMS_LIST* itemsList = &aPanel->GetScreen()->m_BlockLocate.m_ItemsSelection; PCB_BASE_FRAME* frame = (PCB_BASE_FRAME*) aPanel->GetParent(); g_Offset_Module = -aOffset; for( unsigned ii = 0; ii < itemsList->GetCount(); ii++ ) { BOARD_ITEM* item = (BOARD_ITEM*) itemsList->GetPickedItem( ii ); switch( item->Type() ) { case PCB_MODULE_T: frame->GetBoard()->m_Status_Pcb &= ~RATSNEST_ITEM_LOCAL_OK; DrawModuleOutlines( aPanel, aDC, (MODULE*) item ); break; case PCB_LINE_T: case PCB_TEXT_T: case PCB_TRACE_T: case PCB_VIA_T: case PCB_TARGET_T: case PCB_DIMENSION_T: // Currently markers are not affected by block commands case PCB_MARKER_T: item->Draw( aPanel, aDC, GR_XOR, aOffset ); break; case PCB_ZONE_AREA_T: item->Draw( aPanel, aDC, GR_XOR, aOffset ); ((ZONE_CONTAINER*) item)->DrawFilledArea( aPanel, aDC, GR_XOR, aOffset ); break; default: break; } } g_Offset_Module = wxPoint( 0, 0 ); }
int getOptimalModulePlacement( PCB_EDIT_FRAME* aFrame, MODULE* aModule, wxDC* aDC ) { int error = 1; wxPoint LastPosOK; double min_cost, curr_cost, Score; bool TstOtherSide; bool showRats = g_Show_Module_Ratsnest; BOARD* brd = aFrame->GetBoard(); aModule->CalculateBoundingBox(); g_Show_Module_Ratsnest = false; brd->m_Status_Pcb &= ~RATSNEST_ITEM_LOCAL_OK; aFrame->SetMsgPanel( aModule ); LastPosOK = RoutingMatrix.m_BrdBox.GetOrigin(); wxPoint mod_pos = aModule->GetPosition(); EDA_RECT fpBBox = aModule->GetFootprintRect(); // Move fpBBox to have the footprint position at (0,0) fpBBox.Move( -mod_pos ); wxPoint fpBBoxOrg = fpBBox.GetOrigin(); // Calculate the limit of the footprint position, relative // to the routing matrix area wxPoint xylimit = RoutingMatrix.m_BrdBox.GetEnd() - fpBBox.GetEnd(); wxPoint initialPos = RoutingMatrix.m_BrdBox.GetOrigin() - fpBBoxOrg; // Stay on grid. initialPos.x -= initialPos.x % RoutingMatrix.m_GridRouting; initialPos.y -= initialPos.y % RoutingMatrix.m_GridRouting; CurrPosition = initialPos; // Undraw the current footprint g_Offset_Module = wxPoint( 0, 0 ); DrawModuleOutlines( aFrame->GetCanvas(), aDC, aModule ); g_Offset_Module = mod_pos - CurrPosition; /* Examine pads, and set TstOtherSide to true if a footprint * has at least 1 pad through. */ TstOtherSide = false; if( RoutingMatrix.m_RoutingLayersCount > 1 ) { D_PAD* Pad; int otherLayerMask = LAYER_BACK; if( aModule->GetLayer() == LAYER_N_BACK ) otherLayerMask = LAYER_FRONT; for( Pad = aModule->Pads(); Pad != NULL; Pad = Pad->Next() ) { if( ( Pad->GetLayerMask() & otherLayerMask ) == 0 ) continue; TstOtherSide = true; break; } } // Draw the initial bounding box position EDA_COLOR_T color = BROWN; fpBBox.SetOrigin( fpBBoxOrg + CurrPosition ); draw_FootprintRect(aFrame->GetCanvas()->GetClipBox(), aDC, fpBBox, color); min_cost = -1.0; aFrame->SetStatusText( wxT( "Score ??, pos ??" ) ); for( ; CurrPosition.x < xylimit.x; CurrPosition.x += RoutingMatrix.m_GridRouting ) { wxYield(); if( aFrame->GetCanvas()->GetAbortRequest() ) { if( IsOK( aFrame, _( "OK to abort?" ) ) ) return ESC; else aFrame->GetCanvas()->SetAbortRequest( false ); } CurrPosition.y = initialPos.y; for( ; CurrPosition.y < xylimit.y; CurrPosition.y += RoutingMatrix.m_GridRouting ) { // Erase traces. draw_FootprintRect( aFrame->GetCanvas()->GetClipBox(), aDC, fpBBox, color ); fpBBox.SetOrigin( fpBBoxOrg + CurrPosition ); g_Offset_Module = mod_pos - CurrPosition; int keepOutCost = TstModuleOnBoard( brd, aModule, TstOtherSide ); // Draw at new place color = keepOutCost >= 0 ? BROWN : RED; draw_FootprintRect( aFrame->GetCanvas()->GetClipBox(), aDC, fpBBox, color ); if( keepOutCost >= 0 ) // i.e. if the module can be put here { error = 0; aFrame->build_ratsnest_module( aModule ); curr_cost = compute_Ratsnest_PlaceModule( brd ); Score = curr_cost + keepOutCost; if( (min_cost >= Score ) || (min_cost < 0 ) ) { LastPosOK = CurrPosition; min_cost = Score; wxString msg; msg.Printf( wxT( "Score %g, pos %s, %s" ), min_cost, GetChars( ::CoordinateToString( LastPosOK.x ) ), GetChars( ::CoordinateToString( LastPosOK.y ) ) ); aFrame->SetStatusText( msg ); } } } } // erasing the last traces GRRect( aFrame->GetCanvas()->GetClipBox(), aDC, fpBBox, 0, BROWN ); g_Show_Module_Ratsnest = showRats; // Regeneration of the modified variable. CurrPosition = LastPosOK; brd->m_Status_Pcb &= ~( RATSNEST_ITEM_LOCAL_OK | LISTE_PAD_OK ); MinCout = min_cost; return error; }
void WinEDA_BasePcbFrame::Change_Side_Module(MODULE * Module, wxDC * DC) /**********************************************************************/ /* Change de cote un composant : il y a inversion MIROIR autour de l'axe X Le changement n'est fait que si la couche est - CUIVRE ou CMP Si DC == NULL, il n'y a pas de redessin du composant et du chevelu */ { D_PAD* pt_pad ; TEXTE_MODULE* pt_texte; EDGE_MODULE * pt_edgmod ; EDA_BaseStruct * PtStruct; if ( Module == NULL ) return; if( (Module->m_Layer != CMP_N) && (Module->m_Layer != CUIVRE_N) ) return; m_CurrentScreen->SetModify(); if ( ! (Module->m_Flags & IS_MOVED) ) { m_Pcb->m_Status_Pcb &= ~( LISTE_CHEVELU_OK | CONNEXION_OK); if ( DC ) Module->Draw(DrawPanel, DC, wxPoint(0,0), GR_XOR); /* Effacement chevelu general si necessaire */ if ( DC && g_Show_Ratsnest) DrawGeneralRatsnest(DC); /* Init des variables utilisees dans la routine Dessine_Drag_segment() */ g_Offset_Module.x = 0; g_Offset_Module.y = 0; } else // Module en deplacement { /* efface empreinte ( vue en contours) si elle a ete deja dessinee */ if ( DC ) { DrawModuleOutlines(DrawPanel, DC, Module); Dessine_Segments_Dragges(DrawPanel, DC); } } /* mise a jour du Flag de l'empreinte et des couches des contours et textes */ Module->m_Layer = ChangeSideNumLayer(Module->m_Layer); /* Inversion miroir de l'orientation */ Module->m_Orient = - Module->m_Orient; NORMALIZE_ANGLE_POS(Module->m_Orient); /* Inversion miroir + layers des pastilles */ pt_pad = Module->m_Pads; for ( ; pt_pad != NULL; pt_pad = (D_PAD*) pt_pad->Pnext ) { pt_pad->m_Pos.y -= Module->m_Pos.y ; pt_pad->m_Pos.y = -pt_pad->m_Pos.y; pt_pad->m_Pos.y += Module->m_Pos.y; pt_pad->m_Pos0.y = - pt_pad->m_Pos0.y; pt_pad->m_Offset.y = -pt_pad->m_Offset.y; pt_pad->m_DeltaSize.y = -pt_pad->m_DeltaSize.y; NEGATE_AND_NORMALIZE_ANGLE_POS(pt_pad->m_Orient); /* change cote pour pastilles surfaciques */ pt_pad->m_Masque_Layer = ChangeSideMaskLayer(pt_pad->m_Masque_Layer); } /* Inversion miroir de la Reference et mise en miroir : */ pt_texte = Module->m_Reference; pt_texte->m_Pos.y -= Module->m_Pos.y; pt_texte->m_Pos.y = -pt_texte->m_Pos.y; pt_texte->m_Pos.y += Module->m_Pos.y; pt_texte->m_Pos0.y = pt_texte->m_Pos0.y; pt_texte->m_Miroir = 1 ; NEGATE_AND_NORMALIZE_ANGLE_POS(pt_texte->m_Orient); pt_texte->m_Layer = Module->m_Layer; pt_texte->m_Layer = ChangeSideNumLayer(pt_texte->m_Layer); if( Module->m_Layer == CUIVRE_N) pt_texte->m_Layer = SILKSCREEN_N_CU; if( Module->m_Layer == CMP_N) pt_texte->m_Layer = SILKSCREEN_N_CMP; if( (Module->m_Layer == SILKSCREEN_N_CU) || (Module->m_Layer == ADHESIVE_N_CU) || (Module->m_Layer == CUIVRE_N) ) pt_texte->m_Miroir = 0 ; /* Inversion miroir de la Valeur et mise en miroir : */ pt_texte = Module->m_Value; pt_texte->m_Pos.y -= Module->m_Pos.y; pt_texte->m_Pos.y = -pt_texte->m_Pos.y; pt_texte->m_Pos.y += Module->m_Pos.y; pt_texte->m_Pos0.y = pt_texte->m_Pos0.y; pt_texte->m_Miroir = 1 ; NEGATE_AND_NORMALIZE_ANGLE_POS(pt_texte->m_Orient); pt_texte->m_Layer = Module->m_Layer; pt_texte->m_Layer = ChangeSideNumLayer(pt_texte->m_Layer); if( Module->m_Layer == CUIVRE_N) pt_texte->m_Layer = SILKSCREEN_N_CU; if( Module->m_Layer == CMP_N) pt_texte->m_Layer = SILKSCREEN_N_CMP; if( (Module->m_Layer == SILKSCREEN_N_CU) || (Module->m_Layer == ADHESIVE_N_CU) || (Module->m_Layer == CUIVRE_N) ) pt_texte->m_Miroir = 0 ; /* Inversion miroir des dessins de l'empreinte : */ PtStruct = Module->m_Drawings; for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext) { switch( PtStruct->m_StructType) { case TYPEEDGEMODULE: pt_edgmod = (EDGE_MODULE *) PtStruct; pt_edgmod->m_Start.y -= Module->m_Pos.y; pt_edgmod->m_Start.y = -pt_edgmod->m_Start.y ; pt_edgmod->m_Start.y += Module->m_Pos.y; pt_edgmod->m_End.y -= Module->m_Pos.y; pt_edgmod->m_End.y = -pt_edgmod->m_End.y ; pt_edgmod->m_End.y += Module->m_Pos.y; /* inversion des coords locales */ pt_edgmod->m_Start0.y = -pt_edgmod->m_Start0.y; pt_edgmod->m_End0.y = -pt_edgmod->m_End0.y; if ( pt_edgmod->m_Shape == S_ARC ) { pt_edgmod->m_Angle = - pt_edgmod->m_Angle; } pt_edgmod->m_Layer = ChangeSideNumLayer(pt_edgmod->m_Layer); break; case TYPETEXTEMODULE: /* Inversion miroir de la position et mise en miroir : */ pt_texte = (TEXTE_MODULE*)PtStruct; pt_texte->m_Pos.y -= Module->m_Pos.y; pt_texte->m_Pos.y = -pt_texte->m_Pos.y; pt_texte->m_Pos.y += Module->m_Pos.y; pt_texte->m_Pos0.y = pt_texte->m_Pos0.y; pt_texte->m_Miroir = 1 ; NEGATE_AND_NORMALIZE_ANGLE_POS(pt_texte->m_Orient); pt_texte->m_Layer = Module->m_Layer; pt_texte->m_Layer = ChangeSideNumLayer(pt_texte->m_Layer); if( Module->m_Layer == CUIVRE_N) pt_texte->m_Layer = SILKSCREEN_N_CU; if(Module->m_Layer == CMP_N) pt_texte->m_Layer = SILKSCREEN_N_CMP; if((Module->m_Layer == SILKSCREEN_N_CU) || (Module->m_Layer == ADHESIVE_N_CU) || (Module->m_Layer == CUIVRE_N)) pt_texte->m_Miroir = 0 ; break; default: DisplayError(this, wxT("Unknown Draw Type")); break; } } /* calcul du rectangle d'encadrement */ Module->Set_Rectangle_Encadrement(); Module->Display_Infos(this); if( !(Module->m_Flags & IS_MOVED) ) /* Inversion simple */ { if ( DC ) { Module->Draw(DrawPanel, DC, wxPoint(0,0), GR_OR); /* affichage chevelu general si necessaire */ ReCompile_Ratsnest_After_Changes( DC ); } } else { if ( DC ) { DrawModuleOutlines(DrawPanel, DC, Module); Dessine_Segments_Dragges(DrawPanel, DC); } m_Pcb->m_Status_Pcb &= ~CHEVELU_LOCAL_OK; } }
void Exit_Module(WinEDA_DrawFrame * frame, wxDC *DC) /***************************************************/ /* fonction de sortie de l'application */ { DRAG_SEGM * pt_drag; TRACK * pt_segm; MODULE * module; WinEDA_BasePcbFrame * pcbframe = (WinEDA_BasePcbFrame*)frame; module = (MODULE *) frame->m_CurrentScreen->m_CurrentItem; pcbframe->m_Pcb->m_Status_Pcb &= ~CHEVELU_LOCAL_OK; if (module) { // effacement module a l'ecran: DrawModuleOutlines(frame->DrawPanel, DC, module); /* restitution de l'empreinte si move ou effacement copie*/ if (module->m_Flags & IS_MOVED ) { /* Move en cours : remise a l'etat d'origine */ if( g_Drag_Pistes_On) { /* Effacement des segments dragges */ pt_drag = g_DragSegmentList; for( ; pt_drag != NULL; pt_drag = pt_drag->Pnext) { pt_segm = pt_drag->m_Segm; pt_segm->Draw(frame->DrawPanel, DC, GR_XOR); } } /* Remise en etat d'origine des segments dragges */ pt_drag = g_DragSegmentList; for( ; pt_drag != NULL; pt_drag = pt_drag->Pnext) { pt_segm = pt_drag->m_Segm; pt_segm->SetState(EDIT,OFF); pt_drag->SetInitialValues(); pt_segm->Draw(frame->DrawPanel, DC, GR_OR); } EraseDragListe(); module->m_Flags = 0; } if (module->m_Flags & IS_NEW ) { DeleteStructure(module); module = NULL; pcbframe->m_Pcb->m_Status_Pcb = 0 ; pcbframe->build_liste_pads() ; } } /* Reaffichage du module a l'ecran */ if ( module ) { if ( ModuleInitOrient != module->m_Orient ) pcbframe->Rotate_Module(NULL,module, ModuleInitOrient, FALSE); if( ModuleInitLayer != module->m_Layer ) pcbframe->Change_Side_Module(module, NULL); module->Draw(frame->DrawPanel, DC, wxPoint(0,0), GR_OR); } g_Drag_Pistes_On = FALSE; frame->m_CurrentScreen->ManageCurseur = NULL; frame->m_CurrentScreen->ForceCloseManageCurseur = NULL; frame->m_CurrentScreen->m_CurrentItem = NULL; }