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.opencascade.org/SALOME/ or email : webmaster.salome@opencascade.org
24 // File : GEOM_Actor.cxx
25 // Author : Christophe ATTANASIO
31 \class GEOM_Actor GEOM_Actor.h
32 \brief This class allows to display an OpenCASCADE CAD model in a VTK viewer.
35 #include "GEOM_Actor.h"
37 // OpenCASCADE Includes
38 #include "GEOM_OCCReader.h"
39 #include <BRep_Tool.hxx>
41 //-------------------------------------------------------------
43 //-------------------------------------------------------------
46 GEOM_Actor* GEOM_Actor::New()
48 // First try to create the object from the vtkObjectFactory
49 vtkObject* ret = vtkObjectFactory::CreateInstance("GEOM_Actor");
52 return (GEOM_Actor*)ret;
54 // If the factory was unable to create the object, then create it here.
55 return new GEOM_Actor;
59 GEOM_Actor::GEOM_Actor()
61 this->Device = vtkActor::New();
63 this->WireframeMapper = NULL;
64 this->ShadingMapper = NULL;
66 this->ShadingProperty = NULL;
67 this->WireframeProperty = NULL;
75 this->HighlightProperty = NULL;
76 this->ishighlighted = false;
78 this->subshape = false;
79 this->myIsInfinite = false;
82 GEOM_Actor::~GEOM_Actor()
84 if (WireframeMapper != NULL)
85 WireframeMapper->Delete();
86 if (ShadingMapper != NULL)
87 ShadingMapper->Delete();
88 if (ShadingProperty != NULL)
89 ShadingProperty->Delete();
90 if (WireframeProperty != NULL)
91 WireframeProperty->Delete();
92 if (HighlightProperty != NULL)
93 HighlightProperty->Delete();
97 void GEOM_Actor::ShallowCopy(vtkProp *prop)
99 GEOM_Actor *f = GEOM_Actor::SafeDownCast(prop);
102 this->setInputShape(f->getTopo(),f->getDeflection(),f->getDisplayMode());
103 this->setName( f->getName() );
105 this->setIO( f->getIO() );
106 this->ShadingMapper = NULL;
107 this->WireframeMapper = NULL;
111 this->ShadingMapper = NULL;
112 this->WireframeMapper = NULL;
116 this->SALOME_Actor::ShallowCopy(prop);
119 //-------------------------------------------------------------
121 //-------------------------------------------------------------
124 void GEOM_Actor::setDisplayMode(int thenewmode) {
125 myDisplayMode = thenewmode;
126 if ( thenewmode >=1 ) {
127 if ((myShape.ShapeType() == TopAbs_WIRE) ||
128 (myShape.ShapeType() == TopAbs_EDGE) ||
129 (myShape.ShapeType() == TopAbs_VERTEX)) {
131 CreateWireframeMapper();
135 CreateShadingMapper();
137 CreateWireframeMapper();
140 void GEOM_Actor::setDeflection(double adef) {
144 void GEOM_Actor::setInputShape(const TopoDS_Shape& aShape,double adef,int imode) {
147 setDisplayMode(imode);
150 //-------------------------------------------------------------
152 //-------------------------------------------------------------
154 const TopoDS_Shape& GEOM_Actor::getTopo() {
158 double GEOM_Actor::getDeflection() {
162 void GEOM_Actor::SetWireframeProperty(vtkProperty* Prop) {
163 this->WireframeProperty = Prop;
166 void GEOM_Actor::SetShadingProperty(vtkProperty* Prop) {
167 this->ShadingProperty = Prop;
171 //-------------------------------------------------------------
172 // Mapper creating function
173 //-------------------------------------------------------------
174 void GEOM_Actor::CreateMapper(int theMode) {
175 this->myIsInfinite = myShape.Infinite();
176 if(myShape.ShapeType() == TopAbs_VERTEX) {
177 gp_Pnt aPnt = BRep_Tool::Pnt(TopoDS::Vertex(myShape));
178 this->SetPosition(aPnt.X(),aPnt.Y(),aPnt.Z());
180 GEOM_OCCReader* aread = GEOM_OCCReader::New();
181 aread->setTopo(myShape);
182 aread->setDisplayMode(theMode);
183 aread->GetOutput()->ReleaseDataFlagOn();
185 vtkPolyDataMapper* aMapper = vtkPolyDataMapper::New();
187 aMapper->SetInput(aread->GetOutput());
189 vtkPolyDataNormals *normals = vtkPolyDataNormals::New();
190 normals->SetInput(aread->GetOutput());
191 aMapper->SetInput(normals->GetOutput());
194 this->SetMapper(theMode == 0? WireframeMapper = aMapper : ShadingMapper = aMapper);
197 void GEOM_Actor::CreateShadingMapper() {
202 void GEOM_Actor::CreateWireframeMapper() {
206 //-------------------------------------------------------------
208 //-------------------------------------------------------------
210 void GEOM_Actor::Render(vtkRenderer *ren, vtkMapper *Mapper)
212 /* render the property */
213 if (!this->Property) {
214 // force creation of a property
216 this->Property->SetInterpolation(1);
217 this->Property->SetRepresentationToSurface();
218 this->Property->SetAmbient(0.3);
219 this->Property->SetAmbientColor(0.88,0.86,0.2);
220 this->Property->SetDiffuseColor(0.99,0.7,0.21);
221 this->Property->SetSpecularColor(0.99,0.98,0.83);
226 this->Property = PreviewProperty;
227 else if(myDisplayMode >= 1) {
229 this->Property = ShadingProperty;
232 this->Property = WireframeProperty;
237 this->Property->Render(this, ren);
238 if (this->BackfaceProperty) {
239 this->BackfaceProperty->BackfaceRender(this, ren);
240 this->Device->SetBackfaceProperty(this->BackfaceProperty);
242 this->Device->SetProperty(this->Property);
243 // Store information on time it takes to render.
244 // We might want to estimate time from the number of polygons in mapper.
245 if(myDisplayMode >= 1) {
246 if((myShape.ShapeType() == TopAbs_WIRE) ||
247 (myShape.ShapeType() == TopAbs_EDGE) ||
248 (myShape.ShapeType() == TopAbs_VERTEX)) {
250 if(WireframeMapper==NULL) CreateWireframeMapper();
255 if(ShadingMapper==NULL) CreateShadingMapper();
259 if(WireframeMapper==NULL) CreateWireframeMapper();
261 if(myShape.ShapeType() == TopAbs_VERTEX) {
263 //The parameter determine size of vertex actor relate to diagonal of RendererWindow
264 static float delta = 0.01;
265 float X1 = -1, Y1 = -1, Z1 = 0;
266 ren->ViewToWorld(X1,Y1,Z1);
267 float X2 = +1, Y2 = +1, Z2 = 0;
268 ren->ViewToWorld(X2,Y2,Z2);
269 Z2 = sqrt((X2-X1)*(X2-X1) + (Y2-Y1)*(Y2-Y1) + (Z2-Z1)*(Z2-Z1));
270 this->SetScale(Z2*delta);
272 vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New();
273 this->GetMatrix(ren->GetActiveCamera(), aMatrix);
274 this->Device->SetUserMatrix(aMatrix);
275 this->Device->Render(ren,this->Mapper);
278 this->Device->Render(ren, this->Mapper);
279 if(WireframeMapper!=NULL) this->EstimatedRenderTime = WireframeMapper->GetTimeToDraw();
280 else if(ShadingMapper!=NULL) this->EstimatedRenderTime = ShadingMapper->GetTimeToDraw();
284 void GEOM_Actor::SubShapeOn()
288 void GEOM_Actor::SubShapeOff()
293 //-------------------------------------------------------------
295 //-------------------------------------------------------------
297 void GEOM_Actor::SetOpacity(float opa)
299 //HighlightProperty->SetOpacity(opa);
300 SALOME_Actor::SetOpacity(opa);
301 ShadingProperty->SetOpacity(opa);
304 float GEOM_Actor::GetOpacity() {
305 return ShadingProperty->GetOpacity();
308 //-------------------------------------------------------------
310 //-------------------------------------------------------------
311 void GEOM_Actor::SetColor(float r,float g,float b) {
312 ShadingProperty->SetColor(r,g,b);
315 void GEOM_Actor::GetColor(float& r,float& g,float& b) {
317 ShadingProperty->GetColor(color);
323 //-------------------------------------------------------------
325 //-------------------------------------------------------------
327 void GEOM_Actor::highlight(Standard_Boolean highlight) {
329 if(highlight && !ishighlighted) {
331 // build highlight property is necessary
332 if(HighlightProperty==NULL) {
333 HighlightProperty = vtkProperty::New();
334 HighlightProperty->SetAmbient(0.5);
335 HighlightProperty->SetDiffuse(0.3);
336 HighlightProperty->SetSpecular(0.2);
337 HighlightProperty->SetRepresentationToSurface();
338 HighlightProperty->SetAmbientColor(1, 1, 1);
339 HighlightProperty->SetDiffuseColor(1, 1, 1);
340 HighlightProperty->SetSpecularColor(0.5, 0.5, 0.5);
343 this->Property = HighlightProperty;
346 else if (!highlight) {
349 if(myDisplayMode==1) {
350 //unhilight in shading
351 this->Property = ShadingProperty;
354 //unhilight in wireframe
355 this->Property = WireframeProperty;
361 bool GEOM_Actor::hasHighlight()
366 void GEOM_Actor::SetHighlightProperty(vtkProperty* Prop) {
367 this->HighlightProperty = Prop;
371 void GEOM_Actor::ReleaseGraphicsResources(vtkWindow *renWin)
373 vtkActor::ReleaseGraphicsResources(renWin);
375 // broadcast the message down to the individual LOD mappers
377 if(WireframeMapper) this->WireframeMapper->ReleaseGraphicsResources(renWin);
378 if(ShadingMapper) this->ShadingMapper->ReleaseGraphicsResources(renWin);
382 // Copy the follower's composite 4x4 matrix into the matrix provided.
383 void GEOM_Actor::GetMatrix(vtkCamera* theCam, vtkMatrix4x4 *result)
386 double Rx[3], Ry[3], Rz[3], p1[3];
387 vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
391 this->GetOrientation();
392 this->Transform->Push();
393 this->Transform->PostMultiply();
394 this->Transform->Identity();
396 // apply user defined matrix last if there is one
397 if (this->UserMatrix)
399 this->Transform->Concatenate(this->UserMatrix);
402 this->Transform->Translate(-this->Origin[0],
406 this->Transform->Scale(this->Scale[0],
411 this->Transform->RotateY(this->Orientation[1]);
412 this->Transform->RotateX(this->Orientation[0]);
413 this->Transform->RotateZ(this->Orientation[2]);
419 pos = theCam->GetPosition();
420 vup = theCam->GetViewUp();
422 if (theCam->GetParallelProjection())
424 theCam->GetDirectionOfProjection(Rz);
429 (pos[0] - this->Position[0])*(pos[0] - this->Position[0]) +
430 (pos[1] - this->Position[1])*(pos[1] - this->Position[1]) +
431 (pos[2] - this->Position[2])*(pos[2] - this->Position[2]));
432 for (i = 0; i < 3; i++)
434 Rz[i] = (pos[i] - this->Position[i])/distance;
438 vtkMath::Cross(vup,Rz,Rx);
439 vtkMath::Normalize(Rx);
440 vtkMath::Cross(Rz,Rx,Ry);
442 matrix->Element[0][0] = Rx[0];
443 matrix->Element[1][0] = Rx[1];
444 matrix->Element[2][0] = Rx[2];
445 matrix->Element[0][1] = Ry[0];
446 matrix->Element[1][1] = Ry[1];
447 matrix->Element[2][1] = Ry[2];
448 matrix->Element[0][2] = Rz[0];
449 matrix->Element[1][2] = Rz[1];
450 matrix->Element[2][2] = Rz[2];
452 this->Transform->Concatenate(matrix);
455 // translate to projection reference point PRP
456 // this is the camera's position blasted through
457 // the current matrix
458 p1[0] = this->Origin[0] + this->Position[0];
459 p1[1] = this->Origin[1] + this->Position[1];
460 p1[2] = this->Origin[2] + this->Position[2];
462 this->Transform->Translate(p1[0],p1[1],p1[2]);
463 this->Transform->GetMatrix(result);
466 this->Transform->Pop();