1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkHedgeHog.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #include "vtkHedgeHog.h"
16 
17 #include "vtkCellArray.h"
18 #include "vtkInformation.h"
19 #include "vtkInformationVector.h"
20 #include "vtkObjectFactory.h"
21 #include "vtkPointData.h"
22 #include "vtkPoints.h"
23 #include "vtkPolyData.h"
24 
25 vtkStandardNewMacro(vtkHedgeHog);
26 
vtkHedgeHog()27 vtkHedgeHog::vtkHedgeHog()
28 {
29   this->ScaleFactor = 1.0;
30   this->VectorMode = VTK_USE_VECTOR;
31   this->OutputPointsPrecision = vtkAlgorithm::DEFAULT_PRECISION;
32 }
33 
RequestData(vtkInformation * vtkNotUsed (request),vtkInformationVector ** inputVector,vtkInformationVector * outputVector)34 int vtkHedgeHog::RequestData(
35   vtkInformation *vtkNotUsed(request),
36   vtkInformationVector **inputVector,
37   vtkInformationVector *outputVector)
38 {
39   // get the info objects
40   vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
41   vtkInformation *outInfo = outputVector->GetInformationObject(0);
42 
43   // get the input and output
44   vtkDataSet *input = vtkDataSet::SafeDownCast(
45     inInfo->Get(vtkDataObject::DATA_OBJECT()));
46   vtkPolyData *output = vtkPolyData::SafeDownCast(
47     outInfo->Get(vtkDataObject::DATA_OBJECT()));
48 
49   vtkIdType numPts;
50   vtkPoints *newPts;
51   vtkPointData *pd;
52   vtkDataArray *inVectors;
53   vtkDataArray *inNormals;
54   vtkIdType ptId;
55   int i;
56   vtkIdType pts[2];
57   vtkCellArray *newLines;
58   double x[3], v[3];
59   double newX[3];
60   vtkPointData *outputPD = output->GetPointData();
61 
62   // Initialize
63   //
64   numPts = input->GetNumberOfPoints();
65   pd = input->GetPointData();
66   inVectors = pd->GetVectors();
67   if ( numPts < 1 )
68   {
69     vtkErrorMacro(<<"No input data");
70     return 1;
71   }
72   if ( !inVectors && this->VectorMode == VTK_USE_VECTOR)
73   {
74     vtkErrorMacro(<<"No vectors in input data");
75     return 1;
76   }
77 
78   inNormals = pd->GetNormals();
79   if ( !inNormals && this->VectorMode == VTK_USE_NORMAL)
80   {
81     vtkErrorMacro(<<"No normals in input data");
82     return 1;
83   }
84   outputPD->CopyAllocate(pd, 2*numPts);
85 
86   newPts = vtkPoints::New();
87 
88     // Set the desired precision for the points in the output.
89   if(this->OutputPointsPrecision == vtkAlgorithm::DEFAULT_PRECISION)
90   {
91     vtkPointSet *inputPointSet = vtkPointSet::SafeDownCast(input);
92     if(inputPointSet)
93     {
94       newPts->SetDataType(inputPointSet->GetPoints()->GetDataType());
95     }
96     else
97     {
98       newPts->SetDataType(VTK_FLOAT);
99     }
100   }
101   else if(this->OutputPointsPrecision == vtkAlgorithm::SINGLE_PRECISION)
102   {
103     newPts->SetDataType(VTK_FLOAT);
104   }
105   else if(this->OutputPointsPrecision == vtkAlgorithm::DOUBLE_PRECISION)
106   {
107     newPts->SetDataType(VTK_DOUBLE);
108   }
109 
110   newPts->SetNumberOfPoints(2*numPts);
111   newLines = vtkCellArray::New();
112   newLines->Allocate(newLines->EstimateSize(numPts,2));
113 
114   // Loop over all points, creating oriented line
115   //
116   for (ptId=0; ptId < numPts; ptId++)
117   {
118     if ( ! (ptId % 10000) ) //abort/progress
119     {
120         this->UpdateProgress(static_cast<double>(ptId)/numPts);
121       if (this->GetAbortExecute())
122       {
123         break;
124       }
125     }
126 
127     input->GetPoint(ptId, x);
128     if (this->VectorMode == VTK_USE_VECTOR)
129     {
130       inVectors->GetTuple(ptId, v);
131     }
132     else
133     {
134       inNormals->GetTuple(ptId, v);
135     }
136     for (i=0; i<3; i++)
137     {
138       newX[i] = x[i] + this->ScaleFactor * v[i];
139     }
140 
141     pts[0] = ptId;
142     pts[1] = ptId + numPts;
143 
144     newPts->SetPoint(pts[0], x);
145     newPts->SetPoint(pts[1], newX);
146 
147     newLines->InsertNextCell(2,pts);
148 
149     outputPD->CopyData(pd,ptId,pts[0]);
150     outputPD->CopyData(pd,ptId,pts[1]);
151   }
152 
153   // Update ourselves and release memory
154   //
155   output->SetPoints(newPts);
156   newPts->Delete();
157 
158   output->SetLines(newLines);
159   newLines->Delete();
160 
161   return 1;
162 }
163 
FillInputPortInformation(int,vtkInformation * info)164 int vtkHedgeHog::FillInputPortInformation(int, vtkInformation *info)
165 {
166   info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkDataSet");
167   return 1;
168 }
169 
PrintSelf(ostream & os,vtkIndent indent)170 void vtkHedgeHog::PrintSelf(ostream& os, vtkIndent indent)
171 {
172   this->Superclass::PrintSelf(os,indent);
173 
174   os << indent << "Scale Factor: " << this->ScaleFactor << "\n";
175   os << indent << "Orient Mode: " << (this->VectorMode == VTK_USE_VECTOR ?
176                                        "Orient by vector\n" : "Orient by normal\n");
177   os << indent << "Output Points Precision: " << this->OutputPointsPrecision << "\n";
178 }
179