Block align to end pline (s) multiples

Block align to end pline (s) multiples

Edwin.Saez
Advisor Advisor
4,255 Views
45 Replies
Message 1 of 46

Block align to end pline (s) multiples

Edwin.Saez
Advisor
Advisor

Hi

I come to your great help: oops: so I can Provide some lisp routine for the following:

* I want to place a block That multiply at the ends of Several polylines, perpendicular and Placing them to leave the color, and the layer of each polyline are Selecting.
I Explained in the best dwg I'm attached.

Edwin Saez


LinkedIn / AutoCAD Certified Professional


EESignature


 


Si mi respuesta fue una solución para usted, por favor seleccione "Aceptar Solución", para que también sirva a otro usuarios.

0 Likes
Accepted solutions (3)
4,256 Views
45 Replies
Replies (45)
Message 2 of 46

Kent1Cooper
Consultant
Consultant

That should not be difficult, but it would be much easier if you can REDEFINE THE BLOCK so that its rotation direction goes directly along the Polyline, that is, so that when Inserted at zero degrees rotation it looks like this:  EDIT:  Never mind -- I see now that it is already defined that way -- the isolated one in the drawing is Inserted at 90 degrees.

BlockOrientation.PNG

 

Also, if those are Polylines, are they always just single-segment ones [that would also make it easier], or might they sometimes continue beyond the other end, with things like bends or arc segments?  Even with a single-segment Polyline, might it ever be a single arc segment?  Might they ever be just Lines?

Kent Cooper, AIA
0 Likes
Message 3 of 46

Edwin.Saez
Advisor
Advisor

hi @Kent1Cooper :

 

They would have to be polylines, since the idea is that selecting several near its end perpendicular block is inserted as shown in dwg to attach.

 

muestra.png

Edwin Saez


LinkedIn / AutoCAD Certified Professional


EESignature


 


Si mi respuesta fue una solución para usted, por favor seleccione "Aceptar Solución", para que también sirva a otro usuarios.

0 Likes
Message 4 of 46

john.uhden
Mentor
Mentor

Kent:

 

Might he want to be using something like


(setq Ang (apply 'atan (reverse (@2d (vlax-curve-getFirstDeriv Object (vlax-curve-getparamatpoint Object P)) ) ) ) ) ;; where (defun @2d (p) (list (car p)(cadr p)) )

John F. Uhden

0 Likes
Message 5 of 46

Kent1Cooper
Consultant
Consultant

That looks like it would depend on the direction in which the Polyline was drawn.  To cover both possibilities, there should be a test of whether the endpoint in question is the start or end of the object, and reverse that angle if it's at the end.  Or it could take the angle not from the first derivative, but from the endpoint in question to the point at either the next- or the previous-parameter vertex, again depending on which end you're at.

Kent Cooper, AIA
0 Likes
Message 6 of 46

Edwin.Saez
Advisor
Advisor

@john.uhden thanks for answering,

 

 

@Kent1Cooper

 

passing through the polyline, the block should jogging and have the same angle of the last segment of the polyline.
you have any further questions for you to help me with a lisp?

 

Edwin Saez


LinkedIn / AutoCAD Certified Professional


EESignature


 


Si mi respuesta fue una solución para usted, por favor seleccione "Aceptar Solución", para que también sirva a otro usuarios.

0 Likes
Message 7 of 46

Kent1Cooper
Consultant
Consultant

@Edwin.Saez.Jamanca wrote:

@john.uhden 

passing through the polyline, the block should jogging and have the same angle of the last segment of the polyline.
you have any further questions for you to help me with a lisp?


Yes, just to confirm that if the Block goes at the start ["upstream" end] end of a Polyline, it should have the same rotation as the angle of the first segment, but if it's at the "downstream" end, it should have rotation 180 degrees around from the angle of the last segment.  [If it's the same angle as the direction of the last segment, it will face away from the end.]

 

Also, would the end to put such a Block on ever be a Polyline arc segment?  It can be done, easily enough, but could be a little simpler if they are always line segments.

Kent Cooper, AIA
0 Likes
Message 8 of 46

Edwin.Saez
Advisor
Advisor

@Kent1Cooper

 

(Start or end is relative), the block should always be only one side of the polyline (the side will be the closer to where select the polyline).
This means that if at some point is necario placed on both sides, will select both end sides of the segment of the polyline.
will never be arc segments. will always only straight segments.

Edwin Saez


LinkedIn / AutoCAD Certified Professional


EESignature


 


Si mi respuesta fue una solución para usted, por favor seleccione "Aceptar Solución", para que también sirva a otro usuarios.

0 Likes
Message 9 of 46

john.uhden
Mentor
Mentor

With what I wrote in post #4 you should be able to figure it out.

If the point selected is closer to one end vs. the other then adjust the angle appropriately by additive pi, depending on the block definition and which way you want it to face.

The point is that (vlax-curve-getfirstderiv) will return a 3D list of the tangent angle at the point selected, whether the segment is straight or curved.

John F. Uhden

0 Likes
Message 10 of 46

Edwin.Saez
Advisor
Advisor

@john.uhden 

thanks for your help,

 the problem is that I'm still in my 2nd class lisp.Smiley Sad

 and I need you to help me with the complete LISP code. Smiley Embarassed

Edwin Saez


LinkedIn / AutoCAD Certified Professional


EESignature


 


Si mi respuesta fue una solución para usted, por favor seleccione "Aceptar Solución", para que también sirva a otro usuarios.

0 Likes
Message 11 of 46

CADaSchtroumpf
Advisor
Advisor

Try this!

 

(vl-load-com)
(defun c:blk2end ( / js n obj dxf_obj obj_vlax pt1_start pt2_start par pt1_end pt2_end name_blk scale_blk dxf_210)
(defun z_dir (p1 p2 / )
  (trans
    '(0.0 1.0 0.0)
    (mapcar
      '(lambda (k)
        (/ k
          (sqrt
            (apply '+
              (mapcar
                '(lambda (x) (* x x))
                (mapcar '- p2 p1)
              )
            )
          )
        )
      )
      (mapcar '- p2 p1)
    )
    0
  )
)
  (princ "\nSelect polylines: ")
  (setq js (ssget '((0 . "LWPOLYLINE, POLYLINE"))))
  (repeat (setq n (sslength js))
    (setq obj (ssname js (setq n (1- n))))
    (cond
      ((zerop (boole 1 112 (cdr (assoc 70 (setq dxf_obj (entget obj))))))
        (setq
          obj_vlax (vlax-ename->vla-object obj)
          pt1_start (vlax-curve-getStartPoint obj_vlax)
          pt1_end (vlax-curve-getEndPoint obj_vlax)
          par (vlax-curve-getParamAtPoint obj_vlax pt1_end)
        )
        (cond
          ((not (zerop par))
            (setq
              pt2_start (vlax-curve-getPointAtParam obj_vlax 1)
              pt2_end (vlax-curve-getPointAtParam obj_vlax (1- par))
            )
            (if (not name_blk)
              (while (not (tblsearch "BLOCK" (setq name_blk (getstring "\nName of block?: " T))))
                (princ "\n ** incorrect name block! **")
              )
            )
            (if (not scale_blk)
              (progn
                (initget 7)
                (setq scale_blk (getreal "\nInsertion scale of block?: "))
              )
            )
            (foreach n (list (list pt1_end pt1_start))
              (setq dxf_210 (z_dir (car n) (cadr n)))
              (entmake
                (list
                  (cons 0 "INSERT")
                  (cons 100 "AcDbEntity")
                  (assoc 67 dxf_obj)
                  (assoc 410 dxf_obj)
                  (cons 8 (cdr (assoc 8 dxf_obj)))
                  (cons 100 "AcDbBlockReference")
                  (cons 2 name_blk)
                  (cons 10 (trans (car n) 0 dxf_210))
                  (cons 41 scale_blk)
                  (cons 42 scale_blk)
                  (cons 43 scale_blk)
                  (cons 50 (angle (trans (car n) 0 dxf_210) (trans (cadr n) 0 dxf_210)))
                  (cons 210 dxf_210)
                )
              )
            )
          )
        )
      )
      (T
        (princ "\nIsn't 2Dpolyline avalaible for this function!")
      )
    )
  )
  (prin1)
)
Message 12 of 46

Edwin.Saez
Advisor
Advisor

hi @CADaSchtroumpf,

 Thank you for your contribution but,


- the lisp causes the block is placed at the end of the polyline, but not perpendicular (inserted with a different rotation).
- Do not placed on the side closer to the polyline, only at the end vertex. Smiley Frustrated

Edwin Saez


LinkedIn / AutoCAD Certified Professional


EESignature


 


Si mi respuesta fue una solución para usted, por favor seleccione "Aceptar Solución", para que también sirva a otro usuarios.

0 Likes
Message 13 of 46

john.uhden
Mentor
Mentor

This ought to work, depending on the block definition.  I tested it with a block whose entities are to the right of its insertion point.

If you need it the other way, then it's a simple fix I will do for you.

The command is "BATEND."

 

;; Block At End by John Uhden 11-6-16
;; For Edwin Saez Jamanca
(defun c:Batend ( / *error* @2d P E D Dend Ang1 Ang2)
    (or *acad* (setq *acad* (vlax-get-acad-object)))
    (or *doc* (setq *doc* (vla-get-ActiveDocument *acad*)))
    (defun *error* (error)
      (if (vl-position cmdecho '(0 1))(setvar "cmdecho" cmdecho))
      (vla-endundomark *doc*)
      (cond
        ((not error))
        ((wcmatch (strcase error) "*QUIT*,*CANCEL*"))
        (1
          (princ (strcat "\nERROR: " error))
        )
      )
      (princ)
    )
    (defun @2d (p)(if p (list (car p)(cadr p))))
    (vla-endundomark *doc*)
    (vla-startundomark *doc*)
    (setq cmdecho (getvar "cmdecho"))
    (setvar "cmdecho" 0)
    (command "_.expert" (getvar "expert"))
    (and
       (setq Bname (getstring "\nEnter block name to insert: "))
       (or
         (tblsearch "block" Bname)
         (setq Bname (findfile (strcat Bname ".dwg")))
         (prompt (strcat Bname " neither defined nor found."))
       )
       (while (setq  E (entsel "\nSelect polyline anywhere near preferred end: "))
         (setq P (cadr E)
                    E (car E)
                    P (vlax-curve-getclosestpointto E P)
                    D (vlax-curve-getdistatpoint E P)
                    Dend (vlax-curve-getdistatparam E (vlax-curve-getendparam E))
        )
        (if (> D (/ Dend 2))
          (setq Ang (apply 'atan (reverse (@2d (vlax-curve-getfirstderiv E (vlax-curve-getendparam E)))))
                     P (vlax-curve-getpointatdist E Dend)
          )
          (setq Ang (+ (apply 'atan (reverse (@2d (vlax-curve-getfirstderiv E 0.0)))) pi)
                     P (vlax-curve-getpointatparam E 0.0)
          )
        )
        (vl-cmdf "_.insert" Bname P "" "" (angtos Ang 1 4))
      )
    )
    (*error* nil)
  )

John F. Uhden

0 Likes
Message 14 of 46

Edwin.Saez
Advisor
Advisor

hi @john.uhden

 

Might modified to:
- Only it allows me to select a polyline at a time, and must allow multiple selection
- The block is inserted into the original angle but should be inserted with the angle of the polyline in which is placed

 

thanks for answering

 

Edwin Saez


LinkedIn / AutoCAD Certified Professional


EESignature


 


Si mi respuesta fue una solución para usted, por favor seleccione "Aceptar Solución", para que también sirva a otro usuarios.

0 Likes
Message 15 of 46

john.uhden
Mentor
Mentor
Hey Uhden, you simpleton. Your code allows picking any object, not just a polyline. It happens to work with lines, but only halfway with arcs, and circles are a laugh. It will obviously fail on anything that is not a vlax-curve thingy. Shame!

John F. Uhden

0 Likes
Message 16 of 46

Edwin.Saez
Advisor
Advisor

@john.uhden.

 

I know it's complicated, but seriously would greatly appreciate your help as it is a routine I have to do much.
I appreciate you're helping me Smiley Embarassed

Edwin Saez


LinkedIn / AutoCAD Certified Professional


EESignature


 


Si mi respuesta fue una solución para usted, por favor seleccione "Aceptar Solución", para que también sirva a otro usuarios.

0 Likes
Message 17 of 46

john.uhden
Mentor
Mentor
In post #8 you said "(Start or end is relative), the block should always be only one side of the polyline (the side will be the closer to where select the polyline).
This means that if at some point is necario placed on both sides, will select both end sides of the segment of the polyline."

So you want to select multiple polylines at once? Like by Window or Crossing? In that case I can see placing the block insertion at the start, or at the end, or at both ends, but I don't see how to determine which end (if they are to vary) by such method of selection.

John F. Uhden

0 Likes
Message 18 of 46

Edwin.Saez
Advisor
Advisor
could by selection "fence" go putting the block on the side nearest the end of the polyline? (The nearest side where the "fence" pass by polyline)
if not could, then it would be best that it can be a multiple selection regardless it is placed at both ends of the polilina.

Edwin Saez


LinkedIn / AutoCAD Certified Professional


EESignature


 


Si mi respuesta fue una solución para usted, por favor seleccione "Aceptar Solución", para que también sirva a otro usuarios.

0 Likes
Message 19 of 46

john.uhden
Mentor
Mentor
When you say "side" I presume you really mean "end."
I don't have any experience using ssnamex, but I like learning.
So... if the selection is by fence or single selection, then insert at only
the closest end to the point of selection, right? If by window or
crossing, then insert at both ends, right?
When you tested, did the angle come out correctly, or was it off by 180°?

John F. Uhden

0 Likes
Message 20 of 46

Edwin.Saez
Advisor
Advisor

this is how you say.
and as for the angle in which it is inserted, it does so with the original angle of the block.
It does not change the angle that should suit the polyline perpendicular as shown in the image.

 

Block.jpg

Edwin Saez


LinkedIn / AutoCAD Certified Professional


EESignature


 


Si mi respuesta fue una solución para usted, por favor seleccione "Aceptar Solución", para que también sirva a otro usuarios.

0 Likes