1 // Copyright (C) 2007-2010 CEA/DEN, EDF R&D, OPEN CASCADE
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 "VISU_StreamLine.hxx"
22 #include "vtkCellArray.h"
23 #include "vtkDataSet.h"
24 #include "vtkFloatArray.h"
25 #include "vtkInformation.h"
26 #include "vtkInformationVector.h"
28 #include "vtkObjectFactory.h"
29 #include "vtkPointData.h"
30 #include "vtkPolyData.h"
31 #include "vtkPolyLine.h"
33 vtkCxxRevisionMacro(VISU_StreamLine, "$Revision$");
34 vtkStandardNewMacro(VISU_StreamLine);
36 // Construct object with step size set to 1.0.
37 VISU_StreamLine::VISU_StreamLine()
39 this->StepLength = 1.0;
40 this->NumberOfStreamers = 0;
43 int VISU_StreamLine::RequestData(
45 vtkInformationVector **inputVector,
46 vtkInformationVector *outputVector)
48 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
49 vtkInformation *outInfo = outputVector->GetInformationObject(0);
50 vtkInformation *sourceInfo = inputVector[1]->GetInformationObject(0);
52 vtkDataSet *input = vtkDataSet::SafeDownCast(
53 inInfo->Get(vtkDataObject::DATA_OBJECT()));
54 vtkPolyData *output = vtkPolyData::SafeDownCast(
55 outInfo->Get(vtkDataObject::DATA_OBJECT()));
56 vtkDataSet *source = 0;
59 source = vtkDataSet::SafeDownCast(
60 sourceInfo->Get(vtkDataObject::DATA_OBJECT()));
63 vtkStreamer::StreamPoint *sPrev, *sPtr;
65 vtkFloatArray *newVectors;
66 vtkFloatArray *newScalars=NULL;
67 vtkCellArray *newLines;
68 vtkIdType ptId, i, id;
71 double tOffset, x[3], v[3], s, r;
73 vtkPolyLine* lineNormalGenerator = NULL;
74 vtkFloatArray* normals = NULL;
75 vtkFloatArray* rotation = 0;
77 this->SavePointInterval = this->StepLength;
78 this->VISU_Streamer::Integrate(input, source);
79 if ( this->NumberOfStreamers <= 0 ) {return 1;}
81 pts = vtkIdList::New();
85 // Convert streamer into lines. Lines may be dashed.
87 newPts = vtkPoints::New();
88 newPts->Allocate(1000);
89 newVectors = vtkFloatArray::New();
90 newVectors->SetNumberOfComponents(3);
91 newVectors->Allocate(3000);
92 if ( this->Vorticity )
94 lineNormalGenerator = vtkPolyLine::New();
95 normals = vtkFloatArray::New();
96 normals->SetNumberOfComponents(3);
97 normals->Allocate(3000);
98 rotation = vtkFloatArray::New();
99 rotation->SetNumberOfComponents(1);
100 rotation->Allocate(1000);
101 rotation->SetName("Thetas");
102 output->GetPointData()->AddArray(rotation);
105 if ( input->GetPointData()->GetScalars() || this->SpeedScalars
106 || this->OrientationScalars)
108 newScalars = vtkFloatArray::New();
109 newScalars->Allocate(1000);
111 newLines = vtkCellArray::New();
112 newLines->Allocate(newLines->EstimateSize(2*this->NumberOfStreamers,
115 // Loop over all streamers generating points
117 for (ptId=0; ptId < this->NumberOfStreamers; ptId++)
119 if ( this->Streamers[ptId].GetNumberOfPoints() < 2 )
123 sPrev = this->Streamers[ptId].GetStreamPoint(0);
124 sPtr = this->Streamers[ptId].GetStreamPoint(1);
126 if ( this->Streamers[ptId].GetNumberOfPoints() == 2 && sPtr->cellId >= 0 )
134 i < this->Streamers[ptId].GetNumberOfPoints() && sPtr->cellId >= 0;
135 i++, sPrev=sPtr, sPtr=this->Streamers[ptId].GetStreamPoint(i) )
138 // Create points for line
140 while ( tOffset >= sPrev->t && tOffset < sPtr->t )
142 r = (tOffset - sPrev->t) / (sPtr->t - sPrev->t);
146 x[j] = sPrev->x[j] + r * (sPtr->x[j] - sPrev->x[j]);
147 v[j] = sPrev->v[j] + r * (sPtr->v[j] - sPrev->v[j]);
151 id = newPts->InsertNextPoint(x);
152 pts->InsertNextId(id);
153 newVectors->InsertTuple(id,v);
157 s = sPrev->s + r * (sPtr->s - sPrev->s);
158 newScalars->InsertTuple(id,&s);
161 if ( this->Vorticity )
163 // Store the rotation values. Used after all the streamlines
165 theta = sPrev->theta + r * (sPtr->theta - sPrev->theta);
166 rotation->InsertTuple(id, &theta);
169 tOffset += this->StepLength;
172 } //for this streamer
174 if ( pts->GetNumberOfIds() > 1 )
176 newLines->InsertNextCell(pts);
179 } //for all streamers
181 vtkDebugMacro(<<"Created " << newPts->GetNumberOfPoints() << " points, "
182 << newLines->GetNumberOfCells() << " lines");
186 // Rotate the normal vectors with stream vorticity
188 vtkIdType *linePts=0;
189 double normal[3], local1[3], local2[3], length, costheta, sintheta;
191 lineNormalGenerator->GenerateSlidingNormals(newPts,newLines,normals);
193 // Loop over all lines, from the above code we are know that each line
194 // will have at least two points and that no points will be shared
195 // between lines. It is important to loop over the points used by the
196 // lines because newPts may actually contain points that are not used by
197 // any lines. The normals are only calculated for points that are used
198 // in lines so referencing normals for all points can lead to UMRs
199 for (newLines->InitTraversal(); newLines->GetNextCell(nPts,linePts); )
201 for(i=0; i<nPts; i++)
203 normals->GetTuple(linePts[i], normal);
204 newVectors->GetTuple(linePts[i], v);
205 // obtain two unit orthogonal vectors on the plane perpendicular to
209 local1[j] = normal[j];
211 length = vtkMath::Normalize(local1);
212 vtkMath::Cross(local1, v, local2);
213 vtkMath::Normalize(local2);
214 // Rotate the normal with theta
215 rotation->GetTuple(linePts[i], &theta);
216 costheta = cos(theta);
217 sintheta = sin(theta);
220 normal[j] = length* (costheta*local1[j] + sintheta*local2[j]);
222 normals->SetTuple(linePts[i], normal);
225 output->GetPointData()->SetNormals(normals);
227 lineNormalGenerator->Delete();
231 output->SetPoints(newPts);
234 output->GetPointData()->SetVectors(newVectors);
235 newVectors->Delete();
239 int idx = output->GetPointData()->AddArray(newScalars);
240 output->GetPointData()->SetActiveAttribute(idx, vtkDataSetAttributes::SCALARS);
241 newScalars->Delete();
245 output->SetLines(newLines);
248 // Delete the streamers since they are no longer needed
249 delete[] this->Streamers;
251 this->NumberOfStreamers = 0;
258 void VISU_StreamLine::PrintSelf(ostream& os, vtkIndent indent)
260 this->Superclass::PrintSelf(os,indent);
262 os << indent << "Step Length: " << this->StepLength << "\n";