void DIALOG_GLOBAL_MODULES_FIELDS_EDITION::OnOKClick( wxCommandEvent& event ) { m_refSelection = m_ReferenceOpt->GetValue(); m_valueSelection = m_ValueOpt->GetValue(); m_othersSelection = m_OtherFields->GetValue(); m_filterString = m_ModuleFilter->GetValue(); m_brdSettings->m_ModuleTextSize.x = ReturnValueFromTextCtrl( *m_SizeX_Value ); m_brdSettings->m_ModuleTextSize.y = ReturnValueFromTextCtrl( *m_SizeY_Value ); m_brdSettings->m_ModuleTextWidth = ReturnValueFromTextCtrl( *m_TicknessValue ); // clip m_ModuleTextWidth to the 1/4 of min size, to keep it always readable int minsize = std::min( m_brdSettings->m_ModuleTextSize.x, m_brdSettings->m_ModuleTextSize.y ) / 4; if( m_brdSettings->m_ModuleTextWidth > minsize ) m_brdSettings->m_ModuleTextWidth = minsize; m_parent->ResetModuleTextSizes( m_filterString, m_refSelection, m_valueSelection, m_othersSelection ); EndModal( wxID_OK ); }
void DIALOG_PLOT_SCHEMATIC::getPlotOptions() { m_config->Write( PLOT_MODECOLOR_KEY, getModeColor() ); m_config->Write( PLOT_FRAME_REFERENCE_KEY, getPlotFrameRef() ); m_config->Write( PLOT_FORMAT_KEY, (long) GetPlotFileFormat() ); m_config->Write( PLOT_HPGL_ORIGIN_KEY, GetPlotOriginCenter() ); m_HPGLPaperSizeSelect = m_HPGLPaperSizeOption->GetSelection(); m_config->Write( PLOT_HPGL_PAPERSIZE_KEY, m_HPGLPaperSizeSelect ); // HPGL Pen Size is stored in mm in config m_config->Write( PLOT_HPGL_PEN_SIZE_KEY, m_HPGLPenSize/IU_PER_MM ); m_pageSizeSelect = m_PaperSizeOption->GetSelection(); SetDefaultLineThickness( ReturnValueFromTextCtrl( *m_DefaultLineSizeCtrl ) ); }
void DIALOG_SVG_PRINT::SetPenWidth() { int pensize = ReturnValueFromTextCtrl( *m_DialogDefaultPenSize ); if( pensize > WIDTH_MAX_VALUE ) { pensize = WIDTH_MAX_VALUE; } if( pensize < WIDTH_MIN_VALUE ) { pensize = WIDTH_MIN_VALUE; } g_DrawDefaultLineThickness = pensize; m_DialogDefaultPenSize->SetValue( ReturnStringFromValue( g_UserUnit, pensize ) ); }
bool DIALOG_COPPER_ZONE::AcceptOptions( bool aPromptForErrors, bool aUseExportableSetupOnly ) { switch( m_PadInZoneOpt->GetSelection() ) { case 3: // Pads are not covered m_settings.SetPadConnection( PAD_NOT_IN_ZONE ); break; case 2: // Use thermal relief for THT pads m_settings.SetPadConnection( THT_THERMAL ); break; case 1: // Use thermal relief for pads m_settings.SetPadConnection( THERMAL_PAD ); break; case 0: // pads are covered by copper m_settings.SetPadConnection( PAD_IN_ZONE ); break; } switch( m_OutlineAppearanceCtrl->GetSelection() ) { case 0: m_settings.m_Zone_HatchingStyle = CPolyLine::NO_HATCH; break; case 1: m_settings.m_Zone_HatchingStyle = CPolyLine::DIAGONAL_EDGE; break; case 2: m_settings.m_Zone_HatchingStyle = CPolyLine::DIAGONAL_FULL; break; } m_settings.m_ArcToSegmentsCount = m_ArcApproximationOpt->GetSelection() == 1 ? ARC_APPROX_SEGMENTS_COUNT_HIGHT_DEF : ARC_APPROX_SEGMENTS_COUNT_LOW_DEF; if( m_Config ) { m_Config->Write( ZONE_NET_OUTLINES_HATCH_OPTION_KEY, (long) m_settings.m_Zone_HatchingStyle ); wxString filter = m_DoNotShowNetNameFilter->GetValue(); m_Config->Write( ZONE_NET_FILTER_STRING_KEY, filter ); } m_netNameShowFilter = m_ShowNetNameFilter->GetValue(); m_settings.m_FillMode = (m_FillModeCtrl->GetSelection() == 0) ? 0 : 1; wxString txtvalue = m_ZoneClearanceCtrl->GetValue(); m_settings.m_ZoneClearance = ReturnValueFromString( g_UserUnit, txtvalue ); // Test if this is a reasonable value for this parameter // A too large value can hang Pcbnew #define CLEARANCE_MAX_VALUE ZONE_CLEARANCE_MAX_VALUE_MIL*IU_PER_MILS if( m_settings.m_ZoneClearance > CLEARANCE_MAX_VALUE ) { wxString msg; msg.Printf( _( "Clearance must be smaller than %f\" / %f mm." ), ZONE_CLEARANCE_MAX_VALUE_MIL / 1000.0, ZONE_CLEARANCE_MAX_VALUE_MIL * 0.0254 ); DisplayError( this, msg ); return false; } txtvalue = m_ZoneMinThicknessCtrl->GetValue(); m_settings.m_ZoneMinThickness = ReturnValueFromString( g_UserUnit, txtvalue ); if( m_settings.m_ZoneMinThickness < (ZONE_THICKNESS_MIN_VALUE_MIL*IU_PER_MILS) ) { wxString msg; msg.Printf( _( "Minimum width must be larger than %f\" / %f mm." ), ZONE_THICKNESS_MIN_VALUE_MIL / 1000.0, ZONE_THICKNESS_MIN_VALUE_MIL * 0.0254 ); DisplayError( this, msg ); return false; } m_settings.SetCornerSmoothingType( m_cornerSmoothingChoice->GetSelection() ); txtvalue = m_cornerSmoothingCtrl->GetValue(); m_settings.SetCornerRadius( ReturnValueFromString( g_UserUnit, txtvalue ) ); m_settings.m_ZonePriority = m_PriorityLevelCtrl->GetValue(); if( m_OrientEdgesOpt->GetSelection() == 0 ) m_settings.m_Zone_45_Only = false; else m_settings.m_Zone_45_Only = true; m_settings.m_ThermalReliefGap = ReturnValueFromTextCtrl( *m_AntipadSizeValue ); m_settings.m_ThermalReliefCopperBridge = ReturnValueFromTextCtrl( *m_CopperWidthValue ); if( m_Config ) { ConfigBaseWriteDouble( m_Config, ZONE_CLEARANCE_WIDTH_STRING_KEY, (double) m_settings.m_ZoneClearance / IU_PER_MILS ); ConfigBaseWriteDouble( m_Config, ZONE_MIN_THICKNESS_WIDTH_STRING_KEY, (double) m_settings.m_ZoneMinThickness / IU_PER_MILS ); ConfigBaseWriteDouble( m_Config, ZONE_THERMAL_RELIEF_GAP_STRING_KEY, (double) m_settings.m_ThermalReliefGap / IU_PER_MILS ); ConfigBaseWriteDouble( m_Config, ZONE_THERMAL_RELIEF_COPPER_WIDTH_STRING_KEY, (double) m_settings.m_ThermalReliefCopperBridge / IU_PER_MILS ); } if( m_settings.m_ThermalReliefCopperBridge <= m_settings.m_ZoneMinThickness ) { DisplayError( this, _( "Thermal relief spoke width is smaller than the minimum width." ) ); return false; } // If we use only exportable to others zones parameters, exit here: if( aUseExportableSetupOnly ) return true; // Get the layer selection for this zone int ii = m_LayerSelectionCtrl->GetFirstSelected(); if( ii < 0 && aPromptForErrors ) { DisplayError( this, _( "No layer selected." ) ); return false; } m_settings.m_CurrentZone_Layer = m_LayerId[ii]; // Get the net name selection for this zone ii = m_ListNetNameSelection->GetSelection(); if( ii < 0 && aPromptForErrors ) { DisplayError( this, _( "No net selected." ) ); return false; } if( ii == 0 ) // the not connected option was selected: this is not a good practice: warn: { if( !IsOK( this, _( "You have chosen the \"not connected\" option. This will create insulated copper islands. Are you sure ?" ) ) ) return false; } wxString net_name = m_ListNetNameSelection->GetString( ii ); m_settings.m_NetcodeSelection = 0; // Search net_code for this net, if a net was selected if( m_ListNetNameSelection->GetSelection() > 0 ) { NETINFO_ITEM* net = m_Parent->GetBoard()->FindNet( net_name ); if( net ) m_settings.m_NetcodeSelection = net->GetNet(); } return true; }
void DIALOG_MODULE_BOARD_EDITOR::OnOkClick( wxCommandEvent& event ) { wxPoint modpos; wxString msg; if( m_CurrentModule->GetFlags() == 0 ) // this is a simple edition, we // must create an undo entry m_Parent->SaveCopyInUndoList( m_CurrentModule, UR_CHANGED ); if( m_DC ) { m_Parent->GetCanvas()->CrossHairOff( m_DC ); m_CurrentModule->Draw( m_Parent->GetCanvas(), m_DC, GR_XOR ); } // Init Fields (should be first, because they can be moved or/and flipped later): m_CurrentModule->Reference().Copy( m_ReferenceCopy ); m_CurrentModule->Value().Copy( m_ValueCopy ); // Initialize masks clearances m_CurrentModule->SetLocalClearance( ReturnValueFromTextCtrl( *m_NetClearanceValueCtrl ) ); m_CurrentModule->SetLocalSolderMaskMargin( ReturnValueFromTextCtrl( *m_SolderMaskMarginCtrl ) ); m_CurrentModule->SetLocalSolderPasteMargin( ReturnValueFromTextCtrl( *m_SolderPasteMarginCtrl ) ); double dtmp = 0.0; msg = m_SolderPasteMarginRatioCtrl->GetValue(); msg.ToDouble( &dtmp ); // A -50% margin ratio means no paste on a pad, the ratio must be >= -50% if( dtmp < -50.0 ) dtmp = -50.0; // A margin ratio is always <= 0 // 0 means use full pad copper area if( dtmp > 0.0 ) dtmp = 0.0; m_CurrentModule->SetLocalSolderPasteMarginRatio( dtmp / 100 ); switch( m_ZoneConnectionChoice->GetSelection() ) { default: case 0: m_CurrentModule->SetZoneConnection( UNDEFINED_CONNECTION ); break; case 1: m_CurrentModule->SetZoneConnection( PAD_IN_ZONE ); break; case 2: m_CurrentModule->SetZoneConnection( THERMAL_PAD ); break; case 3: m_CurrentModule->SetZoneConnection( PAD_NOT_IN_ZONE ); break; } // Set Module Position modpos.x = ReturnValueFromTextCtrl( *m_ModPositionX ); modpos.y = ReturnValueFromTextCtrl( *m_ModPositionY ); m_CurrentModule->SetPosition( modpos ); m_CurrentModule->SetLocked( m_AutoPlaceCtrl->GetSelection() == 1 ); switch( m_AttributsCtrl->GetSelection() ) { case 0: m_CurrentModule->SetAttributes( 0 ); break; case 1: m_CurrentModule->SetAttributes( MOD_CMS ); break; case 2: m_CurrentModule->SetAttributes( MOD_VIRTUAL ); break; } m_CurrentModule->SetPlacementCost90( m_CostRot90Ctrl->GetValue() ); m_CurrentModule->SetPlacementCost180( m_CostRot180Ctrl->GetValue() ); /* Now, set orientation. must be made after others changes, * because rotation changes fields positions on board according to the new orientation * (relative positions are not modified) */ long orient = 0; msg = m_OrientValue->GetValue(); msg.ToLong( &orient ); if( m_CurrentModule->GetOrientation() != orient ) m_CurrentModule->Rotate( m_CurrentModule->GetPosition(), orient - m_CurrentModule->GetOrientation() ); // Set component side, that also have effect on the fields positions on board bool change_layer = false; if( m_LayerCtrl->GetSelection() == 0 ) // layer req = COMPONENT { if( m_CurrentModule->GetLayer() == LAYER_N_BACK ) change_layer = true; } else if( m_CurrentModule->GetLayer() == LAYER_N_FRONT ) change_layer = true; if( change_layer ) m_CurrentModule->Flip( m_CurrentModule->GetPosition() ); // Update 3D shape list int ii = m_3D_ShapeNameListBox->GetSelection(); if( ii >= 0 ) TransfertDisplayTo3DValues( ii ); S3D_MASTER* draw3D = m_CurrentModule->Models(); for( unsigned ii = 0; ii < m_Shapes3D_list.size(); ii++ ) { S3D_MASTER* draw3DCopy = m_Shapes3D_list[ii]; if( draw3DCopy->GetShape3DName().IsEmpty() ) continue; if( draw3D == NULL ) { draw3D = new S3D_MASTER( draw3D ); m_CurrentModule->Models().Append( draw3D ); } draw3D->SetShape3DName( draw3DCopy->GetShape3DName() ); draw3D->m_MatScale = draw3DCopy->m_MatScale; draw3D->m_MatRotation = draw3DCopy->m_MatRotation; draw3D->m_MatPosition = draw3DCopy->m_MatPosition; draw3D = draw3D->Next(); } // Remove old extra 3D shapes S3D_MASTER* nextdraw3D; for( ; draw3D != NULL; draw3D = nextdraw3D ) { nextdraw3D = (S3D_MASTER*) draw3D->Next(); delete m_CurrentModule->Models().Remove( draw3D ); } // Fill shape list with one void entry, if no entry if( m_CurrentModule->Models() == NULL ) m_CurrentModule->Models().PushBack( new S3D_MASTER( m_CurrentModule ) ); m_CurrentModule->CalculateBoundingBox(); m_Parent->OnModify(); EndModal( 1 ); if( m_DC ) { m_CurrentModule->Draw( m_Parent->GetCanvas(), m_DC, GR_OR ); m_Parent->GetCanvas()->CrossHairOn( m_DC ); } }
bool DIALOG_PAD_PROPERTIES::transferDataToPad( D_PAD* aPad ) { wxString msg; int x, y; aPad->SetAttribute( CodeType[m_PadType->GetSelection()] ); aPad->SetShape( CodeShape[m_PadShape->GetSelection()] ); // Read pad clearances values: aPad->SetLocalClearance( ReturnValueFromTextCtrl( *m_NetClearanceValueCtrl ) ); aPad->SetLocalSolderMaskMargin( ReturnValueFromTextCtrl( *m_SolderMaskMarginCtrl ) ); aPad->SetLocalSolderPasteMargin( ReturnValueFromTextCtrl( *m_SolderPasteMarginCtrl ) ); aPad->SetThermalWidth( ReturnValueFromTextCtrl( *m_ThermalWidthCtrl ) ); aPad->SetThermalGap( ReturnValueFromTextCtrl( *m_ThermalGapCtrl ) ); double dtmp = 0.0; msg = m_SolderPasteMarginRatioCtrl->GetValue(); msg.ToDouble( &dtmp ); // A -50% margin ratio means no paste on a pad, the ratio must be >= -50% if( dtmp < -50.0 ) dtmp = -50.0; // A margin ratio is always <= 0 // 0 means use full pad copper area if( dtmp > 0.0 ) dtmp = 0.0; aPad->SetLocalSolderPasteMarginRatio( dtmp / 100 ); switch( m_ZoneConnectionChoice->GetSelection() ) { default: case 0: aPad->SetZoneConnection( UNDEFINED_CONNECTION ); break; case 1: aPad->SetZoneConnection( PAD_IN_ZONE ); break; case 2: aPad->SetZoneConnection( THERMAL_PAD ); break; case 3: aPad->SetZoneConnection( PAD_NOT_IN_ZONE ); break; } // Read pad position: x = ReturnValueFromTextCtrl( *m_PadPosition_X_Ctrl ); y = ReturnValueFromTextCtrl( *m_PadPosition_Y_Ctrl ); aPad->SetPosition( wxPoint( x, y ) ); aPad->SetPos0( wxPoint( x, y ) ); // Read pad drill: x = ReturnValueFromTextCtrl( *m_PadDrill_X_Ctrl ); y = ReturnValueFromTextCtrl( *m_PadDrill_Y_Ctrl ); if( m_DrillShapeCtrl->GetSelection() == 0 ) { aPad->SetDrillShape( PAD_CIRCLE ); y = x; } else aPad->SetDrillShape( PAD_OVAL ); aPad->SetDrillSize( wxSize( x, y ) ); // Read pad shape size: x = ReturnValueFromTextCtrl( *m_ShapeSize_X_Ctrl ); y = ReturnValueFromTextCtrl( *m_ShapeSize_Y_Ctrl ); if( aPad->GetShape() == PAD_CIRCLE ) y = x; aPad->SetSize( wxSize( x, y ) ); // Read pad length die aPad->SetPadToDieLength( ReturnValueFromTextCtrl( *m_LengthPadToDieCtrl ) ); // Read pad shape delta size: // m_DeltaSize.x or m_DeltaSize.y must be NULL. for a trapezoid. wxSize delta; if( m_trapDeltaDirChoice->GetSelection() == 0 ) delta.x = ReturnValueFromTextCtrl( *m_ShapeDelta_Ctrl ); else delta.y = ReturnValueFromTextCtrl( *m_ShapeDelta_Ctrl ); // Test bad values (be sure delta values are not too large) // remember DeltaSize.x is the Y size variation bool error = false; if( delta.x < 0 && delta.x <= -aPad->GetSize().y ) { delta.x = -aPad->GetSize().y + 2; error = true; } if( delta.x > 0 && delta.x >= aPad->GetSize().y ) { delta.x = aPad->GetSize().y - 2; error = true; } if( delta.y < 0 && delta.y <= -aPad->GetSize().x ) { delta.y = -aPad->GetSize().x + 2; error = true; } if( delta.y > 0 && delta.y >= aPad->GetSize().x ) { delta.y = aPad->GetSize().x - 2; error = true; } aPad->SetDelta( delta ); // Read pad shape offset: x = ReturnValueFromTextCtrl( *m_ShapeOffset_X_Ctrl ); y = ReturnValueFromTextCtrl( *m_ShapeOffset_Y_Ctrl ); aPad->SetOffset( wxPoint( x, y ) ); double orient_value = 0; msg = m_PadOrientCtrl->GetValue(); msg.ToDouble( &orient_value ); aPad->SetOrientation( orient_value ); msg = m_PadNumCtrl->GetValue().Left( 4 ); aPad->SetPadName( msg ); aPad->SetNetname( m_PadNetNameCtrl->GetValue() ); // Clear some values, according to the pad type and shape switch( aPad->GetShape() ) { case PAD_CIRCLE: aPad->SetOffset( wxPoint( 0, 0 ) ); aPad->SetDelta( wxSize( 0, 0 ) ); x = aPad->GetSize().x; aPad->SetSize( wxSize( x, x ) ); break; case PAD_RECT: aPad->SetDelta( wxSize( 0, 0 ) ); break; case PAD_OVAL: aPad->SetDelta( wxSize( 0, 0 ) ); break; case PAD_TRAPEZOID: break; default: ; } switch( aPad->GetAttribute() ) { case PAD_STANDARD: break; case PAD_CONN: case PAD_SMD: // SMD and PAD_CONN has no hole. // basically, SMD and PAD_CONN are same type of pads // PAD_CONN has just a default non technical layers that differs from SMD // and are intended to be used in virtual edge board connectors // However we can accept a non null offset, // mainly to allow complex pads build from a set of from basic pad shapes aPad->SetDrillSize( wxSize( 0, 0 ) ); break; case PAD_HOLE_NOT_PLATED: // Mechanical purpose only: // no offset, no net name, no pad name allowed aPad->SetOffset( wxPoint( 0, 0 ) ); aPad->SetPadName( wxEmptyString ); aPad->SetNetname( wxEmptyString ); break; default: DisplayError( NULL, wxT( "Error: unknown pad type" ) ); break; } LAYER_MSK padLayerMask = NO_LAYERS; switch( m_rbCopperLayersSel->GetSelection() ) { case 0: padLayerMask |= LAYER_FRONT; break; case 1: padLayerMask |= LAYER_BACK; break; case 2: padLayerMask |= ALL_CU_LAYERS; break; case 3: // No copper layers break; } if( m_PadLayerAdhCmp->GetValue() ) padLayerMask |= ADHESIVE_LAYER_FRONT; if( m_PadLayerAdhCu->GetValue() ) padLayerMask |= ADHESIVE_LAYER_BACK; if( m_PadLayerPateCmp->GetValue() ) padLayerMask |= SOLDERPASTE_LAYER_FRONT; if( m_PadLayerPateCu->GetValue() ) padLayerMask |= SOLDERPASTE_LAYER_BACK; if( m_PadLayerSilkCmp->GetValue() ) padLayerMask |= SILKSCREEN_LAYER_FRONT; if( m_PadLayerSilkCu->GetValue() ) padLayerMask |= SILKSCREEN_LAYER_BACK; if( m_PadLayerMaskCmp->GetValue() ) padLayerMask |= SOLDERMASK_LAYER_FRONT; if( m_PadLayerMaskCu->GetValue() ) padLayerMask |= SOLDERMASK_LAYER_BACK; if( m_PadLayerECO1->GetValue() ) padLayerMask |= ECO1_LAYER; if( m_PadLayerECO2->GetValue() ) padLayerMask |= ECO2_LAYER; if( m_PadLayerDraft->GetValue() ) padLayerMask |= DRAW_LAYER; aPad->SetLayerMask( padLayerMask ); return error; }
void DIALOG_MODULE_MODULE_EDITOR::OnOkClick( wxCommandEvent& event ) { // First, test for invalid chars in module name wxString footprintName = m_FootprintNameCtrl->GetValue(); if( ! footprintName.IsEmpty() ) { if( ! MODULE::IsLibNameValid( footprintName ) ) { wxString msg; msg.Printf( _( "Error:\none of invalid chars <%s> found\nin <%s>" ), MODULE::ReturnStringLibNameInvalidChars( true ), GetChars( footprintName ) ); DisplayError( NULL, msg ); return; } } m_parent->SaveCopyInUndoList( m_currentModule, UR_MODEDIT ); m_currentModule->SetLocked( m_AutoPlaceCtrl->GetSelection() == 1 ); switch( m_AttributsCtrl->GetSelection() ) { case 0: m_currentModule->SetAttributes( 0 ); break; case 1: m_currentModule->SetAttributes( MOD_CMS ); break; case 2: m_currentModule->SetAttributes( MOD_VIRTUAL ); break; } m_currentModule->SetPlacementCost90( m_CostRot90Ctrl->GetValue() ); m_currentModule->SetPlacementCost180( m_CostRot180Ctrl->GetValue() ); m_currentModule->SetDescription( m_DocCtrl->GetValue() ); m_currentModule->SetKeywords( m_KeywordCtrl->GetValue() ); // Init footprint name in library if( ! footprintName.IsEmpty() ) m_currentModule->SetFPID( FPID( footprintName ) ); // Init Fields: m_currentModule->Reference().Copy( m_referenceCopy ); m_currentModule->Value().Copy( m_valueCopy ); // Initialize masks clearances m_currentModule->SetLocalClearance( ReturnValueFromTextCtrl( *m_NetClearanceValueCtrl ) ); m_currentModule->SetLocalSolderMaskMargin( ReturnValueFromTextCtrl( *m_SolderMaskMarginCtrl ) ); m_currentModule->SetLocalSolderPasteMargin( ReturnValueFromTextCtrl( *m_SolderPasteMarginCtrl ) ); double dtmp; wxString msg = m_SolderPasteMarginRatioCtrl->GetValue(); msg.ToDouble( &dtmp ); // A -50% margin ratio means no paste on a pad, the ratio must be >= -50 % if( dtmp < -50.0 ) dtmp = -50.0; // A margin ratio is always <= 0 if( dtmp > 0.0 ) dtmp = 0.0; m_currentModule->SetLocalSolderPasteMarginRatio( dtmp / 100 ); // Update 3D shape list int ii = m_3D_ShapeNameListBox->GetSelection(); if ( ii >= 0 ) TransfertDisplayTo3DValues( ii ); S3D_MASTER* draw3D = m_currentModule->Models(); for( unsigned ii = 0; ii < m_shapes3D_list.size(); ii++ ) { S3D_MASTER* draw3DCopy = m_shapes3D_list[ii]; if( draw3DCopy->GetShape3DName().IsEmpty() ) continue; if( draw3D == NULL ) { draw3D = new S3D_MASTER( draw3D ); m_currentModule->Models().Append( draw3D ); } draw3D->SetShape3DName( draw3DCopy->GetShape3DName() ); draw3D->m_MatScale = draw3DCopy->m_MatScale; draw3D->m_MatRotation = draw3DCopy->m_MatRotation; draw3D->m_MatPosition = draw3DCopy->m_MatPosition; draw3D = draw3D->Next(); } // Remove old extra 3D shapes S3D_MASTER* nextdraw3D; for( ; draw3D != NULL; draw3D = nextdraw3D ) { nextdraw3D = (S3D_MASTER*) draw3D->Next(); delete m_currentModule->Models().Remove( draw3D ); } // Fill shape list with one void entry, if no entry if( m_currentModule->Models() == NULL ) m_currentModule->Models().PushBack( new S3D_MASTER( m_currentModule ) ); m_currentModule->CalculateBoundingBox(); m_parent->OnModify(); EndModal( 1 ); }