Example #1
0
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);
		}
	}
}
Example #2
0
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);
}
Example #3
0
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;
}
Example #5
0
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;
	}
}
Example #6
0
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;
}