tutorial.h

来自「finite element mesh 参数化有限元网格划分」· C头文件 代码 · 共 167 行

H
167
字号
/*! \page tutorial MeshMaker Tutorial
 *
In this tutorial you will learn how to work with the MeshMaker. You will add a button and a menu item, which, when clicked/selected, will open a working thread which will load a VRML file and change the background color.
The tutorial is designed for Microsoft Visual C++ 2005.

\ref s1 \n
\ref s2 \n
\ref s3 \n
\ref s4 \n
\ref s5 \n
\ref s6 \n
\ref s7 \n

\section s1 Step 1: Opening the workplace 
  - Unzip the MeskMaker.zip file into a directory of your choice. This will create a few subdirectories as well.
  - In the directory you chose, there should be a Visual Studio Workplace file, called MeshMaker.sln. Open this file in Visual Studio and this will open the developing workplace.
  - In the left frame you should see your Workspace data (if you don't see it, click on View->Workspace). There are 3 tabs in this frame:
		- Solution Explorer - All the files used by the workplace, divided into categories (Source Files, Header Files and Resource Files). Double clicking on any file name will open it in the main frame.
		- Resource View - All the available resources for the project, including the menu items and toolbar buttons.
		- Class View - All the classes defined in the project. Opening a class node will list all the class's variables and methods.

\section s2 Step 2: Adding a menu item
  - Open the menu bar by clicking the ResourceView tab->Menu->IDR_MAINFRAME.
  - On the right of the "Help" menu, add your own new menu, let's call it "MyMenu": simply click with the mouse on the right on the "Help" menu, and type "MyMenu". 
    Access the properties of the menu item, by right clicking on it, and choosing "properties". 
	Make sure the Pop-up option is true. Now you will add a menu item. Notice that now when you click on "MyMenu", an empty menu item is shown underneath it. 
	Click on the empty menu item and type "MyTutorial". You can access the ID of your menu item, by right clicking it, and choosing "properties".
	You can either leave it empty, in which case MFC will automatically fill in a proper ID for you, or choose an ID for yourself (for example, "ID_MY_TUTORIAL").

\section s3 Step 3: Adding a toolbar button
  - Open the toolbar by clicking the ResourceView tab-> Toolbar ->IDR_MAINFRAME.
  - Click (once) on the empty button on the right. This will allow you to edit a new button. 
  - In the main frame you have a zoomed view of the button. Draw on the button using the painting tools on the right. 
  - After you're done, double-click the button (in the top frame, where the whole toolbar is shown). 
    This will open the toolbar button properties on the right. 
	You can either choose an ID for your new button by yourself, or let MFC give the button a default ID. In this tutorial, we want the menu item and the toolbar button to have the same effect (the same function called), so we will give the new button the same ID as you gave the menu item above (for example, "ID_MY_TUTORIAL").
\n Now both the toolbar button and the menu item have the same ID.

\section s4 Step 4: Connect the button/menu item to a callback function
  - Now open the EventHandlerWizard to define a method that will be called when the application receives a message with the ID you previously defined for the menu item and toolbar button ("ID_MY_TUTORIAL"). 
    To open the EventHandlerWizard, right-click on the menu item you added previously, and choose "Add Event Handler...".
  - The "Command name" contains the ID you previously defined for the menu item and button ("ID_MY_TUTORIAL").
  - In the "Class name" listbox, pick the CMeshMakerView class. This will be the class that will handle the message.
  - In the "Function handler name" you are given a default function name ("OnMyTutorial "), which you can change if you want. 
  - In the "Messages" list box you have 2 choices - "COMMAND" and "UPDATE_COMMAND_UI". The first one handles a menu item or button click. The second message is called when the menu item or toolbar need to be redrawn. We can use this message to have a "button pressed/unpressed" and "menu item checked/unchecked" effect.
     \n Choose the "COMMAND" message and click "Add and Edit". The function declaration is automatically put into the CMeshMakerView header file, and the function is ready for your implementation (that is where you will be brought).

\section s5 Step 5: Writing the function
  - Now all we need is to implement the function.
	\n You will usually want your code to be executed, and at the same time be able to interact with the model around. In order to do this, your code needs to be in a separate thread. You can easily open a thread by using the function: startNewThread(), which receives a function name and a pointer holding the parameter(s) for the function. 
\code CWinThread* startNewThread(AFX_THREADPROC pfnThreadProc, LPVOID pParam); \endcode
The function for the thread should have the following signature: 
\code UINT funcName (LPVOID param);  \endcode
  - In our tutorial, we will write a function called "myCode", which will receive 2 parameters: a file name (of a VRML model) and a new background color. In the function signature above, you can see that the function actually receives only one parameter. If you want to send one parameter, simply send its address. If you want to send more than 1 parameter, you can define a struct that will contain all the parameters, and send the address of the struct. We will use the following struct:
\code typedef struct Params {
	char* filename;
	Color bgcolor;
} Params;  
\endcode
  - But first we will start the new thread. In the function CMeshMakerView::OnMyTutorial() add the following code:
\code void CMeshMakerView::OnMyTutorial() {
	// initialize the parameters
	Params* params = new Params;
	params->filename = _strdup("vrml\\demo.wrl");
	params->bgcolor.setColor(1.0, 0.0, 0.0);

	// start the new thread
	startNewThread(myCode, params);
}
\endcode
  - Now we will write the myCode function:
\code
UINT myCode (LPVOID param) {
	Params *params = (Params*)param;
	mesh->openVRMLFile(params->filename);
	renderer->setBgColor(params->bgcolor);
	renderer->refreshScreen ();
	return 0;
}
\endcode

\section s6 Step 6: Compile and run
  - Our program is now done, and we can compile and run it. 
  - To compile, click on 'Build'->'Build MeshMaker.exe' (F7 for shortcut). 
  - To run, click on 'Build'->'Execute MeshMaker.exe' (ctrl+F5 for shortcut ).

\section s7 Step 7: Extra features
  - Now let's add another feature to our button and menu item - the ability to make them checked/unchecked.
	We'll change the program so that when the button/menu item are first selected, the background color changes and a model is loaded, but when the button/menu item is selected again the screen is cleared.
  - To do so we will add a new variable which will remember the current state. To do so, go to the ClassView tab on the left. Right-click on CMeshMakerView and choose "Add->Add variable...". 
  - In "Variable Type" write "bool", in "Variable Name" write for example "butState". 
  - Click "Finish". The new variable was added to the CMeshMakerView class. 
  - To initialize it, go to the class constructor (CMeshMakerView::CMeshMakerView()), available in the CMeshMakerView.cpp file. Add the code:
\code butState = false; 
\endcode
  - When the butState variable is false, it means that the button/menu item are not checked.
  - Now let's go back to our function  OnMyTutorial(). Let's change it to have the following code:
\code void CMeshMakerView::OnMyTutorial() {

	// initialize the parameters
	Params* params = new Params;

	if (butState) {
		params->filename = NULL;
		params->bgcolor.setColor(1.0, 1.0, 1.0);
	}
	else {
		params->filename = _strdup("vrml\\demo.wrl");
		params->bgcolor.setColor(1.0, 0.0, 0.0);
	}
	butState = ! butState;

	// start the new thread
	startNewThread(myCode, params);
}
\endcode
  - When the button/menu item are first selected, the demo.wrl file will be loaded and the background color will change to red. The next time they are selected, the screen will be cleared with white background.
  - Let's update the myCode function accordingly, and add yet more extra functions - when the filename is not NULL, the demo.wrl file will be loaded, one of its vertices will be removed and the remaining hole will be triangulated. If no filename is given, a new model will be started, to which we will add 2 faces.
\code UINT myCode (LPVOID param) {
	Params *params = (Params*)param;
	if (params->filename) {
		mesh->openVRMLFile(params->filename);
		LinkedList<Face>* faces = new LinkedList<Face>();  // a list of the new faces to be created
		VertexID faceVertices[] = {0, 1, 3};
		Face face(faceVertices);
		faces->push_back(face);
		faceVertices[0] = 3;  faceVertices[1] = 1;  faceVertices[2] = 2;
		face.set(faceVertices);
		faces->push_back(face);
		LinkedList<FaceID> *newFaces = new LinkedList<FaceID>();
		mesh->removeVertexTriangulate(12, faces, newFaces);  
	}
	else {
		renderer->setAutoScale();
		mesh->startNewModel();
		VertexID vid1, vid2, vid3, vid4;
		Coord c1(0.0, 0.0, 0.0), c2(-1.5, 0.5, -1.0), c3(0.0, 2.0, 0.0), c4(2.0, 1.0, -2.0);
		mesh->addVertex(c1, vid1);
		mesh->addVertex(c2, vid2);
		mesh->addVertex(c3, vid3);
		mesh->addVertex(c4, vid4);

		VertexID faceVertices1[] = {vid1, vid2, vid3};
		VertexID faceVertices2[] = {vid1, vid3, vid4};
		Face face1(faceVertices1);
		Face face2(faceVertices2);
		FaceID fid1, fid2;
		mesh->addFace(face1, fid1);
		mesh->addFace(face2, fid2);
	}
	renderer->setBgColor(params->bgcolor);
	renderer->refreshScreen();
	return 0;
}
\endcode
  - And for the final touch, we will make the button look pressed/unpressed according to the variable butState, and the menu item checked/unchecked in the same way.
	To do so, we will use the message "UPDATE_COMMAND_UI" we saw earlier in the EventHandlerWizard.
  - Open the EventHandlerWizard again for the added menu item, choose CMeshMakerView in the Class Name box, then click on "UPDATE_COMMAND_UI" in the Messages box and click "Add and Edit" as before. 
  - Now let's edit the code:
\code void CMeshMakerView::OnUpdateMyTutorial(CCmdUI* pCmdUI)
{
	pCmdUI->SetCheck(butState);
	pCmdUI->Enable();
}
\endcode
  - Our program is ready. Compile and run it as before to see the results.
 */

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?