1 // Copyright (C) 2007-2008 CEA/DEN, EDF R&D, OPEN CASCADE
3 // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN,
4 // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS
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.
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.
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
20 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
22 // SMESH OBJECT : interactive object for SMESH visualization
28 #include "VISU_GaussPtsDeviceActor.h"
30 #include "VISU_GaussPointsPL.hxx"
31 #include "VISU_OpenGLPointSpriteMapper.hxx"
33 #include "VTKViewer_Transform.h"
34 #include "VTKViewer_TransformFilter.h"
35 #include <SALOME_ExtractPolyDataGeometry.h>
37 #include <vtkObjectFactory.h>
38 #include <vtkPolyData.h>
39 #include <vtkRenderer.h>
40 #include <vtkTextProperty.h>
41 #include <vtkProperty.h>
42 #include <vtkTexture.h>
43 #include <vtkPassThroughFilter.h>
44 #include <vtkImageData.h>
48 #include "utilities.h"
49 #include "VISU_PipeLineUtils.hxx"
52 static int MYDEBUG = 0;
54 static int MYDEBUG = 0;
58 //----------------------------------------------------------------
63 Image2VTI(const std::string& theImageFileName)
65 QFileInfo aFileInfo( theImageFileName.c_str() );
66 QString aFormat = aFileInfo.suffix();
68 QString aTmpDir = getenv( "TEMP" );
70 QString aTmpDir = QString( "/tmp/" ) + getenv("USER");
72 QString aVTIName = aTmpDir + "-" + aFileInfo.completeBaseName() + ".vti";
73 QString aCommand = QString( "VISU_img2vti " ) + aFormat + " " + theImageFileName.c_str() + " " + aVTIName;
75 if ( system( aCommand.toLatin1().data() ) == 0 )
76 return aVTIName.toLatin1().data();
83 RemoveFile(const std::string& theFileName)
85 if( theFileName != "" ){
87 QString aCommand = QString( "rm -fr " ) + theFileName.c_str();
89 QString aCommand = QString( "del /F " ) + theFileName.c_str();
91 system( aCommand.toLatin1().data() );
97 GetTexture(const std::string& theMainTexture,
98 const std::string& theAlphaTexture)
100 typedef std::pair<std::string,std::string> TTextureKey;
101 typedef std::map<TTextureKey,TTextureValue> TTextureMap;
103 static TTextureMap aTextureMap;
105 TTextureValue aTextureValue;
106 TTextureKey aTextureKey( theMainTexture.c_str(), theAlphaTexture.c_str() );
107 TTextureMap::const_iterator anIter = aTextureMap.find( aTextureKey );
108 if ( anIter != aTextureMap.end() ) {
109 aTextureValue = anIter->second;
111 QString aMainTextureVTI = Image2VTI(theMainTexture).c_str();
112 QString anAlphaTextureVTI = Image2VTI(theAlphaTexture).c_str();
114 if( !aMainTextureVTI.isNull() && !anAlphaTextureVTI.isNull() ){
116 VISU_GaussPointsPL::MakeTexture( aMainTextureVTI.toLatin1().data(),
117 anAlphaTextureVTI.toLatin1().data() );
119 if( aTextureValue.GetPointer() )
120 aTextureMap[aTextureKey] = aTextureValue;
123 RemoveFile(aMainTextureVTI.toLatin1().data());
124 RemoveFile(anAlphaTextureVTI.toLatin1().data());
127 return aTextureValue;
132 //----------------------------------------------------------------
133 vtkStandardNewMacro(VISU_GaussDeviceActorBase);
136 VISU_GaussDeviceActorBase
137 ::VISU_GaussDeviceActorBase():
138 myTransformFilter(VTKViewer_TransformFilter::New()),
139 myPolyDataExtractor(0)
141 if(MYDEBUG) MESSAGE("VISU_GaussDeviceActorBase - "<<this);
143 myTransformFilter->Delete();
145 for(int i = 0; i < 3; i++){
146 PPassThroughFilter aFilter(vtkPassThroughFilter::New());
147 myPassFilter.push_back(aFilter);
153 VISU_GaussDeviceActorBase
154 ::~VISU_GaussDeviceActorBase()
156 if(MYDEBUG) MESSAGE("~VISU_GaussDeviceActorBase - "<<this);
160 //----------------------------------------------------------------
162 VISU_GaussDeviceActorBase
163 ::Render(vtkRenderer *ren, vtkMapper *vtkNotUsed(m))
165 if (this->Mapper == NULL)
167 vtkErrorMacro("No mapper for actor.");
171 // render the property
174 // force creation of a property
177 this->Property->Render(this, ren);
178 if (this->BackfaceProperty)
180 this->BackfaceProperty->BackfaceRender(this, ren);
181 this->Device->SetBackfaceProperty(this->BackfaceProperty);
183 this->Device->SetProperty(this->Property);
185 // render the texture
188 this->Texture->Render(ren);
191 // make sure the device has the same matrix
192 vtkMatrix4x4 *matrix = this->Device->GetUserMatrix();
193 this->GetMatrix(matrix);
195 this->Device->Render(ren,Mapper);
196 this->EstimatedRenderTime = Mapper->GetTimeToDraw();
200 //----------------------------------------------------------------
202 VISU_GaussDeviceActorBase
203 ::SetTransform(VTKViewer_Transform* theTransform)
205 myTransformFilter->SetTransform(theTransform);
208 //----------------------------------------------------------------
210 VISU_GaussDeviceActorBase
211 ::SetPointSpriteMapper(VISU_OpenGLPointSpriteMapper* theMapper)
213 vtkPolyData* aDataSet = theMapper->GetInput();
214 myMapper = theMapper;
217 if (myPolyDataExtractor) {
218 myPolyDataExtractor->SetInput(aDataSet);
219 myPassFilter[ anId ]->SetInput( myPolyDataExtractor->GetOutput() );
221 myPassFilter[ anId ]->SetInput( aDataSet );
223 myPassFilter[ anId + 1 ]->SetInput( myPassFilter[ anId ]->GetOutput() );
226 myTransformFilter->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() );
229 myPassFilter[ anId ]->SetInput( myTransformFilter->GetOutput() );
231 myMapper->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() );
233 Superclass::SetMapper( theMapper );
237 VISU_GaussDeviceActorBase
238 ::DoMapperShallowCopy( vtkMapper* theMapper,
239 bool theIsCopyInput )
241 VISU::CopyMapper( GetMapper(), theMapper, theIsCopyInput );
244 VISU_OpenGLPointSpriteMapper*
245 VISU_GaussDeviceActorBase
246 ::GetPointSpriteMapper()
248 return myMapper.GetPointer();
251 //----------------------------------------------------------------------------
253 VISU_GaussDeviceActorBase
256 vtkDataSet* aDataSet = GetMapper()->GetInput();
257 return aDataSet->GetActualMemorySize() * 1024;
262 //----------------------------------------------------------------
263 vtkStandardNewMacro(VISU_GaussPtsDeviceActor);
266 VISU_GaussPtsDeviceActor
267 ::VISU_GaussPtsDeviceActor()
271 VISU_GaussPtsDeviceActor
272 ::~VISU_GaussPtsDeviceActor()
276 //----------------------------------------------------------------------------
278 VISU_GaussPtsDeviceActor
279 ::AddToRender(vtkRenderer* theRenderer)
281 theRenderer->AddActor(this);
285 VISU_GaussPtsDeviceActor
286 ::RemoveFromRender(vtkRenderer* theRenderer)
288 theRenderer->RemoveActor(this);
292 //----------------------------------------------------------------------------
294 VISU_GaussPtsDeviceActor
295 ::SetPipeLine(VISU_GaussPointsPL* thePipeLine)
297 SetPointSpriteMapper( thePipeLine->GetPointSpriteMapper() );
299 myPipeLine = thePipeLine;
303 VISU_GaussPtsDeviceActor
306 return myPipeLine.GetPointer();
310 VISU_GaussPtsDeviceActor
311 ::ShallowCopyPL(VISU_GaussPointsPL* thePipeLine)
313 myPipeLine->ShallowCopy(thePipeLine, true);
317 //----------------------------------------------------------------------------
319 VISU_GaussPtsDeviceActor
322 if(Superclass::GetPickable()){
323 if(vtkMapper* aMapper = GetMapper()){
324 if(vtkDataSet* aDataSet= aMapper->GetInput()){
326 return aDataSet->GetNumberOfCells() > 0;
335 //----------------------------------------------------------------------------
337 VISU_GaussPtsDeviceActor
340 unsigned long int aSize = Superclass::GetMemorySize();
342 aSize += GetPipeLine()->GetMemorySize();
349 //============================================================================
350 #include <vtkActor.h>
351 #include <vtkProperty.h>
352 #include <vtkConeSource.h>
353 #include <vtkAppendPolyData.h>
354 #include <vtkPolyDataMapper.h>
357 //----------------------------------------------------------------------------
358 vtkStandardNewMacro(VISU_CursorPyramid);
360 //----------------------------------------------------------------------------
362 ::VISU_CursorPyramid():
365 myMagnification(1.0),
368 myAppendFilter(vtkAppendPolyData::New()),
369 myMapper(vtkPolyDataMapper::New())
371 myAppendFilter->Delete();
374 myMapper->SetInput(myAppendFilter->GetOutput());
376 for(int i = 0; i < myNbCones; i++){
377 vtkConeSource* aConeSource = vtkConeSource::New();
378 myAppendFilter->AddInput(aConeSource->GetOutput());
379 aConeSource->SetResolution(4);
380 mySources[i] = aConeSource;
381 aConeSource->Delete();
386 //----------------------------------------------------------------------------
389 ::Render(vtkRenderer *ren, vtkMapper *vtkNotUsed(m))
393 vtkErrorMacro("No mapper for actor.");
398 vtkFloatingPointType aMRadius = myRadius*myMagnification;
399 Init(myHeight,aMRadius*myCursorSize);
402 vtkFloatingPointType aPoint1[3] = {0.0, 0.0, 0.0};
403 ren->SetDisplayPoint(aPoint1);
404 ren->DisplayToWorld();
405 ren->GetWorldPoint(aPoint1);
407 vtkFloatingPointType aPoint2[3] = {0.0, myClamp, 0.0};
408 ren->SetDisplayPoint(aPoint2);
409 ren->DisplayToWorld();
410 ren->GetWorldPoint(aPoint2);
412 vtkFloatingPointType aWorldClamp =
413 (aPoint2[0] - aPoint1[0])*(aPoint2[0] - aPoint1[0]) +
414 (aPoint2[1] - aPoint1[1])*(aPoint2[1] - aPoint1[1]) +
415 (aPoint2[2] - aPoint1[2])*(aPoint2[2] - aPoint1[2]);
417 aWorldClamp = sqrt(aWorldClamp);
418 vtkFloatingPointType aMDiameter = 2.0 * aMRadius;
419 vtkFloatingPointType aCoeff = aWorldClamp / aMDiameter;
422 this->SetScale(aCoeff);
423 //Init(myHeight/aCoeff,aMRadius*aCoeff);
427 if (this->Mapper == NULL)
429 vtkErrorMacro("No mapper for actor.");
433 // render the property
436 // force creation of a property
439 this->Property->Render(this, ren);
440 if (this->BackfaceProperty)
442 this->BackfaceProperty->BackfaceRender(this, ren);
443 this->Device->SetBackfaceProperty(this->BackfaceProperty);
445 this->Device->SetProperty(this->Property);
447 // render the texture
450 this->Texture->Render(ren);
453 // make sure the device has the same matrix
454 vtkMatrix4x4 *matrix = this->Device->GetUserMatrix();
455 this->GetMatrix(matrix);
457 this->Device->Render(ren,Mapper);
458 this->EstimatedRenderTime = Mapper->GetTimeToDraw();
462 //----------------------------------------------------------------------------
465 ::AddToRender(vtkRenderer* theRenderer)
467 theRenderer->AddActor(this);
472 ::RemoveFromRender(vtkRenderer* theRenderer)
474 theRenderer->RemoveActor(this);
477 //----------------------------------------------------------------------------
480 ::SetPreferences(vtkFloatingPointType theHeight,
481 vtkFloatingPointType theCursorSize)
483 Init(theHeight, theCursorSize, myRadius, myMagnification, myClamp, GetPosition(), GetProperty()->GetColor());
486 //----------------------------------------------------------------------------
489 ::Init(vtkFloatingPointType theHeight,
490 vtkFloatingPointType theCursorSize,
491 vtkFloatingPointType theRadius,
492 vtkFloatingPointType theMagnification,
493 vtkFloatingPointType theClamp,
494 vtkFloatingPointType thePos[3],
495 vtkFloatingPointType theColor[3])
497 Init(theHeight,theRadius*theMagnification*theCursorSize);
498 SetPosition(thePos[0],thePos[1],thePos[2]);
499 GetProperty()->SetColor(theColor);
500 SetMapper(myMapper.GetPointer());
502 myHeight = theHeight;
503 myCursorSize = theCursorSize;
505 myRadius = theRadius;
506 myMagnification = theMagnification;
514 ::Init(vtkFloatingPointType theHeight,
515 vtkFloatingPointType theRadius)
517 for(int i = 0; i < myNbCones; ++i){
518 vtkConeSource* aSource = mySources[i].GetPointer();
519 aSource->SetHeight(theHeight);
520 // Set the angle of the cone. As a side effect, the angle plus height sets
521 // the base radius of the cone.
522 aSource->SetAngle(20.0);
525 vtkFloatingPointType aDisplacement = -0.5*theHeight - theRadius;
528 mySources[0]->SetDirection(1.0, 0.0, 0.0);
529 mySources[0]->SetCenter(aDisplacement, 0.0, 0.0);
531 // It is impossible to inverse direction around X axis (VTK bug)
532 mySources[1]->SetDirection(-VTK_LARGE_FLOAT, 1.0, 0.0); // A workaround
533 mySources[1]->SetCenter(-aDisplacement, 0.0, 0.0);
536 mySources[2]->SetDirection(0.0, 1.0, 0.0);
537 mySources[2]->SetCenter(0.0, aDisplacement, 0.0);
539 mySources[3]->SetDirection(0.0, -1.0, 0.0);
540 mySources[3]->SetCenter(0.0, -aDisplacement, 0.0);
543 mySources[4]->SetDirection(0.0, 0.0, 1.0);
544 mySources[4]->SetCenter(0.0, 0.0, aDisplacement);
546 mySources[5]->SetDirection(0.0, 0.0, -1.0);
547 mySources[5]->SetCenter(0.0, 0.0, -aDisplacement);