2

I’m not sure when open entities for read is necessary, and when it may be omit. For example I know I don’t need to open entity when I want to use objectId() but there are some methods which require to open entity before. I don’t know if it’s necessary to open AcDbPolyline before getArcSegAt(). In many cases I can simple try to use method before it’s open I will get what I want or not. But maybe there is some easy rule for that?

Example:

AcDbObjectId id = somethingNotImportant();
AcDbPolyline* _pPoly = NULL;
if (id.isValid())
{
    AcDbEntity* pEnt = NULL;
    Acad::ErrorStatus es;
    es = acdbOpenObject(pEnt, id, AcDb::kForRead);
    if( es == Acad::eOk)
    {
        if(pEnt->isKindOf(AcDbPolyline::desc()))
        {
            this->_pPoly = AcDbPolyline::cast(pEnt);
        }
        es = pEnt->close();
    }
}   

now _pPoly is initiallized , but it is closed because of pEnt->close(); now I want for example use:

AcGePoint3d Px = initializedSomehow();
double distAtPx = 0;
_pPoly->getDistAtPoint(Px , distAtPx);

do I need to :

es = acdbOpenObject(_pPoly, id, AcDb::kForRead);

before:

_pPoly->getDistAtPoint(Px , distAtPx);
crashmstr
  • 28,043
  • 9
  • 61
  • 79
CAD Developer
  • 1,532
  • 2
  • 21
  • 27
  • it's not clear what you mean by "use before open"... you'll need to call open with the ID to instantiate the C++ pointer, so you're opening the entity. I would suggest to avoid open for write unless really needed (as this consume more resources). – Augusto Goncalves Oct 25 '16 at 11:05
  • Please put an example where did you get AcDbPolyline* from without opening corresponding DB-resident entity? – Dmitriy Zapevalov Oct 25 '16 at 11:56

2 Answers2

1

I would consider it good practise to use the appropriate read access on your object first. That way you are guaranteed to know if you are only able to read the entity or also write to the entity.

This way you are in control. If you just go ahead and use the entity you have no way of knowing in the underlying library changes it's default behaviour.

Sorry if this does not answer your question.

Andrew Truckle
  • 17,769
  • 16
  • 66
  • 164
1

I've looked in the documentation, and I'm not seeing anything that indicates anything about being able to use methods on a closed object. I expect that the assumption is that to work with any real AutoCAD data requires the object to be open for at least reading.

In that case, there are two ways to improve upon your example.

First option: do the work before closing the object. This keeps the open/close code all together with the work being done in the middle. This is nice that it should be clear when the object is open and can be worked with and that the object is not left open. This also meets the recommendation in the documentation to not keep object open any longer than necessary.

AcGePoint3d Px = initializedSomehow();
double distAtPx = 0;
AcDbObjectId id = somethingNotImportant();
if (id.isValid())
{
    AcDbEntity* pEnt = NULL;
    Acad::ErrorStatus es;
    es = acdbOpenObject(pEnt, id, AcDb::kForRead);
    if( es == Acad::eOk)
    {
        if(pEnt->isKindOf(AcDbPolyline::desc()))
        {
            AcDbPolyline*_pPoly = AcDbPolyline::cast(pEnt);
            //Do work with poly here
            _pPoly->getDistAtPoint(Px , distAtPx);
        }
        es = pEnt->close();
    }
}

Second option: close the object only after doing the work, and only if the object is the right type. This allows for non-local usage of the opened object, but you need to make sure you close it later!

AcDbObjectId id = somethingNotImportant();
AcDbPolyline* _pPoly = NULL;
if (id.isValid())
{
    AcDbEntity* pEnt = NULL;
    Acad::ErrorStatus es;
    es = acdbOpenObject(pEnt, id, AcDb::kForRead);
    if( es == Acad::eOk)
    {
        if(pEnt->isKindOf(AcDbPolyline::desc()))
        {
            _pPoly = AcDbPolyline::cast(pEnt);
        }
        else
            es = pEnt->close(); //not polyline, close now
    }
}
AcGePoint3d Px = initializedSomehow();
double distAtPx = 0;
if (_pPoly)
{
    //Do work with poly here
    _pPoly->getDistAtPoint(Px , distAtPx);
    _pPoly->close();
}
crashmstr
  • 28,043
  • 9
  • 61
  • 79
  • The first way is the way I use. But there are some methods which not need to open entity, like objectId or isKindof , so I wonder which else not need to open – CAD Developer Nov 02 '16 at 17:52
  • Your example above closes then uses the object later. My first example shows doing the work before closing the object. My second example works like your example, but keeps the object open until it is used later. I don't know if any documentation shows it, but I would think you need the object open for most operations. – crashmstr Nov 02 '16 at 17:58