Salome HOME
3391c08c7cad9eae79e8ad96d46edcdf39466f8a
[modules/gui.git] / src / VTKViewer / VTKViewer_ShrinkFilter.cxx
1 //  SALOME OBJECT : kernel of SALOME component
2 //
3 //  Copyright (C) 2003  OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 //  CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS 
5 // 
6 //  This library is free software; you can redistribute it and/or 
7 //  modify it under the terms of the GNU Lesser General Public 
8 //  License as published by the Free Software Foundation; either 
9 //  version 2.1 of the License. 
10 // 
11 //  This library is distributed in the hope that it will be useful, 
12 //  but WITHOUT ANY WARRANTY; without even the implied warranty of 
13 //  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU 
14 //  Lesser General Public License for more details. 
15 // 
16 //  You should have received a copy of the GNU Lesser General Public 
17 //  License along with this library; if not, write to the Free Software 
18 //  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA 
19 // 
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
21 //
22 //
23 //
24 //  File   : SALOME_GeometryFilter.cxx
25 //  Author : Michael ZORIN
26 //  Module : SALOME
27 //  $Header$
28
29 #include "VTKViewer_ShrinkFilter.h"
30
31 #include <vtkCell.h>
32 #include <vtkCellData.h>
33 #include <vtkIdList.h>
34 #include <vtkObjectFactory.h>
35 #include <vtkPointData.h>
36 #include <vtkUnstructuredGrid.h>
37 #include <vtkInformation.h>
38 #include <vtkInformationVector.h>
39
40 vtkCxxRevisionMacro(VTKViewer_ShrinkFilter, "$Revision$");
41 vtkStandardNewMacro(VTKViewer_ShrinkFilter);
42
43 /*!Constructor. Sets store mapping to zero.*/
44 VTKViewer_ShrinkFilter::VTKViewer_ShrinkFilter(): 
45   myStoreMapping(0)
46 {}
47
48 /*!Destructor.*/
49 VTKViewer_ShrinkFilter::~VTKViewer_ShrinkFilter()
50 {}
51
52
53 /*!Execute method. Calculate output.*/
54 int VTKViewer_ShrinkFilter::RequestData(
55   vtkInformation *vtkNotUsed(request),
56   vtkInformationVector **inputVector,
57   vtkInformationVector *outputVector)
58 {
59   // get the info objects
60   vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
61   vtkInformation *outInfo = outputVector->GetInformationObject(0);
62
63   // get the input and ouptut
64   vtkDataSet *input = vtkDataSet::SafeDownCast(
65     inInfo->Get(vtkDataObject::DATA_OBJECT()));
66   vtkUnstructuredGrid *output = vtkUnstructuredGrid::SafeDownCast(
67     outInfo->Get(vtkDataObject::DATA_OBJECT()));
68
69   vtkPoints *newPts;
70   int i, j, numIds, abort=0;
71   vtkIdType cellId, numCells, numPts;
72   vtkIdType oldId, newId;
73   vtkFloatingPointType center[3], *p, pt[3];
74   vtkPointData *pd, *outPD;;
75   vtkIdList *ptIds, *newPtIds;
76   vtkIdType tenth;
77   vtkFloatingPointType decimal;
78
79   vtkDebugMacro(<<"Shrinking cells");
80
81   numCells=input->GetNumberOfCells();
82   numPts = input->GetNumberOfPoints();
83   if (numCells < 1 || numPts < 1)
84     {
85     vtkErrorMacro(<<"No data to shrink!");
86     return 0;
87     }
88
89   ptIds = vtkIdList::New();
90   ptIds->Allocate(VTK_CELL_SIZE);
91   newPtIds = vtkIdList::New();
92   newPtIds->Allocate(VTK_CELL_SIZE);
93
94   output->Allocate(numCells);
95   newPts = vtkPoints::New();
96   newPts->Allocate(numPts*8,numPts);
97   pd = input->GetPointData();
98   outPD = output->GetPointData();
99   outPD->CopyAllocate(pd,numPts*8,numPts);
100
101   // Traverse all cells, obtaining node coordinates.  Compute "center" of cell,
102   // then create new vertices shrunk towards center.
103   //
104   tenth   = numCells/10 + 1;
105   decimal = 0.0;
106   if(myStoreMapping){
107     myVTK2ObjIds.clear();
108     myVTK2ObjIds.reserve(numCells);
109   }
110
111   for (cellId=0; cellId < numCells && !abort; cellId++)
112     {
113     input->GetCellPoints(cellId, ptIds);
114     numIds = ptIds->GetNumberOfIds();
115
116     //abort/progress methods
117     if (cellId % tenth == 0) 
118       {
119       decimal += 0.1;
120       this->UpdateProgress (decimal);
121       abort = this->GetAbortExecute();
122       }
123
124     // get the center of the cell
125     center[0] = center[1] = center[2] = 0.0;
126     for (i=0; i < numIds; i++)
127       {
128       p = input->GetPoint(ptIds->GetId(i));
129       for (j=0; j < 3; j++)
130         {
131         center[j] += p[j];
132         }
133       }
134     for (j=0; j<3; j++)
135       {
136       center[j] /= numIds;
137       }
138
139     // Create new points and cells
140     newPtIds->Reset();
141     for (i=0; i < numIds; i++)
142       {
143       p = input->GetPoint(ptIds->GetId(i));
144       for (j=0; j < 3; j++)
145         {
146         pt[j] = center[j] + this->ShrinkFactor*(p[j] - center[j]);
147         }
148
149       oldId = ptIds->GetId(i);
150       newId = newPts->InsertNextPoint(pt);
151       if(myStoreMapping)
152         myVTK2ObjIds.push_back(oldId);
153       newPtIds->InsertId(i,newId);
154
155       outPD->CopyData(pd, oldId, newId);
156       }
157     output->InsertNextCell(input->GetCellType(cellId), newPtIds);
158     }//for all cells
159
160   // Update ourselves and release memory
161   //
162   output->GetCellData()->PassData(input->GetCellData());
163
164   output->SetPoints(newPts);
165   output->Squeeze();
166
167   ptIds->Delete();
168   newPtIds->Delete();
169   newPts->Delete();
170   
171   return 1;
172 }
173
174 /*!Sets store mapping.*/
175 void VTKViewer_ShrinkFilter::SetStoreMapping(int theStoreMapping){
176   myStoreMapping = theStoreMapping;
177   this->Modified();
178 }
179
180
181 /*!Return node object id by vtk node id.
182  *\retval -1 - if no object, else return id.
183  */
184 vtkIdType VTKViewer_ShrinkFilter::GetNodeObjId(int theVtkID)
185 {
186   if ( myVTK2ObjIds.empty() || theVtkID > (int)myVTK2ObjIds.size() )
187     return -1;
188   return myVTK2ObjIds.at(theVtkID);
189 }