小狼 发表于 2009-9-27 12:40:00

[原创]小狼专集——使用"Overrule“实现Cass电力线

本帖最后由 作者 于 2009-9-28 16:05:39 编辑

被飞狐批评了,改了重发一个

namespace WolfDrawOverrule
{
    class WolfPoleOverrule : IExtensionApplication
    {
      #region IExtensionApplication Members

      //初始化例程,重定义生效
      void IExtensionApplication.Initialize()
      {
            WolfHelper.OverruleStart();
            Overrule.Overruling = true;
      }
      //
      void IExtensionApplication.Terminate()
      {
            WolfHelper.OverruleEnd();
            Overrule.Overruling = false;
      }
      #endregion
    }
    static class WolfHelper
    {
      //Xdata应用程序名称
      public readonly static string PoleRegAppName = "Wolf.Pole";
      //是否显示基线
      public static bool DrawPoleBaseLine = false;
      public static void OverruleStart()
      {
            Overrule.AddOverrule(RXObject.GetClass(typeof(Autodesk.AutoCAD.DatabaseServices.Polyline)), TelegraphPoleOverrule.TheOverrule, false);
            Overrule.AddOverrule(RXObject.GetClass(typeof(Autodesk.AutoCAD.DatabaseServices.Polyline)), TelegraphPoleTransformOverrule.TheOverrule, false);
      }
      public static void OverruleEnd()
      {
            Overrule.RemoveOverrule(RXObject.GetClass(typeof(Autodesk.AutoCAD.DatabaseServices.Polyline)), TelegraphPoleOverrule.TheOverrule);
            Overrule.RemoveOverrule(RXObject.GetClass(typeof(Autodesk.AutoCAD.DatabaseServices.Polyline)), TelegraphPoleTransformOverrule.TheOverrule);
      }
      //测试代码,使用不方便,可以自行替换。Esc生成对象
      
      public static void AddPole()
      {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;
            PromptPointResult res = ed.GetPoint("\n请输入起点:");
            Point3dCollection point3dColl = new Point3dCollection();
            while (res.Status == PromptStatus.OK)
            {
                point3dColl.Add(res.Value);
                PromptPointOptions opts = new PromptPointOptions("\n请输入下一点:");
                opts.BasePoint = res.Value;
                opts.UseBasePoint = true;
                res = ed.GetPoint(opts);
            }
            if (point3dColl.Count < 2)
            {
                ed.WriteMessage("\n错误线段点位小于2个,不能画线.");
                return;
            }
            Database db = doc.Database;
            using (Transaction trans = AcadPropers.Tm.StartTransaction())
            {
                RegAppTable rat = (RegAppTable)trans.GetObject(AcadPropers.Database.RegAppTableId, OpenMode.ForRead, false);
                if (!rat.Has(PoleRegAppName))
                {
                  rat.UpgradeOpen();
                  RegAppTableRecord regapp = new RegAppTableRecord();
                  regapp.Name = PoleRegAppName;
                  rat.Add(regapp);
                  trans.AddNewlyCreatedDBObject(regapp, true);
                }
                Autodesk.AutoCAD.DatabaseServices.Polyline polyline = new Autodesk.AutoCAD.DatabaseServices.Polyline();
                for (int i = 0; i < point3dColl.Count - 1; i++)
                {
                  Point2d point2d = new Point2d(point3dColl.X, point3dColl.Y);
                  polyline.AddVertexAt(i, point2d, 0, 0, 0);
                }
                //设置代码及图块名称
                SetTo(polyline, WolfHelper.PoleRegAppName, "171101", "gc013a");
                BlockTableRecord btr =
                            (BlockTableRecord)trans.GetObject(
                              db.CurrentSpaceId,
                              OpenMode.ForWrite,
                              false);
                btr.AppendEntity(polyline);
                trans.AddNewlyCreatedDBObject(polyline, true);
                trans.Commit();
            }
      }
      //设置对象XData属性
      public static void SetTo(Entity entity, string RegAppName, string code, string blockName)
      {
            ResultBuffer rb = new ResultBuffer();
            rb.Add(new TypedValue((int)DxfCode.ExtendedDataRegAppName, RegAppName));
            if (code != "" || blockName != "")
            {
                rb.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, code));
                rb.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, blockName));
            }
            entity.XData = rb;
      }
    }
    static class PoleGeometryHelper
    {
      //获取重定义规则对象
      public static DBObjectCollection GetPoleGeometrys(Autodesk.AutoCAD.DatabaseServices.Polyline polyline)
      {
            DBObjectCollection dbObjColl = new DBObjectCollection();
            try
            {
                string layer = polyline.Layer;
                Point3dCollection point3dColl = polyline.GetPolylinePoint3ds();
                ResultBuffer rb = polyline.XData;
                //获取电力线方向箭头块
                string blockName = rb.AsArray().Value as string;
                for (int i = 0; i < point3dColl.Count; i++)
                {
                  Point3d startPoint3d = point3dColl;
                  BlockReference block = GetBlock("gc170", startPoint3d, layer, 0, new Scale3d(1, 1, 1));
                  dbObjColl.Add(block);
                  if (i + 1 < point3dColl.Count)
                  {
                        Point3d endPoint3d = point3dColl;
                        Vector3d vector = (startPoint3d - endPoint3d).GetNormal();
                        double douAngle = vector.AngleOnPlane(polyline.GetPlane());
                        block = GetBlock(blockName, startPoint3d, layer, (douAngle - Math.PI), new Scale3d(1, 1, 1));
                        dbObjColl.Add(block);
                        block = GetBlock(blockName, endPoint3d, layer, douAngle, new Scale3d(1, 1, 1));
                        dbObjColl.Add(block);
                  }
                }
                return dbObjColl;
            }
            catch
            {
                return dbObjColl;
            }
      }
      //获取图块
       private static BlockReference GetBlock(string blcokName, Point3d insertPt, string layer, double angle, Scale3d scale3d)
      {
            Database db = AcadPropers.Database;
            BlockReference blockRef = null;
            using (Transaction trans = AcadPropers.Tm.StartTransaction())
            {
                BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
                if (bt.Has(blcokName))
                {
                  ObjectId blkId = bt;
                  blockRef = new BlockReference(insertPt, blkId);
                  blockRef.ScaleFactors = new Scale3d(1, 1, 1);
                  blockRef.Rotation = angle;
                  blockRef.ScaleFactors = scale3d;
                  blockRef.Layer = layer;
                }
                trans.Commit();
            }
            return blockRef;
      }
    }
    //显示重定义
    class TelegraphPoleOverrule : DrawableOverrule
    {
      public static TelegraphPoleOverrule TheOverrule = new TelegraphPoleOverrule();
      //设置重定义的过滤条件
      public TelegraphPoleOverrule()
      {
            SetXDataFilter(WolfHelper.PoleRegAppName);
      }
      //显示重载
      public override bool WorldDraw(Drawable drawable, WorldDraw wd)
      {
            Autodesk.AutoCAD.DatabaseServices.Polyline polyline = (Autodesk.AutoCAD.DatabaseServices.Polyline)drawable;
            DBObjectCollection dbObjColl = PoleGeometryHelper.GetPoleGeometrys(polyline);
            foreach (DBObject dbObject in dbObjColl)
            {
                wd.Geometry.Draw(dbObject);
            }
            //是否显示基线
            if (WolfHelper.DrawPoleBaseLine)
                base.WorldDraw(drawable, wd);
            return true;
      }
    }
    class TelegraphPoleTransformOverrule : TransformOverrule
    {
      public static TelegraphPoleTransformOverrule TheOverrule = new TelegraphPoleTransformOverrule();
      public TelegraphPoleTransformOverrule()
      {
            SetXDataFilter(WolfHelper.PoleRegAppName);
      }
      //重载Explode方法
      public override void Explode(Entity entity, DBObjectCollection entitySet)
      {
            Autodesk.AutoCAD.DatabaseServices.Polyline polyline = (Autodesk.AutoCAD.DatabaseServices.Polyline)entity;
            DBObjectCollection dbObjColl = PoleGeometryHelper.GetPoleGeometrys(polyline);
            foreach (DBObject dbObj in dbObjColl)
            {
                //此处必须使用add方法
                //entitySet = dbObjColl;无法生存对象
                entitySet.Add(dbObj);
            }
      }
    }
}

lzx838 发表于 2009-9-27 13:17:00

<p>小狼的专集终于开张啦,恭喜恭喜!!!</p><p>不过要是能加点说明或GIF图就更好.</p><p>小狼加油...</p>

nonsmall 发表于 2009-9-27 14:23:00

很帅 是诱惑我学习的动力!

小狼 发表于 2009-9-27 15:00:00

<p>总于有个加精的帖子了</p><p>好激动啊</p>

asdfxx 发表于 2009-9-27 17:25:00

serious support<p></p>

gyl 发表于 2009-9-28 23:57:00

这个比较有意思,好好学习一下。

gyl 发表于 2009-9-28 23:59:00

<p>能否在端点外也画个箭头啊?</p><p>如果一个电杆上有两条以上电线怎么办啊?</p>

小狼 发表于 2009-9-29 08:56:00

<p>没有做完善的</p><p>暂时没有时间弄了</p><p>可以做两个属性</p><p>表示起点和终点是否电杆和电力线方向符号</p>

yswoyh 发表于 2009-9-29 16:35:00

<p>有点意思</p>

xiaook 发表于 2009-10-18 10:58:00

CASS里面是用骨架线实现的,我觉得还算方便,修改骨架线后,使用里面的"重新生成功能",像围墙,活树篱笆之类的还是比较方便的.
页: [1] 2
查看完整版本: [原创]小狼专集——使用"Overrule“实现Cass电力线