cad.net 外部参照功能和相对路径转换
外部参照功能:
#if !HC2020
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.Runtime;
using Acap = Autodesk.AutoCAD.ApplicationServices.Application;
#else
using GrxCAD.DatabaseServices;
using GrxCAD.Geometry;
using GrxCAD.Runtime;
using Acap = GrxCAD.ApplicationServices.Application;
#endif
namespace JoinBox
{
public class Xref
{
[CommandMethod("CmdText_InsertXref")]
public void CmdText_InsertXref()
{
var dm = Acap.DocumentManager;
var doc = dm.MdiActiveDocument;
var ed = doc.Editor;
var db = doc.Database;
ed.WriteMessage("\n插入附着参照到当前图纸");
db.Action(tr => {
string PathName = @"D:\桌面\01.饰施图\03.平面图\01.平面图.dwg";
var file = System.IO.Path.GetFileNameWithoutExtension(PathName);
var acXrefId = db.AttachXref(PathName, file);//附着外部参照 具体处理要防止参照名称已存在
// 如果创建了有效引用,则继续
if (!acXrefId.IsNull)//不可以换成ok
{
//插入的基点
var insPt = new Point3d(0, 0, 0);
using (var acBlkRef = new BlockReference(insPt, acXrefId))
{
var acBlkTblRec = tr.GetObject(db.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord;
acBlkTblRec.AppendEntity(acBlkRef);
tr.AddNewlyCreatedDBObject(acBlkRef, true);
}
}
});
}
[CommandMethod("CmdText_BreakXref")]
public void CmdText_BreakXref()
{
var dm = Acap.DocumentManager;
var doc = dm.MdiActiveDocument;
var ed = doc.Editor;
var db = doc.Database;
ed.WriteMessage("\n卸载/重载/拆离/绑定");
db.SetXref(XrefEnum.UnloadXrefs);
db.SetXref(XrefEnum.ReloadXrefs);
db.SetXref(XrefEnum.DetachXref);
db.SetXref(XrefEnum.BindXrefs);
}
}
}
静态方法
public enum XrefEnum
{
/// <summary>
/// 卸载
/// </summary>
UnloadXrefs,
/// <summary>
/// 重载
/// </summary>
ReloadXrefs,
/// <summary>
/// 拆离
/// </summary>
DetachXref,
/// <summary>
/// 绑定
/// </summary>
BindXrefs,
}
public static class XrefHelper
{
/// <summary>
/// 修改外部参照
/// </summary>
/// <param name="db">数据库</param>
/// <param name="xe">设置的枚举状态</param>
/// <param name="names">要处理的参照名称,null就处理所有的参照</param>
public static void SetXref(this Database db, XrefEnum xe, IEnumerable<string> names = null)
{
List<string> namesUp = null;
if (names != null)
{
namesUp = names.ToList();
namesUp.ForEach(item => item = item.ToUpper());
}
var ids = new ObjectIdCollection();
db.ResolveXrefs(false, true); //解析外部参照(线性引擎,只做新的)
var xg = db.GetHostDwgXrefGraph(true);//参数:包含僵尸参照
for (int i = 0; i < xg.NumNodes; i++)
{
var xNode = xg.GetXrefNode(i);
if (!xNode.BlockTableRecordId.IsOk())
continue;
// if (xNode.XrefStatus != XrefStatus.Resolved) //状态判断
if (namesUp == null)
{
ids.Add(xNode.BlockTableRecordId); //每个都加入
continue;
}
foreach (var item in namesUp)
{
if (item == xNode.Name.ToUpper()) //只加入名称相同的
ids.Add(xNode.BlockTableRecordId);
}
}
// btRec.IsFromOverlayReference 是覆盖?
// XrefStatus 外部参照状态
// GetXrefDatabase 外部参照数据库
if (ids.Count == 0)
return;
switch (xe)
{
case XrefEnum.BindXrefs://绑定后会自动拆离
db.BindXrefs(ids, true);
break;
case XrefEnum.DetachXref: //拆离
foreach (ObjectId item in ids)
db.DetachXref(item);
break;
case XrefEnum.UnloadXrefs://卸载
db.UnloadXrefs(ids);
break;
case XrefEnum.ReloadXrefs://重载
db.ReloadXrefs(ids);
break;
}
}
}
public static partial class EntityEdit
{
/// <summary>
/// id有效,未被删除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public static bool IsOk(this ObjectId id)
{
return !id.IsNull && id.IsValid && !id.IsErased && !id.IsEffectivelyErased && id.IsResident;
}
}
相对路径转换:
using System;
using System.IO;
using System.Linq;
using System.Text;
namespace JoinBox.BasalCurrency
{
public static partial class StringHelper
{
// https://blog.csdn.net/my98800/article/details/51450696
// https://blog.csdn.net/lishuangquan1987/article/details/53678215
// https://www.cnblogs.com/hont/p/5412340.html
#if true
// StringHelper.GetRelativePath(@"D:\MyProj\Release", @"D:\MyProj\Log\MyFile.txt");
// StringHelper.GetRelativePath("G:\\A1.项目\\20190920金山谷黄宅\\01.饰施图\\03.平面图", "G:\\A1.项目\\20190920金山谷黄宅\\01.饰施图\\01.辅助文件\\图框\\A3图框.dwg");
/// <summary>
/// 绝对路径->相对路径
/// </summary>
/// <param name="strDbPath">绝对路径</param>
/// <param name="strXrefPath">相对关系</param>
/// <returns></returns>
public static string GetRelativePath(string strDbPath, string strXrefPath)
{
string[] strDbPaths = strDbPath.Split('\\');
string[] strXrefPaths = strXrefPath.Split('\\');
//获取两条路径中的最短路径
int length = strDbPaths.Length < strXrefPaths.Length ?
strDbPaths.Length : strXrefPaths.Length;
//用于确定我们退出的循环中的位置。
int lastCommonRoot = -1;
int index;
//找到共根
for (index = 0; index < length; index++)
{
if (strDbPaths[index] == strXrefPaths[index])
lastCommonRoot = index;
else
break;
}
//如果我们没有找到一个共同的前缀,那么抛出
if (lastCommonRoot == -1)
throw new ArgumentException("路径没有公共相同路径部分");
//建立相对路径
var sb = new StringBuilder();
for (index = lastCommonRoot + 1; index < strDbPaths.Length; index++)
{
if (strDbPaths[index].Length > 0)
sb.Append("..\\");//上级目录加入
}
//添加文件夹
for (index = lastCommonRoot + 1; index < strXrefPaths.Length - 1; index++)
sb.Append(strXrefPaths[index] + "\\");
//本级目录
if (sb.Length == 0)
sb.Append(".\\");
sb.Append(strXrefPaths[strXrefPaths.Length - 1]);//下级目录加入
return sb.ToString();
}
#else
/// <summary>
/// 绝对路径->相对路径
/// StringHelper.GetRelativePath(@"D:\MyProj\Release", @"D:\MyProj\Log\MyFile.txt");
/// StringHelper.GetRelativePath("G:\\A1.项目\\20190920金山谷黄宅\\01.饰施图\\03.平面图", "G:\\A1.项目\\20190920金山谷黄宅\\01.饰施图\\01.辅助文件\\图框\\A3图框.dwg");
/// </summary>
/// <param name="strDbPath">绝对路径</param>
/// <param name="strXrefPath">相对关系</param>
/// <returns></returns>
public static string GetRelativePath(string strDbPath, string strXrefPath)
{
Uri uri1 = new Uri(strXrefPath);
Uri uri2 = new Uri(strDbPath);
Uri relativeUri = uri2.MakeRelativeUri(uri1);//测试例子变成 01.%E8%BE%85%E5%8A%A9%E6%96%87%E4%BB%B6/%E5%9B%BE%E6%A1%86/A3%E5%9B%BE%E6%A1%86.dwg
string str = relativeUri.ToString();
//因为这里不会实现".\A.dwg"而是"A.dwg",所以加入这个操作,满足同目录文件
var strs = str.Split('\\');
if (strs.Length == 1)
str = ".\\" + str;
return str;
}
#endif
/// <summary>
/// 相对路径->绝对路径
/// </summary>
/// <param name="path_dwg">dwg基础路径</param>
/// <param name="xiangdui">相对路径</param>
/// <returns>完整路径</returns>
public static string GetCompletePath(string path_dwg, string xiangdui)
{
string re_path_opend;
var path_dwgs = path_dwg.Split('\\');
path_dwgs = path_dwgs.Where(s => !string.IsNullOrEmpty(s)).ToArray();//清理空数组
var path_xiangduis = Path.GetDirectoryName(xiangdui).Split('\\');
//判断向上删除几个
int inx = 0;
foreach (var item in path_xiangduis)
{
if (item == "..")
inx++;
else
break;
}
//前段
var pathA = new StringBuilder();
for (int i = 0; i < path_dwgs.Length - inx; i++)
pathA.Append(path_dwgs[i] + "\\");
//后段
var pathB = new StringBuilder();
foreach (var item in path_xiangduis)
{
if (item != "." && item != "..")
pathB.Append(item + "\\");
}
if (!string.IsNullOrEmpty(xiangdui) && xiangdui[0] == '.')
re_path_opend = pathA.ToString() + pathB.ToString() + Path.GetFileName(xiangdui);
else
re_path_opend = xiangdui;
return re_path_opend;
}
}
}
(完)