"white_dune" is a continuation of the "dune" project by Stephan F. White.
"dune" is a graphical VRML97 Editor, simple NURBS modeller and animation
tool with some OpenGL scene rendering capabilities.
In princple, the structure of the white_dune program can be written as:
The GUI of white_dune consists of 2 parts:
The 2D GUI mainloop of white_dune is event driven. Typical events are
mouse-movement, mouse-click, resize of window and so on.
Additionally the mainloop can produce timer events.
When a event occures, the matching callback function is started.
The callbacks work for every subwindow of white_dune.
The following image shows the subwindows (red text) of the mainwindow.
A additional callback OnUpdate is used to distribute
messages like UPDATE_FIELD or UPDATE_ADD_NODE to the
child classes of SceneView. OnUpdate is started by
the function UpdateViews of class Scene.
Some operations require additional input of data. Then a "Dialog"
is opened, that block the data input to all other windows.
The class Scene (Scene.h/cpp) can be identified with one VRML file. For example Scene.write() writes the VRML file to disk.
The global variable TheApp of class DuneApp (DuneApp.h/cpp) can be identified with things that are global to all VRML files.
The internals of each VRML Nodes are implemented in the files named NodeNodeName (for example NodeTransform (NodeTransform.h/cpp), NodeShape (NodeShape.h/cpp) or NodeBox (NodeBox.h/cpp)).
Every NodeNodeName.h file contain 2 classes: the
class NodeNodeName which contain functionality
like draw() for 3D rendering of shapes and the class
ProtoNodeName which are used to build the definitions
of the VRML97 standard.
For example, the definiton of the Transform Node in
the ISO/IEC 14772 standard
is implemented in the constructor of the class ProtoTransform
(in file NodeTransform.cpp):
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))); }Different fields are internally handled as integer values.
SFVec3f * | center (void) |
void | center (SFVec3f *value) |
void | center (SFVec3f &value) |
int | center_Index (void) |
Functionality common to all Nodes (like writing a Node to a file (Node.write())
is in the class Node (file Node.h/cpp). All NodeNodeName classes are
subclasses of the class Node.
Some of the memberfunctions of the class Node are virtual and can be
overwritten by the NodeNodeName classes (for example, the
class NodeScript need a special version of Node.write()).
Here is a list of important virtual Node memberfunctions:
Dune need to read and parse ("understand") VRML97 files.
This is done with using the tools lex/yacc (it looks like, the advanced
tools flex and bison from the GNU project are needed).
The file lexer.l do the lexical analysis (detect things like "what is
a string", "what is a number", "what is that VRML97 keyword").
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).
The buildin stringtype ("MyString") can be misleading, it act very
pointerlike. For example be carefull about constructs like the following:
MyString str = node->getProto()->getName(); str += "something";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 !
In this situation, it is better to use something like
MyString str = strdup(node->getProto()->getName()); str += "something";
MENUITEM "Something", ID_NEW_SOMETHINGunder
POPUP "Scripted PROTOs (slow)" BEGINand
ID_NEW_SOMETHING "Create a new Something Scripted PROTO\nSomething Sc$in dune.rc (or dune.english.rc for UNIX type compilation with configure))
_protos["Something"] = new ProtoSomething(this);in a matching place (sorted by the alphabet) in Scene::Scene() and add
#include "NodeSomething.h"to Scene.cpp
NODE_SOMETHING, ID_NEW_SOMETHING,to
static int buttonsScripted[] = {in Windows.cpp
sh batch/inserticon.sh NODE_SOMETHINGgimp will then open and select the matching node icons that has to be moved 16 pixels to left. Use "edit->cut" and "edit->paste" then move the icons to the left border of the gimp window. Draw your new icon in the new 16 pixels wide white gap.
case ID_NEW_SOMETHING: CreateGeometryNode("Something"); break;to MainWindow::OnCommand(int id)
The method to translate the program to a foreign language with
ASCII characters is rather simple: you need only to translate the strings
in the resource file "dune.rc".
The problems when trying to translate the program to a foreign
language with non ASCII characters is unknown.
From programmers point of view, always try to use the function "swLoadString" to get a string (e.g. for a errormessage) from the "dune.rc" file.
Copy "dune.rc" to a name containing the new language, e.g. "dune.english.rc"
or "dune.german.rc" and change the strings.
For example, to translate the line from dune.english.rc
POPUP "&File"to german language, use
POPUP "&Datei"The "&" sign marks the keyboard shortcut. The next character after "&" should not be ambient in the same level of a menu.
Take care about the fact, that each modification of the menus of white_dune in dune.rc requires the change of a all "dune.somelanguage.rc" files.
If you are able to handle autoconf input files, insert a configuration option
like "--with-menugerman" into the configure.in file for easy handling under
Linux/UNIX/MacOSX.
Otherwise (or to install the program with a new language under M$Windows)
you can simply copy "dune.somelanguage.rc" to "dune.rc" in the source
directory and recompile.
The name of most sourcefiles in the "src" directory is identical to the name of the major contained class.
The following class/filenames have special meanings:
If doxygen
is installed, a class hierarchy of white_dune can be produced by typing
make documentationand can then be found here.