Minor cleanup.
[lsystem3d.git] / src / lindenmayersystem.cpp
index c0fd3a727e1cfff98034b3c940f275a9c90056ca..18339122df83c5e9b8938c7f8bdd73d5568e21ce 100644 (file)
@@ -1,6 +1,6 @@
 // Copyright (C) 2006 Erik Dahlberg
 // 
-// This file is part of LSystem3d.
+// 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
 
 #include <cmath>
 
-#include <map>
 #include <string>
 
 #include "lindenmayersystem.h"
 #include "model.h"
+#include "rule.h"
+#include "ruleset.h"
 #include "turtle.h"
 
+using namespace std;
+
 
 
 /**
@@ -62,7 +65,7 @@ void LindenmayerSystem::clear()
     _axiom.clear();
     _rules.clear();
     _turtle->setAngle(0.0);
-    _numIterations = 0;
+    _depth = 0;
     
     _turtle->reset();
     _model->clear();
@@ -78,31 +81,40 @@ void LindenmayerSystem::generate()
     // model session
     _model->begin();
         _model->setColorIndex(0);
-        recursiveWalk(_axiom, _numIterations);
+        recursiveWalk(_axiom.getPreprocessedContent(), _depth);
     _model->end();
 }
 
 
 
+/**
+ * Render L-system data
+ */
+void LindenmayerSystem::render()
+{
+    _model->draw();
+}
+
+
+
 /**
  * Set the initial rule (the axiom)
  * @param axiom the axiom
  */
-void LindenmayerSystem::setAxiom(string axiom)
+void LindenmayerSystem::setAxiom(Rule axiom)
 {
-    _axiom = verifyAndPreprocessRule(axiom);
+    _axiom = axiom;
 }
 
 
 
 /**
  * Set one rule
- * @param name rule name
  * @param rule the rule
  */
-void LindenmayerSystem::setRule(string name, string rule)
+void LindenmayerSystem::setRule(Rule rule)
 {
-    _rules[name] = verifyAndPreprocessRule(rule);
+    _rules.addRule(rule);
 }
 
 
@@ -122,29 +134,30 @@ void LindenmayerSystem::setAngle(double degrees)
 
 
 /**
- * Set the number of iterations
- * @param numIterations number of iterations
+ * Set recursion depth
+ * @param depth depth of recursion
  */
-void LindenmayerSystem::setNumIterations(int numIterations)
+void LindenmayerSystem::setDepth(int depth)
 {
-    _numIterations = numIterations;
+    _depth = depth;
 }
 
 
 
 /**
- * Set diameter of segment
+ * Set initial segment diameter
  * @param diameter the diameter
  */
 void LindenmayerSystem::setDiameter(double diameter)
 {
+    _segmentDiameter = diameter;
     _model->setDiameter(diameter);
 }
 
 
 
 /**
- * Set diameter factor
+ * Set segment diameter factor
  * @param diameterFactor the diameter factor
  */
 void LindenmayerSystem::setDiameterFactor(double diameterFactor)
@@ -158,9 +171,9 @@ void LindenmayerSystem::setDiameterFactor(double diameterFactor)
  * Get the initial rule (the axiom)
  * @return the axiom
  */
-string LindenmayerSystem::getAxiom()
+Rule LindenmayerSystem::getAxiom()
 {
-    return unpreprocessRule(_axiom);
+    return _axiom;
 }
 
 
@@ -169,18 +182,9 @@ string LindenmayerSystem::getAxiom()
  * Get all rules
  * @return the rules
  */
-map<string,string> LindenmayerSystem::getRules()
+RuleSet 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;
+    return _rules;
 }
 
 
@@ -202,30 +206,41 @@ double LindenmayerSystem::getAngle()
 
 
 /**
- * Get the number of iterations
- * @return number of iterations
+ * Get recursion depth
+ * @return depth of recursion
  */
-int LindenmayerSystem::getNumIterations()
+int LindenmayerSystem::getDepth()
 {
-    return _numIterations;
+    return _depth;
 }
 
 
 
 /**
- * Get the generated model
- * @return generated model
+ * Get initial segment diameter
+ * @return the diameter
  */
-Model *LindenmayerSystem::getModel()
+double LindenmayerSystem::getDiameter()
 {
-    return _model;
+    return _segmentDiameter;
+}
+
+
+
+/**
+ * Get segment diameter factor
+ * @return the diameter factor
+ */
+double LindenmayerSystem::getDiameterFactor()
+{
+    return _model->getDiameterFactor();
 }
 
 
 
 /**
  * Recursively apply the replacement rules
- * @param rule rule
+ * @param rule the rule
  * @param level recursion level
  */
 void LindenmayerSystem::recursiveWalk(string rule, int level)
@@ -244,8 +259,8 @@ void LindenmayerSystem::recursiveWalk(string rule, int level)
                 // recursion
                 if (level > 0)
                 {
-                    char ruleName[] = {rule[i], '\0'};
-                    recursiveWalk(_rules[ruleName], level - 1);
+                    string name = rule.substr(i, 1);
+                    recursiveWalk(_rules.findRule(name).getPreprocessedContent(), level - 1);
                 }
                     
                 break;
@@ -254,17 +269,20 @@ void LindenmayerSystem::recursiveWalk(string rule, int level)
             // walk / rule
             case 'F':
                 
-                // replacement rule for 'F'?
-                if (_rules.count("F") != 0 && level > 0)
                 {
-                    recursiveWalk(_rules["F"], level - 1);
-                }
-                else
-                {
-                    // no rule for "F"
-                    _turtle->walk();
-                }
-                                        
+                    // replacement rule for 'F'?
+                    Rule rule = _rules.findRule("F");
+                    if (rule.getProbability() != 0.0 && level > 0)
+                    {
+                        recursiveWalk(rule.getPreprocessedContent(), level - 1);
+                    }
+                    else
+                    {
+                        // no rule for "F"
+                        _turtle->walk();
+                    }
+                }      
+                                     
                 break;
                 
                 
@@ -324,7 +342,7 @@ void LindenmayerSystem::recursiveWalk(string rule, int level)
                 break;
                 
                 
-            // restore state from stack
+            // load state from stack
             case ']':
                 
                 _turtle->pop();
@@ -352,7 +370,7 @@ void LindenmayerSystem::recursiveWalk(string rule, int level)
                 break;
                 
                 
-            // decrement diameter of segment
+            // decrement segment diameter
             case '!':
                 
                 _model->decrementDiameter();
@@ -374,55 +392,3 @@ void LindenmayerSystem::recursiveWalk(string rule, int level)
         }
     }
 }
-
-
-
-/**
- * Verify and preprocess one rule string
- * @param rule the rule
- * @return the preprocessed rule
- */
-string LindenmayerSystem::verifyAndPreprocessRule(string rule)
-{
-    // TODO: verifying
-    
-    string preprocessedRule;
-    
-    // check every element in rule
-    for (int i = 0; i < rule.size(); i++)
-    {
-        // TODO: allow strings as names
-        if (rule[i] >= 'A' && rule[i] <= 'Z' && rule[i] != 'F')
-        {
-            // add rule operator
-            preprocessedRule += '@';
-        }
-        preprocessedRule += rule[i];
-    }
-
-    return preprocessedRule;
-}
-
-
-
-/**
- * Unpreprocess one rule string
- * @param rule the rule
- * @return the unpreprocessed rule
- */
-string LindenmayerSystem::unpreprocessRule(string rule)
-{
-    string unpreprocessedRule;
-    
-    // check every element in rule
-    for (int i = 0; i < rule.size(); i++)
-    {
-        // ignore rule operator
-        if (rule[i] != '@')
-        {
-            unpreprocessedRule += rule[i];
-        }
-    }
-    
-    return unpreprocessedRule;
-}