f3d icon indicating copy to clipboard operation
f3d copied to clipboard

Unable to open .3MF from 3D Printing slicer

Open LightDestory opened this issue 1 month ago • 4 comments

Describe the bug F3D is not able to open, visualize, generate thumbnail for .3MF file generated by a slicer program (3D printing software).

I think that it is a customization of the .3MF file.

To Reproduce Steps to reproduce the behavior:

  1. Try to open the attached file

Expected behavior Be able to preview the 3D content or visualize the static 2D png preview (common on such .3mf customizations).

System Information:

  • OS: Windows 11
  • GPU and GPU driver: NVIDIA RTX 2070S

F3D Information F3D 3.3.0

F3D - A fast and minimalist 3D viewer Version: 3.3.0. Build date: 2025-10-22 15:21:13. Build system: Windows 64-bits. Compiler: MSVC 19.44.35217.0. Module ImGui: ON. Module OpenEXR: ON. Module Raytracing: OFF. Module WebP: ON. VTK version: 9.5.2-1520-g01b47f3856 (date: 20251018). Copyright (C) 2019-2021 Kitware SAS. Copyright (C) 2021-2025 Michael Migliore, Mathieu Westphal. License BSD-3-Clause.

Additional context There files are generated by BambuStudio/Orca Slicer

Cube02ProfileMini.zip

LightDestory avatar Nov 21 '25 19:11 LightDestory

If you extract the content of such .3mf file you can find static thumbnail inside the \Auxiliaries\.thumbnails directory.

The 3D data can be retrieved inside the 3D folder

LightDestory avatar Nov 21 '25 19:11 LightDestory

The following python sample code converts .model file to a .obj:

import xml.etree.ElementTree as ET
import sys
from pathlib import Path

def convert_xml_to_obj(xml_file, obj_file):
    tree = ET.parse(xml_file)
    root = tree.getroot()
    ns = {'ns': 'http://schemas.microsoft.com/3dmanufacturing/core/2015/02'}

    if obj_file is None:
        obj_file = Path(xml_file).with_suffix(".obj")

    with open(obj_file, 'w') as f:
        mesh = root.find('.//ns:mesh', ns)
        if mesh is None:
            print("No mesh found in XML")
            return

        vertices = mesh.find('ns:vertices', ns)
        if vertices is not None:
            for vertex in vertices.findall('ns:vertex', ns):
                x = vertex.get('x')
                y = vertex.get('y')
                z = vertex.get('z')
                f.write(f"v {x} {y} {z}\n")

        triangles = mesh.find('ns:triangles', ns)
        if triangles is not None:
            for triangle in triangles.findall('ns:triangle', ns):
                v1 = int(triangle.get('v1')) + 1 # OBJ is 1-indexed
                v2 = int(triangle.get('v2')) + 1
                v3 = int(triangle.get('v3')) + 1
                f.write(f"f {v1} {v2} {v3}\n")

    print(f"Converted {xml_file} to {obj_file}")

if __name__ == "__main__":
    if len(sys.argv) < 2:
        print("Usage: python model_to_obj.py <input.model> [output.obj]")
        sys.exit(1)
    in_path = sys.argv[1]
    out_path = sys.argv[2] if len(sys.argv) >= 3 else None
    convert_xml_to_obj(in_path, out_path)

LightDestory avatar Nov 21 '25 20:11 LightDestory

I haven't checked the provided file but we've seen issues with 3mf from BambuStudio/OrcaSlicer before due to the assimp library not handling model instancing/references: #1708

Upstream issue: https://github.com/assimp/assimp/issues/5811

snoyer avatar Nov 22 '25 06:11 snoyer


ERROR: In vtkF3DAssimpImporter.cxx, line 641
vtkF3DAssimpImporter (0x55be97b3d1e0): Assimp failed to load: /home/glow/data/tmp/Cube02ProfileMini.3mf


ERROR: In vtkF3DAssimpImporter.cxx, line 644
vtkF3DAssimpImporter (0x55be97b3d1e0): Assimp error: Validation failed: aiScene::mNumMeshes is 0. At least one mesh must be there


Some of these files could not be loaded: failed to load scene
  /home/glow/data/tmp/Cube02ProfileMini.3mf

Indeed, thats the same issue. Since the other one on our repo is closed, I think we should keep this one open for visibility.

mwestphal avatar Nov 22 '25 06:11 mwestphal