Files
geMoldInsight/venv/lib/python3.11/site-packages/vtkmodules/web/camera.py
T

641 lines
22 KiB
Python
Raw Normal View History

2026-02-12 23:22:11 +08:00
from math import *
# -----------------------------------------------------------------------------
# Set of helper functions
# -----------------------------------------------------------------------------
def normalize(vect, tolerance=0.00001):
mag2 = sum(n * n for n in vect)
if abs(mag2 - 1.0) > tolerance:
mag = sqrt(mag2)
vect = tuple(n / mag for n in vect)
return vect
def q_mult(q1, q2):
w1, x1, y1, z1 = q1
w2, x2, y2, z2 = q2
w = w1 * w2 - x1 * x2 - y1 * y2 - z1 * z2
x = w1 * x2 + x1 * w2 + y1 * z2 - z1 * y2
y = w1 * y2 + y1 * w2 + z1 * x2 - x1 * z2
z = w1 * z2 + z1 * w2 + x1 * y2 - y1 * x2
return w, x, y, z
def q_conjugate(q):
w, x, y, z = q
return (w, -x, -y, -z)
def qv_mult(q1, v1):
q2 = (0.0,) + v1
return q_mult(q_mult(q1, q2), q_conjugate(q1))[1:]
def axisangle_to_q(v, theta):
v = normalize(v)
x, y, z = v
theta /= 2
w = cos(theta)
x = x * sin(theta)
y = y * sin(theta)
z = z * sin(theta)
return w, x, y, z
def vectProduct(axisA, axisB):
xa, ya, za = axisA
xb, yb, zb = axisB
normalVect = (ya * zb - za * yb, za * xb - xa * zb, xa * yb - ya * xb)
normalVect = normalize(normalVect)
return normalVect
def dotProduct(vecA, vecB):
return (vecA[0] * vecB[0]) + (vecA[1] * vecB[1]) + (vecA[2] * vecB[2])
def rotate(axis, angle, center, point):
angleInRad = 3.141592654 * angle / 180.0
rotation = axisangle_to_q(axis, angleInRad)
tPoint = tuple((point[i] - center[i]) for i in range(3))
rtPoint = qv_mult(rotation, tPoint)
rPoint = tuple((rtPoint[i] + center[i]) for i in range(3))
return rPoint
# -----------------------------------------------------------------------------
# Spherical Camera
# -----------------------------------------------------------------------------
class SphericalCamera(object):
def __init__(
self, dataHandler, focalPoint, position, phiAxis, phiAngles, thetaAngles
):
self.dataHandler = dataHandler
self.cameraSettings = []
self.thetaBind = {
"mouse": {
"drag": {"modifier": 0, "coordinate": 1, "step": 30, "orientation": 1}
}
}
self.phiBind = {
"mouse": {
"drag": {"modifier": 0, "coordinate": 0, "step": 30, "orientation": 1}
}
}
# Convert to serializable type
fp = tuple(i for i in focalPoint)
# Register arguments to the data handler
if len(phiAngles) > 1 and phiAngles[-1] + phiAngles[1] == 360:
self.dataHandler.registerArgument(
priority=0,
name="phi",
values=phiAngles,
ui="slider",
loop="modulo",
bind=self.phiBind,
)
else:
self.dataHandler.registerArgument(
priority=0, name="phi", values=phiAngles, ui="slider", bind=self.phiBind
)
if thetaAngles[0] < 0 and thetaAngles[0] >= -90:
idx = 0
for theta in thetaAngles:
if theta < 0:
idx += 1
self.dataHandler.registerArgument(
priority=0,
name="theta",
values=[(x + 90) for x in thetaAngles],
ui="slider",
default=idx,
bind=self.thetaBind,
)
else:
self.dataHandler.registerArgument(
priority=0,
name="theta",
values=thetaAngles,
ui="slider",
bind=self.thetaBind,
)
# Compute all camera settings
for theta in thetaAngles:
for phi in phiAngles:
phiPos = rotate(phiAxis, -phi, fp, position)
thetaAxis = vectProduct(
phiAxis, tuple(fp[i] - phiPos[i] for i in range(3))
)
thetaPhiPos = rotate(thetaAxis, theta, fp, phiPos)
viewUp = rotate(thetaAxis, theta, (0, 0, 0), phiAxis)
self.cameraSettings.append(
{
"theta": theta,
"thetaIdx": thetaAngles.index(theta),
"phi": phi,
"phiIdx": phiAngles.index(phi),
"focalPoint": fp,
"position": thetaPhiPos,
"viewUp": viewUp,
}
)
self.dataHandler.updateBasePattern()
def updatePriority(self, priorityList):
keyList = ["theta", "phi"]
for idx in range(min(len(priorityList), len(keyList))):
self.dataHandler.updatePriority(keyList[idx], priorityList[idx])
def __iter__(self):
for cameraData in self.cameraSettings:
self.dataHandler.setArguments(
phi=cameraData["phiIdx"], theta=cameraData["thetaIdx"]
)
yield cameraData
# -----------------------------------------------------------------------------
# Cylindrical Camera
# -----------------------------------------------------------------------------
class CylindricalCamera(object):
def __init__(
self,
dataHandler,
focalPoint,
position,
rotationAxis,
phiAngles,
translationValues,
):
self.dataHandler = dataHandler
self.cameraSettings = []
# Register arguments to the data handler
self.dataHandler.registerArgument(
priority=0, name="phi", values=phiAngles, ui="slider", loop="modulo"
)
self.dataHandler.registerArgument(
priority=0, name="n_pos", values=translationValues, ui="slider"
)
# Compute all camera settings
for translation in translationValues:
for phi in phiAngles:
phiPos = rotate(rotationAxis, phi, focalPoint, position)
newfocalPoint = tuple(
focalPoint[i] + (translation * rotationAxis[i]) for i in range(3)
)
transPhiPoint = tuple(
phiPos[i] + (translation * rotationAxis[i]) for i in range(3)
)
self.cameraSettings.append(
{
"n_pos": translation,
"n_posIdx": translationValues.index(translation),
"phi": phi,
"phiIdx": phiAngles.index(phi),
"focalPoint": newfocalPoint,
"position": transPhiPoint,
"viewUp": rotationAxis,
}
)
self.dataHandler.updateBasePattern()
def updatePriority(self, priorityList):
keyList = ["n_pos", "phi"]
for idx in range(min(len(priorityList), len(keyList))):
self.dataHandler.updatePriority(keyList[idx], priorityList[idx])
def __iter__(self):
for cameraData in self.cameraSettings:
self.dataHandler.setArguments(
phi=cameraData["phiIdx"], n_pos=cameraData["n_posIdx"]
)
yield cameraData
# -----------------------------------------------------------------------------
# MultiView Cube Camera
# -----------------------------------------------------------------------------
class CubeCamera(object):
# positions = [ { position: [x,y,z], args: { i: 1, j: 0, k: 7 } }, ... ]
def __init__(self, dataHandler, viewForward, viewUp, positions):
self.dataHandler = dataHandler
self.cameraSettings = []
self.viewForward = viewForward
self.viewUp = viewUp
self.rightDirection = vectProduct(viewForward, viewUp)
self.positions = positions
# Register arguments to the data handler
self.dataHandler.registerArgument(
priority=0, name="orientation", values=["f", "b", "r", "l", "u", "d"]
)
# Register arguments to id position
self.args = {}
for pos in positions:
for key in pos["args"]:
if key not in self.args:
self.args[key] = {}
self.args[key][pos["args"][key]] = True
for key in self.args:
self.args[key] = sorted(self.args[key], key=lambda k: int(k))
self.keyList = self.args.keys()
for key in self.args:
self.dataHandler.registerArgument(
priority=1, name=key, values=self.args[key]
)
self.dataHandler.updateBasePattern()
def updatePriority(self, priorityList):
keyList = ["orientation"]
for idx in range(min(len(priorityList), len(keyList))):
self.dataHandler.updatePriority(keyList[idx], priorityList[idx])
def __iter__(self):
for pos in self.positions:
cameraData = {
"position": pos["position"],
}
print("=" * 80)
for key in pos["args"]:
idx = self.args[key].index(pos["args"][key])
self.dataHandler.setArguments(**{key: idx})
print(key, idx)
print("position", cameraData["position"])
# front
cameraData["focalPoint"] = [
(cameraData["position"][i] + self.viewForward[i]) for i in range(3)
]
cameraData["viewUp"] = [self.viewUp[i] for i in range(3)]
cameraData["orientation"] = "front"
self.dataHandler.setArguments(orientation=0)
yield cameraData
# back
cameraData["focalPoint"] = [
(cameraData["position"][i] - self.viewForward[i]) for i in range(3)
]
cameraData["viewUp"] = [self.viewUp[i] for i in range(3)]
cameraData["orientation"] = "back"
self.dataHandler.setArguments(orientation=1)
yield cameraData
# right
self.dataHandler.setArguments(orientation=2)
cameraData["focalPoint"] = [
(cameraData["position"][i] + self.rightDirection[i]) for i in range(3)
]
cameraData["viewUp"] = [self.viewUp[i] for i in range(3)]
cameraData["orientation"] = "right"
yield cameraData
# left
self.dataHandler.setArguments(orientation=3)
cameraData["focalPoint"] = [
(cameraData["position"][i] - self.rightDirection[i]) for i in range(3)
]
cameraData["viewUp"] = [self.viewUp[i] for i in range(3)]
cameraData["orientation"] = "left"
yield cameraData
# up
self.dataHandler.setArguments(orientation=4)
cameraData["focalPoint"] = [
(cameraData["position"][i] + self.viewUp[i]) for i in range(3)
]
cameraData["viewUp"] = [(-self.viewForward[i]) for i in range(3)]
cameraData["orientation"] = "up"
yield cameraData
# doww
self.dataHandler.setArguments(orientation=5)
cameraData["focalPoint"] = [
(cameraData["position"][i] - self.viewUp[i]) for i in range(3)
]
cameraData["viewUp"] = [self.viewForward[i] for i in range(3)]
cameraData["orientation"] = "down"
yield cameraData
# -----------------------------------------------------------------------------
# MultiView Cube Camera
# -----------------------------------------------------------------------------
class StereoCubeCamera(object):
# positions = [ { position: [x,y,z], args: { i: 1, j: 0, k: 7 } }, ... ]
def __init__(self, dataHandler, viewForward, viewUp, positions, eyeSpacing):
self.dataHandler = dataHandler
self.cameraSettings = []
self.viewForward = viewForward
self.viewUp = viewUp
self.rightDirection = vectProduct(viewForward, viewUp)
self.positions = positions
self.eyeSpacing = eyeSpacing
# Register arguments to the data handler
self.dataHandler.registerArgument(
priority=0, name="orientation", values=["f", "b", "r", "l", "u", "d"]
)
self.dataHandler.registerArgument(
priority=0, name="eye", values=["left", "right"]
)
# Register arguments to id position
self.args = {}
for pos in positions:
for key in pos["args"]:
if key not in self.args:
self.args[key] = {}
self.args[key][pos["args"][key]] = True
for key in self.args:
self.args[key] = sorted(self.args[key], key=lambda k: int(k))
self.keyList = self.args.keys()
for key in self.args:
self.dataHandler.registerArgument(
priority=1, name=key, values=self.args[key]
)
self.dataHandler.updateBasePattern()
def updatePriority(self, priorityList):
keyList = ["orientation"]
for idx in range(min(len(priorityList), len(keyList))):
self.dataHandler.updatePriority(keyList[idx], priorityList[idx])
def __iter__(self):
for pos in self.positions:
cameraData = {}
for key in pos["args"]:
idx = self.args[key].index(pos["args"][key])
self.dataHandler.setArguments(**{key: idx})
# front
cameraData["orientation"] = "front"
self.dataHandler.setArguments(orientation=0)
deltaVect = [
(v * float(self.eyeSpacing) * 0.5) for v in self.rightDirection
]
## Left-Eye
self.dataHandler.setArguments(eye=0)
cameraData["viewUp"] = [self.viewUp[i] for i in range(3)]
cameraData["position"] = [
(pos["position"][idx] - deltaVect[idx]) for idx in range(3)
]
cameraData["focalPoint"] = [
(pos["position"][i] + self.viewForward[i] - deltaVect[i])
for i in range(3)
]
yield cameraData
## Right-Eye
self.dataHandler.setArguments(eye=1)
cameraData["viewUp"] = [self.viewUp[i] for i in range(3)]
cameraData["position"] = [
(pos["position"][idx] + deltaVect[idx]) for idx in range(3)
]
cameraData["focalPoint"] = [
(pos["position"][i] + self.viewForward[i] + deltaVect[i])
for i in range(3)
]
yield cameraData
# back
cameraData["orientation"] = "back"
self.dataHandler.setArguments(orientation=1)
deltaVect = [
-(v * float(self.eyeSpacing) * 0.5) for v in self.rightDirection
]
## Left-Eye
self.dataHandler.setArguments(eye=0)
cameraData["viewUp"] = [self.viewUp[i] for i in range(3)]
cameraData["position"] = [
(pos["position"][idx] - deltaVect[idx]) for idx in range(3)
]
cameraData["focalPoint"] = [
(pos["position"][i] - self.viewForward[i] - deltaVect[i])
for i in range(3)
]
yield cameraData
## Right-Eye
self.dataHandler.setArguments(eye=1)
cameraData["viewUp"] = [self.viewUp[i] for i in range(3)]
cameraData["position"] = [
(pos["position"][idx] + deltaVect[idx]) for idx in range(3)
]
cameraData["focalPoint"] = [
(pos["position"][i] - self.viewForward[i] + deltaVect[i])
for i in range(3)
]
yield cameraData
# right
self.dataHandler.setArguments(orientation=2)
cameraData["orientation"] = "right"
deltaVect = [-(v * float(self.eyeSpacing) * 0.5) for v in self.viewForward]
## Left-Eye
self.dataHandler.setArguments(eye=0)
cameraData["viewUp"] = [self.viewUp[i] for i in range(3)]
cameraData["position"] = [
(pos["position"][idx] - deltaVect[idx]) for idx in range(3)
]
cameraData["focalPoint"] = [
(pos["position"][i] + self.rightDirection[i] - deltaVect[i])
for i in range(3)
]
yield cameraData
## Right-Eye
self.dataHandler.setArguments(eye=1)
cameraData["viewUp"] = [self.viewUp[i] for i in range(3)]
cameraData["position"] = [
(pos["position"][idx] + deltaVect[idx]) for idx in range(3)
]
cameraData["focalPoint"] = [
(pos["position"][i] + self.rightDirection[i] + deltaVect[i])
for i in range(3)
]
yield cameraData
# left
self.dataHandler.setArguments(orientation=3)
cameraData["orientation"] = "left"
deltaVect = [(v * float(self.eyeSpacing) * 0.5) for v in self.viewForward]
## Left-Eye
self.dataHandler.setArguments(eye=0)
cameraData["viewUp"] = [self.viewUp[i] for i in range(3)]
cameraData["position"] = [
(pos["position"][idx] - deltaVect[idx]) for idx in range(3)
]
cameraData["focalPoint"] = [
(pos["position"][i] - self.rightDirection[i] - deltaVect[i])
for i in range(3)
]
yield cameraData
## Right-Eye
self.dataHandler.setArguments(eye=1)
cameraData["viewUp"] = [self.viewUp[i] for i in range(3)]
cameraData["position"] = [
(pos["position"][idx] + deltaVect[idx]) for idx in range(3)
]
cameraData["focalPoint"] = [
(pos["position"][i] - self.rightDirection[i] + deltaVect[i])
for i in range(3)
]
yield cameraData
# up
self.dataHandler.setArguments(orientation=4)
cameraData["orientation"] = "up"
deltaVect = [
(v * float(self.eyeSpacing) * 0.5) for v in self.rightDirection
]
## Left-Eye
self.dataHandler.setArguments(eye=0)
cameraData["viewUp"] = [(-self.viewForward[i]) for i in range(3)]
cameraData["position"] = [
(pos["position"][idx] - deltaVect[idx]) for idx in range(3)
]
cameraData["focalPoint"] = [
(pos["position"][i] + self.viewUp[i] - deltaVect[i]) for i in range(3)
]
yield cameraData
## Right-Eye
self.dataHandler.setArguments(eye=1)
cameraData["viewUp"] = [(-self.viewForward[i]) for i in range(3)]
cameraData["position"] = [
(pos["position"][idx] + deltaVect[idx]) for idx in range(3)
]
cameraData["focalPoint"] = [
(pos["position"][i] + self.viewUp[i] + deltaVect[i]) for i in range(3)
]
yield cameraData
# doww
self.dataHandler.setArguments(orientation=5)
cameraData["orientation"] = "down"
deltaVect = [
(v * float(self.eyeSpacing) * 0.5) for v in self.rightDirection
]
## Left-Eye
self.dataHandler.setArguments(eye=0)
cameraData["viewUp"] = [self.viewForward[i] for i in range(3)]
cameraData["position"] = [
(pos["position"][idx] - deltaVect[idx]) for idx in range(3)
]
cameraData["focalPoint"] = [
(pos["position"][i] - self.viewUp[i] - deltaVect[i]) for i in range(3)
]
yield cameraData
## Right-Eye
self.dataHandler.setArguments(eye=1)
cameraData["viewUp"] = [self.viewForward[i] for i in range(3)]
cameraData["position"] = [
(pos["position"][idx] + deltaVect[idx]) for idx in range(3)
]
cameraData["focalPoint"] = [
(pos["position"][i] - self.viewUp[i] + deltaVect[i]) for i in range(3)
]
yield cameraData
# -----------------------------------------------------------------------------
# MultiView Camera
# -----------------------------------------------------------------------------
class MultiViewCamera(object):
def __init__(self, dataHandler):
self.dataHandler = dataHandler
self.cameraSettings = []
self.positionNames = []
def registerViewPoint(self, name, focalPoint, position, viewUp):
self.cameraSettings.append(
{
"name": name,
"nameIdx": len(self.positionNames),
"focalPoint": focalPoint,
"position": position,
"viewUp": viewUp,
}
)
self.positionNames.append(name)
self.dataHandler.registerArgument(
priority=0, name="multiView", values=self.positionNames
)
self.dataHandler.updateBasePattern()
def updatePriority(self, priorityList):
keyList = ["multiView"]
for idx in range(min(len(priorityList), len(keyList))):
self.dataHandler.updatePriority(keyList[idx], priorityList[idx])
def __iter__(self):
for cameraData in self.cameraSettings:
self.dataHandler.setArguments(multiView=cameraData["nameIdx"])
yield cameraData
# -----------------------------------------------------------------------------
# Helper methods
# -----------------------------------------------------------------------------
def update_camera(renderer, cameraData):
camera = renderer.GetActiveCamera()
camera.SetPosition(cameraData["position"])
camera.SetFocalPoint(cameraData["focalPoint"])
camera.SetViewUp(cameraData["viewUp"])
def create_spherical_camera(renderer, dataHandler, phiValues, thetaValues):
camera = renderer.GetActiveCamera()
return SphericalCamera(
dataHandler,
camera.GetFocalPoint(),
camera.GetPosition(),
camera.GetViewUp(),
phiValues,
thetaValues,
)
def create_cylindrical_camera(renderer, dataHandler, phiValues, translationValues):
camera = renderer.GetActiveCamera()
return CylindricalCamera(
dataHandler,
camera.GetFocalPoint(),
camera.GetPosition(),
camera.GetViewUp(),
phiValues,
translationValues,
)