1 // Copyright (C) 2010-2012 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "vtkElevationSurfaceFilter.h"
21 #include "vtkInformation.h"
22 #include "vtkInformationVector.h"
23 #include "vtkObjectFactory.h"
24 #include "vtkElevationSurfaceFilter.h"
25 #include "vtkPolyData.h"
26 #include "vtkIdTypeArray.h"
27 #include "vtkPolyData.h"
28 #include "vtkUnstructuredGrid.h"
29 #include "vtkDemandDrivenPipeline.h"
30 #include "vtkStreamingDemandDrivenPipeline.h"
31 #include "vtkGenericCell.h"
32 #include "vtkSmartPointer.h"
33 #include "vtkPoints.h"
34 #include "vtkCellArray.h"
35 #include "vtkPointData.h"
36 #include "vtkCellData.h"
37 //#include "vtkDataSetSurfaceFilter.h"
41 vtkCxxRevisionMacro(vtkElevationSurfaceFilter, "$Revision$");
42 vtkStandardNewMacro(vtkElevationSurfaceFilter);
44 vtkElevationSurfaceFilter::vtkElevationSurfaceFilter()
46 this->SetNumberOfInputPorts(1);
47 this->SetNumberOfOutputPorts(1);
49 this->ScaleFactor = 0.5;
50 this->Direction[0] = 0.0;
51 this->Direction[1] = 0.0;
52 this->Direction[2] = 1.0;
53 this->AutoDetectDirection = 1;
56 vtkElevationSurfaceFilter::~vtkElevationSurfaceFilter()
60 //----------------------------------------------------------------------------
61 int vtkElevationSurfaceFilter::ProcessRequest(vtkInformation* request,
62 vtkInformationVector** inputVector,
63 vtkInformationVector* outputVector)
66 if(request->Has(vtkDemandDrivenPipeline::REQUEST_DATA()))
68 return this->RequestData(request, inputVector, outputVector);
71 if(request->Has(vtkStreamingDemandDrivenPipeline::REQUEST_UPDATE_EXTENT()))
73 return this->RequestUpdateExtent(request, inputVector, outputVector);
76 // execute information
77 if(request->Has(vtkDemandDrivenPipeline::REQUEST_INFORMATION()))
79 return this->RequestInformation(request, inputVector, outputVector);
82 return this->Superclass::ProcessRequest(request, inputVector, outputVector);
85 //----------------------------------------------------------------------------
86 int vtkElevationSurfaceFilter::FillOutputPortInformation(
87 int vtkNotUsed(port), vtkInformation* info)
90 info->Set(vtkDataObject::DATA_TYPE_NAME(), "vtkUnstructuredGrid");
94 //----------------------------------------------------------------------------
95 int vtkElevationSurfaceFilter::FillInputPortInformation(
96 int vtkNotUsed(port), vtkInformation* info)
98 info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkPointSet");
102 //----------------------------------------------------------------------------
103 int vtkElevationSurfaceFilter::RequestUpdateExtent(
104 vtkInformation* vtkNotUsed(request),
105 vtkInformationVector** inputVector,
106 vtkInformationVector* vtkNotUsed(outputVector))
108 int numInputPorts = this->GetNumberOfInputPorts();
109 for (int i=0; i<numInputPorts; i++)
111 int numInputConnections = this->GetNumberOfInputConnections(i);
112 for (int j=0; j<numInputConnections; j++)
114 vtkInformation* inputInfo = inputVector[i]->GetInformationObject(j);
115 inputInfo->Set(vtkStreamingDemandDrivenPipeline::EXACT_EXTENT(), 1);
121 int vtkElevationSurfaceFilter::RequestInformation(vtkInformation *request,
122 vtkInformationVector **input, vtkInformationVector *output)
127 int vtkElevationSurfaceFilter::RequestData(vtkInformation *request,
128 vtkInformationVector **input, vtkInformationVector *output)
130 vtkPointSet *psIn = vtkPointSet::SafeDownCast(
131 input[0]->GetInformationObject(0)->Get(vtkDataObject::DATA_OBJECT()));
133 //vtkPolyData *psIn = vtkPolyData::SafeDownCast(
134 // input[0]->GetInformationObject(0)->Get(vtkDataObject::DATA_OBJECT()));
136 /*vtkSmartPointer<vtkDataSetSurfaceFilter> surfaceFilter = vtkSmartPointer<vtkDataSetSurfaceFilter>::New();
137 surfaceFilter->SetInput(psIn);
138 vtkPolyData* psIn = vtkPolyData::SafeDownCast(surfaceFilter->GetOutput());*/
140 vtkUnstructuredGrid *usgOut = vtkUnstructuredGrid::SafeDownCast(
141 output->GetInformationObject(0)->Get(vtkDataObject::DATA_OBJECT()));
143 vtkDataArray* array = this->GetInputArrayToProcess(0, input);
145 if(psIn == NULL || array == NULL || usgOut == NULL
146 || array->GetNumberOfComponents() != 1)
148 vtkDebugMacro("vtkElevationSurfaceFilter no correctly configured");
153 if(this->AutoDetectDirection)
155 this->ComputeDirection(psIn, dir);
159 dir[0] = this->Direction[0];
160 dir[1] = this->Direction[1];
161 dir[2] = this->Direction[2];
164 double len = dir[0]*dir[0] + dir[1]*dir[1] + dir[2]*dir[2];
178 dir[0] *= this->GetScaleFactor();
179 dir[1] *= this->GetScaleFactor();
180 dir[2] *= this->GetScaleFactor();
182 usgOut->Allocate(psIn->GetNumberOfCells());
184 vtkSmartPointer<vtkPoints> newPts = vtkSmartPointer<vtkPoints>::New();
185 usgOut->SetPoints(newPts);
187 usgOut->GetPointData()->CopyAllocate(psIn->GetPointData(),
188 2*psIn->GetNumberOfPoints());
189 usgOut->GetCellData()->CopyAllocate(psIn->GetCellData(),
190 psIn->GetNumberOfCells());
192 vtkIdType ncell = psIn->GetNumberOfCells();
193 vtkSmartPointer<vtkIdList> newIds = vtkSmartPointer<vtkIdList>::New();
194 vtkSmartPointer<vtkIdList> polyhedronIds = vtkSmartPointer<vtkIdList>::New();
195 vtkSmartPointer<vtkIdList> neighbors = vtkSmartPointer<vtkIdList>::New();
196 for(vtkIdType cellId=0; cellId < ncell; cellId++)
198 vtkCell* cell = psIn->GetCell(cellId);
199 if(cell->GetCellDimension() != 2)
202 unsigned char newCellType = VTK_EMPTY_CELL;
203 unsigned char oldCellType = cell->GetCellType();
207 newCellType = VTK_WEDGE;
210 newCellType = VTK_HEXAHEDRON;
213 newCellType = VTK_POLYHEDRON;
214 // default : add new cell types to extrude here
216 if(newCellType == VTK_EMPTY_CELL)
219 double cellScalar = array->GetTuple1(cellId);
221 vtkIdList* oldIds = cell->GetPointIds();
222 int oldPtsNumber = oldIds->GetNumberOfIds();
223 int newPtsNumber = oldPtsNumber * 2;
224 newIds->SetNumberOfIds(newPtsNumber);
225 double coords[VTK_CELL_SIZE*3];
226 for(int ptid = 0; ptid < oldPtsNumber; ptid++)
228 psIn->GetPoint(oldIds->GetId(ptid), coords + 3*ptid);
230 for(int ptid = 0; ptid < oldPtsNumber; ptid++)
232 coords[(ptid+oldPtsNumber)*3+0] = coords[ptid*3+0] + cellScalar*dir[0];
233 coords[(ptid+oldPtsNumber)*3+1] = coords[ptid*3+1] + cellScalar*dir[1];
234 coords[(ptid+oldPtsNumber)*3+2] = coords[ptid*3+2] + cellScalar*dir[2];
237 bool minInitialized = false;
238 for(int ptid = 0; ptid < oldPtsNumber; ptid++)
240 neighbors->Initialize();
241 psIn->GetPointCells(oldIds->GetId(ptid), neighbors);
242 for(int neiCellIt = 0; neiCellIt < neighbors->GetNumberOfIds(); neiCellIt++)
244 vtkIdType neigCellId = neighbors->GetId(neiCellIt);
245 if(neigCellId == cellId)
247 double neighborScalar = array->GetTuple1(neigCellId);
248 if(neighborScalar != 0.0)
251 minScalar = neighborScalar;
253 minScalar = (neighborScalar < minScalar ? neighborScalar : minScalar);
254 minInitialized = true;
260 for(int ptid = 0; ptid < oldPtsNumber; ptid++)
264 coords[(ptid)*3+0] = coords[ptid*3+0] + minScalar*dir[0];
265 coords[(ptid)*3+1] = coords[ptid*3+1] + minScalar*dir[1];
266 coords[(ptid)*3+2] = coords[ptid*3+2] + minScalar*dir[2];
270 coords[(ptid+oldPtsNumber)*3+0] = coords[ptid*3+0] + minScalar*dir[0];
271 coords[(ptid+oldPtsNumber)*3+1] = coords[ptid*3+1] + minScalar*dir[1];
272 coords[(ptid+oldPtsNumber)*3+2] = coords[ptid*3+2] + minScalar*dir[2];
275 for(int ptid=0; ptid<newPtsNumber; ptid++)
277 vtkIdType newId = newPts->InsertNextPoint(coords + 3*ptid);
278 newIds->SetId(ptid, newId);
279 usgOut->GetPointData()->CopyData(psIn->GetPointData(),
280 oldIds->GetId(ptid % oldPtsNumber),
281 newIds->GetId(ptid));
284 if(newCellType == VTK_POLYHEDRON)
286 polyhedronIds->Initialize();
287 // in the polyhedron case, I will generate a quad for each edge
288 // of the input, and two capping faces
289 polyhedronIds->InsertNextId(2+oldPtsNumber);
290 // insert the bottom face
291 polyhedronIds->InsertNextId(oldPtsNumber);
292 for(int ptid = 0; ptid < oldPtsNumber; ptid++)
294 polyhedronIds->InsertNextId(newIds->GetId(ptid));
296 // insert the top face
297 polyhedronIds->InsertNextId(oldPtsNumber);
298 for(int ptid = oldPtsNumber; ptid < 2*oldPtsNumber; ptid++)
300 polyhedronIds->InsertNextId(newIds->GetId(ptid));
302 // insert the bording quads
303 for(int qid = 0; qid < oldPtsNumber; qid++)
305 polyhedronIds->InsertNextId(4);
306 polyhedronIds->InsertNextId(newIds->GetId(qid));
307 polyhedronIds->InsertNextId(newIds->GetId(qid+oldPtsNumber));
308 polyhedronIds->InsertNextId(newIds->GetId(qid+((oldPtsNumber+1)%oldPtsNumber)));
309 polyhedronIds->InsertNextId(newIds->GetId((qid+1)%oldPtsNumber));
311 newIds->Initialize();
312 for(int jj=0; jj<polyhedronIds->GetNumberOfIds(); jj++)
314 newIds->InsertNextId(polyhedronIds->GetId(jj));
317 newCellId = usgOut->InsertNextCell(newCellType, newIds);
318 usgOut->GetCellData()->CopyData(psIn->GetCellData(),
323 usgOut->GetFieldData()->ShallowCopy(psIn->GetFieldData());
330 void vtkElevationSurfaceFilter::ComputeDirection(vtkPointSet* psIn, double *outDir)
332 double tmp[2][3] = {{0, 0, 0}, {0, 0, 0}};
333 outDir[0] = outDir[1] = outDir[2] = 0;
335 vtkPoints* pts = psIn->GetPoints();
336 vtkSmartPointer<vtkGenericCell> cell = vtkSmartPointer<vtkGenericCell>::New();
338 for(vtkIdType cellId = 0; cellId < psIn->GetNumberOfCells(); cellId++)
340 psIn->GetCell(cellId, cell);
341 if(cell->GetCellDimension() != 2)
344 vtkIdList* ptIds = cell->GetPointIds();
345 for(int i=0; i<ptIds->GetNumberOfIds(); i++)
347 vtkIdType firstId = ptIds->GetId(i);
348 vtkIdType secondId = ptIds->GetId((i+1)%ptIds->GetNumberOfIds());
349 pts->GetPoint(firstId, tmp[0]);
350 pts->GetPoint(secondId, tmp[1]);
351 outDir[0] += tmp[0][1]*tmp[1][2] - tmp[0][2]*tmp[1][1];
352 outDir[1] += tmp[0][2]*tmp[1][0] - tmp[0][0]*tmp[1][2];
353 outDir[2] += tmp[0][0]*tmp[1][1] - tmp[0][1]*tmp[1][0];
358 void vtkElevationSurfaceFilter::PrintSelf(ostream& os, vtkIndent indent)
360 this->Superclass::PrintSelf(os, indent);
362 os << indent << "ScaleFactor : " << this->ScaleFactor << endl;