实现模型轻量化接口,支持保留外壳删除内部元件
Co-authored-by: factory-droid[bot] <138933559+factory-droid[bot]@users.noreply.github.com>
This commit is contained in:
parent
69f32020fa
commit
bf35d98365
40
Commands/SimplifyModelCommand.cs
Normal file
40
Commands/SimplifyModelCommand.cs
Normal file
@ -0,0 +1,40 @@
|
||||
using System;
|
||||
using TellmePdmsPluging.Core;
|
||||
using TellmePdmsPluging.Models;
|
||||
|
||||
namespace TellmePdmsPluging.Commands
|
||||
{
|
||||
public class SimplifyModelCommand : ICommand
|
||||
{
|
||||
public SimplifyModelCommand(SimplifyModelRequest request)
|
||||
{
|
||||
Request = request ?? new SimplifyModelRequest();
|
||||
CommandId = Guid.NewGuid().ToString("N");
|
||||
}
|
||||
|
||||
public string CommandId { get; }
|
||||
|
||||
public string CommandType
|
||||
{
|
||||
get { return "SimplifyModel"; }
|
||||
}
|
||||
|
||||
public bool CanCancel
|
||||
{
|
||||
get { return false; }
|
||||
}
|
||||
|
||||
public SimplifyModelRequest Request { get; }
|
||||
|
||||
public object Execute()
|
||||
{
|
||||
Request.ApplyDefaults();
|
||||
return PdmsManager.Instance.SimplifyModel(Request);
|
||||
}
|
||||
|
||||
public void Cancel()
|
||||
{
|
||||
throw new NotSupportedException("SimplifyModelCommand 不支持取消");
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,7 @@ using System.Collections.Generic;
|
||||
using TellmePdmsPluging.Models;
|
||||
using Aveva.ApplicationFramework;
|
||||
using Aveva.Pdms.Database;
|
||||
using System.Linq;
|
||||
|
||||
namespace TellmePdmsPluging.Core
|
||||
{
|
||||
@ -31,6 +32,94 @@ namespace TellmePdmsPluging.Core
|
||||
{
|
||||
}
|
||||
|
||||
public SimplifyModelResult SimplifyModel(SimplifyModelRequest request)
|
||||
{
|
||||
var effectiveRequest = request ?? new SimplifyModelRequest();
|
||||
effectiveRequest.ApplyDefaults();
|
||||
|
||||
var result = new SimplifyModelResult
|
||||
{
|
||||
DryRun = effectiveRequest.DryRun,
|
||||
StartedAt = DateTime.Now
|
||||
};
|
||||
|
||||
try
|
||||
{
|
||||
if (!IsPdmsConnected())
|
||||
{
|
||||
result.Success = false;
|
||||
result.CompletedAt = DateTime.Now;
|
||||
result.Message = "PDMS 未连接";
|
||||
result.Errors.Add("PDMS 未连接");
|
||||
return result;
|
||||
}
|
||||
|
||||
var currentMdb = MDB.CurrentMDB;
|
||||
var designDb = currentMdb?.GetFirstDB(DbType.Design);
|
||||
if (designDb == null || designDb.World == null)
|
||||
{
|
||||
result.Success = false;
|
||||
result.CompletedAt = DateTime.Now;
|
||||
result.Message = "未找到有效的设计数据库";
|
||||
result.Errors.Add("未找到有效的设计数据库");
|
||||
return result;
|
||||
}
|
||||
|
||||
var context = new SimplifyContext(effectiveRequest, result);
|
||||
var sites = designDb.World.Members();
|
||||
bool processed = false;
|
||||
|
||||
if (sites != null)
|
||||
{
|
||||
foreach (var site in sites)
|
||||
{
|
||||
if (!IsElementValid(site) || !string.Equals(GetElementTypeName(site), "SITE", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var zones = site.Members();
|
||||
if (zones == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach (var zone in zones)
|
||||
{
|
||||
if (!IsElementValid(zone) || !string.Equals(GetElementTypeName(zone), "ZONE", StringComparison.OrdinalIgnoreCase))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!context.ShouldProcessZone(zone))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
processed = true;
|
||||
context.EnterZone(zone);
|
||||
context.ProcessChildren(zone);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
result.Success = processed && result.Errors.Count == 0;
|
||||
result.Message = processed
|
||||
? (result.DryRun ? "模型轻量化干跑完成" : "模型轻量化完成")
|
||||
: "未找到符合过滤条件的Zone";
|
||||
result.CompletedAt = DateTime.Now;
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
result.Success = false;
|
||||
result.Errors.Add(ex.Message);
|
||||
result.Message = "模型轻量化失败";
|
||||
result.CompletedAt = DateTime.Now;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
||||
public ModelStatusResponse GetModelStatus()
|
||||
{
|
||||
try
|
||||
@ -321,8 +410,162 @@ namespace TellmePdmsPluging.Core
|
||||
};
|
||||
}
|
||||
}
|
||||
private static bool IsElementValid(DbElement element)
|
||||
{
|
||||
return element != null && !element.IsNull && element.IsValid;
|
||||
}
|
||||
|
||||
private static string GetElementTypeName(DbElement element)
|
||||
{
|
||||
try
|
||||
{
|
||||
var type = element?.GetActualType();
|
||||
return type?.Name ?? string.Empty;
|
||||
}
|
||||
catch
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
}
|
||||
|
||||
private static string BuildElementPath(DbElement element)
|
||||
{
|
||||
var segments = new List<string>();
|
||||
var current = element;
|
||||
int guard = 0;
|
||||
|
||||
while (IsElementValid(current) && guard < 128)
|
||||
{
|
||||
string name = string.Empty;
|
||||
try
|
||||
{
|
||||
if (!current.GetValidString(DbAttributeInstance.NAME, ref name) || string.IsNullOrEmpty(name))
|
||||
{
|
||||
name = current.ToString();
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
name = current.ToString();
|
||||
}
|
||||
|
||||
segments.Add(name.Trim());
|
||||
current = current.Owner;
|
||||
guard++;
|
||||
}
|
||||
|
||||
segments.Reverse();
|
||||
return "/" + string.Join("/", segments.ToArray());
|
||||
}
|
||||
|
||||
private class SimplifyContext
|
||||
{
|
||||
private const int MaxRemovedSnapshots = 200;
|
||||
|
||||
public SimplifyContext(SimplifyModelRequest request, SimplifyModelResult result)
|
||||
{
|
||||
Request = request;
|
||||
Result = result;
|
||||
_keepTypes = new HashSet<string>(request.KeepTypes ?? new List<string>());
|
||||
_removeTypes = new HashSet<string>(request.RemoveTypes ?? new List<string>());
|
||||
}
|
||||
|
||||
public SimplifyModelRequest Request { get; }
|
||||
public SimplifyModelResult Result { get; }
|
||||
public string CurrentZoneName { get; private set; }
|
||||
|
||||
private readonly HashSet<string> _keepTypes;
|
||||
private readonly HashSet<string> _removeTypes;
|
||||
|
||||
public bool ShouldProcessZone(DbElement zone)
|
||||
{
|
||||
if (Request.ZoneFilters == null || Request.ZoneFilters.Count == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
var zonePath = BuildElementPath(zone).ToUpperInvariant();
|
||||
return Request.ZoneFilters.Any(filter => zonePath.Contains(filter));
|
||||
}
|
||||
|
||||
public void EnterZone(DbElement zone)
|
||||
{
|
||||
CurrentZoneName = BuildElementPath(zone);
|
||||
if (!Result.ZoneSummaries.Contains(CurrentZoneName))
|
||||
{
|
||||
Result.ZoneSummaries.Add(CurrentZoneName);
|
||||
}
|
||||
}
|
||||
|
||||
public void ProcessChildren(DbElement parent)
|
||||
{
|
||||
var members = parent.Members();
|
||||
if (members == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
foreach (var child in members)
|
||||
{
|
||||
ProcessElement(child);
|
||||
}
|
||||
}
|
||||
|
||||
private void ProcessElement(DbElement element)
|
||||
{
|
||||
if (!IsElementValid(element))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Result.TotalVisited++;
|
||||
var typeName = GetElementTypeName(element);
|
||||
var normalizedType = string.IsNullOrEmpty(typeName) ? string.Empty : typeName.ToUpperInvariant();
|
||||
|
||||
bool keep = _keepTypes.Contains(normalizedType);
|
||||
bool remove = _removeTypes.Contains(normalizedType) && !keep;
|
||||
|
||||
if (remove)
|
||||
{
|
||||
RemoveElement(element, normalizedType);
|
||||
return;
|
||||
}
|
||||
|
||||
Result.KeptCount++;
|
||||
ProcessChildren(element);
|
||||
}
|
||||
|
||||
private void RemoveElement(DbElement element, string typeName)
|
||||
{
|
||||
var elementPath = BuildElementPath(element);
|
||||
|
||||
if (Request.DryRun)
|
||||
{
|
||||
SnapshotRemoval(elementPath, typeName, true);
|
||||
return;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
element.Delete();
|
||||
SnapshotRemoval(elementPath, typeName, false);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Result.Errors.Add($"删除元素 {elementPath} 失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private void SnapshotRemoval(string elementPath, string typeName, bool dryRun)
|
||||
{
|
||||
Result.RemovedCount++;
|
||||
|
||||
if (Result.RemovedElements.Count < MaxRemovedSnapshots)
|
||||
{
|
||||
var marker = dryRun ? "DRY" : "DEL";
|
||||
Result.RemovedElements.Add($"[{marker}] {elementPath} ({typeName})");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
121
Models/SimplifyModelRequest.cs
Normal file
121
Models/SimplifyModelRequest.cs
Normal file
@ -0,0 +1,121 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
|
||||
namespace TellmePdmsPluging.Models
|
||||
{
|
||||
public class SimplifyModelRequest
|
||||
{
|
||||
public bool DryRun { get; set; } = true;
|
||||
|
||||
public List<string> ZoneFilters
|
||||
{
|
||||
get { return _zoneFilters; }
|
||||
set { _zoneFilters = NormalizeList(value); }
|
||||
}
|
||||
|
||||
public List<string> KeepTypes
|
||||
{
|
||||
get { return _keepTypes; }
|
||||
set { _keepTypes = NormalizeList(value); }
|
||||
}
|
||||
|
||||
public List<string> RemoveTypes
|
||||
{
|
||||
get { return _removeTypes; }
|
||||
set { _removeTypes = NormalizeList(value); }
|
||||
}
|
||||
|
||||
public ShellPaddingOptions BoundingShell { get; set; } = new ShellPaddingOptions();
|
||||
|
||||
private List<string> _zoneFilters;
|
||||
private List<string> _keepTypes;
|
||||
private List<string> _removeTypes;
|
||||
|
||||
public void ApplyDefaults()
|
||||
{
|
||||
if (_keepTypes == null || _keepTypes.Count == 0)
|
||||
{
|
||||
_keepTypes = new List<string> { "SITE", "ZONE", "STRU", "FRAME", "SHELL", "PLAT", "WALL" };
|
||||
}
|
||||
|
||||
if (_removeTypes == null || _removeTypes.Count == 0)
|
||||
{
|
||||
_removeTypes = new List<string> { "PIPE", "BRAN", "ELBO", "VALV", "FITT", "NOZZ", "EQUI" };
|
||||
}
|
||||
|
||||
if (_zoneFilters == null)
|
||||
{
|
||||
_zoneFilters = new List<string>();
|
||||
}
|
||||
|
||||
if (BoundingShell == null)
|
||||
{
|
||||
BoundingShell = new ShellPaddingOptions();
|
||||
}
|
||||
}
|
||||
|
||||
private static List<string> NormalizeList(IEnumerable<string> source)
|
||||
{
|
||||
if (source == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
var normalized = new List<string>();
|
||||
|
||||
foreach (var item in source)
|
||||
{
|
||||
if (IsNullOrWhiteSpace(item))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
var formatted = item.Trim().ToUpperInvariant();
|
||||
if (!normalized.Contains(formatted))
|
||||
{
|
||||
normalized.Add(formatted);
|
||||
}
|
||||
}
|
||||
|
||||
return normalized;
|
||||
}
|
||||
|
||||
private static bool IsNullOrWhiteSpace(string value)
|
||||
{
|
||||
if (value == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < value.Length; i++)
|
||||
{
|
||||
if (!char.IsWhiteSpace(value[i]))
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public class ShellPaddingOptions
|
||||
{
|
||||
public double Padding { get; set; } = 0d;
|
||||
}
|
||||
}
|
||||
|
||||
public class SimplifyModelResult
|
||||
{
|
||||
public bool Success { get; set; }
|
||||
public bool DryRun { get; set; }
|
||||
public int TotalVisited { get; set; }
|
||||
public int RemovedCount { get; set; }
|
||||
public int KeptCount { get; set; }
|
||||
public List<string> RemovedElements { get; set; } = new List<string>();
|
||||
public List<string> Errors { get; set; } = new List<string>();
|
||||
public DateTime StartedAt { get; set; }
|
||||
public DateTime CompletedAt { get; set; }
|
||||
public string Message { get; set; }
|
||||
public List<string> ZoneSummaries { get; set; } = new List<string>();
|
||||
}
|
||||
}
|
||||
@ -3,6 +3,8 @@ using System.Net;
|
||||
using System.Text;
|
||||
using System.IO;
|
||||
using System.Collections.Generic;
|
||||
using System.Web.Script.Serialization;
|
||||
using TellmePdmsPluging.Commands;
|
||||
using TellmePdmsPluging.Core;
|
||||
using TellmePdmsPluging.Models;
|
||||
|
||||
@ -121,6 +123,9 @@ namespace TellmePdmsPluging.Network
|
||||
case "/api/status/model":
|
||||
responseJson = HandleModelStatus();
|
||||
break;
|
||||
case "/api/model/simplify":
|
||||
responseJson = HandleModelSimplify(request);
|
||||
break;
|
||||
default:
|
||||
response.StatusCode = 404;
|
||||
responseJson = CreateErrorResponse(404, "接口不存在");
|
||||
@ -211,6 +216,54 @@ namespace TellmePdmsPluging.Network
|
||||
}
|
||||
}
|
||||
|
||||
private string HandleModelSimplify(HttpListenerRequest request)
|
||||
{
|
||||
try
|
||||
{
|
||||
var payload = ReadRequestBody(request);
|
||||
if (string.IsNullOrEmpty(payload))
|
||||
{
|
||||
return CreateErrorResponse(400, "请求体不能为空");
|
||||
}
|
||||
|
||||
var serializer = new JavaScriptSerializer();
|
||||
var simplifyRequest = serializer.Deserialize<SimplifyModelRequest>(payload) ?? new SimplifyModelRequest();
|
||||
|
||||
var command = new SimplifyModelCommand(simplifyRequest);
|
||||
var result = command.Execute() as SimplifyModelResult;
|
||||
|
||||
if (result == null)
|
||||
{
|
||||
return CreateErrorResponse(500, "模型轻量化结果为空");
|
||||
}
|
||||
|
||||
if (!result.Success)
|
||||
{
|
||||
var message = string.IsNullOrEmpty(result.Message) ? "模型轻量化失败" : result.Message;
|
||||
return CreateErrorResponse(500, message);
|
||||
}
|
||||
|
||||
return CreateSuccessResponse(result);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
return CreateErrorResponse(500, $"模型轻量化失败: {ex.Message}");
|
||||
}
|
||||
}
|
||||
|
||||
private string ReadRequestBody(HttpListenerRequest request)
|
||||
{
|
||||
if (request == null || request.InputStream == null)
|
||||
{
|
||||
return string.Empty;
|
||||
}
|
||||
|
||||
using (var reader = new StreamReader(request.InputStream, request.ContentEncoding ?? Encoding.UTF8))
|
||||
{
|
||||
return reader.ReadToEnd();
|
||||
}
|
||||
}
|
||||
|
||||
private bool CheckPdmsStatus()
|
||||
{
|
||||
try
|
||||
|
||||
@ -69,13 +69,16 @@
|
||||
<Reference Include="System.Data.DataSetExtensions" />
|
||||
<Reference Include="System.Data" />
|
||||
<Reference Include="System.Xml" />
|
||||
<Reference Include="System.Web.Extensions" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Compile Include="Class1.cs" />
|
||||
<Compile Include="Commands\SimplifyModelCommand.cs" />
|
||||
<Compile Include="Core\ICommand.cs" />
|
||||
<Compile Include="Core\ApiResponse.cs" />
|
||||
<Compile Include="Core\PdmsManager.cs" />
|
||||
<Compile Include="Models\ModelStatusResponse.cs" />
|
||||
<Compile Include="Models\SimplifyModelRequest.cs" />
|
||||
<Compile Include="Network\HttpServer.cs" />
|
||||
<Compile Include="Properties\AssemblyInfo.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
Loading…
Reference in New Issue
Block a user