Salome HOME
Fix for the "0051899: curves are not shown in opened study" issue.
[modules/visu.git] / src / CONVERTOR / VISU_MergeFilter.cxx
index 4cabc7fbe1bf39518abdc0076fb913eb5b901656..2c87548a5926c7ba0c779af900c12d055e542ecf 100644 (file)
-//  SALOME VTKViewer : build VTK viewer into Salome desktop
+// Copyright (C) 2007-2013  CEA/DEN, EDF R&D, OPEN CASCADE
 //
-//  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
-//  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
-// 
-//  This library is free software; you can redistribute it and/or 
-//  modify it under the terms of the GNU Lesser General Public 
-//  License as published by the Free Software Foundation; either 
-//  version 2.1 of the License. 
-// 
-//  This library 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 
-//  Lesser General Public License for more details. 
-// 
-//  You should have received a copy of the GNU Lesser General Public 
-//  License along with this library; if not, write to the Free Software 
-//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
-// 
-// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
+// Copyright (C) 2003-2007  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
+// CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
+//
+// This library is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 2.1 of the License.
 //
+// This library 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
+// Lesser General Public License for more details.
 //
+// You should have received a copy of the GNU Lesser General Public
+// License along with this library; if not, write to the Free Software
+// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+//
+// See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
 //
+
+//  SALOME VTKViewer : build VTK viewer into Salome desktop
 //  File   : 
 //  Author : 
 //  Module : SALOME
 //  $Header$
-
+//
 #include "VISU_MergeFilter.hxx"
+#include "VISU_MergeFilterUtilities.hxx"
 
-#include <vtkCellData.h>
 #include <vtkObjectFactory.h>
-#include <vtkPointData.h>
-#include <vtkPolyData.h>
-#include <vtkRectilinearGrid.h>
-#include <vtkStructuredGrid.h>
-#include <vtkStructuredPoints.h>
 #include <vtkUnstructuredGrid.h>
+#include <vtkPolyData.h>
 
-namespace VISU
-{
-
-  class TFieldNode
-  {
-  public:
-    TFieldNode(const char* name, vtkDataSet* ptr=0)
-    {
-      int length = static_cast<int>(strlen(name));
-      if (length > 0) {
-       this->Name = new char[length+1];
-       strcpy(this->Name, name);
-      } else {
-        this->Name = 0;
-      }
-      this->Ptr = ptr;
-      this->Next = 0;
-    }
-    ~TFieldNode()
-    {
-      delete[] this->Name;
-    }
-
-    const char* GetName()
-    {
-      return Name;
-    }
-    vtkDataSet* Ptr;
-    TFieldNode* Next;
-  private:
-    TFieldNode(const TFieldNode&) {}
-    void operator=(const TFieldNode&) {}
-    char* Name;
-  };
-
-  class TFieldList
-  {
-  public:
-    TFieldList()
-    {
-      this->First = 0;
-      this->Last = 0;
-    }
-    ~TFieldList()
-    {
-      TFieldNode* node = this->First;
-      TFieldNode* next;
-      while(node){
-        next = node->Next;
-        delete node;
-        node = next;
-      }
-    }
+#include <vtkExecutive.h>
+#include <vtkInformation.h>
+#include <vtkInformationVector.h>
+#include <vtkStreamingDemandDrivenPipeline.h>
 
 
-    void Add(const char* name, vtkDataSet* ptr)
-    {
-      TFieldNode* newNode = new TFieldNode(name, ptr);
-      if (!this->First) {
-       this->First = newNode;
-       this->Last = newNode;
-      } else {
-        this->Last->Next = newNode;
-        this->Last = newNode;
-      }
-    }
-
-    friend class TFieldListIterator;
-    
-  private:
-    TFieldNode* First;
-    TFieldNode* Last;
-  };
-  
-  class TFieldListIterator
-  {
-  public:
-    TFieldListIterator(TFieldList* list)
-    {
-      this->List = list;
-      this->Position = 0;
-    }
-    void Begin()
-    {
-      this->Position = this->List->First;
-    }
-    void Next()
-    {
-      if (this->Position) {
-       this->Position = this->Position->Next;
-      }
-    }
-    int End()
-    {
-      return this->Position ? 0 : 1;
-    }
-    TFieldNode* Get()
-    {
-      return this->Position;
-    }
-    
-  private:
-    TFieldNode* Position;
-    TFieldList* List;
-  };
-  
-}
-
 //------------------------------------------------------------------------------
 vtkStandardNewMacro(VISU_MergeFilter);
 
 //------------------------------------------------------------------------------
-
-// Create object with no input or output.
-VISU_MergeFilter::VISU_MergeFilter()
+VISU_MergeFilter
+::VISU_MergeFilter():
+  myIsMergingInputs(false)
 {
   this->FieldList = new VISU::TFieldList;
+  this->SetNumberOfInputPorts(6);
 }
 
+//------------------------------------------------------------------------------
 VISU_MergeFilter::~VISU_MergeFilter()
 {
   delete this->FieldList;
 }
 
-void VISU_MergeFilter::SetScalars(vtkDataSet *input)
+//------------------------------------------------------------------------------
+void VISU_MergeFilter::SetGeometryConnection(vtkAlgorithmOutput *input)
 {
-  this->vtkProcessObject::SetNthInput(1, input);
+  this->Superclass::SetInputConnection(input);
 }
-vtkDataSet *VISU_MergeFilter::GetScalars()
+
+//------------------------------------------------------------------------------
+void VISU_MergeFilter::SetGeometryData(vtkDataSet *input)
 {
-  if (this->NumberOfInputs < 2)
-    {
-    return NULL;
-    }
-  return (vtkDataSet *)(this->Inputs[1]);
+  this->Superclass::SetInputData(input);
 }
 
-void VISU_MergeFilter::SetVectors(vtkDataSet *input)
+//------------------------------------------------------------------------------
+void VISU_MergeFilter::SetScalarsData(vtkDataSet *input)
 {
-  this->vtkProcessObject::SetNthInput(2, input);
-}
-vtkDataSet *VISU_MergeFilter::GetVectors()
-{
-  if (this->NumberOfInputs < 3)
-    {
-    return NULL;
-    }
-  return (vtkDataSet *)(this->Inputs[2]);
+  this->SetInputData(1, input);
 }
 
-void VISU_MergeFilter::SetNormals(vtkDataSet *input)
+//------------------------------------------------------------------------------
+void VISU_MergeFilter::SetScalarsConnection(vtkAlgorithmOutput *input)
 {
-  this->vtkProcessObject::SetNthInput(3, input);
+  this->SetInputConnection(1, input);
 }
-vtkDataSet *VISU_MergeFilter::GetNormals()
+
+//------------------------------------------------------------------------------
+void VISU_MergeFilter::SetVectorsData(vtkDataSet *input)
 {
-  if (this->NumberOfInputs < 4)
-    {
-    return NULL;
-    }
-  return (vtkDataSet *)(this->Inputs[3]);
+  this->SetInputData(2, input);
 }
 
-void VISU_MergeFilter::SetTCoords(vtkDataSet *input)
+//------------------------------------------------------------------------------
+void VISU_MergeFilter::SetVectorsConnection(vtkAlgorithmOutput *input)
 {
-  this->vtkProcessObject::SetNthInput(4, input);
+  this->SetInputConnection(2, input);
 }
-vtkDataSet *VISU_MergeFilter::GetTCoords()
+
+//------------------------------------------------------------------------------
+void VISU_MergeFilter::SetNormals(vtkAlgorithmOutput *input)
 {
-  if (this->NumberOfInputs < 5)
-    {
-    return NULL;
-    }
-  return (vtkDataSet *)(this->Inputs[4]);
+  this->SetInputConnection(3, input);
 }
 
-void VISU_MergeFilter::SetTensors(vtkDataSet *input)
+//------------------------------------------------------------------------------
+void VISU_MergeFilter::SetTCoords(vtkAlgorithmOutput *input)
 {
-  this->vtkProcessObject::SetNthInput(5, input);
+  this->SetInputConnection(4, input);
 }
-vtkDataSet *VISU_MergeFilter::GetTensors()
+
+//------------------------------------------------------------------------------
+void VISU_MergeFilter::SetTensors(vtkAlgorithmOutput *input)
 {
-  if (this->NumberOfInputs < 6)
-    {
-    return NULL;
-    }
-  return (vtkDataSet *)(this->Inputs[5]);
+  this->SetInputConnection(5, input);
 }
 
+//------------------------------------------------------------------------------
 void VISU_MergeFilter::AddField(const char* name, vtkDataSet* input)
 {
   this->FieldList->Add(name, input);
 }
 
-void VISU_MergeFilter::Execute()
+//------------------------------------------------------------------------------
+void VISU_MergeFilter::RemoveFields()
 {
-  vtkIdType numPts, numScalars=0, numVectors=0, numNormals=0, numTCoords=0;
-  vtkIdType numTensors=0;
-  vtkIdType numCells, numCellScalars=0, numCellVectors=0, numCellNormals=0;
-  vtkIdType numCellTCoords=0, numCellTensors=0;
-  vtkPointData *pd;
-  vtkDataArray *scalars = NULL;
-  vtkDataArray *vectors = NULL;
-  vtkDataArray *normals = NULL;
-  vtkDataArray *tcoords = NULL;
-  vtkDataArray *tensors = NULL;
-  vtkCellData *cd;
-  vtkDataArray *cellScalars = NULL;
-  vtkDataArray *cellVectors = NULL;
-  vtkDataArray *cellNormals = NULL;
-  vtkDataArray *cellTCoords = NULL;
-  vtkDataArray *cellTensors = NULL;
-  vtkDataSet *output = this->GetOutput();
-  vtkPointData *outputPD = output->GetPointData();
-  vtkCellData *outputCD = output->GetCellData();
-  
-  vtkDebugMacro(<<"Merging data!");
+  delete this->FieldList;
+  this->FieldList = new VISU::TFieldList;
+}
 
-  // geometry needs to be copied
-  output->CopyStructure(this->GetInput());
-  if ( (numPts = this->GetInput()->GetNumberOfPoints()) < 1 )
-    {
-    vtkWarningMacro(<<"Nothing to merge!");
-    }
-  numCells = this->GetInput()->GetNumberOfCells();
-  
-  if ( this->GetScalars() ) 
-    {
-    pd = this->GetScalars()->GetPointData();
-    scalars = pd->GetScalars();
-    if ( scalars != NULL )
-      {
-      numScalars = scalars->GetNumberOfTuples();
-      }
-    cd = this->GetScalars()->GetCellData();
-    cellScalars = cd->GetScalars();
-    if ( cellScalars != NULL )
-      {
-      numCellScalars = cellScalars->GetNumberOfTuples();
-      }
-    }
 
-  if ( this->GetVectors() ) 
-    {
-    pd = this->GetVectors()->GetPointData();
-    vectors = pd->GetVectors();
-    if ( vectors != NULL )
-      {
-      numVectors= vectors->GetNumberOfTuples();
-      }
-    cd = this->GetVectors()->GetCellData();
-    cellVectors = cd->GetVectors();
-    if ( cellVectors != NULL )
-      {
-      numCellVectors = cellVectors->GetNumberOfTuples();
-      }
-    }
+//---------------------------------------------------------------
+void
+VISU_MergeFilter
+::SetMergingInputs(bool theIsMergingInputs)
+{
+  if(myIsMergingInputs == theIsMergingInputs)
+    return;
 
-  if ( this->GetNormals() ) 
-    {
-    pd = this->GetNormals()->GetPointData();
-    normals = pd->GetNormals();
-    if ( normals != NULL )
-      {
-      numNormals= normals->GetNumberOfTuples();
-      }
-    cd = this->GetNormals()->GetCellData();
-    cellNormals = cd->GetNormals();
-    if ( cellNormals != NULL )
-      {
-      numCellNormals = cellNormals->GetNumberOfTuples();
-      }
-    }
+  myIsMergingInputs = theIsMergingInputs;
+  Modified();
+}
 
-  if ( this->GetTCoords() ) 
-    {
-    pd = this->GetTCoords()->GetPointData();
-    tcoords = pd->GetTCoords();
-    if ( tcoords != NULL )
-      {
-      numTCoords= tcoords->GetNumberOfTuples();
-      }
-    cd = this->GetTCoords()->GetCellData();
-    cellTCoords = cd->GetTCoords();
-    if ( cellTCoords != NULL )
-      {
-      numCellTCoords = cellTCoords->GetNumberOfTuples();
-      }
-    }
+  
+//---------------------------------------------------------------
+bool
+VISU_MergeFilter
+::IsMergingInputs()
+{
+  return myIsMergingInputs;
+}
+  
 
-  if ( this->GetTensors() ) 
+//---------------------------------------------------------------
+int
+VISU_MergeFilter
+::RequestData(vtkInformation *theRequest,
+              vtkInformationVector **theInputVector,
+              vtkInformationVector *theOutputVector)
+{
+  vtkInformation *inInfo0 = theInputVector[0]->GetInformationObject(0);
+  vtkInformation *inInfo1 = theInputVector[1]->GetInformationObject(0);
+  vtkInformation *inInfo2 = theInputVector[2]->GetInformationObject(0);
+  vtkInformation *inInfo3 = theInputVector[3]->GetInformationObject(0);
+  vtkInformation *inInfo4 = theInputVector[4]->GetInformationObject(0);
+  vtkInformation *inInfo5 = theInputVector[5]->GetInformationObject(0);
+  vtkInformation *outInfo = theOutputVector->GetInformationObject(0);
+
+  // get the input and output
+  vtkDataSet *anInput = vtkDataSet::SafeDownCast(inInfo0->Get(vtkDataObject::DATA_OBJECT()));
+  vtkDataSet *aScalars = theInputVector[1]->GetNumberOfInformationObjects() > 0 ?
+    vtkDataSet::SafeDownCast(inInfo1->Get(vtkDataObject::DATA_OBJECT())) : NULL;
+  vtkDataSet *aVectors = theInputVector[2]->GetNumberOfInformationObjects() > 0 ?
+    vtkDataSet::SafeDownCast(inInfo2->Get(vtkDataObject::DATA_OBJECT())) : NULL;
+  vtkDataSet *aNormals = theInputVector[3]->GetNumberOfInformationObjects() > 0 ?
+    vtkDataSet::SafeDownCast(inInfo3->Get(vtkDataObject::DATA_OBJECT())) : NULL;
+  vtkDataSet *aTCoords = theInputVector[4]->GetNumberOfInformationObjects() > 0 ?
+    vtkDataSet::SafeDownCast(inInfo4->Get(vtkDataObject::DATA_OBJECT())) : NULL;
+  vtkDataSet *aTensors = theInputVector[5]->GetNumberOfInformationObjects() > 0 ?
+    vtkDataSet::SafeDownCast(inInfo5->Get(vtkDataObject::DATA_OBJECT())) : NULL;
+  vtkDataSet *anOutput = vtkDataSet::SafeDownCast(outInfo->Get(vtkDataObject::DATA_OBJECT()));
+
+  if(vtkUnstructuredGrid *anInputUG = dynamic_cast<vtkUnstructuredGrid*>(anInput)){
+    vtkUnstructuredGrid *anOutputUG = dynamic_cast<vtkUnstructuredGrid*>(anOutput);
+    return VISU::Execute(anInputUG,
+                         anOutputUG,
+                         aScalars,
+                         aVectors,
+                         aNormals,
+                         aTCoords,
+                         aTensors,
+                         this->FieldList,
+                         IsMergingInputs());
+  }else if(vtkPolyData *anInputPD = dynamic_cast<vtkPolyData*>(anInput)){
+    vtkPolyData *anOutputPD =  dynamic_cast<vtkPolyData*>(anOutput);
+    return VISU::Execute(anInputPD,
+                         anOutputPD,
+                         aScalars,
+                         aVectors,
+                         aNormals,
+                         aTCoords,
+                         aTensors,
+                         this->FieldList,
+                         IsMergingInputs());
+  }
+
+  return Superclass::RequestData(theRequest,
+                                 theInputVector,
+                                 theOutputVector);
+}
+
+//----------------------------------------------------------------------------
+//  Trick:  Abstract data types that may or may not be the same type
+// (structured/unstructured), but the points/cells match up.
+// Output/Geometry may be structured while ScalarInput may be 
+// unstructured (but really have same triagulation/topology as geometry).
+// Just request all the input. Always generate all of the output (todo).
+int
+VISU_MergeFilter
+::RequestUpdateExtent(vtkInformation *vtkNotUsed(request),
+                      vtkInformationVector **inputVector,
+                      vtkInformationVector *vtkNotUsed(outputVector))
+{
+  vtkInformation *inputInfo;
+  int idx;
+  
+  for (idx = 0; idx < 6; ++idx)
     {
-    pd = this->GetTensors()->GetPointData();
-    tensors = pd->GetTensors();
-    if ( tensors != NULL )
+    inputInfo = inputVector[idx]->GetInformationObject(0);
+    if (inputInfo)
       {
-      numTensors = tensors->GetNumberOfTuples();
+      inputInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_PIECE_NUMBER(),
+                     0);
+      inputInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_PIECES(),
+                     1);
+      inputInfo->Set(vtkStreamingDemandDrivenPipeline::UPDATE_NUMBER_OF_GHOST_LEVELS(),
+                     0);
+      inputInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 1);
       }
-    cd = this->GetTensors()->GetCellData();
-    cellTensors = cd->GetTensors();
-    if ( cellTensors != NULL )
-      {
-      numCellTensors = cellTensors->GetNumberOfTuples();
-      }
-    }
-
-  // merge data only if it is consistent
-  if ( numPts == numScalars )
-    {
-    outputPD->SetScalars(scalars);
-    }
-  if ( numCells == numCellScalars )
-    {
-    outputCD->SetScalars(cellScalars);
-    }
-
-  if ( numPts == numVectors )
-    {
-    outputPD->SetVectors(vectors);
-    }
-  if ( numCells == numCellVectors )
-    {
-    outputCD->SetVectors(cellVectors);
-    }
-    
-  if ( numPts == numNormals )
-    {
-    outputPD->SetNormals(normals);
-    }
-  if ( numCells == numCellNormals )
-    {
-    outputCD->SetNormals(cellNormals);
-    }
-
-  if ( numPts == numTCoords )
-    {
-    outputPD->SetTCoords(tcoords);
-    }
-  if ( numCells == numCellTCoords )
-    {
-    outputCD->SetTCoords(cellTCoords);
     }
+  return 1;
+}
 
-  if ( numPts == numTensors )
-    {
-    outputPD->SetTensors(tensors);
-    }
-  if ( numCells == numCellTensors )
-    {
-    outputCD->SetTensors(cellTensors);
-    }
 
-  VISU::TFieldListIterator it(this->FieldList);
-  vtkDataArray* da;
-  const char* name;
-  vtkIdType num;
-  for(it.Begin(); !it.End() ; it.Next())
+//----------------------------------------------------------------------------
+int
+VISU_MergeFilter
+::FillInputPortInformation(int port, vtkInformation *info)
+{
+  int retval = this->Superclass::FillInputPortInformation(port, info);
+  if (port > 0)
     {
-    pd = it.Get()->Ptr->GetPointData();
-    cd = it.Get()->Ptr->GetCellData();
-    name = it.Get()->GetName();
-    if ( (da=pd->GetArray(name)) )
-      {
-      num = da->GetNumberOfTuples();
-      if (num == numPts)
-        {
-        outputPD->AddArray(da);
-        }
-      }
-    if ( (da=cd->GetArray(name)) )
-      {
-      num = da->GetNumberOfTuples();
-      if (num == numCells) // To fix a VTK bug
-        {
-        outputCD->AddArray(da);
-        }
-      }
+    info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
     }
+  return retval;
 }
+