<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" "http://www.w3.org/TR/REC-html40/loose.dtd"> <html> <head> <title>White_dune developer documentation</title> </head> <body> <h1>White_dune developer documentation</h1> <h2>"white_dune", what's that ?</h2> <p> "white_dune" is a continuation of the "dune" project by Stephan F. White.<br> "dune" is a graphical VRML97 Editor, simple NURBS modeller and animation tool with some OpenGL scene rendering capabilities. </p> <h2>white_dune program overview</h2> <p> In princple, the structure of the white_dune program can be written as: <ol> <li> evaluate commandline parameters </li> <li> enter GUI (Grapical User Interface) mainloop </li> </ol> For details, see the file <b>main.cpp</b> </p> <h2>white_dune GUI overview</h2> <p> The GUI of white_dune consists of 2 parts: <ol> <li> 2D GUI<br> This handles two dimensional operations like opening windows, display icons, menus, buttons etc.<br> 2D GUI operations are seperated in a extra programming level, called swt (Stephan White Toolkit).<br> Currently, there are two different implementations of swt written in C, one for Motif/Lesstif (Unix/Linux) and one for Win32 (M$Windows).<br> For details, see the directory <b>swt</b>. swt use M$Windows rc files. For details about non M$Windows implementation see the directory <b>swt/rc</b>.<br> </li> <li>3D GUI<br> This handles three dimensional operations. This is displaying 3D data (rendering, implemented in OpenGL) and manipulating 3D Objects.<br> Some 3D operations, like mouseinput and reaction to desktop events (e.g. resize of Windows) are handled in connection with the 2D GUI (see the file <b>Scene3DView.cpp</b> for details).<br> Additional, there are other sources of information for manipulating 3D Objects (also handled in <b>Scene3DView.cpp</b>): input from devices like joystick, dialbox or spaceball. Code for input from this devices is located in the file <b>InputDevice.cpp</b>. </li> </ol> </p> <p> The 2D GUI mainloop of white_dune is event driven. Typical events are mouse-movement, mouse-click, resize of window and so on.<br> Additionally the mainloop can produce timer events.<br> When a event occures, the matching callback function is started. The callbacks work for every subwindow of white_dune.<br> The following image shows the subwindows (red text) of the mainwindow.<br> <center> <img src=dune.png alt="subwindows of the mainwindow" align="top"> </center><br> Some 2D GUI events are distributed to the different subwindows. The distribution of this events is based on inheritance.<br> The class <b>SceneView</b> define inheritable 2D GUI callbacks like <i>OnMouseMove</i> and is parent class to the classes <b>ChannelView</b>, <b>FieldView</b>, <b>Scene3DView</b>, <b>SceneGraphView</b>, <b>SceneTreeView</b>, <b>StatusBar</b>, <b>ToolbarWindow</b> and <b>PanedWindow</b>. <b>PanedWindow</b> is parent class to the class <b>MainWindow</b>. </p> <p> A additional callback <i>OnUpdate</i> is used to distribute messages like <i>UPDATE_FIELD</i> or <i>UPDATE_ADD_NODE</i> to the child classes of <b>SceneView</b>. <i>OnUpdate</i> is started by the function <i>UpdateViews</i> of class <b>Scene</b>.<br> </p> <p> Some operations require additional input of data. Then a "Dialog" is opened, that block the data input to all other windows.<br> <center> <img src=dialog.jpg alt="a example of a dialog" align="top"> </center><br> *Dialog classes are all inheritable from the class <b>Dialog</b>, which implements functions like SaveData() and Validate().<br> The layout of Dialogs (as well as the layout of the menues) is defined in the dune*.rc files. </p> <h2> VRML implementation overview</h2> <p> The class <b>Scene</b> (Scene.h/cpp) can be identified with one VRML file. For example Scene.write() writes the VRML file to disk. </p> <p> The global variable <i>TheApp</i> of class <b>DuneApp</b> (DuneApp.h/cpp) can be identified with things that are global to all VRML files. </p> <p> The internals of each VRML Nodes are implemented in the files named Node<b>NodeName</b> (for example Node<b>Transform</b> (NodeTransform.h/cpp), Node<b>Shape</b> (NodeShape.h/cpp) or Node<b>Box</b> (NodeBox.h/cpp)). </p> <p> Every Node<b>NodeName</b>.h file contain 2 classes: the class Node<b>NodeName</b> which contain functionality like draw() for 3D rendering of shapes and the class Proto<b>NodeName</b> which are used to build the definitions of the VRML97 standard.<br> For example, the definiton of the Transform Node in the ISO/IEC 14772 standard <br> <img src=standard.jpg alt="example from vrml standard" align="top"><br> is implemented in the constructor of the class Proto<b>Transform</b> (in file NodeTransform.cpp):<br> <pre> ProtoTransform::ProtoTransform(Scene *scene) : Proto(scene, "Transform") { addEventIn(MFNODE, "addChildren"); addEventIn(MFNODE, "removeChildren"); center.set(addExposedField(SFVEC3F, "center", new SFVec3f(0.0f, 0.0f, 0.0f))); children.set (addExposedField(MFNODE, "children", new MFNode(), NODE_CHILD)); rotation.set(addExposedField(SFROTATION, "rotation", new SFRotation(0.0f, 0.0f, 1.0f, 0.0f))); scale.set(addExposedField(SFVEC3F, "scale", new SFVec3f(1.0f, 1.0f, 1.0f), new SFFloat(0.0f))); scaleOrientation.set(addExposedField(SFROTATION, "scaleOrientation",new SFRotation(0.0f, 0.0f, 1.0f, 0.0f))); translation.set(addExposedField(SFVEC3F, "translation", new SFVec3f(0.0f, 0.0f, 0.0f))); bboxCenter.set(addField(SFVEC3F, "bboxCenter", new SFVec3f(0, 0, 0))); bboxSize.set(addField(SFVEC3F, "bboxSize", new SFVec3f(-1, -1, -1), new SFFloat(-1.0f))); } </pre><br> Different fields are internally handled as integer values. The variables center, children, rotation, scale, scaleOrientation, translation, bboxCenter and bboxSize are of type "fieldIndex", something like a readonly integer, that can be only set once.<br> There are NodeTransform memberfunctions to get and set field values. For example, the memberfunctions for the field "center" of class "NodeTransform" are:<br><br> <table border=0 cellpadding=0 cellspacing=0> <tr><td nowrap align=right valign=top><a href="doxygen_out_html/html/classSFVec3f.html">SFVec3f</a> * </td><td valign=bottom><a href="doxygen_out_html/html/classNodeTransform.html#a17">center</a> (void)</td></tr> <tr><td nowrap align=right valign=top>void </td><td valign=bottom><a href="doxygen_out_html/html/classNodeTransform.html#a18">center</a> (<a href="doxygen_out_html/html/classSFVec3f.html">SFVec3f</a> *value)</td></tr> <tr><td nowrap align=right valign=top>void </td><td valign=bottom><a href="doxygen_out_html/html/classNodeTransform.html#a19">center</a> (<a href="doxygen_out_html/html/classSFVec3f.html">SFVec3f</a> &value)</td></tr> <tr><td nowrap align=right valign=top>int </td><td valign=bottom><a href="doxygen_out_html/html/classNodeTransform.html#a20">center_Index</a> (void)</td></tr> </table> <br> The memberfunctions "something_Index()" deliver the integer number that is needed for example for a <a href="doxygen_out_html/html/classMoveCommand.html#a0"> MoveCommand</a> to move nodes in the scenegraph. </p> <p> Functionality common to all Nodes (like writing a Node to a file (Node.write()) is in the class Node (file Node.h/cpp). All Node<b>NodeName</b> classes are subclasses of the class Node.<br> Some of the memberfunctions of the class Node are virtual and can be overwritten by the Node<b>NodeName</b> classes (for example, the class NodeScript need a special version of Node.write()).<br> Here is a list of important virtual Node memberfunctions: <ul> <li><b><a href=doxygen_out_html/html/classNodeData.html#a17>getType()</a></b><br> deliver a <a href=doxygen_out_html/html/Node_8h.html#a83> value</a> needed to identify different nodes. For example, the transform node deliver NODE_TRANSFORM. <li><b><a href=doxygen_out_html/html/classNodeData.html#a2>write<a></b><br> write the node to a VRML file. <li><b><a href=doxygen_out_html/html/classNodeData.html#a30>update<a></b><br> update a node after a field change. <li><b><a href=doxygen_out_html/html/classNodeData.html#a63>setHandle<a></b><br> change a node field from handles (e.g. white boxes in the Scene3DView, that can be moved around with the mouse). <li><b><a href=doxygen_out_html/html/classNodeData.html#a62>getHandle<a></b><br> get the value of a handle. <li><b><a href=doxygen_out_html/html/classNodeData.html#a61>drawHandles<a></b><br> draw the handle in the Scene3DView. <li><b><a href=doxygen_out_html/html/classNodeData.html#a55>preDraw<a></b><br> do operations that prepare the drawing of nodes in the Scene3DView. <li><b><a href=doxygen_out_html/html/classNodeData.html#a58>draw<a></b><br> drawing the nodes in the Scene3DView (and internally to find mouse hits). </ul> </p> <h2>VRML97 parser</h2> <p> Dune need to read and parse ("understand") VRML97 files.<br> This is done with using the tools lex/yacc (it looks like, the advanced tools flex and bison from the GNU project are needed). <br> The file lexer.l do the lexical analysis (detect things like "what is a string", "what is a number", "what is that VRML97 keyword").<br> The file parser.y do the grammatical analysis (detect and prove, if the tokens found by the lexical analysis form valid VRML contructions (like Node or ROUTE statements). </p> <h2>Dangerous constructs</h2> <p> The buildin stringtype ("MyString") can be misleading, it act very pointerlike. For example be carefull about constructs like the following: <br> <pre> MyString str = node->getProto()->getName(); str += "something"; </pre> This do not only copy the name of a Proto of "node" to str and append "something" to it, it also appends "something" to the name of a Proto ! <p> </p> In this situation, it is better to use something like <br> <pre> MyString str = strdup(node->getProto()->getName()); str += "something"; </pre> </p> <h2> class overview</h2> <p> The name of most sourcefiles in the "src" directory is identical to the name of the major contained class. </p> <p> The following class/filenames have special meanings: <ul> <li> <b>Node</b>SomeNodeName:<br> Implement details for the VRML Node "SomeNodeName" </li> <li> Something<b>Dialog</b>, Something<b>Window</b>, Something<b>View</b>:<br> Implement details for the graphical user interface (GUI) </li> <li> Something<b>App</b>:<br> Implement details for data global to the whole application </li> <li> Something<b>Command</b>:<br> Implement details for sending internal commands </li> <li> <b>SF</b>Something, <b>MF</b>Something:<br> Implement details for VRML datatypes </li> </ul> </p> <p> If <a href=http://www.stack.nl/~dimitri/doxygen>doxygen</a> is installed, a class hierarchy of white_dune can be produced by typing <br> <br> <pre> make documentation </pre> and can then be found <a href=doxygen_out_html/html/hierarchy.html>here</a>. </p> </body>