清理代码
This commit is contained in:
@@ -1,21 +0,0 @@
|
||||
using System.Reflection;
|
||||
|
||||
using ShrlAlgoToolkit.Core.Assists;
|
||||
using ShrlAlgoToolkit;
|
||||
using ShrlAlgoToolkit.Core;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Assists;
|
||||
|
||||
public static class EnumAssist
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取当前枚举值的描述,没有描述则返回空字符串
|
||||
/// </summary>
|
||||
/// <param name="value"></param>
|
||||
/// <returns></returns>
|
||||
public static T GetAttribute<T>(this Enum value) where T : Attribute
|
||||
{
|
||||
var fieldInfo = value.GetType().GetField(value.ToString());
|
||||
return fieldInfo.GetCustomAttribute<T>();
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,13 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.Drawing;
|
||||
using System.Drawing.Text;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Interop;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
|
||||
using ShrlAlgoToolkit.Core.Assists;
|
||||
using ShrlAlgoToolkit;
|
||||
using ShrlAlgoToolkit.Core;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Assists;
|
||||
|
||||
public static class ImageAssist
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
using System.IO;
|
||||
using System.Text;
|
||||
|
||||
using ShrlAlgoToolkit.Core.Assists;
|
||||
using ShrlAlgoToolkit;
|
||||
using ShrlAlgoToolkit.Core;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Assists;
|
||||
|
||||
public static class LogAssist
|
||||
|
||||
@@ -1,649 +0,0 @@
|
||||
using System.Diagnostics;
|
||||
using System.Drawing;
|
||||
using System.IO;
|
||||
using System.IO.Packaging;
|
||||
using System.Reflection;
|
||||
using System.Text;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Xml;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Assists
|
||||
{
|
||||
/// <summary>
|
||||
/// 直接读取文件的信息(不依赖RevitAPI)
|
||||
/// </summary>
|
||||
public class RevitFileAssist
|
||||
{
|
||||
public RevitFileAssist(string filePath)
|
||||
{
|
||||
if (filePath.EndsWith(".rvt") || filePath.EndsWith(".rte") || filePath.EndsWith(".rfa") ||
|
||||
filePath.EndsWith(".rft"))
|
||||
{
|
||||
ParserRevitFile(filePath);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
throw new Exception("文件格式不正确!");
|
||||
}
|
||||
}
|
||||
/// <summary>
|
||||
/// 图片资源转字节
|
||||
/// </summary>
|
||||
/// <param name="bitmapSource"></param>
|
||||
/// <returns></returns>
|
||||
private static byte[] BitSourceToArray(BitmapSource bitmapSource)
|
||||
{
|
||||
BitmapEncoder encoder = new JpegBitmapEncoder();
|
||||
using var ms = new MemoryStream();
|
||||
encoder.Frames.Add(BitmapFrame.Create(bitmapSource));
|
||||
encoder.Save(ms);
|
||||
return ms.ToArray();
|
||||
}
|
||||
|
||||
private static int GetPngStartingOffset(byte[] previewData)
|
||||
{
|
||||
var markerFound = false;
|
||||
var startingOffset = 0;
|
||||
var previousValue = 0;
|
||||
using var ms = new MemoryStream(previewData);
|
||||
for (var i = 0; i < previewData.Length; i++)
|
||||
{
|
||||
var currentValue = ms.ReadByte();
|
||||
// possible start of PNG file data
|
||||
if (currentValue == 137) // 0x89
|
||||
{
|
||||
markerFound = true;
|
||||
startingOffset = i;
|
||||
previousValue = currentValue;
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (currentValue)
|
||||
{
|
||||
case 80: // 0x50
|
||||
if (markerFound && previousValue == 137)
|
||||
{
|
||||
previousValue = currentValue;
|
||||
continue;
|
||||
}
|
||||
|
||||
markerFound = false;
|
||||
break;
|
||||
|
||||
case 78: // 0x4E
|
||||
if (markerFound && previousValue == 80)
|
||||
{
|
||||
previousValue = currentValue;
|
||||
continue;
|
||||
}
|
||||
|
||||
markerFound = false;
|
||||
break;
|
||||
|
||||
case 71: // 0x47
|
||||
if (markerFound && previousValue == 78)
|
||||
{
|
||||
previousValue = currentValue;
|
||||
continue;
|
||||
}
|
||||
|
||||
markerFound = false;
|
||||
break;
|
||||
|
||||
case 13: // 0x0D
|
||||
if (markerFound && previousValue == 71)
|
||||
{
|
||||
previousValue = currentValue;
|
||||
continue;
|
||||
}
|
||||
|
||||
markerFound = false;
|
||||
break;
|
||||
|
||||
case 10: // 0x0A
|
||||
if (markerFound && previousValue == 26)
|
||||
{
|
||||
return startingOffset;
|
||||
}
|
||||
|
||||
if (markerFound && previousValue == 13)
|
||||
{
|
||||
previousValue = currentValue;
|
||||
continue;
|
||||
}
|
||||
|
||||
markerFound = false;
|
||||
break;
|
||||
|
||||
case 26: // 0x1A
|
||||
if (markerFound && previousValue == 10)
|
||||
{
|
||||
previousValue = currentValue;
|
||||
continue;
|
||||
}
|
||||
|
||||
markerFound = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 获取缩略图
|
||||
/// </summary>
|
||||
/// <param name="previewData"></param>
|
||||
/// <returns></returns>
|
||||
private static Image GetPreviewAsImage(byte[] previewData)
|
||||
{
|
||||
if (previewData is not { Length: > 0 })
|
||||
{
|
||||
using var newBitmap = new Bitmap(128, 128);
|
||||
return newBitmap.Clone() as Bitmap;
|
||||
}
|
||||
|
||||
// read past the Revit metadata to the start of the PNG image
|
||||
var startingOffset = GetPngStartingOffset(previewData);
|
||||
if (startingOffset == 0)
|
||||
{
|
||||
using var newBitmap = new Bitmap(128, 128);
|
||||
return newBitmap.Clone() as Bitmap;
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
var pngDataBuffer = new byte[previewData.GetUpperBound(0) - startingOffset + 1];
|
||||
// read the PNG image data into a byte array
|
||||
using (var ms = new MemoryStream(previewData))
|
||||
{
|
||||
ms.Position = startingOffset;
|
||||
ms.Read(pngDataBuffer, 0, pngDataBuffer.Length);
|
||||
}
|
||||
|
||||
byte[] decoderData = null;
|
||||
|
||||
// if the image data is valid
|
||||
if (pngDataBuffer != null)
|
||||
{
|
||||
// use a memory stream to decode the PNG image data
|
||||
// and copy the decoded data into a byte array
|
||||
using var ms = new MemoryStream(pngDataBuffer);
|
||||
var decoder = new PngBitmapDecoder(ms, BitmapCreateOptions.PreservePixelFormat,
|
||||
BitmapCacheOption.Default);
|
||||
decoderData = BitSourceToArray(decoder.Frames[0]);
|
||||
}
|
||||
|
||||
if (decoderData is { Length: > 0 })
|
||||
{
|
||||
// use another memory stream to create a Bitmap
|
||||
// and then an Image from that Bitmap
|
||||
using var ms = new MemoryStream(decoderData);
|
||||
using var newBitmap = new Bitmap(ms);
|
||||
using Image newImage = newBitmap;
|
||||
return newImage.Clone() as Image;
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Debug.WriteLine(ex.Message);
|
||||
}
|
||||
|
||||
using (var newBitmap = new Bitmap(128, 128))
|
||||
{
|
||||
return newBitmap.Clone() as Bitmap;
|
||||
}
|
||||
}
|
||||
|
||||
private static StringBuilder ParseContents(string unicodeData)
|
||||
{
|
||||
var s = new StringBuilder();
|
||||
|
||||
var basicFileInfoParts = unicodeData.Split('\0');
|
||||
|
||||
foreach (var basicFileInfoPart in basicFileInfoParts)
|
||||
{
|
||||
if (basicFileInfoPart.IndexOf("\r\n", StringComparison.Ordinal) >= 0)
|
||||
{
|
||||
var detailInfoParts = basicFileInfoPart.Split(new[] { "\r\n" }, new StringSplitOptions());
|
||||
foreach (var detailPart in detailInfoParts)
|
||||
{
|
||||
s.Append(ParseDetailInfo(detailPart) + "\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
|
||||
private static string ParseDetailInfo(string detailInfo)
|
||||
{
|
||||
try
|
||||
{
|
||||
detailInfo = detailInfo.Trim();
|
||||
var index = detailInfo.IndexOf(":", StringComparison.Ordinal);
|
||||
var detailValue = detailInfo.Substring(index + 1);
|
||||
var detailKey = detailInfo.Substring(0, index);
|
||||
detailKey = detailKey.Trim().ToUpper().Replace(" ", string.Empty);
|
||||
detailKey = PurgeUnprintableCharacters(detailKey);
|
||||
detailValue = PurgeUnprintableCharacters(detailValue);
|
||||
return $"{detailKey}:{detailValue}";
|
||||
//Console.WriteLine($"{detailKey}:{detailValue}");
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
return detailInfo;
|
||||
}
|
||||
|
||||
//switch (detailKey)
|
||||
//{
|
||||
// case "WORKSHARING":
|
||||
// if (string.IsNullOrEmpty(detailValue))
|
||||
// {
|
||||
// WorkSharing = WorkSharingMode.HCLight;
|
||||
// return;
|
||||
// }
|
||||
|
||||
// string workSharing = detailValue.Replace(" ", string.Empty).Trim().ToUpper();
|
||||
// switch (workSharing)
|
||||
// {
|
||||
// case "NOTENABLED":
|
||||
// WorkSharing = WorkSharingMode.NotEnabled;
|
||||
// break;
|
||||
|
||||
// case "LOCAL":
|
||||
// WorkSharing = WorkSharingMode.Local;
|
||||
// break;
|
||||
|
||||
// case "CENTRAL":
|
||||
// WorkSharing = WorkSharingMode.Central;
|
||||
// break;
|
||||
|
||||
// default:
|
||||
// WorkSharing = WorkSharingMode.HCLight;
|
||||
// break;
|
||||
// }
|
||||
// break;
|
||||
|
||||
// case "USERNAME":
|
||||
// UserName = detailValue.Trim();
|
||||
// break;
|
||||
|
||||
// case "CENTRALFILEPATH":
|
||||
// CentralFilePath = detailValue.Trim();
|
||||
// break;
|
||||
|
||||
// case "REVITBUILD":
|
||||
// RevitBuild = detailValue.Trim();
|
||||
// break;
|
||||
|
||||
// case "LASTSAVEPATH":
|
||||
// LastSavedpath = detailValue.Trim();
|
||||
// break;
|
||||
|
||||
// case "OPENWORKSETDEFAULT":
|
||||
// OpenWorksetDefault = Convert.ToInt32(detailValue.Trim());
|
||||
// break;
|
||||
|
||||
// default:
|
||||
// Console.WriteLine($"{detailKey}:{detailValue}");
|
||||
// //Debug.Assert(false, string.Format("{0} was not found in the case tests.", detailKey));
|
||||
// break;
|
||||
//}
|
||||
}
|
||||
|
||||
private static StringBuilder ParseFileInfo(string unicodeData)
|
||||
{
|
||||
var s = new StringBuilder();
|
||||
|
||||
var basicFileInfoParts = unicodeData.Split('\0');
|
||||
|
||||
foreach (var basicFileInfoPart in basicFileInfoParts)
|
||||
{
|
||||
if (basicFileInfoPart.IndexOf("\r\n", StringComparison.Ordinal) >= 0)
|
||||
{
|
||||
var detailInfoParts = basicFileInfoPart.Split(new[] { "\r\n" }, new StringSplitOptions());
|
||||
foreach (var detailPart in detailInfoParts)
|
||||
{
|
||||
s.Append(ParseDetailInfo(detailPart) + "\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 解析参数
|
||||
/// </summary>
|
||||
/// <param name="streamInfo"></param>
|
||||
private List<FamilyTypeDefinition> ParseParameterDefinition(StreamInfo streamInfo)
|
||||
{
|
||||
var document = new XmlDocument();
|
||||
|
||||
string xmlStr;
|
||||
byte[] streamData;
|
||||
using var streamReader = streamInfo.GetStream(FileMode.Open, FileAccess.Read);
|
||||
streamData = new byte[streamReader.Length];
|
||||
streamReader.Read(streamData, 0, streamData.Length);
|
||||
xmlStr = Encoding.UTF8.GetString(streamData);
|
||||
document.LoadXml(xmlStr);
|
||||
//string xmldocpath = Path.GetFileNameWithoutExtension(FileName) + ".xml";
|
||||
//document.Save(xmldocpath);
|
||||
|
||||
//读取参数信息
|
||||
var root = document.DocumentElement;
|
||||
//节点前缀的命名空间
|
||||
var nameSpace = root.GetNamespaceOfPrefix("A");
|
||||
//string nameSpace = root.NamespaceURI;
|
||||
var nsmgr = new XmlNamespaceManager(document.NameTable);
|
||||
;
|
||||
nsmgr.AddNamespace("entry", nameSpace);
|
||||
|
||||
//族类型
|
||||
var xnlist = document.GetElementsByTagName("A:part");
|
||||
|
||||
var fileinfo = document.GetElementsByTagName("A:design-file");
|
||||
foreach (XmlNode xn in fileinfo)
|
||||
{
|
||||
if (xn.HasChildNodes)
|
||||
{
|
||||
foreach (XmlNode child in xn.ChildNodes)
|
||||
{
|
||||
if (child.Name == "A:title")
|
||||
{
|
||||
SafeName = child.InnerText;
|
||||
}
|
||||
|
||||
if (child.Name == "A:product")
|
||||
{
|
||||
Product = child.InnerText;
|
||||
}
|
||||
|
||||
if (child.Name == "A:product-version")
|
||||
{
|
||||
RevitVersion = child.InnerText;
|
||||
}
|
||||
|
||||
if (child.Name == "A:product-updated")
|
||||
{
|
||||
UpdateTime = child.InnerText;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
//XmlNode rootnode = document.SelectSingleNode("/entry/A: family/A:part", nsmgr);
|
||||
//XmlNodeList xnlist = rootnode.ChildNodes;
|
||||
|
||||
var symbols = new List<FamilyTypeDefinition>();
|
||||
foreach (XmlNode xn in xnlist)
|
||||
{
|
||||
//XmlAttributeCollection attriCol = xn.Attributes;
|
||||
//foreach (XmlAttribute xmlAttri in attriCol)
|
||||
//{
|
||||
// string name = xmlAttri.Name;
|
||||
// string value = xmlAttri.Value;
|
||||
//}
|
||||
var symbol = new FamilyTypeDefinition();
|
||||
if (xn.HasChildNodes)
|
||||
{
|
||||
foreach (XmlNode child in xn.ChildNodes)
|
||||
{
|
||||
var p = new ParameterDefinition();
|
||||
if (child.Name == "title")
|
||||
{
|
||||
symbol.Name = child.InnerText;
|
||||
continue;
|
||||
}
|
||||
|
||||
//族类型节点
|
||||
p.Name = child.Name;
|
||||
//族名称
|
||||
p.Value = child.InnerText;
|
||||
symbol.ParameterDefinitions.Add(p);
|
||||
}
|
||||
}
|
||||
|
||||
symbols.Add(symbol);
|
||||
}
|
||||
|
||||
return symbols;
|
||||
}
|
||||
|
||||
private static StringBuilder ParsePartAtom(string unicodeData)
|
||||
{
|
||||
var s = new StringBuilder();
|
||||
var basicFileInfoParts = unicodeData.Split('\0');
|
||||
|
||||
foreach (var basicFileInfoPart in basicFileInfoParts)
|
||||
{
|
||||
if (basicFileInfoPart.IndexOf("\r\n", StringComparison.Ordinal) >= 0)
|
||||
{
|
||||
var detailInfoParts = basicFileInfoPart.Split(new[] { "\r\n" }, new StringSplitOptions());
|
||||
foreach (var detailPart in detailInfoParts)
|
||||
{
|
||||
s.Append(ParseDetailInfo(detailPart) + "\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
/// <summary>
|
||||
/// 解析预览图像(使用循环确保完整读取,避免 CA2022 警告)
|
||||
/// </summary>
|
||||
/// <param name="stream"></param>
|
||||
/// <returns></returns>
|
||||
private static Image ParsePreviewImage(StreamInfo stream)
|
||||
{
|
||||
byte[] streamData;
|
||||
using (var streamReader = stream.GetStream(FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
// 获取长度并校验
|
||||
long lengthLong = streamReader.Length;
|
||||
if (lengthLong < 0)
|
||||
{
|
||||
throw new IOException("Stream length is negative.");
|
||||
}
|
||||
|
||||
if (lengthLong > int.MaxValue)
|
||||
{
|
||||
throw new IOException("Stream is too large to be read into a single byte array.");
|
||||
}
|
||||
|
||||
var totalBytes = (int)lengthLong;
|
||||
streamData = new byte[totalBytes];
|
||||
|
||||
int offset = 0;
|
||||
while (offset < totalBytes)
|
||||
{
|
||||
int bytesRead = streamReader.Read(streamData, offset, totalBytes - offset);
|
||||
if (bytesRead == 0)
|
||||
{
|
||||
// 流在预期字节读取完成前就结束,抛出异常以避免不完整数据处理
|
||||
throw new EndOfStreamException("Unable to read the full stream data.");
|
||||
}
|
||||
|
||||
offset += bytesRead;
|
||||
}
|
||||
}
|
||||
|
||||
return GetPreviewAsImage(streamData);
|
||||
}
|
||||
/// <summary>
|
||||
/// 解析传输数据
|
||||
/// </summary>
|
||||
/// <param name="unicodeData"></param>
|
||||
/// <returns></returns>
|
||||
private static StringBuilder ParseTransMissionData(string unicodeData)
|
||||
{
|
||||
var s = new StringBuilder();
|
||||
|
||||
var basicFileInfoParts = unicodeData.Split('\0');
|
||||
|
||||
foreach (var basicFileInfoPart in basicFileInfoParts)
|
||||
{
|
||||
if (basicFileInfoPart.IndexOf("\r\n") >= 0)
|
||||
{
|
||||
var detailInfoParts = basicFileInfoPart.Split(new[] { "\r\n" }, new StringSplitOptions());
|
||||
foreach (var detailPart in detailInfoParts)
|
||||
{
|
||||
s.Append(ParseDetailInfo(detailPart) + "\r\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
//public static StringBuilder GetFamilyInfo(List<FamilyTypeDefinition> symbols)
|
||||
//{
|
||||
// var sb = new StringBuilder();
|
||||
// foreach (var symbol in symbols)
|
||||
// {
|
||||
// sb.Append($"族类型:{symbol.Name}{symbol.Value}\r\n");
|
||||
// foreach (var param in symbol.ParameterDefinitions)
|
||||
// {
|
||||
// sb.Append($" {param.Name}:{param.Value}\r\n");
|
||||
// }
|
||||
// }
|
||||
// return sb;
|
||||
//}
|
||||
/// <summary>
|
||||
/// 解析Revit文件信息
|
||||
/// </summary>
|
||||
/// <param name="filename"></param>
|
||||
private void ParserRevitFile(string filename)
|
||||
{
|
||||
//获取Storageroot Object
|
||||
var bindingFlags = BindingFlags.Static | BindingFlags.Instance | BindingFlags.Public |
|
||||
BindingFlags.NonPublic | BindingFlags.InvokeMethod;
|
||||
|
||||
var storageRootType = typeof(StorageInfo).Assembly.GetType("System.IO.Packaging.StorageRoot", true, false);
|
||||
//Type storageRootType = typeof(StorageInfo).Assembly.GetType("System.IO.Packaging", true, false);
|
||||
object[] file =
|
||||
{
|
||||
filename,
|
||||
FileMode.Open,
|
||||
FileAccess.Read,
|
||||
FileShare.Read
|
||||
};
|
||||
var Storage = (StorageInfo)storageRootType.InvokeMember("Open", bindingFlags, null, null, file);
|
||||
|
||||
//if (Storage != null)
|
||||
//{
|
||||
// storageRootType.InvokeMember("CloseTrigger", bindingFlags, null, Storage, file);
|
||||
|
||||
// //Console.Write($"{filePath}文件无法作为结构存储,并打开打开");
|
||||
//}
|
||||
|
||||
//var x = Storage.ThumbnailImage.GetPreviewAsImage();
|
||||
//读取结构化存储文件
|
||||
var streams = Storage.GetStreams();
|
||||
foreach (var streamInfo in streams)
|
||||
{
|
||||
string unicodeData;
|
||||
using (var streamReader = streamInfo.GetStream(FileMode.Open, FileAccess.Read))
|
||||
{
|
||||
byte[] streamData = new byte[streamReader.Length];
|
||||
streamReader.Read(streamData, 0, streamData.Length);
|
||||
unicodeData = Encoding.Unicode.GetString(streamData);
|
||||
//unicodeData = Encoding.UTF8.GetString(streamData);
|
||||
}
|
||||
|
||||
if (streamInfo.Name.ToUpper().Equals("BASICFILEINFO"))
|
||||
{
|
||||
FileInfo = ParseFileInfo(unicodeData);
|
||||
}
|
||||
|
||||
if (streamInfo.Name.ToUpper().Equals("PARTATOM"))
|
||||
{
|
||||
//Console.WriteLine("部分原子:\r\n" + ParsePartAtom(unicodeData));
|
||||
if (filename.EndsWith(".rfa"))
|
||||
{
|
||||
SymbolTypes = ParseParameterDefinition(streamInfo);
|
||||
//Console.WriteLine("族参数:\r\n" + GetFamilyInfo(symbols));
|
||||
}
|
||||
}
|
||||
|
||||
if (streamInfo.Name.ToUpper().Equals("TRANSMISSIONDATA"))
|
||||
{
|
||||
TransMissionData = ParseTransMissionData(unicodeData);
|
||||
}
|
||||
|
||||
if (streamInfo.Name.ToUpper().Equals("REVITPREVIEW4.0"))
|
||||
{
|
||||
PreviewImage = ParsePreviewImage(streamInfo);
|
||||
}
|
||||
|
||||
if (streamInfo.Name.ToUpper().Equals("CONTENTS"))
|
||||
{
|
||||
Content = ParseContents(unicodeData);
|
||||
}
|
||||
}
|
||||
//if (Storage != null)
|
||||
//{
|
||||
// try
|
||||
// {
|
||||
// storageRootType.InvokeMember("CloseTrigger", bindingFlags, null, Storage, file);
|
||||
// }
|
||||
// catch (Exception ex)
|
||||
// {
|
||||
// MessageBox.ShowAhead(ex.ViewMessage);
|
||||
// }
|
||||
//}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 清理无效字符
|
||||
/// </summary>
|
||||
/// <param name="oldValue"></param>
|
||||
/// <returns></returns>
|
||||
public static string PurgeUnprintableCharacters(string oldValue)
|
||||
{
|
||||
var sb = new StringBuilder();
|
||||
var oldValueArray = oldValue.ToCharArray();
|
||||
foreach (var letter in oldValueArray)
|
||||
{
|
||||
int decimalValue = letter;
|
||||
if (decimalValue is >= 32 and <= 126)
|
||||
{
|
||||
sb.Append(letter);
|
||||
}
|
||||
}
|
||||
|
||||
oldValue = sb.ToString();
|
||||
sb.Length = 0;
|
||||
sb.Capacity = 0;
|
||||
sb = null;
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
public StringBuilder Content { get; private set; }
|
||||
|
||||
public StringBuilder FileInfo { get; private set; }
|
||||
public Image PreviewImage { get; private set; }
|
||||
public string Product { get; private set; }
|
||||
public string RevitVersion { get; private set; }
|
||||
public string SafeName { get; private set; }
|
||||
public List<FamilyTypeDefinition> SymbolTypes { get; private set; }
|
||||
public StringBuilder TransMissionData { get; private set; }
|
||||
public string UpdateTime { get; private set; }
|
||||
|
||||
public class FamilyTypeDefinition
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public List<ParameterDefinition> ParameterDefinitions { get; set; } = new();
|
||||
public string Value { get; set; }
|
||||
}
|
||||
|
||||
public class ParameterDefinition
|
||||
{
|
||||
public string Name { get; set; }
|
||||
public string TypeOfParameterDefinition { get; set; }
|
||||
public string Value { get; set; }
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,9 +1,5 @@
|
||||
using System.Windows;
|
||||
|
||||
using ShrlAlgoToolkit.Core.Assists;
|
||||
using ShrlAlgoToolkit;
|
||||
using ShrlAlgoToolkit.Core;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Assists;
|
||||
|
||||
public sealed record SingletonViewAssist<T>
|
||||
|
||||
@@ -1,339 +0,0 @@
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using ShrlAlgoToolkit.Core.Assists;
|
||||
using ShrlAlgoToolkit;
|
||||
using ShrlAlgoToolkit.Core;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Assists;
|
||||
|
||||
public class StringAssist
|
||||
{
|
||||
/// <summary>
|
||||
/// 获取大写字母列表
|
||||
/// </summary>
|
||||
/// <param name="n"></param>
|
||||
/// <returns></returns>
|
||||
public List<string> GetChar(int n)
|
||||
{
|
||||
var list = new List<string>();
|
||||
if (n > 26)
|
||||
{
|
||||
n = 26;
|
||||
}
|
||||
|
||||
for (var i = 0; i < n; i++)
|
||||
{
|
||||
var c = ((char)(i + 65)).ToString();
|
||||
list.Add(c);
|
||||
}
|
||||
|
||||
return list;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 取得中文字符
|
||||
/// </summary>
|
||||
/// <param name="oriText"></param>
|
||||
/// <returns></returns>
|
||||
public static string GetChineseWord(string oriText)
|
||||
{
|
||||
var x = @"[\u4E00-\u9FFF]+";
|
||||
var matches = Regex.Matches(oriText, x, RegexOptions.IgnoreCase);
|
||||
var sb = new StringBuilder();
|
||||
foreach (Match nextMatch in matches)
|
||||
{
|
||||
sb.Append(nextMatch.Value);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 固定间隔插入字符
|
||||
/// </summary>
|
||||
/// <param name="input">源字符串</param>
|
||||
/// <param name="interval">间隔</param>
|
||||
/// <param name="value">插入字符</param>
|
||||
/// <returns></returns>
|
||||
public static string InsertFormat(string input, int interval, string value)
|
||||
{
|
||||
for (var i = interval - 1; i < input.Length; i += interval + 1)
|
||||
{
|
||||
input = input.Insert(i, value);
|
||||
}
|
||||
|
||||
return input;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断更严谨,包含的有空串("")、空白符(空格""," ",制表符"\t",回车符"\r","\n"等)以及null值;
|
||||
/// </summary>
|
||||
/// <param name="str"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsBlank(string str)
|
||||
{
|
||||
int strLen;
|
||||
if (str == null || (strLen = str.Length) == 0)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (var i = 0; i < strLen; i++)
|
||||
{
|
||||
if (char.IsWhiteSpace(str.ElementAt(i)) == false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 是否为Double类型
|
||||
/// </summary>
|
||||
/// <param name="expression"></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsDouble(object expression)
|
||||
{
|
||||
return expression != null && Regex.IsMatch(expression.ToString(), @"^([0-9])[0-9]*(\.\w*)?$");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 判断对象是否为Int32类型的数字
|
||||
/// </summary>
|
||||
/// <param name="expression">The expression<see cref="string" /></param>
|
||||
/// <returns></returns>
|
||||
public static bool IsNumeric(string expression)
|
||||
{
|
||||
if (expression != null)
|
||||
{
|
||||
var str = expression;
|
||||
if (str.Length > 0 && str.Length <= 11 && Regex.IsMatch(str, @"^[-]?[0-9]*[.]?[0-9]*$"))
|
||||
{
|
||||
if (str.Length < 10 || (str.Length == 10 && str[0] == '1') || (str.Length == 11 && str[0] == '-' && str[1] == '1'))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 比较字符串相似度
|
||||
/// </summary>
|
||||
/// <param name="str1"></param>
|
||||
/// <param name="str2"></param>
|
||||
/// <returns></returns>
|
||||
public static float Levenshtein(string str1, string str2)
|
||||
{
|
||||
var len1 = str1.Length;
|
||||
var len2 = str2.Length;
|
||||
var dif = new int[len1 + 1, len2 + 1];
|
||||
for (var a = 0; a <= len1; a++)
|
||||
{
|
||||
dif[a, 0] = a;
|
||||
}
|
||||
|
||||
for (var a = 0; a <= len2; a++)
|
||||
{
|
||||
dif[0, a] = a;
|
||||
}
|
||||
|
||||
int temp;
|
||||
for (var i = 1; i <= len1; i++)
|
||||
{
|
||||
for (var j = 1; j <= len2; j++)
|
||||
{
|
||||
temp = str1.ElementAt(i - 1) == str2.ElementAt(j - 1) ? 0 : 1;
|
||||
|
||||
dif[i, j] = Min(dif[i - 1, j - 1] + temp, dif[i, j - 1] + 1, dif[i - 1, j] + 1);
|
||||
}
|
||||
}
|
||||
|
||||
var similarity = 1 - ((float)dif[len1, len2] / Math.Max(len1, len2));
|
||||
return similarity;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 获取最短长度
|
||||
/// </summary>
|
||||
/// <param name="arr"></param>
|
||||
/// <returns></returns>
|
||||
private static int Min(params int[] arr)
|
||||
{
|
||||
var min = int.MaxValue;
|
||||
foreach (var i in arr)
|
||||
{
|
||||
if (min > i)
|
||||
{
|
||||
min = i;
|
||||
}
|
||||
}
|
||||
|
||||
return min;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 数字转字母
|
||||
/// </summary>
|
||||
/// <param name="index"></param>
|
||||
/// <returns></returns>
|
||||
public static string NumberToLetter(int index)
|
||||
{
|
||||
var str = string.Empty;
|
||||
if (index >= "ABCDEFGHIJKLMNOPQRSTUVWXYZ".Length)
|
||||
{
|
||||
var num = index / "ABCDEFGHIJKLMNOPQRSTUVWXYZ".Length;
|
||||
index %= "ABCDEFGHIJKLMNOPQRSTUVWXYZ".Length;
|
||||
str += num.ToString();
|
||||
}
|
||||
|
||||
return str + "ABCDEFGHIJKLMNOPQRSTUVWXYZ"[index];
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 指定字符串的固定长度,如果字符串小于固定长度,
|
||||
/// 则在字符串的前面补足零,可设置的固定长度最大为9位
|
||||
/// </summary>
|
||||
/// <param name="text">原始字符串</param>
|
||||
/// <param name="limitedLength">字符串的固定长度</param>
|
||||
/// <returns>The <see cref="string" /></returns>
|
||||
public static string RepairZero(string text, int limitedLength)
|
||||
{
|
||||
//补足0的字符串
|
||||
var temp = string.Empty;
|
||||
|
||||
//补足0
|
||||
for (var i = 0; i < limitedLength - text.Length; i++)
|
||||
{
|
||||
temp += "0";
|
||||
}
|
||||
|
||||
//连接text
|
||||
temp += text;
|
||||
|
||||
//返回补足0的字符串
|
||||
return temp;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 使用指定字符集将string转换成byte[]
|
||||
/// </summary>
|
||||
/// <param name="text">要转换的字符串</param>
|
||||
/// <param name="encoding">字符编码</param>
|
||||
public static byte[] StringToBytes(string text, Encoding encoding)
|
||||
{
|
||||
return encoding.GetBytes(text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// string型转换为decimal型
|
||||
/// </summary>
|
||||
/// <param name="expression">The expression<see cref="string" /></param>
|
||||
/// <param name="defValue">缺省值</param>
|
||||
/// <returns>转换后的decimal类型结果</returns>
|
||||
public static decimal StrToDecimal(string expression, decimal defValue)
|
||||
{
|
||||
if (expression == null || expression.Length > 10)
|
||||
{
|
||||
return defValue;
|
||||
}
|
||||
|
||||
var intValue = defValue;
|
||||
{
|
||||
var isDecimal = Regex.IsMatch(expression, @"^([-]|[0-9])[0-9]*(\.\w*)?$");
|
||||
if (isDecimal)
|
||||
{
|
||||
decimal.TryParse(expression, out intValue);
|
||||
}
|
||||
}
|
||||
|
||||
return intValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// string型转换为float型
|
||||
/// </summary>
|
||||
/// <param name="expression">The expression<see cref="string" /></param>
|
||||
/// <param name="defValue">缺省值</param>
|
||||
/// <returns>转换后的int类型结果</returns>
|
||||
public static float StrToFloat(string expression, float defValue)
|
||||
{
|
||||
if (expression == null || expression.Length > 10)
|
||||
{
|
||||
return defValue;
|
||||
}
|
||||
|
||||
var intValue = defValue;
|
||||
{
|
||||
var isFloat = Regex.IsMatch(expression, @"^([-]|[0-9])[0-9]*(\.\w*)?$");
|
||||
if (isFloat)
|
||||
{
|
||||
float.TryParse(expression, out intValue);
|
||||
}
|
||||
}
|
||||
|
||||
return intValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 将字符串转换为Int32类型
|
||||
/// </summary>
|
||||
/// <param name="expression">要转换的字符串</param>
|
||||
/// <param name="defValue">缺省值</param>
|
||||
/// <returns>转换后的int类型结果</returns>
|
||||
public static int StrToInt(string expression, int defValue)
|
||||
{
|
||||
return string.IsNullOrEmpty(expression) || expression.Trim().Length >= 11 || !Regex.IsMatch(expression.Trim(), @"^([-]|[0-9])[0-9]*(\.\w*)?$")
|
||||
? defValue
|
||||
: int.TryParse(expression, out var rv)
|
||||
? rv
|
||||
: Convert.ToInt32(StrToFloat(expression, defValue));
|
||||
}
|
||||
#region 格式化
|
||||
|
||||
//StringFormat={}{0:C} $123.46
|
||||
//StringFormat={}{0:C1} $123.5
|
||||
//StringFormat=单价:{0:C} 单价:$123.46
|
||||
//StringFormat={}{0}元 123.45678元
|
||||
//StringFormat={}{0:D6} 086723
|
||||
//StringFormat={}{0:F4} 28768234.9329
|
||||
//StringFormat={}{0:N3} 28,768,234.933
|
||||
//StringFormat={}{0:P1} 78.9 %
|
||||
//StringFormat={}{0:0000.00} 0123.46
|
||||
//StringFormat={}{0:####.##} 123.46
|
||||
//StringFormat={}{0:d} 5/4/2015
|
||||
//StringFormat={}{0:D} Monday, May 04, 2015
|
||||
//StringFormat={}{0:f} Monday, May 04, 2015 5:46 PM
|
||||
//StringFormat={}{0:F} Monday, May 04, 2015 5:46:56 PM
|
||||
//StringFormat={}{0:g} 5/4/2015 5:46 PM
|
||||
//StringFormat={}{0:G} 5/4/2015 5:46:56 PM
|
||||
//StringFormat={}{0:m} May 04
|
||||
//StringFormat={}{0:Distinct} May 04
|
||||
//StringFormat={}{0:t} 5:46 PM
|
||||
//StringFormat={}{0:Command} 5:46:56 PM
|
||||
//StringFormat={}{0:yyyy年MM月dd日} 2015年05月04日
|
||||
//StringFormat={}{0:yyyy-MM-dd} 2015-05-04
|
||||
//StringFormat={}{0:yyyy-MM-dd HH:mm} 2015-05-04 17:46
|
||||
//StringFormat={}{0:yyyy-MM-dd HH:mm:ss},,ConverterCulture=zh-CN||StringFormat='yyyy:MM:dd HH:mm:ss',,ConverterCulture=zh-CN 2015-05-04 17:46:56
|
||||
//< TextBox.Text >
|
||||
// < MultiBinding StringFormat = "姓名:{0}	{1}" >
|
||||
// < Binding Path = "FristName" />
|
||||
// < Binding Path = "LastName" />
|
||||
// </ MultiBinding >
|
||||
//</ TextBox.Text >
|
||||
// < !--
|
||||
// \a  BEL
|
||||
// \b  BS - Backspace
|
||||
// \f  FF - Formfeed
|
||||
// \n 
 LF, NL - Linefeed, New Line
|
||||
// \r 
 CR - Carriage return
|
||||
// \t 	 HT - Tab, Horizontal Tabelator
|
||||
// \v  VT - Vertical Tabelator
|
||||
|
||||
#endregion
|
||||
}
|
||||
@@ -1,8 +1,4 @@
|
||||
using ShrlAlgoToolkit.Core.Assists;
|
||||
using ShrlAlgoToolkit;
|
||||
using ShrlAlgoToolkit.Core;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Assists;
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Assists;
|
||||
|
||||
public enum ThumbnailOptions
|
||||
{
|
||||
|
||||
@@ -2,10 +2,6 @@
|
||||
using System.Text;
|
||||
using System.Text.RegularExpressions;
|
||||
|
||||
using ShrlAlgoToolkit.Core.Assists;
|
||||
using ShrlAlgoToolkit;
|
||||
using ShrlAlgoToolkit.Core;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Assists;
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -11,8 +11,6 @@ using CommunityToolkit.Mvvm.ComponentModel;
|
||||
|
||||
using Microsoft.Win32;
|
||||
|
||||
using ShrlAlgoToolkit.Core.Assists;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Assists;
|
||||
|
||||
public static class WinDialogAssist
|
||||
|
||||
@@ -3,10 +3,6 @@ using System.Drawing.Imaging;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
|
||||
using ShrlAlgoToolkit.Core.Assists;
|
||||
using ShrlAlgoToolkit;
|
||||
using ShrlAlgoToolkit.Core;
|
||||
|
||||
namespace ShrlAlgoToolkit.RevitAddins.Assists;
|
||||
|
||||
/// <summary>
|
||||
|
||||
Reference in New Issue
Block a user