cad.net 外部参照功能和相对路径转换

外部参照功能: 

        [CommandMethod("Charu_Xref")]
        public void Charu()
        {
            Document doc = Acap.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            ed.WriteMessage("
附着参照到当前图纸");
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                string PathName = @"D:桌面1.饰施图3.平面图1.平面图.dwg"; //附着的路径
                var file = Path.GetFileNameWithoutExtension(PathName);
                ObjectId 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);
                    }
                }
                tr.Commit();
            }
        }

        [CommandMethod("Chaili_Xref")]
        public void Chaili()
        {
            Document doc = Acap.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            Database db = doc.Database;
            ed.WriteMessage("
卸载/重载/拆离/绑定");
            db.SetXref(XrefEnum.UnloadXrefs);
            db.SetXref(XrefEnum.ReloadXrefs);
            db.SetXref(XrefEnum.DetachXref);
            db.SetXref(XrefEnum.BindXrefs);
        } 
View Code
namespace JoinBox
{
    public enum XrefEnum
    {
        /// <summary>
        /// 卸载
        /// </summary>
        UnloadXrefs,
        /// <summary>
        /// 重载
        /// </summary>
        ReloadXrefs, 
        /// <summary>
        /// 拆离
        /// </summary>
        DetachXref,
        /// <summary>
        /// 绑定
        /// </summary>
        BindXrefs, 
    }

    public static class XrefTool
    {
        /// <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)
        {
            db.ResolveXrefs(false, true);//解析外部参照(使用线性引擎,只做新的) 
            var ids = new ObjectIdCollection();
            var xg = db.GetHostDwgXrefGraph(true);//神马是僵尸参照
            for (int i = 0; i < xg.NumNodes; i++)
            {
                var xNode = xg.GetXrefNode(i) as XrefGraphNode;
                // if (xNode.XrefStatus != XrefStatus.Resolved) //状态判断
                if (xNode.BlockTableRecordId.IsOk())
                {
                    if (names != null)
                    {
                        foreach (var item in names)
                        {
                            //只加入名称相同的
                            if (item.ToUpper() == xNode.Name.ToUpper())
                            {
                                ids.Add(xNode.BlockTableRecordId);
                            }
                        }
                    }
                    else
                    {
                        //每个都加入
                        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;
            }
        }
    }
}

        /// <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;
        }
View Code

相对路径转换:

using System;
using System.IO;
using System.Linq;
using System.Text;

namespace JoinBoxCurrency
{
    public static partial class StringTool
    {
        // 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
        // StringTool.GetRelativePath(@"D:MyProjRelease", @"D:MyProjLogMyFile.txt");
        // StringTool.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 relativePath = new StringBuilder();
            for (index = lastCommonRoot + 1; index < strDbPaths.Length; index++)
            {
                if (strDbPaths[index].Length > 0)
                {
                    relativePath.Append("..\");//上级目录加入
                }
            }
            //添加文件夹
            for (index = lastCommonRoot + 1; index < strXrefPaths.Length - 1; index++)
            {
                relativePath.Append(strXrefPaths[index] + "\");
            }
            //本级目录
            if (relativePath.Length == 0)
            {
                relativePath.Append(".\");
            }
            relativePath.Append(strXrefPaths[strXrefPaths.Length - 1]);//下级目录加入
            return relativePath.ToString();
        }
#else
        /// <summary>
        /// 绝对路径->相对路径
        /// StringTool.GetRelativePath(@"D:MyProjRelease", @"D:MyProjLogMyFile.txt");
        /// StringTool.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;
        }
    }
}
View Code

(完)

原文地址:https://www.cnblogs.com/JJBox/p/12407217.html