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