insert specified block at the end of polyline

insert specified block at the end of polyline

eng_mohamedmustafa
Enthusiast Enthusiast
2,340 Views
10 Replies
Message 1 of 11

insert specified block at the end of polyline

eng_mohamedmustafa
Enthusiast
Enthusiast

hello

with an attached lisp I can to insert a block with the specified name to the end of the chosen polyline... but insertion done for both ends of polyline >>> i want to insert block for one side only ... thank you

 

(defun c:BAE ( / *error* _StartUndo _EndUndo _Insert _AngleAtParam doc block ss )

 

(vl-load-com)

(setq block "endtick") ;; << Block Name

(defun *error* ( msg )
(and doc (_EndUndo doc))
(or (wcmatch (strcase msg) "*BREAK,*CANCEL*,*EXIT*")
(princ (strcat "\n** Error: " msg " **")))
(princ)
)

(defun _StartUndo ( doc ) (_EndUndo doc)
(vla-StartUndoMark doc)
)

(defun _EndUndo ( doc )
(if (= 8 (logand 8 (getvar 'UNDOCTL)))
(vla-EndUndoMark doc)
)
)

(defun _Insert ( block point rotation )
(entmakex
(list
(cons 0 "INSERT")
(cons 2 block)
(cons 10 point)
(cons 50 rotation)
)
)
)

(defun _AngleatParam ( entity param )
(angle '(0. 0. 0.) (vlax-curve-getFirstDeriv entity param))
)

(setq doc (vla-get-ActiveDocument (vlax-get-acad-object)))

(cond
( (= 4 (logand 4 (cdr (assoc 70 (tblsearch "LAYER" (getvar 'CLAYER))))))

(princ "\n** Current Layer Locked **")
)
( (not
(or
(and (tblsearch "BLOCK" (vl-filename-base block))
(setq block (vl-filename-base block))
)
(and
(setq block
(findfile
(strcat block
(if (eq "" (vl-filename-extension block)) ".dwg" "")
)
)
)
(
(lambda ( / ocm )
(setq ocm (getvar 'CMDECHO)) (setvar 'CMDECHO 0)
(command "_.-insert" block) (command)
(setvar 'CMDECHO ocm)

(tblsearch "BLOCK" (setq block (vl-filename-base block)))
)
)
)
)
)

(princ "\n** Block not Found **")
)
( (not (setq ss (ssget '((0 . "*POLYLINE")))))

(princ "\n*Cancel*")
)
(t

(_StartUndo doc)

(
(lambda ( i / e )
(while (setq e (ssname ss (setq i (1+ i))))
(foreach param (list (vlax-curve-getStartParam e) (vlax-curve-getEndParam e))
(_Insert block (vlax-curve-getPointatParam e param) (_AngleAtParam e param))
)
)
)
-1
)

(_EndUndo doc)
)
)

(princ)
)

 

0 Likes
2,341 Views
10 Replies
Replies (10)
Message 2 of 11

Kent1Cooper
Consultant
Consultant

@eng_mohamedmustafa wrote:

.... but insertion done for both ends of polyline >>> i want to insert block for one side only ...

....

( (not (setq ss (ssget '((0 . "*POLYLINE")))))

....

(foreach param (list (vlax-curve-getStartParam e) (vlax-curve-getEndParam e))
....


 

That operates with a selection set, so that it can put them on the ends of any number of Polylines selected at once, and it just finds the start and endpoints of every Polyline.  May I assume that if you want the Block on only one end, you do not necessarily want them at the same end of all Polylines, i.e. not all at the start or all at the end?  If that's a valid assumption, I assume you would need to pick each Polyline, individually, presumably closer to the end where you want the Block placed.  Is that correct?

Kent Cooper, AIA
0 Likes
Message 3 of 11

eng_mohamedmustafa
Enthusiast
Enthusiast

I want to select more than polyline at the same time but insert this block on the chosen ends not both ends of polylines 

0 Likes
Message 4 of 11

Kent1Cooper
Consultant
Consultant

@eng_mohamedmustafa wrote:

I want to select more than polyline at the same time but insert this block on the chosen ends not both ends of polylines 


That implies that while you select more than one, you still need to pick on each one so that there will be a "chosen end" for each one.  That would mean you can't select them in a window or lasso selection, or if you could, you would then need to go around and pick on a chosen end for each one after  the group selection.

 

If that's the case, it doesn't seem to me that there's any benefit to selection-set multiple-object selection, but instead you may as well pick one and have the Block put on its closer end immediately, then pick the next and its Block would be added, and so on.  If you don't agree, can you describe in detail the steps you expect the User to go through?

Kent Cooper, AIA
0 Likes
Message 5 of 11

eng_mohamedmustafa
Enthusiast
Enthusiast

i want to select polylines seen in the attached photo ... and insert the block that appeared in the photo 

 

spline.png

0 Likes
Message 6 of 11

Kent1Cooper
Consultant
Consultant

I think that could be done IF  you are willing to restrict your selection method(s) to only  either picking individually or with Fence selection [not, for example, with a Crossing window], in both cases closer to the end where you want the Block.  You could combine those methods, for example using two Fence selections, one on either side, or selecting some by Fence and some by individual pick, in the same command.

 

With those selection methods, AutoLisp is capable of knowing at what point each object was selected, either the individual pick point or where the Fence crossed it, and therefore would be able to decide at which end of it to put the Block.  It can't do that with Crossing-window selection, or regular Window, or CP or CW or Lasso or Last or Previous.

Kent Cooper, AIA
0 Likes
Message 7 of 11

eng_mohamedmustafa
Enthusiast
Enthusiast

ok ... can you edit this for me to do this

0 Likes
Message 8 of 11

eng_mohamedmustafa
Enthusiast
Enthusiast

this is another lisp that insert block at the end point of polyline i choose ... i want to edit this to choose multiple point to insert multi blocks (the same block) at the same time ) 

 

(vl-load-com)
(defun C:iar (/ ang obj pickpt pt spt ss)
(setq osm (getvar "osmode"))
(setvar "osmode" 1)
(setq pt (getpoint "\nPick a point near to desured end of polyline >>"))
(if (and(setq ss (ssget pt (list (cons 0 "*POLYLINE"))))
(= 1 (sslength ss)))
(progn
(setq obj (vlax-ename->vla-object (ssname ss 0)))
(setq pickpt (vlax-curve-getclosestpointto obj pt))
(if (< (vlax-curve-getparamatpoint obj pickpt)
(/ (vlax-curve-getendparam obj) 2))
(progn
(setq spt (vlax-curve-getstartpoint obj))
(setq sign nil))
(progn
(setq spt (vlax-curve-getendpoint obj))
(setq sign T))
)
(setq ang (angle '(0. 0. 0.)
(vlax-curve-getfirstderiv
obj
(vlax-curve-getparamatpoint
obj
pickpt
)
)
)
)
(vlax-invoke
(vla-get-modelspace
(vla-get-activedocument (vlax-get-acad-object)))
'InsertBlock
spt
"endtick"
1
1
1
(if sign
ang
(+ ang pi)))
)
)
(setvar "osmode" osm)
(princ)
)

0 Likes
Message 9 of 11

ВeekeeCZ
Consultant
Consultant

@eng_mohamedmustafa wrote:

this is another lisp that insert block at the end point of polyline i choose ... i want to edit this to choose multiple point to insert multi blocks (the same block) at the same time ) 

...


 

You're not listening, not reading. You're totally missing the point. It's about to figure out an ALGORITHM of how to make it MULTIPLE!!! All the rest is easy.

 

(vl-load-com)
; beekeecz

(defun c:PEndArrow ( / :addarrow pt0 pt1 pll pur ptm sel i obj pts pte pnt)
  
  (defun :addarrow (obj pnt / ang)
    (and (setq ang (angle '(0 0) (vlax-curve-getfirstderiv obj (vlax-curve-getparamatpoint obj pnt))))
	 (vlax-invoke (vla-get-modelspace (vla-get-activedocument (vlax-get-acad-object))) 'InsertBlock pnt "_Integral" 1 1 1 ang)))
    
  ; -----------------------------------------------------------------------------------------------------------------------------------------
    
  (if (and (setq pt0 (getpoint "\nFirst point: "))
	   (setq pt1 (getcorner pt0 "\nOpposite corner: " ))
	   (setq pll (list (apply 'min (mapcar 'car (list pt0 pt1)))
			   (apply 'min (mapcar 'cadr (list pt0 pt1)))))
	   (setq pur (list (apply 'max (mapcar 'car (list pt0 pt1)))
			   (apply 'max (mapcar 'cadr (list pt0 pt1)))))
	   (setq ptm (mapcar '/ (mapcar '+ pt0 pt1) '(2 2)))
	   (setq sel (ssget "_C" pll pur '((0 . "LINE,LWPOLYLINE,ARC"))))
	   (or (tblsearch "BLOCK" "_Integral")
	       (prompt "Error: '_Integral' block is not in drawing."))
	   )
    (repeat (setq i (sslength sel))
      (and (setq obj (vlax-ename->vla-object (ssname sel (setq i (1- i)))))
	   (setq pts (vlax-curve-getstartpoint obj))
	   (setq pte (vlax-curve-getendpoint obj))
	   (setq pnt (cond ((and (<= (car  pll) (car  pts) (car  pur))
				 (<= (cadr pll) (cadr pts) (cadr pur)))
			    pts)
			   ((and (<= (car  pll) (car  pte) (car  pur))
				 (<= (cadr pll) (cadr pte) (cadr pur)))
			    pte)
			   ((if (< (distance pts ptm) (distance pte ptm))
			      pts
			      pte))
			   ))
	   (:addarrow obj pnt))))
  (princ)
  )

 Not sure how about the blue part. You might want to comment that out.

0 Likes
Message 10 of 11

Kent1Cooper
Consultant
Consultant

@Kent1Cooper wrote:

I think that could be done IF  you are willing to restrict your selection method(s) to only  either picking individually or with Fence selection [not, for example, with a Crossing window], in both cases closer to the end where you want the Block.  You could combine those methods, for example using two Fence selections, one on either side, or selecting some by Fence and some by individual pick, in the same command.

....


 

Try this [lightly tested, and without the usual enhancements yet]:

(defun C:IBNE ; = Insert Block at Near End
  (/ ss ent nogo)
  (prompt "\nUsing only individual-pick or Fence selection option(s),")
  (if (setq ss (ssget '((0 . "LINE,*POLYLINE,ARC")))) ;; include Spline/Ellipse if open? Ray?
    (foreach item (ssnamex ss)
      (if (member (car item) '(1 4)); individual-pick or Fence selection used
        (progn ; then
          (setq ent (cadr item)); entity name
          (command "_.insert" "YourBlockName" "_scale" 1 "_none"
            (if
              (<
                (vlax-curve-getDistAtPoint ent (vlax-curve-getClosestPointTo ent (last (last item))))
                (/ (vlax-curve-getDistAtParam ent (vlax-curve-getEndParam ent)) 2); half length
              ); <
              (vlax-curve-getStartPoint ent); then -- closer to start
              (vlax-curve-getEndPoint ent); else
            ); if
            (* ; rotation
              (/
                (angle
'(0 0 0)
(vlax-curve-getFirstDeriv ent (vlax-curve-getParamAtPoint ent (getvar 'lastpoint)))
); angle pi ); / 180 ); * ); command ); progn (setq nogo T); else -- selected by wrong method ); if ); foreach ); if (if nogo (prompt "\nSome object(s) selected by incorrect method(s).")) (princ) ); defun
Kent Cooper, AIA
0 Likes
Message 11 of 11

ronjonp
Advisor
Advisor

Here's another grread version based off of code HERE.

(defun c:foo (/ a ang e l p s x)
  ;; RJP » 2019-05-01
  ;; Place block on closest end of polyline using grread
  (cond	((null (tblobjname "block" "sample"))
	 (entmake '((0 . "BLOCK")
		    (100 . "AcDbEntity")
		    (67 . 0)
		    (8 . "0")
		    (100 . "AcDbBlockReference")
		    (2 . "sample")
		    (10 0. 0. 0.)
		    (70 . 0)
		   )
	 )
	 (entmake '((0 . "LWPOLYLINE")
		    (100 . "AcDbEntity")
		    (67 . 0)
		    (8 . "0")
		    (100 . "AcDbPolyline")
		    (90 . 2)
		    (70 . 128)
		    (10 -0.5 0.)
		    (10 0.5 0.)
		   )
	 )
	 (entmake '((0 . "ENDBLK") (100 . "AcDbBlockEnd") (8 . "0")))
	)
  )
  ;; Create a list of points to check against so we're not duplicating blocks
  (and (setq s (ssget "_X" '((0 . "insert") (2 . "sample"))))
       (setq s (mapcar '(lambda (x) (cdr (assoc 10 (entget x)))) (mapcar 'cadr (ssnamex s))))
  )
  (while (and (setq a (grread t 15 0)) (not (member (cadr a) '(13 32))))
    (cond
      ((and (= 5 (car a))
	    (setq e (car (nentselp (setq p (cadr a)))))
	    (= 'list (type (setq l (vl-catch-all-apply 'vlax-curve-getstartpoint (list e)))))
	    (setq l (list l (vlax-curve-getendpoint e)))
	    (setq p (car (vl-sort l '(lambda (a b) (< (distance p a) (distance p b))))))
	    (null (vl-some '(lambda (x) (equal p x 1e-4)) s))
       )
       (setq ang (+ (/ pi 2)
		    (angle '(0 0 0) (vlax-curve-getfirstderiv e (vlax-curve-getparamatpoint e p)))
		 )
       )
       (entmakex (list '(0 . "insert") '(2 . "sample") '(8 . "sample") (cons 10 p) (cons 50 ang)))
       (setq s (cons p s))
      )
    )
  )
  (princ)
)
(vl-load-com)

2019-05-01_13-09-31.gif

0 Likes