Author Topic: draw order in block  (Read 6362 times)

0 Members and 1 Guest are viewing this topic.

kruuger

  • Swamp Rat
  • Posts: 625
draw order in block
« on: October 15, 2014, 07:47:15 AM »
hello
did everyone try change object order in block ?
no errors but also no changes.
Code: [Select]
(defun c:BAB (/ _GetBlockName)
  (defun _GetBlockName (Block)
    (if (vlax-property-available-p Block 'EffectiveName)
      (vla-get-EffectiveName Block)
      (vla-get-name Block)
    )
  )
  (vlax-for %1 (cd:ACX_Blocks)
    (if
      (and
        (not (eq (vla-get-IsLayout %1) :vlax-true))
        (not (eq (vla-get-isXRef %1) :vlax-true))
      )
      (foreach %2 (cd:BLK_GetEntity (_GetBlockName %1) nil)
        (if (= (cdr (assoc 8 (entget %2))) "Z-ELEV-PATT-BACK-N")
          (progn
            (LM:MovetoBottom (cd:ACX_ADoc) (ssadd %2 (ssadd)))
            (princ (cdr (assoc 0 (entget %2))))
          )
        )
      )
    )
    (vla-regen (vla-get-activeDocument (vlax-get-acad-object)) acAllViewports)
  )
 
  (princ)
)
a lot of sub's are missing but just want to show how i try to achieve this.

thanks
kruuger

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: draw order in block
« Reply #1 on: October 15, 2014, 08:20:14 AM »
Are you testing with dynamic or static block definitions?

kruuger

  • Swamp Rat
  • Posts: 625
Re: draw order in block
« Reply #2 on: October 15, 2014, 08:23:46 AM »
Are you testing with dynamic or static block definitions?
just try both and nothing.
k.

danallen

  • Guest
Re: draw order in block
« Reply #3 on: October 15, 2014, 09:21:15 AM »
can you update the block definition to recreate entities in order of creation that achieves same draw order? I believe if they have new handles, then they lose their link to draw order table

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: draw order in block
« Reply #4 on: October 15, 2014, 10:12:05 AM »
The code works OK in BricsCAD. Can you post a sample?

kruuger

  • Swamp Rat
  • Posts: 625
Re: draw order in block
« Reply #5 on: October 15, 2014, 10:42:53 AM »
The code works OK in BricsCAD. Can you post a sample?
(3) gray poly (millwork wall blocking) should be send back.
kruuger

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: draw order in block
« Reply #6 on: October 15, 2014, 11:20:24 AM »
The code work just fine on your sample.
Maybe one of your subs is causing the problem? I am thinking of a possible variable localizing issue.
Maybe it is an AutoCAD issue?

Since you did not supply your subs I have adapted your code by adding workarounds. See below. Note: (vle-collection->list) is a built-in BricsCAD function.
Code: [Select]
(defun c:BAB (/ _GetBlockName)
  (defun _GetBlockName (Block)
    (if (vlax-property-available-p Block 'effectivename)
      (vla-get-effectivename Block)
      (vla-get-name Block)
    )
  )
  (vlax-for %1 (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object)))
    (if
      (and
        (not (eq (vla-get-islayout %1) :vlax-true))
        (not (eq (vla-get-isxref %1) :vlax-true))
      )
      (foreach %2 (cd:BLK_GetEntity (_GetBlockName %1) nil)
        (if (= (cdr (assoc 8 (entget %2))) "Z-ELEV-PATT-BACK-N")
          (progn
            (LM:MovetoBottom (vla-get-activedocument (vlax-get-acad-object)) (ssadd %2 (ssadd)))
            (princ (cdr (assoc 0 (entget %2))))
          )
        )
      )
    )
    (vla-regen (vla-get-activedocument (vlax-get-acad-object)) acallviewports)
  )
 
  (princ)
)

(defun cd:BLK_GetEntity (name x)
  (mapcar
    'vlax-vla-object->ename
    (vle-collection->list (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) name))
  )
)

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: draw order in block
« Reply #7 on: October 15, 2014, 11:27:44 AM »
I get error when having blocks that have entities residing to specific layer... If there are no blocks, everything is fine...

My code :

Code: [Select]
(defun c:layertobottom ( / colnestblklay adoc lay entcoll objlst lst )

  (vl-load-com)

  (defun colnestblklay ( blk lay / e )
    (setq e (tblobjname "BLOCK" (cdr (assoc 2 (entget (vlax-vla-object->ename blk))))))
    (while (setq e (entnext e))
      (if (eq (cdr (assoc 8 (entget e))) lay)
        (setq lst (cons (vlax-ename->vla-object e) lst))
      )
      (if (eq (cdr (assoc 0 (entget e))) "INSERT")
        (if (eq (vla-get-isxref (vla-item (vla-get-blocks adoc) (cdr (assoc 2 (entget e))))) :vlax-false)
          (colnestblklay (vlax-ename->vla-object e) lay)
        )
      )
    )
    lst
  )

  (setq adoc (vla-get-activedocument (vlax-get-acad-object)))
  (setq lay (dos_listbox "LAYERS" "Select Layer to move residing entities to bottom" (ai_table "LAYER" 4)))
  (setq entcoll (vla-get-block (vla-get-activelayout adoc)))
  (vlax-for ent entcoll
    (if (eq (cdr (assoc 0 (entget (vlax-vla-object->ename ent)))) "INSERT")
      (if (eq (vla-get-isxref (vla-item (vla-get-blocks adoc) (cdr (assoc 2 (entget (vlax-vla-object->ename ent)))))) :vlax-false)
        (setq objlst (colnestblklay ent lay))
      )
      (if (eq (cdr (assoc 8 (entget (vlax-vla-object->ename ent)))) lay)
        (setq objlst (cons ent objlst))
      )
    )
  )
  (LM:movetobottom adoc objlst)
  (princ)
)
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: draw order in block
« Reply #8 on: October 15, 2014, 12:17:47 PM »
Code: [Select]
  (foreach obj objlst
    (LM:movetotop adoc (list obj))
  )

With this instead of my last line, it doesn't throw an error, and if there are no blocks then it's OK, but if there are blocks, then nothing happens...??? Owner of object is obtained from each object...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: draw order in block
« Reply #9 on: October 15, 2014, 02:10:48 PM »
I've debugged it...

Code: [Select]
(defun c:layertotop ( / colnestblklay adoc lay entcoll objlst lst )

  (vl-load-com)

  (defun colnestblklay ( blk lay / e )
    (setq e (tblobjname "BLOCK" (cdr (assoc 2 (entget (vlax-vla-object->ename blk))))))
    (while (setq e (entnext e))
      (if (eq (cdr (assoc 8 (entget e))) lay)
        (setq lst (cons (vlax-ename->vla-object e) lst))
      )
      (if (eq (cdr (assoc 0 (entget e))) "INSERT")
        (if (eq (vla-get-isxref (vla-item (vla-get-blocks adoc) (cdr (assoc 2 (entget e))))) :vlax-false)
          (colnestblklay (vlax-ename->vla-object e) lay)
        )
      )
    )
    lst
  )

  (setq adoc (vla-get-activedocument (vlax-get-acad-object)))
  (setq lay (dos_listbox "LAYERS" "Select Layer to move residing entities to top" (ai_table "LAYER" 4)))
  (setq entcoll (vla-get-block (vla-get-activelayout adoc)))
  (vlax-for ent entcoll
    (if (eq (cdr (assoc 0 (entget (vlax-vla-object->ename ent)))) "INSERT")
      (if (eq (vla-get-isxref (vla-item (vla-get-blocks adoc) (cdr (assoc 2 (entget (vlax-vla-object->ename ent)))))) :vlax-false)
        (setq objlst (append objlst (colnestblklay ent lay)))
      )
      (if (eq (cdr (assoc 8 (entget (vlax-vla-object->ename ent)))) lay)
        (setq objlst (cons ent objlst))
      )
    )
  )
  (foreach obj objlst
    (LM:movetotop adoc (list obj))
  )
  (princ)
)

(defun c:layertobottom ( / colnestblklay adoc lay entcoll objlst lst )

  (vl-load-com)

  (defun colnestblklay ( blk lay / e )
    (setq e (tblobjname "BLOCK" (cdr (assoc 2 (entget (vlax-vla-object->ename blk))))))
    (while (setq e (entnext e))
      (if (eq (cdr (assoc 8 (entget e))) lay)
        (setq lst (cons (vlax-ename->vla-object e) lst))
      )
      (if (eq (cdr (assoc 0 (entget e))) "INSERT")
        (if (eq (vla-get-isxref (vla-item (vla-get-blocks adoc) (cdr (assoc 2 (entget e))))) :vlax-false)
          (colnestblklay (vlax-ename->vla-object e) lay)
        )
      )
    )
    lst
  )

  (setq adoc (vla-get-activedocument (vlax-get-acad-object)))
  (setq lay (dos_listbox "LAYERS" "Select Layer to move residing entities to bottom" (ai_table "LAYER" 4)))
  (setq entcoll (vla-get-block (vla-get-activelayout adoc)))
  (vlax-for ent entcoll
    (if (eq (cdr (assoc 0 (entget (vlax-vla-object->ename ent)))) "INSERT")
      (if (eq (vla-get-isxref (vla-item (vla-get-blocks adoc) (cdr (assoc 2 (entget (vlax-vla-object->ename ent)))))) :vlax-false)
        (setq objlst (append objlst (colnestblklay ent lay)))
      )
      (if (eq (cdr (assoc 8 (entget (vlax-vla-object->ename ent)))) lay)
        (setq objlst (cons ent objlst))
      )
    )
  )
  (foreach obj objlst
    (LM:movetobottom adoc (list obj))
  )
  (princ)
)

The bug was in this line :
Code: [Select]
(setq objlst (colnestblklay ent lay))

Should be :
Code: [Select]
(setq objlst (append objlst (colnestblklay ent lay)))
« Last Edit: October 16, 2014, 07:56:10 AM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

kruuger

  • Swamp Rat
  • Posts: 625
Re: draw order in block
« Reply #10 on: October 15, 2014, 03:44:35 PM »
marko your updated code works perfect, great :)

roy_043 - in autocad there is no vle-collection->list need to modify so:
Code: [Select]
(defun cd:BLK_GetEntity (name x / res)
  (mapcar
    'vlax-vla-object->ename
    (vlax-for % (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) Name)
      (setq res (cons % res))
    )
  )
)

but code still doesn't work. dig it more and looks like:
Code: [Select]
(LM:MovetoBottom (cd:ACX_ADoc) (ssadd %2 (ssadd)))need replace with
Code: [Select]
(LM:MovetoBottom (cd:ACX_ADoc) (list (vlax-ename->vla-object %2)))and finally it works :)

thanks again
kruuger

roy_043

  • Water Moccasin
  • Posts: 1895
  • BricsCAD 18
Re: draw order in block
« Reply #11 on: October 16, 2014, 03:30:18 AM »
@ kruuger:
I was surprised by your use of ssadd. But according to the docs it should work in AutoCAD as well.
According to those same docs you could also have used:
Code: [Select]
(ssadd %2)

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: draw order in block
« Reply #12 on: October 16, 2014, 07:58:59 AM »
I don't know if this new code is 100% correct, so please test it... I thought I could make something different than with just QSELECT - blocks by name => DRAWORDER...

Code: [Select]
(defun c:blkstotop ( / _selblks adoc )

  (vl-load-com)

  (defun _selblks ( / bln ss pbln )
    (setq bln (dos_listbox "BLOCKS" "Select block to place residing entities to top" (ai_table "BLOCK" 4)))
    (while (eq (vla-get-isxref (vla-item (vla-get-blocks adoc) bln)) :vlax-true)
      (prompt "\nSelected block name refers to Xref... Please choose different name again...")
      (princ)
      (setq bln (dos_listbox "BLOCKS" "Select block to place residing entities to top" (ai_table "BLOCK" 4)))
    )
    (setq ss (ssget "_A" (list '(0 . "INSERT") (cons 2 bln) (cons 410 (if (= 1 (getvar 'cvport)) (getvar 'ctab) "Model")))))
    (if (null ss)
      (progn
        (setq pbln (cdr (assoc 2 (entget (cdr (assoc 330 (entget (cdr (assoc 331 (reverse (entget (cdr (assoc 330 (entget (tblobjname "BLOCK" bln)))))))))))))))
        (if (eq (vla-get-isxref (vla-item (vla-get-blocks adoc) pbln)) :vlax-false)
          (progn
            (command "_.BEDIT" pbln)
            (LM:movetotop adoc (ssget "_A" (list '(0 . "INSERT") (cons 2 bln) (cons 410 (if (= 1 (getvar 'cvport)) (getvar 'ctab) "Model")))))
            (command "_.BCLOSE" "")
          )
          (progn
            (prompt "\nParent reference entity of selected block belongs to Xref entity... Please choose different name again...")
            (princ)
            (_selblks)
          )
        )
      )
      ss
    )
  )

  (setq adoc (vla-get-activedocument (vlax-get-acad-object)))
  (LM:movetotop adoc (_selblks))
  (princ)
)

(defun c:blkstobottom ( / _selblks adoc )

  (vl-load-com)

  (defun _selblks ( / bln ss pbln )
    (setq bln (dos_listbox "BLOCKS" "Select block to place residing entities to bottom" (ai_table "BLOCK" 4)))
    (while (eq (vla-get-isxref (vla-item (vla-get-blocks adoc) bln)) :vlax-true)
      (prompt "\nSelected block name refers to Xref... Please choose different name again...")
      (princ)
      (setq bln (dos_listbox "BLOCKS" "Select block to place residing entities to bottom" (ai_table "BLOCK" 4)))
    )
    (setq ss (ssget "_A" (list '(0 . "INSERT") (cons 2 bln) (cons 410 (if (= 1 (getvar 'cvport)) (getvar 'ctab) "Model")))))
    (if (null ss)
      (progn
        (setq pbln (cdr (assoc 2 (entget (cdr (assoc 330 (entget (cdr (assoc 331 (reverse (entget (cdr (assoc 330 (entget (tblobjname "BLOCK" bln)))))))))))))))
        (if (eq (vla-get-isxref (vla-item (vla-get-blocks adoc) pbln)) :vlax-false)
          (progn
            (command "_.BEDIT" pbln)
            (LM:movetobottom adoc (ssget "_A" (list '(0 . "INSERT") (cons 2 bln) (cons 410 (if (= 1 (getvar 'cvport)) (getvar 'ctab) "Model")))))
            (command "_.BCLOSE" "")
          )
          (progn
            (prompt "\nParent reference entity of selected block belongs to Xref entity... Please choose different name again...")
            (princ)
            (_selblks)
          )
        )
      )
      ss
    )
  )

  (setq adoc (vla-get-activedocument (vlax-get-acad-object)))
  (LM:movetobottom adoc (_selblks))
  (princ)
)

Regards, M.R.
« Last Edit: October 25, 2014, 01:20:19 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: draw order in block
« Reply #13 on: October 16, 2014, 09:27:18 AM »
I've found some mistakes in my last posted code - now fixed...

HTH, M.R.

[EDIT:] I figured out that I programmed code too much... Only this is what is necessary... - Added new code - it operates now and on Xrefs... [/EDIT]

Code: [Select]
(defun c:blkstotop ( / _selblks adoc )

  (vl-load-com)

  (defun _selblks ( / bln ss pbln )
    (setq bln (dos_listbox "BLOCKS" "Select block to place residing entities to top" (ai_table "BLOCK" 4)))
    (setq ss (ssget "_A" (list '(0 . "INSERT") (cons 2 bln) (cons 410 (if (= 1 (getvar 'cvport)) (getvar 'ctab) "Model")))))
    (if (null ss)
      (progn
        (setq pbln (cdr (assoc 2 (entget (cdr (assoc 330 (entget (cdr (assoc 331 (reverse (entget (cdr (assoc 330 (entget (tblobjname "BLOCK" bln)))))))))))))))
        (command "_.BEDIT" pbln)
        (LM:movetotop adoc (ssget "_A" (list '(0 . "INSERT") (cons 2 bln) (cons 410 (if (= 1 (getvar 'cvport)) (getvar 'ctab) "Model")))))
        (command "_.BCLOSE" "")
      )
      ss
    )
  )

  (setq adoc (vla-get-activedocument (vlax-get-acad-object)))
  (LM:movetotop adoc (_selblks))
  (princ)
)

(defun c:blkstobottom ( / _selblks adoc )

  (vl-load-com)

  (defun _selblks ( / bln ss pbln )
    (setq bln (dos_listbox "BLOCKS" "Select block to place residing entities to bottom" (ai_table "BLOCK" 4)))
    (setq ss (ssget "_A" (list '(0 . "INSERT") (cons 2 bln) (cons 410 (if (= 1 (getvar 'cvport)) (getvar 'ctab) "Model")))))
    (if (null ss)
      (progn
        (setq pbln (cdr (assoc 2 (entget (cdr (assoc 330 (entget (cdr (assoc 331 (reverse (entget (cdr (assoc 330 (entget (tblobjname "BLOCK" bln)))))))))))))))
        (command "_.BEDIT" pbln)
        (LM:movetobottom adoc (ssget "_A" (list '(0 . "INSERT") (cons 2 bln) (cons 410 (if (= 1 (getvar 'cvport)) (getvar 'ctab) "Model")))))
        (command "_.BCLOSE" "")
      )
      ss
    )
  )

  (setq adoc (vla-get-activedocument (vlax-get-acad-object)))
  (LM:movetobottom adoc (_selblks))
  (princ)
)
« Last Edit: October 25, 2014, 01:21:14 PM by ribarm »
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: draw order in block
« Reply #14 on: October 16, 2014, 02:22:54 PM »
Added shorted and improved version of codes that manipulates draw order with Blocks/Xrefs...
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube

kruuger

  • Swamp Rat
  • Posts: 625
Re: draw order in block
« Reply #15 on: October 16, 2014, 02:53:46 PM »
@ kruuger:
I was surprised by your use of ssadd. But according to the docs it should work in AutoCAD as well.
According to those same docs you could also have used:
Code: [Select]
(ssadd %2)
this one also doesn't work. i stay with (list VLA)

marko not sure what exactly your new code should do :(
if i'm correct you can eliminate xref from the list with (ai_table "BLOCK" (+ 4 8) ). not necessary to check for xrefs.

kruuger

ribarm

  • Gator
  • Posts: 3225
  • Marko Ribar, architect
Re: draw order in block
« Reply #16 on: October 16, 2014, 03:26:56 PM »
marko not sure what exactly your new code should do :(
if i'm correct you can eliminate xref from the list with (ai_table "BLOCK" (+ 4 8 ) ). not necessary to check for xrefs.

kruuger

I want to reduce time, (qselect - block by name - draworder)... And also qselect is not very appropriate when dealing with selections of External References by name... Also my routine can find nested block and BEDIT its parent reference to set appropriate draworder inside parent... I hope this has some sense, unless you have time to do all this manually...

BTW. Firstly I wanted to eliminate Xrefs from routine operations, but then I realized this problem with qselect and hopefully I did find solution - I want routine to operate both and blocks and Xrefs... And now so it does...

Regards... Marko
Marko Ribar, d.i.a. (graduated engineer of architecture)

:)

M.R. on Youtube