Changeset - 2accd83924da
[Not reviewed]
default
0 20 0
Roeland Merks - 15 years ago 2010-11-25 14:57:33
roeland.merks@cwi.nl
Some last fine-tuning
- File dialogs start from appropriate data directories
- XML files contain right values for datadir
- Reordered parameter dialog
- Added new "make perl" heading to the makefile
- Corrected segfault for batch mode

user: Roeland Merks <roeland.merks@cwi.nl>
branch 'default'
changed data/leaves/auxin_growth.xml
changed data/leaves/meinhardt_init.xml
changed data/leaves/tutorial1_init.xml
changed data/leaves/tutorial2_init.xml
changed data/leaves/tutorial3_init.xml
changed data/leaves/tutorial4_init.xml
changed data/leaves/tutorial5_init.xml
changed src/Makefile
changed src/VirtualLeaf.cpp
changed src/VirtualLeafpar.tmpl
changed src/canvas.cpp
changed src/canvas.h
changed src/mesh.cpp
changed src/mesh.h
changed src/modelcatalogue.cpp
changed src/modelcatalogue.h
changed src/parameter.cpp
changed src/parameter.h
changed src/pardialog.cpp
changed src/pardialog.h
16 files changed:
0 comments (0 inline, 0 general)
data/leaves/auxin_growth.xml
Show inline comments
 
binary diff not shown
data/leaves/meinhardt_init.xml
Show inline comments
 
binary diff not shown
data/leaves/tutorial1_init.xml
Show inline comments
 
binary diff not shown
data/leaves/tutorial2_init.xml
Show inline comments
 
binary diff not shown
data/leaves/tutorial3_init.xml
Show inline comments
 
binary diff not shown
data/leaves/tutorial4_init.xml
Show inline comments
 
binary diff not shown
data/leaves/tutorial5_init.xml
Show inline comments
 
binary diff not shown
src/Makefile
Show inline comments
 
# $Id$
 

	
 
# Set an environment varible $(MAKE) to the name of the make command
 
# on your machine, e.g. 'make' on UNIX and 'mingw32-make' on windows.
 
# Fallback default is UNIX make.
 

	
 
ifeq ($(MAKE),)
 
	MAKE=make
 
endif
 

	
 
# Ditto for QMAKE
 
ifeq ($(QMAKE),)
 
	QMAKE=qmake
 
endif
 

	
 
all: VirtualLeaf libplugin plugins tutorials
 

	
 
VirtualLeaf: Makefile.VirtualLeaf
 
	$(MAKE) -f Makefile.VirtualLeaf
 

	
 
Makefile.VirtualLeaf: VirtualLeaf.pro
 
	$(QMAKE) -o $@ $< 
 

	
 
libplugin: Makefile.libplugin
 
	$(MAKE) -f Makefile.libplugin
 

	
 
Makefile.libplugin: libplugin.pro
 
	$(QMAKE) -o $@ $< 
 

	
 
plugins:
 
	$(MAKE) -C build_models -f Makefile
 

	
 
tutorials:
 
	$(MAKE) -C build_models -f Makefile
 
	$(MAKE) -C TutorialCode -f Makefile
 

	
 
perl: Makefile.perl
 
	$(MAKE) -f Makefile.perl
 

	
 
clean:
 
	$(MAKE) -f Makefile.libplugin clean
 
	$(MAKE) -f Makefile.VirtualLeaf clean
 
	$(MAKE) -C build_models -f Makefile clean
 
	$(MAKE) -C TutorialCode -f Makefile clean
 
ifeq ($(MAKE),make)
 
	touch VirtualLeaf.pro
 
	touch libplugin.pro
 
else
 
	copy /b VirtualLeaf.pro +,,
 
	copy /b libplugin.pro +,,
 
endif
 

	
 
#finis
src/VirtualLeaf.cpp
Show inline comments
 
@@ -114,199 +114,204 @@ 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());
 
		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.WallCircumference()).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();
 

	
 
  int count=(int)mesh.getTime();
 

	
 
  if (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()) 
 
    mesh.LoopWalls( bind2nd( mem_fun_ref( &Wall::DrawApoplast ), &canvas ) );
 
*/
 
  if (ShowMeshP()) 
 
    mesh.DrawNodes(&canvas);
 

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

	
 
  if ( ( batch || MovieFramesP() )) {
 
    if (!(count%par.storage_stride) ) {
 
      stringstream fname;
 
      fname << par.datadir << "/leaf.";
 
      fname.fill('0');
 
      fname.width(6);
 
      fname << count << ".png";
 
      // Write high-res PNG snapshot every plot step
 
      Save(fname.str().c_str(), "PNG", 1024, 768);
 
    }
 

	
 
    if (!(count%par.xml_storage_stride)) {
 
      stringstream fname;
 
      fname << par.datadir << "/leaf.";
 
      fname.fill('0');
 
      fname.width(6);
 
      fname << count << ".xml";
 
      // Write XML file every ten plot steps
 
      mesh.XMLSave(fname.str().c_str(), XMLSettingsTree());
 
    }
 
  }
 
}
 

	
 

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

	
 
    if (qApp->type()==QApplication::Tty) {
 
      
 
      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 {
 
      ((Main *)main_window)->readStateXML(leaffile);
 
    }
 
    
 
  } else {
 
    mesh.StandardInit();
 
  }
 
  
 
  Cell::SetMagnification(1);
 
  Cell::setOffset(0,0);
 
  
 
  FitLeafToCanvas();
 
  Plot();
 

	
 
}
 

	
 
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();
 
      mesh.DoCellHouseKeeping();
 
      //mesh.LoopCurrentCells(mem_fun(&plugin->CellHouseKeeping)); // this includes cell division
 

	
 
      // Reaction diffusion	
 
      mesh.ReactDiffuse(par.rd_dt);
 
      t++;
 
      Plot(par.resize_stride);
 
    }
 
  } else {
 
    mesh.ReactDiffuse(par.rd_dt);
 
    Plot(par.resize_stride);
 
  }
 
  i++;
 
  return mesh.getTime();
 
}
 

	
 

	
 

	
 
/* Called if a cell is clicked */
 
void Cell::OnClick(QMouseEvent *e){}
 

	
 

	
 
/* Custom message handler - Default appends a newline character to the end of each line. */ 
 
void vlMessageOutput(QtMsgType type, const char *msg)
 
{
 
  switch (type) {
 
  case QtDebugMsg:
 
    //fprintf(stderr, "Debug: %s\n", msg);
 
    cerr << msg << flush;
 
    break;
 
  case QtWarningMsg:
 
    //fprintf(stderr, "Warning: %s\n", msg);
 
    cerr << "Warning: " << msg << flush;
 
    break;
 
  case QtCriticalMsg:
 
    fprintf(stderr, "Critical: %s\n", msg);
 
    cerr << "Critical: " << msg << flush;
 
    break;
 
  case QtFatalMsg:
 
    //fprintf(stderr, "Fatal: %s\n", msg);
 
    cerr << "Fatal: " << msg << flush;
 
    abort();
 
  }
 
}
 

	
 

	
 
Parameter par;
 

	
 
int main(int argc,char **argv) {
 

	
 
  try {
 
    int c;
 
    char *leaffile=0;
 
    char *modelfile=0;
 

	
 
    while (1) {
 
@@ -320,145 +325,145 @@ int main(int argc,char **argv) {
 
      };
 

	
 
      // short option 'p' creates trouble for non-commandline usage on MacOSX. Option -p changed to -P (capital)
 
      static char *short_options = "blm";
 
      c = getopt_long (argc, argv, "bl:m:",
 
		       long_options, &option_index);
 
      if (c == -1)
 
	break;
 

	
 

	
 
      if (c==0) {
 
	printf ("option %s", long_options[option_index].name);
 
	if (optarg)
 
	  printf (" with arg %s", optarg);
 
	printf ("\n");
 

	
 
	c = short_options[option_index];
 
      }
 

	
 
      switch (c) {
 
      case 'b':
 
	cerr << "Running in batch mode\n";
 
	batch=true;
 
	break;
 

	
 
      case 'l':
 
	leaffile=strdup(optarg);
 
	if (!leaffile) {
 
	  throw("Out of memory");
 
	}
 
	printf("Reading leaf state file '%s'\n", leaffile);
 
	break;
 

	
 
      case 'm':
 
	modelfile=strdup(optarg);
 
	if (!modelfile) {
 
	  throw("Out of memory");
 
	}
 
	break;
 

	
 
      case '?':
 
	break;
 

	
 
      default:
 
	printf ("?? getopt returned character code 0%o ??\n", c);
 
      }
 
    }
 

	
 

	
 
    if (optind < argc) {
 
      printf ("non-option ARGV-elements: ");
 
      while (optind < argc)
 
	printf ("%s ", argv[optind++]);
 
      printf ("\n");
 
    }
 

	
 
    bool useGUI = !batch;
 
    qInstallMsgHandler(vlMessageOutput); // custom message handler
 
    QApplication app(argc,argv,useGUI);
 

	
 

	
 

	
 
    QPalette tooltippalette = QToolTip::palette();
 
    QColor transparentcolor = QColor(tooltippalette.brush(QPalette::Window).color());
 

	
 
    tooltippalette.setBrush (QPalette::Window, QBrush (transparentcolor) );
 
    QToolTip::setPalette( tooltippalette );
 

	
 
    QGraphicsScene canvas(0,0,8000,6000);
 

	
 

	
 
    if (useGUI) {
 
      main_window=new Main(canvas, mesh);
 
      if ( QApplication::desktop()->width() > ((Main *)main_window)->width() + 10
 
	   && QApplication::desktop()->height() > ((Main *)main_window)->height() +30 ) {
 

	
 
	((Main *)main_window)->show();
 
	((Main *)main_window)->resize( ((Main *)main_window)->sizeHint());
 
      } else {
 
        ((Main *)main_window)->showMaximized();
 
      }
 
      
 
      // show "About" window at start up
 
      ((Main *)main_window)->about();
 
    } else {
 
      main_window=new MainBase(canvas, mesh);
 
    }
 

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

	
 
    //    main_window->Init(leaffile);
 

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

	
 

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

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

	
 
    main_window->FitLeafToCanvas();
 

	
 
    main_window->Plot();
 
    */
 
    if (batch) {
 
      double t=0.;
 
      do {
 
	t = main_window->TimeStep();
 
      } while (t < par.maxt);
 
    } else
 
      return app.exec();
 

	
 
  } catch (const char *message) {
 
    if (batch) { 
 
      cerr << "Exception caught:" << endl;
 
      cerr << message << endl;
 
      abort();
 
    } else {
 
      QString qmess=QString("Exception caught: %1").arg(message);
 
      QMessageBox::critical(0, "Critical Error", qmess);
 
      abort();
 
    }
 
  } catch (ios_base::failure) {
 
    stringstream error_message;
 
    error_message << "I/O failure: " << strerror(errno);
 
    if (batch) {
 
      cerr << error_message.str() <<endl;
 
      abort();
 
    } else {
 
      QString qmess(error_message.str().c_str());
 
      QMessageBox::critical(0, "I/O Error", qmess );
 
      abort();
 
    }
 
  }
 
}
 

	
 
/* finis */
src/VirtualLeafpar.tmpl
Show inline comments
 
title = Parameter values for The Virtual Leaf / title
 
label = <b>Visualization</b> / label
 
arrowcolor = white / string
 
arrowsize = 100 / double
 
textcolor = red / string
 
cellnumsize = 1 / int
 
nodenumsize = 1 / int
 
node_mag = 1.0 / double 
 
outlinewidth = 1.0 / double
 
cell_outline_color = forestgreen / string
 
resize_stride = 0 / int
 
label = / label
 
label = <b>Data Export</b> / label
 
export_interval = 0 / int
 
export_fn_prefix = cell. / string
 
storage_stride = 10 / int
 
xml_storage_stride = 500 / int
 
datadir = . / directory 
 
label = / label
 
label = <b>Cell mechanics</b> / label
 
T = 1.0 / double
 
lambda_length = 100. / double
 
yielding_threshold = 4. / double
 
lambda_celllength = 0. / double
 
target_length = 60. / double 
 
cell_expansion_rate = 1. / double
 
cell_div_expansion_rate = 0. / double
 
auxin_dependent_growth = true / bool
 
ode_accuracy = 1e-4 / double
 
mc_stepsize = 0.4 / double
 
mc_cell_stepsize = 0.2 / double
 
energy_threshold = 1000. / double
 
bend_lambda = 0. / double
 
alignment_lambda = 0. / double
 
rel_cell_div_threshold = 2. / double
 
rel_perimeter_stiffness = 2 / double
 
collapse_node_threshold = 0.05 / double
 
morphogen_div_threshold = 0.2 / double
 
morphogen_expansion_threshold = 0.01 / double
 
copy_wall = true / bool
 
label = / label
 
label = <b>Auxin transport and PIN1 dynamics</b> / label
 
source = 0. / double
 
D = 0., 0.0, 0.0, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. / doublelist
 
initval = 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. / doublelist
 
k1 = 1. / double
 
k2 = 0.3 / double
 
r = 1. / double
 
kr = 1. / double
 
#k3 = 1 / double
 
#k4 = 0.3 / double
 
km = 1. / double
 
Pi_tot = 1. / double
 
transport = 0.036 / double
 
ka = 1 / double
 
# d = 1e-06 / double
 
# e = 0.01 / double
 
# f = 10 / double
 
pin_prod = 0.001 / double
 
pin_prod_in_epidermis = 0.1 / double
 
pin_breakdown = 0.001 / double
 
pin_breakdown_internal = 0.001 / double
 
aux1prod = 0.001 / double
 
aux1prodmeso = 0. / double
 
aux1decay = 0.001 / double
 
aux1decaymeso = 0.1 / double
 
aux1transport = 0.036 / double
 
aux_cons = 0. / double
 
aux_breakdown = 0. / double
 
kaux1 = 1 / double
 
kap = 1 / double
 
leaf_tip_source = 0.001 / double
 
sam_efflux = 0.0001 / double
 
sam_auxin = 10. / double
 
# gf_prod = 1e-3 / double
 
# gf_decay = 1e-3 / double
 
sam_auxin_breakdown = 0 / double
 
#label = / label
 
#label = <b>miscellaneous</b> / label
 
van3prod = 0.002 / double
 
van3autokat = 0.1 / double
 
van3sat = 10 / double
 
k2van3 = 0.3 / double
 
#glvprod = 0.0 / double
 
#glvbreakdown = 0. / double
 
label = / label
 
label = <b>Integration parameters</b> / label
 
dt = 0.1 / double 
 
rd_dt = 1.0 / double
 
datadir = . / directory 
 
movie = false / bool
 
nit = 100000 / int
 
maxt = 1000. / double
 
storage_stride = 10 / int
 
xml_storage_stride = 500 / int
 
rseed = -1 / int
 
#label = / label
 
#label = <b>Parameters for new chemical</b> / label
 
#glvproduction = 0. / double
 
#glvdecay = 0. / double
 
#glvdiffthreshold = 0. / double
 
label = / label
 
label = <b>Meinhardt leaf venation model</b> / label
 
constituous_expansion_limit = 16 / int
 
vessel_inh_level = 1 / double
 
vessel_expansion_rate = 0.25 / double
 
d = 0. / double
 
e = 0. / double
 
f = 0. / double
 
c = 0. / double
 
mu = 0. / double
 
nu = 0. / double
 
rho0 = 0. / double
 
rho1 = 0. / double
 
c0 = 0. / double
 
gamma = 0. / double
 
eps = 0. / double
 
label = / label
 
label = <b>User-defined parameters</b> / label
 
k = 0., 0.0, 0.0, 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. / doublelist
 
i1 = 0 / int
 
i2 = 0 / int
 
i3 = 0 / int
 
i4 = 0 / int
 
i5 = 0 / int
 
s1 =  / string
 
s2 =  / string
 
s3 =  / string
 
b1 = false / bool
 
b2 = false / bool
 
b3 = false / bool
 
b4 = false / bool
 
dir1 = . / directory
 
dir2 = . / directory
 
export_interval = 0 / int
 
export_fn_prefix = cell. / string
src/canvas.cpp
Show inline comments
 
@@ -552,260 +552,264 @@ Main::Main(QGraphicsScene& c, Mesh &m, Q
 

	
 
  // 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->insertSeparator();
 
  helpmenu->insertItem("&LICENSE", this, SLOT(gpl()) );
 
  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();
 
}
 

	
 
void Main::newView()
 
{
 
  // Open a new view... have it delete when closed.
 
  Main *m = new Main(canvas, mesh, 0, 0, Qt::WDestructiveClose);
 
  qApp->setMainWidget(m);
 
  m->show();
 
  qApp->setMainWidget(0);
 
}
 

	
 

	
 
void Main::EditParameters()
 
{
 

	
 
  ParameterDialog *pardial = new ParameterDialog(this, "stridediag");
 

	
 
  // Make sure the values in the parameter dialog are updated after a file is read 
 
  // each method changing the parameters (reading XML or PAR files) should
 
  // emit this signal
 
  QObject::connect(   this, SIGNAL( ParsChanged() ), pardial, SLOT( Reset() ) );
 
}
 

	
 
void Main::savePars()
 
{
 

	
 
  stopSimulation();
 

	
 
  Q3FileDialog *fd = new Q3FileDialog( this, "file dialog", TRUE );
 
  fd->setMode( Q3FileDialog::AnyFile );
 
  fd->setFilter( "Parameter files (*.par)");
 
  fd->setDir(par.datadir);
 

	
 
  QString fileName;
 
  if ( fd->exec() == QDialog::Accepted ) {
 
    fileName = fd->selectedFile();
 
    ofstream parfile((const char *)fileName);
 
    par.Write(parfile);
 
  }
 

	
 
  startSimulation();
 
}
 

	
 
void Main::readPars()
 
{
 

	
 
  stopSimulation();
 

	
 
  Q3FileDialog *fd = new Q3FileDialog( this, "file dialog", TRUE );
 
  fd->setMode( Q3FileDialog::ExistingFile );
 
  fd->setFilter( "Parameter files (*.par)");
 
  fd->setDir(par.datadir);
 

	
 
  QString fileName;
 
  if ( fd->exec() == QDialog::Accepted ) {
 
    fileName = fd->selectedFile();
 
    par.Read((const char *)fileName);
 
  }
 

	
 
  emit ParsChanged();
 
}
 

	
 

	
 
void Main::saveStateXML()
 
{
 

	
 
  stopSimulation();
 
  Q3FileDialog *fd = new Q3FileDialog( this, "file dialog", TRUE );
 
  fd->setMode( Q3FileDialog::AnyFile );
 
  fd->setFilter( "LeafML files (*.xml)");
 
  fd->setDir(par.datadir);
 
  QString fileName;
 

	
 
  if ( fd->exec() == QDialog::Accepted ) {
 
    fileName = fd->selectedFile();
 
    if ( QFile::exists( fileName ) &&
 
	 QMessageBox::question(
 
			       this,
 
			       tr("Overwrite File? -- Leaf Growth"),
 
			       tr("A file called %1 already exists."
 
				  " Do you want to overwrite it?")
 
			       .arg( fileName ),
 
			       tr("&Yes"), tr("&No"),
 
			       QString::null, 1, 1 ) ) {
 
      return saveStateXML();
 

	
 
    } else {
 

	
 
      mesh.XMLSave((const char *)fileName, XMLSettingsTree());
 

	
 
    }
 
  }
 
}
 

	
 

	
 

	
 
void Main::snapshot()
 
{
 

	
 

	
 
  stopSimulation();
 
  Q3FileDialog *fd = new Q3FileDialog( this, "Save snapshot", TRUE );
 
  fd->setDir(par.datadir);
 
  fd->setMode( Q3FileDialog::AnyFile );
 
  fd->setFilter( "Image files (*.pdf *.png *.jpg *.tif *.bpm)");
 
  QString fileName;
 

	
 
  if ( fd->exec() == QDialog::Accepted ) {
 
    fileName = fd->selectedFile();
 
    
 
    // extract extension from filename
 
    QFileInfo fi(fileName);
 
    QString extension = fi.suffix();
 
    
 
    if (extension.isEmpty()) {
 
      extension = "jpg";
 
      fileName += ".";
 
      fileName += extension;
 
    }
 
    
 
    
 
    if ( QFile::exists( fileName ) &&
 
	 QMessageBox::question(
 
			       this,
 
			       tr("Overwrite file? -- Cell data export"),
 
			       tr("A file called %1 already exists."
 
				  " Do you want to overwrite it?").arg( fileName ),
 
			       QMessageBox::Yes, QMessageBox::No 
 
			       ) == QMessageBox::No
 
	 ) {
 
      
 
      return snapshot();
 
      
 
    } else {
 

	
 
      // Save bitmaps at 1024x768
 
      Save((const char *)fileName, extension, 1024, 768);
 
      QString status_message = QString("Wrote snapshot to %1").arg(fileName);
 
      cerr << status_message.toStdString() << endl;
 
      statusBar()->showMessage(status_message);
 

	
 
    }
 
  }
 
}
 

	
 

	
 

	
 
void Main::readPrevStateXML()
 
{
 

	
 
  // if we have already read a file, read the next file
 
  if (!currentFile.isEmpty() && working_dir) {
 
    QString next_file;
 

	
 
    QStringList xml_files = working_dir->entryList("*.xml");
 
    QString currentFile_nopath = currentFile.section( '/', -1 );
 
    QString currentFile_path = currentFile.section( '/', 0, -2 );
 

	
 
    QList<QString>::iterator f = xml_files.find( currentFile_nopath );
 

	
 
    if (f == xml_files.end()) {
 
      return;
 
    }
 

	
 
    if (f==xml_files.begin()) {
 
      QMessageBox mb( "Read previous leaf",
 
		      "No more files",
 
		      QMessageBox::Information,
 
		      QMessageBox::Ok | QMessageBox::Default,
 
		      QMessageBox::NoButton,
 
		      QMessageBox::NoButton);
 
      mb.exec();
 
      return;
 
    }
 
    next_file = *(--f);
 
    next_file = currentFile_path+"/"+next_file;
 

	
 
    readStateXML((const char *)next_file);
 

	
 
  }
 
}
 

	
 
int Main::readStateXML(const char *filename, bool geometry, bool pars, bool simtime)
 
{
 

	
 
  try {
 
    xmlNode *settings;
 
    mesh.XMLRead((const char *)filename, &settings, geometry, pars, simtime);
 
#ifdef QDEBUG
 
    qDebug() << "Reading done."<< endl;
 
#endif
 
    XMLReadSettings(settings);
 
    xmlFree(settings);
 
    Cell::SetMagnification(1);
 
    Cell::setOffset(0,0);
 

	
 
    FitLeafToCanvas();
 
    
 
    currentFile =  QString(filename);
 
@@ -817,206 +821,245 @@ int Main::readStateXML(const char *filen
 
    statusBar()->message(status_message);
 
    emit ParsChanged();
 
#ifdef QDEBUG
 
    qDebug() << "Done. Returning 0." << endl;
 
#endif
 
    return 0;
 
  } catch (const char *error_message) {
 
    QMessageBox mb( "Read leaf from XML file",
 
		    QString(error_message),
 
		    QMessageBox::Critical,
 
		    QMessageBox::Ok | QMessageBox::Default,
 
		    Qt::NoButton,
 
		    Qt::NoButton);
 
    mb.exec();
 
    return 1;
 
  }
 
}
 

	
 

	
 
void Main::readNextStateXML()
 
{
 

	
 
  // if we have already read a file, read the next file
 
  if (!currentFile.isEmpty() && working_dir) {
 
    QString next_file;
 

	
 
    QStringList xml_files = working_dir->entryList("*.xml");
 
    QString currentFile_nopath = currentFile.section( '/', -1 );
 
    QString currentFile_path = currentFile.section( '/', 0, -2 );
 

	
 

	
 
    QList<QString>::iterator f = xml_files.find( currentFile_nopath );
 

	
 
    if (f == xml_files.end()) {
 
      return;
 
    }
 

	
 
    ++f;
 
    if (f==xml_files.end()) {
 
      QMessageBox mb( "Read next leaf",
 
		      "No more files",
 
		      QMessageBox::Information,
 
		      QMessageBox::Ok | QMessageBox::Default,
 
		      QMessageBox::NoButton,
 
		      QMessageBox::NoButton);
 
      mb.exec();
 
      return;
 
    }
 
    next_file = *f;
 
    next_file = currentFile_path+"/"+next_file;
 

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

	
 
void Main::readLastStateXML()
 
{
 

	
 
  // if we have already read a file, read the next file
 
  if (!currentFile.isEmpty() && working_dir) {
 
    QString next_file;
 

	
 
    QStringList xml_files = working_dir->entryList("*.xml");
 
    QString currentFile_nopath = currentFile.section( '/', -1 );
 
    QString currentFile_path = currentFile.section( '/', 0, -2 );
 

	
 

	
 
    next_file = xml_files.back();
 

	
 
    next_file = currentFile_path+"/"+next_file;
 

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

	
 

	
 
void Main::readFirstStateXML()
 
{
 

	
 
  // if we have already read a file, read the next file
 
  if (!currentFile.isEmpty() && working_dir) {
 
    QString next_file;
 

	
 
    QStringList xml_files = working_dir->entryList("*.xml");
 
    QString currentFile_nopath = currentFile.section( '/', -1 );
 
    QString currentFile_path = currentFile.section( '/', 0, -2 );
 

	
 

	
 
    next_file = xml_files.front();
 

	
 
    next_file = currentFile_path+"/"+next_file;
 

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

	
 
QDir Main::GetLeafDir(void) {
 
   
 
  QDir LeafDir(QApplication::applicationDirPath()); 
 
  QStringList plugin_filters; // filter for plugins, i.e "*.dll", "*.dylib"
 
  
 
  
 
#if defined(Q_OS_WIN) 
 
  if (LeafDir.dirName().toLower() =="debug" 
 
      ||LeafDir.dirName().toLower() =="release") 
 
    LeafDir.cdUp(); 
 
  //plugin_filters << "*.dll";
 
#elif defined(Q_OS_MAC) 
 
  if (LeafDir.dirName() =="MacOS"){ 
 
    LeafDir.cdUp(); 
 
    LeafDir.cdUp(); 
 
    LeafDir.cdUp(); 
 
  }
 
  
 
#endif
 
  // for all OS-es. Move from "bin" directory to root application folder.
 
  if (LeafDir.dirName() == "bin") {
 
    LeafDir.cdUp();
 
  }
 

	
 
  LeafDir.cd("data/leaves");
 
  /* if (!LeafDir.cd("data/leaves")) {
 
    QString status_message = QString("No directory data/leaves");
 
    statusBar()->showMessage(status_message);
 
    
 
    return LeafDir;
 
  } 
 
  */
 
  return LeafDir;
 
      
 
}
 
 
 

	
 
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( "LeafML files (*.xml)");
 
  if (working_dir) {
 
    fd->setDir(*working_dir);
 
  } else {
 
    fd->setDir(par.datadir);
 
  }
 
  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
 
    ( "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>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"); // Where Linux expects gpl3.txt
 
  QString path = docDir.filePath("gpl3.txt");
 
  if (!docDir.exists("gpl3.txt")){
 
    docDir = QApplication::applicationDirPath();
 
    docDir.cd("doc"); // Where Windows expects gpl3.txt
 
    path = docDir.filePath("gpl3.txt");
 
  }
 

	
 
  // At this point path points either to the linux variant, which
 
  // exists, or the windows variant, which may exist. Testing the
 
  // ifstream object will determine whether we've found 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" );
 
}
 

	
 
void Main::toggleShowCellCenters()
 
{
 
  Plot();
 
}
 

	
 
@@ -1302,170 +1345,169 @@ void Main::CleanMeshChemicals(void)
 

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

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

	
 
  mesh.CleanChemicals(clean_chem);
 
  mesh.setTime(0);
 
  Plot();
 

	
 
  editor->FullRedraw();
 
}
 

	
 
void Main::CleanMeshTransporters(void) 
 
{
 
  vector<double> clean_transporters(Cell::NChem());
 
  for (int i=0;i<Cell::NChem();i++) {
 
    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);
 
  
 
  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);
 
  hidecellsp = view->isItemChecked( hide_cells_id);
 

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

	
 

	
 
#define QDEBUG
 

	
 
void Main::exportCellData(QString fileName) {
 
  
 
#ifdef QDEBUG  
 
  qDebug() << "exportCellData fileName: " << fileName << endl;
 
#endif
 

	
 
  QFile file(fileName);
 
  if ( file.open( IO_WriteOnly ) ) {
 
    QTextStream stream( &file );
 
    mesh.CSVExportCellData(stream);
 
    mesh.CSVExportWallData(stream);
 
    mesh.CSVExportMeshData(stream);
 
    file.close();
 
  }
 
}
 

	
 

	
 
void Main::exportCellData() {
 
  QString fileName;
 
  Q3FileDialog *fd = new Q3FileDialog( this, "file dialog", TRUE );
 

	
 
  fd->setDir(par.datadir); 
 
  stopSimulation();
 
  fd->setMode( Q3FileDialog::AnyFile );
 
  if ( fd->exec() == QDialog::Accepted ) {
 
    fileName = fd->selectedFile();
 

	
 
    // extract extension from filename
 
    QFileInfo fi(fileName);
 
    QString extension = fi.suffix();
 
    
 
    if (extension.isEmpty()) {
 
      extension = "csv";
 
      fileName += ".";
 
      fileName += extension;
 
    }
 

	
 
    if (extension!="csv" && extension!="CSV") {
 
      
 
      if (
 
	  QMessageBox::question(
 
				 this,
 
				 tr("Change extension? -- Cell data export"),
 
				 tr("VirtualLeaf can only export data to CSV format (Excel-compatible)."
 
				    "Do you want to change the file extension to \".csv\"?"),
 
				 QMessageBox::Yes, QMessageBox::No ) == QMessageBox::No 
 
	  ) {
 

	
 
	return exportCellData();
 
      } else {
 
	fileName.replace(extension,"csv");
 
	extension="csv";
 
      }
 
    }
 
    if ( QFile::exists( fileName ) &&
 
	 QMessageBox::question(
 
			       this,
 
			       tr("Overwrite file? -- Cell data export"),
 
			       tr("A file called %1 already exists."
 
				  " Do you want to overwrite it?").arg( fileName ),
 
			       QMessageBox::Yes, QMessageBox::No 
 
			       ) == QMessageBox::No
 
	 ) {
 
      return exportCellData();
 
    } else {
 
      exportCellData(fileName);
 
      QString status_message = QString("Wrote data file to %1").arg(fileName);
 
      statusBar()->showMessage(status_message);
 
    }
 
  }
 
}
 

	
 

	
 
  /* finis */
src/canvas.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  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.
 
 *
 
 *  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 <QDir>
 

	
 
#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
 

	
 

	
 
class QFile;
 
class QDir;
 
class ModelCatalogue;
 
class InfoBar;
 

	
 
class FigureEditor : public QGraphicsView {
 
  Q_OBJECT
 

	
 
    friend class Main;
 
 public:
 
  FigureEditor(QGraphicsScene&, Mesh&, QWidget* parent=0, const char* name=0, Qt::WFlags f=0);
 
  void clear();
 
  void Save(const char *fname, const char *format, int sizex=640, int sizey=480);
 
  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 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);
 

	
 
  int readStateXML(const char *filename, bool geometry = true, bool pars=true, bool simtime = true);
 
  
 
  void EnterRotationMode(void)
 
  {
 

	
 
    UserMessage("Rotation mode. Click mouse to exit.");
 
    if (editor) {
 
      editor->rot_angle = 0. ; 
 

	
 
      // Exit rotation mode if mouse is clicked
 
      connect(editor, SIGNAL(MousePressed()), this, SLOT(ExitRotationMode()));
 
      
 
      editor->setMouseTracking(true);
 

	
 
    }
 

	
 
  }
 
  void ExitRotationMode(void)
 
  { 
 
    UserMessage("Exited rotation mode.",2000);
 

	
 
    options->setItemChecked(rotation_mode_id, false); 
 
    if (editor)
 
      disconnect(editor, SIGNAL(MousePressed()), this, SLOT(ExitRotationMode()));
 
    editor->setMouseTracking(false);
 
 
 
  }
 

	
 
  virtual void UserMessage(QString message, int timeout=0);
 
  void Refresh(void) { Plot(); }
 
  void PauseIfRunning(void);
 
  void ContIfRunning(void);
 
  virtual void XMLReadSettings(xmlNode *settings);
 

	
 
  private slots:
 
  void aboutQt();
 
  void newView();
 
  void EditParameters();
 
  QDir GetLeafDir(void);
 
  void readStateXML();
 
  int readStateXML(const char *filename, bool geometry = true, bool pars=true, bool simtime = true);
 
  void readNextStateXML();
 
  void readPrevStateXML();
 
  void readFirstStateXML();
 
  void readLastStateXML();
 
  void exportCellData();
 
  void exportCellData(QString);
 
  void saveStateXML();
 
  void snapshot();
 
  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 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/mesh.cpp
Show inline comments
 
@@ -1972,110 +1972,146 @@ void Mesh::StandardInit(void) {
 

	
 

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

	
 
  // Step 1. Prepare data for 2D hull code - get boundary polygon
 
  int pc=0;
 
  Point *p=new Point[boundary_polygon->nodes.size()+1];
 
  for (list<Node *>::const_iterator i = boundary_polygon->nodes.begin(); 
 
       i!=boundary_polygon->nodes.end(); i++) {
 
    p[pc++]=Point((*i)->x,(*i)->y);
 
  }
 
  
 
  // chainHull algorithm requires sorted points
 
  qSort( p, p+pc );
 

	
 
 
 
  // Step 2: call 2D Hull code
 
  int np=boundary_polygon->nodes.size();
 
  Point *hull=new Point[np+1];
 
  int nph=chainHull_2D(p,np,hull);
 
  
 
  
 
  // Step 3: calculate area and circumference of convex hull
 
  double hull_area=0.;
 
  double hull_circumference=0.;
 

	
 
  for (int i=0;i<nph-1;i++) {
 
    hull_area+=hull[i].x * hull[i+1].y - hull[i+1].x * hull[i].y;
 
    double s_dx=(hull[i+1].x-hull[i].x);
 
    double s_dy=(hull[i+1].y-hull[i].y);
 
    double l=sqrt(s_dx*s_dx+s_dy*s_dy);
 
    //    f << hull[i].x << " " << hull[i].y << " " << hull[i+1].x << " " << hull[i+1].y << " " << l << endl;
 
    hull_circumference+=l;
 
      
 
  }
 
  hull_area/=2.;
 

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

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

	
 

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

	
 
}
 

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

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

	
 
  
 
}
 

	
 

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

	
 
  csv_stream << "\"Wall Index\",\"Cell A\",\"Cell B\",\"Length\"";
 
  
 
  for (int c=0;c<Cell::NChem(); c++) {
 
    csv_stream << ",\"Transporter A:" << c << "\"";
 
  }
 
  for (int c=0;c<Cell::NChem(); c++) {
 
    csv_stream << ",\"Transporter B:" << c << "\"";
 
  }
 
  csv_stream << endl;
 
  for (list<Wall *>::const_iterator i=walls.begin();
 
       i!=walls.end();
 
       i++) {
 
    csv_stream << (*i)->Index() << ","
 
	       << (*i)->C1()->Index() << ","
 
	       << (*i)->C2()->Index() << ","
 
	       << (*i)->Length();
 
	      
 
    for (int c=0;c<Cell::NChem(); c++) {
 
      csv_stream << "," << (*i)->Transporters1(c);
 
    }
 
    for (int c=0;c<Cell::NChem(); c++) {
 
      csv_stream << "," << (*i)->Transporters2(c);
 
    }
 

	
 
    csv_stream << endl;
 
  }
 

	
 
  
 
}
 

	
 

	
 
void Mesh::CSVExportMeshData(QTextStream &csv_stream) { 
 
  
 
  csv_stream << "\"Morph area\",\"Number of cells\",\"Number of nodes\",\"Compactness\",\"Hull area\",\"Morph circumference\",\"Hull circumference\"" << endl;
 
  
 
  double res_compactness, res_area, res_cell_area, hull_circumference;
 
  Compactness(&res_compactness, &res_area, &res_cell_area, &hull_circumference);
 
  double morph_circumference = boundary_polygon->ExactCircumference();
 
  csv_stream << Area() << ", " << NCells() << ", " << NNodes() << ", " << res_compactness << ", " << res_area << ", " << morph_circumference << ", " << hull_circumference << endl;
 
  
 
}
 
/* finis */
src/mesh.h
Show inline comments
 
@@ -295,143 +295,144 @@ class Mesh {
 
    }
 
  }
 

	
 
  void InsertNodes(void) {
 
    // insert the nodes in the insertion queue
 
    while (!node_insertion_queue.empty()) {
 

	
 
      //cerr << node_insertion_queue.front() << endl;
 
      InsertNode(node_insertion_queue.front());
 
      node_insertion_queue.pop();
 
    }
 

	
 
  }
 

	
 
  void Clear(); 
 

	
 
  void ReactDiffuse( double delta_t = 1 );
 
  double SumChemical(int ch);
 
  void SetChemical(int ch, double value) {
 
    for (vector<Cell *>::iterator c=cells.begin();
 
	 c!=cells.end();
 
	 c++) {
 
      (*c)->chem[ch]=value;
 
    }
 
  }
 

	
 
  // used for interacing with ODE-solvers (e.g. NRCRungeKutta)
 
  void setValues(double x, double *y);
 
  double *getValues(int *neqs);
 
  void Derivatives(double *derivs);
 
#ifdef QTGRAPHICS
 
  inline void DrawBoundary(QGraphicsScene *c) {
 
    boundary_polygon->Draw(c);
 
  }
 
  void DrawNodes(QGraphicsScene *c) const;
 

	
 
#endif
 
  double max_chem;
 

	
 
  void XMLSave(const char *docname, xmlNode *settings=0) const;
 
  void XMLRead(const char *docname, xmlNode **settings=0, bool geometry = true, bool pars = true, bool simtime = true);
 
  void XMLReadPars(const xmlNode * root_node);
 
  void XMLReadGeometry(const xmlNode *root_node);
 
  void XMLReadSimtime(const xmlNode *root_node);
 
  void XMLReadNodes(xmlNode *cur);
 
  void XMLReadCells(xmlNode *cur);
 
  void XMLParseTree(const xmlNode * root_node);
 
  void XMLReadWalls(xmlNode *cur, vector<Wall *> *tmp_cells);
 
  void XMLReadWallsToCells(xmlNode *root, vector<Wall *> *tmp_walls);
 
  void XMLReadNodeSets(xmlNode *root);
 
  void XMLReadNodeSetsToNodes(xmlNode *root);
 
  void PerturbChem(int chemnum, double range);
 
  void CleanUpCellNodeLists(void);
 
  void CleanUpWalls(void);
 
  void CutAwayBelowLine( Vector startpoint, Vector endpoint );
 
  void CutAwaySAM(void);
 
  void RepairBoundaryPolygon(void);
 
  void Rotate(double angle, Vector center);
 
  void PrintWallList( void );
 
  void TestIllegalWalls(void);
 
  Vector FirstConcMoment(int chem);
 
  inline Vector Centroid(void) {
 
    return boundary_polygon->Centroid();
 
  }
 

	
 
  inline Vector Offset(void) {
 
    return boundary_polygon->Offset();
 
  }
 

	
 
  inline double Factor(void) {
 
    return boundary_polygon->Factor();
 
  }
 

	
 
  void DeleteLooseWalls(void);
 
  void FitLeafToCanvas(double width, double height);
 
  void AddNodeSet(NodeSet *node_set) {
 
    node_sets.push_back(node_set);
 
  }
 

	
 
  void CleanChemicals(const vector<double> &clean_chem);
 
  void CleanTransporters(const vector<double> &clean_transporters);
 
  void RandomizeChemicals(const vector<double> &max_chem, const vector<double> &max_transporters);
 
  inline double getTime(void) const { return time; }
 
  string getTimeHours(void) const; 
 
  inline void setTime(double t) { time = t; }
 
  double CalcProtCellsWalls(int ch) const;  
 
  void SettoInitVals(void);
 
  QVector<qreal> VertexAngles(void);
 
  QVector< QPair<qreal,int> > VertexAnglesValues(void);
 
  void SetSimPlugin(SimPluginInterface *new_plugin) {
 
    plugin=new_plugin;
 
  }
 
  QString ModelID(void) { return plugin?plugin->ModelID():QString("undefined"); }
 
  void StandardInit(void);	
 
  double Compactness(double *res_compactness=0, double *res_area=0, double *res_cell_area=0, double *hull_circumference=0);
 
  void CSVExportCellData(QTextStream &csv_stream) const;
 
  void CSVExportWallData(QTextStream &csv_stream) const;
 
  void CSVExportMeshData(QTextStream &csv_stream);
 
  
 
  Node* findNextBoundaryNode(Node*);
 

	
 
 private:
 

	
 
  // Data members
 
  vector<Cell *> cells;
 
  vector<Node *> nodes;
 
  list<Wall *> walls; // we need to erase elements from this container frequently, hence a list.
 
 public:
 
  vector<NodeSet *> node_sets;
 
 private:
 
  vector<Node *> shuffled_nodes;
 
  vector<Cell *> shuffled_cells;
 
  unique_queue<Edge> node_insertion_queue;
 
  BoundaryPolygon *boundary_polygon;
 
  double time;
 
  SimPluginInterface *plugin;
 

	
 
  // Private member functions
 
  void AddNodeToCell(Cell *c, Node *n, Node *nb1 , Node *nb2);
 
  void AddNodeToCellAtIndex(Cell *c, Node *n, Node *nb1 , Node *nb2, list<Node *>::iterator ins_pos);
 
  void InsertNode(Edge &e);
 
  inline Node *AddNode(Node *n) {
 
    nodes.push_back(n);
 
    shuffled_nodes.push_back(n);
 
    n->m=this;
 
    return n;
 
  }
 

	
 
  inline Cell *AddCell(Cell *c) {
 
    cells.push_back(c);
 
    shuffled_cells.push_back(c);
 
    //cerr << "Shuffled cell indices:  ";
 
    /*copy(shuffled_cells.begin(),shuffled_cells.end(),ostream_iterator<int>(cerr," "));
 
      cerr << endl;*/
 
    c->m=this;
 
    return c;
 
  }
 

	
 
  void CircumCircle(double x1,double y1,double x2,double y2,double x3,double y3,
 
		    double *xc,double *yc,double *r);
 
};
 
#endif
 

	
 
/* finis */
src/modelcatalogue.cpp
Show inline comments
 
/*
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  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.
 
 *
 
 *  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) {
 
ModelCatalogue::ModelCatalogue(Mesh *_mesh, MainBase *_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);
 

	
 
  if (!pluginDir.cd("models")) {
 
    MyWarning::error("Directory 'models' not found!");
 
  }
 

	
 

	
 
  //QVector<SimPluginInterface *> plugins;
 
  foreach (QString fileName, pluginDir.entryList(QDir::Files)){ 
 
    QPluginLoader loader(pluginDir.absoluteFilePath(fileName)); 
 
    if (SimPluginInterface *plugin = 
 
	qobject_cast<SimPluginInterface *>(loader.instance())) {
 
      models.append(plugin); 
 
    } else {
 
      cerr << loader.errorString().toStdString().c_str() << endl;
 
      MyWarning::warning("Could not load model %s: %s",fileName.toStdString().c_str(), loader.errorString().toStdString().c_str());
 
    }
 
  }
 
  if (models.size()==0) {
 
    MyWarning::error("No models could be loaded.");
 
  }
 
}
 

	
 
void ModelCatalogue::LoadPlugin(const char *model) {
 

	
 

	
 
  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
 
  plugin_filters << model;
 
  pluginDir.setNameFilters(plugin_filters);
 

	
 
  if (!pluginDir.cd("models")) {
 
    MyWarning::error("Directory 'models' not found!");
 
  }
 

	
 
  QStringList modelnames=pluginDir.entryList(QDir::Files);
 
  if (modelnames.empty()) {
 
    MyWarning::error("Model %s not found - hint: do not include path in filename.",model);
 
  }
 
  foreach (QString fileName, modelnames){ 
 
    QPluginLoader loader(pluginDir.absoluteFilePath(fileName)); 
 

	
 
    if (SimPluginInterface *plugin = 
 
	qobject_cast<SimPluginInterface *>(loader.instance())) {
 
      models.append(plugin); 
 
      //MyWarning::warning("Successfully loaded model %s",fileName.toStdString().c_str());
 
    } else {
 
      MyWarning::warning("Could not load plugin %s",fileName.toStdString().c_str());
 
    }
 
  }
 
}
 

	
 
void ModelCatalogue::InstallFirstModel() {
 
  InstallModel(models[0]);
 
}
 
void ModelCatalogue::PopulateModelMenu() {
 
  foreach (SimPluginInterface *model, models) {
 
    QAction *modelaction = new QAction(model->ModelID(), mainwin); 
 
    QAction *modelaction = new QAction(model->ModelID(), (Main *)mainwin); 
 
    QVariant data;
 
    data.setValue(model);
 
    modelaction->setData(data);
 
    mainwin->modelmenu->addAction(modelaction);
 
    ((Main *)mainwin)->modelmenu->addAction(modelaction);
 

	
 
  }
 
  connect(mainwin->modelmenu, SIGNAL(triggered(QAction *)), this, SLOT(InstallModel(QAction *)) );
 
  connect(((Main *)mainwin)->modelmenu, SIGNAL(triggered(QAction *)), this, SLOT(InstallModel(QAction *)) );
 
}	
 

	
 
void ModelCatalogue::InstallModel(QAction *modelaction) {
 
  QVariant data = modelaction->data();
 
  SimPluginInterface *model = data.value<SimPluginInterface *>();
 
  cerr << "You chose model " << model->ModelID().toStdString() << "!\n";
 
  mesh->Clean();
 
  InstallModel(model);
 
}
 

	
 
void ModelCatalogue::InstallModel(SimPluginInterface *plugin) {
 

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

	
 
  mesh->SetSimPlugin(plugin);
 
 
 

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

	
 
}
src/modelcatalogue.h
Show inline comments
 
/*
 
 *
 
 *  $Id$
 
 *
 
 *  This file is part of the Virtual Leaf.
 
 *
 
 *  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.
 
 *
 
 *  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); 	
 
  ModelCatalogue(Mesh *mesh, MainBase *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;
 
  MainBase *mainwin;
 
};
 

	
 
#endif
 

	
 
/* finis */

Changeset was too big and was cut off... Show full diff anyway

0 comments (0 inline, 0 general)