scalismo.ui.rendering.actor.TetrahedralActor.scala Maven / Gradle / Ivy
/*
* Copyright (C) 2016 University of Basel, Graphics and Vision Research Group
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
/*
* Copyright (C) 2016 University of Basel, Graphics and Vision Research Group
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see .
*/
package scalismo.ui.rendering.actor
import scalismo.common.DiscreteField.ScalarVolumeMeshField
import scalismo.geometry._3D
import scalismo.mesh.TetrahedralMesh
import scalismo.ui.model._
import scalismo.ui.model.capabilities.Transformable
import scalismo.ui.model.properties._
import scalismo.ui.rendering.Caches
import scalismo.ui.rendering.Caches.FastCachingTetrahedralMesh
import scalismo.ui.rendering.actor.TetrahedralActor.TetrahedralRenderable
import scalismo.ui.rendering.actor.mixin._
import scalismo.ui.rendering.util.VtkUtil
import scalismo.ui.view.{ViewportPanel, ViewportPanel2D, ViewportPanel3D}
import scalismo.utils.{TetrahedralMeshConversion}
import vtk.vtkUnstructuredGrid
object TetrahedralMeshActor extends SimpleActorsFactory[TetrahedralMeshNode] {
override def actorsFor(renderable: TetrahedralMeshNode, viewport: ViewportPanel): Option[Actors] = {
viewport match {
case _: ViewportPanel3D => Some(new TetrahedralMeshActor3D(renderable))
case _2d: ViewportPanel2D => Some(new TetrahedralMeshActor2D(renderable, _2d))
}
}
}
object ScalarTetrahedralMeshFieldActor extends SimpleActorsFactory[ScalarTetrahedralMeshFieldNode] {
override def actorsFor(renderable: ScalarTetrahedralMeshFieldNode, viewport: ViewportPanel): Option[Actors] = {
viewport match {
case _: ViewportPanel3D => Some(new ScalarTetrahedralMeshFieldActor3D(renderable))
case _2d: ViewportPanel2D => Some(new ScalarTetrahedralMeshFieldActor2D(renderable, _2d))
}
}
}
object TetrahedralActor {
trait TetrahedralRenderable {
type MeshType
def opacity: OpacityProperty
def lineWidth: LineWidthProperty
def mesh: MeshType
def node: SceneNode
}
private[actor] object TetrahedralRenderable {
class TetrahedralMeshRenderable(override val node: TetrahedralMeshNode) extends TetrahedralRenderable {
type MeshType = TetrahedralMesh[_3D]
override def mesh: TetrahedralMesh[_3D] = node.transformedSource
override def opacity: OpacityProperty = node.opacity
override def lineWidth: LineWidthProperty = node.lineWidth
def color: ColorProperty = node.color
}
class ScalarTetrahedralMeshFieldRenderable(override val node: ScalarTetrahedralMeshFieldNode)
extends TetrahedralRenderable {
type MeshType = TetrahedralMesh[_3D]
override def opacity: OpacityProperty = node.opacity
override def lineWidth: LineWidthProperty = node.lineWidth
override def mesh: TetrahedralMesh[_3D] = field.mesh
def scalarRange: ScalarRangeProperty = node.scalarRange
def field: ScalarVolumeMeshField[Float] = node.transformedSource
}
def apply(source: TetrahedralMeshNode): TetrahedralMeshRenderable = new TetrahedralMeshRenderable(source)
def apply(source: ScalarTetrahedralMeshFieldNode): ScalarTetrahedralMeshFieldRenderable =
new ScalarTetrahedralMeshFieldRenderable(source)
}
}
trait TetrahedralActor[R <: TetrahedralRenderable] extends SingleDataSetActor with ActorOpacity with ActorSceneNode {
def renderable: R
override def opacity: OpacityProperty = renderable.opacity
override def sceneNode: SceneNode = renderable.node
protected def meshToUnstructuredGrid(template: Option[vtkUnstructuredGrid]): vtkUnstructuredGrid
protected var unstructuredgrid: vtkUnstructuredGrid = meshToUnstructuredGrid(None)
// this is invoked from within the rerender method, if the geometry has changed.
protected def onGeometryChanged(): Unit
protected def rerender(geometryChanged: Boolean): Unit = {
if (geometryChanged) {
unstructuredgrid = meshToUnstructuredGrid(None)
onGeometryChanged()
}
actorChanged(geometryChanged)
}
protected def onInstantiated(): Unit = {}
//FIXME: pick control -- this should probably go into a trait or something.
renderable.node match {
case p: HasPickable =>
SetPickable(if (p.pickable.value) 1 else 0)
listenTo(p.pickable)
reactions += {
case NodeProperty.event.PropertyChanged(s) if s == p.pickable =>
SetPickable(if (p.pickable.value) 1 else 0)
}
case _ =>
}
onInstantiated()
rerender(geometryChanged = true)
listenTo(renderable.node)
reactions += {
case Transformable.event.GeometryChanged(_) => rerender(geometryChanged = true)
}
}
trait TetrahedralMeshActor extends TetrahedralActor[TetrahedralRenderable.TetrahedralMeshRenderable] with ActorColor {
override def renderable: TetrahedralRenderable.TetrahedralMeshRenderable
override def color: ColorProperty = renderable.color
override protected def meshToUnstructuredGrid(template: Option[vtkUnstructuredGrid]): vtkUnstructuredGrid = {
Caches.TetrahedralMeshCache.getOrCreate(
FastCachingTetrahedralMesh(renderable.mesh),
TetrahedralMeshConversion.tetrahedralMeshToVTKUnstructuredGrid(renderable.mesh, template)
)
}
}
trait TetrahedralMeshScalarFieldActor
extends TetrahedralActor[TetrahedralRenderable.ScalarTetrahedralMeshFieldRenderable]
with ActorScalarRange {
override def renderable: TetrahedralRenderable.ScalarTetrahedralMeshFieldRenderable
override def scalarRange: ScalarRangeProperty = renderable.scalarRange
override protected def meshToUnstructuredGrid(template: Option[vtkUnstructuredGrid]): vtkUnstructuredGrid = {
Caches.ScalarTetrahedralMeshFieldCache
.getOrCreate(renderable.field,
TetrahedralMeshConversion.scalarVolumeMeshFieldToVtkUnstructuredGrid(renderable.field, template))
}
}
abstract class TetrahedralActor3D[R <: TetrahedralRenderable](override val renderable: R) extends TetrahedralActor[R] {
override protected def onInstantiated(): Unit = {
mapper.SetInputData(unstructuredgrid)
}
override protected def onGeometryChanged(): Unit = {
mapper.SetInputData(unstructuredgrid)
}
}
abstract class TetrahedralActor2D[R <: TetrahedralRenderable](override val renderable: R, viewport: ViewportPanel2D)
extends SlicingActor(viewport)
with TetrahedralActor[R]
with ActorLineWidth {
override def lineWidth: LineWidthProperty = renderable.lineWidth
override protected def onSlicingPositionChanged(): Unit = rerender(geometryChanged = false)
override protected def onGeometryChanged(): Unit = {
planeCutter.SetInputData(unstructuredgrid)
planeCutter.Modified()
}
override protected def sourceBoundingBox: BoundingBox = VtkUtil.bounds2BoundingBox(unstructuredgrid.GetBounds())
}
class TetrahedralMeshActor3D(node: TetrahedralMeshNode)
extends TetrahedralActor3D(TetrahedralRenderable(node))
with TetrahedralMeshActor
class TetrahedralMeshActor2D(node: TetrahedralMeshNode, viewport: ViewportPanel2D)
extends TetrahedralActor2D(TetrahedralRenderable(node), viewport)
with TetrahedralMeshActor
class ScalarTetrahedralMeshFieldActor3D(node: ScalarTetrahedralMeshFieldNode)
extends TetrahedralActor3D(TetrahedralRenderable(node))
with TetrahedralMeshScalarFieldActor
class ScalarTetrahedralMeshFieldActor2D(node: ScalarTetrahedralMeshFieldNode, viewport: ViewportPanel2D)
extends TetrahedralActor2D(TetrahedralRenderable(node), viewport)
with TetrahedralMeshScalarFieldActor