1 // GEOM OBJECT : interactive object for Geometry entities visualization
3 // Copyright (C) 2003 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
24 // File : GEOM_Actor.cxx
25 // Author : Christophe ATTANASIO
30 \class GEOM_Actor GEOM_Actor.h
31 \brief This class allows to display an OpenCASCADE CAD model in a VTK viewer.
34 #include "GEOM_Actor.h"
36 #include <vtkObjectFactory.h>
37 #include <vtkPolyData.h>
38 #include <vtkPolyDataMapper.h>
39 #include <vtkPolyDataNormals.h>
41 #include <vtkTransform.h>
42 #include <vtkMatrix4x4.h>
45 #include <vtkProperty.h>
46 #include <vtkRenderer.h>
47 #include <vtkCamera.h>
49 // OpenCASCADE Includes
50 #include "GEOM_OCCReader.h"
51 #include <BRep_Tool.hxx>
55 //-------------------------------------------------------------
57 //-------------------------------------------------------------
60 GEOM_Actor* GEOM_Actor::New()
62 // First try to create the object from the vtkObjectFactory
63 vtkObject* ret = vtkObjectFactory::CreateInstance("GEOM_Actor");
66 return (GEOM_Actor*)ret;
68 // If the factory was unable to create the object, then create it here.
69 return new GEOM_Actor;
73 GEOM_Actor::GEOM_Actor()
75 this->Device = vtkActor::New();
77 this->WireframeMapper = NULL;
78 this->ShadingMapper = NULL;
80 this->ShadingProperty = NULL;
81 this->WireframeProperty = NULL;
89 this->HighlightProperty = NULL;
90 this->myIsHighlighted = false;
92 this->subshape = false;
93 this->myIsInfinite = false;
96 GEOM_Actor::~GEOM_Actor()
98 if (WireframeMapper != NULL)
99 WireframeMapper->Delete();
100 if (ShadingMapper != NULL)
101 ShadingMapper->Delete();
102 if (ShadingProperty != NULL)
103 ShadingProperty->Delete();
104 if (WireframeProperty != NULL)
105 WireframeProperty->Delete();
106 if (HighlightProperty != NULL)
107 HighlightProperty->Delete();
111 void GEOM_Actor::ShallowCopy(vtkProp *prop)
113 GEOM_Actor *f = GEOM_Actor::SafeDownCast(prop);
116 this->setInputShape(f->getTopo(),f->getDeflection(),f->getDisplayMode(),f->isVector());
117 this->setName( f->getName() );
119 this->setIO( f->getIO() );
120 this->ShadingMapper = NULL;
121 this->WireframeMapper = NULL;
125 this->ShadingMapper = NULL;
126 this->WireframeMapper = NULL;
130 this->SALOME_Actor::ShallowCopy(prop);
133 //-------------------------------------------------------------
135 //-------------------------------------------------------------
138 void GEOM_Actor::setDisplayMode(int thenewmode) {
139 myDisplayMode = thenewmode;
140 if ( thenewmode >=1 ) {
141 if ((myShape.ShapeType() == TopAbs_WIRE) ||
142 (myShape.ShapeType() == TopAbs_EDGE) ||
143 (myShape.ShapeType() == TopAbs_VERTEX)) {
145 CreateWireframeMapper();
149 CreateShadingMapper();
151 CreateWireframeMapper();
154 void GEOM_Actor::setDeflection(double adef) {
158 void GEOM_Actor::setInputShape(const TopoDS_Shape& aShape, double adef,
159 int imode, bool isVector)
163 myIsVector = isVector;
164 setDisplayMode(imode);
167 //-------------------------------------------------------------
169 //-------------------------------------------------------------
171 const TopoDS_Shape& GEOM_Actor::getTopo() {
175 double GEOM_Actor::getDeflection() {
179 void GEOM_Actor::SetWireframeProperty(vtkProperty* Prop) {
180 this->WireframeProperty = Prop;
183 void GEOM_Actor::SetShadingProperty(vtkProperty* Prop) {
184 this->ShadingProperty = Prop;
188 //-------------------------------------------------------------
189 // Mapper creating function
190 //-------------------------------------------------------------
191 void GEOM_Actor::CreateMapper(int theMode) {
192 this->myIsInfinite = (bool)myShape.Infinite();
193 if(myShape.ShapeType() == TopAbs_VERTEX) {
194 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(myShape));
195 this->SetPosition(aPnt.X(),aPnt.Y(),aPnt.Z());
197 GEOM_OCCReader* aread = GEOM_OCCReader::New();
198 aread->setTopo(myShape, myIsVector);
199 aread->setDisplayMode(theMode);
200 aread->GetOutput()->ReleaseDataFlagOn();
202 vtkPolyDataMapper* aMapper = vtkPolyDataMapper::New();
204 aMapper->SetInput(aread->GetOutput());
206 vtkPolyDataNormals *normals = vtkPolyDataNormals::New();
207 normals->SetInput(aread->GetOutput());
208 aMapper->SetInput(normals->GetOutput());
211 this->SetMapper(theMode == 0? WireframeMapper = aMapper : ShadingMapper = aMapper);
214 void GEOM_Actor::CreateShadingMapper() {
219 void GEOM_Actor::CreateWireframeMapper() {
223 //-------------------------------------------------------------
225 //-------------------------------------------------------------
227 void GEOM_Actor::Render(vtkRenderer *ren, vtkMapper *Mapper)
229 /* render the property */
230 if (!this->Property) {
231 // force creation of a property
233 this->Property->SetInterpolation(1);
234 this->Property->SetRepresentationToSurface();
235 this->Property->SetAmbient(0.3);
236 this->Property->SetAmbientColor(0.88,0.86,0.2);
237 this->Property->SetDiffuseColor(0.99,0.7,0.21);
238 this->Property->SetSpecularColor(0.99,0.98,0.83);
241 if(!myIsHighlighted) {
242 if ( myIsPreselected )
243 this->Property = PreviewProperty;
244 else if(myDisplayMode >= 1) {
246 this->Property = ShadingProperty;
249 this->Property = WireframeProperty;
254 this->Property->Render(this, ren);
255 if (this->BackfaceProperty) {
256 this->BackfaceProperty->BackfaceRender(this, ren);
257 this->Device->SetBackfaceProperty(this->BackfaceProperty);
259 this->Device->SetProperty(this->Property);
260 // Store information on time it takes to render.
261 // We might want to estimate time from the number of polygons in mapper.
262 if(myDisplayMode >= 1) {
263 if((myShape.ShapeType() == TopAbs_WIRE) ||
264 (myShape.ShapeType() == TopAbs_EDGE) ||
265 (myShape.ShapeType() == TopAbs_VERTEX)) {
267 if(WireframeMapper==NULL) CreateWireframeMapper();
272 if(ShadingMapper==NULL) CreateShadingMapper();
276 if(WireframeMapper==NULL) CreateWireframeMapper();
278 if(myShape.ShapeType() == TopAbs_VERTEX) {
280 //The parameter determine size of vertex actor relate to diagonal of RendererWindow
281 static vtkFloatingPointType delta = 0.01;
282 vtkFloatingPointType X1 = -1, Y1 = -1, Z1 = 0;
283 ren->ViewToWorld(X1,Y1,Z1);
284 vtkFloatingPointType X2 = +1, Y2 = +1, Z2 = 0;
285 ren->ViewToWorld(X2,Y2,Z2);
286 Z2 = sqrt((X2-X1)*(X2-X1) + (Y2-Y1)*(Y2-Y1) + (Z2-Z1)*(Z2-Z1));
287 this->SetScale(Z2*delta);
289 vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New();
290 this->GetMatrix(ren->GetActiveCamera(), aMatrix);
291 this->Device->SetUserMatrix(aMatrix);
292 this->Device->Render(ren,this->Mapper);
295 this->Device->Render(ren, this->Mapper);
296 if(WireframeMapper!=NULL) this->EstimatedRenderTime = WireframeMapper->GetTimeToDraw();
297 else if(ShadingMapper!=NULL) this->EstimatedRenderTime = ShadingMapper->GetTimeToDraw();
301 void GEOM_Actor::SubShapeOn()
305 void GEOM_Actor::SubShapeOff()
310 //-------------------------------------------------------------
312 //-------------------------------------------------------------
314 void GEOM_Actor::SetOpacity(vtkFloatingPointType opa)
316 //HighlightProperty->SetOpacity(opa);
317 SALOME_Actor::SetOpacity(opa);
318 ShadingProperty->SetOpacity(opa);
321 vtkFloatingPointType GEOM_Actor::GetOpacity() {
322 return ShadingProperty->GetOpacity();
325 //-------------------------------------------------------------
327 //-------------------------------------------------------------
328 void GEOM_Actor::SetColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b) {
329 ShadingProperty->SetColor(r,g,b);
332 void GEOM_Actor::GetColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b) {
333 vtkFloatingPointType color[3];
334 ShadingProperty->GetColor(color);
340 //-------------------------------------------------------------
342 //-------------------------------------------------------------
344 void GEOM_Actor::highlight(bool highlight) {
346 if(highlight && !myIsHighlighted) {
347 myIsHighlighted=true;
348 // build highlight property is necessary
349 if(HighlightProperty==NULL) {
350 HighlightProperty = vtkProperty::New();
351 HighlightProperty->SetAmbient(0.5);
352 HighlightProperty->SetDiffuse(0.3);
353 HighlightProperty->SetSpecular(0.2);
354 HighlightProperty->SetRepresentationToSurface();
355 HighlightProperty->SetAmbientColor(1, 1, 1);
356 HighlightProperty->SetDiffuseColor(1, 1, 1);
357 HighlightProperty->SetSpecularColor(0.5, 0.5, 0.5);
360 this->Property = HighlightProperty;
363 else if (!highlight) {
364 if(myIsHighlighted) {
365 myIsHighlighted=false;
366 if(myDisplayMode==1) {
367 //unhilight in shading
368 this->Property = ShadingProperty;
371 //unhilight in wireframe
372 this->Property = WireframeProperty;
378 void GEOM_Actor::SetHighlightProperty(vtkProperty* Prop) {
379 this->HighlightProperty = Prop;
383 void GEOM_Actor::ReleaseGraphicsResources(vtkWindow *renWin)
385 vtkActor::ReleaseGraphicsResources(renWin);
387 // broadcast the message down to the individual LOD mappers
389 if(WireframeMapper) this->WireframeMapper->ReleaseGraphicsResources(renWin);
390 if(ShadingMapper) this->ShadingMapper->ReleaseGraphicsResources(renWin);
394 // Copy the follower's composite 4x4 matrix into the matrix provided.
395 void GEOM_Actor::GetMatrix(vtkCamera* theCam, vtkMatrix4x4 *result)
398 double Rx[3], Ry[3], Rz[3], p1[3];
399 vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
403 this->GetOrientation();
404 this->Transform->Push();
405 this->Transform->PostMultiply();
406 this->Transform->Identity();
408 // apply user defined matrix last if there is one
409 if (this->UserMatrix)
411 this->Transform->Concatenate(this->UserMatrix);
414 this->Transform->Translate(-this->Origin[0],
418 this->Transform->Scale(this->Scale[0],
423 this->Transform->RotateY(this->Orientation[1]);
424 this->Transform->RotateX(this->Orientation[0]);
425 this->Transform->RotateZ(this->Orientation[2]);
431 pos = theCam->GetPosition();
432 vup = theCam->GetViewUp();
434 if (theCam->GetParallelProjection())
436 theCam->GetDirectionOfProjection(Rz);
441 (pos[0] - this->Position[0])*(pos[0] - this->Position[0]) +
442 (pos[1] - this->Position[1])*(pos[1] - this->Position[1]) +
443 (pos[2] - this->Position[2])*(pos[2] - this->Position[2]));
444 for (i = 0; i < 3; i++)
446 Rz[i] = (pos[i] - this->Position[i])/distance;
450 vtkMath::Cross(vup,Rz,Rx);
451 vtkMath::Normalize(Rx);
452 vtkMath::Cross(Rz,Rx,Ry);
454 matrix->Element[0][0] = Rx[0];
455 matrix->Element[1][0] = Rx[1];
456 matrix->Element[2][0] = Rx[2];
457 matrix->Element[0][1] = Ry[0];
458 matrix->Element[1][1] = Ry[1];
459 matrix->Element[2][1] = Ry[2];
460 matrix->Element[0][2] = Rz[0];
461 matrix->Element[1][2] = Rz[1];
462 matrix->Element[2][2] = Rz[2];
464 this->Transform->Concatenate(matrix);
467 // translate to projection reference point PRP
468 // this is the camera's position blasted through
469 // the current matrix
470 p1[0] = this->Origin[0] + this->Position[0];
471 p1[1] = this->Origin[1] + this->Position[1];
472 p1[2] = this->Origin[2] + this->Position[2];
474 this->Transform->Translate(p1[0],p1[1],p1[2]);
475 this->Transform->GetMatrix(result);
478 this->Transform->Pop();