Author Topic: eNullObjectPointer  (Read 3225 times)

0 Members and 1 Guest are viewing this topic.

Andrey Bushman

  • Swamp Rat
  • Posts: 864
eNullObjectPointer
« on: July 09, 2016, 08:00:10 AM »
AutoCAD 2009-2016 x64 Enu with all service packs installed.

My users want to have an opportunity to find an entity wich is used by a Field for info reading. But I get the eNullObjectPointer error when I try to do it. Look the attached screens, please.

Code - C#: [Select]
  1. /* ObjSearch
  2.  * Commands.cs
  3.  * © Andrey Bushman, 2016
  4.  *
  5.  * Searching the AutoCAD database entities through their
  6.  * ObjectId values.
  7.  */
  8. using System;
  9. using System.Collections.Generic;
  10. using System.Linq;
  11. using System.Text;
  12.  
  13. using cad = Autodesk.AutoCAD.ApplicationServices.Application;
  14. using Autodesk.AutoCAD.ApplicationServices;
  15. using Autodesk.AutoCAD.DatabaseServices;
  16. using Autodesk.AutoCAD.EditorInput;
  17. using Autodesk.AutoCAD.Runtime;
  18. using Autodesk.AutoCAD.Geometry;
  19.  
  20. [assembly: CommandClass(typeof(Bushman.AutoCAD
  21.     .DatabaseServices.ObjSearch.Commands))]
  22.  
  23. namespace Bushman.AutoCAD.DatabaseServices.ObjSearch {
  24.  
  25.     public sealed class Commands {
  26.  
  27.         const string cmd_group = "bushman";
  28.  
  29.         /// <summary>
  30.         /// Find and zoom the Entity item by its ObjectId value
  31.         /// </summary>
  32.         [CommandMethod(cmd_group, "FindEntity", CommandFlags
  33.             .Modal)]
  34.         public void FindEntity() {
  35.  
  36.             Document doc = cad.DocumentManager
  37.                 .MdiActiveDocument;
  38.  
  39.             if (doc == null) return;
  40.  
  41.             Editor ed = doc.Editor;
  42.             Database db = doc.Database;
  43.  
  44.             using (doc.LockDocument()) {
  45.  
  46.                 /* just in case... */
  47.                 db.UpdateExt(true);
  48.  
  49.                 PromptResult pr = ed.GetString(
  50.                     "\nEnter ObjectId: ");
  51.  
  52.                 if (pr.Status != PromptStatus.OK) return;
  53.  
  54.                 // Convert hexadecimal string to 64-bit integer
  55.                 long ln = Convert.ToInt64(pr.StringResult);
  56.  
  57.                 ObjectId id = StaticMethods.GetEntityIds(db,
  58.                     (n) => n.OldIdPtr.ToInt64() == ln)
  59.                     .FirstOrDefault();
  60.  
  61.                 Extents3d ext;
  62.  
  63.                 using (Transaction tr = db.TransactionManager
  64.                     .StartTransaction()) {
  65.  
  66.                     Entity ent = (Entity) tr.GetObject(id,
  67.                         OpenMode.ForRead);
  68.  
  69.                     ext = ent.GeometricExtents;
  70.  
  71.                     ext.TransformBy(ed
  72.                         .CurrentUserCoordinateSystem.Inverse())
  73.                         ;
  74.  
  75.                     double x = (ext.MaxPoint.X - ext.MinPoint.X
  76.                         ) / 2.0 + ext.MinPoint.X;
  77.  
  78.                     double y = (ext.MaxPoint.Y - ext.MinPoint.Y
  79.                         ) / 2.0 + ext.MinPoint.Y;
  80.  
  81.                     double z = (ext.MaxPoint.Z - ext.MinPoint.Z
  82.                         ) / 2.0 + ext.MinPoint.Z;
  83.  
  84.                     Point3d point = new Point3d(x, y, z);
  85.  
  86.                     ed.WriteMessage("Entity type: {0}\n"
  87.                         , ent.GetType().ToString());
  88.  
  89.                     ed.WriteMessage("Entity coordinates: {0}\n"
  90.                         , point.ToString());
  91.  
  92.                     BlockTableRecord btr = tr.GetObject(
  93.                         ent.BlockId, OpenMode.ForRead) as
  94.                         BlockTableRecord;
  95.  
  96.                     if (btr.IsLayout) {
  97.  
  98.                         Layout layout = tr.GetObject(btr
  99.                             .LayoutId, OpenMode.ForRead) as
  100.                             Layout;
  101.  
  102.                         if (LayoutManager.Current.CurrentLayout
  103.                             != layout.LayoutName) {
  104.  
  105.                             LayoutManager.Current.CurrentLayout
  106.                                 = layout.LayoutName;
  107.                         }
  108.  
  109.                         ed.WriteMessage("The entity is " +
  110.                             "located on the '{0}' layout.\n\n",
  111.                             layout.LayoutName);
  112.  
  113.                         if (!db.TileMode) {
  114.                             /* Main paper space area Viewport
  115.                              * ObjectId.
  116.                              *
  117.                              * # Note: First ObjectId from
  118.                              * GetViewports() is the main paper
  119.                              * space area Viewport ObjectId.*/
  120.                             ObjectId mainPSpaceVportId = layout
  121.                                 .GetViewports()[0];
  122.  
  123.                             /* Create Extents3d based on
  124.                              * BlockTableRecord entities.
  125.                              *
  126.                              * # Note: Exclude main paper space
  127.                              * viewport ObjectId. */
  128.                             Extents3d extents = new Extents3d()
  129.                                 ;
  130.                             foreach (ObjectId _id in btr) {
  131.                                 if (_id != mainPSpaceVportId) {
  132.                                     Entity _ent = tr.GetObject(
  133.                                         _id, OpenMode.ForRead)
  134.                                         as Entity;
  135.  
  136.                                     if (_ent != null) {
  137.                                         try {
  138.                                             /* EXCEPTION:
  139.                                              * Here I get the
  140.                                              * 'eNullExtents'
  141.                                              * errors for
  142.                                              * 'BlockReference'
  143.                                              * instances. */
  144.                                             extents.AddExtents(
  145.                                                 _ent
  146.                                                 .GeometricExtents
  147.                                                 );
  148.                                         }
  149.                                         catch (System.Exception
  150.                                             ex) {
  151.  
  152.                                             ed.WriteMessage(
  153.                                                 "{0} item. " +
  154.                                                 "Error: {1}\n",
  155.                                                 _ent.GetType()
  156.                                                 .ToString(),
  157.                                                 ex.Message);
  158.                                         }
  159.                                     }
  160.                                 }
  161.                             }
  162.                             /* Create Extents3d based on paper
  163.                              * space layout limits. */
  164.                             Extents3d limits = new Extents3d(
  165.                                  new Point3d(layout.Limits
  166.                                      .MinPoint.X, layout.Limits
  167.                                      .MinPoint.Y, 0),
  168.                                      new Point3d(layout.Limits
  169.                                          .MaxPoint.X, layout
  170.                                          .Limits.MaxPoint.Y, 0)
  171.                                          );
  172.  
  173.                             extents.AddExtents(limits);
  174.  
  175.                             // Update Pextmin and Pextmax.
  176.                             db.Pextmin = extents.MinPoint;
  177.                             db.Pextmax = extents.MaxPoint;
  178.                         }
  179.                     }
  180.                     else if (btr.IsAnonymous) {
  181.                         ed.WriteMessage("The entity is located"
  182.                         + " in the '{0}' anonymous block.\n\n",
  183.                             btr.Name);
  184.                     }
  185.                     else if (btr.IsAProxy) {
  186.                         ed.WriteMessage("The entity is located"
  187.                         + " in the '{0}' proxy block.\n\n",
  188.                             btr.Name);
  189.                     }
  190.                     else if (btr.IsDynamicBlock) {
  191.                         ed.WriteMessage("The entity is located"
  192.                         + " in the '{0}' dynamuc block.\n\n",
  193.                             btr.Name);
  194.                     }
  195.  
  196.                     tr.Commit();
  197.                 }
  198.  
  199.                 PrintExtends(db.Extmin, db.Extmax, db.Pextmin,
  200.                     db.Pextmax);
  201.  
  202.                 try {
  203.                     /* EXCEPTION: Here I get the
  204.                      * 'eNullObjectPointer' error.
  205.                      *
  206.                      * I looked these resources also:
  207.                      *
  208.                      * http://adndevblog.typepad.com/autocad/2012/08/incorrect-extmin-extmax-values-for-a-drawing.html
  209.                      *
  210.                      * http://forums.autodesk.com/t5/net/drawing-extents-in-paperspace/m-p/3178638#M25435
  211.                      *
  212.                      * but they didn't help me...
  213.                      */
  214.                     ZoomWin(ed, ext.MinPoint, ext.MaxPoint);
  215.                 }
  216.                 catch (System.Exception ex) {
  217.                     ed.WriteMessage("{0}\n", ex.Message
  218.                         );
  219.                 }
  220.             }
  221.         }
  222.  
  223.         private void PrintExtends(Point3d extmin, Point3d
  224.             extmax, Point3d pextmin, Point3d pextmax) {
  225.  
  226.             Document doc = cad.DocumentManager
  227.                 .MdiActiveDocument;
  228.  
  229.             if (doc == null) return;
  230.  
  231.             Editor ed = cad.DocumentManager.MdiActiveDocument
  232.                 .Editor;
  233.  
  234.             ed.WriteMessage("\nEXTMIN: {0}\n", extmin);
  235.             ed.WriteMessage("EXTMAX: {0}\n\n", extmax);
  236.  
  237.             ed.WriteMessage("PEXTMIN: {0}\n", pextmin);
  238.             ed.WriteMessage("PEXTMAX: {0}\n\n", pextmax);
  239.         }
  240.  
  241.         private static void ZoomWin(Editor ed, Point3d min,
  242.             Point3d max) {
  243.  
  244.             Point2d min2d = new Point2d(min.X, min.Y);
  245.             Point2d max2d = new Point2d(max.X, max.Y);
  246.             ViewTableRecord view = new ViewTableRecord();
  247.  
  248.             view.CenterPoint = min2d + ((max2d - min2d) / 2.0);
  249.             view.Height = max2d.Y - min2d.Y;
  250.             view.Width = max2d.X - min2d.X;
  251.  
  252.             ed.SetCurrentView(view);
  253.         }
  254.     }
  255. }

The problems was marked by 'EXCEPTION:' in code. Attachment contains DWG which shows the problem with eNullObjectPointer. But this file doesn't repeat the eNullExtents errors. I can't attach the original DWG where are both types of errors, sorry... :(

How can I solve the eNullObjectPointer problem?

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: eNullObjectPointer
« Reply #1 on: July 09, 2016, 08:23:44 AM »
Code of the ZoomWin method was copied from here.

Just in case I tried to modify that code - I added the ViewTableRecord instance into the ViewTable

Code - C#: [Select]
  1. private static void ZoomWin(Editor ed, Point3d min,
  2.     Point3d max) {
  3.  
  4.     Point2d min2d = new Point2d(min.X, min.Y);
  5.     Point2d max2d = new Point2d(max.X, max.Y);
  6.  
  7.     Database db = cad.DocumentManager.MdiActiveDocument
  8.         .Database;
  9.  
  10.     using (Transaction tr = db.TransactionManager
  11.         .StartTransaction()) {
  12.  
  13.         ViewTable vt = tr.GetObject(db.ViewTableId,
  14.                 OpenMode.ForWrite) as ViewTable;
  15.  
  16.         ViewTableRecord view = new ViewTableRecord();
  17.  
  18.         view.CenterPoint = min2d + ((max2d - min2d) /
  19.             2.0);
  20.  
  21.         view.Height = max2d.Y - min2d.Y;
  22.         view.Width = max2d.X - min2d.X;
  23.  
  24.         vt.Add(view);
  25.         tr.AddNewlyCreatedDBObject(view, true);
  26.  
  27.         ed.SetCurrentView(view);
  28.  
  29.         tr.Commit();
  30.     }
  31. }

However still I receive eNullObjectPointer error.

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: eNullObjectPointer
« Reply #2 on: July 09, 2016, 10:23:05 AM »
Thank you to Alexander Rivilis. His answer is here.

Atook

  • Swamp Rat
  • Posts: 1029
  • AKA Tim
Re: eNullObjectPointer
« Reply #3 on: July 09, 2016, 12:10:58 PM »
Andrey, I want to thank you for posting good questions, along with the code in question.

I also want to thank you for posting the solutions you come up with so that the thread is useful for others in the future.

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: eNullObjectPointer
« Reply #4 on: July 09, 2016, 02:43:37 PM »
If my questions and their answers will be useful to other people then I'll be glad. :)

Alexander Rivilis

  • Bull Frog
  • Posts: 214
  • Programmer from Kyiv (Ukraine)
Re: eNullObjectPointer
« Reply #5 on: July 10, 2016, 06:08:15 AM »
Code - C#: [Select]
  1. private static void ZoomWin(Editor ed, Point3d min, Point3d max)
  2.     {
  3.      
  4.       Point2d min2d = new Point2d(min.X, min.Y);
  5.       Point2d max2d = new Point2d(max.X, max.Y);
  6.       using (ViewTableRecord view = new ViewTableRecord())
  7.       {
  8.         view.CenterPoint = min2d + ((max2d - min2d) / 2.0);
  9.         view.Height = max2d.Y - min2d.Y;
  10.         view.Width = max2d.X - min2d.X;
  11.         Database db = ed.Document.Database;
  12.         view.IsPaperspaceView =
  13.           (!db.TileMode && db.PaperSpaceVportId == ed.CurrentViewportObjectId);
  14.         ed.SetCurrentView(view);
  15.       }
  16.     }

n.yuan

  • Bull Frog
  • Posts: 348
Re: eNullObjectPointer
« Reply #6 on: July 10, 2016, 09:20:55 AM »
As for eNullExtents exception when trying to get a BlockReference' GeometricExtents (or Bounds) property), see this post:

http://adndevblog.typepad.com/autocad/2012/12/entitygeometricextents-throws-an-exception-enullextents.html

One may call BlockReference.GeometricExtentsBestFit() method instead.

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: eNullObjectPointer
« Reply #7 on: July 10, 2016, 04:19:11 PM »
As for eNullExtents exception when trying to get a BlockReference' GeometricExtents (or Bounds) property), see this post:

http://adndevblog.typepad.com/autocad/2012/12/entitygeometricextents-throws-an-exception-enullextents.html
Thank you for the link.

Hm... Try\catch... This is very bad "solution", because the iteration with a lot of such "as designed" items will takes A LOT of time. For example you can see the result of the try\catch using here (5 min. 36,186 sec. against 0,278 sec.).

In this context the decision (by Marat Mirgaleev) through try\cath seems like an offering to brush teeth through the ass (in my opinion). Yes, it is possible, but to do it through a mouth would be more convenient...

If you have read my code, then for certain you noted that I already use try\catch. However I think that this decision is very bad.

One may call BlockReference.GeometricExtentsBestFit() method instead.
I will try to do it.
« Last Edit: July 11, 2016, 02:56:20 AM by Andrey Bushman »

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: eNullObjectPointer
« Reply #8 on: July 11, 2016, 06:34:32 AM »
Quote from: n.yuan
One may call BlockReference.GeometricExtentsBestFit() method instead.
I've checked. It didn't help. 

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: eNullObjectPointer
« Reply #9 on: July 11, 2016, 07:43:41 AM »
I did the refactoring. It works for me:

Code - C#: [Select]
  1. const string cmd_group = "bushman";
  2.  
  3. /// <summary>
  4. /// Find and zoom the Entity item by its ObjectId value
  5. /// </summary>
  6. [CommandMethod(cmd_group, "FindEntity", CommandFlags
  7.     .Modal)]
  8. public void FindEntity() {
  9.  
  10.     Document doc = cad.DocumentManager
  11.         .MdiActiveDocument;
  12.  
  13.     if (doc == null) return;
  14.  
  15.     Editor ed = doc.Editor;
  16.     Database db = doc.Database;
  17.  
  18.     using (doc.LockDocument()) {
  19.  
  20.         // It takes a lot of time:
  21.         // db.UpdateExt(true);
  22.  
  23.         PromptResult pr = ed.GetString(
  24.             "\nEnter ObjectId: ");
  25.  
  26.         if (pr.Status != PromptStatus.OK) return;
  27.  
  28.         long ln = 0;
  29.  
  30.         try {
  31.             /* Convert hexadecimal string to 64-bit
  32.              * integer */
  33.             ln = Convert.ToInt64(pr.StringResult);
  34.         }
  35.         catch (System.Exception ex) {
  36.             ed.WriteMessage("{0}\n", ex.Message);
  37.             return;
  38.         }
  39.         ObjectId id = new ObjectId(new IntPtr(ln));
  40.  
  41.         Extents3d ext;
  42.  
  43.         using (Transaction tr = db.TransactionManager
  44.             .StartTransaction()) {
  45.  
  46.             Entity ent = (Entity) tr.GetObject(id,
  47.                 OpenMode.ForRead);
  48.  
  49.             ext = ent.GeometricExtents;
  50.  
  51.             ext.TransformBy(ed
  52.                 .CurrentUserCoordinateSystem.Inverse())
  53.                 ;
  54.  
  55.             double x = (ext.MaxPoint.X - ext.MinPoint.X
  56.                 ) / 2.0 + ext.MinPoint.X;
  57.  
  58.             double y = (ext.MaxPoint.Y - ext.MinPoint.Y
  59.                 ) / 2.0 + ext.MinPoint.Y;
  60.  
  61.             double z = (ext.MaxPoint.Z - ext.MinPoint.Z
  62.                 ) / 2.0 + ext.MinPoint.Z;
  63.  
  64.             Point3d point = new Point3d(x, y, z);
  65.  
  66.             ed.WriteMessage("Entity type: {0}\n"
  67.                 , ent.GetType().Name);
  68.  
  69.             ed.WriteMessage("Entity coordinates: {0}\n"
  70.                 , point.ToString());
  71.  
  72.             ed.WriteMessage("Layer: {0}\n", ent.Layer);
  73.  
  74.             LayerTableRecord layer = tr.GetObject(ent
  75.                 .LayerId, OpenMode.ForRead) as
  76.                 LayerTableRecord;
  77.  
  78.             if (layer.IsFrozen) {
  79.                 ed.WriteMessage("Layer is frozen.\n");
  80.             }
  81.  
  82.             if (layer.IsHidden) {
  83.                 ed.WriteMessage("Layer is hidden.\n");
  84.             }
  85.  
  86.             BlockTableRecord btr = tr.GetObject(
  87.                 ent.BlockId, OpenMode.ForRead) as
  88.                 BlockTableRecord;
  89.  
  90.             if (btr.IsLayout) {
  91.  
  92.                 Layout layout = tr.GetObject(btr
  93.                     .LayoutId, OpenMode.ForRead) as
  94.                     Layout;
  95.  
  96.                 if (LayoutManager.Current.CurrentLayout
  97.                     != layout.LayoutName) {
  98.  
  99.                     LayoutManager.Current.CurrentLayout
  100.                         = layout.LayoutName;
  101.                 }
  102.  
  103.                 ed.WriteMessage("The entity is " +
  104.                     "located on the '{0}' layout.\n\n",
  105.                     layout.LayoutName);
  106.             }
  107.             else if (btr.IsAnonymous) {
  108.                 ed.WriteMessage("The entity is located"
  109.                 + " in the '{0}' anonymous block.\n\n",
  110.                     btr.Name);
  111.             }
  112.             else if (btr.IsAProxy) {
  113.                 ed.WriteMessage("The entity is located"
  114.                 + " in the '{0}' proxy block.\n\n",
  115.                     btr.Name);
  116.             }
  117.             else if (btr.IsDynamicBlock) {
  118.                 ed.WriteMessage("The entity is located"
  119.                 + " in the '{0}' dynamuc block.\n\n",
  120.                     btr.Name);
  121.             }
  122.  
  123.             tr.Commit();
  124.         }
  125.  
  126.         try {
  127.             ZoomWin(ed, ext.MinPoint, ext.MaxPoint);
  128.         }
  129.         catch (System.Exception ex) {
  130.             ed.WriteMessage("{0}\n", ex.Message
  131.                 );
  132.         }
  133.     }
  134. }
  135.  
  136. private static void ZoomWin(Editor ed, Point3d min,
  137.     Point3d max) {
  138.  
  139.     Point2d min2d = new Point2d(min.X, min.Y);
  140.     Point2d max2d = new Point2d(max.X, max.Y);
  141.  
  142.     using (ViewTableRecord view = new ViewTableRecord()
  143.         ) {
  144.         view.CenterPoint = min2d + ((max2d - min2d) /
  145.             2.0);
  146.         view.Height = max2d.Y - min2d.Y;
  147.         view.Width = max2d.X - min2d.X;
  148.  
  149.         Database db = ed.Document.Database;
  150.  
  151.         view.IsPaperspaceView =
  152.           (!db.TileMode && db.PaperSpaceVportId == ed
  153.           .CurrentViewportObjectId);
  154.  
  155.         ed.SetCurrentView(view);
  156.     }
  157. }