1 // Copyright (C) 2007-2011 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
23 // SMESH OBJECT : interactive object for SMESH visualization
29 #include "VISU_GaussPtsDeviceActor.h"
31 #include "VISU_GaussPointsPL.hxx"
32 #include "VISU_OpenGLPointSpriteMapper.hxx"
34 #include "VTKViewer_Transform.h"
35 #include "VTKViewer_TransformFilter.h"
36 #include <SALOME_ExtractPolyDataGeometry.h>
38 #include <vtkObjectFactory.h>
39 #include <vtkPolyData.h>
40 #include <vtkRenderer.h>
41 #include <vtkTextProperty.h>
42 #include <vtkProperty.h>
43 #include <vtkTexture.h>
44 #include <vtkPassThroughFilter.h>
45 #include <vtkImageData.h>
49 #include "utilities.h"
50 #include "VISU_PipeLineUtils.hxx"
53 static int MYDEBUG = 0;
55 static int MYDEBUG = 0;
59 //----------------------------------------------------------------
64 Image2VTI(const std::string& theImageFileName)
66 QFileInfo aFileInfo( theImageFileName.c_str() );
67 QString aFormat = aFileInfo.suffix();
69 QString aTmpDir = getenv( "TEMP" );
71 QString aTmpDir = QString( "/tmp/" ) + getenv("USER");
73 QString aVTIName = aTmpDir + "-" + aFileInfo.completeBaseName() + ".vti";
74 QString aCommand = QString( "VISU_img2vti " ) + aFormat + " " + theImageFileName.c_str() + " " + aVTIName;
76 if ( system( aCommand.toLatin1().data() ) == 0 )
77 return aVTIName.toLatin1().data();
84 RemoveFile(const std::string& theFileName)
86 if( theFileName != "" ){
88 QString aCommand = QString( "rm -fr " ) + theFileName.c_str();
90 QString aCommand = QString( "del /F " ) + theFileName.c_str();
92 system( aCommand.toLatin1().data() );
98 GetTexture(const std::string& theMainTexture,
99 const std::string& theAlphaTexture)
101 typedef std::pair<std::string,std::string> TTextureKey;
102 typedef std::map<TTextureKey,TTextureValue> TTextureMap;
104 static TTextureMap aTextureMap;
106 TTextureValue aTextureValue;
107 TTextureKey aTextureKey( theMainTexture.c_str(), theAlphaTexture.c_str() );
108 TTextureMap::const_iterator anIter = aTextureMap.find( aTextureKey );
109 if ( anIter != aTextureMap.end() ) {
110 aTextureValue = anIter->second;
112 QString aMainTextureVTI = Image2VTI(theMainTexture).c_str();
113 QString anAlphaTextureVTI = Image2VTI(theAlphaTexture).c_str();
115 if( !aMainTextureVTI.isNull() && !anAlphaTextureVTI.isNull() ){
117 VISU_GaussPointsPL::MakeTexture( aMainTextureVTI.toLatin1().data(),
118 anAlphaTextureVTI.toLatin1().data() );
120 if( aTextureValue.GetPointer() )
121 aTextureMap[aTextureKey] = aTextureValue;
124 RemoveFile(aMainTextureVTI.toLatin1().data());
125 RemoveFile(anAlphaTextureVTI.toLatin1().data());
128 return aTextureValue;
133 //----------------------------------------------------------------
134 vtkStandardNewMacro(VISU_GaussDeviceActorBase);
137 VISU_GaussDeviceActorBase
138 ::VISU_GaussDeviceActorBase():
139 myTransformFilter(VTKViewer_TransformFilter::New()),
140 myPolyDataExtractor(0)
142 if(MYDEBUG) MESSAGE("VISU_GaussDeviceActorBase - "<<this);
144 myTransformFilter->Delete();
146 for(int i = 0; i < 3; i++){
147 PPassThroughFilter aFilter(vtkPassThroughFilter::New());
148 myPassFilter.push_back(aFilter);
154 VISU_GaussDeviceActorBase
155 ::~VISU_GaussDeviceActorBase()
157 if(MYDEBUG) MESSAGE("~VISU_GaussDeviceActorBase - "<<this);
161 //----------------------------------------------------------------
163 VISU_GaussDeviceActorBase
164 ::Render(vtkRenderer *ren, vtkMapper *vtkNotUsed(m))
166 if (this->Mapper == NULL)
168 vtkErrorMacro("No mapper for actor.");
172 // render the property
175 // force creation of a property
178 this->Property->Render(this, ren);
179 if (this->BackfaceProperty)
181 this->BackfaceProperty->BackfaceRender(this, ren);
182 this->Device->SetBackfaceProperty(this->BackfaceProperty);
184 this->Device->SetProperty(this->Property);
186 // render the texture
189 this->Texture->Render(ren);
192 // make sure the device has the same matrix
193 vtkMatrix4x4 *matrix = this->Device->GetUserMatrix();
194 this->GetMatrix(matrix);
196 this->Device->Render(ren,Mapper);
197 this->EstimatedRenderTime = Mapper->GetTimeToDraw();
201 //----------------------------------------------------------------
203 VISU_GaussDeviceActorBase
204 ::SetTransform(VTKViewer_Transform* theTransform)
206 myTransformFilter->SetTransform(theTransform);
209 //----------------------------------------------------------------
211 VISU_GaussDeviceActorBase
212 ::SetPointSpriteMapper(VISU_OpenGLPointSpriteMapper* theMapper)
214 vtkPolyData* aDataSet = theMapper->GetInput();
215 myMapper = theMapper;
218 if (myPolyDataExtractor) {
219 myPolyDataExtractor->SetInput(aDataSet);
220 myPassFilter[ anId ]->SetInput( myPolyDataExtractor->GetOutput() );
222 myPassFilter[ anId ]->SetInput( aDataSet );
224 myPassFilter[ anId + 1 ]->SetInput( myPassFilter[ anId ]->GetOutput() );
227 myTransformFilter->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() );
230 myPassFilter[ anId ]->SetInput( myTransformFilter->GetOutput() );
232 myMapper->SetInput( myPassFilter[ anId ]->GetPolyDataOutput() );
234 Superclass::SetMapper( theMapper );
238 VISU_GaussDeviceActorBase
239 ::DoMapperShallowCopy( vtkMapper* theMapper,
240 bool theIsCopyInput )
242 VISU::CopyMapper( GetMapper(), theMapper, theIsCopyInput );
245 VISU_OpenGLPointSpriteMapper*
246 VISU_GaussDeviceActorBase
247 ::GetPointSpriteMapper()
249 return myMapper.GetPointer();
252 //----------------------------------------------------------------------------
254 VISU_GaussDeviceActorBase
257 vtkDataSet* aDataSet = GetMapper()->GetInput();
258 return aDataSet->GetActualMemorySize() * 1024;
263 //----------------------------------------------------------------
264 vtkStandardNewMacro(VISU_GaussPtsDeviceActor);
267 VISU_GaussPtsDeviceActor
268 ::VISU_GaussPtsDeviceActor()
272 VISU_GaussPtsDeviceActor
273 ::~VISU_GaussPtsDeviceActor()
277 //----------------------------------------------------------------------------
279 VISU_GaussPtsDeviceActor
280 ::AddToRender(vtkRenderer* theRenderer)
282 theRenderer->AddActor(this);
286 VISU_GaussPtsDeviceActor
287 ::RemoveFromRender(vtkRenderer* theRenderer)
289 theRenderer->RemoveActor(this);
293 //----------------------------------------------------------------------------
295 VISU_GaussPtsDeviceActor
296 ::SetPipeLine(VISU_GaussPointsPL* thePipeLine)
298 SetPointSpriteMapper( thePipeLine->GetPointSpriteMapper() );
300 myPipeLine = thePipeLine;
304 VISU_GaussPtsDeviceActor
307 return myPipeLine.GetPointer();
311 VISU_GaussPtsDeviceActor
312 ::ShallowCopyPL(VISU_GaussPointsPL* thePipeLine)
314 myPipeLine->ShallowCopy(thePipeLine, true);
318 //----------------------------------------------------------------------------
320 VISU_GaussPtsDeviceActor
323 if(Superclass::GetPickable()){
324 if(vtkMapper* aMapper = GetMapper()){
325 if(vtkDataSet* aDataSet= aMapper->GetInput()){
327 return aDataSet->GetNumberOfCells() > 0;
336 //----------------------------------------------------------------------------
338 VISU_GaussPtsDeviceActor
341 unsigned long int aSize = Superclass::GetMemorySize();
343 aSize += GetPipeLine()->GetMemorySize();
350 //============================================================================
351 #include <vtkActor.h>
352 #include <vtkProperty.h>
353 #include <vtkConeSource.h>
354 #include <vtkAppendPolyData.h>
355 #include <vtkPolyDataMapper.h>
358 //----------------------------------------------------------------------------
359 vtkStandardNewMacro(VISU_CursorPyramid);
361 //----------------------------------------------------------------------------
363 ::VISU_CursorPyramid():
366 myMagnification(1.0),
369 myAppendFilter(vtkAppendPolyData::New()),
370 myMapper(vtkPolyDataMapper::New())
372 myAppendFilter->Delete();
375 myMapper->SetInput(myAppendFilter->GetOutput());
377 for(int i = 0; i < myNbCones; i++){
378 vtkConeSource* aConeSource = vtkConeSource::New();
379 myAppendFilter->AddInput(aConeSource->GetOutput());
380 aConeSource->SetResolution(4);
381 mySources[i] = aConeSource;
382 aConeSource->Delete();
387 //----------------------------------------------------------------------------
390 ::Render(vtkRenderer *ren, vtkMapper *vtkNotUsed(m))
394 vtkErrorMacro("No mapper for actor.");
399 vtkFloatingPointType aMRadius = myRadius*myMagnification;
400 Init(myHeight,aMRadius*myCursorSize);
403 vtkFloatingPointType aPoint1[3] = {0.0, 0.0, 0.0};
404 ren->SetDisplayPoint(aPoint1);
405 ren->DisplayToWorld();
406 ren->GetWorldPoint(aPoint1);
408 vtkFloatingPointType aPoint2[3] = {0.0, myClamp, 0.0};
409 ren->SetDisplayPoint(aPoint2);
410 ren->DisplayToWorld();
411 ren->GetWorldPoint(aPoint2);
413 vtkFloatingPointType aWorldClamp =
414 (aPoint2[0] - aPoint1[0])*(aPoint2[0] - aPoint1[0]) +
415 (aPoint2[1] - aPoint1[1])*(aPoint2[1] - aPoint1[1]) +
416 (aPoint2[2] - aPoint1[2])*(aPoint2[2] - aPoint1[2]);
418 aWorldClamp = sqrt(aWorldClamp);
419 vtkFloatingPointType aMDiameter = 2.0 * aMRadius;
420 vtkFloatingPointType aCoeff = aWorldClamp / aMDiameter;
423 this->SetScale(aCoeff);
424 //Init(myHeight/aCoeff,aMRadius*aCoeff);
428 if (this->Mapper == NULL)
430 vtkErrorMacro("No mapper for actor.");
434 // render the property
437 // force creation of a property
440 this->Property->Render(this, ren);
441 if (this->BackfaceProperty)
443 this->BackfaceProperty->BackfaceRender(this, ren);
444 this->Device->SetBackfaceProperty(this->BackfaceProperty);
446 this->Device->SetProperty(this->Property);
448 // render the texture
451 this->Texture->Render(ren);
454 // make sure the device has the same matrix
455 vtkMatrix4x4 *matrix = this->Device->GetUserMatrix();
456 this->GetMatrix(matrix);
458 this->Device->Render(ren,Mapper);
459 this->EstimatedRenderTime = Mapper->GetTimeToDraw();
463 //----------------------------------------------------------------------------
466 ::AddToRender(vtkRenderer* theRenderer)
468 theRenderer->AddActor(this);
473 ::RemoveFromRender(vtkRenderer* theRenderer)
475 theRenderer->RemoveActor(this);
478 //----------------------------------------------------------------------------
481 ::SetPreferences(vtkFloatingPointType theHeight,
482 vtkFloatingPointType theCursorSize)
484 Init(theHeight, theCursorSize, myRadius, myMagnification, myClamp, GetPosition(), GetProperty()->GetColor());
487 //----------------------------------------------------------------------------
490 ::Init(vtkFloatingPointType theHeight,
491 vtkFloatingPointType theCursorSize,
492 vtkFloatingPointType theRadius,
493 vtkFloatingPointType theMagnification,
494 vtkFloatingPointType theClamp,
495 vtkFloatingPointType thePos[3],
496 vtkFloatingPointType theColor[3])
498 Init(theHeight,theRadius*theMagnification*theCursorSize);
499 SetPosition(thePos[0],thePos[1],thePos[2]);
500 GetProperty()->SetColor(theColor);
501 SetMapper(myMapper.GetPointer());
503 myHeight = theHeight;
504 myCursorSize = theCursorSize;
506 myRadius = theRadius;
507 myMagnification = theMagnification;
515 ::Init(vtkFloatingPointType theHeight,
516 vtkFloatingPointType theRadius)
518 for(int i = 0; i < myNbCones; ++i){
519 vtkConeSource* aSource = mySources[i].GetPointer();
520 aSource->SetHeight(theHeight);
521 // Set the angle of the cone. As a side effect, the angle plus height sets
522 // the base radius of the cone.
523 aSource->SetAngle(20.0);
526 vtkFloatingPointType aDisplacement = -0.5*theHeight - theRadius;
529 mySources[0]->SetDirection(1.0, 0.0, 0.0);
530 mySources[0]->SetCenter(aDisplacement, 0.0, 0.0);
532 // It is impossible to inverse direction around X axis (VTK bug)
533 mySources[1]->SetDirection(-VTK_LARGE_FLOAT, 1.0, 0.0); // A workaround
534 mySources[1]->SetCenter(-aDisplacement, 0.0, 0.0);
537 mySources[2]->SetDirection(0.0, 1.0, 0.0);
538 mySources[2]->SetCenter(0.0, aDisplacement, 0.0);
540 mySources[3]->SetDirection(0.0, -1.0, 0.0);
541 mySources[3]->SetCenter(0.0, -aDisplacement, 0.0);
544 mySources[4]->SetDirection(0.0, 0.0, 1.0);
545 mySources[4]->SetCenter(0.0, 0.0, aDisplacement);
547 mySources[5]->SetDirection(0.0, 0.0, -1.0);
548 mySources[5]->SetCenter(0.0, 0.0, -aDisplacement);