Jump to content

Align Block to a reference line


Sambuddy

Recommended Posts

image.png.4a4c57a0e780def6d6e90dab3ca37d4e.png

Please see below the lisp I have been using to align blocks I had referencing a line. On the snapshot above, as can be seen, the block (customized text leader block) my reference block is at the tip of the leader and not as i prefer (Position2) on this specific block.

Can someonw let me know how I can manipulate this lisp so it would take Position2 as a point to align and not 0,0 "Position". The reason for doing this is the leader pointer can be dragged but I would like the alignment to happen on that fixed "Position2". This lisp works well with my other blocks I need to align due to the proper placement of 0,0.

alternatively, is there a way, if I cannot specify "Position2", to select which point I would like to be aligned?

Thanks

 

 

(defun C:alit ()
(prompt "\nPick base line upon which project/align objects:")
(setq ent (entsel))
(setq pt2 (cadr ent))
(setq nlin (car ent))
(setq pt2 (osnap pt2 "Nea"))

(prompt "\nSelect texts/blocks to project/align: ")
(setq conj (ssget))
(setq num 0)
(setq con (ssadd))
(setq lon (sslength conj))
(repeat lon
(setq name (ssname conj num))
(setq lst (entget name))
(setq tip (cdr (assoc 0 lst)))
(if (or (= tip "TEXT")(= tip "INSERT"))
(ssadd name con)
)
(setq num (+ 1 num))
) ; end repeat
(setq lon1 (sslength con))
(setq num1 0)
(repeat lon1
(setq e1 (entget (ssname con num1)))
(setq pt1 ( cdr (assoc 10 e1))) 
(setq name (cdr (assoc -1 e1)))
( command "line" pt1 (osnap pt2 "per") "")
(setq pfin (cdr (assoc 11 (entget (entlast)))))
(command "_erase" (entlast) "")
(command "_move" name "" pt1 pfin)
(setq num1 (+ 1 num1))
);end repeat
(initget "Yes No")
(setq what (getkword "\n¿Erase base line? (Y/N) <Y>: "))
(if (= what nil)(setq what "Yes"));end if
(cond
((= what "Yes")(command "_erase" nlin ""))
); end cond
(princ)
) ; end defun

Link to comment
Share on other sites

Good morning Emmanuel,

Please see attached. I included a bunch of annotations - Please note that all my annotations are done in layout and not the model space. These are some of the annotation blocks I developed over the years but there are many more. The only common thing they have is that insertion point is at the pointer location and not "Position2". 

Thanks

 

Edited by Sambuddy
Link to comment
Share on other sites

That's funny, I just answered a question that requires more or less the same code.

 

See if this helps. 

I don't expect it to work in all situations.  The order of set props can mess things up. 

Maybe I will have to restrict which props must be changed.

 

Command CDP (for copy dynamic props)

Select source, then in a while loop select 1 or multiple destination blocks

 

Tell me if this is part of the solution and what specific problems occur (if any)

 


(vl-load-com)

;; http://www.lee-mac.com/dynamicblockfunctions.html

;; Get Dynamic Block Properties  -  Lee Mac
;; Returns an association list of Dynamic Block properties & values.
;; blk - [vla] VLA Dynamic Block Reference object
;; Returns: [lst] Association list of ((<prop> . <value>) ... )
(defun LM:getdynprops ( blk )
    (mapcar '(lambda ( x ) (cons (vla-get-propertyname x) (vlax-get x 'value)))
        (vlax-invoke blk 'getdynamicblockproperties)
    )
)

;; Set Dynamic Block Properties  -  Lee Mac
;; Modifies values of Dynamic Block properties using a supplied association list.
;; blk - [vla] VLA Dynamic Block Reference object
;; lst - [lst] Association list of ((<Property> . <Value>) ... )
;; Returns: nil
(defun LM:setdynprops ( blk lst / itm )
    (setq lst (mapcar '(lambda ( x ) (cons (strcase (car x)) (cdr x))) lst))
    (foreach x (vlax-invoke blk 'getdynamicblockproperties)
        (if (setq itm (assoc (strcase (vla-get-propertyname x)) lst))
            (vla-put-value x (vlax-make-variant (cdr itm) (vlax-variant-type (vla-get-value x))))
        )
    )
)

;;;;;;;;;;;;;;;;;;;;;;;;;


;; returns the common props, so we don't set props that don't exist on the destination block
(defun common_props (props1 props2 / res)
  (setq res (list))
  (foreach a props1
    ;; see if that prop exists in props2
    (if (assoc (car a) props2)   ;; skip "Origin"
      (if (/= "Origin" (car a))
        (setq res (append res (list a)))
      )
    )
  )
  res
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;; CDP for Copy Dynamic Block
(defun c:cdp ( / blk props1 props2 cprops bname pt dblk)
  ;; read source block
  (setq blk (car (entsel "\nSelect source block: ")))
  (setq props1 (LM:getdynprops  (vlax-ename->vla-object blk)))
  (while
    (setq dblk (car (entsel "\nSelect destination block: ")))
    (setq props2 (LM:getdynprops  (vlax-ename->vla-object dblk)))
    (setq cprops (common_props props1 props2))
    (LM:setdynprops (vlax-ename->vla-object dblk) cprops)
  )
  (princ)
)

 

Link to comment
Share on other sites

Hey,

I am getting "**bad argument type: stringp nil".

 

maybe my posing of  question was confusing - the annotation blocks are already on an existing drawing. The code I posted at the beginning does a fantastic job of aligning my blocks based on a vertical line I draw but not with these annotation blocks since the insertion point is defined (strangely enough) on the pointer/ leader head. That was my first mistake of defining them that way. Is there a way to modify my lisp to not take the insertion point as a reference to align rather me choosing a point.

the snapshot below is when I run my "alit" lisp:

image.thumb.png.2822680a3fd704ceaa40198d61deb059.png

Link to comment
Share on other sites

If you look at lee-mac.com and get his dynamic property lisp, if you look at  Block Name: "Tx - Leader avec notes - 11x17 - Anglais" "position 2 X" you can change this value very easy, just pick a X point then pick your blocks change to this value a line is not needed. 

 

You may want 2 versions ? A Y version also 

 

I just looked at "Properties" of the block and changed values so you know the dyn variable name.

 

Ok had another look and some problems, the dynamic variable name is different for the blocks but similar control point. You have two choices make a block look up list that has the say point name, alternatively make the blocks all the same way and use the same dynamic name for the common point. For me the latter method. 

 

You need to get the insert point then look at X value 

;sample code starts here  Block Name: Tx - Leader avec notes - 11x17 - Anglais
(setq ptx (car (getpoint "Pick X point")))
(while (setq blk (vlax-ename->vla-object (car (entsel "Pick block"))))
(setq insx (car (vlax-get blk 'insertionPoint)))
(setq x (- ptx insx))
(LM:setdynpropvalue  blk "Position2 X" x)
)

 

Edited by BIGAL
Link to comment
Share on other sites

It worked for me but only the 1 block name that had position2 x they all lined up. I copied the block multiple times.

 

Ok I used a different version of lee-macs dynamic block lisp.

 

;; Set Dynamic Block Property Value  -  Lee Mac
;; Modifies the value of a Dynamic Block property (if present)
;; blk - [vla] VLA Dynamic Block Reference object
;; prp - [str] Dynamic Block property name (case-insensitive)
;; val - [any] New value for property
;; Returns: [any] New value if successful, else nil

(defun LM:setdynpropvalue ( blk prp val )
    (setq prp (strcase prp))
    (vl-some
       '(lambda ( x )
            (if (= prp (strcase (vla-get-propertyname x)))
                (progn
                    (vla-put-value x (vlax-make-variant val (vlax-variant-type (vla-get-value x))))
                    (cond (val) (t))
                )
            )
        )
        (vlax-invoke blk 'getdynamicblockproperties)
    )
)

(defun c:alidyn ( / insx x blk ptx)
(setq ptx (car (getpoint "Pick a point to align to ")))
(while (setq blk (vlax-ename->vla-object (car (entsel "Pick block"))))
(setq insx (car (vlax-get blk 'insertionPoint)))
(setq x (- ptx insx))
(LM:setdynpropvalue blk "Position2 X" x)
)
)

image.thumb.png.a30bbdd77efe9b2557eada7bff86ff90.png

Link to comment
Share on other sites

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...