/* Place module on Routing matrix.
 */
void genModuleOnRoutingMatrix( MODULE* Module )
{
    int         ox, oy, fx, fy;
    int         layerMask;
    D_PAD*      Pad;

    EDA_RECT    fpBBox = Module->GetBoundingBox();

    fpBBox.Inflate( RoutingMatrix.m_GridRouting / 2 );
    ox  = fpBBox.GetX();
    fx  = fpBBox.GetRight();
    oy  = fpBBox.GetY();
    fy  = fpBBox.GetBottom();

    if( ox < RoutingMatrix.m_BrdBox.GetX() )
        ox = RoutingMatrix.m_BrdBox.GetX();

    if( ox > RoutingMatrix.m_BrdBox.GetRight() )
        ox = RoutingMatrix.m_BrdBox.GetRight();

    if( fx < RoutingMatrix.m_BrdBox.GetX() )
        fx = RoutingMatrix.m_BrdBox.GetX();

    if( fx > RoutingMatrix.m_BrdBox.GetRight() )
        fx = RoutingMatrix.m_BrdBox.GetRight();

    if( oy < RoutingMatrix.m_BrdBox.GetY() )
        oy = RoutingMatrix.m_BrdBox.GetY();

    if( oy > RoutingMatrix.m_BrdBox.GetBottom() )
        oy = RoutingMatrix.m_BrdBox.GetBottom();

    if( fy < RoutingMatrix.m_BrdBox.GetY() )
        fy = RoutingMatrix.m_BrdBox.GetY();

    if( fy > RoutingMatrix.m_BrdBox.GetBottom() )
        fy = RoutingMatrix.m_BrdBox.GetBottom();

    layerMask = 0;

    if( Module->GetLayer() == LAYER_N_FRONT )
        layerMask = LAYER_FRONT;

    if( Module->GetLayer() == LAYER_N_BACK )
        layerMask = LAYER_BACK;

    TraceFilledRectangle( ox, oy, fx, fy, layerMask,
                          CELL_is_MODULE, WRITE_OR_CELL );

    // Trace pads + clearance areas.
    for( Pad = Module->Pads(); Pad != NULL; Pad = Pad->Next() )
    {
        int margin = (RoutingMatrix.m_GridRouting / 2) + Pad->GetClearance();
        ::PlacePad( Pad, CELL_is_MODULE, margin, WRITE_OR_CELL );
    }

    // Trace clearance.
    int margin = ( RoutingMatrix.m_GridRouting * Module->GetPadCount() ) / GAIN;
    CreateKeepOutRectangle( ox, oy, fx, fy, margin, KEEP_OUT_MARGIN, layerMask );
}
예제 #2
0
void PlacePad( D_PAD* aPad, int color, int marge, int op_logic )
{
    int     dx, dy;
    wxPoint shape_pos = aPad->ShapePos();

    dx = aPad->GetSize().x / 2;
    dx += marge;

    if( aPad->GetShape() == PAD_CIRCLE )
    {
        TraceFilledCircle( shape_pos.x, shape_pos.y, dx,
                           aPad->GetLayerSet(), color, op_logic );
        return;
    }

    dy = aPad->GetSize().y / 2;
    dy += marge;

    if( aPad->GetShape() == PAD_TRAPEZOID )
    {
        dx += abs( aPad->GetDelta().y ) / 2;
        dy += abs( aPad->GetDelta().x ) / 2;
    }

    // The pad is a rectangle ( horizontal or vertical )
    if( int( aPad->GetOrientation() ) % 900 == 0 )
    {
        // Orientation turned 90 deg.
        if( aPad->GetOrientation() == 900  ||  aPad->GetOrientation() == 2700 )
        {
            EXCHG( dx, dy );
        }

        TraceFilledRectangle( shape_pos.x - dx, shape_pos.y - dy,
                              shape_pos.x + dx, shape_pos.y + dy,
                              aPad->GetLayerSet(), color, op_logic );
    }
    else
    {
        TraceFilledRectangle( shape_pos.x - dx, shape_pos.y - dy,
                              shape_pos.x + dx, shape_pos.y + dy,
                              aPad->GetOrientation(),
                              aPad->GetLayerSet(), color, op_logic );
    }
}
예제 #3
0
/* Initialise les cellules du board a la valeur HOLE et VIA_IMPOSSIBLE
	selon les marges d'isolement
	les elements de net_code = net_code ne seront pas places comme occupe
	mais en VIA_IMPOSSIBLE uniquement
	Pour Routage 1 seule face:
		le plan BOTTOM est utilise
		et Route_Layer_BOTTOM = Route_Layer_TOP

	Selon les bits = 1 du parametre flag:
		si FORCE_PADS : tous les pads seront places meme ceux de meme net_code
*/
void PlaceCells(BOARD * Pcb, int net_code, int flag)
{
int ii;
LISTE_PAD* ptr;
TRACK * pt_segm;
TEXTE_PCB * PtText;
DRAWSEGMENT * DrawSegm;
EDA_BaseStruct * PtStruct;
int ux0 = 0 , uy0 = 0, ux1, uy1, dx, dy;
int marge, via_marge;
int masque_layer;

	marge = g_DesignSettings.m_TrackClearence + (g_DesignSettings.m_CurrentTrackWidth /2);
	via_marge = g_DesignSettings.m_TrackClearence + (g_DesignSettings.m_CurrentViaSize /2);

	/////////////////////////////////////
	// Placement des PADS sur le board //
	/////////////////////////////////////
	ptr = (LISTE_PAD*)Pcb->m_Pads; ii = Pcb->m_NbPads;
	for( ; ii > 0 ; ii-- , ptr++)
		{
		if( (net_code != (*ptr)->m_NetCode ) || (flag & FORCE_PADS) )
			{
			Place_1_Pad_Board(Pcb, *ptr, HOLE, marge, WRITE_CELL);
			}
		Place_1_Pad_Board(Pcb, *ptr, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL);
		}

	///////////////////////////////////////////////
	// Placement des elements de modules sur PCB //
	///////////////////////////////////////////////
	PtStruct = Pcb->m_Modules;
	for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
		{
		EDA_BaseStruct * PtModStruct = ((MODULE*)PtStruct)->m_Drawings;
		for( ;PtModStruct != NULL; PtModStruct = PtModStruct->Pnext )
			{
			switch( PtModStruct->m_StructType )
				{
				case TYPEEDGEMODULE:
					{
					TRACK * TmpSegm = new TRACK(NULL);
					TmpSegm->m_Layer = ((EDGE_MODULE *) PtModStruct)->m_Layer;
					if(TmpSegm->m_Layer == EDGE_N) TmpSegm->m_Layer = -1;

					TmpSegm->m_Start = ((EDGE_MODULE *) PtModStruct)->m_Start;
					TmpSegm->m_End = ((EDGE_MODULE *) PtModStruct)->m_End;
					TmpSegm->m_Shape = ((EDGE_MODULE *) PtModStruct)->m_Shape;
					TmpSegm->m_Width = ((EDGE_MODULE *) PtModStruct)->m_Width;
					TmpSegm->m_Param = ((EDGE_MODULE *) PtModStruct)->m_Angle;
					TmpSegm->m_NetCode = -1;

					TraceSegmentPcb(Pcb, TmpSegm, HOLE, marge,WRITE_CELL );
					TraceSegmentPcb(Pcb, TmpSegm, VIA_IMPOSSIBLE, via_marge,
									WRITE_OR_CELL );
					delete TmpSegm;
					break;
					}

				default: break;
				}
			}
		}

	////////////////////////////////////////////
	// Placement des contours et segments PCB //
	////////////////////////////////////////////
	PtStruct = Pcb->m_Drawings;
	for( ; PtStruct != NULL; PtStruct = PtStruct->Pnext )
		{
		switch( PtStruct->m_StructType)
			{
			case TYPEDRAWSEGMENT:
				{
				int type_cell = HOLE;
				TRACK * TmpSegm = new TRACK(NULL);
				DrawSegm = (DRAWSEGMENT *) PtStruct;
				TmpSegm->m_Layer = DrawSegm->m_Layer;
				if(DrawSegm->m_Layer == EDGE_N)
					{
					TmpSegm->m_Layer = -1;
					type_cell |= CELL_is_EDGE;
					}

				TmpSegm->m_Start = DrawSegm->m_Start;
				TmpSegm->m_End = DrawSegm->m_End;
				TmpSegm->m_Shape = DrawSegm->m_Shape;
				TmpSegm->m_Width = DrawSegm->m_Width;
				TmpSegm->m_Param = DrawSegm->m_Angle;
				TmpSegm->m_NetCode = -1;

				TraceSegmentPcb(Pcb, TmpSegm, type_cell, marge,WRITE_CELL );
//				TraceSegmentPcb(Pcb, TmpSegm, VIA_IMPOSSIBLE, via_marge,WRITE_OR_CELL );
				delete TmpSegm;
				break;
				}

			case TYPETEXTE:
				PtText = (TEXTE_PCB*) PtStruct;
				if(PtText->GetLength() == 0 ) break;
				ux0 = PtText->m_Pos.x; uy0 = PtText->m_Pos.y;

				dx = PtText->Pitch()* PtText->GetLength();
				dy = PtText->m_Size.y + PtText->m_Width;

				/* Calcul du rectangle d'encadrement */
				dx /= 2; dy /= 2; /* dx et dy = demi dimensionx X et Y */
				ux1 = ux0 + dx; uy1 = uy0 + dy;
				ux0 -= dx; uy0 -= dy;

				masque_layer = g_TabOneLayerMask[PtText->m_Layer];

				TraceFilledRectangle(Pcb, ux0-marge, uy0-marge, ux1+marge, uy1+marge,
								(int)(PtText->m_Orient),
								masque_layer, HOLE, WRITE_CELL);
				TraceFilledRectangle(Pcb, ux0-via_marge, uy0-via_marge,
								ux1+via_marge, uy1+via_marge,
								(int)(PtText->m_Orient),
								masque_layer, VIA_IMPOSSIBLE, WRITE_OR_CELL);
				break;

			default: break;
			}
		}

	/* Placement des PISTES */
	pt_segm = Pcb->m_Track;
	for( ; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext)
		{
		if(net_code == pt_segm->m_NetCode) continue;
		TraceSegmentPcb(Pcb, pt_segm, HOLE, marge, WRITE_CELL );
		TraceSegmentPcb(Pcb, pt_segm, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL );
		}

	/* Placement des ZONES */
	pt_segm = (TRACK*) Pcb->m_Zone;
	for( ; pt_segm != NULL; pt_segm = (TRACK*) pt_segm->Pnext)
		{
		if(net_code == pt_segm->m_NetCode) continue;
		TraceSegmentPcb(Pcb, pt_segm, HOLE, marge, WRITE_CELL );
		TraceSegmentPcb(Pcb, pt_segm, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL );
		}
}
예제 #4
0
/**
 * Function PlaceCells
 * Initialize the matrix routing by setting obstacles for each occupied cell
 * a cell set to HOLE is an obstacle for tracks and vias
 * a cell set to VIA_IMPOSSIBLE is an obstacle for vias only.
 * a cell set to CELL_is_EDGE is a frontier.
 * Tracks and vias having the same net code as net_code are skipped
 * (htey do not are obstacles)
 *
 * For single-sided Routing 1:
 * BOTTOM side is used, and Route_Layer_BOTTOM = Route_Layer_TOP
 *
 * If flag == FORCE_PADS: all pads will be put in matrix as obstacles.
 */
void PlaceCells( BOARD* aPcb, int net_code, int flag )
{
    int       ux0 = 0, uy0 = 0, ux1, uy1, dx, dy;
    int       marge, via_marge;
    LAYER_MSK layerMask;

    // use the default NETCLASS?
    NETCLASS* nc = aPcb->m_NetClasses.GetDefault();

    int       trackWidth = nc->GetTrackWidth();
    int       clearance  = nc->GetClearance();
    int       viaSize    = nc->GetViaDiameter();

    marge     = clearance + (trackWidth / 2);
    via_marge = clearance + (viaSize / 2);

    // Place PADS on matrix routing:
    for( unsigned i = 0; i < aPcb->GetPadCount(); ++i )
    {
        D_PAD* pad = aPcb->GetPad( i );

        if( net_code != pad->GetNet() || (flag & FORCE_PADS) )
        {
            ::PlacePad( pad, HOLE, marge, WRITE_CELL );
        }

        ::PlacePad( pad, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL );
    }

    // Place outlines of modules on matrix routing, if they are on a copper layer
    // or on the edge layer
    TRACK tmpSegm( NULL );  // A dummy track used to create segments.

    for( MODULE* module = aPcb->m_Modules; module; module = module->Next() )
    {
        for( BOARD_ITEM* item = module->GraphicalItems(); item; item = item->Next() )
        {
            switch( item->Type() )
            {
            case PCB_MODULE_EDGE_T:
            {
                EDGE_MODULE* edge = (EDGE_MODULE*) item;

                tmpSegm.SetLayer( edge->GetLayer() );

                if( tmpSegm.GetLayer() == EDGE_N )
                    tmpSegm.SetLayer( UNDEFINED_LAYER );

                tmpSegm.SetStart( edge->GetStart() );
                tmpSegm.SetEnd(   edge->GetEnd() );
                tmpSegm.SetShape( edge->GetShape() );
                tmpSegm.SetWidth( edge->GetWidth() );
                tmpSegm.m_Param = edge->GetAngle();
                tmpSegm.SetNet( -1 );

                TraceSegmentPcb( &tmpSegm, HOLE, marge, WRITE_CELL );
                TraceSegmentPcb( &tmpSegm, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL );
            }
            break;

            default:
                break;
            }
        }
    }

    // Place board outlines and texts on copper layers:
    for( BOARD_ITEM* item = aPcb->m_Drawings; item; item = item->Next() )
    {
        switch( item->Type() )
        {
        case PCB_LINE_T:
        {
            DRAWSEGMENT* DrawSegm;

            int          type_cell = HOLE;
            DrawSegm = (DRAWSEGMENT*) item;
            tmpSegm.SetLayer( DrawSegm->GetLayer() );

            if( DrawSegm->GetLayer() == EDGE_N )
            {
                tmpSegm.SetLayer( UNDEFINED_LAYER );
                type_cell |= CELL_is_EDGE;
            }

            tmpSegm.SetStart( DrawSegm->GetStart() );
            tmpSegm.SetEnd(   DrawSegm->GetEnd() );
            tmpSegm.SetShape( DrawSegm->GetShape() );
            tmpSegm.SetWidth( DrawSegm->GetWidth() );
            tmpSegm.m_Param = DrawSegm->GetAngle();
            tmpSegm.SetNet( -1 );

            TraceSegmentPcb( &tmpSegm, type_cell, marge, WRITE_CELL );
        }
        break;

        case PCB_TEXT_T:
        {
            TEXTE_PCB* PtText;
            PtText = (TEXTE_PCB*) item;

            if( PtText->GetText().Length() == 0 )
                break;

            EDA_RECT textbox = PtText->GetTextBox( -1 );
            ux0 = textbox.GetX();
            uy0 = textbox.GetY();
            dx  = textbox.GetWidth();
            dy  = textbox.GetHeight();

            /* Put bounding box (rectangle) on matrix */
            dx /= 2;
            dy /= 2;

            ux1 = ux0 + dx;
            uy1 = uy0 + dy;

            ux0 -= dx;
            uy0 -= dy;

            layerMask = GetLayerMask( PtText->GetLayer() );

            TraceFilledRectangle( ux0 - marge, uy0 - marge, ux1 + marge,
                                  uy1 + marge, PtText->GetOrientation(),
                                  layerMask, HOLE, WRITE_CELL );

            TraceFilledRectangle( ux0 - via_marge, uy0 - via_marge,
                                  ux1 + via_marge, uy1 + via_marge,
                                  PtText->GetOrientation(),
                                  layerMask, VIA_IMPOSSIBLE, WRITE_OR_CELL );
        }
        break;

        default:
            break;
        }
    }

    /* Put tracks and vias on matrix */
    for( TRACK* track = aPcb->m_Track; track; track = track->Next() )
    {
        if( net_code == track->GetNet() )
            continue;

        TraceSegmentPcb( track, HOLE, marge, WRITE_CELL );
        TraceSegmentPcb( track, VIA_IMPOSSIBLE, via_marge, WRITE_OR_CELL );
    }
}