10 #include <vtkImageData.h> 11 #include <vtkRenderer.h> 12 #include <vtkAbstractPicker.h> 13 #include <vtkPicker.h> 14 #include <vtkAbstractCellLocator.h> 15 #include <vtkIdList.h> 16 #include <vtkCellPicker.h> 17 #include <vtkLODProp3D.h> 18 #include <vtkMapper.h> 19 #include <vtkGenericCell.h> 21 #include <vtkTexture.h> 22 #include <vtkObjectFactory.h> 23 #include <vtkSmartPointer.h> 24 #include <vtkPoints.h> 25 #include <vtkProperty.h> 34 cell_ = vtkGenericCell::New();
62 vtkDataSet *data = mapper->GetInput();
63 double tMin = VTK_DOUBLE_MAX;
65 double pDistMin = VTK_DOUBLE_MAX;
66 vtkIdType minCellId = -1;
69 minXYZ[0] = minXYZ[1] = minXYZ[2] = 0.0;
70 double ray[3] = {p2[0]-p1[0], p2[1]-p1[1], p2[2]-p1[2]};
71 vtkMath::Normalize(ray);
72 vtkActor * actor = vtkActor::SafeDownCast(prop);
75 int isPolyData = data->IsA(
"vtkPolyData");
77 vtkCollectionSimpleIterator iter;
78 vtkAbstractCellLocator *locator = 0;
79 this->Locators->InitTraversal(iter);
80 while ( (locator = static_cast<vtkAbstractCellLocator *>(
81 this->Locators->GetNextItemAsObject(iter))) )
83 if (locator->GetDataSet() == data)
91 q1[0] = p1[0]; q1[1] = p1[1]; q1[2] = p1[2];
92 q2[0] = p2[0]; q2[1] = p2[1]; q2[2] = p2[2];
93 if (t1 != 0.0 || t2 != 1.0)
95 for (
int j = 0; j < 3; j++)
97 q1[j] = p1[j]*(1.0 - t1) + p2[j]*t1;
98 q2[j] = p1[j]*(1.0 - t2) + p2[j]*t2;
108 locator->IntersectWithLine(q1, q2, intersectPoints, intersectCells);
109 for(
int i = 0; i < intersectPoints->GetNumberOfPoints(); i++ )
112 intersectPoints->GetPoint(i, intersection);
115 if (!locator->IntersectWithLine(q1, q2, tol, tMin, minXYZ,
116 minPCoords, minSubId, minCellId,
119 return VTK_DOUBLE_MAX;
123 if (t1 != 0.0 || t2 != 1.0)
125 tMin = t1*(1.0 - tMin) + t2*tMin;
129 this->SubCellFromCell(this->
cell_, minSubId);
134 vtkIdType numCells = data->GetNumberOfCells();
136 for (vtkIdType cellId = 0; cellId < numCells; cellId++)
141 pcoords[0] = pcoords[1] = pcoords[2] = 0;
146 int cellType = data->GetCellType(cellId);
147 int useSubCells = this->HasSubCells(cellType);
151 data->GetCellPoints(cellId, pointIds);
152 numSubIds = this->GetNumberOfSubCells(pointIds, cellType);
156 for (
int subId = 0; subId < numSubIds; subId++)
161 this->GetSubCell(data, pointIds, subId, cellType, this->
cell_);
165 data->GetCell(cellId, this->
cell_);
172 cellPicked = this->
cell_->IntersectWithLine(
173 const_cast<double *>(p1), const_cast<double *>(p2),
174 tol, t, x, pcoords, newSubId);
181 cellPicked = this->
cell_->IntersectWithLine(
182 q1, q2, tol, t, x, pcoords, newSubId);
185 if (t1 != 0.0 || t2 != 1.0)
187 t = t1*(1.0 - t) + t2*t;
191 if (cellPicked && t <= (tMin + this->Tolerance) && t >= t1 && t <= t2)
193 double pDist = this->
cell_->GetParametricDistance(pcoords);
194 if (pDist < pDistMin || (pDist == pDistMin && t < tMin))
200 if(actor->GetProperty()->GetBackfaceCulling() ||
201 actor->GetProperty()->GetFrontfaceCulling())
204 vtkIdType numPoints = this->
cell_->GetNumberOfPoints();
205 double *weights =
new double[numPoints];
206 for (vtkIdType i = 0; i < numPoints; i++)
212 double point[3] = {0.0,0.0,0.0};
213 this->
cell_->EvaluateLocation(minSubId, minPCoords, point, weights);
215 double normal[3] = {0.0,0.0,0.0};
217 if (this->ComputeSurfaceNormal(data, this->
cell_, weights, normal))
219 if(actor->GetProperty()->GetBackfaceCulling())
221 visible = ray[0]*normal[0] + ray[1]*normal[1] + ray[2]*normal[2] <= 0;
225 visible = ray[0]*normal[0] + ray[1]*normal[1] + ray[2]*normal[2] >= 0;
241 for (
int k = 0; k < 3; k++)
244 minPCoords[k] = pcoords[k];
257 if (minCellId >= 0 && tMin < this->GlobalTMin)
259 this->ResetPickInfo();
262 vtkGenericCell *cell = this->
cell_;
267 int cellType = data->GetCellType(minCellId);
269 if (this->HasSubCells(cellType))
271 data->GetCellPoints(minCellId, this->
pointIds_);
272 this->GetSubCell(data, this->
pointIds_, minSubId, cellType, cell);
276 data->GetCell(minCellId, cell);
281 vtkIdType numPoints = cell->GetNumberOfPoints();
282 double *weights =
new double[numPoints];
283 for (vtkIdType i = 0; i < numPoints; i++)
290 cell->EvaluateLocation(minSubId, minPCoords, point, weights);
292 this->Mapper = mapper;
296 vtkLODProp3D *lodActor = 0;
297 if ( (actor = vtkActor::SafeDownCast(prop)) )
299 this->Texture = actor->GetTexture();
301 else if ( (lodActor = vtkLODProp3D::SafeDownCast(prop)) )
303 int lodId = lodActor->GetPickLODID();
304 lodActor->GetLODTexture(lodId, &this->Texture);
307 if (this->PickTextureData && this->Texture)
310 vtkImageData *image = this->Texture->GetInput();
311 this->DataSet = image;
315 image->GetExtent(extent);
316 int dimensionsAreValid = 1;
318 for (
int i = 0; i < 3; i++)
320 dimensions[i] = extent[2*i + 1] - extent[2*i] + 1;
321 dimensionsAreValid = (dimensionsAreValid && dimensions[i] > 0);
326 if (dimensionsAreValid &&
327 this->ComputeSurfaceTCoord(data, cell, weights, tcoord))
331 x[0] = extent[0] + tcoord[0]*dimensions[0] - 0.5;
332 x[1] = extent[2] + tcoord[1]*dimensions[1] - 0.5;
333 x[2] = extent[4] + tcoord[2]*dimensions[2] - 0.5;
335 this->SetImageDataPickInfo(x, extent);
341 this->DataSet = data;
342 this->CellId = minCellId;
343 this->SubId = minSubId;
344 this->PCoords[0] = minPCoords[0];
345 this->PCoords[1] = minPCoords[1];
346 this->PCoords[2] = minPCoords[2];
349 double maxWeight = 0;
350 vtkIdType iMaxWeight = -1;
351 for (vtkIdType i = 0; i < numPoints; i++)
353 if (weights[i] > maxWeight)
360 if (iMaxWeight != -1)
362 this->PointId = cell->PointIds->GetId(iMaxWeight);
367 this->MapperPosition[0] = minXYZ[0];
368 this->MapperPosition[1] = minXYZ[1];
369 this->MapperPosition[2] = minXYZ[2];
372 if (!this->ComputeSurfaceNormal(data, cell, weights, this->MapperNormal))
375 this->MapperNormal[0] = p1[0] - p2[0];
376 this->MapperNormal[1] = p1[1] - p2[1];
377 this->MapperNormal[2] = p1[2] - p2[2];
378 vtkMath::Normalize(this->MapperNormal);
vtkStandardNewMacro(CloudViewerCellPicker)
virtual double IntersectActorWithLine(const double p1[3], const double p2[3], double t1, double t2, double tol, vtkProp3D *prop, vtkMapper *mapper)
virtual ~CloudViewerCellPicker()