.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Overrule worlddraw according visual style

10 REPLIES 10
SOLVED
Reply
Message 1 of 11
O_Eckmann
500 Views, 10 Replies

Overrule worlddraw according visual style

Hi,

 

Before searching too much, I just want to know if it's possible.

I work with pointcloud, and visualisation pc + other objects (hatch, blocks, texts...) in 3D visualstyle is very slow.

So I want to split my screen into 2 vertical viewport : 

 - left viewport is in 2D visual style (PC isn't display natively by AutoCAD), and all other objects are displayed

 - rigth viewport is in 3D visual style (PC is displayed) and I want to "hide" all other object except 3D polyline.

I have thought to write a overrule to display objects or not according to visual style in each viewport.

 

Do you think it's available? I don't ask for code to do that, just to know if you think it's possible, and if it can solve my problem of performance. If yes, I'm going to search.

 

Thanks

 

Olivier

Olivier Eckmann

EESignature

10 REPLIES 10
Message 2 of 11
O_Eckmann
in reply to: O_Eckmann

Hi,

 

I begin to look at this discussion : https://forums.autodesk.com/t5/net/how-to-hide-some-entities-temporary-by-a-command-cmd1-and-then/td...  message 5 accepted as Solution.

 

I've modified code to hide every object except 3D Polyline and PointCloud

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

namespace Namespace1
{
   /// <summary>
   /// A specialization of DrawableOverrule whose sole purpose is
   /// to temporarily hide objects, without having to modify their
   /// Visible property or keep track of what objects need to have 
   /// the value of that property restored.
   /// 
   /// Derive a class from VisibilityOverrule, specifying the base
   /// type of the entities you want to affect, override the
   /// IsVisible() method and have it return true if the argument
   /// should be visible, or false if not.
   /// 
   /// To return to normal display conditions, just dispose the
   /// instance of the VisibilityOverrule-based class.
   /// 
   /// A regen is required to alter the visiblity of affected objects.
   /// </summary>
   /// <typeparam name="T"></typeparam>
   
   public abstract class VisibilityOverrule<T> : DrawableOverrule where T : Entity
   {
      bool disposed = false;
      static RXClass targetClass = RXClass.GetClass(typeof(T));

      public VisibilityOverrule()
      {
         AddOverrule(targetClass, this, false);
      }

      public abstract bool IsVisible(T entity);

      public override bool WorldDraw(Drawable drawable, WorldDraw wd)
      {
         return IsVisible((T) drawable) ? base.WorldDraw(drawable, wd) : true;
      }

      public override void ViewportDraw(Drawable drawable, ViewportDraw vd)
      {
         if(IsVisible((T) drawable))
            base.ViewportDraw(drawable, vd);
      }

      protected override void Dispose(bool disposing)
      {
         if(!disposed)
         {
            disposed = true;
            RemoveOverrule(targetClass, this); 
         }
         base.Dispose(disposing);
      }
   }

   /// Example use of VisibilityOverrule that hides all object except PC and 3DPoly

   public class Hide2DOverrule : VisibilityOverrule<Entity>
   {
      public override bool IsVisible(Entity oEnt)
      {
        string sDxfName = oEnt.Id.ObjectClass.DxfName;
        return (sDxfName == "POLYLINE" || sDxfName == "ACDBPOINTCLOUDEX");
      }
   }

   public static class Commands
   {
      static Hide2DOverrule PcOverrule = null;

      [CommandMethod("TEST2DVIS")]
      public static void ShowHide2D()
      {
         Document doc = Application.DocumentManager.MdiActiveDocument;
         if(doc != null)
         {
            if(PcOverrule == null)
            {
               PcOverrule = new Hide2DOverrule();
               doc.Editor.WriteMessage("\n2D hidden\n");
            }
            else
            {
               PcOverrule.Dispose();
               PcOverrule = null;
               doc.Editor.WriteMessage("\n2D visible\n");
            }
            doc.Editor.Regen();
         }
      }
   }
}

This code works fine in 2D visual style, but doesn't work in 3D visualstyle.

WorldDraw and ViewportDraw Overrules doesn't work in 3D?

 

Olivier

Olivier Eckmann

EESignature

Message 3 of 11

Since that code looks familiar😉, I'll venture to ask if you have verified that the WorldDraw and/or ViewportDraw methods are being called when the view is using a 3D visual Style?

 

Also, have you tried using the REGEN3 command?

Message 4 of 11

@O_Eckmann 

Maybe this code (instead Editor.Regen()) help you: https://forums.autodesk.com/t5/net/regen3-via-api/td-p/9627601

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 5 of 11

Hi @ActivistInvestor ,

 

It's fantastic, I use REGEN3 (in command line) instead of REGEN and overrule works fine.

I had never heard of this command before. Always something to learn.

 

And thanks for your original code.

 

Olivier

Olivier Eckmann

EESignature

Message 6 of 11

Hi @Alexander.Rivilis ,

 

REGEN3 is OK to take into account my overrule.

I'll implement your code to check that everything works, but I've no doubt.

 

Thanks

 

Olivier

Olivier Eckmann

EESignature

Message 7 of 11

Hi,

 

I've a new problem, because I'm not sure to well understand how works WorldDraw and ViewportDraw.

In lots of sample WorldDraw implements :

return base.WorldDraw(drawable, wd);

In this case if object is well drawn, it returns true and never call ViewportDraw. Is that OK?

If I implement

return false;

Object isn't drawn and ViewportDraw is called. OK?

 

In my ViewportDraw, I've implemented this code

bool bVisible = IsVisible((T)drawable);
bool bDrawable = dctVp2D.ContainsKey(vd.Viewport.AcadWindowId) ? dctVp2D[vd.Viewport.AcadWindowId] : true;
if (bVisible || bDrawable)
  base.ViewportDraw(drawable, vd);

dctVp2D is a Dictionnary<int,bool> containing ID of view port (CVPORT number), and true if visual style is 2D, otherwise false.

IsVisible return true only for PointcloudEx, false for other objects.

 

So I want to obtain :

  VisualStyle = 2DWireFrame => all objetcs are drawn

  VisualStyle != 2DWireFrame => only PointCloud are drawn

And it doesn't work as expected :

  VisualStyle = 2DWireFrame => all objetcs are drawn except LINE, POLYLINE, POINTCLOUD

  VisualStyle != 2DWireFrame => No object are drawn.

 

In this screencast, I write message with object's type, Visible, Drawable and even with viewportdraw called, some objects aren't visible.

 

Thanks for any help.

 

Olivier Eckmann

EESignature

Message 8 of 11

I would suggest removing all code from your ViewportDraw override and doing nothing more than super-message the base method, and observing the result and seeing if it yields the expected result.

Message 9 of 11

Hi @ActivistInvestor ,

 

I've taken your original code for locked layer.

I've drawn 1 LINE, 1 CIRCLE and 1 LWPOLYLINE on Layer1 which is locked and copy these objects to Layer2 which is unlocked.

O_Eckmann_0-1696500530396.png

 

If I use your code, I never go to ViewportDraw, only WorldDraw is called. It confirms that if WorldDraw is implemented and return true, ViewportDraw is never called.

So I modify code to do nothing in WorldDraw and returning false => AutoCAD call ViewportDraw at each regen.

All object on Layer1 (locked) doesn't display => OK because I don't execute ViewportDraw => nothing drawn

On Layer 2, ViewportDraw is called for each objet, but only LWPOLYLINE is shown. LINE and CIRCLE isn't visible.

Here is the code I've modified

    public override bool WorldDraw(Drawable drawable, WorldDraw wd)
    {
      //return IsVisible((T)drawable) ? base.WorldDraw(drawable, wd) : true;
      return false;
    }

    public override void ViewportDraw(Drawable drawable, ViewportDraw vd)
    {
      Document doc = Application.DocumentManager.MdiActiveDocument;
      Entity oEnt = (Entity)drawable;
      string sLayerName = string.Empty;
      if (oEnt.Database != null && !oEnt.LayerId.IsNull)
      {
        using (LayerTableRecord ltr = (LayerTableRecord)oEnt.LayerId.Open(OpenMode.ForRead))
          sLayerName = ltr.Name;
      }
      doc.Editor.WriteMessage("\nViewportDraw = " + drawable.GetRXClass().DxfName + ", " + sLayerName + " => ");
      if (IsVisible((T)drawable))
      {
        doc.Editor.WriteMessage(" drawn\n");
        base.ViewportDraw(drawable, vd);
      }
      else
        doc.Editor.WriteMessage(" NOT drawn\n");

    }

Here is what I obtain on command line when I launch LOCKEDLAYERVIS

Commande: LOCKEDLAYERVIS
Locked layers hidden
Régénération du modèle.
ViewportDraw = LWPOLYLINE, Layer2 => drawn
ViewportDraw = CIRCLE, Layer2 => drawn
ViewportDraw = LINE, Layer2 => drawn
ViewportDraw = LWPOLYLINE, Layer1 => NOT drawn
ViewportDraw = CIRCLE, Layer1 => NOT drawn
ViewportDraw = LINE, Layer1 => NOT drawn

 

And what I obtain on screen

O_Eckmann_1-1696500656353.png

 

If I add ARC, TEXT, MTEXT, SPLINE, HATCH, ELLIPSE

O_Eckmann_4-1696501037118.png

 

After launching command, I obtain this in command line

Commande: LOCKEDLAYERVIS
Locked layers hidden
Régénération du modèle.
ViewportDraw = LWPOLYLINE, Layer2 =>  drawn
ViewportDraw = HATCH, Layer2 =>  drawn
ViewportDraw = CIRCLE, Layer2 =>  drawn
ViewportDraw = LINE, Layer2 =>  drawn
ViewportDraw = LWPOLYLINE, Layer1 =>  NOT drawn
ViewportDraw = CIRCLE, Layer1 =>  NOT drawn
ViewportDraw = LINE, Layer1 =>  NOT drawn
ViewportDraw = ARC, Layer2 =>  drawn
ViewportDraw = TEXT, Layer2 =>  drawn
ViewportDraw = MTEXT, Layer2 =>  drawn
ViewportDraw = SPLINE, Layer2 =>  drawn
ViewportDraw = HATCH, Layer1 =>  NOT drawn
ViewportDraw = ARC, Layer1 =>  NOT drawn
ViewportDraw = TEXT, Layer1 =>  NOT drawn
ViewportDraw = MTEXT, Layer1 =>  NOT drawn
ViewportDraw = SPLINE, Layer1 =>  NOT drawn

And on screen I obtain

O_Eckmann_5-1696501094287.png

LINE, ARC, CIRCLE aren't visible. (for my purpose, I've also tried PointCloud, but it reacts like line... => not visible)

 

If you have explanation of what I'm doing wrong, I'll very happy to understand.

 

Thanks a lot

Olivier Eckmann

EESignature

Message 10 of 11

The problem appears to be (as I feared) that you cannot regenerate all types of entities on a per-viewport basis using ViewportDraw(). The reason is most-likely because not all types of entities implement ViewportDraw().

 

You can find one attempt to work around that problem here (although it looks like a real 'kludge-o-rama').

Message 11 of 11

Hi @ActivistInvestor ,

 

Thanks a lot for this article. It doesn't seem so easy to implement 🙄

 

I'll investigate to try to understand all concept.

 

Olivier

Olivier Eckmann

EESignature

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Technology Administrators


Autodesk Design & Make Report