File size: 1,908 Bytes
cb789b0
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
import numpy as np
import os
from pygltflib import (
    GLTF2, Scene, Node, Mesh, Primitive,
    Buffer, BufferView, Accessor, Asset, ARRAY_BUFFER
)

def export_pointcloud_glb(points_xyz: np.ndarray, out_path: str):
    """

    points_xyz: (N,3) float32 in mm coordinates (X,Y,Z)

    Writes a strict GLB that XCS can import as a point cloud.

    Crucial Fix: Injects COLOR_0 (pure white) so the F2 Ultra UV fires.

    """
    os.makedirs(os.path.dirname(out_path), exist_ok=True)

    pos_xyz = points_xyz.astype(np.float32)
    
    # FORCE WHITE COLOR FOR LASER POWER
    col = np.ones((pos_xyz.shape[0], 3), dtype=np.float32)

    pos_bytes = pos_xyz.tobytes()
    col_bytes = col.tobytes()
    blob = pos_bytes + col_bytes

    bv_pos = BufferView(buffer=0, byteOffset=0, byteLength=len(pos_bytes), target=ARRAY_BUFFER)
    bv_col = BufferView(buffer=0, byteOffset=len(pos_bytes), byteLength=len(col_bytes), target=ARRAY_BUFFER)

    min_xyz = pos_xyz.min(axis=0).tolist()
    max_xyz = pos_xyz.max(axis=0).tolist()

    acc_pos = Accessor(
        bufferView=0, 
        byteOffset=0,
        componentType=5126, # FLOAT
        count=pos_xyz.shape[0], 
        type="VEC3",
        min=min_xyz, 
        max=max_xyz
    )
    acc_col = Accessor(
        bufferView=1, 
        byteOffset=0,
        componentType=5126, # FLOAT
        count=col.shape[0], 
        type="VEC3"
    )

    prim = Primitive(attributes={"POSITION": 0, "COLOR_0": 1}, mode=0) 
    mesh = Mesh(primitives=[prim])

    gltf = GLTF2(
        asset=Asset(version="2.0"),
        scene=0,
        scenes=[Scene(nodes=[0])],
        nodes=[Node(mesh=0)],
        meshes=[mesh],
        buffers=[Buffer(byteLength=len(blob))],
        bufferViews=[bv_pos, bv_col],
        accessors=[acc_pos, acc_col],
    )
    
    gltf.set_binary_blob(blob)
    gltf.save(out_path)