Lisp Plan - Set block attributes to default value

Lisp Plan - Set block attributes to default value

Shneuph
Collaborator Collaborator
1,362 Views
5 Replies
Message 1 of 6

Lisp Plan - Set block attributes to default value

Shneuph
Collaborator
Collaborator

Hello all,

 

I'm not looking for written out lisp code per se, but just a plan and method to get where I want to be.  I have the need to set the attributes of many blocks to their default values.  My plan is something like this:

 

Lisp Command:

  User selects blocks whose attributes will revert to their default values.

  Pass these blocks to the following function in the form of ???

 

Function Lisp:

  Accept list (?) of blocks in the form of (list of vla objects/list of names [strings], selection set?)

  Find the block definition object and save the default values of the attributes  (I pretty much have this part down)

  Apply the default attributes to the attributes of each block instance selected.

 

Any thoughts on the best way to save and pass block instances between command and function?

 

I guess, it would be a good idea to pass a list of VLA-Objects and just have the function process them 1 at a time instead of saving all the attribute tags and values to a list for later use? 

 

Or, does the command have a selection set that it passes 1 at a time to a function that handles 1 block at a time?

 

🤔

 

---sig---------------------------------------
'(83 104 110 101 117 112 104 64 71 109 97 105 108 46 99 111 109)
0 Likes
Accepted solutions (1)
1,363 Views
5 Replies
Replies (5)
Message 2 of 6

pbejse
Mentor
Mentor

@Shneuph wrote:

Lisp Command:

  User selects blocks whose attributes will revert to their default values.

  Pass these blocks to the following function in the form of ???

....

Any thoughts on the best way to save and pass block instances between command and function?

...


Is that selecting one instance of the every block definitions whose attributes will revert to their default values. Say "BLOCKNAME1" "BLOCKNAME2" 

 

Because those are the only collection you need to save, from you ReadBlockData  function using block name as argument, result  in the form of:

(("BLOCKNAME" (("TAG" "DFVALUE")("TAG2" "DFVALUE")))
  ("BLOCKNAME2" (("TAG" "DFVALUE")("TAG2" "DFVALUE"))
   ))

 

Dont even need to save any Vla-objects, you process them as you go along, of course using the names from the initial selection as filter for the ALL same block attributes i the drawing.

 

Or are initial selection is ALL objects to be processed?

 ssget
 repeat
	getblockname
		Check name if name exist
		Yes	| use data
		No 	| process name with ReadBlock function
			  save to list [ format above ] use data

	process block

 

Regardless, there's no need to save VLA-objects , all you need is the list from ReadBlockData function.

 

... saving all the attribute tags and values to a list for later use? 


You got my vote there, you only need to do that one time.

 

my 0.2 cents

 

 

0 Likes
Message 3 of 6

Shneuph
Collaborator
Collaborator

The initial selection set could be several instances but not all instances of a block.  Or, several instances but not all instances of many blocks.

 

Here is the function to process.  If I pass it a vla-object I can just use all the properties to accomplish what I'm looking for.  I guess I'm just better at dealing with VLA objects than creating and reading from lists.  Which I know is not great since lisp is literall "LIST PROCESSING" and I'm not good with lists.

 

So, the plan is to create a list of objects and pass 1 at a time to let the function process them.  Do you think that'll be significantly slower than what you said?

 

(this is working but still incomplete)

(defun TLF-Att_Default_Value (tlv-binst / tlv-cbdef tlv-dbname tlv-n tlv-cattdef tlv-attdefval)
  
  (setq tlv-cbdef (vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) (vla-get-name tlv-binst))
	tlv-cbname (vla-get-name tlv-binst)
	tlv-n 0
	tll-BInstAttributes (vlax-safearray->list (vlax-variant-Value (vla-getattributes tlv-binst)))
	);setq

  (foreach att (vlax-safearray->list (vlax-variant-value (vla-getattributes tlv-binst)))
    (while (< tlv-n (vla-get-count tlv-cbdef))
      ;(princ (vla-get-objectname (vla-item tlv-cbdef tlv-n)))
      (if (= (vla-get-objectname (vla-item tlv-cbdef tlv-n)) "AcDbAttributeDefinition")
	(if (= (vla-get-tagstring (vla-item tlv-cbdef tlv-n)) (vla-get-tagstring att))
	  (vla-put-textstring att (vla-get-textstring (vla-item tlv-cbdef tlv-n)))
	  );if
	);if
      (setq tlv-n (1+ tlv-n))
      );while
    (setq tlv-n 0)
    );foreach
  (princ)
  );defun

 

---sig---------------------------------------
'(83 104 110 101 117 112 104 64 71 109 97 105 108 46 99 111 109)
0 Likes
Message 4 of 6

pbejse
Mentor
Mentor
Accepted solution

@Shneuph wrote:

The initial selection set could be several instances but not all instances of a block.  Or, several instances but not all instances of many blocks.

 

Here is the function to process.  If I pass it a vla-object I can just use all the properties to accomplish what I'm looking for.  I guess I'm just better at dealing with VLA objects than creating and reading from lists.  Which I know is not great since lisp is literall "LIST PROCESSING" and I'm not good with lists.

 

So, the plan is to create a list of objects and pass 1 at a time to let the function process them.  Do you think that'll be significantly slower than what you said?


 

You made your TLF-Att_Default_Value too complicated. it passes the name of the block to the blocks collection for every instance of the same block name [ each and everytime ].  Which you dont have to as i outlined on my first message. and towards the end of your code you then assign the value.

 

What you need to to check ONCE for the default value of the attributes. [ a separate function ] and another to process. [ not even, you can just go ahead and edit the attribute while processing every selection. ]

 

 

(vla-item (vla-get-blocks (vla-get-activedocument (vlax-get-acad-object))) blkname)

 

 

Grab value Tagstring and Textstring and save list as the one i poste above.

 

Holler if you need help

 

BTW: YES, what you have now is  significantly slower

Besides, if your looking to reset ALL values, why not just use a lisp to reinisert the blocks using the existing onject properties and save you the trouble of collecting attribtue datas from the block definition.

 

 

 

 

Message 5 of 6

Shneuph
Collaborator
Collaborator

I get what you're saying.  I know for every instance it has to go to the definition and pull the default value.

 

Let me take a stab at it your way.

 

>Select Block instances

>Pull default att values to a list

>update atts in instances from list instead of definition each time.

👍

 

Thanks for your input!

---sig---------------------------------------
'(83 104 110 101 117 112 104 64 71 109 97 105 108 46 99 111 109)
0 Likes
Message 6 of 6

pbejse
Mentor
Mentor

@Shneuph wrote:

I get what you're saying.  I know for every instance it has to go to the definition and pull the default value.


Yes, just ONCE

 


@Shneuph wrote:

>Select Block instances

>Pull default att values to a list

>update atts in instances from list instead of definition each time.


YES

YES

and YES

 

Role with the selection of all objects. [ as the posted pseudo code ]

🙂

 

 

0 Likes