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
Solved! Go to Solution.
Solved by ActivistInvestor. Go to Solution.
Solved by Alexander.Rivilis. Go to Solution.
Solved by ActivistInvestor. Go to Solution.
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
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?
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
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
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
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
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.
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.
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
If I add ARC, TEXT, MTEXT, SPLINE, HATCH, ELLIPSE
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
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
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').
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
Can't find what you're looking for? Ask the community or share your knowledge.