NavisworksTransport/src/Utils/PathHelper.cs

242 lines
9.4 KiB
C#
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

using System;
using System.Drawing.Imaging;
using System.IO;
using System.Linq;
using System.Text.RegularExpressions;
using Autodesk.Navisworks.Api;
namespace NavisworksTransport.Utils
{
/// <summary>
/// 路径处理工具类 - 提供文件路径相关的通用方法
/// </summary>
public static class PathHelper
{
/// <summary>
/// 获取插件目录路径
/// </summary>
public static string GetPluginDirectory()
{
return Path.Combine(
Environment.GetFolderPath(Environment.SpecialFolder.CommonApplicationData),
"Autodesk",
"Navisworks Manage 2026",
"plugins",
"TransportPlugin"
);
}
/// <summary>
/// 获取截图目录路径
/// </summary>
public static string GetScreenshotDirectory()
{
return Path.Combine(GetPluginDirectory(), "screenshots");
}
/// <summary>
/// 获取报告目录路径
/// </summary>
public static string GetReportDirectory()
{
return Path.Combine(GetPluginDirectory(), "reports");
}
/// <summary>
/// 确保目录存在,不存在则创建
/// </summary>
public static void EnsureDirectoryExists(string directory)
{
if (!string.IsNullOrEmpty(directory) && !Directory.Exists(directory))
{
Directory.CreateDirectory(directory);
}
}
/// <summary>
/// 清理文件名中的非法字符
/// </summary>
/// <param name="fileName">原始文件名</param>
/// <returns>清理后的文件名</returns>
public static string SanitizeFileName(string fileName)
{
if (string.IsNullOrEmpty(fileName))
{
return "unnamed";
}
var invalidChars = Path.GetInvalidFileNameChars();
var cleanedFileName = new string(fileName.Where(c => !invalidChars.Contains(c)).ToArray());
// 如果清理后为空,返回默认名称
return string.IsNullOrWhiteSpace(cleanedFileName) ? "unnamed" : cleanedFileName;
}
/// <summary>
/// 生成带时间戳的文件名
/// </summary>
/// <param name="prefix">文件名前缀</param>
/// <param name="extension">文件扩展名(不含点号)</param>
/// <returns>带时间戳的文件名</returns>
public static string GenerateTimestampedFileName(string prefix, string extension)
{
string timestamp = DateTime.Now.ToString("yyyyMMdd_HHmmss");
return $"{prefix}_{timestamp}.{extension}";
}
/// <summary>
/// 生成碰撞检测报告文件名。
/// 格式碰撞检测报告_{路径名}_{时间戳}.{extension}
/// </summary>
public static string GenerateCollisionReportFileName(string pathName, string extension, DateTime? now = null)
{
string sanitizedName = SanitizeFileName(pathName ?? "未知路径");
string normalizedExtension = string.IsNullOrWhiteSpace(extension)
? "html"
: extension.Trim().TrimStart('.');
string timestamp = (now ?? DateTime.Now).ToString("yyyyMMdd_HHmmss");
return $"碰撞检测报告_{sanitizedName}_{timestamp}.{normalizedExtension}";
}
/// <summary>
/// 生成复制路径名称。
/// 如果原名称以 MMdd_HHmmss 结尾则重建时间戳否则仅添加“副本_”前缀。
/// </summary>
public static string BuildDuplicatedPathName(string originalName, DateTime? now = null)
{
var normalizedName = string.IsNullOrWhiteSpace(originalName) ? "路径" : originalName.Trim();
var timestampPattern = new Regex(@"^(.*)_\d{4}_\d{6}$");
var match = timestampPattern.Match(normalizedName);
if (!match.Success)
{
return $"副本_{normalizedName}";
}
var baseName = match.Groups[1].Value;
var timestamp = (now ?? DateTime.Now).ToString("MMdd_HHmmss");
return $"副本_{baseName}_{timestamp}";
}
/// <summary>
/// 计算从HTML文件到目标文件的相对路径
/// </summary>
/// <param name="fromPath">HTML文件路径</param>
/// <param name="toPath">目标文件路径</param>
/// <returns>相对路径(使用正斜杠)</returns>
public static string GetRelativePath(string fromPath, string toPath)
{
try
{
var fromUri = new Uri(fromPath);
var toUri = new Uri(toPath);
var relativeUri = fromUri.MakeRelativeUri(toUri);
return Uri.UnescapeDataString(relativeUri.ToString()).Replace('\\', '/');
}
catch (Exception ex)
{
LogManager.Error($"计算相对路径失败: {ex.Message}");
return toPath; // 失败时返回绝对路径
}
}
/// <summary>
/// 将ImageFormat转换为文件扩展名
/// </summary>
public static string ImageFormatToExtension(ImageFormat format)
{
if (format.Equals(ImageFormat.Jpeg))
return "jpg";
if (format.Equals(ImageFormat.Png))
return "png";
if (format.Equals(ImageFormat.Bmp))
return "bmp";
return "png"; // 默认
}
/// <summary>
/// 将文件扩展名转换为ImageFormat
/// </summary>
public static ImageFormat ExtensionToImageFormat(string extension)
{
if (string.IsNullOrEmpty(extension))
return ImageFormat.Png;
extension = extension.ToLowerInvariant();
if (extension == ".jpg" || extension == ".jpeg")
return ImageFormat.Jpeg;
if (extension == ".png")
return ImageFormat.Png;
if (extension == ".bmp")
return ImageFormat.Bmp;
return ImageFormat.Png; // 默认
}
/// <summary>
/// 生成场景截图(通用方法)
/// </summary>
/// <param name="sceneName">场景名称</param>
/// <param name="width">图像宽度</param>
/// <param name="height">图像高度</param>
/// <param name="format">图像格式</param>
/// <param name="prefix">文件名前缀</param>
/// <returns>截图文件路径失败返回null</returns>
public static string GenerateSceneScreenshot(string sceneName, int width, int height, ImageFormat format, string prefix = "scene")
{
return GenerateSceneScreenshotInternal(GetScreenshotDirectory(), sceneName, width, height, format, prefix);
}
/// <summary>
/// 生成场景截图到指定目录
/// </summary>
/// <param name="outputDirectory">输出目录</param>
/// <param name="sceneName">场景名称</param>
/// <param name="width">图像宽度</param>
/// <param name="height">图像高度</param>
/// <param name="format">图像格式</param>
/// <param name="prefix">文件名前缀</param>
/// <returns>截图文件路径失败返回null</returns>
public static string GenerateSceneScreenshotToDirectory(string outputDirectory, string sceneName, int width, int height, ImageFormat format, string prefix = "scene")
{
return GenerateSceneScreenshotInternal(outputDirectory, sceneName, width, height, format, prefix);
}
/// <summary>
/// 生成场景截图内部实现
/// </summary>
private static string GenerateSceneScreenshotInternal(string outputDirectory, string sceneName, int width, int height, ImageFormat format, string prefix)
{
try
{
LogManager.Debug(string.Format("开始生成场景截图: {0}_{1}, 尺寸={2}x{3}, 目录={4}", prefix, sceneName, width, height, outputDirectory));
// 生成文件名SaveNavigationMapImage会确保目录存在
string extension = ImageFormatToExtension(format);
string sanitizedName = SanitizeFileName(sceneName);
string filename = GenerateTimestampedFileName(string.Format("{0}_{1}", prefix, sanitizedName), extension);
string screenshotPath = Path.Combine(outputDirectory, filename);
// 调用截图生成器(复用 NavigationMapGenerator
var generator = new Core.NavigationMapGenerator();
var bitmap = generator.GenerateNavigationMapImage(
ImageGenerationStyle.ScenePlusOverlay,
width,
height,
false
);
// 保存截图SaveNavigationMapImage内部会确保目录存在
generator.SaveNavigationMapImage(bitmap, screenshotPath, format);
LogManager.Debug(string.Format("场景截图已生成: {0}", screenshotPath));
return screenshotPath;
}
catch (Exception ex)
{
LogManager.Error(string.Format("生成场景截图失败: {0}", ex.Message), ex);
return null;
}
}
}
}