Commit 68bb565b authored by Ken Martin's avatar Ken Martin Committed by Kitware Robot

Merge topic 'update_pointgaussian'

779e58dd improve the picking on the pointgaussian mapper
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Acked-by: Utkarsh Ayachit's avatarUtkarsh Ayachit <utkarsh.ayachit@kitware.com>
Merge-request: !4278
parents 447b2067 779e58dd
......@@ -116,6 +116,7 @@ set(shader_files
glsl/vtkGaussianBlurPassVS.glsl
glsl/vtkGlyph3DVS.glsl
glsl/vtkPointGaussianVS.glsl
glsl/vtkPointGaussianGS.glsl
glsl/vtkPointFillPassFS.glsl
glsl/vtkPolyData2DFS.glsl
glsl/vtkPolyData2DVS.glsl
......
......@@ -26,6 +26,7 @@ vtk_add_test_cxx(vtkRenderingOpenGL2CxxTests tests
TestMultiTexturing.cxx
TestOffscreenRenderingResize.cxx
TestPointFillPass.cxx
TestPointGaussianSelection.cxx,NO_DATA
TestPropPicker2Renderers.cxx,NO_DATA
TestPointGaussianMapper.cxx
TestPointGaussianMapperOpacity.cxx
......
......@@ -30,6 +30,7 @@
#include "vtkActor.h"
#include "vtkCamera.h"
#include "vtkLookupTable.h"
#include "vtkProperty.h"
#include "vtkPointGaussianMapper.h"
#include "vtkRenderer.h"
......@@ -122,6 +123,16 @@ int TestPointGaussianMapper(int argc, char *argv[])
mapper->SetScaleArray("RandomPointVectors");
mapper->SetScaleArrayComponent(3);
// Note that LookupTable is 4x faster than
// ColorTransferFunction. So if you have a choice
// Usa a lut instead.
//
// vtkNew<vtkLookupTable> lut;
// lut->SetHueRange(0.1,0.2);
// lut->SetSaturationRange(1.0,0.5);
// lut->SetValueRange(0.8,1.0);
// mapper->SetLookupTable(lut);
vtkNew<vtkColorTransferFunction> ctf;
ctf->AddHSVPoint(0.0,0.1,1.0,0.8);
ctf->AddHSVPoint(1.0,0.2,0.5,1.0);
......
/*=========================================================================
Program: Visualization Toolkit
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
#include "vtkTestUtilities.h"
#include "vtkRegressionTestImage.h"
#include "vtkActor.h"
#include "vtkCamera.h"
#include "vtkLookupTable.h"
#include "vtkHardwareSelector.h"
#include "vtkIdTypeArray.h"
#include "vtkInformation.h"
#include "vtkNew.h"
#include "vtkPointGaussianMapper.h"
#include "vtkPointSource.h"
#include "vtkProp3DCollection.h"
#include "vtkRandomAttributeGenerator.h"
#include "vtkRenderedAreaPicker.h"
#include "vtkRenderer.h"
#include "vtkRenderWindowInteractor.h"
#include "vtkRenderWindow.h"
#include "vtkSelection.h"
#include "vtkSelectionNode.h"
int TestPointGaussianSelection(int argc, char *argv[])
{
int desiredPoints = 1.0e3;
vtkNew<vtkPointSource> points;
points->SetNumberOfPoints(desiredPoints);
points->SetRadius(pow(desiredPoints,0.33)*20.0);
points->Update();
vtkNew<vtkRandomAttributeGenerator> randomAttr;
randomAttr->SetInputConnection(points->GetOutputPort());
vtkNew<vtkPointGaussianMapper> mapper;
vtkNew<vtkRenderer> renderer;
renderer->SetBackground(0.0, 0.0, 0.0);
vtkNew<vtkRenderWindow> renderWindow;
renderWindow->SetSize(300, 300);
renderWindow->SetMultiSamples(0);
renderWindow->AddRenderer(renderer);
vtkNew<vtkRenderWindowInteractor> iren;
iren->SetRenderWindow(renderWindow);
vtkNew<vtkActor> actor;
actor->SetMapper(mapper);
renderer->AddActor(actor);
#ifdef TestPoints
randomAttr->SetDataTypeToUnsignedChar();
randomAttr->GeneratePointVectorsOn();
randomAttr->SetMinimumComponentValue(0);
randomAttr->SetMaximumComponentValue(255);
randomAttr->Update();
mapper->SetInputConnection(randomAttr->GetOutputPort());
mapper->SelectColorArray("RandomPointVectors");
mapper->SetScalarModeToUsePointFieldData();
mapper->SetScaleFactor(0.0);
mapper->EmissiveOff();
#else
randomAttr->SetDataTypeToFloat();
randomAttr->GeneratePointScalarsOn();
randomAttr->GeneratePointVectorsOn();
randomAttr->Update();
mapper->SetInputConnection(randomAttr->GetOutputPort());
mapper->SetColorModeToMapScalars();
mapper->SetScalarModeToUsePointFieldData();
mapper->SelectColorArray("RandomPointVectors");
mapper->SetInterpolateScalarsBeforeMapping(0);
mapper->SetScaleArray("RandomPointVectors");
mapper->SetScaleArrayComponent(3);
// Note that LookupTable is 4x faster than
// ColorTransferFunction. So if you have a choice
// Usa a lut instead.
//
vtkNew<vtkLookupTable> lut;
lut->SetHueRange(0.1,0.2);
lut->SetSaturationRange(1.0,0.5);
lut->SetValueRange(0.8,1.0);
mapper->SetLookupTable(lut);
#endif
renderWindow->Render();
renderer->GetActiveCamera()->Zoom(3.5);
renderWindow->Render();
vtkNew<vtkHardwareSelector> selector;
selector->SetFieldAssociation(vtkDataObject::FIELD_ASSOCIATION_POINTS);
selector->SetRenderer(renderer);
selector->SetArea(10,10,50,50);
vtkSelection *result = selector->Select();
bool goodPick = false;
if (result->GetNumberOfNodes() == 1)
{
vtkSelectionNode *node = result->GetNode(0);
vtkIdTypeArray *selIds = vtkArrayDownCast<vtkIdTypeArray>(
node->GetSelectionList());
// Separate the selection ids into atoms and bonds
if (selIds)
{
vtkIdType numIds = selIds->GetNumberOfTuples();
for (vtkIdType i = 0; i < numIds; ++i)
{
vtkIdType curId = selIds->GetValue(i);
cerr << curId << "\n";
}
}
if (node->GetProperties()->Has(vtkSelectionNode::PROP_ID())
&& node->GetProperties()->Get(vtkSelectionNode::PROP()) == actor.Get()
&& node->GetProperties()->Get(vtkSelectionNode::COMPOSITE_INDEX()) == 1
&& selIds
&& selIds->GetNumberOfTuples() == 15
&& selIds->GetValue(4) == 227
)
{
goodPick = true;
}
}
result->Delete();
if (!goodPick)
{
cerr << "Incorrect splats picked!\n";
return EXIT_FAILURE;
}
// Interact if desired
int retVal = vtkRegressionTestImage(renderWindow);
if ( retVal == vtkRegressionTester::DO_INTERACTOR)
{
iren->Start();
}
return !retVal;
}
//VTK::System::Dec
/*=========================================================================
Program: Visualization Toolkit
Module: vtkPolyDataWideLineGS.glsl
Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
All rights reserved.
See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
This software is distributed WITHOUT ANY WARRANTY; without even
the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
PURPOSE. See the above copyright notice for more information.
=========================================================================*/
// Template for the polydata mappers geometry shader
// primitiveID
//VTK::PrimID::Dec
// optional color passed in from the vertex shader, vertexColor
//VTK::Color::Dec
layout(points) in;
layout(triangle_strip, max_vertices = 3) out;
uniform int cameraParallel;
uniform float triangleScale;
uniform mat4 VCDCMatrix;
in float offsetVSOutput[];
out vec2 offsetVCGSOutput;
// clipping plane vars
//VTK::Clip::Dec
void main()
{
// the offsets sent down are positioned
// as radius*triangleScale from the center of the
// gaussian. This has to be consistent
// with the offsets we build into the VBO
float radius = offsetVSOutput[0]/triangleScale;
int i = 0;
vec4 offset;
vec4 base1 = vec4(1.0,0.0,0.0,0.0);
vec4 base2 = vec4(0.0,1.0,0.0,0.0);
// make the triangle face the camera
if (cameraParallel == 0)
{
vec3 dir = normalize(-gl_in[0].gl_Position.xyz);
base2 = vec4(normalize(cross(dir,vec3(1.0,0.0,0.0))), 0.0);
base1 = vec4(cross(base2.xyz,dir),0.0);
}
//VTK::PrimID::Impl
//VTK::Clip::Impl
//VTK::Color::Impl
offset = vec4(-2.0*offsetVSOutput[0], -offsetVSOutput[0], 0.0, 0.0);
offsetVCGSOutput = offset.xy/radius;
gl_Position = VCDCMatrix * (gl_in[0].gl_Position + offset.x*base1 + offset.y*base2);
EmitVertex();
offset = vec4(2.0*offsetVSOutput[0], -offsetVSOutput[0], 0.0, 0.0);
offsetVCGSOutput = offset.xy/radius;
gl_Position = VCDCMatrix * (gl_in[0].gl_Position + offset.x*base1 + offset.y*base2);
EmitVertex();
offset = vec4(0.0, 2.0*offsetVSOutput[0], 0.0, 0.0);
offsetVCGSOutput = offset.xy/radius;
gl_Position = VCDCMatrix * (gl_in[0].gl_Position + offset.x*base1 + offset.y*base2);
EmitVertex();
EndPrimitive();
}
......@@ -17,7 +17,7 @@
// this shader implements imposters in OpenGL for Spheres
in vec4 vertexMC;
in vec2 offsetMC;
in float offsetMC;
// optional normal declaration
//VTK::Normal::Dec
......@@ -34,10 +34,7 @@ in vec2 offsetMC;
// camera and actor matrix values
//VTK::Camera::Dec
out vec2 offsetVCVSOutput;
uniform int cameraParallel;
uniform float triangleScale;
out float offsetVSOutput;
void main()
{
......@@ -52,26 +49,7 @@ void main()
// compute the projected vertex position
vec4 vertexVC = MCVCMatrix * vertexMC;
// the offsets sent down are positioned
// at 2.0*radius*triangleScale from the center of the
// gaussian. This has to be consistent
// with the offsets we build into the VBO
float radius = 0.5*sqrt(dot(offsetMC,offsetMC))/triangleScale;
// make the triangle face the camera
if (cameraParallel == 0)
{
vec3 dir = normalize(-vertexVC.xyz);
vec3 base2 = normalize(cross(dir,vec3(1.0,0.0,0.0)));
vec3 base1 = cross(base2,dir);
vertexVC.xyz = vertexVC.xyz + offsetMC.x*base1 + offsetMC.y*base2;
}
else
{
// add in the offset
vertexVC.xy = vertexVC.xy + offsetMC;
}
offsetVCVSOutput = offsetMC/radius;
gl_Position = VCDCMatrix * vertexVC;
offsetVSOutput = offsetMC;
gl_Position = vertexVC;
}
......@@ -37,6 +37,7 @@
#include "vtkShaderProgram.h"
#include "vtkPointGaussianVS.h"
#include "vtkPointGaussianGS.h"
#include "vtkPolyDataFS.h"
#include "vtk_glew.h"
......@@ -143,10 +144,10 @@ void vtkOpenGLPointGaussianMapperHelper::GetShaderTemplate(
else
{
this->UsingPoints = false;
// for splats use a special shader than handles the offsets
// for splats use a special shader that handles the offsets
shaders[vtkShader::Vertex]->SetSource(vtkPointGaussianVS);
shaders[vtkShader::Geometry]->SetSource(vtkPointGaussianGS);
}
}
void vtkOpenGLPointGaussianMapperHelper::ReplaceShaderPositionVC(
......@@ -412,12 +413,6 @@ void vtkOpenGLPointGaussianMapperHelperColors(
vtkOpenGLPointGaussianMapperHelperComputeColor(
vPtr, colors, colorComponents, indices[i], opacities,
opacitiesComponent, self);
if (!self->UsingPoints)
{
memcpy(vPtr + 4, vPtr, 4);
memcpy(vPtr + 8, vPtr, 4);
vPtr += 8;
}
vPtr += 4;
}
}
......@@ -429,12 +424,6 @@ void vtkOpenGLPointGaussianMapperHelperColors(
vtkOpenGLPointGaussianMapperHelperComputeColor(
vPtr, colors, colorComponents, i, opacities,
opacitiesComponent, self);
if (!self->UsingPoints)
{
memcpy(vPtr + 4, vPtr, 4);
memcpy(vPtr + 8, vPtr, 4);
vPtr += 8;
}
vPtr += 4;
}
}
......@@ -479,7 +468,6 @@ void vtkOpenGLPointGaussianMapperHelperSizes(
vtkCellArray *verts)
{
float *it = static_cast<float *>(scales->GetVoidPointer(0));
float cos30 = cos(vtkMath::RadiansFromDegrees(30.0));
// iterate over cells or not
if (verts->GetNumberOfCells())
......@@ -498,12 +486,7 @@ void vtkOpenGLPointGaussianMapperHelperSizes(
}
float radiusFloat =
vtkOpenGLPointGaussianMapperHelperGetRadius(size, self);
*(it++) = -2.0f*radiusFloat*cos30;
*(it++) = -radiusFloat;
*(it++) = 2.0f*radiusFloat*cos30;
*(it++) = -radiusFloat;
*(it++) = 0.0f;
*(it++) = 2.0f*radiusFloat;
*(it++) = radiusFloat;
}
}
}
......@@ -519,12 +502,7 @@ void vtkOpenGLPointGaussianMapperHelperSizes(
}
float radiusFloat =
vtkOpenGLPointGaussianMapperHelperGetRadius(size, self);
*(it++) = -2.0f*radiusFloat*cos30;
*(it++) = -radiusFloat;
*(it++) = 2.0f*radiusFloat*cos30;
*(it++) = -radiusFloat;
*(it++) = 0.0f;
*(it++) = 2.0f*radiusFloat;
*(it++) = radiusFloat;
}
}
}
......@@ -532,59 +510,24 @@ void vtkOpenGLPointGaussianMapperHelperSizes(
template< typename PointDataType >
void vtkOpenGLPointGaussianMapperHelperPoints(
vtkFloatArray *vcoords,
PointDataType* points, vtkIdType numPts,
vtkOpenGLPointGaussianMapperHelper *self,
PointDataType* points,
vtkCellArray *verts)
{
float *vPtr = static_cast<float *>(vcoords->GetVoidPointer(0));
PointDataType *pointPtr;
// iterate over cells or not
if (verts->GetNumberOfCells())
vtkIdType* indices(nullptr);
vtkIdType npts(0);
for (verts->InitTraversal(); verts->GetNextCell(npts, indices); )
{
vtkIdType* indices(nullptr);
vtkIdType npts(0);
for (verts->InitTraversal(); verts->GetNextCell(npts, indices); )
for (int i = 0; i < npts; ++i)
{
for (int i = 0; i < npts; ++i)
{
pointPtr = points + indices[i]*3;
// Vertices
*(vPtr++) = pointPtr[0];
*(vPtr++) = pointPtr[1];
*(vPtr++) = pointPtr[2];
if (!self->UsingPoints)
{
*(vPtr++) = pointPtr[0];
*(vPtr++) = pointPtr[1];
*(vPtr++) = pointPtr[2];
*(vPtr++) = pointPtr[0];
*(vPtr++) = pointPtr[1];
*(vPtr++) = pointPtr[2];
}
}
}
}
else
{
for (vtkIdType i = 0; i < numPts; i++)
{
pointPtr = points + i*3;
pointPtr = points + indices[i]*3;
// Vertices
*(vPtr++) = pointPtr[0];
*(vPtr++) = pointPtr[1];
*(vPtr++) = pointPtr[2];
if (!self->UsingPoints)
{
*(vPtr++) = pointPtr[0];
*(vPtr++) = pointPtr[1];
*(vPtr++) = pointPtr[2];
*(vPtr++) = pointPtr[0];
*(vPtr++) = pointPtr[1];
*(vPtr++) = pointPtr[2];
}
}
}
}
......@@ -722,40 +665,41 @@ void vtkOpenGLPointGaussianMapperHelper::BuildBufferObjects(
// then the scalars do not have to be regenerted.
this->MapScalars(1.0);
// Figure out how big each block will be, currently 6 floats.
int splatCount = poly->GetPoints()->GetNumberOfPoints();
if (poly->GetVerts()->GetNumberOfCells())
{
splatCount = poly->GetVerts()->GetNumberOfConnectivityEntries() -
poly->GetVerts()->GetNumberOfCells();
}
if (!this->UsingPoints)
// need to build points?
if (poly->GetVerts()->GetNumberOfCells())
{
splatCount *= 3;
vtkFloatArray *pts = vtkFloatArray::New();
pts->SetNumberOfComponents(3);
pts->SetNumberOfTuples(splatCount);
switch(poly->GetPoints()->GetDataType())
{
vtkTemplateMacro(
vtkOpenGLPointGaussianMapperHelperPoints(
pts,
static_cast<VTK_TT*>(poly->GetPoints()->GetVoidPointer(0)),
poly->GetVerts()
));
}
this->VBOs->CacheDataArray("vertexMC", pts, ren, VTK_FLOAT);
pts->Delete();
}
vtkFloatArray *pts = vtkFloatArray::New();
pts->SetNumberOfComponents(3);
pts->SetNumberOfTuples(splatCount);
switch(poly->GetPoints()->GetDataType())
else // just pass the points
{
vtkTemplateMacro(
vtkOpenGLPointGaussianMapperHelperPoints(
pts,
static_cast<VTK_TT*>(poly->GetPoints()->GetVoidPointer(0)),
poly->GetPoints()->GetNumberOfPoints(),
this,
poly->GetVerts()
));
this->VBOs->CacheDataArray("vertexMC",
poly->GetPoints()->GetData(), ren, VTK_FLOAT);
}
this->VBOs->CacheDataArray("vertexMC", pts, ren, VTK_FLOAT);
pts->Delete();
if (!this->UsingPoints)
{
vtkFloatArray *offsets = vtkFloatArray::New();
offsets->SetNumberOfComponents(2);
offsets->SetNumberOfComponents(1);
offsets->SetNumberOfTuples(splatCount);
if (hasScaleArray)
......@@ -820,7 +764,7 @@ void vtkOpenGLPointGaussianMapperHelper::BuildBufferObjects(
{
this->Primitives[i].IBO->IndexCount = 0;
}
this->Primitives[PrimitiveTris].IBO->IndexCount = splatCount;
this->Primitives[PrimitivePoints].IBO->IndexCount = splatCount;
this->VBOBuildTime.Modified();
}
......@@ -831,25 +775,19 @@ void vtkOpenGLPointGaussianMapperHelper::RenderPieceDraw(vtkRenderer* ren, vtkAc
int numVerts = this->VBOs->GetNumberOfTuples("vertexMC");
if (numVerts)
{
vtkOpenGLState *ostate = static_cast<vtkOpenGLRenderer *>(ren)->GetState();
this->UpdateShaders(this->Primitives[PrimitivePoints], ren, actor);
// save off current state of src / dst blend functions
vtkOpenGLState::ScopedglBlendFuncSeparate bfsaver(ostate);
if (this->Owner->GetEmissive() != 0)
if (this->Owner->GetEmissive() != 0 && !ren->GetSelector())
{
vtkOpenGLState *ostate = static_cast<vtkOpenGLRenderer *>(ren)->GetState();
vtkOpenGLState::ScopedglBlendFuncSeparate bfsaver(ostate);
ostate->vtkglBlendFunc( GL_SRC_ALPHA, GL_ONE); // additive for emissive sources
}
// First we do the triangles or points, update the shader, set uniforms, etc.
this->UpdateShaders(this->Primitives[PrimitiveTris], ren, actor);
if (this->UsingPoints)
{
glDrawArrays(GL_POINTS, 0,
static_cast<GLuint>(numVerts));
glDrawArrays(GL_POINTS, 0, static_cast<GLuint>(numVerts));
}
else
{
glDrawArrays(GL_TRIANGLES, 0,
static_cast<GLuint>(numVerts));
glDrawArrays(GL_POINTS, 0, static_cast<GLuint>(numVerts));
}
}
}
......
......@@ -1535,12 +1535,9 @@ void vtkOpenGLPolyDataMapper::ReplaceShaderPrimID(
}
else
{
if (this->HaveCellNormals || this->HaveCellScalars || this->HavePickScalars)
{
vtkShaderProgram::Substitute(GSSource,
"//VTK::PrimID::Impl",
"gl_PrimitiveID = gl_PrimitiveIDIn;");
}
vtkShaderProgram::Substitute(GSSource,
"//VTK::PrimID::Impl",
"gl_PrimitiveID = gl_PrimitiveIDIn;");
}
shaders[vtkShader::Vertex]->SetSource(VSSource);
shaders[vtkShader::Geometry]->SetSource(GSSource);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment