Hi,<div><br></div><div>I have found a numerical precision problem with the method vtkCellLocator::IntersectWithLine.</div><div><div><br></div><div>in line 287 of revision 1.89:</div><div> if (cell->IntersectWithLine(a0, a1, tol, t, x, pcoords, subId) )</div>
<div> {</div><div> if ( ! this->IsInOctantBounds(x) ) </div><div><br></div></div><div>sometimes the resulting intersection point returned by the cell->IntersectWithLine is a (0.000000000000004) little out of the bounds and the call to IsInOctantBounds discard the point :(</div>
<div><br></div><div>following is an example that illustrates that.</div><div>a vtkCellLocator is filled with a cube and a line going from dPoint to dPoint2 intersect the box.</div><div>in Z axis, the bounds of the box are (1.0; -20)</div>
<div><br></div><div>if dPoint2[2] = -77.76333863288239, the resulting intersection point is at -20 and all is correct</div><div>if dPoint2[2] = -77.76333863288238, the resulting intersection point is at -20.000000000000004, so out of bounds.</div>
<div><br></div><div><br></div><div>So will it be a good thing to add a tolerance to the method vtkCellLocator::IsInOctantBounds(double x[3]) ?</div><div><div><br></div></div><div><br></div><div><br></div><div><div>#include <vtk/vtkActor.h></div>
<div>#include <vtk/vtkCamera.h></div><div>#include <vtk/vtkCellLocator.h></div><div>#include <vtk/vtkCubeSource.h></div><div>#include <vtk/vtkGenericCell.h></div><div>#include <vtk/vtkInteractorStyleTrackballCamera.h></div>
<div>#include <vtk/vtkLineSource.h></div><div>#include <vtk/vtkPolyData.h></div><div>#include <vtk/vtkPolyDataMapper.h></div><div>#include <vtk/vtkProperty.h></div><div>#include <vtk/vtkRenderer.h></div>
<div>#include <vtk/vtkRenderWindow.h></div><div>#include <vtk/vtkRenderWindowInteractor.h></div><div>#include <vtk/vtkSmartPointer.h></div><div>#include <vtk/vtkSphereSource.h></div><div>#include <vtk/vtkSTLReader.h></div>
<div>#include <vtk/vtkTriangleFilter.h></div><div><br></div><div>#define MY_SP(class, variable)\</div><div> vtkSmartPointer<class> variable = vtkSmartPointer<class>::New();</div><div><br></div><div>double dPoint[3] = {</div>
<div> 19.277858734130859,</div><div> 23.247093200683594,</div><div> -0.45018148422241211</div><div>};</div><div><br></div><div>double dPoint2[3] = {</div><div> 19.277858734130859,</div><div> 23.247093200683594,</div>
<div> // error</div><div> -77.76333863288238</div><div> // ok</div><div> //-77.76333863288239</div><div>};</div><div><br></div><div>//---------------------------------------------------------------------------------------------</div>
<div>void Test(vtkPolyData *data, double sourcePnt[3], double destinPnt[3])</div><div>{</div><div> MY_SP(vtkCellLocator, loc);</div><div> loc->SetTolerance(0.0);</div><div> loc->FreeSearchStructure();</div><div>
loc->CacheCellBoundsOn();</div><div> loc->AutomaticOn();</div><div> loc->SetDataSet(data);</div><div> loc->BuildLocator();</div><div> loc->Update();</div><div><br></div><div> vtkIdType cellId;</div>
<div> int subId;</div><div> double param_t, intersect[3], paraCoord[3];</div><div> vtkGenericCell *cell = vtkGenericCell::New();</div><div><br></div><div> if(! loc->IntersectWithLine(sourcePnt, destinPnt, 0.0010, param_t, </div>
<div> intersect, paraCoord, subId, cellId, cell) )</div><div> {</div><div> cout << "error" << endl;</div><div> }</div><div><br></div><div> cout << "intersection point: " << intersect[0] << " " << intersect[1] << " " << intersect[2] << endl;</div>
<div><br></div><div> cell->Delete();</div><div>}</div><div><br></div><div>//---------------------------------------------------------------------------------------------</div><div>int main(int , char* [])</div><div>{</div>
<div> MY_SP(vtkRenderer, ren1);</div><div> ren1->SetBackground(0.2, 0.2, 0.2);</div><div> MY_SP(vtkRenderWindow, renWin);</div><div> renWin->SetSize( 800, 800 );</div><div> renWin->AddRenderer(ren1);</div>
<div> MY_SP(vtkRenderWindowInteractor, iren);</div><div> iren->SetRenderWindow(renWin);</div><div><br></div><div> MY_SP(vtkInteractorStyleTrackballCamera, vtk_style);</div><div> iren->SetInteractorStyle(vtk_style);</div>
<div><br></div><div> /////</div><div> MY_SP(vtkCubeSource, cube);</div><div> cube->SetBounds(-43.5, 43.5, -35.0, 35.0, -20.0, 1.0);</div><div><br></div><div> MY_SP(vtkTriangleFilter, tri);</div><div> tri->SetInputConnection(cube->GetOutputPort());</div>
<div> tri->Update();</div><div><br></div><div> MY_SP(vtkPolyDataMapper, Mapper);</div><div> Mapper->SetInputConnection(tri->GetOutputPort());</div><div> Mapper->ImmediateModeRenderingOn();</div><div><br>
</div><div> MY_SP(vtkActor, Actor);</div><div> Actor->SetMapper(Mapper);</div><div> Actor->GetProperty()->SetRepresentationToWireframe();</div><div><br></div><div> ren1->AddActor(Actor);</div><div><br>
</div><div> //////</div><div> MY_SP(vtkSphereSource, sph);</div><div> sph->SetCenter(dPoint);</div><div> sph->SetRadius(1);</div><div> MY_SP(vtkPolyDataMapper, MapperSph);</div><div> MapperSph->SetInputConnection(sph->GetOutputPort());</div>
<div> MapperSph->ImmediateModeRenderingOn();</div><div><br></div><div> MY_SP(vtkActor, ActorSph);</div><div> ActorSph->SetMapper(MapperSph);</div><div> ActorSph->GetProperty()->SetColor(1.0, 0.0, 0.0);</div>
<div> ren1->AddActor(ActorSph);</div><div><br></div><div> MY_SP(vtkSphereSource, sph2);</div><div> sph2->SetCenter(dPoint2);</div><div> sph2->SetRadius(1);</div><div> MY_SP(vtkPolyDataMapper, MapperSph2);</div>
<div> MapperSph2->SetInputConnection(sph2->GetOutputPort());</div><div> MapperSph2->ImmediateModeRenderingOn();</div><div><br></div><div> MY_SP(vtkActor, ActorSph2);</div><div> ActorSph2->SetMapper(MapperSph2);</div>
<div> ActorSph2->GetProperty()->SetColor(0.0, 0.0, 1.0);</div><div> ren1->AddActor(ActorSph2);</div><div><br></div><div> MY_SP(vtkLineSource, line);</div><div> line->SetPoint1(dPoint);</div><div> line->SetPoint2(dPoint2);</div>
<div> MY_SP(vtkPolyDataMapper, Mapperline);</div><div> Mapperline->SetInputConnection(line->GetOutputPort());</div><div> Mapperline->ImmediateModeRenderingOn();</div><div><br></div><div> MY_SP(vtkActor, Actorline);</div>
<div> Actorline->SetMapper(Mapperline);</div><div> Actorline->GetProperty()->SetColor(0.0, 1.0, 0.0);</div><div> ren1->AddActor(Actorline);</div><div><br></div><div> Test(cube->GetOutput(), dPoint, dPoint2);</div>
<div><br></div><div> ren1->ResetCamera();</div><div> renWin->Render();</div><div> iren->Start();</div><div><br></div><div> ren1 = 0;</div><div><br></div><div> return 0;</div><div>}</div><div>//---------------------------------------------------------------------------------------------</div>
<div><br></div></div>