TheSwamp

Code Red => .NET => Topic started by: MexicanCustard on January 29, 2013, 03:45:29 PM

Title: AutoCAD MEP Display Manager Override
Post by: MexicanCustard on January 29, 2013, 03:45:29 PM
Has anyone got an example on overriding the display manager properties on a single object.  The examples that come with MEP are only for Walls and Materials which use DisplayPropertiesWallPlan() and DisplayPropertiesMaterial().  For pipe and fittings I'm assuming I need to use DisplayProperties() which when you create a new instance has no DisplayComponents.
Title: Re: AutoCAD MEP Display Manager Override
Post by: Keith Brown on January 29, 2013, 10:52:02 PM
Here are two examples from an old AU class.  They also use a wall but not in the manner you describe......  I think.

Code - C#: [Select]
  1.        #region Example_DisplayOverrideDefaultDrawing
  2.         [CommandMethod("ACAClassCode", "ExDisplayOverrideDefaultDrawing", CommandFlags.Modal)]
  3.         public void DisplayOverrideDefaultDrawing()
  4.         {
  5.             Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  6.             try
  7.             {
  8.                 PromptEntityOptions entopts = new PromptEntityOptions("Pick an entity of your choice from the drawing to change colors.");
  9.                 entopts.Message = "Pick an entity of your choice from the drawing to change colors.";
  10.                 PromptEntityResult entRes = null;
  11.                 try
  12.                 {
  13.                     entRes = ed.GetEntity(entopts);
  14.                 }
  15.                 catch
  16.                 {
  17.                     ed.WriteMessage("You did not select a valid entity");
  18.                     return;
  19.                 }
  20.  
  21.                 if (entRes.Status != PromptStatus.Error)
  22.                 {
  23.                     ObjectId entid = entRes.ObjectId;
  24.                     Database db = Application.DocumentManager.MdiActiveDocument.Database;
  25.                     Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager;
  26.                     using (Transaction trans1 = tm.StartTransaction())
  27.                     {
  28.                         // we have object level overrides if this is > 0
  29.                         ObjectIdCollection dispIdsFromEntity = DisplayProperties.GetDisplayPropertiesFromOverride(entid);
  30.                         foreach (ObjectId id in dispIdsFromEntity)
  31.                         {
  32.                             DoColorOverrideChange(id, 1);
  33.                         }
  34.  
  35.                         // See if there is a style ovverride and change its color only if present
  36.                         ObjectId wallStyleId = new ObjectId();
  37.  
  38.                         using (Transaction trans2 = tm.StartTransaction())
  39.                         {
  40.                             Autodesk.AutoCAD.DatabaseServices.Entity ent = (Autodesk.AutoCAD.DatabaseServices.Entity)tm.GetObject(entid, OpenMode.ForRead, true);
  41.                             if (ent.GetType() == typeof(Wall))
  42.                             {
  43.                                 Wall wall = ent as Wall;
  44.                                 wallStyleId = wall.StyleId;
  45.                             }
  46.                             trans2.Commit();
  47.                         }
  48.  
  49.                         if (!wallStyleId.IsNull)
  50.                         {
  51.                             ObjectIdCollection dispIdsFromStyle = DisplayProperties.GetDisplayPropertiesFromOverride(wallStyleId);
  52.                             foreach (ObjectId id in dispIdsFromStyle)
  53.                             {
  54.                                 DoColorOverrideChange(id, 2);
  55.                             }
  56.                         }
  57.  
  58.                         // Now, just blanket the drawing level override with a new color for the wall class.
  59.  
  60.                         DisplayRepresentationManager mgr = new DisplayRepresentationManager();
  61.                         ObjectIdCollection idsReps = mgr.GetDisplayRepresentationIdsFromCurrentViewport(RXObject.GetClass(typeof(Wall)));
  62.                         using (Transaction trans3 = tm.StartTransaction())
  63.                         {
  64.                             foreach (ObjectId id in idsReps)
  65.                             {
  66.                                 DisplayRepresentation rep = (DisplayRepresentation)tm.GetObject(id, OpenMode.ForRead, true);
  67.                                 if (rep.Name == "AecDbDispRepWallPlan") // this is a sanity check, I believe because we are getting the displayreps frmo the current viewport, based on wall, there can be only this one per class per drawing...
  68.                                 {
  69.                                     Autodesk.AutoCAD.DatabaseServices.Entity ent = (Autodesk.AutoCAD.DatabaseServices.Entity)tm.GetObject(entid, OpenMode.ForRead, true);
  70.                                     ObjectId idDispProp = rep.GetDisplayPropertiesId(ent);
  71.                                     DoColorOverrideChange(idDispProp, 6);
  72.                                 }
  73.                             }
  74.                             trans3.Commit();
  75.                         }
  76.  
  77.  
  78.                         trans1.Commit();
  79.                     }
  80.                 }
  81.             }
  82.             catch (System.Exception e)
  83.             {
  84.                 ed.WriteMessage("\nException: " + e.Message);
  85.             }
  86.             finally
  87.             {
  88.             }
  89.         }
  90.  
  91.         void DoColorOverrideChange(ObjectId id, short color)
  92.         {
  93.             Database db = HostApplicationServices.WorkingDatabase;
  94.             Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager;
  95.             using (Transaction trans = tm.StartTransaction())
  96.             {
  97.                 DisplayProperties dispProps = (DisplayProperties)tm.GetObject(id, OpenMode.ForRead, true);
  98.                 System.Collections.Specialized.StringCollection compNames = new System.Collections.Specialized.StringCollection();
  99.                 DisplayComponent[] comps = dispProps.GetDisplayComponents(out compNames);
  100.                 if (compNames.Contains("Shrink Wrap"))
  101.                 {
  102.                     if (comps[compNames.IndexOf("Shrink Wrap")].GetType() == typeof(DisplayComponentEntity))
  103.                     {
  104.                         DisplayComponentEntity compEntity = comps[compNames.IndexOf("Shrink Wrap")] as DisplayComponentEntity;
  105.                         dispProps.UpgradeOpen();
  106.                         if (compEntity.Color.ColorMethod == Autodesk.AutoCAD.Colors.ColorMethod.ByAci)
  107.                             compEntity.ColorIndex = color;
  108.                         else
  109.                             compEntity.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByColor, color);
  110.  
  111.                     }
  112.                 }
  113.                 trans.Commit();
  114.             }
  115.         }
  116.         #endregion
  117.  
  118.         #region Example_DisplayOverrideAddEntity
  119.         [CommandMethod("ACAClassCode", "ExDisplayOverrideAddEntity", CommandFlags.Modal)]
  120.         public void DisplayOverrideEntity()
  121.         {
  122.             Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
  123.             try
  124.             {
  125.                 PromptEntityOptions entopts = new PromptEntityOptions("Pick an entity of your choice from the drawing to add color override.");
  126.                 entopts.Message = "Pick an entity of your choice from the drawing to add color override.";
  127.                 PromptEntityResult entRes = null;
  128.                 try
  129.                 {
  130.                     entRes = ed.GetEntity(entopts);
  131.                 }
  132.                 catch
  133.                 {
  134.                     ed.WriteMessage("You did not select a valid entity");
  135.                     return;
  136.                 }
  137.  
  138.                 if (entRes.Status != PromptStatus.Error)
  139.                 {
  140.                     ObjectId entid = entRes.ObjectId;
  141.                     Database db = Application.DocumentManager.MdiActiveDocument.Database;
  142.                     Autodesk.AutoCAD.DatabaseServices.TransactionManager tm = db.TransactionManager;
  143.                     using (Transaction trans1 = tm.StartTransaction())
  144.                     {
  145.                         DisplayRepresentationManager mgr = new DisplayRepresentationManager();
  146.                         ObjectIdCollection idsReps = mgr.GetDisplayRepresentationIdsFromCurrentViewport(RXObject.GetClass(typeof(Wall)));
  147.                         ObjectId idRep = idsReps[0];
  148.                         DisplayRepresentation rep = (DisplayRepresentation)tm.GetObject(idRep, OpenMode.ForRead, true);
  149.                         if (rep.Name == "AecDbDispRepWallPlan")
  150.                         {
  151.                             DisplayProperties newProps = rep.CreateNewDisplayProperties();
  152.                             newProps.SetToStandard(db);
  153.                             newProps.SubSetDatabaseDefaults(db);
  154.                             newProps.SetDisplayRepDefaults(rep);
  155.                             //                
  156.                             System.Collections.Specialized.StringCollection compNames = new System.Collections.Specialized.StringCollection();
  157.                             DisplayComponent[] comps = newProps.GetDisplayComponents(out compNames);
  158.                             if (compNames.Contains("Shrink Wrap"))
  159.                             {
  160.                                 if (comps[compNames.IndexOf("Shrink Wrap")].GetType() == typeof(DisplayComponentEntity))
  161.                                 {
  162.                                     DisplayComponentEntity compEntity = comps[compNames.IndexOf("Shrink Wrap")] as DisplayComponentEntity;
  163.                                     compEntity.ResetEnt();
  164.                                     if (compEntity.Color.ColorMethod == Autodesk.AutoCAD.Colors.ColorMethod.ByAci)
  165.                                         compEntity.ColorIndex = 30; // Made a code change here so we could see it!!!!
  166.                                     else
  167.                                         compEntity.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex(Autodesk.AutoCAD.Colors.ColorMethod.ByColor, 30); // Made a code change here so we could see it!!!!
  168.  
  169.                                 }
  170.                             }
  171.                             //
  172.                             ObjectId idNOD = db.NamedObjectsDictionaryId;
  173.                             Autodesk.AutoCAD.DatabaseServices.DBDictionary nodDict = (Autodesk.AutoCAD.DatabaseServices.DBDictionary)tm.GetObject(idNOD, OpenMode.ForRead, true);
  174.  
  175.                             ObjectId idOverrideExtDict = new ObjectId();
  176.                             try
  177.                             {
  178.                                 idOverrideExtDict = nodDict.GetAt(Override.ExtensionDictionaryName);
  179.                             }
  180.                             catch (Autodesk.AutoCAD.Runtime.Exception e)
  181.                             {
  182.                                 if (e.ErrorStatus == Autodesk.AutoCAD.Runtime.ErrorStatus.KeyNotFound)
  183.                                 {
  184.                                     DBDictionary dict = new DBDictionary();
  185.                                     nodDict.UpgradeOpen();
  186.                                     idOverrideExtDict = nodDict.SetAt(Override.ExtensionDictionaryName, dict);
  187.                                     nodDict.DowngradeOpen();
  188.                                     trans1.AddNewlyCreatedDBObject(dict, true);
  189.                                 }
  190.                             }
  191.                             if (idOverrideExtDict.IsNull)
  192.                                 return;
  193.  
  194.                             Autodesk.AutoCAD.DatabaseServices.DBDictionary overrideExtDict = (Autodesk.AutoCAD.DatabaseServices.DBDictionary)tm.GetObject(idOverrideExtDict, OpenMode.ForWrite, true);
  195.                             ObjectId idNewProps = overrideExtDict.SetAt("*A", newProps);
  196.                             trans1.AddNewlyCreatedDBObject(newProps, true);
  197.  
  198.                             OverrideDisplayProperties overProps = new OverrideDisplayProperties();
  199.                             overProps.ViewId = idRep;
  200.                             overProps.DisplayPropertyId = idNewProps;
  201.                             Autodesk.Aec.DatabaseServices.Entity ent = (Autodesk.Aec.DatabaseServices.Entity)tm.GetObject(entid, OpenMode.ForWrite, true);
  202.                             ent.Overrides.Add(overProps);
  203.                         }
  204.                         trans1.Commit();
  205.                     }
  206.                 }
  207.             }
  208.             catch (System.Exception e)
  209.             {
  210.                 ed.WriteMessage("\nError: " + e.Message);
  211.             }
  212.             finally
  213.             {
  214.             }
  215.         }
  216.         #endregion
  217.  
Title: Re: AutoCAD MEP Display Manager Override
Post by: MexicanCustard on January 30, 2013, 08:08:25 AM
Thanks for posting that.  The method DisplayOverrideEntity() is the example I wished I had yesterday. I was able, through lots of trial and error, to find the key, DisplayRepresentation.CreateNewDisplayProperties().  Using that method instead of instantiating a new instance of DisplayProperties is where you get the DisplayComponents for the view you are working on.  From there its the same as the examples included with MEP.
Title: Re: AutoCAD MEP Display Manager Override
Post by: MexicanCustard on January 31, 2013, 02:37:54 PM
Ok, I'm still having a problem creating a new Override.  If the current DisplayRepresentation is anything other than "Plan" or a "Plan" derivative then using DisplayRepresentation.CreateNewDisplayProperties() returns a DisplayProperties with an empty DisplayComponent collection.  Using the GetDisplayComponents() method from the new DisplayProperties returns an empty array of DisplayComponents.

 I'm trying to change the color of the object, a pipe, while in the current display.  Without the DisplayComponent "Contour" I have nothing to change.

Code: [Select]
                    var displayManager = new DisplayRepresentationManager(db);
                    var pipeIds = displayManager.GetDisplayRepresentationIdsFromCurrentViewport(RXObject.GetClass(typeof(Pipe)));
                    var pipeDisplayRep = (DisplayRepresentation)pipeIds[0].GetObject(OpenMode.ForRead);
                    var pipeDisplayProp = pipeDisplayRep.CreateNewDisplayProperties(); <--If pipeDisplayRep is anything other than "Plan"
                    pipeDisplayProp.SetToStandard(db);
                    pipeDisplayProp.SubSetDatabaseDefaults(db);

                    var sc = new StringCollection();
                    var components = pipeDisplayProp.GetDisplayComponents(out sc); <--components will be an empty array
                    foreach (DisplayComponentEntity component in fittingComponents)
                    {
                        component.Color = Color.FromColorIndex(ColorMethod.ByAci, 1);
                    }



So if anyone can point me in the right direction it would be greatly appreciated.
Title: Re: AutoCAD MEP Display Manager Override
Post by: Micaletti on August 07, 2013, 04:02:04 PM
Ok, I'm still having a problem creating a new Override.  If the current DisplayRepresentation is anything other than "Plan" or a "Plan" derivative then using DisplayRepresentation.CreateNewDisplayProperties() returns a DisplayProperties with an empty DisplayComponent collection.  Using the GetDisplayComponents() method from the new DisplayProperties returns an empty array of DisplayComponents.

 I'm trying to change the color of the object, a pipe, while in the current display.  Without the DisplayComponent "Contour" I have nothing to change.

Code: [Select]
                    var displayManager = new DisplayRepresentationManager(db);
                    var pipeIds = displayManager.GetDisplayRepresentationIdsFromCurrentViewport(RXObject.GetClass(typeof(Pipe)));
                    var pipeDisplayRep = (DisplayRepresentation)pipeIds[0].GetObject(OpenMode.ForRead);
                    var pipeDisplayProp = pipeDisplayRep.CreateNewDisplayProperties(); <--If pipeDisplayRep is anything other than "Plan"
                    pipeDisplayProp.SetToStandard(db);
                    pipeDisplayProp.SubSetDatabaseDefaults(db);

                    var sc = new StringCollection();
                    var components = pipeDisplayProp.GetDisplayComponents(out sc); <--components will be an empty array
                    foreach (DisplayComponentEntity component in fittingComponents)
                    {
                        component.Color = Color.FromColorIndex(ColorMethod.ByAci, 1);
                    }



So if anyone can point me in the right direction it would be greatly appreciated.

I don't see where you are adding the override to the Named Objects Dictionary anywhere. You are also missing pipeDisplayProp.SetDisplayRepDefaults()
Title: Re: AutoCAD MEP Display Manager Override
Post by: MexicanCustard on August 08, 2013, 07:55:58 AM
I don't see where you are adding the override to the Named Objects Dictionary anywhere. You are also missing pipeDisplayProp.SetDisplayRepDefaults()

Like I mentioned, all the examples are for Wall types and none of them show adding the Override to the NOD.  I did try calling SetDisplayRepDefaults and if the view is in anything other than "Plan" if wouldn't fill in any of the properties so I removed it from my example.  Can you post an example of how you accomplished this?
Title: Re: AutoCAD MEP Display Manager Override
Post by: Micaletti on August 08, 2013, 01:27:09 PM
The code above uses a catch block *gasp*  ;-) to find the override extension dictionary inside the named objects dictionary, then adds the override to it. I was able translate the example and get it working for schedule table display reps. Just do what they're doing but with a pipe and not a door.
Title: Re: AutoCAD MEP Display Manager Override
Post by: MexicanCustard on August 08, 2013, 03:21:48 PM
The code above uses a catch block *gasp*  ;-) to find the override extension dictionary inside the named objects dictionary, then adds the override to it. I was able translate the example and get it working for schedule table display reps. Just do what they're doing but with a pipe and not a door.

How about your example using a Pipe?
Title: Re: AutoCAD MEP Display Manager Override
Post by: Micaletti on August 08, 2013, 04:51:33 PM
The code above uses a catch block *gasp*  ;-) to find the override extension dictionary inside the named objects dictionary, then adds the override to it. I was able translate the example and get it working for schedule table display reps. Just do what they're doing but with a pipe and not a door.

How about your example using a Pipe?

I suspected SetDisplayRepDefaults was the problem but you're saying it's not so I can't give you an example for a pipe. Can't set the override till you get past this point. I assume you have tried all of the pipeIds? DisplayRepresentationManager.GetAllDisplayRepresentationsWorkForSpecifiedClass?
Title: Re: AutoCAD MEP Display Manager Override
Post by: MexicanCustard on August 09, 2013, 07:11:02 AM
I can't remember if I had tried GetAllDisplayRepresentationsWorkForSpecifiedClass I don't think I did but that was eight months ago.  I'll have to go back and look at my experimental code and see if I can recall exactly what I tried and what I discovered.  I ended up solving the problem using DisplayThemes instead of overriding the individual fitting Display Properties.