Changeset - 9a40ab737a73
[Not reviewed]
default
0 14 2
Roeland Merks - 15 years ago 2010-09-08 17:31:50
merks@cwi.nl
* Added functionality for numerical output (CSV) format. See functions starting with "CSV" in mesh.cpp. External code hull.cpp is responsible for convex hull calculations.
- ToDo: adopt menu item "File->export cell areas" so user can choose a file name or set up periodic output of numerical data.
- ToDo: add parameters re: periodic numeric output to "<settings>" block of LeafML-file, so it becomes possible to set up numeric output interactively, then write the LeafML file and run the program in batch mode to retrieve periodic numeric output.

* Added new functionality to plugin interface. It becomes possible to define a default LeafML init file for a plugin. It is read whenever the model plugin is loaded.
- ToDo: define default LeafML files for all plugins, according to the LeafML files mentioned in the Plant Phys. tutorial.


user: Roeland Merks <merks@cwi.nl>
branch 'default'
added src/hull.cpp
added src/hull.h
changed src/TutorialCode/Tutorial0/tutorial0.pro
changed src/VirtualLeaf.cpp
changed src/VirtualLeaf.pro
changed src/build_models/auxingrowthplugin.cpp
changed src/build_models/auxingrowthplugin.h
changed src/canvas.cpp
changed src/canvas.h
changed src/mainbase.h
changed src/mesh.cpp
changed src/mesh.h
changed src/modelcatalogue.cpp
changed src/simplugin.cpp
changed src/simplugin.h
changed src/xmlwrite.cpp
16 files changed with 340 insertions and 20 deletions:
0 comments (0 inline, 0 general)
src/TutorialCode/Tutorial0/tutorial0.pro
Show inline comments
 
@@ -29,13 +29,13 @@ CONFIG += plugin
 

	
 
BINDIR = $${VLEAFHOME}/bin
 
LIBDIR = $${VLEAFHOME}/lib
 
INCDIR = $${VLEAFHOME}/src
 
DEFINES = QTGRAPHICS # VLEAFPLUGIN
 
DESTDIR = $${BINDIR}/models
 
HEADERS = $${TARGET}.h 
 
HEADERS = $${TARGET}.h $${INCDIR}/simplugin.h
 
INCLUDEPATH += $${INCDIR}	
 

	
 
QMAKE_CXXFLAGS += -fexceptions #-I$${INCDIR}
 
QMAKE_CXXFLAGS_DEBUG += -g3
 
QMAKE_CXXFLAGS_DEBUG += -DQDEBUG
 
QT += qt3support
src/VirtualLeaf.cpp
Show inline comments
 
@@ -223,12 +223,19 @@ INIT {
 
    xmlFree(settings);
 
    main_window->UserMessage(QString("Ready. Time is %1").arg(mesh.getTimeHours().c_str()));
 

	
 
  } else {
 
    mesh.StandardInit();
 
  }
 
  
 
  Cell::SetMagnification(1);
 
  Cell::setOffset(0,0);
 
  
 
  FitLeafToCanvas();
 
  Plot();
 

	
 
}
 

	
 
TIMESTEP {
 

	
 
  static int i=0;
 
  static int t=0;
 
@@ -409,28 +416,31 @@ int main(int argc,char **argv) {
 

	
 
    canvas.setSceneRect(QRectF());
 
    if (!batch) {
 
      QObject::connect( qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()) );
 
    }
 

	
 
    //    main_window->Init(leaffile);
 

	
 
    // Install model or read catalogue of models
 
    ModelCatalogue model_catalogue(&mesh, useGUI?(Main *)main_window:0,modelfile);
 

	
 

	
 
    if (useGUI)
 
      model_catalogue.PopulateModelMenu();
 
    model_catalogue.InstallFirstModel();
 
    
 
    
 

	
 
    if (leaffile) 
 
      main_window->Init(leaffile);
 

	
 
    Cell::SetMagnification(1);
 
    /*    Cell::SetMagnification(1);
 
    Cell::setOffset(0,0);
 

	
 
    main_window->FitLeafToCanvas();
 

	
 
    main_window->Plot();
 

	
 
    */
 
    if (batch) {
 
      double t=0.;
 
      do {
 
	t = main_window->TimeStep();
 
      } while (t < par.maxt);
 
    } else
src/VirtualLeaf.pro
Show inline comments
 
@@ -16,14 +16,14 @@
 
#  You should have received a copy of the GNU General Public License
 
#  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
#
 
#  Copyright 2010 Roeland Merks.
 
#
 

	
 
CONFIG += release
 
CONFIG -= debug
 
CONFIG -= release
 
CONFIG += debug
 
CONFIG += qt
 

	
 
QMAKE_CXXFLAGS += -fexceptions
 
QMAKE_CXXFLAGS_DEBUG += -g3
 
QMAKE_CXXFLAGS_DEBUG += -DQDEBUG
 

	
 
@@ -79,12 +79,13 @@ HEADERS += \
 
 apoplastitem.h \
 
 canvas.h \
 
 cellbase.h \
 
 cell.h \
 
 cellitem.h \
 
 forwardeuler.h \
 
       hull.h \ 
 
 infobar.h \
 
 mainbase.h \
 
 mainbase.h \
 
 matrix.h \
 
 mesh.h \
 
 miscq.h \
 
@@ -120,12 +121,13 @@ SOURCES += \
 
 apoplastitem.cpp \
 
 canvas.cpp \
 
 cellbase.cpp \
 
 cell.cpp \
 
 cellitem.cpp \
 
 forwardeuler.cpp \
 
 hull.cpp \
 
 mainbase.cpp \
 
 matrix.cpp \
 
 mesh.cpp \
 
 miscq.cpp \
 
 modelcatalogue.cpp \
 
 Neighbor.cpp \
src/build_models/auxingrowthplugin.cpp
Show inline comments
 
@@ -254,9 +254,12 @@ void AuxinGrowthPlugin::CellDynamics(Cel
 
		
 
    // source of auxin
 
    dchem[0] = par->aux_cons - par->aux_breakdown * c->Chemical(0);
 
  }
 
}
 

	
 

	
 

	
 

	
 
Q_EXPORT_PLUGIN2(auxingrowthplugin, AuxinGrowthPlugin)
 

	
 
/* finis */
src/build_models/auxingrowthplugin.h
Show inline comments
 
@@ -52,13 +52,15 @@ class AuxinGrowthPlugin : public QObject
 
  virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2);
 
	
 
  // to be executed for coloring a cell
 
  virtual void SetCellColor(CellBase *c, QColor *color);	
 
  // return number of chemicals
 
  virtual int NChem(void) { return 2; }
 
	
 

	
 
  virtual QString DefaultLeafML(void) { return QString("auxin_growth.xml"); }
 
 
 
 private:
 
  double complex_PijAj(CellBase *here, CellBase *nb, Wall *w);
 
};
 

	
 
#endif
 

	
src/canvas.cpp
Show inline comments
 
@@ -474,12 +474,13 @@ Main::Main(QGraphicsScene& c, Mesh &m, Q
 

	
 
  file->insertSeparator();
 
  file->insertItem("Read next leaf", this, SLOT(readNextStateXML()), Qt::Key_PageDown);
 
  file->insertItem("Read previous leaf", this, SLOT(readPrevStateXML()), Qt::Key_PageUp);
 
  file->insertItem("Read last leaf", this, SLOT(readLastStateXML()), Qt::Key_End);
 
  file->insertItem("Read first leaf", this, SLOT(readFirstStateXML()), Qt::Key_Home);
 
  file->insertItem("Export cell areas", this, SLOT(exportCellData()));
 

	
 
  file->insertSeparator();
 
  file->insertItem("&Print...", this, SLOT(print()), Qt::CTRL+Qt::Key_P);
 
  file->insertSeparator();
 
  file->insertItem("E&xit", qApp, SLOT(quit()), Qt::CTRL+Qt::Key_Q);
 
  menu->insertItem("&File", file);
 
@@ -1350,7 +1351,21 @@ xmlNode *Main::XMLSettingsTree(void)
 
  xmlNode *settings = MainBase::XMLSettingsTree();
 
  QTransform viewport(editor->transform());
 
  xmlAddChild(settings, XMLViewportTree(viewport));
 
  return settings;
 
}
 

	
 
void Main::exportCellData(void) {
 

	
 
  // perhaps make this more general: a popup window were user selects data he wants to export
 
  // can go to "settings" section of XML file as well so this can also be measured off-line
 
  // mesh.CSVExport would take an QMap or so to record all options
 
  // first line gives legenda
 
  QFile file("areas.csv");
 
  if ( file.open( IO_WriteOnly ) ) {
 
    QTextStream stream( &file );
 
    mesh.CSVExportCellData(stream);
 
    mesh.CSVExportMeshData(stream);
 
    file.close();
 
  }
 
}
 
/* finis */
src/canvas.h
Show inline comments
 
@@ -203,12 +203,13 @@ class Main : public Q3MainWindow, public
 
  void readStateXML();
 
  int readStateXML(const char *filename, bool geometry = true, bool pars=true, bool simtime = true);
 
  void readNextStateXML();
 
  void readPrevStateXML();
 
  void readFirstStateXML();
 
  void readLastStateXML();
 
  void exportCellData();
 
  void saveStateXML();
 
  void snapshot();
 
  void savePars();
 
  void readPars();
 
  void clear();
 
  void init();
src/hull.cpp
Show inline comments
 
new file 100644
 
// Copyright 2001, softSurfer (www.softsurfer.com)
 
// This code may be freely used and modified for any purpose
 
// providing that this copyright notice is included with it.
 
// SoftSurfer makes no warranty for this code, and cannot be held
 
// liable for any real or imagined damage resulting from its use.
 
// Users of this code must verify correctness for their application.
 

	
 
// Assume that a class is already given for the object:
 
//    Point with coordinates {float x, y;}
 
//===================================================================
 

	
 
// isLeft(): tests if a point is Left|On|Right of an infinite line.
 
//    Input:  three points P0, P1, and P2
 
//    Return: >0 for P2 left of the line through P0 and P1
 
//            =0 for P2 on the line
 
//            <0 for P2 right of the line
 
//    See: the January 2001 Algorithm on Area of Triangles
 

	
 
#include "hull.h"
 

	
 

	
 
inline float
 
isLeft( Point P0, Point P1, Point P2 )
 
{
 
    return (P1.x - P0.x)*(P2.y - P0.y) - (P2.x - P0.x)*(P1.y - P0.y);
 
}
 
//===================================================================
 
 
 

	
 
// chainHull_2D(): Andrew's monotone chain 2D convex hull algorithm
 
//     Input:  P[] = an array of 2D points
 
//                   presorted by increasing x- and y-coordinates
 
//             n = the number of points in P[]
 
//     Output: H[] = an array of the convex hull vertices (max is n)
 
//     Return: the number of points in H[]
 
int
 
chainHull_2D( Point* P, int n, Point* H )
 
{
 
    // the output array H[] will be used as the stack
 
    int    bot=0, top=(-1);  // indices for bottom and top of the stack
 
    int    i;                // array scan index
 

	
 
    // Get the indices of points with min x-coord and min|max y-coord
 
    int minmin = 0, minmax;
 
    float xmin = P[0].x;
 
    for (i=1; i<n; i++)
 
        if (P[i].x != xmin) break;
 
    minmax = i-1;
 
    if (minmax == n-1) {       // degenerate case: all x-coords == xmin
 
        H[++top] = P[minmin];
 
        if (P[minmax].y != P[minmin].y) // a nontrivial segment
 
            H[++top] = P[minmax];
 
        H[++top] = P[minmin];           // add polygon endpoint
 
        return top+1;
 
    }
 

	
 
    // Get the indices of points with max x-coord and min|max y-coord
 
    int maxmin, maxmax = n-1;
 
    float xmax = P[n-1].x;
 
    for (i=n-2; i>=0; i--)
 
        if (P[i].x != xmax) break;
 
    maxmin = i+1;
 

	
 
    // Compute the lower hull on the stack H
 
    H[++top] = P[minmin];      // push minmin point onto stack
 
    i = minmax;
 
    while (++i <= maxmin)
 
    {
 
        // the lower line joins P[minmin] with P[maxmin]
 
        if (isLeft( P[minmin], P[maxmin], P[i]) >= 0 && i < maxmin)
 
            continue;          // ignore P[i] above or on the lower line
 

	
 
        while (top > 0)        // there are at least 2 points on the stack
 
        {
 
            // test if P[i] is left of the line at the stack top
 
            if (isLeft( H[top-1], H[top], P[i]) > 0)
 
                break;         // P[i] is a new hull vertex
 
            else
 
                top--;         // pop top point off stack
 
        }
 
        H[++top] = P[i];       // push P[i] onto stack
 
    }
 

	
 
    // Next, compute the upper hull on the stack H above the bottom hull
 
    if (maxmax != maxmin)      // if distinct xmax points
 
        H[++top] = P[maxmax];  // push maxmax point onto stack
 
    bot = top;                 // the bottom point of the upper hull stack
 
    i = maxmin;
 
    while (--i >= minmax)
 
    {
 
        // the upper line joins P[maxmax] with P[minmax]
 
        if (isLeft( P[maxmax], P[minmax], P[i]) >= 0 && i > minmax)
 
            continue;          // ignore P[i] below or on the upper line
 

	
 
        while (top > bot)    // at least 2 points on the upper stack
 
        {
 
            // test if P[i] is left of the line at the stack top
 
            if (isLeft( H[top-1], H[top], P[i]) > 0)
 
                break;         // P[i] is a new hull vertex
 
            else
 
                top--;         // pop top point off stack
 
        }
 
        H[++top] = P[i];       // push P[i] onto stack
 
    }
 
    if (minmax != minmin)
 
        H[++top] = P[minmin];  // push joining endpoint onto stack
 

	
 
    return top+1;
 
}
 

	
src/hull.h
Show inline comments
 
new file 100644
 
// Class point needed by 2D convex hull code
 
class Point {
 

	
 
public:
 
  Point(float xx, float yy) {
 
    x=xx;
 
    y=yy;
 
  }
 
  Point(void) {
 
    x=0; y=0;
 
  }
 
  float x,y;
 

	
 
};
 

	
 
int chainHull_2D( Point* P, int n, Point* H );
 

	
src/mainbase.h
Show inline comments
 
@@ -60,13 +60,13 @@ class MainBase  {
 
    showtooltipsp = false;
 
    hidecellsp = false;
 
  }
 
  virtual ~MainBase() {};
 

	
 
  virtual double TimeStep();
 
  virtual void Init(char *leaffile=0);
 
  virtual void Init(const char *leaffile=0);
 

	
 
  virtual bool ShowCentersP(void) {return showcentersp;}
 
  virtual bool ShowMeshP(void) {return showmeshp; }
 
  virtual bool ShowBorderCellsP(void) {return showbordercellp; }
 
  virtual bool PausedP(void) {return false; }
 
  virtual bool ShowNodeNumbersP(void) {return shownodenumbersp; }
 
@@ -130,11 +130,11 @@ class MainBase  {
 
  bool showtooltipsp;
 
  bool hidecellsp;
 
};
 

	
 
//#include <qapplication.h>
 
#define TIMESTEP double MainBase::TimeStep(void)
 
#define INIT void MainBase::Init(char *leaffile)
 
#define INIT void MainBase::Init(const char *leaffile)
 

	
 
#endif
 

	
 
/* finis */
src/mesh.cpp
Show inline comments
 
@@ -43,12 +43,13 @@
 
#include "simplugin.h"
 

	
 
#include <QDebug>
 
#include <set>
 
#include <iostream>
 
#include <iterator>
 
#include <QTextStream>
 

	
 
static const std::string _module_id("$Id$");
 

	
 
extern Parameter par;
 

	
 
void Mesh::AddNodeToCellAtIndex(Cell *c, Node *n, Node *nb1, Node *nb2, list<Node *>::iterator ins_pos) {
 
@@ -464,13 +465,16 @@ void Mesh::Clear(void) {
 
    delete *i;
 
  }
 

	
 
  cells.clear();
 
  Cell::NCells() = 0;
 

	
 
  delete boundary_polygon;
 
  if (boundary_polygon) {
 
    delete boundary_polygon;
 
    boundary_polygon=0;
 
  }
 

	
 
  // Clear walls
 
  for (list<Wall *>::iterator i=walls.begin(); i!=walls.end(); i++) {
 
    delete *i;
 
  }
 

	
 
@@ -1992,14 +1996,16 @@ void Mesh::Clean(void) {
 
  }
 
  //Cell::static_data_members = old_static_data_mem;
 

	
 
  cells.clear();
 
  Cell::NCells()=0;
 

	
 
  delete boundary_polygon; // (already deleted during cleaning of cells?)
 

	
 
  if (boundary_polygon) {
 
    delete boundary_polygon; // (already deleted during cleaning of cells?)
 
    boundary_polygon=0;
 
  }
 
#ifdef QDEBUG
 
  qDebug() << "Freeing walls" << endl;
 
#endif
 
  for (list<Wall *>::iterator i=walls.begin(); i!=walls.end(); i++) {
 
    delete *i;
 
  }
 
@@ -2024,7 +2030,100 @@ void Mesh::StandardInit(void) {
 
  // clean up chemicals 
 
  for (int c=0; c<Cell::NChem(); c++) {
 
    circle.SetChemical(c, 0.);
 
  }
 
}
 

	
 
#include "hull.h"
 

	
 
double Mesh::Compactness(double *res_compactness, double *res_area, double *res_cell_area) {
 
  
 
  // Calculate compactness using the convex hull of the cells
 
  // We use Andrew's Monotone Chain Algorithm (see hull.cpp)
 

	
 
  // Step 1. Prepare data for 2D hull code - get boundary polygon
 
  int pc=0;
 
  Point *p=new Point[boundary_polygon->nodes.size()];
 
  for (list<Node *>::const_iterator i = boundary_polygon->nodes.begin(); 
 
       i!=boundary_polygon->nodes.end(); i++) {
 
    p[pc++]=Point((*i)->x,(*i)->y);
 
  }
 
  
 
  // Step 2: call 2D Hull code
 
  int np=boundary_polygon->nodes.size();
 
  Point *hull=new Point[np];
 
  int nph=chainHull_2D(p,np,hull);
 
  
 
  
 
  // Step 3: calculate area of convex hull
 
  double hull_area=0.;
 
  for (int i=0;i<nph-1;i++) {
 
    hull_area+=hull[i].x * hull[i+1].y - hull[i+1].x * hull[i].y;
 
  }
 
  hull_area/=2.;
 

	
 
  // Step 4: get area of bounary polygon
 
  double boundary_pol_area = boundary_polygon->CalcArea();
 
  
 

	
 
  /*  ofstream datastr("hull.dat");
 
  for (int i=0;i<nph<i++) {
 
    datastr << hull.x << " " << hull.y << endl;
 
  }
 
  ofstream polstr("pol.dat");
 
  for (int i=0;i<np;h*/
 
  delete[] p;
 
  delete[] hull;
 

	
 

	
 
  // put intermediate results into optional pointers
 
  if (res_compactness) {
 
    *res_compactness = boundary_pol_area/hull_area;
 
  }
 
  if (res_area) {
 
    *res_area = hull_area;
 
  }
 
  if (res_cell_area) {
 
    *res_cell_area = boundary_pol_area;
 
  }
 

	
 
  // return compactness
 
  return boundary_pol_area/hull_area;
 

	
 
}
 

	
 
// DataExport
 
void Mesh::CSVExportCellData(QTextStream &csv_stream) const {
 

	
 
  csv_stream << "\"Cell Index\",\"Center of mass (x)\",\"Center of mass (y)\",\"Cell area\",\"Cell length\"";
 
  
 
  for (int c=0;c<Cell::NChem(); c++) {
 
    csv_stream << ",\"Chemical " << c << "\"";
 
  }
 
  csv_stream << endl;
 
  for (vector<Cell *>::const_iterator i=cells.begin();
 
       i!=cells.end();
 
       i++) {
 
    Vector centroid = (*i)->Centroid();
 
    csv_stream << (*i)->Index() << ", "
 
	       << centroid.x << ", "
 
	       << centroid.y << ", " 
 
	       <<  (*i)->Area() << ", "
 
	       <<(*i)->Length();
 
    for (int c=0;c<Cell::NChem(); c++) {
 
      csv_stream << ", " << (*i)->Chemical(c);
 
    }
 
    csv_stream << endl;
 
  }
 
}
 

	
 

	
 
void Mesh::CSVExportMeshData(QTextStream &csv_stream) { 
 
  
 
  csv_stream << "\"Mesh area\",\"Number of cells\",\"Number of nodes\",\"Compactness\",\"Hull area\",\"Cell area\"" << endl;
 
  
 
  double res_compactness, res_area, res_cell_area;
 
  Compactness(&res_compactness, &res_area, &res_cell_area);
 
  csv_stream << Area() << ", " << NCells() << ", " << NNodes() << ", " << res_compactness << ", " << res_area << ", " << res_cell_area  << endl;
 
  
 
}
 
/* finis */
src/mesh.h
Show inline comments
 
@@ -38,12 +38,13 @@
 
#include "cell.h"
 
#include "node.h"
 
#include "simplugin.h"
 
#include <QVector>
 
#include <QPair>
 
#include <QDebug>
 
#include <QTextStream>
 

	
 
using namespace std;
 
// new queue which rejects duplicate elements
 
template<class T, class C = deque<T> > class unique_queue : public queue<T,C> {
 

	
 
 public:
 
@@ -78,15 +79,19 @@ class Mesh {
 
    // this issue (solved now).
 
    cells.reserve(2);
 
    nodes.reserve(500);
 

	
 
    time = 0.;
 
    plugin = 0;
 
    boundary_polygon=0;
 
  };
 
  ~Mesh(void) {
 
    delete boundary_polygon;
 
    if (boundary_polygon) {
 
      delete boundary_polygon;
 
      boundary_polygon=0;
 
    }
 
  };
 

	
 
  void Clean(void);
 
  Cell &EllipticCell(double xc, double yc, double ra, double rb, int nnodes=10, double rotation=0);
 
  Cell &CircularCell(double xc, double yc, double r, int nnodes=10) {
 
    return EllipticCell(xc, yc, r, r, nnodes, 0);
 
@@ -377,13 +382,16 @@ class Mesh {
 
  QVector< QPair<qreal,int> > VertexAnglesValues(void);
 
  void SetSimPlugin(SimPluginInterface *new_plugin) {
 
    plugin=new_plugin;
 
  }
 
  QString ModelID(void) { return plugin?plugin->ModelID():QString("undefined"); }
 
  void StandardInit(void);	
 

	
 
  double Compactness(double *res_compactness=0, double *res_area=0, double *res_cell_area=0);
 
  void CSVExportCellData(QTextStream &csv_stream) const;
 
  void CSVExportMeshData(QTextStream &csv_stream);
 
  
 
  Node* findNextBoundaryNode(Node*);
 

	
 
 private:
 

	
 
  // Data members
 
  vector<Cell *> cells;
src/modelcatalogue.cpp
Show inline comments
 
@@ -144,17 +144,61 @@ void ModelCatalogue::InstallModel(QActio
 
  InstallModel(model);
 
}
 

	
 
void ModelCatalogue::InstallModel(SimPluginInterface *plugin) {
 

	
 
  // make sure both main and plugin use the same static datamembers (ncells, nchems...)
 
  mesh->Clean();
 
  plugin->SetCellsStaticDatamembers(CellBase::GetStaticDataMemberPointer());
 

	
 
  mesh->SetSimPlugin(plugin);
 
 
 

	
 
  Cell::SetNChem(plugin->NChem());
 
  plugin->SetParameters(&par);
 

	
 
  
 
  if (mainwin) {
 
    mainwin->RefreshInfoBar();
 
    mainwin->Init(0);
 
    if (plugin->DefaultLeafML().isEmpty()) {
 
      mainwin->Init(0);
 
    } else {
 
      // locate LeafML file
 
      
 
      QDir pluginDir(QApplication::applicationDirPath()); 
 
      QStringList plugin_filters; // filter for plugins, i.e "*.dll", "*.dylib"
 
      
 
      
 
#if defined(Q_OS_WIN) 
 
      if (pluginDir.dirName().toLower() =="debug" 
 
	  ||pluginDir.dirName().toLower() =="release") 
 
	pluginDir.cdUp(); 
 
      //plugin_filters << "*.dll";
 
#elif defined(Q_OS_MAC) 
 
      if (pluginDir.dirName() =="MacOS"){ 
 
	pluginDir.cdUp(); 
 
	pluginDir.cdUp(); 
 
	pluginDir.cdUp(); 
 
      }
 
     
 
#endif
 
       // for all OS-es. Move from "bin" directory to root application folder.
 
      pluginDir.cdUp();
 
      cerr << "pluginDir: " << pluginDir.dirName().toStdString().c_str() << endl;
 
      if (!pluginDir.cd("data/leaves")) {
 
	MyWarning::warning("Directory 'data/leaves' not found! Cannot load LeafML file '%s'. Reverting to standard initial condition now...",plugin->DefaultLeafML().toStdString().c_str());
 
	mainwin->Init(0);
 
      } else {
 
      
 
	if (!pluginDir.exists(plugin->DefaultLeafML())) {
 
	  MyWarning::error("LeafML file '%s' not found - hint: is file in data/leaves folder? Reverting to standard initial condition now...",plugin->DefaultLeafML().toStdString().c_str());
 
	  mainwin->Init(0); 
 
	} else {
 
	  // Initialize simulation using default LeafML file referenced in plugin.
 
	  //mainwin->Init(0);
 
	  cerr << "Default LeafML: " << plugin->DefaultLeafML().toStdString().c_str() << endl;
 
	  mainwin->Init(pluginDir.absFilePath(plugin->DefaultLeafML()).toStdString().c_str());
 
	}
 
      }
 
    }
 
  }
 

	
 
}
src/simplugin.cpp
Show inline comments
 
@@ -17,12 +17,13 @@
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include <QString>
 
#include "simplugin.h"
 

	
 
static const std::string _module_id("$Id$");
 

	
 
void SimPluginInterface::SetParameters(Parameter *pass_pars)
 
{
 
@@ -31,7 +32,9 @@ void SimPluginInterface::SetParameters(P
 

	
 
void SimPluginInterface::SetCellsStaticDatamembers( CellsStaticDatamembers *cells_static_data_members_of_main)
 
{
 
  CellBase::static_data_members = cells_static_data_members_of_main;
 
}
 

	
 
QString SimPluginInterface::DefaultLeafML(void) { return QString(); }
 

	
 
/* finis */
src/simplugin.h
Show inline comments
 
@@ -62,20 +62,23 @@ class SimPluginInterface {
 
  // to be executed for coloring a cell
 
  virtual void SetCellColor(CellBase *c, QColor *color) = 0;
 

	
 
  // Number of chemicals
 
  virtual int NChem(void) = 0;
 

	
 
  // Default LeafML-file to be read after model startup
 
  virtual QString DefaultLeafML(void);
 
  
 
  // For internal use; not to be redefined by end users
 
  virtual void SetParameters(Parameter *pass_pars);// { par = pass_pars; }
 
  virtual void SetCellsStaticDatamembers (CellsStaticDatamembers *cells_static_data_members_of_main);
 

	
 
 protected:
 
  class Parameter *par;
 
};
 

	
 
Q_DECLARE_INTERFACE(SimPluginInterface, "nl.cwi.VirtualLeaf.SimPluginInterface/1.2") 
 
Q_DECLARE_INTERFACE(SimPluginInterface, "nl.cwi.VirtualLeaf.SimPluginInterface/1.3") 
 
Q_DECLARE_METATYPE(SimPluginInterface *)
 

	
 
#endif
 

	
 
/* finis */
src/xmlwrite.cpp
Show inline comments
 
@@ -1443,13 +1443,16 @@ void Mesh::XMLReadCells(xmlNode *root)
 
    delete *i;
 
  }
 

	
 
  cells.clear();
 
  Cell::NCells() = 0;
 

	
 
  delete boundary_polygon;
 
  if (boundary_polygon) {
 
    delete boundary_polygon;
 
    boundary_polygon=0;
 
  }
 

	
 
  xmlNode *cur = root->xmlChildrenNode;
 

	
 
  while (cur!=NULL) {
 

	
 
    Cell *new_cell=0;
0 comments (0 inline, 0 general)