diff framework/Document.cpp @ 329:f72d58d1ccb0 tonioni

Adapt additional models created during a transform so they can be returned through a callback in an async method
author Chris Cannam
date Wed, 29 Jan 2014 17:32:47 +0000
parents 1e61f0c26593
children 151b7c5864e3
line wrap: on
line diff
--- a/framework/Document.cpp	Fri Jan 17 11:59:49 2014 -0500
+++ b/framework/Document.cpp	Wed Jan 29 17:32:47 2014 +0000
@@ -224,7 +224,7 @@
                               const ModelTransformer::Input &input)
 {
     QString message;
-    vector<Model *> newModels = addDerivedModels(transforms, input, message);
+    vector<Model *> newModels = addDerivedModels(transforms, input, message, 0);
 
     if (newModels.empty()) {
         //!!! This identifier may be wrong!
@@ -235,8 +235,101 @@
         emit modelGenerationWarning(transforms[0].getIdentifier(), message);
     }
 
+    QStringList names;
+    for (int i = 0; i < newModels.size(); ++i) {
+        names.push_back(getUniqueLayerName
+                        (TransformFactory::getInstance()->
+                         getTransformFriendlyName
+                         (transforms[i].getIdentifier())));
+    }
+
+    vector<Layer *> layers = createLayersForDerivedModels(newModels, names);
+    return layers;
+}
+
+class AdditionalModelConverter : 
+    public ModelTransformerFactory::AdditionalModelHandler
+{
+public:
+    AdditionalModelConverter(Document *doc, 
+                             Document::LayerCreationHandler *handler) :
+        m_doc(doc),
+        m_handler(handler) {
+    }
+
+    virtual ~AdditionalModelConverter() { }
+
+    void
+    setPrimaryLayers(vector<Layer *> layers) {
+        m_primary = layers;
+    }
+
+    void
+    moreModelsAvailable(vector<Model *> models) {
+        std::cerr << "AdditionalModelConverter::moreModelsAvailable: " << models.size() << " model(s)" << std::endl;
+        // We can't automatically regenerate the additional models on
+        // reload -- we should delete them instead
+        QStringList names;
+        foreach (Model *model, models) {
+            m_doc->addAdditionalModel(model);
+            names.push_back(QString());
+        }
+        vector<Layer *> layers = m_doc->createLayersForDerivedModels
+            (models, names);
+        m_handler->layersCreated(m_primary, layers);
+        delete this;
+    }
+
+    void
+    noMoreModelsAvailable() {
+        std::cerr << "AdditionalModelConverter::noMoreModelsAvailable" << std::endl;
+        delete this;
+    }
+
+private:
+    Document *m_doc;
+    vector<Layer *> m_primary;
+    Document::LayerCreationHandler *m_handler; //!!! how to handle destruction of this?
+};
+
+void
+Document::createDerivedLayersAsync(const Transforms &transforms,
+                                   const ModelTransformer::Input &input,
+                                   LayerCreationHandler *handler)
+{
+    QString message;
+
+    AdditionalModelConverter *amc = new AdditionalModelConverter(this, handler);
+    
+    vector<Model *> newModels = addDerivedModels
+        (transforms, input, message, amc);
+
+    QStringList names;
+    for (int i = 0; i < newModels.size(); ++i) {
+        names.push_back(getUniqueLayerName
+                        (TransformFactory::getInstance()->
+                         getTransformFriendlyName
+                         (transforms[i].getIdentifier())));
+    }
+
+    vector<Layer *> layers = createLayersForDerivedModels(newModels, names);
+    amc->setPrimaryLayers(layers);
+
+    if (newModels.empty()) {
+        //!!! This identifier may be wrong!
+        emit modelGenerationFailed(transforms[0].getIdentifier(), message);
+    } else if (message != "") {
+        //!!! This identifier may be wrong!
+        emit modelGenerationWarning(transforms[0].getIdentifier(), message);
+    }
+}
+
+vector<Layer *>
+Document::createLayersForDerivedModels(vector<Model *> newModels, 
+                                       QStringList names)
+{
     vector<Layer *> layers;
-
+    
     for (int i = 0; i < (int)newModels.size(); ++i) {
 
         Model *newModel = newModels[i];
@@ -245,7 +338,7 @@
             LayerFactory::getInstance()->getValidLayerTypes(newModel);
 
         if (types.empty()) {
-            cerr << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << transforms[i].getIdentifier() << endl;
+            cerr << "WARNING: Document::createLayerForTransformer: no valid display layer for output of transform " << names[i] << endl;
             //!!! inadequate cleanup:
             newModel->aboutToDelete();
             emit modelAboutToBeDeleted(newModel);
@@ -275,10 +368,7 @@
         // model pointer in both layers, so they can't actually be cloned.
     
         if (newLayer) {
-            newLayer->setObjectName(getUniqueLayerName
-                                    (TransformFactory::getInstance()->
-                                     getTransformFriendlyName
-                                     (transforms[i].getIdentifier())));
+            newLayer->setObjectName(names[i]);
         }
 
         emit layerAdded(newLayer);
@@ -423,6 +513,14 @@
     }
 
     for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) {
+        if (i->second.additional) {
+            Model *m = i->first;
+            emit modelAboutToBeDeleted(m);
+            delete m;
+        }
+    }
+
+    for (ModelMap::iterator i = m_models.begin(); i != m_models.end(); ++i) {
 
         Model *m = i->first;
 
@@ -457,21 +555,21 @@
 }
 
 void
-Document::addDerivedModel(const Transform &transform,
-                          const ModelTransformer::Input &input,
-                          Model *outputModelToAdd)
+Document::addAlreadyDerivedModel(const Transform &transform,
+                                 const ModelTransformer::Input &input,
+                                 Model *outputModelToAdd)
 {
     if (m_models.find(outputModelToAdd) != m_models.end()) {
-	cerr << "WARNING: Document::addDerivedModel: Model already added"
+	cerr << "WARNING: Document::addAlreadyDerivedModel: Model already added"
 		  << endl;
 	return;
     }
 
 #ifdef DEBUG_DOCUMENT
     if (input.getModel()) {
-        cerr << "Document::addDerivedModel: source is " << input.getModel() << " \"" << input.getModel()->objectName() << "\"" << endl;
+        cerr << "Document::addAlreadyDerivedModel: source is " << input.getModel() << " \"" << input.getModel()->objectName() << "\"" << endl;
     } else {
-        cerr << "Document::addDerivedModel: source is " << input.getModel() << endl;
+        cerr << "Document::addAlreadyDerivedModel: source is " << input.getModel() << endl;
     }
 #endif
 
@@ -479,6 +577,7 @@
     rec.source = input.getModel();
     rec.channel = input.getChannel();
     rec.transform = transform;
+    rec.additional = false;
     rec.refcount = 0;
 
     outputModelToAdd->setSourceModel(input.getModel());
@@ -486,7 +585,7 @@
     m_models[outputModelToAdd] = rec;
 
 #ifdef DEBUG_DOCUMENT
-    SVDEBUG << "Document::addDerivedModel: Added model " << outputModelToAdd << endl;
+    cerr << "Document::addAlreadyDerivedModel: Added model " << outputModelToAdd << endl;
     cerr << "Models now: ";
     for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) {
         cerr << i->first << " ";
@@ -510,6 +609,7 @@
     ModelRecord rec;
     rec.source = 0;
     rec.refcount = 0;
+    rec.additional = false;
 
     m_models[model] = rec;
 
@@ -527,6 +627,36 @@
     emit modelAdded(model);
 }
 
+void
+Document::addAdditionalModel(Model *model)
+{
+    if (m_models.find(model) != m_models.end()) {
+	cerr << "WARNING: Document::addAdditionalModel: Model already added"
+		  << endl;
+	return;
+    }
+
+    ModelRecord rec;
+    rec.source = 0;
+    rec.refcount = 0;
+    rec.additional = true;
+
+    m_models[model] = rec;
+
+#ifdef DEBUG_DOCUMENT
+    SVDEBUG << "Document::addAdditionalModel: Added model " << model << endl;
+    cerr << "Models now: ";
+    for (ModelMap::const_iterator i = m_models.begin(); i != m_models.end(); ++i) {
+        cerr << i->first << " ";
+    } 
+    cerr << endl;
+#endif
+
+    if (m_autoAlignment) alignModel(model);
+
+    emit modelAdded(model);
+}
+
 Model *
 Document::addDerivedModel(const Transform &transform,
                           const ModelTransformer::Input &input,
@@ -543,7 +673,7 @@
 
     Transforms tt;
     tt.push_back(transform);
-    vector<Model *> mm = addDerivedModels(tt, input, message);
+    vector<Model *> mm = addDerivedModels(tt, input, message, 0);
     if (mm.empty()) return 0;
     else return mm[0];
 }
@@ -551,11 +681,12 @@
 vector<Model *>
 Document::addDerivedModels(const Transforms &transforms,
                            const ModelTransformer::Input &input,
-                           QString &message)
+                           QString &message,
+                           AdditionalModelConverter *amc)
 {
     vector<Model *> mm = 
         ModelTransformerFactory::getInstance()->transformMultiple
-        (transforms, input, message);
+        (transforms, input, message, amc);
 
     for (int j = 0; j < (int)mm.size(); ++j) {
 
@@ -579,7 +710,7 @@
         if (!model) {
             cerr << "WARNING: Document::addDerivedModel: no output model for transform " << applied.getIdentifier() << endl;
         } else {
-            addDerivedModel(applied, input, model);
+            addAlreadyDerivedModel(applied, input, model);
         }
     }