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_ElnoDisassembleFilter.hxx"
21 #include "VISU_PipeLineUtils.hxx"
22 #include "VISU_ElnoMeshValue.hxx"
24 #include <vtkCellData.h>
25 #include <vtkInformation.h>
26 #include <vtkInformationVector.h>
27 #include <vtkObjectFactory.h>
28 #include <vtkPointData.h>
29 #include <vtkUnstructuredGrid.h>
30 #include <vtkPoints.h>
31 #include <vtkCellArray.h>
34 //----------------------------------------------------------------------------
35 vtkStandardNewMacro( VISU_ElnoDisassembleFilter );
38 //----------------------------------------------------------------------------
39 VISU_ElnoDisassembleFilter::VISU_ElnoDisassembleFilter()
41 this->SetInputArrayToProcess( 0, // idx
44 vtkDataObject::FIELD_ASSOCIATION_CELLS, // field association
45 "ELNO_FIELD" ); // name
47 this->SetInputArrayToProcess( 1, // idx
50 vtkDataObject::FIELD_ASSOCIATION_CELLS, // field association
51 "ELNO_COMPONENT_MAPPER" ); // name
53 this->myShrinkFactor = -0.999;
57 //----------------------------------------------------------------------------
58 VISU_ElnoDisassembleFilter::~VISU_ElnoDisassembleFilter()
62 //----------------------------------------------------------------------------
63 void VISU_ElnoDisassembleFilter::SetShrinkFactor( vtkFloatingPointType theValue )
65 if ( VISU::CheckIsSameValue( theValue, myShrinkFactor ) )
68 myShrinkFactor = theValue;
73 //----------------------------------------------------------------------------
74 vtkFloatingPointType VISU_ElnoDisassembleFilter::GetShrinkFactor()
76 return myShrinkFactor;
80 //----------------------------------------------------------------------------
83 //----------------------------------------------------------------------------
84 template < int points_type, int elno_type >
87 vtkUnstructuredGrid *myInput;
88 vtkUnstructuredGrid *myOutput;
89 vtkDataArray *myElnoDataArray;
90 vtkDataArray *myElnoDataMapper;
91 vtkFloatingPointType myShrinkFactor;
93 typedef typename VISU::TL::TEnum2VTKArrayType< points_type >::TResult TPointsDataArray;
94 typedef typename VISU::TL::TEnum2VTKBasicType< points_type >::TResult TPointsDataType;
96 typedef typename VISU::TL::TEnum2VTKArrayType< elno_type >::TResult TElnoDataArray;
97 typedef typename VISU::TL::TEnum2VTKBasicType< elno_type >::TResult TElnoDataType;
99 VISU::TGetElnoNodeData< elno_type > myGetElnoNodeData;
100 vtkCellArray *myConnectivity;
101 vtkPointData *myInputPointData;
102 vtkPointData *myOutputPointData;
103 TPointsDataArray *myInputPointsArray;
104 TPointsDataArray *myOutputPointsArray;
105 TElnoDataArray* myElnoFullDataArray;
106 TElnoDataArray* myElnoPartialDataArray;
107 TPointsDataArray *myElnoPointCoords;
108 vtkIntArray* myInputPointsMapper;
109 vtkIntArray* myOutputPointsMapper;
111 //----------------------------------------------------------------------------
112 TExecute2( vtkUnstructuredGrid *theInput,
113 vtkUnstructuredGrid *theOutput,
114 vtkDataArray *theElnoDataArray,
115 vtkDataArray *theElnoDataMapper,
116 vtkFloatingPointType theShrinkFactor )
117 : myGetElnoNodeData( theElnoDataArray, theElnoDataMapper )
118 , myInput( theInput )
119 , myOutput( theOutput )
120 , myElnoDataArray( theElnoDataArray )
121 , myElnoDataMapper( theElnoDataMapper )
122 , myShrinkFactor( theShrinkFactor )
124 myConnectivity = vtkCellArray::New();
125 myConnectivity->DeepCopy( theInput->GetCells() );
127 vtkPoints *anInputPoints = theInput->GetPoints();
128 vtkPoints *aPoints = anInputPoints->New( anInputPoints->GetDataType() );
129 vtkIdType aNbCells = myConnectivity->GetNumberOfCells();
130 vtkIdType aNbPoints = myConnectivity->GetNumberOfConnectivityEntries() - aNbCells;
131 aPoints->Allocate( aNbPoints );
133 myInputPointsArray = TPointsDataArray::SafeDownCast( anInputPoints->GetData() );
134 myOutputPointsArray = TPointsDataArray::SafeDownCast( aPoints->GetData() );
136 myInputPointData = theInput->GetPointData();
137 myOutputPointData = theOutput->GetPointData();
138 myOutputPointData->Allocate( aNbPoints );
140 vtkCellData *anInputCellData = theInput->GetCellData();
142 // To create a new copy of initial data for output
143 myElnoFullDataArray = TElnoDataArray::New();
144 myElnoFullDataArray->SetName( "VISU_FIELD" );
145 myElnoFullDataArray->SetNumberOfComponents( myGetElnoNodeData.getNbComp() );
146 myElnoFullDataArray->SetNumberOfTuples( aNbPoints );
148 // To create a new copy of partial initial data for output
149 myElnoPartialDataArray = TElnoDataArray::New();
150 // This partial data can be represented as in terms of vectors as scalars
151 if ( anInputCellData->GetVectors() != NULL )
152 myElnoPartialDataArray->SetNumberOfComponents( 3 );
154 myElnoPartialDataArray->SetNumberOfComponents( 1 );
155 myElnoPartialDataArray->SetNumberOfTuples( aNbPoints );
157 myElnoPointCoords = TPointsDataArray::New();
158 myElnoPointCoords->SetName( "ELNO_POINT_COORDS" );
159 myElnoPointCoords->SetNumberOfComponents( 3 );
160 myElnoPointCoords->SetNumberOfTuples( aNbPoints );
162 vtkDataArray* anArray = myInputPointData->GetArray( "VISU_POINTS_MAPPER" );
163 myInputPointsMapper = vtkIntArray::SafeDownCast( anArray );
165 myOutputPointsMapper = vtkIntArray::New();
166 myOutputPointsMapper->SetName( myInputPointsMapper->GetName() );
167 myOutputPointsMapper->SetNumberOfComponents( myInputPointsMapper->GetNumberOfComponents() );
168 myOutputPointsMapper->SetNumberOfTuples( aNbPoints );
170 if ( theShrinkFactor > 0.0 )
171 this->ShrinkExecute();
173 this->SimpleExecute();
175 theOutput->SetPoints( aPoints );
177 theOutput->SetCells( theInput->GetCellTypesArray(),
178 theInput->GetCellLocationsArray(),
181 myConnectivity->Delete();
183 vtkCellData *anOutputCellData = theOutput->GetCellData();
184 anOutputCellData->PassData( anInputCellData );
186 anOutputCellData->RemoveArray( "ELNO_COMPONENT_MAPPER" );
187 anOutputCellData->RemoveArray( "ELNO_FIELD" );
188 anOutputCellData->RemoveArray( "VISU_FIELD" );
189 anOutputCellData->SetVectors( NULL );
191 //anOutputPointData->PassData( anInputPointData );
193 myOutputPointData->AddArray( myElnoFullDataArray );
194 myElnoFullDataArray->Delete();
196 if ( anInputCellData->GetVectors() != NULL )
197 myOutputPointData->SetVectors( myElnoPartialDataArray );
199 myOutputPointData->SetScalars( myElnoPartialDataArray );
200 myElnoPartialDataArray->Delete();
202 myOutputPointData->AddArray( myElnoPointCoords );
203 myElnoPointCoords->Delete();
205 myOutputPointData->AddArray( myOutputPointsMapper );
206 myOutputPointsMapper->Delete();
209 //----------------------------------------------------------------------------
212 // To reserve a temproary value holder
213 vtkIdType aNbComp = std::max( 3, myGetElnoNodeData.getNbComp() );
214 std::vector< TElnoDataType > anElnoDataValues( aNbComp );
216 std::vector< int > anPointsMapperValues( myInputPointsMapper->GetNumberOfComponents() );
218 myConnectivity->InitTraversal();
219 vtkIdType aNbPts = 0, *aPts = 0;
220 for ( vtkIdType aCellId = 0; myConnectivity->GetNextCell( aNbPts, aPts ); aCellId++ ) {
221 for ( vtkIdType aPntId = 0; aPntId < aNbPts; aPntId++ ) {
222 TPointsDataType aCoords[ 3 ];
223 vtkIdType aCurrentPntId = aPts[ aPntId ];
224 myInputPointsArray->GetTupleValue( aCurrentPntId, aCoords );
226 aPts[ aPntId ] = myOutputPointsArray->InsertNextTupleValue( aCoords );
227 vtkIdType aNewPntId = aPts[ aPntId ];
229 myElnoPointCoords->SetTupleValue( aNewPntId, aCoords );
231 myOutputPointData->CopyData( myInputPointData, aCurrentPntId, aNewPntId );
233 TElnoDataType* anElnoData = myGetElnoNodeData( aCellId, aPntId );
234 myElnoFullDataArray->SetTupleValue( aNewPntId, anElnoData );
236 myElnoFullDataArray->GetTupleValue( aNewPntId, &anElnoDataValues[ 0 ] );
237 myElnoPartialDataArray->SetTupleValue( aNewPntId, &anElnoDataValues[ 0 ] );
239 myInputPointsMapper->GetTupleValue( aCurrentPntId, &anPointsMapperValues[ 0 ] );
240 myOutputPointsMapper->SetTupleValue( aNewPntId, &anPointsMapperValues[ 0 ] );
245 //----------------------------------------------------------------------------
248 // To reserve a temproary value holder
249 vtkIdType aNbComp = std::max( 3, myGetElnoNodeData.getNbComp() );
250 std::vector< TElnoDataType > anElnoDataValues( aNbComp );
252 std::vector< int > anPointsMapperValues( myInputPointsMapper->GetNumberOfComponents() );
254 myConnectivity->InitTraversal();
255 vtkIdType aNbPts = 0, *aPts = 0;
256 for ( vtkIdType aCellId = 0; myConnectivity->GetNextCell( aNbPts, aPts ); aCellId++ ) {
258 TPointsDataType aCenter[ 3 ] = { TPointsDataType(), TPointsDataType(), TPointsDataType() };
260 for ( vtkIdType aPntId = 0; aPntId < aNbPts; aPntId++ ) {
261 TPointsDataType aCoords[ 3 ];
262 myInputPointsArray->GetTupleValue( aPts[ aPntId ], aCoords );
264 aCenter[ 0 ] += aCoords[ 0 ];
265 aCenter[ 1 ] += aCoords[ 1 ];
266 aCenter[ 2 ] += aCoords[ 2 ];
269 aCenter[ 0 ] /= aNbPts;
270 aCenter[ 1 ] /= aNbPts;
271 aCenter[ 2 ] /= aNbPts;
273 for ( vtkIdType aPntId = 0; aPntId < aNbPts; aPntId++ ) {
274 TPointsDataType aCoords[ 3 ];
275 vtkIdType aCurrentPntId = aPts[ aPntId ];
276 myInputPointsArray->GetTupleValue( aCurrentPntId, aCoords );
278 TPointsDataType aNewCoords[ 3 ];
280 aNewCoords[ 0 ] = aCenter[ 0 ] +
281 TPointsDataType( myShrinkFactor * ( aCoords[ 0 ] - aCenter[ 0 ] ) );
282 aNewCoords[ 1 ] = aCenter[ 1 ] +
283 TPointsDataType( myShrinkFactor * ( aCoords[ 1 ] - aCenter[ 1 ] ) );
284 aNewCoords[ 2 ] = aCenter[ 2 ] +
285 TPointsDataType( myShrinkFactor * ( aCoords[ 2 ] - aCenter[ 2 ] ) );
287 aPts[ aPntId ] = myOutputPointsArray->InsertNextTupleValue( aNewCoords );
288 vtkIdType aNewPntId = aPts[ aPntId ];
290 myElnoPointCoords->SetTupleValue( aNewPntId, aCoords );
292 myOutputPointData->CopyData( myInputPointData, aCurrentPntId, aNewPntId );
294 TElnoDataType* anElnoData = myGetElnoNodeData( aCellId, aPntId );
295 myElnoFullDataArray->SetTupleValue( aNewPntId, anElnoData );
297 myElnoFullDataArray->GetTupleValue( aNewPntId, &anElnoDataValues[ 0 ] );
298 myElnoPartialDataArray->SetTupleValue( aNewPntId, &anElnoDataValues[ 0 ] );
300 myInputPointsMapper->GetTupleValue( aCurrentPntId, &anPointsMapperValues[ 0 ] );
301 myOutputPointsMapper->SetTupleValue( aNewPntId, &anPointsMapperValues[ 0 ] );
308 //----------------------------------------------------------------------------
309 template < int points_type, int elno_type >
310 int Execute2( vtkUnstructuredGrid *theInput,
311 vtkUnstructuredGrid *theOutput,
312 vtkDataArray *theElnoDataArray,
313 vtkDataArray *theElnoDataMapper,
314 vtkFloatingPointType theShrinkFactor )
316 TExecute2< points_type, elno_type >( theInput,
326 //----------------------------------------------------------------------------
327 template < int points_type >
328 int Execute( vtkUnstructuredGrid *theInput,
329 vtkUnstructuredGrid *theOutput,
330 vtkDataArray *theElnoDataArray,
331 vtkDataArray *theElnoDataMapper,
332 vtkFloatingPointType theShrinkFactor )
334 switch( theElnoDataArray->GetDataType() ){
336 return Execute2< points_type, VTK_DOUBLE >
337 ( theInput, theOutput, theElnoDataArray, theElnoDataMapper, theShrinkFactor );
339 return Execute2< points_type, VTK_FLOAT >
340 ( theInput, theOutput, theElnoDataArray, theElnoDataMapper, theShrinkFactor );
342 return Execute2< points_type, VTK_INT >
343 ( theInput, theOutput, theElnoDataArray, theElnoDataMapper, theShrinkFactor );
345 return Execute2< points_type, VTK_LONG >
346 ( theInput, theOutput, theElnoDataArray, theElnoDataMapper, theShrinkFactor );
355 //----------------------------------------------------------------------------
359 //----------------------------------------------------------------------------
360 int VISU_ElnoDisassembleFilter::RequestData( vtkInformation *vtkNotUsed(request),
361 vtkInformationVector **inputVector,
362 vtkInformationVector *outputVector )
364 // get the info objects
365 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
366 vtkInformation *outInfo = outputVector->GetInformationObject(0);
368 // get the input and ouptut
369 vtkUnstructuredGrid *anInput =
370 vtkUnstructuredGrid::SafeDownCast( inInfo->Get( vtkDataObject::DATA_OBJECT() ) );
371 vtkUnstructuredGrid *anOutput =
372 vtkUnstructuredGrid::SafeDownCast( outInfo->Get( vtkDataObject::DATA_OBJECT() ) );
374 vtkDataArray *anElnoDataArray = this->GetInputArrayToProcess( 0, inputVector );
375 vtkDataArray *anElnoDataMapper = this->GetInputArrayToProcess( 1, inputVector );
377 if ( !anElnoDataArray ) {
378 anOutput->ShallowCopy( anInput );
382 vtkPoints *aPoints = anInput->GetPoints();
383 switch( aPoints->GetDataType() ){
385 return ::Execute< VTK_DOUBLE >( anInput, anOutput, anElnoDataArray, anElnoDataMapper, myShrinkFactor );
387 return ::Execute< VTK_FLOAT >( anInput, anOutput, anElnoDataArray, anElnoDataMapper, myShrinkFactor );
389 return ::Execute< VTK_INT >( anInput, anOutput, anElnoDataArray, anElnoDataMapper, myShrinkFactor );
391 return ::Execute< VTK_LONG >( anInput, anOutput, anElnoDataArray, anElnoDataMapper, myShrinkFactor );
400 //----------------------------------------------------------------------------