Scaling Glyphs by Camera but to a Limit

classic Classic list List threaded Threaded
1 message Options
Reply | Threaded
Open this post in threaded view
|

Scaling Glyphs by Camera but to a Limit

Stuart, Travis

Hi,

I’m having trouble achieving a particular rendering behavior with VTK. I would like to render glyphs of my point cloud with a fixed screen size up until the camera is zoomed in close enough for the glyph to be its actual size. I want them to be scaled up but not down.

 

I can fake this behavior by rendering two sets on top of each other. One set not scaled and the other scaled by distance to camera. But this is not ideal for huge data sets and I’d like to learn the correct way to solve this with one set.

 

At first I thought the scale clamping functionality of the vtkGlyph3DMapper could do this but setting the range to clamp seems to just scale the 'DistanceToCamera' values to the range.

 

One idea I had was to create a programmable filter that takes the vtkDistanceToCamera as input and outputs the same object but with an additional array. The same ‘DistanceToCamera’ array but with capped values below a certain threshold. Like any value under 1 would be set to 1.

 

This is my failed attempt: It causes Python to immediately crash without error message.

 

cap_array_filter = vtk.vtkProgrammableFilter()

cap_array_filter.SetInputConnection(camera_dist_b.GetOutputPort())

 

def cap_array():

    d2c_array = cap_array_filter.GetPolyDataInput().GetPointData().GetArray('DistanceToCamera')

 

    new_array = vtk.vtkDoubleArray()

    new_array.SetName('DistanceToCameraCapped')

 

    for i in range(0, d2c_array.GetSize()):

        new_value = d2c_array.GetTuple1(i)

        if new_value < 1:

            new_value = 1

 

        new_array.InsertNextValue(new_value)

 

    cap_array_filter.GetPointData().AddArray(new_array)

 

 

cap_array_filter.SetExecuteMethod(cap_array)

camera_dist_b.SetInputConnection(cap_array_filter.GetOutputPort())

 

mapper_b = vtk.vtkGlyph3DMapper()

mapper_b.SetInputData(self.nominal_poly_data)

mapper_b.SetSourceConnection(sphere.GetOutputPort())

 

mapper_b.SetInputConnection(camera_dist_b.GetOutputPort())

mapper_b.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_POINTS, 'DistanceToCameraCapped')

 

 

I also tried creating a VTKPythonAlgorithm to pass in a vtkDistanceToCamera and add the capped array. But I can’t get the instance to initialize without errors so not much progress there.

 

class DistanceToCameraCapper(VTKPythonAlgorithmBase):

    def __init__(self):

        VTKPythonAlgorithmBase.__init__(self,

        nInputPorts=1, inputType= vtkDistanceToCamera,

        nOutputPorts=1, outputType= vtkDistanceToCamera)

 

    def RequestData(self, request, inInfo, outInfo):

        print('Executing')

        input = vtk.vtkDistanceToCamera.GetData(inInfo[0])

        output = vtk.vtkDistanceToCamera.GetData(outInfo)

 

        d2c = vtk.vtkDistanceToCamera()

        d2c.SetInputData(input)

        d2c.Update()

        output.ShallowCopy(d2c.GetOutput())

 

        return 1

 

I’d be grateful for any ideas or hints on how to accomplish this idea.

 

I’ve attached a demonstration. The red spheres are not scaled. The green spheres are scaled by distance to camera. The purple spheres show the visual behavior that I want. It’s using the “fake” method of rendering two sets of spheres on top of each other. One set scaled and the other not.

 

Thanks,

Travis Stuart


_______________________________________________
Powered by www.kitware.com

Visit other Kitware open-source projects at http://www.kitware.com/opensource/opensource.html

Please keep messages on-topic and check the VTK FAQ at: http://www.vtk.org/Wiki/VTK_FAQ

Search the list archives at: http://markmail.org/search/?q=vtkusers

Follow this link to subscribe/unsubscribe:
https://vtk.org/mailman/listinfo/vtkusers

d2c limit example.py (3K) Download Attachment