diff --git a/QuickLook.Plugin/QuickLook.Plugin.HelixViewer/Handler.cs b/QuickLook.Plugin/QuickLook.Plugin.HelixViewer/Handler.cs
index c4724e4..f837abd 100644
--- a/QuickLook.Plugin/QuickLook.Plugin.HelixViewer/Handler.cs
+++ b/QuickLook.Plugin/QuickLook.Plugin.HelixViewer/Handler.cs
@@ -15,8 +15,10 @@
// You should have received a copy of the GNU General Public License
// along with this program. If not, see .
+using System;
using System.IO;
using System.Linq;
+using System.Text;
namespace QuickLook.Plugin.HelixViewer;
@@ -26,6 +28,7 @@ internal static class Handler
{
var ext = Path.GetExtension(path).ToLower();
+ // Simple solution to doubts
if (ext == ".obj")
{
var firstLines = File.ReadLines(path).Take(10);
@@ -38,9 +41,27 @@ internal static class Handler
}
}
}
+#if S_DXF
+ else if (ext == ".dxf")
+ {
+ using var s = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
+ const int bufferLength = 16 * 1024;
+ var buffer = new byte[bufferLength];
+ int size = s.Read(buffer, 0, buffer.Length);
+
+ for (int i = 0; i < size - 1; i++)
+ {
+ if (buffer[i] == (byte)'3' && buffer[i + 1] == (byte)'D')
+ {
+ return true;
+ }
+ }
+ }
+#endif
else
{
- return true; // Assume other formats are supported
+ // Assume other formats are supported
+ return true;
}
return false;
diff --git a/QuickLook.Plugin/QuickLook.Plugin.HelixViewer/HelixPanel.Import.cs b/QuickLook.Plugin/QuickLook.Plugin.HelixViewer/HelixPanel.Import.cs
new file mode 100644
index 0000000..7fa8b84
--- /dev/null
+++ b/QuickLook.Plugin/QuickLook.Plugin.HelixViewer/HelixPanel.Import.cs
@@ -0,0 +1,104 @@
+// Copyright © 2017-2025 QL-Win Contributors
+//
+// This file is part of QuickLook program.
+//
+// This program is free software: you can redistribute it and/or modify
+// it under the terms of the GNU General Public License as published by
+// the Free Software Foundation, either version 3 of the License, or
+// (at your option) any later version.
+//
+// This program is distributed in the hope that it will be useful,
+// but WITHOUT ANY WARRANTY; without even the implied warranty of
+// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU General Public License
+// along with this program. If not, see .
+
+using Assimp;
+using HelixToolkit.Wpf;
+using System;
+using System.IO;
+using System.Linq;
+using System.Windows.Media;
+using System.Windows.Media.Media3D;
+
+namespace QuickLook.Plugin.HelixViewer;
+
+public partial class HelixPanel
+{
+ private void Load()
+ {
+ var importerType = Importer.GetImporterType(_path);
+
+ try
+ {
+ if (importerType == ImporterType.Extended)
+ {
+ var context = new AssimpContext();
+ var scene = context.ImportFile(_path, PostProcessSteps.Triangulate);
+
+ foreach (var mesh in scene.Meshes)
+ {
+ var geometry = new MeshGeometry3D()
+ {
+ Positions = [.. mesh.Vertices.Select(v => new Point3D(v.X, v.Y, v.Z))],
+ TriangleIndices = [.. mesh.GetIndices()],
+ };
+ var model = new GeometryModel3D()
+ {
+ Geometry = geometry,
+ Material = Materials.Gray,
+ };
+
+ modelVisual.Content = model;
+ }
+ }
+ else
+ {
+ var modelImporter = new ModelImporter();
+ var model3DGroup = modelImporter.Load(_path);
+ var diffuseMaterial = new DiffuseMaterial(new SolidColorBrush(Color.FromRgb(0xA0, 0xA0, 0xA0)));
+
+ foreach (GeometryModel3D child in model3DGroup.Children.Cast())
+ {
+ child.Material = diffuseMaterial;
+ child.BackMaterial = diffuseMaterial;
+ }
+
+ modelVisual.Content = model3DGroup;
+ }
+ }
+ catch (Exception ex)
+ {
+ errorInfo.Text = $"[{nameof(ImporterType)}.{importerType}] {ex}";
+ errorInfo.Visibility = System.Windows.Visibility.Visible;
+ viewer.Visibility = System.Windows.Visibility.Collapsed;
+ }
+ }
+}
+
+file static class Importer
+{
+ public static ImporterType GetImporterType(string path)
+ {
+ if (string.IsNullOrEmpty(path))
+ return ImporterType.Unknown;
+
+ return Path.GetExtension(path).ToLower() switch
+ {
+ ".stl" or ".obj" or ".3ds" or ".lwo" or ".ply" => ImporterType.Default,
+ ".fbx" or ".3mf" or ".glb" or ".gltf" or ".dae" or ".dxf" => ImporterType.Extended,
+ ".pmx" => ImporterType.Extended_MMD,
+ _ => ImporterType.Unknown,
+ };
+ }
+}
+
+file enum ImporterType
+{
+ Unknown,
+ Default,
+ Extended,
+ Extended_MMD,
+}
diff --git a/QuickLook.Plugin/QuickLook.Plugin.HelixViewer/HelixPanel.xaml b/QuickLook.Plugin/QuickLook.Plugin.HelixViewer/HelixPanel.xaml
index aa2b44c..adcdc77 100644
--- a/QuickLook.Plugin/QuickLook.Plugin.HelixViewer/HelixPanel.xaml
+++ b/QuickLook.Plugin/QuickLook.Plugin.HelixViewer/HelixPanel.xaml
@@ -9,6 +9,12 @@
d:DesignWidth="800"
mc:Ignorable="d">
+
.
-using Assimp;
-using HelixToolkit.Wpf;
-using System;
-using System.Linq;
using System.Windows.Controls;
-using System.Windows.Media;
-using System.Windows.Media.Media3D;
namespace QuickLook.Plugin.HelixViewer;
@@ -39,43 +33,4 @@ public partial class HelixPanel : UserControl
{
InitializeComponent();
}
-
- private void Load()
- {
- if (_path.EndsWith(".fbx", StringComparison.OrdinalIgnoreCase))
- {
- var context = new AssimpContext();
- var scene = context.ImportFile(_path, PostProcessSteps.Triangulate);
-
- foreach (var mesh in scene.Meshes)
- {
- var geometry = new MeshGeometry3D()
- {
- Positions = [.. mesh.Vertices.Select(v => new Point3D(v.X, v.Y, v.Z))],
- TriangleIndices = [.. mesh.GetIndices()],
- };
- var model = new GeometryModel3D()
- {
- Geometry = geometry,
- Material = Materials.Gray,
- };
-
- modelVisual.Content = model;
- }
- }
- else
- {
- var modelImporter = new ModelImporter();
- var model3DGroup = modelImporter.Load(_path);
- var diffuseMaterial = new DiffuseMaterial(new SolidColorBrush(Color.FromRgb(0xA0, 0xA0, 0xA0)));
-
- foreach (GeometryModel3D child in model3DGroup.Children.Cast())
- {
- child.Material = diffuseMaterial;
- child.BackMaterial = diffuseMaterial;
- }
-
- modelVisual.Content = model3DGroup;
- }
- }
}
diff --git a/QuickLook.Plugin/QuickLook.Plugin.HelixViewer/Plugin.cs b/QuickLook.Plugin/QuickLook.Plugin.HelixViewer/Plugin.cs
index 029a937..16fc1bf 100644
--- a/QuickLook.Plugin/QuickLook.Plugin.HelixViewer/Plugin.cs
+++ b/QuickLook.Plugin/QuickLook.Plugin.HelixViewer/Plugin.cs
@@ -19,21 +19,34 @@ using QuickLook.Common.Plugin;
using System;
using System.Collections.Generic;
using System.IO;
+using System.Linq;
using System.Windows;
namespace QuickLook.Plugin.HelixViewer;
public class Plugin : IViewer
{
+ ///
+ ///
+ ///
private static readonly HashSet WellKnownExtensions = new(
[
+ // Default
".stl", ".obj", ".3ds", ".lwo", ".ply",
- ".fbx",
+
+ // Extended
+ ".fbx", ".3mf", ".blend", ".glb", ".gltf", ".dae",
+#if S_DXF
+ ".dxf",
+#endif
+
+ // Extended_MMD
+ ".pmx",
]);
private HelixPanel _hp;
- public int Priority => 0;
+ public int Priority => -5;
public void Init()
{
@@ -42,7 +55,7 @@ public class Plugin : IViewer
public bool CanHandle(string path)
{
return !Directory.Exists(path)
- && WellKnownExtensions.Contains(Path.GetExtension(path.ToLower()))
+ && WellKnownExtensions.Any(ext => path.EndsWith(ext, StringComparison.OrdinalIgnoreCase))
&& Handler.CanHandle(path);
}