Initial revision
authorspixx <spixx>
Tue, 25 Apr 2006 13:27:34 +0000 (13:27 +0000)
committerspixx <spixx>
Tue, 25 Apr 2006 13:27:34 +0000 (13:27 +0000)
19 files changed:
lsystem3d/src/callbacks.cpp [new file with mode: 0644]
lsystem3d/src/callbacks.h [new file with mode: 0644]
lsystem3d/src/coordinate.cpp [new file with mode: 0644]
lsystem3d/src/coordinate.h [new file with mode: 0644]
lsystem3d/src/lindenmayersystem.cpp [new file with mode: 0644]
lsystem3d/src/lindenmayersystem.h [new file with mode: 0644]
lsystem3d/src/lsystem.cpp [new file with mode: 0644]
lsystem3d/src/lsystemparameters.cpp [new file with mode: 0644]
lsystem3d/src/lsystemparameters.h [new file with mode: 0644]
lsystem3d/src/model.cpp [new file with mode: 0644]
lsystem3d/src/model.h [new file with mode: 0644]
lsystem3d/src/openglwindow.cpp [new file with mode: 0644]
lsystem3d/src/openglwindow.h [new file with mode: 0644]
lsystem3d/src/turtle.cpp [new file with mode: 0644]
lsystem3d/src/turtle.h [new file with mode: 0644]
lsystem3d/src/vector.cpp [new file with mode: 0644]
lsystem3d/src/vector.h [new file with mode: 0644]
lsystem3d/src/xmlstructure.cpp [new file with mode: 0644]
lsystem3d/src/xmlstructure.h [new file with mode: 0644]

diff --git a/lsystem3d/src/callbacks.cpp b/lsystem3d/src/callbacks.cpp
new file mode 100644 (file)
index 0000000..b4437b2
--- /dev/null
@@ -0,0 +1,180 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#include <unistd.h>
+
+#include <GL/freeglut.h>
+
+#include "callbacks.h"
+#include "openglwindow.h"
+
+extern OpenGLWindow *openglWindow;
+
+
+
+// GLUT callback functions
+// -----------------------
+
+/**
+ * Key press
+ * @param key the key
+ * @param x mouse x-coordinate
+ * @param y mouse y-coordinate
+ */
+void glutKeyboardCB(unsigned char key, int x, int y)
+{
+    switch (key)
+    {
+        // quit
+        case 27:    // escape key
+            glutLeaveMainLoop();
+            break;
+    
+        // zoom in
+        case '+':
+            openglWindow->zoomIn();
+            break;
+    
+        // zoom out    
+        case '-':
+            openglWindow->zoomOut();
+            break;
+            
+        // rotate around the y-axis
+        case 'y':
+        case 'Y':
+            openglWindow->rotateY();
+    
+        default:
+            break;
+    }
+}
+
+
+
+/**
+ * Special key press
+ * @param key the key
+ * @param x mouse x-coordinate
+ * @param y mouse y-coordinate
+ */
+void glutSpecialCB(int key, int x, int y)
+{
+    switch (key)
+    {
+        // move camera left
+        case GLUT_KEY_LEFT:
+            openglWindow->left();
+            break;
+    
+        // move camera right
+        case GLUT_KEY_RIGHT:
+            openglWindow->right();
+            break;
+    
+        // move camera up
+        case GLUT_KEY_UP:
+            openglWindow->up();
+            break;
+    
+        // move camera down
+        case GLUT_KEY_DOWN:
+            openglWindow->down();
+            break;
+            
+        // move camera forth
+        case GLUT_KEY_PAGE_UP:
+            openglWindow->forth();
+            break;
+            
+        // move camera back
+        case GLUT_KEY_PAGE_DOWN:
+            openglWindow->back();
+            break;
+    
+        default:
+            break;
+    }
+}
+
+
+
+/**
+ * Redraw of screen
+ */
+void glutDisplayCB()
+{
+    openglWindow->draw();
+}
+
+
+
+/**
+ * Idling
+ */
+void glutIdleCB()
+{
+    // spare some cpu cycles
+    usleep(1);
+}
+
+
+
+// GLUI callback functions
+// -----------------------
+
+/**
+ * Angle changes
+ * @param id not used
+ */
+void gluiSpinnerAngleCB(int id)
+{
+    // regenerate and draw l-system only if "live mode" is enabled
+    
+    if (openglWindow->liveActivated())
+    {
+        openglWindow->generate();
+        glutPostRedisplay();
+    }
+}
+
+
+
+/**
+ * Reset button pressed
+ * @param id not used
+ */
+void gluiButtonResetCB(int id)
+{
+    // place camera at initial position
+    openglWindow->defaultView();
+}
+
+
+
+/**
+ * Generate button pressed
+ * @param id not used
+ */
+void gluiButtonGenerateCB(int id)
+{
+    openglWindow->generate();
+}
diff --git a/lsystem3d/src/callbacks.h b/lsystem3d/src/callbacks.h
new file mode 100644 (file)
index 0000000..f827f4d
--- /dev/null
@@ -0,0 +1,81 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#ifndef CALLBACKS_H
+#define CALLBACKS_H
+
+
+
+// GLUT callback functions
+// -----------------------
+
+/**
+ * Key press
+ * @param key the key
+ * @param x mouse x-coordinate
+ * @param y mouse y-coordinate
+ */
+void glutKeyboardCB(unsigned char key, int x, int y);
+
+/**
+ * Special key press
+ * @param key the key
+ * @param x mouse x-coordinate
+ * @param y mouse y-coordinate
+ */
+void glutSpecialCB(int key, int x, int y);
+
+/**
+ * Redraw of screen
+ */
+void glutDisplayCB();
+
+/**
+ * Idling
+ */
+void glutIdleCB();
+
+
+
+// GLUI callback functions
+// -----------------------
+
+/**
+ * Angle changes
+ * @param id not used
+ */
+void gluiSpinnerAngleCB(int id);
+
+/**
+ * Reset button pressed
+ * @param id not used
+ */
+void gluiButtonResetCB(int id);
+
+/**
+ * Generate button pressed
+ * @param id not used
+ */
+void gluiButtonGenerateCB(int id);
+
+
+
+#endif
diff --git a/lsystem3d/src/coordinate.cpp b/lsystem3d/src/coordinate.cpp
new file mode 100644 (file)
index 0000000..026addb
--- /dev/null
@@ -0,0 +1,89 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#include "coordinate.h"
+
+
+
+/**
+ * Constructor
+ */
+Coordinate::Coordinate()
+{
+    setXYZ(0.0, 0.0, 0.0);
+}
+
+
+
+/**
+ * Destructor
+ */
+Coordinate::~Coordinate()
+{
+}
+
+
+
+/**
+ * Get x-coordinate
+ * @return the x-coordinate
+ */
+double Coordinate::getX()
+{
+    return _x;
+}
+
+
+
+/**
+ * Get y-coordinate
+ * @return the y-coordinate
+ */
+double Coordinate::getY()
+{
+    return _y;
+}
+
+
+
+/**
+ * Get z-coordinate
+ * @return the z-coordinate
+ */
+double Coordinate::getZ()
+{
+    return _z;
+}
+
+
+
+/**
+ * Set coordinate
+ * @param x the x-coordinate
+ * @param y the y-coordinate
+ * @param z the z-coordinate
+ */
+void Coordinate::setXYZ(double x, double y, double z)
+{
+    _x = x;
+    _y = y;
+    _z = z;
+}
diff --git a/lsystem3d/src/coordinate.h b/lsystem3d/src/coordinate.h
new file mode 100644 (file)
index 0000000..cac2a1a
--- /dev/null
@@ -0,0 +1,76 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#ifndef COORDINATE_H
+#define COORDINATE_H
+
+
+
+/**
+ * 3d coordinate
+ */
+class Coordinate
+{
+public:
+    /**
+     * Constructor
+     */
+    Coordinate();
+
+    /**
+     * Destructor
+     */
+    ~Coordinate();
+    
+    /**
+     * Get x-coordinate
+     * @return the x-coordinate
+     */
+    double getX();
+    
+    /**
+     * Get y-coordinate
+     * @return the y-coordinate
+     */
+    double getY();
+    
+    /**
+     * Get z-coordinate
+     * @return the z-coordinate
+     */
+    double getZ();
+    
+    /**
+     * Set coordinate
+     * @param x the x-coordinate
+     * @param y the y-coordinate
+     * @param z the z-coordinate
+     */
+    void setXYZ(double x, double y, double z);
+
+protected:
+    
+    double _x, _y, _z;
+};
+
+
+
+#endif
diff --git a/lsystem3d/src/lindenmayersystem.cpp b/lsystem3d/src/lindenmayersystem.cpp
new file mode 100644 (file)
index 0000000..9a66023
--- /dev/null
@@ -0,0 +1,370 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#include <cmath>
+
+#include <map>
+#include <iostream>
+#include <string>
+
+#include "lindenmayersystem.h"
+#include "model.h"
+#include "turtle.h"
+
+using namespace std;
+
+
+
+/**
+ * Constructor
+ * @param model the model for generation
+ */
+LindenmayerSystem::LindenmayerSystem(Model *model)
+{
+    _model = model;
+    _turtle = new Turtle(model);
+    
+    _axiom.clear();
+    _rules.clear();
+    _numIterations = 0;
+}
+
+
+
+/**
+ * Destructor
+ */
+LindenmayerSystem::~LindenmayerSystem()
+{
+    delete _turtle;
+}
+
+
+
+/**
+ * Set the initial rule (the axiom)
+ * @param axiom the axiom
+ */
+void LindenmayerSystem::setAxiom(string axiom)
+{
+    _axiom = verifyAndPreprocessRule(axiom);
+}
+
+
+
+/**
+ * Set one rule
+ * @param name rule name
+ * @param rule the rule
+ */
+void LindenmayerSystem::setRule(string name, string rule)
+{
+    _rules[name] = verifyAndPreprocessRule(rule);
+}
+
+
+
+/**
+ * Set the turn/pitch/roll angle
+ * @param degrees the angle, in degrees
+ */
+void LindenmayerSystem::setAngle(double degrees)
+{
+    // convert from degrees to radians
+    double radians = (degrees / 360.0) * (2.0 * M_PIl);
+    
+    _turtle->setAngle(radians);
+}
+
+
+
+/**
+ * Set the number of iterations
+ * @param numIterations number of iterations
+ */
+void LindenmayerSystem::setNumIterations(int numIterations)
+{
+    _numIterations = numIterations;
+}
+
+
+
+/**
+ * Get the initial rule (the axiom)
+ * @return the axiom
+ */
+string LindenmayerSystem::getAxiom()
+{
+    return unpreprocessRule(_axiom);
+}
+
+
+
+/**
+ * Get all rules
+ * @return the rules
+ */
+map<string,string> LindenmayerSystem::getRules()
+{
+    map<string,string> theUnpreprocessedRules;
+
+    // unpreprocess all rules
+    map<string,string>::iterator currentRule;
+    for (currentRule = _rules.begin(); currentRule != _rules.end(); currentRule++)
+    {
+        theUnpreprocessedRules[currentRule->first] = unpreprocessRule(currentRule->second);
+    }
+    
+    return theUnpreprocessedRules;
+}
+
+
+
+/**
+ * Get the turn/pitch/roll angle
+ * @return the angle, in degrees
+ */
+double LindenmayerSystem::getAngle()
+{
+    double radians = _turtle->getAngle();
+    
+    // convert from radians to degrees
+    double degrees = 360.0 * (radians / (2.0 * M_PIl));
+    
+    return degrees;
+}
+
+
+
+/**
+ * Get the number of iterations
+ * @return number of iterations
+ */
+int LindenmayerSystem::getNumIterations()
+{
+    return _numIterations;
+}
+
+
+
+/**
+ * Generate l-system data
+ */
+void LindenmayerSystem::generate()
+{
+    _model->clear();
+    
+    recursiveWalk(_axiom, _numIterations);
+    
+    _turtle->reset();
+}
+
+
+
+/**
+ * Walk through the rule string for specified number of levels
+ * @param rule the rule
+ * @param level current iteration level
+ */
+void LindenmayerSystem::recursiveWalk(string rule, int level)
+{
+    // Process every element in the rule string
+    for (int i = 0; i < rule.size(); i++)
+    {
+        switch (rule[i])
+        {
+            // walk
+            case '@':
+                
+                // ignore marker, i.e. the "@"
+                i++;
+                
+                // recursion
+                if (level == 0)
+                {
+                    // at lowest level, start rendering
+                    
+                    _turtle->walk();
+                }
+                else
+                {
+                    // more levels to go
+                    
+                    char ruleName[] = {rule[i], '\0'};
+                    recursiveWalk(_rules[ruleName], level - 1);
+                }
+                    
+                break;
+                
+                
+            // turn left
+            case '+':
+                
+                _turtle->turnLeft();
+                break;
+                
+                
+            // turn right
+            case '-':
+                
+                _turtle->turnRight();
+                break;
+                
+                
+            // pitch down
+            case '&':
+            
+                _turtle->pitchDown();
+                break;
+                
+                
+            // pitch up
+            case '^':
+                
+                _turtle->pitchUp();
+                break;
+                
+                
+            // roll left
+            case '\\':
+                
+                _turtle->rollLeft();
+                break;
+                
+                
+            // roll right
+            case '/':
+                    
+                _turtle->rollRight();
+                break;
+                
+                
+            // turn around 180 degrees
+            case '|':
+                
+                _turtle->turnAround();
+                break;
+                
+                
+            // save state to stack
+            case '[':
+                
+                _turtle->push();
+                break;
+                
+                
+            // restore state from stack
+            case ']':
+                
+                _turtle->pop();
+                break;
+                
+                
+            // first vertex in a filled surface
+            case '{':
+                
+                _turtle->fenceInBegin();
+                break;
+                
+                
+            // last vertex in a filled surface
+            case '}':
+                
+                _turtle->fenceInEnd();
+                break;
+                
+                
+            // one vertex in a filled surface
+            case 'f':
+                
+                _turtle->walk();
+                break;
+                
+                
+            // decrement diameter of segment
+            case '!':
+                
+                _turtle->decrementDiameter();
+                break;
+                
+                
+            // unknown operation
+            default :
+                
+                // TODO: filter these out when preprocessing
+                cerr << "Unknown operator in rule string:" << rule[i] << endl;
+                break;
+        }
+    }
+}
+
+
+
+/**
+ * Verify and preprocess one rule string
+ * @param ruleOrAxiom the rule
+ * @return the preprocessed rule
+ */
+string LindenmayerSystem::verifyAndPreprocessRule(string ruleOrAxiom)
+{
+    // for now, simply put "@" before every rewriting operator
+    // TODO: verifying
+    
+    string preprocessedRule;
+    
+    // check every element in rule
+    for (int i = 0; i < ruleOrAxiom.size(); i++)
+    {
+        // TODO: remove the A-Z limit: use strings, not single chars
+        if (ruleOrAxiom[i] >= 'A' && ruleOrAxiom[i] <= 'Z')
+        {
+            // mark as rewriting operator
+            preprocessedRule += '@';
+        }
+        preprocessedRule += ruleOrAxiom[i];
+    }
+
+    return preprocessedRule;
+}
+
+
+
+/**
+ * Unpreprocess one rule string
+ * @param ruleOrAxiom the rule
+ * @return the unpreprocessed rule
+ */
+string LindenmayerSystem::unpreprocessRule(string ruleOrAxiom)
+{
+    string unpreprocessedRule;
+    
+    // check every element in rule
+    for (int i = 0; i < ruleOrAxiom.size(); i++)
+    {
+        // ignore rewriting marker
+        if (ruleOrAxiom[i] != '@')
+        {
+            unpreprocessedRule += ruleOrAxiom[i];
+        }
+    }
+    
+    return unpreprocessedRule;
+}
diff --git a/lsystem3d/src/lindenmayersystem.h b/lsystem3d/src/lindenmayersystem.h
new file mode 100644 (file)
index 0000000..efadab9
--- /dev/null
@@ -0,0 +1,140 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#ifndef LINDENMAYERSYSTEM_H
+#define LINDENMAYERSYSTEM_H
+
+#include <map>
+#include <string>
+
+#include "model.h"
+#include "turtle.h"
+
+using namespace std;
+
+
+
+/**
+ * Lindenmayer System
+ */
+class LindenmayerSystem
+{
+public:
+    /**
+     * Constructor
+     * @param model the model for generation
+     */
+    LindenmayerSystem(Model *model);
+
+    /**
+     * Destructor
+     */
+    ~LindenmayerSystem();
+    
+    /**
+     * Set the initial rule (the axiom)
+     * @param axiom the axiom
+     */
+    void setAxiom(string axiom);
+    
+    /**
+     * Set one rule
+     * @param name rule name
+     * @param rule the rule
+     */
+    void setRule(string name, string rule);
+    
+    /**
+     * Set the turn/pitch/roll angle
+     * @param degrees the angle, in degrees
+     */
+    void setAngle(double degrees);
+    
+    /**
+     * Set the number of iterations
+     * @param numIterations number of iterations
+     */
+    void setNumIterations(int numIterations);
+    
+    /**
+     * Get the initial rule (the axiom)
+     * @return the axiom
+     */
+    string getAxiom();
+    
+    /**
+     * Get all rules
+     * @return the rules
+     */
+    map<string,string> getRules();
+    
+    /**
+     * Get the turn/pitch/roll angle
+     * @return the angle, in degrees
+     */
+    double getAngle();
+    
+    /**
+     * Get the number of iterations
+     * @return number of iterations
+     */
+    int getNumIterations();
+    
+    /**
+     * Generate l-system data
+     */
+    void generate();
+    
+protected:
+    
+    /**
+     * Walk through the rule string for specified number of levels
+     * @param rule the rule
+     * @param level current iteration level
+     */
+    void recursiveWalk(string rule, int level);
+    
+    /**
+     * Verify and preprocess one rule string
+     * @param ruleOrAxiom the rule
+     * @return the preprocessed rule
+     */
+    string verifyAndPreprocessRule(string ruleOrAxiom);
+    
+    /**
+     * Unpreprocess one rule string
+     * @param ruleOrAxiom the rule
+     * @return the unpreprocessed rule
+     */
+    string unpreprocessRule(string ruleOrAxiom);
+    
+    // Parameters
+    string _axiom;
+    map<string,string> _rules;      // TODO: use unsorted container?
+    int _numIterations;
+    
+    Model *_model;      // The model for generation
+    Turtle *_turtle;    // The rendering turtle
+};
+
+
+
+#endif
diff --git a/lsystem3d/src/lsystem.cpp b/lsystem3d/src/lsystem.cpp
new file mode 100644 (file)
index 0000000..27e51d3
--- /dev/null
@@ -0,0 +1,45 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <cstdlib>
+
+#include <GL/freeglut.h>
+
+#include "openglwindow.h"
+
+
+OpenGLWindow *openglWindow = NULL;
+
+
+
+int main(int argc, char *argv[])
+{
+    glutInit(&argc, argv);
+    
+    OpenGLWindow window;
+    
+    
+    return EXIT_SUCCESS;
+}
diff --git a/lsystem3d/src/lsystemparameters.cpp b/lsystem3d/src/lsystemparameters.cpp
new file mode 100644 (file)
index 0000000..c12e9e3
--- /dev/null
@@ -0,0 +1,138 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#include <iostream>
+#include <string>
+
+#include "lsystemparameters.h"
+
+using namespace std;
+
+
+
+/**
+ * Constructor
+ */
+LSystemParameters::LSystemParameters()
+{
+}
+
+
+
+/**
+ * Destructor
+ */
+LSystemParameters::~LSystemParameters()
+{
+}
+
+
+
+/**
+ * Load parameters from xml file
+ * @param lsystem put parameters into this l-system
+ * @param path path to xml file
+ */
+void LSystemParameters::load(LindenmayerSystem *lsystem, string path)
+{
+    if (lsystem)
+    {
+        try
+        {
+            // load
+            loadFromDisk(path);
+    
+            // axiom
+            findChild("axiom");
+            lsystem->setAxiom(getString());
+            
+            // rules
+            if (findChild("rule"))
+            {
+                do
+                {
+                    lsystem->setRule(getAttribute("name"), getString());
+                } while (findNextChild());
+            }
+    
+            // angle
+            findChild("angle");
+            lsystem->setAngle(getNumber());
+            
+            // iterations        
+            findChild("iterations");
+            lsystem->setNumIterations((int)getNumber());
+        }
+        catch (xmlpp::exception e)
+        {
+            cerr << "LSystemParameters::load(): " << e.what() << endl;
+        }
+    }
+    else
+    {
+        cerr << "invalid lsystem" << endl;
+    }
+}
+
+
+
+/**
+ * Save parameters to xml file
+ * @param lsystem get parameters from this l-system
+ * @param path path to xml file
+ */
+void LSystemParameters::save(LindenmayerSystem *lsystem, string path)
+{
+    if (lsystem && !lsystem->getAxiom().empty() && !lsystem->getRules().empty())
+    {
+        // new document with root node
+        createDocumentWithRoot("lsystem");
+        
+        // axiom
+        addChildToRoot("axiom");
+        addString(lsystem->getAxiom());
+        
+        // rules
+        map<string,string> rules = lsystem->getRules();
+        map<string,string>::iterator currentRule;
+        for (currentRule = rules.begin(); currentRule != rules.end(); currentRule++)
+        {
+            addChildToRoot("rule");
+            addString(currentRule->second);
+            addAttribute("name", currentRule->first);
+        }
+        
+        // angle
+        addChildToRoot("angle");
+        addNumber(lsystem->getAngle());
+        
+        // iterations
+        addChildToRoot("iterations");
+        addNumber(lsystem->getNumIterations());
+        
+        // save
+        saveToDisk(path);
+    }
+    else
+    {
+        cerr << "invalid lsystem" << endl;
+    }
+}
diff --git a/lsystem3d/src/lsystemparameters.h b/lsystem3d/src/lsystemparameters.h
new file mode 100644 (file)
index 0000000..1d80635
--- /dev/null
@@ -0,0 +1,67 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#ifndef LSYSTEMPARAMETERS_H
+#define LSYSTEMPARAMETERS_H
+
+#include <string>
+
+#include "lindenmayersystem.h"
+#include "xmlstructure.h"
+
+using namespace std;
+
+
+
+/**
+ * Save and load a l-system specification
+ */
+class LSystemParameters : protected XMLStructure
+{
+public:
+    /**
+     * Constructor
+     */
+    LSystemParameters();
+
+    /**
+     * Destructor
+     */
+    ~LSystemParameters();
+    
+    /**
+     * Load parameters from xml file
+     * @param lsystem put parameters into this l-system
+     * @param path path to xml file
+     */
+    void load(LindenmayerSystem *lsystem, string path);
+    
+    /**
+     * Save parameters to xml file
+     * @param lsystem get parameters from this l-system
+     * @param path path to xml file
+     */
+    void save(LindenmayerSystem *lsystem, string path);
+};
+
+
+
+#endif
diff --git a/lsystem3d/src/model.cpp b/lsystem3d/src/model.cpp
new file mode 100644 (file)
index 0000000..48308a0
--- /dev/null
@@ -0,0 +1,175 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#include "GL/gl.h"
+#include "GL/glu.h"
+
+#include "model.h"
+#include "vector.h"
+
+
+
+/**
+ * Constructor
+ */
+Model::Model()
+{
+    _displayList = glGenLists(1);
+}
+
+
+
+/**
+ * Destructor
+ */
+Model::~Model()
+{
+    glDeleteLists(_displayList, 1);
+}
+
+
+
+/**
+ * Connect two points
+ * @param diameter diameter of segment
+ * @param x1 x start point
+ * @param y1 y start point
+ * @param z1 z start point
+ * @param x2 x end point
+ * @param y2 y end point
+ * @param z2 z end point
+ */
+void Model::segment(double diameter, double x1, double y1, double z1, double x2, double y2, double z2)
+{
+    // wireframe
+    //
+    // glColor3f(1,1,1);
+    // glBegin(GL_LINES);
+    //     glVertex3d(x1, y1, z1);
+    //     glVertex3d(x2, y2, z2);
+    // glEnd();
+    
+    
+    
+    // solid
+    
+    // find rotation vector and angle of cylinder
+    
+    Vector initial(0.0,   1.0,   0.0);      // initial rotation of cylinder
+    Vector desired(x2-x1, y2-y1, z2-z1);    // desired rotation of cylinder
+    desired.normalize();
+    
+    // rotation angle 
+    double angle = initial.getAngle(desired);
+    
+    // rotation vector
+    Vector crossProduct = initial.getCrossProduct(desired);
+    crossProduct.normalize();
+    
+    
+    // render the cylinder
+    
+    GLUquadric *quadric = gluNewQuadric();
+    
+    glColor3f(1.0, 0.5, 0.0);
+        
+    glPushMatrix();
+        glTranslatef(x1, y1, z1);
+        glRotatef(angle, crossProduct.getX(), crossProduct.getY(), crossProduct.getZ());
+        glRotatef(-90, 1, 0, 0);
+        
+        gluCylinder(quadric, diameter, diameter, 1.0, 6, 6);
+    glPopMatrix();
+}
+
+
+
+/**
+ * Draw model to screen
+ */
+void Model::draw()
+{
+    glCallList(_displayList);
+}
+
+
+
+/**
+ * Clear the model
+ */
+void Model::clear()
+{
+    // TODO: not needed?
+}
+
+
+
+/**
+ * Start recording of drawing operations
+ */
+void Model::begin()
+{
+    glNewList(_displayList, GL_COMPILE);
+}
+
+
+
+/**
+ * Stop recording of drawing operations
+ */
+void Model::end()
+{
+    glEndList();
+}
+
+
+
+/**
+ * Begin creation of a filled surface
+ */
+void Model::fillBegin()
+{
+    glColor3f(0.0, 0.5, 0.0);
+    glBegin(GL_POLYGON);
+}
+
+
+
+/**
+ * End creation of a filled surface
+ */
+void Model::fillEnd()
+{
+    glEnd();
+}
+
+
+
+/**
+ * Create one vertex in the filled surface
+ * @param x x-coordinate
+ * @param y y-coordinate
+ * @param z z-coordinate
+ */
+void Model::point(double x, double y, double z)
+{
+    glVertex3d(x, y, z);
+}
diff --git a/lsystem3d/src/model.h b/lsystem3d/src/model.h
new file mode 100644 (file)
index 0000000..d7ebf26
--- /dev/null
@@ -0,0 +1,103 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#ifndef MODEL_H
+#define MODEL_H
+
+#include <GL/gl.h>
+
+
+
+/**
+ * The generated l-system model
+ * TODO: inheritance, i.e. Model<-OpenGLModel/WireModel/...?
+ */
+class Model
+{
+public:
+    /**
+     * Constructor
+     */
+    Model();
+
+    /**
+     * Destructor
+     */
+    ~Model();
+    
+    /**
+     * Connect two points
+     * @param diameter diameter of segment
+     * @param x1 x start point
+     * @param y1 y start point
+     * @param z1 z start point
+     * @param x2 x end point
+     * @param y2 y end point
+     * @param z2 z end point
+     */
+    void segment(double diameter, double x1, double y1, double z1, double x2, double y2, double z2);
+    
+    /**
+     * Draw model to screen
+     */
+    void draw();
+    
+    /**
+     * Clear the model
+     */
+    void clear();
+    
+    /**
+     * Start recording of drawing operations
+     */
+    void begin();
+    
+    /**
+     * Stop recording of drawing operations
+     */
+    void end();
+    
+    /**
+     * Begin creation of a filled surface
+     */
+    void fillBegin();
+    
+    /**
+     * End creation of a filled surface
+     */
+    void fillEnd();
+    
+    /**
+     * Create one vertex in the filled surface
+     * @param x x-coordinate
+     * @param y y-coordinate
+     * @param z z-coordinate
+     */
+    void point(double x, double y, double z);
+    
+protected:
+    
+    GLuint _displayList;    // all drawing operations
+};
+
+
+
+#endif
diff --git a/lsystem3d/src/openglwindow.cpp b/lsystem3d/src/openglwindow.cpp
new file mode 100644 (file)
index 0000000..ba5c753
--- /dev/null
@@ -0,0 +1,391 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#include <string>
+
+#include <glui.h>
+#include <GL/gl.h>
+#include <GL/glu.h>
+#include <GL/freeglut.h>
+
+#include "callbacks.h"
+#include "lindenmayersystem.h"
+#include "lsystemparameters.h"
+#include "model.h"
+#include "openglwindow.h"
+
+using namespace std;
+
+extern OpenGLWindow *openglWindow;
+
+
+
+/**
+ * Constructor
+ */
+OpenGLWindow::OpenGLWindow()
+{
+    // misc init
+    
+    openglWindow = this;
+    _busyGenerating = true;
+    lsystemParametersPath = "lsystem.xml";
+    defaultView();
+
+        
+    
+    // init GLUT & GLUI
+    // ----------------
+     
+    // drawing window
+    glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
+    glutInitWindowSize(800, 800); 
+    int _window = glutCreateWindow("lsystem");
+     
+    // return control after closing the window
+    glutSetOption(GLUT_ACTION_ON_WINDOW_CLOSE, 1);
+     
+    // register callbacks
+    glutKeyboardFunc(glutKeyboardCB);
+    glutSpecialFunc(glutSpecialCB);
+    glutDisplayFunc(glutDisplayCB);
+    GLUI_Master.set_glutIdleFunc(glutIdleCB);
+    
+    // GUI window
+    _glui = GLUI_Master.create_glui("lsystem");
+    
+    // model and l-system creation
+    _model = new Model;
+    _lsystem = new LindenmayerSystem(_model);
+    
+    // load lsystem parameters
+    _lsystemParameters.load(_lsystem, lsystemParametersPath.c_str());
+    
+    
+    
+    // create GLUI widgets
+    // -------------------
+    
+    // axiom
+    _axiomEditText = _glui->add_edittext("Axiom", GLUI_EDITTEXT_TEXT);
+    _axiomEditText->set_text((char *)_lsystem->getAxiom().c_str());
+    
+    // rules
+    // TODO: make dynamic!
+    GLUI_Panel *panel = _glui->add_panel("Rules", GLUI_PANEL_EMBOSSED);
+    _ruleEditTexts.push_back(_glui->add_edittext_to_panel(panel, "#1", GLUI_EDITTEXT_TEXT));
+    _ruleEditTexts.push_back(_glui->add_edittext_to_panel(panel, "#2", GLUI_EDITTEXT_TEXT));
+    _ruleEditTexts.push_back(_glui->add_edittext_to_panel(panel, "#3", GLUI_EDITTEXT_TEXT));
+    _ruleEditTexts.push_back(_glui->add_edittext_to_panel(panel, "#4", GLUI_EDITTEXT_TEXT));
+    _ruleEditTexts.push_back(_glui->add_edittext_to_panel(panel, "#5", GLUI_EDITTEXT_TEXT));
+    _ruleEditTexts[0]->set_w(200);
+    _ruleEditTexts[1]->set_w(200);
+    _ruleEditTexts[2]->set_w(200);
+    _ruleEditTexts[3]->set_w(200);
+    _ruleEditTexts[4]->set_w(200);
+    
+    // sync gui and l-system
+    map<string,string> rules = _lsystem->getRules();
+    map<string,string>::iterator currentRule;
+    int i = 0;
+    for (currentRule = rules.begin(); currentRule != rules.end(); currentRule++)
+    {
+        string rule = currentRule->first + "=" + currentRule->second;
+        // TODO: bounds?
+        _ruleEditTexts[i++]->set_text((char *)rule.c_str());
+    }
+    
+    // angle
+    _angleSpinner = _glui->add_spinner("Angle", GLUI_SPINNER_FLOAT, NULL, -1, (GLUI_Update_CB)gluiSpinnerAngleCB);
+    _angleSpinner->set_float_val(_lsystem->getAngle());
+    _angleSpinner->set_speed(1.0);
+    
+    // iterations
+    _iterationsSpinner = _glui->add_spinner("Iterations", GLUI_SPINNER_INT);
+    _iterationsSpinner->set_int_val(_lsystem->getNumIterations());
+    
+    
+    _glui->add_separator();
+    
+    
+    // live update
+    _liveUpdates = 1;
+    _liveCheckbox = _glui->add_checkbox("Live update", &_liveUpdates);
+    
+    // reset
+    _glui->add_button("Reset view", -1, (GLUI_Update_CB)gluiButtonResetCB);
+    
+    // generate
+    _glui->add_button("Generate", -1, (GLUI_Update_CB)gluiButtonGenerateCB);
+    
+    
+    _glui->set_main_gfx_window(_window);
+    
+     
+
+    
+    // init OpenGL view
+    // ----------------
+
+    // projection
+    glMatrixMode(GL_PROJECTION);
+    glLoadIdentity();
+    gluPerspective(65, 1, 1, 100);
+
+    // model view
+    glMatrixMode(GL_MODELVIEW);
+    glLoadIdentity();
+    gluLookAt(0.0, 0.0, 2.0,
+              0.0, 0.0, 0.0,
+              0.0, 1.0, 0.0);
+
+    glClearColor(0.0, 0.0, 0.0, 0.0);
+    
+    glShadeModel(GL_SMOOTH);
+
+    // light
+    GLfloat lightPosition[] = {0.0, 0.0, 2.0, 0.0};
+    GLfloat white[] = {1.0, 1.0, 1.0, 1.0};
+    glLightfv(GL_LIGHT0, GL_DIFFUSE, white);
+    glLightfv(GL_LIGHT0, GL_POSITION, lightPosition);
+    
+    glEnable(GL_COLOR_MATERIAL);
+    glEnable(GL_LIGHTING);
+    glEnable(GL_LIGHT0);
+    glEnable(GL_DEPTH_TEST);
+
+    glutMainLoop();
+}
+
+
+
+/**
+ * Destructor
+ */
+OpenGLWindow::~OpenGLWindow()
+{
+    // save current l-system to disk
+    _lsystemParameters.save(_lsystem, lsystemParametersPath.c_str());
+    
+    delete _lsystem;
+    delete _model;
+}
+
+
+
+/**
+ * Start generation of l-system data
+ */
+void OpenGLWindow::generate()
+{   
+    _busyGenerating = true;
+    
+        // read GLUI widgets and set corresponding l-system parameters
+    
+        // axiom
+        char *axiom = _axiomEditText->get_text();
+        _lsystem->setAxiom(axiom);
+        
+        // rules
+        vector<char *> rules;
+        rules.push_back(_ruleEditTexts[0]->get_text());
+        rules.push_back(_ruleEditTexts[1]->get_text());
+        rules.push_back(_ruleEditTexts[2]->get_text());
+        rules.push_back(_ruleEditTexts[3]->get_text());
+        rules.push_back(_ruleEditTexts[4]->get_text());
+        
+        for (int i = 0; i < rules.size(); i++)
+        {
+            if (rules[i][0] != '\0')
+            {
+                // non-empty rule
+
+                // separate rule name from the actual rule
+                string ruleName(rules[i], 1);
+                string theRule(rules[i]+2);
+                
+                _lsystem->setRule(ruleName, theRule);
+            }
+        }
+        
+        // angle
+        float angle = _angleSpinner->get_float_val();
+        _lsystem->setAngle(angle);
+        
+        // iterations
+        int iterations = _iterationsSpinner->get_int_val();
+        _lsystem->setNumIterations(iterations);
+
+        
+        // start generation
+        _model->begin();
+        _lsystem->generate();
+        _model->end();
+    
+    _busyGenerating = false;
+}
+
+
+
+/**
+ * Move camera left
+ */
+void OpenGLWindow::left()
+{
+    _xModel += 0.1;
+    glutPostRedisplay();
+}
+
+
+
+/**
+ * Move camera right
+ */
+void OpenGLWindow::right()
+{
+    _xModel -= 0.1;
+    glutPostRedisplay();
+}
+    
+    
+
+/**
+ * Move camera up
+ */
+void OpenGLWindow::up()
+{
+    _yModel -= 0.1;
+    glutPostRedisplay();
+}
+
+
+    
+/**
+ * Move camera down
+ */
+void OpenGLWindow::down()
+{
+    _yModel += 0.1;
+    glutPostRedisplay();
+}
+
+
+
+/**
+ * Move camera forth
+ */
+void OpenGLWindow::forth()
+{
+    _zModel += 1;
+    glutPostRedisplay();
+}
+
+
+
+/**
+ * Move camera back
+ */
+void OpenGLWindow::back()
+{
+    _zModel -= 1;
+    glutPostRedisplay();
+}
+
+
+
+/**
+ * Zoom in
+ */
+void OpenGLWindow::zoomIn()
+{
+    _scaleModel *= 1.1;
+    glutPostRedisplay();
+}
+
+
+
+/**
+ * Zoom out
+ */
+void OpenGLWindow::zoomOut()
+{
+     _scaleModel /= 1.1;
+    glutPostRedisplay();
+}
+
+
+
+/**
+ * Rotate around y-axis
+ */
+void OpenGLWindow::rotateY()
+{
+    _yRotationModel = int(_yRotationModel + 5.0) % 360;
+    glutPostRedisplay();
+}
+
+
+
+/**
+ * Draw l-system model to screen
+ */
+void OpenGLWindow::draw()
+{
+    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
+    
+    if (!_busyGenerating)
+    {
+        // ready for rendering
+        
+        glPushMatrix();
+            glTranslatef(_xModel, _yModel, _zModel);
+            glScalef(_scaleModel, _scaleModel, _scaleModel);
+            glRotatef(_yRotationModel, 0.0, 1.0, 0.0);
+            
+            _model->draw();
+        glPopMatrix();
+    }
+    
+    glutSwapBuffers();
+}
+
+
+
+/**
+ * Reset to default view
+ */
+void OpenGLWindow::defaultView()
+{
+    _xModel = _yModel = _zModel = 0.0;
+    _scaleModel = 1.0;
+    _yRotationModel = 0.0;
+}
+
+
+
+/**
+ * Check if live mode is activated
+ * @return true, if activated
+ */
+bool OpenGLWindow::liveActivated()
+{
+    return _liveUpdates;
+}
diff --git a/lsystem3d/src/openglwindow.h b/lsystem3d/src/openglwindow.h
new file mode 100644 (file)
index 0000000..53dbf61
--- /dev/null
@@ -0,0 +1,151 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#ifndef OPENGLWINDOW_H
+#define OPENGLWINDOW_H
+
+#include <string>
+#include <vector>
+
+#include <glui.h>
+
+#include "lindenmayersystem.h"
+#include "lsystemparameters.h"
+#include "model.h"
+
+using namespace std;
+
+
+
+/**
+ * OpenGL drawing context
+ */
+class OpenGLWindow
+{
+public:
+    /**
+     * Constructor
+     */
+    OpenGLWindow();
+
+    /**
+     * Destructor
+     */
+    ~OpenGLWindow();
+    
+    /**
+     * Start generation of l-system data
+     */
+    void generate();
+    
+    /**
+     * Move camera left
+     */
+    void left();
+    
+    /**
+     * Move camera right
+     */
+    void right();
+    
+    /**
+     * Move camera up
+     */
+    void up();
+    
+    /**
+     * Move camera down
+     */
+    void down();
+    
+    /**
+     * Move camera forth
+     */
+    void forth();
+    
+    /**
+     * Move camera back
+     */
+    void back();
+    
+    /**
+     * Zoom in
+     */
+    void zoomIn();
+            
+    /**
+     * Zoom out
+     */
+    void zoomOut();
+    
+    /**
+     * Rotate around y-axis
+     */
+    void rotateY();
+    
+    /**
+     * Draw l-system model to screen
+     */
+    void draw();
+    
+    /**
+     * Reset to default view
+     */
+    void defaultView();
+    
+    /**
+     * Check if live mode is activated
+     * @return true, if activated
+     */
+    bool liveActivated();
+    
+protected:
+    
+    // Model view
+    double _xModel,            // model coordinate (starting point)
+           _yModel,
+           _zModel;
+    double _scaleModel;        // model scale factor
+    double _yRotationModel;    // model rotation
+    
+    // L-system
+    LindenmayerSystem *_lsystem;                // l-system generator
+    Model *_model;                              // the generated l-system model
+    LSystemParameters _lsystemParameters;       // saves/loads l-system parameters from file
+    string lsystemParametersPath;               // where to find the l-system rules
+    
+    // Rendering window
+    int _window;                // the rendering window
+    bool _busyGenerating;       // currently generating?
+    
+    // GUI window
+    GLUI *_glui;                                // the GUI window
+    GLUI_EditText *_axiomEditText;              // axiom textbox
+    vector<GLUI_EditText *> _ruleEditTexts;     // rule textboxes
+    GLUI_Spinner *_angleSpinner;                // angle spinner
+    GLUI_Spinner *_iterationsSpinner;           // iteration spinner
+    GLUI_Checkbox *_liveCheckbox;               // live checkbox
+    int _liveUpdates;                           // status of live checkbox
+};
+
+
+
+#endif
diff --git a/lsystem3d/src/turtle.cpp b/lsystem3d/src/turtle.cpp
new file mode 100644 (file)
index 0000000..9847b5a
--- /dev/null
@@ -0,0 +1,291 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#include <cmath>
+
+#include <stack>
+
+#include "coordinate.h"
+#include "model.h"
+#include "turtle.h"
+#include "vector.h"
+
+
+
+/**
+ * Constructor
+ * @param model render this model
+ */
+Turtle::Turtle(Model *model)
+{
+    // initial position and orientation
+    reset();
+
+    // 90 degrees
+    _angle = M_PIl / 2.0;
+    
+    _model = model;
+}
+
+
+
+/**
+ * Destructor
+ */
+Turtle::~Turtle()
+{
+}
+
+
+
+/**
+ * Turn left
+ */
+void Turtle::turnLeft()
+{
+    // rotate around "up vector"
+    _heading.rotate(-_angle, _up);
+    _left.rotate(-_angle, _up);
+}
+
+
+
+/**
+ * Turn right
+ */
+void Turtle::turnRight()
+{
+    // rotate around "up vector"
+    _heading.rotate(_angle, _up);
+    _left.rotate(_angle, _up);
+}
+
+
+
+/**
+ * Pitch down
+ */
+void Turtle::pitchDown()
+{
+    // rotate around "left vector"
+    _heading.rotate(-_angle, _left);
+    _up.rotate(-_angle, _left);
+}
+
+
+
+/**
+ * Pitch up
+ */
+void Turtle::pitchUp()
+{
+    // rotate around "left vector"
+    _heading.rotate(_angle, _left);
+    _up.rotate(_angle, _left);
+}
+
+
+
+/**
+ * Roll left
+ */
+void Turtle::rollLeft()
+{
+    // rotate around "heading vector"
+    _left.rotate(_angle, _heading);
+    _up.rotate(_angle, _heading);
+}
+
+
+
+/**
+ * Roll right
+ */
+void Turtle::rollRight()
+{
+    // rotate around "heading vector"
+    _left.rotate(-_angle, _heading);
+    _up.rotate(-_angle, _heading);
+}
+
+
+
+/**
+ * Turn around
+ */
+void Turtle::turnAround()
+{
+    // rotate 180 degrees around "up vector"
+    _heading.rotate(M_PIl, _up);
+    _left.rotate(M_PIl, _up);
+}
+
+
+
+/**
+ * Walk forward
+ */
+void Turtle::walk()
+{
+    // start point
+    double startX = _position.getX();
+    double startY = _position.getY();
+    double startZ = _position.getZ();
+    
+    // end point
+    double endX = startX + _heading.getX();
+    double endY = startY + _heading.getY();
+    double endZ = startZ + _heading.getZ();
+    
+    
+    // move turtle to new position
+    _position.setXYZ(endX, endY, endZ);
+    
+    if (!_fenceMode)
+    {
+        // connect the points
+        _model->segment(_diameter,
+                         startX, startY, startZ,
+                         endX,   endY,   endZ);
+    }
+    else
+    {
+        // part of a filled surface
+        _model->point(endX, endY, endZ);
+    }
+}
+
+
+
+/**
+ * Save current state to stack
+ */
+void Turtle::push()
+{
+    // position
+    _positionStack.push(_position);
+    
+    // orientation
+    _headingStack.push(_heading);
+    _leftStack.push(_left);
+    _upStack.push(_up);
+    
+    // diameter
+    _diameterStack.push(_diameter);
+}
+
+
+
+/**
+ * Restore old state from stack
+ */
+void Turtle::pop()
+{
+    // position
+    _position = _positionStack.top();       _positionStack.pop();
+
+    // orientation
+    _heading = _headingStack.top();         _headingStack.pop();
+    _left = _leftStack.top();               _leftStack.pop();
+    _up = _upStack.top();                   _upStack.pop();
+    
+    // diameter
+    _diameter = _diameterStack.top();       _diameterStack.pop();
+}
+
+
+
+/**
+ * Reset to default state
+ */
+void Turtle::reset()
+{
+    _diameter = 0.1;
+    
+    _fenceMode = false;
+    
+    
+    // put turtle at (0,0,0), head upwards, back towards camera
+    
+    _position.setXYZ(0.0, 0.0, 0.0);
+    
+    _heading.setXYZ(0.0, 1.0, 0.0);
+    _left.setXYZ(1.0, 0.0, 0.0);
+    _up.setXYZ(0.0, 0.0, 1.0);
+}
+
+
+
+/**
+ * Decrement diameter of segment
+ */
+void Turtle::decrementDiameter()
+{
+    // TODO: dynamic value...
+    _diameter *= 0.8;
+}
+
+
+
+/**
+ * Begin creation of a filled surface
+ */
+void Turtle::fenceInBegin()
+{
+    _fenceMode = true;
+    
+    _model->fillBegin();
+    _model->point(_position.getX(), _position.getY(), _position.getZ());
+}
+
+
+
+/**
+ * End creation of a filled surface
+ */
+void Turtle::fenceInEnd()
+{
+    _model->fillEnd();
+    
+    _fenceMode = false;
+}
+
+
+
+/**
+ * Set turn/pitch/roll angle
+ * @param angle the angle, in radians
+ */
+void Turtle::setAngle(double radians)
+{
+    _angle = radians;
+}
+
+
+
+/**
+ * Get turn/pitch/roll angle
+ * @return the angle, in radians
+ */
+double Turtle::getAngle()
+{
+    return _angle;
+}
diff --git a/lsystem3d/src/turtle.h b/lsystem3d/src/turtle.h
new file mode 100644 (file)
index 0000000..d56c09a
--- /dev/null
@@ -0,0 +1,157 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#ifndef TURTLE_H
+#define TURTLE_H
+
+#include <stack>
+
+#include "coordinate.h"
+#include "model.h"
+#include "vector.h"
+
+using namespace std;
+
+
+
+/**
+ * The model renderer
+ */
+class Turtle
+{
+public:
+    /**
+     * Constructor
+     * @param model render this model
+     */
+    Turtle(Model *model);
+
+    /**
+     * Destructor
+     */
+    ~Turtle();
+    
+    /**
+     * Turn left
+     */
+    void turnLeft();
+    
+    /**
+     * Turn right
+     */
+    void turnRight();
+    
+    /**
+     * Pitch down
+     */
+    void pitchDown();
+    
+    /**
+     * Pitch up
+     */
+    void pitchUp();
+    
+    /**
+     * Roll left
+     */
+    void rollLeft();
+    
+    /**
+     * Roll right
+     */
+    void rollRight();
+    
+    /**
+     * Turn around
+     */
+    void turnAround();
+    
+    /**
+     * Walk forward
+     */
+    void walk();
+    
+    /**
+     * Save current state to stack
+     */
+    void push();
+    
+    /**
+     * Restore old state from stack
+     */
+    void pop();
+    
+    /**
+     * Reset to default state
+     */
+    void reset();
+    
+    /**
+     * Decrement diameter of segment
+     */
+    void decrementDiameter();
+    
+    /**
+     * Begin creation of a filled surface
+     */
+    void fenceInBegin();
+    
+    /**
+     * End creation of a filled surface
+     */
+    void fenceInEnd();
+    
+    /**
+     * Set turn/pitch/roll angle
+     * @param angle the angle, in radians
+     */
+    void setAngle(double radians);
+    
+    /**
+     * Get turn/pitch/roll angle
+     * @return the angle, in radians
+     */
+    double getAngle();
+    
+protected:
+    
+    Coordinate _position;       // current position
+    
+    Vector _heading;    // forward pointing vector
+    Vector _left;       // left pointing vector
+    Vector _up;         // up pointing vector
+    
+    double _angle;          // turn/pitch/roll angle
+    double _diameter;       // diameter of segment
+    bool _fenceMode;        // create filled surface?
+    
+    stack<Coordinate> _positionStack;       // positions in stack
+    stack<Vector> _headingStack;            // heading vectors in stack
+    stack<Vector> _leftStack;               // left vectors in stack
+    stack<Vector> _upStack;                 // up vectors in stack
+    stack<double> _diameterStack;           // diameters in stack
+    
+    Model *_model;    // the rendered model
+};
+
+
+
+#endif
diff --git a/lsystem3d/src/vector.cpp b/lsystem3d/src/vector.cpp
new file mode 100644 (file)
index 0000000..7b51842
--- /dev/null
@@ -0,0 +1,145 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#include <cmath>
+
+#include "vector.h"
+
+
+
+/**
+ * Constructor
+ * @param x the x-coordinate
+ * @param y the y-coordinate
+ * @param z the z-coordinate
+ */
+Vector::Vector(double x, double y, double z)
+{
+    setXYZ(x, y, z);
+}
+
+
+
+/**
+ * Destructor
+ */
+Vector::~Vector()
+{
+}
+
+
+
+/**
+ * Rotate around another vector
+ * @param angle rotation angle
+ * @param vector arbitrary vector to rotate around
+ */
+void Vector::rotate(double angle, Vector vector)
+{
+    double c = cos(angle);
+    double s = sin(angle);
+    
+    double x =
+    _x * (vector._x * vector._x * (1.0 - c) + c) +
+    _y * (vector._x * vector._y * (1.0 - c) + vector._z * s) +
+    _z * (vector._x * vector._z * (1.0 - c) - vector._y * s);
+    
+    double y =
+    _x * (vector._y * vector._x * (1.0 - c) - vector._z * s) +
+    _y * (vector._y * vector._y * (1.0 - c) + c) +
+    _z * (vector._y * vector._z * (1.0 - c) + vector._x * s);
+    
+    double z =
+    _x * (vector._z * vector._x * (1.0 - c) + vector._y * s) +
+    _y * (vector._z * vector._y * (1.0 - c) - vector._x * s) +
+    _z * (vector._z * vector._z * (1.0 - c) + c);
+    
+    _x = x;
+    _y = y;
+    _z = z;
+    
+    // TODO: call it from outside?
+    normalize();
+}
+
+
+
+/**
+ * Normalize vector
+ */
+void Vector::normalize()
+{
+    double length = sqrt(_x * _x + _y * _y + _z * _z);
+    
+    if (length != 0)
+    {
+        _x /= length;
+        _y /= length;
+        _z /= length;
+    }
+}
+
+
+
+/**
+ * Get scalar product of the vectors
+ * @param vector arbitrary vector
+ * @return the scalar product
+ */
+double Vector::getScalarProduct(Vector vector)
+{
+    double scalarProduct = getX() * vector.getX() +
+                           getY() * vector.getY() +
+                           getZ() * vector.getZ();
+    
+    return scalarProduct;
+}
+
+
+
+/**
+ * Get cross product of the vectors
+ * @param vector arbitrary vector
+ * @return the cross product
+ */
+Vector Vector::getCrossProduct(Vector vector)
+{
+    Vector crossProduct(getY() * vector.getZ() - getZ() * vector.getY(),
+                        getZ() * vector.getX() - getX() * vector.getZ(),
+                        getX() * vector.getY() - getY() * vector.getX());
+
+    return crossProduct;
+}
+
+
+
+/**
+ * Get angle between the vectors
+ * @param vector the second (normalized) vector
+ * @return the angle, in degrees
+ */
+double Vector::getAngle(Vector vector)
+{
+    double scalarProduct = getScalarProduct(vector);
+    double angle = (acos(scalarProduct) / (M_PIl * 2.0)) * 360.0;
+    
+    return angle;
+}
diff --git a/lsystem3d/src/vector.h b/lsystem3d/src/vector.h
new file mode 100644 (file)
index 0000000..df1e758
--- /dev/null
@@ -0,0 +1,84 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#ifndef VECTOR_H
+#define VECTOR_H
+
+#include "coordinate.h"
+
+
+
+/**
+ * 3d vector
+ */
+class Vector : public Coordinate
+{
+public:
+    /**
+     * Constructor
+     * @param x the x-coordinate
+     * @param y the y-coordinate
+     * @param z the z-coordinate
+     */
+    Vector(double x = 0.0, double y = 1.0, double z = 0.0);
+    
+    /**
+     * Destructor
+     */
+    ~Vector();
+    
+    /**
+     * Rotate around another vector
+     * @param angle rotation angle
+     * @param vector arbitrary vector to rotate around
+     */
+    void rotate(double angle, Vector vector);
+    
+    /**
+     * Normalize vector
+     */
+    void normalize();
+    
+    /**
+     * Get scalar product of the vectors
+     * @param vector arbitrary vector
+     * @return the scalar product
+     */
+    double getScalarProduct(Vector vector);
+    
+    /**
+     * Get cross product of the vectors
+     * @param vector arbitrary vector
+     * @return the cross product
+     */
+    Vector getCrossProduct(Vector vector);
+    
+    /**
+     * Get angle between the vectors
+     * @param vector the second (normalized) vector
+     * @return the angle, in degrees
+     */
+    double getAngle(Vector vector);
+};
+
+
+
+#endif
diff --git a/lsystem3d/src/xmlstructure.cpp b/lsystem3d/src/xmlstructure.cpp
new file mode 100644 (file)
index 0000000..b7466c0
--- /dev/null
@@ -0,0 +1,231 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#include <string>
+
+#include <libxml++/document.h>
+#include <libxml++/nodes/element.h>
+#include <libxml++/nodes/node.h>
+#include <libxml++/parsers/domparser.h>
+
+#include <glibmm/stringutils.h>
+
+#include "xmlstructure.h"
+
+using namespace std;
+
+
+
+/**
+ * Constructor
+ */
+XMLStructure::XMLStructure()
+{
+    _rootElement = NULL;
+    _activeElement = NULL;
+    _activeDocument = NULL;
+    _activeChildInList = NULL;
+}
+
+
+
+/**
+ * Destructor
+ */
+XMLStructure::~XMLStructure()
+{
+    delete _activeDocument;
+}
+
+
+
+/**
+ * Create new document with root node
+ * @param rootName name of root
+ */
+void XMLStructure::createDocumentWithRoot(string rootName)
+{
+    delete _activeDocument;
+    _activeDocument = new xmlpp::Document;
+    
+    _rootElement = _activeDocument->create_root_node(rootName);
+}
+
+
+
+/**
+ * Add new child to root
+ * @param name name of child
+ */
+void XMLStructure::addChildToRoot(string name)
+{
+    _activeElement = _rootElement->add_child(name);
+}
+
+
+
+/**
+ * Add a string as content of current child
+ * @param text the text
+ */
+void XMLStructure::addString(string text)
+{
+    _activeElement->add_child_text(text);
+}
+
+
+
+/**
+ * Add a number as content of current child
+ * @param value the number
+ */
+void XMLStructure::addNumber(double value)
+{
+    // convert double -> string
+    string numberAsString = Glib::Ascii::dtostr(value);
+    
+    addString(numberAsString);
+}
+
+
+
+/**
+ * Add attribute to current child
+ * @param name name of attribute
+ * @param value value of attribute
+ */
+void XMLStructure::addAttribute(string name, string value)
+{
+    _activeElement->set_attribute(name, value);
+}
+
+
+
+/**
+ * Save document to file
+ * @param path path to file
+ */
+void XMLStructure::saveToDisk(string path)
+{
+    _activeDocument->write_to_file_formatted(path);
+}
+
+
+
+/**
+ * Load document from file
+ * @param path path to file
+ */
+void XMLStructure::loadFromDisk(string path)
+{
+    // TODO: validate?
+    //_parser.set_validate(true);
+    
+    _parser.parse_file(path);
+        
+    _rootElement = _parser.get_document()->get_root_node();
+}
+
+
+
+/**
+ * Find all children with the specified name
+ * @param name name of children
+ * @return true if found, else false
+ */
+bool XMLStructure::findChild(string name)
+{
+    _activeList = _rootElement->get_children(name);
+    _activeChildInList = _activeList.begin();
+    
+    return !_activeList.empty();
+}
+
+
+
+/**
+ * Find next child in current search result list
+ * @return true if found, else false
+ */
+bool XMLStructure::findNextChild()
+{
+    _activeChildInList++;
+    
+    bool endOfList = false;
+    
+    // last child?
+    if (_activeChildInList == _activeList.end())
+    {
+        _activeChildInList--;
+        endOfList = true;
+    }
+    
+    return !endOfList;
+}
+
+
+
+/**
+ * Get content of current child as a string
+ * @return the string
+ */
+string XMLStructure::getString()
+{
+    // the child
+    xmlpp::Node *child = (*_activeChildInList)->get_children().front();
+    
+    // its content
+    string content = dynamic_cast<xmlpp::ContentNode*>(child)->get_content();
+    
+    return content;
+}
+
+
+
+/**
+ * Get content of current child as a number
+ * @return the number
+ */
+double XMLStructure::getNumber()
+{
+    // convert string -> double
+    double number = Glib::Ascii::strtod(getString());
+
+    return number;
+}
+
+
+
+/**
+ * Get attribute value of current child
+ * @param name name of attribute
+ * @return the value
+ */
+string XMLStructure::getAttribute(string name)
+{
+    // the child
+    xmlpp::Element *child = dynamic_cast<xmlpp::Element*>(*_activeChildInList);
+    
+    // its attribute value
+    string attributeValue = child->get_attribute(name)->get_value();
+    
+    return attributeValue;
+}
diff --git a/lsystem3d/src/xmlstructure.h b/lsystem3d/src/xmlstructure.h
new file mode 100644 (file)
index 0000000..6f3f658
--- /dev/null
@@ -0,0 +1,151 @@
+// Copyright (C) 2006 Erik Dahlberg
+// 
+// This file is part of LSystem3d.
+// 
+// LSystem3D is free software; you can redistribute it and/or
+// modify it under the terms of the GNU General Public License
+// as published by the Free Software Foundation; either version 2
+// of the License, or (at your option) any later version.
+// 
+// LSystem3D is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+// GNU General Public License for more details.
+// 
+// You should have received a copy of the GNU General Public License
+// along with LSystem3D; if not, write to the Free Software
+// Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+
+
+
+
+#ifndef XMLSTRUCTURE_H
+#define XMLSTRUCTURE_H
+
+#include <string>
+
+#include <libxml++/document.h>
+#include <libxml++/nodes/element.h>
+#include <libxml++/nodes/node.h>
+#include <libxml++/parsers/domparser.h>
+
+using namespace std;
+
+
+
+/**
+ * Basic logic for building and parsing xml-structures
+ */
+class XMLStructure
+{
+public:
+    /**
+     * Constructor
+     */
+    XMLStructure();
+
+    /**
+     * Destructor
+     */
+    ~XMLStructure();
+    
+protected:
+    
+    // Saver
+    // -----
+    
+    /**
+     * Create new document with root node
+     * @param rootName name of root
+     */
+    void createDocumentWithRoot(string rootName);
+    
+    /**
+     * Add new child to root
+     * @param name name of child
+     */
+    void addChildToRoot(string name);
+    
+    /**
+     * Add a string as content of current child
+     * @param text the text
+     */
+    void addString(string text);
+    
+    /**
+     * Add a number as content of current child
+     * @param value the number
+     */
+    void addNumber(double value);
+    
+    /**
+     * Add attribute to current child
+     * @param name name of attribute
+     * @param value value of attribute
+     */
+    void addAttribute(string name, string value);
+    
+    /**
+     * Save document to file
+     * @param path path to file
+     */
+    void saveToDisk(string path);
+    
+    
+    // Loader
+    // ------
+    
+    /**
+     * Load document from file
+     * @param path path to file
+     */
+    void loadFromDisk(string path);
+    
+    /**
+     * Find all children with the specified name
+     * @param name name of children
+     * @return true if found, else false
+     */
+    bool findChild(string name);
+    
+    /**
+     * Find next child in current search result list
+     * @return true if found, else false
+     */
+    bool findNextChild();
+    
+    /**
+     * Get content of current child as a string
+     * @return the string
+     */
+    string getString();
+    
+    /**
+     * Get content of current child as a number
+     * @return the number
+     */
+    double getNumber();
+    
+    /**
+     * Get attribute value of current child
+     * @param name name of attribute
+     * @return the value
+     */
+    string getAttribute(string name);    
+    
+private:
+    
+    // Saver
+    xmlpp::Element *_rootElement;
+    xmlpp::Element *_activeElement;
+    xmlpp::Document *_activeDocument;
+    
+    // Loader
+    xmlpp::DomParser _parser;
+    xmlpp::Node::NodeList _activeList;
+    xmlpp::Node::NodeList::iterator _activeChildInList;
+};
+
+
+
+#endif