Skip to content

Commit

Permalink
add vtkFollower
Browse files Browse the repository at this point in the history
  • Loading branch information
xavArtley committed Jun 22, 2020
1 parent 295ce22 commit b120036
Show file tree
Hide file tree
Showing 3 changed files with 152 additions and 0 deletions.
7 changes: 7 additions & 0 deletions panel/models/vtk/util.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {linspace} from "@bokehjs/core/util/array"
import {Follower} from "./vtkfollower"

export const ARRAY_TYPES = {
uint8: Uint8Array,
Expand Down Expand Up @@ -27,6 +28,7 @@ if (vtk) {
vtkns["CubeSource"] = vtk.Filters.Sources.vtkCubeSource
vtkns["DataAccessHelper"] = vtk.IO.Core.DataAccessHelper
vtkns["DataArray"] = vtk.Common.Core.vtkDataArray
vtkns["Follower"] = Follower
vtkns["FullScreenRenderWindow"] = vtk.Rendering.Misc.vtkFullScreenRenderWindow
vtkns["Glyph3DMapper"] = vtk.Rendering.Core.vtkGlyph3DMapper
vtkns["HttpSceneLoader"] = vtk.IO.Core.vtkHttpSceneLoader
Expand Down Expand Up @@ -80,6 +82,11 @@ if (vtk) {
vtkns.VolumeMapper.newInstance,
vtkObjectManager.oneTimeGenericUpdater
)
vtkObjectManager.setTypeMapping(
"vtkFollower",
Follower.newInstance,
vtkObjectManager.genericUpdater
)
}

declare type RGBnode = {
Expand Down
134 changes: 134 additions & 0 deletions panel/models/vtk/vtkfollower.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,134 @@
import { vec3, mat4 } from 'gl-matrix'


export let Follower: any

const vtk = (window as any).vtk

if(vtk) {
const macro = vtk.macro
const vtkActor = vtk.Rendering.Core.vtkActor

function vtkFollower(publicAPI: any, model: any) {
console.log("Hello")
// Set our className
model.classHierarchy.push('vtkFollower')

// Capture 'parentClass' api for internal use
const superClass = { ...publicAPI }

publicAPI.getMTime = () => {
let mt = superClass.getMTime()
if (model.camera !== null) {
const time = model.camera.getMTime()
mt = time > mt ? time : mt
}

return mt;
};

publicAPI.computeMatrix = () => {
// check whether or not need to rebuild the matrix
if (publicAPI.getMTime() > model.matrixMTime.getMTime()) {
mat4.identity(model.matrix)
if (model.userMatrix) {
mat4.multiply(model.matrix, model.matrix, model.userMatrix)
}
mat4.translate(model.matrix, model.matrix, model.origin)
mat4.translate(model.matrix, model.matrix, model.position)
mat4.multiply(model.matrix, model.matrix, model.rotation)
mat4.scale(model.matrix, model.matrix, model.scale)

if (model.camera) {
// first compute our target viewUp
const vup = vec3.fromValues(model.viewUp[0], model.viewUp[1], model.viewUp[2])
if (!model.useViewUp) {
const cvup = model.camera.getViewUp()
vec3.set(vup, cvup[0], cvup[1], cvup[2])
}

// compute a vpn
const vpn = vec3.create();
if (model.camera.getParallelProjection()) {
const cvpn = model.camera.getViewPlaneNormal()
vec3.set(vpn, cvpn[0], cvpn[1], cvpn[2])
} else {
vec3.set(vpn, model.position[0], model.position[1], model.position[2])
const cpos = model.camera.getPosition()
const tmpv3 = vec3.fromValues(cpos[0], cpos[1], cpos[2])
vec3.subtract(vpn, tmpv3, vpn)
vec3.normalize(vpn, vpn)
}

// compute vright
const vright = vec3.create();
vec3.cross(vright, vup, vpn)
vec3.normalize(vright, vright)

// now recompute the vpn so that it is orthogonal to vup
vec3.cross(vpn, vright, vup)
vec3.normalize(vpn, vpn)

model.followerMatrix[0] = vright[0]
model.followerMatrix[1] = vright[1]
model.followerMatrix[2] = vright[2]

model.followerMatrix[4] = vup[0]
model.followerMatrix[5] = vup[1]
model.followerMatrix[6] = vup[2]

model.followerMatrix[8] = vpn[0]
model.followerMatrix[9] = vpn[1]
model.followerMatrix[10] = vpn[2]

mat4.multiply(model.matrix, model.followerMatrix, model.matrix);
}

mat4.translate(model.matrix, model.matrix, [
-model.origin[0],
-model.origin[1],
-model.origin[2],
]);
mat4.transpose(model.matrix, model.matrix);

// check for identity
model.isIdentity = false;
model.matrixMTime.modified();
}
}
}

// ----------------------------------------------------------------------------
// Object factory
// ----------------------------------------------------------------------------

const DEFAULT_VALUES = {
viewUp: [0, 1, 0],
useViewUp: false,
camera: null,
}

// ----------------------------------------------------------------------------

Follower = {
newInstance: macro.newInstance((publicAPI: any, model: any, initialValues = {}) => {
Object.assign(model, DEFAULT_VALUES, initialValues)

// Inheritance
vtkActor.extend(publicAPI, model, initialValues)

model.followerMatrix = mat4.create()
model.camera = vtk.Rendering.Core.vtkCamera.newInstance()
mat4.identity(model.followerMatrix)

// Build VTK API
macro.setGet(publicAPI, model, ['useViewUp', 'camera'])

macro.setGetArray(publicAPI, model, ['viewUp'], 3)

// Object methods
vtkFollower(publicAPI, model);
}, 'vtkFollower')
}

}
11 changes: 11 additions & 0 deletions panel/pane/vtk/synchronizable_serializer.py
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,7 @@ def initializeSerializers():
registerInstanceSerializer('vtkImageSlice', genericProp3DSerializer)
registerInstanceSerializer('vtkVolume', genericProp3DSerializer)
registerInstanceSerializer('vtkOpenGLActor', genericActorSerializer)
registerInstanceSerializer('vtkFollower', genericActorSerializer)
registerInstanceSerializer('vtkPVLODActor', genericActorSerializer)


Expand Down Expand Up @@ -575,6 +576,16 @@ def genericActorSerializer(parent, actor, actorId, context, depth):
'forceOpaque': actor.GetForceOpaque(),
'forceTranslucent': actor.GetForceTranslucent()
})

if actor.IsA('vtkFollower'):
camera = actor.GetCamera()
cameraId = context.getReferenceId(camera)
cameraInstance = serializeInstance(
actor, camera, cameraId, context, depth + 1)
if cameraInstance:
instance['dependencies'].append(cameraInstance)
instance['calls'].append(['setCamera', [wrapId(cameraId)]])

return instance

# -----------------------------------------------------------------------------
Expand Down

0 comments on commit b120036

Please sign in to comment.