雪山飞狐_lzh 发表于 2009-5-13 21:30:00

NetArx2010新特性-规则重定义

本帖最后由 作者 于 2009-5-14 14:46:31 编辑

.NetArx终于在AutoCad2010版实现了自定义实体的子集--规则重定义,算是个好消息,
虽然很晚,而且功能没有ObjectArx的自定义实体强,但好歹没有强:)
下面的例子利用多行文字重定义为序号球,
更多的相关例子请看这里
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;
using Autodesk.AutoCAD.ApplicationServices;


namespace TlsCad
{
    class TlsApplication : IExtensionApplication
    {
      void IExtensionApplication.Initialize()
      {
            XhqHelper.OverruleStart();
            Overrule.Overruling = true;
      }
      void IExtensionApplication.Terminate()
      {
            XhqHelper.OverruleEnd();
            Overrule.Overruling = false;
      }
    }
    #region Helper
    static class XhqHelper
    {
      public readonly static string RegAppName = "TlsCad.Xhq";
      public readonly static double Radius = 8;
      public readonly static double TextHeight = 8;
      //获取起点
      public static Point3d GetPoint(MText mtxt)
      {
            ResultBuffer rb = mtxt.GetXDataForApplication(RegAppName);
            return (Point3d)rb.AsArray().Value;
      }
      //设置起点,注意这里使用1011组码保存点,支持Copy、Move、Mirror等命令时实时更新XData
      public static void SetPoint(MText mtxt, Point3d point)
      {
            ResultBuffer rb = new ResultBuffer(new TypedValue[] { new TypedValue(1001, RegAppName), new TypedValue(1011, point) });
            mtxt.XData = rb;
      }
      
      public static void XHQ()
      {
            PromptIntegerResult res1 = CadHelper.Editor.GetInteger(new PromptIntegerOptions("\n请输入序号:"));
            PromptPointResult res2 = CadHelper.Editor.GetPoint(new PromptPointOptions("\n请输入起点:"));
            XhqJig jig = new XhqJig(res2.Value, res1.Value.ToString());
            PromptResult res = CadHelper.Editor.Drag(jig);

            if (res.Status == PromptStatus.OK)
            {
                Database db = Application.DocumentManager.MdiActiveDocument.Database;
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                  BlockTableRecord btr =
                        (BlockTableRecord)tr.GetObject(
                            db.CurrentSpaceId,
                            OpenMode.ForWrite,
                            false);
                  MText mtxt = jig.GetEntity();
                  btr.AppendEntity(mtxt);
                  tr.AddNewlyCreatedDBObject(mtxt, true);
                  RegAppTable rat =
                        (RegAppTable)tr.GetObject(
                            db.RegAppTableId,
                            OpenMode.ForRead,
                            false);
                  if (!rat.Has(RegAppName))
                  {
                        rat.UpgradeOpen();
                        RegAppTableRecord regapp = new RegAppTableRecord();
                        regapp.Name = RegAppName;
                        rat.Add(regapp);
                        tr.AddNewlyCreatedDBObject(regapp, true);
                  }
                  SetPoint(mtxt, res2.Value);
                  tr.Commit();
                }
            }
      }

      public static void OverruleStart()
      {
            Overrule.AddOverrule(RXObject.GetClass(typeof(MText)), XhqDrawOverrule.TheOverrule, false);
            Overrule.AddOverrule(RXObject.GetClass(typeof(MText)), XhqGripOverrule.TheOverrule, false);
            Overrule.AddOverrule(RXObject.GetClass(typeof(MText)), XhqOsnapOverrule.TheOverrule, false);
            Overrule.AddOverrule(RXObject.GetClass(typeof(MText)), XhqTransformOverrule.TheOverrule, false);
      }
      public static void OverruleEnd()
      {
            Overrule.RemoveOverrule(RXObject.GetClass(typeof(MText)), XhqDrawOverrule.TheOverrule);
            Overrule.RemoveOverrule(RXObject.GetClass(typeof(MText)), XhqGripOverrule.TheOverrule);
            Overrule.RemoveOverrule(RXObject.GetClass(typeof(MText)), XhqOsnapOverrule.TheOverrule);
            Overrule.RemoveOverrule(RXObject.GetClass(typeof(MText)), XhqTransformOverrule.TheOverrule);
      }
    }
    #endregion
    #region Jig
    //序号球拖动类
    class XhqJig : DrawJig
    {
      Point3d m_Location;
      Line m_Line;
      MText m_MText;
      Circle m_Circle;
      public XhqJig(Point3d FirstPoint, string No)
      {
            m_MText = new MText();
            m_MText.Attachment = AttachmentPoint.MiddleCenter;
            m_MText.Location = FirstPoint;
            m_MText.TextHeight = XhqHelper.TextHeight;
            m_MText.Contents = No;
            m_Line = new Line(FirstPoint, FirstPoint);
            m_Circle = new Circle();
            m_Circle.Center = FirstPoint;
            m_Circle.Radius = XhqHelper.Radius;
      }
      protected override SamplerStatus Sampler(JigPrompts prompts)
      {
            JigPromptPointOptions jigOpts = new JigPromptPointOptions();
            jigOpts.UserInputControls =
                UserInputControls.Accept3dCoordinates |
                UserInputControls.NoZeroResponseAccepted |
                UserInputControls.NoNegativeResponseAccepted;
            jigOpts.Message = "\n请输入终点:";
            PromptPointResult res = prompts.AcquirePoint(jigOpts);
            Point3d positionTemp = res.Value;
            if (positionTemp != m_Location)
            {
                m_Location = positionTemp;
            }
            else
                return SamplerStatus.NoChange;
            if (res.Status == PromptStatus.Cancel)
                return SamplerStatus.Cancel;
            else
                return SamplerStatus.OK;
      }

      protected override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.WorldDraw draw)
      {
            try
            {
                Update();
                draw.Geometry.Draw(m_Circle);
                draw.Geometry.Draw(m_Line);
                draw.Geometry.Draw(m_MText);
            }
            catch (System.Exception)
            {
                return false;
            }
            return true;
      }
      private void Update()
      {
            m_Circle.Center = m_Location;
            Vector3d vec = m_Location - m_Line.StartPoint;
            if (vec.Length <= m_Circle.Radius)
            {
                m_Line.EndPoint = m_Line.StartPoint;
            }
            else
            {
                vec = vec / vec.Length * m_Circle.Radius;
                m_Line.EndPoint = m_Location - vec;
            }
            m_MText.Location = m_Location;
      }
      public MText GetEntity()
      {
            Update();
            return m_MText;
      }
    }
    #endregion
    #region Overrule
    //夹点重定义
    public class XhqGripOverrule : GripOverrule
    {
      public static XhqGripOverrule TheOverrule = new XhqGripOverrule();
      public XhqGripOverrule()
      {
            SetXDataFilter(XhqHelper.RegAppName);
      }
      public override void GetGripPoints(Entity entity, Point3dCollection gripPoints, IntegerCollection snapModes, IntegerCollection geometryIds)
      {
            MText mtxt = (MText)entity;
            Point3d pt = mtxt.Location;
            gripPoints.Add(pt + new Vector3d(0, XhqHelper.Radius, 0));
            gripPoints.Add(pt + new Vector3d(XhqHelper.Radius, 0, 0));
            gripPoints.Add(pt - new Vector3d(0, XhqHelper.Radius, 0));
            gripPoints.Add(pt - new Vector3d(XhqHelper.Radius, 0, 0));
            gripPoints.Add(XhqHelper.GetPoint(mtxt));
      }
      public override void MoveGripPointsAt(Entity entity, IntegerCollection indices, Vector3d offset)
      {
            MText mtxt = (MText)entity;
            foreach (int index in indices)
            {
                switch (index)
                {
                  case 0:
                  case 1:
                  case 2:
                  case 3:
                        mtxt.Location += offset;
                        break;
                  case 4:
                        XhqHelper.SetPoint(mtxt, XhqHelper.GetPoint(mtxt) + offset);
                        break;
                }
            }
      }
    }
    //捕捉重定义
    public class XhqOsnapOverrule : OsnapOverrule
    {
      public static XhqOsnapOverrule TheOverrule = new XhqOsnapOverrule();
      public XhqOsnapOverrule()
      {
            SetXDataFilter(XhqHelper.RegAppName);
      }
      public override void GetObjectSnapPoints(Entity entity, ObjectSnapModes snapMode, System.IntPtr gsSelectionMark, Point3d pickPoint, Point3d lastPoint, Matrix3d viewTransform, Point3dCollection snapPoints, IntegerCollection geometryIds, Matrix3d insertionMat)
      {
            MText mtxt = (MText)entity;
            switch (snapMode)
            {
                case ObjectSnapModes.ModeEnd:
                  snapPoints.Add(XhqHelper.GetPoint(mtxt));
                  break;
                case ObjectSnapModes.ModeQuad:
                  Point3d pt = mtxt.Location;
                  snapPoints.Add(pt + new Vector3d(0, XhqHelper.Radius, 0));
                  snapPoints.Add(pt + new Vector3d(XhqHelper.Radius, 0, 0));
                  snapPoints.Add(pt + new Vector3d(0, -XhqHelper.Radius, 0));
                  snapPoints.Add(pt + new Vector3d(-XhqHelper.Radius, 0, 0));
                  break;
            }
      }
    }
    //
    public class XhqTransformOverrule : TransformOverrule
    {
      public static XhqTransformOverrule TheOverrule = new XhqTransformOverrule();
      public XhqTransformOverrule()
      {
            SetXDataFilter(XhqHelper.RegAppName);
      }
      public override void Explode(Entity entity, DBObjectCollection entitySet)
      {
            base.Explode(entity, entitySet);
            MText mtxt = (MText)entity;
            entitySet.Add(new Circle(mtxt.Location, mtxt.Normal, XhqHelper.Radius));
            Point3d pt1 = XhqHelper.GetPoint(mtxt);
            Vector3d vec = mtxt.Location - pt1;
            if (vec.Length > XhqHelper.Radius)
            {
                vec = vec / vec.Length * XhqHelper.Radius;
                entitySet.Add(new Line(pt1, mtxt.Location - vec));
            }
      }
    }
    //MText->序号球
    public class XhqDrawOverrule : DrawableOverrule
    {
      public static XhqDrawOverrule TheOverrule = new XhqDrawOverrule();
      public XhqDrawOverrule()
      {
            SetXDataFilter(XhqHelper.RegAppName);
      }
      public override bool WorldDraw(Drawable drawable, WorldDraw wd)
      {
            MText mtxt = (MText)drawable;
            wd.Geometry.Circle(mtxt.Location, XhqHelper.Radius, new Vector3d(0, 0, 1));
            Point3d pt1 = XhqHelper.GetPoint(mtxt);
            Vector3d vec = mtxt.Location - pt1;
            if (vec.Length > XhqHelper.Radius)
            {
                vec = vec / vec.Length * XhqHelper.Radius;
                wd.Geometry.WorldLine(pt1, mtxt.Location - vec);
            }
            return base.WorldDraw(drawable, wd);
      }
    }
    #endregion
}


zyz398298804 发表于 2022-7-14 17:18:45

雪山飞狐_lzh 发表于 2009-5-14 23:31
来自于Autodesk开发者网络课程上的例子,会变色的温度计
当你移动当中三个空心的圆圈时,对应的温度数值会 ...

这个例子 现在加载好像没有反应

evergreenxq 发表于 2018-9-28 15:45:09

终于找到,我想要的东西了感谢感谢

yunzhong80 发表于 2009-5-14 11:26:00

我正在弄标号,可惜我弄得的CAD2008

雪山飞狐_lzh 发表于 2009-5-14 23:31:00

本帖最后由 作者 于 2009-5-15 7:49:14 编辑

来自于Autodesk开发者网络课程上的例子,会变色的温度计
当你移动当中三个空心的圆圈时,对应的温度数值会自动变化。

用netload命令加载下面的文件体验一下
命令TestOn,然后选择直线


using System;
using Autodesk.AutoCAD.ApplicationServices;
using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.EditorInput;
using Autodesk.AutoCAD.Geometry;
using Autodesk.AutoCAD.GraphicsInterface;
using Autodesk.AutoCAD.Runtime;


namespace abc
{
    #region "HelperClass"
    // Global helper class (singleton). Contains central definitions of some global constants,
    // and a few helper functions
    public class HelperClass
    {
      const String mExtDictName = "SGP_MyDict";
      // Defines Dictionary name for the Extension Dictionary demo
      const String mXRecName = "SGP_MyDATA";
      // Defines Dictionary name for the Extension Dictionary demo
      private static HelperClass mMe;
      // Name of our dictionary in extension dictionary
      public String DictionaryName
      {
            get
            {
                return mExtDictName;
            }
      }
      // Name of our XRecord
      public String XRecordName
      {
            get
            {
                return mXRecName;
            }
      }
      // Protected constructor - to enforce singleton behavior
      protected HelperClass()
      {
      }
      // static function to retrieve one and only instance of singleton
      public static HelperClass GetSingleton
      {
            get
            {
                if (mMe == null)
                {
                  mMe = new HelperClass();
                }
                return mMe;
            }
      }
      // Retrieve data (as resbuf) from or Xrecord.
      // Returns null object if there's a problem
      public ResultBuffer GetXRecordData(DBObject obj)
      {
            Xrecord xRec = null;
            ObjectId id = obj.ExtensionDictionary;
            // Make sure we have an ext dict befoore proceeding
            if (id.IsValid)
            {
                // Retrieve data using a transaction
                Database db = Application.DocumentManager.MdiActiveDocument.Database;
                using (Transaction tr = db.TransactionManager.StartTransaction())
                {
                  DBDictionary extDict = (DBDictionary)tr.GetObject(id, OpenMode.ForRead, false);
                  if (extDict.Contains(DictionaryName))
                  {
                        // We're assuming that if my dictionary exists, then so will the XRecord in it.
                        ObjectId dictId = extDict.GetAt((String)DictionaryName);
                        DBDictionary myDict = (DBDictionary)tr.GetObject(dictId, OpenMode.ForRead);
                        xRec = (Xrecord)tr.GetObject(myDict.GetAt((String)XRecordName),
                            OpenMode.ForRead);
                  }
                }
            }
            if (xRec == null)
            {
                return null;
            }
            else
            {
                return xRec.Data;
            }
      }
      // Modifies data in our XRecord.
      // (creates ou rdictionary and XRecoird if it doesn't already exist)
      public void SetXRecordData(DBObject obj, ResultBuffer myData)
      {
            Database db = Application.DocumentManager.MdiActiveDocument.Database;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                DBDictionary myDict = default(DBDictionary);
                Xrecord xRec = null;
                ObjectId id = obj.ExtensionDictionary;
                if (id == ObjectId.Null)
                {
                  obj.CreateExtensionDictionary();
                  id = obj.ExtensionDictionary;
                }
                DBDictionary extDict = (DBDictionary)tr.GetObject(id, OpenMode.ForWrite);
                if (extDict.Contains(DictionaryName))
                {
                  ObjectId dictId = extDict.GetAt((String)DictionaryName);
                  myDict = (DBDictionary)tr.GetObject(dictId, OpenMode.ForWrite);
                }
                else
                {
                  myDict = new DBDictionary();
                  extDict.SetAt((String)DictionaryName, myDict);
                  tr.AddNewlyCreatedDBObject(myDict, true);
                }
                if (myDict.Contains(XRecordName))
                {
                  xRec = (Xrecord)tr.GetObject(myDict.GetAt((String)XRecordName),
                        OpenMode.ForWrite);
                }
                else
                {
                  xRec = new Xrecord();
                  myDict.SetAt((String)XRecordName, xRec);
                  tr.AddNewlyCreatedDBObject(xRec, true);
                }
                xRec.Data = myData;
                tr.Commit();
            }
      }
    }
    #endregion
    // Grip overrule to add our custom grips to the line
    public class MyGripOverrule : GripOverrule
    {
      public class MyGrip : GripData
      {
            private int mGripNum;
            public int Ordinal
            {
                get
                {
                  return mGripNum;
                }
                set
                {
                  mGripNum = value;
                }
            }
            // Call this to tell the grip to move itself
            public void Move(Vector3d vec)
            {
                GripPoint = GripPoint + vec;
            }
            public override bool ViewportDraw(ViewportDraw worldDraw, ObjectId entityId,
                GripData.DrawType type, Point3d? imageGripPoint, int gripSizeInPixels)
            {
                Point2d unit = worldDraw.Viewport.GetNumPixelsInUnitSquare(GripPoint);
                worldDraw.Geometry.Circle(GripPoint, 1.5 * gripSizeInPixels / unit.X,
                  worldDraw.Viewport.ViewDirection);
                return true;
            }
      }
      // Array to hold our 3 grips
      GripData[] mGripData = new GripData;
      public override void GetGripPoints(Entity entity, GripDataCollection grips,
            double curViewUnitSize, int gripSize, Vector3d curViewDir, GetGripPointsFlags bitFlags)
      {
            ResultBuffer rb = HelperClass.GetSingleton.GetXRecordData(entity);
            // We assume entity is a line
            Line myLine = (Line)entity;
            // Set grip positions to represent temperatures (we're using Celsius)
            // min temperature
            int temp = (int)rb.AsArray().Value;
            double pos = myLine.StartParam + (temp / 100.0) * (myLine.EndParam - myLine.StartParam);
            Point3d pt = myLine.GetPointAtParameter(pos);
            MyGrip grip = new MyGrip();
            grip.Ordinal = 0;
            grip.GripPoint = pt;
            mGripData = grip;
            // max temperature
            temp = (int)rb.AsArray().Value;
            pos = myLine.StartParam + (temp / 100.0) * (myLine.EndParam - myLine.StartParam);
            pt = myLine.GetPointAtParameter(pos);
            grip = new MyGrip();
            grip.Ordinal = 1;
            grip.GripPoint = pt;
            mGripData = grip;
            // current temperature
            temp = (int)rb.AsArray().Value;
            pos = myLine.StartParam + (temp / 100.0) * (myLine.EndParam - myLine.StartParam);
            pt = myLine.GetPointAtParameter(pos);
            grip = new MyGrip();
            grip.Ordinal = 2;
            grip.GripPoint = pt;
            mGripData = grip;
            // Add our grips to the list
            foreach (MyGrip g in mGripData)
            {
                grips.Add(g);
            }
            // Get the standard line grip points as well
            base.GetGripPoints(entity, grips, curViewUnitSize, gripSize, curViewDir, bitFlags);
            Point3d qq1 = grips.GripPoint;
            Point3d qq2 = grips.GripPoint;
      }
      public override void MoveGripPointsAt(Entity entity, GripDataCollection grips,
            Vector3d offset, MoveGripPointsFlags bitFlags)
      {
            // We only take action when we get this call on a database resident entity
            // Dragging operation makes shallow clone of line,
            // and setting clomeMeForDragging to false is generally a bad idea.
            // (If you do set clone me for dragging to false, then don't call bae class overriden methods).
            if (entity.Id.IsValid)
            {
                // Cast to a Line so we can access properties
                Line myLine = (Line)entity;
                Vector3d lineDir = (myLine.EndPoint - myLine.StartPoint);
                lineDir = lineDir.GetNormal();
                // Direction of Line
                double offsetDist = lineDir.DotProduct(offset);
                // Component of mouse translation along like
                // Iterate through list of all grips being moved
                foreach (GripData g in grips)
                {
                  if (g is MyGrip)
                  {
                        MyGrip grip = (MyGrip)g;
                        // Cast to our grip type
                        // Make sure offset never takes grip beyond either end of line
                        if (offsetDist >= 0)
                        {
                            if (offsetDist > (myLine.EndPoint - grip.GripPoint).Length)
                            {
                              offsetDist = (myLine.EndPoint - grip.GripPoint).Length;
                            }
                        }
                        else
                        {
                            if (-offsetDist > (myLine.StartPoint - grip.GripPoint).Length)
                            {
                              offsetDist = -(myLine.StartPoint - grip.GripPoint).Length;
                            }
                        }
                        lineDir = lineDir * offsetDist;
                        // retrieve stored data and edit the changed value
                        ResultBuffer rb = HelperClass.GetSingleton.GetXRecordData(entity);
                        TypedValue[] typeValue = rb.AsArray();
                        String val1 = (String)typeValue.Value;
                        int[] intVal = new int;
                        intVal = (int)typeValue.Value;
                        // min
                        intVal = (int)typeValue.Value;
                        // max
                        intVal = (int)typeValue.Value;
                        // current
                        // Tell grip to move itself long the line
                        grip.Move(lineDir);
                        // Calculate new temperature from grip position along the line
                        double newParam = myLine.GetParameterAtPoint(grip.GripPoint);
                        int newTemp = (int)(100 * (newParam - myLine.StartParam) / (myLine.EndParam - myLine.StartParam));
                        // Don't let min temp value rise above max temp
                        // And don't let max temp go below min temp
                        if (grip.Ordinal == 0)
                        {
                            if (newTemp < intVal)
                            {
                              intVal = newTemp;
                            }
                            else
                            {
                              intVal = intVal - 1;
                            }
                        }
                        else if (grip.Ordinal == 1)
                        {
                            if (newTemp > intVal)
                            {
                              intVal = newTemp;
                            }
                            else
                            {
                              intVal = intVal + 1;
                            }
                        }
                        else
                        {
                            intVal = newTemp;
                        }
                        // Create new resbuf with new data and put back in Xrecord
                        ResultBuffer newRb = new ResultBuffer(new TypedValue((int)DxfCode.Text, val1),
                            new TypedValue((int)DxfCode.Int32, intVal),
                            new TypedValue((int)DxfCode.Int32, intVal),
                            new TypedValue((int)DxfCode.Int32, intVal));
                        HelperClass.GetSingleton.SetXRecordData(myLine, newRb);
                  }
                }
            }
            // Remove our grips from the list befroe calling base class function
            // (Doesn't seem to like my grips)
            for (int i = grips.Count - 1; i >= 0; i += -1)
            {
                if (grips is MyGrip)
                {
                  grips.Remove(grips);
                }
            }
            // If any grips left, then we call base class function
            if (grips.Count > 0)
            {
                base.MoveGripPointsAt(entity, grips, offset, bitFlags);
            }
      }
    }
    #region "Simple DrawableOverrule "
    // This overrule adds our custom graphhics to the Line
    // We're going to turn our Line into a Thermometer
    public class MyDrawOverrule : DrawableOverrule
    {
      const int mSize = 30;
      // Universal scaling constant - so I don't have to edit every calculation
      // if I want the thermometer thicker or thinner
      // This is the function that gets called to add/replace an entity's WorldDraw graphics
      public override bool WorldDraw(Drawable drawable, WorldDraw wd)
      {
            // Is it a line? (It should be)
            if (!(drawable is Line))
            {
                return base.WorldDraw(drawable, wd);
            }
            Line myLine = (Line)drawable;
            Point3dCollection pts = new Point3dCollection();
            // Read Xrecord values to populate prompt defauls
            ResultBuffer resbuf = HelperClass.GetSingleton.GetXRecordData(myLine);
            TypedValue[] typeValue = resbuf.AsArray();
            // Room name
            String myText = (String)typeValue.Value;
            // Min temp
            int lowerTemp = (int)typeValue.Value;
            // max temp
            int upperTemp = (int)typeValue.Value;
            // Current temp
            int curTemp = (int)typeValue.Value;
            double curPos = curTemp / 100.0;
            Vector3d perpVec = (myLine.EndPoint - myLine.StartPoint).CrossProduct(myLine.Normal).GetNormal();
            double startParam = myLine.GetParameterAtPoint(myLine.StartPoint);
            double endParam = myLine.GetParameterAtPoint(myLine.EndPoint);
            var oldColIndex = wd.SubEntityTraits.Color;
            FillType oldFillType = wd.SubEntityTraits.FillType;
            double posParam = 0;
            IntPtr gsMarker = default(IntPtr);
            // Draw thermometer body
            wd.SubEntityTraits.FillType = FillType.FillNever;
            // right body edge
            pts.Clear();
            pts.Add(myLine.StartPoint + perpVec * myLine.Length * 2.5 / mSize);
            pts.Add(myLine.EndPoint + perpVec * myLine.Length * 2.5 / mSize);
            gsMarker = (System.IntPtr)1;
            wd.Geometry.Polyline(pts, myLine.Normal, gsMarker);
            // left body edge
            pts.Clear();
            pts.Add(myLine.EndPoint - perpVec * myLine.Length * 2.5 / mSize);
            pts.Add(myLine.StartPoint - perpVec * myLine.Length * 2.5 / mSize);
            gsMarker = (System.IntPtr)2;
            wd.Geometry.Polyline(pts, myLine.Normal, gsMarker);
            // top body edge
            wd.Geometry.CircularArc(myLine.EndPoint - perpVec * myLine.Length * 2.5 / mSize,
                myLine.EndPoint + (myLine.EndPoint - myLine.StartPoint) * 2.5 / mSize,
                myLine.EndPoint + perpVec * myLine.Length * 2.5 / mSize, ArcType.ArcSimple);
            // bottom body edge
            double theta = Math.PI / 6;
            double rad = (myLine.Length * 2.5 / mSize) / Math.Sin(theta);
            double a = (myLine.Length * 2.5 / mSize) / Math.Tan(theta);
            Point3d bowlCenter = myLine.StartPoint + (myLine.StartPoint - myLine.EndPoint).GetNormal() * a;
            wd.Geometry.CircularArc(myLine.StartPoint + perpVec * myLine.Length * 2.5 / mSize,
                myLine.StartPoint + (myLine.StartPoint - myLine.EndPoint).GetNormal() * (rad + a),
                myLine.StartPoint - perpVec * myLine.Length * 2.5 / mSize, ArcType.ArcSimple);
            // Draw upper temperature marker (in red)
            wd.SubEntityTraits.Color = 1;
            posParam = startParam + (endParam - startParam) * (upperTemp / 100.0);
            pts.Clear();
            pts.Add(myLine.GetPointAtParameter(posParam) - perpVec * myLine.Length * 3 / mSize);
            pts.Add(myLine.GetPointAtParameter(posParam) + perpVec * myLine.Length * 3 / mSize);
            gsMarker = (System.IntPtr)3;
            wd.Geometry.Polyline(pts, myLine.Normal, gsMarker);
            wd.Geometry.Text(myLine.GetPointAtParameter(posParam) + perpVec * myLine.Length * 4 / mSize,
                myLine.Normal, perpVec, myLine.Length * 1.2 / mSize, 1, 0,
                "Max. Temp = " + upperTemp.ToString());
            // Draw lower temperature marker (in blue)
            wd.SubEntityTraits.Color = 5;
            posParam = startParam + (endParam - startParam) * (lowerTemp / 100.0);
            pts.Clear();
            pts.Add(myLine.GetPointAtParameter(posParam) - perpVec * myLine.Length * 3 / mSize);
            pts.Add(myLine.GetPointAtParameter(posParam) + perpVec * myLine.Length * 3 / mSize);
            gsMarker = (System.IntPtr)3;
            wd.Geometry.Polyline(pts, myLine.Normal, gsMarker);
            wd.Geometry.Text(myLine.GetPointAtParameter(posParam) + perpVec * myLine.Length * 4 / mSize,
                myLine.Normal, perpVec, myLine.Length * 1.2 / mSize, 1, 0,
                "Min. Temp = " + lowerTemp.ToString());
            // Draw current temperature marker in different color depending on position w.r.t. min and max temps
            short colIndex = 0;
            if (curTemp <= lowerTemp)
            {
                colIndex = 5;
                // Blue
            }
            else if (curTemp >= upperTemp)
            {
                colIndex = 1;
                // Red
            }
            else
            {
                colIndex = 94;
                // Dark green
            }
            // Draw current Temperature marker
            wd.SubEntityTraits.Color = colIndex;
            posParam = startParam + (endParam - startParam) * (curTemp / 100.0);
            pts.Clear();
            pts.Add(myLine.GetPointAtParameter(posParam) - perpVec * myLine.Length * 3 / mSize);
            pts.Add(myLine.GetPointAtParameter(posParam) + perpVec * myLine.Length * 3 / mSize);
            gsMarker = (System.IntPtr)4;
            wd.Geometry.Polyline(pts, myLine.Normal, gsMarker);
            wd.Geometry.Text(myLine.GetPointAtParameter(posParam) + perpVec * myLine.Length * 4 / mSize,
                myLine.Normal, perpVec, myLine.Length * 1.2 / mSize, 1, 0,
                myText + " Temp = " + curTemp.ToString());
            // We want to draw filled primitives (polygon and circle) to
            // represent the mercury in the thermometer
            wd.SubEntityTraits.FillType = FillType.FillAlways;
            // drawable mercury - line first, then bowl
            pts.Clear();
            Vector3d offset = perpVec * myLine.Length / mSize;
            Point3d pt1 = myLine.StartPoint + offset;
            pts.Add(bowlCenter + offset);
            pts.Add(bowlCenter - offset);
            pts.Add(myLine.GetPointAtParameter(posParam) - offset);
            pts.Add(myLine.GetPointAtParameter(posParam) + offset);
            wd.Geometry.Polygon(pts);
            // mercury bowl
            theta = Math.PI / 6;
            rad = 1.5 * (offset.Length) / Math.Sin(theta);
            a = (offset.Length) / Math.Tan(theta);
            wd.Geometry.Circle(bowlCenter, rad, myLine.Normal);
            // Set old subentitytrait values, then call overriden class worlddraw fn
            wd.SubEntityTraits.FillType = oldFillType;
            wd.SubEntityTraits.Color = oldColIndex;
            return base.WorldDraw(drawable, wd);
      }
    }
    #endregion
    #region "Implementation of the commands"
    public class TestOverrule : IExtensionApplication
    {
      // Setup some global variables
      static MyDrawOverrule mDrawOverrule;
      // One and only instance of this DrawableOverrule
      static MyGripOverrule mGripOverrule;
      // One and only instance of this TransformOverrule
      // Called when DLL is loaded by AutoCAD.
      public void Initialize()
      {
            // Instantiate our global Overrule and set it to overrule lines with my data attached
            mDrawOverrule = new MyDrawOverrule();
            Overrule.AddOverrule(RXObject.GetClass(typeof(Line)), mDrawOverrule, false);
            mDrawOverrule.SetExtensionDictionaryEntryFilter(HelperClass.GetSingleton.DictionaryName);
            // Instantiate our global Overrule and set it to overrule lines with my data attached
            mGripOverrule = new MyGripOverrule();
            Overrule.AddOverrule(RXObject.GetClass(typeof(Line)), mGripOverrule, false);
            mGripOverrule.SetExtensionDictionaryEntryFilter(HelperClass.GetSingleton.DictionaryName);
            // Turn overruling on
            Overrule.Overruling = true;
      }
      // Clean up after ourselves.
      public void Terminate()
      {
            Overrule.RemoveOverrule(RXObject.GetClass(typeof(Line)), mDrawOverrule);
            mDrawOverrule = null;
            Overrule.RemoveOverrule(RXObject.GetClass(typeof(Line)), mGripOverrule);
            mDrawOverrule = null;
      }
      // Toggles all overrules on and off.
      
      public void ToggleOverrule()
      {
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            Overrule.Overruling = !Overrule.Overruling;
            ed.WriteMessage("\n*** Overrule is now " + Overrule.Overruling.ToString() + " ***\n");
            ed.Regen();
      }
      // Demo of Extension Dictionary filter.
      // There's also an Xdata filter, but we won't demonstrate it here - its basically the same).
      // This command needs tidying up to use HelperClass functions for XData access. (Currently does its own thing).
      
      public void AddXDictFilter()
      {
            // Select a line
            Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
            PromptEntityOptions opts = new PromptEntityOptions("\nSelect a line to add Extension dictionary to:");
            opts.SetRejectMessage("\nSorry dude! That's not a line\n");
            opts.AddAllowedClass(typeof(Line), true);
            PromptEntityResult res = ed.GetEntity(opts);
            // Only continue if a circle was selected
            if (res.Status != PromptStatus.OK)
            {
                return;
            }
            // Open circle and make sure it has our dictionary in its extension dictionary
            ObjectId objId = res.ObjectId;
            Database db = objId.Database;
            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                Entity ent = (Entity)tr.GetObject(objId, OpenMode.ForRead);
                ObjectId extId = ent.ExtensionDictionary;
                // Create ext dict if necessary
                if (extId == ObjectId.Null)
                {
                  ent.UpgradeOpen();
                  ent.CreateExtensionDictionary();
                  extId = ent.ExtensionDictionary;
                }
                // Open ext dict
                DBDictionary extDict = (DBDictionary)tr.GetObject(extId, OpenMode.ForWrite);
                // make sure we clone data when entity is cloned for dragging
                extDict.TreatElementsAsHard = true;
                // If it doesn't contain our dictionary, we add one
                PromptIntegerOptions temp1Opts = new PromptIntegerOptions("\nEnter Lower Temperature:");
                PromptIntegerOptions temp2Opts = new PromptIntegerOptions("\nEnter Upper Temperature:");
                PromptIntegerOptions temp3Opts = new PromptIntegerOptions("\nEnter Current Temperature:");
                PromptStringOptions nameOpts = new PromptStringOptions("\nEnter Name:");
                temp1Opts.LowerLimit = 0;
                temp1Opts.UpperLimit = 100;
                temp2Opts.LowerLimit = 0;
                temp2Opts.UpperLimit = 100;
                temp3Opts.LowerLimit = 0;
                temp1Opts.UpperLimit = 100;

                ObjectId xRecObjID;
                Xrecord xRec;
                DBDictionary myDict;
                if (!extDict.Contains(HelperClass.GetSingleton.XRecordName))
                {
                  // If dict is not present, then we add it and set up default Xrec to be edited later
                  extDict.UpgradeOpen();
                  myDict = new DBDictionary();
                  // make sure we clone data when entity is cloned for dragging
                  myDict.TreatElementsAsHard = true;
                  extDict.SetAt(HelperClass.GetSingleton.DictionaryName, myDict);
                  tr.AddNewlyCreatedDBObject(myDict, true);
                  temp1Opts.DefaultValue = 20;
                  temp2Opts.DefaultValue = 30;
                  temp3Opts.DefaultValue = 25;
                  nameOpts.DefaultValue = "San Rafael";
                  xRec = new Xrecord();
                  xRec.Data = new ResultBuffer(new TypedValue((int)DxfCode.Text, nameOpts.DefaultValue),
                        new TypedValue((int)DxfCode.Int32, temp1Opts.DefaultValue),
                        new TypedValue((int)DxfCode.Int32, temp2Opts.DefaultValue),
                        new TypedValue((int)DxfCode.Int32, temp3Opts.DefaultValue));
                  xRecObjID = myDict.SetAt(HelperClass.GetSingleton.XRecordName, xRec);
                  tr.AddNewlyCreatedDBObject(xRec, true);
                }
                else
                {
                  // If dict exists, then we extract values from XRecord to populate default values from prompt
                  // We're assuming that if my dictionary exists, then so will the XRecord in it.
                  ObjectId dictId = extDict.GetAt(HelperClass.GetSingleton.DictionaryName);
                  myDict = (DBDictionary)tr.GetObject(dictId, OpenMode.ForWrite, false);
                  temp1Opts.DefaultValue = 20;
                  temp1Opts.DefaultValue = 30;
                  xRecObjID = myDict.GetAt(HelperClass.GetSingleton.XRecordName);
                  xRec = (Xrecord)tr.GetObject(xRecObjID, OpenMode.ForRead, false);
                }
                // xRec now points to our XRecord, which is open for write.
                // Read Xrecord values to populate prompt defauls
                TypedValue[] typeValue = xRec.Data.AsArray();
                TypedValue val1 = typeValue;
                // Room name
                TypedValue val2 = typeValue;
                // Min temp
                TypedValue val3 = typeValue;
                // Max temp
                TypedValue val4 = typeValue;
                // Current temp
                nameOpts.DefaultValue = (String)val1.Value;
                temp1Opts.DefaultValue = (int)val2.Value;
                temp2Opts.DefaultValue = (int)val3.Value;
                temp3Opts.DefaultValue = (int)val4.Value;
                // Prompt for new values
                PromptResult nameRes = ed.GetString(nameOpts);
                if (nameRes.Status == PromptStatus.OK)
                {
                  val1 = new TypedValue((int)DxfCode.Text, nameRes.StringResult);
                }
                PromptIntegerResult temp1Res = ed.GetInteger(temp1Opts);
                if (temp1Res.Status == PromptStatus.OK)
                {
                  val2 = new TypedValue((int)DxfCode.Int32, temp1Res.Value);
                }
                PromptIntegerResult temp2Res = ed.GetInteger(temp2Opts);
                if (temp2Res.Status == PromptStatus.OK)
                {
                  val3 = new TypedValue((int)DxfCode.Int32, temp2Res.Value);
                }
                PromptIntegerResult temp3Res = ed.GetInteger(temp3Opts);
                if (temp3Res.Status == PromptStatus.OK)
                {
                  val4 = new TypedValue((int)DxfCode.Int32, temp3Res.Value);
                }
                // Now set Xrecord contents to new values
                xRec.Data = new ResultBuffer(val1, val2, val3, val4);
                tr.Commit();
            }
            // Display new results
            ed.Regen();
      }
    }
    #endregion
}


sailorcwx 发表于 2009-5-14 23:51:00

<p>问个问题,2010能不能存成低版本的,如果可以,存成低版本后,自定义实体会变成什么样子的,是否会消失?</p>

雪山飞狐_lzh 发表于 2009-5-15 07:45:00

<p>可以存成低版本的,但别说存低版本,就是不加载Dll,Overrule就会还原</p><p>注意Overrule是规则重定义,采取的手段只是在现有的实体上附加数据(XData或LData),然后由dll读取数据解释为重定义后形式</p><p>感觉这一版的Overrule要么是自动桌子的一次尝试,可能下一版本会推出真的自定义实体(严重怀疑)</p><p>要么就是内部开发人员在Net这块出现了分歧,不打算支持自定义实体(自己猜的)</p><p>不过现阶段真正的自定义实体可以用ObjectArx实现,然后NetArx去调用</p>Overrule的用途现在想到的只有图纸加密:重要的东西规则重定义,别人没有我的Dll就看不见,:)

lntuzjc 发表于 2009-7-24 09:59:00

<p>GripOverrule...需要引用什么才可以用?</p><p>我用的是2008!</p>

雪山飞狐_lzh 发表于 2009-7-24 10:42:00

注意AutoCad要2010版本

tomcom 发表于 2009-8-26 10:12:00

<p>GripOverrule...需要引用什么才可以用?</p>

asdfxx 发表于 2009-9-28 18:01:00

xulintao 发表于 2009-10-22 16:57:00

<p>飞狐兄,这些真是不错啊·但可惜的是必须要高版本的·</p><p>支持!</p><p>支持!</p><p></p>
页: [1] 2
查看完整版本: NetArx2010新特性-规则重定义