Author Topic: (entprev)  (Read 56515 times)

0 Members and 1 Guest are viewing this topic.

ribarm

  • Gator
  • Posts: 3265
  • Marko Ribar, architect
Re: (entprev)
« Reply #90 on: November 27, 2013, 11:29:04 AM »
...
So, please when benchmarking, take this code in consideration among others that are correct (I don't know much ab. arx and other languages)...

OP, M.R.
Remember that the code in VovKa-MR-entprev do not work if you select
a block (not the attribs).

Marc'Antonio, can you elaborate that... If I pick normal block in DWG made of normal blocks, it returns previous block of picked one... If I pick attributed block in DWG made of attributed blocks, it returns SEQUEND entity, and that is exactly previous entity of picked one - that is correct...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: (entprev)
« Reply #91 on: November 27, 2013, 11:40:03 AM »
Marc'Antonio, can you elaborate that... If I pick normal block in DWG made of normal blocks, it returns previous block of picked one... If I pick attributed block in DWG made of attributed blocks, it returns SEQUEND entity, and that is exactly previous entity of picked one - that is correct...
Try with "Nentsel":
(entnext (VovKa-MR-entprev (car (nentsel))))

ribarm

  • Gator
  • Posts: 3265
  • Marko Ribar, architect
Re: (entprev)
« Reply #92 on: November 27, 2013, 12:09:24 PM »
Try with "Nentsel":
(entnext (VovKa-MR-entprev (car (nentsel))))

Thats not the point... (entnext) won't work with (car (nentsel))... The function (entprev) should perform exactly the opposite than (entnext)... So (VovKa-MR-entprev) is correct function...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: (entprev)
« Reply #93 on: November 27, 2013, 12:11:54 PM »
This is related to the use of "assoc 360" (my function and VovKa's),  I found a problem with Bricscad:
Code: [Select]
(defun c:TestDxf360 ( / EntNam EntDat PrnEnt PrnDat)
  (setq EntNam (car (nentsel))) ;select a block (not attribs)
  (setq EntDat (entget EntNam))
  (setq PrnEnt (cdr (assoc 330 EntDat)))
  (setq PrnDat (entget (setq PrnEnt (cdr (assoc 330 EntDat)))))
  (princ "\n ")
  (entget (cdr (assoc 360 prndat)))
)
Code: [Select]
;   >>>>>>>>>>>>>>>>>>  Bricscad V14  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Seleziona entità:
;
; ----- LISP : Call Stack -----
; [0]...C:TESTDXF360 <<--
;
; ----- Error around expression -----
(ASSOC 360 PRNDAT)
;
; error : bad argument type <NIL> ; expected ENTITYNAME at [ENTGET]
;   >>>>>>>>>>>>>>>>>>  Bricscad V14  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Code: [Select]
;   >>>>>>>>>>>>>>>>>>  AutoCAD 2013  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
Selezionare oggetto:
 ((-1 . <Nome entità: 7ffffb579c0>) (0 . "BLOCK") (330 . <Nome entità: 7ffffb57990>) (5 . "AFEC") (100 . "AcDbEntity") (67 . 0) (8 . "0") (100 . "AcDbBlockBegin") (70 . 0) (10 0.0 0.0 0.0) (-2 . <Nome entità: 7ffffb579a0>) (2 . "ASSO010L") (1 . ""))
;   >>>>>>>>>>>>>>>>>>  AutoCAD 2013  <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<

VovKa

  • Water Moccasin
  • Posts: 1629
  • Ukraine
Re: (entprev)
« Reply #94 on: November 27, 2013, 12:24:28 PM »
Try with "Nentsel":
(entnext (VovKa-MR-entprev (car (nentsel))))

Thats not the point... (entnext) won't work with (car (nentsel))... The function (entprev) should perform exactly the opposite than (entnext)... So (VovKa-MR-entprev) is correct function...
Marko, entnext works with nentsel
anyway i suggest using this variant http://www.theswamp.org/index.php?topic=45732.msg508956#msg508956
it's faster and works within nested objects if the argument supplied is a part of a complex entity
« Last Edit: November 27, 2013, 12:38:05 PM by VovKa »

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: (entprev)
« Reply #95 on: November 27, 2013, 12:27:52 PM »
Try with "Nentsel":
(entnext (VovKa-MR-entprev (car (nentsel))))

Thats not the point... (entnext) won't work with (car (nentsel))... The function (entprev) should perform exactly the opposite than (entnext)... So (VovKa-MR-entprev) is correct function...
Hummm...
Try with my last DWG posted (without nentsel):
Comando: (VovKa-MR-entprev (handent "4D3F"))
nil

Comando: (handent "4D3F")
<Nome entità: 7ffffbc9770>

Comando: (ALE_EntPrevious (handent "4D3F"))
(<Nome entità: 7ffffbc9760>

Comando: (entnext (ALE_EntPrevious (handent "4D3F")))
<Nome entità: 7ffffbc9770>

Marc'Antonio Alessi

  • Swamp Rat
  • Posts: 1451
  • Marco
Re: (entprev)
« Reply #96 on: November 27, 2013, 12:36:08 PM »
...
anyway i suggest using this variant http://www.theswamp.org/index.php?topic=45732.msg508956#msg508956
it's faster and works within nested objects if the argument supplied is a part of a complex entity

>>>    e1 (cdr    (cond ((assoc 360 (reverse e1)))

Yes, now it works.

Ciao.

ribarm

  • Gator
  • Posts: 3265
  • Marko Ribar, architect
Re: (entprev)
« Reply #97 on: November 27, 2013, 12:38:51 PM »
Marko, entnext works with nentsel
anyway i suggest using this variant http://www.theswamp.org/index.php?topic=45732.msg508956#msg508956
it's faster and works within nested objects if the argument supplied is a part of a complex entity

Yes, it seems that you're right again... My apology... But what can we do ab (entprev)... Regularly (entnext <block entity>) won't step inside that <block entity> and find very next nested entity... Only if (entnext <nested entity>) if will find next nested entity...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

VovKa

  • Water Moccasin
  • Posts: 1629
  • Ukraine
Re: (entprev)
« Reply #98 on: November 27, 2013, 12:48:00 PM »
Regularly (entnext <block entity>) won't step inside that <block entity> and find very next nested entity... Only if (entnext <nested entity>) if will find next nested entity...
entprev works the same way
the main condition for entprev function is (eq (entnext (entprev e)) e)

LE3

  • Guest
Re: (entprev)
« Reply #99 on: November 27, 2013, 12:59:34 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!
 :)
Grazie a te, spero di ritrovarti ancora.
Gracias a ti, espero encontrarte de nuevo.  :kewl:
Grazie Marco, so che sarà difficile non partecipare...

OK I have to fix my code, here it is again - I did not tested a lot, but appears to work, on the vertexes iterator, you cannot set the position of the iterator using an entity for database-resident we need to use the vertex selected objectId, also now it will use the ownerId of the selected object instead of the currentSpaceId:
Code - C++: [Select]
  1. static int ads_entpreviousFrom(void)
  2. {
  3.         struct resbuf *rb = acedGetArgs();
  4.         if (!rb)
  5.         {
  6.                 acutPrintf(_T("\nError: function requires an ENAME argument. \n"));
  7.                 return RSERR;
  8.         }
  9.         AcDbObjectId objId;
  10.         ads_name objName;
  11.         if (rb && (rb->restype == RTENAME))
  12.         {
  13.                 if (acdbGetObjectId(objId, rb->resval.rlname) == Acad::eOk)
  14.                 {
  15.                         AcDbObjectPointer<AcDbEntity> pObj(objId, AcDb::kForRead);
  16.                         if (pObj.openStatus() == Acad::eOk)
  17.                         {
  18.                                 if (pObj->isKindOf(AcDb2dVertex::desc()))
  19.                                 {
  20.                                         AcDbObjectPointer<AcDb2dPolyline> pPline(pObj->ownerId(), AcDb::kForRead);
  21.                                         if (pPline.openStatus() == Acad::eOk)
  22.                                         {
  23.                                                 AcDbObjectIterator* pVertIterator = pPline->vertexIterator();
  24.                                                 pVertIterator->start();
  25.                                                 pVertIterator->setPosition(pObj->objectId());
  26.                                                 pVertIterator->step(true);
  27.                                                 AcDbObjectPointer<AcDb2dVertex> pVertex(pVertIterator->objectId(), AcDb::kForRead);
  28.                                                 if (pVertex.openStatus() == Acad::eOk)
  29.                                                 {
  30.                                                         if (acdbGetAdsName(objName, pVertex->objectId()) == Acad::eOk)
  31.                                                         {
  32.                                                                 acedRetName(objName, RTENAME); // return the previous entity
  33.                                                         }
  34.                                                 }
  35.                                                 delete pVertIterator;
  36.                                         }
  37.                                 }
  38.                                 else
  39.                                 {
  40.                                         //AcDbBlockTableRecordPointer pBTR(acdbCurDwg()->currentSpaceId(), AcDb::kForRead);
  41.                                         AcDbBlockTableRecordPointer pBTR(pObj->ownerId(), AcDb::kForRead);
  42.                                         if (pBTR.openStatus() == Acad::eOk)
  43.                                         {
  44.                                                 AcDbBlockTableRecordIterator* pIterator = NULL;
  45.                                                 if (pBTR->newIterator(pIterator) == Acad::eOk)
  46.                                                 {
  47.                                                         AcDbEntity* pEnt = NULL;
  48.                                                         if (pIterator->seek(pObj) == Acad::eOk) // if found from ename
  49.                                                         {
  50.                                                                 pIterator->step(false, true); // step back
  51.                                                                 AcDbObjectId objId;
  52.                                                                 pIterator->getEntityId(objId);
  53.                                                                 AcDbObjectPointer<AcDbEntity> pEnt(objId, AcDb::kForRead);
  54.                                                                 if (pEnt.openStatus() == Acad::eOk)
  55.                                                                 {
  56.                                                                         if (acdbGetAdsName(objName, objId) == Acad::eOk)
  57.                                                                         {
  58.                                                                                 acedRetName(objName, RTENAME); // return the previous entity
  59.                                                                         }
  60.                                                                 }
  61.                                                         }
  62.                                                         delete pIterator;
  63.                                                 }
  64.                                         }
  65.                                 }
  66.                         }
  67.                 }
  68.         }
  69.         return (RSRSLT);
  70. }
  71.  

attached it is the arx debug version for autocad 2014 and x64. --- Hope that works and helps. Have fun!

ribarm

  • Gator
  • Posts: 3265
  • Marko Ribar, architect
Re: (entprev)
« Reply #100 on: November 27, 2013, 01:02:33 PM »
entprev works the same way
the main condition for entprev function is (eq (entnext (entprev e)) e)

No, VovKa, if I select with (car (nentsel)) second - next nested entity in block that contains more nested entities, (entprev) won't give that previous nested entity, but if I select that previous - first nested entity with (car (nentsel)), (entnext) returns second nested entity I previously picked... So (entnext) works in space of that block, but (entprev) can't enter that space, because (entnext <parent entity>) returns entity in space of parent entities and this is how (entprev) works, using only parent space...

Beside all this, my further investigations tell me that this issue isn't only related for "INSERT" entities, but also for "DIMENSION" entities - they also have separate space... Just checked, so if we solve problem for "INSERT", that must be applied for "DIMENSION" too...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3265
  • Marko Ribar, architect
Re: (entprev)
« Reply #101 on: November 27, 2013, 01:40:34 PM »
I think, I've solved it... Test it now with : (entprev (car (nentsel)))

Code - Auto/Visual Lisp: [Select]
  1. (defun entprev (e / e1 e2)
  2.   (if (eq (type e) 'ename)
  3.     (if (eq e (entnext))
  4.       nil
  5.       (progn
  6.         (if (not
  7.               (or
  8.                 (eq (cdr (assoc 2 (entget (cdr (assoc 330 (entget e)))))) "*Model_Space")
  9.                 (eq (cdr (assoc 2 (entget (cdr (assoc 330 (entget e)))))) "*Paper_Space")
  10.               )
  11.             )
  12.           (progn
  13.             (setq e1 (cdr (assoc -2 (entget (cdr (assoc 360 (entget (cdr (assoc 330 (entget e))))))))))
  14.             (if (eq e e1) nil
  15.               (progn
  16.                 (while (and e1 (not (eq e (setq e2 (entnext e1)))))
  17.                   (setq e1 e2)
  18.                 )
  19.                 e1
  20.               )
  21.             )
  22.           )
  23.           (progn
  24.             (setq e1 (entnext))
  25.             (while (and e1 (not (eq e (setq e2 (entnext e1)))))
  26.               (setq e1 e2)
  27.             )
  28.             e1
  29.           )
  30.         )
  31.       )
  32.     )
  33.     (entget e)
  34.   )
  35. )
  36.  

M.R.
« Last Edit: November 27, 2013, 02:35:23 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

VovKa

  • Water Moccasin
  • Posts: 1629
  • Ukraine
Re: (entprev)
« Reply #102 on: November 27, 2013, 01:45:22 PM »
No, VovKa, if I select with (car (nentsel)) second - next nested entity in block that contains more nested entities, (entprev) won't give that previous nested entity, but if I select that previous - first nested entity with (car (nentsel)), (entnext) returns second nested entity I previously picked... So (entnext) works in space of that block, but (entprev) can't enter that space, because (entnext <parent entity>) returns entity in space of parent entities and this is how (entprev) works, using only parent space...
i think i can not fully understand your explanation.
can you test your drawing with this?
Code: [Select]
(while (setq e (car (nentsel)))
  (princ (if (eq (entnext (entprev e)) e)
   "ok"
   "error"
)
  )
)

ribarm

  • Gator
  • Posts: 3265
  • Marko Ribar, architect
Re: (entprev)
« Reply #103 on: November 27, 2013, 02:07:55 PM »
i think i can not fully understand your explanation.
can you test your drawing with this?
Code: [Select]
(while (setq e (car (nentsel)))
  (princ (if (eq (entnext (entprev e)) e)
   "ok"
   "error"
)
  )
)

I see what you're getting on... Code updated :
- If I pick nested entity that isn't very first one inside block/dimension - it should return "ok"...
- Now changed not to loop forever - If I pick very first entity (entprev e)=nil, so now in both your cases - it should return "ok" (what I ment to say "error") (entprev e)=nil => (eq e (entnext (entprev e))) = nil...
« Last Edit: November 27, 2013, 02:16:31 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3265
  • Marko Ribar, architect
Re: (entprev)
« Reply #104 on: November 27, 2013, 02:38:22 PM »
Code updated oce more - changed last line to (entget e)...

So now both versions should break the same way if condition (entnext nil) or (entprev nil) :
Code: [Select]
(while (setq e (car (nentsel)))
  (princ (if (eq (entnext (entprev e)) e)
   "ok"
   "error"
)
  )
)
Code: [Select]
(while (setq e (car (nentsel)))
  (princ (if (eq (entprev (entnext e)) e)
   "ok"
   "error"
)
  )
)
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube