//==== Drag Parameters ====// void StackGeom::LoadDragFactors( DragFactors& drag_factors ) { double max_xsec_area = 0.000000000001; for ( int i = 0 ; i < ( int )m_XSecSurf.NumXSec() ; i++ ) { XSec* xs = m_XSecSurf.FindXSec( i ); XSecCurve* xsc = xs->GetXSecCurve(); double a = xsc->ComputeArea( ); if ( a > max_xsec_area ) { max_xsec_area = a; } } // drag_factors.m_Length = m_Length(); drag_factors.m_MaxXSecArea = max_xsec_area; // drag_factors.m_LengthToDia = m_Length() / dia; }
//==== Update Fuselage And Cross Section Placement ====// void PropGeom::UpdateSurf() { int nxsec = m_XSecSurf.NumXSec(); double radius = m_Diameter() / 2.0; double rfirst = 0.0; double rlast = 1.0; vector < double > uvec( nxsec ); vector < double > rvec( nxsec ); double rev = 1.0; if ( m_ReverseFlag() ) { rev = -1.0; } //==== Update XSec Location/Rotation ====// for ( int i = 0 ; i < nxsec ; i++ ) { PropXSec* xs = ( PropXSec* ) m_XSecSurf.FindXSec( i ); if ( xs ) { if ( xs->GetXSecCurve()->GetType() == XS_POINT ) { printf( "Warning: XS_POINT type not valid for propellers\n" ); // Propellers are constructed in two phases. The first phase stacks // all the XSecs with unit chord. Intermediate curves are extracted // from that surface and are scaled to match the required chord. // Since XS_POINT XSecs already have zero chord, they mess up this // process. } //==== Reset Group Names ====// xs->SetGroupDisplaySuffix( i ); //==== Set X Limits ====// EnforceOrder( xs, i ); xs->SetRefLength( radius ); bool first = false; bool last = false; if( i == 0 ) first = true; else if( i == (nxsec-1) ) last = true; if ( first ) { rfirst = xs->m_RadiusFrac(); } if ( last ) { rlast = xs->m_RadiusFrac(); } uvec[i] = i; rvec[i] = xs->m_RadiusFrac(); } } m_rtou = Vsp1DCurve(); m_rtou.InterpolateLinear( uvec, rvec, false ); EnforcePCurveOrder( rfirst, rlast ); // Set lower limit for activity factor integration limit m_AFLimit.SetLowerLimit( rfirst ); // Integrate activity factor. m_AF.Set( m_ChordCurve.IntegrateAF( m_AFLimit() ) ); m_AF.Deactivate(); if ( m_UseBeta34Flag() == 1 ) { if ( rfirst <= 0.75 ) { double theta34 = m_TwistCurve.Comp( 0.75 ); m_Feather = m_Beta34() - theta34; } else { m_Feather = m_Beta34(); } m_Beta34.Activate(); m_Feather.Deactivate(); } else { if ( rfirst <= 0.75 ) { double theta34 = m_TwistCurve.Comp( 0.75 ); m_Beta34 = m_Feather() + theta34; } else { m_Beta34 = m_Feather(); } m_Beta34.Deactivate(); m_Feather.Activate(); } // Set up fold axis & store for visualization. Matrix4d fold, foldrot; fold.loadIdentity(); fold.rotateY( m_AzimuthFoldDir() ); fold.rotateX( m_ElevationFoldDir() ); m_FoldAxDirection = fold.xform( vec3d( 0, 0, 1 ) ); m_FoldAxOrigin = vec3d( m_AxialFoldAxis() * radius, m_RadFoldAxis() * radius, m_OffsetFoldAxis() * radius ); //==== Cross Section Curves & joint info ====// vector< VspCurve > crv_vec; crv_vec.resize( nxsec ); //==== Update XSec Location/Rotation ====// for ( int i = 0 ; i < nxsec ; i++ ) { PropXSec* xs = ( PropXSec* ) m_XSecSurf.FindXSec( i ); if ( xs ) { XSecCurve* xsc = xs->GetXSecCurve(); double r = xs->m_RadiusFrac(); double w = m_ChordCurve.Comp( r ) * radius; if ( xsc ) { //==== Find Width Parm ====// string width_id = xsc->GetWidthParmID(); Parm* width_parm = ParmMgr.FindParm( width_id ); piecewise_curve_type pwc; if ( width_parm ) { width_parm->Deactivate(); Airfoil* af = dynamic_cast < Airfoil* > ( xsc ); if ( af ) { width_parm->Set( 1.0 ); xs->GetXSecCurve()->SetFakeWidth( w ); xs->GetXSecCurve()->SetUseFakeWidth( true ); pwc = xs->GetCurve().GetCurve(); xs->GetXSecCurve()->SetUseFakeWidth( false ); width_parm->Set( w ); } else { CircleXSec* cir = dynamic_cast < CircleXSec* > ( xsc ); if ( cir ) { width_parm->Set( 1.0 ); pwc = xs->GetCurve().GetCurve(); width_parm->Set( w ); } else { double h = xs->GetXSecCurve()->GetHeight(); xsc->SetWidthHeight( 1.0, h/w ); pwc = xs->GetCurve().GetCurve(); xsc->SetWidthHeight( w, h ); } } } else { pwc = xs->GetCurve().GetCurve(); } // Set up prop positioner for highlight curves - not lofting. xs->m_PropPos.m_ParentProp = GetXSecSurf( 0 ); xs->m_PropPos.m_Radius = r * radius; xs->m_PropPos.m_Chord = w; xs->m_PropPos.m_Twist = m_TwistCurve.Comp( r ); xs->m_PropPos.m_XRotate = 0.0; xs->m_PropPos.m_ZRotate = atan( -m_RakeCurve.Compdt( r ) ) * 180.0 / PI; xs->m_PropPos.m_Rake = m_RakeCurve.Comp( r ) * radius; xs->m_PropPos.m_Skew = m_SkewCurve.Comp( r ) * radius; xs->m_PropPos.m_PropRot = m_Rotate(); xs->m_PropPos.m_Feather = m_Feather(); xs->m_PropPos.m_FoldOrigin = m_FoldAxOrigin; xs->m_PropPos.m_FoldDirection = m_FoldAxDirection; xs->m_PropPos.m_FoldAngle = m_FoldAngle(); xs->m_PropPos.m_Reverse = rev; crv_vec[i].SetCurve( pwc ); } } } // This surface linearly interpolates the airfoil sections without // any other transformations. // These sections can be extracted (as u-const curves) and then // transformed to their final position before skinning. m_FoilSurf = VspSurf(); m_FoilSurf.SkinC0( crv_vec, false ); // Find the union of stations required to approximate the blade parameters // with cubic functions. vector < double > tmap = rvec; // Initialize with specified XSecs. vector < double > tdisc; tdisc.push_back( rfirst ); tdisc.push_back( rlast ); for ( int i = 0; i < m_pcurve_vec.size(); i++ ) { vector < double > tm; vector < double > tmout; vector < double > td; m_pcurve_vec[i]->GetTMap( tm, td ); std::set_union( tmap.begin(), tmap.end(), tm.begin(), tm.end(), std::back_inserter(tmout), &aboutcomp ); std::swap( tmout, tmap ); } // Not sure why above set_union leaves duplicate entries, but // sort and force unique just to be sure. std::sort( tmap.begin(), tmap.end() ); auto tmit = std::unique( tmap.begin(), tmap.end(), &abouteq ); tmap.erase( tmit, tmap.end() ); // Treat all control points as possible discontinuities. tdisc = tmap; // Refine by adding two intermediate points to each cubic section // this is needed because the adaptive algorithm above uses derivatives // while our later reconstruction does not. vector < double > tref( ( tmap.size() - 1 ) * 3 + 1 ); for ( int i = 0; i < tmap.size() - 1; i++ ) { int iref = 3*i; double t = tmap[i]; double tnxt = tmap[i+1]; double dt = (tnxt-t)/3.0; tref[iref] = t; tref[iref+1] = t + dt; tref[iref+2] = t + 2 * dt; } tref.back() = tmap.back(); std::swap( tmap, tref ); // Convert tdisc to final parameterization. for ( int i = 0; i < tdisc.size(); i++ ) { tdisc[i] = ( tdisc[i] - rfirst ) / ( rlast - rfirst ); } // Pseudo cross sections // Not directly user-controlled, but an intermediate step in lofting the // surface. int npseudo = tmap.size(); vector < rib_data_type > rib_vec( npseudo ); vector < double > u_pseudo( npseudo ); for ( int i = 0; i < npseudo; i++ ) { // Assume linear interpolation means linear u/r relationship. double r = tmap[i]; double u = m_rtou.CompPnt( r ); VspCurve c; m_FoilSurf.GetUConstCurve( c, u ); vec3d v = c.CompPnt( 0 ); c.OffsetZ( -v.z() ); PropPositioner pp; pp.m_ParentProp = this->GetXSecSurf( 0 ); pp.m_Radius = r * radius; pp.m_Chord = m_ChordCurve.Comp( r ) * radius; pp.m_Twist = m_TwistCurve.Comp( r ); pp.m_XRotate = 0.0; pp.m_ZRotate = atan( -m_RakeCurve.Compdt( r ) ) * 180.0 / PI; pp.m_Rake = m_RakeCurve.Comp( r ) * radius; pp.m_Skew = m_SkewCurve.Comp( r ) * radius; pp.m_PropRot = m_Rotate(); pp.m_Feather = m_Feather(); pp.m_FoldOrigin = m_FoldAxOrigin; pp.m_FoldDirection = m_FoldAxDirection; pp.m_FoldAngle = m_FoldAngle(); pp.m_Reverse = rev; // Set a bunch of other pp variables. pp.SetCurve( c ); pp.Update(); rib_vec[i].set_f( pp.GetCurve().GetCurve() ); u_pseudo[i] = ( r - rfirst ) / ( rlast - rfirst ); } m_MainSurfVec.resize( 1 ); m_MainSurfVec.reserve( m_Nblade() ); m_MainSurfVec[0].SetMagicVParm( false ); m_MainSurfVec[0].SkinCubicSpline( rib_vec, u_pseudo, tdisc, false ); m_MainSurfVec[0].SetMagicVParm( true ); m_MainSurfVec[0].SetSurfType( PROP_SURF ); m_MainSurfVec[0].SetClustering( m_LECluster(), m_TECluster() ); m_MainSurfVec[0].SetFoilSurf( &m_FoilSurf ); if ( m_XSecSurf.GetFlipUD() ) { m_MainSurfVec[0].FlipNormal(); } if ( this->m_ReverseFlag() ) { m_MainSurfVec[0].FlipNormal(); } // UpdateEndCaps here so we only have to cap one blade. UpdateEndCaps(); m_MainSurfVec.resize( m_Nblade(), m_MainSurfVec[0] ); // Duplicate capping variables m_CapUMinSuccess.resize( m_Nblade(), m_CapUMinSuccess[0] ); m_CapUMaxSuccess.resize( m_Nblade(), m_CapUMaxSuccess[0] ); m_CapWMinSuccess.resize( m_Nblade(), m_CapWMinSuccess[0] ); m_CapWMaxSuccess.resize( m_Nblade(), m_CapWMaxSuccess[0] ); Matrix4d rot; for ( int i = 1; i < m_Nblade(); i++ ) { double theta = 360.0 * i / ( double )m_Nblade(); rot.loadIdentity(); rot.rotateX( theta ); m_MainSurfVec[i].Transform( rot ); } CalculateMeshMetrics( u_pseudo ); }
void FuselageScreen::GuiDeviceCallBack( GuiDevice* gui_device ) { //==== Find Fuselage Ptr ====// Geom* geom_ptr = m_ScreenMgr->GetCurrGeom(); if ( !geom_ptr || geom_ptr->GetType().m_Type != FUSELAGE_GEOM_TYPE ) { return; } FuselageGeom* fuselage_ptr = dynamic_cast< FuselageGeom* >( geom_ptr ); assert( fuselage_ptr ); if ( gui_device == &m_XSecIndexSelector ) { fuselage_ptr->SetActiveXSecIndex( m_XSecIndexSelector.GetIndex() ); fuselage_ptr->Update(); } else if ( gui_device == &m_XSecTypeChoice ) { int t = m_XSecTypeChoice.GetVal(); fuselage_ptr->SetActiveXSecType( t ); } else if ( gui_device == &m_ShowXSecButton ) { m_ScreenMgr->ShowScreen( ScreenMgr::VSP_XSEC_SCREEN ); } else if ( gui_device == &m_CutXSec ) { fuselage_ptr->CutActiveXSec(); } else if ( gui_device == &m_CopyXSec ) { fuselage_ptr->CopyActiveXSec(); } else if ( gui_device == &m_PasteXSec ) { fuselage_ptr->PasteActiveXSec(); } else if ( gui_device == &m_InsertXSec ) { fuselage_ptr->InsertXSec( ); } else if ( gui_device == &m_ReadFuseFileButton ) { int xsid = fuselage_ptr->GetActiveXSecIndex(); XSec* xs = fuselage_ptr->GetXSec( xsid ); if ( xs ) { XSecCurve* xsc = xs->GetXSecCurve(); if ( xsc ) { if ( xsc->GetType() == XS_FILE_FUSE ) { FileXSec* file_xs = dynamic_cast< FileXSec* >( xsc ); assert( file_xs ); string newfile = m_ScreenMgr->GetSelectFileScreen()->FileChooser( "Fuselage Cross Section", "*.fxs" ); file_xs->ReadXsecFile( newfile ); file_xs->Update(); xs->Update(); fuselage_ptr->Update(); } } } } else if ( gui_device == &m_AfReadFileButton ) { int xsid = fuselage_ptr->GetActiveXSecIndex(); XSec* xs = fuselage_ptr->GetXSec( xsid ); if ( xs ) { XSecCurve* xsc = xs->GetXSecCurve(); if ( xsc ) { if ( xsc->GetType() == XS_FILE_AIRFOIL ) { FileAirfoil* affile_xs = dynamic_cast< FileAirfoil* >( xsc ); assert( affile_xs ); string newfile = m_ScreenMgr->GetSelectFileScreen()->FileChooser( "Airfoil File", "*.{af,dat}", false ); affile_xs->ReadFile( newfile ); affile_xs->Update(); xs->Update(); fuselage_ptr->Update(); } } } } else if ( gui_device == &m_DesignPolicyChoice ) { // This is a hack to get the XSecXSlider to update its ranges. This // requires setting the ID to another valid FractionParm's ID. In this // case, m_YLocPercent of the same XSec. It will get set back to // m_XLocPercent in Update() before anyone notices the change. int xsid = fuselage_ptr->GetActiveXSecIndex(); FuseXSec* xs = (FuseXSec*) fuselage_ptr->GetXSec( xsid ); if ( xs ) { m_XSecXSlider.Update( xs->m_YLocPercent.GetID() ); } } SkinScreen::GuiDeviceCallBack( gui_device ); }
//==== Update Pod Screen ====// bool FuselageScreen::Update() { assert( m_ScreenMgr ); Geom* geom_ptr = m_ScreenMgr->GetCurrGeom(); if ( !geom_ptr || geom_ptr->GetType().m_Type != FUSELAGE_GEOM_TYPE ) { Hide(); return false; } SkinScreen::Update(); m_NumUSlider.Deactivate(); FuselageGeom* fuselage_ptr = dynamic_cast< FuselageGeom* >( geom_ptr ); assert( fuselage_ptr ); //==== Design ====// m_LengthSlider.Update( fuselage_ptr->m_Length.GetID() ); m_DesignPolicyChoice.Update( fuselage_ptr->m_OrderPolicy.GetID() ); //==== Skin & XSec Index Display ===// int xsid = fuselage_ptr->GetActiveXSecIndex(); m_XSecIndexSelector.SetIndex( xsid ); FuseXSec* xs = ( FuseXSec* ) fuselage_ptr->GetXSec( xsid ); if ( xs ) { bool firstxs = xsid == 0; bool lastxs = xsid == ( fuselage_ptr->GetXSecSurf( 0 )->NumXSec() - 1 ); //==== XSec ====// m_SectUTessSlider.Update( xs->m_SectTessU.GetID() ); if ( firstxs ) { m_SectUTessSlider.Deactivate(); } m_XSecXSlider.Update( xs->m_XLocPercent.GetID() ); m_XSecYSlider.Update( xs->m_YLocPercent.GetID() ); m_XSecZSlider.Update( xs->m_ZLocPercent.GetID() ); m_XSecXRotSlider.Update( xs->m_XRotate.GetID() ); m_XSecYRotSlider.Update( xs->m_YRotate.GetID() ); m_XSecZRotSlider.Update( xs->m_ZRotate.GetID() ); m_XSecSpinSlider.Update( xs->m_Spin.GetID() ); if ( firstxs && ( fuselage_ptr->m_OrderPolicy() == FuselageGeom::FUSE_MONOTONIC || fuselage_ptr->m_OrderPolicy() == FuselageGeom::FUSE_LOOP ) ) { m_XSecXSlider.Deactivate(); } if ( lastxs && fuselage_ptr->m_OrderPolicy() == FuselageGeom::FUSE_MONOTONIC ) { m_XSecXSlider.Deactivate(); } if ( lastxs && fuselage_ptr->m_OrderPolicy() == FuselageGeom::FUSE_LOOP ) { m_XSecXSlider.Deactivate(); m_XSecYSlider.Deactivate(); m_XSecZSlider.Deactivate(); m_XSecXRotSlider.Deactivate(); m_XSecYRotSlider.Deactivate(); m_XSecZRotSlider.Deactivate(); m_XSecSpinSlider.Deactivate(); } XSecCurve* xsc = xs->GetXSecCurve(); if ( xsc ) { m_XSecTypeChoice.SetVal( xsc->GetType() ); if ( lastxs && fuselage_ptr->m_OrderPolicy() == FuselageGeom::FUSE_LOOP ) { m_XSecTypeChoice.Deactivate(); } else { m_XSecTypeChoice.Activate(); } if ( lastxs && fuselage_ptr->m_OrderPolicy() == FuselageGeom::FUSE_LOOP ) { DisplayGroup ( NULL); } else if ( xsc->GetType() == XS_POINT ) { DisplayGroup( NULL ); } else if ( xsc->GetType() == XS_SUPER_ELLIPSE ) { DisplayGroup( &m_SuperGroup ); SuperXSec* super_xs = dynamic_cast< SuperXSec* >( xsc ); assert( super_xs ); m_SuperHeightSlider.Update( super_xs->m_Height.GetID() ); m_SuperWidthSlider.Update( super_xs->m_Width.GetID() ); m_SuperMSlider.Update( super_xs->m_M.GetID() ); m_SuperNSlider.Update( super_xs->m_N.GetID() ); } else if ( xsc->GetType() == XS_CIRCLE ) { DisplayGroup( &m_CircleGroup ); CircleXSec* circle_xs = dynamic_cast< CircleXSec* >( xsc ); assert( circle_xs ); m_DiameterSlider.Update( circle_xs->m_Diameter.GetID() ); } else if ( xsc->GetType() == XS_ELLIPSE ) { DisplayGroup( & m_EllipseGroup ); EllipseXSec* ellipse_xs = dynamic_cast< EllipseXSec* >( xsc ); m_EllipseHeightSlider.Update( ellipse_xs->m_Height.GetID() ); m_EllipseWidthSlider.Update( ellipse_xs->m_Width.GetID() ); } else if ( xsc->GetType() == XS_ROUNDED_RECTANGLE ) { DisplayGroup( & m_RoundedRectGroup ); RoundedRectXSec* rect_xs = dynamic_cast< RoundedRectXSec* >( xsc ); assert( rect_xs ); m_RRHeightSlider.Update( rect_xs->m_Height.GetID() ); m_RRWidthSlider.Update( rect_xs->m_Width.GetID() ); m_RRRadiusSlider.Update( rect_xs->m_Radius.GetID() ); } else if ( xsc->GetType() == XS_GENERAL_FUSE ) { DisplayGroup( &m_GenGroup ); GeneralFuseXSec* gen_xs = dynamic_cast< GeneralFuseXSec* >( xsc ); assert( gen_xs ); m_GenHeightSlider.Update( gen_xs->m_Height.GetID() ); m_GenWidthSlider.Update( gen_xs->m_Width.GetID() ); m_GenMaxWidthLocSlider.Update( gen_xs->m_MaxWidthLoc.GetID() ); m_GenCornerRadSlider.Update( gen_xs->m_CornerRad.GetID() ); m_GenTopTanAngleSlider.Update( gen_xs->m_TopTanAngle.GetID() ); m_GenBotTanAngleSlider.Update( gen_xs->m_BotTanAngle.GetID() ); m_GenTopStrSlider.Update( gen_xs->m_TopStr.GetID() ); m_GenBotStrSlider.Update( gen_xs->m_BotStr.GetID() ); m_GenUpStrSlider.Update( gen_xs->m_UpStr.GetID() ); m_GenLowStrSlider.Update( gen_xs->m_LowStr.GetID() ); } else if ( xsc->GetType() == XS_FOUR_SERIES ) { DisplayGroup( &m_FourSeriesGroup ); FourSeries* fs_xs = dynamic_cast< FourSeries* >( xsc ); assert( fs_xs ); m_FourChordSlider.Update( fs_xs->m_Chord.GetID() ); m_FourThickChordSlider.Update( fs_xs->m_ThickChord.GetID() ); m_FourCamberSlider.Update( fs_xs->m_Camber.GetID() ); m_FourCamberLocSlider.Update( fs_xs->m_CamberLoc.GetID() ); m_FourInvertButton.Update( fs_xs->m_Invert.GetID() ); m_FourNameOutput.Update( fs_xs->GetAirfoilName() ); } else if ( xsc->GetType() == XS_SIX_SERIES ) { DisplayGroup( &m_SixSeriesGroup ); SixSeries* ss_xs = dynamic_cast< SixSeries* >( xsc ); assert( ss_xs ); m_SixChordSlider.Update( ss_xs->m_Chord.GetID() ); m_SixThickChordSlider.Update( ss_xs->m_ThickChord.GetID() ); m_SixIdealClSlider.Update( ss_xs->m_IdealCl.GetID() ); m_SixASlider.Update( ss_xs->m_A.GetID() ); m_SixInvertButton.Update( ss_xs->m_Invert.GetID() ); m_SixNameOutput.Update( ss_xs->GetAirfoilName() ); m_SixSeriesChoice.Update( ss_xs->m_Series.GetID() ); } else if ( xsc->GetType() == XS_BICONVEX ) { DisplayGroup( &m_BiconvexGroup ); Biconvex* bi_xs = dynamic_cast< Biconvex* >( xsc ); assert( bi_xs ); m_BiconvexChordSlider.Update( bi_xs->m_Chord.GetID() ); m_BiconvexThickChordSlider.Update( bi_xs->m_ThickChord.GetID() ); } else if ( xsc->GetType() == XS_WEDGE ) { DisplayGroup( &m_WedgeGroup ); Wedge* we_xs = dynamic_cast< Wedge* >( xsc ); assert( we_xs ); m_WedgeChordSlider.Update( we_xs->m_Chord.GetID() ); m_WedgeThickChordSlider.Update( we_xs->m_ThickChord.GetID() ); m_WedgeThickLocSlider.Update( we_xs->m_ThickLoc.GetID() ); } else if ( xsc->GetType() == XS_FILE_FUSE ) { DisplayGroup( &m_FuseFileGroup ); FileXSec* file_xs = dynamic_cast< FileXSec* >( xsc ); assert( file_xs ); m_FileHeightSlider.Update( file_xs->m_Height.GetID() ); m_FileWidthSlider.Update( file_xs->m_Width.GetID() ); } else if ( xsc->GetType() == XS_FILE_AIRFOIL ) { DisplayGroup( &m_AfFileGroup ); FileAirfoil* affile_xs = dynamic_cast< FileAirfoil* >( xsc ); assert( affile_xs ); m_AfFileChordSlider.Update( affile_xs->m_Chord.GetID() ); m_AfFileInvertButton.Update( affile_xs->m_Invert.GetID() ); m_AfFileNameOutput.Update( affile_xs->GetAirfoilName() ); } } } return true; }
void WingScreen::GuiDeviceCallBack( GuiDevice* gui_device ) { //==== Find Fuselage Ptr ====// Geom* geom_ptr = m_ScreenMgr->GetCurrGeom(); if ( !geom_ptr || geom_ptr->GetType().m_Type != MS_WING_GEOM_TYPE ) { return; } WingGeom* wing_ptr = dynamic_cast< WingGeom* >( geom_ptr ); assert( wing_ptr ); if ( gui_device == &m_AfIndexSelector ) { wing_ptr->SetActiveAirfoilIndex( m_AfIndexSelector.GetIndex() ); wing_ptr->Update(); } else if ( gui_device == &m_AfModIndexSelector ) { wing_ptr->SetActiveAirfoilIndex( m_AfModIndexSelector.GetIndex() ); wing_ptr->Update(); } else if ( gui_device == &m_SectIndexSelector ) { wing_ptr->SetActiveXSecIndex( m_SectIndexSelector.GetIndex() ); wing_ptr->Update(); } else if ( gui_device == &m_SplitSectButton ) { int wsid = wing_ptr->GetActiveXSecIndex(); wing_ptr->SplitWingSect( wsid ); wing_ptr->Update(); } else if ( gui_device == &m_CutSectButton ) { int wsid = wing_ptr->GetActiveXSecIndex(); wing_ptr->CutWingSect( wsid ); wing_ptr->Update(); } else if ( gui_device == &m_CopySectButton ) { int wsid = wing_ptr->GetActiveXSecIndex(); wing_ptr->CopyWingSect( wsid ); wing_ptr->Update(); } else if ( gui_device == &m_PasteSectButton ) { int wsid = wing_ptr->GetActiveXSecIndex(); wing_ptr->PasteWingSect( wsid ); wing_ptr->Update(); } else if ( gui_device == &m_InsertSectButton ) { int wsid = wing_ptr->GetActiveXSecIndex(); wing_ptr->InsertWingSect( wsid ); wing_ptr->Update(); } else if ( gui_device == &m_AfTypeChoice ) { int t = m_AfTypeChoice.GetVal(); wing_ptr->SetActiveAirfoilType( t ); wing_ptr->Update(); } else if ( gui_device == &m_ShowXSecButton ) { m_ScreenMgr->ShowScreen( ScreenMgr::VSP_XSEC_SCREEN ); } else if ( gui_device == &m_CopyAfButton ) { int afid = wing_ptr->GetActiveAirfoilIndex(); wing_ptr->CopyAirfoil( afid ); } else if ( gui_device == &m_PasteAfButton ) { int afid = wing_ptr->GetActiveAirfoilIndex(); wing_ptr->PasteAirfoil(afid); wing_ptr->Update(); } else if ( gui_device == &m_ReadFuseFileButton ) { int xsid = wing_ptr->GetActiveAirfoilIndex(); XSec* xs = wing_ptr->GetXSec( xsid ); if ( xs ) { XSecCurve* xsc = xs->GetXSecCurve(); if ( xsc ) { if ( xsc->GetType() == XS_FILE_FUSE ) { FileXSec* file_xs = dynamic_cast< FileXSec* >( xsc ); assert( file_xs ); string newfile = m_ScreenMgr->GetSelectFileScreen()->FileChooser( "Fuselage Cross Section", "*.fxs" ); file_xs->ReadXsecFile( newfile ); file_xs->Update(); xs->Update(); wing_ptr->Update(); } } } } else if ( gui_device == &m_AfReadFileButton ) { int xsid = wing_ptr->GetActiveAirfoilIndex(); XSec* xs = wing_ptr->GetXSec( xsid ); if ( xs ) { XSecCurve* xsc = xs->GetXSecCurve(); if ( xsc ) { if ( xsc->GetType() == XS_FILE_AIRFOIL ) { FileAirfoil* affile_xs = dynamic_cast< FileAirfoil* >( xsc ); assert( affile_xs ); string newfile = m_ScreenMgr->GetSelectFileScreen()->FileChooser( "Airfoil File", "*.{af,dat}", false ); affile_xs->ReadFile( newfile ); affile_xs->Update(); xs->Update(); wing_ptr->Update(); } } } } else if ( gui_device == &m_UpPromoteButton ) { int xsid = wing_ptr->GetActiveAirfoilIndex(); XSec* xs = wing_ptr->GetXSec( xsid ); if ( xs ) { XSecCurve* xsc = xs->GetXSecCurve(); if ( xsc ) { if ( xsc->GetType() == XS_CST_AIRFOIL ) { CSTAirfoil* cst_xs = dynamic_cast< CSTAirfoil* >( xsc ); assert( cst_xs ); cst_xs->PromoteUpper(); cst_xs->Update(); xs->Update(); wing_ptr->Update(); } } } } else if ( gui_device == &m_LowPromoteButton ) { int xsid = wing_ptr->GetActiveAirfoilIndex(); XSec* xs = wing_ptr->GetXSec( xsid ); if ( xs ) { XSecCurve* xsc = xs->GetXSecCurve(); if ( xsc ) { if ( xsc->GetType() == XS_CST_AIRFOIL ) { CSTAirfoil* cst_xs = dynamic_cast< CSTAirfoil* >( xsc ); assert( cst_xs ); cst_xs->PromoteLower(); cst_xs->Update(); xs->Update(); wing_ptr->Update(); } } } } else if ( gui_device == &m_UpDemoteButton ) { int xsid = wing_ptr->GetActiveAirfoilIndex(); XSec* xs = wing_ptr->GetXSec( xsid ); if ( xs ) { XSecCurve* xsc = xs->GetXSecCurve(); if ( xsc ) { if ( xsc->GetType() == XS_CST_AIRFOIL ) { CSTAirfoil* cst_xs = dynamic_cast< CSTAirfoil* >( xsc ); assert( cst_xs ); cst_xs->DemoteUpper(); cst_xs->Update(); xs->Update(); wing_ptr->Update(); } } } } else if ( gui_device == &m_LowDemoteButton ) { int xsid = wing_ptr->GetActiveAirfoilIndex(); XSec* xs = wing_ptr->GetXSec( xsid ); if ( xs ) { XSecCurve* xsc = xs->GetXSecCurve(); if ( xsc ) { if ( xsc->GetType() == XS_CST_AIRFOIL ) { CSTAirfoil* cst_xs = dynamic_cast< CSTAirfoil* >( xsc ); assert( cst_xs ); cst_xs->DemoteLower(); cst_xs->Update(); xs->Update(); wing_ptr->Update(); } } } } else if ( ( gui_device == &m_FourFitCSTButton ) || ( gui_device == &m_SixFitCSTButton ) || ( gui_device == &m_AfFileFitCSTButton ) ) { int xsid = wing_ptr->GetActiveAirfoilIndex(); XSec* xs = wing_ptr->GetXSec( xsid ); if ( xs ) { XSecCurve* xsc = xs->GetXSecCurve(); if ( xsc ) { Airfoil* af_xs = dynamic_cast< Airfoil* >( xsc ); if ( af_xs ) { VspCurve c = af_xs->GetOrigCurve(); int deg = af_xs->m_FitDegree(); wing_ptr->SetActiveAirfoilType( XS_CST_AIRFOIL ); XSec* newxs = wing_ptr->GetXSec( xsid ); if ( newxs ) { XSecCurve* newxsc = newxs->GetXSecCurve(); if ( newxsc ) { if ( newxsc->GetType() == XS_CST_AIRFOIL ) { CSTAirfoil* cst_xs = dynamic_cast< CSTAirfoil* >( newxsc ); assert( cst_xs ); cst_xs->FitCurve( c, deg ); cst_xs->Update(); newxs->Update(); wing_ptr->Update(); } } } } } } } else if ( gui_device == &m_TestDriverGroupButton ) { int wsid = wing_ptr->GetActiveXSecIndex(); WingSect* wing_sect = dynamic_cast<WingSect*>(wing_ptr->GetXSec( wsid )); if ( wing_sect ) { vector< string > parm_ids = wing_sect->GetDriverParms(); wing_sect->m_DriverGroup.Test( parm_ids, 1e-4 ); } } GeomScreen::GuiDeviceCallBack( gui_device ); }
//==== Update Wing Screen ====// bool WingScreen::Update() { assert( m_ScreenMgr ); char str[256]; Geom* geom_ptr = m_ScreenMgr->GetCurrGeom(); if ( !geom_ptr || geom_ptr->GetType().m_Type != MS_WING_GEOM_TYPE ) { Hide(); return false; } GeomScreen::Update(); m_NumUSlider.Deactivate(); WingGeom* wing_ptr = dynamic_cast< WingGeom* >( geom_ptr ); assert( wing_ptr ); //==== Plan Parms ===// m_PlanSpanSlider.Update( wing_ptr->m_TotalSpan.GetID() ); m_PlanProjSpanSlider.Update( wing_ptr->m_TotalProjSpan.GetID() ); m_PlanChordSlider.Update( wing_ptr->m_TotalChord.GetID() ); m_PlanAreaSlider.Update( wing_ptr->m_TotalArea.GetID() ); m_LEClusterSlider.Update( wing_ptr->m_LECluster.GetID() ); m_TEClusterSlider.Update( wing_ptr->m_TECluster.GetID() ); sprintf( str, "%6.4f", wing_ptr->m_TotalProjSpan() * wing_ptr->m_TotalProjSpan() / wing_ptr->m_TotalArea() ); m_PlanAROutput.Update( str ); m_RootCapTypeChoice.Update( wing_ptr->m_CapUMinOption.GetID() ); m_TipCapTypeChoice.Update( wing_ptr->m_CapUMaxOption.GetID() ); if ( wing_ptr->m_CapUMinOption() == VspSurf::NO_END_CAP && wing_ptr->m_CapUMaxOption() == VspSurf::NO_END_CAP ) { m_CapTessSlider.Deactivate(); } else { m_CapTessSlider.Update( wing_ptr->m_CapUMinTess.GetID() ); } WingSect* root_sect = dynamic_cast<WingSect*>(wing_ptr->GetXSec( 0 )); if ( root_sect ) { m_IncidenceSlider.Update( root_sect->m_Twist.GetID() ); m_IncidenceLocSlider.Update( root_sect->m_TwistLoc.GetID() ); } sprintf( str, " %d", wing_ptr->NumXSec()-1 ); m_NumSectOutput.Update( str ); ////==== Wing Section Index Display ====// int ws_index = wing_ptr->GetActiveXSecIndex(); m_SectIndexSelector.SetIndex( ws_index ); WingSect* wing_sect = dynamic_cast<WingSect*>(wing_ptr->GetXSec( ws_index )); if ( wing_sect ) { m_SectUTessSlider.Update( wing_sect->m_SectTessU.GetID() ); m_RootClusterSlider.Update( wing_sect->m_RootCluster.GetID() ); m_TipClusterSlider.Update( wing_sect->m_TipCluster.GetID() ); m_WingDriverGroupBank.SetDriverGroup( &wing_sect->m_DriverGroup ); vector< string > parm_ids = wing_sect->GetDriverParms(); wing_sect->m_DriverGroup.UpdateGroup( parm_ids ); m_WingDriverGroupBank.Update( parm_ids ); m_SweepSlider.Update( wing_sect->m_Sweep.GetID() ); m_SweepLocSlider.Update( wing_sect->m_SweepLoc.GetID() ); m_SecSweepLocSlider.Update( wing_sect->m_SecSweepLoc.GetID() ); m_TwistSlider.Update( wing_sect->m_Twist.GetID() ); m_TwistLocSlider.Update( wing_sect->m_TwistLoc.GetID() ); m_DihedralSlider.Update( wing_sect->m_Dihedral.GetID() ); m_DihedralAbsRelToggle.Update( wing_ptr->m_RelativeDihedralFlag.GetID() ); m_TwistAbsRelToggle.Update( wing_ptr->m_RelativeTwistFlag.GetID() ); m_RotateFoilMatchDihedral.Update( wing_ptr->m_RotateAirfoilMatchDiedralFlag.GetID() ); sprintf( str, " %6.4f", wing_sect->GetProjectedSpan() ); m_SectProjSpanOutput.Update( str ); } //==== XSec Index Display ===// int xsid = wing_ptr->GetActiveAirfoilIndex(); m_AfIndexSelector.SetIndex( xsid ); m_AfModIndexSelector.SetIndex( xsid ); WingSect* ws = ( WingSect* ) wing_ptr->GetXSec( xsid ); if ( ws ) { XSecCurve* xsc = ws->GetXSecCurve(); if ( xsc ) { m_AfTypeChoice.SetVal( xsc->GetType() ); if ( xsc->GetType() == XS_POINT ) { DisplayGroup( NULL ); } else if ( xsc->GetType() == XS_SUPER_ELLIPSE ) { DisplayGroup( &m_SuperGroup ); SuperXSec* super_xs = dynamic_cast< SuperXSec* >( xsc ); assert( super_xs ); m_SuperHeightSlider.Update( super_xs->m_Height.GetID() ); m_SuperWidthSlider.Update( super_xs->m_Width.GetID() ); m_SuperMSlider.Update( super_xs->m_M.GetID() ); m_SuperNSlider.Update( super_xs->m_N.GetID() ); } else if ( xsc->GetType() == XS_CIRCLE ) { DisplayGroup( &m_CircleGroup ); CircleXSec* circle_xs = dynamic_cast< CircleXSec* >( xsc ); assert( circle_xs ); m_DiameterSlider.Update( circle_xs->m_Diameter.GetID() ); } else if ( xsc->GetType() == XS_ELLIPSE ) { DisplayGroup( & m_EllipseGroup ); EllipseXSec* ellipse_xs = dynamic_cast< EllipseXSec* >( xsc ); m_EllipseHeightSlider.Update( ellipse_xs->m_Height.GetID() ); m_EllipseWidthSlider.Update( ellipse_xs->m_Width.GetID() ); } else if ( xsc->GetType() == XS_ROUNDED_RECTANGLE ) { DisplayGroup( & m_RoundedRectGroup ); RoundedRectXSec* rect_xs = dynamic_cast< RoundedRectXSec* >( xsc ); assert( rect_xs ); m_RRHeightSlider.Update( rect_xs->m_Height.GetID() ); m_RRWidthSlider.Update( rect_xs->m_Width.GetID() ); m_RRRadiusSlider.Update( rect_xs->m_Radius.GetID() ); } else if ( xsc->GetType() == XS_GENERAL_FUSE ) { DisplayGroup( &m_GenGroup ); GeneralFuseXSec* gen_xs = dynamic_cast< GeneralFuseXSec* >( xsc ); assert( gen_xs ); m_GenHeightSlider.Update( gen_xs->m_Height.GetID() ); m_GenWidthSlider.Update( gen_xs->m_Width.GetID() ); m_GenMaxWidthLocSlider.Update( gen_xs->m_MaxWidthLoc.GetID() ); m_GenCornerRadSlider.Update( gen_xs->m_CornerRad.GetID() ); m_GenTopTanAngleSlider.Update( gen_xs->m_TopTanAngle.GetID() ); m_GenBotTanAngleSlider.Update( gen_xs->m_BotTanAngle.GetID() ); m_GenTopStrSlider.Update( gen_xs->m_TopStr.GetID() ); m_GenBotStrSlider.Update( gen_xs->m_BotStr.GetID() ); m_GenUpStrSlider.Update( gen_xs->m_UpStr.GetID() ); m_GenLowStrSlider.Update( gen_xs->m_LowStr.GetID() ); } else if ( xsc->GetType() == XS_FOUR_SERIES ) { DisplayGroup( &m_FourSeriesGroup ); FourSeries* fs_xs = dynamic_cast< FourSeries* >( xsc ); assert( fs_xs ); m_FourChordSlider.Update( fs_xs->m_Chord.GetID() ); m_FourThickChordSlider.Update( fs_xs->m_ThickChord.GetID() ); m_FourCamberSlider.Update( fs_xs->m_Camber.GetID() ); m_FourCamberLocSlider.Update( fs_xs->m_CamberLoc.GetID() ); m_FourInvertButton.Update( fs_xs->m_Invert.GetID() ); m_FourNameOutput.Update( fs_xs->GetAirfoilName() ); m_FourDegreeCounter.Update( fs_xs->m_FitDegree.GetID() ); m_FourEqArcLenButton.Update( fs_xs->m_EqArcLen.GetID() ); } else if ( xsc->GetType() == XS_SIX_SERIES ) { DisplayGroup( &m_SixSeriesGroup ); SixSeries* ss_xs = dynamic_cast< SixSeries* >( xsc ); assert( ss_xs ); m_SixChordSlider.Update( ss_xs->m_Chord.GetID() ); m_SixThickChordSlider.Update( ss_xs->m_ThickChord.GetID() ); m_SixIdealClSlider.Update( ss_xs->m_IdealCl.GetID() ); m_SixASlider.Update( ss_xs->m_A.GetID() ); m_SixInvertButton.Update( ss_xs->m_Invert.GetID() ); m_SixNameOutput.Update( ss_xs->GetAirfoilName() ); m_SixSeriesChoice.Update( ss_xs->m_Series.GetID() ); m_SixDegreeCounter.Update( ss_xs->m_FitDegree.GetID() ); } else if ( xsc->GetType() == XS_BICONVEX ) { DisplayGroup( &m_BiconvexGroup ); Biconvex* bi_xs = dynamic_cast< Biconvex* >( xsc ); assert( bi_xs ); m_BiconvexChordSlider.Update( bi_xs->m_Chord.GetID() ); m_BiconvexThickChordSlider.Update( bi_xs->m_ThickChord.GetID() ); } else if ( xsc->GetType() == XS_WEDGE ) { DisplayGroup( &m_WedgeGroup ); Wedge* we_xs = dynamic_cast< Wedge* >( xsc ); assert( we_xs ); m_WedgeChordSlider.Update( we_xs->m_Chord.GetID() ); m_WedgeThickChordSlider.Update( we_xs->m_ThickChord.GetID() ); m_WedgeThickLocSlider.Update( we_xs->m_ThickLoc.GetID() ); } else if ( xsc->GetType() == XS_FILE_FUSE ) { DisplayGroup( &m_FuseFileGroup ); FileXSec* file_xs = dynamic_cast< FileXSec* >( xsc ); assert( file_xs ); m_FileHeightSlider.Update( file_xs->m_Height.GetID() ); m_FileWidthSlider.Update( file_xs->m_Width.GetID() ); } else if ( xsc->GetType() == XS_FILE_AIRFOIL ) { DisplayGroup( &m_AfFileGroup ); FileAirfoil* affile_xs = dynamic_cast< FileAirfoil* >( xsc ); assert( affile_xs ); m_AfFileChordSlider.Update( affile_xs->m_Chord.GetID() ); m_AfFileInvertButton.Update( affile_xs->m_Invert.GetID() ); m_AfFileNameOutput.Update( affile_xs->GetAirfoilName() ); m_AfFileDegreeCounter.Update( affile_xs->m_FitDegree.GetID() ); } else if ( xsc->GetType() == XS_CST_AIRFOIL ) { DisplayGroup( &m_CSTAirfoilGroup ); CSTAirfoil* cst_xs = dynamic_cast< CSTAirfoil* >( xsc ); assert( cst_xs ); int num_up = cst_xs->m_UpDeg() + 1; int num_low = cst_xs->m_LowDeg() + 1; char str[255]; sprintf( str, "%d", cst_xs->m_UpDeg() ); m_UpDegreeOutput.Update( str ); sprintf( str, "%d", cst_xs->m_LowDeg() ); m_LowDegreeOutput.Update( str ); m_CSTInvertButton.Update( cst_xs->m_Invert.GetID() ); m_CSTContLERadButton.Update( cst_xs->m_ContLERad.GetID() ); m_CSTEqArcLenButton.Update( cst_xs->m_EqArcLen.GetID() ); if ( ( m_UpCoeffSliderVec.size() != num_up ) || ( m_LowCoeffSliderVec.size() != num_low ) ) { RebuildCSTGroup( cst_xs ); } for ( int i = 0; i < num_up; i++ ) { Parm *p = cst_xs->m_UpCoeffParmVec[i]; if ( p ) { m_UpCoeffSliderVec[i].Update( p->GetID() ); } } for ( int i = 0; i < num_low; i++ ) { Parm *p = cst_xs->m_LowCoeffParmVec[i]; if ( p ) { m_LowCoeffSliderVec[i].Update( p->GetID() ); } } if ( cst_xs->m_ContLERad() && num_low > 0 ) { m_LowCoeffSliderVec[0].Deactivate(); } } m_TECloseChoice.Update( xsc->m_TECloseType.GetID() ); m_TECloseGroup.Update( xsc->m_TECloseAbsRel.GetID() ); m_CloseThickSlider.Update( xsc->m_TECloseThick.GetID() ); m_CloseThickChordSlider.Update( xsc->m_TECloseThickChord.GetID() ); if ( xsc->m_TECloseType() != CLOSE_NONE ) { m_TECloseABSButton.Activate(); m_TECloseRELButton.Activate(); if ( xsc->m_TECloseAbsRel() == ABS ) { m_CloseThickSlider.Activate(); m_CloseThickChordSlider.Deactivate(); } else { m_CloseThickSlider.Deactivate(); m_CloseThickChordSlider.Activate(); } } else { m_CloseThickSlider.Deactivate(); m_CloseThickChordSlider.Deactivate(); m_TECloseABSButton.Deactivate(); m_TECloseRELButton.Deactivate(); } m_TETrimChoice.Update( xsc->m_TETrimType.GetID() ); m_TETrimGroup.Update( xsc->m_TETrimAbsRel.GetID() ); m_TrimXSlider.Update( xsc->m_TETrimX.GetID() ); m_TrimXChordSlider.Update( xsc->m_TETrimXChord.GetID() ); m_TrimThickSlider.Update( xsc->m_TETrimThick.GetID() ); m_TrimThickChordSlider.Update( xsc->m_TETrimThickChord.GetID() ); m_TrimXSlider.Deactivate(); m_TrimXChordSlider.Deactivate(); m_TrimThickSlider.Deactivate(); m_TrimThickChordSlider.Deactivate(); m_TETrimABSButton.Deactivate(); m_TETrimRELButton.Deactivate(); if ( xsc->m_TETrimType() != TRIM_NONE ) { m_TETrimABSButton.Activate(); m_TETrimRELButton.Activate(); } if ( xsc->m_TETrimType() == TRIM_X ) { if ( xsc->m_TETrimAbsRel() == ABS ) { m_TrimXSlider.Activate(); } else { m_TrimXChordSlider.Activate(); } } else if ( xsc->m_TETrimType() == TRIM_THICK ) { if ( xsc->m_TETrimAbsRel() == ABS ) { m_TrimThickSlider.Activate(); } else { m_TrimThickChordSlider.Activate(); } } m_AFThetaSlider.Update( xsc->m_Theta.GetID() ); m_AFScaleSlider.Update( xsc->m_Scale.GetID() ); m_AFDeltaXSlider.Update( xsc->m_DeltaX.GetID() ); m_AFDeltaYSlider.Update( xsc->m_DeltaY.GetID() ); m_AFShiftLESlider.Update( xsc->m_ShiftLE.GetID() ); } } return true; }
void StackScreen::GuiDeviceCallBack( GuiDevice* gui_device ) { //==== Find Fuselage Ptr ====// Geom* geom_ptr = m_ScreenMgr->GetCurrGeom(); if ( !geom_ptr || geom_ptr->GetType().m_Type != STACK_GEOM_TYPE ) { return; } StackGeom* stackgeom_ptr = dynamic_cast< StackGeom* >( geom_ptr ); assert( stackgeom_ptr ); if ( gui_device == &m_XSecIndexSelector ) { stackgeom_ptr->SetActiveXSecIndex( m_XSecIndexSelector.GetIndex() ); stackgeom_ptr->Update(); } else if ( gui_device == &m_XSecTypeChoice ) { int t = m_XSecTypeChoice.GetVal(); stackgeom_ptr->SetActiveXSecType( t ); } else if ( gui_device == &m_ShowXSecButton ) { m_ScreenMgr->ShowScreen( ScreenMgr::VSP_XSEC_SCREEN ); } else if ( gui_device == &m_CutXSec ) { stackgeom_ptr->CutActiveXSec(); } else if ( gui_device == &m_CopyXSec ) { stackgeom_ptr->CopyActiveXSec(); } else if ( gui_device == &m_PasteXSec ) { stackgeom_ptr->PasteActiveXSec(); } else if ( gui_device == &m_InsertXSec ) { stackgeom_ptr->InsertXSec( ); } else if ( gui_device == &m_ReadFuseFileButton ) { int xsid = stackgeom_ptr->GetActiveXSecIndex(); XSec* xs = stackgeom_ptr->GetXSec( xsid ); if ( xs ) { XSecCurve* xsc = xs->GetXSecCurve(); if ( xsc ) { if ( xsc->GetType() == XS_FILE_FUSE ) { FileXSec* file_xs = dynamic_cast< FileXSec* >( xsc ); assert( file_xs ); string newfile = m_ScreenMgr->GetSelectFileScreen()->FileChooser( "Fuselage Cross Section", "*.fxs" ); file_xs->ReadXsecFile( newfile ); file_xs->Update(); xs->Update(); stackgeom_ptr->Update(); } } } } else if ( gui_device == &m_AfReadFileButton ) { int xsid = stackgeom_ptr->GetActiveXSecIndex(); XSec* xs = stackgeom_ptr->GetXSec( xsid ); if ( xs ) { XSecCurve* xsc = xs->GetXSecCurve(); if ( xsc ) { if ( xsc->GetType() == XS_FILE_AIRFOIL ) { FileAirfoil* affile_xs = dynamic_cast< FileAirfoil* >( xsc ); assert( affile_xs ); string newfile = m_ScreenMgr->GetSelectFileScreen()->FileChooser( "Airfoil File", "*.{af,dat}" ); affile_xs->ReadFile( newfile ); affile_xs->Update(); xs->Update(); stackgeom_ptr->Update(); } } } } SkinScreen::GuiDeviceCallBack( gui_device ); }