package org.bytedeco.open3d.examples
/** Open3D Scala Benchmark - calls Java NativePointCloud from Scala */
@main
def Open3DScalaBenchmark(): Unit =
println("========================================")
println(" Open3D Scala Benchmark (via JavaCPP)")
println("========================================")
println(s"Java: ${System.getProperty("java.version")}")
println(s"Scala: ${scala.util.Properties.versionNumberString}")
println()
var passed = 0
var failed = 0
// Test 1: PointCloud creation
try
val pc = new org.bytedeco.open3d.NativePointCloud()
assert(pc.getNativeAddr() != 0, "PointCloud should have valid native address")
pc.nativeDestroy()
passed += 1
println(" [PASS] PointCloud create/destroy")
catch
case e: Throwable =>
failed += 1
println(s" [FAIL] ${e.getMessage}")
e.printStackTrace()
// Test 2: Create sphere points
try
val pc = new org.bytedeco.open3d.NativePointCloud()
val ok = pc.createSpherePoints(1000, 1.0)
assert(ok, "createSpherePoints should succeed")
val n = pc.getNumPoints()
assert(n == 1000, s"Expected 1000 points, got $n")
val hasColors = pc.hasColors()
assert(hasColors, "Should have colors")
passed += 1
println(s" [PASS] Created $n sphere points with colors=$hasColors")
pc.nativeDestroy()
catch
case e: Throwable =>
failed += 1
println(s" [FAIL] ${e.getMessage}")
e.printStackTrace()
// Test 3: Get points data
try
val pc = new org.bytedeco.open3d.NativePointCloud()
pc.createSpherePoints(100, 2.0)
val allPoints = pc.getAllPoints()
assert(allPoints != null && allPoints.length == 300, "Should have 300 values (100 points � 3)")
val pt0 = pc.getPoint(0)
assert(pt0 != null && pt0.length == 3, "Point should have 3 coords")
val r = Math.sqrt(pt0(0)*pt0(0) + pt0(1)*pt0(1) + pt0(2)*pt0(2))
assert(r <= 2.0 && r >= 0, "Point should be inside sphere")
val minB = pc.getMinBound()
val maxB = pc.getMaxBound()
assert(minB != null && minB.length == 3, "Should have min bound")
assert(maxB != null && maxB.length == 3, "Should have max bound")
passed += 1
println(s" [PASS] Data access: ${allPoints.length} values, bounds=[${minB.mkString(",")}] to [${maxB.mkString(",")}]")
pc.nativeDestroy()
catch
case e: Throwable =>
failed += 1
println(s" [FAIL] ${e.getMessage}")
e.printStackTrace()
// Test 4: Normal estimation
try
val pc = new org.bytedeco.open3d.NativePointCloud()
pc.createSpherePoints(500, 1.0)
val ok = pc.estimateNormals(30)
assert(ok, "estimateNormals should succeed")
val hasNormals = pc.hasNormals()
assert(hasNormals, "Should have normals after estimation")
val n0 = pc.getNormal(0)
assert(n0 != null && n0.length == 3, "Normal should have 3 components")
val len = Math.sqrt(n0(0)*n0(0) + n0(1)*n0(1) + n0(2)*n0(2))
assert(Math.abs(len - 1.0) < 0.01, "Normal should be unit length")
// Orient normals
pc.orientNormalsToAlignWithDirection(0, 0, 1)
passed += 1
println(s" [PASS] Normal estimation: hasNormals=$hasNormals, first normal=(${n0.mkString(",")})")
pc.nativeDestroy()
catch
case e: Throwable =>
failed += 1
println(s" [FAIL] ${e.getMessage}")
e.printStackTrace()
// Test 5: TriangleMesh sphere
try
val mesh = org.bytedeco.open3d.NativeTriangleMesh.createSphere(1.0, 20)
assert(mesh.getNativeAddr() != 0, "Mesh should have valid address")
val verts = mesh.getNumVertices()
val tris = mesh.getNumTriangles()
assert(verts > 0, "Should have vertices")
assert(tris > 0, "Should have triangles")
val ok = mesh.computeVertexNormals()
assert(ok, "computeVertexNormals should succeed")
assert(mesh.hasVertexNormals(), "Should have vertex normals")
passed += 1
println(s" [PASS] Sphere: $verts vertices, $tris triangles")
mesh.nativeDestroy()
catch
case e: Throwable =>
failed += 1
println(s" [FAIL] ${e.getMessage}")
e.printStackTrace()
// Test 6: TriangleMesh box
try
val mesh = org.bytedeco.open3d.NativeTriangleMesh.createBox(2.0, 3.0, 4.0)
assert(mesh.getNativeAddr() != 0, "Mesh should have valid address")
val verts = mesh.getNumVertices()
val tris = mesh.getNumTriangles()
assert(verts == 8, s"Expected 8 vertices, got $verts")
assert(tris == 12, s"Expected 12 triangles, got $tris")
val ok = mesh.paintVertexColor(1.0, 0.0, 0.0)
assert(ok, "paintVertexColor should succeed")
assert(mesh.hasVertexColors(), "Should have vertex colors")
passed += 1
println(s" [PASS] Box: $verts vertices, $tris triangles")
mesh.nativeDestroy()
catch
case e: Throwable =>
failed += 1
println(s" [FAIL] ${e.getMessage}")
e.printStackTrace()
// Test 7: VoxelGrid from PointCloud
try
val pc = new org.bytedeco.open3d.NativePointCloud()
pc.createSpherePoints(1000, 1.0)
val vg = org.bytedeco.open3d.NativeVoxelGrid.createFromPointCloud(pc, 0.1)
assert(vg != null && vg.getNativeAddr() != 0, "VoxelGrid should have valid address")
val numVoxels = vg.getNumberOfVoxels()
assert(numVoxels > 0, "Should have voxels")
val minB = vg.getMinBound()
val maxB = vg.getMaxBound()
assert(minB != null && maxB != null, "Should have bounds")
passed += 1
println(s" [PASS] VoxelGrid: $numVoxels voxels, bounds=[${minB.mkString(",")}] to [${maxB.mkString(",")}]")
pc.nativeDestroy()
vg.nativeDestroy()
catch
case e: Throwable =>
failed += 1
println(s" [FAIL] ${e.getMessage}")
e.printStackTrace()
// Test 8: PointCloud I/O
val testFile = "/tmp/test_open3d_scala.ply"
try
val pc = new org.bytedeco.open3d.NativePointCloud()
pc.createSpherePoints(100, 1.0)
pc.estimateNormals(20)
val ok = pc.nativeWriteFile(testFile)
assert(ok, "Write file should succeed")
val pc2 = new org.bytedeco.open3d.NativePointCloud()
val ok2 = pc2.nativeReadFile(testFile)
assert(ok2, "Read file should succeed")
val n2 = pc2.getNumPoints()
assert(n2 == 100, s"Expected 100 points, got $n2")
passed += 1
println(s" [PASS] I/O: wrote/read $n2 points from $testFile")
pc.nativeDestroy()
pc2.nativeDestroy()
new java.io.File(testFile).delete()
catch
case e: Throwable =>
failed += 1
println(s" [FAIL] ${e.getMessage}")
e.printStackTrace()
// Test 9: FPFH Feature
try
val pc = new org.bytedeco.open3d.NativePointCloud()
pc.createSpherePoints(200, 1.0)
pc.estimateNormals(20)
val feature = org.bytedeco.open3d.NativeFeature.computeFPFH(pc, 30)
assert(feature.getNativeAddr() != 0, "Feature should have valid address")
val dim = feature.getDimension()
val num = feature.getNumPoints()
assert(dim > 0, s"Expected positive dimension, got $dim")
assert(num == 200, s"Expected 200 points, got $num")
val data = feature.getData(0)
assert(data != null && data.length == dim, "Should get feature data")
passed += 1
println(s" [PASS] FPFH: dim=$dim, num=$num")
pc.nativeDestroy()
feature.nativeDestroy()
catch
case e: Throwable =>
failed += 1
println(s" [FAIL] ${e.getMessage}")
e.printStackTrace()
// Test 10: PointCloud operations
try
val pc = new org.bytedeco.open3d.NativePointCloud()
pc.createSpherePoints(100, 1.0)
// Scale
val ok = pc.scale(2.0)
assert(ok, "Scale should succeed")
val maxB = pc.getMaxBound()
assert(maxB(0) > 1.0, "Scaled max bound should increase")
// Normalize
val normOk = pc.normalizeToUnit()
assert(normOk, "normalizeToUnit should succeed")
val maxB2 = pc.getMaxBound()
assert(maxB2(0) > 0.5, "Normalized max should be positive")
// Distance
val pc2 = new org.bytedeco.open3d.NativePointCloud()
pc2.createSpherePoints(100, 1.0)
val dist = pc.computePointCloudDistance(pc2)
assert(dist >= 0, "Distance should be non-negative")
// Remove non-finite
val removed = pc.removeNonFinitePoints(true, true)
assert(removed >= 0, "Remove non-finite should succeed")
passed += 1
println(s" [PASS] Operations: scale, normalize, distance, remove work correctly")
pc.nativeDestroy()
pc2.nativeDestroy()
catch
case e: Throwable =>
failed += 1
println(s" [FAIL] ${e.getMessage}")
e.printStackTrace()
// Test 11: Image
try
val img = new org.bytedeco.open3d.NativeImage(640, 480, 3, 1)
assert(img.getNativeAddr() != 0, "Image should have valid address")
assert(img.getWidth() == 640, "Width should be 640")
assert(img.getHeight() == 480, "Height should be 480")
assert(img.getNumChannels() == 3, "Channels should be 3")
assert(img.getBytesPerChannel() == 1, "Bytes per channel should be 1")
passed += 1
println(s" [PASS] Image: ${img.getWidth}x${img.getHeight}x${img.getNumChannels} (${img.getBytesPerChannel} bytes/channel)")
img.nativeDestroy()
catch
case e: Throwable =>
failed += 1
println(s" [FAIL] ${e.getMessage}")
e.printStackTrace()
println()
println("========================================")
println(s" Results: $passed passed, $failed failed")
println("========================================")
if failed > 0 then System.exit(1)
link #7463
https://private-user-images.githubusercontent.com/6143404/600504931-132b378e-a16b-47e5-b06c-a28238a89bd1.png?jwt=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3ODAxNTY4NDYsIm5iZiI6MTc4MDE1NjU0NiwicGF0aCI6Ii82MTQzNDA0LzYwMDUwNDkzMS0xMzJiMzc4ZS1hMTZiLTQ3ZTUtYjA2Yy1hMjgyMzhhODliZDEucG5nP1gtQW16LUFsZ29yaXRobT1BV1M0LUhNQUMtU0hBMjU2JlgtQW16LUNyZWRlbnRpYWw9QUtJQVZDT0RZTFNBNTNQUUs0WkElMkYyMDI2MDUzMCUyRnVzLWVhc3QtMSUyRnMzJTJGYXdzNF9yZXF1ZXN0JlgtQW16LURhdGU9MjAyNjA1MzBUMTU1NTQ2WiZYLUFtei1FeHBpcmVzPTMwMCZYLUFtei1TaWduYXR1cmU9MGJiZDdiMDgzNzc2OTBmMDIxZTc2ZjgwOGRhZDAxZmUzZTllZTVmMzlkMDc1NDhkYTBjYTkxNTJlNmYzZWM0MCZYLUFtei1TaWduZWRIZWFkZXJzPWhvc3QmcmVzcG9uc2UtY29udGVudC10eXBlPWltYWdlJTJGcG5nIn0.MgmSe-xz_OP9T30K-yd0Ojn9dOK4JgcCm2-1z3XgunA