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;
        }
    }
}

(完)

posted @ 2020-03-04 06:42  惊惊  阅读(2255)  评论(0编辑  收藏  举报