Commit 1c7a1fc2 authored by promayon's avatar promayon
Browse files

NEW action to generate SOFA scene + MML document from a tetrahedral model...

NEW action to generate SOFA scene + MML document from a tetrahedral model (with default behavior, as well as selected node null translation constraint)
FIXED now using vtk smart pointer for selection (vtk pointer should be banned)
FIXED mispelling in enum



git-svn-id: svn+ssh://scm.forge.imag.fr/var/lib/gforge/chroot/scmrepos/svn/camitk/trunk/camitk@1594 ec899d31-69d1-42ba-9299-647d76f65fb3
parent b8763c4f
......@@ -2,7 +2,7 @@ camitk_extension(ACTION_EXTENSION
NEEDS_LIBXML2
NEEDS_XSD
NEEDS_CEP_LIBRARIES pml mml monitoring lml
NEEDS_COMPONENT_EXTENSION physicalmodel mml vtkmesh physicalmodel
NEEDS_COMPONENT_EXTENSION physicalmodel mml vtkmesh physicalmodel msh
CEP_NAME CEP_MODELING
DESCRIPTION "Action MML features algorithms applicable on MML components."
TEST_APPLICATION ${APPLICATION_TEST_ACTION}
......
......@@ -22,6 +22,12 @@
*
* $CAMITK_LICENCE_END$
****************************************************************************/
// because of namespace problems with Component, put these include first
#include <monitoring/manager/MonitoringManagerFactory.h>
#include <monitoring/simulator/SimulatorFactory.h>
#include <mml/MonitorIn.hxx>
#include <lml/Translation.h>
#include <MultiComponent.h>
#include "GenerateModel.h"
#include <Component.h>
......@@ -29,34 +35,229 @@
#include <Core.h>
#include <Application.h>
#include <MeshComponent.h>
using namespace camitk;
#include <ExtensionManager.h>
#include <Property.h>
#include <set>
#include <vtkSelectionNode.h>
#include <vtkIdTypeArray.h>
#include <QFileInfo>
#include <QDateTime>
#include <QFileDialog>
using namespace camitk;
// -------------------- GenerateModel --------------------
GenerateModel::GenerateModel(ActionExtension* extension) : Action(extension) {
this->setName("Generate Model");
this->setDescription("Generates a model from a mesh: mml, pml and corresponding lml are generated");
this->setComponent("MeshComponent");
this->setFamily("Mesh Processing");
this->addTag("Build Biomechanical Model");
GenerateModel::GenerateModel( ActionExtension* extension ) : Action( extension ) {
this->setName( "Generate Model" );
this->setDescription( "Generates a model from a mesh: mml, pml and corresponding lml are generated" );
this->setComponent( "MeshComponent" );
this->setFamily( "Mesh Processing" );
this->addTag( "Build Biomechanical Model" );
addParameter( new Property( "Selection Is Constrained", true, "Use the current point selection to add a null displacement constraint to the model. If this is true, all the currently selected nodes will be fixed during the simulation", "" ) );
addParameter( new Property( "Gravity", QVector3D( -9.81, 0.0, 0.0 ), "Direction of the simulated gravity, X- is the default", "acceleration in m/s^2" ) );
addParameter( new Property( "SOFA Only", false, "Generate the model using only the SOFA simulator (without the help of MML", "" ) );
}
// --------------- apply -------------------
Action::ApplyStatus GenerateModel::apply() {
CAMITK_INFO("GenerateModel", "apply", "GenerateModel " << getTargets().last()->getName().toStdString());
// set waiting cursor
QApplication::setOverrideCursor ( QCursor ( Qt::WaitCursor ) );
QApplication::setOverrideCursor( QCursor( Qt::WaitCursor ) );
//-- get the mesh, prepare the filename
targetMesh = dynamic_cast<MeshComponent*>( getTargets().last() );
QString originalFilename = targetMesh->getFileName();
if( originalFilename.isEmpty() ) {
// ask the user
originalFilename = QFileDialog::getSaveFileName( NULL, "Generate Model", "", "ModelingML (*.mml)" );
if( originalFilename.isNull() )
return ABORTED;
}
QString baseFilename = QFileInfo( originalFilename ).absolutePath() + "/" + QFileInfo( originalFilename ).completeBaseName();
//-- 0) get the selected node index into an handy list
fixedDOFIndex.clear();
vtkSmartPointer<vtkSelectionNode> currentlySelected = targetMesh->getSelection( "Selected Points" );
if( currentlySelected != NULL ) {
vtkSmartPointer<vtkIdTypeArray> idList = vtkIdTypeArray::SafeDownCast( currentlySelected->GetSelectionList() );
// if the selection is not empty
if( idList != NULL ) {
for( vtkIdType i = 0; i < idList->GetNumberOfTuples(); i++ ) {
fixedDOFIndex.insert( idList->GetValue( i ) );
}
}
}
//-- 1) save the selected component as a .msh (to simplify .scn)
targetMesh->setFileName( baseFilename + "-model.msh" );
Application::save( targetMesh );
targetMesh->setFileName( originalFilename ); // just to avoid a discrepancy in case of another saveAs
//-- 2) save the corresponding .scn file
saveSOFAFile( baseFilename );
//-- 3) save LML, PML, and MML
if( !property( "SOFA Only" ).toBool() )
saveMMLFiles( baseFilename );
// TODO: write the code here!
// restore the normal cursor
QApplication::restoreOverrideCursor();
return SUCCESS;
}
// --------------- saveSOFAFile -------------------
void GenerateModel::saveSOFAFile( QString baseFilename ) {
// largely inspired (i.e. completely copied) from liver.scn demo file
QString SOFAFileName = baseFilename + "-model.scn";
QString mshFilename = baseFilename + "-model.msh";
QVector3D gravity = property( "Gravity" ).value<QVector3D>();
ofstream scnFile( SOFAFileName.toUtf8() );
scnFile << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
scnFile << "<!-- Created by " << Core::shortVersion << " -->" << endl;
QDateTime now = QDateTime::currentDateTime();
scnFile << "<!-- " << now.toString().toStdString() << " " << now.toTime_t() << "-->" << endl;
scnFile << "<Node name=\"root\" gravity=\"" << gravity.x() << " " << gravity.y() << " " << gravity.z() << "\" dt=\"0.02\" showBehaviorModels=\"0\" showCollisionModels=\"0\" showMappings=\"0\" showForceFields=\"0\">" << endl;
scnFile << " <DefaultPipeline name=\"CollisionPipeline\" verbose=\"0\" />" << endl;
scnFile << " <BruteForceDetection name=\"N2\" />" << endl;
scnFile << " <DefaultContactManager name=\"collision response\" response=\"default\"/>" << endl;
scnFile << " <Node name=\"" << targetMesh->getName().toStdString() << "\" gravity=\"0 -9.81 0\" depend=\"topo dofs\">" << endl;
scnFile << " <EulerImplicitSolver name=\"cg_odesolver\" printLog=\"0\" />" << endl;
scnFile << " <CGLinearSolver template=\"GraphScattered\" name=\"linear solver\" iterations=\"25\" tolerance=\"1e-09\" threshold=\"1e-09\" />" << endl;
scnFile << " <MeshGmshLoader name=\"loader\" filename=\"" << mshFilename.toStdString() << "\" />" << endl;
scnFile << " <TetrahedronSetTopologyContainer name=\"topo\" position=\"@loader.position\" edges=\"@loader.edges\" triangles=\"@loader.triangles\" tetrahedra=\"@loader.tetras\"/>" << endl;
scnFile << " <MechanicalObject template=\"Vec3d\" name=\"dofs\" position=\"0 0 0\" velocity=\"0 0 0\" force=\"0 0 0\" derivX=\"0 0 0\" free_position=\"0 0 0\" free_velocity=\"0 0 0\" restScale=\"1\" />" << endl;
scnFile << " <TetrahedronSetGeometryAlgorithms name=\"tetraGeo\" />" << endl;
scnFile << " <DiagonalMass template=\"Vec3d\" name=\"computed using mass density\" massDensity=\"1\" />" << endl;
scnFile << " <TetrahedralCorotationalFEMForceField template=\"Vec3d\" name=\"FEM\" method=\"large\" poissonRatio=\"0.4\" youngModulus=\"5000\" computeGlobalMatrix=\"0\" />" << endl;
if( property( "SOFA Only" ).toBool() && property( "Selection Is Constrained" ).toBool() && fixedDOFIndex.size() > 0 ) {
// Without LML, you would have to do this:
scnFile << " <FixedConstraint template=\"Vec3d\" name=\"FixedConstraint\" indices=\"";
std::set<int>::const_iterator pos;
// preincrement and predecrement are usually faster than postincrement and postdecrement...
for( pos = fixedDOFIndex.begin(); pos != fixedDOFIndex.end(); ++pos )
scnFile << *pos << " ";
scnFile << "\" />" << endl;
}
scnFile << " </Node>" << endl;
scnFile << "</Node>" << endl;
scnFile.close();
}
// --------------- saveMMLFiles -------------------
void GenerateModel::saveMMLFiles( QString baseFilename ) {
//-- Generate LML
QString lmlFilename;
if( fixedDOFIndex.size() > 0 ) {
Loads l;
Translation *t = new Translation();
std::set<int>::const_iterator pos;
for( pos = fixedDOFIndex.begin(); pos != fixedDOFIndex.end(); ++pos )
t->addTarget( *pos );
t->setUnit( TranslationUnit::MM() );
Direction d;
d.setNullX();
d.setNullY();
d.setNullZ();
t->setDirection( d );
t->addValueEvent( 1, 0.0 );
l.addLoad( t );
lmlFilename = baseFilename + "-boundary-condition.lml";
ofstream lmlofs( lmlFilename.toStdString().c_str() );
l.xmlPrint( lmlofs );
lmlofs.close();
}
//-- Generate MML
// generate a default runable mml using this .scn
// dt and refresh
QString pmlFilename = QFileInfo(baseFilename).completeBaseName() + "-model.pml"; // in the mml, the pml file name is relative
mml::TimeParameter dt = mml::TimeParameter( 0.1, "s" );
mml::TimeParameter refresh = mml::TimeParameter( 0.1, "s" );
mml::MonitoringIn mmlIn( dt, refresh, "sofa" );
// add the simulator file
QString SOFAFileName = baseFilename + "-model.scn";
mmlIn.simulatorFile( QFileInfo( SOFAFileName ).fileName().toStdString().c_str() );
// add stopping criteria
mml::Position notALotOfMovement( mml::Threshold( 0.1 ), "mm" );
notALotOfMovement.method().scope( mml::Scope::Any );
mml::Time enoughTimeToStart( mml::MinThreshold( 0.5 ), "s" );
enoughTimeToStart.method().scope( mml::Scope::Any );
mml::MultipleCriteria multipleCriteria( mml::LogicalOp::And );
multipleCriteria.criteria().push_back( notALotOfMovement );
multipleCriteria.criteria().push_back( enoughTimeToStart );
mml::StoppingCriteria stoppingCriteria;
stoppingCriteria.multipleCriteria( multipleCriteria );
mmlIn.stoppingCriteria( stoppingCriteria );
//TODO
// add monitors
//mml::Monitor displacement(mml::TimeParameter(0.0,"s"),mml::TimeParameter(1000000.0,"s"),mml::MonitorType::PointSetDistance,1,QFileInfo(pmlFilename).fileName().toStdString().c_str());//TODO change!
//mml::Monitors monitors;
//monitors.monitor().push_back(displacement);
//mmlIn.monitors(monitors);
// add lml
if( fixedDOFIndex.size() > 0 ) {
// in the mml the lml fileName is relative
mmlIn.lmlFile( QFileInfo( lmlFilename ).fileName().toStdString().c_str() );
}
xml_schema::namespace_infomap map;
map[""].name = "";
map[""].schema = "";
QString mmlFilename = baseFilename + "-model.mml";
ofstream mmlofs( mmlFilename.toStdString().c_str() );
mml::monitoringIn( mmlofs, mmlIn, map );
mmlofs.close();
//-- Automatically generate proper PML from SCN
// (this is a temporary hack) read the mml file to create the proper pml
// this hack should become a call to a static method to transform a sofa scn to a pml
MonitoringManager *mml = MonitoringManagerFactory::createManager( mmlFilename.toStdString().c_str() );
// Modify mml to use pml file instead of sofa
mmlIn.simulatorFile().reset();
mmlIn.pmlFile( pmlFilename.toStdString().c_str() );
// reopen for rewrite
mmlofs.open( mmlFilename.toStdString().c_str(), std::ios_base::trunc );
mml::monitoringIn( mmlofs, mmlIn, map );
mmlofs.close();
// Modify the pml to have the selected nodes fixed
QString completePmlFilename = baseFilename + "-model.pml";
PhysicalModel *pml = new PhysicalModel( completePmlFilename.toStdString().c_str() );
// add the informative components containing the fixed dof
if (fixedDOFIndex.size()>0 && property( "Selection Is Constrained" ).toBool() ) {
StructuralComponent *fixedDof = new StructuralComponent( pml, "Fixed Dof" );
std::set<int>::const_iterator pos;
for( pos = fixedDOFIndex.begin(); pos != fixedDOFIndex.end(); ++pos )
fixedDof->addStructure( pml->getAtom( *pos ) );
pml->getInformativeComponents()->addSubComponent( fixedDof );
}
// reopen for rewrite
ofstream pmlofs( completePmlFilename.toStdString().c_str(), std::ios_base::trunc );
pml->xmlPrint( pmlofs );
pmlofs.close();
Application::open( mmlFilename );
}
......@@ -27,6 +27,14 @@
#define GENERATEMODEL_H
#include <Action.h>
#include <QVector3D>
#include <set>
namespace camitk {
class MeshComponent;
}
/**
* @ingroup group_cepmodeling_actions_mml
*
......@@ -44,13 +52,25 @@ public:
/// the destructor
virtual ~GenerateModel() {};
/// no widget yet
virtual QWidget * getWidget() { return NULL; }
/// default widget
virtual QWidget * getWidget() { return Action::getWidget(); }
public slots:
/// method applied when the action is called
virtual ApplyStatus apply();
private:
/// save the .scn file, TODO add the choice to save MML with another simulator
void saveSOFAFile(QString baseFilename);
/// save all the MML, PML and LML file
void saveMMLFiles(QString baseFilename);
// list of index that are potentially fixed (null displacement constraint)
std::set<int> fixedDOFIndex;
/// The current managed mesh
camitk::MeshComponent *targetMesh;
};
#endif // GENERATEMODEL_H
......@@ -23,15 +23,15 @@
* $CAMITK_LICENCE_END$
****************************************************************************/
#include "MMLActionExtension.h"
#include "CreateSC.h"
//#include "GenerateModel.h"
#include "CreateSC.h"
#include "GenerateModel.h"
// --------------- declare the extension -------------------
Q_EXPORT_PLUGIN2(mmlactionextension, MMLActionExtension)
// -------------------- init --------------------
void MMLActionExtension::init() {
// registerNewAction(GenerateModel);
registerNewAction(CreateSC);
registerNewAction(GenerateModel);
registerNewAction(CreateSC);
}
......@@ -29,40 +29,40 @@
using namespace camitk;
// --------------- declare the plugin -------------------
Q_EXPORT_PLUGIN2(mml, MMLComponentExtension);
Q_EXPORT_PLUGIN2( mml, MMLComponentExtension );
// --------------- getName -------------------
QString MMLComponentExtension::getName() const {
return "MML Component";
return "MML Component";
}
// --------------- getDescription -------------------
QString MMLComponentExtension::getDescription() const {
return "Manage <em>.mml</em> document in <b>CamiTK</b>.<br/>Lots of things are possible with MML!";
return "Manage <em>.mml</em> document in <b>CamiTK</b>.<br/>Lots of things are possible with MML!";
}
// --------------- getFileExtensions -------------------
QStringList MMLComponentExtension::getFileExtensions() const {
QStringList ext;
ext << "mml";
ext << "scn";
return ext;
QStringList ext;
ext << "mml";
ext << "scn";
return ext;
}
// --------------- open -------------------
camitk::Component * MMLComponentExtension::open(const QString & fileName) throw(AbortException) {
return new MMLComponent(fileName);
camitk::Component * MMLComponentExtension::open( const QString & fileName ) throw( AbortException ) {
return new MMLComponent( fileName );
}
// -------------------- save --------------------
bool MMLComponentExtension::save(Component* component) const {
MMLComponent *mmlComp = dynamic_cast<MMLComponent*>(component);
bool saveStatus = true;
if (mmlComp) {
bool MMLComponentExtension::save( Component* component ) const {
MMLComponent *mmlComp = dynamic_cast<MMLComponent*>( component );
bool saveStatus = true;
if( mmlComp ) {
mmlComp->saveMML();
mmlComp->setModified(false);
mmlComp->setModified( false );
}
else
saveStatus = ComponentExtension::save(component);
return saveStatus;
saveStatus = ComponentExtension::save( component );
return saveStatus;
}
......@@ -26,7 +26,10 @@
#include <pml/PhysicalModel.h>
#include <pml/Atom.h>
#include <AtomDC.h>
#include <StructuralComponentDC.h>
#include <PMManagerDC.h>
#include <LoadsManager.h>
#include <LoadsSimulation.h>
#include <monitoringgui/MonitoringGuiManager.h>
#include <monitoringgui/MonitoringDialog.h>
......@@ -42,32 +45,32 @@
#include <QtGui>
#include "MMLMonitorDisplayFactory.h"
MMLDisplay::MMLDisplay(MMLComponent* mmlManager):QObject()
{
this->mmlManager=mmlManager;
QObject* qobj=(QObject*)(mmlManager->getMonitoringGuiManager());
QObject* qobj2=(QObject*)(mmlManager->getMonitoringGuiManager()->getDialog());
connect(qobj, SIGNAL(changed()), this, SLOT(updateDisplay()));
connect(qobj2, SIGNAL(monitorsChanged()), this, SLOT(updateMonitorsTable()));
connect(qobj, SIGNAL(reconnectPml()), this, SLOT(connectPml()));
monitorDisplay=NULL;
#include <applications/gui/MonitoringDriver.h>
#include <vtkPointData.h>
MMLDisplay::MMLDisplay( MMLComponent* mmlManager ): QObject() {
this->mmlManager = mmlManager;
QObject* qobj = ( QObject* )( mmlManager->getMonitoringGuiManager() );
QObject* qobj2 = ( QObject* )( mmlManager->getMonitoringGuiManager()->getDialog() );
connect( qobj, SIGNAL( changed() ), this, SLOT( updateDisplay() ) );
connect( qobj2, SIGNAL( monitorsChanged() ), this, SLOT( updateMonitorsTable() ) );
connect( qobj, SIGNAL( reconnectPml() ), this, SLOT( connectPml() ) );
monitorDisplay = NULL;
// add two column in monitors table for displaying monitors
QTableWidget* table=mmlManager->getMonitoringGuiManager()->getDialog()->getMonitorsTableWidget();
int i=table->columnCount();
table->setColumnCount(i+2);
QTableWidget* table = mmlManager->getMonitoringGuiManager()->getDialog()->getMonitorsTableWidget();
int i = table->columnCount();
table->setColumnCount( i + 2 );
QTableWidgetItem* item1 = new QTableWidgetItem();
item1->setText(tr("Display"));
table->setHorizontalHeaderItem(i,item1);
item1->setText( tr( "Display" ) );
table->setHorizontalHeaderItem( i, item1 );
QTableWidgetItem* item2 = new QTableWidgetItem();
item2->setText(tr("Display Type"));
table->setHorizontalHeaderItem(i+1,item2);
item2->setText( tr( "Display Type" ) );
table->setHorizontalHeaderItem( i + 1, item2 );
}
MMLDisplay::~MMLDisplay()
{
if (monitorDisplay)
MMLDisplay::~MMLDisplay() {
if( monitorDisplay )
delete monitorDisplay;
}
......@@ -78,111 +81,110 @@ void MMLDisplay::updateDisplay() {
double pos[3];
AtomDC* adc;
Atom* a;
PMManagerDC* pmMgr=mmlManager->getPMManager();
PMManagerDC* pmMgr = mmlManager->getPMManager();
PhysicalModel* pm = mmlManager->getMonitoringGuiManager()->getMonitoringManager()->getPml();
StructuralComponent * theAtoms = pm->getAtoms();
for ( unsigned int i = 0; i < theAtoms->getNumberOfStructures(); i++ ) {
for( unsigned int i = 0; i < theAtoms->getNumberOfStructures(); i++ ) {
// get the target index
a = ( Atom * ) theAtoms->getStructure ( i );
a = ( Atom * ) theAtoms->getStructure( i );
// activate the target's 3D representation
adc = pmMgr->getDC ( a );
if ( adc != NULL ) {
a->getPosition ( pos );
adc = pmMgr->getDC( a );
if( adc != NULL ) {
a->getPosition( pos );
adc->resetAlreadyMovedFlag();
adc->setPosition ( pos[0], pos[1], pos[2] );
adc->setPosition( pos[0], pos[1], pos[2] );
}
}
//Update monitor display
if (monitorDisplay)
if( monitorDisplay )
monitorDisplay->update();
// update loads and atom data if any (override monitors)
pmMgr->getLoadsManager()->getLoadsSimulation()->updateAtomData();
pmMgr->getLoadsManager()->updateLoadsDisplay();
camitk::InteractiveViewer::get3DViewer()->refreshRenderer();
}
// ---------------------- connectMonitor ----------------------------
void MMLDisplay::connectMonitor()
{
void MMLDisplay::connectMonitor() {
Monitor* m=NULL;
std::string s="";
Monitor* m = NULL;
std::string s = "";
QTableWidget* table=mmlManager->getMonitoringGuiManager()->getDialog()->getMonitorsTableWidget();
QTableWidget* table = mmlManager->getMonitoringGuiManager()->getDialog()->getMonitorsTableWidget();
for (int i = 0; i < table->rowCount(); i++) {
QRadioButton* qrb=(QRadioButton*)(table->cellWidget(i,5));
if (qrb->isChecked()) {
m=mmlManager->getMonitoringGuiManager()->getMonitoringManager()->getMonitor(i);
QComboBox* qcb=(QComboBox*)(table->cellWidget(i,6));
s=qcb->currentText().toStdString();
for( int i = 0; i < table->rowCount(); i++ ) {
QRadioButton* qrb = ( QRadioButton* )( table->cellWidget( i, 5 ) );
if( qrb->isChecked() ) {
m = mmlManager->getMonitoringGuiManager()->getMonitoringManager()->getMonitor( i );
QComboBox* qcb = ( QComboBox* )( table->cellWidget( i, 6 ) );
s = qcb->currentText().toStdString();
}
}
if (m) {
if (monitorDisplay) {
if( m ) {
if( monitorDisplay ) {
monitorDisplay->hide();
delete monitorDisplay;
}
MMLMonitorDisplayFactory* fact=MMLMonitorDisplayFactory::getInstance();
monitorDisplay=fact->createMonitorDisplay(s,m,mmlManager);
MMLMonitorDisplayFactory* fact = MMLMonitorDisplayFactory::getInstance();
monitorDisplay = fact->createMonitorDisplay( s, m, mmlManager );
}
updateDisplay();
}
// ---------------------- updateMonitorsTable ----------------------------
void MMLDisplay::updateMonitorsTable()
{
QTableWidget* table=mmlManager->getMonitoringGuiManager()->getDialog()->getMonitorsTableWidget();
void MMLDisplay::updateMonitorsTable() {
QTableWidget* table = mmlManager->getMonitoringGuiManager()->getDialog()->getMonitorsTableWidget();
for (int i = 0; i < table->rowCount(); i++) {
QRadioButton* r=new QRadioButton();
table->setCellWidget(i ,5 , r);
connect(r,SIGNAL(toggled(bool)),this,SLOT(connectMonitor()));
for( int i = 0; i < table->rowCount(); i++ ) {
QRadioButton* r = new QRadioButton();
table->setCellWidget( i , 5 , r );
connect( r, SIGNAL( toggled( bool ) ), this, SLOT( connectMonitor() ) );
// create a combo box to choose how to display monitor
QComboBox* cbox=new QComboBox();
Monitor* monitor=mmlManager->getMonitoringGuiManager()->getMonitoringManager()->getMonitor(i);
MMLMonitorDisplayFactory* fact=MMLMonitorDisplayFactory::getInstance();
for (unsigned int j = 0; j < fact->getNumberOfDisplaysByType(monitor->getValueType()); j++) {
std::string s=fact->getDisplayByType(monitor->getValueType(),j);
cbox->insertItem(j,s.c_str());
QComboBox* cbox = new QComboBox();
Monitor* monitor = mmlManager->getMonitoringGuiManager()->getMonitoringManager()->getMonitor( i );
MMLMonitorDisplayFactory* fact = MMLMonitorDisplayFactory::getInstance();
for( unsigned int j = 0; j < fact->getNumberOfDisplaysByType( monitor->getValueType() ); j++ ) {
std::string s = fact->getDisplayByType( monitor->getValueType(), j );
cbox->insertItem( j, s.c_str() );
}
table->setCellWidget(i ,6 , cbox);
connect(cbox,SIGNAL(currentIndexChanged(int)),this,SLOT(connectMonitor()));
table->setCellWidget( i , 6 , cbox );
connect( cbox, SIGNAL( currentIndexChanged( int ) ), this, SLOT( connectMonitor() ) );
}
}
//--------------- refreshModified ---------------------------------
Monitor* MMLDisplay::getDisplayedMonitor()
{
QTableWidget* table=mmlManager->getMonitoringGuiManager()->getDialog()->getMonitorsTableWidget();
for (int i = 0; i < table->rowCount(); i++) {
QRadioButton* qrb=(QRadioButton*)(table->cellWidget(i,5));
if (qrb->isChecked())
return mmlManager->getMonitoringGuiManager()->getMonitoringManager()->getMonitor(i);