//********************************************************************************
CBCGPBaseRibbonElement* CBCGPRibbonBackstageViewPanel::MouseButtonDown (CPoint point)
{
	CBCGPBaseRibbonElement* pHit = CBCGPRibbonMainPanel::MouseButtonDown (point);
	if (pHit == NULL || pHit->IsDisabled())
	{
		return NULL;
	}

	if (!m_rectPageTransition.IsRectEmpty())
	{
		StopPageTransition();
		OnPageTransitionFinished();

		if (pHit->GetRect().PtInRect(point))
		{
			SelectView(pHit);
			return pHit;
		}

		return NULL;
	}

	m_bSelectedByMouseClick = TRUE;
	SelectView(pHit);

	return pHit;
}
Exemplo n.º 2
0
void MyFrame::OnLoadNonLinearModes(wxCommandEvent& event)
{
  wxFileDialog *dlg = new wxFileDialog(this, _T("Load nonlinear modes"), uiState.currentWorkingDirectory, _T(""), _T("Modal Matrix Files(*.U)|*.U|All files(*.*)|*.*"), wxFD_OPEN /*| wxHIDE_READONLY*/, wxDefaultPosition);

  if ( dlg->ShowModal() == wxID_OK )
  {
    wxString nonLinearModesFilename( dlg->GetPath());
    SaveCurrentWorkingDirectory(nonLinearModesFilename);
    if( !nonLinearModesFilename.empty() )
    {
      int newrNonLin;
      double * newNonLinearModes = NULL;

      int n1;
      SetCursor(*wxHOURGLASS_CURSOR);
      const char * filename = nonLinearModesFilename.mb_str();
      int code = ReadMatrixFromDisk((char*)filename, &n1, &newrNonLin, &newNonLinearModes);
      SetCursor(*wxSTANDARD_CURSOR);

      if (code != 0)
      {
        this->errMsg( _T("Loading error"),  
          _T("Unable to load nonlinear modes from ") + nonLinearModesFilename );
        dlg->Destroy();
        return;
      }

      if (n1 != 3 * precomputationState.simulationMesh->getNumVertices())
      {
        this->errMsg( _T("Loading error"),  
          _T("The number of vertices in ") + nonLinearModesFilename + _T(" does not match the simulation mesh."));
        free(newNonLinearModes);
        dlg->Destroy();
        return;
      }

      // success
      delete(precomputationState.nonLinearModalMatrix);
      precomputationState.rNonLin = newrNonLin;
      precomputationState.nonLinearModalMatrix = new ModalMatrix(precomputationState.simulationMesh->getNumVertices(), precomputationState.rNonLin, newNonLinearModes);
      free(newNonLinearModes);

      precomputationState.nonLinearModesAvailable = true;

      modeSelectionControl->SetValue(1);

      SelectView(UIState::VIEW_NONLINEAR_MODES);
      SetAutoRenderingMagnitude(precomputationState.nonLinearModalMatrix);

      UpdateMenus();

      myGLCanvas->UpdateNonLinearModesRenderData();

      Refresh();
    }
  }

  dlg->Destroy();
}
Exemplo n.º 3
0
void MyFrame::ActivateVertexSelection(bool activate, int noViewSelect)
{
   uiState.vertexSelectionActivated = activate;
   menuBar->Check(ID_SelectFixedVertices, uiState.vertexSelectionActivated);

   if ((!noViewSelect) && (uiState.vertexSelectionActivated))
     SelectView(UIState::VIEW_SIMULATION_MESH);
}
Exemplo n.º 4
0
void DisplayElementsPanel::OnButtonDeleteViewClick(wxCommandEvent& event)
{
    if (mSeqData->NumFrames() == 0) return;
    int result = wxMessageBox("Are you sure you want to delete this View?", "Confirm Deletion", wxOK | wxCANCEL | wxCENTER);
    if (result != wxOK) return;

    ListCtrlViews->Freeze();
    long itemIndex = -1;

    for (;;) {
        itemIndex = ListCtrlViews->GetNextItem(itemIndex,
                                               wxLIST_NEXT_ALL,
                                               wxLIST_STATE_SELECTED);

        if (itemIndex == -1) break;

        // Got a selected item so handle it
        if( itemIndex > 0 )  // don't delete master view
        {
            mSequenceElements->RemoveView(itemIndex);
            wxString name = mSequenceElements->GetViewName(itemIndex);
            for(wxXmlNode* view=mViews->GetChildren(); view!=NULL; view=view->GetNext() )
            {
                if( view->GetAttribute("name") == name )
                {
                    mViews->RemoveChild(view);
                    delete view;
                    break;
                }
            }

            ListCtrlViews->DeleteItem(itemIndex);
            mNumViews--;
            break;
        }
        itemIndex = -1; // reset to delete next item which may have same index
    }
    ListCtrlViews->Thaw();
    ListCtrlViews->Refresh();
    mSequenceElements->SetCurrentView(MASTER_VIEW);
    SelectView("Master View");
    MarkViewsChanged();
    PopulateViews();
}
Exemplo n.º 5
0
void DisplayElementsPanel::OnButtonAddViewsClick(wxCommandEvent& event)
{
    if (mSeqData->NumFrames() == 0) return;
    wxTextEntryDialog dialog(this,_("Enter Name for View"),_("Create View"));
    int DlgResult=dialog.ShowModal();;
    if (DlgResult != wxID_OK) return;
    std::string viewName=dialog.GetValue().Trim().ToStdString();

    wxXmlNode* new_node = new wxXmlNode(wxXML_ELEMENT_NODE, "view");
    new_node->AddAttribute("name", viewName);
    new_node->AddAttribute("models", "");
    mViews->AddChild(new_node);

    AddViewToList(viewName, true);
    mSequenceElements->AddView(viewName);
    SelectView(viewName);
    MarkViewsChanged();
    PopulateViews();
}
//**********************************************************************************
BOOL CBCGPRibbonBackstageViewPanel::OnKey (UINT nChar)
{
	if (!m_rectPageTransition.IsRectEmpty())
	{
		return TRUE;
	}

	if ((nChar == VK_RIGHT || nChar == VK_TAB) && m_pHighlighted != NULL &&
		m_pHighlighted->GetBackstageAttachedView() != NULL)
	{
		CBCGPRibbonBackstageViewItemForm* pForm = DYNAMIC_DOWNCAST(CBCGPRibbonBackstageViewItemForm, m_pHighlighted->GetBackstageAttachedView());
		if (pForm != NULL && pForm->m_pWndForm->GetSafeHwnd() != NULL)
		{
			pForm->m_pWndForm->SetFocus();
			return FALSE;
		}
	}

	if (!CBCGPRibbonMainPanel::OnKey(nChar))
	{
		return FALSE;
	}

	switch (nChar)
	{
	case VK_HOME:
		GetParentWnd()->SetFocus();
		return TRUE;

	case VK_UP:
	case VK_DOWN:
		break;

	default:
		SelectView(m_pHighlighted);
		break;
	}

	GetParentWnd()->SetFocus();
	return TRUE;
}
Exemplo n.º 7
0
void MyFrame::OnViewRuntimeSimulation(wxCommandEvent& event)
{
  SelectView(UIState::VIEW_RUNTIME_SIMULATION);
}
Exemplo n.º 8
0
void MyFrame::OnViewNonlinearModes(wxCommandEvent& event)
{
  SelectView(UIState::VIEW_NONLINEAR_MODES);
}
Exemplo n.º 9
0
void MyFrame::OnViewSimulationMesh(wxCommandEvent& event)
{
  SelectView(UIState::VIEW_SIMULATION_MESH);
}
Exemplo n.º 10
0
void MyFrame::OnViewRenderingMesh(wxCommandEvent& event)
{
  SelectView(UIState::VIEW_RENDERING_MESH);
}
Exemplo n.º 11
0
void MyFrame::OnComputeNonLinearModes(wxCommandEvent& event)
{
  if (! ( (precomputationState.linearModesAvailable && 
           precomputationState.frequenciesAvailable &&
           precomputationState.modalDerivativesAvailable)
         || (precomputationState.sketchDataAvailable)
         )
     )
  {
    this->errMsg( _T("Cannot compute the simulation basis"),  
      _T("You must compute/provide at least one of the following:\n"
         "  (1) linear modes, frequencies, and modal derivatives, OR\n"
         "  (2) external simulation data.\n"
      ) );
      return;
  }

  char numNonLinearModesStringC[256];
  sprintf(numNonLinearModesStringC, "%d", uiState.numComputedNonLinearModes);

  wxDialog * dlg = new wxDialog(this, -1, _T("Compute nonlinear modes (via SVD)"),
    wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE, _T("dialogBox") );
  
  wxBoxSizer * dlgSizer = new wxBoxSizer(wxVERTICAL);

  // create dialog box to choose source of data
  wxString radioBoxChoices[2] = { 
    _T("Linear modes and modal derivatives"), _T("External simulation data") };

  wxRadioBox * dataOriginRadioBox = new wxRadioBox(dlg, -1, 
    _T("Source of data for nonlinear modes:"),
    wxDefaultPosition, wxDefaultSize, 2, radioBoxChoices, 
    2, wxRA_SPECIFY_ROWS);

  dataOriginRadioBox->Enable(0, precomputationState.modalDerivativesAvailable);
  dataOriginRadioBox->Enable(1, precomputationState.sketchDataAvailable);

  if (precomputationState.modalDerivativesAvailable)
    dataOriginRadioBox->SetSelection(0);
  else
    dataOriginRadioBox->SetSelection(1);

  dlgSizer->Add(dataOriginRadioBox, wxLEFT | wxRIGHT | wxBOTTOM | wxCENTER, 8);

  wxStaticText * numModesText = new wxStaticText(dlg, -1, 
       _T("Number of nonlinear modes: "), wxDefaultPosition, wxDefaultSize, 
       wxALIGN_CENTER, _T( "staticText"));

  wxTextCtrl * numModesControl = new wxTextCtrl(dlg, -1, 
      wxString(numNonLinearModesStringC, wxConvUTF8), 
      wxDefaultPosition, wxSize(100,-1));

  wxBoxSizer * numModesSizer = new wxBoxSizer(wxHORIZONTAL);
  numModesSizer->Add(numModesText, 0, wxCENTER);
  numModesSizer->Add(numModesControl, 0, wxCENTER);
  dlgSizer->Add(numModesSizer, 0, wxALL | wxCENTER, 8);

  dlgSizer->Add(dlg->CreateButtonSizer(wxOK | wxCANCEL), 0, 
    wxLEFT | wxRIGHT | wxBOTTOM | wxCENTER, 8);

  dlg->SetSizer(dlgSizer);
  dlgSizer->SetSizeHints(dlg);

  if (dlg->ShowModal() != wxID_OK)
  {
    delete(dlg);
    return;
  }

  wxString valueString = numModesControl->GetValue();
  int dataOrigin = dataOriginRadioBox->GetSelection();

  delete(dlg);

  long value;
  bool goodInput = valueString.ToLong(&value);

  if (goodInput)
  {
    if ((value <= 0) || (value > 16384))
      goodInput = false;
  }

  if (goodInput)
  {
    uiState.numComputedNonLinearModes = value;

    double * newNonLinearModes = NULL;

    SetCursor(*wxHOURGLASS_CURSOR);
    int code;
    NonLinearModesWorker(&code, dataOrigin,
      uiState.numComputedNonLinearModes,
      &newNonLinearModes );
    SetCursor(*wxSTANDARD_CURSOR);

    if (code != 0)
    {
      char s[96];
      if (code < 0)
        sprintf(s, "Nonlinear mode computation failed. Memory allocation error.");
      else
        sprintf(s, "Nonlinear mode computation failed. dgesvd exit code: %d\n", code);
      this->errMsg( _T("Nonlinear mode computation failed"),  wxString(s, wxConvUTF8));
      free(newNonLinearModes);
      return;
    }
    else
    {
      precomputationState.nonLinearModesAvailable = true;
      UpdateMenus();
 
      delete(precomputationState.nonLinearModalMatrix);
      precomputationState.rNonLin = uiState.numComputedNonLinearModes;
      precomputationState.nonLinearModalMatrix = new ModalMatrix(
        precomputationState.simulationMesh->getNumVertices(), 
        precomputationState.rNonLin, newNonLinearModes);
      free(newNonLinearModes);

      modeSelectionControl->SetValue(1);

      SelectView(UIState::VIEW_NONLINEAR_MODES);
      SetAutoRenderingMagnitude(precomputationState.nonLinearModalMatrix);

      UpdateMenus();

      myGLCanvas->UpdateNonLinearModesRenderData();

      Refresh();
    }
  }
  else
  {
    this->errMsg( _T("Invalid number of nonlinear modes"),  _T("Invalid number of nonlinear modes: ") + valueString );
  }
}
Exemplo n.º 12
0
void
AppView::InitView()
{
	PRINT(("AppView::InitView()\n"));

	m_preferences = new Preferences();

	SetViewColor(ui_color(B_PANEL_BACKGROUND_COLOR));

	m_pick_list_view = new PickListView("m_pick_list_view");

	AddOnView * aView;

	// Edit view
	aView = new EditorView(m_preferences);
	if (aView->InitCheck() == B_OK)
		m_pick_list_view->AddView(aView);
	else
		delete aView;

	// Copy view
	aView = new TAView(m_preferences);
	if (aView->InitCheck() == B_OK)
		m_pick_list_view->AddView(aView);
	else
		delete aView;

	// Name view
	aView = new NAView(m_preferences);
	if (aView->InitCheck() == B_OK)
		m_pick_list_view->AddView(aView);
	else
		delete aView;

	// MPEG view
	aView = new MPEGView(m_preferences);
	if (aView->InitCheck() == B_OK)
		m_pick_list_view->AddView(aView);
	else
		delete aView;

#ifdef _TTE_
	aView = new TTInfoView(m_preferences);
	if (aView->InitCheck() == B_OK)
		m_pick_list_view->AddView(aView);
	else
		delete aView;
#endif

	m_list_view = new AKListView("m_list_view",B_MULTIPLE_SELECTION_LIST);
	m_list_view->SetSelectionMessage(new BMessage(SELECTION_CHANGED));

	m_scroll_view = new BScrollView("m_scroll_view",m_list_view, 0, true, true);
	m_scroll_view->SetExplicitMinSize(BSize(300, 0));
	
	m_selected_string_view = new BStringView("m_selected_string_view","");
	m_selected_string_view->SetAlignment(B_ALIGN_RIGHT);
	m_selected_string_view->SetFontSize(10);

	m_apply_button = new BButton("m_apply_button", APPLY_BUTTON,
		new BMessage(MSG_APPLY));
	m_apply_button->SetEnabled(false);

	m_reset_button = new BButton("m_reset_button", RESET_BUTTON,
		new BMessage(MSG_RESET));
	m_reset_button->SetEnabled(true);

	m_status_bar = new BStatusBar("m_status_bar","0%","100%");
	m_status_bar->Hide();

	m_barberpole = new Barberpole("barberpole", B_WILL_DRAW|B_FRAME_EVENTS);

	m_status_card = new BCardLayout();

	BLayoutBuilder::Group<>(this, B_VERTICAL)
		.SetInsets(B_USE_WINDOW_INSETS, 0, B_USE_WINDOW_INSETS,
			B_USE_WINDOW_INSETS)
		.AddGroup(B_HORIZONTAL)
			.Add(m_pick_list_view)
			.Add(m_scroll_view)
		.End()
		.AddGroup(B_HORIZONTAL)
			.AddGlue()
			.Add(m_selected_string_view)
		.End()
		.AddGroup(B_HORIZONTAL)
			.Add(m_status_card)
			.Add(m_reset_button)
			.Add(m_apply_button);

	m_status_card->AddView(m_barberpole);
	m_status_card->AddView(m_status_bar);

	m_status_card->SetVisibleItem((int32)0);

/*
	BView *dragger = FindView("_dragger_");
	if (dragger) {
		RemoveChild(dragger); // tricky: avoid redraw bugs
		AddChild(dragger);
		dragger->SetViewColor(ViewColor());
		dragger->SetLowColor(LowColor());
	}
*/
	// The following is a kludge to give each addon view a
	// pointer to the list view. It's done this way, for now,
	// as the m_list_view is created after the add-ons
	// due to how the layout is done.

	AddOnView* addOnView;
	int numViews = m_pick_list_view->CountViews();
	for (int i = 0; i < numViews; i++) {
		addOnView = dynamic_cast<AddOnView*>(m_pick_list_view->ViewAt(i));
		addOnView->SetListView(m_list_view);
	}

	SelectView(m_preferences->GetMode());
}
Exemplo n.º 13
0
void DisplayElementsPanel::OnListCtrlViewsItemSelect(wxListEvent& event)
{
    int index = event.m_itemIndex;
    SelectView(ListCtrlViews->GetItemText(index, 1).ToStdString());
}
Exemplo n.º 14
0
void DisplayElementsPanel::OnViewSelect(wxCommandEvent &event) {
    SelectView(MainViewsChoice->GetString(MainViewsChoice->GetSelection()).ToStdString());
}
Exemplo n.º 15
0
void MyFrame::OnComputeLinearModes(wxCommandEvent& event)
{
  char numLinearModesStringC[256];

  int numSuggestedModes = uiState.numComputedLinearModes;
  if (uiState.firstModalComputation)
  {
    // increase the number of suggested modes based on the number of constrained vertices
    if (precomputationState.fixedVertices.size() == 2)
    {
      numSuggestedModes += 1;
    }
    else if (precomputationState.fixedVertices.size() == 1)
    {
      numSuggestedModes += 3;
    }
    else if (precomputationState.fixedVertices.size() == 0)
    {
      numSuggestedModes += 6;
    }
  }

  sprintf(numLinearModesStringC, "%d", numSuggestedModes);

  wxDialog * dlg = new wxDialog(this, -1, _T("Select number of modes"),
    wxDefaultPosition, wxDefaultSize, wxDEFAULT_DIALOG_STYLE, _T("dialogBox") );
  
  wxBoxSizer * dlgSizer = new wxBoxSizer(wxVERTICAL);

  wxStaticText * numModesText = new wxStaticText(dlg, -1, 
       _T("Number of modes: "), wxDefaultPosition, wxDefaultSize, 
       wxALIGN_CENTER, _T( "staticText"));

  wxTextCtrl * numModesControl = new wxTextCtrl(dlg, -1, 
      wxString(numLinearModesStringC, wxConvUTF8), wxDefaultPosition, wxSize(100,-1));

  wxBoxSizer * numModesSizer = new wxBoxSizer(wxHORIZONTAL);
  numModesSizer->Add(numModesText, 0, wxCENTER);
  numModesSizer->Add(numModesControl, 0, wxCENTER);
  dlgSizer->Add(numModesSizer, 0, wxALL | wxCENTER, 8);

  dlgSizer->Add(dlg->CreateButtonSizer(wxOK | wxCANCEL), 0, wxLEFT | wxRIGHT | wxBOTTOM | wxCENTER, 8);

  dlg->SetSizer(dlgSizer);
  dlgSizer->SetSizeHints(dlg);

  if (dlg->ShowModal() != wxID_OK)
  {
    delete(dlg);
    return;
  }

  wxString valueString = numModesControl->GetValue();

  delete(dlg);

  long value;
  bool goodInput = valueString.ToLong(&value);

  if (goodInput)
  {
    if ((value <= 0) || (value > 16384))
      goodInput = false;
  }

  if (goodInput)
  {
    int oldNumModes = uiState.numComputedLinearModes;
    uiState.numComputedLinearModes = value;

    double * newFrequencies = NULL;
    double * newLinearModes = NULL;
    int newr;

    SetCursor(*wxHOURGLASS_CURSOR);
    LinearModesWorker(
      uiState.numComputedLinearModes,
      &newr, &newFrequencies, &newLinearModes );
    SetCursor(*wxSTANDARD_CURSOR);

    if (newr != uiState.numComputedLinearModes)
    {
      uiState.numComputedLinearModes = oldNumModes;
      this->errMsg( _T("Linear mode computation failed"), 
             _T("Linear mode computation failed.") );
      free(newFrequencies);
      free(newLinearModes);
      return;
    }
    else
    {
      precomputationState.linearModesAvailable = true;
      uiState.firstModalComputation = false;
      UpdateMenus();
 
      delete(precomputationState.linearModalMatrix);
      precomputationState.rLin = uiState.numComputedLinearModes;
      precomputationState.linearModalMatrix = new ModalMatrix(
        precomputationState.simulationMesh->getNumVertices(), 
        precomputationState.rLin, newLinearModes);
      free(newLinearModes);

      free(precomputationState.frequencies);
      precomputationState.frequencies = newFrequencies;
      precomputationState.frequenciesAvailable = true;

      precomputationState.linearModesAvailable = true;
      uiState.eraseRangeHi = precomputationState.rLin;

      // set the rigid modes based on the number of constrained vertices
      if (precomputationState.fixedVertices.size() >= 3)
      {
        precomputationState.numRigidModes = 0;
      }
      else if (precomputationState.fixedVertices.size() == 2)
      {
        precomputationState.numRigidModes = 1;
      }
      else if (precomputationState.fixedVertices.size() == 1)
      {
        precomputationState.numRigidModes = 3;
      }
      else
      {
        precomputationState.numRigidModes = 6;
      }

      uiState.numComputedNonLinearModes = 2 * (precomputationState.rLin - precomputationState.numRigidModes);

      modeSelectionControl->SetValue(1);

      SelectView(UIState::VIEW_LINEAR_MODES);
      SetAutoRenderingMagnitude(precomputationState.linearModalMatrix);

      UpdateMenus();

      myGLCanvas->UpdateLinearModesRenderData();

      Refresh();
    }
  }
  else
  {
    this->errMsg( _T("Invalid number of linear modes"),  _T("Invalid number of linear modes: ") +  valueString );
  }
}
Exemplo n.º 16
0
void MyFrame::OnLoadLinearModes(wxCommandEvent& event)
{
  wxFileDialog *dlg = new wxFileDialog(this, _T("Load linear modes"), uiState.currentWorkingDirectory, _T(""), _T("Modal Matrix Files(*.Ulin)|*.Ulin|Modal Matrix Files(*.U)|*.U|All files(*.*)|*.*"), wxFD_OPEN /*| wxHIDE_READONLY*/, wxDefaultPosition);

  if ( dlg->ShowModal() == wxID_OK )
  {
    wxString linearModesFilename( dlg->GetPath());
    SaveCurrentWorkingDirectory(linearModesFilename);
    if( !linearModesFilename.empty() )
    {
      int newr;
      double * newLinearModes = NULL;

      int n1;
      SetCursor(*wxHOURGLASS_CURSOR);
      const char * filename = linearModesFilename.mb_str();
      int code = ReadMatrixFromDisk((char*)filename, &n1, &newr, &newLinearModes);
      SetCursor(*wxSTANDARD_CURSOR);

      if (code != 0)
      {
        this->errMsg( _T("Loading error"),  _T("Unable to load linear modes from ") + linearModesFilename );
        dlg->Destroy();
        return;
      }

      if (n1 != 3 * precomputationState.simulationMesh->getNumVertices())
      {
        this->errMsg( _T("Loading error"), _T("The number of vertices in ") + linearModesFilename + _T(" does not match the simulation mesh."));
        free(newLinearModes);
        dlg->Destroy();
        return;
      }

      if (precomputationState.frequenciesAvailable)
      {
        // check that the number of modes is consistent with the existing number of frequencies
        if (newr != precomputationState.rLin)
        {
          wxMessageDialog * confirmationDialog = new wxMessageDialog (this, _T("Warning: number of existing frequencies does not match the number of modes. Delete existing frequencies?"), _T("Mismatch in the number of frequencies"), wxYES_NO | wxICON_EXCLAMATION);

          if (confirmationDialog->ShowModal() != wxID_YES)
          {
            free(newLinearModes);
            delete(confirmationDialog);
            dlg->Destroy();
            return;
          }
          else
          {
            delete(confirmationDialog);
            free(precomputationState.frequencies);
            precomputationState.frequenciesAvailable = false;
          }
        }
      }

      // success
      delete(precomputationState.linearModalMatrix);
      precomputationState.rLin = newr;
      precomputationState.linearModalMatrix = new ModalMatrix(
        precomputationState.simulationMesh->getNumVertices(), precomputationState.rLin, newLinearModes);
      free(newLinearModes);

      precomputationState.linearModesAvailable = true;

      uiState.numComputedNonLinearModes = 2 * (precomputationState.rLin - precomputationState.numRigidModes);
      uiState.eraseRangeHi = precomputationState.rLin;

      modeSelectionControl->SetValue(1);

      SelectView(UIState::VIEW_LINEAR_MODES);
      SetAutoRenderingMagnitude(precomputationState.linearModalMatrix);

      UpdateMenus();

      myGLCanvas->UpdateLinearModesRenderData();

      Refresh();
    }
  }

  dlg->Destroy();
}