- solver now supports animated time steps, gravity
authorNils Thuerey <nils@thuerey.de>
Wed, 23 Nov 2005 12:51:07 +0000 (12:51 +0000)
committerNils Thuerey <nils@thuerey.de>
Wed, 23 Nov 2005 12:51:07 +0000 (12:51 +0000)
  and viscosity, an example can be found here:
  http://www10.informatik.uni-erlangen.de/~sinithue/temp/fluid_timeanim.mpg
- for simulation time animation the time IPO of the object is currently used,
  for all three there should probably be new ipos in the fluidsim struct
- started the API in elbeem.cpp, to get rid of parser & export
  via HD (it's not yet used)

37 files changed:
intern/elbeem/extern/LBM_fluidsim.h
intern/elbeem/intern/attributes.cpp
intern/elbeem/intern/attributes.h
intern/elbeem/intern/blendercall.cpp
intern/elbeem/intern/cfglexer.cpp
intern/elbeem/intern/cfgparser.cpp
intern/elbeem/intern/cfgparser.h
intern/elbeem/intern/elbeem.cpp
intern/elbeem/intern/elbeem.h [new file with mode: 0644]
intern/elbeem/intern/globals.h
intern/elbeem/intern/isosurface.cpp
intern/elbeem/intern/ntl_blenderdumper.cpp
intern/elbeem/intern/ntl_blenderdumper.h
intern/elbeem/intern/ntl_bsptree.cpp
intern/elbeem/intern/ntl_geometrymodel.cpp
intern/elbeem/intern/ntl_geometrymodel.h
intern/elbeem/intern/ntl_geometryobject.cpp
intern/elbeem/intern/ntl_geometryobject.h
intern/elbeem/intern/ntl_material.h
intern/elbeem/intern/ntl_scene.h
intern/elbeem/intern/ntl_vector3dim.h
intern/elbeem/intern/ntl_world.cpp
intern/elbeem/intern/ntl_world.h
intern/elbeem/intern/parametrizer.cpp
intern/elbeem/intern/parametrizer.h
intern/elbeem/intern/particletracer.h
intern/elbeem/intern/simulation_object.cpp
intern/elbeem/intern/simulation_object.h
intern/elbeem/intern/solver_class.h
intern/elbeem/intern/solver_init.cpp
intern/elbeem/intern/solver_interface.cpp
intern/elbeem/intern/solver_interface.h
intern/elbeem/intern/solver_main.cpp
intern/elbeem/intern/solver_relax.h
intern/elbeem/intern/solver_util.cpp
intern/elbeem/intern/utilities.cpp
intern/elbeem/intern/utilities.h

index 884a243e6a61a1446b1a1ff2cf1414290cd3a3a5..ff0b0a465dde38e2c6fde55e29ce61140dabce58 100644 (file)
@@ -57,18 +57,27 @@ struct Mesh* readBobjgz(char *filename, struct Mesh *orgmesh);
 
 /* create derived mesh for fluid sim objects */
 // WARNING - currently implemented in DerivedMesh.c!
-struct DerivedMesh *getFluidsimDerivedMesh(struct Object *srcob, int useRenderParams, float *extverts, float *nors);
+void loadFluidsimMesh(struct Object *srcob, int useRenderParams);
 
 /* run simulation with given config file */
 // WARNING - implemented in intern/elbeem/blendercall.cpp
 int performElbeemSimulation(char *cfgfilename);
 
+/* init axis aligned BB for mesh object */
+// implemented in source/blender/blenkernel/intern/DerivedMesh.c
+void fluidsimGetAxisAlignedBB(struct Mesh *mesh, float obmat[][4],
+                /*RET*/ float start[3], /*RET*/ float size[3] );
+
 // implemented in intern/elbeem/utilities.cpp
 /* set elbeem debug output level (0=off to 10=full on) */
 void elbeemSetDebugLevel(int level);
 /* elbeem debug output function */
 void elbeemDebugOut(char *msg);
 
+/* estimate how much memory a given setup will require */
+double elbeemEstimateMemreq(int res, 
+               float sx, float sy, float sz,
+               int refine, char *retstr);
 
 #endif
 
index 97e33e3d65eb4c2e9a08bc98c0524046582f4417..8689a3fe98ed978daf8325aef74b7ddd645a2e50 100644 (file)
  * attribute conversion functions
  *****************************************************************************/
 
+bool Attribute::initChannel(int elemSize) {
+       if(!mIsChannel) return true;
+       if(mChannelInited==elemSize) {
+               // already inited... ok
+               return true;
+       } else {
+               // sanity check
+               if(mChannelInited>0) {
+                       errMsg("Attribute::initChannel","Duplicate channel init!? ("<<mChannelInited<<" vs "<<elemSize<<")...");
+                       return false;
+               }
+       }
+       
+       if((mValue.size() % (elemSize+1)) !=  0) {
+               errMsg("Attribute::initChannel","Invalid # elements in Attribute...");
+               return false;
+       }
+       
+       int numElems = mValue.size()/(elemSize+1);
+       vector<string> newvalue;
+       for(int i=0; i<numElems; i++) {
+       //errMsg("ATTR"," i"<<i<<" "<<mName); // debug
+
+               vector<string> elem(elemSize);
+               for(int j=0; j<elemSize; j++) {
+               //errMsg("ATTR"," j"<<j<<" "<<mValue[i*(elemSize+1)+j]  ); // debug
+                       elem[j] = mValue[i*(elemSize+1)+j];
+               }
+               mChannel.push_back(elem);
+               // use first value as default
+               if(i==0) newvalue = elem;
+               
+               double t = 0.0; // similar to getAsFloat
+               const char *str = mValue[i*(elemSize+1)+elemSize].c_str();
+               char *endptr;
+               t = strtod(str, &endptr);
+               if((str!=endptr) && (*endptr != '\0')) return false;
+               mTimes.push_back(t);
+               //errMsg("ATTR"," t"<<t<<" "); // debug
+       }
+       for(int i=0; i<numElems-1; i++) {
+               if(mTimes[i]>mTimes[i+1]) {
+                       errMsg("Attribute::initChannel","Invalid time at entry "<<i<<" setting to "<<mTimes[i]);
+                       mTimes[i+1] = mTimes[i];
+               }
+       }
+
+       // dont change until done with parsing, and everythings ok
+       mValue = newvalue;
+
+       mChannelInited = elemSize;
+       print();
+       return true;
+}
+
 // get value as string 
 string Attribute::getAsString()
 {
+       if(mIsChannel) {
+               errMsg("Attribute::getAsString", "Attribute \"" << mName << "\" used as string is a channel! Not allowed...");
+               print();
+               return string("");
+       }
        if(mValue.size()!=1) {
                //errMsg("Attribute::getAsString", "Attribute \"" << mName << "\" used as string has invalid value '"<< getCompleteString() <<"' ");
                // for directories etc. , this might be valid! cutoff "..." first
@@ -37,19 +97,26 @@ int Attribute::getAsInt()
 {
        bool success = true;
        int ret = 0;
-       if(mValue.size()!=1) success = false;
-       else {
-               const char *str = mValue[0].c_str();
-               char *endptr;
-               ret = strtol(str, &endptr, 10);
-               if( (str==endptr) ||
-                               ((str!=endptr) && (*endptr != '\0')) )success = false;
+
+       if(!initChannel(1)) success=false; 
+       if(success) {
+               if(mValue.size()!=1) success = false;
+               else {
+                       const char *str = mValue[0].c_str();
+                       char *endptr;
+                       ret = strtol(str, &endptr, 10);
+                       if( (str==endptr) ||
+                                       ((str!=endptr) && (*endptr != '\0')) )success = false;
+               }
        }
 
        if(!success) {
-               errMsg("Attribute::getAsString", "Attribute \"" << mName << "\" used as int has invalid value '"<< getCompleteString() <<"' ");
-               errMsg("Attribute::getAsString", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
-               errMsg("Attribute::getAsString", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
+               errMsg("Attribute::getAsInt", "Attribute \"" << mName << "\" used as int has invalid value '"<< getCompleteString() <<"' ");
+               errMsg("Attribute::getAsInt", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
+               errMsg("Attribute::getAsInt", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
+#if ELBEEM_PLUGIN!=1
+               gElbeemState = -4; // parse error
+#endif
                return 0;
        }
        return ret;
@@ -70,18 +137,26 @@ double Attribute::getAsFloat()
 {
        bool success = true;
        double ret = 0.0;
-       if(mValue.size()!=1) success = false;
-       else {
-               const char *str = mValue[0].c_str();
-               char *endptr;
-               ret = strtod(str, &endptr);
-               if((str!=endptr) && (*endptr != '\0')) success = false;
+
+       if(!initChannel(1)) success=false; 
+       if(success) {
+               if(mValue.size()!=1) success = false;
+               else {
+                       const char *str = mValue[0].c_str();
+                       char *endptr;
+                       ret = strtod(str, &endptr);
+                       if((str!=endptr) && (*endptr != '\0')) success = false;
+               }
        }
 
        if(!success) {
+               print();
                errMsg("Attribute::getAsFloat", "Attribute \"" << mName << "\" used as double has invalid value '"<< getCompleteString() <<"' ");
                errMsg("Attribute::getAsFloat", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
                errMsg("Attribute::getAsFloat", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
+#if ELBEEM_PLUGIN!=1
+               gElbeemState = -4; // parse error
+#endif
                return 0.0;
        }
        return ret;
@@ -92,41 +167,48 @@ ntlVec3d Attribute::getAsVec3d()
 {
        bool success = true;
        ntlVec3d ret(0.0);
-       if(mValue.size()==1) {
-               const char *str = mValue[0].c_str();
-               char *endptr;
-               double rval = strtod(str, &endptr);
-               if( (str==endptr) ||
-                               ((str!=endptr) && (*endptr != '\0')) )success = false;
-               if(success) ret = ntlVec3d( rval );
-       } else if(mValue.size()==3) {
-               char *endptr;
-               const char *str = NULL;
 
-               str = mValue[0].c_str();
-               double rval1 = strtod(str, &endptr);
-               if( (str==endptr) ||
-                               ((str!=endptr) && (*endptr != '\0')) )success = false;
-
-               str = mValue[1].c_str();
-               double rval2 = strtod(str, &endptr);
-               if( (str==endptr) ||
-                               ((str!=endptr) && (*endptr != '\0')) )success = false;
-
-               str = mValue[2].c_str();
-               double rval3 = strtod(str, &endptr);
-               if( (str==endptr) ||
-                               ((str!=endptr) && (*endptr != '\0')) )success = false;
-
-               if(success) ret = ntlVec3d( rval1, rval2, rval3 );
-       } else {
-               success = false;
+       if(!initChannel(3)) success=false; 
+       if(success) {
+               if(mValue.size()==1) {
+                       const char *str = mValue[0].c_str();
+                       char *endptr;
+                       double rval = strtod(str, &endptr);
+                       if( (str==endptr) ||
+                                       ((str!=endptr) && (*endptr != '\0')) )success = false;
+                       if(success) ret = ntlVec3d( rval );
+               } else if(mValue.size()==3) {
+                       char *endptr;
+                       const char *str = NULL;
+
+                       str = mValue[0].c_str();
+                       double rval1 = strtod(str, &endptr);
+                       if( (str==endptr) ||
+                                       ((str!=endptr) && (*endptr != '\0')) )success = false;
+
+                       str = mValue[1].c_str();
+                       double rval2 = strtod(str, &endptr);
+                       if( (str==endptr) ||
+                                       ((str!=endptr) && (*endptr != '\0')) )success = false;
+
+                       str = mValue[2].c_str();
+                       double rval3 = strtod(str, &endptr);
+                       if( (str==endptr) ||
+                                       ((str!=endptr) && (*endptr != '\0')) )success = false;
+
+                       if(success) ret = ntlVec3d( rval1, rval2, rval3 );
+               } else {
+                       success = false;
+               }
        }
 
        if(!success) {
                errMsg("Attribute::getAsVec3d", "Attribute \"" << mName << "\" used as Vec3d has invalid value '"<< getCompleteString() <<"' ");
                errMsg("Attribute::getAsVec3d", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
                errMsg("Attribute::getAsVec3d", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
+#if ELBEEM_PLUGIN!=1
+               gElbeemState = -4; // parse error
+#endif
                return ntlVec3d(0.0);
        }
        return ret;
@@ -180,6 +262,9 @@ ntlMat4Gfx Attribute::getAsMat4Gfx()
                errMsg("Attribute::getAsMat4Gfx", "Attribute \"" << mName << "\" used as Mat4x4 has invalid value '"<< getCompleteString() <<"' ");
                errMsg("Attribute::getAsMat4Gfx", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
                errMsg("Attribute::getAsMat4Gfx", "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!" );
+#if ELBEEM_PLUGIN!=1
+               gElbeemState = -4; // parse error
+#endif
                return ntlMat4Gfx(0.0);
        }
        return ret;
@@ -198,6 +283,68 @@ string Attribute::getCompleteString()
 }
 
 
+/******************************************************************************
+ * channel returns
+ *****************************************************************************/
+
+//! get channel as double value
+AnimChannel<double> Attribute::getChannelFloat() {
+       vector<double> timeVec;
+       vector<double> valVec;
+       
+       if((!initChannel(1)) || (!mIsChannel)) {
+               timeVec.push_back( 0.0 );
+               valVec.push_back( getAsFloat() );
+       } else {
+       for(size_t i=0; i<mChannel.size(); i++) {
+               mValue = mChannel[i];
+               double val = getAsFloat();
+               timeVec.push_back( mTimes[i] );
+               valVec.push_back( val );
+       }}
+
+       return AnimChannel<double>(valVec,timeVec);
+}
+
+//! get channel as integer value
+AnimChannel<int> Attribute::getChannelInt() { 
+       vector<double> timeVec;
+       vector<int> valVec;
+       
+       if((!initChannel(1)) || (!mIsChannel)) {
+               timeVec.push_back( 0.0 );
+               valVec.push_back( getAsInt() );
+       } else {
+       for(size_t i=0; i<mChannel.size(); i++) {
+               mValue = mChannel[i];
+               int val = getAsInt();
+               timeVec.push_back( mTimes[i] );
+               valVec.push_back( val );
+       }}
+
+       return AnimChannel<int>(valVec,timeVec);
+}
+
+//! get channel as integer value
+AnimChannel<ntlVec3d> Attribute::getChannelVec3d() { 
+       vector<double> timeVec;
+       vector<ntlVec3d> valVec;
+       
+       if((!initChannel(3)) || (!mIsChannel)) {
+               timeVec.push_back( 0.0 );
+               valVec.push_back( getAsVec3d() );
+       } else {
+       for(size_t i=0; i<mChannel.size(); i++) {
+               mValue = mChannel[i];
+               ntlVec3d val = getAsVec3d();
+               timeVec.push_back( mTimes[i] );
+               valVec.push_back( val );
+       }}
+
+       return AnimChannel<ntlVec3d>(valVec,timeVec);
+}
+
+
 /******************************************************************************
  * check if there were unknown params
  *****************************************************************************/
@@ -292,6 +439,20 @@ bool AttributeList::ignoreParameter(string name, string source) {
        return true;
 }
                
+// read channels
+AnimChannel<double> AttributeList::readChannelFloat(string name) {
+       if(!exists(name)) { return AnimChannel<double>(0.0); } 
+       return find(name)->getChannelFloat(); 
+}
+AnimChannel<int> AttributeList::readChannelInt(string name) {
+       if(!exists(name)) { return AnimChannel<int>(0); } 
+       return find(name)->getChannelInt(); 
+}
+AnimChannel<ntlVec3d> AttributeList::readChannelVec3d(string name) {
+       if(!exists(name)) { return AnimChannel<ntlVec3d>(0.0); } 
+       return find(name)->getChannelVec3d(); 
+}
+
 /******************************************************************************
  * destructor
  *****************************************************************************/
@@ -314,10 +475,23 @@ AttributeList::~AttributeList() {
 void Attribute::print()
 {
        std::ostringstream ostr;
-       ostr << "  "<< mName <<"= ";
+       ostr << "ATTR "<< mName <<"= ";
        for(size_t i=0;i<mValue.size();i++) {
                ostr <<"'"<< mValue[i]<<"' ";
        }
+       if(mIsChannel) {
+               ostr << " CHANNEL: ";
+               if(mChannelInited>0) {
+               for(size_t i=0;i<mChannel.size();i++) {
+                       for(size_t j=0;j<mChannel[i].size();j++) {
+                               ostr <<"'"<< mChannel[i][j]<<"' ";
+                       }
+                       ostr << "@"<<mTimes[i]<<"; ";
+               }
+               } else {
+                       ostr <<" -nyi- ";
+               }                       
+       }
        ostr <<" (at line "<<mLine<<") "; //<< std::endl;
        debugOut( ostr.str(), 10);
 }
index bc92999a05f05bb99c4ba31ac8650af1ac3eadc2..f9f44e2eb52786432a4df9259eafd3dbb75d559c 100644 (file)
 #include "ntl_matrices.h"
 
 
+//! An animated attribute channel
+template<class Scalar>
+class AnimChannel
+{
+       public:
+               // null init constructor
+               AnimChannel(Scalar null) : 
+                       mValue(1), mTimes(1) { mValue[0]=null; mTimes[0]=0.0; };
+
+               // proper init
+               AnimChannel(vector<Scalar> v, vector<double> t) : 
+                       mValue(v), mTimes(t) { };
+
+               // desctructor, nothing to do
+               ~AnimChannel() { };
+
+               // get interpolated value at time t
+               Scalar get(double t) {
+                       if(t<=mTimes[0])               { return mValue[0]; }
+                       if(t>=mTimes[mTimes.size()-1]) { return mValue[mTimes.size()-1]; }
+                       for(size_t i=0; i<mTimes.size()-1; i++) {
+                               // find first time thats in between
+                               if((mTimes[i]<=t)&&(mTimes[i+1]>t)) { 
+                                       // interpolate
+                                       double d = mTimes[i+1]-mTimes[i];
+                                       double f = (t-mTimes[i])/d;
+                                       return mValue[i] * (1.0-f) + mValue[i+1] * f;
+                               }
+                       }
+                       // whats this...?
+                       return mValue[0];
+               };
+
+               // get uninterpolated value at time t
+               Scalar getConstant(double t) {
+                       //errMsg("DEBB","getc"<<t<<" ");
+                       if(t<=mTimes[0])               { return mValue[0]; }
+                       if(t>=mTimes[mTimes.size()-1]) { return mValue[mTimes.size()-1]; }
+                       for(size_t i=0; i<mTimes.size()-1; i++) {
+                               //errMsg("DEBB","getc i"<<i<<" "<<mTimes[i]);
+                               // find first time thats in between
+                               if((mTimes[i]<=t)&&(mTimes[i+1]>t)) { return mValue[i]; }
+                       }
+                       // whats this...?
+                       return mValue[0];
+               };
+
+               // reset to null value
+               void reset(Scalar null) {
+                       mValue.clear();
+                       mTimes.clear();
+                       mValue.push_back(null);
+                       mTimes.push_back(0.0);
+               }
+
+       protected:
+
+               /*! anim channel attribute values */
+               vector<Scalar> mValue;
+               /*! anim channel attr times */
+               vector<double> mTimes;
+};
+
 //! A single attribute
 class Attribute
 {
        public:
        //! Standard constructor
-       Attribute(string mn, vector<string> &value, int setline) :
+       Attribute(string mn, vector<string> &value, int setline,bool channel) :
                        mName(mn), mValue(value), 
-                       mLine(setline), mUsed(false) { };
+                       mLine(setline), mUsed(false), mIsChannel(channel),
+                       mChannelInited(-1)      { };
        //! Copy constructor
        Attribute(Attribute &a) :
                        mName(a.mName), mValue(a.mValue), 
-                       mLine(a.mLine), mUsed(false) { };
+                       mLine(a.mLine), mUsed(false), mIsChannel(a.mIsChannel),
+                       mChannelInited(a.mChannelInited),
+                       mChannel(a.mChannel), mTimes(a.mTimes)  { };
        //! Destructor
        ~Attribute() { /* empty */ };
 
@@ -34,24 +100,31 @@ class Attribute
                //! get used flag
                bool getUsed() { return mUsed; }
 
+               //! set channel flag
+               void setIsChannel(bool set){ mIsChannel = set; }
+               //! get channel flag
+               bool getIsChannel() { return mIsChannel; }
+
                //! get value as string 
                string getAsString();
-
                //! get value as integer value
                int getAsInt();
-
                //! get value as boolean
                bool getAsBool();
-
                //! get value as double value
                double getAsFloat();
-
                //! get value as 3d vector 
                ntlVec3d getAsVec3d();
-
                //! get value as 4x4 matrix
                ntlMat4Gfx getAsMat4Gfx();
 
+               //! get channel as integer value
+               AnimChannel<int> getChannelInt();
+               //! get channel as double value
+               AnimChannel<double> getChannelFloat();
+               //! get channel as double value
+               AnimChannel<ntlVec3d> getChannelVec3d();
+
                //! get the concatenated string of all value string
                string getCompleteString();
 
@@ -60,6 +133,9 @@ class Attribute
                
        protected:
 
+               /*! internal - init channel before access */
+               bool initChannel(int elemSize);
+
                /*! the attr name */
                string mName;
 
@@ -71,6 +147,16 @@ class Attribute
 
                /*! was this attribute used? */
                bool mUsed;
+
+               /*! does this attribute have a channel? */
+               bool mIsChannel;
+               /*! does this attribute have a channel? */
+               int mChannelInited;
+
+               /*! channel attribute values (first one equals mValue) */
+               vector< vector< string > > mChannel;
+               /*! channel attr times */
+               vector< double > mTimes;
 };
 
 
@@ -85,9 +171,9 @@ class AttributeList
        ~AttributeList();
 
                /*! add an attribute to this list */
-               void addAttr(string name, vector<string> &value, int line) {
+               void addAttr(string name, vector<string> &value, int line, bool isChannel) {
                        if(exists(name)) delete mAttrs[name];
-                       mAttrs[name] = new Attribute(name,value,line);
+                       mAttrs[name] = new Attribute(name,value,line, isChannel);
                }
 
                /*! check if an attribute is set */
@@ -102,7 +188,7 @@ class AttributeList
                                errFatal("AttributeList::find","Invalid attribute '"<<name<<"' , not found...",SIMWORLD_INITERROR );
                                // just create a new empty one (warning: small memory leak!), and exit as soon as possible
                                vector<string> empty;
-                               return new Attribute(name,empty, -1);
+                               return new Attribute(name,empty, -1, 0);
                        }
                        return mAttrs[name];
                }
@@ -122,6 +208,10 @@ class AttributeList
                string   readString(string name, string defaultValue,   string source,string target, bool needed);
                ntlVec3d readVec3d(string name, ntlVec3d defaultValue,  string source,string target, bool needed);
                ntlMat4Gfx readMat4Gfx(string name, ntlMat4Gfx defaultValue,  string source,string target, bool needed);
+               //! read attributes channels (attribute should be inited before)
+               AnimChannel<int>     readChannelInt(string name);
+               AnimChannel<double>  readChannelFloat(string name);
+               AnimChannel<ntlVec3d> readChannelVec3d(string name);
 
                //! set that a parameter can be given, and will be ignored...
                bool ignoreParameter(string name, string source);
@@ -139,7 +229,6 @@ class AttributeList
 
 };
 
-
 #define NTL_ATTRIBUTES_H
 #endif
 
index 847dbdd48434d69e016fd36a753438eb16558344..f1617da82969f4167e4eb2289473c829598bcb97 100644 (file)
  *****************************************************************************/
  
 #include "globals.h"
+#include "utilities.h"
 #include "ntl_blenderdumper.h"
 #include <stdlib.h>
 
+// ELBEEM_BLENDER always =1 here
 extern "C" void elbeemCheckDebugEnv(void);
 
 extern "C" 
 int performElbeemSimulation(char *cfgfilename) {
-       gWorldState = SIMWORLD_INVALID;
-       strcpy(gWorldStringState,"[none]");
+       gElbeemState = SIMWORLD_INVALID;
+       strcpy(gElbeemErrorString,"[none]");
 
        //if(gDebugLevel>0) {
        elbeemCheckDebugEnv();
@@ -27,12 +29,14 @@ int performElbeemSimulation(char *cfgfilename) {
        // load given file in command line mode
        ntlBlenderDumper elbeem(cfgfilename, true);
        if(SIMWORLD_OK()) {
-               gWorldState = SIMWORLD_INITED;
+               gElbeemState = SIMWORLD_INITED;
                myTime_t timestart = getTime();
                elbeem.renderAnimation();
                myTime_t timeend = getTime();
                debMsgStd("performElbeemSimulation",DM_NOTIFY, "El'Beem simulation done, time: "<<((timeend-timestart)/(double)1000.0) <<" seconds.\n", 2 ); 
        } else {
+               // signal there was an initialization problem
+               setGlobalBakeState( -2 );
        }
        return 1;
 };
index c8492f8105cbe31ab67563a99b5502964285be39..472c692945111eaa05abda780fb238d8fedc855f 100644 (file)
@@ -358,70 +358,70 @@ struct yy_trans_info
        flex_int32_t yy_verify;
        flex_int32_t yy_nxt;
        };
-static yyconst flex_int16_t yy_accept[567] =
+static yyconst flex_int16_t yy_accept[566] =
     {   0,
         0,    0,    0,    0,    6,    6,   99,   97,   97,   95,
        96,   97,   93,   97,   97,   97,   89,   97,   97,   97,
        97,   97,   97,   97,   97,   97,   97,   97,   97,   97,
        97,   97,   97,   97,   97,    1,    2,   97,   96,    4,
-        3,    6,    7,    6,    6,    6,    7,    1,    2,    0,
-        1,    2,    0,   93,    0,   89,   90,   94,   92,   89,
+        3,    6,    6,    6,    6,    7,    1,    2,    0,    1,
+        2,    0,   93,    0,   89,   90,   94,   92,   89,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,   85,    0,    0,    0,    0,    0,    0,    0,    0,
+       85,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 
-        0,    0,    0,    0,    0,    0,    1,    2,    0,    3,
-        4,    3,    6,    6,    5,    6,    6,    6,   91,   92,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,   45,
-        0,    0,    0,    0,    0,    0,    0,    0,   52,    0,
+        0,    0,    0,    0,    0,    1,    2,    0,    3,    4,
+        3,    6,    6,    5,    6,    6,    6,   91,   92,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,   45,    0,
+        0,    0,    0,    0,    0,    0,    0,   52,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,   86,    0,    0,
+        0,    0,    0,    0,    0,    0,   86,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,    0,    6,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        6,    0,    0,    0,    0,    0,    0,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
 
-        0,    0,    0,   18,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,   64,    0,    0,    0,   76,    0,
-        0,   53,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,   87,   44,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,   63,
-        0,    0,   79,    0,    0,    0,    0,    0,    0,    0,
-       88,    0,    0,    0,    0,    0,    0,    0,    0,   75,
-        0,    0,    0,    0,    0,    0,    0,    0,   62,    0,
-        0,    0,    0,    0,    0,    0,    0,    0,    0,   51,
-        0,    0,    0,   17,    0,    0,   77,    0,    0,    0,
-
-        0,   19,    0,    0,    0,    0,    0,   78,    0,    0,
-        0,    0,   40,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,   60,    0,   16,    0,    0,   68,    0,    0,
+        0,    0,   18,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,   64,    0,    0,    0,   76,    0,    0,
+       53,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,   87,   44,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,   63,    0,
+        0,   79,    0,    0,    0,    0,    0,    0,    0,   88,
+        0,    0,    0,    0,    0,    0,    0,    0,   75,    0,
+        0,    0,    0,    0,    0,    0,    0,   62,    0,    0,
+        0,    0,    0,    0,    0,    0,    0,    0,   51,    0,
+        0,    0,   17,    0,    0,   77,    0,    0,    0,    0,
+
+       19,    0,    0,    0,    0,    0,   78,    0,    0,    0,
+        0,   40,    0,    0,    0,    0,    0,    0,    0,    0,
+        0,   60,    0,   16,    0,    0,   68,    0,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,   46,    0,    0,    0,    0,   56,    0,   65,    0,
+       46,    0,    0,    0,    0,   56,    0,   65,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,    0,   66,    0,    0,    0,    0,    0,   73,
-        0,    0,    0,    0,    0,    0,    0,    0,   54,    0,
+        0,    0,   66,    0,    0,    0,    0,    0,   73,    0,
+        0,    0,    0,    0,    0,    0,    0,   54,    0,    0,
         0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,    0,   50,    0,    0,   22,    0,    0,    0,    0,
-
-        0,    0,    0,    0,    0,    0,    0,    0,    0,    0,
-       15,   59,   26,    8,    0,   43,    0,   61,    0,    0,
-        0,   47,    0,   80,    0,    0,    0,    0,    0,    0,
-       67,   35,    0,    0,    0,    0,    0,    0,   23,    0,
-       14,   39,    0,    0,    0,    0,    0,    0,    0,    0,
-        0,   10,    0,    0,    0,   25,    0,    0,    0,    0,
-        0,    0,    0,    0,    0,    0,   83,    0,    0,    0,
-        0,    0,    0,    0,   38,   21,    0,    0,    0,    0,
-        0,    0,    9,   11,   34,    0,   74,   58,    0,    0,
-        0,   36,   12,    0,    0,    0,   13,    0,    0,    0,
-
-        0,    0,    0,    0,    0,   37,   48,    0,    0,   84,
-        0,   41,   31,   57,   55,    0,   70,    0,    0,    0,
-       72,    0,    0,    0,   20,   24,    0,    0,    0,    0,
-        0,    0,    0,    0,   69,   32,    0,    0,    0,    0,
-        0,    0,    0,    0,   30,   71,    0,    0,    0,   81,
-        0,    0,   49,   27,    0,    0,    0,   82,    0,    0,
-       28,   29,    0,   33,   42,    0
+        0,   50,    0,    0,   22,    0,    0,    0,    0,    0,
+
+        0,    0,    0,    0,    0,    0,    0,    0,    0,   15,
+       59,   26,    8,    0,   43,    0,   61,    0,    0,    0,
+       47,    0,   80,    0,    0,    0,    0,    0,    0,   67,
+       35,    0,    0,    0,    0,    0,    0,   23,    0,   14,
+       39,    0,    0,    0,    0,    0,    0,    0,    0,    0,
+       10,    0,    0,    0,   25,    0,    0,    0,    0,    0,
+        0,    0,    0,    0,    0,   83,    0,    0,    0,    0,
+        0,    0,    0,   38,   21,    0,    0,    0,    0,    0,
+        0,    9,   11,   34,    0,   74,   58,    0,    0,    0,
+       36,   12,    0,    0,    0,   13,    0,    0,    0,    0,
+
+        0,    0,    0,    0,   37,   48,    0,    0,   84,    0,
+       41,   31,   57,   55,    0,   70,    0,    0,    0,   72,
+        0,    0,    0,   20,   24,    0,    0,    0,    0,    0,
+        0,    0,    0,   69,   32,    0,    0,    0,    0,    0,
+        0,    0,    0,   30,   71,    0,    0,    0,   81,    0,
+        0,   49,   27,    0,    0,    0,   82,    0,    0,   28,
+       29,    0,   33,   42,    0
     } ;
 
 static yyconst flex_int32_t yy_ec[256] =
@@ -465,138 +465,138 @@ static yyconst flex_int32_t yy_meta[44] =
         6,    1,    1
     } ;
 
-static yyconst flex_int16_t yy_base[577] =
+static yyconst flex_int16_t yy_base[576] =
     {   0,
         0,    0,   43,   86,  128,  170,  704,  705,   60,  705,
        63,    0,    0,   43,  692,   53,   50,   47,   53,   78,
        47,   39,   87,  681,   43,   82,   54,   80,  117,   92,
        93,  112,  116,  669,   99,  123,  138,  149,  152,    0,
-      141,    0,  705,  695,  156,  101,  705,  157,  160,  163,
-      175,  180,  694,    0,  687,  176,  686,  705,    0,  177,
-      660,  677,  153,  662,  657,  673,  101,  651,  161,   46,
-      175,  178,  670,  668,  660,  659,  649,  647,  186,  653,
-      645,  651,  658,  649,  168,  645,  649,  648,  650,  653,
-      644,  705,  652,  641,  174,  630,  192,  653,  131,  652,
-
-      633,  198,  635,  628,  631,  629,  214,  219,  222,  226,
-        0,  227,    0,  658,  657,  230,    0,  235,  705,    0,
-      636,  635,  146,  634,  637,  623,  629,  625,  624,  705,
-      617,  617,  620,  618,  612,  623,  619,  624,  705,  613,
-      609,  622,  617,  600,  611,  604,  609,  616,  601,  611,
-      607,  612,  598,  597,  609,  206,  600,  705,  603,  597,
-      596,  584,  599,  587,  601,  587,  600,  588,  598,  598,
-      595,  581,  578,  583,  591,  590,  589,  588,  572,  582,
-      238,  568,  584,  570,  567,  585,  582,  575,  576,  578,
-      567,  561,  559,  183,  577,  570,  562,  570,  553,  558,
-
-      567,  216,  567,  705,  565,  555,  563,  549,  545,  545,
-      563,  545,  561,  546,  705,  545,  554,  543,  705,  550,
-      549,  548,  534,  535,  543,  550,  545,  537,  533,  526,
-      528,  525,  531,  524,  529,  705,  705,  538,  535,  537,
-      533,  523,  535,  534,  522,  513,  530,  513,  525,  705,
-      521,  519,  705,  509,  508,  221,  520,  521,  504,  513,
-      705,  506,  519,  507,  499,  512,  496,  495,  496,  705,
-      493,  503,  486,  492,  497,  490,  503,  494,  705,  490,
-      495,  502,  480,  498,  482,  478,  475,  485,  491,  705,
-      480,  193,  493,  705,  469,  480,  705,  471,  477,  471,
-
-      479,  705,  466,  471,  467,  483,  480,  705,  477,  476,
-      465,  470,  478,  457,  471,  461,  470,  460,  470,  460,
-      458,  451,  705,  462,  705,  466,  462,  705,  440,  444,
-      458,  461,  447,  445,  456,  453,  448,  453,  435,  441,
-      452,  705,  448,  221,  450,  426,  705,  444,  436,  442,
-      426,  444,  424,  422,  441,  437,  227,  428,  417,  434,
-      413,  435,  417,  705,  414,  428,  427,  418,  421,  705,
-      404,  427,  415,  421,  418,  415,  411,  402,  705,  407,
-      411,  400,  404,  416,  407,  414,  396,  408,  408,  391,
-      392,  227,  705,  400,  219,  705,  389,  402,  392,  385,
-
-      389,  385,  394,  231,  399,  395,  394,  393,  377,  387,
-      705,  705,  705,  705,  379,  705,  391,  705,  377,  377,
-      388,  705,  370,  705,  375,  380,  383,  365,  370,  368,
-      705,  705,  374,  379,  376,  375,  361,  371,  705,  368,
-      705,  357,  371,  354,  350,  354,  356,  369,  351,  355,
-      355,  705,  354,  345,  361,  705,  358,  342,  347,  355,
-      341,  351,  356,  351,  336,  340,  351,  332,  336,  336,
-      333,  339,  339,  333,  705,  705,  327,  325,  342,  322,
-      325,  335,  705,  705,  705,  321,  705,  705,  330,  318,
-      317,  705,  705,  331,  310,  313,  705,  323,  322,  318,
-
-      326,  308,  326,  306,  320,  705,  705,  320,  308,  705,
-      308,  312,  705,  705,  705,  305,  705,  310,  317,  295,
-      705,  311,  307,  300,  705,  705,  236,  299,  305,  309,
-      287,  306,  289,  302,  705,  705,  299,  296,  296,  281,
-      274,  267,  264,  263,  705,  705,  269,  258,  261,  705,
-      267,  250,  705,  705,  245,  225,  222,  705,  212,  166,
-      705,  705,  155,  705,  705,  705,  268,  274,  277,  283,
-      113,  289,  295,  301,  307,  313
+      141,    0,  695,  156,  101,  705,  157,  160,  163,  175,
+      180,  694,    0,  687,  176,  686,  705,    0,  177,  660,
+      677,  153,  662,  657,  673,  101,  651,  161,   46,  175,
+      178,  670,  668,  660,  659,  649,  647,  186,  653,  645,
+      651,  658,  649,  168,  645,  649,  648,  650,  653,  644,
+      705,  652,  641,  174,  630,  192,  653,  131,  652,  633,
+
+      198,  635,  628,  631,  629,  214,  219,  222,  226,    0,
+      227,    0,  658,  657,  230,    0,  235,  705,    0,  636,
+      635,  146,  634,  637,  623,  629,  625,  624,  705,  617,
+      617,  620,  618,  612,  623,  619,  624,  705,  613,  609,
+      622,  617,  600,  611,  604,  609,  616,  601,  611,  607,
+      612,  598,  597,  609,  206,  600,  705,  603,  597,  596,
+      584,  599,  587,  601,  587,  600,  588,  598,  598,  595,
+      581,  578,  583,  591,  590,  589,  588,  572,  582,  238,
+      568,  584,  570,  567,  585,  582,  575,  576,  578,  567,
+      561,  559,  183,  577,  570,  562,  570,  553,  558,  567,
+
+      216,  567,  705,  565,  555,  563,  549,  545,  545,  563,
+      545,  561,  546,  705,  545,  554,  543,  705,  550,  549,
+      548,  534,  535,  543,  550,  545,  537,  533,  526,  528,
+      525,  531,  524,  529,  705,  705,  538,  535,  537,  533,
+      523,  535,  534,  522,  513,  530,  513,  525,  705,  521,
+      519,  705,  509,  508,  221,  520,  521,  504,  513,  705,
+      506,  519,  507,  499,  512,  496,  495,  496,  705,  493,
+      503,  486,  492,  497,  490,  503,  494,  705,  490,  495,
+      502,  480,  498,  482,  478,  475,  485,  491,  705,  480,
+      193,  493,  705,  469,  480,  705,  471,  477,  471,  479,
+
+      705,  466,  471,  467,  483,  480,  705,  477,  476,  465,
+      470,  478,  457,  471,  461,  470,  460,  470,  460,  458,
+      451,  705,  462,  705,  466,  462,  705,  440,  444,  458,
+      461,  447,  445,  456,  453,  448,  453,  435,  441,  452,
+      705,  448,  221,  450,  426,  705,  444,  436,  442,  426,
+      444,  424,  422,  441,  437,  227,  428,  417,  434,  413,
+      435,  417,  705,  414,  428,  427,  418,  421,  705,  404,
+      427,  415,  421,  418,  415,  411,  402,  705,  407,  411,
+      400,  404,  416,  407,  414,  396,  408,  408,  391,  392,
+      227,  705,  400,  219,  705,  389,  402,  392,  385,  389,
+
+      385,  394,  231,  399,  395,  394,  393,  377,  387,  705,
+      705,  705,  705,  379,  705,  391,  705,  377,  377,  388,
+      705,  370,  705,  375,  380,  383,  365,  370,  368,  705,
+      705,  374,  379,  376,  375,  361,  371,  705,  368,  705,
+      357,  371,  354,  350,  354,  356,  369,  351,  355,  355,
+      705,  354,  345,  361,  705,  358,  342,  347,  355,  341,
+      351,  356,  351,  336,  340,  351,  332,  336,  336,  333,
+      339,  339,  333,  705,  705,  327,  325,  342,  322,  325,
+      335,  705,  705,  705,  321,  705,  705,  330,  318,  317,
+      705,  705,  331,  310,  313,  705,  323,  322,  318,  326,
+
+      308,  326,  306,  320,  705,  705,  320,  308,  705,  308,
+      312,  705,  705,  705,  305,  705,  310,  317,  295,  705,
+      311,  307,  300,  705,  705,  236,  299,  305,  309,  287,
+      306,  289,  302,  705,  705,  299,  296,  296,  281,  274,
+      267,  264,  263,  705,  705,  269,  258,  261,  705,  267,
+      250,  705,  705,  245,  225,  222,  705,  212,  166,  705,
+      705,  155,  705,  705,  705,  268,  274,  277,  283,  113,
+      289,  295,  301,  307,  313
     } ;
 
-static yyconst flex_int16_t yy_def[577] =
+static yyconst flex_int16_t yy_def[576] =
     {   0,
-      566,    1,  567,  567,  568,  568,  566,  566,  566,  566,
-      566,  569,  570,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  571,
-      566,  572,  566,  573,  574,  572,  566,  572,  572,  566,
-      566,  566,  569,  570,  566,  566,  566,  566,  575,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      571,  566,  572,  573,  573,  574,  572,  576,  566,  575,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      576,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,    0,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566
+      565,    1,  566,  566,  567,  567,  565,  565,  565,  565,
+      565,  568,  569,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  570,
+      565,  571,  572,  573,  571,  565,  571,  571,  565,  565,
+      565,  568,  569,  565,  565,  565,  565,  574,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  570,
+      565,  571,  572,  572,  573,  571,  575,  565,  574,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  575,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,    0,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565
     } ;
 
 static yyconst flex_int16_t yy_nxt[749] =
@@ -606,83 +606,83 @@ static yyconst flex_int16_t yy_nxt[749] =
        22,   23,   24,    8,   25,    8,    8,   26,   27,   28,
        29,   30,    8,   31,   32,   33,   34,   35,    8,    8,
         8,   36,   37,    8,   38,   10,   39,    8,   13,    8,
-        8,   55,   16,   56,    8,    8,   41,    8,   55,   58,
-       60,   50,   59,   50,   50,   61,   50,   71,   73,   66,
-       85,   72,   81,  133,  134,   62,   63,   82,   86,   74,
-       67,   64,   65,   68,   36,   37,    8,   38,   10,   39,
-        8,   13,    8,    8,   69,   16,   87,    8,    8,   41,
-
-        8,   51,   52,   75,   51,   52,   83,  117,   70,   96,
-      118,   76,   84,   97,   77,   94,   88,   78,  111,  105,
-       79,  128,   95,  106,  107,  129,  107,   36,   37,    9,
-       43,   11,   44,   45,   89,   98,  101,   46,   90,  108,
-       47,  108,  112,   99,  112,   91,   92,  100,   93,  102,
-      109,  170,  109,  109,  171,  109,  103,   54,  107,   54,
-      107,  108,  110,  108,   50,  110,   50,  184,   54,   48,
-       49,    9,   43,   11,   44,   45,  107,  123,  107,   46,
-      185,  108,   47,  108,   55,   55,   56,   60,  124,  565,
-       51,   52,  135,   51,   52,  131,  136,  132,  137,  138,
-
-      564,  162,  145,  152,   51,   52,  146,  153,  163,  344,
-      165,   48,   49,  166,  174,  107,  253,  107,  175,  254,
-      108,  167,  108,  109,  345,  109,  168,  112,  112,  112,
-      112,   54,  563,   54,  176,  110,  120,  216,  120,  120,
-      389,  120,   54,  217,  262,  263,  436,  120,  310,  311,
-      120,  402,  312,  439,  440,  538,  390,  562,  403,  448,
-      561,  404,  437,   51,   52,  560,  449,  539,   40,   40,
+        8,   54,   16,   55,    8,    8,   41,    8,   54,   57,
+       59,   49,   58,   49,   49,   60,   49,   70,   72,   65,
+       84,   71,   80,  132,  133,   61,   62,   81,   85,   73,
+       66,   63,   64,   67,   36,   37,    8,   38,   10,   39,
+        8,   13,    8,    8,   68,   16,   86,    8,    8,   41,
+
+        8,   50,   51,   74,   50,   51,   82,  116,   69,   95,
+      117,   75,   83,   96,   76,   93,   87,   77,  110,  104,
+       78,  127,   94,  105,  106,  128,  106,   36,   37,    9,
+       10,   11,   43,   44,   88,   97,  100,   45,   89,  107,
+       46,  107,  111,   98,  111,   90,   91,   99,   92,  101,
+      108,  169,  108,  108,  170,  108,  102,   53,  106,   53,
+      106,  107,  109,  107,   49,  109,   49,  183,   53,   47,
+       48,    9,   10,   11,   43,   44,  106,  122,  106,   45,
+      184,  107,   46,  107,   54,   54,   55,   59,  123,  564,
+       50,   51,  134,   50,   51,  130,  135,  131,  136,  137,
+
+      563,  161,  144,  151,   50,   51,  145,  152,  162,  343,
+      164,   47,   48,  165,  173,  106,  252,  106,  174,  253,
+      107,  166,  107,  108,  344,  108,  167,  111,  111,  111,
+      111,   53,  562,   53,  175,  109,  119,  215,  119,  119,
+      388,  119,   53,  216,  261,  262,  435,  119,  309,  310,
+      119,  401,  311,  438,  439,  537,  389,  561,  402,  447,
+      560,  403,  436,   50,   51,  559,  448,  538,   40,   40,
        40,   40,   40,   40,   42,   42,   42,   42,   42,   42,
-       53,   53,   53,   54,   54,  559,   54,   54,   54,  113,
-      558,  557,  556,  113,  113,  114,  555,  554,  553,  114,
-
-      114,  116,  116,  552,  116,  116,  116,  120,  120,  551,
-      120,  120,  120,  181,  181,  550,  181,  181,  181,  549,
-      548,  547,  546,  545,  544,  543,  542,  541,  540,  537,
-      536,  535,  534,  533,  532,  531,  530,  529,  528,  527,
-      526,  525,  524,  523,  522,  521,  520,  519,  518,  517,
-      516,  515,  514,  513,  512,  511,  510,  509,  508,  507,
-      506,  505,  504,  503,  502,  501,  500,  499,  498,  497,
-      496,  495,  494,  493,  492,  491,  490,  489,  488,  487,
-      486,  485,  484,  483,  482,  481,  480,  479,  478,  477,
-      476,  475,  474,  473,  472,  471,  470,  469,  468,  467,
-
-      466,  465,  464,  463,  462,  461,  460,  459,  458,  457,
-      456,  455,  454,  453,  452,  451,  450,  447,  446,  445,
-      444,  443,  442,  441,  438,  435,  434,  433,  432,  431,
-      430,  429,  428,  427,  426,  425,  424,  423,  422,  421,
-      420,  419,  418,  417,  416,  415,  414,  413,  412,  411,
-      410,  409,  408,  407,  406,  405,  401,  400,  399,  398,
-      397,  396,  395,  394,  393,  392,  391,  388,  387,  386,
-      385,  384,  383,  382,  381,  380,  379,  378,  377,  376,
-      375,  374,  373,  372,  371,  370,  369,  368,  367,  366,
-      365,  364,  363,  362,  361,  360,  359,  358,  357,  356,
-
-      355,  354,  353,  352,  351,  350,  349,  348,  347,  346,
-      343,  342,  341,  340,  339,  338,  337,  336,  335,  334,
-      333,  332,  331,  330,  329,  328,  327,  326,  325,  324,
-      323,  322,  321,  320,  319,  318,  317,  316,  315,  314,
-      313,  309,  308,  307,  306,  305,  304,  303,  302,  301,
-      300,  299,  298,  297,  296,  295,  294,  293,  292,  291,
-      290,  289,  288,  287,  286,  285,  284,  283,  282,  281,
-      280,  279,  278,  277,  276,  275,  274,  273,  272,  271,
-      270,  269,  268,  267,  266,  265,  264,  261,  260,  259,
-      258,  257,  256,  255,  252,  251,  250,  249,  248,  247,
-
-      246,  245,  244,  243,  242,  241,  240,  239,  238,  237,
-      236,  235,  234,  233,  232,  231,  230,  229,  228,  227,
-      226,  225,  224,  223,  222,  221,  220,  219,  218,  215,
-      214,  213,  212,  211,  210,  209,  208,  207,  206,  205,
-      204,  203,  202,  201,  200,  199,  198,  197,  196,  195,
-      194,  193,  192,  191,  190,  189,  188,  187,  186,  183,
-      182,  115,  115,  180,  179,  178,  177,  173,  172,  169,
-      164,  161,  160,  159,  158,  157,  156,  155,  154,  151,
-      150,  149,  148,  147,  144,  143,  142,  141,  140,  139,
-      130,  127,  126,  125,  122,  121,   57,   57,  119,  115,
-
-      104,   80,   57,  566,    7,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566
+       52,   52,   52,   53,   53,  558,   53,   53,   53,  112,
+      557,  556,  555,  112,  112,  113,  554,  553,  552,  113,
+
+      113,  115,  115,  551,  115,  115,  115,  119,  119,  550,
+      119,  119,  119,  180,  180,  549,  180,  180,  180,  548,
+      547,  546,  545,  544,  543,  542,  541,  540,  539,  536,
+      535,  534,  533,  532,  531,  530,  529,  528,  527,  526,
+      525,  524,  523,  522,  521,  520,  519,  518,  517,  516,
+      515,  514,  513,  512,  511,  510,  509,  508,  507,  506,
+      505,  504,  503,  502,  501,  500,  499,  498,  497,  496,
+      495,  494,  493,  492,  491,  490,  489,  488,  487,  486,
+      485,  484,  483,  482,  481,  480,  479,  478,  477,  476,
+      475,  474,  473,  472,  471,  470,  469,  468,  467,  466,
+
+      465,  464,  463,  462,  461,  460,  459,  458,  457,  456,
+      455,  454,  453,  452,  451,  450,  449,  446,  445,  444,
+      443,  442,  441,  440,  437,  434,  433,  432,  431,  430,
+      429,  428,  427,  426,  425,  424,  423,  422,  421,  420,
+      419,  418,  417,  416,  415,  414,  413,  412,  411,  410,
+      409,  408,  407,  406,  405,  404,  400,  399,  398,  397,
+      396,  395,  394,  393,  392,  391,  390,  387,  386,  385,
+      384,  383,  382,  381,  380,  379,  378,  377,  376,  375,
+      374,  373,  372,  371,  370,  369,  368,  367,  366,  365,
+      364,  363,  362,  361,  360,  359,  358,  357,  356,  355,
+
+      354,  353,  352,  351,  350,  349,  348,  347,  346,  345,
+      342,  341,  340,  339,  338,  337,  336,  335,  334,  333,
+      332,  331,  330,  329,  328,  327,  326,  325,  324,  323,
+      322,  321,  320,  319,  318,  317,  316,  315,  314,  313,
+      312,  308,  307,  306,  305,  304,  303,  302,  301,  300,
+      299,  298,  297,  296,  295,  294,  293,  292,  291,  290,
+      289,  288,  287,  286,  285,  284,  283,  282,  281,  280,
+      279,  278,  277,  276,  275,  274,  273,  272,  271,  270,
+      269,  268,  267,  266,  265,  264,  263,  260,  259,  258,
+      257,  256,  255,  254,  251,  250,  249,  248,  247,  246,
+
+      245,  244,  243,  242,  241,  240,  239,  238,  237,  236,
+      235,  234,  233,  232,  231,  230,  229,  228,  227,  226,
+      225,  224,  223,  222,  221,  220,  219,  218,  217,  214,
+      213,  212,  211,  210,  209,  208,  207,  206,  205,  204,
+      203,  202,  201,  200,  199,  198,  197,  196,  195,  194,
+      193,  192,  191,  190,  189,  188,  187,  186,  185,  182,
+      181,  114,  114,  179,  178,  177,  176,  172,  171,  168,
+      163,  160,  159,  158,  157,  156,  155,  154,  153,  150,
+      149,  148,  147,  146,  143,  142,  141,  140,  139,  138,
+      129,  126,  125,  124,  121,  120,   56,   56,  118,  114,
+
+      103,   79,   56,  565,    7,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565
     } ;
 
 static yyconst flex_int16_t yy_chk[749] =
@@ -694,81 +694,81 @@ static yyconst flex_int16_t yy_chk[749] =
         1,    1,    1,    3,    3,    3,    3,    3,    3,    3,
         3,   14,    3,   14,    3,    3,    3,    3,   17,   16,
        17,    9,   16,    9,   11,   18,   11,   21,   22,   19,
-       27,   21,   25,   70,   70,   18,   18,   25,   27,   22,
+       27,   21,   25,   69,   69,   18,   18,   25,   27,   22,
        19,   18,   18,   19,    3,    3,    4,    4,    4,    4,
         4,    4,    4,    4,   20,    4,   28,    4,    4,    4,
 
-        4,    9,    9,   23,   11,   11,   26,   46,   20,   31,
-       46,   23,   26,   31,   23,   30,   28,   23,  571,   35,
-       23,   67,   30,   35,   36,   67,   36,    4,    4,    5,
+        4,    9,    9,   23,   11,   11,   26,   45,   20,   31,
+       45,   23,   26,   31,   23,   30,   28,   23,  570,   35,
+       23,   66,   30,   35,   36,   66,   36,    4,    4,    5,
         5,    5,    5,    5,   29,   32,   33,    5,   29,   37,
         5,   37,   41,   32,   41,   29,   29,   32,   29,   33,
-       38,   99,   38,   39,   99,   39,   33,   45,   48,   45,
-       48,   49,   38,   49,   50,   39,   50,  123,   45,    5,
-        5,    6,    6,    6,    6,    6,   51,   63,   51,    6,
-      123,   52,    6,   52,   56,   60,   56,   60,   63,  563,
-       38,   38,   71,   39,   39,   69,   71,   69,   72,   72,
-
-      560,   95,   79,   85,   50,   50,   79,   85,   95,  292,
-       97,    6,    6,   97,  102,  107,  194,  107,  102,  194,
-      108,   97,  108,  109,  292,  109,   97,  110,  112,  110,
-      112,  116,  559,  116,  102,  109,  118,  156,  118,  181,
-      344,  181,  116,  156,  202,  202,  392,  118,  256,  256,
-      181,  357,  256,  395,  395,  527,  344,  557,  357,  404,
-      556,  357,  392,  109,  109,  555,  404,  527,  567,  567,
-      567,  567,  567,  567,  568,  568,  568,  568,  568,  568,
-      569,  569,  569,  570,  570,  552,  570,  570,  570,  572,
-      551,  549,  548,  572,  572,  573,  547,  544,  543,  573,
-
-      573,  574,  574,  542,  574,  574,  574,  575,  575,  541,
-      575,  575,  575,  576,  576,  540,  576,  576,  576,  539,
-      538,  537,  534,  533,  532,  531,  530,  529,  528,  524,
-      523,  522,  520,  519,  518,  516,  512,  511,  509,  508,
-      505,  504,  503,  502,  501,  500,  499,  498,  496,  495,
-      494,  491,  490,  489,  486,  482,  481,  480,  479,  478,
-      477,  474,  473,  472,  471,  470,  469,  468,  467,  466,
-      465,  464,  463,  462,  461,  460,  459,  458,  457,  455,
-      454,  453,  451,  450,  449,  448,  447,  446,  445,  444,
-      443,  442,  440,  438,  437,  436,  435,  434,  433,  430,
-
-      429,  428,  427,  426,  425,  423,  421,  420,  419,  417,
-      415,  410,  409,  408,  407,  406,  405,  403,  402,  401,
-      400,  399,  398,  397,  394,  391,  390,  389,  388,  387,
-      386,  385,  384,  383,  382,  381,  380,  378,  377,  376,
-      375,  374,  373,  372,  371,  369,  368,  367,  366,  365,
-      363,  362,  361,  360,  359,  358,  356,  355,  354,  353,
-      352,  351,  350,  349,  348,  346,  345,  343,  341,  340,
-      339,  338,  337,  336,  335,  334,  333,  332,  331,  330,
-      329,  327,  326,  324,  322,  321,  320,  319,  318,  317,
-      316,  315,  314,  313,  312,  311,  310,  309,  307,  306,
-
-      305,  304,  303,  301,  300,  299,  298,  296,  295,  293,
-      291,  289,  288,  287,  286,  285,  284,  283,  282,  281,
-      280,  278,  277,  276,  275,  274,  273,  272,  271,  269,
-      268,  267,  266,  265,  264,  263,  262,  260,  259,  258,
-      257,  255,  254,  252,  251,  249,  248,  247,  246,  245,
-      244,  243,  242,  241,  240,  239,  238,  235,  234,  233,
-      232,  231,  230,  229,  228,  227,  226,  225,  224,  223,
-      222,  221,  220,  218,  217,  216,  214,  213,  212,  211,
-      210,  209,  208,  207,  206,  205,  203,  201,  200,  199,
-      198,  197,  196,  195,  193,  192,  191,  190,  189,  188,
-
-      187,  186,  185,  184,  183,  182,  180,  179,  178,  177,
-      176,  175,  174,  173,  172,  171,  170,  169,  168,  167,
-      166,  165,  164,  163,  162,  161,  160,  159,  157,  155,
-      154,  153,  152,  151,  150,  149,  148,  147,  146,  145,
-      144,  143,  142,  141,  140,  138,  137,  136,  135,  134,
-      133,  132,  131,  129,  128,  127,  126,  125,  124,  122,
-      121,  115,  114,  106,  105,  104,  103,  101,  100,   98,
-       96,   94,   93,   91,   90,   89,   88,   87,   86,   84,
-       83,   82,   81,   80,   78,   77,   76,   75,   74,   73,
-       68,   66,   65,   64,   62,   61,   57,   55,   53,   44,
-
-       34,   24,   15,    7,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566,  566,  566,
-      566,  566,  566,  566,  566,  566,  566,  566
+       38,   98,   38,   39,   98,   39,   33,   44,   47,   44,
+       47,   48,   38,   48,   49,   39,   49,  122,   44,    5,
+        5,    6,    6,    6,    6,    6,   50,   62,   50,    6,
+      122,   51,    6,   51,   55,   59,   55,   59,   62,  562,
+       38,   38,   70,   39,   39,   68,   70,   68,   71,   71,
+
+      559,   94,   78,   84,   49,   49,   78,   84,   94,  291,
+       96,    6,    6,   96,  101,  106,  193,  106,  101,  193,
+      107,   96,  107,  108,  291,  108,   96,  109,  111,  109,
+      111,  115,  558,  115,  101,  108,  117,  155,  117,  180,
+      343,  180,  115,  155,  201,  201,  391,  117,  255,  255,
+      180,  356,  255,  394,  394,  526,  343,  556,  356,  403,
+      555,  356,  391,  108,  108,  554,  403,  526,  566,  566,
+      566,  566,  566,  566,  567,  567,  567,  567,  567,  567,
+      568,  568,  568,  569,  569,  551,  569,  569,  569,  571,
+      550,  548,  547,  571,  571,  572,  546,  543,  542,  572,
+
+      572,  573,  573,  541,  573,  573,  573,  574,  574,  540,
+      574,  574,  574,  575,  575,  539,  575,  575,  575,  538,
+      537,  536,  533,  532,  531,  530,  529,  528,  527,  523,
+      522,  521,  519,  518,  517,  515,  511,  510,  508,  507,
+      504,  503,  502,  501,  500,  499,  498,  497,  495,  494,
+      493,  490,  489,  488,  485,  481,  480,  479,  478,  477,
+      476,  473,  472,  471,  470,  469,  468,  467,  466,  465,
+      464,  463,  462,  461,  460,  459,  458,  457,  456,  454,
+      453,  452,  450,  449,  448,  447,  446,  445,  444,  443,
+      442,  441,  439,  437,  436,  435,  434,  433,  432,  429,
+
+      428,  427,  426,  425,  424,  422,  420,  419,  418,  416,
+      414,  409,  408,  407,  406,  405,  404,  402,  401,  400,
+      399,  398,  397,  396,  393,  390,  389,  388,  387,  386,
+      385,  384,  383,  382,  381,  380,  379,  377,  376,  375,
+      374,  373,  372,  371,  370,  368,  367,  366,  365,  364,
+      362,  361,  360,  359,  358,  357,  355,  354,  353,  352,
+      351,  350,  349,  348,  347,  345,  344,  342,  340,  339,
+      338,  337,  336,  335,  334,  333,  332,  331,  330,  329,
+      328,  326,  325,  323,  321,  320,  319,  318,  317,  316,
+      315,  314,  313,  312,  311,  310,  309,  308,  306,  305,
+
+      304,  303,  302,  300,  299,  298,  297,  295,  294,  292,
+      290,  288,  287,  286,  285,  284,  283,  282,  281,  280,
+      279,  277,  276,  275,  274,  273,  272,  271,  270,  268,
+      267,  266,  265,  264,  263,  262,  261,  259,  258,  257,
+      256,  254,  253,  251,  250,  248,  247,  246,  245,  244,
+      243,  242,  241,  240,  239,  238,  237,  234,  233,  232,
+      231,  230,  229,  228,  227,  226,  225,  224,  223,  222,
+      221,  220,  219,  217,  216,  215,  213,  212,  211,  210,
+      209,  208,  207,  206,  205,  204,  202,  200,  199,  198,
+      197,  196,  195,  194,  192,  191,  190,  189,  188,  187,
+
+      186,  185,  184,  183,  182,  181,  179,  178,  177,  176,
+      175,  174,  173,  172,  171,  170,  169,  168,  167,  166,
+      165,  164,  163,  162,  161,  160,  159,  158,  156,  154,
+      153,  152,  151,  150,  149,  148,  147,  146,  145,  144,
+      143,  142,  141,  140,  139,  137,  136,  135,  134,  133,
+      132,  131,  130,  128,  127,  126,  125,  124,  123,  121,
+      120,  114,  113,  105,  104,  103,  102,  100,   99,   97,
+       95,   93,   92,   90,   89,   88,   87,   86,   85,   83,
+       82,   81,   80,   79,   77,   76,   75,   74,   73,   72,
+       67,   65,   64,   63,   61,   60,   56,   54,   52,   43,
+
+       34,   24,   15,    7,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565,  565,  565,
+      565,  565,  565,  565,  565,  565,  565,  565
     } ;
 
 static yy_state_type yy_last_accepting_state;
@@ -1035,13 +1035,13 @@ yy_match:
                        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                                {
                                yy_current_state = (int) yy_def[yy_current_state];
-                               if ( yy_current_state >= 567 )
+                               if ( yy_current_state >= 566 )
                                        yy_c = yy_meta[(unsigned int) yy_c];
                                }
                        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
                        ++yy_cp;
                        }
-               while ( yy_current_state != 566 );
+               while ( yy_current_state != 565 );
                yy_cp = (yy_last_accepting_cpos);
                yy_current_state = (yy_last_accepting_state);
 
@@ -1085,11 +1085,13 @@ YY_RULE_SETUP
 { /* attribute name = normal string */
                strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 );
                yy_lval.charValue = charBuffer;
+                       // "CHANNEL"                            { return KW_ATTRCHANNEL;  /* global attr list */ }
+                       if(!strcmp(charBuffer,"CHANNEL")) return KW_ATTRCHANNEL;
                return DT_ATTRNAME; }
        YY_BREAK
 case 5:
 YY_RULE_SETUP
-#line 68 "src/cfglexer.ll"
+#line 70 "src/cfglexer.ll"
 { /* quoted string! attribute name = normal string */
                strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 );
                        /* get rid of " " */
@@ -1100,442 +1102,441 @@ YY_RULE_SETUP
        YY_BREAK
 case 6:
 YY_RULE_SETUP
-#line 75 "src/cfglexer.ll"
+#line 77 "src/cfglexer.ll"
 { /* ends at newline or ';' */
                strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 );
                yy_lval.charValue = charBuffer;
                return DT_ATTRVALUE; }
        YY_BREAK
 case 7:
-/* rule 7 can match eol */
 YY_RULE_SETUP
-#line 79 "src/cfglexer.ll"
+#line 81 "src/cfglexer.ll"
 { /* return end token... */
                        BEGIN(ATTR); 
                        return KW_ATTREND; }
        YY_BREAK
 case 8:
 YY_RULE_SETUP
-#line 84 "src/cfglexer.ll"
+#line 86 "src/cfglexer.ll"
 { return KW_LBMSIM; }
        YY_BREAK
 case 9:
 YY_RULE_SETUP
-#line 85 "src/cfglexer.ll"
+#line 87 "src/cfglexer.ll"
 { return KW_COMPARELBM; }
        YY_BREAK
 case 10:
 YY_RULE_SETUP
-#line 86 "src/cfglexer.ll"
+#line 88 "src/cfglexer.ll"
 { return KW_DEBUGMODE; }
        YY_BREAK
 case 11:
 YY_RULE_SETUP
-#line 87 "src/cfglexer.ll"
+#line 89 "src/cfglexer.ll"
 { return KW_DEBUGLEVEL; }
        YY_BREAK
 case 12:
 YY_RULE_SETUP
-#line 88 "src/cfglexer.ll"
+#line 90 "src/cfglexer.ll"
 { return KW_RAYTRACING; }
        YY_BREAK
 case 13:
 YY_RULE_SETUP
-#line 91 "src/cfglexer.ll"
+#line 93 "src/cfglexer.ll"
 { return KW_RESOLUTION; }
        YY_BREAK
 case 14:
 YY_RULE_SETUP
-#line 92 "src/cfglexer.ll"
+#line 94 "src/cfglexer.ll"
 { return KW_ANTIALIAS; }
        YY_BREAK
 case 15:
 YY_RULE_SETUP
-#line 93 "src/cfglexer.ll"
+#line 95 "src/cfglexer.ll"
 { return KW_EYEPOINT; }
        YY_BREAK
 case 16:
 YY_RULE_SETUP
-#line 94 "src/cfglexer.ll"
+#line 96 "src/cfglexer.ll"
 { return KW_LOOKAT ; }
        YY_BREAK
 case 17:
 YY_RULE_SETUP
-#line 95 "src/cfglexer.ll"
+#line 97 "src/cfglexer.ll"
 { return KW_UPVEC ; }
        YY_BREAK
 case 18:
 YY_RULE_SETUP
-#line 96 "src/cfglexer.ll"
+#line 98 "src/cfglexer.ll"
 { return KW_FOVY; }
        YY_BREAK
 case 19:
 YY_RULE_SETUP
-#line 97 "src/cfglexer.ll"
+#line 99 "src/cfglexer.ll"
 { return KW_ASPECT ; }
        YY_BREAK
 case 20:
 YY_RULE_SETUP
-#line 98 "src/cfglexer.ll"
+#line 100 "src/cfglexer.ll"
 { return KW_AMBIENCE; }
        YY_BREAK
 case 21:
 YY_RULE_SETUP
-#line 99 "src/cfglexer.ll"
+#line 101 "src/cfglexer.ll"
 { return KW_BACKGROUND; }
        YY_BREAK
 case 22:
 YY_RULE_SETUP
-#line 100 "src/cfglexer.ll"
+#line 102 "src/cfglexer.ll"
 { return KW_ANISTART; }
        YY_BREAK
 case 23:
 YY_RULE_SETUP
-#line 101 "src/cfglexer.ll"
+#line 103 "src/cfglexer.ll"
 { return KW_ANIFRAMES; }
        YY_BREAK
 case 24:
 YY_RULE_SETUP
-#line 102 "src/cfglexer.ll"
+#line 104 "src/cfglexer.ll"
 { return KW_ANIFRAMETIME; }
        YY_BREAK
 case 25:
 YY_RULE_SETUP
-#line 103 "src/cfglexer.ll"
+#line 105 "src/cfglexer.ll"
 { return KW_FRAMESKIP; }
        YY_BREAK
 case 26:
 YY_RULE_SETUP
-#line 104 "src/cfglexer.ll"
+#line 106 "src/cfglexer.ll"
 { return KW_FILENAME; }
        YY_BREAK
 case 27:
 YY_RULE_SETUP
-#line 105 "src/cfglexer.ll"
+#line 107 "src/cfglexer.ll"
 { return KW_PMCAUSTICS; }
        YY_BREAK
 case 28:
 YY_RULE_SETUP
-#line 106 "src/cfglexer.ll"
+#line 108 "src/cfglexer.ll"
 { return KW_CAUSTICDIST; }
        YY_BREAK
 case 29:
 YY_RULE_SETUP
-#line 107 "src/cfglexer.ll"
+#line 109 "src/cfglexer.ll"
 { return KW_CAUSTICPHOT; }
        YY_BREAK
 case 30:
 YY_RULE_SETUP
-#line 108 "src/cfglexer.ll"
+#line 110 "src/cfglexer.ll"
 { return KW_SHADOWMAPBIAS; }
        YY_BREAK
 case 31:
 YY_RULE_SETUP
-#line 109 "src/cfglexer.ll"
+#line 111 "src/cfglexer.ll"
 { return KW_MAXRAYDEPTH; }
        YY_BREAK
 case 32:
 YY_RULE_SETUP
-#line 110 "src/cfglexer.ll"
+#line 112 "src/cfglexer.ll"
 { return KW_TREEMAXDEPTH; }
        YY_BREAK
 case 33:
 YY_RULE_SETUP
-#line 111 "src/cfglexer.ll"
+#line 113 "src/cfglexer.ll"
 { return KW_TREEMAXTRIANGLES; }
        YY_BREAK
 case 34:
 YY_RULE_SETUP
-#line 112 "src/cfglexer.ll"
+#line 114 "src/cfglexer.ll"
 { return KW_DEBUGPIXEL; }
        YY_BREAK
 case 35:
 YY_RULE_SETUP
-#line 113 "src/cfglexer.ll"
+#line 115 "src/cfglexer.ll"
 { return KW_TESTMODE; }
        YY_BREAK
 case 36:
 YY_RULE_SETUP
-#line 114 "src/cfglexer.ll"
+#line 116 "src/cfglexer.ll"
 { return KW_OPENGLATTR; }
        YY_BREAK
 case 37:
 YY_RULE_SETUP
-#line 115 "src/cfglexer.ll"
+#line 117 "src/cfglexer.ll"
 { return KW_BLENDERATTR; }
        YY_BREAK
 case 38:
 YY_RULE_SETUP
-#line 117 "src/cfglexer.ll"
+#line 119 "src/cfglexer.ll"
 { return KW_OBJATTR; /* assign attr to obj */ }
        YY_BREAK
 case 39:
 YY_RULE_SETUP
-#line 118 "src/cfglexer.ll"
+#line 120 "src/cfglexer.ll"
 { BEGIN(ATTR); return KW_ATTRIBUTE;  /* global attr list */ }
        YY_BREAK
 case 40:
 YY_RULE_SETUP
-#line 119 "src/cfglexer.ll"
+#line 121 "src/cfglexer.ll"
 { BEGIN(ATTR); return KW_DEFINEATTR; /* obj defines new attrs */ }
        YY_BREAK
 case 41:
 YY_RULE_SETUP
-#line 120 "src/cfglexer.ll"
+#line 122 "src/cfglexer.ll"
 { BEGIN(ATTR); return KW_DEFINEATTR; }
        YY_BREAK
 case 42:
 YY_RULE_SETUP
-#line 121 "src/cfglexer.ll"
+#line 123 "src/cfglexer.ll"
 { BEGIN(ATTR); return KW_DEFINEATTR; }
        YY_BREAK
 case 43:
 YY_RULE_SETUP
-#line 123 "src/cfglexer.ll"
+#line 125 "src/cfglexer.ll"
 { return KW_GEOMETRY; }
        YY_BREAK
 case 44:
 YY_RULE_SETUP
-#line 124 "src/cfglexer.ll"
+#line 126 "src/cfglexer.ll"
 { return KW_TYPE; }
        YY_BREAK
 case 45:
 YY_RULE_SETUP
-#line 125 "src/cfglexer.ll"
+#line 127 "src/cfglexer.ll"
 { return KW_GEOTYPE_BOX; }
        YY_BREAK
 case 46:
 YY_RULE_SETUP
-#line 126 "src/cfglexer.ll"
+#line 128 "src/cfglexer.ll"
 { return KW_GEOTYPE_SPHERE; }
        YY_BREAK
 case 47:
 YY_RULE_SETUP
-#line 127 "src/cfglexer.ll"
+#line 129 "src/cfglexer.ll"
 { return KW_GEOTYPE_OBJMODEL; }
        YY_BREAK
 case 48:
 YY_RULE_SETUP
-#line 128 "src/cfglexer.ll"
+#line 130 "src/cfglexer.ll"
 { return KW_CASTSHADOWS; }  
        YY_BREAK
 case 49:
 YY_RULE_SETUP
-#line 129 "src/cfglexer.ll"
+#line 131 "src/cfglexer.ll"
 { return KW_RECEIVESHADOWS ; }
        YY_BREAK
 case 50:
 YY_RULE_SETUP
-#line 130 "src/cfglexer.ll"
+#line 132 "src/cfglexer.ll"
 { return KW_VISIBLE; }  
        YY_BREAK
 case 51:
 YY_RULE_SETUP
-#line 131 "src/cfglexer.ll"
+#line 133 "src/cfglexer.ll"
 { return KW_BOX_START; }
        YY_BREAK
 case 52:
 YY_RULE_SETUP
-#line 132 "src/cfglexer.ll"
+#line 134 "src/cfglexer.ll"
 { return KW_BOX_END; }
        YY_BREAK
 case 53:
 YY_RULE_SETUP
-#line 133 "src/cfglexer.ll"
+#line 135 "src/cfglexer.ll"
 { return KW_POLY ; }
        YY_BREAK
 case 54:
 YY_RULE_SETUP
-#line 134 "src/cfglexer.ll"
+#line 136 "src/cfglexer.ll"
 { return KW_POLY ; }
        YY_BREAK
 case 55:
 YY_RULE_SETUP
-#line 135 "src/cfglexer.ll"
+#line 137 "src/cfglexer.ll"
 { return KW_NUMVERTICES; }
        YY_BREAK
 case 56:
 YY_RULE_SETUP
-#line 136 "src/cfglexer.ll"
+#line 138 "src/cfglexer.ll"
 { return KW_VERTEX; }
        YY_BREAK
 case 57:
 YY_RULE_SETUP
-#line 137 "src/cfglexer.ll"
+#line 139 "src/cfglexer.ll"
 { return KW_NUMPOLYGONS; }
        YY_BREAK
 case 58:
 YY_RULE_SETUP
-#line 138 "src/cfglexer.ll"
+#line 140 "src/cfglexer.ll"
 { return KW_ISOSURF; }  
        YY_BREAK
 case 59:
 YY_RULE_SETUP
-#line 139 "src/cfglexer.ll"
+#line 141 "src/cfglexer.ll"
 { return KW_FILEMODE; }  
        YY_BREAK
 case 60:
 YY_RULE_SETUP
-#line 140 "src/cfglexer.ll"
+#line 142 "src/cfglexer.ll"
 { return KW_INVERT; }  
        YY_BREAK
 case 61:
 YY_RULE_SETUP
-#line 142 "src/cfglexer.ll"
+#line 144 "src/cfglexer.ll"
 { return KW_MATERIAL; }
        YY_BREAK
 case 62:
 YY_RULE_SETUP
-#line 143 "src/cfglexer.ll"
+#line 145 "src/cfglexer.ll"
 { return KW_MATTYPE_PHONG; }
        YY_BREAK
 case 63:
 YY_RULE_SETUP
-#line 144 "src/cfglexer.ll"
+#line 146 "src/cfglexer.ll"
 { return KW_MATTYPE_BLINN; }
        YY_BREAK
 case 64:
 YY_RULE_SETUP
-#line 145 "src/cfglexer.ll"
+#line 147 "src/cfglexer.ll"
 { return KW_NAME; }
        YY_BREAK
 case 65:
 YY_RULE_SETUP
-#line 146 "src/cfglexer.ll"
+#line 148 "src/cfglexer.ll"
 { return KW_AMBIENT; }
        YY_BREAK
 case 66:
 YY_RULE_SETUP
-#line 147 "src/cfglexer.ll"
+#line 149 "src/cfglexer.ll"
 { return KW_DIFFUSE; }
        YY_BREAK
 case 67:
 YY_RULE_SETUP
-#line 148 "src/cfglexer.ll"
+#line 150 "src/cfglexer.ll"
 { return KW_SPECULAR; }
        YY_BREAK
 case 68:
 YY_RULE_SETUP
-#line 149 "src/cfglexer.ll"
+#line 151 "src/cfglexer.ll"
 { return KW_MIRROR; }
        YY_BREAK
 case 69:
 YY_RULE_SETUP
-#line 150 "src/cfglexer.ll"
+#line 152 "src/cfglexer.ll"
 { return KW_TRANSPARENCE; }
        YY_BREAK
 case 70:
 YY_RULE_SETUP
-#line 151 "src/cfglexer.ll"
+#line 153 "src/cfglexer.ll"
 { return KW_REFRACINDEX; }
        YY_BREAK
 case 71:
 YY_RULE_SETUP
-#line 152 "src/cfglexer.ll"
+#line 154 "src/cfglexer.ll"
 { return KW_TRANSADDITIVE; }
        YY_BREAK
 case 72:
 YY_RULE_SETUP
-#line 153 "src/cfglexer.ll"
+#line 155 "src/cfglexer.ll"
 { return KW_TRANSATTCOL; }
        YY_BREAK
 case 73:
 YY_RULE_SETUP
-#line 154 "src/cfglexer.ll"
+#line 156 "src/cfglexer.ll"
 { return KW_FRESNEL; }
        YY_BREAK
 case 74:
 YY_RULE_SETUP
-#line 155 "src/cfglexer.ll"
+#line 157 "src/cfglexer.ll"
 { return KW_FRESNEL; }
        YY_BREAK
 case 75:
 YY_RULE_SETUP
-#line 157 "src/cfglexer.ll"
+#line 159 "src/cfglexer.ll"
 { return KW_LIGHT; }
        YY_BREAK
 case 76:
 YY_RULE_SETUP
-#line 158 "src/cfglexer.ll"
+#line 160 "src/cfglexer.ll"
 { return KW_LIGHT_OMNI; }
        YY_BREAK
 case 77:
 YY_RULE_SETUP
-#line 159 "src/cfglexer.ll"
+#line 161 "src/cfglexer.ll"
 { return KW_ACTIVE; }
        YY_BREAK
 case 78:
 YY_RULE_SETUP
-#line 160 "src/cfglexer.ll"
+#line 162 "src/cfglexer.ll"
 { return KW_COLOUR; }
        YY_BREAK
 case 79:
 YY_RULE_SETUP
-#line 161 "src/cfglexer.ll"
+#line 163 "src/cfglexer.ll"
 { return KW_COLOUR; }
        YY_BREAK
 case 80:
 YY_RULE_SETUP
-#line 162 "src/cfglexer.ll"
+#line 164 "src/cfglexer.ll"
 { return KW_POSITION; }
        YY_BREAK
 case 81:
 YY_RULE_SETUP
-#line 163 "src/cfglexer.ll"
+#line 165 "src/cfglexer.ll"
 { return KW_CAUSTICPHOTONS; }
        YY_BREAK
 case 82:
 YY_RULE_SETUP
-#line 164 "src/cfglexer.ll"
+#line 166 "src/cfglexer.ll"
 { return KW_CAUSTICSTRENGTH; }
        YY_BREAK
 case 83:
 YY_RULE_SETUP
-#line 165 "src/cfglexer.ll"
+#line 167 "src/cfglexer.ll"
 { return KW_SHADOWMAP; }
        YY_BREAK
 case 84:
 YY_RULE_SETUP
-#line 166 "src/cfglexer.ll"
+#line 168 "src/cfglexer.ll"
 { return KW_CAUSTICSMAP; }
        YY_BREAK
 case 85:
 YY_RULE_SETUP
-#line 168 "src/cfglexer.ll"
+#line 170 "src/cfglexer.ll"
 { yy_lval.intValue = 1; return DT_INTEGER; }
        YY_BREAK
 case 86:
 YY_RULE_SETUP
-#line 169 "src/cfglexer.ll"
+#line 171 "src/cfglexer.ll"
 { yy_lval.intValue = 0; return DT_INTEGER; }
        YY_BREAK
 case 87:
 YY_RULE_SETUP
-#line 170 "src/cfglexer.ll"
+#line 172 "src/cfglexer.ll"
 { yy_lval.intValue = 1; return DT_INTEGER; }
        YY_BREAK
 case 88:
 YY_RULE_SETUP
-#line 171 "src/cfglexer.ll"
+#line 173 "src/cfglexer.ll"
 { yy_lval.intValue = 0; return DT_INTEGER; }
        YY_BREAK
 case 89:
 YY_RULE_SETUP
-#line 174 "src/cfglexer.ll"
+#line 176 "src/cfglexer.ll"
 { // integer number
   yy_lval.intValue = atoi( yy_text );
   return DT_INTEGER; }
        YY_BREAK
 case 90:
 YY_RULE_SETUP
-#line 178 "src/cfglexer.ll"
+#line 180 "src/cfglexer.ll"
 { // floating point number
   yy_lval.floatValue = atof( yy_text );
   return DT_FLOAT; }
        YY_BREAK
 case 91:
 YY_RULE_SETUP
-#line 182 "src/cfglexer.ll"
+#line 184 "src/cfglexer.ll"
 { /* normal character strings, now also for paths/filenames */
   strncpy( charBuffer, yy_text, CHAR_BUFFER_SIZE-2 );
        /* get rid of " " */
@@ -1546,17 +1547,17 @@ YY_RULE_SETUP
        YY_BREAK
 case 92:
 YY_RULE_SETUP
-#line 190 "src/cfglexer.ll"
+#line 192 "src/cfglexer.ll"
 { /* one line comment */  }
        YY_BREAK
 case 93:
 YY_RULE_SETUP
-#line 191 "src/cfglexer.ll"
+#line 193 "src/cfglexer.ll"
 { /* one line comment */  }
        YY_BREAK
 case 94:
 YY_RULE_SETUP
-#line 192 "src/cfglexer.ll"
+#line 194 "src/cfglexer.ll"
 { /* multiline comment */
        register int c; 
        for ( ; ; )     {
@@ -1582,26 +1583,26 @@ YY_RULE_SETUP
 case 95:
 /* rule 95 can match eol */
 YY_RULE_SETUP
-#line 216 "src/cfglexer.ll"
+#line 218 "src/cfglexer.ll"
 { // count line numbers
   lineCount++; }
        YY_BREAK
 case 96:
 YY_RULE_SETUP
-#line 219 "src/cfglexer.ll"
+#line 221 "src/cfglexer.ll"
 { /* do nothing by default... */ }
        YY_BREAK
 case 97:
 YY_RULE_SETUP
-#line 221 "src/cfglexer.ll"
+#line 223 "src/cfglexer.ll"
 { /*errorOut( "cfgLexer, Line "<<lineCount<<" : Unknown character '"<<(char)yyinput()<<"' " ); xit(1); */ }
        YY_BREAK
 case 98:
 YY_RULE_SETUP
-#line 224 "src/cfglexer.ll"
+#line 226 "src/cfglexer.ll"
 ECHO;
        YY_BREAK
-#line 1605 "<stdout>"
+#line 1606 "<stdout>"
 case YY_STATE_EOF(INITIAL):
 case YY_STATE_EOF(ATTR):
 case YY_STATE_EOF(ATTRVALUE):
@@ -1888,7 +1889,7 @@ static int yy_get_next_buffer (void)
                while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                        {
                        yy_current_state = (int) yy_def[yy_current_state];
-                       if ( yy_current_state >= 567 )
+                       if ( yy_current_state >= 566 )
                                yy_c = yy_meta[(unsigned int) yy_c];
                        }
                yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
@@ -1916,11 +1917,11 @@ static int yy_get_next_buffer (void)
        while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state )
                {
                yy_current_state = (int) yy_def[yy_current_state];
-               if ( yy_current_state >= 567 )
+               if ( yy_current_state >= 566 )
                        yy_c = yy_meta[(unsigned int) yy_c];
                }
        yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c];
-       yy_is_jam = (yy_current_state == 566);
+       yy_is_jam = (yy_current_state == 565);
 
        return yy_is_jam ? 0 : yy_current_state;
 }
@@ -2566,4 +2567,4 @@ void yy_free (void * ptr )
 #undef YY_DECL_IS_OURS
 #undef YY_DECL
 #endif
-#line 224 "src/cfglexer.ll"
+#line 226 "src/cfglexer.ll"
index d47b3485153f56313a74a5ca4a8be794e79ce11a..16a8772ff7274d06faf3195ad7a05bfe94915fea 100644 (file)
      KW_OPENGLATTR = 314,
      KW_BLENDERATTR = 315,
      KW_ATTRIBUTE = 316,
-     KW_OBJATTR = 317,
-     KW_EQUALS = 318,
-     KW_DEFINEATTR = 319,
-     KW_ATTREND = 320,
-     KW_GEOMETRY = 321,
-     KW_TYPE = 322,
-     KW_GEOTYPE_BOX = 323,
-     KW_GEOTYPE_FLUID = 324,
-     KW_GEOTYPE_OBJMODEL = 325,
-     KW_GEOTYPE_SPHERE = 326,
-     KW_CASTSHADOWS = 327,
-     KW_RECEIVESHADOWS = 328,
-     KW_VISIBLE = 329,
-     KW_BOX_END = 330,
-     KW_BOX_START = 331,
-     KW_POLY = 332,
-     KW_NUMVERTICES = 333,
-     KW_VERTEX = 334,
-     KW_NUMPOLYGONS = 335,
-     KW_ISOSURF = 336,
-     KW_FILEMODE = 337,
-     KW_INVERT = 338,
-     KW_MATERIAL = 339,
-     KW_MATTYPE_PHONG = 340,
-     KW_MATTYPE_BLINN = 341,
-     KW_NAME = 342,
-     KW_AMBIENT = 343,
-     KW_DIFFUSE = 344,
-     KW_SPECULAR = 345,
-     KW_MIRROR = 346,
-     KW_TRANSPARENCE = 347,
-     KW_REFRACINDEX = 348,
-     KW_TRANSADDITIVE = 349,
-     KW_TRANSATTCOL = 350,
-     KW_FRESNEL = 351,
-     KW_LIGHT = 352,
-     KW_ACTIVE = 353,
-     KW_COLOUR = 354,
-     KW_POSITION = 355,
-     KW_LIGHT_OMNI = 356,
-     KW_CAUSTICPHOTONS = 357,
-     KW_CAUSTICSTRENGTH = 358,
-     KW_SHADOWMAP = 359,
-     KW_CAUSTICSMAP = 360
+     KW_ATTRCHANNEL = 317,
+     KW_OBJATTR = 318,
+     KW_EQUALS = 319,
+     KW_DEFINEATTR = 320,
+     KW_ATTREND = 321,
+     KW_GEOMETRY = 322,
+     KW_TYPE = 323,
+     KW_GEOTYPE_BOX = 324,
+     KW_GEOTYPE_FLUID = 325,
+     KW_GEOTYPE_OBJMODEL = 326,
+     KW_GEOTYPE_SPHERE = 327,
+     KW_CASTSHADOWS = 328,
+     KW_RECEIVESHADOWS = 329,
+     KW_VISIBLE = 330,
+     KW_BOX_END = 331,
+     KW_BOX_START = 332,
+     KW_POLY = 333,
+     KW_NUMVERTICES = 334,
+     KW_VERTEX = 335,
+     KW_NUMPOLYGONS = 336,
+     KW_ISOSURF = 337,
+     KW_FILEMODE = 338,
+     KW_INVERT = 339,
+     KW_MATERIAL = 340,
+     KW_MATTYPE_PHONG = 341,
+     KW_MATTYPE_BLINN = 342,
+     KW_NAME = 343,
+     KW_AMBIENT = 344,
+     KW_DIFFUSE = 345,
+     KW_SPECULAR = 346,
+     KW_MIRROR = 347,
+     KW_TRANSPARENCE = 348,
+     KW_REFRACINDEX = 349,
+     KW_TRANSADDITIVE = 350,
+     KW_TRANSATTCOL = 351,
+     KW_FRESNEL = 352,
+     KW_LIGHT = 353,
+     KW_ACTIVE = 354,
+     KW_COLOUR = 355,
+     KW_POSITION = 356,
+     KW_LIGHT_OMNI = 357,
+     KW_CAUSTICPHOTONS = 358,
+     KW_CAUSTICSTRENGTH = 359,
+     KW_SHADOWMAP = 360,
+     KW_CAUSTICSMAP = 361
    };
 #endif
 #define DT_INTEGER 258
 #define KW_OPENGLATTR 314
 #define KW_BLENDERATTR 315
 #define KW_ATTRIBUTE 316
-#define KW_OBJATTR 317
-#define KW_EQUALS 318
-#define KW_DEFINEATTR 319
-#define KW_ATTREND 320
-#define KW_GEOMETRY 321
-#define KW_TYPE 322
-#define KW_GEOTYPE_BOX 323
-#define KW_GEOTYPE_FLUID 324
-#define KW_GEOTYPE_OBJMODEL 325
-#define KW_GEOTYPE_SPHERE 326
-#define KW_CASTSHADOWS 327
-#define KW_RECEIVESHADOWS 328
-#define KW_VISIBLE 329
-#define KW_BOX_END 330
-#define KW_BOX_START 331
-#define KW_POLY 332
-#define KW_NUMVERTICES 333
-#define KW_VERTEX 334
-#define KW_NUMPOLYGONS 335
-#define KW_ISOSURF 336
-#define KW_FILEMODE 337
-#define KW_INVERT 338
-#define KW_MATERIAL 339
-#define KW_MATTYPE_PHONG 340
-#define KW_MATTYPE_BLINN 341
-#define KW_NAME 342
-#define KW_AMBIENT 343
-#define KW_DIFFUSE 344
-#define KW_SPECULAR 345
-#define KW_MIRROR 346
-#define KW_TRANSPARENCE 347
-#define KW_REFRACINDEX 348
-#define KW_TRANSADDITIVE 349
-#define KW_TRANSATTCOL 350
-#define KW_FRESNEL 351
-#define KW_LIGHT 352
-#define KW_ACTIVE 353
-#define KW_COLOUR 354
-#define KW_POSITION 355
-#define KW_LIGHT_OMNI 356
-#define KW_CAUSTICPHOTONS 357
-#define KW_CAUSTICSTRENGTH 358
-#define KW_SHADOWMAP 359
-#define KW_CAUSTICSMAP 360
+#define KW_ATTRCHANNEL 317
+#define KW_OBJATTR 318
+#define KW_EQUALS 319
+#define KW_DEFINEATTR 320
+#define KW_ATTREND 321
+#define KW_GEOMETRY 322
+#define KW_TYPE 323
+#define KW_GEOTYPE_BOX 324
+#define KW_GEOTYPE_FLUID 325
+#define KW_GEOTYPE_OBJMODEL 326
+#define KW_GEOTYPE_SPHERE 327
+#define KW_CASTSHADOWS 328
+#define KW_RECEIVESHADOWS 329
+#define KW_VISIBLE 330
+#define KW_BOX_END 331
+#define KW_BOX_START 332
+#define KW_POLY 333
+#define KW_NUMVERTICES 334
+#define KW_VERTEX 335
+#define KW_NUMPOLYGONS 336
+#define KW_ISOSURF 337
+#define KW_FILEMODE 338
+#define KW_INVERT 339
+#define KW_MATERIAL 340
+#define KW_MATTYPE_PHONG 341
+#define KW_MATTYPE_BLINN 342
+#define KW_NAME 343
+#define KW_AMBIENT 344
+#define KW_DIFFUSE 345
+#define KW_SPECULAR 346
+#define KW_MIRROR 347
+#define KW_TRANSPARENCE 348
+#define KW_REFRACINDEX 349
+#define KW_TRANSADDITIVE 350
+#define KW_TRANSATTCOL 351
+#define KW_FRESNEL 352
+#define KW_LIGHT 353
+#define KW_ACTIVE 354
+#define KW_COLOUR 355
+#define KW_POSITION 356
+#define KW_LIGHT_OMNI 357
+#define KW_CAUSTICPHOTONS 358
+#define KW_CAUSTICSTRENGTH 359
+#define KW_SHADOWMAP 360
+#define KW_CAUSTICSMAP 361
 
 
 
@@ -363,7 +365,7 @@ typedef union YYSTYPE {
   char  *charValue;
 } YYSTYPE;
 /* Line 190 of yacc.c.  */
-#line 367 "bld-std-gcc/src/cfgparser.cpp"
+#line 369 "bld-std-gcc/src/cfgparser.cpp"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
@@ -375,7 +377,7 @@ typedef union YYSTYPE {
 
 
 /* Line 213 of yacc.c.  */
-#line 379 "bld-std-gcc/src/cfgparser.cpp"
+#line 381 "bld-std-gcc/src/cfgparser.cpp"
 
 #if ! defined (yyoverflow) || YYERROR_VERBOSE
 
@@ -477,20 +479,20 @@ union yyalloc
 /* YYFINAL -- State number of the termination state. */
 #define YYFINAL  15
 /* YYLAST -- Last index in YYTABLE.  */
-#define YYLAST   277
+#define YYLAST   288
 
 /* YYNTOKENS -- Number of terminals. */
-#define YYNTOKENS  106
+#define YYNTOKENS  107
 /* YYNNTS -- Number of nonterminals. */
-#define YYNNTS  78
+#define YYNNTS  82
 /* YYNRULES -- Number of rules. */
-#define YYNRULES  138
+#define YYNRULES  143
 /* YYNRULES -- Number of states. */
-#define YYNSTATES  240
+#define YYNSTATES  249
 
 /* YYTRANSLATE(YYLEX) -- Bison symbol number corresponding to YYLEX.  */
 #define YYUNDEFTOK  2
-#define YYMAXUTOK   360
+#define YYMAXUTOK   361
 
 #define YYTRANSLATE(YYX)                                               \
   ((unsigned int) (YYX) <= YYMAXUTOK ? yytranslate[YYX] : YYUNDEFTOK)
@@ -534,7 +536,7 @@ static const unsigned char yytranslate[] =
       75,    76,    77,    78,    79,    80,    81,    82,    83,    84,
       85,    86,    87,    88,    89,    90,    91,    92,    93,    94,
       95,    96,    97,    98,    99,   100,   101,   102,   103,   104,
-     105
+     105,   106
 };
 
 #if YYDEBUG
@@ -554,52 +556,54 @@ static const unsigned short int yyprhs[] =
      240,   243,   246,   249,   252,   257,   262,   265,   270,   277,
      280,   282,   284,   286,   288,   290,   292,   294,   296,   298,
      300,   302,   304,   306,   309,   314,   319,   323,   326,   329,
-     332,   335,   340,   343,   344,   351,   354,   356,   357,   358,
-     365,   368,   370,   372,   374,   376,   378,   380,   382
+     332,   335,   340,   343,   344,   351,   354,   356,   358,   360,
+     361,   362,   370,   371,   372,   379,   382,   384,   386,   388,
+     390,   392,   394,   396
 };
 
 /* YYRHS -- A `-1'-separated list of the rules' RHS. */
 static const short int yyrhs[] =
 {
-     107,     0,    -1,   107,   108,    -1,   108,    -1,   111,    -1,
-     171,    -1,   109,    -1,   110,    -1,    11,     3,    -1,    12,
-       3,    -1,    34,    35,   112,    36,    -1,   112,   113,    -1,
-     113,    -1,   116,    -1,   114,    -1,   115,    -1,   117,    -1,
-     118,    -1,   119,    -1,   120,    -1,   121,    -1,   122,    -1,
-     123,    -1,   124,    -1,   125,    -1,   126,    -1,   127,    -1,
-     128,    -1,   129,    -1,   130,    -1,   131,    -1,   132,    -1,
-     133,    -1,   134,    -1,   135,    -1,   143,    -1,   174,    -1,
-     157,    -1,    48,   182,    -1,    10,   182,    -1,    49,   181,
-      -1,    50,   183,    -1,    45,   181,   181,    -1,    46,     3,
-      -1,    47,   180,   180,   180,    -1,    51,   180,   180,   180,
-      -1,    52,   180,   180,   180,    -1,    53,   180,    -1,    54,
-     180,    -1,    55,   180,   180,   180,    -1,    56,   180,   180,
-     180,    -1,    37,     5,    -1,    43,   181,    -1,    44,   181,
-      -1,    39,   181,    -1,    57,     3,     3,    -1,    58,   183,
-      -1,    59,     5,    -1,    60,     5,    -1,    97,    35,    67,
-     137,   136,    36,    -1,   136,   138,    -1,   138,    -1,   101,
-      -1,   139,    -1,   140,    -1,   141,    -1,   142,    -1,    98,
-     183,    -1,    72,   183,    -1,    99,   180,   180,   180,    -1,
-     100,   180,   180,   180,    -1,    -1,    66,    35,    67,   146,
-     144,   145,    36,    -1,   145,   147,    -1,   147,    -1,    68,
-      -1,    71,    -1,    70,    -1,     8,    -1,     9,    -1,   148,
-      -1,   149,    -1,   150,    -1,   151,    -1,   152,    -1,   153,
-      -1,   154,    -1,   155,    -1,   156,    -1,    87,     5,    -1,
-      84,     5,    -1,    72,   183,    -1,    73,   183,    -1,    74,
-     183,    -1,    76,   180,   180,   180,    -1,    75,   180,   180,
-     180,    -1,    62,     5,    -1,    64,    35,   173,    36,    -1,
-      84,    35,    67,   159,   158,    36,    -1,   158,   160,    -1,
-     160,    -1,    85,    -1,    86,    -1,   161,    -1,   162,    -1,
-     163,    -1,   164,    -1,   165,    -1,   167,    -1,   166,    -1,
-     168,    -1,   169,    -1,   170,    -1,    87,     5,    -1,    88,
-     178,   178,   178,    -1,    89,   178,   178,   178,    -1,    90,
-     180,   180,    -1,    91,   179,    -1,    92,   179,    -1,    93,
-     180,    -1,    94,   179,    -1,    95,   180,   180,   180,    -1,
-      96,   182,    -1,    -1,    61,     6,    35,   172,   173,    36,
-      -1,   173,   174,    -1,   174,    -1,    -1,    -1,     6,    63,
-     175,   177,   176,    65,    -1,   177,     7,    -1,     7,    -1,
-     179,    -1,   180,    -1,     4,    -1,     3,    -1,     3,    -1,
-       3,    -1,     3,    -1
+     108,     0,    -1,   108,   109,    -1,   109,    -1,   112,    -1,
+     172,    -1,   110,    -1,   111,    -1,    11,     3,    -1,    12,
+       3,    -1,    34,    35,   113,    36,    -1,   113,   114,    -1,
+     114,    -1,   117,    -1,   115,    -1,   116,    -1,   118,    -1,
+     119,    -1,   120,    -1,   121,    -1,   122,    -1,   123,    -1,
+     124,    -1,   125,    -1,   126,    -1,   127,    -1,   128,    -1,
+     129,    -1,   130,    -1,   131,    -1,   132,    -1,   133,    -1,
+     134,    -1,   135,    -1,   136,    -1,   144,    -1,   175,    -1,
+     158,    -1,    48,   187,    -1,    10,   187,    -1,    49,   186,
+      -1,    50,   188,    -1,    45,   186,   186,    -1,    46,     3,
+      -1,    47,   185,   185,   185,    -1,    51,   185,   185,   185,
+      -1,    52,   185,   185,   185,    -1,    53,   185,    -1,    54,
+     185,    -1,    55,   185,   185,   185,    -1,    56,   185,   185,
+     185,    -1,    37,     5,    -1,    43,   186,    -1,    44,   186,
+      -1,    39,   186,    -1,    57,     3,     3,    -1,    58,   188,
+      -1,    59,     5,    -1,    60,     5,    -1,    98,    35,    68,
+     138,   137,    36,    -1,   137,   139,    -1,   139,    -1,   102,
+      -1,   140,    -1,   141,    -1,   142,    -1,   143,    -1,    99,
+     188,    -1,    73,   188,    -1,   100,   185,   185,   185,    -1,
+     101,   185,   185,   185,    -1,    -1,    67,    35,    68,   147,
+     145,   146,    36,    -1,   146,   148,    -1,   148,    -1,    69,
+      -1,    72,    -1,    71,    -1,     8,    -1,     9,    -1,   149,
+      -1,   150,    -1,   151,    -1,   152,    -1,   153,    -1,   154,
+      -1,   155,    -1,   156,    -1,   157,    -1,    88,     5,    -1,
+      85,     5,    -1,    73,   188,    -1,    74,   188,    -1,    75,
+     188,    -1,    77,   185,   185,   185,    -1,    76,   185,   185,
+     185,    -1,    63,     5,    -1,    65,    35,   174,    36,    -1,
+      85,    35,    68,   160,   159,    36,    -1,   159,   161,    -1,
+     161,    -1,    86,    -1,    87,    -1,   162,    -1,   163,    -1,
+     164,    -1,   165,    -1,   166,    -1,   168,    -1,   167,    -1,
+     169,    -1,   170,    -1,   171,    -1,    88,     5,    -1,    89,
+     183,   183,   183,    -1,    90,   183,   183,   183,    -1,    91,
+     185,   185,    -1,    92,   184,    -1,    93,   184,    -1,    94,
+     185,    -1,    95,   184,    -1,    96,   185,   185,   185,    -1,
+      97,   187,    -1,    -1,    61,     6,    35,   173,   174,    36,
+      -1,   174,   175,    -1,   175,    -1,   179,    -1,   176,    -1,
+      -1,    -1,    62,     6,    64,   177,   182,   178,    66,    -1,
+      -1,    -1,     6,    64,   180,   182,   181,    66,    -1,   182,
+       7,    -1,     7,    -1,   184,    -1,   185,    -1,     4,    -1,
+       3,    -1,     3,    -1,     3,    -1,     3,    -1
 };
 
 /* YYRLINE[YYN] -- source line where rule number YYN was defined.  */
@@ -617,8 +621,9 @@ static const unsigned short int yyrline[] =
      448,   454,   460,   466,   471,   486,   502,   508,   518,   529,
      530,   533,   538,   542,   543,   544,   545,   546,   547,   548,
      549,   550,   551,   556,   561,   566,   571,   577,   582,   587,
-     592,   597,   602,   613,   613,   623,   623,   626,   627,   626,
-     634,   637,   647,   650,   662,   664,   670,   681,   693
+     592,   597,   602,   613,   613,   623,   623,   626,   626,   629,
+     630,   629,   637,   638,   637,   645,   648,   658,   661,   673,
+     675,   681,   692,   704
 };
 #endif
 
@@ -642,10 +647,11 @@ static const char *const yytname[] =
   "KW_ANISTART", "KW_ANIFRAMES", "KW_FRAMESKIP", "KW_LOOKAT", "KW_UPVEC",
   "KW_FOVY", "KW_ASPECT", "KW_AMBIENCE", "KW_BACKGROUND", "KW_DEBUGPIXEL",
   "KW_TESTMODE", "KW_OPENGLATTR", "KW_BLENDERATTR", "KW_ATTRIBUTE",
-  "KW_OBJATTR", "KW_EQUALS", "KW_DEFINEATTR", "KW_ATTREND", "KW_GEOMETRY",
-  "KW_TYPE", "KW_GEOTYPE_BOX", "KW_GEOTYPE_FLUID", "KW_GEOTYPE_OBJMODEL",
-  "KW_GEOTYPE_SPHERE", "KW_CASTSHADOWS", "KW_RECEIVESHADOWS", "KW_VISIBLE",
-  "KW_BOX_END", "KW_BOX_START", "KW_POLY", "KW_NUMVERTICES", "KW_VERTEX",
+  "KW_ATTRCHANNEL", "KW_OBJATTR", "KW_EQUALS", "KW_DEFINEATTR",
+  "KW_ATTREND", "KW_GEOMETRY", "KW_TYPE", "KW_GEOTYPE_BOX",
+  "KW_GEOTYPE_FLUID", "KW_GEOTYPE_OBJMODEL", "KW_GEOTYPE_SPHERE",
+  "KW_CASTSHADOWS", "KW_RECEIVESHADOWS", "KW_VISIBLE", "KW_BOX_END",
+  "KW_BOX_START", "KW_POLY", "KW_NUMVERTICES", "KW_VERTEX",
   "KW_NUMPOLYGONS", "KW_ISOSURF", "KW_FILEMODE", "KW_INVERT",
   "KW_MATERIAL", "KW_MATTYPE_PHONG", "KW_MATTYPE_BLINN", "KW_NAME",
   "KW_AMBIENT", "KW_DIFFUSE", "KW_SPECULAR", "KW_MIRROR",
@@ -680,9 +686,9 @@ static const char *const yytname[] =
   "materialexpression_transparence", "materialexpression_refracindex",
   "materialexpression_transadd", "materialexpression_transattcol",
   "materialexpression_fresnel", "attribute_section", "@2",
-  "attribute_line", "attribute_expression", "@3", "@4", "attrvalue_list",
-  "DT_COLOR", "DT_ZEROTOONE", "DT_REALVAL", "DT_INTLTZERO", "DT_POSINT",
-  "DT_BOOLEAN", 0
+  "attribute_line", "attribute_expression", "attribute_channel", "@3",
+  "@4", "attribute_normal", "@5", "@6", "attrvalue_list", "DT_COLOR",
+  "DT_ZEROTOONE", "DT_REALVAL", "DT_INTLTZERO", "DT_POSINT", "DT_BOOLEAN", 0
 };
 #endif
 
@@ -701,27 +707,28 @@ static const unsigned short int yytoknum[] =
      325,   326,   327,   328,   329,   330,   331,   332,   333,   334,
      335,   336,   337,   338,   339,   340,   341,   342,   343,   344,
      345,   346,   347,   348,   349,   350,   351,   352,   353,   354,
-     355,   356,   357,   358,   359,   360
+     355,   356,   357,   358,   359,   360,   361
 };
 # endif
 
 /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives.  */
 static const unsigned char yyr1[] =
 {
-       0,   106,   107,   107,   108,   108,   108,   108,   109,   110,
-     111,   112,   112,   113,   113,   113,   113,   113,   113,   113,
-     113,   113,   113,   113,   113,   113,   113,   113,   113,   113,
-     113,   113,   113,   113,   113,   113,   113,   113,   114,   115,
-     116,   117,   118,   119,   120,   121,   122,   123,   124,   125,
-     126,   127,   128,   129,   130,   131,   132,   133,   134,   135,
-     136,   136,   137,   138,   138,   138,   138,   139,   140,   141,
-     142,   144,   143,   145,   145,   146,   146,   146,   146,   146,
-     147,   147,   147,   147,   147,   147,   147,   147,   147,   148,
-     149,   150,   151,   152,   153,   154,   155,   156,   157,   158,
-     158,   159,   159,   160,   160,   160,   160,   160,   160,   160,
-     160,   160,   160,   161,   162,   163,   164,   165,   166,   167,
-     168,   169,   170,   172,   171,   173,   173,   175,   176,   174,
-     177,   177,   178,   179,   180,   180,   181,   182,   183
+       0,   107,   108,   108,   109,   109,   109,   109,   110,   111,
+     112,   113,   113,   114,   114,   114,   114,   114,   114,   114,
+     114,   114,   114,   114,   114,   114,   114,   114,   114,   114,
+     114,   114,   114,   114,   114,   114,   114,   114,   115,   116,
+     117,   118,   119,   120,   121,   122,   123,   124,   125,   126,
+     127,   128,   129,   130,   131,   132,   133,   134,   135,   136,
+     137,   137,   138,   139,   139,   139,   139,   140,   141,   142,
+     143,   145,   144,   146,   146,   147,   147,   147,   147,   147,
+     148,   148,   148,   148,   148,   148,   148,   148,   148,   149,
+     150,   151,   152,   153,   154,   155,   156,   157,   158,   159,
+     159,   160,   160,   161,   161,   161,   161,   161,   161,   161,
+     161,   161,   161,   162,   163,   164,   165,   166,   167,   168,
+     169,   170,   171,   173,   172,   174,   174,   175,   175,   177,
+     178,   176,   180,   181,   179,   182,   182,   183,   184,   185,
+     185,   186,   187,   188
 };
 
 /* YYR2[YYN] -- Number of symbols composing right hand side of rule YYN.  */
@@ -739,8 +746,9 @@ static const unsigned char yyr2[] =
        2,     2,     2,     2,     4,     4,     2,     4,     6,     2,
        1,     1,     1,     1,     1,     1,     1,     1,     1,     1,
        1,     1,     1,     2,     4,     4,     3,     2,     2,     2,
-       2,     4,     2,     0,     6,     2,     1,     0,     0,     6,
-       2,     1,     1,     1,     1,     1,     1,     1,     1
+       2,     4,     2,     0,     6,     2,     1,     1,     1,     0,
+       0,     7,     0,     0,     6,     2,     1,     1,     1,     1,
+       1,     1,     1,     1
 };
 
 /* YYDEFACT[STATE-NAME] -- Default rule to reduce with in state
@@ -752,83 +760,87 @@ static const unsigned char yydefact[] =
        5,     8,     9,     0,     0,     1,     2,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,     0,    12,    14,    15,    13,    16,    17,    18,
-      19,    20,    21,    22,    23,    24,    25,    26,    27,    28,
-      29,    30,    31,    32,    33,    34,    35,    37,    36,   123,
-     127,   137,    39,    51,   136,    54,    52,    53,     0,    43,
-     135,   134,     0,    38,    40,   138,    41,     0,     0,    47,
-      48,     0,     0,     0,    56,    57,    58,     0,     0,     0,
-      10,    11,     0,     0,    42,     0,     0,     0,     0,     0,
-      55,     0,     0,     0,     0,   126,   131,   128,    44,    45,
-      46,    49,    50,    78,    79,    75,    77,    76,    71,   101,
-     102,     0,    62,     0,   124,   125,   130,     0,     0,     0,
+       0,     0,     0,     0,    12,    14,    15,    13,    16,    17,
+      18,    19,    20,    21,    22,    23,    24,    25,    26,    27,
+      28,    29,    30,    31,    32,    33,    34,    35,    37,    36,
+     128,   127,   123,   132,   142,    39,    51,   141,    54,    52,
+      53,     0,    43,   140,   139,     0,    38,    40,   143,    41,
+       0,     0,    47,    48,     0,     0,     0,    56,    57,    58,
+       0,     0,     0,     0,    10,    11,     0,     0,    42,     0,
+       0,     0,     0,     0,    55,   129,     0,     0,     0,     0,
+     126,   136,   133,    44,    45,    46,    49,    50,     0,    78,
+      79,    75,    77,    76,    71,   101,   102,     0,    62,     0,
+     124,   125,   135,     0,   130,     0,     0,     0,     0,     0,
+       0,     0,     0,     0,     0,     0,     0,   100,   103,   104,
+     105,   106,   107,   109,   108,   110,   111,   112,     0,     0,
+       0,     0,     0,    61,    63,    64,    65,    66,   134,     0,
        0,     0,     0,     0,     0,     0,     0,     0,     0,     0,
-     100,   103,   104,   105,   106,   107,   109,   108,   110,   111,
-     112,     0,     0,     0,     0,     0,    61,    63,    64,    65,
-      66,   129,     0,     0,     0,     0,     0,     0,     0,     0,
-       0,     0,    74,    80,    81,    82,    83,    84,    85,    86,
-      87,    88,   113,     0,   132,   133,     0,     0,   117,   118,
-     119,   120,     0,   122,    98,    99,    68,    67,     0,     0,
-      59,    60,    96,     0,    91,    92,    93,     0,     0,    90,
-      89,    72,    73,     0,     0,   116,     0,     0,     0,     0,
-       0,     0,   114,   115,   121,    69,    70,    97,    95,    94
+      74,    80,    81,    82,    83,    84,    85,    86,    87,    88,
+     113,     0,   137,   138,     0,     0,   117,   118,   119,   120,
+       0,   122,    98,    99,    68,    67,     0,     0,    59,    60,
+     131,    96,     0,    91,    92,    93,     0,     0,    90,    89,
+      72,    73,     0,     0,   116,     0,     0,     0,     0,     0,
+       0,   114,   115,   121,    69,    70,    97,    95,    94
 };
 
 /* YYDEFGOTO[NTERM-NUM]. */
 static const short int yydefgoto[] =
 {
-      -1,     5,     6,     7,     8,     9,    42,    43,    44,    45,
-      46,    47,    48,    49,    50,    51,    52,    53,    54,    55,
-      56,    57,    58,    59,    60,    61,    62,    63,    64,    65,
-     165,   133,   166,   167,   168,   169,   170,    66,   138,   181,
-     128,   182,   183,   184,   185,   186,   187,   188,   189,   190,
-     191,    67,   149,   131,   150,   151,   152,   153,   154,   155,
-     156,   157,   158,   159,   160,    10,   102,   114,    68,   103,
-     137,   117,   193,   194,   195,    75,    72,    86
+      -1,     5,     6,     7,     8,     9,    43,    44,    45,    46,
+      47,    48,    49,    50,    51,    52,    53,    54,    55,    56,
+      57,    58,    59,    60,    61,    62,    63,    64,    65,    66,
+     172,   139,   173,   174,   175,   176,   177,    67,   145,   189,
+     134,   190,   191,   192,   193,   194,   195,   196,   197,   198,
+     199,    68,   156,   137,   157,   158,   159,   160,   161,   162,
+     163,   164,   165,   166,   167,    10,   106,   119,    69,    70,
+     128,   179,    71,   107,   143,   122,   201,   202,   203,    78,
+      75,    89
 };
 
 /* YYPACT[STATE-NUM] -- Index in YYTABLE of the portion describing
    STATE-NUM.  */
-#define YYPACT_NINF -115
+#define YYPACT_NINF -123
 static const short int yypact[] =
 {
-       7,    10,    22,    -9,    27,    11,  -115,  -115,  -115,  -115,
-    -115,  -115,  -115,   170,     2,  -115,  -115,   -21,    35,    34,
-      40,    40,    40,    40,    43,    17,    35,    40,    44,    17,
-      17,    17,    17,    17,    17,    46,    44,    48,    51,    23,
-      25,    29,    49,  -115,  -115,  -115,  -115,  -115,  -115,  -115,
-    -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,
-    -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,
-    -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,    40,  -115,
-    -115,  -115,    17,  -115,  -115,  -115,  -115,    17,    17,  -115,
-    -115,    17,    17,    62,  -115,  -115,  -115,   -13,     3,     4,
-    -115,  -115,    63,    66,  -115,    17,    17,    17,    17,    17,
-    -115,    19,   -69,   -23,    -5,  -115,  -115,    70,  -115,  -115,
-    -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,
-    -115,   181,  -115,   -48,  -115,  -115,  -115,    14,   169,   106,
-      17,    17,    17,    17,    17,    17,    17,    17,    35,    74,
-    -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,
-    -115,    44,    44,    17,    17,   -24,  -115,  -115,  -115,  -115,
-    -115,  -115,   107,    83,    44,    44,    44,    17,    17,   114,
-     116,   124,  -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,
-    -115,  -115,  -115,    17,  -115,  -115,    17,    17,  -115,  -115,
-    -115,  -115,    17,  -115,  -115,  -115,  -115,  -115,    17,    17,
-    -115,  -115,  -115,    63,  -115,  -115,  -115,    17,    17,  -115,
-    -115,  -115,  -115,    17,    17,  -115,    17,    17,    17,     8,
-      17,    17,  -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115
+       3,    27,    33,   -11,    37,    11,  -123,  -123,  -123,  -123,
+    -123,  -123,  -123,   180,    13,  -123,  -123,   -20,    43,    44,
+      47,    47,    47,    47,    48,    29,    43,    47,    49,    29,
+      29,    29,    29,    29,    29,    50,    49,    52,    56,    61,
+      19,    23,    36,    53,  -123,  -123,  -123,  -123,  -123,  -123,
+    -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,
+    -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,
+    -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,
+    -123,    47,  -123,  -123,  -123,    29,  -123,  -123,  -123,  -123,
+      29,    29,  -123,  -123,    29,    29,    59,  -123,  -123,  -123,
+      -9,     8,    25,    57,  -123,  -123,    21,    70,  -123,    29,
+      29,    29,    29,    29,  -123,  -123,     9,   -52,    -7,     6,
+    -123,  -123,   109,  -123,  -123,  -123,  -123,  -123,    70,  -123,
+    -123,  -123,  -123,  -123,  -123,  -123,  -123,   191,  -123,   -60,
+    -123,  -123,  -123,    51,   109,    67,   113,    29,    29,    29,
+      29,    29,    29,    29,    29,    43,    78,  -123,  -123,  -123,
+    -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,    49,    49,
+      29,    29,   -26,  -123,  -123,  -123,  -123,  -123,  -123,    55,
+     121,    93,    49,    49,    49,    29,    29,   131,   132,   185,
+    -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,
+    -123,    29,  -123,  -123,    29,    29,  -123,  -123,  -123,  -123,
+      29,  -123,  -123,  -123,  -123,  -123,    29,    29,  -123,  -123,
+    -123,  -123,    21,  -123,  -123,  -123,    29,    29,  -123,  -123,
+    -123,  -123,    29,    29,  -123,    29,    29,    29,    20,    29,
+      29,  -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123
 };
 
 /* YYPGOTO[NTERM-NUM].  */
-static const yysigned_char yypgoto[] =
+static const short int yypgoto[] =
 {
-    -115,  -115,   118,  -115,  -115,  -115,  -115,    82,  -115,  -115,
-    -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,
-    -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,
-    -115,  -115,   -40,  -115,  -115,  -115,  -115,  -115,  -115,  -115,
-    -115,   -55,  -115,  -115,  -115,  -115,  -115,  -115,  -115,  -115,
-    -115,  -115,  -115,  -115,   -20,  -115,  -115,  -115,  -115,  -115,
-    -115,  -115,  -115,  -115,  -115,  -115,  -115,   -82,   -99,  -115,
-    -115,  -115,   -80,  -114,   -25,    13,   -16,   -34
+    -123,  -123,   134,  -123,  -123,  -123,  -123,   107,  -123,  -123,
+    -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,
+    -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,
+    -123,  -123,   -19,  -123,  -123,  -123,  -123,  -123,  -123,  -123,
+    -123,   -33,  -123,  -123,  -123,  -123,  -123,  -123,  -123,  -123,
+    -123,  -123,  -123,  -123,     1,  -123,  -123,  -123,  -123,  -123,
+    -123,  -123,  -123,  -123,  -123,  -123,  -123,   -68,  -103,  -123,
+    -123,  -123,  -123,  -123,  -123,    30,  -110,  -122,   -25,    -2,
+     -24,   -35
 };
 
 /* YYTABLE[YYPACT[STATE-NUM]].  What to do in state STATE-NUM.  If
@@ -838,96 +850,99 @@ static const yysigned_char yypgoto[] =
 #define YYTABLE_NINF -1
 static const unsigned char yytable[] =
 {
-      82,    17,    94,   115,    87,    88,    89,    90,    91,    92,
-      83,    15,   210,    11,    17,   135,   129,   130,     1,     2,
-      80,    81,     1,     2,   161,    12,    13,   123,   124,   198,
-     199,   134,   201,    14,    76,    77,    78,    69,    71,    73,
-      84,     3,    70,    74,   237,     3,    79,    85,   161,    93,
-     162,   163,   164,    95,   111,    17,    96,   105,    97,    18,
-      98,   196,   106,   107,    99,   110,   108,   109,     4,    17,
-     112,   113,     4,   116,   162,   163,   164,   136,   132,   171,
-     118,   119,   120,   121,   122,   100,    19,   125,    20,   126,
-     127,   104,    21,    22,    23,    24,    25,    26,    27,    28,
-      29,    30,    31,    32,    33,    34,    35,    36,    37,    38,
-     204,   192,   212,   223,   115,    39,   224,   197,   213,   219,
-     200,   220,   202,    16,   101,   211,   222,   206,   207,   205,
-     135,   229,   203,    40,     0,     0,     0,     0,   208,   209,
-     214,   215,   216,   232,   233,     0,    41,     0,     0,     0,
-       0,     0,   217,   218,     0,     0,     0,     0,     0,     0,
-     221,   139,   140,   141,   142,   143,   144,   145,   146,   147,
-     148,     0,   225,     0,     0,     0,    17,   226,     0,     0,
-      18,     0,     0,   227,   228,     0,   172,     0,   173,     0,
-       0,     0,   230,   231,     0,     0,   174,   175,   176,   177,
-     178,   234,   235,   236,     0,   238,   239,    19,   179,    20,
-       0,   180,     0,    21,    22,    23,    24,    25,    26,    27,
+      85,    97,    86,   120,    90,    91,    92,    93,    94,    95,
+     218,    15,    17,   168,     1,     2,   141,   129,   130,    79,
+      80,    81,     1,     2,    13,    87,    17,    17,   206,   207,
+      11,   209,    83,    84,   135,   136,    12,     3,   204,   169,
+     170,   171,   140,    14,    73,     3,    74,   168,    72,    76,
+      77,    82,    88,    96,   101,   115,   246,    98,   102,    17,
+     109,    99,   114,    18,     4,   110,   111,   100,    39,   112,
+     113,   103,     4,   169,   170,   171,   116,   121,   131,   108,
+     132,   133,    39,    39,   123,   124,   125,   126,   127,   104,
+      19,   232,    20,   117,   233,   138,    21,    22,    23,    24,
+      25,    26,    27,    28,    29,    30,    31,    32,    33,    34,
+      35,    36,    37,    38,   212,    39,   142,   178,   200,   120,
+      40,   220,   241,   242,   205,   118,   221,   208,   222,   210,
+     180,   211,   181,   214,   215,   141,   228,   229,    41,    16,
+     182,   183,   184,   185,   186,   216,   217,   223,   224,   225,
+     105,    42,   187,   219,   238,   188,   231,   213,   144,     0,
+     226,   227,     0,     0,     0,     0,   146,   147,   148,   149,
+     150,   151,   152,   153,   154,   155,     0,     0,     0,     0,
+     234,     0,     0,     0,     0,   235,    17,     0,     0,     0,
+      18,   236,   237,     0,     0,     0,     0,     0,     0,     0,
+       0,   239,   240,     0,     0,     0,     0,     0,     0,     0,
+     243,   244,   245,     0,   247,   248,     0,    19,     0,    20,
+       0,   230,     0,    21,    22,    23,    24,    25,    26,    27,
       28,    29,    30,    31,    32,    33,    34,    35,    36,    37,
-      38,   172,     0,   173,     0,     0,    39,     0,     0,     0,
-       0,   174,   175,   176,   177,   178,     0,     0,     0,     0,
-       0,     0,     0,   179,    40,     0,   180,     0,     0,     0,
-       0,     0,     0,     0,     0,     0,     0,    41,   139,   140,
-     141,   142,   143,   144,   145,   146,   147,   148
+      38,     0,    39,     0,     0,     0,     0,    40,   180,     0,
+     181,     0,     0,     0,     0,     0,     0,     0,   182,   183,
+     184,   185,   186,     0,     0,    41,     0,     0,     0,     0,
+     187,     0,     0,   188,     0,     0,     0,     0,    42,   146,
+     147,   148,   149,   150,   151,   152,   153,   154,   155
 };
 
 static const short int yycheck[] =
 {
-      25,     6,    36,   102,    29,    30,    31,    32,    33,    34,
-      26,     0,    36,     3,     6,   114,    85,    86,    11,    12,
-       3,     4,    11,    12,    72,     3,    35,     8,     9,   143,
-     144,    36,   146,     6,    21,    22,    23,    35,     3,     5,
-      27,    34,    63,     3,    36,    34,     3,     3,    72,     3,
-      98,    99,   100,     5,    67,     6,     5,    82,    35,    10,
-      35,   141,    87,    88,    35,     3,    91,    92,    61,     6,
-      67,    67,    61,     7,    98,    99,   100,     7,   101,    65,
-     105,   106,   107,   108,   109,    36,    37,    68,    39,    70,
-      71,    78,    43,    44,    45,    46,    47,    48,    49,    50,
-      51,    52,    53,    54,    55,    56,    57,    58,    59,    60,
-      36,     5,     5,   193,   213,    66,   196,   142,    35,     5,
-     145,     5,   147,     5,    42,   165,   181,   161,   162,   149,
-     229,   213,   148,    84,    -1,    -1,    -1,    -1,   163,   164,
-     174,   175,   176,   223,   224,    -1,    97,    -1,    -1,    -1,
-      -1,    -1,   177,   178,    -1,    -1,    -1,    -1,    -1,    -1,
-      36,    87,    88,    89,    90,    91,    92,    93,    94,    95,
-      96,    -1,   197,    -1,    -1,    -1,     6,   202,    -1,    -1,
-      10,    -1,    -1,   208,   209,    -1,    62,    -1,    64,    -1,
-      -1,    -1,   217,   218,    -1,    -1,    72,    73,    74,    75,
-      76,   226,   227,   228,    -1,   230,   231,    37,    84,    39,
-      -1,    87,    -1,    43,    44,    45,    46,    47,    48,    49,
+      25,    36,    26,   106,    29,    30,    31,    32,    33,    34,
+      36,     0,     6,    73,    11,    12,   119,     8,     9,    21,
+      22,    23,    11,    12,    35,    27,     6,     6,   150,   151,
+       3,   153,     3,     4,    86,    87,     3,    34,   148,    99,
+     100,   101,    36,     6,    64,    34,     3,    73,    35,     5,
+       3,     3,     3,     3,    35,    64,    36,     5,    35,     6,
+      85,     5,     3,    10,    61,    90,    91,     6,    62,    94,
+      95,    35,    61,    99,   100,   101,    68,     7,    69,    81,
+      71,    72,    62,    62,   109,   110,   111,   112,   113,    36,
+      37,   201,    39,    68,   204,   102,    43,    44,    45,    46,
+      47,    48,    49,    50,    51,    52,    53,    54,    55,    56,
+      57,    58,    59,    60,    36,    62,     7,    66,     5,   222,
+      67,    66,   232,   233,   149,    68,     5,   152,    35,   154,
+      63,   155,    65,   168,   169,   238,     5,     5,    85,     5,
+      73,    74,    75,    76,    77,   170,   171,   182,   183,   184,
+      43,    98,    85,   172,   222,    88,   189,   156,   128,    -1,
+     185,   186,    -1,    -1,    -1,    -1,    88,    89,    90,    91,
+      92,    93,    94,    95,    96,    97,    -1,    -1,    -1,    -1,
+     205,    -1,    -1,    -1,    -1,   210,     6,    -1,    -1,    -1,
+      10,   216,   217,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+      -1,   226,   227,    -1,    -1,    -1,    -1,    -1,    -1,    -1,
+     235,   236,   237,    -1,   239,   240,    -1,    37,    -1,    39,
+      -1,    36,    -1,    43,    44,    45,    46,    47,    48,    49,
       50,    51,    52,    53,    54,    55,    56,    57,    58,    59,
-      60,    62,    -1,    64,    -1,    -1,    66,    -1,    -1,    -1,
-      -1,    72,    73,    74,    75,    76,    -1,    -1,    -1,    -1,
-      -1,    -1,    -1,    84,    84,    -1,    87,    -1,    -1,    -1,
-      -1,    -1,    -1,    -1,    -1,    -1,    -1,    97,    87,    88,
-      89,    90,    91,    92,    93,    94,    95,    96
+      60,    -1,    62,    -1,    -1,    -1,    -1,    67,    63,    -1,
+      65,    -1,    -1,    -1,    -1,    -1,    -1,    -1,    73,    74,
+      75,    76,    77,    -1,    -1,    85,    -1,    -1,    -1,    -1,
+      85,    -1,    -1,    88,    -1,    -1,    -1,    -1,    98,    88,
+      89,    90,    91,    92,    93,    94,    95,    96,    97
 };
 
 /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing
    symbol of state STATE-NUM.  */
 static const unsigned char yystos[] =
 {
-       0,    11,    12,    34,    61,   107,   108,   109,   110,   111,
-     171,     3,     3,    35,     6,     0,   108,     6,    10,    37,
+       0,    11,    12,    34,    61,   108,   109,   110,   111,   112,
+     172,     3,     3,    35,     6,     0,   109,     6,    10,    37,
       39,    43,    44,    45,    46,    47,    48,    49,    50,    51,
-      52,    53,    54,    55,    56,    57,    58,    59,    60,    66,
-      84,    97,   112,   113,   114,   115,   116,   117,   118,   119,
+      52,    53,    54,    55,    56,    57,    58,    59,    60,    62,
+      67,    85,    98,   113,   114,   115,   116,   117,   118,   119,
      120,   121,   122,   123,   124,   125,   126,   127,   128,   129,
-     130,   131,   132,   133,   134,   135,   143,   157,   174,    35,
-      63,     3,   182,     5,     3,   181,   181,   181,   181,     3,
-       3,     4,   180,   182,   181,     3,   183,   180,   180,   180,
-     180,   180,   180,     3,   183,     5,     5,    35,    35,    35,
-      36,   113,   172,   175,   181,   180,   180,   180,   180,   180,
-       3,    67,    67,    67,   173,   174,     7,   177,   180,   180,
-     180,   180,   180,     8,     9,    68,    70,    71,   146,    85,
-      86,   159,   101,   137,    36,   174,     7,   176,   144,    87,
-      88,    89,    90,    91,    92,    93,    94,    95,    96,   158,
-     160,   161,   162,   163,   164,   165,   166,   167,   168,   169,
-     170,    72,    98,    99,   100,   136,   138,   139,   140,   141,
-     142,    65,    62,    64,    72,    73,    74,    75,    76,    84,
-      87,   145,   147,   148,   149,   150,   151,   152,   153,   154,
-     155,   156,     5,   178,   179,   180,   178,   180,   179,   179,
-     180,   179,   180,   182,    36,   160,   183,   183,   180,   180,
-      36,   138,     5,    35,   183,   183,   183,   180,   180,     5,
-       5,    36,   147,   178,   178,   180,   180,   180,   180,   173,
-     180,   180,   178,   178,   180,   180,   180,    36,   180,   180
+     130,   131,   132,   133,   134,   135,   136,   144,   158,   175,
+     176,   179,    35,    64,     3,   187,     5,     3,   186,   186,
+     186,   186,     3,     3,     4,   185,   187,   186,     3,   188,
+     185,   185,   185,   185,   185,   185,     3,   188,     5,     5,
+       6,    35,    35,    35,    36,   114,   173,   180,   186,   185,
+     185,   185,   185,   185,     3,    64,    68,    68,    68,   174,
+     175,     7,   182,   185,   185,   185,   185,   185,   177,     8,
+       9,    69,    71,    72,   147,    86,    87,   160,   102,   138,
+      36,   175,     7,   181,   182,   145,    88,    89,    90,    91,
+      92,    93,    94,    95,    96,    97,   159,   161,   162,   163,
+     164,   165,   166,   167,   168,   169,   170,   171,    73,    99,
+     100,   101,   137,   139,   140,   141,   142,   143,    66,   178,
+      63,    65,    73,    74,    75,    76,    77,    85,    88,   146,
+     148,   149,   150,   151,   152,   153,   154,   155,   156,   157,
+       5,   183,   184,   185,   183,   185,   184,   184,   185,   184,
+     185,   187,    36,   161,   188,   188,   185,   185,    36,   139,
+      66,     5,    35,   188,   188,   188,   185,   185,     5,     5,
+      36,   148,   183,   183,   185,   185,   185,   185,   174,   185,
+     185,   183,   183,   185,   185,   185,    36,   185,   185
 };
 
 #if ! defined (YYSIZE_T) && defined (__SIZE_TYPE__)
@@ -2011,36 +2026,50 @@ yyreduce:
                        currentAttrib = NULL; }
     break;
 
-  case 127:
-#line 626 "src/cfgparser.yy"
+  case 129:
+#line 629 "src/cfgparser.yy"
     { currentAttrValue.clear(); currentAttribAddName = (yyvsp[-1].charValue); }
     break;
 
-  case 128:
-#line 627 "src/cfgparser.yy"
+  case 130:
+#line 630 "src/cfgparser.yy"
     {
-      currentAttrib->addAttr( currentAttribAddName, currentAttrValue, lineCount); 
-                       //std::cerr << " ADD ATTR " << currentAttribAddName << std::endl;
+      currentAttrib->addAttr( currentAttribAddName, currentAttrValue, lineCount, true); 
+                       //std::cerr << " ADD ATTRCHANNEL " << currentAttribAddName << std::endl;
                        //currentAttrib->find( currentAttribAddName )->print();
                }
     break;
 
-  case 130:
-#line 634 "src/cfgparser.yy"
+  case 132:
+#line 637 "src/cfgparser.yy"
+    { currentAttrValue.clear(); currentAttribAddName = (yyvsp[-1].charValue); }
+    break;
+
+  case 133:
+#line 638 "src/cfgparser.yy"
+    {
+      currentAttrib->addAttr( currentAttribAddName, currentAttrValue, lineCount, false); 
+                       //std::cerr << " ADD ATTRNORM " << currentAttribAddName << std::endl;
+                       //currentAttrib->find( currentAttribAddName )->print();
+               }
+    break;
+
+  case 135:
+#line 645 "src/cfgparser.yy"
     { 
-               //std::cerr << "LLL "<<$2<<endl; 
-               currentAttrValue.push_back((yyvsp[0].charValue)); }
+               //std::cerr << "LLL "<<$2<<std::endl; // ignore newline entries  
+               if(strcmp((yyvsp[0].charValue),"\n")) currentAttrValue.push_back((yyvsp[0].charValue)); }
     break;
 
-  case 131:
-#line 637 "src/cfgparser.yy"
+  case 136:
+#line 648 "src/cfgparser.yy"
     {  
-               //std::cerr << "LRR "<<$1<<endl; 
-               currentAttrValue.push_back((yyvsp[0].charValue)); }
+               //std::cerr << "LRR "<<$1<<std::endl;
+               if(strcmp((yyvsp[0].charValue),"\n")) currentAttrValue.push_back((yyvsp[0].charValue)); }
     break;
 
-  case 133:
-#line 651 "src/cfgparser.yy"
+  case 138:
+#line 662 "src/cfgparser.yy"
     {
   if ( ((yyvsp[0].floatValue) < 0.0) || ((yyvsp[0].floatValue) > 1.0) ) {
     yyerror("Value out of range (only 0 to 1 allowed)");
@@ -2051,18 +2080,18 @@ yyreduce:
 }
     break;
 
-  case 134:
-#line 663 "src/cfgparser.yy"
+  case 139:
+#line 674 "src/cfgparser.yy"
     { (yyval.floatValue) = (yyvsp[0].floatValue); }
     break;
 
-  case 135:
-#line 665 "src/cfgparser.yy"
+  case 140:
+#line 676 "src/cfgparser.yy"
     { (yyval.floatValue) = (float) (yyvsp[0].intValue); /* conversion from integers */ }
     break;
 
-  case 136:
-#line 671 "src/cfgparser.yy"
+  case 141:
+#line 682 "src/cfgparser.yy"
     {
   if ( (yyvsp[0].intValue) <= 0 ) {
     yy_error("Value out of range (has to be above zero)");
@@ -2073,8 +2102,8 @@ yyreduce:
 }
     break;
 
-  case 137:
-#line 682 "src/cfgparser.yy"
+  case 142:
+#line 693 "src/cfgparser.yy"
     {
   //cout << " " << $1 << " ";
   if ( (yyvsp[0].intValue) < 0 ) {
@@ -2086,8 +2115,8 @@ yyreduce:
 }
     break;
 
-  case 138:
-#line 694 "src/cfgparser.yy"
+  case 143:
+#line 705 "src/cfgparser.yy"
     {
   if( ( (yyvsp[0].intValue) != 0 ) && ( (yyvsp[0].intValue) != 1 ) ) {
     yy_error("Boolean value has to be 1|0, 'true'|'false' or 'on'|'off'!");
@@ -2101,7 +2130,7 @@ yyreduce:
     }
 
 /* Line 1037 of yacc.c.  */
-#line 2105 "bld-std-gcc/src/cfgparser.cpp"
+#line 2134 "bld-std-gcc/src/cfgparser.cpp"
 \f
   yyvsp -= yylen;
   yyssp -= yylen;
@@ -2329,7 +2358,7 @@ yyreturn:
 }
 
 
-#line 702 "src/cfgparser.yy"
+#line 713 "src/cfgparser.yy"
 
 
 /*---------------------------------------------------------------------------*/
index c2b6c6c438c42e00c5defeb721634110785557d8..20b46f4e34638dc65e99d93539f17ad07020d55a 100644 (file)
      KW_OPENGLATTR = 314,
      KW_BLENDERATTR = 315,
      KW_ATTRIBUTE = 316,
-     KW_OBJATTR = 317,
-     KW_EQUALS = 318,
-     KW_DEFINEATTR = 319,
-     KW_ATTREND = 320,
-     KW_GEOMETRY = 321,
-     KW_TYPE = 322,
-     KW_GEOTYPE_BOX = 323,
-     KW_GEOTYPE_FLUID = 324,
-     KW_GEOTYPE_OBJMODEL = 325,
-     KW_GEOTYPE_SPHERE = 326,
-     KW_CASTSHADOWS = 327,
-     KW_RECEIVESHADOWS = 328,
-     KW_VISIBLE = 329,
-     KW_BOX_END = 330,
-     KW_BOX_START = 331,
-     KW_POLY = 332,
-     KW_NUMVERTICES = 333,
-     KW_VERTEX = 334,
-     KW_NUMPOLYGONS = 335,
-     KW_ISOSURF = 336,
-     KW_FILEMODE = 337,
-     KW_INVERT = 338,
-     KW_MATERIAL = 339,
-     KW_MATTYPE_PHONG = 340,
-     KW_MATTYPE_BLINN = 341,
-     KW_NAME = 342,
-     KW_AMBIENT = 343,
-     KW_DIFFUSE = 344,
-     KW_SPECULAR = 345,
-     KW_MIRROR = 346,
-     KW_TRANSPARENCE = 347,
-     KW_REFRACINDEX = 348,
-     KW_TRANSADDITIVE = 349,
-     KW_TRANSATTCOL = 350,
-     KW_FRESNEL = 351,
-     KW_LIGHT = 352,
-     KW_ACTIVE = 353,
-     KW_COLOUR = 354,
-     KW_POSITION = 355,
-     KW_LIGHT_OMNI = 356,
-     KW_CAUSTICPHOTONS = 357,
-     KW_CAUSTICSTRENGTH = 358,
-     KW_SHADOWMAP = 359,
-     KW_CAUSTICSMAP = 360
+     KW_ATTRCHANNEL = 317,
+     KW_OBJATTR = 318,
+     KW_EQUALS = 319,
+     KW_DEFINEATTR = 320,
+     KW_ATTREND = 321,
+     KW_GEOMETRY = 322,
+     KW_TYPE = 323,
+     KW_GEOTYPE_BOX = 324,
+     KW_GEOTYPE_FLUID = 325,
+     KW_GEOTYPE_OBJMODEL = 326,
+     KW_GEOTYPE_SPHERE = 327,
+     KW_CASTSHADOWS = 328,
+     KW_RECEIVESHADOWS = 329,
+     KW_VISIBLE = 330,
+     KW_BOX_END = 331,
+     KW_BOX_START = 332,
+     KW_POLY = 333,
+     KW_NUMVERTICES = 334,
+     KW_VERTEX = 335,
+     KW_NUMPOLYGONS = 336,
+     KW_ISOSURF = 337,
+     KW_FILEMODE = 338,
+     KW_INVERT = 339,
+     KW_MATERIAL = 340,
+     KW_MATTYPE_PHONG = 341,
+     KW_MATTYPE_BLINN = 342,
+     KW_NAME = 343,
+     KW_AMBIENT = 344,
+     KW_DIFFUSE = 345,
+     KW_SPECULAR = 346,
+     KW_MIRROR = 347,
+     KW_TRANSPARENCE = 348,
+     KW_REFRACINDEX = 349,
+     KW_TRANSADDITIVE = 350,
+     KW_TRANSATTCOL = 351,
+     KW_FRESNEL = 352,
+     KW_LIGHT = 353,
+     KW_ACTIVE = 354,
+     KW_COLOUR = 355,
+     KW_POSITION = 356,
+     KW_LIGHT_OMNI = 357,
+     KW_CAUSTICPHOTONS = 358,
+     KW_CAUSTICSTRENGTH = 359,
+     KW_SHADOWMAP = 360,
+     KW_CAUSTICSMAP = 361
    };
 #endif
 #define DT_INTEGER 258
 #define KW_OPENGLATTR 314
 #define KW_BLENDERATTR 315
 #define KW_ATTRIBUTE 316
-#define KW_OBJATTR 317
-#define KW_EQUALS 318
-#define KW_DEFINEATTR 319
-#define KW_ATTREND 320
-#define KW_GEOMETRY 321
-#define KW_TYPE 322
-#define KW_GEOTYPE_BOX 323
-#define KW_GEOTYPE_FLUID 324
-#define KW_GEOTYPE_OBJMODEL 325
-#define KW_GEOTYPE_SPHERE 326
-#define KW_CASTSHADOWS 327
-#define KW_RECEIVESHADOWS 328
-#define KW_VISIBLE 329
-#define KW_BOX_END 330
-#define KW_BOX_START 331
-#define KW_POLY 332
-#define KW_NUMVERTICES 333
-#define KW_VERTEX 334
-#define KW_NUMPOLYGONS 335
-#define KW_ISOSURF 336
-#define KW_FILEMODE 337
-#define KW_INVERT 338
-#define KW_MATERIAL 339
-#define KW_MATTYPE_PHONG 340
-#define KW_MATTYPE_BLINN 341
-#define KW_NAME 342
-#define KW_AMBIENT 343
-#define KW_DIFFUSE 344
-#define KW_SPECULAR 345
-#define KW_MIRROR 346
-#define KW_TRANSPARENCE 347
-#define KW_REFRACINDEX 348
-#define KW_TRANSADDITIVE 349
-#define KW_TRANSATTCOL 350
-#define KW_FRESNEL 351
-#define KW_LIGHT 352
-#define KW_ACTIVE 353
-#define KW_COLOUR 354
-#define KW_POSITION 355
-#define KW_LIGHT_OMNI 356
-#define KW_CAUSTICPHOTONS 357
-#define KW_CAUSTICSTRENGTH 358
-#define KW_SHADOWMAP 359
-#define KW_CAUSTICSMAP 360
+#define KW_ATTRCHANNEL 317
+#define KW_OBJATTR 318
+#define KW_EQUALS 319
+#define KW_DEFINEATTR 320
+#define KW_ATTREND 321
+#define KW_GEOMETRY 322
+#define KW_TYPE 323
+#define KW_GEOTYPE_BOX 324
+#define KW_GEOTYPE_FLUID 325
+#define KW_GEOTYPE_OBJMODEL 326
+#define KW_GEOTYPE_SPHERE 327
+#define KW_CASTSHADOWS 328
+#define KW_RECEIVESHADOWS 329
+#define KW_VISIBLE 330
+#define KW_BOX_END 331
+#define KW_BOX_START 332
+#define KW_POLY 333
+#define KW_NUMVERTICES 334
+#define KW_VERTEX 335
+#define KW_NUMPOLYGONS 336
+#define KW_ISOSURF 337
+#define KW_FILEMODE 338
+#define KW_INVERT 339
+#define KW_MATERIAL 340
+#define KW_MATTYPE_PHONG 341
+#define KW_MATTYPE_BLINN 342
+#define KW_NAME 343
+#define KW_AMBIENT 344
+#define KW_DIFFUSE 345
+#define KW_SPECULAR 346
+#define KW_MIRROR 347
+#define KW_TRANSPARENCE 348
+#define KW_REFRACINDEX 349
+#define KW_TRANSADDITIVE 350
+#define KW_TRANSATTCOL 351
+#define KW_FRESNEL 352
+#define KW_LIGHT 353
+#define KW_ACTIVE 354
+#define KW_COLOUR 355
+#define KW_POSITION 356
+#define KW_LIGHT_OMNI 357
+#define KW_CAUSTICPHOTONS 358
+#define KW_CAUSTICSTRENGTH 359
+#define KW_SHADOWMAP 360
+#define KW_CAUSTICSMAP 361
 
 
 
@@ -249,7 +251,7 @@ typedef union YYSTYPE {
   char  *charValue;
 } YYSTYPE;
 /* Line 1318 of yacc.c.  */
-#line 253 "bld-std-gcc/src/cfgparser.hpp"
+#line 255 "bld-std-gcc/src/cfgparser.hpp"
 # define yystype YYSTYPE /* obsolescent; will be withdrawn */
 # define YYSTYPE_IS_DECLARED 1
 # define YYSTYPE_IS_TRIVIAL 1
index a8bd99e2082047a6ffdbc5d6827420118f0a888c..a1072d842972bfaac82031edb6712366477bd2a0 100644 (file)
@@ -6,9 +6,15 @@
  * Copyright 2003-2005 Nils Thuerey
  *
  * Main program functions
- *
  */
 
+#include "elbeem.h"
+#include "ntl_blenderdumper.h"
+extern "C" void elbeemCheckDebugEnv(void);
+
+#include "ntl_scene.h"
+#include "ntl_geometrymodel.h"
+
 /*****************************************************************************/
 // region of interest global vars
 // currently used by e.g. fsgr solver
@@ -21,27 +27,72 @@ double guiRoiEZ = 1.0;
 int guiRoiMaxLev=6, guiRoiMinLev=0;
 
 //! global raytracer pointer (=world)
-class ntlWorld;
-ntlWorld *gpWorld = (ntlWorld*)0;
+ntlWorld *gpWorld = NULL;
 
 //! debug output switch
 bool myDebugOut = false;
 
-//! global leave program variable
+//! global leave program / abort variable
 bool gQuit = false;
 
-//! start simulation?
-bool gThreadRunning = false;
-
-/* usage message */
-char* usageString = 
-       "El'Beem - Lattice Boltzmann Free Surface Simulator\n\
-  Command-line Options: \n\
-  -b : .obj file dump mode for Blender\n\
-  -c : Force command line mode for rendering \n\
-  -d : Dump mode for ECR\n\
-  -f <filename> : Specify fluid description file to use as <filename>\n\
-  -h : Display this message \n\
-       -o : single frame output to given file\n\
-  \n ";
+
+// API
+
+int elbeemInit(elbeemSimulationSettings *settings) {
+       gElbeemState = SIMWORLD_INVALID;
+       strcpy(gElbeemErrorString,"[none]");
+
+       elbeemCheckDebugEnv();
+       debMsgStd("performElbeemSimulation",DM_NOTIFY,"El'Beem Simulation Init Start as Plugin, debugLevel:"<<gDebugLevel<<" ...\n", 2);
+       
+       // create world object with initial settings
+       ntlBlenderDumper *elbeem = new ntlBlenderDumper(settings);
+       gpWorld = elbeem;
+       return 0;
+}
+
+int elbeemAddMesh(elbeemMesh *mesh) {
+       int initType = -1;
+       switch(mesh->type) {
+               case OB_FLUIDSIM_OBSTACLE: initType = FGI_BNDNO; break;
+               case OB_FLUIDSIM_FLUID: initType = FGI_FLUID; break;
+               case OB_FLUIDSIM_INFLOW: initType = FGI_MBNDINFLOW; break;
+               case OB_FLUIDSIM_OUTFLOW: initType = FGI_MBNDOUTFLOW; break;
+       }
+       // invalid type?
+       if(initType<0) return 1;
+       
+       ntlGeometryObjModel *obj = new ntlGeometryObjModel( );
+       gpWorld->getRenderGlobals()->getScene()->addGeoClass( obj );
+       obj->initModel(mesh->numVertices, mesh->vertices, mesh->numTriangles, mesh->triangles);
+       obj->setGeoInitId(true);
+       obj->setGeoInitIntersect(true);
+       obj->setGeoInitType(initType);
+       obj->setInitialVelocity( ntlVec3Gfx(mesh->iniVelx, mesh->iniVely, mesh->iniVelz) );
+       return 0;
+}
+
+int elbeemSimulate(void) {
+       if(!gpWorld) return 1;
+
+       gpWorld->finishWorldInit();
+       
+       if(SIMWORLD_OK()) {
+               gElbeemState = SIMWORLD_INITED;
+               myTime_t timestart = getTime();
+               gpWorld->renderAnimation();
+               myTime_t timeend = getTime();
+               debMsgStd("performElbeemSimulation",DM_NOTIFY, "El'Beem simulation done, time: "<<((timeend-timestart)/(double)1000.0) <<" seconds.\n", 2 ); 
+
+               // ok, we're done...
+               delete gpWorld;
+               gpWorld = NULL;
+               return 0;
+       } 
+
+       // failure...
+       return 1;
+}
+
+
 
diff --git a/intern/elbeem/intern/elbeem.h b/intern/elbeem/intern/elbeem.h
new file mode 100644 (file)
index 0000000..efbda58
--- /dev/null
@@ -0,0 +1,97 @@
+/******************************************************************************
+ *
+ * El'Beem - Free Surface Fluid Simulation with the Lattice Boltzmann Method
+ * All code distributed as part of El'Beem is covered by the version 2 of the 
+ * GNU General Public License. See the file COPYING for details.
+ * Copyright 2003-2005 Nils Thuerey
+ *
+ * API header
+ */
+#ifndef ELBEEM_API_H
+#define ELBEEM_API_H
+
+
+
+/*! fluid geometry init types */
+#define FGI_FLAGSTART   16
+#define FGI_FLUID                        (1<<(FGI_FLAGSTART+ 0))
+#define FGI_NO_FLUID     (1<<(FGI_FLAGSTART+ 1))
+#define FGI_BNDNO                        (1<<(FGI_FLAGSTART+ 2))
+#define FGI_BNDFREE              (1<<(FGI_FLAGSTART+ 3))
+#define FGI_BNDPART              (1<<(FGI_FLAGSTART+ 4))
+#define FGI_NO_BND               (1<<(FGI_FLAGSTART+ 5))
+#define FGI_MBNDINFLOW (1<<(FGI_FLAGSTART+ 6))
+#define FGI_MBNDOUTFLOW        (1<<(FGI_FLAGSTART+ 7))
+
+#define FGI_ALLBOUNDS ( FGI_BNDNO | FGI_BNDFREE | FGI_BNDPART | FGI_MBNDINFLOW | FGI_MBNDOUTFLOW )
+
+
+/*! blender types for mesh->type */
+//#define OB_FLUIDSIM_DOMAIN      2
+#define OB_FLUIDSIM_FLUID       4
+#define OB_FLUIDSIM_OBSTACLE    8
+#define OB_FLUIDSIM_INFLOW      16
+#define OB_FLUIDSIM_OUTFLOW     32
+
+
+// global settings for the simulation
+typedef struct elbeemSimulationSettings {
+  /* version number */
+  short version;
+
+       /* geometrical extent */
+       float geoStart[3], geoSize[3];
+
+  /* resolutions */
+  short resolutionxyz;
+  short previewresxyz;
+  /* size of the domain in real units (meters along largest resolution x,y,z extent) */
+  float realsize;
+
+  /* fluid properties */
+  double viscosity;
+  /* gravity strength */
+  float gravx,gravy,gravz;
+  /* anim start end time */
+  float animStart, aniFrameTime;
+  /* g star param (LBM compressibility) */
+  float gstar;
+  /* activate refinement? */
+  short maxRefine;
+
+  /* store output path, and file prefix for baked fluid surface */
+  char surfdataPath[160+80];
+} elbeemSimulationSettings;
+
+
+// a single mesh object
+typedef struct elbeemMesh {
+  /* obstacle,fluid or inflow... */
+  short type;
+
+  /* initial velocity (for fluid/inflow) */
+  float iniVelx,iniVely,iniVelz;
+
+       /* vertices */
+  int numVertices;
+       float *vertices; // = float[][3];
+
+       /* triangles */
+       int   numTriangles;
+  int   *triangles; // = int[][3];
+} elbeemMesh;
+
+// API functions
+
+// start fluidsim init
+int elbeemInit(struct elbeemSimulationSettings*);
+
+// add mesh as fluidsim object
+int elbeemAddMesh(struct elbeemMesh*);
+
+// do the actual simulation
+int elbeemSimulate(void);
+
+
+
+#endif // ELBEEM_API_H
index 60a60b45e5a0703091570a4e0927bb2c293069c4..c2a092ab1c9bc8f39c8ebf5c292ae69888fdbae6 100644 (file)
@@ -21,12 +21,6 @@ extern ntlWorld *gpWorld;
 // debug output switch
 extern bool myDebugOut;
 
-// global leave program variable
+// global leave program / abort variable
 extern bool gQuit;
 
-//! start simulation?
-extern bool gThreadRunning;
-
-//! short manual
-extern char* usageString;
-
index 38b0ecceb2ca0dd555bdfdb4b959f7c83ef3c8a6..545cdc89eff7b5ea98e2aa486413299fb31fa2c0 100644 (file)
@@ -83,10 +83,11 @@ void IsoSurface::initializeIsosurface(int setx, int sety, int setz, ntlVec3Gfx e
   mpEdgeVerticesY = new int[nodes];
   mpEdgeVerticesZ = new int[nodes];
   for(int i=0;i<nodes;i++) { mpEdgeVerticesX[i] = mpEdgeVerticesY[i] = mpEdgeVerticesZ[i] = -1; }
+       // WARNING - make sure this is consistent with calculateMemreqEstimate
   
        // marching cubes are ready 
        mInitDone = true;
-       unsigned long int memCnt = (3*sizeof(int)*nodes + sizeof(float)*nodes);
+       /*unsigned long int memCnt = (3*sizeof(int)*nodes + sizeof(float)*nodes);
        double memd = memCnt;
        char *sizeStr = "";
        const double sfac = 1000.0;
@@ -95,7 +96,7 @@ void IsoSurface::initializeIsosurface(int setx, int sety, int setz, ntlVec3Gfx e
        if(memd>sfac){ memd /= sfac; sizeStr="GB"; }
        if(memd>sfac){ memd /= sfac; sizeStr="TB"; }
 
-       debMsgStd("IsoSurface::initializeIsosurface",DM_MSG,"Inited "<<PRINT_VEC(setx,sety,setz)<<" alloced:"<< memd<<" "<<sizeStr<<"." ,10);
+       debMsgStd("IsoSurface::initializeIsosurface",DM_MSG,"Inited "<<PRINT_VEC(setx,sety,setz)<<" alloced:"<< memd<<" "<<sizeStr<<"." ,10);*/
 }
 
 
@@ -318,6 +319,7 @@ void IsoSurface::getTriangles( vector<ntlTriangle> *triangles,
                debugOut("IsoSurface::getTriangles warning: Not initialized! ", 10);
                return;
        }
+       //return; // DEBUG
 
   /* triangulate field */
   triangulate();
index d6ac0b84ed7bc08abc2905dfda2b0de8b6f567c0..e9e67b1a72d1fc36059686772deafdb2fffee3c9 100644 (file)
@@ -32,8 +32,16 @@ ntlBlenderDumper::ntlBlenderDumper(string filename, bool commandlineMode) :
        mpTrafo = new ntlMat4Gfx(0.0);
        mpTrafo->initId();
        (*mpTrafo) = pAttrs->readMat4Gfx("transform" , (*mpTrafo), "ntlBlenderDumper","mpTrafo", false ); 
-       
-       //for(int i=0; i<4;i++) { for(int j=0; j<4;j++) { errMsg("T"," "<<i<<","<<j<<" "<<mpTrafo->value[i][j]); } } // DEBUG
+}
+ntlBlenderDumper::ntlBlenderDumper(elbeemSimulationSettings *settings) :
+       ntlWorld(settings), mpTrafo(NULL)
+{
+       // same as normal constructor here
+  ntlRenderGlobals *glob = mpGlob;
+       AttributeList *pAttrs = glob->getBlenderAttributes();
+       mpTrafo = new ntlMat4Gfx(0.0);
+       mpTrafo->initId();
+       (*mpTrafo) = pAttrs->readMat4Gfx("transform" , (*mpTrafo), "ntlBlenderDumper","mpTrafo", false ); 
 }
 
 
index 403531a10a49288934faa300f7d232668a752c97..64f9f81021dccd0c4686b2fa3ad74d55769f9e50 100644 (file)
@@ -17,6 +17,7 @@ class ntlBlenderDumper :
 public:
   /*! Constructor */
   ntlBlenderDumper(string filename, bool commandlineMode);
+  ntlBlenderDumper(elbeemSimulationSettings *);
   /*! Destructor */
   virtual ~ntlBlenderDumper( void );
 
index 8f25272e49670d98fc76c5ab463384ab8e4f6542..59b0fd50ea2cc8c003e1d0b9bda3c8ac4b402067 100644 (file)
@@ -386,15 +386,8 @@ void ntlTree::subdivide(BSPNode *node, int depth, int axis)
                /* distribute triangles */
                bool haveCloneVec[2] = {false, false};
                for( int i=0; i<2; i++) {
-                       /*if(thisTriDoubles[i] == (int)node->members->size()) {
-                               node->child[i]->members = node->members;
-                               node->child[i]->cloneVec = (node->cloneVec+1);
-                               haveCloneVec[i] = true;
-                       } else */
-                       {
-                               node->child[i]->members = new vector<ntlTriangle *>( thisTrisFor[i] );
-                               node->child[i]->cloneVec = 0;
-                       }
+                       node->child[i]->members = new vector<ntlTriangle *>( thisTrisFor[i] );
+                       node->child[i]->cloneVec = 0;
                }
 
                int tind0 = 0;
@@ -415,12 +408,9 @@ void ntlTree::subdivide(BSPNode *node, int depth, int axis)
                                                tind1++;
                                        }
                                }
-
-                               //if(depth>38) errorOut(" N d"<<depth<<" t"<<t<<" td"<<(int)mpTriDist[t]<<"  S"<<(int)allTriDistSet);
                                t++;
                        } /* end of loop over all triangles */
                }
-               //D errorOut( "    MMM"<<i<<": "<<(unsigned int)(node->child[i]->members->size())<<" "<<thisTrisFor[i]<<" tind"<<tind[i] ); // DEBG!
 
                // subdivide children
                for( int i=0; i<2; i++) {
@@ -430,12 +420,9 @@ void ntlTree::subdivide(BSPNode *node, int depth, int axis)
 
                /* if we are here, this are childs, so we dont need the members any more... */
                /* delete unecessary members */
-               if( (!haveCloneVec[0]) && (!haveCloneVec[1]) && (node->cloneVec == 0) ){ // ??? FIXME?
-               //if( (!haveCloneVec[0]) && (!haveCloneVec[1]) ){
+               if( (!haveCloneVec[0]) && (!haveCloneVec[1]) && (node->cloneVec == 0) ){ 
                        delete node->members; 
                }
-               else {
-                       errMsg("LLLLLLLL","ASD"); }
                node->members = NULL;
 
        } /* subdivision necessary */
@@ -624,10 +611,6 @@ void ntlTree::intersect(const ntlRay &ray, gfxReal &distance,
        if(mint == GFX_REAL_MAX) {
                distance = -1.0;
        } else {
-               if((ray.getRenderglobals())&&(ray.getRenderglobals()->getDebugOut() > 5)) {  // DEBUG!!!
-                       errorOut("Intersection outside BV ");
-               }
-
                // intersection outside the BSP bounding volumes might occur due to roundoff...
                //retnormal = (*mpVertNormals)[ hit->getPoints()[0] ] * (1.0-mintu-mintv)+ (*mpVertNormals)[ hit->getPoints()[1] ]*mintu + (*mpVertNormals)[ hit->getPoints()[2] ]*mintv;
                if(forceNonsmooth) {
@@ -775,18 +758,6 @@ void ntlTree::intersectX(const ntlRay &ray, gfxReal &distance,
                                                mint = t;         
                                                hit = (*iter);
                                                mintu = u; mintv = v;
-                                               
-                                               if((ray.getRenderglobals())&&(ray.getRenderglobals()->getDebugOut() > 5)) {  // DEBUG!!!
-                                                       errorOut("Tree tri hit at "<<t<<","<<mint<<" triangle: "<<PRINT_TRIANGLE( (*hit), (*mpVertices) ) );
-                                                       gfxReal u1=0.0,v1=0.0, t1=-1.0;
-                                                       ray.intersectTriangleX( mpVertices, hit, t1,u1,v1);
-                                                       errorOut("Tree second test1 :"<<t1<<" u1:"<<u1<<" v1:"<<v1 );
-                                                       if(t==GFX_REAL_MAX) errorOut( "Tree MAX t " );
-                                                       //errorOut( mpVertices[ (*iter).getPoints()[0] ][0] );
-                                               }
-
-                                               //retnormal = -(e2-e0).crossProd(e1-e0); // DEBUG
-
                                        }
                                }
 
@@ -832,12 +803,8 @@ void ntlTree::intersectX(const ntlRay &ray, gfxReal &distance,
        if(mint == GFX_REAL_MAX) {
                distance = -1.0;
        } else {
-               if((ray.getRenderglobals())&&(ray.getRenderglobals()->getDebugOut() > 5)) {  // DEBUG!!!
-                       errorOut("Intersection outside BV ");
-               }
 
                // intersection outside the BSP bounding volumes might occur due to roundoff...
-               //retnormal = (*mpVertNormals)[ hit->getPoints()[0] ] * (1.0-mintu-mintv)+ (*mpVertNormals)[ hit->getPoints()[1] ]*mintu + (*mpVertNormals)[ hit->getPoints()[2] ]*mintv;
                if(forceNonsmooth) {
                        // calculate triangle normal
                        ntlVec3Gfx e0,e1,e2;
index 51b2b5e7f9ac7860e54f6bbf3c8ad9eb81d25606..2ab80f5be79c5ba7da70e2f10b9f4e04cf0c7422 100644 (file)
@@ -186,11 +186,37 @@ int ntlGeometryObjModel::loadBobjModel(string filename)
        gzclose( gzf );
        return 0;
 gzreaderror:
+       mTriangles.clear();
+       mVertices.clear();
+       mNormals.clear();
        gzclose( gzf );
        errFatal("ntlGeometryObjModel::loadBobjModel","Reading GZ_BOBJ, Unable to load '"<< filename <<"', exiting...\n", SIMWORLD_INITERROR );
        return 1;
 }
 
 
+/******************************************************************************
+ * init model from given vertex and triangle arrays 
+ *****************************************************************************/
+
+int ntlGeometryObjModel::initModel(int numVertices, float *vertices, int numTriangles, int *triangles)
+{
+       mVertices.clear();
+       mVertices.resize( numVertices );
+       for(int i=0; i<numVertices; i++) {
+               //mVertices[i] = ntlVec3Gfx(vertices[i][0],vertices[i][1],vertices[i][2]);
+               mVertices[i] = ntlVec3Gfx(vertices[i*3+0],vertices[i*3+1],vertices[i*3+2]);
+       }
+
+       mTriangles.clear();
+       mTriangles.resize( 3*numTriangles );
+       for(int i=0; i<numTriangles; i++) {
+               mTriangles[3*i+0] = triangles[i*3+0];
+               mTriangles[3*i+1] = triangles[i*3+1];
+               mTriangles[3*i+2] = triangles[i*3+2];
+       }
+
+       return 0;
+}
 
 
index c98e7d72fe6fda7147f00c7dbb6c7fa0f1e51b73..929b8c598417bd38bc8d36b67aaf7e240b779856 100644 (file)
@@ -36,6 +36,8 @@ class ntlGeometryObjModel : public ntlGeometryObject
 
                /*! load model from .bobj file, returns !=0 upon error */
                int loadBobjModel(string filename);
+               /*! init model from given vertex and triangle arrays */
+               int initModel(int numVertices, float *vertices, int numTriangles, int *triangles);
 
        private:
 
index b05b3d5ec9a9e31506984440d924a480dcf72b4a..a9340fd2dec7dbf1adaee9742ddb69a1b8549134 100644 (file)
@@ -13,7 +13,7 @@
 #include "ntl_renderglobals.h"
 
 // for FGI
-#include "ntl_scene.h"
+#include "elbeem.h"
 
 
 
index ca34b53b07ba5cac142d8bf9c4fbc89c996fbbe5..71a5566d8eb81965ae14547bb2b6c32b0dd3953a 100644 (file)
@@ -59,6 +59,10 @@ class ntlGeometryObject : public ntlGeometryClass
                /*! Returns the cast shadows attribute */
                inline int getCastShadows() const { return mCastShadows; }
 
+               /*! Returns the geo init id */
+               inline void setGeoInitId(int set) { mGeoInitId=set; }
+               /*! Returns the geo init typ */
+               inline void setGeoInitType(int set) { mGeoInitType=set; }
                /*! Returns the geo init id */
                inline int getGeoInitId() const { return mGeoInitId; }
                /*! Returns the geo init typ */
index 4a1362257900538ca7e35bc22ccba3a1957e84b6..41bfd167bb25cbf18263817c8094cdb38819565c 100644 (file)
@@ -168,7 +168,7 @@ ntlMaterial::ntlMaterial( string name,
 #define GET_GLOBAL_DEFAULT_MATERIAL new ntlMaterial( "default",\
                                         ntlColor( 0.5 ), ntlColor(0.0), \
                                         1.0, 5.0, 0.0,   \
-                                                                                                                                                               0.0, 1.0, 0.0, \
+                                                                                                                                                               /*0.0 test:*/ 0.5 , 1.0, 0.0, \
                                                                                                                                                                ntlColor( 0.0 ), 0 ); 
                                                                                                                                                                                                                                                        
 
index 94f40058196aaeb676b5fb0f2fa7f4883fe28c5b..f01aedc84afeb3e59e69ec75441f4b2dfc59afa7 100644 (file)
 class ntlRay;
 class ntlGeometryObject;
 
-/*! fluid geometry init types */
-#define FGI_FLAGSTART   16
-#define FGI_FLUID                        (1<<(FGI_FLAGSTART+ 0))
-#define FGI_NO_FLUID     (1<<(FGI_FLAGSTART+ 1))
-#define FGI_BNDNO                        (1<<(FGI_FLAGSTART+ 2))
-#define FGI_BNDFREE              (1<<(FGI_FLAGSTART+ 3))
-#define FGI_BNDPART              (1<<(FGI_FLAGSTART+ 4))
-#define FGI_NO_BND               (1<<(FGI_FLAGSTART+ 5))
-#define FGI_MBNDINFLOW (1<<(FGI_FLAGSTART+ 6))
-#define FGI_MBNDOUTFLOW        (1<<(FGI_FLAGSTART+ 7))
-
-#define FGI_ALLBOUNDS ( FGI_BNDNO | FGI_BNDFREE | FGI_BNDPART | FGI_MBNDINFLOW | FGI_MBNDOUTFLOW )
-
 
 //! convenience macro for adding triangles
 #define sceneAddTriangle(p1,p2,p3, pn1,pn2,pn3, trin, smooth)   {\
index ed0beee32a31a9b512c32ebe86f7fc77375c571b..de4d5f8722a4a977ac01c1572b5c00aa96d7446a 100644 (file)
@@ -65,8 +65,7 @@ using std::string;
 
 #else // WIN32
 
-// linux,*bsd etc...
-#include <limits.h>
+// floating point limits for linux,*bsd etc...
 #include <float.h>
 
 #endif // WIN32
@@ -95,6 +94,20 @@ using std::string;
 #define M_PI 3.1415926536
 #endif
 
+// make sure elbeem plugin def is valid
+#if ELBEEM_BLENDER==1
+#ifndef ELBEEM_PLUGIN
+#define ELBEEM_PLUGIN 1
+#endif // !ELBEEM_PLUGIN
+#endif // ELBEEM_BLENDER==1
+
+// make sure GUI support is disabled for plugin use
+#if ELBEEM_PLUGIN==1
+#ifndef NOGUI
+#define NOGUI 1
+#endif // !NOGUI
+#endif // ELBEEM_PLUGIN==1
+
 
 // basic inlined vector class
 template<class Scalar>
@@ -812,7 +825,7 @@ typedef float gfxReal;
 //#define vecGfx2F(x) (x)
 //#define vecD2Gfx(x) vecD2F(x)
 //#define vecGfx2D(x) vecF2D(x)
-#define VECTOR_EPSILON (1e-5)
+#define VECTOR_EPSILON (1e-5f)
 #else
 typedef double gfxReal;
 #define GFX_REAL_MAX __DBL_MAX__
@@ -832,8 +845,8 @@ typedef ntlVector3Dim<gfxReal>  ntlVec3Gfx;
 template<class T> inline ntlVec3Gfx vec2G(T v) { return ntlVec3Gfx(v[0],v[1],v[2]); }
 
 /* get minimal vector length value that can be discriminated.  */
-//template<class Scalar> inline Scalar getVecEpsilon()
-inline double getVecEpsilon() { return (double)VECTOR_EPSILON; }
+//inline double getVecEpsilon() { return (double)VECTOR_EPSILON; }
+inline gfxReal getVecEpsilon() { return (gfxReal)VECTOR_EPSILON; }
 
 #define HAVE_GFXTYPES
 
index b2677fe701141e6960bc219eaa54be6c7f9a2239..c207fd94b9090ee7af97242cbc78f52beeba108e 100644 (file)
@@ -34,15 +34,18 @@ void setPointers( ntlRenderGlobals *setglob);
 /******************************************************************************
  * Constructor
  *****************************************************************************/
-ntlWorld::ntlWorld(string filename, bool commandlineMode) :
+ntlWorld::ntlWorld(string filename, bool commandlineMode) 
+       /*:
        mpGlob(NULL), 
   mpLightList(NULL), mpPropList(NULL), mpSims(NULL),
        mpOpenGLRenderer(NULL),
        mStopRenderVisualization( false ),
        mThreadRunning( false ), 
        mSimulationTime(0.0), mFirstSim(-1),
-       mSingleStepDebug( false )
+       mSingleStepDebug( false ),
+       mFrameCnt(0)*/
 {
+#if 0
   /* create scene storage */
   mpGlob = new ntlRenderGlobals();
   mpLightList = new vector<ntlLightObject*>;
@@ -62,10 +65,23 @@ ntlWorld::ntlWorld(string filename, bool commandlineMode) :
        scene = new ntlScene( mpGlob );
        mpGlob->setScene( scene );
 
+       // moved TODO test...
+#endif // 0
+
+       initDefaults();
+#ifndef NOGUI
+       // setup opengl display, save first animation step for start time 
+       if(!commandlineMode) {
+               mpOpenGLRenderer = new ntlOpenGLRenderer( mpGlob );
+       }
+#else // NOGUI
+       commandlineMode = true; // remove warning...
+#endif // NOGUI
        // load config
   setPointers( getRenderGlobals() );
   parseFile( filename.c_str() );
-       if(!SIMWORLD_OK()) return;
+       finishWorldInit();
+       /*if(!SIMWORLD_OK()) return;
 
        // init the scene for the first time
   long sstartTime = getTime();
@@ -103,7 +119,7 @@ ntlWorld::ntlWorld(string filename, bool commandlineMode) :
                        debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Anistart Time: "<<(*mpSims)[mFirstSim]->getStartTime() ,10);
                        while(mSimulationTime < (*mpSims)[mFirstSim]->getStartTime() ) {
                        debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Anistart Time: "<<(*mpSims)[mFirstSim]->getStartTime()<<" simtime:"<<mSimulationTime ,10);
-                               advanceSims();
+                               advanceSims(-1);
                        }
                        long stopTime = getTime();
 
@@ -116,15 +132,128 @@ ntlWorld::ntlWorld(string filename, bool commandlineMode) :
                        if(!mpGlob->getSingleFrameMode()) debMsgStd("ntlWorld::ntlWorld",DM_WARNING,"No active simulations!", 1);
                }
        }
+*/
+}
+
+ntlWorld::ntlWorld(elbeemSimulationSettings *settings)
+{
+       initDefaults();
+       // todo init settings
+       SimulationObject *sim = new SimulationObject();
+       mpGlob->getSims()->push_back( sim );
+       mpGlob->getScene()->addGeoClass( sim );
+       sim->setGeoStart(ntlVec3Gfx(settings->geoStart[0],settings->geoStart[1],settings->geoStart[2]));
+       sim->setGeoEnd(ntlVec3Gfx(
+                       settings->geoStart[0]+settings->geoSize[0],
+                       settings->geoStart[1]+settings->geoSize[1],
+                       settings->geoStart[2]+settings->geoSize[2] ));
+       sim->getSolver()->setSmoothing(1.0, 0.0);
+       sim->getSolver()->setPreviewSize(settings->previewresxyz);
+       sim->getSolver()->setRefinementDesired(settings->maxRefine);
+
+       Parametrizer *param = sim->getParametrizer();
+       param->setSize( settings->resolutionxyz );
+       param->setDomainSize( settings->realsize );
+       param->setViscosity( settings->viscosity );
+       param->setGravity( ParamVec(settings->gravx, settings->gravy, settings->gravx) );
+       param->setAniStart( settings->animStart );
+       param->setAniFrameTime( settings->aniFrameTime );
+       param->setNormalizedGStar( settings->gstar );
+
+       // dont setup lights, camera, materials...?
+  /*
+       ntlMaterial *fluidmat = new ntlMaterial( );
+       currentMaterial->setAmbientRefl( ntlColor(0.3, 0.5, 0.9) ); 
+       currentMaterial->setDiffuseRefl( ntlColor(0.3, 0.5, 0.9) ); 
+       currentMaterial->setSpecular( 0.2 ); 
+       currentMaterial->setSpecExponent( 10.0 ); 
+       mpGlob->getMaterials()->push_back( fluidmat );
+       // */
+}
+
+void ntlWorld::initDefaults()
+{
+       mStopRenderVisualization = false;
+       mThreadRunning =  false;
+       mSimulationTime = 0.0; 
+       mFirstSim = 1;
+       mSingleStepDebug =  false;
+       mFrameCnt = 0;
+       mpOpenGLRenderer = NULL;
+
+  /* create scene storage */
+  mpGlob = new ntlRenderGlobals();
+  mpLightList = new vector<ntlLightObject*>;
+  mpPropList = new vector<ntlMaterial*>;
+  mpSims = new vector<SimulationObject*>;
+
+  mpGlob->setLightList(mpLightList);
+  mpGlob->setMaterials(mpPropList);
+  mpGlob->setSims(mpSims);
+
+       /* init default material */
+  ntlMaterial *def = GET_GLOBAL_DEFAULT_MATERIAL;
+       mpPropList->push_back( def );
+
+       /* init the scene object */
+       ntlScene *newscene = new ntlScene( mpGlob );
+       mpGlob->setScene( newscene );
+}
+
+void ntlWorld::finishWorldInit()
+{
+       if(!SIMWORLD_OK()) return;
 
+       // init the scene for the first time
+  long sstartTime = getTime();
+       mpGlob->getScene()->buildScene();
+       long sstopTime = getTime();
+       debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Scene build time: "<< getTimeString(sstopTime-sstartTime) <<" ", 10);
+
+       if(!SIMWORLD_OK()) return;
+       // TODO check simulations, run first steps
+       mFirstSim = -1;
+       if(mpSims->size() > 0) {
+
+               // use values from first simulation as master time scale
+               long startTime = getTime();
+               
+               // remember first active sim
+               for(size_t i=0;i<mpSims->size();i++) {
+                       if(!(*mpSims)[i]->getVisible()) continue;
+                       if((*mpSims)[i]->getPanic())    continue;
+
+                       // check largest timestep
+                       if(mFirstSim>=0) {
+                               if( (*mpSims)[i]->getStepTime() > (*mpSims)[mFirstSim]->getStepTime() ) {
+                                       mFirstSim = i;
+                                       debMsgStd("ntlWorld::ntlWorld",DM_MSG,"First Sim changed: "<<i ,10);
+                               }
+                       }
+                       // check any valid sim
+                       if(mFirstSim<0) {
+                               mFirstSim = i;
+                               debMsgStd("ntlWorld::ntlWorld",DM_MSG,"First Sim: "<<i ,10);
+                       }
+               }
+
+               if(mFirstSim>=0) {
+                       debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Anistart Time: "<<(*mpSims)[mFirstSim]->getStartTime() ,10);
+                       while(mSimulationTime < (*mpSims)[mFirstSim]->getStartTime() ) {
+                       debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Anistart Time: "<<(*mpSims)[mFirstSim]->getStartTime()<<" simtime:"<<mSimulationTime ,10);
+                               advanceSims(-1);
+                       }
+                       long stopTime = getTime();
+
+                       mSimulationTime += (*mpSims)[mFirstSim]->getStartTime();
+                       debMsgStd("ntlWorld::ntlWorld",DM_MSG,"Time for start simulations times "<<": "<< getTimeString(stopTime-startTime) <<"s ", 1);
 #ifndef NOGUI
-       // setup opengl display, save first animation step for start time 
-       if(!commandlineMode) {
-               mpOpenGLRenderer = new ntlOpenGLRenderer( mpGlob, scene );
+                       guiResetSimulationTimeRange( mSimulationTime );
+#endif
+               } else {
+                       if(!mpGlob->getSingleFrameMode()) debMsgStd("ntlWorld::ntlWorld",DM_WARNING,"No active simulations!", 1);
+               }
        }
-#else // NOGUI
-       commandlineMode = true; // remove warning...
-#endif // NOGUI
 }
 
 
@@ -154,11 +283,14 @@ void ntlWorld::setSingleFrameOut(string singleframeFilename) {
 /******************************************************************************
  * render a whole animation (command line mode) 
  *****************************************************************************/
+
+// blender interface
 #if ELBEEM_BLENDER==1
 extern "C" {
        void simulateThreadIncreaseFrame(void);
 }
 #endif // ELBEEM_BLENDER==1
+
 int ntlWorld::renderAnimation( void )
 {
        // only single pic currently
@@ -175,23 +307,21 @@ int ntlWorld::renderAnimation( void )
 
        mThreadRunning = true; // not threaded, but still use the same flags
        renderScene();
-       for(int i=0; ((i<mpGlob->getAniFrames()) && (!getStopRenderVisualization() )); i++) {
-               if(!advanceSims()) {
-                       renderScene();
-               } // else means sim panicked, so dont render...
+       if(mpSims->size() <= 0) {
+               debMsgStd("ntlWorld::renderAnimation",DM_NOTIFY,"No simulations found, stopping...",1);
+               return 1;
+       }
 
+       for(mFrameCnt=0; ((mFrameCnt<mpGlob->getAniFrames()) && (!getStopRenderVisualization() )); mFrameCnt++) {
+               if(!advanceSims(mFrameCnt)) {
+                       renderScene();
 #if ELBEEM_BLENDER==1
-               // update gui display
-               simulateThreadIncreaseFrame();
+                       // update Blender gui display after each frame
+                       simulateThreadIncreaseFrame();
 #endif // ELBEEM_BLENDER==1
-
-               if(mpSims->size() <= 0) {
-                       debMsgStd("ntlWorld::renderAnimation",DM_NOTIFY,"No simulations found, stopping...",1);
-                       return 1;
-               }
+               } // else means sim panicked, so dont render...
        }
        mThreadRunning = false;
-       
        return 0;
 }
 
@@ -216,7 +346,8 @@ int ntlWorld::renderVisualization( bool multiThreaded )
                // determine stepsize
                if(!mSingleStepDebug) {
                        long startTime = getTime();
-                       advanceSims();
+                       advanceSims(mFrameCnt);
+                       mFrameCnt++;
                        long stopTime = getTime();
                        debMsgStd("ntlWorld::renderVisualization",DM_MSG,"Time for "<<mSimulationTime<<": "<< getTimeString(stopTime-startTime) <<"s ", 10);
                } else {
@@ -281,13 +412,31 @@ int ntlWorld::singleStepVisualization( void )
 /******************************************************************************
  * advance simulations by time t 
  *****************************************************************************/
-int ntlWorld::advanceSims()
+int ntlWorld::advanceSims(int framenum)
 {
        bool done = false;
        bool allPanic = true;
-       double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getFrameTime();
        //debMsgStd("ntlWorld::advanceSims",DM_MSG,"Advancing sims to "<<targetTime, 10 ); // timedebug
 
+       for(size_t i=0;i<mpSims->size();i++) { (*mpSims)[i]->setFrameNum(framenum); }
+       double targetTime = mSimulationTime + (*mpSims)[mFirstSim]->getFrameTime();
+//FIXME check blender abort here...
+//FIXME check no ipo export
+
+       // time stopped? nothing else to do...
+       if( (*mpSims)[mFirstSim]->getFrameTime() <= 0.0 ){ 
+               done=true; allPanic=false; 
+       }
+
+#if ELBEEM_BLENDER==1
+       // same as solver_main check, but no mutex check here
+       if(getGlobalBakeState()<0) {
+               // this means abort... cause panic
+               allPanic = true; done = true;
+       }
+#endif // ELBEEM_BLENDER==1
+
+       // step all the sims, and check for panic
        while(!done) {
                double nextTargetTime = (*mpSims)[mFirstSim]->getCurrentTime() + (*mpSims)[mFirstSim]->getStepTime();
                singleStepSims(nextTargetTime);
@@ -309,6 +458,8 @@ int ntlWorld::advanceSims()
                setStopRenderVisualization( true );
                return 1;
        }
+
+       // finish step
        for(size_t i=0;i<mpSims->size();i++) {
                SimulationObject *sim = (*mpSims)[i];
                if(!sim->getVisible()) continue;
index 0da7171bad6278d57ddcda5ff531e4fb4a10c1cd..97c27b0645671483400b676d30829964212976e8 100644 (file)
@@ -16,6 +16,7 @@
 #include "ntl_renderglobals.h"
 #include "ntl_material.h"
 #include "simulation_object.h"
+#include "elbeem.h"
 class ntlOpenGLRenderer;
 
 class ntlWorld
@@ -23,8 +24,14 @@ class ntlWorld
        public:
                /*! Constructor */
                ntlWorld(string filename, bool commandlineMode);
+               /*! Constructor for API init */
+               ntlWorld(elbeemSimulationSettings *simSettings);
                /*! Destructor */
                virtual ~ntlWorld( void );
+               /*! default init for all contructors */
+               void initDefaults();
+               /*! common world contruction stuff once the scene is set up */
+               void finishWorldInit();
 
                /*! render a whole animation (command line mode) */
                int renderAnimation( void );
@@ -33,7 +40,7 @@ class ntlWorld
                /*! render a single step for viz mode */
                int singleStepVisualization( void );
                /*! advance simulations by time frame time */
-               int advanceSims();
+               int advanceSims(int framenum);
                /*! advance simulations by a single step */
                void singleStepSims(double targetTime);
 
@@ -45,8 +52,6 @@ class ntlWorld
                /*! render scene (a single pictures) */
                virtual int renderScene( void );
 
-               /*! display world with opengl */
-               //int draw( void );
                /*! set single frame rendering to filename */
                void setSingleFrameOut( string singleframeFilename );
 
@@ -100,6 +105,9 @@ class ntlWorld
 
                /*! single step mode for debugging */
                bool mSingleStepDebug;
+
+               /*! count no. of frame for viz render */
+               int mFrameCnt;
 };
 
 #endif
index c2126314c0a128ac317dc3efb1c0b4d23659fbbd..581b04216bb74d16fb30d64b97e7430f57df2385 100644 (file)
@@ -42,20 +42,24 @@ char *ParamStrings[] = {
  * Default constructor
  *****************************************************************************/
 Parametrizer::Parametrizer( void ) :
-       mSetupType("caro"),
   mRelaxTime( 1.0 ), mReynolds( 0.0 ),
-       mViscosity( 8.94e-7 ), mSoundSpeed( 1500 ),
+       mViscosity( 8.94e-7 ), mcViscosity( 8.94e-7 ), 
+       mSoundSpeed( 1500 ),
        mDomainSize( 0.1 ), mCellSize( 0.01 ),
-       mGravity(0.0, 0.0, 0.0), mLatticeGravity(0.0, 0.0, 0.0),
-       mStepTime(0.01), mDesiredStepTime(-1.0),
+       mGravity(0.0, 0.0, 0.0), mcGravity( ParamVec(0.0) ),
+       mLatticeGravity(0.0, 0.0, 0.0),
+       mStepTime(0.0001), mDesiredStepTime(-1.0),
+       mMaxStepTime(-1.0),
+       mMinStepTime(-1.0), 
        mSizex(50), mSizey(50), mSizez(50),
        mTimeFactor( 1.0 ),
        //mAniFrames(0), 
-       mAniFrameTime(0.0), mAniStart(0.0),
+       mAniFrameTime(0.0001), mcAniFrameTime(0.0001),
+       mAniStart(0.0),
        mExtent(1.0, 1.0, 1.0), mSurfaceTension( 0.0 ),
        mDensity(1000.0), mGStar(0.0001), mFluidVolumeHeight(0.0),
-       mMaxSpeed(0.0), mSimulationMaxSpeed(0.0),
-       mTadapMaxOmega(1.95), mTadapMaxSpeed(0.1), mTadapLevels(1),
+       mSimulationMaxSpeed(0.0),
+       mTadapMaxOmega(2.0), mTadapMaxSpeed(0.1)/*FIXME test 0.16666 */, mTadapLevels(1),
        mSeenValues( 0 ), mCalculatedValues( 0 )
        //mActive( false )
 {
@@ -80,8 +84,11 @@ void Parametrizer::parseAttrList()
                return;
        }
 
-       //mActive = mpAttrs->readBool("p_active",mActive, "Parametrizer","mActive", false);
+       // unused
+       string  mSetupType = "";
        mSetupType = mpAttrs->readString("p_setup",mSetupType, "Parametrizer","mSetupType", false); 
+
+       // real params
        mRelaxTime = mpAttrs->readFloat("p_relaxtime",mRelaxTime, "Parametrizer","mRelaxTime", false); 
        if(getAttributeList()->exists("p_relaxtime")) seenThis( PARAM_RELAXTIME );
 
@@ -89,6 +96,7 @@ void Parametrizer::parseAttrList()
        if(getAttributeList()->exists("p_reynolds")) seenThis( PARAM_REYNOLDS );
 
        mViscosity = mpAttrs->readFloat("p_viscosity",mViscosity, "Parametrizer","mViscosity", false); 
+       mcViscosity = mpAttrs->readChannelFloat("p_viscosity");
        if(getAttributeList()->exists("p_viscosity")) seenThis( PARAM_VISCOSITY );
 
        mSoundSpeed = mpAttrs->readFloat("p_soundspeed",mSoundSpeed, "Parametrizer","mSoundSpeed", false); 
@@ -102,6 +110,7 @@ void Parametrizer::parseAttrList()
        }
 
        mGravity = mpAttrs->readVec3d("p_gravity",mGravity, "Parametrizer","mGravity", false); 
+       mcGravity = mpAttrs->readChannelVec3d("p_gravity");
        if(getAttributeList()->exists("p_gravity")) seenThis( PARAM_GRAVITY );
 
        mStepTime = mpAttrs->readFloat("p_steptime",mStepTime, "Parametrizer","mStepTime", false); 
@@ -111,8 +120,9 @@ void Parametrizer::parseAttrList()
        if(getAttributeList()->exists("p_timefactor")) seenThis( PARAM_TIMEFACTOR );
 
        mAniFrameTime = mpAttrs->readFloat("p_aniframetime",mAniFrameTime, "Parametrizer","mAniFrameTime", false); 
-       if(getAttributeList()->exists("p_aniframetime")) seenThis( PARAM_ANIFRAMETIME );
-       if(mAniFrameTime<=0.0) {
+       mcAniFrameTime = mpAttrs->readChannelFloat("p_aniframetime");
+       if(getAttributeList()->exists("p_aniframetime")) { seenThis( PARAM_ANIFRAMETIME ); }
+       if(mAniFrameTime<0.0) {
                errMsg("Parametrizer::parseAttrList","Invalid frame time:"<<mAniFrameTime<<", resetting to 0.0001");
                mAniFrameTime = 0.0001;
        }
@@ -139,13 +149,25 @@ void Parametrizer::parseAttrList()
        mNormalizedGStar = mpAttrs->readFloat("p_normgstar",mNormalizedGStar, "Parametrizer","mNormalizedGStar", false); 
        if(getAttributeList()->exists("p_normgstar")) seenThis( PARAM_NORMALIZEDGSTAR );
 
-       mMaxSpeed = mpAttrs->readFloat("p_maxspeed",mMaxSpeed, "Parametrizer","mMaxSpeed", false); 
-       if(getAttributeList()->exists("p_maxspeed")) seenThis( PARAM_MAXSPEED );
-
        mTadapMaxOmega = mpAttrs->readFloat("p_tadapmaxomega",mTadapMaxOmega, "Parametrizer","mTadapMaxOmega", false); 
        mTadapMaxSpeed = mpAttrs->readFloat("p_tadapmaxspeed",mTadapMaxSpeed, "Parametrizer","mTadapMaxSpeed", false); 
 }
 
+/******************************************************************************
+ *! advance to next render/output frame 
+ *****************************************************************************/
+void Parametrizer::setFrameNum(int num) {
+       double frametime = (double)num;
+       double oldval = mAniFrameTime;
+       mAniFrameTime = mcAniFrameTime.get(frametime);
+       if(mAniFrameTime<0.0) {
+               errMsg("Parametrizer::setFrameNum","Invalid frame time:"<<mAniFrameTime<<" at frame "<<num<<", resetting to "<<oldval);
+               mAniFrameTime = oldval;
+       }
+       //errMsg("ChannelAnimDebug","anim: anif"<<mAniFrameTime<<" at "<<num<<" ");
+       getAttributeList()->find("p_aniframetime")->print();
+}
+
 /******************************************************************************
  * scale a given speed vector in m/s to lattice values 
  *****************************************************************************/
@@ -175,8 +197,13 @@ ParamFloat Parametrizer::calculateCellSize(void)
 /*****************************************************************************/
 
 /*! get omega for LBM */
-ParamFloat Parametrizer::calculateOmega( void ) { 
-       //return (mTimeFactor/mRelaxTime); 
+//ParamFloat Parametrizer::calculateOmega( void ) { return (1.0/mRelaxTime); }
+/*! get omega for LBM from channel */
+ParamFloat Parametrizer::calculateOmega( ParamFloat t ) { 
+       mViscosity = mcViscosity.get(t);
+       ParamFloat viscStar = calculateLatticeViscosity();
+       mRelaxTime = (6.0 * viscStar + 1) * 0.5;
+       //errMsg("ChannelAnimDebug","anim: omega"<<(1.0/mRelaxTime)<<" v"<<mViscosity<<" at "<<t<<" ");
        return (1.0/mRelaxTime); 
 }
 
@@ -187,7 +214,12 @@ int Parametrizer::calculateNoOfSteps( ParamFloat timelen ) {
 }
 
 /*! get external force x component */
-ParamVec Parametrizer::calculateGravity( void ) { 
+//ParamVec Parametrizer::calculateGravity( void ) { return mLatticeGravity; }
+ParamVec Parametrizer::calculateGravity( ParamFloat t ) { 
+       mGravity = mcGravity.get(t);
+       ParamFloat forceFactor = (mStepTime *mStepTime)/mCellSize;
+       mLatticeGravity = mGravity * forceFactor;
+       //errMsg("ChannelAnimDebug","anim: grav"<<mLatticeGravity<<" g"<<mGravity<<" at "<<t<<" ");
        return mLatticeGravity; 
 }
 
@@ -310,16 +342,19 @@ bool Parametrizer::calculateAllMissingValues( bool silent )
 
                        
        /* Carolin init , see DA for details */
-       //ParamFloat viscMax = 0.7600;    // max lattice viscosity
-       //ParamFloat viscMin = 0.0033;  // min lattice viscosity
        ParamFloat maxDeltaT = 0.0;
-       ParamFloat maxSpeed = 0.1; // for reynolds approx
+       ParamFloat maxSpeed  = 1.0/6.0; // for rough reynolds approx
 
        /* normalized gstar init */
        reqValues = PARAM_NORMALIZEDGSTAR;
        valuesChecked |= reqValues;
        if(checkSeenValues( reqValues ) ){
                //if(checkSeenValues( PARAM_GSTAR ) ){ if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_WARNING," g star value override by normalizedGStar!",1); }
+               const ParamFloat normgstarReset = 0.005;
+               if(mNormalizedGStar<=1e-6) {
+                       errMsg("Parametrizer::calculateAllMissingValues","Invalid NormGstar: "<<mNormalizedGStar<<"... resetting to "<<normgstarReset);
+                       mNormalizedGStar = normgstarReset;
+               }
                mGStar = mNormalizedGStar/maxsize;
                if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," g star set to "<<mGStar<<" from normalizedGStar="<<mNormalizedGStar ,1);
                seenThis(PARAM_GSTAR);
@@ -330,7 +365,7 @@ bool Parametrizer::calculateAllMissingValues( bool silent )
        valuesChecked |= reqValues;
        if(checkSeenValues( reqValues ) ){
                const ParamFloat gstarReset = 0.0005;
-               if(getCurrentGStar()<=0.0) {
+               if(getCurrentGStar()<=1e-6) {
                        errMsg("Parametrizer::calculateAllMissingValues","Invalid Gstar: "<<getCurrentGStar()<<" (set to "<<mGStar<<") ... resetting to "<<gstarReset);
                        mGStar = gstarReset;
                }
@@ -341,34 +376,17 @@ bool Parametrizer::calculateAllMissingValues( bool silent )
                }
                if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," g star = "<<gStar, 10);
 
-               if(mSetupType=="caro") {
-                       if(!checkSeenValues(PARAM_GRAVITY)) {
-                               errMsg("Parametrizer::calculateAllMissingValues","Setup type '"<<mSetupType<<"' requires gravity force!");
-                               goto failure;
-                       }
-                       ParamFloat forceStrength = norm(mGravity);
-                       if(forceStrength<=0) {
-                               errMsg("Parametrizer::calculateAllMissingValues"," Init failed - forceStrength = "<<forceStrength);
-                               goto failure;
-                       }
+               //if(!checkSeenValues(PARAM_GRAVITY)) { errMsg("Parametrizer::calculateAllMissingValues","Setup requires gravity force!"); goto failure; }
+               ParamFloat forceStrength = 0.0;
+               if(checkSeenValues(PARAM_GRAVITY)) { forceStrength = norm(mGravity); }
+               //if(forceStrength<=0) { errMsg("Parametrizer::calculateAllMissingValues"," Init failed - forceStrength = "<<forceStrength); goto failure; }
 
-                       // determine max. delta density per timestep trough gravity force
+               // determine max. delta density per timestep trough gravity force
+               if(forceStrength>0.0) {
                        maxDeltaT = sqrt( gStar*mCellSize/forceStrength );
-               } else if(mSetupType=="maxspeed") {
-                       // determine max. delta t from maximum speed (explicity set)
-                       if((!checkSeenValues(PARAM_MAXSPEED))||(mMaxSpeed<=0.0)) {
-                               errMsg("Parametrizer::calculateAllMissingValues","Setup type '"<<mSetupType<<"' requires maximum speed ("<<mMaxSpeed<<") !");
-                               goto failure;
-                       }
-                       ParamFloat maxLatticeSpeed = 0.0333333; //?
-                       maxDeltaT = ( maxLatticeSpeed * mCellSize) / mMaxSpeed;
-                       maxSpeed = mMaxSpeed;
-               } else if(mSetupType=="falling") {
-                       // determine max. delta t from maximum speed that can be caused by falling through the domain
-                       errMsg("Parametrizer::calculateAllMissingValues"," NYI setup falling");
                } else {
-                       errMsg("Parametrizer::calculateAllMissingValues","Setup type '"<<mSetupType<<"' unknown!");
-                       goto failure;
+                       // use 1 lbm setp = 1 anim step as max
+                       maxDeltaT = mAniFrameTime;
                }
 
                if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," targeted step time = "<<maxDeltaT, 10);
@@ -376,21 +394,19 @@ bool Parametrizer::calculateAllMissingValues( bool silent )
                ParamFloat viscStarFac = mViscosity/(mCellSize*mCellSize);
                if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," viscStarFac = "<<viscStarFac, 10);
 
-               // FIXME remove for LES?
-               //if( (viscStarFac*maxDeltaT>=viscMin) && (viscStarFac*maxDeltaT<=viscMax) ) {
-                       //if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," delta t: "<<viscMin<<" <? "<<maxDeltaT*viscStarFac<<" <? "<<viscMax, 1);
-               //} else {
-                       //if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_WARNING," delta t not in valid range: "<<viscMin<<" <? "<<maxDeltaT*viscStarFac<<" <? "<<viscMax, 1);
-               //}
-
                // time step adaptivty, only for caro with max sim speed
                ParamFloat setDeltaT = maxDeltaT;
                if(mDesiredStepTime>0.0) {
+                       // explicitly set step time according to max velocity in sim
                        setDeltaT = mDesiredStepTime;
                        mDesiredStepTime = -1.0;
                        if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," desired step time = "<<setDeltaT, 10);
-               } else if((mSetupType=="caro") && (checkSeenValues( PARAM_SIMMAXSPEED )) ) {
-                       // determine minimal delta t by omega max.
+               } else {
+                       // just use max delta t as current
+               }
+               
+               // and once for init determine minimal delta t by omega max. 
+               if((mMinStepTime<0.0) || (mMaxStepTime<0.0)) {
                        ParamFloat minDeltaT; 
                        ParamFloat maxOmega = mTadapMaxOmega;
                        ParamFloat minRelaxTime = 1.0/maxOmega;
@@ -410,14 +426,10 @@ bool Parametrizer::calculateAllMissingValues( bool silent )
                        if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," min delta t = "<<minDeltaT<<" , range = " << (maxDeltaT/minDeltaT) ,1);
 
                        // sim speed + accel shouldnt exceed 0.1?
-                       //if(mSimulationMaxSpeed + norm(mGravity*)) { ParamFloat nextmax = 0.1-mSimulationMaxSpeed }
                        mMaxStepTime = maxDeltaT;
                        mMinStepTime = minDeltaT;
-                       // only use once...
-               } else {
-                       debMsgStd("Parametrizer::calculateAllMissingValues",DM_WARNING,"Warning - setup type set to '"<<mSetupType<<"' ",1);
-                       mMaxStepTime = mMinStepTime = setDeltaT;
-               }
+                       // only use once...  
+               } 
 
                setStepTime( setDeltaT ); // set mStepTime to new value
 
@@ -425,12 +437,11 @@ bool Parametrizer::calculateAllMissingValues( bool silent )
                ParamFloat viscStar = calculateLatticeViscosity();
                mRelaxTime = (6.0 * viscStar + 1) * 0.5;
                init = true;    
-
        }
 
        // finish init
        if(init) {
-               if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," omega = "<<calculateOmega()<<", relax time = "<<mRelaxTime<<", delt="<<mStepTime,1);
+               if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," omega = "<<calculateOmega(0.0)<<", relax time = "<<mRelaxTime<<", delt="<<mStepTime,1);
                //debMsgStd("Parametrizer::calculateAllMissingValues: lbm steps = "<<calculateNoOfSteps()<<" ",1);
 
                if(checkSeenValues(PARAM_GRAVITY)) {
@@ -465,16 +476,19 @@ bool Parametrizer::calculateAllMissingValues( bool silent )
                }
 
                // calculate reynolds number
-               ParamFloat reynoldsApprox = -1.0;
-               ParamFloat gridSpeed = (maxSpeed*mCellSize/mStepTime);
-               reynoldsApprox = (mDomainSize*gridSpeed) / mViscosity;
-               if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," reynolds number (D="<<mDomainSize<<", assuming V="<<gridSpeed<<")= "<<reynoldsApprox<<" ", 1);
-
+               if(mViscosity>0.0) {
+                       ParamFloat reynoldsApprox = -1.0;
+                       ParamFloat gridSpeed = (maxSpeed*mCellSize/mStepTime);
+                       reynoldsApprox = (mDomainSize*gridSpeed) / mViscosity;
+                       if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues",DM_MSG," reynolds number (D="<<mDomainSize<<", assuming V="<<gridSpeed<<")= "<<reynoldsApprox<<" ", 1);
+               }
+                       
+               if(!SIMWORLD_OK()) return false;
                // everything ok
                return true;
        }
 
-failure:
+       // init failed ... failure:
        errMsg("Parametrizer::calculateAllMissingValues "," invalid configuration!");
        if(!silent) debMsgStd("Parametrizer::calculateAllMissingValues ",DM_WARNING, " values seen:", 1);
        for(int i=0;i<PARAM_NUMIDS;i++) {
index 71b7514cda580ee6e2647b954911068401d78342..9140deefc0be301c73e74a778a9482a676ff417f 100644 (file)
@@ -34,7 +34,6 @@ typedef ntlVec3d ParamVec;
 #define PARAM_DENSITY                                  (1<<14)
 #define PARAM_CELLSIZE                         (1<<15)
 #define PARAM_GSTAR                                            (1<<16)
-#define PARAM_MAXSPEED                         (1<<17)
 #define PARAM_SIMMAXSPEED                      (1<<18)
 #define PARAM_FLUIDVOLHEIGHT  (1<<19)
 #define PARAM_NORMALIZEDGSTAR (1<<20)
@@ -83,6 +82,8 @@ class Parametrizer {
                void setCalculatedValues(int set) { mCalculatedValues = set; }
                /*! check if the calculated flags are set in the values int */
                bool checkCalculatedValues(int check) { /*errorOut( " b"<<((mSeenValues&check)==check) );*/ return ((mCalculatedValues&check)==check); }
+               /*! advance to next render/output frame */
+               void setFrameNum(int num);
 
                /*! scale a given speed vector in m/s to lattice values 
                 *  usage string is only needed for debugging */
@@ -90,11 +91,11 @@ class Parametrizer {
 
                /* simple calulation functions */
                /*! get omega for LBM */
-               ParamFloat calculateOmega( void );
+               ParamFloat calculateOmega( ParamFloat t );
                /*! get no. of timesteps for LBM */
                int calculateNoOfSteps( ParamFloat timelen );
                /*! get external force x component */
-               ParamVec calculateGravity( void );
+               ParamVec calculateGravity( ParamFloat t );
                /*! get no of steps for the given length in seconds */
                int calculateStepsForSecs( ParamFloat s );
                /*! get start time of animation */
@@ -129,8 +130,11 @@ class Parametrizer {
                ParamFloat getReynolds( void )   { return mReynolds; }
 
                /*! set kinematic viscosity */
-               void setViscosity(ParamFloat set) { mViscosity = set; seenThis( PARAM_VISCOSITY ); }
-               /*! get kinematic viscosity */
+               void setViscosity(ParamFloat set) { 
+                       mViscosity = set; seenThis( PARAM_VISCOSITY ); 
+                       mcViscosity = AnimChannel<ParamFloat>(mViscosity);
+               }
+               /*! get current kinematic viscosity (warning - this might change over time) */
                ParamFloat getViscosity( void )   { return mViscosity; }
 
                /*! set speed of sound */
@@ -139,8 +143,14 @@ class Parametrizer {
                ParamFloat getSoundSpeed( void )   { return mSoundSpeed; }
 
                /*! set the external force */
-               void setGravity(ParamFloat setx, ParamFloat sety, ParamFloat setz) { mGravity = ParamVec(setx,sety,setz); seenThis( PARAM_GRAVITY ); }
-               void setGravity(ParamVec set) { mGravity = set; seenThis( PARAM_GRAVITY ); }
+               void setGravity(ParamFloat setx, ParamFloat sety, ParamFloat setz) { 
+                       mGravity = ParamVec(setx,sety,setz); seenThis( PARAM_GRAVITY ); 
+                       mcGravity = AnimChannel<ParamVec>(mGravity);
+               }
+               void setGravity(ParamVec set) { 
+                       mGravity = set; seenThis( PARAM_GRAVITY ); 
+                       mcGravity = AnimChannel<ParamVec>(mGravity);
+               }
 
                /*! set the length of a single time step */
                void setStepTime(ParamFloat set) { mStepTime = set; seenThis( PARAM_STEPTIME ); }
@@ -216,11 +226,6 @@ class Parametrizer {
                /*! Returns the attribute list pointer */
                inline AttributeList *getAttributeList() { return mpAttrs; }
 
-               /*! set maximum allowed speed for maxspeed setup */
-               void setMaxSpeed(ParamFloat set) { mMaxSpeed = set; seenThis( PARAM_MAXSPEED ); }
-               /*! get maximum allowed speed for maxspeed setup */
-               ParamFloat getMaxSpeed( void )   { return mMaxSpeed; }
-
                /*! set maximum allowed speed for maxspeed setup */
                void setSimulationMaxSpeed(ParamFloat set) { mSimulationMaxSpeed = set; seenThis( PARAM_SIMMAXSPEED ); }
                /*! get maximum allowed speed for maxspeed setup */
@@ -241,6 +246,8 @@ class Parametrizer {
                /*! get maximum allowed omega for time adaptivity */
                int getTadapLevels( void )   { return mTadapLevels; }
 
+               /*! get current gravity value (warning this might change over time!) */
+               ParamVec getGravity( void )   { return mGravity; }
 
                /*! set */
                //      void set(ParamFloat set) { m = set; seenThis( PARAM_ ); }
@@ -251,9 +258,6 @@ class Parametrizer {
 
        private:
 
-               /*! type of parameter setup to use */
-               string mSetupType;
-
                /*! relaxation time [s] */
                ParamFloat mRelaxTime;
 
@@ -262,6 +266,8 @@ class Parametrizer {
 
                /*! kinematic viscosity of the fluid [m^2/s] */
                ParamFloat mViscosity;
+               /*! animated channel */
+               AnimChannel<ParamFloat> mcViscosity;
 
                /*! speed of sound of the fluid [m/s] */
                ParamFloat mSoundSpeed;
@@ -277,6 +283,7 @@ class Parametrizer {
 
                /*! external force as acceleration [m/s^2] */
                ParamVec mGravity;
+               AnimChannel<ParamVec> mcGravity;
                /*! force converted to lattice units (returned by calc gravity) */
                ParamVec mLatticeGravity;
 
@@ -296,6 +303,8 @@ class Parametrizer {
 
                /*! for renderer - length of an animation step [s] */
                ParamFloat mAniFrameTime;
+               /*! animated channel */
+               AnimChannel<ParamFloat> mcAniFrameTime;
 
                /*! for renderer - start time of the animation [s] */
                ParamFloat mAniStart;
@@ -316,9 +325,6 @@ class Parametrizer {
                /*! fluid volume/height multiplier for GStar */
                ParamFloat mFluidVolumeHeight;
 
-               /*! max speed (for maxspeed setup) */
-               ParamFloat mMaxSpeed;
-
                /*! current max speed of the simulation (for adaptive time steps) */
                ParamFloat mSimulationMaxSpeed;
                /*! maximum omega (for adaptive time steps) */
index 71e7ed1a788d4bf8f08874dc5b8ca61b81120da3..b5f5838d87fe29af6eba964760a448a83977b9a1 100644 (file)
@@ -17,30 +17,49 @@ class ParticleObject
        public:
        //! Standard constructor
        inline ParticleObject(ntlVec3Gfx mp) :
-                       mPos(mp), mActive( true ) { };
+                       mPos(mp),mVel(0.0), mStatus(0), mActive( true ) { };
        //! Copy constructor
        inline ParticleObject(const ParticleObject &a) :
-                       mPos(a.mPos), mActive(a.mActive) { };
+                       mPos(a.mPos), mVel(a.mVel), 
+                       mStatus(a.mStatus), mActive(a.mActive) { };
        //! Destructor
        inline ~ParticleObject() { /* empty */ };
 
                //! add vector to position
                inline void advance(double vx, double vy, double vz) {
                        mPos[0] += vx; mPos[1] += vy; mPos[2] += vz; }
+               //! advance with own velocity
+               inline void advanceVel() { mPos += mVel; }
+               //! add acceleration to velocity
+               inline void addToVel(ntlVec3Gfx acc) { mVel += acc; }
 
-               //! add vector to position
+               //! get vector to position
                inline ntlVec3Gfx getPos() { return mPos; }
+               //! set velocity
+               inline void setVel(ntlVec3Gfx set) { mVel = set; }
+               //! set velocity
+               inline void setVel(gfxReal x, gfxReal y, gfxReal z) { mVel = ntlVec3Gfx(x,y,z); }
+               //! get velocity
+               inline ntlVec3Gfx getVel() { return mVel; }
 
                //! get active flag
                inline bool getActive() { return mActive; }
                //! set active flag
                inline void setActive(bool set) { mActive = set; }
+               //! get status int
+               inline int getStatus() { return mStatus; }
+               //! setstatus int
+               inline void setStatus(int set) { mStatus = set; }
                
        protected:
 
                /*! the particle position */
                ntlVec3Gfx mPos;
+               /*! the particle velocity */
+               ntlVec3Gfx mVel;
 
+               /*! particle status */
+               int mStatus;
                /*! particle active? */
                bool mActive;
 };
@@ -93,6 +112,8 @@ class ParticleTracer :
                inline vector<ParticleObject>::iterator getParticlesBegin() { return mParts[0].begin(); }
                //! end iterator for newest particles
                inline vector<ParticleObject>::iterator getParticlesEnd() { return mParts[0].end(); }
+               //! end iterator for newest particles
+               inline ParticleObject* getLast() { return &(mParts[0][ mParts[0].size()-1 ]); }
                
                /*! set geometry start (for renderer) */
                inline void setStart(ntlVec3Gfx set) { mStart = set; }
index dfb92050af4f09e530f67f224de2c5bda56000f4..bec1e82ca21fa5f21f559e75fd1e3c20b7d93357 100644 (file)
@@ -10,6 +10,7 @@
 #include "simulation_object.h"
 #include "ntl_bsptree.h"
 #include "ntl_scene.h"
+#include "particletracer.h"
 
 #ifdef _WIN32
 #else
@@ -100,6 +101,7 @@ void SimulationObject::freeGeoTree() {
  *****************************************************************************/
 int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
 {
+       if(!SIMWORLD_OK()) return 1;
        mpGlob = glob;
        if(!getVisible()) {
                mpAttrs->setAllUsed();
@@ -126,14 +128,18 @@ int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
        // for non-param simulations
        mpLbm->setParametrizer( mpParam );
        mpParam->setAttrList( getAttributeList() );
-       mpParam->setSize( mpLbm->getSizeX(), mpLbm->getSizeY(), mpLbm->getSizeZ() );
+       // not needed.. done in solver_init: mpParam->setSize ...
        mpParam->parseAttrList();
 
        mpLbm->setAttrList( getAttributeList() );
        mpLbm->parseAttrList();
-       mParts.parseAttrList( getAttributeList() );
-       mParts.setName( getName() + "_part" );
-       mParts.initialize( glob );
+       mpParts = new ParticleTracer();
+       mpParts->parseAttrList( getAttributeList() );
+
+       if(!SIMWORLD_OK()) return 1;
+       mpParts->setName( getName() + "_part" );
+       mpParts->initialize( glob );
+       if(!SIMWORLD_OK()) return 1;
        
        // init material settings
        string matMc("default");
@@ -146,7 +152,7 @@ int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
        mpLbm->setGeoEnd( mGeoEnd );
        mpLbm->setRenderGlobals( mpGlob );
        mpLbm->setName( getName() + "_lbm" );
-       mpLbm->initialize( NULL, mpGlob->getScene()->getObjects() );
+       mpLbm->initializeSolver();
 
        // print cell type stats
        const int jmax = sizeof(CellFlagType)*8;
@@ -185,13 +191,12 @@ int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
        {
                std::ostringstream out;
                out.precision(2); out.width(4);
-               int totNum = flagCount[0]+flagCount[2]+flagCount[10]+flagCount[11];
-               double ebFrac = (double)(flagCount[0]+flagCount[2]) / totNum;
-               double flFrac = (double)(flagCount[10]) / totNum;
-               double ifFrac = (double)(flagCount[11]) / totNum;
-               double eifFrac = (double)(flagCount[11]+flagCount[26]+flagCount[27]) / totNum;
+               int totNum = flagCount[1]+flagCount[2]+flagCount[7]+flagCount[8];
+               double ebFrac = (double)(flagCount[1]+flagCount[2]) / totNum;
+               double flFrac = (double)(flagCount[7]) / totNum;
+               double ifFrac = (double)(flagCount[8]) / totNum;
                //???
-               out<<"\tFractions: [empty/bnd - fluid - interface - ext. if]  =  [" << ebFrac<<" - " << flFrac<<" - " << ifFrac<<" - " << eifFrac <<"] "<< charNl;
+               out<<"\tFractions: [empty/bnd - fluid - interface - ext. if]  =  [" << ebFrac<<" - " << flFrac<<" - " << ifFrac<<"] "<< charNl;
 
                if(diffInits > 0) {
                        debugOut("SimulationObject::initializeLbmSimulation celltype Warning: Diffinits="<<diffInits<<" !!!!!!!!!" , 5);
@@ -200,7 +205,7 @@ int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
        }
 #endif // ELBEEM_BLENDER==1
 
-       mpLbm->initParticles( &mParts );
+       mpLbm->initParticles(mpParts);
 
        // this has to be inited here - before, the values might be unknown
        ntlGeometryObject *surf = mpLbm->getSurfaceGeoObj();
@@ -213,12 +218,12 @@ int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
                if(mShowSurface) mObjects.push_back( surf );
        }
        
-       mParts.setStart( mGeoStart );
-       mParts.setEnd( mGeoEnd );
-       mParts.setCastShadows( false );
-       mParts.setReceiveShadows( false );
-       mParts.searchMaterial( glob->getMaterials() );
-       if(mShowParticles) mObjects.push_back( &mParts );
+       mpParts->setStart( mGeoStart );
+       mpParts->setEnd( mGeoEnd );
+       mpParts->setCastShadows( false );
+       mpParts->setReceiveShadows( false );
+       mpParts->searchMaterial( glob->getMaterials() );
+       if(mShowParticles) mObjects.push_back(mpParts);
 
        // add objects to display for debugging (e.g. levelset particles)
        vector<ntlGeometryObject *> debugObjs = mpLbm->getDebugObjects();
@@ -231,17 +236,25 @@ int SimulationObject::initializeLbmSimulation(ntlRenderGlobals *glob)
        return 0;
 }
 
+/*! set current frame */
+void SimulationObject::setFrameNum(int num) {
+       // advance parametrizer
+       mpParam->setFrameNum(num);
+}
 
 /******************************************************************************
  * simluation interface: advance simulation another step (whatever delta time that might be) 
  *****************************************************************************/
 void SimulationObject::step( void )
 {
-       mpLbm->step();
+       if(mpParam->getAniFrameTime()>0.0) {
+               // dont advance for stopped time
+               mpLbm->step();
 
-       mParts.savePreviousPositions();
-       mpLbm->advanceParticles( &mParts );
-       mTime += mpParam->getStepTime();
+               mpParts->savePreviousPositions();
+               mpLbm->advanceParticles(mpParts);
+               mTime += mpParam->getStepTime();
+       }
        if(mpLbm->getPanic()) mPanic = true;
 
   //debMsgStd("SimulationObject::step",DM_MSG," Sim '"<<mName<<"' stepped to "<<mTime<<" (stept="<<(mpParam->getStepTime())<<", framet="<<getFrameTime()<<") ", 10);
index ae9060db8597dd9e3b4e0070371e87ae2135653f..3105a4946613b240a8dce0971693748871cc3f7c 100644 (file)
 #include "ntl_geometryshader.h"
 #include "solver_interface.h"
 #include "parametrizer.h"
-#include "particletracer.h"
 
 class ntlTree;
 class ntlRenderGlobals;
 class ntlRenderGlobals;
+class ParticleTracer;
 
 
 //! type fluid geometry init 
@@ -80,6 +80,9 @@ class SimulationObject :
                /*! simluation interface: initialize simulation */
                int initializeLbmSimulation(ntlRenderGlobals *glob);
 
+               /*! set current frame */
+               void setFrameNum(int num);
+
                /*! Do geo etc. init */
                virtual int postGeoConstrInit(ntlRenderGlobals *glob) { return initializeLbmSimulation(glob); };
                virtual int initializeShader() { /* ... */ return true; };
@@ -138,7 +141,7 @@ class SimulationObject :
                /*! debug info to display */
                int mDebugType;
 
-               //! dimension of the simulation - now given by LBMDIM define globally
+               //! dimension of the simulation - now given by LBM-DIM define globally
                //! solver type
                string mSolverType;
 
@@ -155,7 +158,7 @@ class SimulationObject :
                Parametrizer *mpParam;
 
                /*! particle tracing object */
-               ParticleTracer mParts;
+               ParticleTracer *mpParts;
 
                /*! show parts of the simulation toggles */
                bool mShowSurface;
index 40e562b1ab0728d7f1c28b7615c2472f13df3eff..98c1882d79c5feac68ab9ca82f90204db003c8b5 100644 (file)
 #ifndef LBM_SOLVERCLASS_H
 #define LBM_SOLVERCLASS_H
 
-// blender interface
-#if ELBEEM_BLENDER==1
-// warning - for MSVC this has to be included
-// _before_ ntl_vector3dim
-#include "SDL.h"
-#include "SDL_thread.h"
-#include "SDL_mutex.h"
-extern "C" {
-       void simulateThreadIncreaseFrame(void);
-       extern SDL_mutex *globalBakeLock;
-       extern int        globalBakeState;
-       extern int        globalBakeFrame;
-}
-#endif // ELBEEM_BLENDER==1
-
 #include "utilities.h"
 #include "solver_interface.h"
 #include "ntl_scene.h"
@@ -48,6 +33,12 @@ ERROR - define model first!
 
 // general solver setting defines
 
+// default to 3dim
+#ifndef LBMDIM
+#define LBMDIM 3
+#endif // LBMDIM
+
+
 //! debug coordinate accesses and the like? (much slower)
 #define FSGR_STRICT_DEBUG 0
 
@@ -61,9 +52,6 @@ ERROR - define model first!
 //#define TIMEINTORDER 0
 // TODO remove interpol t param, also interTime
 
-//! refinement border method (1 = small border / 2 = larger)
-#define REFINEMENTBORDER 1
-
 // use optimized 3D code?
 #if LBMDIM==2
 #define OPT3D 0
@@ -79,16 +67,6 @@ ERROR - define model first!
 #      endif // FSGR_STRICT_DEBUG==1
 #endif
 
-// enable/disable fine grid compression for finest level
-#if LBMDIM==3
-#define COMPRESSGRIDS 1
-#else 
-#define COMPRESSGRIDS 0
-#endif 
-
-//! threshold for level set fluid generation/isosurface
-#define LS_FLUIDTHRESHOLD 0.5
-
 //! invalid mass value for unused mass data
 #define MASS_INVALID -1000.0
 
@@ -102,6 +80,13 @@ ERROR - define model first!
 //! maxmimum no. of grid levels
 #define FSGR_MAXNOOFLEVELS 5
 
+// enable/disable fine grid compression for finest level
+#if LBMDIM==3
+#define COMPRESSGRIDS 1
+#else 
+#define COMPRESSGRIDS 0
+#endif 
+
 // helper for comparing floats with epsilon
 #define GFX_FLOATNEQ(x,y) ( ABS((x)-(y)) > (VECTOR_EPSILON) )
 #define LBM_FLOATNEQ(x,y) ( ABS((x)-(y)) > (10.0*LBM_EPSILON) )
@@ -114,13 +99,6 @@ ERROR - define model first!
 #define FORDF0M for(int m= 0; m< LBM_DFNUM; ++m)
 #define FORDF1M for(int m= 1; m< LBM_DFNUM; ++m)
 
-// aux. field indices (same for 2d)
-#define dFfrac 19
-#define dMass 20
-#define dFlux 21
-// max. no. of cell values for 3d
-#define dTotalNum 22
-
 // iso value defines
 // border for marching cubes
 #define ISOCORR 3
@@ -237,13 +215,15 @@ class LbmFsgrSolver :
                virtual ~LbmFsgrSolver();
                //! id string of solver
                virtual string getIdString();
+               //! dimension of solver
+               virtual int getDimension();
 
                //! initilize variables fom attribute list 
                virtual void parseAttrList();
                //! Initialize omegas and forces on all levels (for init/timestep change)
                void initLevelOmegas();
                //! finish the init with config file values (allocate arrays...) 
-               virtual bool initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*objects*/ );
+               virtual bool initializeSolver(); //( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*objects*/ );
 
 #if LBM_USE_GUI==1
                //! show simulation info (implement LbmSolverInterface pure virtual func)
@@ -290,11 +270,9 @@ class LbmFsgrSolver :
                void fineAdvance();
                void coarseAdvance(int lev);
                void coarseCalculateFluxareas(int lev);
-               // coarsen a given level (returns true if sth. was changed)
-               bool performRefinement(int lev);
-               bool performCoarsening(int lev);
-               //void oarseInterpolateToFineSpaceTime(int lev,LbmFloat t);
-               void interpolateFineFromCoarse(int lev,LbmFloat t);
+               // adaptively coarsen grid
+               bool adaptGrid(int lev);
+               // restrict fine grid DFs to coarse grid
                void coarseRestrictFromFine(int lev);
 
                /* simulation object interface, just calls stepMain */
@@ -341,6 +319,7 @@ class LbmFsgrSolver :
                LBM_INLINED void addToNewInterList( int ni, int nj, int nk );   
                //! cell is interpolated from coarse level (inited into set, source sets are determined by t)
                void interpolateCellFromCoarse(int lev, int i, int j,int k, int dstSet, LbmFloat t, CellFlagType flagSet,bool markNbs);
+               void coarseRestrictCell(int lev, int i,int j,int k, int srcSet, int dstSet);
 
                //! minimal and maximal z-coords (for 2D/3D loops)
                LBM_INLINED int getForZMinBnd();
@@ -365,8 +344,6 @@ class LbmFsgrSolver :
 
                //! Mcubes object for surface reconstruction 
                IsoSurface *mpPreviewSurface;
-               float mSmoothSurface;
-               float mSmoothNormals;
                
                //! use time adaptivity? 
                bool mTimeAdap;
@@ -375,9 +352,6 @@ class LbmFsgrSolver :
                //! part slip value for domain
                LbmFloat mDomainPartSlipValue;
 
-               //! output surface preview? if >0 yes, and use as reduzed size 
-               int mOutputSurfacePreview;
-               LbmFloat mPreviewFactor;
                //! fluid vol height
                LbmFloat mFVHeight;
                LbmFloat mFVArea;
@@ -419,11 +393,7 @@ class LbmFsgrSolver :
                bool checkSymmetry(string idstring);
                //! kepp track of max/min no. of filled cells
                int mMaxNoCells, mMinNoCells;
-#ifndef USE_MSVC6FIXES
-               long long int mAvgNumUsedCells;
-#else
-               _int64 mAvgNumUsedCells;
-#endif
+               LONGINT mAvgNumUsedCells;
 
                //! for interactive - how to drop drops?
                int mDropMode;
@@ -451,11 +421,16 @@ class LbmFsgrSolver :
 
                /*! precomputed cell area values */
                LbmFloat mFsgrCellArea[27];
+               /*! restriction interpolation weights */
+               LbmFloat mGaussw[27];
 
                /*! LES C_smago paramter for finest grid */
                float mInitialCsmago;
                /*! LES stats for non OPT3D */
                LbmFloat mDebugOmegaRet;
+               /*! remember last init for animated params */
+               LbmFloat mLastOmega;
+               LbmVec   mLastGravity;
 
                //! fluid stats
                int mNumInterdCells;
@@ -468,13 +443,15 @@ class LbmFsgrSolver :
                //! debug function to force tadap syncing
                int mForceTadapRefine;
 
-#if ELBEEM_BLENDER!=1
+#ifndef ELBEEM_BLENDER
                // test functions
                bool mUseTestdata;
                LbmTestdata *mpTest;
                void initTestdata();
                void destroyTestdata();
                void handleTestdata();
+               void exportTestdata();
+               ParticleTracer *mpParticles;
 #endif // ELBEEM_BLENDER==1
 
                // strict debug interface
index 8d3cc34808cf04c00aa1707e6fbab13135f56d25..a138ad19ca8a95d35f978bbeda94cb7759d73205 100644 (file)
@@ -7,12 +7,12 @@
  *
  *****************************************************************************/
 
-#ifndef __APPLE_CC__
+#if ((!defined(__APPLE_CC__)) && (!defined(__INTEL_COMPILER))) || defined(LBM_FORCEINCLUDE)
 #include "solver_class.h"
 #include "solver_relax.h"
-#endif // __APPLE_CC__
 
-#if !defined(__APPLE_CC__) || defined(LBM_FORCEINCLUDE)
+// for geo init FGI_ defines
+#include "elbeem.h"
 
 /******************************************************************************
  * Lbm Constructor
@@ -24,9 +24,7 @@ LbmFsgrSolver<D>::LbmFsgrSolver() :
        mNumProblems(0), 
        mAvgMLSUPS(0.0), mAvgMLSUPSCnt(0.0),
        mpPreviewSurface(NULL), 
-       mSmoothSurface(0.0), mSmoothNormals(0.0),
-       mTimeAdap(false), mDomainBound("noslip"), mDomainPartSlipValue(0.1),
-       mOutputSurfacePreview(0), mPreviewFactor(0.25),
+       mTimeAdap(true), mDomainBound("noslip"), mDomainPartSlipValue(0.1),
        mFVHeight(0.0), mFVArea(1.0), mUpdateFVHeight(false),
        mInitSurfaceSmoothing(0),
        mTimestepReduceLock(0),
@@ -36,19 +34,21 @@ LbmFsgrSolver<D>::LbmFsgrSolver() :
        mMaxNoCells(0), mMinNoCells(0), mAvgNumUsedCells(0),
        mDropMode(1), mDropSize(0.15), mDropSpeed(0.0),
        mObjectSpeeds(), mObjectPartslips(),
-       mIsoWeightMethod(2),
+       mIsoWeightMethod(1),
        mMaxRefine(1), 
        mDfScaleUp(-1.0), mDfScaleDown(-1.0),
        mInitialCsmago(0.04), mDebugOmegaRet(0.0),
+       mLastOmega(1e10), mLastGravity(1e10),
        mNumInvIfTotal(0), mNumFsgrChanges(0),
        mDisableStandingFluidInit(0),
        mForceTadapRefine(-1)
 {
   // not much to do here... 
        D::mpIso = new IsoSurface( D::mIsoValue, false );
-#if ELBEEM_BLENDER!=1
+#if ELBEEM_PLUGIN!=1
        mpTest = new LbmTestdata();
-#endif // ELBEEM_BLENDER!=1
+       mpParticles = NULL;
+#endif // ELBEEM_PLUGIN!=1
 
   // init equilibrium dist. func 
   LbmFloat rho=1.0;
@@ -105,6 +105,26 @@ LbmFsgrSolver<D>::LbmFsgrSolver() :
                        ) * -1.0; 
        }
 
+       // calculate gauss weights for restriction
+       //LbmFloat mGaussw[27];
+       LbmFloat totGaussw = 0.0;
+       const LbmFloat alpha = 1.0;
+       const LbmFloat gw = sqrt(2.0*D::cDimension);
+#if ELBEEM_PLUGIN!=1
+       errMsg("coarseRestrictFromFine", "TCRFF_DFDEBUG2 test df/dir num!");
+#endif
+       for(int n=0;(n<D::cDirNum); n++) { mGaussw[n] = 0.0; }
+       //for(int n=0;(n<D::cDirNum); n++) { 
+       for(int n=0;(n<D::cDfNum); n++) { 
+               const LbmFloat d = norm(LbmVec(D::dfVecX[n], D::dfVecY[n], D::dfVecZ[n]));
+               LbmFloat w = expf( -alpha*d*d ) - expf( -alpha*gw*gw );
+               mGaussw[n] = w;
+               totGaussw += w;
+       }
+       for(int n=0;(n<D::cDirNum); n++) { 
+               mGaussw[n] = mGaussw[n]/totGaussw;
+       }
+
        //addDrop(false,0,0);
 }
 
@@ -129,10 +149,10 @@ LbmFsgrSolver<D>::~LbmFsgrSolver()
        delete D::mpIso;
        if(mpPreviewSurface) delete mpPreviewSurface;
 
-#if ELBEEM_BLENDER!=1
-       if(mUseTestdata) destroyTestdata();
+#if ELBEEM_PLUGIN!=1
+       destroyTestdata();
        delete mpTest;
-#endif // ELBEEM_BLENDER!=1
+#endif // ELBEEM_PLUGIN!=1
 
        // always output performance estimate
        debMsgStd("LbmFsgrSolver::~LbmFsgrSolver",DM_MSG," Avg. MLSUPS:"<<(mAvgMLSUPS/mAvgMLSUPSCnt), 5);
@@ -154,15 +174,15 @@ LbmFsgrSolver<D>::parseAttrList()
        string matIso("default");
        matIso = D::mpAttrs->readString("material_surf", matIso, "SimulationLbm","mpIso->material", false );
        D::mpIso->setMaterialName( matIso );
-       mOutputSurfacePreview = D::mpAttrs->readInt("surfacepreview", mOutputSurfacePreview, "SimulationLbm","mOutputSurfacePreview", false );
+       D::mOutputSurfacePreview = D::mpAttrs->readInt("surfacepreview", D::mOutputSurfacePreview, "SimulationLbm","D::mOutputSurfacePreview", false );
        mTimeAdap = D::mpAttrs->readBool("timeadap", mTimeAdap, "SimulationLbm","mTimeAdap", false );
        mDomainBound = D::mpAttrs->readString("domainbound", mDomainBound, "SimulationLbm","mDomainBound", false );
        mDomainPartSlipValue = D::mpAttrs->readFloat("domainpartslip", mDomainPartSlipValue, "SimulationLbm","mDomainPartSlipValue", false );
 
        mIsoWeightMethod= D::mpAttrs->readInt("isoweightmethod", mIsoWeightMethod, "SimulationLbm","mIsoWeightMethod", false );
        mInitSurfaceSmoothing = D::mpAttrs->readInt("initsurfsmooth", mInitSurfaceSmoothing, "SimulationLbm","mInitSurfaceSmoothing", false );
-       mSmoothSurface = D::mpAttrs->readFloat("smoothsurface", mSmoothSurface, "SimulationLbm","mSmoothSurface", false );
-       mSmoothNormals = D::mpAttrs->readFloat("smoothnormals", mSmoothNormals, "SimulationLbm","mSmoothNormals", false );
+       D::mSmoothSurface = D::mpAttrs->readFloat("smoothsurface", D::mSmoothSurface, "SimulationLbm","mSmoothSurface", false );
+       D::mSmoothNormals = D::mpAttrs->readFloat("smoothnormals", D::mSmoothNormals, "SimulationLbm","mSmoothNormals", false );
 
        mInitialCsmago = D::mpAttrs->readFloat("csmago", mInitialCsmago, "SimulationLbm","mInitialCsmago", false );
        // deprecated!
@@ -175,7 +195,8 @@ LbmFsgrSolver<D>::parseAttrList()
 #endif // USE_LES==1
 
        // refinement
-       mMaxRefine  = D::mpAttrs->readInt("maxrefine",  mMaxRefine ,"LbmFsgrSolver", "mMaxRefine", true);
+       mMaxRefine = D::mRefinementDesired;
+       mMaxRefine  = D::mpAttrs->readInt("maxrefine",  mMaxRefine ,"LbmFsgrSolver", "mMaxRefine", false);
        if(mMaxRefine<0) mMaxRefine=0;
        if(mMaxRefine>FSGR_MAXNOOFLEVELS) mMaxRefine=FSGR_MAXNOOFLEVELS-1;
        mDisableStandingFluidInit = D::mpAttrs->readInt("disable_stfluidinit", mDisableStandingFluidInit,"LbmFsgrSolver", "mDisableStandingFluidInit", false);
@@ -186,10 +207,11 @@ LbmFsgrSolver<D>::parseAttrList()
        // FIXME check needed?
        mFVArea   = D::mpAttrs->readFloat("fvolarea", mFVArea, "LbmFsgrSolver","mFArea", false );
 
-#if ELBEEM_BLENDER!=1
+#if ELBEEM_PLUGIN!=1
+       mUseTestdata = 0;
        mUseTestdata = D::mpAttrs->readBool("use_testdata", mUseTestdata,"LbmFsgrSolver", "mUseTestdata", false);
        mpTest->parseTestdataAttrList(D::mpAttrs);
-#endif // ELBEEM_BLENDER!=1
+#endif // ELBEEM_PLUGIN!=1
 }
 
 
@@ -201,10 +223,15 @@ void
 LbmFsgrSolver<D>::initLevelOmegas()
 {
        // no explicit settings
-       D::mOmega = D::mpParam->calculateOmega();
-       D::mGravity = vec2L( D::mpParam->calculateGravity() );
+       D::mOmega = D::mpParam->calculateOmega(mSimulationTime);
+       D::mGravity = vec2L( D::mpParam->calculateGravity(mSimulationTime) );
        D::mSurfaceTension = D::mpParam->calculateSurfaceTension(); // unused
 
+       // check if last init was ok
+       LbmFloat gravDelta = norm(D::mGravity-mLastGravity);
+       //errMsg("ChannelAnimDebug","t:"<<mSimulationTime<<" om:"<<D::mOmega<<" - lom:"<<mLastOmega<<" gv:"<<D::mGravity<<" - "<<mLastGravity<<" , "<<gravDelta  );
+       if((D::mOmega == mLastOmega) && (gravDelta<=0.0)) return;
+
        if(mInitialCsmago<=0.0) {
                if(OPT3D==1) {
                        errFatal("LbmFsgrSolver::initLevelOmegas","Csmago-LES = 0 not supported for optimized 3D version...",SIMWORLD_INITERROR); 
@@ -229,13 +256,6 @@ LbmFsgrSolver<D>::initLevelOmegas()
                nomega                = 1.0/nomega;
                mLevel[i].omega       = (LbmFloat)nomega;
                mLevel[i].stepsize    = 2.0 * mLevel[i+1].stepsize;
-               //mLevel[i].lcsmago     = mLevel[i+1].lcsmago*mCsmagoRefineMultiplier;
-               //if(mLevel[i].lcsmago>1.0) mLevel[i].lcsmago = 1.0;
-               //if(strstr(D::getName().c_str(),"Debug")){ 
-               //mLevel[i].lcsmago = mLevel[mMaxRefine].lcsmago; // DEBUG
-               // if(strstr(D::getName().c_str(),"Debug")) mLevel[i].lcsmago = mLevel[mMaxRefine].lcsmago * (LbmFloat)(mMaxRefine-i)*0.5+1.0; 
-               //if(strstr(D::getName().c_str(),"Debug")) mLevel[i].lcsmago = mLevel[mMaxRefine].lcsmago * ((LbmFloat)(mMaxRefine-i)*1.0 + 1.0 ); 
-               //if(strstr(D::getName().c_str(),"Debug")) mLevel[i].lcsmago = 0.99;
                mLevel[i].lcsmago = mInitialCsmago;
                mLevel[i].lcsmago_sqr = mLevel[i].lcsmago*mLevel[i].lcsmago;
                mLevel[i].lcnu        = (2.0* (1.0/mLevel[i].omega)-1.0) * (1.0/6.0);
@@ -249,6 +269,8 @@ LbmFsgrSolver<D>::initLevelOmegas()
                mLevel[i].gravity = (mLevel[i+1].gravity * mLevel[i+1].omega) * 2.0 / mLevel[i].omega;
        }
 
+       mLastOmega = D::mOmega;
+       mLastGravity = D::mGravity;
        // debug? invalidate old values...
        D::mGravity = -100.0;
        D::mOmega = -100.0;
@@ -278,65 +300,60 @@ LbmFsgrSolver<D>::initLevelOmegas()
  *****************************************************************************/
 template<class D>
 bool 
-LbmFsgrSolver<D>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*objects*/ )
+//LbmFsgrSolver<D>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*objects*/ )
+LbmFsgrSolver<D>::initializeSolver()
 {
   debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Init start... (Layout:"<<ALSTRING<<") ",1);
 
-       // fix size inits to force cubic cells and mult4 level dimensions
-       const int debugGridsizeInit = 1;
-       mPreviewFactor = (LbmFloat)mOutputSurfacePreview / (LbmFloat)D::mSizex;
-       int maxGridSize = D::mSizex; // get max size
-       if(D::mSizey>maxGridSize) maxGridSize = D::mSizey;
-       if(D::mSizez>maxGridSize) maxGridSize = D::mSizez;
-       LbmFloat maxGeoSize = (D::mvGeoEnd[0]-D::mvGeoStart[0]); // get max size
-       if((D::mvGeoEnd[1]-D::mvGeoStart[1])>maxGridSize) maxGeoSize = (D::mvGeoEnd[1]-D::mvGeoStart[1]);
-       if((D::mvGeoEnd[2]-D::mvGeoStart[2])>maxGridSize) maxGeoSize = (D::mvGeoEnd[2]-D::mvGeoStart[2]);
-       // FIXME better divide max geo size by corresponding resolution rather than max? no prob for rx==ry==rz though
-       LbmFloat cellSize = (maxGeoSize / (LbmFloat)maxGridSize);
-  if(debugGridsizeInit) debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Start:"<<D::mvGeoStart<<" End:"<<D::mvGeoEnd<<" maxS:"<<maxGeoSize<<" maxG:"<<maxGridSize<<" cs:"<<cellSize, 10);
-       // force grid sizes according to geom. size, rounded
-       D::mSizex = (int) ((D::mvGeoEnd[0]-D::mvGeoStart[0]) / cellSize +0.5);
-       D::mSizey = (int) ((D::mvGeoEnd[1]-D::mvGeoStart[1]) / cellSize +0.5);
-       D::mSizez = (int) ((D::mvGeoEnd[2]-D::mvGeoStart[2]) / cellSize +0.5);
-       // match refinement sizes, round downwards to multiple of 4
-       int sizeMask = 0;
-       int maskBits = mMaxRefine;
-       if(PARALLEL==1) maskBits+=2;
-       for(int i=0; i<maskBits; i++) { sizeMask |= (1<<i); }
-
-       // at least size 4 on coarsest level
-       int minSize = (int)pow(2.0, maskBits+2.0);
-       if(D::mSizex<minSize) D::mSizex = minSize;
-       if(D::mSizey<minSize) D::mSizey = minSize;
-       if(D::mSizez<minSize) D::mSizez = minSize;
-errMsg("MMS","minSize"<<minSize);
+       // size inits to force cubic cells and mult4 level dimensions
+       // and make sure we dont allocate too much...
+       bool memOk = false;
+       int orgSx = D::mSizex;
+       int orgSy = D::mSizey;
+       int orgSz = D::mSizez;
+       double sizeReduction = 1.0;
+       double memCnt = -1.0;
+       string memreqStr("");   
+       while(!memOk) {
+               initGridSizes( D::mSizex, D::mSizey, D::mSizez,
+                               D::mvGeoStart, D::mvGeoEnd, mMaxRefine, PARALLEL);
+               calculateMemreqEstimate( D::mSizex, D::mSizey, D::mSizez, mMaxRefine, &memCnt, &memreqStr );
+               
+               double memLimit;
+               if(sizeof(int)==4) {
+                       // 32bit system, limit to 2GB
+                       memLimit = 2.0* 1024.0*1024.0*1024.0;
+               } else {
+                       // 64bit, just take 16GB as limit for now...
+                       memLimit = 16.0* 1024.0*1024.0*1024.0;
+               }
+               if(memCnt>memLimit) {
+                       sizeReduction *= 0.9;
+                       D::mSizex = (int)(orgSx * sizeReduction);
+                       D::mSizey = (int)(orgSy * sizeReduction);
+                       D::mSizez = (int)(orgSz * sizeReduction);
+                       debMsgStd("LbmFsgrSolver::initialize",DM_WARNING,"initGridSizes: memory limit exceeded "<<memCnt<<"/"<<memLimit<<", retrying: "
+                                       <<D::mSizex<<" Y:"<<D::mSizey<<" Z:"<<D::mSizez, 3 );
+               } else {
+                       memOk = true;
+               } 
+       }
        
-       sizeMask = ~sizeMask;
-  if(debugGridsizeInit) debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Size X:"<<D::mSizex<<" Y:"<<D::mSizey<<" Z:"<<D::mSizez<<" m"<<convertCellFlagType2String(sizeMask) ,10);
-       D::mSizex &= sizeMask;
-       D::mSizey &= sizeMask;
-       D::mSizez &= sizeMask;
-
-       // force geom size to match rounded/modified grid sizes
-       D::mvGeoEnd[0] = D::mvGeoStart[0] + cellSize*(LbmFloat)D::mSizex;
-       D::mvGeoEnd[1] = D::mvGeoStart[1] + cellSize*(LbmFloat)D::mSizey;
-       D::mvGeoEnd[2] = D::mvGeoStart[2] + cellSize*(LbmFloat)D::mSizez;
-
-  debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Final domain size X:"<<D::mSizex<<" Y:"<<D::mSizey<<" Z:"<<D::mSizez<<
-                       ", Domain: "<<D::mvGeoStart<<":"<<D::mvGeoEnd<<", "<<(D::mvGeoEnd-D::mvGeoStart) ,2);
+       D::mPreviewFactor = (LbmFloat)D::mOutputSurfacePreview / (LbmFloat)D::mSizex;
+  debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"initGridSizes: Final domain size X:"<<D::mSizex<<" Y:"<<D::mSizey<<" Z:"<<D::mSizez<<
+         ", Domain: "<<D::mvGeoStart<<":"<<D::mvGeoEnd<<", "<<(D::mvGeoEnd-D::mvGeoStart)<<
+         ", est. Mem.Req.: "<<memreqStr        ,2);
   //debMsgStd("LbmFsgrSolver::initialize",DM_MSG, ,2);
        D::mpParam->setSize(D::mSizex, D::mSizey, D::mSizez);
 
   //debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Size X:"<<D::mSizex<<" Y:"<<D::mSizey<<" Z:"<<D::mSizez ,2);
 
-#if ELBEEM_BLENDER!=1
+#if ELBEEM_PLUGIN!=1
   debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Definitions: "
                <<"LBM_EPSILON="<<LBM_EPSILON       <<" "
                <<"FSGR_STRICT_DEBUG="<<FSGR_STRICT_DEBUG       <<" "
-               <<"REFINEMENTBORDER="<<REFINEMENTBORDER        <<" "
                <<"OPT3D="<<OPT3D        <<" "
                <<"COMPRESSGRIDS="<<COMPRESSGRIDS<<" "
-               <<"LS_FLUIDTHRESHOLD="<<LS_FLUIDTHRESHOLD        <<" "
                <<"MASS_INVALID="<<MASS_INVALID        <<" "
                <<"FSGR_LISTTRICK="<<FSGR_LISTTRICK            <<" "
                <<"FSGR_LISTTTHRESHEMPTY="<<FSGR_LISTTTHRESHEMPTY          <<" "
@@ -344,7 +361,7 @@ errMsg("MMS","minSize"<<minSize);
                <<"FSGR_MAGICNR="<<FSGR_MAGICNR              <<" " 
                <<"USE_LES="<<USE_LES              <<" " 
                ,10);
-#endif // ELBEEM_BLENDER!=1
+#endif // ELBEEM_PLUGIN!=1
 
        // perform 2D corrections...
        if(D::cDimension == 2) D::mSizez = 1;
@@ -362,12 +379,9 @@ errMsg("MMS","minSize"<<minSize);
                errFatal("LbmFsgrSolver::initialize","Fatal: failed to init parameters! Aborting...",SIMWORLD_INITERROR);
                return false;
        }
-       // recalc objects speeds in geo init
-
 
 
        // init vectors
-       //if(mMaxRefine >= FSGR_MAXNOOFLEVELS) { errFatal("LbmFsgrSolver::initializeLbmGridref"," error: Too many levels!", SIMWORLD_INITERROR); return false; }
        for(int i=0; i<=mMaxRefine; i++) {
                mLevel[i].id = i;
                mLevel[i].nodeSize = 0.0; 
@@ -393,36 +407,6 @@ errMsg("MMS","minSize"<<minSize);
                mLevel[i].lSizex = mLevel[i+1].lSizex/2;
                mLevel[i].lSizey = mLevel[i+1].lSizey/2;
                mLevel[i].lSizez = mLevel[i+1].lSizez/2;
-               /*if( ((mLevel[i].lSizex % 4) != 0) || ((mLevel[i].lSizey % 4) != 0) || ((mLevel[i].lSizez % 4) != 0) ) {
-                       errMsg("LbmFsgrSolver","Init: error invalid sizes on level "<<i<<" "<<PRINT_VEC(mLevel[i].lSizex,mLevel[i].lSizey,mLevel[i].lSizez) );
-                       xit(1);
-               }// old QUAD handling */
-       }
-
-       // estimate memory usage
-       {
-               unsigned long int memCnt = 0;
-               unsigned long int rcellSize = ((mLevel[mMaxRefine].lSizex*mLevel[mMaxRefine].lSizey*mLevel[mMaxRefine].lSizez) *dTotalNum);
-               memCnt += sizeof(CellFlagType) * (rcellSize/dTotalNum +4) *2;
-#if COMPRESSGRIDS==0
-               memCnt += sizeof(LbmFloat) * (rcellSize +4) *2;
-#else // COMPRESSGRIDS==0
-               unsigned long int compressOffset = (mLevel[mMaxRefine].lSizex*mLevel[mMaxRefine].lSizey*dTotalNum*2);
-               memCnt += sizeof(LbmFloat) * (rcellSize+compressOffset +4);
-#endif // COMPRESSGRIDS==0
-               for(int i=mMaxRefine-1; i>=0; i--) {
-                       rcellSize = ((mLevel[i].lSizex*mLevel[i].lSizey*mLevel[i].lSizez) *dTotalNum);
-                       memCnt += sizeof(CellFlagType) * (rcellSize/dTotalNum +4) *2;
-                       memCnt += sizeof(LbmFloat) * (rcellSize +4) *2;
-               }
-               double memd = memCnt;
-               char *sizeStr = "";
-               const double sfac = 1000.0;
-               if(memd>sfac){ memd /= sfac; sizeStr="KB"; }
-               if(memd>sfac){ memd /= sfac; sizeStr="MB"; }
-               if(memd>sfac){ memd /= sfac; sizeStr="GB"; }
-               if(memd>sfac){ memd /= sfac; sizeStr="TB"; }
-               debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Required Grid memory: "<< memd <<" "<< sizeStr<<" ",4);
        }
 
        // safety check
@@ -431,22 +415,25 @@ errMsg("MMS","minSize"<<minSize);
                return false;
        }
 
+       double memCheck = 0.0;
        mLevel[ mMaxRefine ].nodeSize = ((D::mvGeoEnd[0]-D::mvGeoStart[0]) / (LbmFloat)(D::mSizex));
        mLevel[ mMaxRefine ].simCellSize = D::mpParam->getCellSize();
        mLevel[ mMaxRefine ].lcellfactor = 1.0;
-       unsigned long int rcellSize = ((mLevel[mMaxRefine].lSizex*mLevel[mMaxRefine].lSizey*mLevel[mMaxRefine].lSizez) *dTotalNum);
+       LONGINT rcellSize = ((mLevel[mMaxRefine].lSizex*mLevel[mMaxRefine].lSizey*mLevel[mMaxRefine].lSizez) *dTotalNum);
        // +4 for safety ?
        mLevel[ mMaxRefine ].mprsFlags[0] = new CellFlagType[ rcellSize/dTotalNum +4 ];
        mLevel[ mMaxRefine ].mprsFlags[1] = new CellFlagType[ rcellSize/dTotalNum +4 ];
+       memCheck += 2 * sizeof(CellFlagType) * (rcellSize/dTotalNum +4);
 
 #if COMPRESSGRIDS==0
        mLevel[ mMaxRefine ].mprsCells[0] = new LbmFloat[ rcellSize +4 ];
        mLevel[ mMaxRefine ].mprsCells[1] = new LbmFloat[ rcellSize +4 ];
+       memCheck += 2 * sizeof(LbmFloat) * (rcellSize+4);
 #else // COMPRESSGRIDS==0
-       unsigned long int compressOffset = (mLevel[mMaxRefine].lSizex*mLevel[mMaxRefine].lSizey*dTotalNum*2);
+       LONGINT compressOffset = (mLevel[mMaxRefine].lSizex*mLevel[mMaxRefine].lSizey*dTotalNum*2);
        mLevel[ mMaxRefine ].mprsCells[1] = new LbmFloat[ rcellSize +compressOffset +4 ];
        mLevel[ mMaxRefine ].mprsCells[0] = mLevel[ mMaxRefine ].mprsCells[1]+compressOffset;
-       //errMsg("CGD","rcs:"<<rcellSize<<" cpff:"<<compressOffset<< " c0:"<<mLevel[ mMaxRefine ].mprsCells[0]<<" c1:"<<mLevel[ mMaxRefine ].mprsCells[1]<< " c0e:"<<(mLevel[ mMaxRefine ].mprsCells[0]+rcellSize)<<" c1:"<<(mLevel[ mMaxRefine ].mprsCells[1]+rcellSize)); // DEBUG
+       memCheck += sizeof(LbmFloat) * (rcellSize +compressOffset +4);
 #endif // COMPRESSGRIDS==0
 
        LbmFloat lcfdimFac = 8.0;
@@ -460,10 +447,21 @@ errMsg("MMS","minSize"<<minSize);
                rcellSize = ((mLevel[i].lSizex*mLevel[i].lSizey*mLevel[i].lSizez) *dTotalNum);
                mLevel[i].mprsFlags[0] = new CellFlagType[ rcellSize/dTotalNum +4 ];
                mLevel[i].mprsFlags[1] = new CellFlagType[ rcellSize/dTotalNum +4 ];
+               memCheck += 2 * sizeof(CellFlagType) * (rcellSize/dTotalNum +4);
                mLevel[i].mprsCells[0] = new LbmFloat[ rcellSize +4 ];
                mLevel[i].mprsCells[1] = new LbmFloat[ rcellSize +4 ];
+               memCheck += 2 * sizeof(LbmFloat) * (rcellSize+4);
        }
 
+       // isosurface memory
+       memCheck += (3*sizeof(int)+sizeof(float)) * ((D::mSizex+2)*(D::mSizey+2)*(D::mSizez+2));
+       // sanity check
+#if ELBEEM_PLUGIN!=1
+       if(ABS(1.0-memCheck/memCnt)>0.01) {
+               errMsg("LbmFsgrSolver::initialize","Sanity Error - memory estimate is off: "<<memCheck<<" vs. "<<memCnt );
+       }
+#endif // ELBEEM_PLUGIN!=1
+       
        // init sizes for _all_ levels
        for(int i=mMaxRefine; i>=0; i--) {
                mLevel[i].lOffsx = mLevel[i].lSizex;
@@ -485,8 +483,8 @@ errMsg("MMS","minSize"<<minSize);
        D::mpIso->setIsolevel( D::mIsoValue );
        // approximate feature size with mesh resolution
        float featureSize = mLevel[ mMaxRefine ].nodeSize*0.5;
-       D::mpIso->setSmoothSurface( mSmoothSurface * featureSize );
-       D::mpIso->setSmoothNormals( mSmoothNormals * featureSize );
+       D::mpIso->setSmoothSurface( D::mSmoothSurface * featureSize );
+       D::mpIso->setSmoothNormals( D::mSmoothNormals * featureSize );
 
        // init iso weight values mIsoWeightMethod
        int wcnt = 0;
@@ -539,7 +537,11 @@ errMsg("MMS","minSize"<<minSize);
        for(int lev=0; lev<=mMaxRefine; lev++) {
                FSGR_FORIJK_BOUNDS(lev) {
                        RFLAG(lev,i,j,k,0) = RFLAG(lev,i,j,k,0) = 0; // reset for changeFlag usage
-                       initEmptyCell(lev, i,j,k, CFEmpty, -1.0, -1.0); 
+                       if(!D::mAllfluid) {
+                               initEmptyCell(lev, i,j,k, CFEmpty, -1.0, -1.0); 
+                       } else {
+                               initEmptyCell(lev, i,j,k, CFFluid, 1.0, 1.0); 
+                       }
                }
        }
 
@@ -549,11 +551,8 @@ errMsg("MMS","minSize"<<minSize);
 
   /* init boundaries */
   debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Boundary init...",10);
-
-
-       // use the density init?
        initGeometryFlags();
-       D::initGenericTestCases();
+       // TODO check for invalid cells? nitGenericTestCases();
        
        // new - init noslip 1 everywhere...
        // half fill boundary cells?
@@ -615,7 +614,7 @@ errMsg("MMS","minSize"<<minSize);
     }
        // */
 
-       /*for(int ii=0; ii<(int)pow(2.0,mMaxRefine)-1; ii++) {
+       /*for(int ii=0; ii<(int)po w_change?(2.0,mMaxRefine)-1; ii++) {
                errMsg("BNDTESTSYMM","set "<<mLevel[mMaxRefine].lSizex-2-ii );
                for(int k=0;k<mLevel[mMaxRefine].lSizez;k++)
                        for(int j=0;j<mLevel[mMaxRefine].lSizey;j++) {
@@ -656,7 +655,7 @@ errMsg("MMS","minSize"<<minSize);
        mInitialMass = 0.0; // reset, and use actual value after first step
 
        //mStartSymm = false;
-#if ELBEEM_BLENDER!=1
+#if ELBEEM_PLUGIN!=1
        if((D::cDimension==2)&&(D::mSizex<200)) {
                if(!checkSymmetry("init")) {
                        errMsg("LbmFsgrSolver::initialize","Unsymmetric init...");
@@ -664,7 +663,7 @@ errMsg("MMS","minSize"<<minSize);
                        errMsg("LbmFsgrSolver::initialize","Symmetric init!");
                }
        }
-#endif // ELBEEM_BLENDER!=1
+#endif // ELBEEM_PLUGIN!=1
        
 
        // ----------------------------------------------------------------------
@@ -672,11 +671,9 @@ errMsg("MMS","minSize"<<minSize);
        myTime_t fsgrtstart = getTime(); 
        for(int lev=mMaxRefine-1; lev>=0; lev--) {
                debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Coarsening level "<<lev<<".",8);
-               performRefinement(lev);
-               performCoarsening(lev);
+               adaptGrid(lev);
                coarseRestrictFromFine(lev);
-               performRefinement(lev);
-               performCoarsening(lev);
+               adaptGrid(lev);
                coarseRestrictFromFine(lev);
        }
        D::markedClearList();
@@ -693,34 +690,6 @@ errMsg("MMS","minSize"<<minSize);
                if(D::dfVecZ[l]!=0) area *= 0.5;
                mFsgrCellArea[l] = area;
        } // l
-       /*for(int lev=0; lev<mMaxRefine; lev++) {
-       FSGR_FORIJK_BOUNDS(lev) {
-               if( RFLAG(lev, i,j,k,mLevel[lev].setCurr) & CFFluid) {
-                       if( RFLAG(lev+1, i*2,j*2,k*2,mLevel[lev+1].setCurr) & CFGrFromCoarse) {
-                               LbmFloat totArea = mFsgrCellArea[0]; // for l=0
-                               for(int l=1; l<D::cDirNum; l++) { 
-                                       int ni=(2*i)+D::dfVecX[l], nj=(2*j)+D::dfVecY[l], nk=(2*k)+D::dfVecZ[l];
-                                       if(RFLAG(lev+1, ni,nj,nk, mLevel[lev+1].setCurr)&
-                                                       (CFGrFromCoarse|CFUnused|CFEmpty) //? (CFBnd|CFEmpty|CFGrFromCoarse|CFUnused)
-                                                       //(CFUnused|CFEmpty) //? (CFBnd|CFEmpty|CFGrFromCoarse|CFUnused)
-                                                       ) { 
-                                               //LbmFloat area = 0.25; if(D::dfVecX[l]!=0) area *= 0.5; if(D::dfVecY[l]!=0) area *= 0.5; if(D::dfVecZ[l]!=0) area *= 0.5;
-                                               totArea += mFsgrCellArea[l];
-                                       }
-                               } // l
-                               QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) = totArea;
-                       } else if( RFLAG(lev+1, i*2,j*2,k*2,mLevel[lev+1].setCurr) & CFEmpty) {
-                               QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) = 1.0;
-                       } else {
-                               QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) = 0.0;
-                       }
-                       errMsg("DFINI"," at l"<<lev<<" "<<PRINT_IJK<<" v:"<<QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) );
-               }
-       } } // */
-
-       // now really done...
-  debugOut("LbmFsgrSolver::initialize : Init done ...",10);
-       D::mInitDone = 1;
 
        // make sure both sets are ok
        // copy from other to curr
@@ -732,13 +701,12 @@ errMsg("MMS","minSize"<<minSize);
 
        
        if(D::cDimension==2) {
-               if(mOutputSurfacePreview) {
+               if(D::mOutputSurfacePreview) {
                        errMsg("LbmFsgrSolver::init","No preview in 2D allowed!");
-                       mOutputSurfacePreview = 0; }
+                       D::mOutputSurfacePreview = 0; }
        }
-       if(mOutputSurfacePreview) {
+       if(D::mOutputSurfacePreview) {
 
-               //int previewSize = mOutputSurfacePreview;
                // same as normal one, but use reduced size
                mpPreviewSurface = new IsoSurface( D::mIsoValue, false );
                mpPreviewSurface->setMaterialName( mpPreviewSurface->getMaterialName() );
@@ -749,17 +717,20 @@ errMsg("MMS","minSize"<<minSize);
                mpPreviewSurface->setStart( vec2G(isostart) );
                mpPreviewSurface->setEnd(   vec2G(isoend) );
                LbmVec pisodist = isoend-isostart;
-               mpPreviewSurface->initializeIsosurface( (int)(mPreviewFactor*D::mSizex)+2, (int)(mPreviewFactor*D::mSizey)+2, (int)(mPreviewFactor*D::mSizez)+2, vec2G(pisodist) );
+               LbmFloat pfac = D::mPreviewFactor;
+               mpPreviewSurface->initializeIsosurface( (int)(pfac*D::mSizex)+2, (int)(pfac*D::mSizey)+2, (int)(pfac*D::mSizez)+2, vec2G(pisodist) );
                //mpPreviewSurface->setName( D::getName() + "preview" );
                mpPreviewSurface->setName( "preview" );
        
-               debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Preview with sizes "<<(mPreviewFactor*D::mSizex)<<","<<(mPreviewFactor*D::mSizey)<<","<<(mPreviewFactor*D::mSizez)<<" enabled",10);
+               debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Preview with sizes "<<(pfac*D::mSizex)<<","<<(pfac*D::mSizey)<<","<<(pfac*D::mSizez)<<" enabled",10);
        }
 
-#if ELBEEM_BLENDER==1
+#if ELBEEM_PLUGIN!=1
+       initTestdata();
+#endif // ELBEEM_PLUGIN!=1
+
        // make sure fill fracs are right for first surface generation
        stepMain();
-#endif // ELBEEM_BLENDER==1
 
        // prepare once...
        prepareVisualization();
@@ -769,16 +740,10 @@ errMsg("MMS","minSize"<<minSize);
                RFLAG(lev, i,j,k,mLevel[lev].setOther) = RFLAG(lev, i,j,k,mLevel[lev].setCurr);
        } } // first copy flags */
 
-       /*{ int lev=mMaxRefine;
-               FSGR_FORIJK_BOUNDS(lev) { // COMPRT deb out
-               debMsgDirect("\n x="<<PRINT_IJK);
-               for(int l=0; l<D::cDfNum; l++) {
-                       debMsgDirect(" df="<< QCELL(lev, i,j,k,mLevel[lev].setCurr, l) );
-               }
-               debMsgDirect(" m="<< QCELL(lev, i,j,k,mLevel[lev].setCurr, dMass) );
-               debMsgDirect(" f="<< QCELL(lev, i,j,k,mLevel[lev].setCurr, dFfrac) );
-               debMsgDirect(" x="<< QCELL(lev, i,j,k,mLevel[lev].setCurr, dFlux) );
-       } } // COMPRT ON */
+
+       // now really done...
+  debugOut("LbmFsgrSolver::initialize : Init done ...",10);
+       D::mInitDone = 1;
        return true;
 }
 
@@ -787,6 +752,7 @@ errMsg("MMS","minSize"<<minSize);
 /*****************************************************************************/
 /*! perform geometry init (if switched on) */
 /*****************************************************************************/
+extern int globGeoInitDebug; //solver_interface
 template<class D>
 bool 
 LbmFsgrSolver<D>::initGeometryFlags() {
@@ -802,8 +768,12 @@ LbmFsgrSolver<D>::initGeometryFlags() {
        dvec = nodesize;
        debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"Performing geometry init ("<< D::mGeoInitId <<") v"<<dvec,3);
 
-       /* set interface cells */
+       /* init object velocities, this has always to be called for init */
        D::initGeoTree(D::mGeoInitId);
+       if(D::mAllfluid) { 
+               D::freeGeoTree();
+               return true; }
+
        ntlVec3Gfx maxIniVel = vec2G( D::mpParam->calculateLattVelocityFromRw( vec2P(D::getGeoMaxInitialVelocity()) ));
        D::mpParam->setSimulationMaxSpeed( norm(maxIniVel) + norm(mLevel[level].gravity) );
        LbmFloat allowMax = D::mpParam->getTadapMaxSpeed();  // maximum allowed velocity
@@ -819,7 +789,9 @@ LbmFsgrSolver<D>::initGeometryFlags() {
                debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"New maximum Velocity from geo init="<< maxIniVel,5);
        }
        recalculateObjectSpeeds();
+       // */
 
+       /* set interface cells */
        ntlVec3Gfx pos,iniPos; // position of current cell
        LbmFloat rhomass = 0.0;
        int savedNodes = 0;
@@ -846,6 +818,7 @@ LbmFsgrSolver<D>::initGeometryFlags() {
                for(int j=1;j<mLevel[level].lSizey-1;j++) {
                        for(int i=1;i<mLevel[level].lSizex-1;i++) {
                                CellFlagType ntype = CFInvalid;
+                               
                                if(D::geoInitCheckPointInside( GETPOS(i,j,k) , FGI_ALLBOUNDS, OId, distance)) {
                                //if(D::geoInitCheckPointInside( GETPOS(i,j,k) , ntlVec3Gfx(1.0,0.0,0.0), FGI_ALLBOUNDS, OId, distance, dvec[0]*0.5, thinHit, true)) {
                                        pObj = (*D::mpGiObjects)[OId];
@@ -889,7 +862,7 @@ LbmFsgrSolver<D>::initGeometryFlags() {
                                                }
                                        }
                                } 
-                               // *
+                               // */
 
                        } 
                } 
@@ -1012,7 +985,24 @@ LbmFsgrSolver<D>::initGeometryFlags() {
 
                                CellFlagType ntype = CFInvalid;
                                int inits = 0;
-                               if(D::geoInitCheckPointInside( GETPOS(i,j,k) , FGI_FLUID, OId, distance)) {
+                               // DEBUG
+                               if((j==mLevel[level].lSizey/2)&&(k==getForZMax1(level)*7/10)) globGeoInitDebug=1;
+                               else globGeoInitDebug=0;
+                               //errMsg("AAA","j"<<j<<"|"<<(mLevel[level].lSizey/2)<<" k"<<k<<"|"<<(getForZMax1(level)*7/10)<<" gd"<<globGeoInitDebug);
+                               
+                               if((i==1) && (j==31) && (k==48)) globGeoInitDebug=1;
+                               else globGeoInitDebug=0;
+                               bool inside = D::geoInitCheckPointInside( GETPOS(i,j,k) , FGI_FLUID, OId, distance);
+                               /*if((i==1) && (j==31) && (inside)) {
+                                       globGeoInitDebug=1;
+                                       D::geoInitCheckPointInside( GETPOS(i,j,k) , FGI_FLUID, OId, distance);
+                                       globGeoInitDebug=0;
+                                       errMsg("III"," i1 at "<<PRINT_IJK);
+                               } // DEBUG */
+                               if(inside) {
+                               // DEBUG
+
+                               //if(D::geoInitCheckPointInside( GETPOS(i,j,k) , FGI_FLUID, OId, distance)) {
                                        ntype = CFFluid;
                                }
                                if(ntype != CFInvalid) {
@@ -1042,9 +1032,6 @@ LbmFsgrSolver<D>::initGeometryFlags() {
                } 
        } // zmax
 
-#if ELBEEM_BLENDER!=1
-       if(mUseTestdata) initTestdata();
-#endif // ELBEEM_BLENDER!=1
        D::freeGeoTree();
        myTime_t geotimeend = getTime(); 
        debMsgStd("LbmFsgrSolver::initGeometryFlags",DM_MSG,"Geometry init done ("<< ((geotimeend-geotimestart)/(double)1000.0)<<"s,"<<savedNodes<<") " , 10 ); 
@@ -1062,21 +1049,6 @@ LbmFsgrSolver<D>::initFreeSurfaces() {
        // set interface cells 
        FSGR_FORIJK1(mMaxRefine) {
 
-               /*if( TESTFLAG( RFLAG(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr), CFEmpty )) {
-                       int initInter = 0;
-                       // check for neighboring fluid cells 
-                       FORDF1 {
-                               if( TESTFLAG( RFLAG_NBINV(mMaxRefine, i, j, k,  mLevel[mMaxRefine].setCurr,l), CFFluid ) ) {
-                                       initInter = 1;
-                               }
-                       }
-
-                       if(initInter) {
-                               initEmptyCell(mMaxRefine, i,j,k, CFInter, 1.0, interfaceFill);
-                       }
-
-               } // empty cells  OLD */
-
                if( TESTFLAG( RFLAG(mMaxRefine, i,j,k, mLevel[mMaxRefine].setCurr), CFFluid )) {
                        int initInter = 0; // check for neighboring empty cells 
                        FORDF1 {
@@ -1085,9 +1057,7 @@ LbmFsgrSolver<D>::initFreeSurfaces() {
                                }
                        }
                        if(initInter) {
-                               QCELL(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr, dMass) = 
-                                       //QCELL(mMaxRefine,i,j,k,mLevel[mMaxRefine].setOther, dMass) =  // COMPRT OFF
-                                       interfaceFill;
+                               QCELL(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr, dMass) = interfaceFill;
                                RFLAG(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr) = RFLAG(mMaxRefine,i,j,k,mLevel[mMaxRefine].setOther) = CFInter;
                        }
                }
@@ -1190,7 +1160,7 @@ LbmFsgrSolver<D>::initStandingFluidGradient() {
                                if( ( (RFLAG(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr) & (CFInter)) ) || \
                                                ( (RFLAG(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr) & (CFEmpty)) ) ){  \
                                        if((iindex)>1) { haveStandingFluid=(iindex); } \
-                                       j = mLevel[mMaxRefine].lSizey; i=mLevel[mMaxRefine].lSizex; k=D::getForZMaxBnd(); \
+                                       j = mLevel[mMaxRefine].lSizey; i=mLevel[mMaxRefine].lSizex; k=getForZMaxBnd(); \
                                        continue; \
                                } 
        int gravIndex[3] = {0,0,0};
@@ -1232,15 +1202,11 @@ LbmFsgrSolver<D>::initStandingFluidGradient() {
 
        GRAVLOOP {
                int i = gravIndex[0], j = gravIndex[1], k = gravIndex[2];
-               //if((gravIndex[gravComp1]==gravIMin[gravComp1]) && (gravIndex[gravComp2]==gravIMin[gravComp2])) {debMsgStd("Standing fluid preinit", DM_MSG, "fluidheightinit check "<<PRINT_IJK<<" "<< haveStandingFluid, 1 ); }
-               //STANDFLAGCHECK(gravIndex[maxGravComp]);
                if( ( (RFLAG(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr) & (CFInter)) ) || 
                                ( (RFLAG(mMaxRefine,i,j,k,mLevel[mMaxRefine].setCurr) & (CFEmpty)) ) ){  
                        int fluidHeight = (ABS(gravIndex[maxGravComp] - gravIMin[maxGravComp]));
                        if(debugStandingPreinit) errMsg("Standing fp","fh="<<fluidHeight<<" gmax="<<gravIMax[maxGravComp]<<" gi="<<gravIndex[maxGravComp] );
-                       //if(gravIndex[maxGravComp]>1)  
-                       if(fluidHeight>1) 
-                       {
+                       if(fluidHeight>1) {
                                haveStandingFluid = fluidHeight; //gravIndex[maxGravComp]; 
                                gravIMax[maxGravComp] = gravIndex[maxGravComp] + gravDir[maxGravComp];
                        }
@@ -1250,9 +1216,10 @@ LbmFsgrSolver<D>::initStandingFluidGradient() {
        // _PRINTGDIRS;
 
        LbmFloat fluidHeight;
-       //if(gravDir>0) { fluidHeight = (LbmFloat)haveStandingFluid;
-       //} else { fluidHeight = (LbmFloat)haveStandingFluid; }
        fluidHeight = (LbmFloat)(ABS(gravIMax[maxGravComp]-gravIMin[maxGravComp]));
+#if ELBEEM_PLUGIN!=1
+       mpTest->mFluidHeight = (int)fluidHeight;
+#endif // ELBEEM_PLUGIN!=1
        if(debugStandingPreinit) debMsgStd("Standing fluid preinit", DM_MSG, "fheight="<<fluidHeight<<" min="<<PRINT_VEC(gravIMin[0],gravIMin[1],       gravIMin[2])<<" max="<<PRINT_VEC(gravIMax[0], gravIMax[1],gravIMax[2])<<
                        " mgc="<<maxGravComp<<" mc1="<<gravComp1<<" mc2="<<gravComp2<<" dir="<<gravDir[maxGravComp]<<" have="<<haveStandingFluid ,10);
                                
@@ -1265,7 +1232,7 @@ LbmFsgrSolver<D>::initStandingFluidGradient() {
        // also important for corasening later on
        const int lev = mMaxRefine;
        CellFlagType nbflag[LBM_DFNUM], nbored; 
-       for(int k=D::getForZMinBnd();k<D::getForZMaxBnd();++k) {
+       for(int k=getForZMinBnd();k<getForZMaxBnd(mMaxRefine);++k) {
                for(int j=0;j<mLevel[lev].lSizey-0;++j) {
                        for(int i=0;i<mLevel[lev].lSizex-0;++i) {
                                if( (RFLAG(lev, i,j,k,SRCS(lev)) & (CFFluid)) ) {
@@ -1286,8 +1253,9 @@ LbmFsgrSolver<D>::initStandingFluidGradient() {
        if(haveStandingFluid) {
                int rhoworkSet = mLevel[lev].setCurr;
                myTime_t timestart = getTime(); // FIXME use user time here?
+               LbmFloat lcsmqo;
 #if OPT3D==1 
-               LbmFloat lcsmqadd, lcsmqo, lcsmeq[LBM_DFNUM], lcsmomega;
+               LbmFloat lcsmqadd, lcsmeq[LBM_DFNUM], lcsmomega;
 #endif // OPT3D==true 
 
                GRAVLOOP {
@@ -1315,7 +1283,8 @@ LbmFsgrSolver<D>::initStandingFluidGradient() {
                        }
 
                } // GRAVLOOP
-               debMsgStd("Standing fluid preinit", DM_MSG, "Density gradient inited", 8);
+               debMsgStd("Standing fluid preinit", DM_MSG, "Density gradient inited (max-rho:"<<
+                       (1.0+ (fluidHeight) * (mLevel[lev].gravity[maxGravComp])* (-3.0/1.0)*(mLevel[lev].omega)) <<", h:"<< fluidHeight<<") ", 8);
                
                int preinitSteps = (haveStandingFluid* ((mLevel[lev].lSizey+mLevel[lev].lSizez+mLevel[lev].lSizex)/3) );
                preinitSteps = (haveStandingFluid>>2); // not much use...?
@@ -1335,7 +1304,7 @@ LbmFsgrSolver<D>::initStandingFluidGradient() {
                // grav loop not necessary here
 #define NBFLAG(l) (nbflag[(l)])
                LbmFloat rho, ux,uy,uz, usqr; 
-               int kstart=D::getForZMinBnd(), kend=D::getForZMaxBnd();
+               int kstart=getForZMinBnd(), kend=getForZMaxBnd(mMaxRefine);
 #if COMPRESSGRIDS==0
                for(int k=kstart;k<kend;++k) {
 #else // COMPRESSGRIDS==0
@@ -1474,7 +1443,7 @@ LbmFsgrSolver<D>::checkSymmetry(string idstring)
  * instantiation
  *****************************************************************************/
 
-#ifndef __APPLE_CC__
+#if ((!defined(__APPLE_CC__)) && (!defined(__INTEL_COMPILER))) && (!defined(LBM_FORCEINCLUDE))
 
 #if LBMDIM==2
 #define LBM_INSTANTIATE LbmBGK2D
@@ -1485,13 +1454,6 @@ LbmFsgrSolver<D>::checkSymmetry(string idstring)
 
 template class LbmFsgrSolver< LBM_INSTANTIATE >;
 
-#endif // __APPLE_CC__
-
-// the intel compiler is too smart - so the virtual functions called from other cpp
-// files have to be instantiated explcitly (otherwise this will cause undefined
-// references to "non virtual thunks") ... still not working, though
-//template<class LBM_INSTANTIATE> LbmFsgrSolver<LBM_INSTANTIATE>::~LbmFsgrSolver();
-//template<class LBM_INSTANTIATE> void LbmFsgrSolver<LBM_INSTANTIATE>::parseAttrList();
-//template<class LBM_INSTANTIATE> bool LbmFsgrSolver<LBM_INSTANTIATE>::initialize( ntlTree* /*tree*/, vector<ntlGeometryObject*>* /*objects*/ );
+#endif // __APPLE_CC__ __INTEL_COMPILER
 
 
index 58f9abb05ed7cfccf41d9163713ce7d275914b8e..1de27d4beec2099740420b3070f39cde551262c0 100644 (file)
@@ -14,6 +14,7 @@
 #include "solver_interface.h" 
 #include "ntl_scene.h"
 #include "ntl_ray.h"
+#include "elbeem.h"
 
 
 /*****************************************************************************/
 LbmSolverInterface::LbmSolverInterface() :
        mPanic( false ),
   mSizex(10), mSizey(10), mSizez(10), 
-  mStepCnt( 0 ),
+  mAllfluid(false), mStepCnt( 0 ),
        mFixMass( 0.0 ),
   mOmega( 1.0 ),
   mGravity(0.0),
@@ -308,17 +309,19 @@ LbmSolverInterface::LbmSolverInterface() :
   mInitDensityGradient( false ),
        mpAttrs( NULL ), mpParam( NULL ),
        mNumParticlesLost(0), mNumInvalidDfs(0), mNumFilledCells(0), mNumEmptiedCells(0), mNumUsedCells(0), mMLSUPS(0),
-       mDebugVelScale( 1.0 ), mNodeInfoString("+"),
+       mDebugVelScale( 0.01 ), mNodeInfoString("+"),
        mRandom( 5123 ),
        mvGeoStart(-1.0), mvGeoEnd(1.0),
-       mPerformGeoInit( false ),
        mAccurateGeoinit(0),
        mName("lbm_default") ,
-       mpIso( NULL ), mIsoValue(0.49999),
+       mpIso( NULL ), mIsoValue(0.499),
        mSilent(false) , 
-       mGeoInitId( 0 ),
+       mGeoInitId( 1 ),
        mpGiTree( NULL ),
        mpGiObjects( NULL ), mGiObjInside(), mpGlob( NULL ),
+       mRefinementDesired(0),
+       mOutputSurfacePreview(0), mPreviewFactor(0.25),
+       mSmoothSurface(0.0), mSmoothNormals(0.0),
        mMarkedCells(), mMarkedCellIndex(0)
 {
 #if ELBEEM_BLENDER==1
@@ -327,6 +330,110 @@ LbmSolverInterface::LbmSolverInterface() :
 }
 
 
+
+/******************************************************************************
+ * initialize correct grid sizes given a geometric bounding box
+ * and desired grid resolutions, all params except maxrefine
+ * will be modified
+ *****************************************************************************/
+void initGridSizes(int &sizex, int &sizey, int &sizez,
+               ntlVec3Gfx &geoStart, ntlVec3Gfx &geoEnd, 
+               int mMaxRefine, bool parallel) 
+{
+       // fix size inits to force cubic cells and mult4 level dimensions
+       const int debugGridsizeInit = 1;
+  if(debugGridsizeInit) debMsgStd("initGridSizes",DM_MSG,"Called - size X:"<<sizex<<" Y:"<<sizey<<" Z:"<<sizez<<" " ,10);
+
+       int maxGridSize = sizex; // get max size
+       if(sizey>maxGridSize) maxGridSize = sizey;
+       if(sizez>maxGridSize) maxGridSize = sizez;
+       LbmFloat maxGeoSize = (geoEnd[0]-geoStart[0]); // get max size
+       if((geoEnd[1]-geoStart[1])>maxGeoSize) maxGeoSize = (geoEnd[1]-geoStart[1]);
+       if((geoEnd[2]-geoStart[2])>maxGeoSize) maxGeoSize = (geoEnd[2]-geoStart[2]);
+       // FIXME better divide max geo size by corresponding resolution rather than max? no prob for rx==ry==rz though
+       LbmFloat cellSize = (maxGeoSize / (LbmFloat)maxGridSize);
+  if(debugGridsizeInit) debMsgStd("initGridSizes",DM_MSG,"Start:"<<geoStart<<" End:"<<geoEnd<<" maxS:"<<maxGeoSize<<" maxG:"<<maxGridSize<<" cs:"<<cellSize, 10);
+       // force grid sizes according to geom. size, rounded
+       sizex = (int) ((geoEnd[0]-geoStart[0]) / cellSize +0.5);
+       sizey = (int) ((geoEnd[1]-geoStart[1]) / cellSize +0.5);
+       sizez = (int) ((geoEnd[2]-geoStart[2]) / cellSize +0.5);
+       // match refinement sizes, round downwards to multiple of 4
+       int sizeMask = 0;
+       int maskBits = mMaxRefine;
+       if(parallel==1) maskBits+=2;
+       for(int i=0; i<maskBits; i++) { sizeMask |= (1<<i); }
+
+       // at least size 4 on coarsest level
+       int minSize = 2<<(maskBits+2);
+       if(sizex<minSize) sizex = minSize;
+       if(sizey<minSize) sizey = minSize;
+       if(sizez<minSize) sizez = minSize;
+       
+       sizeMask = ~sizeMask;
+  if(debugGridsizeInit) debMsgStd("initGridSizes",DM_MSG,"Size X:"<<sizex<<" Y:"<<sizey<<" Z:"<<sizez<<" m"<<convertFlags2String(sizeMask) ,10);
+       sizex &= sizeMask;
+       sizey &= sizeMask;
+       sizez &= sizeMask;
+
+       // force geom size to match rounded/modified grid sizes
+       geoEnd[0] = geoStart[0] + cellSize*(LbmFloat)sizex;
+       geoEnd[1] = geoStart[1] + cellSize*(LbmFloat)sizey;
+       geoEnd[2] = geoStart[2] + cellSize*(LbmFloat)sizez;
+}
+
+void calculateMemreqEstimate( int resx,int resy,int resz, int refine,
+               double *reqret, string *reqstr) {
+       // make sure we can handle bid numbers here... all double
+       double memCnt = 0.0;
+       double ddTotalNum = (double)dTotalNum;
+
+       double currResx = (double)resx;
+       double currResy = (double)resy;
+       double currResz = (double)resz;
+       double rcellSize = ((currResx*currResy*currResz) *ddTotalNum);
+       memCnt += (double)(sizeof(CellFlagType) * (rcellSize/ddTotalNum +4.0) *2.0);
+#if COMPRESSGRIDS==0
+       memCnt += (double)(sizeof(LbmFloat) * (rcellSize +4.0) *2.0);
+#else // COMPRESSGRIDS==0
+       double compressOffset = (double)(currResx*currResy*ddTotalNum*2.0);
+       memCnt += (double)(sizeof(LbmFloat) * (rcellSize+compressOffset +4.0));
+#endif // COMPRESSGRIDS==0
+       for(int i=refine-1; i>=0; i--) {
+               currResx /= 2.0;
+               currResy /= 2.0;
+               currResz /= 2.0;
+               rcellSize = ((currResz*currResy*currResx) *ddTotalNum);
+               memCnt += (double)(sizeof(CellFlagType) * (rcellSize/ddTotalNum +4.0) *2.0);
+               memCnt += (double)(sizeof(LbmFloat) * (rcellSize +4.0) *2.0);
+       }
+
+       // isosurface memory
+       memCnt += (double)( (3*sizeof(int)+sizeof(float)) * ((resx+2)*(resy+2)*(resz+2)) );
+
+       double memd = memCnt;
+       char *sizeStr = "";
+       const double sfac = 1000.0;
+       if(memd>sfac){ memd /= sfac; sizeStr="KB"; }
+       if(memd>sfac){ memd /= sfac; sizeStr="MB"; }
+       if(memd>sfac){ memd /= sfac; sizeStr="GB"; }
+       if(memd>sfac){ memd /= sfac; sizeStr="TB"; }
+
+       // return values
+       std::ostringstream ret;
+       if(memCnt< 1024.0*1024.0) {
+               // show full MBs
+               ret << (ceil(memd));
+       } else {
+               // two digits for anything larger than MB
+               ret << (ceil(memd*100.0)/100.0);
+       }
+       ret     << " "<< sizeStr;
+       *reqret = memCnt;
+       *reqstr = ret.str();
+       //debMsgStd("LbmFsgrSolver::initialize",DM_MSG,"Required Grid memory: "<< memd <<" "<< sizeStr<<" ",4);
+}
+
+
 /*******************************************************************************/
 /*! parse a boundary flag string */
 CellFlagType LbmSolverInterface::readBoundaryFlagInt(string name, int defaultValue, string source,string target, bool needed) {
@@ -345,7 +452,7 @@ CellFlagType LbmSolverInterface::readBoundaryFlagInt(string name, int defaultVal
                /* might be used for some in/out flow cases */
                return (CellFlagType)( CFFluid );
        }
-       errMsg("LbmStdSolver::readBoundaryFlagInt","Invalid value '"<<val<<"' " );
+       errMsg("LbmSolverInterface::readBoundaryFlagInt","Invalid value '"<<val<<"' " );
 # if LBM_STRICT_DEBUG==1
        errFatal("readBoundaryFlagInt","Strict abort..."<<val, SIMWORLD_INITERROR);
 # endif
@@ -356,31 +463,30 @@ CellFlagType LbmSolverInterface::readBoundaryFlagInt(string name, int defaultVal
 /*! parse standard attributes */
 void LbmSolverInterface::parseStdAttrList() {
        if(!mpAttrs) {
-               errFatal("LbmStdSolver::parseAttrList","mpAttrs pointer not initialized!",SIMWORLD_INITERROR);
+               errFatal("LbmSolverInterface::parseAttrList","mpAttrs pointer not initialized!",SIMWORLD_INITERROR);
                return; }
 
        // st currently unused
-       //mSurfaceTension  = mpAttrs->readFloat("d_surfacetension",  mSurfaceTension, "LbmStdSolver", "mSurfaceTension", false);
-       mBoundaryEast  = readBoundaryFlagInt("boundary_east",  mBoundaryEast, "LbmStdSolver", "mBoundaryEast", false);
-       mBoundaryWest  = readBoundaryFlagInt("boundary_west",  mBoundaryWest, "LbmStdSolver", "mBoundaryWest", false);
-       mBoundaryNorth = readBoundaryFlagInt("boundary_north", mBoundaryNorth,"LbmStdSolver", "mBoundaryNorth", false);
-       mBoundarySouth = readBoundaryFlagInt("boundary_south", mBoundarySouth,"LbmStdSolver", "mBoundarySouth", false);
-       mBoundaryTop   = readBoundaryFlagInt("boundary_top",   mBoundaryTop,"LbmStdSolver", "mBoundaryTop", false);
-       mBoundaryBottom= readBoundaryFlagInt("boundary_bottom", mBoundaryBottom,"LbmStdSolver", "mBoundaryBottom", false);
+       //mSurfaceTension  = mpAttrs->readFloat("d_surfacetension",  mSurfaceTension, "LbmSolverInterface", "mSurfaceTension", false);
+       mBoundaryEast  = readBoundaryFlagInt("boundary_east",  mBoundaryEast, "LbmSolverInterface", "mBoundaryEast", false);
+       mBoundaryWest  = readBoundaryFlagInt("boundary_west",  mBoundaryWest, "LbmSolverInterface", "mBoundaryWest", false);
+       mBoundaryNorth = readBoundaryFlagInt("boundary_north", mBoundaryNorth,"LbmSolverInterface", "mBoundaryNorth", false);
+       mBoundarySouth = readBoundaryFlagInt("boundary_south", mBoundarySouth,"LbmSolverInterface", "mBoundarySouth", false);
+       mBoundaryTop   = readBoundaryFlagInt("boundary_top",   mBoundaryTop,"LbmSolverInterface", "mBoundaryTop", false);
+       mBoundaryBottom= readBoundaryFlagInt("boundary_bottom", mBoundaryBottom,"LbmSolverInterface", "mBoundaryBottom", false);
 
        LbmVec sizeVec(mSizex,mSizey,mSizez);
-       sizeVec = vec2L( mpAttrs->readVec3d("size",  vec2P(sizeVec), "LbmStdSolver", "sizeVec", false) );
+       sizeVec = vec2L( mpAttrs->readVec3d("size",  vec2P(sizeVec), "LbmSolverInterface", "sizeVec", false) );
        mSizex = (int)sizeVec[0]; 
        mSizey = (int)sizeVec[1]; 
        mSizez = (int)sizeVec[2];
        mpParam->setSize(mSizex, mSizey, mSizez ); // param needs size in any case
 
-       mInitDensityGradient = mpAttrs->readBool("initdensitygradient", mInitDensityGradient,"LbmStdSolver", "mInitDensityGradient", false);
-       mPerformGeoInit = mpAttrs->readBool("geoinit", mPerformGeoInit,"LbmStdSolver", "mPerformGeoInit", false);
-       mGeoInitId = mpAttrs->readInt("geoinitid", mGeoInitId,"LbmStdSolver", "mGeoInitId", false);
+       mInitDensityGradient = mpAttrs->readBool("initdensitygradient", mInitDensityGradient,"LbmSolverInterface", "mInitDensityGradient", false);
+       mGeoInitId = mpAttrs->readInt("geoinitid", mGeoInitId,"LbmSolverInterface", "mGeoInitId", false);
        mIsoValue = mpAttrs->readFloat("isovalue", mIsoValue, "LbmOptSolver","mIsoValue", false );
 
-       mDebugVelScale = mpAttrs->readFloat("debugvelscale", mDebugVelScale,"LbmStdSolver", "mDebugVelScale", false);
+       mDebugVelScale = mpAttrs->readFloat("debugvelscale", mDebugVelScale,"LbmSolverInterface", "mDebugVelScale", false);
        mNodeInfoString = mpAttrs->readString("nodeinfo", mNodeInfoString, "SimulationLbm","mNodeInfoString", false );
 }
 
@@ -421,6 +527,7 @@ void LbmSolverInterface::freeGeoTree() {
 }
 
 
+int globGeoInitDebug = 0;
 /*****************************************************************************/
 /*! check for a certain flag type at position org */
 bool LbmSolverInterface::geoInitCheckPointInside(ntlVec3Gfx org, int flags, int &OId, gfxReal &distance) {
@@ -432,14 +539,18 @@ bool LbmSolverInterface::geoInitCheckPointInside(ntlVec3Gfx org, int flags, int
        //int insCnt = 0;
        bool done = false;
        bool inside = false;
+       vector<int> giObjFirstHistSide;
+       giObjFirstHistSide.resize( mpGiObjects->size() );
        for(size_t i=0; i<mGiObjInside.size(); i++) { 
                mGiObjInside[i] = 0; 
                mGiObjDistance[i] = -1.0; 
                mGiObjSecondDist[i] = -1.0; 
+               giObjFirstHistSide[i] = 0; 
        }
        // if not inside, return distance to first hit
        gfxReal firstHit=-1.0;
        int     firstOId = -1;
+       if(globGeoInitDebug) errMsg("IIIstart"," isect "<<org<<" f"<<flags<<" acc"<<mAccurateGeoinit);
        
        if(mAccurateGeoinit) {
                while(!done) {
@@ -456,13 +567,14 @@ bool LbmSolverInterface::geoInitCheckPointInside(ntlVec3Gfx org, int flags, int
                                        // outside hit
                                        normal *= -1.0;
                                        mGiObjInside[OId]++;
-                                       //mGiObjDistance[OId] = -1.0;
-                                       //errMsg("IIO"," oid:"<<OId<<" org"<<org<<" norg"<<norg);
+                                       if(giObjFirstHistSide[OId]==0) giObjFirstHistSide[OId] = 1;
+                                       if(globGeoInitDebug) errMsg("IIO"," oid:"<<OId<<" org"<<org<<" norg"<<norg<<" orient:"<<orientation);
                                } else {
                                        // inside hit
                                        mGiObjInside[OId]++;
                                        if(mGiObjDistance[OId]<0.0) mGiObjDistance[OId] = distance;
-                                       //errMsg("III"," oid:"<<OId<<" org"<<org<<" norg"<<norg);
+                                       if(globGeoInitDebug) errMsg("III"," oid:"<<OId<<" org"<<org<<" norg"<<norg<<" orient:"<<orientation);
+                                       if(giObjFirstHistSide[OId]==0) giObjFirstHistSide[OId] = -1;
                                }
                                norg += normal * getVecEpsilon();
                                ray = ntlRay(norg, dir, 0, 1.0, mpGlob);
@@ -475,13 +587,26 @@ bool LbmSolverInterface::geoInitCheckPointInside(ntlVec3Gfx org, int flags, int
                        } else {
                                // no more intersections... return false
                                done = true;
-                               //if(insCnt%2) inside=true;
                        }
                }
 
                distance = -1.0;
                for(size_t i=0; i<mGiObjInside.size(); i++) {
-                       //errMsg("CHIII","i"<<i<<" ins="<<mGiObjInside[i]<<" t"<<mGiObjDistance[i]<<" d"<<distance);
+                       if(mGiObjInside[i]>0) {
+                               bool mess = false;
+                               if((mGiObjInside[i]%2)==1) {
+                                       if(giObjFirstHistSide[i] != -1) mess=true;
+                               } else {
+                                       if(giObjFirstHistSide[i] !=  1) mess=true;
+                               }
+                               if(mess) {
+                                       errMsg("IIIproblem","At "<<org<<" obj "<<i<<" inside:"<<mGiObjInside[i]<<" firstside:"<<giObjFirstHistSide[i] );
+                                       mGiObjInside[i]++; // believe first hit side...
+                               }
+                       }
+               }
+               for(size_t i=0; i<mGiObjInside.size(); i++) {
+                       if(globGeoInitDebug) errMsg("CHIII","i"<<i<<" ins="<<mGiObjInside[i]<<" t"<<mGiObjDistance[i]<<" d"<<distance);
                        if(((mGiObjInside[i]%2)==1)&&(mGiObjDistance[i]>0.0)) {
                                if(  (distance<0.0)                             || // first intersection -> good
                                          ((distance>0.0)&&(distance>mGiObjDistance[i])) // more than one intersection -> use closest one
@@ -496,7 +621,7 @@ bool LbmSolverInterface::geoInitCheckPointInside(ntlVec3Gfx org, int flags, int
                        distance = firstHit;
                        OId = firstOId;
                }
-               //errMsg("CHIII","i"<<inside<<"  fh"<<firstHit<<" fo"<<firstOId<<" - h"<<distance<<" o"<<OId);
+               if(globGeoInitDebug) errMsg("CHIII","i"<<inside<<"  fh"<<firstHit<<" fo"<<firstOId<<" - h"<<distance<<" o"<<OId);
 
                return inside;
        } else {
@@ -655,14 +780,16 @@ bool LbmSolverInterface::geoInitCheckPointInside(ntlVec3Gfx org, ntlVec3Gfx dir,
 }
 
 /*****************************************************************************/
-/*! get max. velocity of all objects to initialize as fluid regions */
+/*! get max. velocity of all objects to initialize as fluid regions or inflow */
 ntlVec3Gfx LbmSolverInterface::getGeoMaxInitialVelocity() {
+       ntlVec3Gfx max(0.0);
+       if(mpGlob == NULL) return max;
+
        ntlScene *scene = mpGlob->getScene();
        mpGiObjects = scene->getObjects();
-       ntlVec3Gfx max(0.0);
        
        for(int i=0; i< (int)mpGiObjects->size(); i++) {
-               if( (*mpGiObjects)[i]->getGeoInitType() & FGI_FLUID ){
+               if( (*mpGiObjects)[i]->getGeoInitType() & (FGI_FLUID|FGI_MBNDINFLOW) ){
                        ntlVec3Gfx ovel = (*mpGiObjects)[i]->getInitialVelocity();
                        if( normNoSqrt(ovel) > normNoSqrt(max) ) { max = ovel; } 
                        //errMsg("IVT","i"<<i<<" "<< (*mpGiObjects)[i]->getInitialVelocity() ); // DEBUG
@@ -675,32 +802,6 @@ ntlVec3Gfx LbmSolverInterface::getGeoMaxInitialVelocity() {
 }
 
 
-/*******************************************************************************/
-/*! "traditional" initialization */
-/*******************************************************************************/
-
-
-/*****************************************************************************/
-// handle generic test cases (currently only reset geo init)
-bool LbmSolverInterface::initGenericTestCases() {
-       bool initTypeFound = false;
-       LbmSolverInterface::CellIdentifier cid = getFirstCell();
-       // deprecated! - only check for invalid cells...
-
-       // this is the default init - check if the geometry flag init didnt
-       initTypeFound = true;
-
-       while(noEndCell(cid)) {
-               // check node
-               if( (getCellFlag(cid,0)==CFInvalid) || (getCellFlag(cid,1)==CFInvalid) ) {
-                       warnMsg("LbmSolverInterface::initGenericTestCases","GeoInit produced invalid Flag at "<<cid->getAsString()<<"!" );
-               }
-               advanceCell( cid );
-       }
-
-       deleteCellIterator( &cid );
-       return initTypeFound;
-}
 
 
 /*******************************************************************************/
@@ -755,6 +856,9 @@ string convertSingleFlag2String(CellFlagType cflag) {
        if(flag == CFUnused         ) return string("cCFUnused");
        if(flag == CFEmpty          ) return string("cCFEmpty");      
        if(flag == CFBnd            ) return string("cCFBnd");        
+       if(flag == CFBndNoslip      ) return string("cCFBndNoSlip");        
+       if(flag == CFBndFreeslip    ) return string("cCFBndFreeSlip");        
+       if(flag == CFBndPartslip    ) return string("cCFBndPartSlip");        
        if(flag == CFNoInterpolSrc  ) return string("cCFNoInterpolSrc");
        if(flag == CFFluid          ) return string("cCFFluid");      
        if(flag == CFInter          ) return string("cCFInter");      
@@