PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad ) { PNS_LAYERSET layers( 0, MAX_CU_LAYERS - 1 ); // ignore non-copper pads if ( (aPad->GetLayerSet() & LSET::AllCuMask()).none() ) return NULL; switch( aPad->GetAttribute() ) { case PAD_ATTRIB_STANDARD: break; case PAD_ATTRIB_SMD: case PAD_ATTRIB_HOLE_NOT_PLATED: case PAD_ATTRIB_CONN: { LSET lmsk = aPad->GetLayerSet(); bool is_copper = false; for( int i = 0; i < MAX_CU_LAYERS; i++ ) { if( lmsk[i] ) { is_copper = true; if( aPad->GetAttribute() != PAD_ATTRIB_HOLE_NOT_PLATED ) layers = PNS_LAYERSET( i ); break; } } if( !is_copper ) return NULL; } break; default: TRACE( 0, "unsupported pad type 0x%x", aPad->GetAttribute() ); return NULL; } PNS_SOLID* solid = new PNS_SOLID; solid->SetLayers( layers ); solid->SetNet( aPad->GetNetCode() ); solid->SetParent( aPad ); wxPoint wx_c = aPad->ShapePos(); wxSize wx_sz = aPad->GetSize(); wxPoint offset = aPad->GetOffset(); VECTOR2I c( wx_c.x, wx_c.y ); VECTOR2I sz( wx_sz.x, wx_sz.y ); RotatePoint( &offset, aPad->GetOrientation() ); solid->SetPos( VECTOR2I( c.x - offset.x, c.y - offset.y ) ); solid->SetOffset ( VECTOR2I ( offset.x, offset.y ) ); double orient = aPad->GetOrientation() / 10.0; if( aPad->GetShape() == PAD_SHAPE_CIRCLE ) { solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) ); } else { if( orient == 0.0 || orient == 90.0 || orient == 180.0 || orient == 270.0 ) { if( orient == 90.0 || orient == 270.0 ) sz = VECTOR2I( sz.y, sz.x ); switch( aPad->GetShape() ) { case PAD_SHAPE_OVAL: if( sz.x == sz.y ) solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) ); else { VECTOR2I delta; if( sz.x > sz.y ) delta = VECTOR2I( ( sz.x - sz.y ) / 2, 0 ); else delta = VECTOR2I( 0, ( sz.y - sz.x ) / 2 ); SHAPE_SEGMENT* shape = new SHAPE_SEGMENT( c - delta, c + delta, std::min( sz.x, sz.y ) ); solid->SetShape( shape ); } break; case PAD_SHAPE_RECT: solid->SetShape( new SHAPE_RECT( c - sz / 2, sz.x, sz.y ) ); break; case PAD_SHAPE_TRAPEZOID: { wxPoint coords[4]; aPad->BuildPadPolygon( coords, wxSize( 0, 0 ), aPad->GetOrientation() ); SHAPE_CONVEX* shape = new SHAPE_CONVEX(); for( int ii = 0; ii < 4; ii++ ) { shape->Append( wx_c + coords[ii] ); } solid->SetShape( shape ); break; } default: TRACEn( 0, "unsupported pad shape" ); delete solid; return NULL; } } else { switch( aPad->GetShape() ) { // PAD_SHAPE_CIRCLE already handled above case PAD_SHAPE_OVAL: if( sz.x == sz.y ) solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) ); else { wxPoint start; wxPoint end; wxPoint corner; SHAPE_CONVEX* shape = new SHAPE_CONVEX(); int w = aPad->BuildSegmentFromOvalShape( start, end, 0.0, wxSize( 0, 0 ) ); if( start.y == 0 ) corner = wxPoint( start.x, -( w / 2 ) ); else corner = wxPoint( w / 2, start.y ); RotatePoint( &start, aPad->GetOrientation() ); RotatePoint( &corner, aPad->GetOrientation() ); shape->Append( wx_c + corner ); for( int rot = 100; rot <= 1800; rot += 100 ) { wxPoint p( corner ); RotatePoint( &p, start, rot ); shape->Append( wx_c + p ); } if( end.y == 0 ) corner = wxPoint( end.x, w / 2 ); else corner = wxPoint( -( w / 2 ), end.y ); RotatePoint( &end, aPad->GetOrientation() ); RotatePoint( &corner, aPad->GetOrientation() ); shape->Append( wx_c + corner ); for( int rot = 100; rot <= 1800; rot += 100 ) { wxPoint p( corner ); RotatePoint( &p, end, rot ); shape->Append( wx_c + p ); } solid->SetShape( shape ); } break; case PAD_SHAPE_RECT: case PAD_SHAPE_TRAPEZOID: { wxPoint coords[4]; aPad->BuildPadPolygon( coords, wxSize( 0, 0 ), aPad->GetOrientation() ); SHAPE_CONVEX* shape = new SHAPE_CONVEX(); for( int ii = 0; ii < 4; ii++ ) { shape->Append( wx_c + coords[ii] ); } solid->SetShape( shape ); break; } default: TRACEn( 0, "unsupported pad shape" ); delete solid; return NULL; } } } return solid; }
PNS_ITEM* PNS_ROUTER::syncPad( D_PAD* aPad ) { PNS_LAYERSET layers; switch( aPad->GetAttribute() ) { case PAD_STANDARD: layers = PNS_LAYERSET( 0, 15 ); break; case PAD_SMD: case PAD_CONN: { LAYER_MSK lmsk = aPad->GetLayerMask(); int i; for( i = FIRST_COPPER_LAYER; i <= LAST_COPPER_LAYER; i++ ) { if( lmsk & (1 << i) ) { layers = PNS_LAYERSET( i ); break; } } break; } default: TRACE( 0, "unsupported pad type 0x%x", aPad->GetAttribute() ); return NULL; } PNS_SOLID* solid = new PNS_SOLID; solid->SetLayers( layers ); solid->SetNet( aPad->GetNet() ); wxPoint wx_c = aPad->GetPosition(); wxSize wx_sz = aPad->GetSize(); VECTOR2I c( wx_c.x, wx_c.y ); VECTOR2I sz( wx_sz.x, wx_sz.y ); solid->SetCenter( c ); double orient = aPad->GetOrientation() / 10.0; if( orient == 90.0 || orient == 270.0 ) sz = VECTOR2I( sz.y, sz.x ); else if( orient != 0.0 && orient != 180.0 ) { TRACEn( 0, "non-orthogonal pad rotations not supported yet" ); delete solid; return NULL; } switch( aPad->GetShape() ) { case PAD_CIRCLE: solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) ); break; case PAD_OVAL: if( sz.x == sz.y ) solid->SetShape( new SHAPE_CIRCLE( c, sz.x / 2 ) ); else solid->SetShape( new SHAPE_RECT( c - sz / 2, sz.x, sz.y ) ); break; case PAD_RECT: solid->SetShape( new SHAPE_RECT( c - sz / 2, sz.x, sz.y ) ); break; default: TRACEn( 0, "unsupported pad shape" ); delete solid; return NULL; } solid->SetParent( aPad ); return solid; }