Salome HOME
Fix for Bug IPAL8945
[modules/visu.git] / src / PIPELINE / VISU_GaussPointsPL.cxx
1 //  VISU OBJECT : interactive object for VISU entities implementation
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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
21 //
22 //
23 //
24 // File:    VISU_GaussPoints.cxx
25 // Author:  Alexey PETROV
26 // Module : VISU
27
28
29 #include "VISU_GaussPointsPL.hxx"
30 #include "VISU_DeformedShapePL.hxx"
31 #include "VISU_PipeLineUtils.hxx"
32 #include "SALOME_ExtractGeometry.h"
33 #include "VISU_DeformedShapePL.hxx"
34 #include "VISU_OpenGLPointSpriteMapper.hxx"
35 #include "VTKViewer_PassThroughFilter.h"
36
37 #include <vtkPointSource.h>
38 #include <vtkElevationFilter.h>
39 #include <vtkImageGaussianSource.h>
40 #include <vtkXMLImageDataReader.h>
41 #include <vtkGeometryFilter.h>
42 #include <vtkImageData.h>
43 #include <vtkWarpVector.h>
44 #include <vtkGlyph3D.h>
45 #include <vtkSphereSource.h>
46
47 //----------------------------------------------------------------------------
48 vtkStandardNewMacro(VISU_GaussPointsPL);
49
50 //----------------------------------------------------------------------------
51 VISU_GaussPointsPL
52 ::VISU_GaussPointsPL():
53   myIsDeformed(false),
54   myScaleFactor(0.0),
55   myResolution( 8 ),
56   myMagnificationIncrement(2)
57 {
58   myExtractGeometry->SetExtractInside(0);
59
60   myPSMapper = VISU_OpenGLPointSpriteMapper::New();
61   myPSMapper->SetColorModeToMapScalars();
62   myPSMapper->ScalarVisibilityOn();
63
64   myGeomFilter = vtkGeometryFilter::New();
65
66   myWarpVector = vtkWarpVector::New();
67   myCellDataToPointData = vtkCellDataToPointData::New();
68   myCellDataToPointData->SetPassCellData(true);
69
70   myGlyph = vtkGlyph3D::New();
71   myGlyph->SetScaleModeToScaleByScalar();
72   myGlyph->SetColorModeToColorByScalar();
73   myGlyph->ClampingOn();
74
75   myExtractor->SetInput( myExtractGeometry->GetOutput() );
76   myFieldTransform->SetInput( myExtractor->GetOutput() );
77
78   myCellDataToPointData->SetInput( myFieldTransform->GetUnstructuredGridOutput() );
79
80   mySphereSource = vtkSphereSource::New();
81   myGlyph->SetSource( mySphereSource->GetOutput() );
82
83   for(int i = 0; i < 2; i++)
84     myPassFilter.push_back(VTKViewer_PassThroughFilter::New());
85 }
86
87
88 //----------------------------------------------------------------------------
89 VISU_GaussPointsPL
90 ::~VISU_GaussPointsPL()
91 {
92   if (this->myPSMapper)
93   {
94     this->myPSMapper->Delete();
95     this->myPSMapper = NULL;
96   }
97   if (this->myGeomFilter)
98   {
99     this->myGeomFilter->Delete();
100     this->myGeomFilter = NULL;
101   }
102
103   myWarpVector->Delete();
104
105   myCellDataToPointData->Delete();
106
107   myGlyph->Delete();
108
109   mySphereSource->Delete();
110
111   for(int i = 0; i < 2; i++)
112     myPassFilter[i]->Delete();
113 }
114
115
116 //----------------------------------------------------------------------------
117 void
118 CopyGlyph( vtkGlyph3D* source, vtkGlyph3D* dest )
119 {
120   dest->SetRange( source->GetRange() );
121   dest->SetScaling( source->GetScaling() );
122   dest->SetClamping( source->GetClamping() );
123   dest->SetScaleMode( source->GetScaleMode() );
124   dest->SetColorMode( source->GetColorMode() );
125   dest->SetScaleFactor( source->GetScaleFactor() );
126 }
127
128
129 //----------------------------------------------------------------------------
130 void
131 VISU_GaussPointsPL
132 ::ShallowCopy(VISU_PipeLine *thePipeLine)
133 {
134   if(VISU_GaussPointsPL *aPipeLine = dynamic_cast<VISU_GaussPointsPL*>(thePipeLine)){
135     // To restore mapper input from pipeline
136     vtkPolyData* aDatsSet = myPSMapper->GetInput();
137     myPSMapper->ShallowCopy(aPipeLine->GetPSMapper());
138     myPSMapper->SetInput(aDatsSet);
139
140     SetPrimitiveType(aPipeLine->GetPrimitiveType());
141     SetBicolor(aPipeLine->GetBicolor());
142     SetClamp(aPipeLine->GetClamp());
143     SetSize(aPipeLine->GetSize());
144     SetMinSize(aPipeLine->GetMinSize());
145     SetMaxSize(aPipeLine->GetMaxSize());
146     SetMagnification(aPipeLine->GetMagnification());
147     SetMagnificationIncrement(aPipeLine->GetMagnificationIncrement());
148     SetAlphaThreshold(aPipeLine->GetAlphaThreshold());
149     SetResolution(aPipeLine->GetResolution());
150
151     SetIsDeformed( aPipeLine->GetIsDeformed() );
152     SetScale( aPipeLine->GetScale() );
153
154     mySphereSource->SetRadius( aPipeLine->mySphereSource->GetRadius() );
155     CopyGlyph( aPipeLine->myGlyph, this->myGlyph );
156   }
157   Superclass::ShallowCopy(thePipeLine);
158 }
159
160
161 //----------------------------------------------------------------------------
162 VISU_PipeLine::TMapper* 
163 VISU_GaussPointsPL
164 ::GetMapper()
165 {
166   return GetPSMapper();
167 }
168
169 VISU_OpenGLPointSpriteMapper* 
170 VISU_GaussPointsPL
171 ::GetPSMapper()
172 {
173   if(GetInput()){
174     if(!myPSMapper->GetInput()){
175       GetInput2()->Update();
176       Build();
177       Init();
178     }
179     myPSMapper->Update();
180   }
181   return myPSMapper;
182 }
183
184 vtkDataSet* 
185 VISU_GaussPointsPL
186 ::GetPickableDataSet()
187 {
188   return myGeomFilter->GetOutput();
189 }
190
191 //----------------------------------------------------------------------------
192 void
193 VISU_GaussPointsPL
194 ::Init()
195 {
196   Superclass::Init();
197
198   vtkDataSet* aDataSet = GetParentMesh();
199   float aScaleFactor = VISU_DeformedShapePL::GetScaleFactor( aDataSet );
200
201   float* aScalarRange = GetScalarRange();
202   static double EPS = 1.0 / VTK_LARGE_FLOAT;
203   if(fabs(aScalarRange[1]) > EPS)
204     SetScale( aScaleFactor / aScalarRange[1] );
205   else
206     SetScale(0.0);
207
208   // Deformed Shape
209   myPassFilter[0]->SetInput(myCellDataToPointData->GetUnstructuredGridOutput());
210
211   myGeomFilter->SetInput( myPassFilter[0]->GetOutput() );
212
213   // Geometrical Sphere
214   myPassFilter[1]->SetInput(myGeomFilter->GetOutput());
215
216   myPSMapper->SetInput( myPassFilter[1]->GetPolyDataOutput() );
217 }
218
219 //----------------------------------------------------------------------------
220 void
221 VISU_GaussPointsPL
222 ::Build()
223 {
224 }
225
226 //----------------------------------------------------------------------------
227 void
228 VISU_GaussPointsPL
229 ::Update()
230 {
231   //cout << "VISU_GaussPointsPL::Update()" << endl;
232   float* aScalarRange = GetScalarRange();
233   mySourceScalarRange[0] = aScalarRange[0];
234   mySourceScalarRange[1] = aScalarRange[1];
235   myDeltaScalarRange = aScalarRange[1] - aScalarRange[0];
236
237   SetAverageCellSize( VISU_DeformedShapePL::GetScaleFactor( GetParentMesh() ) );
238
239   vtkMapper* aMapper = GetMapper();
240   vtkDataSet* aDataSet = aMapper->GetInput();
241   vtkCellData* aCellData = aDataSet->GetCellData();
242   myScalarArray = aCellData->GetScalars();
243
244   myPSMapper->SetLookupTable( myMapperTable );
245   myPSMapper->SetScalarRange( aScalarRange );
246
247   this->UpdateGlyph();
248
249   VISU_ScalarMapPL::Update();
250 }
251
252 //----------------------------------------------------------------------------
253 void
254 VISU_GaussPointsPL
255 ::UpdateGlyph()
256 {
257   //cout << "VISU_GaussPointsPL::UpdateGlyph()" << endl;
258
259   float* aScalarRange = GetScalarRange();
260
261   if( myPSMapper->GetPointSpriteMode() == 0 ) // Results
262   {
263     //cout << "Results" << endl;
264     myGlyph->ClampingOn();
265     myGlyph->SetScaleModeToScaleByScalar();
266     myGlyph->SetColorModeToColorByScalar();
267
268     float aRange = 0;
269     float aMinSize = GetMinSize();
270     float aMaxSize = GetMaxSize();
271     if( fabs( aMaxSize - aMinSize ) > 0.0001 )
272       aRange = ( aScalarRange[1] - aScalarRange[0] ) / ( aMaxSize - aMinSize );
273     float aMinRange = aScalarRange[0] - aMinSize * aRange;
274     float aMaxRange = aMinRange + aRange;
275
276     myGlyph->SetRange( aMinRange, aMaxRange );
277     myGlyph->SetScaleFactor( 1.0 );
278   }
279   else if( myPSMapper->GetPointSpriteMode() == 1 ) // Geometry
280   {
281     //cout << "Geometry" << endl;
282     myGlyph->ClampingOff();
283     myGlyph->SetScaleModeToDataScalingOff();
284     myGlyph->SetColorModeToColorByScale();
285
286     myGlyph->SetScaleFactor( GetSize() );
287   }
288   else if( myPSMapper->GetPointSpriteMode() == 2 ) // Outside
289   {
290     //cout << "Outside" << endl;
291     myGlyph->ClampingOff();
292     myGlyph->SetScaleModeToDataScalingOff();
293     myGlyph->SetColorModeToColorByScalar();
294
295     myGlyph->SetScaleFactor( GetSize() );
296   }
297
298   mySphereSource->SetRadius( GetMagnification() * GetAverageCellSize() / 2. );
299 }
300
301 //----------------------------------------------------------------------------
302 VISU::TGaussPointID 
303 VISU_GaussPointsPL
304 ::GetObjID(vtkIdType theID) const
305 {
306   return myGaussPtsIDMapper->GetObjID(theID);
307 }
308
309 float* 
310 VISU_GaussPointsPL
311 ::GetNodeCoord(int theObjID)
312 {
313   vtkIdType anID = GetNodeVTKID(theObjID);
314   vtkDataSet* aDataSet = myGeomFilter->GetInput();
315   return aDataSet->GetPoint(anID);
316 }
317
318 void
319 VISU_GaussPointsPL
320 ::SetGaussPtsIDMapper(const VISU::PGaussPtsIDMapper& theGaussPtsIDMapper)
321 {
322   myGaussPtsIDMapper = theGaussPtsIDMapper;
323   SetIDMapper(myGaussPtsIDMapper);
324 }
325
326 const VISU::PGaussPtsIDMapper&  
327 VISU_GaussPointsPL
328 ::GetGaussPtsIDMapper() const
329 {
330   return myGaussPtsIDMapper;
331 }
332
333 VISU::TVTKOutput*  
334 VISU_GaussPointsPL
335 ::GetParentMesh() const
336 {
337   VISU::TNamedIDMapper* aNamedIDMapper = myGaussPtsIDMapper->GetParent();
338   return aNamedIDMapper->GetVTKOutput();
339 }
340
341 //----------------------------------------------------------------------------
342 void
343 VISU_GaussPointsPL
344 ::SetIsDeformed( bool theIsDeformed )
345 {
346   if( theIsDeformed )
347   {
348     myWarpVector->SetInput( myCellDataToPointData->GetUnstructuredGridOutput() );
349     myPassFilter[0]->SetInput(myWarpVector->GetOutput());
350   }
351   else
352     myPassFilter[0]->SetInput(myCellDataToPointData->GetUnstructuredGridOutput());
353
354   myIsDeformed = theIsDeformed;
355
356   Modified();
357 }
358
359 //----------------------------------------------------------------------------
360 bool
361 VISU_GaussPointsPL
362 ::GetIsDeformed() const
363 {
364   return myIsDeformed;
365 }
366
367 //----------------------------------------------------------------------------
368 void
369 VISU_GaussPointsPL
370 ::SetBicolor(bool theBicolor)
371 {
372   if(GetBicolor() == theBicolor)
373     return;
374
375   myMapperTable->SetBicolor( theBicolor );
376   myBarTable->SetBicolor( theBicolor );
377
378   Modified();
379 }
380
381 //----------------------------------------------------------------------------
382 bool
383 VISU_GaussPointsPL
384 ::GetBicolor()
385 {
386   return myMapperTable->GetBicolor();
387 }
388
389 //----------------------------------------------------------------------------
390 void
391 VISU_GaussPointsPL
392 ::SetIsColored(bool theIsColored)
393 {
394   myPSMapper->SetPointSpriteMode( theIsColored ? 0 : 1 ); // Results / Geometry
395   Modified();
396 }
397
398 //----------------------------------------------------------------------------
399 void
400 VISU_GaussPointsPL
401 ::SetPrimitiveType(int thePrimitiveType)
402 {
403   if( thePrimitiveType == VISU_OpenGLPointSpriteMapper::GeomSphere )
404   {
405     myGlyph->SetInput( myGeomFilter->GetOutput() );
406     myPassFilter[1]->SetInput(myGlyph->GetOutput());
407   }
408   else
409     myPassFilter[1]->SetInput(myGeomFilter->GetOutput());
410
411   myPSMapper->SetPrimitiveType( thePrimitiveType );
412
413   Modified();
414 }
415
416 //----------------------------------------------------------------------------
417 int
418 VISU_GaussPointsPL
419 ::GetPrimitiveType()
420 {
421   return myPSMapper->GetPrimitiveType();
422 }
423
424 //----------------------------------------------------------------------------
425 float
426 VISU_GaussPointsPL
427 ::GetMaximumSupportedSize()
428 {
429   return myPSMapper->GetMaximumSupportedSize();
430 }
431
432 //----------------------------------------------------------------------------
433 void
434 VISU_GaussPointsPL
435 ::SetClamp(float theClamp)
436 {
437   myPSMapper->SetPointSpriteClamp( theClamp );
438   Modified();
439 }
440
441 //----------------------------------------------------------------------------
442 float
443 VISU_GaussPointsPL
444 ::GetClamp()
445 {
446   return myPSMapper->GetPointSpriteClamp();
447 }
448
449 //----------------------------------------------------------------------------
450 void
451 VISU_GaussPointsPL
452 ::SetSize(float theSize)
453 {
454   myPSMapper->SetPointSpriteSize( theSize );
455   Modified();
456 }
457
458 //----------------------------------------------------------------------------
459 float
460 VISU_GaussPointsPL
461 ::GetSize()
462 {
463   return myPSMapper->GetPointSpriteSize();
464 }
465
466 //----------------------------------------------------------------------------
467 void
468 VISU_GaussPointsPL
469 ::SetMinSize(float theMinSize)
470 {
471   myPSMapper->SetPointSpriteMinSize( theMinSize );
472   Modified();
473 }
474
475 //----------------------------------------------------------------------------
476 float
477 VISU_GaussPointsPL
478 ::GetMinSize()
479 {
480   return myPSMapper->GetPointSpriteMinSize();
481 }
482
483 //----------------------------------------------------------------------------
484 void
485 VISU_GaussPointsPL
486 ::SetMaxSize(float theMaxSize)
487 {
488   myPSMapper->SetPointSpriteMaxSize( theMaxSize );
489   Modified();
490 }
491
492 //----------------------------------------------------------------------------
493 float
494 VISU_GaussPointsPL
495 ::GetMaxSize()
496 {
497   return myPSMapper->GetPointSpriteMaxSize();
498 }
499
500 //----------------------------------------------------------------------------
501 void
502 VISU_GaussPointsPL
503 ::SetMagnification(float theMagnification)
504 {
505   myPSMapper->SetPointSpriteMagnification( theMagnification );
506   Modified();
507 }
508
509 //----------------------------------------------------------------------------
510 float
511 VISU_GaussPointsPL
512 ::GetMagnification()
513 {
514   return myPSMapper->GetPointSpriteMagnification();
515 }
516
517 //----------------------------------------------------------------------------
518 void
519 VISU_GaussPointsPL
520 ::SetMagnificationIncrement(float theIncrement)
521 {
522   myMagnificationIncrement = theIncrement;
523 }
524
525 //----------------------------------------------------------------------------
526 void
527 VISU_GaussPointsPL
528 ::SetAlphaThreshold(float theAlphaThreshold)
529 {
530   myPSMapper->SetPointSpriteAlphaThreshold( theAlphaThreshold );
531   Modified();
532 }
533
534 //----------------------------------------------------------------------------
535 float
536 VISU_GaussPointsPL
537 ::GetAlphaThreshold()
538 {
539   return myPSMapper->GetPointSpriteAlphaThreshold();
540 }
541
542 //----------------------------------------------------------------------------
543 void
544 VISU_GaussPointsPL
545 ::SetResolution(int theResolution)
546 {
547   myResolution = theResolution;
548   mySphereSource->SetThetaResolution( myResolution );
549   mySphereSource->SetPhiResolution( myResolution );
550 }
551
552 //----------------------------------------------------------------------------
553 void
554 VISU_GaussPointsPL
555 ::ChangeMagnification( bool up )
556 {
557   float anIncrement = up ? myMagnificationIncrement : 1.0 / myMagnificationIncrement;
558   SetMagnification( GetMagnification() * anIncrement );
559 }
560
561 //----------------------------------------------------------------------------
562 float
563 VISU_GaussPointsPL
564 ::GetPointSize(vtkIdType theID, vtkDataArray* theScalarArray)
565 {
566   float aMaxSize = GetAverageCellSize() * GetMaxSize();
567   float aMinSize = GetAverageCellSize() * GetMinSize();
568   float aDelta = aMaxSize - aMinSize;
569   float aVal = theScalarArray->GetTuple1(theID);
570
571   return aMinSize + aDelta*(aVal - mySourceScalarRange[0])/myDeltaScalarRange;
572 }
573
574 //----------------------------------------------------------------------------
575 float
576 VISU_GaussPointsPL
577 ::GetMaxPointSize()
578 {
579   return GetAverageCellSize() * GetMaxSize();
580 }
581
582 //----------------------------------------------------------------------------
583 float
584 VISU_GaussPointsPL
585 ::GetPointSize(vtkIdType theID)
586 {
587   vtkMapper* aMapper = GetMapper();
588   vtkDataSet* aDataSet = aMapper->GetInput();
589   vtkCellData* aCellData = aDataSet->GetCellData();
590   vtkDataArray* aScalarArray = aCellData->GetScalars();
591   return GetPointSize(theID,aScalarArray);
592 }
593
594 //----------------------------------------------------------------------------
595 void
596 VISU_GaussPointsPL
597 ::SetAverageCellSize(float theAverageCellSize)
598 {
599   myPSMapper->SetAverageCellSize( theAverageCellSize );
600   Modified();
601 }
602
603 //----------------------------------------------------------------------------
604 float
605 VISU_GaussPointsPL
606 ::GetAverageCellSize()
607 {
608   return myPSMapper->GetAverageCellSize();
609 }
610
611 //----------------------------------------------------------------------------
612 void
613 VISU_GaussPointsPL
614 ::SetImageData(vtkImageData* theImageData)
615 {
616   myPSMapper->SetImageData( theImageData );
617 }
618
619 //----------------------------------------------------------------------------
620 vtkSmartPointer<vtkImageData>
621 VISU_GaussPointsPL
622 ::MakeTexture( const char* theMainTexture, 
623                const char* theAlphaTexture )
624 {
625   if( !theMainTexture || !theAlphaTexture )
626     return 0;
627
628   vtkXMLImageDataReader* aMainReader = vtkXMLImageDataReader::New();
629   vtkXMLImageDataReader* anAlphaReader = vtkXMLImageDataReader::New();
630
631   aMainReader->SetFileName( theMainTexture );
632   anAlphaReader->SetFileName( theAlphaTexture );
633
634   aMainReader->Update();
635   anAlphaReader->Update();
636
637   vtkImageData* aMainImageData = aMainReader->GetOutput();
638   vtkImageData* anAlphaImageData = anAlphaReader->GetOutput();
639
640   int* aMainImageSize = aMainImageData->GetDimensions();
641   int* anAlphaImageSize = anAlphaImageData->GetDimensions();
642   if(aMainImageSize[0] != anAlphaImageSize[0] || aMainImageSize[1] != anAlphaImageSize[1])
643     return NULL;
644
645   vtkSmartPointer<vtkImageData> aCompositeImageData = vtkImageData::New();
646   aCompositeImageData->Delete();
647
648   int aNbCompositeComponents = 4;
649   aCompositeImageData->SetDimensions(aMainImageSize);
650   aCompositeImageData->SetScalarTypeToUnsignedChar();        
651   aCompositeImageData->SetNumberOfScalarComponents(aNbCompositeComponents);
652   aCompositeImageData->AllocateScalars();
653
654   unsigned char* aMainDataPtr = (unsigned char*)aMainImageData->GetScalarPointer();
655   unsigned char* anAlphaDataPtr = (unsigned char*)anAlphaImageData->GetScalarPointer();
656   unsigned char *aCompositeDataPtr = (unsigned char * )aCompositeImageData->GetScalarPointer();
657
658   int aNbMainComponents = aMainImageData->GetNumberOfScalarComponents();
659   int aNbAlphaComponents = anAlphaImageData->GetNumberOfScalarComponents();
660   int aCompositeSize = aMainImageSize[0] * aMainImageSize[1] * aNbCompositeComponents;
661   
662   int aMainId = 0, anAlphaId = 0, aCompositeId = 0;
663   for(; aCompositeId < aCompositeSize;)
664   {
665     aCompositeDataPtr[aCompositeId] = aMainDataPtr[aMainId];
666     aCompositeDataPtr[aCompositeId + 1] = aMainDataPtr[aMainId + 1];
667     aCompositeDataPtr[aCompositeId + 2] = aMainDataPtr[aMainId + 2];
668     aCompositeDataPtr[aCompositeId + 3] = anAlphaDataPtr[anAlphaId];
669
670     aMainId += aNbMainComponents;
671     anAlphaId += aNbAlphaComponents;
672     aCompositeId += aNbCompositeComponents;
673   }
674   aMainReader->Delete();
675   anAlphaReader->Delete();
676   aCompositeImageData->Update();
677
678   return aCompositeImageData;
679 }
680
681 void VISU_GaussPointsPL::SetScale( float theScale )
682 {
683   myWarpVector->SetScaleFactor( theScale );
684   myScaleFactor = GetScale();
685   Modified();
686 }
687
688 float VISU_GaussPointsPL::GetScale()
689 {
690   return myWarpVector->GetScaleFactor();
691 }
692
693 void VISU_GaussPointsPL::SetMapScale( float theMapScale )
694 {
695   VISU_ScalarMapPL::SetMapScale( theMapScale );
696
697   myWarpVector->SetScaleFactor( myScaleFactor * theMapScale );
698   Modified();
699 }