CalculateMeshLowerLODsCommand not working as expecting, creating NaN vertex positions #69

Open
opened 2025-01-02 17:15:54 +08:00 by nlerin · 0 comments
nlerin commented 2025-01-02 17:15:54 +08:00 (Migrated from github.com)

I'm trying to use CalculateMeshLowerLODsCommand to transfer changes made to LOD0 to the remaining lods but I'm running into two issues which are probably related. Tested with release 1.3.1

Problem 1: Some vertices on the teeth_lod1_mesh mesh get NaN positions on three vertices. I've tested a few different dna files from the default characters and the results are exactly the same. The vertices are 913, 2658, 2659 and you can see the missing faces which fail to render in maya.
nan_vertices

Problem 2: Meshes that are the same, with the exact same UV, doesn't match after running the command CalculateMeshLowerLODsCommand. This is not the case with release 1.2.0 and lower (earlier release has other issues though when UVs on lower lods are outside UV shell of LOD0).
Here's a comparison between eyeEdge_lod0_mesh and eyeEdge_lod1_mesh which should be a perfect match since they have the same topology and UVs
image

Here's the full command I've tested with

from dna_viewer import (
    DNA,
    Config,
    build_meshes,
)
from dnacalib import (
    CommandSequence,
    DNACalibDNAReader,
    CalculateMeshLowerLODsCommand
)

from dna import (
    BinaryStreamReader,
    BinaryStreamWriter,
    DataLayer_All,
    FileStream,
    Status,
)

dna_in = r"E:\MetaHuman-DNA-Calibration\data\dna_files\Ada.dna"
dna_out = r"E:\MetaHuman-DNA-Calibration\data\dna_files\Ada_calibrated.dna"

def load_dna(path):
    stream = FileStream(path, FileStream.AccessMode_Read, FileStream.OpenMode_Binary)
    reader = BinaryStreamReader(stream, DataLayer_All)
    reader.read()
    if not Status.isOk():
        status = Status.get()
        raise RuntimeError(f"Error loading DNA: {status.message}")
    return reader
    
def save_dna(reader, path):
    stream = FileStream(
        path,
        FileStream.AccessMode_Write,
        FileStream.OpenMode_Binary,
    )
    writer = BinaryStreamWriter(stream)
    writer.setFrom(reader)
    writer.write()

    if not Status.isOk():
        status = Status.get()
        raise RuntimeError(f"Error saving DNA: {status.message}")


reader = load_dna(dna_in)
calibrated = DNACalibDNAReader(reader)

dna = DNA(dna_in)
mesh_idx = dna.get_mesh_indices_for_lod(0)
commands = CommandSequence()
for id in mesh_idx:
    meshname = dna.get_mesh_name(id)

    calculate_command = CalculateMeshLowerLODsCommand()
    calculate_command.setMeshIndex(id)
    commands.add(calculate_command)

commands.run(calibrated)

save_dna(calibrated, dna_out)
config = Config(
    group_by_lod=False,
    create_display_layers=False,
    add_mesh_name_to_blend_shape_channel_name=True,
)

dna = DNA(dna_out)
result = build_meshes(dna=dna, config=config)
I'm trying to use `CalculateMeshLowerLODsCommand` to transfer changes made to LOD0 to the remaining lods but I'm running into two issues which are probably related. Tested with release 1.3.1 Problem 1: Some vertices on the `teeth_lod1_mesh` mesh get NaN positions on three vertices. I've tested a few different dna files from the default characters and the results are exactly the same. The vertices are 913, 2658, 2659 and you can see the missing faces which fail to render in maya. ![nan_vertices](https://github.com/user-attachments/assets/18efe3be-55ea-4cb0-9a2a-73c1ecd52378) Problem 2: Meshes that are the same, with the exact same UV, doesn't match after running the command CalculateMeshLowerLODsCommand. This is not the case with release 1.2.0 and lower (earlier release has other issues though when UVs on lower lods are outside UV shell of LOD0). Here's a comparison between eyeEdge_lod0_mesh and eyeEdge_lod1_mesh which should be a perfect match since they have the same topology and UVs <img width="1171" alt="image" src="https://github.com/user-attachments/assets/cf53b3bc-62c2-42b4-a1df-dc1dc4e32233" /> Here's the full command I've tested with ``` from dna_viewer import ( DNA, Config, build_meshes, ) from dnacalib import ( CommandSequence, DNACalibDNAReader, CalculateMeshLowerLODsCommand ) from dna import ( BinaryStreamReader, BinaryStreamWriter, DataLayer_All, FileStream, Status, ) dna_in = r"E:\MetaHuman-DNA-Calibration\data\dna_files\Ada.dna" dna_out = r"E:\MetaHuman-DNA-Calibration\data\dna_files\Ada_calibrated.dna" def load_dna(path): stream = FileStream(path, FileStream.AccessMode_Read, FileStream.OpenMode_Binary) reader = BinaryStreamReader(stream, DataLayer_All) reader.read() if not Status.isOk(): status = Status.get() raise RuntimeError(f"Error loading DNA: {status.message}") return reader def save_dna(reader, path): stream = FileStream( path, FileStream.AccessMode_Write, FileStream.OpenMode_Binary, ) writer = BinaryStreamWriter(stream) writer.setFrom(reader) writer.write() if not Status.isOk(): status = Status.get() raise RuntimeError(f"Error saving DNA: {status.message}") reader = load_dna(dna_in) calibrated = DNACalibDNAReader(reader) dna = DNA(dna_in) mesh_idx = dna.get_mesh_indices_for_lod(0) commands = CommandSequence() for id in mesh_idx: meshname = dna.get_mesh_name(id) calculate_command = CalculateMeshLowerLODsCommand() calculate_command.setMeshIndex(id) commands.add(calculate_command) commands.run(calibrated) save_dna(calibrated, dna_out) config = Config( group_by_lod=False, create_display_layers=False, add_mesh_name_to_blend_shape_channel_name=True, ) dna = DNA(dna_out) result = build_meshes(dna=dna, config=config) ```
Sign in to join this conversation.
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: CGNICO/Metahuman_DNA_Calibration#69
No description provided.