conda-forge / vtk-feedstock

A conda-smithy repository for vtk.
BSD 3-Clause "New" or "Revised" License
13 stars 64 forks source link

VTK 7.1.0 conda-forge is incorrectly reporting attribute error #29

Closed Garyfallidis closed 7 years ago

Garyfallidis commented 7 years ago

Hello all, Here is the error when trying to add a shader in a polydatamapper

AttributeError: 'vtkRenderingOpenGLPython.vtkOpenGLPolyDataMapper' object has no attribute 'SetVertexShaderCode' This was tested in Ubuntu 16.04 in Anaconda2

When tested in Windows and Anaconda3 using the clinicalgraphics channel there was no problem. Thanks in advance.

Garyfallidis commented 7 years ago

Here is also the code that generates the attribute error. It has no dependencies apart from vtk.

#!/usr/bin/env python

# This simple example shows how to do basic rendering and pipeline
# creation.

import vtk
# The colors module defines various useful colors.
from vtk.util.colors import tomato

# This creates a polygonal cylinder model with eight circumferential
# facets.
cylinder = vtk.vtkCylinderSource()
cylinder.SetResolution(8)

# The mapper is responsible for pushing the geometry into the graphics
# library. It may also do color mapping, if scalars or other
# attributes are defined.
cylinderMapper = vtk.vtkOpenGLPolyDataMapper()
cylinderMapper.SetInputConnection(cylinder.GetOutputPort())

# METHOD #2
# Use our own hardcoded shader code. Generally this is a bad idea in a
# general purpose program as there are so many things VTK supports that
# hardcoded shaders will not handle depth peeling, picking, etc, but if you
# know what your data will be like it can be very useful. The mapper will set
# a bunch of uniforms regardless of if you are using them. But feel free to
# use them :-)
cylinderMapper.SetVertexShaderCode(
"//VTK::System::Dec\n"  # always start with this line
"attribute vec4 vertexMC;\n"
# use the default normal decl as the mapper
# will then provide the normalMatrix uniform
# which we use later on
"//VTK::Normal::Dec\n"
"uniform mat4 MCDCMatrix;\n"
"void main () {\n"
"  normalVCVSOutput = normalMatrix * normalMC;\n"
# do something weird with the vertex positions
# this will mess up your head if you keep
# rotating and looking at it, very trippy
"  vec4 tmpPos = MCDCMatrix * vertexMC;\n"
"  gl_Position = tmpPos*vec4(0.2+0.8*abs(tmpPos.x),0.2+0.8*abs(tmpPos.y),1.0,1.0);\n"
"}\n"
)

cylinderMapper.SetFragmentShaderCode(
"//VTK::System::Dec\n"  # always start with this line
"//VTK::Output::Dec\n"  # always have this line in your FS
"varying vec3 normalVCVSOutput;\n"
"uniform vec3 diffuseColorUniform;\n"
"void main () {\n"
"  float df = max(0.0, normalVCVSOutput.z);\n"
"  float sf = pow(df, 20.0);\n"
"  vec3 diffuse = df * diffuseColorUniform;\n"
"  vec3 specular = sf * vec3(0.4,0.4,0.4);\n"
"  gl_FragData[0] = vec4(0.3*abs(normalVCVSOutput) + 0.7*diffuse + specular, 1.0);\n"
"}\n"
)

# The actor is a grouping mechanism: besides the geometry (mapper), it
# also has a property, transformation matrix, and/or texture map.
# Here we set its color and rotate it -22.5 degrees.
cylinderActor = vtk.vtkActor()
cylinderActor.SetMapper(cylinderMapper)
cylinderActor.GetProperty().SetColor(tomato)
cylinderActor.RotateX(30.0)
cylinderActor.RotateY(-45.0)

# Create the graphics structure. The renderer renders into the render
# window. The render window interactor captures mouse events and will
# perform appropriate camera or actor manipulation depending on the
# nature of the events.
ren = vtk.vtkRenderer()
renWin = vtk.vtkRenderWindow()
renWin.AddRenderer(ren)
iren = vtk.vtkRenderWindowInteractor()
iren.SetRenderWindow(renWin)

# Add the actors to the renderer, set the background and size
ren.AddActor(cylinderActor)
ren.SetBackground(0.1, 0.2, 0.4)
renWin.SetSize(200, 200)

# This allows the interactor to initalize itself. It has to be
# called before an event loop.
iren.Initialize()

# We'll zoom in a little by accessing the camera and invoking a "Zoom"
# method on it.
ren.ResetCamera()
ren.GetActiveCamera().Zoom(1.5)
renWin.Render()

# Start the event loop.
iren.Start()
grlee77 commented 7 years ago

Hi @Garyfallidis,

I suspect this is due to the older OpenGL rendering backend specified here: https://github.com/conda-forge/vtk-feedstock/blob/1937a994f03c2767b5b306931729cc4ae1696d30/recipe/build.sh#L37

The clinicalgraphics package uses the newer OpenGL2 backend which is the default backend for VTK7 builds.

I was interested in changing the default to OpenGL2, but there was some disagreement on that point in: https://github.com/conda-forge/vtk-feedstock/issues/7

In general, building VTK on conda-forge has been a pain due to build time limitations on the CI services.

p.s. Back when I made a PR related to VTK7 support in your dipy package, I was using VTK 7.0 built with the OpenGL2 backend so it makes sense that the clinicalgraphics build is working better for you. Most likely VTK 7 built with the older OpenGL backend should use a similar code path to the VTK 6 case. For robustness it may be necessary to check for existance of the specific attribute rather than relying on the VTK version number.

Garyfallidis commented 7 years ago

Hi @grlee. Do you have any plans in trying again to built conda-forge with the new backend? Or support both? Right now clinical graphics works only in python 3 not 2. Correct me if wrong. We really need shaders for what we do now for improving our visualization tools and the new backend has good support for that.

grlee77 commented 7 years ago

I think providing options for both OpenGL and OpenGL2 would be a substantial amount of work.

@Korijn: In #7 you stated that the conda-forge packages intentionally uses the older OpenGL backend. However, I see that the clinicalgraphics channel packages use OpenGL2. Is there a strong reason not to also go to OpenGL2 on conda-forge?

@Garyfallidis: Which platforms and python versions do you most need? If you just need it for local use, you can always checkout this repository and then modify a single line of the build.sh or bld.bat to select OpenGL2 and then build locally. The process for that is: conda build -c conda-forge --python=2.7 recipe conda install --use-local vtk

You can see what the clinicalgraphics channel has at https://anaconda.org/clinicalgraphics/vtk/files It appears that for Python 2.7 there is only a linux build of 7.1.0

The problem on the CI is we often see timeouts on CircleCI building more than two versions. For example #27 is currently timing out trying to build for 2.7, 3.5 and 3.6. If we drop 3.5, it will probably complete. We probably will have to make separate branches if we want more than two versions.

Garyfallidis commented 7 years ago

Thank you @grlee77. I want vtk 7.1.0 to be supported both for Python 2 and 3 with GL2 support and be available in conda. I need all the platforms linux, osx and windows. I don't need this for local use. I would like that the dipy users can install vtk with GL2 support in an easy way. I think for anyone looking at the 7.1.0 documentation the assumption would be that GL2 will be the default option. So, not having these attributes was surprising for us especially when in Python 3 clinical graphics did the job. We cannot use vtk 7.0.0 because of some bugs which are now solved in 7.1.0. So, vtk 7.1.0 is currently our only option. For this dipy release we can live without shaders. But with next release we would love to have something with shaders and GL2 support.

Garyfallidis commented 7 years ago

I would like also to understand why @Korijn preferred the old OpenGL backend. We waited for long time to finally move to GL2 and the advantages that this provides to VTK are numerous.

Korijn commented 7 years ago

I prefer opengl2 backend actually (I work at clinical graphics). :) As I've stated in #7 you can open a PR and see how far you can get.

Korijn commented 7 years ago

Also, if you're interested in the full history of this recipe, I recommend to check the original PR here: https://github.com/conda-forge/staged-recipes/pull/453

grlee77 commented 7 years ago

If there are no strong objections to OpenGL2 then let's switch to that. There are basically two main things that need to happen:

1.) workaround CI limits to get 2.7, 3.5 and 3.6 all built (see suggested solution using two branches in the recent comments in #27) with updated dependencies (#23). 2.) switch to OpenGL2 backend

Korijn commented 7 years ago

Nice work so far @grlee77 ! Thanks for picking this up.

Garyfallidis commented 7 years ago

Thank you @grlee77 :+1:

grlee77 commented 7 years ago

I had forgotten that we skip OS X entirely because we were unable to get even one build to complete within the 1 hour limit on Travis. I doubt that will be resolved in the immediate future, so for now it will still be necessary to obtain OS X packages from another channel.

To work around the time limits, there was talk somewhere of a mechanism for uploading offline builds from trusted sources to the conda-forge channel, but I don't know of any concrete developments in that direction.

patricksnape commented 7 years ago

Unless some sort of ccache is enabled?

grlee77 commented 7 years ago

Unless some sort of ccache is enabled?

It looks like it is possible to configure Travis to use ccache on OS X, but I have no experience with using it. Presumably the build would still time out initially, but then if manually restarted it might find the previously cached files and resume from there?

https://docs.travis-ci.com/user/caching/

grlee77 commented 7 years ago

closing this as resolved via the switch to OpenGL2 made in #30 and #31 (the example given above now runs successfully).