Skip to content

Commit

Permalink
Feat/native mesh decimation (#416)
Browse files Browse the repository at this point in the history
* feat: native scala version of Fast-Quadric-Mesh-Simplification

---------

Co-authored-by: Andreas Morel-Forster <[email protected]>
  • Loading branch information
Dennis Madsen and Andreas-Forster authored Jan 26, 2024
1 parent f649930 commit 1e55a3c
Show file tree
Hide file tree
Showing 11 changed files with 467 additions and 15 deletions.
2 changes: 1 addition & 1 deletion src/main/scala/scalismo/mesh/MeshBoundaryPredicates.scala
Original file line number Diff line number Diff line change
Expand Up @@ -178,7 +178,7 @@ object MeshBoundaryPredicates {
}
val edgeOnBorderBuilder = new CSCMatrix.Builder[Boolean](nPts, nPts)

edgeOnBorderSet.foreach{case(v1, v2) =>
edgeOnBorderSet.foreach { case (v1, v2) =>
edgeOnBorderBuilder.add(v1, v2, true)
edgeOnBorderBuilder.add(v2, v1, true)
}
Expand Down
29 changes: 19 additions & 10 deletions src/main/scala/scalismo/mesh/MeshOperations.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ import scalismo.mesh.boundingSpheres.{
TriangulatedSurfaceIntersectionIndex,
VolumeSpatialIndex
}
import scalismo.mesh.decimate.MeshDecimation
import scalismo.utils.MeshConversion

import scala.collection.parallel.immutable.ParVector
Expand Down Expand Up @@ -229,17 +230,25 @@ class TriangleMesh3DOperations(private val mesh: TriangleMesh[_3D]) {
* The decimated mesh
*/
def decimate(targetedNumberOfVertices: Int): TriangleMesh[_3D] = {
val refVtk = MeshConversion.meshToVtkPolyData(mesh)
val decimate = new vtk.vtkQuadricDecimation()

val reductionRate = 1.0 - (targetedNumberOfVertices / mesh.pointSet.numberOfPoints.toDouble)

decimate.SetTargetReduction(reductionRate)
require(targetedNumberOfVertices > 0)
val fraction = math.min(1.0, targetedNumberOfVertices.toDouble / mesh.pointSet.numberOfPoints)
decimateFaces((mesh.triangulation.triangles.length * fraction).toInt)
}

decimate.SetInputData(refVtk)
decimate.Update()
val decimatedRefVTK = decimate.GetOutput()
MeshConversion.vtkPolyDataToTriangleMesh(decimatedRefVTK).get
/**
* @param targetedNumberOfFaces
* @param aggressiveness
* A value from 0 to 9, while larger values allow for larger approximation errors.
* @return
*/
def decimateFaces(targetedNumberOfFaces: Int, aggressiveness: Int = 2): TriangleMesh[_3D] = {
require(targetedNumberOfFaces > 0)
require(aggressiveness >= 0 && aggressiveness < 10)
if (targetedNumberOfFaces >= mesh.triangulation.triangles.length) {
mesh
} else {
MeshDecimation.simplify(mesh, targetedNumberOfFaces, aggressiveness + 5)
}
}

/**
Expand Down
3 changes: 3 additions & 0 deletions src/main/scala/scalismo/mesh/decimate/ErrorEntry.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
package scalismo.mesh.decimate

case class ErrorEntry(vertexError: Array[Double] = Array.fill(3)(0.0), var minVertexError: Double = 0.0)
Loading

0 comments on commit 1e55a3c

Please sign in to comment.