外部參照功能:
#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;
}
}
}
(完)
