Author Topic: Teigha eNotOpenForRead  (Read 4710 times)

0 Members and 1 Guest are viewing this topic.

lup

  • Guest
Teigha eNotOpenForRead
« on: May 20, 2016, 04:22:04 AM »
Hi there,

I'm currently translating an autocad plug-in for bricscad v16 and have a problem to access DBObject properties now.
the method transaction.GetObject returns a object, but on printing .handle the error eNotOpenForRead appears.
in autocad it works fine.
i have no idea, whats wrong.
im using Bricsys SDK v15.

Code - C#: [Select]
  1. Document document = Bricscad.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  2. Database database = document.Database;
  3. DBObject autoCadDatabaseObject = null;
  4. using (Transaction transaction = database.TransactionManager.StartTransaction())
  5. {
  6.         using (DocumentLock documentLock = document.LockDocument())
  7.         {
  8.                 autoCadDatabaseObject = transaction.GetObject(pObjectId, OpenMode.ForRead);
  9.                 transaction.Commit();
  10.                 if (autoCadDatabaseObject == null)
  11.                 {
  12.                         logger.Debug("object is null");
  13.                 }else{
  14.                         logger.Debug("object is not null: " + autoCadDatabaseObject.GetType().ToString()); // works fine
  15.                         logger.Debug("the handle: " + autoCadDatabaseObject.Handle.ToString()); // Teigha.Runtime.Exception: eNotOpenForRead at Teigha.DatabaseServices.DBObject.get_Handle()
  16.                 }
  17.         }
  18. }
  19.  


Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: Teigha eNotOpenForRead
« Reply #1 on: May 20, 2016, 04:38:47 AM »
The `transaction.Commit();` are to be the last code string in your Transaction's `using` block in my opinion.

lup

  • Guest
Re: Teigha eNotOpenForRead
« Reply #2 on: May 20, 2016, 05:32:01 AM »
Many thanks for your answer. That brought me one step further.
But why is the access to the properties only within the transaction possible?
I have a method "GetAutoCadDBObjectByObjectId " which works fine with autocad.
Do I really need to refactor my code now?

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: Teigha eNotOpenForRead
« Reply #3 on: May 20, 2016, 05:59:23 AM »
If you are getting the object through the transaction mechanism, then you are to work with it within the transaction scope before transaction will be canseled or commited. But you can to get the object without transaction or through transaction emulation.

Some info about it you can read here (there is russian text, but you can read source sode):
http://bushman-andrey.blogspot.ru/2013/01/database-autocad.html
http://bushman-andrey.blogspot.ru/2014/09/blog-post.html

Bryco

  • Water Moccasin
  • Posts: 1883
Re: Teigha eNotOpenForRead
« Reply #4 on: May 20, 2016, 07:25:11 PM »
Does     pObjectId.Handle.ToString();   print without any transaction? (May still need the doc lock)

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: Teigha eNotOpenForRead
« Reply #5 on: May 21, 2016, 03:04:40 AM »
Does     pObjectId.Handle.ToString();   print without any transaction? (May still need the doc lock)

Quote from: ObjectARX 2016 SDK documentation
AcApDocManager::lockDocument

This function is used for locking documents in order to access their resources. Resources include all AcDbDatabases objects associated with a document, and AcDbObject objects in those databases, and all AcDbDatabase resident system variables. It also includes all document based system variables, and the Transaction Manager associated with a document. The document does not need to be locked to open an AcDbObject in AcDb::kForRead, nor to get system variables.

Applications should normally never have to lock or unlock the current document. Commands registered with addCommand() or aceddefun() will have the current document locked before starting, and unlocked after ending. This can be controlled using the addCommand() function tags.

Note
The kForRead mode is an exclusive read.

Returns:
Acad::eOk if the lock change was successful.

Acad::eLockChangeInProgress if an attempt to lock a document is made from the document lock change reactor callback. You cannot "nest" locking requests.

Acad::eVetoed if the lock change is vetoed by another application.

Acad::eNoDocument if pDoc is NULL.

So, in my opinion, at this case the document locking is not necessary.

lup

  • Guest
Re: Teigha eNotOpenForRead
« Reply #6 on: May 23, 2016, 07:39:20 AM »
@Andrey Bushman: thanks for your posts but I realize it's just not .
I want to create a hatch ( works ) and also removed it again.
I would like to cache the hatch in a member variable.
when access to the membervaribale in the delete method I get the error message.
can you tell me what am I doing wrong? (in acad it still works fine.)

Code - C#: [Select]
  1. public partial class myClass
  2. {
  3.         private Hatch _hatch = null;
  4.        
  5.         private void AddNewHighlightingHatch()
  6.     {
  7.                
  8.                 // works
  9.                 Document document = Bricscad.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  10.                 Database database = document.Database;
  11.                 Editor editor = document.Editor;
  12.  
  13.                 if (_hatch == null)
  14.                 {
  15.                        
  16.                         ObjectId selectedObjectId = AutoCADController.GetObjectIdByHandle(currentItemProperty.AutoCADHandle);
  17.                        
  18.                         _hatch = new Hatch();
  19.                         _hatch.SetHatchPattern(HatchPatternType.PreDefined, "SOLID");
  20.                         _hatch.ColorIndex = AutoCADController.MyColorIndex;
  21.                         _hatch.Associative = true;
  22.                         _hatch.Transparency = new Transparency(127);
  23.                         _hatch.EvaluateHatch(true);
  24.  
  25.                         using (DocumentLock documentLock = document.LockDocument())
  26.                         {
  27.                                 database.Fillmode = true;
  28.  
  29.                                 using (Transaction transaction = database.TransactionManager.StartTransaction())
  30.                                 {
  31.                                         BlockTable blockTable;
  32.                                         blockTable = transaction.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable;
  33.  
  34.                                         BlockTableRecord blockTableRecord;
  35.                                         blockTableRecord = transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord;
  36.  
  37.                                         using (ObjectIdCollection objectIdCollection = new ObjectIdCollection())
  38.                                         {
  39.                                                 objectIdCollection.Add(selectedObjectId);
  40.  
  41.                                                 // Create the hatch object and append it to the block table record
  42.                                                 blockTableRecord.AppendEntity(_hatch);
  43.  
  44.                                                 _hatch.AppendLoop(HatchLoopTypes.Outermost, objectIdCollection);
  45.                                                 transaction.AddNewlyCreatedDBObject(_hatch, true);
  46.                                                 editor.Regen();
  47.                                         }
  48.                                         transaction.Commit();
  49.                                 }
  50.                         }
  51.                 }
  52.         }
  53.        
  54.         private void DeleteOldHighlightingHatch()
  55.         {
  56.                 try
  57.                 {
  58.                         Document document = Bricscad.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
  59.                         Database database = document.Database;
  60.                         Editor editor = document.Editor;
  61.  
  62.                         if (_hatch != null)
  63.                         {
  64.                                
  65.                                 //hatch is not null - it should be cached by AddNewHighlightingHatch
  66.                                
  67.                                 database.Fillmode = true;
  68.                                 using (DocumentLock documentLock = document.LockDocument())
  69.                                 {
  70.                                         using (Transaction transaction = database.TransactionManager.StartTransaction())
  71.                                         {
  72.                                                 logger.Debug("using transaction");
  73.                                                 BlockTable blockTable;
  74.                                                 blockTable = transaction.GetObject(database.BlockTableId, OpenMode.ForRead) as BlockTable;
  75.  
  76.                                                 using (BlockTableRecord blockTableRecord = transaction.GetObject(blockTable[BlockTableRecord.ModelSpace], OpenMode.ForWrite) as BlockTableRecord)
  77.                                                 {
  78.                                                         logger.Debug("_hatch.ObjectId.Handle: " + _hatch.ObjectId.Handle); //Exception eNotOpenForRead
  79.                                                         _hatch = null;
  80.                                                         editor.Regen();
  81.  
  82.                                                 }
  83.                                                 logger.Debug("transaction.Commit();");
  84.                                                 transaction.Commit();
  85.                                         }
  86.                                 }
  87.                         }
  88.                 }
  89.                 catch (Exception ex)
  90.                 {
  91.                         logger.Error(ex.Message + "\n" + ex.StackTrace);
  92.                 }
  93.         }
  94. }
  95.  

lup

  • Guest
Re: Teigha eNotOpenForRead
« Reply #7 on: May 24, 2016, 02:58:08 AM »
i found a similar post BricsCAD returning BlockReference
Quote
BricsCAD is indeed reacting different. Your ReturnBlockRef is empty or not available after the Commit.

ObjectId is the best option to return.

now im going to refactor all the code.  :sniffles:

Andrey Bushman

  • Swamp Rat
  • Posts: 864
Re: Teigha eNotOpenForRead
« Reply #8 on: May 24, 2016, 04:38:14 AM »
ObjectId is the best option to return.
It is true for AutoCAD too, not only for the Teigha-based applications.

Atook

  • Swamp Rat
  • Posts: 1029
  • AKA Tim
Re: Teigha eNotOpenForRead
« Reply #9 on: May 24, 2016, 12:17:33 PM »
now im going to refactor ALL the code.  :sniffles:

Story of my life friend, thanks for the laugh!  :2funny:

lup

  • Guest
Re: Teigha eNotOpenForRead
« Reply #10 on: May 24, 2016, 11:50:23 PM »
Well, it's just a tiny sample of a bigger application. I'm pretty new in acad/bcad plugins and still have a lot to learn. :-)