All Downloads are FREE. Search and download functionalities are using the official Maven repository.

scalismo.ui.rendering.actor.PointCloudActor.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 .
 */

package scalismo.ui.rendering.actor

import scalismo.ui.model.capabilities.Transformable
import scalismo.ui.model.properties.{ColorProperty, LineWidthProperty, NodeProperty, OpacityProperty}
import scalismo.ui.model.{BoundingBox, PointCloudNode}
import scalismo.ui.rendering.actor.mixin.{ActorColor, ActorLineWidth, ActorOpacity, ActorSceneNode}
import scalismo.ui.rendering.util.VtkUtil
import scalismo.ui.view.{ViewportPanel, ViewportPanel2D, ViewportPanel3D}
import vtk.{vtkGlyph3D, vtkPoints, vtkPolyData, vtkSphereSource}

object PointCloudActor extends SimpleActorsFactory[PointCloudNode] {
  override def actorsFor(renderable: PointCloudNode, viewport: ViewportPanel): Option[Actors] = {
    viewport match {
      case _: ViewportPanel3D   => Some(new PointCloudActor3D(renderable))
      case _2d: ViewportPanel2D => Some(new PointCloudActor2D(renderable, _2d))
    }
  }
}

trait PointCloudActor extends SingleDataSetActor with ActorOpacity with ActorColor with ActorSceneNode {
  override def sceneNode: PointCloudNode

  override def opacity: OpacityProperty = sceneNode.opacity

  override def color: ColorProperty = sceneNode.color

  protected def onInstantiated(): Unit

  lazy val sphere = new vtkSphereSource

  private def transformedPoints: vtkPoints = new vtkPoints {
    sceneNode.transformedSource.foreach { point =>
      InsertNextPoint(point(0), point(1), point(2))
    }
  }

  lazy val polydata = new vtkPolyData

  protected lazy val glyph: vtkGlyph3D = new vtkGlyph3D {
    SetSourceConnection(sphere.GetOutputPort)
    SetInputData(polydata)
  }

  def rerender(geometryChanged: Boolean): Unit = {
    if (geometryChanged) {
      polydata.SetPoints(transformedPoints)
    }
    sphere.SetRadius(sceneNode.radius.value)
    mapper.Modified()
    actorChanged(geometryChanged)
  }

  listenTo(sceneNode, sceneNode.radius)

  reactions += {
    case Transformable.event.GeometryChanged(_)                         => rerender(true)
    case NodeProperty.event.PropertyChanged(p) if p eq sceneNode.radius => rerender(true)
  }

  onInstantiated()

  rerender(true)

}

class PointCloudActor2D(override val sceneNode: PointCloudNode, viewport: ViewportPanel2D)
    extends SlicingActor(viewport)
    with PointCloudActor
    with ActorLineWidth {
  override def lineWidth: LineWidthProperty = sceneNode.lineWidth

  override protected def onSlicingPositionChanged(): Unit = rerender(false)

  override protected def onInstantiated(): Unit = {
    planeCutter.SetInputConnection(glyph.GetOutputPort())
  }

  override protected def sourceBoundingBox: BoundingBox = VtkUtil.bounds2BoundingBox(polydata.GetBounds())

}

class PointCloudActor3D(override val sceneNode: PointCloudNode) extends PointCloudActor {
  override protected def onInstantiated(): Unit = {
    mapper.SetInputConnection(glyph.GetOutputPort)
  }

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy