epwt 发表于 2011-3-28 09:30:45

DrawJig闪烁

重写DrawJig的方法时,
绘制出来的实体一直在闪烁。
应该是WorldDraw一直在捕获光标位置重绘的问题。
但是除了计算光标上一次到本次距离,来减少重绘的次数,
让闪烁不是那么明显,是否还有别的科学的方法呢。
对重绘的内部机制了解的不是特别清楚,
求高手解答。
多谢!

carrot1983 发表于 2020-9-29 15:53:10

应该不是代码的问题。以下这段代码是gile 大神写的。
public class MoveJig : DrawJig
    {
      protected Point3d basePt;
      protected Entity[] entities;

      public MoveJig(Entity[] entities, Point3d basePt)
      {
            this.entities = entities;
            this.basePt = basePt;
      }

      public Matrix3d Displacement { get; private set; }

      protected override SamplerStatus Sampler(JigPrompts prompts)
      {
            var options = new JigPromptPointOptions("\nSecond point: ");
            options.UserInputControls = UserInputControls.Accept3dCoordinates;
            options.BasePoint = basePt;
            options.UseBasePoint = true;
            options.Cursor = CursorType.RubberBand;
            var result = prompts.AcquirePoint(options);

            if (basePt.DistanceTo(result.Value) < Tolerance.Global.EqualPoint)
                return SamplerStatus.NoChange;

            Displacement = Matrix3d.Displacement(result.Value - basePt);
            return SamplerStatus.OK;
      }

      protected override bool WorldDraw(WorldDraw draw)
      {
            var geo = draw.Geometry;
            if (geo != null)
            {
                geo.PushModelTransform(Displacement);
                foreach (var ent in entities) geo.Draw(ent);
                geo.PopModelTransform();
            }
            return true;
      }
    }

      
      public void Test()
      {
            var doc = Application.DocumentManager.MdiActiveDocument;
            var db = doc.Database;
            var ed = doc.Editor;

            var selection = ed.GetSelection();
            if (selection.Status != PromptStatus.OK) return;

            var ptResult = ed.GetPoint("\nBase point: ");
            if (ptResult.Status != PromptStatus.OK) return;

            using (Transaction tr = db.TransactionManager.StartTransaction())
            {
                Entity[] entities = new Entity;
                for (int i = 0; i < selection.Value.Count; i++)
                {
                  entities = (Entity)tr.GetObject(selection.Value.ObjectId, OpenMode.ForRead);
                }

                var jig = new MoveJig(entities, ptResult.Value.TransformBy(ed.CurrentUserCoordinateSystem));
                var result = ed.Drag(jig);

                if (result.Status == PromptStatus.OK)
                {
                  foreach (var ent in entities)
                  {
                        ent.UpgradeOpen();
                        ent.TransformBy(jig.Displacement);
                  }
                }
                tr.Commit();
            }
      }
    }

sieben 发表于 2020-9-30 08:51:13

    /// <summary>
    /// 模拟AutoCAD移动命令Move
    /// </summary>
    public void sMoveJig()
    {
      try
      {

      PromptSelectionResult psres = ac.ed.GetSelection();
      if (psres.Status != PromptStatus.OK)
          return;
      ents = new Entity;
      using (Transaction ctrans = ac.db.TransactionManager.StartTransaction())
      {
          for (int i = 0; i < psres.Value.Count; i++)
          {
            Entity ent = (Entity)ctrans.GetObject(psres.Value.ObjectId, OpenMode.ForRead);
            ents = (Entity)ent.Clone();
          }
          ctrans.Commit();
      }
      PromptPointResult ppRes = ac.ed.GetPoint("\n基准点");
      if (ppRes.Status != PromptStatus.OK)
          return;
      Point3d startPoint = ppRes.Value;
      _PrePosition = startPoint;
      PromptResult pres = ac.ed.Drag(this);
      if (pres.Status == PromptStatus.OK)
      {
          Vector3d displacementVector = _CurPosition - startPoint;
          using (Transaction ctrans = ac.db.TransactionManager.StartTransaction())
          {
            for (int i = 0; i < psres.Value.Count; i++)
            {
            Entity ent = (Entity)ctrans.GetObject(psres.Value.ObjectId, OpenMode.ForWrite);
            ent.TransformBy(Matrix3d.Displacement(displacementVector));
            }
            ctrans.Commit();
          }
      }
      }
      catch (System.Exception ex)
      {
      ae.WriteMessage(ex);
      }
      finally
      {
      for (int i = 0; i < ents.Length; i++)
      {
          ents.Dispose();
      }
      }
    }

sieben 发表于 2020-9-30 08:58:06

    /// <summary>
    /// 模拟AutoCAD复制命令Copy
    /// </summary>
   
    static public void sCmd_Copy()
    {
      aModifyJig tJig = new aModifyJig();
      tJig.sCopyJig();
    }
    /// <summary>
    /// 模拟AutoCAD复制命令Copy
    /// </summary>
    public void sCopyJig()
    {
      try
      {
      PromptSelectionResult psRes = ac.ed.GetSelection();
      if (psRes.Status != PromptStatus.OK) return;
      ents = new Entity;
      using (Transaction ctrans = ac.db.TransactionManager.StartTransaction())
      {
          for (int i = 0; i < psRes.Value.Count; i++)
          {
            Entity ent = (Entity)ctrans.GetObject(psRes.Value.ObjectId, OpenMode.ForRead);
            ents = (Entity)ent.Clone();
          }
          ctrans.Commit();
      }
      aApp.SetSystemVariable("OSMODE", 16383);
      _PrePosition = ac.ed.GetPoint("\nBase Point").Value;
      PromptResult pres = ac.ed.Drag(this);
      if (pres.Status == PromptStatus.OK)
      {
          DBObjectCollection dbClt = new DBObjectCollection();
          for (int i = 0; i < ents.Length; i++)
          {
            dbClt.Add(ents);
          }
          an.DrawEntity(dbClt, aEntclls.Null, false);
      }
      else
      {
          for (int i = 0; i < ents.Length; i++)
          {
            ents.Dispose();
          }
      }
      }
      catch (System.Exception ex)
      {
      ae.WriteMessage(ex);
      for (int i = 0; i < ents.Length; i++)
      {
          ents.Dispose();
      }
      }
    }

CADKaifa 发表于 2011-3-28 14:41:33

这个MS不好解决,你看CAD中,插入块的操作,就可以看出来,也是一直闪烁的

epwt 发表于 2011-3-28 18:22:29

恩,多谢!
现在用了一个比较笨的方法解决。
就是先把实体加入到块表中,
然后再WorldDraw的时候改实体的某些属性,
这样就不会闪了。
但是具体原理我还不是很清楚。
希望高手能解答。
多谢。

bluelightcsy 发表于 2011-5-26 20:57:22

一直都应该是你这种做法啊,先创建Block定义,然后创建Reference去Jig。

baowdong 发表于 2011-9-17 09:40:19

请问您改了实体的哪些属性,就不闪烁了,等待回复中.....

carrot1983 发表于 2020-9-28 23:09:04

最近在折腾,确实没法解决闪烁的问题 。用lisp的grread函数,都不会这么闪。其它人有没有解决办法?

sieben 发表于 2020-9-29 09:21:39

Jig闪烁是自己的问题,请检查自己代码,检查是否使用正确的jig

carrot1983 发表于 2020-9-29 15:54:02

sieben 发表于 2020-9-29 09:21
Jig闪烁是自己的问题,请检查自己代码,检查是否使用正确的jig

Jig闪烁,出来的效果就像是cad的move命令一样。但是,如果我用lisp的grread函数就不会。

carrot1983 发表于 2020-9-29 16:05:45

以下是用lisp 写的。效果很稳,不会像CAD自带move命令和8楼的movejig。不会闪烁。

(defun C:TEST (/ DATA GRR GRRPT KEY LOOP OBJECTS PT SS)
;; by carrot1983 2020.09.29
(setq SS (ssget))
(setq PT (getpoint "\n指定点:"))
(setq OBJECTS (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex SS)))))
(setq LOOP t)
(while LOOP
    (setq GRR (grread t 15 2))
    (setq KEY (car GRR))
    (setq DATA (cadr GRR))
    (cond ((= KEY 5)
           (setq GRRPT DATA)
           (foreach O OBJECTS
             (vla-move O (vlax-3d-point PT) (vlax-3d-point GRRPT))
           )
          ) ;_移动
          ((or (= KEY 3) (= DATA 13))
           (setq LOOP NIL)
          ) ;_3左击 13回车 表示确认
          ((member KEY '(12 25))
           (redraw)
           (setq LOOP NIL)
          ) ;_右键退出
    )
    (setq PT GRRPT) ;_新基点
)
(redraw)
)
页: [1] 2
查看完整版本: DrawJig闪烁