<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0in;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:#0563C1;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:#954F72;
        text-decoration:underline;}
span.EmailStyle17
        {mso-style-type:personal-compose;
        font-family:"Calibri",sans-serif;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-family:"Calibri",sans-serif;}
@page WordSection1
        {size:8.5in 11.0in;
        margin:1.0in 1.0in 1.0in 1.0in;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="EN-US" link="#0563C1" vlink="#954F72">
<div class="WordSection1">
<p class="MsoNormal">Hi,<o:p></o:p></p>
<p class="MsoNormal">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.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">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.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">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.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">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.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">This is my failed attempt: It causes Python to immediately crash without error message.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">cap_array_filter = vtk.vtkProgrammableFilter()<o:p></o:p></p>
<p class="MsoNormal">cap_array_filter.SetInputConnection(camera_dist_b.GetOutputPort())<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">def cap_array():<o:p></o:p></p>
<p class="MsoNormal">    d2c_array = cap_array_filter.GetPolyDataInput().GetPointData().GetArray('DistanceToCamera')<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">    new_array = vtk.vtkDoubleArray()<o:p></o:p></p>
<p class="MsoNormal">    new_array.SetName('DistanceToCameraCapped')<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">    for i in range(0, d2c_array.GetSize()):<o:p></o:p></p>
<p class="MsoNormal">        new_value = d2c_array.GetTuple1(i)<o:p></o:p></p>
<p class="MsoNormal">        if new_value < 1:<o:p></o:p></p>
<p class="MsoNormal">            new_value = 1<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        new_array.InsertNextValue(new_value)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">    cap_array_filter.GetPointData().AddArray(new_array)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">cap_array_filter.SetExecuteMethod(cap_array)<o:p></o:p></p>
<p class="MsoNormal">camera_dist_b.SetInputConnection(cap_array_filter.GetOutputPort())<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">mapper_b = vtk.vtkGlyph3DMapper()<o:p></o:p></p>
<p class="MsoNormal">mapper_b.SetInputData(self.nominal_poly_data)<o:p></o:p></p>
<p class="MsoNormal">mapper_b.SetSourceConnection(sphere.GetOutputPort())<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">mapper_b.SetInputConnection(camera_dist_b.GetOutputPort())<o:p></o:p></p>
<p class="MsoNormal">mapper_b.SetInputArrayToProcess(0, 0, 0, vtk.vtkDataObject.FIELD_ASSOCIATION_POINTS, 'DistanceToCameraCapped')<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">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.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">class DistanceToCameraCapper(VTKPythonAlgorithmBase):<o:p></o:p></p>
<p class="MsoNormal">    def __init__(self):<o:p></o:p></p>
<p class="MsoNormal">        VTKPythonAlgorithmBase.__init__(self,<o:p></o:p></p>
<p class="MsoNormal">        nInputPorts=1, inputType= vtkDistanceToCamera,<o:p></o:p></p>
<p class="MsoNormal">        nOutputPorts=1, outputType= vtkDistanceToCamera)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">    def RequestData(self, request, inInfo, outInfo):<o:p></o:p></p>
<p class="MsoNormal">        print('Executing')<o:p></o:p></p>
<p class="MsoNormal">        input = vtk.vtkDistanceToCamera.GetData(inInfo[0])<o:p></o:p></p>
<p class="MsoNormal">        output = vtk.vtkDistanceToCamera.GetData(outInfo)<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        d2c = vtk.vtkDistanceToCamera()<o:p></o:p></p>
<p class="MsoNormal">        d2c.SetInputData(input)<o:p></o:p></p>
<p class="MsoNormal">        d2c.Update()<o:p></o:p></p>
<p class="MsoNormal">        output.ShallowCopy(d2c.GetOutput())<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">        return 1<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">I’d be grateful for any ideas or hints on how to accomplish this idea.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">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.<o:p></o:p></p>
<p class="MsoNormal"><o:p> </o:p></p>
<p class="MsoNormal">Thanks,<o:p></o:p></p>
<p class="MsoNormal">Travis Stuart<o:p></o:p></p>
</div>
</body>
</html>