Author Topic: (entprev)  (Read 55604 times)

0 Members and 1 Guest are viewing this topic.

LE3

  • Guest
Re: (entprev)
« Reply #60 on: November 26, 2013, 01:13:38 PM »
Hi Marco,
Tried your latest function and works.

Can you test the latest entPreviousFrom function? and also maybe do a benchmark?

Have not added the part for selection of nested objects inside of blocks.

Here it is the updated function - source code:
Code: [Select]
static int ads_entpreviousFrom(void)
{
struct resbuf *rb = acedGetArgs();
if (!rb)
{
acutPrintf(_T("\nError: function requires an ENAME argument. \n"));
return RSERR;
}
AcDbObjectId objId;
ads_name objName;
if (rb && (rb->restype == RTENAME))
{
if (acdbGetObjectId(objId, rb->resval.rlname) == Acad::eOk)
{
AcDbObjectPointer<AcDbEntity> pObj(objId, AcDb::kForRead);
if (pObj.openStatus() == Acad::eOk)
{
if (pObj->isKindOf(AcDb2dVertex::desc()))
{
AcDbObjectPointer<AcDb2dPolyline> pPline(pObj->ownerId(), AcDb::kForRead);
if (pPline.openStatus() == Acad::eOk)
{
AcDbObjectIterator* pVertIterator = pPline->vertexIterator();
pVertIterator->setPosition(pObj);
pVertIterator->start(true);
pVertIterator->step(true);
AcDbObjectPointer<AcDb2dVertex> pVertex(pVertIterator->objectId(), AcDb::kForRead);
if (pVertex.openStatus() == Acad::eOk)
{
if (acdbGetAdsName(objName, objId) == Acad::eOk)
{
acedRetName(objName, RTENAME); // return the previous entity
}
}
delete pVertIterator;
}
}
else
{
AcDbBlockTableRecordPointer pBTR(acdbCurDwg()->currentSpaceId(), AcDb::kForRead); //pObj->ownerId()
if (pBTR.openStatus() == Acad::eOk)
{
AcDbBlockTableRecordIterator* pIterator = NULL;
if (pBTR->newIterator(pIterator) == Acad::eOk)
{
AcDbEntity* pEnt = NULL;
if (pIterator->seek(pObj) == Acad::eOk) // if found from ename
{
pIterator->step(false, true); // step back
AcDbObjectId objId;
pIterator->getEntityId(objId);
AcDbObjectPointer<AcDbEntity> pEnt(objId, AcDb::kForRead);
if (pEnt.openStatus() == Acad::eOk)
{
if (acdbGetAdsName(objName, objId) == Acad::eOk)
{
acedRetName(objName, RTENAME); // return the previous entity
}
}
}
delete pIterator;
}
}
}
}
}
}
return (RSRSLT);
}

Thanks.
« Last Edit: November 26, 2013, 01:18:47 PM by LE »

VovKa

  • Water Moccasin
  • Posts: 1626
  • Ukraine
Re: (entprev)
« Reply #61 on: November 26, 2013, 01:27:24 PM »
...
Marc'Antonio, why do you use (ssget "_X")?
Try to bench with my sample DWG, I think it is faster because you do not need
to pass all nested entities.
but entnext doesn't step into nested objects

Lee Mac

  • Seagull
  • Posts: 12906
  • London, England
Re: (entprev)
« Reply #62 on: November 26, 2013, 01:37:25 PM »
but entnext doesn't step into nested objects

By 'nested', I think Marc is referring to Attributes & Vertices in this case.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: (entprev)
« Reply #63 on: November 26, 2013, 01:45:21 PM »
but entnext doesn't step into nested objects

By 'nested', I think Marc is referring to Attributes & Vertices in this case.
@Lee: Yes, thanks for your clarification.

@VovKa: the last version do not work on "normal" entities...

@Louis: I have tested your version, it seem works but I can not do do a benchmark, I need a version that accept argument. Also I think it is difficult to compare Lisp and ARX at the same time.


VovKa

  • Water Moccasin
  • Posts: 1626
  • Ukraine
Re: (entprev)
« Reply #64 on: November 26, 2013, 01:50:15 PM »
but entnext doesn't step into nested objects

By 'nested', I think Marc is referring to Attributes & Vertices in this case.
now i see, thanks. but in this case (entnext (entprev e)) will not be equal to e
and more (ssget "_X") will iterate through all entities on all layouts

LE3

  • Guest
Re: (entprev)
« Reply #65 on: November 26, 2013, 01:52:57 PM »
Marco.-

The entPreviousFrom it is an autolisp function and accepts one argument - what do you mean by that accept argument?.

Where: <ename> normal or nested
Usage: (entPreviousFrom <ename>)

VovKa

  • Water Moccasin
  • Posts: 1626
  • Ukraine
Re: (entprev)
« Reply #66 on: November 26, 2013, 01:53:17 PM »
@VovKa: the last version do not work on "normal" entities...
yep, thank you
i've fixed it, reverse was missing

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: (entprev)
« Reply #67 on: November 26, 2013, 02:47:46 PM »
...
now i see, thanks. but in this case (entnext (entprev e)) will not be equal to e
and more (ssget "_X") will iterate through all entities on all layouts
(ssget "_X")  make a selection of all entities in all layout:

Command: (setq kkkk (ssget "_X"))
<Selection set: b2>

Command: M
MOVE
Select objects: !kkkk
<Selection set: b2>
2396 found
2395 were not in current space.
1 was the paper space viewport.

VovKa

  • Water Moccasin
  • Posts: 1626
  • Ukraine
Re: (entprev)
« Reply #68 on: November 26, 2013, 03:07:50 PM »
Command: (setq kkkk (ssget "_X"))
<Selection set: b2>
Code: [Select]
(sslength kkkk)

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: (entprev)
« Reply #69 on: November 26, 2013, 03:08:34 PM »
Marco.-

The entPreviousFrom it is an autolisp function and accepts one argument - what do you mean by that accept argument?.

Where: <ename> normal or nested
Usage: (entPreviousFrom <ename>)
OK Louis, I'm sorry I did not realize... read below...

Code: [Select]
Benchmark.lsp | © 2005 Michael Puckett | All Rights Reserved

>>> from "nested" entity
Elapsed milliseconds / relative speed for 16384 iteration(s):
    (ALE_ENTPREVIOUS KKKK).....1451 / 1.27 <fastest>
    (entpreviousfrom KKKK).....1841 / 1 <slowest>

>>> from "nested" entity
Elapsed milliseconds / relative speed for 16384 iteration(s):
    (entpreviousfrom KKKK).....2418 / 1.18 <fastest>
    (ALE_ENTPREVIOUS KKKK).....2855 / 1 <slowest>

>>> from "nested" entity
Elapsed milliseconds / relative speed for 16384 iteration(s):
    (entpreviousfrom KKKK).....1077 / 1.26 <fastest>
    (ALE_ENTPREVIOUS KKKK).....1357 / 1 <slowest>


>>> from "normal" entity
Elapsed milliseconds / relative speed for 16384 iteration(s):
    (entpreviousfrom KKKK).......1794 / 64.37 <fastest>
    (ALE_ENTPREVIOUS KKKK).....115487 / 1 <slowest>


But from "normal" entity I get wrong results

(defun c:TestL ( / EntRef EntPrv)
(setq EntRef (car (nentsel)))
(princ "\nEntRef         ") (princ EntRef)
(princ "\nentPreviousFrom") (princ (entnext (setq EntPrv (entPreviousFrom EntRef))))
(princ "\nALE_EntPrevious") (princ (entnext (setq EntPrv (ALE_EntPrevious EntRef))))
(princ "\n")
(textpage)(princ)
)

Select object:
EntRef         <Entity name: 7ffffb40240>
entPreviousFrom<Entity name: 7ffffb401f0>
ALE_EntPrevious<Entity name: 7ffffb40240>

Command:  TESTL

Select object:
EntRef         <Entity name: 7ffffb06c00>
entPreviousFrom<Entity name: 7ffffb06c00>
ALE_EntPrevious<Entity name: 7ffffb06c00>

Command:  TESTL

Select object:
EntRef         <Entity name: 7ffffb06bf0>
entPreviousFrom<Entity name: 7ffffb06ae0>
ALE_EntPrevious<Entity name: 7ffffb06bf0>


LE3

  • Guest
Re: (entprev)
« Reply #71 on: November 26, 2013, 03:23:24 PM »
Hi Marco,
Thank you a lot for taking the time to run the tests and doing the benchmarking.... for me I guess it is all about my contribution on this thread, was fun but I do not use autolisp nor I work with objectarx anymore or even use AutoCAD nowadays. My sample code is there open, so anyone can use it and update it and make it better!!!.

Have fun!
 :-)

VovKa

  • Water Moccasin
  • Posts: 1626
  • Ukraine
Re: (entprev)
« Reply #72 on: November 26, 2013, 04:49:19 PM »
Command: (sslength kkkk)
2396
(ssget "_X") returns entities in the following order:
EntitiesOnLayout1+EntitiesOnLayout2...+...EntitiesOnLayoutN+EntitiesInModelSpace
so if are looking for an entity that is in the model space you will iterate through all layout entities first

irneb

  • Water Moccasin
  • Posts: 1794
  • ACad R9-2016, Revit Arch 6-2016
Re: (entprev)
« Reply #73 on: November 27, 2013, 12:09:38 AM »
so if are looking for an entity that is in the model space you will iterate through all layout entities first
I think we might be talking in circles. The OP was about a function which operates in reverse from what entnext does.

So:
  • If supplied argument = nil (unfortunately ALisp doesn't allow for optional arguments in defuns), then get entlast (instead of the 1st entity in the DWG)
  • If supplied argument is an ename of an enetity contained either in the Model Space or any Paper Space then get the previous entity
    • That could be a joined entity like an attribute, not to be confused with nested entities like lines inside blocks.
    • Note entnext runs along all entities in MS/PS1/PS2 ... PSn as if they're all contained in one group (not each separately).
  • If the argument is an entity nested inside a complex entity like a block definition, then get the previous entity inside that block - stop at the block record itself.
Common sense - the curse in disguise. Because if you have it, you have to live with those that don't.

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: (entprev)
« Reply #74 on: November 27, 2013, 04:00:23 AM »
Command: (sslength kkkk)
2396
(ssget "_X") returns entities in the following order:
EntitiesOnLayout1+EntitiesOnLayout2...+...EntitiesOnLayoutN+EntitiesInModelSpace
so if are looking for an entity that is in the model space you will iterate through all layout entities first
Try my new test DWG and put a counter inside your function:
Code: [Select]
; Version 3.02_Test - 2013/11/27 - no DXF function
(defun ALE_EntPrevious_Test (EntNam / SelSet EntDat Countr SsLngt EntOut PrnEnt PrnDat TrueFl)
  (setq Countr 0);test
  (if
    (and
      (setq EntDat (entget EntNam))
      (setq TrueFl
        (=
          "BLOCK_RECORD"
          (cdr (assoc 0 (setq PrnDat (entget (setq PrnEnt (cdr (assoc 330 EntDat)))))))
        )
      )
      (assoc 410 EntDat)
    )
    (progn
      (setq SelSet (ssget "_X")   Countr 0   SsLngt (sslength SelSet))
      (while (> SsLngt Countr)
        (if (eq EntNam (ssname SelSet Countr)) (setq SsLngt 0) (setq Countr (1+ Countr)))
      )
      (setq EntOut (ssname SelSet (1+ Countr))  PrnEnt EntOut)
    )
    (setq EntOut (if TrueFl (cdr (assoc 360 PrnDat)) PrnEnt))
  )
  (while (and EntOut (not (eq EntNam (setq PrnEnt (entnext EntOut)))))
    (setq EntOut PrnEnt   Countr (1+ Countr));test
;   (setq EntOut PrnEnt)
  )
  (list EntOut Countr);test
; EntOut
)

(defun c:Test ( / EntRef EntPrv)
  (setq EntRef (car (nentsel)))
  (princ "\nEntRef              ") (princ EntRef)
  (princ "\nALE_EntPrevious_Test") (princ (entnext (car (setq EntPrv (ALE_EntPrevious_Test EntRef)))))
  (princ "  ")(princ (cadr EntPrv))
  (princ "\nVK_entprev1         ") (princ (entnext (car (setq EntPrv (VK_entprev1     EntRef)))))
  (princ "  ")(princ (cadr EntPrv))
  (textpage)(princ)
)

My DWG:
4228 total entities
1414 Model
1406 Layout L1
1406 Layout L2

Code: [Select]
Select the red line on magenta rectangle, is the (entlast) in model space,
results:

Selezionare oggetto:
EntRef              <Nome entità: 7ffffb61930>
ALE_EntPrevious_Test<Nome entità: 7ffffb61930>  2814
VK_entprev1         <Nome entità: 7ffffb61930>  12515