Visual LISP, AutoLISP and General Customization
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Insert Dynamic Block programmatically

15 REPLIES 15
Reply
Message 1 of 16
kbeake
1243 Views, 15 Replies

Insert Dynamic Block programmatically

I figured out how to entmake a Block with attributes based on user input for insert point, rotation, etc.

My block is a detail bubble that is a circle with a tail, that cuts the object and shows direction of cut. I will include that with this post.

My problem lies in this. I've used dynamic block features such as linear for the tail length, and the cut length, and angle for the direction of the tail.

My old routine was simple, it would ask for detail point and angle. From that it would insert a block that was just the bubble and draw the tail and cut with a polyline.

Since then I've been able to use entmake, which is a lot more powerful for creating entities in AutoCAD. But for the life of me I can't figure out how to add the dynamic properties of my "new" detail block that has the tail, cut and bubble in one.

If anyone could look at this and please provide some guidance by telling me what I need in the entmake statement to make this create programmatically instead of inserting the block, then modifying it, if possible.

Thanks,
Keith
15 REPLIES 15
Message 2 of 16
Anonymous
in reply to: kbeake

To be clear, are you entmake'ing the Block or a BlockInsertion?

To further complicate it for you, you will need to use ActiveX methods &
properties to do this. Here is an example to Insert the block and set the 2
distance properties.

(vl-load-com)
(setq *doc* (vla-get-activedocument (vlax-get-acad-object)))
(setq blk (vlax-invoke (vla-get-modelspace *doc*) 'insertblock
'(0.0 0.0 0.0) ;;insertion point
"DB1" ;;block name
1.0 ;; X scale
1.0 ;; Y scale
1.0 ;; Z scale
0.0 ;; rotation angle
))
(setq props (vlax-invoke blk 'getdynamicblockproperties))
(foreach prop props
(setq name (vla-get-propertyname prop))
(cond ((eq name "Distance")
(vla-put-value prop 96.0);;use whatever value you want here
)
((eq name "Distance1")
(vla-put-value prop 24.0);;use whatever value you want here
)
;;;more cond tests here for the other props.
)
)

Note that you must make sure to pass the correct Type value for the
property. The distance props require REAL numbers, Others may need strings
or boolean (true/false)

Good luck!


"kbeake" wrote in message news:5856658@discussion.autodesk.com...
I figured out how to entmake a Block with attributes based on user input for
insert point, rotation, etc.

My block is a detail bubble that is a circle with a tail, that cuts the
object and shows direction of cut. I will include that with this post.

My problem lies in this. I've used dynamic block features such as linear for
the tail length, and the cut length, and angle for the direction of the
tail.

My old routine was simple, it would ask for detail point and angle. From
that it w
ould insert a block that was just the bubble and draw the tail and cut with
a polyline.

Since then I've been able to use entmake, which is a lot more powerful for
creating entities in AutoCAD. But for the life of me I can't figure out how
to add the dynamic properties of my "new" detail block that has the tail,
cut and bubble in one.

If anyone could look at this and please provide some guidance by telling me
what I need in the entmake statement to make this create programmatically
instead of inserting the block, then modifying it, if possible.

Thanks,
Keith
Message 3 of 16
kbeake
in reply to: kbeake

Well, I would like to entmake the blockinsertion as well, I've done the first part by checking the table record for the block instance. It then passes nil or true to my routine, and if it's nil, what method do you recommend for putting the block into the drawing?
Message 4 of 16
Anonymous
in reply to: kbeake

I would have it in a standard drawing somewhere in my support path, then use
ObjectDBX to copy the block definition from that drawing into the current
drawing. AFAIK, there is no way to create a Dynamic block, using (entmake)
or ActiveX, so it must be created and saved somewhere first.

You can still use your (entmake) to insert the block and set the
attribute(s), but you will still need to use the ActiveX code I showed to
access the Dynamic Properties. To get the inserted block to do this, after
you insert it using (entlast) should return the insert's ename. Use
(vlax-ename->vla-object (entlast)) to get the VLA-Object for use with the
ActiveX method.

wrote in message news:5856780@discussion.autodesk.com...
Well, I would like to entmake the blockinsertion as well, I've done the
first part by checking the table record for the block instance. It then
passes nil or true to my routine, and if it's nil, what method do you
recommend for putting the block into the drawing?
Message 5 of 16
Tom Smith
in reply to: kbeake

Jeff, thanks for posting the code. We're switching to a dynamic section cut tag, somewhat similar to the OOTB example.

In order to replace the old style block with the new one in an existing drawing, I'm doing as you suggest, inserting the new block copying over the old attribute values, and altering its dynamic properties based on information gleaned from the old block.

An anomaly I've encountered is that the solid hatch in the tag doesn't display correctly until the drawing is regenerated. It looks as if it's still pointing the same way, even though the symbol rotation parameter was changed.

Neither (entupd) nor (redraw) will update the block's on-screen display. Manually, a single regen will work, but (oddly) it takes two regens in my lisp code to ensure that the new block looks right.

This isn't too obnoxious if I run a routine to upgrade all the tags in a drawing at once, but like the OP, I'd like to automate the process of inserting the new--style tag with dynamic properties set, which would involve the same process, and I hate to do a double regen every time a block's inserted.

Any thoughts? Have you encountered this? It's only the solid hatch which displays wrongly.
Message 6 of 16
Anonymous
in reply to: kbeake

Tom -

My experience is that HATChes inside dynamic blocks are notoriously flaky.

Any chance of replacing a solid HATCH with a 2d SOLID?
Message 7 of 16
Tom Smith
in reply to: kbeake

Thanks, Herman, maybe I'll try that. Nothing else I've done seems to help.
Message 8 of 16
Tom Smith
in reply to: kbeake

>HATChes inside dynamic blocks are notoriously flaky

Yep, Herman, they sure are. Here's another related quirk.

To insert a the same section tag DB at predetermined orientations, I tried using toll palette properties, and they behave just as they do when they're inserted and modified programmatically, namely, the solid hatch isn't generated properly and the tag looks bad until the drawing's regenerated.

But, get this -- in 2007, I discovered acidentally, if you press CTRL+ALT, the correct display of the hatches shows on the screen, in addition to the bad display. Release the keys, and you're back to the bad display. But if you move the cursor over the blocks while holding down CTRL+ALT, the hatches are redrawn correctly! What the heck is the deal on that??

Now if there was a only way to accomplish the same thing without regenerating ...
Message 9 of 16
Dewlevlak
in reply to: Anonymous

First, Thank you for posting this code.  I have been searching for it a long time.

Second, I need further help!  I have messed around with foreach, mapcar, etc and I have not been able to figure it out.
How do I change the line (setq obj (car (entsel) ) );*** to something like: (setq obj (ssget))?
So that I can enter a length and have it change the specific property in all objects selected.

 

 


(defun ChangePropertyLength()
(vl-load-com)
  (setq acadObject (vlax-get-acad-object) )
  (setq acadDocument (vlax-get-property acadObject 'ActiveDocument) )
  (setq mSpace (vlax-get-property acadDocument 'Modelspace) )
  (setq TheLength (getreal "\nWhat length? ") )
 
  (setq obj (car (entsel) ) );***

  (setq ename (vlax-ename->vla-object obj) )
  (setq props (vlax-invoke ename 'getdynamicblockproperties) )
  (foreach prop props
    (setq name (vla-get-propertyname prop) )
    (if
      (eq name "TheLength")
      (vla-put-value prop TheLength)
      )
    )
  )

Message 10 of 16
pbejse
in reply to: Dewlevlak


@Dewlevlak wrote:

,,,,

How do I change the line (setq obj (car (entsel) ) );*** to something like: (setq obj (ssget))?
 ,,,,

 


(defun ChangePropertyLength  (ent pnme len / props name)
      (vl-load-com)
      (setq props (vlax-invoke ent 'getdynamicblockproperties))
      (foreach  prop  props
            (if
                  (eq (strcase (vla-get-propertyname prop)) (strcase pnme))
                       (vla-put-value prop len)
                       )
            )
      )


(defun c:test  ( / TheLength objs ename)
  (if (and
            (setq TheLength (getreal "\nWhat length? "))
            (setq objs (ssget ":L" '((0 . "INSERT")))))
        (repeat (setq i (sslength objs))
              (setq ename (vlax-ename->vla-object
                                (ssname objs
                                        (setq i (1- i)))))
              (ChangePropertyLength
                    ename  "TheLength" TheLength))
      )
  )

 

 

Message 11 of 16
Dewlevlak
in reply to: kbeake

Thank you for your quick reply.  I am trying it without success.  Here is a sample file with a simple line block which has a length paramerter 'TheLength'.  I would like to be able to change all of these lengths with LISP all at once. Then, I can train a Button to automatically change all these parameters in the drawing.  I am able to change the lenth of one block selection at a time with (setq obj (car (entsel))). 

 

Thanks again,

Message 12 of 16
pbejse
in reply to: Dewlevlak


@Dewlevlak wrote:

Thank you for your quick reply.  I am trying it without success.  Here is a sample file with a simple line block which has a length paramerter 'TheLength'.  I would like to be able to change all of these lengths with LISP all at once. Then, I can train a Button to automatically change all these parameters in the drawing.  I am able to change the lenth of one block selection at a time with (setq obj (car (entsel))). 

 

Thanks again,


Guess i need to put it together for you then.

 

(defun c:chpname  ( / ChangePropertyLength  objs ename)
 (vl-load-com)     
 ;;; Generic sub for property name  ;;;
 (defun ChangePropertyLength  (ent pnme len / props name)
      (setq props (vlax-invoke ent 'getdynamicblockproperties))
      (foreach  prop  props
            (if
                  (eq (strcase (vla-get-propertyname prop)) (strcase pnme))
                       (vla-put-value prop len)
                       )
            )
      )
  (if (and
 (setq TheLength
           (cond  ((getdist
                        (strcat "\nEnter Length <"
                                (rtos (setq TheLength
                                                 (cond (TheLength) (1.00))
                                            ) 2 2 )  ">: " )))
                 (TheLength)))
            (setq objs (ssget ":L" '((0 . "INSERT")))))
        (repeat (setq i (sslength objs))
              (setq ename (vlax-ename->vla-object
                                (ssname objs
                                        (setq i (1- i)))))
              (ChangePropertyLength
                    ename  "TheLength" TheLength))
      )
  )

 

There are many ways to write this code, but i opted not to deviate from the orignal.

 

HTH

Message 13 of 16
Dewlevlak
in reply to: Dewlevlak

:smileyhappy Oh Sweet!  That is so AWESOME!  Thank you!  Thank you! Thank you!  That works great! 

I will go through it to try to understand how it all works.  But it does work in the drawings the way I needed it to! Smiley Very Happy

Message 14 of 16
Dewlevlak
in reply to: pbejse

Hello again

Thank you, your help has been very  helpful.  I have been able to modify and use your program to modify all parameters of blocks in the drawing for different purposes.  I have come across another situation to which I need help.

 

I would like to change the "Visibility" of blocks nested in another block.  I have a block in the drawing which has 3 blocks nested in it.  How do I selet the nested blocks within a particular block to be changed?   

 

Thanks again,

 

Message 15 of 16
pbejse
in reply to: Dewlevlak


@Dewlevlak wrote:

 

I would like to change the "Visibility" of blocks nested in another block.  I have a block in the drawing which has 3 blocks nested in it.  How do I selet the nested blocks within a particular block to be changed?   

 

Thanks again,

 


As it affect every instance of the block in the drawing might as well Bedit or Refedit the block then run the code there.

 

 

Message 16 of 16
Dewlevlak
in reply to: pbejse

Thank you, that worked slick. Sometimes it is easy when programing to forget the simple used all the time AutoCAD commands.

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost