Jump to content

Recommended Posts

Posted

Hi folkes,

 

I have an issue with my current lisp. My intention is to go trough all blocks in my drawing which have its origin in this particular drawing and do something to them. In some drawings I started to go through the "block" symbol table but soon I noticed that my code is running into errors. To find the issue I counted how much entities the table has and was surprised to see that is has over 500 lines (I expected ~35). While going through the table manually afterwards I noticed that also xrefs and even their blocks are listed in this table :( Of course my code should not touch the xref and its blocks. They are causing the issues. In drawings without an xref the code does exactly what it should. At first I thought about detaching the xref in the lisp and than run the code, but actually I still need the context afterwards and I thought there might be a smarter way than detach -> run code -> attach again.

 

So here is my question: 

 

Is there a way to detect if an entity in the symbol table "block" is a xref or a block inside an attached xref and than skip this line and go ahead?

 

Thank you for your support!

Posted

Hi,

If you are iterating via DXF Block Table then check THIS LINK and read about the Group Code 70 but if you are iterating via Active-X with vla-get-blocks then you can use the function vlax-get-isxref to check if the return of this function is equal to :vlax-true then the object is an xref object for sure.

Posted

Thank you Tharwat,

while waiting for replies I also went ahead searching. But because I didn't know how this "container" like (70 . 44) was called it was actually hard to find something usefull. Thank you for the correct hint on "group codes".

I may jump to conclusions, but if I'm not wrong a simple condition like:

(/= 0 (logand 2 (cdr (assoc 70 (tblsearch "block" BNAME)))))

Should give me back T only for blocks that are defined in my drawing.

Or do I miss something? I have the feeling that I may exclude to much (even if I define a block with attributes and set a few of them to be constant it looks like it is giving back T which contradicts in my understanding the explanation in the linked manual).

 

Posted (edited)

Close enough, but since the GC has many options then just target your desired one as follows:

(= 4 (logand 4 (cdr (assoc 70 (tblsearch "block" BNAME)))))

I expected that you are using the tblnext function and not tblsearch unless you are checking a few selected blocks and not going through the block table itself.

Edited by Tharwat
Posted (edited)

I have this condition as a part of a while loop which loops through the tblnext till it finds a entity whichs name was not already processed (I create new blocks in the macro and rename the block at first step to be able to reuse the same name later. So at the end of the table new blocks will be added which have the same name as the first ones before renaming) ;) 

(while (or (/= nil (member BNAME LIBNAME)) (/= 0 (logand 2 (cdr (assoc 70 (tblsearch "block" BNAME))))))
	(setq BNAME (cdr (assoc 2 (tblnext "block"))))
);while

I tried first with your proposal, but it seems like blocks in an xref doesn't carry the bit 4.

Befehl: (setq tb1 (tblsearch "block" "Context_P01|BLOCK479"))
((0 . "BLOCK") (2 . "Context_P01|BLOCK479") (70 . 48) (4 . "") (10 0.0 0.0 0.0) (-2 . <Objektname: 77bdace0>))

As a depentent of the xref it carries the bit 16. than maybe I should exclude 4 and 16 to not miss something? But from what I see I should exclude most of the bit options for code 70 to avoid getting stuck in an external or anonymous block.

How does a typical block with (70 . 0) looks like. I'm not sure I should skip them too.

 

Edit: Oh, a bit more testing gave me the answer.

I think I should make sure I get all blocks with bit 0 and 2 processed and ignore the others.

 

Your reply was really helpfull Tharwat, can' thank you enough!

Edited by Ament
Posted
(while (setq b (tblnext "BLOCK" (not b)))
  (if (and (null (cdr (assoc 1 b)))
           (not (= 4 (logand 4 (cdr (assoc 70 b)))))
           (not (= 2 (logand 2 (cdr (assoc 70 b)))))
           (not (wcmatch (setq n (cdr (assoc 2 b))) "*|*,`**U*"))
      )
    (setq l (cons n l))
  )
)

 

Posted (edited)

Since the property of being an external reference or an anonymous block are all encoded by DXF group 70, there needn't be as many tests to obtain a list of block names which are not external references (or dependent on external references), or anonymous blocks - I believe the following will suffice:

(defun getblocks ( / d l )
    (while (setq d (tblnext "block" (not d)))
        (if (zerop (logand 21 (cdr (assoc 70 d))))
            (setq l (cons (cdr (assoc 2 d)) l))
        )
    )
    (reverse l)
)

Here:

  • bit 1 tests for anonymity
  • bit 4 tests for an external reference
  • bit 16 tests for dependence on an external reference
Edited by Lee Mac
  • Like 1
Posted (edited)

Post deleted - mistake :)

Edited by ziele_o2k
Posted

Hello both of you,

thank you for your answers. Sorry for the late reply, we had public vacation and I was off from my computer for a few days.

Both of your replies helped me to get a hand on my requirements. I'll just accept bit 0 & 2 and it should work perfectly.

Thanks again,

Ament

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Unfortunately, your content contains terms that we do not allow. Please edit your content to remove the highlighted words below.
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...