MODULE* PCB_EDIT_FRAME::Genere_Self( wxDC* DC ) { D_PAD* pad; int ll; wxString msg; m_canvas->CallMouseCapture( DC, wxDefaultPosition, false ); m_canvas->SetMouseCapture( NULL, NULL ); if( s_inductor_pattern.m_Flag == false ) { DisplayError( this, wxT( "Starting point not init.." ) ); return NULL; } s_inductor_pattern.m_Flag = false; s_inductor_pattern.m_End = GetCrossHairPosition(); wxPoint pt = s_inductor_pattern.m_End - s_inductor_pattern.m_Start; int min_len = KiROUND( EuclideanNorm( pt ) ); s_inductor_pattern.m_lenght = min_len; // Enter the desired length. msg = StringFromValue( g_UserUnit, s_inductor_pattern.m_lenght ); wxTextEntryDialog dlg( this, wxEmptyString, _( "Length of Trace:" ), msg ); if( dlg.ShowModal() != wxID_OK ) return NULL; // canceled by user msg = dlg.GetValue(); s_inductor_pattern.m_lenght = ValueFromString( g_UserUnit, msg ); // Control values (ii = minimum length) if( s_inductor_pattern.m_lenght < min_len ) { DisplayError( this, _( "Requested length < minimum length" ) ); return NULL; } // Calculate the elements. s_inductor_pattern.m_Width = GetDesignSettings().GetCurrentTrackWidth(); std::vector <wxPoint> buffer; ll = BuildCornersList_S_Shape( buffer, s_inductor_pattern.m_Start, s_inductor_pattern.m_End, s_inductor_pattern.m_lenght, s_inductor_pattern.m_Width ); if( !ll ) { DisplayError( this, _( "Requested length too large" ) ); return NULL; } // Generate footprint. the value is also used as footprint name. msg.Empty(); wxTextEntryDialog cmpdlg( this, wxEmptyString, _( "Component Value:" ), msg ); cmpdlg.SetTextValidator( FILE_NAME_CHAR_VALIDATOR( &msg ) ); if( ( cmpdlg.ShowModal() != wxID_OK ) || msg.IsEmpty() ) return NULL; // Aborted by user MODULE* module = CreateNewModule( msg ); // here the module is already in the BOARD, CreateNewModule() does that. module->SetFPID( FPID( std::string( "mw_inductor" ) ) ); module->SetAttributes( MOD_VIRTUAL | MOD_CMS ); module->ClearFlags(); module->SetPosition( s_inductor_pattern.m_End ); // Generate segments for( unsigned jj = 1; jj < buffer.size(); jj++ ) { EDGE_MODULE* PtSegm; PtSegm = new EDGE_MODULE( module ); PtSegm->SetStart( buffer[jj - 1] ); PtSegm->SetEnd( buffer[jj] ); PtSegm->SetWidth( s_inductor_pattern.m_Width ); PtSegm->SetLayer( module->GetLayer() ); PtSegm->SetShape( S_SEGMENT ); PtSegm->SetStart0( PtSegm->GetStart() - module->GetPosition() ); PtSegm->SetEnd0( PtSegm->GetEnd() - module->GetPosition() ); module->GraphicalItems().PushBack( PtSegm ); } // Place a pad on each end of coil. pad = new D_PAD( module ); module->Pads().PushFront( pad ); pad->SetPadName( wxT( "1" ) ); pad->SetPosition( s_inductor_pattern.m_End ); pad->SetPos0( pad->GetPosition() - module->GetPosition() ); pad->SetSize( wxSize( s_inductor_pattern.m_Width, s_inductor_pattern.m_Width ) ); pad->SetLayerSet( LSET( module->GetLayer() ) ); pad->SetAttribute( PAD_ATTRIB_SMD ); pad->SetShape( PAD_SHAPE_CIRCLE ); D_PAD* newpad = new D_PAD( *pad ); module->Pads().Insert( newpad, pad->Next() ); pad = newpad; pad->SetPadName( wxT( "2" ) ); pad->SetPosition( s_inductor_pattern.m_Start ); pad->SetPos0( pad->GetPosition() - module->GetPosition() ); // Modify text positions. SetMsgPanel( module ); wxPoint refPos( ( s_inductor_pattern.m_Start.x + s_inductor_pattern.m_End.x ) / 2, ( s_inductor_pattern.m_Start.y + s_inductor_pattern.m_End.y ) / 2 ); wxPoint valPos = refPos; refPos.y -= module->Reference().GetSize().y; module->Reference().SetPosition( refPos ); valPos.y += module->Value().GetSize().y; module->Value().SetPosition( valPos ); module->CalculateBoundingBox(); module->Draw( m_canvas, DC, GR_OR ); return module; }
MODULE* CreateMicrowaveInductor( PCB_EDIT_FRAME* aPcbFrame, wxString& aErrorMessage ) { /* Build a microwave inductor footprint. * - Length Mself.lng * - Extremities Mself.m_Start and Mself.m_End * We must determine: * Mself.nbrin = number of segments perpendicular to the direction * (The coil nbrin will demicercles + 1 + 2 1 / 4 circle) * Mself.lbrin = length of a strand * Mself.radius = radius of rounded parts of the coil * Mself.delta = segments extremities connection between him and the coil even * * The equations are * Mself.m_Size.x = 2 * Mself.radius + Mself.lbrin * Mself.m_Size.y * Mself.delta = 2 + 2 * Mself.nbrin * Mself.radius * Mself.lng = 2 * Mself.delta / / connections to the coil + (Mself.nbrin-2) * Mself.lbrin / / length of the strands except 1st and last + (Mself.nbrin 1) * (PI * Mself.radius) / / length of rounded * Mself.lbrin + / 2 - Melf.radius * 2) / / length of 1st and last bit * * The constraints are: * Nbrin >= 2 * Mself.radius < Mself.m_Size.x * Mself.m_Size.y = Mself.radius * 4 + 2 * Mself.raccord * Mself.lbrin> Mself.radius * 2 * * The calculation is conducted in the following way: * Initially: * Nbrin = 2 * Radius = 4 * m_Size.x (arbitrarily fixed value) * Then: * Increasing the number of segments to the desired length * (Radius decreases if necessary) */ D_PAD* pad; int ll; wxString msg; wxASSERT( s_inductor_pattern.m_Flag ); s_inductor_pattern.m_Flag = false; wxPoint pt = s_inductor_pattern.m_End - s_inductor_pattern.m_Start; int min_len = KiROUND( EuclideanNorm( pt ) ); s_inductor_pattern.m_length = min_len; // Enter the desired length. msg = StringFromValue( g_UserUnit, s_inductor_pattern.m_length ); wxTextEntryDialog dlg( NULL, wxEmptyString, _( "Length of Trace:" ), msg ); if( dlg.ShowModal() != wxID_OK ) return NULL; // canceled by user msg = dlg.GetValue(); s_inductor_pattern.m_length = ValueFromString( g_UserUnit, msg ); // Control values (ii = minimum length) if( s_inductor_pattern.m_length < min_len ) { aErrorMessage = _( "Requested length < minimum length" ); return NULL; } // Calculate the elements. std::vector <wxPoint> buffer; ll = BuildCornersList_S_Shape( buffer, s_inductor_pattern.m_Start, s_inductor_pattern.m_End, s_inductor_pattern.m_length, s_inductor_pattern.m_Width ); if( !ll ) { aErrorMessage = _( "Requested length too large" ); return NULL; } // Generate footprint. the value is also used as footprint name. msg.Empty(); wxTextEntryDialog cmpdlg( NULL, wxEmptyString, _( "Component Value:" ), msg ); cmpdlg.SetTextValidator( FILE_NAME_CHAR_VALIDATOR( &msg ) ); if( ( cmpdlg.ShowModal() != wxID_OK ) || msg.IsEmpty() ) return NULL; // Aborted by user MODULE* module = aPcbFrame->CreateNewModule( msg ); // here the module is already in the BOARD, CreateNewModule() does that. module->SetFPID( LIB_ID( std::string( "mw_inductor" ) ) ); module->SetAttributes( MOD_VIRTUAL | MOD_CMS ); module->ClearFlags(); module->SetPosition( s_inductor_pattern.m_End ); // Generate segments for( unsigned jj = 1; jj < buffer.size(); jj++ ) { EDGE_MODULE* PtSegm; PtSegm = new EDGE_MODULE( module ); PtSegm->SetStart( buffer[jj - 1] ); PtSegm->SetEnd( buffer[jj] ); PtSegm->SetWidth( s_inductor_pattern.m_Width ); PtSegm->SetLayer( module->GetLayer() ); PtSegm->SetShape( S_SEGMENT ); PtSegm->SetStart0( PtSegm->GetStart() - module->GetPosition() ); PtSegm->SetEnd0( PtSegm->GetEnd() - module->GetPosition() ); module->GraphicalItems().PushBack( PtSegm ); } // Place a pad on each end of coil. pad = new D_PAD( module ); module->Pads().PushFront( pad ); pad->SetPadName( wxT( "1" ) ); pad->SetPosition( s_inductor_pattern.m_End ); pad->SetPos0( pad->GetPosition() - module->GetPosition() ); pad->SetSize( wxSize( s_inductor_pattern.m_Width, s_inductor_pattern.m_Width ) ); pad->SetLayerSet( LSET( module->GetLayer() ) ); pad->SetAttribute( PAD_ATTRIB_SMD ); pad->SetShape( PAD_SHAPE_CIRCLE ); D_PAD* newpad = new D_PAD( *pad ); module->Pads().Insert( newpad, pad->Next() ); pad = newpad; pad->SetPadName( wxT( "2" ) ); pad->SetPosition( s_inductor_pattern.m_Start ); pad->SetPos0( pad->GetPosition() - module->GetPosition() ); // Modify text positions. wxPoint refPos( ( s_inductor_pattern.m_Start.x + s_inductor_pattern.m_End.x ) / 2, ( s_inductor_pattern.m_Start.y + s_inductor_pattern.m_End.y ) / 2 ); wxPoint valPos = refPos; refPos.y -= module->Reference().GetSize().y; module->Reference().SetPosition( refPos ); valPos.y += module->Value().GetSize().y; module->Value().SetPosition( valPos ); module->CalculateBoundingBox(); return module; }