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 // VISU OBJECT : interactive object for VISU entities implementation
23 // File : VISU_SelectVisiblePoints.h
24 // Author : Oleg UVAROV
27 #include "VISU_SelectVisiblePoints.h"
29 #include "vtkCamera.h"
30 #include "vtkCellArray.h"
31 #include "vtkDataSet.h"
32 #include "vtkMatrix4x4.h"
33 #include "vtkInformation.h"
34 #include "vtkInformationVector.h"
35 #include "vtkObjectFactory.h"
36 #include "vtkPointData.h"
37 #include "vtkPoints.h"
38 #include "vtkPolyData.h"
39 #include "vtkRenderWindow.h"
40 #include "vtkRenderer.h"
42 vtkStandardNewMacro(VISU_SelectVisiblePoints);
44 // Instantiate object with no renderer; window selection turned off;
45 // tolerance set to 0.01; and select invisible off.
46 VISU_SelectVisiblePoints::VISU_SelectVisiblePoints()
48 this->Offset[0] = this->Offset[1] = this->Offset[2] = 0.0;
51 VISU_SelectVisiblePoints::~VISU_SelectVisiblePoints()
55 int VISU_SelectVisiblePoints::RequestData(
56 vtkInformation *vtkNotUsed(request),
57 vtkInformationVector **inputVector,
58 vtkInformationVector *outputVector)
60 // get the info objects
61 vtkInformation *inInfo = inputVector[0]->GetInformationObject(0);
62 vtkInformation *outInfo = outputVector->GetInformationObject(0);
64 // get the input and ouptut
65 vtkDataSet *input = vtkDataSet::SafeDownCast(
66 inInfo->Get(vtkDataObject::DATA_OBJECT()));
67 vtkPolyData *output = vtkPolyData::SafeDownCast(
68 outInfo->Get(vtkDataObject::DATA_OBJECT()));
70 vtkIdType ptId, cellId;
73 vtkCellArray *outputVertices;
74 vtkPointData *inPD=input->GetPointData();
75 vtkPointData *outPD=output->GetPointData();
76 vtkIdType numPts=input->GetNumberOfPoints();
77 double x[4], xTrans[4];
81 if ( this->Renderer == NULL )
83 vtkErrorMacro(<<"Renderer must be set");
92 outPts = vtkPoints::New();
93 outPts->Allocate(numPts/2+1);
94 outPD->CopyAllocate(inPD);
96 outputVertices = vtkCellArray::New();
97 output->SetVerts(outputVertices);
98 outputVertices->Delete();
100 int *size = this->Renderer->GetRenderWindow()->GetSize();
102 // specify a selection window to avoid querying
103 if ( this->SelectionWindow )
105 for (int i=0; i<4; i++)
107 selection[i] = this->Selection[i];
112 selection[0] = selection[2] = 0;
113 selection[1] = size[0] - 1;
114 selection[3] = size[1] - 1;
117 // Grab the composite perspective transform. This matrix is used to convert
118 // each point to view coordinates. vtkRenderer provides a WorldToView()
119 // method but it computes the composite perspective transform each time
120 // WorldToView() is called. This is expensive, so we get the matrix once
121 // and handle the transformation ourselves.
122 vtkMatrix4x4 *matrix = vtkMatrix4x4::New();
124 matrix->DeepCopy(this->Renderer->GetActiveCamera()->
125 GetCompositePerspectiveTransformMatrix(
126 this->Renderer->GetTiledAspectRatio(),0,1));
128 // If we have more than a few query points, we grab the z-buffer for the
129 // selection region all at once and probe the resulting array. When we
130 // have just a few points, we perform individual z-buffer queries.
131 const int SimpleQueryLimit = 25;
133 if (numPts > SimpleQueryLimit)
135 zPtr = this->Renderer->GetRenderWindow()->
136 GetZbufferData(selection[0], selection[2], selection[1], selection[3]);
140 vtkIdType progressInterval=numPts/20+1;
142 for (cellId=(-1), ptId=0; ptId < numPts && !abort; ptId++)
144 // perform conversion
145 input->GetPoint(ptId,x);
147 // take into account translation offset (this is the only difference
148 // between this class and native vtkSelectVisiblePoints class)
149 xTrans[0] = x[0] + this->Offset[0];
150 xTrans[1] = x[1] + this->Offset[1];
151 xTrans[2] = x[2] + this->Offset[2];
154 matrix->MultiplyPoint(xTrans, view);
159 this->Renderer->SetViewPoint(view[0]/view[3], view[1]/view[3],
161 this->Renderer->ViewToDisplay();
162 this->Renderer->GetDisplayPoint(dx);
165 if ( ! (ptId % progressInterval) )
167 this->UpdateProgress((double)ptId/numPts);
168 abort = this->GetAbortExecute();
171 // check whether visible and in selection window
172 if ( dx[0] >= selection[0] && dx[0] <= selection[1] &&
173 dx[1] >= selection[2] && dx[1] <= selection[3] )
175 if (numPts > SimpleQueryLimit)
177 // Access the value from the captured zbuffer. Note, we only
178 // captured a portion of the zbuffer, so we need to offset dx by
179 // the selection window.
180 z = zPtr[(int)dx[0] - selection[0]
181 + ((int)dx[1] - selection[2])
182 *(selection[1] - selection[0] + 1)];
186 z = this->Renderer->GetZ(static_cast<int>(dx[0]),
187 static_cast<int>(dx[1]));
189 if( dx[2] < (z + this->Tolerance) )
195 if ( (visible && !this->SelectInvisible) ||
196 (!visible && this->SelectInvisible) )
198 cellId = outPts->InsertNextPoint(x);
199 output->InsertNextCell(VTK_VERTEX, 1, &cellId);
200 outPD->CopyData(inPD,ptId,cellId);
204 output->SetPoints(outPts);
215 vtkDebugMacro(<<"Selected " << cellId + 1 << " out of "
216 << numPts << " original points");
221 void VISU_SelectVisiblePoints::PrintSelf(ostream& os, vtkIndent indent)
223 this->Superclass::PrintSelf(os,indent);
225 os << indent << "Offset: ("
226 << this->Offset[0] << ", "
227 << this->Offset[1] << ", "
228 << this->Offset[2] << ")\n";