123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640 |
- 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,
- )
|