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 // GEOM OBJECT : interactive object for Geometry entities visualization
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.
33 #include "GEOM_Actor.h"
35 #include "GEOM_DeviceActor.h"
36 #include "GEOM_VertexSource.h"
37 #include "GEOM_EdgeSource.h"
38 #include "GEOM_WireframeFace.h"
39 #include "GEOM_ShadingFace.h"
40 #include "SVTK_Actor.h"
42 #include <OCC2VTK_Tools.h>
44 #include <vtkObjectFactory.h>
45 #include <vtkRenderer.h>
46 #include <vtkProperty.h>
47 #include <vtkPointPicker.h>
48 #include <vtkCellPicker.h>
50 #include <TopAbs_ShapeEnum.hxx>
51 #include <TopExp_Explorer.hxx>
53 #include <BRep_Tool.hxx>
56 #include <vtkPolyDataWriter.h>
58 #include <vtkAppendPolyData.h>
59 #include <vtkPolyDataMapper.h>
60 #include <vtkPolyData.h>
61 #include <vtkTransform.h>
62 #include <vtkMatrix4x4.h>
64 #include <vtkCamera.h>
66 #include "utilities.h"
68 #include "SALOME_InteractiveObject.hxx"
70 //vtkStandardNewMacro(GEOM_Actor);
76 GEOM_Actor::GEOM_Actor():
82 // myDisplayMode(eWireframe),
86 myVertexActor(GEOM_DeviceActor::New(),true),
87 myVertexSource(GEOM_VertexSource::New(),true),
89 myIsolatedEdgeActor(GEOM_DeviceActor::New(),true),
90 myIsolatedEdgeSource(GEOM_EdgeSource::New(),true),
92 myOneFaceEdgeActor(GEOM_DeviceActor::New(),true),
93 myOneFaceEdgeSource(GEOM_EdgeSource::New(),true),
95 mySharedEdgeActor(GEOM_DeviceActor::New(),true),
96 mySharedEdgeSource(GEOM_EdgeSource::New(),true),
98 myWireframeFaceActor(GEOM_DeviceActor::New(),true),
99 myWireframeFaceSource(GEOM_WireframeFace::New(),true),
101 myShadingFaceActor(GEOM_DeviceActor::New(),true),
102 myShadingFaceSource(GEOM_ShadingFace::New(),true),
104 myHighlightActor(GEOM_DeviceActor::New(),true),
105 myAppendFilter(vtkAppendPolyData::New(),true),
106 myPolyDataMapper(vtkPolyDataMapper::New(),true),
108 myHighlightProp(vtkProperty::New()),
109 myPreHighlightProp(vtkProperty::New()),
110 myShadingFaceProp(vtkProperty::New())
113 MESSAGE (this<< " GEOM_Actor::GEOM_Actor");
116 myPolyDataMapper->SetInput(myAppendFilter->GetOutput());
117 vtkProperty* aProperty;
119 myHighlightProp->SetAmbient(0.5);
120 myHighlightProp->SetDiffuse(0.3);
121 myHighlightProp->SetSpecular(0.2);
122 myHighlightProp->SetRepresentationToSurface();
123 myHighlightProp->SetAmbientColor(1, 1, 1);
124 myHighlightProp->SetDiffuseColor(1, 1, 1);
125 myHighlightProp->SetSpecularColor(0.5, 0.5, 0.5);
126 myHighlightProp->SetPointSize(SALOME_POINT_SIZE);
127 myHighlightActor->SetProperty(myHighlightProp.GetPointer());
129 this->myHighlightActor->SetInput(myAppendFilter->GetOutput(),false);
131 myPreHighlightProp->SetColor(0,1,1);
132 myPreHighlightProp->SetPointSize(SALOME_POINT_SIZE+2);
133 myPreHighlightProp->SetLineWidth(SALOME_LINE_WIDTH+1);
134 myPreHighlightProp->SetRepresentationToWireframe();
136 myAppendFilter->AddInput(myVertexSource->GetOutput());
137 myVertexActor->SetInput(myVertexSource->GetOutput(),false);
138 aProperty = myVertexActor->GetProperty();
139 aProperty->SetRepresentation(VTK_POINTS);
140 aProperty->SetPointSize(3);
141 aProperty->SetColor(1, 1, 0);
143 myAppendFilter->AddInput(myIsolatedEdgeSource->GetOutput());
144 myIsolatedEdgeActor->SetInput(myIsolatedEdgeSource->GetOutput(),false);
145 aProperty = myIsolatedEdgeActor->GetProperty();
146 aProperty->SetRepresentation(VTK_WIREFRAME);
147 aProperty->SetColor(1, 0, 0);
149 myAppendFilter->AddInput(myOneFaceEdgeSource->GetOutput());
150 myOneFaceEdgeActor->SetInput(myOneFaceEdgeSource->GetOutput(),false);
151 aProperty = myOneFaceEdgeActor->GetProperty();
152 aProperty->SetRepresentation(VTK_WIREFRAME);
153 aProperty->SetColor(0, 1, 0);
155 myAppendFilter->AddInput(mySharedEdgeSource->GetOutput());
156 mySharedEdgeActor->SetInput(mySharedEdgeSource->GetOutput(),false);
157 aProperty = mySharedEdgeActor->GetProperty();
158 aProperty->SetRepresentation(VTK_WIREFRAME);
159 aProperty->SetColor(1, 1, 0);
161 myAppendFilter->AddInput(myWireframeFaceSource->GetOutput());
162 myWireframeFaceActor->SetInput(myWireframeFaceSource->GetOutput(),false);
163 aProperty = myWireframeFaceActor->GetProperty();
164 aProperty->SetRepresentation(VTK_WIREFRAME);
165 aProperty->SetColor(0.5, 0.5, 0.5);
167 myShadingFaceActor->SetInput(myShadingFaceSource->GetOutput(),true);
169 myShadingFaceProp->SetRepresentation(VTK_SURFACE);
170 myShadingFaceProp->SetInterpolationToGouraud();
171 myShadingFaceProp->SetAmbient(1.0);
172 myShadingFaceProp->SetDiffuse(1.0);
173 myShadingFaceProp->SetSpecular(0.4);
174 myShadingFaceProp->SetAmbientColor(0.329412, 0.223529, 0.027451);
175 myShadingFaceProp->SetDiffuseColor(0.780392, 0.568627, 0.113725);
176 myShadingFaceProp->SetSpecularColor(0.992157, 0.941176, 0.807843);
178 myShadingFaceActor->SetProperty(myShadingFaceProp.GetPointer());
180 // Toggle display mode
181 setDisplayMode(0); // WIRE FRAME
187 GEOM_Actor::~GEOM_Actor()
190 MESSAGE (this<< " ~GEOM_Actor::GEOM_Actor");
192 myHighlightProp->Delete();
193 myPreHighlightProp->Delete();
194 myShadingFaceProp->Delete();
201 GEOM_Actor* anObject = new GEOM_Actor();
202 anObject->SetMapper(anObject->myPolyDataMapper.Get());
207 void Write(vtkPolyData* theDataSet, const char* theFileName){
208 vtkPolyDataWriter* aWriter = vtkPolyDataWriter::New();
209 MESSAGE ("Write - "<<theFileName<<"' : "<<theDataSet->GetNumberOfPoints()<<"; "<<theDataSet->GetNumberOfCells());
210 aWriter->SetInput(theDataSet);
211 aWriter->SetFileName(theFileName);
220 this->myVertexSource->Modified();
221 this->myIsolatedEdgeSource->Modified();
222 this->myOneFaceEdgeSource->Modified();
223 this->mySharedEdgeSource->Modified();
224 this->myWireframeFaceSource->Modified();
225 this->myShadingFaceSource->Modified();
230 SetMapper(vtkMapper* theMapper)
232 SALOME_Actor::SetMapper(theMapper);
237 AddToRender(vtkRenderer* theRenderer)
239 //SALOME_Actor::AddToRender(theRenderer);
241 theRenderer->AddActor(this);
243 this->myHighlightActor->AddToRender(theRenderer);
246 myShadingFaceActor->AddToRender(theRenderer);
247 myWireframeFaceActor->AddToRender(theRenderer);
249 mySharedEdgeActor->AddToRender(theRenderer);
250 myOneFaceEdgeActor->AddToRender(theRenderer);
251 myIsolatedEdgeActor->AddToRender(theRenderer);
253 myVertexActor->AddToRender(theRenderer);
258 RemoveFromRender(vtkRenderer* theRenderer)
260 //SALOME_Actor::RemoveFromRender(theRenderer);
263 theRenderer->RemoveActor(this);
265 myHighlightActor->RemoveFromRender(theRenderer);
266 myShadingFaceActor->RemoveFromRender(theRenderer);
267 myWireframeFaceActor->RemoveFromRender(theRenderer);
269 mySharedEdgeActor->RemoveFromRender(theRenderer);
270 myOneFaceEdgeActor->RemoveFromRender(theRenderer);
271 myIsolatedEdgeActor->RemoveFromRender(theRenderer);
273 myVertexActor->RemoveFromRender(theRenderer);
277 SetVisibility(false);
282 setDisplayMode(int theMode)
285 MESSAGE ( "GEOM_Actor::SetDisplayMode = "<<theMode );
287 VTKViewer_Actor::setDisplayMode(theMode);
288 SetVisibility(GetVisibility());
293 SetSelected(bool theIsSelected)
296 MESSAGE ( "GEOM_Actor::SetSelected = "<<theIsSelected );
299 myIsSelected = theIsSelected;
300 SetVisibility(GetVisibility());
305 SetVisibility(int theVisibility)
308 MESSAGE ( "GEOM_Actor::SetVisibility = "<<theVisibility <<" myIsSelected="<< myIsSelected
309 << " theVisibility="<<theVisibility<<" myIsPreselected="<<myIsPreselected );
312 SALOME_Actor::SetVisibility(theVisibility);
314 this->myHighlightActor->SetVisibility(theVisibility && (myIsSelected || myIsPreselected));
316 myShadingFaceActor->SetVisibility(theVisibility && (myDisplayMode == (int)eShading) && (!myIsSelected || !myIsPreselected));
317 myWireframeFaceActor->SetVisibility(theVisibility && (myDisplayMode ==(int)eWireframe) && !myIsSelected);
319 mySharedEdgeActor->SetVisibility(theVisibility && myDisplayMode == (int)eWireframe && !myIsSelected);
320 myOneFaceEdgeActor->SetVisibility(theVisibility && myDisplayMode == (int)eWireframe && !myIsSelected);
321 myIsolatedEdgeActor->SetVisibility(theVisibility && !myIsSelected);
323 myVertexActor->SetVisibility(theVisibility && !myIsSelected);// must be added new mode points
329 ::SetNbIsos(const int theNb[2])
331 myWireframeFaceSource->SetNbIso(theNb);
336 ::GetNbIsos(int &theNbU,int &theNbV)
338 myWireframeFaceSource->GetNbIso(theNbU, theNbV);
343 ::SetVectorMode(bool theMode)
345 myVectorMode = theMode;
346 myIsolatedEdgeSource->SetVectorMode(theMode);
347 myOneFaceEdgeSource->SetVectorMode(theMode);
348 mySharedEdgeSource->SetVectorMode(theMode);
361 SetDeflection(float theDeflection)
363 if( myDeflection == theDeflection )
366 myDeflection = theDeflection;
368 GEOM::MeshShape(myShape,myDeflection);
373 void GEOM_Actor::SetShape (const TopoDS_Shape& theShape,
379 myVertexSource->Clear();
380 myIsolatedEdgeSource->Clear();
381 myOneFaceEdgeSource->Clear();
382 mySharedEdgeSource->Clear();
383 myWireframeFaceSource->Clear();
384 myShadingFaceSource->Clear();
386 TopExp_Explorer aVertexExp (theShape,TopAbs_VERTEX);
387 for (; aVertexExp.More(); aVertexExp.Next())
389 const TopoDS_Vertex& aVertex = TopoDS::Vertex(aVertexExp.Current());
390 myVertexSource->AddVertex(aVertex);
393 SetDeflection(theDeflection);
395 // look if edges are free or shared
396 TopTools_IndexedDataMapOfShapeListOfShape anEdgeMap;
397 TopExp::MapShapesAndAncestors(theShape,TopAbs_EDGE,TopAbs_FACE,anEdgeMap);
399 GEOM::SetShape(theShape,anEdgeMap,theIsVector,
400 myIsolatedEdgeSource.Get(),
401 myOneFaceEdgeSource.Get(),
402 mySharedEdgeSource.Get(),
403 myWireframeFaceSource.Get(),
404 myShadingFaceSource.Get());
406 myIsolatedEdgeSource->IsEmpty() &&
407 myOneFaceEdgeSource->IsEmpty() &&
408 mySharedEdgeSource->IsEmpty() &&
409 myWireframeFaceSource->IsEmpty() &&
410 myShadingFaceSource->IsEmpty();
413 if((bool)myShape.Infinite() || isOnlyVertex ){
414 myVertexActor->GetDeviceActor()->SetInfinitive(true);
415 myHighlightActor->GetDeviceActor()->SetInfinitive(true);
420 void GEOM_Actor::setDeflection(double adef) {
422 MESSAGE ( "GEOM_Actor::setDeflection" );
424 SetDeflection((float)adef);
428 // warning! must be checked!
429 // SetHighlightProperty
430 // SetWireframeProperty
431 // SetShadingProperty
433 void GEOM_Actor::SetHighlightProperty(vtkProperty* Prop)
436 MESSAGE ( "GEOM_Actor::SetHighlightProperty" );
438 this->myHighlightActor->GetProperty()->DeepCopy(Prop);
442 void GEOM_Actor::SetWireframeProperty(vtkProperty* Prop)
445 MESSAGE ( this << " GEOM_Actor::SetWireframeProperty" );
448 myWireframeFaceActor->SetProperty(Prop);
451 void GEOM_Actor::SetShadingProperty(vtkProperty* Prop)
454 MESSAGE ( "GEOM_Actor::SetShadingProperty" );
456 myShadingFaceProp->DeepCopy(Prop);
460 void GEOM_Actor::Render(vtkRenderer *ren, vtkMapper *theMapper)
463 MESSAGE ( "GEOM_Actor::Render" );
469 /* render the property */
470 if (!this->Property) {
471 // force creation of a property
473 this->Property->SetInterpolation(1);
474 this->Property->SetRepresentationToSurface();
475 this->Property->SetAmbient(0.3);
476 this->Property->SetAmbientColor(0.88,0.86,0.2);
477 this->Property->SetDiffuseColor(0.99,0.7,0.21);
478 this->Property->SetSpecularColor(0.99,0.98,0.83);
481 switch(myDisplayMode){
483 myPreHighlightProp->SetRepresentationToWireframe();
484 myHighlightProp->SetRepresentationToWireframe();
487 myPreHighlightProp->SetRepresentationToSurface();
488 myHighlightProp->SetRepresentationToSurface();
494 this->myHighlightActor->SetProperty(myPreHighlightProp.GetPointer());
495 myShadingFaceActor->SetProperty(myPreHighlightProp.GetPointer());
497 this->myHighlightActor->SetProperty(myShadingFaceProp.GetPointer());
498 myShadingFaceActor->SetProperty(myShadingFaceProp.GetPointer());
502 this->myHighlightActor->SetProperty(myHighlightProp.GetPointer());
503 myShadingFaceActor->SetProperty(myHighlightProp.GetPointer());
506 this->Property->Render(this, ren);
507 if (this->BackfaceProperty) {
508 this->BackfaceProperty->BackfaceRender(this, ren);
509 this->Device->SetBackfaceProperty(this->BackfaceProperty);
511 this->Device->SetProperty(this->Property);
512 /* if(myShape.ShapeType() == TopAbs_VERTEX) {
514 //The parameter determine size of vertex actor relate to diagonal of RendererWindow
515 static vtkFloatingPointType delta = 0.01;
516 vtkFloatingPointType X1 = -1, Y1 = -1, Z1 = 0;
517 ren->ViewToWorld(X1,Y1,Z1);
518 vtkFloatingPointType X2 = +1, Y2 = +1, Z2 = 0;
519 ren->ViewToWorld(X2,Y2,Z2);
520 Z2 = sqrt((X2-X1)*(X2-X1) + (Y2-Y1)*(Y2-Y1) + (Z2-Z1)*(Z2-Z1));
521 this->SetScale(Z2*delta);
523 vtkMatrix4x4 *aMatrix = vtkMatrix4x4::New();
524 this->GetMatrix(ren->GetActiveCamera(), aMatrix);
525 this->Device->SetUserMatrix(aMatrix);
526 this->Device->Render(ren,theMapper);
529 this->Device->Render(ren, theMapper);
532 void GEOM_Actor::ReleaseGraphicsResources(vtkWindow *)
535 MESSAGE ( "GEOM_Actor::ReleaseGraphicsResources" );
541 void GEOM_Actor::ShallowCopy(vtkProp *prop)
544 MESSAGE ( "GEOM_Actor::ShallowCopy" );
546 GEOM_Actor *f = GEOM_Actor::SafeDownCast(prop);
549 this->SetShape(f->getTopo(),f->GetDeflection());
553 this->SALOME_Actor::ShallowCopy(prop);
556 const TopoDS_Shape& GEOM_Actor::getTopo() {
558 MESSAGE ( "GEOM_Actor::getTopo" );
563 void GEOM_Actor::setInputShape(const TopoDS_Shape& ashape, double adef1,
564 int imode, bool isVector)
567 MESSAGE ( "GEOM_Actor::setInputShape" );
571 double GEOM_Actor::getDeflection()
574 MESSAGE ( "GEOM_Actor::getDeflection" );
576 return (double) GetDeflection();
580 double GEOM_Actor::isVector()
583 MESSAGE ( "GEOM_Actor::isVector" );
588 void GEOM_Actor::SubShapeOn()
591 MESSAGE ( "GEOM_Actor::SubShapeOn" );
595 void GEOM_Actor::SubShapeOff()
598 MESSAGE ( "GEOM_Actor::SubShapeOff" );
602 void GEOM_Actor::highlight(bool highlight)
605 MESSAGE ( this << " GEOM_Actor::highlight highlight="<<highlight );
607 SALOME_Actor::highlight(highlight);
610 void GEOM_Actor::SetOpacity(vtkFloatingPointType opa)
613 myShadingFaceProp->SetOpacity(opa);
614 myHighlightProp->SetOpacity(opa);
615 myPreHighlightProp->SetOpacity(opa);
616 myVertexActor->GetProperty()->SetOpacity(opa);
619 vtkFloatingPointType GEOM_Actor::GetOpacity()
622 return myShadingFaceProp->GetOpacity();
625 void GEOM_Actor::SetColor(vtkFloatingPointType r,vtkFloatingPointType g,vtkFloatingPointType b)
628 myShadingFaceProp->SetColor(r,g,b); // shading color (Shading)
629 myIsolatedEdgeActor->GetProperty()->SetColor(r,g,b); // standalone edge color (Wireframe)
630 myVertexActor->GetProperty()->SetColor(r,g,b); // vertex actor (Shading/Wireframe)
631 myOneFaceEdgeActor->GetProperty()->SetColor(r,g,b); // standalone face edge color (Wireframe)
632 mySharedEdgeActor->GetProperty()->SetColor(r,g,b); // share edge color (Wireframe)
635 void GEOM_Actor::GetColor(vtkFloatingPointType& r,vtkFloatingPointType& g,vtkFloatingPointType& b)
638 vtkFloatingPointType aRGB[3];
639 myShadingFaceProp->GetColor(aRGB);
645 bool GEOM_Actor::IsInfinitive()
647 return ((bool)myShape.Infinite() || isOnlyVertex);
651 To map current selection to VTK representation
655 ::Highlight(bool theIsHighlight)
657 myIsSelected = theIsHighlight;
659 MESSAGE ( this << " GEOM_Actor::Highlight myIsSelected="<<myIsSelected );
662 SALOME_Actor::Highlight(theIsHighlight); // this method call ::highlight(theIsHighlight) in the end
663 SetVisibility(GetVisibility());
667 To process prehighlight (called from SVTK_InteractorStyle)
671 ::PreHighlight(vtkInteractorStyle *theInteractorStyle,
672 SVTK_SelectionEvent* theSelectionEvent,
676 MESSAGE ( this<<" GEOM_Actor::PreHighlight (3) theIsHighlight="<<theIsHighlight );
679 if ( !GetPickable() )
682 myPreHighlightActor->SetVisibility( false );
683 bool anIsPreselected = myIsPreselected;
685 Selection_Mode aSelectionMode = theSelectionEvent->mySelectionMode;
686 bool anIsChanged = (mySelectionMode != aSelectionMode);
688 if( !theIsHighlight ) {
689 SetPreSelected( false );
691 switch(aSelectionMode){
692 case ActorSelection :
694 // cout << "=============== " << myIO->getEntry() << endl;
695 // int nbio = mySelector->IObjectCount();
696 // cout << " nbio = " << nbio << endl;
698 if( !mySelector->IsSelected( myIO ) ) {
699 // printf ("!!!!!!!!!!!!!!!!\n");
700 SetPreSelected( true );
708 mySelectionMode = aSelectionMode;
709 anIsChanged |= (anIsPreselected != myIsPreselected);
711 SetVisibility(GetVisibility());
716 To process highlight (called from SVTK_InteractorStyle)
720 ::Highlight(vtkInteractorStyle *theInteractorStyle,
721 SVTK_SelectionEvent* theSelectionEvent,
724 // define the selection of object
726 MESSAGE ( std::endl << this << " GEOM_Actor::Highlight (3) myIsSelected="<<myIsSelected );
728 bool aRet = SALOME_Actor::Highlight(theInteractorStyle,theSelectionEvent,theIsHighlight);
729 SetSelected(theIsHighlight);
731 SetPreSelected(false);
737 // Copy the follower's composite 4x4 matrix into the matrix provided.
738 void GEOM_Actor::GetMatrix(vtkCamera* theCam, vtkMatrix4x4 *result)
741 double Rx[3], Ry[3], Rz[3], p1[3];
742 vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
746 this->GetOrientation();
747 this->Transform->Push();
748 this->Transform->PostMultiply();
749 this->Transform->Identity();
751 // apply user defined matrix last if there is one
752 if (this->UserMatrix)
754 this->Transform->Concatenate(this->UserMatrix);
757 this->Transform->Translate(-this->Origin[0],
761 this->Transform->Scale(this->Scale[0],
766 this->Transform->RotateY(this->Orientation[1]);
767 this->Transform->RotateX(this->Orientation[0]);
768 this->Transform->RotateZ(this->Orientation[2]);
774 pos = theCam->GetPosition();
775 vup = theCam->GetViewUp();
777 if (theCam->GetParallelProjection())
779 theCam->GetDirectionOfProjection(Rz);
784 (pos[0] - this->Position[0])*(pos[0] - this->Position[0]) +
785 (pos[1] - this->Position[1])*(pos[1] - this->Position[1]) +
786 (pos[2] - this->Position[2])*(pos[2] - this->Position[2]));
787 for (i = 0; i < 3; i++)
789 Rz[i] = (pos[i] - this->Position[i])/distance;
793 vtkMath::Cross(vup,Rz,Rx);
794 vtkMath::Normalize(Rx);
795 vtkMath::Cross(Rz,Rx,Ry);
797 matrix->Element[0][0] = Rx[0];
798 matrix->Element[1][0] = Rx[1];
799 matrix->Element[2][0] = Rx[2];
800 matrix->Element[0][1] = Ry[0];
801 matrix->Element[1][1] = Ry[1];
802 matrix->Element[2][1] = Ry[2];
803 matrix->Element[0][2] = Rz[0];
804 matrix->Element[1][2] = Rz[1];
805 matrix->Element[2][2] = Rz[2];
807 this->Transform->Concatenate(matrix);
810 // translate to projection reference point PRP
811 // this is the camera's position blasted through
812 // the current matrix
813 p1[0] = this->Origin[0] + this->Position[0];
814 p1[1] = this->Origin[1] + this->Position[1];
815 p1[2] = this->Origin[2] + this->Position[2];
817 this->Transform->Translate(p1[0],p1[1],p1[2]);
818 this->Transform->GetMatrix(result);
821 this->Transform->Pop();