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

ai.dragonfly.mesh.io.PLY.scala Maven / Gradle / Ivy

/*
 * Copyright 2023 dragonfly.ai
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package ai.dragonfly.mesh.io

import slash.vector.*
import ai.dragonfly.mesh.sRGB.*
import ai.dragonfly.mesh.Mesh

import narr.*
import scala.language.implicitConversions

import scala.scalajs.js.annotation.{JSExportAll, JSExportTopLevel}

@JSExportTopLevel("PLY") @JSExportAll
object PLY {

  val defaultComment:String = "Generated by mesh: https://github.com/dragonfly-ai/mesh"

  val defaultHeader = s"ply\nformat ascii 1.0\ncomment $defaultComment"

  val alphaMask:Int = 0xff << 24

  val randomVertexColorMapper: Vec[3] => ARGB32 = (v:Vec[3]) => ARGB32(alphaMask | scala.util.Random.nextInt())

  def writeMesh(mesh: Mesh, out: java.io.OutputStream, vertexColorMapper: Vec[3] => ARGB32): Unit = {
    out.write(fromMesh(mesh, vertexColorMapper).getBytes)
  }

  def fromMesh(mesh: Mesh, vertexColorMapper: Vec[3] => ARGB32):String = {
    val meshPoints: NArray[Vec[3]] = mesh.points

    val sb: StringBuilder = new StringBuilder()

    sb.append(
s"""$defaultHeader
element vertex ${meshPoints.length}
property float x
property float y
property float z
property uchar red
property uchar green
property uchar blue
property uchar alpha
element face ${mesh.triangles.length}
property list uchar uint vertex_indices
end_header
"""
    )

    var i:Int = 0; while (i < meshPoints.length) {
      val v:Vec[3] = meshPoints(i)
      val c: ARGB32 = vertexColorMapper(v)
      sb.append(s"${v.x} ${v.y} ${v.z} ${c.red} ${c.green} ${c.blue} ${c.alpha}\n")
      i += 1
    }

    var t:Int = 0; while (t < mesh.triangles.length) {
      val triangle = mesh.triangles(t)
      sb.append(s"3 ${triangle.v1} ${triangle.v2} ${triangle.v3}\n")
      t += 1
    }

    sb.toString()
  }


  def fromMesh(mesh: Mesh): String = {
    val meshPoints: NArray[Vec[3]] = mesh.points

    val sb: StringBuilder = new StringBuilder()

    sb.append(
      s"""$defaultHeader
element vertex ${meshPoints.length}
property float x
property float y
property float z
element face ${mesh.triangles.length}
property list uchar uint vertex_indices
end_header
"""
    )

    var i:Int = 0; while (i < meshPoints.length) {
      val v: Vec[3] = meshPoints(i)
//      if (v == null) println(s"$i -> null")
//      else
      sb.append(s"${v.x} ${v.y} ${v.z}\n")
      i += 1
    }

    var t: Int = 0; while (t < mesh.triangles.length) {
      val triangle = mesh.triangles(t)
      sb.append(s"3 ${triangle.v1} ${triangle.v2} ${triangle.v3}\n")
      t += 1
    }

    sb.toString()
  }


}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy