Hi,
I am about to write the function using Overrule API to temporary override object’s colour to ByLayer for all entities in the drawing.
At this moment I just have simple class for testing (just to check if it is possible) and so far I can see problem with complex entities.
Entities such as Line, Polyline even BlockReferences work fine but complex objects like HATCH, MTEXT and LEADER do not change colour as set in SetAttribute method.
Below is simple class I was testing.
public class ByLayerColorOverrule : DrawableOverrule
{
public override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.Drawable drawable, Autodesk.AutoCAD.GraphicsInterface.WorldDraw wd)
{
base.WorldDraw(drawable, wd);
return true;
}
public override int SetAttributes(Drawable d, DrawableTraits t)
{
int b = base.SetAttributes(d, t);
if (d is Entity)
{
// Set color to index 256 - By Layer
t.Color = 256;
}
return b ;
}
}
Any idea what I am doing wrong?
Thank you,
Richard
Solved! Go to Solution.
Solved by Balaji_Ram. Go to Solution.
Try to change your function this way:
public override bool WorldDraw(Autodesk.AutoCAD.GraphicsInterface.Drawable drawable, Autodesk.AutoCAD.GraphicsInterface.WorldDraw wd) { Autodesk.AutoCAD.DatabaseServices.Entity en = drawable as Autodesk.AutoCAD.DatabaseServices.Entity; if (en != null) { short clr = 256; clr = wd.SubEntityTraits.Color; wd.SubEntityTraits.Color = 256; en.UpgradeOpen(); en.ColorIndex = clr; if (en.HasPersistentReactor(en.ObjectId)) { ObjectIdCollection ids= en.GetPersistentReactorIds(); if (ids.Count > 0) { foreach (ObjectId id in ids) { Entity obj = id.GetObject(OpenMode.ForWrite,false,false) as Entity; obj.ColorIndex = clr; } } } en.DowngradeOpen(); wd.SubEntityTraits.Color = clr; } return base.WorldDraw(drawable, wd); } public override int SetAttributes(Drawable d, DrawableTraits t) { int b = base.SetAttributes(d, t); if (d is Entity) { // Set color to index 256 - By Layer t.Color = 256; } return b; }
Hi Hallex,
Thank you for your suggestion, it works, but what I want is to change object’s colours just temporarily (in AutoCAD editor only) that why I thought overrule is good tools to do that.
Code you suggested is actually changing colour of entities in file, that is exactly what I want to avoid.
Any other idea?
Thank you,
Richard
Hello Richard,
I have come across a similar query which my colleague had asked to our engineering team.
It seems that the overrule does not change the color of some of the complex objects (leader. mtext for example) due to the way those entities are made up. The components of the complex entity may ignore the color set to the subentity traits while they get drawn.
As a workaround, it was suggested that a clone be created and its WorldDraw be called to draw to the screen.
Based on this suggestion, here is a sample code that I created to overrule the color of a leader / mtext :
public class MyDrawOverrule : DrawableOverrule { Entity _clone = null; public override bool WorldDraw(Drawable drawable, WorldDraw wd) { if ( (drawable is Leader || drawable is MText) && _clone != null) { return _clone.WorldDraw(wd); } return base.WorldDraw(drawable, wd); } public override int SetAttributes(Drawable drawable, DrawableTraits traits) { if(drawable is Leader || drawable is MText) { _clone = drawable.Clone() as Entity; _clone.SetAttributes(traits); _clone.ColorIndex = 2; } return base.SetAttributes(drawable, traits); } } public class Commands { static MyDrawOverrule pldo = null; static List<ObjectId> entityIds = new List<ObjectId>(); [CommandMethod("Test")] public void TestMethod() { Document doc = Application.DocumentManager.MdiActiveDocument; Editor ed = doc.Editor; PromptEntityResult per = ed.GetEntity("\nSelect a Leader or MText"); if (per.Status != PromptStatus.OK) return; entityIds.Add(per.ObjectId); if (pldo == null) { pldo = new MyDrawOverrule(); Overrule.AddOverrule(RXObject.GetClass(typeof(Autodesk.AutoCAD.DatabaseServices.Leader)), pldo, true); Overrule.AddOverrule(RXObject.GetClass(typeof(Autodesk.AutoCAD.DatabaseServices.MText)), pldo, true); pldo.SetIdFilter(entityIds.ToArray()); Overrule.Overruling = true; } else { pldo.SetIdFilter(entityIds.ToArray()); } using (Transaction tr = doc.Database.TransactionManager.StartTransaction()) { Entity reg = (Entity)tr.GetObject(per.ObjectId, OpenMode.ForWrite); reg.RecordGraphicsModified(true); tr.TransactionManager.QueueForGraphicsFlush(); tr.Commit(); } } }
Hi Balaji,
Thank you for a example solving the issue.
It is actually simple but powerful way how to change any properties of entities, not just properties in DrawableTraits class.
Thank you,
Richard
Hi there Balaaji,
Could this be the same reason why we are also having an issue with blocks that are in the worlddraw of an Object Overrule. The colours of the blocks come in a darker. As if they are being selected?
Ta,
Maritn.
Hello Martin,
I havent come across such issue with overrule.
I will try and reproduce the issue and update you in the other post.
http://forums.autodesk.com/t5/NET/Overuled-blocks-appear-darker/td-p/3750867
Hi there Balaji,
were you able to re-create the problem were having?
Regards,
Maritn.
I used your example, and couldn't get it to work. Then I found the issue, which fixed it for me by changing the return to return the _clone rather than the drawable. See below:
public override int SetAttributes(Drawable drawable, DrawableTraits traits)
{
_clone = (Entity)drawable.Clone();
_clone.SetAttributes(traits);
_clone.ColorIndex = 1;
return base.SetAttributes(_clone, traits);
}