Changeset - 15d600891648
[Not reviewed]
default
! ! !
Michael Guravage - 15 years ago 2010-06-24 15:22:58
michael.guravage@cwi.nl
In DrawCell class (VirtualLeaf.cpp) - iterate over NChem to construct info_string. Additional cleanup.

--
user: Michael Guravage <michael.guravage@cwi.nl>
branch 'default'
changed src/ChangeLog
changed src/Neighbor.cpp
changed src/Neighbor.h
changed src/OptionFileDialog.cpp
changed src/OptionFileDialog.h
changed src/UniqueMessage.cpp
changed src/UniqueMessage.h
changed src/VirtualLeaf.cpp
changed src/VirtualLeaf.pro
changed src/build_models/plugin_auxingrowth.pro
changed src/build_models/plugin_meinhardt.pro
changed src/build_models/plugin_test.pro
changed src/canvas.cpp
changed src/canvas.h
changed src/cell.cpp
changed src/cell.h
changed src/cellbase.cpp
changed src/cellbase.h
changed src/cellitem.cpp
changed src/cellitem.h
changed src/forwardeuler.cpp
changed src/forwardeuler.h
changed src/infobar.h
changed src/libplugin.pro
changed src/mainbase.cpp
changed src/mainbase.h
changed src/matrix.cpp
changed src/matrix.h
changed src/mesh.cpp
changed src/mesh.h
changed src/miscq.cpp
changed src/miscq.h
changed src/modelcatalogue.cpp
changed src/modelcatalogue.h
changed src/node.cpp
changed src/node.h
changed src/nodeitem.cpp
changed src/nodeitem.h
changed src/nodeset.cpp
changed src/nodeset.h
changed src/output.cpp
changed src/output.h
changed src/parameter.cpp
changed src/parameter.h
changed src/pardialog.cpp
changed src/parse.cpp
changed src/parse.h
changed src/pi.h
changed src/qcanvasarrow.h
changed src/random.cpp
changed src/random.h
changed src/rungekutta.cpp
changed src/rungekutta.h
changed src/simitembase.cpp
changed src/simitembase.h
changed src/simplugin.h
changed src/sqr.h
changed src/tiny.h
changed src/transporterdialog.cpp
changed src/transporterdialog.h
changed src/vector.cpp
changed src/vector.h
changed src/wall.cpp
changed src/wall.h
changed src/wallbase.cpp
changed src/wallbase.h
changed src/wallitem.cpp
changed src/wallitem.h
changed src/warning.cpp
changed src/warning.h
changed src/xmlwrite.cpp
changed src/xmlwrite.h
72 files changed with 231 insertions and 289 deletions:
0 comments (0 inline, 0 general)
src/ChangeLog
Show inline comments
 
2010-06-24    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* VirtualLeaf.cpp (DrawCell): Iterate over NChem to construct info_string.
 

	
 
2010-06-23    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* simitembase.cpp: Removed NULL assignments to unused variables.
 
	* VirtualLeaf.cpp: Ditto.
 
	* apoplastitem.cpp: Ditto.
 
	* canvas.cpp: Ditto.
 
	* cell.cpp: Ditto.
 
	* cellbase.h: Ditto.
 
	* forwardeuler.cpp: Ditto.
 
	* mainbase.h: Ditto.
 
	* nodeitem.cpp: Ditto.
 
	* qcanvasarrow.h: Ditto.
 
	* simitembase.cpp: Ditto.
 

	
 

	
 
	* Makefile (clean): Add -f Makefile argument to each make invocation.
 

	
 
	* VirtualLeaf-install.nsi: New gpl license text.
 

	
 
	* VirtualLeaf.pro: Disabled console mode.
 

	
 
	* mesh.cpp (Clear): Added parentheses to qDebug statments.
 
	(TestIllegalWalls): Replaced qDebug().
 

	
 
	* canvas.cpp (mouseReleaseEvent): Replaced qDebug() with cerr since qDebug complains about *node_set.
 

	
 
	* wall.cpp (CorrectWall): Rplaced gDebug() with cerr in transform call and when printing *this.
 

	
 
2010-06-22    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* Makefile (tutorials): Add tutorials target.
 

	
 
2010-06-21    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* parameter.cpp: Added particular reassignment of datadir.
 

	
 
	* canvas.cpp (gpl): Added GPL3 License text. Display detail text only if the source text file exists.
 

	
 
2010-06-18    <guravage@caterpie.sen.cwi.nl>
 

	
 
	* canvas.cpp (gpl): Added gpl slot to display GPL license.
 

	
 
	* VirtualLeaf.pro: Changed default LIBXML2DIR, LIBICONVDIR and LIBZDIR to corresponding distribution lib directories.
 
	* libplugin.pro: Ditto.
 

	
 
	* Makefile (clean): add if stmt not to `touch` on windows.
 

	
 
2010-06-17    <guravage@caterpie.sen.cwi.nl>
src/Neighbor.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include "Neighbor.h"
 
#include "cell.h"
 
#include <string>
 

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

	
 
Neighbor::Neighbor(void):
 
  cell(NULL), nb1(NULL), nb2(NULL){}
 
  cell(0), nb1(0), nb2(0){}
 

	
 
Neighbor::Neighbor(Cell *c, Node *n1, Node *n2):
 
  cell(c), nb1(n1), nb2(n2){}
 

	
 
Neighbor::Neighbor(const Neighbor &src):
 
  cell(src.cell), nb1(src.nb1), nb2(src.nb2){} // copy constructor
 

	
 
bool Neighbor::CellEquals(int i) const { return cell->Index() == i; } 
 
bool Neighbor::Cmp(Neighbor &c) const { return cell->Index() < c.cell->Index(); } // Compare cell indices not pointers.
 
bool Neighbor::Eq(Neighbor &c) const { return cell->Index() == c.cell->Index(); }
 
Cell* Neighbor::getCell(void) const { return cell; } 
 

	
 
bool neighbor_cell_eq(const Neighbor &n1, const Neighbor &n2) {
 
  return (n1.getCell())->Index() == (n2.getCell())->Index(); // Compare cell indices not pointers.
 
}
 

	
 
/* finis */
 

	
src/Neighbor.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _NEIGHBOR_H_
 
#define _NEIGHBOR_H_
 

	
 
#include <iostream>
 
#include <libxml/parser.h>
 
#include <libxml/tree.h>
 

	
 
using namespace std;
 

	
 
class Cell;
 
class Node;
 

	
 
class Neighbor {
 

	
 
 protected:
 
  // Proper accessors and mutators should obviate these friend classes!
 
  friend class Cell;
 
  friend class Mesh;
 
  friend class Node;
 
  friend class FigureEditor;
 

	
 
  Cell *cell;
 
  Node *nb1, *nb2;
 

	
 
 public:
 
  Neighbor(void);
 
  Neighbor(Cell*, Node*, Node*);
 
  Neighbor(const Neighbor&);
 

	
 
  bool CellEquals(int) const;
 
  bool Cmp(Neighbor&) const;
 
  bool Eq(Neighbor&) const;
 
  Cell* getCell(void) const;
 
  void XMLAdd(xmlNodePtr) const;
 

	
 
  ostream &print(ostream &os) const;
src/OptionFileDialog.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include "OptionFileDialog.h"
 
#include <QCheckBox>
 
#include <iostream>
 
using namespace  std; 
 

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

	
 
OptionFileDialog::OptionFileDialog(QWidget *parent, const char *name, bool modal) : Q3FileDialog(parent, name, modal)
 
{
 
  //cerr << "This is an OptionFileDialog\n";
 
  geometrycheck = new QCheckBox("geometry",this);
 
  geometrycheck -> setCheckState(Qt::Checked);
 

	
 
  parcheck = new QCheckBox("parameters", this);
 
  parcheck -> setCheckState(Qt::Checked);
 

	
 
  addToolButton(geometrycheck);
 
  addToolButton(parcheck);
 
};
 

	
 
OptionFileDialog::OptionFileDialog ( const QString & dirName, const QString & filter , 
 
				     QWidget * parent, const char * name , bool modal  ) :
 
  Q3FileDialog(dirName, filter, parent, name, modal) {
 

	
 
  cerr << "This is an OptionFileDialog\n";
 
};
 

	
 
/* finis */
src/OptionFileDialog.h
Show inline comments
 
/*
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#ifndef _OPTIONFILEDIALOG_H_
 
#define _OPTIONFILEDIALOG_H_
 

	
 
#include <Q3FileDialog>
 
#include <QCheckBox>
 

	
 
class OptionFileDialog : public Q3FileDialog {
 
  Q_OBJECT
 
 public:
 
  OptionFileDialog(QWidget *parent = 0, const char *name = 0, bool modal = false);
 
  OptionFileDialog ( const QString & dirName, const QString & filter = QString(), 
 
		     QWidget * parent = 0, const char * name = 0, bool modal = false );
 

	
 
  bool readGeometryP(void) const { return geometrycheck->checkState()==Qt::Checked; }
 
  bool readParametersP(void) const { return parcheck->checkState()==Qt::Checked; }
 

	
 
 private:
 
  QCheckBox *geometrycheck;	
 
  QCheckBox *parcheck;
 
};
 

	
 
#endif
 

	
 
/* finis */
src/UniqueMessage.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include <QMessageBox>
 
#include <QCheckBox>
 
#include <QPushButton>
 
#include <QBoxLayout>
 
#include "UniqueMessage.h"
 

	
 
#include <iostream>
 

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

	
 
using namespace std;
 
UniqueMessageBox::UniqueMessageBox ( /* Icon icon,*/ 
 
				    const QString & title, 
 
				    const QString & text, 
 
				    QWidget * parent ,
 
				    Qt::WindowFlags f ) : 
 
  QDialog(parent, f) {
 

	
 
  label = new QLabel(text);
 
  boxtext = text;
 

	
 
  show_again = new QCheckBox(tr("Do not show this message again"));
 
  okButton = new QPushButton(tr("Ok"));
 

	
 
  if (issued_messages.contains(boxtext) ) {
 

	
 
    cerr << "Saw message before\n";
 
    display = false;
 
  } else {
 
    display=true;
 
  }
 

	
 
  connect(okButton, SIGNAL(clicked()), this, SLOT(close()) );
 
  QHBoxLayout *hlayout = new QHBoxLayout;
 
  hlayout->addWidget(label);
 
  hlayout->addWidget(okButton);
src/UniqueMessage.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _UNIQUEMESSAGE_H_
 
#define _UNIQUEMESSAGE_H_
 

	
 
#include <QDialog>
 
#include <QCheckBox>
 
#include <QStringList>
 
#include <QLabel>
 

	
 
class UniqueMessageBox : public QDialog {
 
  Q_OBJECT
 

	
 
 public:
 
  UniqueMessageBox ( /* Icon icon,*/ 
 
		    const QString & title, 
 
		    const QString & text, 
 
		    /* StandardButtons buttons = Ok, */
 
		    QWidget * parent = 0 , Qt::WindowFlags f = Qt::Dialog | Qt::MSWindowsFixedSizeDialogHint );
 
  ~UniqueMessageBox();
 
  int exec(void);
 

	
 
 private:
 
  static QStringList issued_messages;
 
  bool display;
 
  QCheckBox *show_again;
 
  QPushButton *okButton;
 
  QLabel *label;
 
  QString boxtext;
 
};
 

	
 
#endif
 

	
 
/* finis */
src/VirtualLeaf.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include <fstream>
 
#include <sstream>
 
#include <cstring>
 
#include <functional> 
 
#include <getopt.h>
 
#include <cerrno>
 
#include "mesh.h"
 
#include "parameter.h"
 
#include "random.h"
 
#include "pi.h"
 
#include "cellitem.h"
 
#include "canvas.h"
 
#include "cell.h"
 
#include "output.h"
 
#include <qwidget.h>
 
#include <q3process.h>
 
#include <qapplication.h>
 
#include <QDesktopWidget>
 
#include <QGraphicsScene>
 
#include <QMessageBox>
 
//Added by qt3to4:
 
#include <QMouseEvent>
 

	
 
#include <unistd.h>
 
#include <q3textstream.h> 
 

	
 
#ifdef HAVE_QWT
 
#include "data_plot.h"
 
#endif
 
#include <QPalette>
 
#include <QBrush>
 
#include <QToolTip>
 
#include "simplugin.h"
 
#include <QPluginLoader>
 
#include <QDir>
 
#include "modelcatalogue.h"
 
@@ -70,189 +70,195 @@ MainBase *main_window = 0;
 
class PrintNode {
 
public:
 
  void operator() (const Node &n) const 
 
  {
 
    cerr << n.Index() << ": " << n <<  endl;
 
  }
 
};
 

	
 

	
 
class EdgeSource {
 

	
 
public:
 
  void operator() (Cell &c) {
 

	
 
    if (c.AtBoundaryP()) {
 
      cerr << "Cell " << c.Index() << " is a source cell.\n";
 
      c.SetSource(0,par.source);
 
    } else {
 
      cerr << "Cell " << c.Index() << " is _not_ a source cell.\n";
 
    }
 
  }
 
};
 

	
 

	
 

	
 
class CellInfo {
 
public:
 
  void operator() (Cell &c,std::ostream &os) const {
 
    os << "Cell " << c.index << " says: " << endl;
 
    os << "c.nodes.size() = " << c.nodes.size() << endl;
 
    for (list<Node *>::iterator i=c.nodes.begin(); i!=c.nodes.end(); i++) {
 
      cerr << (*i)->Index() << " ";
 
    }
 
    cerr << endl;
 
  }
 
};
 

	
 
double PINSum(Cell &c) {
 
  return c.Chemical(1) + c.SumTransporters(1);// + c.ReduceCellAndWalls<double>( complex_PijAj );
 
}
 

	
 

	
 
class DrawCell {
 
public:
 
  void operator() (Cell &c,QGraphicsScene &canvas, MainBase &m) const {
 
    if (m.ShowBorderCellsP() || c.Boundary()==Cell::None) {
 
      if (!m.ShowBoundaryOnlyP() && !m.HideCellsP()) {
 
	if (m.ShowToolTipsP()) {
 
	  QString info_string=QString("Cell %1, chemicals: ( %2, %3, %4, %5, %6)\n %7 of PIN1 at walls.\n Area is %8\n PIN sum is %9\n Circumference is %10\n Boundary type is %11").arg(c.Index()).arg(c.Chemical(0)).arg(c.Chemical(1)).arg(c.Chemical(2)).arg(c.Chemical(3)).arg(c.Chemical(4)).arg(c.SumTransporters(1)).arg(c.Area()).arg(PINSum(c)).arg(c.Circumference()).arg(c.BoundaryStr());
 

	
 
	  info_string += "\n" + c.printednodelist();
 
	  //QString info_string=QString("Cell %1, chemicals: ( %2, %3, %4, %5, %6)\n %7 of PIN1 at walls.\n Area is %8\n PIN sum is %9\n Circumference is %10\n Boundary type is %11").arg(c.Index()).arg(c.Chemical(0)).arg(c.Chemical(1)).arg(c.Chemical(2)).arg(c.Chemical(3)).arg(c.Chemical(4)).arg(c.SumTransporters(1)).arg(c.Area()).arg(PINSum(c)).arg(c.Circumference()).arg(c.BoundaryStr());
 
		QString info_string=QString("Cell %1, chemicals(%2): ").arg(c.Index()).arg(Cell::NChem());
 
		for (int i=0;i<Cell::NChem();i++) {
 
			info_string += QString("%1 ").arg(c.Chemical(i));
 
		}
 
		info_string += QString("\nArea is %1\n Circumference is %2\n Boundary type is %3").arg(c.Area()).arg(c.Circumference()).arg(c.BoundaryStr());
 
		
 
	  info_string += "\nNodes: " + c.printednodelist();
 
	  c.Draw(&canvas, info_string);
 
	} else {
 
	  c.Draw(&canvas);
 
	}
 
      }
 
      if (m.ShowCentersP()){
 
	c.DrawCenter(&canvas);
 
      }
 
      if (m.ShowFluxesP()){
 
	c.DrawFluxes(&canvas, par.arrowsize);
 
      }
 
    }
 
  }
 
};
 

	
 
Mesh mesh;
 
bool batch=false;
 

	
 
void MainBase::Plot(int resize_stride)
 
{
 

	
 
  clear();
 

	
 
  static int count=0;
 
  if (resize_stride) {
 
    if ( !((++count)%resize_stride) ) {
 
    if ( !((count)%resize_stride) ) {
 
      FitLeafToCanvas();
 
    }
 
  }
 

	
 
  mesh.LoopCells(DrawCell(),canvas,*this);
 

	
 
  if (ShowNodeNumbersP()) 
 
    mesh.LoopNodes( bind2nd (mem_fun_ref ( &Node::DrawIndex), &canvas ) ) ;
 
  if (ShowCellNumbersP()) 
 
    mesh.LoopCells( bind2nd (mem_fun_ref ( &Cell::DrawIndex), &canvas ) ) ;
 

	
 
  if (ShowCellAxesP()) 
 
    mesh.LoopCells( bind2nd (mem_fun_ref ( &Cell::DrawAxis), &canvas ) );
 

	
 
  if (ShowCellStrainP()) 
 
    mesh.LoopCells( bind2nd (mem_fun_ref ( &Cell::DrawStrain), &canvas ) );
 

	
 
  if (ShowWallsP())
 
    mesh.LoopWalls( bind2nd( mem_fun_ref( &Wall::Draw ), &canvas ) );
 

	
 
  if (ShowApoplastsP()) 
 
/*  if (ShowApoplastsP()) 
 
    mesh.LoopWalls( bind2nd( mem_fun_ref( &Wall::DrawApoplast ), &canvas ) );
 

	
 
*/
 
  if (ShowMeshP()) 
 
    mesh.DrawNodes(&canvas);
 

	
 
  if (ShowBoundaryOnlyP()) 
 
    mesh.DrawBoundary(&canvas);
 

	
 
  if ( ( batch || MovieFramesP() )) {
 

	
 
    static int frame = 0;
 
    // frame numbers are sequential for the most frequently written file type.
 
    // for the less frequently written file type they match the other type
 
    if (!(count%par.storage_stride) )  {
 

	
 
      stringstream fname;
 
      fname << par.datadir << "/leaf.";
 
      fname.fill('0');
 
      fname.width(6);
 

	
 
      fname << frame << ".jpg";
 
      if (par.storage_stride <= par.xml_storage_stride) {
 
	frame++;
 
      }
 

	
 
      // Write high-res JPG snapshot every plot step
 
      Save(fname.str().c_str(), "JPEG",1024,768);
 
    }
 

	
 
    if (!(count%par.xml_storage_stride)) {
 
      stringstream fname;
 
      fname << par.datadir << "/leaf.";
 
      fname.fill('0');
 
      fname.width(6);
 
      fname << frame << ".xml";
 

	
 
      if (par.xml_storage_stride < par.storage_stride) {
 
	frame++;
 
      }
 
      // Write XML file every ten plot steps
 
      mesh.XMLSave(fname.str().c_str(), XMLSettingsTree());
 
    }
 
  }
 
 count++;
 
}
 

	
 

	
 

	
 
INIT {
 

	
 
  //mesh.SetSimPlugin(plugin);
 
  if (leaffile) { 
 
    xmlNode *settings;
 
    mesh.XMLRead(leaffile, &settings);
 

	
 
    main_window->XMLReadSettings(settings);
 
    xmlFree(settings);
 
    main_window->UserMessage(QString("Ready. Time is %1").arg(mesh.getTimeHours().c_str()));
 

	
 
  } else {
 
    mesh.StandardInit();
 
  }
 
}
 

	
 
TIMESTEP {
 

	
 
  static int i=0;
 
  static int t=0;
 
  static int ncells;
 

	
 
  if (!batch) {
 
    UserMessage(QString("Time: %1").arg(mesh.getTimeHours().c_str()),0);
 
  }
 

	
 
  ncells=mesh.NCells();
 

	
 

	
 
  double dh;
 

	
 
  if(DynamicCellsP()) {
 
    dh = mesh.DisplaceNodes();
 

	
 
    // Only allow for node insertion, cell division and cell growth
 
    // if the system has equillibrized
 
    // i.e. cell wall tension equillibrization is much faster
 
    // than biological processes, including division, cell wall yielding
 
    // and cell expansion
 
    mesh.InsertNodes(); // (this amounts to cell wall yielding)
 

	
 
    if ( (-dh) < par.energy_threshold) {
 

	
 
      mesh.IncreaseCellCapacityIfNecessary();
src/VirtualLeaf.pro
Show inline comments
 
#
 
#  $Id$
 
#
 
#  This file is part of the Virtual Leaf.
 
#
 
#  The Virtual Leaf is free software: you can redistribute it and/or modify
 
#  it under the terms of the GNU General Public License as published by
 
#  the Free Software Foundation, either version 3 of the License, or
 
#  (at your option) any later version.
 
#
 
#  The Virtual Leaf is distributed in the hope that it will be useful,
 
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
#  GNU General Public License for more details.
 
#
 
#  You should have received a copy of the GNU General Public License
 
#  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
#
 
#  Copyright 2010 Roeland Merks.
 
#
 

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

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

	
 
#REACTIONS = reactions_auxin_growth.h 
 
#REACTIONS = reactions_meinhardt.h
 
#REACTIONS = reactions_pce_growth.h
 
DEFINES += QTGRAPHICS
 
DEFINES += REACTIONS_HEADER=$${REACTIONS}
 
DEFINES += REACTIONS_HEADER_STRING=\"$${REACTIONS}\"
 
DEFINES += FLEMING
 

	
 
BINDIR = ../bin
 
DESTDIR = $$BINDIR
 
TARGET = VirtualLeaf
 
TEMPLATE = app
 
PARTMPL = $${TARGET}par.tmpl
 
MAINSRC = $${TARGET}.cpp
 
QT -= network sql xml
 
QT += qt3support
 

	
 
!win32 {
 
 GRAPHICS = qt #qwt
 
}
 

	
 
win32 {
 
 CONFIG -= console
 
 LIBXML2DIR = ..\lib\libxml2
 
 LIBICONVDIR = ..\lib\libiconv
 
 LIBZDIR = ..\lib\libz
 
 LIBXML2DIR = C:
 
 LIBICONVDIR = C:
 
 LIBZDIR = C:
 
 GRAPHICS = qt 
 
 RC_FILE = VirtualLeaf.rc
 
 QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
# QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
 QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include
 
 LIBS += -L$${LIBXML2DIR}\lib -lxml2 -L$${LIBICONVDIR}\lib -L$${LIBZDIR}\lib  -lz -lm -lwsock32 -liconv
 
}
 

	
 

	
 
macx:release {
 
 LIBS+= -dead_strip
 
}
 

	
 
unix {
 
 CC = /usr/bin/gcc 
 
 QWTDIR = /ufs/guravage/opt/qwt-5.2.1-svn
 
 QMAKE_LIBDIR += $$QWTDIR/lib 
 
 QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2
 
 QMAKE_LFLAGS += -fPIC
 
 LIBS += -lxml2 -lz -lm 
 
}
 

	
 
# Input
 
HEADERS += \
 
 apoplastitem.h \
 
# apoplastitem.h \
 
 canvas.h \
 
 cellbase.h \
 
 cell.h \
 
 cellitem.h \
 
 forwardeuler.h \
 
 infobar.h \
 
 mainbase.h \
 
 mainbase.h \
 
 matrix.h \
 
 mesh.h \
 
 miscq.h \
 
 modelcatalogue.h \
 
 Neighbor.h \
 
 node.h \
 
 nodeitem.h \
 
 nodeset.h \
 
 OptionFileDialog.h \
 
 output.h \
 
 parameter.h \
 
 pardialog.h \
 
 parse.h \
 
 pi.h \
 
 qcanvasarrow.h \
 
 random.h \
 
 rungekutta.h \
 
 simitembase.h \
 
 simplugin.h \
 
 sqr.h \
 
 tiny.h \
 
 transporterdialog.h \
 
 UniqueMessage.h \
 
 vector.h \
 
 wallbase.h \
 
 wall.h \
 
 wallitem.h \
 
 warning.h \
 
 xmlwrite.h \
 
 $${PARTMPL}
 

	
 
SOURCES += \
 
 apoplastitem.cpp \
 
# apoplastitem.cpp \
 
 canvas.cpp \
 
 cellbase.cpp \
 
 cell.cpp \
 
 cellitem.cpp \
 
 forwardeuler.cpp \
 
 mainbase.cpp \
 
 matrix.cpp \
 
 mesh.cpp \
 
 miscq.cpp \
 
 modelcatalogue.cpp \
 
 Neighbor.cpp \
 
 node.cpp \
 
 nodeitem.cpp \
 
 nodeset.cpp \
 
 OptionFileDialog.cpp \
 
 output.cpp \
 
 parameter.cpp \
 
 pardialog.cpp \
 
 parse.cpp \
 
 random.cpp \
 
 rungekutta.cpp \
 
 simitembase.cpp \
 
 transporterdialog.cpp \
 
 UniqueMessage.cpp \
 
 vector.cpp \
 
 wallbase.cpp \
 
 wall.cpp \
 
 wallitem.cpp \
 
 warning.cpp \
 
 xmlwrite.cpp \
 
 $$MAINSRC
 

	
 
contains( TARGET, leaf_fleming ) {
 
 DEFINES += FLEMING	
 
}
 

	
 
contains(GRAPHICS, qwt) {
 
 #macx:LIBS += -L$$QWTDIR/lib -lqwt
 
 #win32:LIBS += -L$$QWTDIR/lib -lqwt5
 
 #LIBS += -L$$QWTDIR/lib -lqwt
 
 INCLUDEPATH += $$QWTDIR/include
 
 DEFINES += HAVE_QWT
 
 HEADERS += data_plot.h
 
 SOURCES += data_plot.cpp
 
}
 

	
 
contains( GRAPHICS, qt ) {
 
 message( "Building Qt executable" )
src/build_models/plugin_auxingrowth.pro
Show inline comments
 
#
 
# $Id$
 
#
 
#  This file is part of the Virtual Leaf.
 
#
 
#  The Virtual Leaf is free software: you can redistribute it and/or modify
 
#  it under the terms of the GNU General Public License as published by
 
#  the Free Software Foundation, either version 3 of the License, or
 
#  (at your option) any later version.
 
#
 
#  The Virtual Leaf is distributed in the hope that it will be useful,
 
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
#  GNU General Public License for more details.
 
#
 
#  You should have received a copy of the GNU General Public License
 
#  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
#
 
#  Copyright 2010 Roeland Merks.
 
#
 

	
 
CONFIG += release
 
CONFIG -= debug
 
CONFIG += plugin
 

	
 
BINDIR = ../../bin
 
LIBDIR = ../../lib
 
DEFINES = QTGRAPHICS # VLEAFPLUGIN
 
DESTDIR = $${BINDIR}/models
 
TARGET = auxingrowth
 
HEADERS = ../simplugin.h $${TARGET}plugin.h  
 
QMAKE_CXXFLAGS += -fexceptions -I..
 
QMAKE_CXXFLAGS_DEBUG += -g3
 
QMAKE_CXXFLAGS_DEBUG += -DQDEBUG
 

	
 
QT += qt3support
 
SOURCES = $${TARGET}plugin.cpp
 
TEMPLATE = lib 
 

	
 
unix {
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2
 
 QMAKE_LFLAGS += -fPIC
 
}
 

	
 
win32 {
 
 LIBXML2DIR = ..\..\lib\libxml2
 
 LIBICONVDIR = ..\..\lib\libiconv
 
 LIBZDIR = ..\..\lib\libz
 
 LIBXML2DIR = $${LIBDIR}\lib\libxml2
 
 LIBICONVDIR = $${LIBDIR}\lib\libiconv
 
 LIBZDIR = $${LIBDIR}\lib\libz
 
 LIBS += -L$${LIBDIR} -Llib -lvleaf
 
 QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
 QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include
 
}
 

	
 
# finis
src/build_models/plugin_meinhardt.pro
Show inline comments
 
#
 
# $Id$
 
#
 
#  This file is part of the Virtual Leaf.
 
#
 
#  The Virtual Leaf is free software: you can redistribute it and/or modify
 
#  it under the terms of the GNU General Public License as published by
 
#  the Free Software Foundation, either version 3 of the License, or
 
#  (at your option) any later version.
 
#
 
#  The Virtual Leaf is distributed in the hope that it will be useful,
 
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
#  GNU General Public License for more details.
 
#
 
#  You should have received a copy of the GNU General Public License
 
#  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
#
 
#  Copyright 2010 Roeland Merks.
 
#
 

	
 
CONFIG += release
 
CONFIG -= debug
 
CONFIG += plugin
 

	
 
BINDIR = ../../bin
 
LIBDIR = ../../lib
 
DEFINES = QTGRAPHICS # VLEAFPLUGIN
 
DESTDIR = $${BINDIR}/models
 
TARGET = meinhardt
 
HEADERS = ../simplugin.h $${TARGET}plugin.h  
 
QMAKE_CXXFLAGS += -fexceptions -I..
 
QMAKE_CXXFLAGS_DEBUG += -g3
 
QMAKE_CXXFLAGS_DEBUG += -DQDEBUG
 

	
 
QT += qt3support
 
SOURCES = $${TARGET}plugin.cpp
 
TEMPLATE = lib 
 

	
 
unix {
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2
 
 QMAKE_LFLAGS += -fPIC
 
}
 

	
 
win32 {
 
 LIBXML2DIR = ..\..\lib\libxml2
 
 LIBICONVDIR = ..\..\lib\libiconv
 
 LIBZDIR = ..\..\lib\libz
 
 LIBXML2DIR = $${LIBDIR}\lib\libxml2
 
 LIBICONVDIR = $${LIBDIR}\lib\libiconv
 
 LIBZDIR = $${LIBDIR}\lib\libz
 
 LIBS += -L$${LIBDIR} -Llib -lvleaf
 
 QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
 QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include
 
}
 

	
 
# finis
 

	
src/build_models/plugin_test.pro
Show inline comments
 
#
 
# $Id$
 
#
 
#  This file is part of the Virtual Leaf.
 
#
 
#  The Virtual Leaf is free software: you can redistribute it and/or modify
 
#  it under the terms of the GNU General Public License as published by
 
#  the Free Software Foundation, either version 3 of the License, or
 
#  (at your option) any later version.
 
#
 
#  The Virtual Leaf is distributed in the hope that it will be useful,
 
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
#  GNU General Public License for more details.
 
#
 
#  You should have received a copy of the GNU General Public License
 
#  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
#
 
#  Copyright 2010 Roeland Merks.
 
#
 

	
 
CONFIG += release
 
CONFIG -= debug
 
CONFIG += plugin
 

	
 
BINDIR = ../../bin
 
LIBDIR = ../../lib
 
DEFINES = QTGRAPHICS # VLEAFPLUGIN
 
DESTDIR = $${BINDIR}/models
 
TARGET = test
 
HEADERS = ../simplugin.h $${TARGET}plugin.h  
 
QMAKE_CXXFLAGS += -fexceptions -I..
 
QMAKE_CXXFLAGS_DEBUG += -g3
 
QMAKE_CXXFLAGS_DEBUG += -DQDEBUG
 

	
 
QT += qt3support
 
SOURCES = $${TARGET}plugin.cpp
 
TEMPLATE = lib 
 

	
 
unix {
 
 LIBS += -L$${LIBDIR} -lvleaf
 
 QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2
 
 QMAKE_LFLAGS += -fPIC
 
}
 

	
 
win32 {
 
 LIBXML2DIR = ..\..\lib\libxml2
 
 LIBICONVDIR = ..\..\lib\libiconv
 
 LIBZDIR = ..\..\lib\libz
 
 LIBXML2DIR = $${LIBDIR}\lib\libxml2
 
 LIBICONVDIR = $${LIBDIR}\lib\libiconv
 
 LIBZDIR = $${LIBDIR}\lib\libz
 
 LIBS += -L$${LIBDIR} -Llib -lvleaf
 
 QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
 QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include
 

	
 
}
 

	
 
# finis
src/canvas.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include <fstream>
 
#include <streambuf>
 
#include <QGraphicsScene>
 
#include <QGraphicsView>
 
#include <qdatetime.h>
 
#include <q3mainwindow.h>
 
#include <qstatusbar.h>
 
#include <qmessagebox.h>
 
#include <qmenubar.h>
 
#include <qapplication.h>
 
#include <qpainter.h>
 
#include <qprinter.h>
 
#include <qlabel.h>
 
#include <qimage.h>
 
#include <q3progressdialog.h>
 
#include <qtimer.h>
 
#include <qslider.h>
 
#include <qpixmap.h>
 
#include <qfile.h>
 
#include <qdir.h>
 
#include <q3filedialog.h>
 
#include <QGraphicsItem>
 
#include <QList>
 
#include <QDir>
 

	
 
#include <QDebug>
 

	
 
#include <set>
 

	
 
//Added by qt3to4:
 
#include <Q3ValueList>
 
#include <Q3PopupMenu>
 
#include <QMouseEvent>
 
#include <typeinfo>
 
#include <cstring>
 
#include <q3process.h>
 
@@ -478,134 +478,135 @@ Main::Main(QGraphicsScene& c, Mesh &m, Q
 
  file->insertItem("Read last leaf", this, SLOT(readLastStateXML()), Qt::Key_End);
 
  file->insertItem("Read first leaf", this, SLOT(readFirstStateXML()), Qt::Key_Home);
 

	
 
  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);
 

	
 
  Q3PopupMenu* edit = new Q3PopupMenu( menu );
 
  edit->insertItem("Reset Chemicals and Transporters", this, SLOT( CleanMesh()), Qt::CTRL+Qt::Key_R );
 
  edit->insertItem("Reset Chemicals", this, SLOT( CleanMeshChemicals()) );
 
  edit->insertItem("Reset Transporters", this, SLOT( CleanMeshTransporters()) );
 
  edit->insertItem("Randomize PIN1 Transporters", this, SLOT( RandomizeMesh()) );
 
  edit->insertItem("Cut away SAM", this, SLOT( CutSAM() ));
 
  menu->insertItem("&Edit", edit);
 

	
 
  run = new Q3PopupMenu( menu );
 
  running = false;
 
  paused_id = run->insertItem("&Simulation paused", this, SLOT(togglePaused()), Qt::Key_S);
 
  run->setItemChecked(paused_id, FALSE);
 

	
 
  menu->insertItem("&Run", run);
 

	
 
  view = new Q3PopupMenu( menu );
 
  view->insertItem("&Zoom in", this, SLOT(zoomIn()), Qt::CTRL+Qt::Key_Equal);
 
  view->insertItem("Zoom &out", this, SLOT(zoomOut()), Qt::CTRL+Qt::Key_Minus);
 
  view->insertSeparator();
 
  com_id = view->insertItem("Show cell &centers", this, SLOT(toggleShowCellCenters()));
 
  view->setItemChecked(com_id, FALSE);
 

	
 
  mesh_id = view->insertItem("Show &nodes", this, SLOT(toggleShowNodes()), Qt::CTRL+Qt::SHIFT+Qt::Key_N);
 
  view->setItemChecked(mesh_id, TRUE);
 
  node_number_id = view->insertItem("Show node numbers", this, SLOT(toggleNodeNumbers()), Qt::CTRL+Qt::SHIFT+Qt::Key_M);
 
  view->setItemChecked(node_number_id, FALSE);
 
  cell_number_id = view->insertItem("Show cell numbers", this, SLOT(toggleCellNumbers()));
 
  view->setItemChecked(cell_number_id, FALSE);
 
  hide_cells_id = view->insertItem("Hide cells", this, SLOT(toggleHideCells()));
 
  view->setItemChecked(hide_cells_id, FALSE);
 
  border_id = view->insertItem("Show &border cells", this, SLOT(toggleShowBorderCells()));
 
  view->setItemChecked(border_id, FALSE);
 
  cell_axes_id = view->insertItem("Show cell &axes", this, SLOT(toggleCellAxes()));
 
  cell_strain_id = view->insertItem("Show cell &strain", this, SLOT(toggleCellStrain()));
 
  view->setItemChecked(cell_axes_id, FALSE);
 
  fluxes_id = view->insertItem("Show &fluxes", this, SLOT(toggleShowFluxes()));
 
  view->setItemChecked(fluxes_id, FALSE);
 
  cell_walls_id = view->insertItem("Show transporters", this, SLOT(toggleShowWalls()));
 
  view->setItemChecked(cell_walls_id, FALSE);
 
  apoplasts_id = view->insertItem("Show apoplasts", this, SLOT(toggleShowApoplasts()));
 
  view->setItemChecked(apoplasts_id, FALSE);
 
 // apoplasts_id = view->insertItem("Show apoplasts", this, SLOT(toggleShowApoplasts()));
 
 // view->setItemChecked(apoplasts_id, FALSE);
 
  view->insertSeparator();
 
  only_boundary_id = view->insertItem("Show only leaf &boundary", this, SLOT(toggleLeafBoundary()));
 
  view->insertSeparator();
 
  movie_frames_id = view->insertItem("Start saving movie &frames", this, SLOT(toggleMovieFrames()));
 
  view->setItemChecked(movie_frames_id, par.movie);
 

	
 
  view->setItemChecked(only_boundary_id, FALSE);
 
  menu->insertItem("&View", view);
 

	
 

	
 
  options = new Q3PopupMenu( menu );
 
  dyn_cells_id = options->insertItem("Cell growth", this, SLOT(toggleDynCells()));
 
  options->setItemChecked(dyn_cells_id, true);
 

	
 
  options->insertItem("Edit &parameters", this, SLOT(EditParameters()), Qt::CTRL+Qt::Key_E);
 

	
 
  rotation_mode_id = options->insertItem("Rotate leaf", this, SLOT(EnterRotationMode()), Qt::CTRL + Qt::SHIFT + Qt::Key_R);
 
  options->setItemChecked(rotation_mode_id, false);
 

	
 
  menu->insertItem("&Options",options);
 

	
 
  // Menu of models
 
  modelmenu = new QMenu( menu );
 
  menu->insertItem("&Models", modelmenu);
 

	
 

	
 
  menu->insertSeparator();
 

	
 
  helpmenu = new Q3PopupMenu( menu );
 
  tooltips_id = helpmenu->insertItem("Show Cell&Info", this, SLOT(Refresh()));
 
  helpmenu->setItemChecked(tooltips_id, true);
 
  helpmenu->insertSeparator();
 
  helpmenu->insertItem("&About", this, SLOT(about()) ); //, Key_F1);
 
  helpmenu->insertSeparator();
 
    //helpmenu->insertSeparator();
 
  helpmenu->insertItem("&LICENSE", this, SLOT(gpl()) );
 
  menu->insertItem("&Help",helpmenu);
 
  helpmenu->insertItem("About", this, SLOT(about()) ); //, Key_F1);
 
	
 
	menu->insertItem("&Help",helpmenu);
 
  statusBar();
 
  setCentralWidget(editor);
 
  printer = 0;
 
  init();
 

	
 
  // Start timer which repetitively invokes
 
  // a simulation time step
 
  timer = new QTimer( this );
 
  connect( timer, SIGNAL(timeout()), SLOT(TimeStepWrap()) );
 

	
 
  stopSimulation();
 
  statusBar()->addWidget(new QLabel("Ready."));
 
  setCaption(caption);
 
  gifanim = 0;
 

	
 
  infobar = new InfoBar();
 
  addDockWindow(infobar);
 
}
 

	
 
void Main::RefreshInfoBar(void)
 
{
 
  infobar->SetText(mesh.ModelID());
 
}
 

	
 

	
 
void Main::UserMessage(QString message, int timeout)
 
{
 
  statusBar()->showMessage(message, timeout);
 
}
 

	
 

	
 
void Main::init()
 
{
 
  clear();
 

	
 
  static int r=24;
 
  srand(++r);
 

	
 
  mainCount++;
 
}
 

	
 
Main::~Main()
 
{
 
  delete printer;
 
  if ( !--mainCount ) {
 
  }
 
  //EndGifAnim();
 
}
 
@@ -883,106 +884,106 @@ void Main::readFirstStateXML()
 

	
 

	
 
    next_file = xml_files.front();
 

	
 
    next_file = currentFile_path+"/"+next_file;
 

	
 
    readStateXML((const char*)next_file);
 
  }
 
}
 

	
 
void Main::readStateXML()
 
{
 

	
 
  //  extern Mesh mesh;
 

	
 
  stopSimulation();
 
#ifdef QDEBUG
 
  qDebug() << "Trying to open an OptionFileDialog" << endl;
 
#endif
 
  OptionFileDialog *fd = new OptionFileDialog( this, "read dialog", TRUE );
 
  fd->setMode( OptionFileDialog::ExistingFile );
 
  fd->setFilter( "XML files (*.xml)");
 
  if (working_dir) {
 
    fd->setDir(*working_dir);
 
  }
 
  QString fileName;
 
  if ( fd->exec() == QDialog::Accepted ) {
 

	
 
    fileName = fd->selectedFile();
 
    if (working_dir) {
 
      delete working_dir;
 
    }
 
    working_dir = fd->dir();
 

	
 
    if (readStateXML((const char *)fileName,fd->readGeometryP(), fd->readParametersP()) )
 
      return readStateXML(); // user can try again
 
  }
 
}
 

	
 

	
 
void Main::clear()
 
{
 
  editor->clear();
 
}
 

	
 
void Main::about()
 
{
 
  static QMessageBox* about = new QMessageBox
 
    ( "Virtual Leaf V1.0",
 
      "<h3>Virtual Leaf V1.0</h3>"
 
    ( "VirtualLeaf V1.0",
 
      "<h3>VirtualLeaf V1.0</h3>"
 
      "<p>"
 
      "An Open Source framework for cell-based modeling of plant tissue growth and development <br>"
 
      "(c) 2005-2008, Roeland Merks <i>et al.</i><br>"
 
      "    <a href=\"http://www.psb.vib-ugent.be\">VIB Department Plant Systems Biology</a>, "
 
      "Ghent, Belgium <br>"
 
      "(c) 2008-2010, <a href=\"http://www.cwi.nl/~merks\">Roeland Merks <i>et al.</i></a> <br>"
 
      "    <a href=\"http://www.cwi.nl\">Centrum Wiskunde & Informatica</a> and <a href=\"http://www.ncsb.nl\">Netherlands Consortium for Systems Biology</a>, Amsterdam, Netherlands <br>"
 
"<br>The Virtual Leaf is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.<br>"
 
"<br>VirtualLeaf is free software: you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.<br>"
 
      "<br>If you use this code for your projects, please cite our paper:"
 
"<br>Merks, Guravage, Inze, and Beemster. An Open Source framework for cell-based modeling of plant tissue growth and development. <i>Plant Physiology,</i> submitted.<br> . <br>"
 
      "<br>Please share your model plugins and extensions at <a href=\"http://virtualleaf.googlecode.com\">http://virtualleaf.googlecode.com</a>.", 
 
      QMessageBox::Information, 1, 0, 0, this, 0, FALSE );
 
  about->setButtonText( 1, "Dismiss" );
 
  about->show();
 
}
 

	
 

	
 
void Main::gpl()
 
{
 
  static QMessageBox* gpl = new QMessageBox ( "GPL License", "", 
 
      QMessageBox::Information, 1, 0, 0, this, 0, FALSE );
 

	
 
  QDir docDir(QApplication::applicationDirPath());
 
  docDir.cd("../doc");
 
  QString path = docDir.filePath("gpl3.txt");
 

	
 
  std::ifstream file(path.toStdString().c_str());
 
  std::string str;
 

	
 
  if (file) {
 
    file.seekg(0, std::ios::end);   
 
    str.reserve(file.tellg());
 
    file.seekg(0, std::ios::beg);
 

	
 
    str.assign((std::istreambuf_iterator<char>(file)),
 
	       std::istreambuf_iterator<char>());
 

	
 
    gpl->setDetailedText(QString(str.c_str()));
 
  }
 

	
 
  gpl->setText(QString( "<h3>GNU GENERAL PUBLIC LICENSE</h3>"
 
			"<p>Version 3, 29 June 2007</p>"
 
			"<p>Copyright &copy; 2007 Free Software Foundation, Inc. "
 
			"&lt;<a href=\"http://fsf.org/\">http://fsf.org/</a>&gt;</p><p>"
 
			"Everyone is permitted to copy and distribute verbatim copies "
 
			"of this license document, but changing it is not allowed.</p>"
 
			"<h2>GNU GENERAL PUBLIC LICENSE</h2>"));
 

	
 
  gpl->setButtonText( 1, "Dismiss" );
 
  gpl->show();
 
}
 

	
 
void Main::aboutQt(){
 
  QMessageBox::aboutQt( this, "Virtual Leaf" );
 
}
 

	
 
@@ -1279,78 +1280,78 @@ void Main::CleanMeshTransporters(void)
 
    clean_transporters[i]=0.;
 
  }
 

	
 
  mesh.CleanTransporters(clean_transporters);
 

	
 
  mesh.setTime(0);
 
  Plot();
 

	
 
  editor->FullRedraw();
 
}
 

	
 
void Main::RandomizeMesh(void) 
 
{
 

	
 
  vector<double> max_chem(Cell::NChem());
 
  vector<double> max_transporters(Cell::NChem());
 

	
 
  for (int i=0;i<Cell::NChem();i++) {
 
    max_transporters[i]=0.;
 
    max_chem[i]=par.initval[i];
 
  }
 

	
 
  // Amount of PIN1 at walls
 
  max_transporters[1] = 0.01;
 

	
 
  mesh.RandomizeChemicals(max_chem, max_transporters);
 

	
 
  Plot();
 
}
 

	
 
void Main::XMLReadSettings(xmlNode *settings) 
 
{
 

	
 
  MainBase::XMLReadSettings(settings);
 
  
 
  view->setItemChecked(com_id, showcentersp);
 
  view->setItemChecked(mesh_id, showmeshp);
 
  view->setItemChecked(border_id, showbordercellp);
 
  view->setItemChecked(node_number_id, shownodenumbersp);
 
  view->setItemChecked(cell_number_id, showcellnumbersp);
 
  view->setItemChecked(cell_axes_id, showcellsaxesp);
 
  view->setItemChecked(cell_strain_id, showcellstrainp);
 
  view->setItemChecked(movie_frames_id, movieframesp);
 
  view->setItemChecked(only_boundary_id, showboundaryonlyp);
 
  view->setItemChecked(fluxes_id, showfluxesp);
 
  view->setItemChecked(hide_cells_id, hidecellsp);
 
  options->setItemChecked(dyn_cells_id, dynamicscellsp);
 
  view->setItemChecked( cell_walls_id, showwallsp);
 
  view->setItemChecked( apoplasts_id, showapoplastsp);
 
 // view->setItemChecked( apoplasts_id, showapoplastsp);
 
  
 
  editor->setTransform(viewport);
 
}
 

	
 
xmlNode *Main::XMLSettingsTree(void) 
 
{
 

	
 
  showcentersp = view->isItemChecked(com_id);
 
  showmeshp = view->isItemChecked(mesh_id);
 
  showbordercellp =  view->isItemChecked(border_id);
 
  shownodenumbersp =  view->isItemChecked(node_number_id);
 
  showcellnumbersp =  view->isItemChecked(cell_number_id);
 
  showcellsaxesp = view->isItemChecked( cell_axes_id );
 
  showcellstrainp = view->isItemChecked( cell_strain_id );
 
  movieframesp = view->isItemChecked(movie_frames_id);;
 
  showboundaryonlyp =  view->isItemChecked(only_boundary_id);
 
  showfluxesp = view->isItemChecked(fluxes_id);
 
  dynamicscellsp = options->isItemChecked(dyn_cells_id);
 
  showwallsp = view->isItemChecked( cell_walls_id);
 
  showapoplastsp = view->isItemChecked( apoplasts_id);
 
  //showapoplastsp = view->isItemChecked( apoplasts_id);
 
  hidecellsp = view->isItemChecked( hide_cells_id);
 

	
 
  xmlNode *settings = MainBase::XMLSettingsTree();
 
  QTransform viewport(editor->transform());
 
  xmlAddChild(settings, XMLViewportTree(viewport));
 
  return settings;
 
}
 

	
 
/* finis */
src/canvas.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#ifndef _CANVAS_H_
 
#define _CANVAS_H_
 

	
 
#include <q3popupmenu.h>
 
#include <q3mainwindow.h>
 
#include <q3intdict.h>
 
#include <QGraphicsScene>
 
#include <QGraphicsView>
 
#include <QList>
 

	
 
#include <string>
 
#include <sstream>
 

	
 
//Added by qt3to4:
 
#include <QMouseEvent>
 
#include <vector>
 
#include "simitembase.h"
 
#include "mainbase.h"
 
#include "cellitem.h"
 
#include "infobar.h"
 

	
 
#include "nodeitem.h"
 
#include "cell.h"
 

	
 
#ifdef HAVE_QWT
 
#include "data_plot.h"
 
#endif
 

	
 
#include <libxml/xpath.h>
 
#include <libxml/xmlreader.h>
 

	
 
#if defined(Q_OS_MAC)
 
#define PREFIX "cmd"
 
#else
 
#define PREFIX "crtl"
 
#endif
 

	
 
@@ -75,97 +75,97 @@ class FigureEditor : public QGraphicsVie
 
  void FullRedraw(void);
 

	
 
 protected:
 
  void mousePressEvent(QMouseEvent*);
 
  void mouseMoveEvent(QMouseEvent*);
 
  void mouseReleaseEvent(QMouseEvent*);
 
  void wheelEvent(QWheelEvent *event);
 
  void scaleView(qreal scaleFactor);
 

	
 
  vector <CellItem *> getIntersectedCells(void);
 
  void insertNode(QPointF p);
 
  NodeItem *selectedNodeItem(QList<QGraphicsItem *> l) const;  
 

	
 
 signals:
 
  void status(const QString&);
 
  void MousePressed(void);
 
  void MouseReleased(void);
 
 protected:
 
  Mesh &mesh;
 

	
 
 private:
 
  //NodeItem* moving;
 
  SimItemBase *moving;
 
  QPointF moving_start;
 

	
 
  QGraphicsLineItem *intersection_line;
 
  bool rotation_mode;
 
  bool insert_mode;
 
  double rot_angle;
 
};
 

	
 
class Main : public Q3MainWindow, public MainBase {
 
  Q_OBJECT
 
    friend class ModelCatalogue; // needs to populate menu item models
 
 public:
 
  Main(QGraphicsScene&, Mesh&, QWidget* parent=0, const char* name=0, Qt::WFlags f=0);
 
  ~Main();
 
  virtual bool ShowCentersP(void) {return view->isItemChecked(com_id);}
 
  virtual bool ShowMeshP(void) {return view->isItemChecked(mesh_id);}
 
  virtual bool ShowBorderCellsP(void) {return view->isItemChecked(border_id);}
 
  virtual bool PausedP(void) {return run->isItemChecked(paused_id);}
 
  virtual bool ShowNodeNumbersP(void) {return view->isItemChecked(node_number_id);}
 
  virtual bool ShowCellNumbersP(void) {return view->isItemChecked(cell_number_id);}
 
  virtual bool ShowCellAxesP(void) {return view->isItemChecked(cell_axes_id);}
 
  virtual bool ShowCellStrainP(void) {return view->isItemChecked(cell_strain_id);}
 
  virtual bool MovieFramesP(void) {return view->isItemChecked(movie_frames_id);}
 
  virtual bool ShowBoundaryOnlyP(void) {return view->isItemChecked(only_boundary_id);}
 
  virtual bool ShowWallsP(void) {return view->isItemChecked(cell_walls_id);}
 
  virtual bool ShowApoplastsP(void) { return view->isItemChecked(apoplasts_id);}
 
 // virtual bool ShowApoplastsP(void) { return view->isItemChecked(apoplasts_id);}
 
  virtual bool ShowFluxesP(void) { return view->isItemChecked(fluxes_id); }
 
  virtual bool DynamicCellsP(void) { return options->isItemChecked(dyn_cells_id); }
 
  virtual bool RotationModeP(void) { return options->isItemChecked(rotation_mode_id); }
 
  virtual bool InsertModeP(void) { return options->isItemChecked(insert_mode_id); }
 
  virtual bool ShowToolTipsP(void) { return helpmenu->isItemChecked(tooltips_id); }
 
  virtual bool HideCellsP(void) { return view->isItemChecked(hide_cells_id); }
 
  void scale(double factor); 
 
  virtual double getFluxArrowsize(void)
 
  {
 
    return flux_arrow_size;
 
  }
 

	
 
  void FitCanvasToWindow();
 
  void FitLeafToCanvas(void);
 

	
 

	
 
  public slots:
 

	
 
  void about();
 
  void gpl();
 
  void TimeStepWrap();
 
  void togglePaused();
 
  void setFluxArrowSize(int size);
 
  void RestartSim(void);
 
  void toggleShowCellCenters(void);
 
  void toggleShowNodes(void);
 
  void toggleShowBorderCells(void);
 
  void toggleShowFluxes(void);
 
  void toggleNodeNumbers(void);
 
  void toggleCellNumbers(void);
 
  void toggleCellAxes(void);
 
  void toggleCellStrain(void);
 
  void toggleShowWalls(void);
 
  void toggleShowApoplasts(void);
 
  void toggleDynCells(void);
 
  void toggleMovieFrames(void);
 
  void toggleLeafBoundary(void);
 
  void toggleHideCells(void);
 
  void print();
 
  void startSimulation(void);
 
  void stopSimulation(void);
 
  void RefreshInfoBar(void);
 

	
 
  void EnterRotationMode(void)
 
  {
 

	
 
    UserMessage("Rotation mode. Click mouse to exit.");
 
    if (editor) {
 
@@ -211,69 +211,69 @@ class Main : public Q3MainWindow, public
 
  void savePars();
 
  void readPars();
 
  void clear();
 
  void init();
 
  virtual void CutSAM() { MainBase::CutSAM(); Refresh();}
 

	
 
  void enlarge();
 
  void shrink();
 
  void zoomIn();
 
  void zoomOut();
 

	
 
  void CleanMesh();
 
  void CleanMeshChemicals(void);
 
  void CleanMeshTransporters(void);
 

	
 
  void RandomizeMesh();
 

	
 
 signals:
 
  void SimulationDone(void);
 
  void ParsChanged(void);
 

	
 
 protected:
 
  Mesh &mesh;
 

	
 
 private:
 
  NodeSet *node_set;
 
  FigureEditor *editor;
 
  Q3PopupMenu* options;
 
  Q3PopupMenu *view;
 
  Q3PopupMenu *run;
 
  QMenu *modelmenu;
 
  Q3PopupMenu *helpmenu;
 

	
 
  QPrinter* printer;
 
  const QDir *working_dir;
 
  QString currentFile;
 
  //  toggle item states 
 
  int dbf_id; // options->Double Buffer
 
  int com_id; // view->Show centers
 
  int mesh_id; // view->Show mesh
 
  int node_number_id; // view->Show Node numbers
 
  int cell_number_id; // view->Show Cell numbers
 
  int border_id; // view->Show border cells
 
  int paused_id; // run->Simulation paused
 
  int cell_axes_id; // view->Show cell axes
 
  int cell_strain_id; // view->Show cell strain
 
  int only_boundary_id; // view ->Show only leaf boundary
 
  int cell_walls_id; // view -> Show transporters
 
  int apoplasts_id; // view -> Show apoplasts
 
  //int apoplasts_id; // view -> Show apoplasts
 
  int tooltips_id; // help -> Show Cell Info
 
  int hide_cells_id; // view->Hide Cells
 
  double flux_arrow_size;
 
  int movie_frames_id;
 
  int fluxes_id;
 
  int dyn_cells_id;
 
  int rotation_mode_id;
 
  int insert_mode_id;
 
  QTimer *timer;
 
  QFile *gifanim;
 
  bool running;
 
  virtual xmlNode *XMLSettingsTree(void);
 
  static const QString caption;
 
  static const QString caption_with_file;
 
  InfoBar *infobar;
 
};
 

	
 
#endif
 

	
 
/* finis*/
src/cell.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <QDebug>
 

	
 
#include <string>
 
#include "cell.h"
 
#include "node.h"
 
#include "mesh.h"
 
#include "tiny.h"
 
#include "nodeset.h"
 
#include "cellitem.h"
 
#include "nodeitem.h"
 
#include "qcanvasarrow.h"
 
#include "parameter.h"
 

	
 

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

	
 
extern Parameter par;
 

	
 
double Cell::factor=1.;
 
double Cell::offset[3]={0,0,0};
 

	
 
Cell::Cell(void) : CellBase()
 
{
 
  m=0;
 
}
 

	
 
Cell::Cell(double x, double y, double z) : CellBase(x,y,z)
 
{
 
  m=0;
 
}
 

	
 
Cell::Cell(const Cell &src) :  CellBase(src)
 
{
 
  m=src.m;
 
}
 

	
 
bool Cell::Cmp(Cell *c) const { return this->Index() < c->Index(); }
src/cell.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#ifndef _CELL_H_
 
#define _CELL_H_
 

	
 
#include <list>
 
#include <vector>
 
#include <iostream>
 
#include <QString>
 
#include "vector.h"
 
#include "parameter.h"
 
#include "wall.h"
 
#include "warning.h"
 
#include "cellbase.h"
 
#include "cell.h"
 

	
 
#include <QGraphicsScene>
 
#include <qcolor.h>
 
#include <QObject>
 

	
 
#include <libxml/parser.h>
 
#include <libxml/tree.h>
 
#include <QMouseEvent>
 

	
 
class Cell : public CellBase 
 
{
 

	
 
  Q_OBJECT
 
    friend class Mesh;
 
  friend class FigureEditor;
 

	
 
 public:
 
  Cell(double x, double y, double z = 0.);
 
  Cell(void);
 
  Cell(const Cell &src);
 
  Cell operator=(const Cell &src);
 
  bool Cmp(Cell*) const;
 
  bool Eq(Cell*) const;
 

	
src/cellbase.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <cmath>
 
#include <string>
 
#include <sstream>
 
#include <vector>
 
#include <algorithm>
 
#include <functional>
 
#ifdef QTGRAPHICS
 
#include <QGraphicsScene>
 
#include <qpainter.h>
 
#include <qcolor.h>
 
#include <qfont.h>
 
#include <qwidget.h>
 
//Added by qt3to4:
 
#include <Q3PointArray>
 
#include <fstream>
 
#include "nodeitem.h"
 
#include "cellitem.h"
 
#include "qcanvasarrow.h"
 
#endif
 
#include "nodeset.h"
 

	
 
#include "cellbase.h"
 
#include "wall.h"
 
#include "random.h"
 
#include "parameter.h" 
 
#include "mesh.h"
 
#include "sqr.h"
 
#include "tiny.h"
 

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

	
 
extern Parameter par;
 

	
 
const char* CellBase::boundary_type_names[4] = {"None", "NoFlux", "SourceSink", "SAM"};
 

	
 
#ifndef VLEAFPLUGIN
 
CellsStaticDatamembers *CellBase::static_data_members = new CellsStaticDatamembers();
 
@@ -91,97 +91,97 @@ CellBase::CellBase(QObject *parent) :
 
  marked = false;
 
  dead = false;
 
  div_counter=0;
 
  cell_type = 0;
 
  flag_for_divide = false;
 
  division_axis = 0;
 
}
 

	
 

	
 
CellBase::CellBase(double x,double y,double z) : QObject(), Vector(x,y,z)
 
{
 
#ifndef VLEAFPLUGIN
 
  if (static_data_members == 0) {
 
    static_data_members = new CellsStaticDatamembers();
 
  }
 
#endif
 
  chem=new double[NChem()];
 
  for (int i=0;i<NChem();i++) {
 
    chem[i]=0.;
 
  }
 
  new_chem=new double[NChem()];
 
  for (int i=0;i<NChem();i++) {
 
    new_chem[i]=0.;
 
  }
 
  boundary=None;
 
  area=0.;
 
  target_area=1;
 
  target_length=0; //par.target_length;
 
  lambda_celllength=0; // par.lambda_celllength;
 

	
 
  index=(NCells()++);
 

	
 
  intgrl_xx=0.; intgrl_xy=0.; intgrl_yy=0.;
 
  intgrl_x=0.; intgrl_y=0.;
 

	
 
  source = false;
 
  fixed = false;
 
  at_boundary=false;
 
  pin_fixed = false;
 
  stiffness = 0;
 
  marked=false;
 
  dead  = false;
 
  div_counter = 0;
 
  cell_type = 0;
 
  flag_for_divide = false;
 
  division_axis = 0;
 
}
 

	
 
CellBase::CellBase(const CellBase &src) :  Vector(src), QObject()
 
CellBase::CellBase(const CellBase &src) :  QObject(), Vector(src)
 
{
 

	
 
  chem=new double[NChem()];
 
  for (int i=0;i<NChem();i++) {
 
    chem[i]=src.chem[i];
 
  }
 
  new_chem=new double[NChem()];
 
  for (int i=0;i<NChem();i++) {
 
    new_chem[i]=src.new_chem[i];
 
  }
 
  boundary=src.boundary;
 
  area=src.area;
 
  target_length=src.target_length;
 
  lambda_celllength=src.lambda_celllength;
 

	
 
  intgrl_xx=src.intgrl_xx; intgrl_xy=src.intgrl_xy; intgrl_yy=src.intgrl_yy;
 
  intgrl_x=src.intgrl_x; intgrl_y=src.intgrl_y;
 

	
 
  target_area=src.target_area;
 
  index=src.index;
 
  nodes=src.nodes;
 
  neighbors=src.neighbors;
 
  walls=src.walls;
 
  source = src.source;
 
  fixed = src.fixed;
 
  source_conc = src.source_conc;
 
  source_chem = src.source_chem;
 
  cellvec = src.cellvec;
 
  at_boundary=src.at_boundary;
 
  pin_fixed = src.pin_fixed;
 
  stiffness = src.stiffness;
 
  marked = src.marked;
 
  dead = src.dead;
 
  cell_type = src.cell_type;
 
  div_counter = src.div_counter;
 
  flag_for_divide = src.flag_for_divide;
 
  division_axis = src.division_axis;
 
}
 

	
 

	
 
CellBase CellBase::operator=(const CellBase &src)
 
{
 
  Vector::operator=(src);
 

	
 
  for (int i=0;i<NChem();i++) {
 
    chem[i]=src.chem[i];
 
  }
 
  for (int i=0;i<NChem();i++) {
src/cellbase.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
// CellBase derives from Vector, where Vector is simply used as a Vertex
 

	
 
#ifndef _CELLBASE_H_
 
#define _CELLBASE_H_
 

	
 
#include <list>
 
#include <vector>
 
#include <iostream>
 
#include <QString>
 
#include <QDebug>
 

	
 
#include "vector.h"
 
#include "parameter.h"
 
#include "wall.h"
 
#include "warning.h"
 
#include "assert.h"
 

	
 
extern Parameter par;
 
using namespace std;
 

	
 
class Mesh;
 
class Node;
 
class CellBase;
 
class NodeSet;
 

	
 
struct ParentInfo {
 

	
 
  Vector polarization;
 
  double PINmembrane;
 
  double PINendosome;
 
};
 

	
 
// We need a little trick here, to make sure the plugin and the main application will see the same static datamembers
 
// otherwise each have their own instantation.
 
// My solution is as follow. I collect all original statics in a class. The main application instantiates it and
 
// My solution is as follows. I collect all original statics in a class. The main application instantiates it and
 
// has a static pointer to it. After loading the plugin I set a static pointer to the same class 
 
class CellsStaticDatamembers {
 

	
 
 public:
 
  CellsStaticDatamembers(void) {
 
    ncells = 0;
 
    nchem = 0;
 
    base_area = 0.;
 
  }
 
  ~CellsStaticDatamembers() {
 
#ifdef QDEBUG
 
    qDebug() << "Oops! Desctructor of CellsStaticDatamembers called" << endl;
 
#endif
 
  }
 
  int ncells;
 
  int nchem;
 
  double base_area;
 
};
 

	
 
class CellBase :  public QObject, public Vector 
 
{
 

	
 
  Q_OBJECT
 

	
 
  friend class Mesh;
 
  friend class CellInfo;
 
  friend class Node;
 
  friend class WallBase;
 
  friend class SimPluginInterface;
 

	
 
 public:
 
  CellBase(QObject *parent=0);
 
  CellBase(double x,double y,double z=0); // constructor
 

	
 
  virtual ~CellBase() {
 
    delete[] chem;
 
    delete[] new_chem;
 
    if (division_axis) delete division_axis;
 
    //cerr << "CellBase " << index << " is dying. " << endl;
 
  }
 

	
 
  CellBase(const CellBase &src); // copy constructor
 
  virtual bool BoundaryPolP(void) const { return false; } 
 

	
 

	
 
  CellBase operator=(const CellBase &src); // assignment operator
 
  CellBase operator=(const Vector &src);
 

	
src/cellitem.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include<QGraphicsScene>
 
#include "cellitem.h"
 

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

	
 
CellItem::CellItem( Cell *c, QGraphicsScene *canvas )
 
  : QGraphicsPolygonItem( 0, canvas ), SimItemBase( c, canvas){
 
}
 

	
 
void CellItem::userMove(double dx, double dy)
 
{
 
  QGraphicsPolygonItem::moveBy( dx, dy );
 

	
 
  // also move the cell itself
 
  class_cast<Cell *>(obj)->x += (dx/Cell::Magnification());
 
  class_cast<Cell *>(obj)->y += (dy/Cell::Magnification());
 

	
 
  class_cast<Cell*>(obj)->Move( (dx/Cell::Magnification()), (dy/Cell::Magnification()) );
 
}
 

	
 
QPainterPath CellItem::shape() const { return QGraphicsPolygonItem::shape(); }
 
QRectF CellItem::boundingRect() const { return QGraphicsPolygonItem::boundingRect(); }
 

	
 

	
 
/* finis */
src/cellitem.h
Show inline comments
 
/*
 
 *  VirtualLeaf
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#ifndef _CELLITEM_H_
 
#define _CELLITEM_H_
 

	
 
#include <QGraphicsScene>
 
#include <QGraphicsPolygonItem>
 
#include <QPainter>
 
#include "simitembase.h"
 
#include "cell.h"
 

	
 

	
 
class CellItem : public QGraphicsPolygonItem, public SimItemBase
 
{
 
 public:
 
  CellItem( Cell *n, QGraphicsScene *canvas );
 
  virtual ~CellItem() {}
 
  Cell &getCell(void) const { return *class_cast<Cell*>(obj); }
 
  virtual void userMove(double dx, double dy);  
 
  QPainterPath shape() const;
 
  QRectF boundingRect() const;
 

	
 
 private:
 
};
 

	
 
#endif
 

	
 
/* finis */
src/forwardeuler.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <cmath>
 
#include <iostream> 
 
#include "forwardeuler.h"
 
#include "warning.h"
 
#include "maxmin.h"
 
#include <string>
 

	
 
using namespace std;
 

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

	
 
// The value Errcon equals (5/Safety) raised to the power (1/PGrow), see use below.
 

	
 
const double ForwardEuler::Safety  = 0.9;
 
const double ForwardEuler::PGrow = -0.2;
 
const double ForwardEuler::Pshrnk = -0.25;
 
const double ForwardEuler::Errcon = 1.89e-4;
 
const double ForwardEuler::Maxstp = 10000000;
 
const double ForwardEuler::Tiny = 1.0e-30;
 

	
 

	
 

	
 
/* User storage for intermediate results. Preset kmax and dxsav in the calling program. If kmax =
 
   0 results are stored at approximate intervals dxsav in the arrays xp[1..kount], yp[1..nvar]
 
   [1..kount], where kount is output by odeint. Defining declarations for these variables, with
 
   memoryallo cations xp[1..kmax] and yp[1..nvar][1..kmax] for the arrays, should be in
 
   the calling program.*/
 

	
 
void ForwardEuler::odeint(double *ystart, int nvar, double x1, double x2, double eps, double h1, double hmin, int *nok, int *nbad)
 
/* Runge-Kutta driver with adaptive stepsize control. Integrate starting values ystart[1..nvar]
 
   from x1 to x2 with accuracy eps, storing intermediate results in global variables. h1 should
 
   be set as a guessed first stepsize, hmin as the minimum allowed stepsize (can be zero). On
 
   output nok and nbad are the number of good and bad (but retried and fixed) steps taken, and
 
   ystart is replaced byv alues at the end of the integration interval. derivs is the user-supplied
 
   routine for calculating the right-hand side derivative, while rkqs is the name of the stepper
 
   routine to be used. */
 
{
src/forwardeuler.h
Show inline comments
 
/*
 
 *  VirtualLeaf
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#ifndef _FORWARDEULER_H_
 
#define _FORWARDEULER_H_
 

	
 
class ForwardEuler  {
 

	
 
 public:
 
  ForwardEuler(void) {
 
    kmax=kount=0;
 
    dxsav=0.;
 
    xp=0;
 
    yp=0;
 
  }
 

	
 
  virtual ~ForwardEuler() {}
 

	
 
  void odeint(double ystart[], int nvar, double x1, double x2, double eps, double h1,
 
	      double hmin, int *nok, int *nbad);
 

	
 
  // implement this function in a derived class
 
 protected:
 
  virtual void derivs(double x, double *y, double *dxdy) = 0;
 
  int kmax,kount;
 
  double *xp,**yp,dxsav;
 

	
 
 private:
 

	
 
  static const double Safety;
 
  static const double PGrow;
 
  static const double Pshrnk;
 
  static const double Errcon;
 
  static const double Maxstp;
 
  static const double Tiny;
 
};
 
#endif
 

	
 
/* finis */
src/infobar.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _INFOBAR_H_
 
#define _INFOBAR_H_
 

	
 

	
 
#include <q3mainwindow.h>
 
#include <QLabel>
 
#include <QBoxLayout>
 

	
 
class InfoBar : public Q3DockWindow {
 

	
 
  Q_OBJECT
 
    public:
 

	
 
  InfoBar(void) : Q3DockWindow() { 
 

	
 
    virtleaf = new QLabel();
 
    SetText("undefined");
 

	
 
    setHorizontalStretchable(true);
 
    boxLayout()->addStretch();
 
    boxLayout()->addWidget(virtleaf);//, Qt::AlignHCenter);
 
    boxLayout()->addStretch();
 
  }
 

	
 
  void SetText(QString text) {
 
    virtleaf->setText(QString("<h1>The Virtual Leaf</h1>\n<center><b>Model:</b> <i>%1</i></center>").arg(text));
 
    virtleaf->setText(QString("<h1>VirtualLeaf</h1>\n<center><b>Model:</b> <i>%1</i></center>").arg(text));
 
  }
 

	
 
 private:
 
  QLabel *virtleaf;
 
};
 

	
 
#endif
 

	
 
/* finis */
src/libplugin.pro
Show inline comments
 
#
 
#  $Id$
 
#
 
#  This file is part of the Virtual Leaf.
 
#
 
#  The Virtual Leaf is free software: you can redistribute it and/or modify
 
#  it under the terms of the GNU General Public License as published by
 
#  the Free Software Foundation, either version 3 of the License, or
 
#  (at your option) any later version.
 
#
 
#  The Virtual Leaf is distributed in the hope that it will be useful,
 
#  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
#  GNU General Public License for more details.
 
#
 
#  You should have received a copy of the GNU General Public License
 
#  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
#
 
#  Copyright 2010 Roeland Merks.
 
#
 

	
 
CONFIG += release
 
CONFIG -= debug
 
CONFIG += staticlib
 

	
 
QMAKE_CXXFLAGS += -fexceptions
 
win32:QMAKE_CXXFLAGS -= O2
 
QMAKE_CXXFLAGS_DEBUG += -g3
 
QMAKE_CXXFLAGS_DEBUG += -DQDEBUG
 
QMAKE_CXXFLAGS_DEBUG -= -finstrument-functions
 

	
 
DEFINES = QTGRAPHICS # VLEAFPLUGIN
 
DESTDIR = ../lib 
 
PARTMPL = VirtualLeafpar.tmpl
 
QT += qt3support
 
TARGET = vleaf
 
TEMPLATE = lib
 

	
 
HEADERS = \
 
 cellbase.h \
 
 matrix.h \
 
 output.h \
 
 parameter.h \
 
 parse.h \
 
 random.h \
 
 simplugin.h \
 
 UniqueMessage.h \
 
 vector.h \
 
 wallbase.h \
 
 warning.h
 

	
 
SOURCES = \
 
 cellbase.cpp \
 
 matrix.cpp \
 
 output.cpp \
 
 parameter.cpp \
 
 parse.cpp \
 
 random.cpp \
 
 simplugin.cpp \
 
 UniqueMessage.cpp \
 
 vector.cpp \
 
 wallbase.cpp \
 
 warning.cpp
 

	
 
unix {
 
 QMAKE_CXXFLAGS += -fPIC -I/usr/include/libxml2
 
 QMAKE_LFLAGS += -fPIC
 
 LIBS += -lxml2 -lz -lm 
 
}
 

	
 
win32 {
 
 LIBXML2DIR = ..\lib\libxml2
 
 LIBICONVDIR = ..\lib\libiconv
 
 LIBZDIR = ..\lib\libz
 
 QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
 LIBXML2DIR = C:
 
 LIBICONVDIR = C:
 
 LIBZDIR = C:
 
# QMAKE_CXXFLAGS += -DLIBXML_STATIC
 
 QMAKE_CXXFLAGS += -I$${LIBXML2DIR}\include -I$${LIBICONVDIR}\include -I$${LIBZDIR}\include
 
}
 

	
 
#
src/mainbase.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <libxml/xpath.h>
 
#include <libxml/xmlreader.h>
 

	
 
#include "mainbase.h"
 
#include "xmlwrite.h"
 

	
 
#include <sstream>
 
#include <string>
 

	
 
#include <QLocale>
 

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

	
 
xmlNode *MainBase::XMLViewportTree(QTransform &transform) const {
 
  
 
  QLocale standardlocale(QLocale::C);
 
  
 

	
 
  xmlNode *xmlviewport = xmlNewNode(NULL, BAD_CAST "viewport");
 
  {
 
    xmlNewProp(xmlviewport, BAD_CAST "m11", BAD_CAST standardlocale.toString(transform.m11()).toStdString().c_str() );
 
    xmlNewProp(xmlviewport, BAD_CAST "m12", BAD_CAST standardlocale.toString(transform.m12()).toStdString().c_str() );    
 
    xmlNewProp(xmlviewport, BAD_CAST "m21", BAD_CAST standardlocale.toString(transform.m21()).toStdString().c_str() );    
 
    xmlNewProp(xmlviewport, BAD_CAST "m22", BAD_CAST standardlocale.toString(transform.m22()).toStdString().c_str() );    
 
    xmlNewProp(xmlviewport, BAD_CAST "dx", BAD_CAST standardlocale.toString(transform.dx()).toStdString().c_str() );    
 
    xmlNewProp(xmlviewport, BAD_CAST "dy", BAD_CAST standardlocale.toString(transform.dy()).toStdString().c_str() );    
 
 }
 
  
 
  return xmlviewport;
 
}
 

	
 
xmlNode *MainBase::XMLSettingsTree(void) const {
 

	
 
  xmlNode *xmlsettings = xmlNewNode(NULL, BAD_CAST "settings");
 
  {
 
    xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL);
 
    xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_cell_centers");
 
@@ -71,103 +71,103 @@ xmlNode *MainBase::XMLSettingsTree(void)
 
    xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL);
 
    xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_node_numbers");
 
    ostringstream text;
 
    text << bool_name(shownodenumbersp);
 
    xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL);
 
    xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_cell_numbers");
 
    ostringstream text;
 
    text << bool_name(showcellnumbersp);
 
    xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL);
 
    xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_border_cells");
 
    ostringstream text;
 
    text << bool_name(showbordercellp);
 
    xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL);
 
    xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_cell_axes");
 
    ostringstream text;
 
    text << bool_name(showcellsaxesp);
 
    xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL);
 
    xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_cell_strain");
 
    ostringstream text;
 
    text << bool_name(showcellstrainp);
 
    xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL);
 
    xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_fluxes");
 
    ostringstream text;
 
    text << bool_name(showfluxesp);
 
    xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL);
 
    xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_walls");
 
    ostringstream text;
 
    text << bool_name(showwallsp);
 
    xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str());
 
  }
 
  {
 
 /* {
 
    xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL);
 
    xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_apoplasts");
 
    ostringstream text;
 
    text << bool_name(showapoplastsp);
 
    xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str());
 
  }
 
  }*/
 
  {
 
    xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL);
 
    xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "save_movie_frames");
 
    ostringstream text;
 
    text << bool_name(movieframesp);
 
    xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL);
 
    xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "show_only_leaf_boundary");
 
    ostringstream text;
 
    text << bool_name(showboundaryonlyp);
 
    xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL);
 
    xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "cell_growth");
 
    ostringstream text;
 
    text << bool_name(dynamicscellsp);
 
    xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str());
 
  }
 
  {
 
    xmlNode *xmloption = xmlNewChild(xmlsettings, NULL, BAD_CAST "setting", NULL);
 
    xmlNewProp(xmloption, BAD_CAST "name", BAD_CAST "hide_cells");
 
    ostringstream text;
 
    text << bool_name(hidecellsp);
 
    xmlNewProp(xmloption, BAD_CAST "val", BAD_CAST text.str().c_str());
 
  }
 
  return xmlsettings;
 
}
 

	
 
void MainBase::XMLReadViewport(xmlNode *settings) {
 

	
 
  if (settings == 0) {
 
    return;
 
  }
 

	
 
  qreal m11=25,m12=0,m21=0,m22=25,dx=0,dy=0;
 
  QLocale standardlocale(QLocale::C);
 
  xmlNode *cur = settings->xmlChildrenNode;
 

	
 
  while (cur!=NULL) {
 
    
 
    if (!xmlStrcmp(cur->name,(const xmlChar *)"viewport")) {
 
      bool ok;
 
      {
 
	xmlChar *v_str = xmlGetProp(cur, BAD_CAST "m11");
 
	
 
@@ -247,99 +247,99 @@ void MainBase::XMLReadViewport(xmlNode *
 
}
 

	
 
void MainBase::XMLReadSettings(xmlNode *settings)
 
{
 

	
 
  // Many files have no settings section, so don't complain about it.
 
  // Defaults will be used instead.
 
  if (settings == 0) {
 
    return;
 
  }
 

	
 
  XMLReadViewport(settings);
 
  xmlNode *cur = settings->xmlChildrenNode;
 

	
 
  while (cur!=NULL) {
 

	
 
    if ((!xmlStrcmp(cur->name, (const xmlChar *)"setting"))){
 

	
 
      xmlChar *name = xmlGetProp(cur, BAD_CAST "name");
 
    
 
      xmlChar *val = xmlGetProp(cur, BAD_CAST "val");
 
      if (!xmlStrcmp(name, (const xmlChar *)"show_cell_centers")) {
 
	showcentersp = strtobool( (const char *)val );
 
      }
 
      if (!xmlStrcmp(name, (const xmlChar *)"show_nodes")) {
 
	showmeshp = strtobool( (const char *)val );
 
      }
 
      if (!xmlStrcmp(name, (const xmlChar *)"show_node_numbers")) {
 
	shownodenumbersp = strtobool( (const char *)val );
 
      }
 
      if (!xmlStrcmp(name, (const xmlChar *)"show_cell_numbers")) {
 
	showcellnumbersp = strtobool( (const char *)val );
 
      }
 
      if (!xmlStrcmp(name, (const xmlChar *)"show_border_cells")) {
 
	showbordercellp = strtobool( (const char *)val );
 
      }
 
      if (!xmlStrcmp(name, (const xmlChar *)"show_cell_axes")) {
 
	showcellsaxesp = strtobool( (const char *)val );
 
      }
 
      if (!xmlStrcmp(name, (const xmlChar *)"show_cell_strain")) {
 
	showcellstrainp = strtobool( (const char *)val );
 
      }
 
      if (!xmlStrcmp(name, (const xmlChar *)"show_fluxes")) {
 
	showfluxesp = strtobool( (const char *)val );
 
      }
 
      if (!xmlStrcmp(name, (const xmlChar *)"show_walls")) {
 
	showwallsp = strtobool( (const char *)val );
 
      }
 
      if (!xmlStrcmp(name, (const xmlChar *)"show_apoplasts")) {
 
     /* if (!xmlStrcmp(name, (const xmlChar *)"show_apoplasts")) {
 
	showapoplastsp = strtobool( (const char *)val );
 
      }
 
      }*/
 
      if (!xmlStrcmp(name, (const xmlChar *)"save_movie_frames")) {
 
	movieframesp = strtobool( (const char *)val );
 
      }
 
      if (!xmlStrcmp(name, (const xmlChar *)"show_only_leaf_boundary")) {
 
	showboundaryonlyp = strtobool( (const char *)val );
 
      }
 
      if (!xmlStrcmp(name, (const xmlChar *)"cell_growth")) {
 
	dynamicscellsp = strtobool( (const char *)val );
 
      }
 
      if (!xmlStrcmp(name,(const xmlChar *)"hide_cells")) {
 
	hidecellsp = strtobool( (const char *)val ); 
 
      }
 
    
 
	
 
  
 
      xmlFree(name);
 
      xmlFree(val);
 
    }
 
    cur=cur->next;
 
  }
 
}
 

	
 
void MainBase::Save(const char *fname, const char *format, int sizex, int sizey)
 
{
 

	
 
  Vector ll,ur;
 
  mesh.BoundingBox(ll, ur);
 

	
 
  if (QString(fname).isEmpty()) {
 
    MyWarning::warning("No output filename given. Saving nothing.\n");
 
    return;
 
  }
 

	
 
  ll*=Cell::Magnification(); ur*=Cell::Magnification();
 

	
 
  // give the leaf some space
 
  Vector border = ((ur-ll)/5.);
 

	
 
  if (!QString(format).contains("pdf", Qt::CaseInsensitive)) {
 

	
 
    QImage *image = new QImage(QSize(sizex, sizey), QImage::Format_RGB32);
 
    image->fill(QColor(Qt::white).rgb());
 
    QPainter *painter=new QPainter(image);
 
    canvas.render(painter);
 
    if (!image->save(QString(fname))) {
 
      MyWarning::warning("Image not saved successfully. Is the disk full or the extension not recognized?");
 
    };
 
    delete painter;
src/mainbase.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _MAINBASE_H_
 
#define _MAINBASE_H_
 

	
 
#include <QGraphicsScene>
 
#include <qpixmap.h>
 
#include <q3picture.h>
 
#include <qpainter.h>
 
#include <qwidget.h>
 
#include <iostream>
 
#include <QGraphicsItem>
 
#include <QPrinter>
 
#include "mesh.h"
 
#include "warning.h"
 

	
 
using namespace std;
 

	
 
/*! Implement these functions in your main application */
 
class MainBase  {
 

	
 
 public:
 
 MainBase(QGraphicsScene &c, Mesh &m) : mesh(m), canvas(c) {
 

	
 
    // Standard options for batch version
 
    showcentersp =  false;
 
    showmeshp =  false;
 
    showbordercellp =  false;
 
    shownodenumbersp =  false;
 
    showcellnumbersp =  false;
 
    showcellsaxesp = false;
 
    showcellstrainp =  false;
 
    movieframesp = true;
 
    showboundaryonlyp =  false;
 
    showwallsp =  false;
 
    showfluxesp = false;
 
    dynamicscellsp = true;
 
    showtooltipsp = false;
 
    hidecellsp = false;
 
  }
 
  virtual ~MainBase() {};
 

	
 
  virtual double TimeStep();
 
  virtual void Init(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; }
 
  virtual bool ShowCellNumbersP(void) {return showcellnumbersp;}
 
  virtual bool ShowCellAxesP(void) {return showcellsaxesp;}
 
  virtual bool ShowCellStrainP(void) {return showcellstrainp;}
 
  virtual bool MovieFramesP(void) {return movieframesp;}
 
  virtual bool ShowBoundaryOnlyP(void) {return showboundaryonlyp;}
 
  virtual bool ShowToolTipsP(void) {return showtooltipsp;}
 
  virtual bool ShowWallsP(void) {return showwallsp;}
 
  virtual bool ShowApoplastsP(void) { return showapoplastsp;}
 
 // virtual bool ShowApoplastsP(void) { return showapoplastsp;}
 
  virtual bool ShowFluxesP(void) { return showfluxesp; }
 
  virtual bool DynamicCellsP(void) { return dynamicscellsp; }
 
  virtual void FitCanvasToWindow() {};
 
  virtual void FitLeafToCanvas() {};
 
  virtual bool HideCellsP(void) { return hidecellsp; }
 
  virtual void clear(void) {
 
    QList<QGraphicsItem *> list = canvas.items();
 
    QList<QGraphicsItem *>::Iterator it = list.begin();
 
    for (; it != list.end(); ++it) {
 
      if ( *it )
 
	delete *it;
 
    }
 
  };
 
  virtual void XMLReadSettings(xmlNode *settings);
 
  virtual void XMLReadViewport(xmlNode *viewport);
 

	
 
  virtual double getFluxArrowsize(void) { return 10.;}
 

	
 
  void Save(const char *fname, const char *format, int sizex=640, int sizey=480);
 
  void CutSAM(void);
 

	
 
  void Plot(int resize_stride=10);
 

	
 
  virtual void UserMessage(QString message, int timeout = 0) {
 
    cerr << message.toAscii().constData() << endl;
 
  }
 

	
 
  Mesh &mesh;
 
  QTransform viewport;
 

	
 
 protected:
 
  QGraphicsScene &canvas;
 
  virtual xmlNode *XMLSettingsTree(void) const;
 
  virtual xmlNode *XMLViewportTree(QTransform &transform) const;
 
  
 
 protected:
 
  bool showcentersp;
 
  bool showmeshp;
 
  bool showbordercellp;
 
  bool shownodenumbersp;
 
  bool showcellnumbersp;
 
  bool showcellsaxesp;
 
  bool showcellstrainp;
 
  bool movieframesp;
 
  bool showboundaryonlyp;
 
  bool showwallsp;
 
  bool showapoplastsp;
 
//  bool showapoplastsp;
 
  bool showfluxesp;
 
  bool dynamicscellsp;
 
  bool showtooltipsp;
 
  bool hidecellsp;
 
};
 

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

	
 
#endif
 

	
 
/* finis */
src/matrix.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include <ostream>
 
#include <cmath>
 
#include "vector.h"
 
#include "matrix.h"
 
#include "tiny.h"
 

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

	
 
Matrix::Matrix(const Vector &c1, const Vector &c2, const Vector &c3) {
 

	
 
  Alloc();
 

	
 
  mat[0][0]=c1.x; mat[0][1]=c2.x; mat[0][2]=c3.x;
 
  mat[1][0]=c1.y; mat[1][1]=c2.y; mat[1][2]=c3.y;
 
  mat[2][0]=c1.z; mat[2][1]=c2.z; mat[2][2]=c3.z;
 
}
 

	
 
void Matrix::Alloc(void)
 
{
 
  // constructor
 
  mat = new double*[3];
 
  mat[0] = new double[9];
 
  for (int i=1;i<3;i++)
 
    mat[i]=mat[i-1]+3;
 
}
 

	
 
Matrix::~Matrix()
 
{
 
  // destructor
 
  delete[] mat[0];
 
  delete[] mat;
 
}
 

	
 
Matrix::Matrix(void)
 
{
 
  // constructor
src/matrix.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _MATRIX_H_
 
#define _MATRIX_H_
 

	
 
// three by three matrix (mostly for changes of basis of the vector object)
 
class Vector;
 

	
 
class Matrix {
 

	
 
 public:
 
  Matrix(const Vector &v1,const Vector &v2, const Vector &v3); // constructor
 
  Matrix(void);
 
  ~Matrix(); // destructor
 

	
 
  void print(ostream *os);
 
  Matrix(const Matrix &source); // copy constructor
 
  void operator=(const Matrix &source); // assignment operator
 

	
 
  Vector operator*(const Vector &v) const; // matrix * vector
 
  bool operator==(Matrix &v) const; // comparison
 
  double Det(void) const; // gives the "determinant" (| m |) of m
 
  Matrix Inverse(void) const; // gives the inverse of m
 
  void Rot2D(double theta); // make a matrix doing a 2D rotation over theta
 
  // data members 
 
  double **mat;
 

	
 
 private:
 

	
 
  void Alloc(void);
 
};
 

	
 
ostream &operator<<(ostream &os, Matrix &v);
 

	
 
#endif
 

	
 
/* finis */
src/mesh.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include <algorithm>
 
#include <vector>
 
#include <sstream>
 
#include <cstdlib>
 
//#include <cerrno>
 
#include <cstring>
 
#include <numeric>
 
#include <functional>
 
#include <fstream>
 
#include <QPair>
 
#include "mesh.h"
 
#include "tiny.h"
 
#include "parameter.h"
 
#include "random.h"
 
#include "pi.h"
 
#include "parse.h"
 
#include "matrix.h"
 
#include "sqr.h"
 
#include "nodeset.h"
 
#include "nodeitem.h"
 
#include "simplugin.h"
 

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

	
 
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) {
 
  c->nodes.insert(ins_pos, n);        
 
  n->owners.push_back( Neighbor(c, nb1, nb2 ) );
 
}
 

	
 
@@ -435,198 +435,185 @@ public:
 
    iy=siy;
 
    ixx=sixx;
 
    ixy=sixy;
 
    iyy=siyy;
 
  }
 
};
 

	
 
void Mesh::Clear(void) {
 

	
 
  // clear nodes
 
  for (vector<Node *>::iterator i=nodes.begin(); i!=nodes.end(); i++) {
 
    delete *i;
 
  }
 

	
 
  nodes.clear();
 
  Node::nnodes=0;
 

	
 
  node_insertion_queue.clear();
 
  // Clear NodeSets
 
  for (vector<NodeSet *>::iterator i=node_sets.begin(); i!=node_sets.end(); i++) {
 
    delete *i;
 
  }
 

	
 
  node_sets.clear();
 
  time = 0;
 

	
 
  // clear cells
 

	
 
  for (vector<Cell *>::iterator i=cells.begin(); i!=cells.end(); i++) {
 
    delete *i;
 
  }
 

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

	
 
  delete boundary_polygon;
 

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

	
 
  walls.clear();
 
  WallBase::nwalls = 0;
 
  //tmp_walls->clear();
 

	
 
  shuffled_cells.clear();
 
  shuffled_nodes.clear();
 
  //Cell::ncells=0;
 
  /*    Cell::ClearNCells();
 
	Node::nnodes=0;
 

	
 
	cells.clear();
 
	nodes.clear();
 
	shuffled_cells.clear();
 
	shuffled_nodes.clear();
 
	node_insertion_queue.empty();
 

	
 
	cerr << "Meshed cleared: cells: " << cells.size() << ", nodes: " << nodes.size() << endl;
 
  */
 

	
 
 
 
#ifdef QDEBUG
 
  qDebug() << "cells.size() = " << cells.size() << endl;
 
  qDebug() << "walls.size() = " << walls.size() << endl;
 
  qDebug() << "nodes.size() = " << nodes.size() << endl;
 
#endif
 
}
 

	
 
double Mesh::DisplaceNodes(void) {
 

	
 
  MyUrand r(shuffled_nodes.size());
 
  random_shuffle(shuffled_nodes.begin(),shuffled_nodes.end(),r);
 

	
 
  double sum_dh=0;
 

	
 
  list<DeltaIntgrl> delta_intgrl_list;
 

	
 
  for_each( node_sets.begin(), node_sets.end(), mem_fun( &NodeSet::ResetDone ) );
 

	
 
  for (vector<Node *>::const_iterator i=shuffled_nodes.begin(); i!=shuffled_nodes.end(); i++) {
 

	
 
    //int n=shuffled_nodes[*i];
 
    Node &node(**i);
 

	
 
    // Do not allow displacement if fixed
 
    //if (node.fixed) continue;
 

	
 
    if (node.DeadP()) continue;
 

	
 
    // Attempt to move this cell in a random direction
 
    double rx=par.mc_stepsize*(RANDOM()-0.5); // was 100.
 
    double ry=par.mc_stepsize*(RANDOM()-0.5);
 

	
 
    // Uniform with a circle of radius par.mc_stepsize
 
    /* double r = RANDOM() * par.mc_stepsize;
 
       double th = RANDOM()*2*Pi;
 

	
 
       double rx = r * cos(th);
 
       double ry = r * sin(th);
 
    */
 
    Vector new_p(node.x+rx,node.y+ry,0);
 
    Vector old_p(node.x,node.y,0);
 

	
 
    /* if (node.boundary  && boundary_polygon->MoveSelfIntersectsP(n,  new_p )) {
 
    // reject if move of boundary results in self intersection
 
    continue;
 
    }*/
 

	
 

	
 
    if (node.node_set) {
 
      // move each node set only once
 
      if (!node.node_set->DoneP()) 
 
	node.node_set->AttemptMove(rx,ry);
 

	
 
    } else {
 

	
 
      // for all cells to which this node belongs:
 
      //   calculate energy difference
 

	
 
      double area_dh=0.;
 
      double length_dh=0.;
 
      double bending_dh=0.;
 
      double cell_length_dh=0.;
 
      double alignment_dh=0.;
 

	
 
      double old_l1=0.,old_l2=0.,new_l1=0.,new_l2=0.;
 

	
 
      double sum_stiff=0.;
 
      double dh=0.;
 

	
 
      for (list<Neighbor>::const_iterator cit=node.owners.begin(); cit!=node.owners.end(); cit++) {
 

	
 
	//Cell &c=m->getCell(cit->cell);
 
	//Cell &c=cit->cell->BoundaryPolP()?*boundary_polygon:*(cit->cell);
 
	
 
	Cell &c=*((Cell *)(cit->cell));
 
	//Cell &c=cells[cit->cell];
 

	
 
	if (c.MoveSelfIntersectsP(&node,  new_p )) {
 
		
 
	  // reject if move results in self intersection
 
	  //
 
	  // I know: using goto's is bad practice... except when jumping out
 
	  // of deeply nested loops :-)
 
	  //cerr << "Rejecting due to self-intersection\n";
 
	  goto next_node;
 
	}
 

	
 
	// summing stiffnesses of cells. Move has to overcome this minimum required energy.
 
	sum_stiff += c.stiffness;
 
	// area - (area after displacement): see notes for derivation
 
	//Vector i_min_1 = m->getNode(cit->nb1);
 

	
 
	
 
	Vector i_min_1 = *(cit->nb1);
 
	//Vector i_plus_1 = m->getNode(cit->nb2);
 
	Vector i_plus_1 = *(cit->nb2);
 

	
 

	
 
	// We must double the weights for the perimeter (otherwise they start bulging...)
 
	double w1, w2;
 
	if (node.boundary && cit->nb1->boundary) 
 
#ifdef FLEMING
 
	  w1 = par.rel_perimeter_stiffness;
 
#else
 
	w1=2;
 
#endif
 
	else
 
	  w1 = 1;
 

	
 
	if (node.boundary && cit->nb2->boundary) 
 
#ifdef FLEMING
 
	  w2 = par.rel_perimeter_stiffness;
 
#else
 
	w2 = 2;
 
#endif
 
	else 
 
	  w2 = 1;
 

	
 
	//if (cit->cell>=0) {
 
	if (!cit->cell->BoundaryPolP()) {
 
	  double delta_A = 0.5 * ( ( new_p.x - old_p.x ) * (i_min_1.y - i_plus_1.y) +
 
				   ( new_p.y - old_p.y ) * ( i_plus_1.x - i_min_1.x ) );
 

	
 
	  area_dh +=  delta_A * (2 * c.target_area - 2 * c.area + delta_A);
 

	
 

	
 
	  // cell length constraint
 
	  // expensive and not always needed
 
	  // so we check the value of lambda_celllength
 

	
 
	  if (/* par.lambda_celllength */  cit->cell->lambda_celllength) {
 

	
 
	    double delta_ix = 
 
	      (i_min_1.x + new_p.x)
 
	      * (new_p.x * i_min_1.y- i_min_1.x * new_p.y) +
 
	      (new_p.x + i_plus_1.x)
 
	      * (i_plus_1.x * new_p.y- new_p.x * i_plus_1.y) -
 

	
 
	      (i_min_1.x + old_p.x)
 
	      * (old_p.x * i_min_1.y- i_min_1.x * old_p.y) -
 
	      (old_p.x + i_plus_1.x)
 
@@ -732,191 +719,143 @@ double Mesh::DisplaceNodes(void) {
 
	    double lambda_b=rhs1+rhs2;
 

	
 

	
 
	    double new_celllength=4*sqrt(lambda_b/(c.area-delta_A));
 
	    //cerr << "new_celllength = "  << new_celllength << endl;
 
	    //cerr << "target_length = "  << c.target_length << endl;
 

	
 
	    cell_length_dh += c.lambda_celllength * ( DSQR(c.target_length - new_celllength) - DSQR(c.target_length-old_celllength) );
 

	
 
	    Vector norm_long_axis(lambda_b - ixx, ixy, 0);
 
	    norm_long_axis.Normalise();
 

	
 
	    double alignment_before = InnerProduct(old_axis, c.cellvec);
 
	    double alignment_after = InnerProduct(norm_long_axis, c.cellvec);
 

	
 
	    /* cerr << "Delta alignment = " << alignment_before - alignment_after << endl;
 
	       cerr << "Old alignment is " << alignment_before << ", new alignment is " << alignment_after << endl;
 
	       cerr << "Old axis is " << old_axis << ", new axis is " << norm_long_axis << endl; 
 
	    */
 
	    alignment_dh += alignment_before - alignment_after;
 

	
 
	    /* cerr << "alignment_dh  = " << alignment_dh << endl;
 
	       cerr << "cellvec = " << c.cellvec << endl;*/
 

	
 
	  } else {
 
	    // if we have no length constraint, still need to update area
 
	    delta_intgrl_list.push_back(DeltaIntgrl(delta_A,0,0,0,0,0));
 

	
 
	  }
 

	
 
	  old_l1=(old_p-i_min_1).Norm();
 
	  old_l2=(old_p-i_plus_1).Norm();
 
	  new_l1=(new_p-i_min_1).Norm();
 
	  new_l2=(new_p-i_plus_1).Norm();
 

	
 

	
 

	
 

	
 
	  static int count=0;
 
	  // Insertion of nodes (cell wall yielding)
 
	  if (!node.fixed) {
 
	    if (old_l1 > 4*Node::target_length && !cit->nb1->fixed) {
 
	      node_insertion_queue.push( Edge(cit->nb1, &node) );
 
	    }
 
	    if (old_l2 > 4*Node::target_length && !cit->nb2->fixed) {
 
	      node_insertion_queue.push( Edge(&node, cit->nb2 ) );
 
	    }
 
	    count++;
 
	    /*length_dh += 2*Node::target_length * (old_l1 + old_l2 - new_l1 - new_l2) 
 
	      + DSQR(new_l1) - DSQR(old_l1) + DSQR(new_l2) - DSQR(old_l2);*/
 

	
 
	  }
 
	  /* length_dh += 2*Node::target_length * ( w1*(old_l1 - new_l1) + 
 
	     w2*(old_l2 - new_l2) ) +
 
	     w1*(DSQR(new_l1) 
 
	     - DSQR(old_l1)) 
 
	     + w2*(DSQR(new_l2) 
 
	     - DSQR(old_l2)); */
 

	
 

	
 
	  /*	if (c.cellvec.ManhattanNorm()!=0) { 
 

	
 
	  // wall element length constraint
 
	  double old_aniso1, old_aniso2;
 
	  double new_aniso1, new_aniso2;
 

	
 
	  // anisotropic expansion?
 
	  old_aniso1 = 1 + par.lambda_aniso*(1 - fabs(InnerProduct((old_p-i_min_1), c.cellvec))/old_l1);
 
	  old_aniso2 = 1 + par.lambda_aniso*(1 - fabs(InnerProduct((old_p-i_plus_1), c.cellvec))/old_l2);
 
	  new_aniso1 = 1 + par.lambda_aniso*(1 - fabs(InnerProduct((new_p-i_min_1),  c.cellvec))/new_l1);
 
	  new_aniso2 = 1 + par.lambda_aniso*(1 - fabs(InnerProduct((new_p-i_plus_1), c.cellvec))/new_l2);
 

	
 

	
 
	  length_dh += w1 * ( new_aniso1 * DSQR(new_l1 - Node::target_length) -
 
	  old_aniso1 * DSQR(old_l1 - Node::target_length) )
 
	  +  w2 * ( new_aniso2 * DSQR(new_l2 - Node::target_length) -
 
	  old_aniso2 * DSQR(old_l2 - Node::target_length) );
 

	
 
	  } else {
 
	  */	  
 
	
 
	  length_dh += 2*Node::target_length * ( w1*(old_l1 - new_l1) + 
 
						 w2*(old_l2 - new_l2) ) +
 
	    w1*(DSQR(new_l1) 
 
		- DSQR(old_l1)) 
 
	    + w2*(DSQR(new_l2) 
 
		  - DSQR(old_l2));
 

	
 

	
 
	  //}
 

	
 
	 
 

	
 

	
 
	}
 

	
 
	// bending energy also holds for outer boundary
 
	// first implementation. Can probably be done more efficiently
 
	// calculate circumcenter radius (gives local curvature)
 
	// the ideal bending state is flat... (K=0)
 
	// if (cit->cell==-1 && node.cells.size()>2 /* boundary_pol, cell and a second cell */)  {
 
	{
 
		  {
 
	  // strong bending energy to resist "cleaving" by division planes
 
	  double r1, r2, xc, yc;
 
	  CircumCircle(i_min_1.x, i_min_1.y, old_p.x, old_p.y, i_plus_1.x, i_plus_1.y,
 
		       &xc,&yc,&r1);
 
	  CircumCircle(i_min_1.x, i_min_1.y, new_p.x, new_p.y, i_plus_1.x, i_plus_1.y,
 
		       &xc,&yc, &r2);
 

	
 
	  if (r1<0 || r2<0) {
 
	    MyWarning::warning("r1 = %f, r2 = %f",r1,r2);
 
	  }
 
	  bending_dh += DSQR(1/r2 - 1/r1);
 
	  //bending_dh += ( DSQR(1/r2) - DSQR(1/r1) );
 

	
 
	  //cerr << "bending_dh = " << par.bend_lambda*bending_dh << endl;
 

	
 
	}
 
	/*cerr << "Bending = " <<  ( DSQR(1/r2) - DSQR(1/r1))  << endl;
 
	  cerr << node.index << ": " << bending_dh << " (" << r1 << ", " << r2 << ") " << cit->nb1 << ", " << cit->nb2 << ")" << endl;
 
	  }*/
 
	/*else
 
	  bending_dh += ( DSQR(1/r2) - DSQR(1/r1) );*/
 

	
 

	
 
	/*if (cit->cell==-1) {
 
	  cerr << node.index << ": " << bending_dh << " (" << r1 << ", " << r2 << ") " << cit->nb1 << ", " << cit->nb2 << ")" << endl;
 
	  }*/
 

	
 
	//bending_dh += r1 - r2;
 

	
 
      }
 

	
 
      //const double bend_lambda = 100000;
 
      //const double bend_lambda = 0;
 
     
 
		
 

	
 
      /* double dh = //(area_dev_sum_after - area_dev_sum_before) +
 
	 area_dh + par.lambda_celllength * cell_length_dh +
 
	 par.lambda_length * length_dh + par.bend_lambda * bending_dh + par.alignment_lambda * alignment_dh;*/
 

	
 
      dh = //(area_dev_sum_after - area_dev_sum_before) +
 
	area_dh + cell_length_dh +
 
      dh = 	area_dh + cell_length_dh +
 
	par.lambda_length * length_dh + par.bend_lambda * bending_dh + par.alignment_lambda * alignment_dh;
 

	
 
      //cerr << "cell_length_dh = " << par.lambda_celllength * cell_length_dh << endl;
 
      //(length_constraint_after - length_constraint_before);
 
         //(length_constraint_after - length_constraint_before);
 

	
 
      if (node.fixed) {
 

	
 
	// search the fixed cell to which this node belongs
 
	// and displace these cells as a whole
 
	// WARNING: undefined things will happen for connected fixed cells...
 
	for (list<Neighbor>::iterator c=node.owners.begin(); c!=node.owners.end(); c++) {
 
	  if (!c->cell->BoundaryPolP() && c->cell->FixedP()) {
 
	    sum_dh+=c->cell->Displace(rx,ry,0);
 
	  }
 
	}
 
      } else {
 

	
 

	
 
	if (dh<-sum_stiff || RANDOM()<exp((-dh-sum_stiff)/par.T)) {
 

	
 
	  // update areas of cells
 
	  list<DeltaIntgrl>::const_iterator di_it = delta_intgrl_list.begin();
 
	  for (list<Neighbor>::iterator cit=node.owners.begin(); cit!=node.owners.end(); ( cit++) ) {
 
	    if (!cit->cell->BoundaryPolP()) {
 
	      cit->cell->area -= di_it->area;
 
	      if (par.lambda_celllength) {
 
		cit->cell->intgrl_x -= di_it->ix;
 
		cit->cell->intgrl_y -= di_it->iy;
 
		cit->cell->intgrl_xx -= di_it->ixx;
 
		cit->cell->intgrl_xy -= di_it->ixy;
 
		cit->cell->intgrl_yy -= di_it->iyy;
 
	      }
 
	      di_it++;
 
	    }
 
	  }
 

	
 
	  double old_nodex, old_nodey;
 

	
 
	  old_nodex=node.x;
 
	  old_nodey=node.y;
 

	
 
	  node.x = new_p.x;
 
	  node.y = new_p.y;
 

	
 
	  for (list<Neighbor>::iterator cit=node.owners.begin();
 
	       cit!=node.owners.end();
 
	       ( cit++) ) {
 

	
 
	    /*   if (cit->cell >= 0 && cells[cit->cell].SelfIntersect()) {
 
		 node.x = old_nodex;		       
 
		 node.y = old_nodey;
 
		 goto next_node;
 
@@ -968,173 +907,172 @@ void Mesh::InsertNode(Edge &e) {
 
  new_node->owners.push_back( Neighbor(boundary_polygon, e.second, e.first ) );
 
  //cerr << "pushing back " << Neighbor(boundary_polygon->index, e.second, e.first ) << endl;
 
  } else {
 
  // insert before second node, so leave ins_pos as it is,
 
  // that is incremented
 
  boundary_polygon->nodes.insert(ins_pos, new_node);
 

	
 
  // .. set the neighbors of the new node ...
 
  new_node->owners.push_back( Neighbor(boundary_polygon, e.first, e.second ) );
 
  // cerr << "pushing back " << Neighbor(boundary_polygon->index, e.second, e.first ) << endl;
 
  }
 

	
 
  }*/
 

	
 

	
 
  list<Neighbor> owners;
 

	
 
  // push all cells owning the two nodes of the divided edges
 
  // onto a list
 
  copy(e.first->owners.begin(),
 
       e.first->owners.end(),
 
       back_inserter(owners));
 
  copy(e.second->owners.begin(),
 
       e.second->owners.end(),
 
       back_inserter(owners));
 

	
 
  //copy(owners.begin(), owners.end(), ostream_iterator<Neighbor>(cerr, " "));
 
  //cerr << endl;
 

	
 
  // sort the nodes
 
  owners.sort( mem_fun_ref( &Neighbor::Cmp ) );
 

	
 
  //  extern ofstream debug_stream;
 

	
 
  //  debug_stream << "Nodes " << e.first << " and " << e.second << endl;
 
  //  copy(owners.begin(), owners.end(), ostream_iterator<Neighbor>(debug_stream, " "));
 
  //  debug_stream << endl;
 

	
 
  // the duplicates in this list indicate cells owning this edge  
 
  list<Neighbor>::iterator c=owners.begin();
 
  while (c!=owners.end()) {
 
    c=adjacent_find(c,owners.end(),  neighbor_cell_eq);
 

	
 

	
 
    if (c!=owners.end()) { // else break;
 

	
 
      //      debug_stream << "Cell " << c->cell << " owns Edge " << e << endl;
 

	
 
      //if (c->cell>=0) {
 
      //if (!c->cell->BoundaryPolP()) {
 
 
 
      // find the position of the edge's first node in cell c...
 
      list<Node *>::iterator ins_pos = find
 
	(c->cell->nodes.begin(),
 
	 c->cell->nodes.end(),
 
	 e.first);
 
      // ... second node comes before or after it ...
 

	
 
      // XXXX probably this test is always false XXXX: No, works okay.
 
      if (*(++ins_pos!=c->cell->nodes.end()?
 
	    ins_pos:c->cell->nodes.begin())!=e.second) {
 
	c->cell->nodes.insert(((ins_pos--)!=c->cell->nodes.begin()?ins_pos:(--c->cell->nodes.end())), new_node);
 
	//cells[c->cell].nodes.insert(--ins_pos, new_node->index);
 
	// .. set the neighbors of the new node ...
 
	// in this case e.second and e.first are inverted
 
	//  cerr << "Inverted\n";
 
	new_node->owners.push_back( Neighbor(c->cell, e.second, e.first ) );
 
      } else {
 
	// insert before second node, so leave ins_pos as it is,
 
	// that is incremented
 
	c->cell->nodes.insert(ins_pos, new_node);	
 
	// .. set the neighbors of the new node ...
 
	// cerr << "Not inverted\n";
 
	new_node->owners.push_back( Neighbor(c->cell, e.first, e.second ) );
 
      }
 

	
 
      // redo the neighbors:
 
      //}
 

	
 

	
 
      // - find cell c among owners of Node e.first
 
      list<Neighbor>::iterator cpos=
 
	find_if( e.first->owners.begin(),
 
		 e.first->owners.end(),
 
		 bind2nd( mem_fun_ref(&Neighbor::CellEquals), c->cell->Index()) );
 

	
 
      // - correct the record
 
      if (cpos->nb1 == e.second) {
 
	cpos->nb1 = new_node;
 
      } else 
 
	if (cpos->nb2 == e.second) {
 
	  cpos->nb2 = new_node;
 
	}
 

	
 
      // - same for Node e.second
 
      cpos=
 
	find_if( e.second->owners.begin(),
 
		 e.second->owners.end(),
 
		 bind2nd( mem_fun_ref(&Neighbor::CellEquals), c->cell->Index()) );
 

	
 
      // - correct the record
 
      if (cpos->nb1 == e.first) {
 
	cpos->nb1 = new_node;
 
      } else 
 
	if (cpos->nb2 == e.first) {
 
	  cpos->nb2 = new_node;
 
	}
 

	
 

	
 
    } else break;
 
    c++; 
 
  }
 

	
 
  // Repair neighborhood lists in a second loop, to make sure all
 
  // `administration' is up to date
 
  while (c!=owners.end()) {
 
    c=adjacent_find(c,owners.end(),  neighbor_cell_eq);
 
    // repair neighborhood lists of cell and Wall lists
 
    //if (c->cell>=0) {
 

	
 
    if (!c->cell->BoundaryPolP()) {
 
      c->cell->ConstructNeighborList();
 
      //      debug_stream << "Repairing NeighborList of " << c->cell << endl;
 
    
 
    }
 
    c++;
 
  }
 
  //  debug_stream.flush();
 

	
 
}
 

	
 

	
 
/*
 
  Calculate circumcircle of triangle (x1,y1), (x2,y2), (x3,y3)
 
  The circumcircle centre is returned in (xc,yc) and the radius in r
 
  NOTE: A point on the edge is inside the circumcircle
 
*/
 
void Mesh::CircumCircle(double x1,double y1,double x2,double y2,double x3,double y3,
 
			double *xc,double *yc,double *r)
 
{
 
  double m1,m2,mx1,mx2,my1,my2;
 
  double dx,dy,rsqr;
 

	
 
  /* Check for coincident points */
 
  /*if (abs(y1-y2) < TINY && abs(y2-y3) < TINY)
 
    return(false);*/
 

	
 
  if (abs(y2-y1) < TINY) {
 
    m2 = - (x3-x2) / (y3-y2);
 
    mx2 = (x2 + x3) / 2.0;
 
    my2 = (y2 + y3) / 2.0;
 
    *xc = (x2 + x1) / 2.0;
 
    *yc = m2 * (*xc - mx2) + my2;
 
  } else if (abs(y3-y2) < TINY) {
 
    m1 = - (x2-x1) / (y2-y1);
 
    mx1 = (x1 + x2) / 2.0;
 
    my1 = (y1 + y2) / 2.0;
 
    *xc = (x3 + x2) / 2.0;
 
    *yc = m1 * (*xc - mx1) + my1;
 
  } else {
 
    m1 = - (x2-x1) / (y2-y1);
 
    m2 = - (x3-x2) / (y3-y2);
 
    mx1 = (x1 + x2) / 2.0;
 
    mx2 = (x2 + x3) / 2.0;
 
    my1 = (y1 + y2) / 2.0;
 
    my2 = (y2 + y3) / 2.0;
 
    *xc = (m1 * mx1 - m2 * mx2 + my2 - my1) / (m1 - m2);
 
    *yc = m1 * (*xc - mx1) + my1;
 
  }
 

	
 
  dx = x2 - *xc;
 
  dy = y2 - *yc;
 
  rsqr = dx*dx + dy*dy;
 
  *r = sqrt(rsqr);
 

	
 
  return;
 
  // Suggested
 
@@ -1433,97 +1371,97 @@ void Mesh::RepairBoundaryPolygon(void) {
 
  foreach (int i, difference){
 
    internal_node_it = find_if (nodes.begin(), nodes.end(), bind2nd(mem_fun(&Node::IndexEquals), i));
 
    internal_node = *internal_node_it; // dereference the itterator to get to the node pointer
 
    if (!internal_node) throw("Found a null Node pointer.");
 
    internal_node->UnsetBoundary();
 
  }
 

	
 
  boundary_polygon->ConstructConnections();
 
  for (list<Wall *>::iterator w=boundary_polygon->walls.begin(); w!=boundary_polygon->walls.end(); w++) {
 
    if ((*w)->DeadP()) {
 
      (*w)=0;
 
    }
 
  }
 
  boundary_polygon->walls.remove(0);
 
  boundary_polygon->ConstructNeighborList();
 

	
 
#ifdef QDEBUG
 
  qDebug() << "Repaired Boundary Polygon node indices: ";
 
  foreach (Node* node, boundary_polygon->nodes){
 
    qDebug() << node->Index() << " " ;
 
  }
 
  qDebug() << endl ;
 

	
 
#ifdef _undefined_
 
  qDebug() << "NODES:" << endl;
 
  foreach(Node* node, nodes) {
 
    qDebug() << *node;
 
  }
 
  qDebug() << endl;
 

	
 
  qDebug() << "WALLS:" << endl;
 
  foreach(Wall* wall, walls) {
 
    qDebug() << *wall;
 
  }
 
  qDebug() << endl;
 

	
 
  qDebug() << "CELLS:" << endl;
 
  foreach(Cell* cell, cells) {
 
    qDebug() << *cell;
 
  }
 
  qDebug() << endl;
 
#endif
 
#endif
 
}
 

	
 

	
 
Node* Mesh::findNextBoundaryNode(Node* boundary_node) {
 
  bool found_next_boundary_node = false;
 
  Node *next_boundary_node = NULL;
 
  Node *next_boundary_node = 0;
 
  set<int> boundary_node_owners; // This is a list of the current boundary node's owners' Ids
 
  vector<int> neighborIds; // A list of the current boundary node's owners' 2nd neighbor Ids
 
  vector<set<int> *>  nodeOwners; // A vector of set pointers where each set contains the owner Ids of the nodes in the neighborIds list.
 
  vector<int> intersection; // set intersection result
 

	
 
  // The next boundary node is that which has only one owner in common with the current boundary node
 
  for (list<Neighbor>::iterator it=boundary_node->owners.begin(); it!=boundary_node->owners.end(); ++it) {
 
    if (it->cell->Index() != -1) boundary_node_owners.insert(it->cell->Index()); // Save each of the current boundary node's owners' Ids - except the boundary polygon 
 
    set<int> *owners = new set<int>; // create a set to hold a 2nd neighbor's owners' Ids
 
    nodeOwners.push_back(owners);
 
    neighborIds.push_back(it->nb2->Index());
 
    foreach(Neighbor neighbor, it->nb2->owners){
 
      if (neighbor.cell->Index() != -1) owners->insert(neighbor.cell->Index()); // Save second neighbors' owners' Ids - except the boundary polygon 
 
    }
 
  }
 
  vector<int>::iterator itt = neighborIds.begin();
 
  vector<set<int> *>::iterator it = nodeOwners.begin();
 

	
 
#ifdef QDEBUG  
 
  qDebug() << "Boundary node: " <<  boundary_node->Index() << " is owned by the following cells: ";
 
  foreach (int i, boundary_node_owners){
 
    qDebug() << i << "  ";
 
  }
 
  qDebug() << endl;
 
#endif
 

	
 
  for (; it < nodeOwners.end(); it++, itt++) {
 
    intersection.clear();
 
    set_intersection(boundary_node_owners.begin(), boundary_node_owners.end(), (*it)->begin(), (*it)->end(), back_inserter(intersection));
 

	
 
#ifdef QDEBUG  
 
    qDebug() << "The intersection of the boundary node(" << boundary_node->Index() << ") owners and its 2nd neighbor(" <<  *itt << ") owners is: ";
 
    foreach (int i, intersection){
 
      qDebug() << i << "  ";
 
    }
 
    qDebug() << endl;
 
#endif
 

	
 
    if (intersection.size() == 1){
 
      found_next_boundary_node = true;
 
      vector<Node *>::iterator next_boundary_node_it = find_if (nodes.begin(), nodes.end(), bind2nd(mem_fun(&Node::IndexEquals), *itt));
 
      next_boundary_node = *next_boundary_node_it; // defeference the itterator to get to the node pointer
 

	
 
#ifdef QDEBUG  
 
      qDebug() << "The Current boundary node is: " << boundary_node->Index()
 
	       << ". The Next boundary node is: " << *itt << ((next_boundary_node->Marked()) ? " Marked" : " Unmarked") << endl << endl;
 
#endif
 

	
 
@@ -1878,99 +1816,96 @@ double *Mesh::getValues(int *neqs) {
 
  }
 
  return values;
 
}
 

	
 
void Mesh::DrawNodes(QGraphicsScene *c) const {
 

	
 
  for (vector<Node *>::const_iterator n=nodes.begin(); n!=nodes.end(); n++) {
 
    Node *i=*n;
 

	
 
    NodeItem *item = new NodeItem ( &(*i), c );
 
    item->setColor();
 

	
 
    item->setZValue(5);
 
    item->show();
 
    item ->setPos(((Cell::offset[0]+i->x)*Cell::factor),
 
		  ((Cell::offset[1]+i->y)*Cell::factor) );
 
  }
 
}
 

	
 
/*! Returns the sum of protein "ch" of a cycling protein in cells and walls */
 
double Mesh::CalcProtCellsWalls(int ch) const {
 

	
 

	
 
  double sum_prot=0.;
 

	
 
  // At membranes
 
  for (list<Wall *>::const_iterator w=walls.begin(); w!=walls.end(); w++) {
 
    sum_prot += (*w)->Transporters1(ch);
 
    sum_prot += (*w)->Transporters2(ch);
 
  }
 

	
 
  // At cells
 
  for (vector<Cell *>::const_iterator c=cells.begin(); c!=cells.end(); c++) {
 
    sum_prot += (*c)->Chemical(ch);
 
  }
 
  return sum_prot;
 
}
 

	
 
void Mesh::SettoInitVals(void) {
 

	
 
  vector<double> clean_chem(Cell::NChem());
 
  vector<double> clean_transporters(Cell::NChem());
 

	
 
  for (int i=0;i<Cell::NChem();i++) {
 
    clean_transporters[i]=0.;
 
    clean_chem[i]=par.initval[i];
 
  }
 

	
 
  // Amount of PIN1
 
  //clean_chem[1] = 0.;
 

	
 
  CleanChemicals(clean_chem);
 
  CleanTransporters(clean_transporters);
 
}
 

	
 
string Mesh::getTimeHours(void) const {
 
  int hours = (int)(time / 3600);
 
  int mins = (int)((time - hours * 3600)/60);
 
  int secs = (int)((time - hours * 3600 - mins * 60));
 
  ostringstream tstr;
 
  tstr << hours << " h " << mins << " m " << secs << " s";
 
  return tstr.str();
 
}
 

	
 
QVector<qreal> Mesh::VertexAngles(void) {
 
  QVector<qreal> angles;
 
  for (vector<Node *>::const_iterator n=nodes.begin(); n!=nodes.end(); n++) {
 
    if ((*n)->Value()>2 && !(*n)->BoundaryP() ) {
 
      angles+=(*n)->NeighbourAngles();
 
    }
 
  }
 
  return angles;
 
}
 

	
 
QVector< QPair<qreal,int> > Mesh::VertexAnglesValues(void) {
 

	
 
  QVector< QPair<qreal,int> > anglesvalues;
 
  for (vector<Node *>::const_iterator n=nodes.begin(); n!=nodes.end(); n++) {
 
    if ((*n)->Value()>2 && !(*n)->BoundaryP() ) {
 
      QVector<qreal> angles = (*n)->NeighbourAngles();
 
      int value_vertex = angles.size();
 
      for (QVector<qreal>::ConstIterator i=angles.begin(); i!=angles.end(); i++) {
 
	anglesvalues += QPair< qreal, int > (*i, value_vertex);
 
      }
 
    }
 
  }
 
  return anglesvalues;
 
}
 

	
 
void Mesh::Clean(void) {
 
#ifdef QDEBUG
 
  qDebug() << "Freeing nodes" << endl;
 
#endif
 
  for (vector<Node *>::iterator i=nodes.begin(); i!=nodes.end(); i++) {
 
    delete *i;
 
  }
 
  nodes.clear();
 
  Node::nnodes=0;
 

	
src/mesh.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
// Cell derives from Vector, where Vector is simply used as a Vertex
 

	
 
#ifndef _MESH_H_
 
#define _MESH_H_
 

	
 
#include <vector>
 
#include <algorithm>
 
#include <queue>
 
#include <iterator>
 
#include <functional>
 
#ifdef QTGRAPHICS
 
#include <QGraphicsScene>
 
#endif
 
#include "cell.h"
 
#include "node.h"
 
#include "simplugin.h"
 
#include <QVector>
 
#include <QPair>
 
#include <QDebug>
 

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

	
 
 public:
 
 typedef typename C::value_type value_type;
 
 // reimplements push: reject element if it exists already
 
 void push(const value_type &x) {
 
   if (find (queue<T,C>::c.begin(),queue<T,C>::c.end(),x)==queue<T,C>::c.end()) {
 
     queue<T,C>::c.push_back(x);
 
   }
 
 }
 
 void clear(void) {
 
   queue<T,C>::c.clear();
 
 }
 
};
src/miscq.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include <QString>
 
#include <QStringList>
 

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

	
 
// Returns the extension of a filename
 
QString getExtension(const QString fn)
 
{
 
  // split on dots
 
  QStringList parts = fn.split(".");
 

	
 
  // return last part, this should be the extension
 
  return QString(parts.last());
 
}
 

	
 
/* finis */
src/miscq.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _MISCQ_h_
 
#define _MISCQ_h_
 

	
 
#include <QString>
 

	
 
// Miscellaneous helper functions, using Qt
 

	
 
QString getExtension(const QString fn);
 

	
 
#endif
 

	
 
/* finis */
src/modelcatalogue.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include "modelcatalogue.h"
 
#include <QVariant>
 

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

	
 
ModelCatalogue::ModelCatalogue(Mesh *_mesh, Main *_mainwin, const char *model=0) {
 
  mesh = _mesh;
 
  mainwin = _mainwin;
 
  if (model) {
 
    cerr << "Loading model: " << model << endl;
 
    LoadPlugin(model);
 
  } else {
 
    cerr << "Loading all models." << endl;
 
    LoadPlugins();
 
  }
 
}
 

	
 
void ModelCatalogue::LoadPlugins() {
 

	
 
  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(); 
 
  } 
 
  plugin_filters << "*.dylib";
 
#endif 
 
  pluginDir.setNameFilters(plugin_filters);
 

	
src/modelcatalogue.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#ifndef _MODELCATALOGUE_H_
 
#define _MODELCATALOGUE_H_
 

	
 
#include "warning.h"
 
#include "cell.h"
 
#include "mesh.h"
 
#include "simplugin.h"
 
#include "canvas.h"
 
#include <QPluginLoader>
 
#include <Q3PopupMenu>
 
#include <QAction>
 
#include <QDir>
 
#include <QApplication>
 
#include <QObject>
 
#include <QAction>
 
#include <QMenu>
 

	
 
class ModelCatalogue : public QObject {
 
  Q_OBJECT
 
    public:
 
  ModelCatalogue(Mesh *mesh, Main *mainwin, const char *model); 	
 
  void LoadPlugins(); 
 
  void LoadPlugin(const char *model);
 

	
 
  void InstallFirstModel();
 
  void PopulateModelMenu();	
 

	
 
  public slots:
 
  void InstallModel(SimPluginInterface *model);	
 
  void InstallModel(QAction *modelaction);
 
 private:
 
  QVector<SimPluginInterface *> models;
 
  Mesh *mesh;
 
  Main *mainwin;
 
};
 

	
 
#endif
src/node.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include <sstream>
 
#ifdef QTGRAPHICS
 
#include <qstring.h>
 
#include <QGraphicsSimpleTextItem>
 
#endif
 
#include "node.h" 
 
#include "cell.h"
 
#include "mesh.h"
 
#include "random.h"
 
#include "parameter.h"
 
#include "sqr.h"
 
#include "pi.h"
 
#include "warning.h"
 

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

	
 
extern Parameter par;
 

	
 
int Node::nnodes=0;
 
double Node::target_length=1;
 

	
 
ostream &Edge::print(ostream &os) const {
 
  return os << "{ " << first->Index() << ", " << second->Index() << " }";
 
}
 

	
 
ostream &Neighbor::print(ostream &os) const {
 

	
 
  os << " {" << cell->Index() << " " << nb1->Index() << " " << nb2->Index() << "}";
 
  return os;
 
}
 

	
 
ostream &operator<<(ostream &os, const Neighbor &n) {
 
  n.print(os);
 
  return os;
 
}
 

	
src/node.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _NODE_H_
 
#define _NODE_H_
 

	
 
#include <list>
 
//#include <pair>
 

	
 
#include <libxml/parser.h>
 
#include <libxml/tree.h>
 

	
 
#ifdef QTGRAPHICS
 
#include <QGraphicsScene>
 
#include <qcolor.h>
 
#include <iostream>
 
#endif
 
#include "vector.h"
 
#include "random.h"
 
#include "parameter.h"
 
#include "cell.h"
 
#include "modelelement.h"
 

	
 
#include <QVector>
 

	
 
#include "Neighbor.h"
 

	
 
extern Parameter par;
 

	
 
class Edge {
 

	
 
 public:
 

	
 
  Edge(void) {
 
    first=0;
 
    second=0;
 
  }
 

	
 
  Edge(Node *f, Node *s) {
src/nodeitem.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include <QGraphicsScene>
 
#include <QGraphicsItem>
 
#include <QPainter>
 
#include <QStyleOption>
 
#include <Qt>
 
#include "nodeitem.h"
 
#include "parameter.h"
 

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

	
 
extern Parameter par;
 

	
 
NodeItem::NodeItem( Node *n, QGraphicsScene *canvas )
 
  : QGraphicsItem( 0, canvas ), SimItemBase( n, canvas) {
 

	
 
  brush = Qt::darkGray;
 

	
 
  const double mag = par.node_mag;
 
  ellipsesize=QRectF(-1*mag, -1*mag, 2*mag, 2*mag);
 
}
 

	
 
void NodeItem::userMove(double dx, double dy)
 
{
 
  QGraphicsItem::moveBy( dx, dy );
 

	
 
  class_cast<Node *>(obj)->x += (dx/Cell::Magnification());
 
  class_cast<Node *>(obj)->y += (dy/Cell::Magnification());
 
}
 

	
 

	
 

	
 
void NodeItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
 
{
 
  painter->setBrush(brush);
 
  painter->setPen(Qt::NoPen);
 
  painter->drawEllipse(ellipsesize);
src/nodeitem.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _NODEITEM_H_
 
#define _NODEITEM_H_
 

	
 
#include <QGraphicsScene>
 
#include <QGraphicsItem>
 
#include "simitembase.h"
 
#include "node.h"
 
#include "cell.h"
 

	
 
class NodeItem: public QGraphicsItem, public SimItemBase
 
{
 
 public:
 
  NodeItem( Node *n, QGraphicsScene *canvas );
 
  ~NodeItem() {}
 
  Node &getNode(void) const { return *class_cast<Node*>(obj); }
 
  virtual void userMove(double dx, double dy);  
 

	
 
  QRectF boundingRect() const;
 
  void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
 
  QPainterPath shape() const;
 
  void setBrush( QBrush newbrush) { brush = newbrush; }
 
  void setColor(void); 
 
  /*! We use this function internally, to (somewhat) interactively edit init configurations.
 
    Simply put the property to be change upon clicking a node in this function. */
 
  void OnClick( const Qt::MouseButton &mb );
 
  void OnClick(void);
 
 protected:
 
  QBrush brush;
 
  QRectF ellipsesize;
 

	
 
 private:
 
};
 

	
 
#endif
 

	
 
/* finis */
src/nodeset.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include <ostream>
 
#include "nodeset.h"
 

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

	
 
ostream &operator<<(ostream &os, const NodeSet &ns)  {
 
  ns.print(os);
 
  return os;
 
}
 

	
 
/* finis */
src/nodeset.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _NODESET_H_
 
#define _NODESET_H_
 

	
 
#include <algorithm>
 
#include <numeric>
 
#include <list>
 
#include <iterator>
 
#include "node.h"
 

	
 
class NodeSet : public list<Node *> {
 

	
 
 public:
 
  NodeSet(void) {
 
    done = false;
 
  }
 

	
 
  inline bool DoneP(void) { return done; }
 
  inline void ResetDone(void) { done = false; }
 

	
 
  void AddNode(Node * n) {
 
    push_back(n);
 
    n->node_set = this;
 
  }
 

	
 
  list <Cell *> getCells(void) {
 

	
 
    list<Cell *> cellset;
 

	
 
    for (list<Node *>::const_iterator i=begin();
 
	 i!=end();
 
	 i++) {
 
      transform ( (*i)->owners.begin(), (*i)->owners.end(), back_inserter( cellset ) , mem_fun_ref ( &Neighbor::getCell ));
 
    }
 

	
 
    cellset.sort();
 

	
src/output.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 
 
#include <string>
 
#include <stdio.h>
 
#include <string.h>
 
#include <stdlib.h>
 
#include <errno.h>
 
#include <sys/types.h>
 
#include <sys/stat.h>
 
#include "warning.h"
 
#include "parameter.h"
 
#include "output.h"
 
 
 
#include <QDir>
 
#include <QFileInfo>
 
 
static const std::string _module_id("$Id$");
 
 
using namespace MyWarning;
 
 
#define FNAMESIZE 100
 
 
int OpenFileAndCheckExistance(FILE **fp,const char *fname,char *ftype) {
 
 
  *fp=fopen(fname,ftype);
 
  if (*fp==NULL) 
 
    return FALSE;
 
 
  if (!strncmp(ftype,"a",1)) {
 
    if (ftell(*fp)>0L) return TRUE;
 
    else return FALSE;
 
  } else return TRUE;
 
}
 
 
int FileExistsP(const char *fname) {
 
 
  FILE *fp;
 
  fp=fopen(fname,"r");
src/output.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _OUTPUT_H_
 
#define _OUTPUT_H_
 

	
 
#ifdef __cplusplus
 
extern "C" {
 
#endif
 

	
 
  int OpenFileAndCheckExistance(FILE **fp,const char *fname,char *ftype);
 
  int YesNoP(const char *message);
 
  FILE *OpenWriteFile(const char *filename);
 
  FILE *OpenGZippedWriteFile(const char *filename);
 
  FILE *OpenReadFile(const char *filename);
 
  char *ReadLine(FILE *fp);
 
  void CheckFile(FILE *fp);
 
  int FileExistsP(const char *fname);
 
  char *Chext(char *filename);
 
  void MakeDir(const char *dirname);
 
  bool CanWeWriteP(char *filename);
 

	
 
#ifdef __cplusplus
 
}
 
#endif
 

	
 

	
 
#define MESS_BUF_SIZE 160
 
#ifndef FALSE
 
#define FALSE 0
 
#define TRUE 1
 
#endif
 

	
 
#endif
 

	
 
/* finis */
src/parameter.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include "parameter.h"
 
#include <cstdio>
 
#include <cstring>
 
#include <cstdlib>
 
#include <cerrno>
 
#include <iostream>
 
#include <sstream>
 
#include "output.h"
 
#include "parse.h"
 
#include "xmlwrite.h"
 
#include "warning.h"
 
#include <QLocale>
 
#include <QDir>
 
#include <QStringList>
 

	
 
using namespace std;
 

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

	
 
Parameter::Parameter() {
 
  arrowcolor = strdup("white");
 
  arrowsize = 100;
 
  textcolor = strdup("red");
 
  cellnumsize = 1;
 
  nodenumsize = 1;
 
  node_mag = 1.0;
 
  outlinewidth = 1.0;
 
  cell_outline_color = strdup("forestgreen");
 
  resize_stride = 0;
 
  T = 1.0;
 
  lambda_length = 100.;
 
  lambda_celllength = 0.;
 
  target_length = 60.;
 
  cell_expansion_rate = 1.;
 
  cell_div_expansion_rate = 0.;
 
  auxin_dependent_growth = true;
 
  ode_accuracy = 1e-4;
src/parameter.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#ifndef _PARAMETER_H_
 
#define _PARAMETER_H_
 
#include "vector.h"
 
#include <vector>
 

	
 
#include <libxml/parser.h>
 
#include <libxml/tree.h>
 

	
 
class Parameter {
 
		
 
 public: 
 
  Parameter();
 
  ~Parameter();
 
  void CleanUp(void);
 
  void Read(const char *filename);
 
  void Write(ostream &os) const;
 
  void XMLAdd(xmlNode *root) const;
 
  void XMLRead(xmlNode *root);
 
  void AssignValToPar(const char *namec, const char *valc);
 
  void AssignValArrayToPar(const char *namec, vector<double> valarray);
 
  char * arrowcolor;
 
  double arrowsize;
 
  char * textcolor;
 
  int cellnumsize;
 
  int nodenumsize;
 
  double node_mag;
 
  double outlinewidth;
 
  char * cell_outline_color;
 
  int resize_stride;
 
  double T;
 
  double lambda_length;
 
  double lambda_celllength;
 
  double target_length;
 
  double cell_expansion_rate;
 
  double cell_div_expansion_rate;
 
  bool auxin_dependent_growth;
 
  double ode_accuracy;
src/pardialog.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include "pardialog.h"
 
#include "parameter.h"
 
#include <cstring>
 
#include <qdialog.h>
 
#include <qlabel.h>
 
#include <qlineedit.h>
 
#include <qmessagebox.h>
 

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

	
 
ParameterDialog::ParameterDialog(QWidget *parent, const char *name, Qt::WindowFlags f) : QDialog(parent,name,false,f) {
 
  extern Parameter par;
 
  arrowcolor_edit = new QLineEdit( QString("%1").arg(par.arrowcolor), this, "arrowcolor_edit" );
 
  arrowsize_edit = new QLineEdit( QString("%1").arg(par.arrowsize), this, "arrowsize_edit" );
 
  textcolor_edit = new QLineEdit( QString("%1").arg(par.textcolor), this, "textcolor_edit" );
 
  cellnumsize_edit = new QLineEdit( QString("%1").arg(par.cellnumsize), this, "cellnumsize_edit" );
 
  nodenumsize_edit = new QLineEdit( QString("%1").arg(par.nodenumsize), this, "nodenumsize_edit" );
 
  node_mag_edit = new QLineEdit( QString("%1").arg(par.node_mag), this, "node_mag_edit" );
 
  outlinewidth_edit = new QLineEdit( QString("%1").arg(par.outlinewidth), this, "outlinewidth_edit" );
 
  cell_outline_color_edit = new QLineEdit( QString("%1").arg(par.cell_outline_color), this, "cell_outline_color_edit" );
 
  resize_stride_edit = new QLineEdit( QString("%1").arg(par.resize_stride), this, "resize_stride_edit" );
 
  T_edit = new QLineEdit( QString("%1").arg(par.T), this, "T_edit" );
 
  lambda_length_edit = new QLineEdit( QString("%1").arg(par.lambda_length), this, "lambda_length_edit" );
 
  lambda_celllength_edit = new QLineEdit( QString("%1").arg(par.lambda_celllength), this, "lambda_celllength_edit" );
 
  target_length_edit = new QLineEdit( QString("%1").arg(par.target_length), this, "target_length_edit" );
 
  cell_expansion_rate_edit = new QLineEdit( QString("%1").arg(par.cell_expansion_rate), this, "cell_expansion_rate_edit" );
 
  cell_div_expansion_rate_edit = new QLineEdit( QString("%1").arg(par.cell_div_expansion_rate), this, "cell_div_expansion_rate_edit" );
 
  auxin_dependent_growth_edit = new QLineEdit( QString("%1").arg(sbool(par.auxin_dependent_growth)), this, "auxin_dependent_growth_edit" );
 
  ode_accuracy_edit = new QLineEdit( QString("%1").arg(par.ode_accuracy), this, "ode_accuracy_edit" );
 
  mc_stepsize_edit = new QLineEdit( QString("%1").arg(par.mc_stepsize), this, "mc_stepsize_edit" );
 
  mc_cell_stepsize_edit = new QLineEdit( QString("%1").arg(par.mc_cell_stepsize), this, "mc_cell_stepsize_edit" );
 
  energy_threshold_edit = new QLineEdit( QString("%1").arg(par.energy_threshold), this, "energy_threshold_edit" );
 
  bend_lambda_edit = new QLineEdit( QString("%1").arg(par.bend_lambda), this, "bend_lambda_edit" );
 
  alignment_lambda_edit = new QLineEdit( QString("%1").arg(par.alignment_lambda), this, "alignment_lambda_edit" );
 
  rel_cell_div_threshold_edit = new QLineEdit( QString("%1").arg(par.rel_cell_div_threshold), this, "rel_cell_div_threshold_edit" );
 
  rel_perimeter_stiffness_edit = new QLineEdit( QString("%1").arg(par.rel_perimeter_stiffness), this, "rel_perimeter_stiffness_edit" );
 
  collapse_node_threshold_edit = new QLineEdit( QString("%1").arg(par.collapse_node_threshold), this, "collapse_node_threshold_edit" );
 
@@ -94,98 +94,98 @@ ParameterDialog::ParameterDialog(QWidget
 
  van3prod_edit = new QLineEdit( QString("%1").arg(par.van3prod), this, "van3prod_edit" );
 
  van3autokat_edit = new QLineEdit( QString("%1").arg(par.van3autokat), this, "van3autokat_edit" );
 
  van3sat_edit = new QLineEdit( QString("%1").arg(par.van3sat), this, "van3sat_edit" );
 
  k2van3_edit = new QLineEdit( QString("%1").arg(par.k2van3), this, "k2van3_edit" );
 
  dt_edit = new QLineEdit( QString("%1").arg(par.dt), this, "dt_edit" );
 
  rd_dt_edit = new QLineEdit( QString("%1").arg(par.rd_dt), this, "rd_dt_edit" );
 
  datadir_edit = new QLineEdit( QString("%1").arg(par.datadir), this, "datadir_edit" );
 
  movie_edit = new QLineEdit( QString("%1").arg(sbool(par.movie)), this, "movie_edit" );
 
  nit_edit = new QLineEdit( QString("%1").arg(par.nit), this, "nit_edit" );
 
  maxt_edit = new QLineEdit( QString("%1").arg(par.maxt), this, "maxt_edit" );
 
  storage_stride_edit = new QLineEdit( QString("%1").arg(par.storage_stride), this, "storage_stride_edit" );
 
  xml_storage_stride_edit = new QLineEdit( QString("%1").arg(par.xml_storage_stride), this, "xml_storage_stride_edit" );
 
  rseed_edit = new QLineEdit( QString("%1").arg(par.rseed), this, "rseed_edit" );
 
  constituous_expansion_limit_edit = new QLineEdit( QString("%1").arg(par.constituous_expansion_limit), this, "constituous_expansion_limit_edit" );
 
  vessel_inh_level_edit = new QLineEdit( QString("%1").arg(par.vessel_inh_level), this, "vessel_inh_level_edit" );
 
  vessel_expansion_rate_edit = new QLineEdit( QString("%1").arg(par.vessel_expansion_rate), this, "vessel_expansion_rate_edit" );
 
  d_edit = new QLineEdit( QString("%1").arg(par.d), this, "d_edit" );
 
  e_edit = new QLineEdit( QString("%1").arg(par.e), this, "e_edit" );
 
  f_edit = new QLineEdit( QString("%1").arg(par.f), this, "f_edit" );
 
  c_edit = new QLineEdit( QString("%1").arg(par.c), this, "c_edit" );
 
  mu_edit = new QLineEdit( QString("%1").arg(par.mu), this, "mu_edit" );
 
  nu_edit = new QLineEdit( QString("%1").arg(par.nu), this, "nu_edit" );
 
  rho0_edit = new QLineEdit( QString("%1").arg(par.rho0), this, "rho0_edit" );
 
  rho1_edit = new QLineEdit( QString("%1").arg(par.rho1), this, "rho1_edit" );
 
  c0_edit = new QLineEdit( QString("%1").arg(par.c0), this, "c0_edit" );
 
  gamma_edit = new QLineEdit( QString("%1").arg(par.gamma), this, "gamma_edit" );
 
  eps_edit = new QLineEdit( QString("%1").arg(par.eps), this, "eps_edit" );
 
  QString k_string("%1,%2,%3,%4,%5,%6,%7,%8,%9,%10,%11,%12,%13,%14,%15");
 
  k_string = k_string.arg(par.k[0]).arg(par.k[1]).arg(par.k[2]).arg(par.k[3]).arg(par.k[4]).arg(par.k[5]).arg(par.k[6]).arg(par.k[7]).arg(par.k[8]).arg(par.k[9]).arg(par.k[10]).arg(par.k[11]).arg(par.k[12]).arg(par.k[13]).arg(par.k[14]);
 
  k_edit = new QLineEdit( k_string, this, "k_edit" );
 
  i1_edit = new QLineEdit( QString("%1").arg(par.i1), this, "i1_edit" );
 
  i2_edit = new QLineEdit( QString("%1").arg(par.i2), this, "i2_edit" );
 
  i3_edit = new QLineEdit( QString("%1").arg(par.i3), this, "i3_edit" );
 
  i4_edit = new QLineEdit( QString("%1").arg(par.i4), this, "i4_edit" );
 
  i5_edit = new QLineEdit( QString("%1").arg(par.i5), this, "i5_edit" );
 
  s1_edit = new QLineEdit( QString("%1").arg(par.s1), this, "s1_edit" );
 
  s2_edit = new QLineEdit( QString("%1").arg(par.s2), this, "s2_edit" );
 
  s3_edit = new QLineEdit( QString("%1").arg(par.s3), this, "s3_edit" );
 
  b1_edit = new QLineEdit( QString("%1").arg(sbool(par.b1)), this, "b1_edit" );
 
  b2_edit = new QLineEdit( QString("%1").arg(sbool(par.b2)), this, "b2_edit" );
 
  b3_edit = new QLineEdit( QString("%1").arg(sbool(par.b3)), this, "b3_edit" );
 
  b4_edit = new QLineEdit( QString("%1").arg(sbool(par.b4)), this, "b4_edit" );
 
  dir1_edit = new QLineEdit( QString("%1").arg(par.dir1), this, "dir1_edit" );
 
  dir2_edit = new QLineEdit( QString("%1").arg(par.dir2), this, "dir2_edit" );
 
  // make a 1x1 grid; it will auto-expand
 
  QGridLayout *grid = new QGridLayout( this, 1, 1 );
 
    
 
  // add the first four widgets with (row, column) addressing
 
  setWindowTitle( QString( " Parameter values for The Virtual Leaf") );
 
  grid->addWidget( new QLabel( "<h3> Parameter values for The Virtual Leaf</h3>",this), 0, 0, 1, -1, Qt::AlignCenter);
 
  setWindowTitle( QString( " Parameter values for VirtualLeaf") );
 
  grid->addWidget( new QLabel( "<h3> Parameter values for VirtualLeaf</h3>",this), 0, 0, 1, -1, Qt::AlignCenter);
 
  grid->addWidget( new QLabel( "", this), 0+1, 0, 1, -1);
 
  grid->addWidget( new QLabel( " <b>Visualization</b>", this), 3, 0, 1, 2 );
 
  grid->addWidget( new QLabel( "arrowcolor", this ),4, 0 );
 
  grid->addWidget( arrowcolor_edit, 4, 0+1  );
 
  grid->addWidget( new QLabel( "arrowsize", this ),5, 0 );
 
  grid->addWidget( arrowsize_edit, 5, 0+1  );
 
  grid->addWidget( new QLabel( "textcolor", this ),6, 0 );
 
  grid->addWidget( textcolor_edit, 6, 0+1  );
 
  grid->addWidget( new QLabel( "cellnumsize", this ),7, 0 );
 
  grid->addWidget( cellnumsize_edit, 7, 0+1  );
 
  grid->addWidget( new QLabel( "nodenumsize", this ),8, 0 );
 
  grid->addWidget( nodenumsize_edit, 8, 0+1  );
 
  grid->addWidget( new QLabel( "node_mag", this ),9, 0 );
 
  grid->addWidget( node_mag_edit, 9, 0+1  );
 
  grid->addWidget( new QLabel( "outlinewidth", this ),10, 0 );
 
  grid->addWidget( outlinewidth_edit, 10, 0+1  );
 
  grid->addWidget( new QLabel( "cell_outline_color", this ),11, 0 );
 
  grid->addWidget( cell_outline_color_edit, 11, 0+1  );
 
  grid->addWidget( new QLabel( "resize_stride", this ),12, 0 );
 
  grid->addWidget( resize_stride_edit, 12, 0+1  );
 
  grid->addWidget( new QLabel( "", this), 13, 0, 1, 2 );
 
  grid->addWidget( new QLabel( " <b>Cell mechanics</b>", this), 14, 0, 1, 2 );
 
  grid->addWidget( new QLabel( "T", this ),15, 0 );
 
  grid->addWidget( T_edit, 15, 0+1  );
 
  grid->addWidget( new QLabel( "lambda_length", this ),16, 0 );
 
  grid->addWidget( lambda_length_edit, 16, 0+1  );
 
  grid->addWidget( new QLabel( "lambda_celllength", this ),17, 0 );
 
  grid->addWidget( lambda_celllength_edit, 17, 0+1  );
 
  grid->addWidget( new QLabel( "target_length", this ),18, 0 );
 
  grid->addWidget( target_length_edit, 18, 0+1  );
 
  grid->addWidget( new QLabel( "cell_expansion_rate", this ),19, 0 );
 
  grid->addWidget( cell_expansion_rate_edit, 19, 0+1  );
 
  grid->addWidget( new QLabel( "cell_div_expansion_rate", this ),20, 0 );
 
  grid->addWidget( cell_div_expansion_rate_edit, 20, 0+1  );
 
  grid->addWidget( new QLabel( "auxin_dependent_growth", this ),21, 0 );
 
  grid->addWidget( auxin_dependent_growth_edit, 21, 0+1  );
 
  grid->addWidget( new QLabel( "ode_accuracy", this ),22, 0 );
 
  grid->addWidget( ode_accuracy_edit, 22, 0+1  );
 
  grid->addWidget( new QLabel( "mc_stepsize", this ),23, 0 );
 
  grid->addWidget( mc_stepsize_edit, 23, 0+1  );
 
  grid->addWidget( new QLabel( "mc_cell_stepsize", this ),24, 0 );
 
  grid->addWidget( mc_cell_stepsize_edit, 24, 0+1  );
 
  grid->addWidget( new QLabel( "energy_threshold", this ),25, 0 );
 
  grid->addWidget( energy_threshold_edit, 25, 0+1  );
 
  grid->addWidget( new QLabel( "bend_lambda", this ),26, 0 );
 
  grid->addWidget( bend_lambda_edit, 26, 0+1  );
 
  grid->addWidget( new QLabel( "alignment_lambda", this ),27, 0 );
 
  grid->addWidget( alignment_lambda_edit, 27, 0+1  );
src/parse.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 
 
#include <stdio.h>
 
#include <string.h>
 
#include <stdlib.h>
 
#include <errno.h>
 
#include <string.h>
 
#include "warning.h"
 
#include "parse.h"
 
#include "output.h"
 
#include <string>
 
 
static const std::string _module_id("$Id$");
 
 
using namespace MyWarning;
 
 
char *ParsePar(FILE *fp, char *parameter, bool wrapflag) 
 
{
 
  char *line,*token;
 
  char *value;
 
 
  line=SearchToken(fp,parameter, wrapflag);
 
  if (line==NULL) {
 
    warning("Warning: Token %s not found.",parameter);
 
    value=0;
 
    return value;
 
  }
 
 
  /* parse the line on = sign */
 
  token=strtok(line,"=");
 
  if (token==NULL) {
 
    error("Parse error: no '=' sign found next to token %s, in line: \n %s.",
 
	  parameter,line);
 
  }
 
 
  // warning("Reading value for token %s...",token);
 
  fprintf(stderr, "[%s = ",token);
 
 
  token=strtok(NULL,"=");
src/parse.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _PARSE_H_
 
#define _PARSE_H_
 

	
 
char *ParsePar(FILE *fp, char *parameter, bool wrapflag);
 
int igetpar(FILE *fp,char *parameter, bool wrapflag);
 
int igetpar(FILE *fp,char *parameter, int default_val, bool wrapflag);
 
float fgetpar(FILE *fp,char *parameter, bool wrapflag);
 
float fgetpar(FILE *fp,char *parameter, double default_val, bool wrapflag);
 

	
 
/* Get a list of n comma separated doubles */
 
double *dgetparlist(FILE *fp,char *parameter, int n, bool wrapflag);
 
char *sgetpar(FILE *fp,char *parameter, bool wrapflag);
 
char *sgetpar(FILE *fp,char *parameter,const char *default_val, bool wrapflag);
 
bool bgetpar(FILE *fp, char *parameter, bool wrapflag);
 
bool bgetpar(FILE *fp, char *parameter, int default_val, bool wrapflag);
 
char *SearchToken(FILE *fp, char *token, bool wrapflag);
 
int TokenInLineP(char *line,char *token);
 
void SkipToken(FILE *fp,char *token, bool wrapflag);
 
void SkipLine(FILE *fp);
 
char *bool_str(bool bool_var);
 

	
 
#endif
 

	
 
/* finis */
src/pi.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _PI_H_
 
#define _PI_H_
 

	
 
const double Pi=3.1415926535897932384626433832795028841971693993751058209749445923078164062862089986280348253421170676;
 

	
 
#endif
 

	
 
/* finis */
src/qcanvasarrow.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _QCANVASARROW_H_
 
#define _QCANVASARROW_H_
 

	
 
#include <QGraphicsScene>
 

	
 
class QGraphicsArrowItem : public QGraphicsLineItem {
 

	
 
 public:
 
 QGraphicsArrowItem(QGraphicsItem *parent, QGraphicsScene *c) : QGraphicsLineItem(parent, c) {};
 

	
 
  void paint ( QPainter *p, const QStyleOptionGraphicsItem *option,
 
	       QWidget *widget ) {
 

	
 
    // construct arrow head
 
    QPointF start=line().p1();
 
    QPointF end=line().p2();
 
    QPointF mid=start + (3./4.)*(end-start);
 

	
 
    double vx=end.x()-start.x();
 
    double vy=end.y()-start.y();
 

	
 
    double length = sqrt(vx*vx+vy*vy);
 
    if (length==0) return;
 

	
 
    // perpendicular vector
 
    double px=-vy/length;
 
    double py=vx/length;
 

	
 
    // Arrow head lines go from end point
 
    // to points about 3/4 of the total arrow, extending sideways about 1/4
 
    // of the arrow length.
 

	
 

	
 
    QPointF arwp1 = mid + QPointF( (int)( (length/4.)*px ),
 
				   (int)( (length/4.)*py ) );
 
    QPointF arwp2 = mid - QPointF( (int)( (length/4.)*px ),
src/random.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 
 
#include <QDebug>
 
#include <string>
 
#include <stdio.h>
 
#include <stdlib.h>
 
#include <sys/timeb.h>
 
#include <iostream>
 
#include "random.h"
 
 
static const std::string _module_id("$Id$");
 
 
static int idum = -1;
 
using namespace std;
 
 
static int counter=0;
 
/*! \return A random double between 0 and 1
 
**/
 
double RANDOM(void)
 
/* Knuth's substrative method, see Numerical Recipes */
 
{
 
  static int inext,inextp;
 
  static long ma[56];
 
  static int iff=0;
 
  counter++;
 
  long mj,mk;
 
  int i,ii,k;
 
 
  if (idum < 0 || iff == 0) {
 
    iff=1;
 
    mj=MSEED-(idum < 0 ? -idum : idum);
 
    mj %= MBIG;
 
    ma[55]=mj;
 
    mk=1;
 
    i=1;
 
    do {
 
      ii=(21*i) % 55;
 
      ma[ii]=mk;
 
      mk=mj-mk;
src/random.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _RANDOM_H_
 
#define _RANDOM_H_
 

	
 
#define MBIG 1000000000
 
#define MSEED 161803398
 
#define MZ 0
 
#define FAC (1.0/MBIG)
 

	
 
double RANDOM();
 
int Seed(int seed);
 
long RandomNumber(long max);
 
void AskSeed();
 
int Randomize(void);
 
int RandomCounter(void);
 

	
 

	
 

	
 
// Class MyUrand, so we can pass the random generator to STL's random_shuffle,
 
// and get identical simulations for a given random seed.
 
class MyUrand {
 

	
 
  long n;
 
 public:
 
  MyUrand(long nn) {
 
    n=nn;
 
  }
 
  MyUrand(void){};
 

	
 
  void seed(long s) {
 
    Seed(s);
 
  }
 

	
 
  long operator()(long nn) { return RandomNumber(nn)-1; }
 
  long operator()(void) { return RandomNumber(n); }
 
};
 

	
src/rungekutta.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include <math.h>
 
#include <iostream>
 
#include "rungekutta.h"
 
#include "warning.h"
 
#include "maxmin.h"
 

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

	
 
// The value Errcon equals (5/Safety) raised to the power (1/PGrow), see use below.
 

	
 
/*
 
  static float maxarg1,maxarg2;
 
  #define FMAX(a,b) (maxarg1=(a),maxarg2=(b),(maxarg1) > (maxarg2) ?\
 
  (maxarg1) : (maxarg2))
 
  static float minarg1,minarg2;
 
  #define FMIN(a,b) (minarg1=(a),minarg2=(b),(minarg1) < (minarg2) ?\
 
  (minarg1) : (minarg2))
 
  #define SIGN(a,b) ((b) >= 0.0 ? fabs(a) : -fabs(a))
 
*/
 

	
 
const double RungeKutta::Safety  = 0.9;
 
const double RungeKutta::PGrow = -0.2;
 
const double RungeKutta::Pshrnk = -0.25;
 
const double RungeKutta::Errcon = 1.89e-4;
 
const double RungeKutta::Maxstp = 10000;
 
const double RungeKutta::Tiny = 1.0e-30;
 

	
 
void RungeKutta::rkqs(double *y, double *dydx, int n, double *x, double htry, double eps,
 
		      double *yscal, double *hdid, double *hnext)
 
/* Fifth-order Runge-Kutta step with monitoring of local truncation error to ensure accuracy and
 
   adjust stepsize. Input are the dependent variable vector y[1..n] and its derivative dydx[1..n]
 
   at the starting value of the independent variable x. Also input are the stepsize to be attempted
 
   htry, the required accuracy eps, and the vector yscal[1..n] against which the error is
 
   scaled. On output, y and x are replaced by their new values, hdid is the stepsize that was
 
   actuallyac complished, and hnext is the estimated next stepsize. derivs is the user-supplied
 
   routine that computes the right-hand side derivatives. */
src/rungekutta.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _RUNGEKUTTA_H_
 
#define _RUNGEKUTTA_H_
 

	
 
class RungeKutta  {
 

	
 
 public:
 
  RungeKutta(void) {
 
    kmax=kount=0;
 
    dxsav=0.;
 
    xp=0;
 
    yp=0;
 
  }
 
  virtual ~RungeKutta() {}
 

	
 
  void odeint(double ystart[], int nvar, double x1, double x2, double eps, double h1,
 
	      double hmin, int *nok, int *nbad);
 

	
 

	
 
 protected:
 
  // implement "derivs" in a derived class
 
  virtual void derivs(double x, double *y, double *dxdy) = 0;
 
  int kmax,kount;
 
  double *xp,**yp,dxsav;
 

	
 
 private:
 
  void rkqs(double *y, double *dydx, int n, double *x, double htry, double eps,
 
	    double *yscal, double *hdid, double *hnext);
 

	
 
  void rkck(double *y, double *dydx, int n, double x, double h, double yout[],
 
	    double *yerr);
 

	
 
  static const double Safety;
 
  static const double PGrow;
 
  static const double Pshrnk;
 
  static const double Errcon;
 
  static const double Maxstp;
src/simitembase.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include <QBrush>
 
#include "simitembase.h"
 

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

	
 
SimItemBase::SimItemBase( void *v, QGraphicsScene *canvas )
 
{
 
  obj=v;
 
};
 

	
 
SimItemBase::~SimItemBase(void) {};
 

	
 
void SimItemBase::userMove(double dx, double dy){};
 

	
 
/* finis */
src/simitembase.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _SIMITEMBASE_H_
 
#define _SIMITEMBASE_H_
 

	
 
#include <QGraphicsScene>
 
#include <QBrush>
 
#include <assert.h>
 
class Vector;
 

	
 

	
 
template<class TYPE> 
 
TYPE class_cast(void * symbol)
 
{
 
  assert(sizeof(void *) == sizeof(TYPE));
 
  union
 
  {
 
    void * symbol;
 
    TYPE unknownclass;
 
  } cast;
 

	
 
  cast.symbol = symbol;
 
  return cast.unknownclass;
 
}
 

	
 
class SimItemBase
 
{
 
 public:
 
  SimItemBase( void *v, QGraphicsScene *canvas );
 
  virtual ~SimItemBase(void);
 
  virtual void userMove(double dx, double dy);
 

	
 

	
 
 protected:
 

	
 
  // I know which simulation object I represent, so if I am moved around
 
  // the canvas, the real object can be moved as well
 

	
src/simplugin.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _SIMPLUGIN_H_
 
#define _SIMPLUGIN_H_
 

	
 
#include <QtPlugin>
 
#include <QMetaType>
 
#include "cellbase.h"
 
#include "wallbase.h"
 

	
 
class Parameter;
 

	
 
#include <QColor>
 
#include <QString>
 

	
 

	
 
class SimPluginInterface {
 

	
 
 public:
 
  virtual QString ModelID(void) = 0; 
 

	
 
  virtual ~SimPluginInterface() { }
 

	
 
  // Executed after the cellular mechanics steps have equillibrized
 
  virtual void CellHouseKeeping(CellBase *c) = 0;
 

	
 
  // Differential equations describing transport of chemicals from cell to cell
 
  virtual void CelltoCellTransport(Wall *, double *dchem_c1, double *dchem_c2) = 0;
 

	
 
  // Differential equations describing chemical reactions taking place at or near the cell walls
 
  // (e.g. PIN accumulation)
 
  virtual void WallDynamics(Wall *w, double *dw1, double *dw)  = 0;
 

	
 
  // Differential equations describing chemical reactions inside the cells
 
  virtual void CellDynamics(CellBase *c, double *dchem) = 0;
 

	
 
  // to be executed after a cell division
 
  virtual void OnDivide(ParentInfo *parent_info, CellBase *daughter1, CellBase *daughter2) = 0;
src/sqr.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  From "Numerical recipes in C"
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#ifndef _SQR_H_
 
#define _SQR_H_
 

	
 

	
 
// redefine these macros as inline functions, to prevent scary
 
// behavior.  (According to compiler warnings, the above macros from
 
// Numerical Recipes in C are officially undefined...)
 
//
 
// However, they seem to work, but it seems safer to redefine them.
 
// Inline functions will behave like macros anyhow.
 
inline double DSQR( double a ) {
 

	
 
  if (a == 0.0) {
 
    return 0.0;
 
  } else {
 
    return a*a;
 
  }
 
}
 

	
 
inline float SQR( float a ) {
 
  if (a == 0.0) {
 
    return 0.0;
 
  } else {
 
    return a*a;
 
  }
 
}
 

	
 
#endif
 

	
 
/* finis */
src/tiny.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _TINY_H_
 
#define _TINY_H_
 

	
 
#define TINY 1e-5
 

	
 
#endif
 

	
 
/* finis */
src/transporterdialog.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <QtGui>
 
#include <QDoubleValidator>
 
#include <sstream>
 
#include "canvas.h"
 
#include "transporterdialog.h"
 

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

	
 
TransporterDialog::TransporterDialog(Wall *w, CellBase *c, int wn, QWidget *parent)
 
  : wall(w), cell(c), wall_num(wn), QDialog(parent)
 
  :  QDialog(parent), wall(w), cell(c), wall_num(wn)
 
{
 
  int frameStyle = QFrame::Plain | QFrame::NoFrame;
 
  QPushButton *ok = new QPushButton(tr("Ok"));
 
  QPushButton *cancel = new QPushButton(tr("Cancel"));
 
  QGridLayout *t_grid = new QGridLayout; // transporter grid
 

	
 
  // connect the slots
 
  connect(ok, SIGNAL(clicked()), this, SLOT(setTransporterValues()));
 
  connect(cancel, SIGNAL(clicked()), this, SLOT(close()));
 

	
 
  // compose a label for the dialog box
 
  std::stringstream label_text; 
 
  label_text << "C("<< wall->C1()->Index() << "," << wall->C2()->Index() << "), N(" 
 
	     << wall->N1()->Index() << "," << wall->N2()->Index() << ")";
 

	
 
  // retrieve the current transporters
 
  QVector <double> transporters;  // transporter vector
 
  ntransporters = cell->NChem(); // size of transporter vector
 
  for (int i=0; i<ntransporters; ++i){
 
    transporters << ((wall_num == 1) ? wall->Transporters1(i) : wall->Transporters2(i)); // dependent on the wall number of course.
 
  }
 

	
 
  // iterate over the vector of transporter values making a label/edit line for each
 
  for (int i=0; i<transporters.size(); ++i) {
 

	
 
    // label
 
    label = new QLabel;
 
    label->setFrameStyle(frameStyle);
 
    label->setText(QString("%1").arg(i+1)); // cardinal numbering
 

	
 
    // line editor
 
    QLineEdit *editor = new QLineEdit();
 
    editors << editor;
 
    editor->setValidator(new QDoubleValidator(editor)); // validator settings
 

	
 
    // assign the current transporter value
 
    QString n;
 
    editor->setText(n.setNum(transporters[i]));
 

	
 
    // insert the label and editor into the transporter grid
 
    t_grid->addWidget(label, i, 0);
 
    t_grid->addWidget(editor, i, 1);
 
  }
 

	
 
  // add OK and Cancel buttons
 
  QGridLayout *b_grid = new QGridLayout; // button grid
 
  b_grid->addWidget(ok, 0, 0);
 
  b_grid->addWidget(cancel, 0, 1);
src/transporterdialog.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _TRANSPORTERDIALOG_H_
 
#define _TRANSPORTERDIALOG_H_
 

	
 
#include <QDialog>
 
#include <QVector>
 
#include <QLineEdit>
 

	
 
class QLabel;
 
class QLineEdit;
 

	
 
class Wall;
 
class CellBase;
 

	
 
class TransporterDialog : public QDialog
 
{
 
  Q_OBJECT
 

	
 
 public:
 
  TransporterDialog(Wall *w, CellBase *c, int wn, QWidget *parent = 0);
 

	
 
  private slots:
 
  void setTransporterValues();
 

	
 
 private:
 
  Wall *wall;
 
  CellBase *cell;
 
  int wall_num;
 
  QLabel *label;
 
  int ntransporters;
 
  QVector <QLineEdit*> editors;
 
};
 

	
 
#endif
 

	
 
/* finis */
src/vector.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include <stddef.h>
 
#include <ostream>
 
#include <limits.h>
 
#include <stdio.h>
 
//#include <math.h>
 
#include <stdarg.h>
 
#include "sqr.h"
 
#include "pi.h"
 
#include "vector.h"
 
#include "tiny.h"
 

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

	
 
void Vector::operator=(const Vector &source) {
 

	
 
  // assignment
 

	
 
  // don't assign to self
 
  if (this==&source) return;
 

	
 
  x=source.x;
 
  y=source.y;
 
  z=source.z;
 
}
 

	
 

	
 
ostream &Vector::print(ostream &os) const {
 
  os << "(" << x << ", " << y << ", " << z << ")";
 
  return os;
 
}
 

	
 

	
 
ostream &operator<<(ostream &os, const Vector &v) {
 
  v.print(os);
 
  return os;
 
}
src/vector.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _VECTOR_H_
 
#define _VECTOR_H_
 

	
 
#include <iostream>
 
#include <cmath>
 
#include "sqr.h"
 
#ifdef QTGRAPHICS
 
#include <QPointF>
 
#endif
 

	
 
// three dimensional vector
 
using namespace std;
 

	
 
class Vector {
 

	
 
 public:
 
  inline Vector(const double cx=0,const double cy=0,const double cz=0) {
 
    x=cx;
 
    y=cy;
 
    z=cz;
 
  }; 
 
  explicit inline Vector(const double m[3]) {
 
    x=m[0];
 
    y=m[1];
 
    z=m[2];
 
  }
 

	
 
  // should be taken over by default arguments of Vector constructor
 
  /*  inline Vector(void) { */
 
  /*     x=0.; */
 
  /*     y=0.; */
 
  /*     z=0.; */
 
  /*   } */
 

	
 
  inline Vector(const Vector &source) { 
 

	
 
    // copy constructor
 

	
 
    x=source.x;
 
    y=source.y;
 
    z=source.z;
 

	
 
  }
 
  // type conversion from and to QPointF (2D vector class from Qt library; we throw away "z" here!!)
 
#ifdef QTGRAPHICS
 
  inline operator QPointF() const {
 
    return QPointF( x, y );
 
  }
 
  inline Vector(const QPointF &p) {
 
    x = p.x();
 
    y = p.y();
 
    z = 0.;
 
  }
 
#endif
 
  virtual ~Vector() {
 

	
 
  };
 

	
 
  virtual ostream& print(ostream &os) const;
 
  void operator=(const Vector &source); // assignment operator
 
  void operator=(const double &s) {
 
    x=s;
 
    y=s;
 
    z=s;
 
  }
 
  Vector operator+(const Vector &v) const; // addition
 
  inline Vector operator-(const Vector &v) const { 
 

	
 
    Vector result;
 

	
 
    result.x=x-v.x;
 
    result.y=y-v.y;
 
    result.z=z-v.z;
 

	
 
    return result;
 
  }
 
  Vector &operator-=(const Vector &v);
 

	
 
  inline Vector &operator+=(const Vector &v) {
 

	
 
    x+=v.x;
src/wall.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include "wall.h"
 
#include "cell.h"
 
#include "wallitem.h"
 
#include "node.h"
 
#include "apoplastitem.h"
 
//#include "apoplastitem.h"
 
#include <algorithm>
 
#include <QGraphicsScene>
 

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

	
 
/*! Check if this Wall still belongs to Cell a, otherwise gives it to Cell b.
 
  \return true: Wall was corrected
 
  \return false: Wall was still correct
 
*/
 
bool Wall::CorrectWall( void ) {
 

	
 

	
 
  // collect all cells to which my nodes are connected on one list
 
  list<CellBase *> owners;
 
  transform(n1->owners.begin(),n1->owners.end(), back_inserter(owners), mem_fun_ref(&Neighbor::getCell));
 
  transform(n2->owners.begin(),n2->owners.end(), back_inserter(owners), mem_fun_ref(&Neighbor::getCell));
 

	
 
  // get the list of duplicates
 
  list<CellBase *> wall_owners;
 
  owners.sort();
 
  //transform(owners.begin(), owners.end(), ostream_iterator<int>(cerr, ", "), mem_fun(&Cell::Index));
 
  duplicates_copy( owners.begin(), owners.end(), back_inserter(wall_owners) );
 

	
 
  // duplicates are the cells to which the Wall belongs
 
  // For the first division, wall finds three "owners", including the boundary_polygon.
 
  // Remove that one from the list.
 
  //cerr << "wall_owners.size() = " << wall_owners.size() << endl;
 
  if (wall_owners.size() == 3 && nwalls==1 /* bug-fix 22/10/2007; confine this condition to first division only */) {
 

	
 
#ifdef QDEBUG
 
    qDebug() << "nwalls = " << nwalls << endl;
 
#endif
 
    // special case for first cleavage
 

	
 
    // find boundary polygon in the wall owners list
 
    list<CellBase *>::iterator bpit = find_if (
 
					       wall_owners.begin(), wall_owners.end(), 
 
					       mem_fun( &CellBase::BoundaryPolP )
 
					       );
 
    if (bpit!=wall_owners.end()) {
 

	
 
      // add a Wall with the boundary_polygon to each cell
 
      Wall *bp_wall1 = new Wall( n2, n1, c1, (*bpit) );
 
      bp_wall1->CopyWallContents(*this);
 
      ((Cell *)c1)->AddWall( bp_wall1);
 
      ((Cell *)(*bpit))->AddWall(bp_wall1);
 

	
 
      Wall *bp_wall2 = new Wall( n1, n2, c2, (*bpit) );
 
@@ -117,100 +117,100 @@ bool Wall::CorrectWall( void ) {
 
  if ( (c1 == cell1 && c2==cell2) || (c1 == cell2 && c2 == cell1) ) {
 

	
 
    return false;
 
  }
 

	
 
  if ( c1 == cell1 ) {
 
    //cerr << "Block 1\n";
 
    ((Cell *)c2) -> RemoveWall(this);
 
    c2 = cell2;
 
    ((Cell *)c2) -> AddWall(this);
 
  } else {
 
    if ( c1 == cell2 ) {
 
      //	cerr << "Block 2\n";
 
      ((Cell *)c2) -> RemoveWall(this);
 
      c2 = cell1;
 
      ((Cell *)c2) -> AddWall(this);
 
    } else {
 
      if ( c2 == cell1) {
 
	((Cell *)c1)->RemoveWall(this);
 
	c1 = cell2;
 
	((Cell *)c1) -> AddWall(this);
 
	//  cerr << "Block 3\n";
 
      } else {
 
	if ( c2 == cell2) {
 
	  ((Cell *)c1)->RemoveWall(this);
 
	  c1 = cell1;
 
	  ((Cell *)c1)->AddWall(this);
 
	  //	  cerr << "Block 3\n";
 
	} else {
 
#ifdef QDEBUG
 
	  qDebug() << "Warning, cell wall was not corrected." << endl;
 
#endif
 
	  return false;
 
	}
 
      }
 
    }
 
  }
 
  return true;
 
}
 

	
 
void Wall::Draw(QGraphicsScene *c) {
 

	
 
  WallItem *wi1 = new WallItem(this, 1, c);
 
  WallItem *wi2 = new WallItem(this, 2, c);
 
  wi1->show();
 
  wi2->show();
 
}
 

	
 
void Wall::DrawApoplast(QGraphicsScene *c) {
 
/* void Wall::DrawApoplast(QGraphicsScene *c) {
 
  ApoplastItem *apo = new ApoplastItem(this, c);
 
  apo->show();
 
}
 
}*/
 

	
 
void Wall::ShowStructure(QGraphicsScene *c) {
 

	
 
  Vector offset = Cell::Offset();
 
  double factor = Cell::Factor();
 

	
 
  Vector startpoint ( ((offset.x+n1->x)*factor),((offset.y+n1->y)*factor)),
 
    endpoint (((offset.x+n2->x)*factor),((offset.y+n2->y)*factor));
 

	
 
  Vector linevec = endpoint - startpoint;
 
  Vector midline = startpoint + linevec/2.;
 
  Vector perpvec = linevec.Normalised().Perp2D();
 
  Vector textpos1 = midline + 100 * perpvec;
 
  Vector textpos2 = midline - 100 * perpvec;
 

	
 
  QGraphicsLineItem *line = new QGraphicsLineItem(0,c);
 

	
 
  line->setPen( QPen(QColor(par.arrowcolor),2) );
 
  line->setLine(startpoint.x, startpoint.y, endpoint.x, endpoint.y );
 
  line->setZValue(10);
 
  line->show();
 

	
 
  QGraphicsSimpleTextItem *text1 = new QGraphicsSimpleTextItem( QString("%1").arg(c2->Index()),0,c);
 
  QGraphicsSimpleTextItem *text2 = new QGraphicsSimpleTextItem( QString("%1").arg(c1->Index()),0,c);
 

	
 
  text1 -> setPos( textpos1.x, textpos1.y );
 
  text2 -> setPos( textpos2.x, textpos2.y );
 
  text1->setZValue(20); text2->setZValue(20);
 

	
 
  text1->setFont( QFont( "Helvetica", par.nodenumsize, QFont::Bold) );
 
  text2->setFont( QFont( "Helvetica", par.nodenumsize, QFont::Bold) );
 

	
 
  text1->setPen ( QColor(par.textcolor) );
 
  text2->setPen ( text1->pen() );
 
  text1->show(); text2->show();
 
}
 
string Wall::WallTypetoStr(const WallType &wt) const {
 

	
 
  if (wt == Normal) {
 
    return string("normal");
 
  }
 

	
 
  if (wt == AuxSource) {
 
    return string("aux_source");
 
  }
 

	
 
  if (wt == AuxSink) {
 
    return string("aux_sink");
src/wall.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _WALL_H_
 
#define _WALL_H_
 

	
 
#include "wallbase.h"
 
#include <libxml/parser.h>
 
#include <libxml/tree.h>
 

	
 
#include<QGraphicsScene>
 

	
 
class Wall : public WallBase {
 

	
 
 public:
 
 Wall(Node *sn1, Node *sn2, CellBase *sc1, CellBase *sc2) : WallBase(sn1, sn2, sc1, sc2) {}
 

	
 

	
 
  void XMLAdd(xmlNodePtr parent_node) const;
 
  bool CorrectWall(void);
 

	
 

	
 
  // Graphics:
 
  //! Visualize transport protein concentrations
 
  void Draw(QGraphicsScene *c);
 

	
 
  //! Visualize contents of the apoplast
 
  void DrawApoplast(QGraphicsScene *c); 
 
  //void DrawApoplast(QGraphicsScene *c); 
 
  /*! \brief Visualize the structure of the wall (Cell ID's etc.). 
 
    Used for debugging purposes.
 
  */
 
  void ShowStructure(QGraphicsScene *c);
 

	
 
 private:
 
  string WallTypetoStr(const WallType &wt) const;
 
};
 

	
 
#endif
 

	
 
/* finis */
src/wallbase.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <QDebug>
 

	
 
#include "wall.h"
 
#include "wallbase.h"
 
#include "node.h"
 
#include "mesh.h"
 
#include "parameter.h"
 
#include <sstream>
 
#include <string>
 
#include "warning.h"
 

	
 
#ifdef QTGRAPHICS
 
#include <QGraphicsScene>
 
#include <QGraphicsLineItem>
 
#include "wallitem.h"
 
#include "apoplastitem.h"
 
//#include "apoplastitem.h"
 
#endif
 

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

	
 
int WallBase::nwalls=0;
 

	
 
ostream &WallBase::print(ostream &os) const {
 
  os << "{ " << n1->Index() << "->" << n2->Index() 
 
     << ", " << c1->Index() << " | " << c2->Index() << "} ";
 
  return os;
 
}
 

	
 
ostream &operator<<(ostream &os, const WallBase &w) { 
 
  w.print(os); 
 
  return os;
 
}
 

	
 

	
 
WallBase::WallBase(Node *sn1, Node *sn2, CellBase *sc1, CellBase *sc2)
 
{
 

	
 
#ifdef QDEBUG
 
  if (sc1==sc2) { 
 
    qDebug() << "Attempting to build a wall between identical cells: " << sc1->Index() << endl; 
 
  }
 
#endif
 

	
 
  c1 = sc1;
 
  c2 = sc2;
 

	
 
  n1 = sn1;
 
  n2 = sn2;
 

	
 
  transporters1 = new double[CellBase::NChem()];
 
  transporters2 = new double[CellBase::NChem()];
 
  new_transporters1 = new double[CellBase::NChem()];
 
  new_transporters2 = new double[CellBase::NChem()];
 

	
 
  for (int i=0;i<CellBase::NChem();i++) {
 
    transporters1[i] = transporters2[i] = new_transporters1[i] = new_transporters2[i] = 0.;
 
  }
 

	
 
  apoplast = new double[CellBase::NChem()]; // not yet in use.
 
//  apoplast = new double[CellBase::NChem()]; // not yet in use.
 

	
 
  SetLength();
 

	
 
  // to visualize flux through WallBase
 
  viz_flux=0;
 
  dead = false;
 
  wall_type = Normal;
 
  wall_index = nwalls++;
 
}
 

	
 
void WallBase::CopyWallContents(const WallBase &src)
 
{
 

	
 
  for (int i=0; i<CellBase::NChem(); i++) {
 
    if (transporters1) {
 
      transporters1[i]=src.transporters1[i];
 
    }
 
    if (transporters2) {
 
      transporters2[i]=src.transporters2[i];
 
    }
 
    if (new_transporters1) {
 
      new_transporters1[i]=src.new_transporters1[i];
 
    }
 
    if (new_transporters2) {
 
      new_transporters2[i]=src.new_transporters2[i];
 
    }
 

	
 
    if (apoplast) {
 
  /*  if (apoplast) {
 
      apoplast[i]=src.apoplast[i];
 
    }
 
    }*/
 
  }
 
  dead = src.dead;
 
  wall_type = src.wall_type;
 
}
 

	
 
void WallBase::SwapWallContents(WallBase *src)
 
{
 

	
 
  for (int i=0; i<CellBase::NChem(); i++) {
 
    if (transporters1) {
 
      double tmp;
 

	
 
      tmp=src->transporters1[i];
 
      src->transporters1[i]=transporters1[i];
 
      transporters1[i]=tmp;
 

	
 
    }
 
    if (transporters2) {
 
      double tmp;
 
      tmp=src->transporters2[i];
 
      src->transporters2[i]=transporters2[i];
 
      transporters2[i]=tmp;
 
    }
 
    if (new_transporters1) {
 
      double tmp;
 
      tmp=src->new_transporters1[i];
 
      src->new_transporters1[i]=new_transporters1[i];
 
      new_transporters1[i]=tmp;
 
    }
 
    if (new_transporters2) {
 
      double tmp;
 
      tmp=src->new_transporters2[i];
 
      src->new_transporters2[i]=new_transporters2[i];
 
      new_transporters2[i]=tmp;			
 
    }
 

	
 
    if (apoplast) {
 
  /*  if (apoplast) {
 
      double tmp;
 
      tmp=src->apoplast[i];
 
      src->apoplast[i]=apoplast[i];
 
      apoplast[i]=tmp;		
 
    }
 
    }*/
 
  }
 
  bool tmp_bool;
 
  tmp_bool = src->dead;
 
  src->dead=dead;
 
  dead = tmp_bool;
 

	
 
  WallType tmp_wall_type;
 
  tmp_wall_type = src->wall_type;
 
  src->wall_type = wall_type;
 
  wall_type = tmp_wall_type;
 
}
 

	
 
bool WallBase::SAM_P(void)
 
{ 
 
  return N1()->sam || N2()->sam; 
 
}  
 

	
 
#include <fstream>
 

	
 
void WallBase::SetLength(void)
 
{
 

	
 
  // Step 1: find the path of nodes leading along the WallBase.
 
  // A WallBase often represents a curved cell wall: we want the total
 
  // length _along_ the wall here...
 

	
 
  // Locate first and second nodes of the edge in Cell's list of nodes
 
  list<Node *>::const_iterator first_node_edge = find(c1->nodes.begin(), c1->nodes.end(), n1);
 
  list<Node *>::const_iterator second_node_edge_plus_1 = ++find(c1->nodes.begin(), c1->nodes.end(), n2);
 

	
 
  // wrap around
 
  if (second_node_edge_plus_1 == c1->nodes.end()) {
 
    second_node_edge_plus_1 = c1->nodes.begin();
 
  }
 

	
 

	
 
  length = 0.;
 

	
 
  // Now, walk to the second node of the edge in the list of nodes
 
  stringstream deb_str;
 

	
 
  for (list<Node *>::const_iterator n=
 
	 (++first_node_edge==c1->nodes.end()?c1->nodes.begin():first_node_edge);
 
       n!=second_node_edge_plus_1;
 
       (++n == c1->nodes.end()) ? (n=c1->nodes.begin()):n  ) {
 

	
 
    list<Node *>::const_iterator prev_n = n; 
 
    if (prev_n==c1->nodes.begin()) prev_n=c1->nodes.end();
src/wallbase.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 

	
 
#ifndef _WALLBASE_H_
 
#define _WALLBASE_H_
 

	
 
#include <list>
 
#include <iostream>
 
#include "vector.h"
 

	
 
class Node;
 
class CellBase;
 

	
 
using namespace std;
 

	
 
// warning, touches original sequence
 
template<class In, class Out> Out duplicates_copy(In first, In last, Out res) {
 

	
 
  In i = adjacent_find(first, last);
 

	
 
  while (i!=last) {
 
    res++ = *i;
 
    i = adjacent_find(++i, last);
 
  }
 

	
 
  return res;
 
}
 

	
 
/*! \class WallBase. A cell wall, which runs between cell "corner points",
 
  and consists of wall elements. */
 
class WallBase {
 

	
 
 protected:
 
  friend class CellBase;
 
  friend class Cell;
 
  friend class Mesh;
 
  //! Cells to which the wall belongs
 
  CellBase *c1, *c2;
 

	
 
  //! A list of transporter protein concentrations associated with the wall
 
  double *transporters1, *transporters2;
 
  double *new_transporters1, *new_transporters2;
 

	
 
  bool IllegalP(void) { return c1 == c2; }
 

	
 
  //! The chemicals in the apoplast at this position
 
  double *apoplast;
 
  //double *apoplast;
 

	
 
  //! Pointers to the wall's corner nodes 
 
  Node *n1, *n2;
 

	
 
  double length;
 

	
 
  double viz_flux;
 

	
 
  //  bool aux_source;
 

	
 
  bool dead;
 
  // disallow usage of empty constructor
 
  WallBase(void) {}
 

	
 

	
 
  enum WallType {Normal, AuxSource, AuxSink};
 
  static int nwalls;
 
 protected:
 
  int wall_index;
 
  WallType wall_type;
 

	
 

	
 
 public:
 
  WallBase(Node *sn1, Node *sn2, CellBase *sc1, CellBase *sc2); 
 

	
 
  // shallow copy
 
  WallBase(const WallBase &src) {
 
    c1 = src.c1;
 
    c2 = src.c2;
 
    transporters1 = src.transporters1;
 
    transporters2 = src.transporters2;
 
    new_transporters1 = src.new_transporters1;
 
    new_transporters2 = src.new_transporters2;
 
    apoplast = src.apoplast;
 
    //apoplast = src.apoplast;
 
    n1 = src.n1;
 
    n2 = src.n2;
 
    length = src.length;
 
    viz_flux = src.viz_flux;
 
    dead = src.dead;
 
    wall_index = src.wall_index;
 
  }
 

	
 
  inline int Index(void) const { return wall_index;}
 
  inline bool DeadP(void) const { return dead; }
 
  inline void Kill(void) { dead = true; }
 
  // deep copying of chemicals and transporters
 
  void CopyWallContents(const WallBase &src);
 
  void SwapWallContents(WallBase *src);
 
  bool is_wall_of_cell_p ( const CellBase *c ) {
 
    return (c1==c || c2==c);
 
  }
 

	
 
  inline CellBase *C1(void) const { return c1; }
 
  inline CellBase *C2(void) const { return c2; }
 
  inline Node *N1(void) const { return n1; }
 
  inline Node *N2(void) const { return n2; }
 
  inline void setTransporters1(int ch, double val) { transporters1[ch]=val; }
 
  inline void setTransporters2(int ch, double val) { transporters2[ch]=val; }
 
  inline void setNewTransporters1(int ch, double val) { new_transporters1[ch]=val; }
 
  inline void setNewTransporters2(int ch, double val) { new_transporters2[ch]=val; }
 
  inline double Transporters1(int ch) { return transporters1[ch]; }
 
  inline double Transporters2(int ch) { return transporters2[ch]; }
 

	
 
  //! Return true if the WallBase adheres to the SAM (shoot apical meristem)
 
  bool SAM_P(void);
 
  // NB. Not checked. If cell is not found, it returns transporters2[ch]!!
 
  //inline double getTransporter(int ch, Cell *c) { return c1 == c ? transporters1[ch] : transporters2[ch]; }
 

	
 
  //! Return true if the WallBase is a source of auxin
 
  inline bool AuxinSource(void) const { return wall_type == AuxSource; }
 
  inline bool AuxinSink(void) const { return wall_type == AuxSink; }
 

	
 
  inline void cycleWallType(void) { 
 

	
 
    if (wall_type == Normal)  
 
      wall_type = AuxSource;
 
    else
 
      if (wall_type == AuxSource) 
 
	wall_type = AuxSink;
 
      else
 
	if (wall_type == AuxSink) {
 
	  wall_type = Normal;
 
	}
 
  }
 
  // checked version. Use during debugging stage.
 
  inline double getTransporter(CellBase *c, int ch) const
 
  { 
 
    return c1 == c ? transporters1[ch] : ( c2 == c ? transporters2[ch] : throw "WallBase::getTransporter called with wrong cell") ; } 
 

	
 
  inline void setTransporter(CellBase *c, int ch, double val) { 
 
    if ( c1 == c ) {
 
      transporters1[ch]=val;
 
    } else 
 

	
 
      if (c2 == c ) {
 
	transporters2[ch]=val;
 
      } else {
 
	throw "WallBase::setTransporter called with wrong cell"; 
 
      }
 
  }
 
  inline double getApoplast(int ch) const { return apoplast[ch]; }
 
  inline void setApoplast(int ch, double val) { apoplast[ch] = val; }
 
  //inline double getApoplast(int ch) const { return apoplast[ch]; }
 
  //inline void setApoplast(int ch, double val) { apoplast[ch] = val; }
 
  inline CellBase *getOtherCell(CellBase *c) { return c1 == c ? c2 : c1; }
 
  Vector getInfluxVector(CellBase *c);
 
  Vector getWallVector(CellBase *c);
 
  void CorrectTransporters(double orig_length);
 

	
 
  inline double Length(void) { return length; }
 
  //double Length(void);
 

	
 
  ostream &print(ostream &os) const; 
 

	
 
  void SetLength(void);
 
  void Transport(void);
 

	
 
  inline void setVizFlux( double value ) { viz_flux = value; } 
 

	
 
  /*! Return vector containing the directional flux through the wall.
 
    as defined by the value "viz_flux" which is supplied by the end-user
 
    in the TransportFunction.
 
  */
 
  Vector VizFlux(void);
 
  bool IntersectsWithDivisionPlaneP(const Vector &p1, const Vector &p2);
 
  void SetTransToNewTrans( void );
 

	
 
 private:
 
};
 

	
 
ostream &operator<<(ostream &os, const WallBase &w);
 
#endif
 

	
 
/* finis */
src/wallitem.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <QDebug>
 
#include <string>
 
#include <QGraphicsScene>
 
#include <QVector>
 
#include "canvas.h"
 
#include "wallitem.h"
 
#include "parameter.h"
 
#include "node.h"
 
#include "transporterdialog.h"
 

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

	
 
WallItem::WallItem( Wall *w, int wallnumber, QGraphicsScene *canvas )
 
  : QGraphicsLineItem( 0, canvas ), SimItemBase( w, canvas){
 

	
 
  wn = wallnumber;
 

	
 
  extern Parameter par;
 

	
 
  setColor();
 

	
 
  // line with "PIN1"is a bit inside the cell wall
 
  Vector edgevec = (*(w->N2())) - (*(w->N1()));
 
  Vector perp = edgevec.Normalised().Perp2D();
 

	
 
  Vector offs = Cell::Offset();
 
  double factor = Cell::Factor();
 

	
 
  Vector from = ( offs + *(w->N1()) ) * factor + (wn==1?-1:1) * par.outlinewidth * 0.5 * factor * perp;
 
  Vector to = ( offs + *(w->N2()) ) *factor + (wn==1?-1:1) * par.outlinewidth * 0.5 * factor * perp;
 

	
 

	
 
  Vector tmp_centroid = ( *(w->N2()) + *(w->N1()) )/2.;
 
  Vector centroid = ( offs + tmp_centroid ) * factor;
 

	
 
  QString text=QString("%1").arg(w->Index());
 
  setLine(( from.x ),
src/wallitem.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _WALLITEM_H_
 
#define _WALLITEM_H_
 

	
 
#include <QGraphicsScene>
 
#include <QGraphicsLineItem>
 
#include <QPainter>
 
#include <qpainter.h>
 
#include <QMouseEvent>
 
#include "simitembase.h"
 
#include "wall.h"
 

	
 
//! Shows transporter concentrations at one side of the wall
 

	
 
class WallItem : public QGraphicsLineItem, public SimItemBase
 
{
 
 public:
 
  WallItem( Wall *n, int wallnumber, QGraphicsScene *canvas );
 
  virtual ~WallItem() {}
 
  Wall &getWall(void) const { return *class_cast<Wall*>(obj); }
 
  void OnClick(QMouseEvent *e);  
 
  void setColor(void);
 
 private:
 
  int wn;
 
};
 

	
 
#endif
 

	
 
/* finis */
src/warning.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include <string>
 
#include <stdarg.h>
 
#include <stdio.h>
 
#include <stdlib.h>
 
#include <iostream>
 
#include "warning.h"
 
#ifdef QTGRAPHICS
 
#include <qapplication.h>
 
#include "canvas.h"
 
#endif
 
#include <QMessageBox>
 

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

	
 
int Quiet=0;
 

	
 
/*
 
 * ERROR: scream and die quickly.
 
 */
 

	
 
#ifndef QTGRAPHICS
 
void MyWarning::error(char * fmt, ...)
 
{
 
  va_list ap;
 

	
 
  va_start(ap, fmt);
 
  vfprintf(stderr, fmt, ap);		/* invoke interface to printf       */
 
  fprintf(stderr,"\n");     /* automatic \n by Roeland */
 
  fflush(stderr);			/* drain std error buffer 	    */
 
  va_end(ap);
 
  exit(1);				/* quit with error status	    */
 
}
 
#else
 
//#include <qmessagebox.h>
 
#include "UniqueMessage.h"
 
void MyWarning::error(const char *fmt, ...)
 
{
src/warning.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _WARNING_H_
 
#define _WARNING_H_
 

	
 
#define MEMORYCHECK(x) if ((x)==NULL) {   fprintf(stderr, "Out of Memory error in "#x" \n");  exit(0); }
 

	
 
#define UNIDENTIFIED 2353996
 

	
 
#ifdef __cplusplus 
 
extern "C" { 
 
#endif
 
  // namespace MyWarning needed because libxml2 also defines a warning token.
 

	
 
  namespace MyWarning {
 
    void error(const char *, ...);
 
    void warning(const char *, ...);
 
    void unique_warning(const char *, ...);
 
  }
 

	
 
#ifdef __cplusplus
 
}
 
#endif
 

	
 
#endif
 

	
 
/* finis */
src/xmlwrite.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 
#include "mesh.h"
 
#include "parameter.h"
 

	
 
#include <ctime>
 
#include <cstring>
 
#include <string>
 
#include <sstream>
 
#include <QString>
 
#include <libxml/parser.h>
 
#include <libxml/tree.h>
 
#include <libxml/xpath.h>
 
#include <libxml/xmlreader.h>
 
#include <QLocale>
 
#include "xmlwrite.h"
 
#include "nodeset.h"
 
#include "warning.h"
 
#include "output.h" 
 

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

	
 
using namespace MyWarning;
 

	
 
void ThrowStringStream(stringstream &s) {
 

	
 
  static char *msg = 0;
 
  msg = (char *)malloc((1+s.str().length())*sizeof(char));
 
  strcpy(msg,s.str().c_str());
 
  throw(msg);
 
}
 

	
 

	
 
// Add this cell to the XML tree
 
void Cell::XMLAdd(xmlNodePtr cells_node) const {
 

	
 
  // Save the cell to a stream so we can reconstruct its state later
 
  xmlNodePtr xmlcell = xmlNewChild(cells_node, NULL, BAD_CAST "cell",NULL);
 
  XMLAddCore(xmlcell);
 
@@ -610,108 +610,108 @@ void Wall::XMLAdd(xmlNode *parent) const
 
    xmlNewProp(xmlwall, BAD_CAST "n2", BAD_CAST text.str().c_str());
 
  }
 

	
 
  {
 
    ostringstream text;
 
    text << length;
 
    xmlNewProp(xmlwall, BAD_CAST "length", BAD_CAST text.str().c_str());
 
  }
 

	
 

	
 
  {
 
    ostringstream text;
 
    text << viz_flux;
 
    xmlNewProp(xmlwall, BAD_CAST "viz_flux", BAD_CAST text.str().c_str());
 
  }
 

	
 
  {
 
    ostringstream text;
 
    text << WallTypetoStr(wall_type);
 
    xmlNewProp(xmlwall, BAD_CAST "wall_type", BAD_CAST text.str().c_str());
 
  }
 

	
 

	
 
  xmlNodePtr tr1_xml = xmlNewChild(xmlwall, NULL, BAD_CAST "transporters1", NULL); 
 
  if (transporters1) {
 
    for (int i=0;i<Cell::NChem();i++) {
 
      xmlNodePtr tr1_val_xml = xmlNewChild(tr1_xml, NULL, BAD_CAST "val", NULL);
 
      { 
 
	ostringstream text;
 
	text << transporters1[i];
 
	xmlNewProp(tr1_val_xml, BAD_CAST "v", BAD_CAST text.str().c_str());
 

	
 
      }
 
    }
 
  }
 
  if (transporters2) {
 
    xmlNodePtr tr2_xml = xmlNewChild(xmlwall, NULL, BAD_CAST "transporters2", NULL); 
 

	
 
    for (int i=0;i<Cell::NChem();i++) {
 
      xmlNodePtr tr2_val_xml = xmlNewChild(tr2_xml, NULL, BAD_CAST "val", NULL);
 
      { 
 
	ostringstream text;
 
	text << transporters2[i];
 
	xmlNewProp(tr2_val_xml, BAD_CAST "v", BAD_CAST text.str().c_str());
 
      }
 
    }
 
  }
 

	
 
  if (apoplast) {
 
/*  if (apoplast) {
 
    xmlNodePtr apo_xml = xmlNewChild(xmlwall, NULL, BAD_CAST "apoplast", NULL); 
 

	
 
    for (int i=0;i<Cell::NChem();i++) {
 
      xmlNodePtr apo_val_xml = xmlNewChild(apo_xml, NULL, BAD_CAST "val", NULL);
 
      { 
 
	ostringstream text;
 
	text << transporters2[i];
 
	xmlNewProp(apo_val_xml, BAD_CAST "v", BAD_CAST text.str().c_str());
 
      }
 
    }
 
  } 
 
  } */
 
}
 

	
 

	
 
vector<double> XMLIO::XMLReadValArray(xmlNode *cur)
 
{
 

	
 
  vector<double> result;
 
  QLocale standardlocale(QLocale::C);
 
  bool ok;
 

	
 
  xmlNode *valarray_node = cur->xmlChildrenNode;
 
  while (valarray_node!=NULL) {
 
    if (!xmlStrcmp(valarray_node->name, (const xmlChar *)"val")) {
 
      xmlChar *vc = xmlGetProp(valarray_node, BAD_CAST "v");
 
      if (vc) {
 
	//result.push_back(strtod( (const char *)vc, 0));
 
	result.push_back(standardlocale.toDouble((char *)vc, &ok));
 
	if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(char *)vc);
 
	xmlFree(vc);
 
      }
 

	
 
    }
 
    valarray_node = valarray_node->next;
 
  }
 
  return result;
 
}
 

	
 
void Mesh::XMLSave(const char *docname, xmlNode *options) const
 
{
 

	
 
  // based on libxml2 example code "tree2.c"
 

	
 
  xmlDocPtr doc = NULL;       /* document pointer */
 
  xmlNodePtr root_node = NULL;/* node pointers */
 
  //xmlDtdPtr dtd = NULL;       /* DTD pointer */
 

	
 
  //  LIBXML_TEST_VERSION;
 

	
 
  /* 
 
   * Creates a new document, a node and set it as a root node
 
   */
 
  doc = xmlNewDoc(BAD_CAST "1.0");
 
  root_node = xmlNewNode(NULL, BAD_CAST "leaf");
 
  xmlDocSetRootElement(doc, root_node);
 

	
 
  /* 
 
   * xmlNewProp() creates attributes, which is "attached" to an node.
 
   * It returns xmlAttrPtr, which isn't used here.
 
@@ -1234,127 +1234,127 @@ void Mesh::XMLReadWalls(xmlNode *root, v
 
		xmlChar *nc = xmlGetProp(v_node, (const xmlChar *) "v");
 

	
 
		if (nc==0) {
 
		  unique_warning("Token \"v\" not found in xmlwrite.cpp at or around line no. 835");
 
		}
 

	
 
		double v = standardlocale.toDouble((const char *)nc, &ok);
 
		if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)nc);
 

	
 
		w->transporters1[nv++]=v;
 
		xmlFree(nc);
 

	
 
	      }
 
	      v_node = v_node->next; 
 
	    }
 
	  }
 

	
 
	  if ((!xmlStrcmp(w_node->name, (const xmlChar *)"transporters2"))) {
 

	
 
	    xmlNode *v_node = w_node->xmlChildrenNode;
 
	    int nv=0;
 
	    while (v_node!=NULL) {
 
	      if ((!xmlStrcmp(v_node->name, (const xmlChar *)"val"))) {
 
		if (nv>=Cell::NChem()) {
 
		  {
 
		    stringstream text;
 
		    text << "Exception in Mesh::XMLRead: Too many transporter values given for wall(s). Ignoring remaining values.";
 
		    unique_warning(text.str().c_str());
 
		    break;
 
		  }
 
		}
 

	
 
		xmlChar *nc = xmlGetProp(v_node, (const xmlChar *) "v");
 

	
 
		if (nc==0) {
 
		  unique_warning("Token \"v\" not found in xmlwrite.cpp at or around line no. 861");
 
		}
 

	
 
		double v = standardlocale.toDouble((const char *)nc, &ok);
 
		if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)nc);
 

	
 
		w->transporters2[nv++]=v;
 
		xmlFree(nc);
 
	      }
 
	      v_node = v_node->next; 
 
	    }
 
	  } 
 

	
 
	  if ((!xmlStrcmp(w_node->name, (const xmlChar *)"apoplast"))) {
 
	/*  if ((!xmlStrcmp(w_node->name, (const xmlChar *)"apoplast"))) {
 

	
 
	    xmlNode *v_node = w_node->xmlChildrenNode;
 
	    int nv=0;
 
	    while (v_node!=NULL) {
 

	
 
	      if ((!xmlStrcmp(v_node->name, (const xmlChar *)"val"))) {
 
		if (nv>=Cell::NChem()) {
 
		  {
 
		    stringstream text;
 
		    text << "Exception in Mesh::XMLRead: Too many transporter values given for wall(s). Ignoring remaining values.";
 

	
 
		    unique_warning(text.str().c_str());
 
		    break;
 
		  }
 
		}
 
		xmlChar *nc = xmlGetProp(v_node, (const xmlChar *) "v");
 

	
 
		if (nc==0) {
 
		  unique_warning("Token \"v\" not found in xmlwrite.cpp at or around line no. 887");
 
		}
 

	
 
		double v = standardlocale.toDouble((const char *)nc, &ok);
 
		if (!ok) MyWarning::error("Could not convert \"%s\" to double in XMLRead.",(const char *)nc);
 

	
 
		w->apoplast[nv++]=v;
 
		xmlFree(nc);
 
	      }
 
	      v_node = v_node->next; 
 
	    }
 
	  }
 
	  }*/
 
	  w_node=w_node->next;
 
	}
 
      }
 
      cur = cur->next;
 
    }
 
  }
 
}
 

	
 

	
 
void Mesh::XMLReadWallsToCells(xmlNode *root, vector<Wall *> *tmp_walls)
 
{
 

	
 
  // Add the walls to the cells (do this after reading the walls; read walls after reading cells...)
 
  // 1. Read Nodes
 
  // 2. Read Cells
 
  // 3. Read Walls
 
  // 4. Read Walls into Cells
 

	
 
  xmlNode *cur = root->xmlChildrenNode;
 
  int ci=0; // cell index
 

	
 
  while (cur!=NULL) {
 

	
 
    if ((!xmlStrcmp(cur->name, (const xmlChar *)"cell")) ||
 
	(!xmlStrcmp(cur->name, (const xmlChar *)"boundary_polygon" ))) {
 

	
 
      vector<int> tmp_walls_ind;
 
      xmlNode *n = cur->xmlChildrenNode;
 

	
 
      while(n!=NULL) {
 

	
 
	if ((!xmlStrcmp(n->name, (const xmlChar *)"wall"))) {
 
	  xmlChar *nc = xmlGetProp(n, BAD_CAST "w");
 

	
 
	  if (nc==0) {
 
	    unique_warning("Token \"w\" not found in xmlwrite.cpp at or around line no. 931");
 
	  }
 
	  tmp_walls_ind.push_back(atoi( (char *)nc));
 
	  xmlFree(nc);
 
	}
 
	n = n->next;
 
      }
 

	
 
      if (!xmlStrcmp(cur->name, (const xmlChar *)"boundary_polygon")) {
 

	
 
	int nwalls = tmp_walls_ind.size();
 
	for (int i=0;i<nwalls;i++) {
 
	  boundary_polygon->walls.push_back((*tmp_walls)[tmp_walls_ind[i]]);
src/xmlwrite.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  The Virtual Leaf is free software: you can redistribute it and/or modify
 
 *  VirtualLeaf is free software: you can redistribute it and/or modify
 
 *  it under the terms of the GNU General Public License as published by
 
 *  the Free Software Foundation, either version 3 of the License, or
 
 *  (at your option) any later version.
 
 *
 
 *  The Virtual Leaf is distributed in the hope that it will be useful,
 
 *  VirtualLeaf is distributed in the hope that it will be useful,
 
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
 
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
 *  GNU General Public License for more details.
 
 *
 
 *  You should have received a copy of the GNU General Public License
 
 *  along with the Virtual Leaf.  If not, see <http://www.gnu.org/licenses/>.
 
 *
 
 *  Copyright 2010 Roeland Merks.
 
 *
 
 */
 

	
 

	
 
#ifndef _XML_WRITE_H_
 
#define _XML_WRITE_H_
 

	
 
#include <vector>
 
#include <libxml/tree.h>
 
#include <cstring>
 

	
 
namespace XMLIO {
 

	
 
  std::vector <double> XMLReadValArray(xmlNode *cur);
 
  template<class For, class E> long list_index (For beg, For end, E *elem) {
 

	
 
    long n = 0;
 
    for (For i=beg;
 
	 i!=end;
 
	 i++) {
 
      if (*i == elem) {
 
	return n;
 
      }
 
      n++;
 
    }
 
    return -1;
 
  }
 
}
 

	
 

	
 
static const char * bool_names[2] = {"true","false"};
 

	
 
inline const char *bool_name(bool q) { return q ? bool_names[0] : bool_names[1]; }
 

	
 
inline bool strtobool(const char *str) { 
 
  if (!strcmp(str, "true")) {
 
    return true;
 
  } else {
 
    if (!strcmp(str, "false")) {
 
      return false;
0 comments (0 inline, 0 general)