Draw polyline with one shape at one end and another shape at the opposite end

Draw polyline with one shape at one end and another shape at the opposite end

Homecad2007
Enthusiast Enthusiast
2,610 Views
22 Replies
Message 1 of 23

Draw polyline with one shape at one end and another shape at the opposite end

Homecad2007
Enthusiast
Enthusiast

Hi there, is is possible to draw a polyline with a rectanlge at the start or end and lets say a circle at the opposite end.  I am trying to use it for a schematic drawing, shapes could differ but I would be ok with a rectangle and circle for starters.  If anyone knows how to even start something like this or examples of similar it would be appreciated.

 

Thanks

Tony

0 Likes
Accepted solutions (3)
2,611 Views
22 Replies
Replies (22)
Message 2 of 23

Sea-Haven
Mentor
Mentor

Do you know anything about lisp ?

 

What you asked for is very simple, when you draw a line, pline or arc you can get start and end point lots of examples. One of the easier is using vlaxcurve properties 

 

; draw a line 
(setq end (vlax-curve-getendpoint (entlast)))
(setq start(vlax-curve-getstartpoint (entlast)))
; draw a pline 
repeat code
; draw a arc
repeat code

 

; simple draw a box 
; By Alan H March 2019
' info@alanh.com.au

(defun ah:box ( / pt1 pt2 pt3 ahl ahh)
(setq oldsnap (getvar 'osmode))
(setq oldang (getvar 'angdir))
(setq pt1 (getpoint "\nPick lower left"))
(setvar 'osmode 0)

(setq ahl (getreal  "\nEnter length")  
        ahh (getreal "\nEnter height "))

(setq ahL (atof (nth 0 ans)))
(setq ahH (atof (nth 1 ans)))
(setq pt2 (polar pt1 0.0 ahl))
(setq pt3 (polar pt2 (/ pi 2.0) ahh))

(command "rectang" pt1 pt3)

)
(ah:box)

 

0 Likes
Message 3 of 23

Kent1Cooper
Consultant
Consultant

Something like this, perhaps [untested]:

(defun C:SLRR (/ pt wid ht); = Square Left Round Right
  (setq
    pt (getpoint "\nLower left corner: ")
    wid (getdist pt "\nHorizontal overall size: ")
    ht (getdist pt "\nVertical size: ")
  ); setq
  (command "_.pline"
    "_non" pt
    "_non" (polar pt 0 (- wid (/ ht 2)))
    "_arc" "_non" (polar (getvar 'lastpoint) (/ pi 2) ht)
    "_line" "_non" (polar pt (/ pi 2) ht)
    "_close"
  ); command
); defun

That's in simplest terms, and could have typical enhancements, but see whether it does what you want.  It could be made to prompt for various other things, such as horizontal or vertical orientation, which end should be round, angle if not always orthogonal, and [for the horizontal orientation] it could check that the horizontal size is at least half the vertical size [otherwise it's not geometrically viable], etc.

 

If it does what you want, study the functions involved in the >AutoLisp Functions Reference<, and you should get an idea of how you can make different shapes.  If that set of functions can't define a particular shape for you, there are more ways to calculate locations relative to other locations.

Kent Cooper, AIA
0 Likes
Message 4 of 23

Homecad2007
Enthusiast
Enthusiast

2020-12-22 7-52-38 AM.png

 Hi there, and thanks for the quick responses.  So basically this is what I am trying to achieve.  The size of rectangle could change and the size of circle could change.  The linetype of the polyline could also change but not as important right now

0 Likes
Message 5 of 23

Kent1Cooper
Consultant
Consultant

Obviously I misunderstood the original description -- a picture is worth....

 

That looks possible, but how would you picture the User procedure?  There could be a command for one with a rectangle at the start and a circle at the end, and a separate command for one with circles at both ends, and a separate command for a circle at the start and a rectangle at the end, and a separate command for... [you get the idea].  Or it could be one command that asks for the shape to use at each end.  The sizes of the end things could be built in, or it could ask for them.  I expect Blocks would be better for the things at the ends than drawing shapes, especially if the shapes might get more complex.  Would the end points that the User would pick be the ends of the between-shapes path part, or the midpoints of the shapes at the ends?  Etc., etc.

Kent Cooper, AIA
0 Likes
Message 6 of 23

CADaSchtroumpf
Advisor
Advisor

Hi,

You use shapes, for try...

(vl-load-com)
(defun C:MY_pline ( / f_shp tbl_st ok_rect ok_circ start_pl end_pl obj dxf_ent pt_start pt_snd pt_end pt_prv)
  (if (not (findfile "RECTANG.shp"))
    (progn
      (setq f_shp (open (strcat (getvar "ROAMABLEROOTPREFIX") "support\\RECTANG.shp") "w"))
      (write-line "*250,6,RECTANG" f_shp)
      (write-line "014,018,02C,010,014,0" f_shp)
      (close f_shp)
      (command "_.compile" (strcat (getvar "ROAMABLEROOTPREFIX") "support\\RECTANG.shp"))
    )
  )
  (if (not (findfile "CIRCLE.shp"))
    (progn
      (setq f_shp (open (strcat (getvar "ROAMABLEROOTPREFIX") "support\\CIRCLE.shp") "w"))
      (write-line "*250,4,CIRCLE" f_shp)
      (write-line "10,1,000,0" f_shp) 
      (close f_shp)
      (command "_.compile" (strcat (getvar "ROAMABLEROOTPREFIX") "support\\CIRCLE.shp"))
    )
  )
  (while (setq tbl_st (tblnext "STYLE" (not tbl_st)))
    (if (eq (cdr (assoc 3 tbl_st)) "support\\rectang.shx") (setq ok_rect T))
    (if (eq (cdr (assoc 3 tbl_st)) "support\\circle.shx") (setq ok_circ T))
  )
  (if (not ok_rect)
    (entmakex
      '(
        (0 . "STYLE")
        (100 . "AcDbSymbolTableRecord")
        (100 . "AcDbTextStyleTableRecord")
        (2 . "")
        (70 . 1)
        (40 . 0.0)
        (41 . 1.0)
        (50 . 0.0)
        (71 . 0)
        (42 . 2.5)
        (3 . "RECTANG.shx")
        (4 . "")
       )
    )
  )
  (if (not ok_circ)
    (entmakex
      '(
        (0 . "STYLE")
        (100 . "AcDbSymbolTableRecord")
        (100 . "AcDbTextStyleTableRecord")
        (2 . "")
        (70 . 1)
        (40 . 0.0)
        (41 . 1.0)
        (50 . 0.0)
        (71 . 0)
        (42 . 2.5)
        (3 . "CIRCLE.shx")
        (4 . "")
       )
    )
  )
  (initget 1 "Rectang Circle")
  (Setq start_pl (getkword "\nWhat you wont at start of pline [Rectang/Circle]; ?"))
  (initget 1 "Rectang Circle")
  (Setq end_pl (getkword "\nWhat you wont at end of pline [Rectang/Circle]; ?"))
  (command "_.pline"
    (while (not (zerop (getvar "cmdactive")))
      (command pause)
    )
  )
  (setq
    obj (vlax-ename->vla-object (entlast))
    dxf_ent (entget (entlast))
    pt_start (vlax-curve-GetPointAtParam obj (vlax-curve-getStartParam obj))
    pt_snd (vlax-curve-GetPointAtParam obj (1+ (vlax-curve-getStartParam obj)))
    pt_end (vlax-curve-GetPointAtParam obj (vlax-curve-getEndParam obj))
    pt_prv (vlax-curve-GetPointAtParam obj (1- (vlax-curve-getEndParam obj)))
  )
  (entmake
    (list
      (cons 0 "SHAPE")
      (cons 100 "AcDbEntity")
      (assoc 67 dxf_ent)
      (assoc 410 dxf_ent)
      (assoc 8 dxf_ent)
      (if (assoc 62 dxf_ent) (assoc 62 dxf_ent) (cons 62 256))
      (if (assoc 6 dxf_ent) (assoc 6 dxf_ent) (cons 6 "BYLAYER"))
      (if (assoc 370 dxf_ent) (assoc 370 dxf_ent) (cons 370 -1))
      (cons 100 "AcDbShape")
      (cons 10 pt_start)
      (cons 40 1.0)
      (cons 2 (strcase start_pl))
      (cons 50 (angle pt_start pt_snd))
      (cons 41 1.0)
      (cons 51 0.0)
      (assoc 210 dxf_ent)
    )
  )
  (entmake
    (list
      (cons 0 "SHAPE")
      (cons 100 "AcDbEntity")
      (assoc 67 dxf_ent)
      (assoc 410 dxf_ent)
      (assoc 8 dxf_ent)
      (if (assoc 62 dxf_ent) (assoc 62 dxf_ent) (cons 62 256))
      (if (assoc 6 dxf_ent) (assoc 6 dxf_ent) (cons 6 "BYLAYER"))
      (if (assoc 370 dxf_ent) (assoc 370 dxf_ent) (cons 370 -1))
      (cons 100 "AcDbShape")
      (cons 10 pt_end)
      (cons 40 1.0)
      (cons 2 (strcase end_pl))
      (cons 50 (angle pt_end pt_prv))
      (cons 41 1.0)
      (cons 51 0.0)
      (assoc 210 dxf_ent)
    )
  )
  (prin1)
)

You change the height of shape after... or in the code

0 Likes
Message 7 of 23

Homecad2007
Enthusiast
Enthusiast

I receive the following error

no function definition: VLAX-ENAME->VLA-OBJECT

 

I see you are calling for rectangle.shp and circle.shp, are these from a font or shape file I need or are these getting created.  I also see rectang.shx and circle.shx but not sure where these are coming from

 

Thanks

Tony

0 Likes
Message 8 of 23

Homecad2007
Enthusiast
Enthusiast

Hi Kent

 

So the way I see this function is to have it work similar to a polyline.  Use begins the command and has a choice of starting with either a rectangle or circle (size could change as well) ...then continue by drawing a pline from the first shape and ending with either a rectangle or circle (size could be determined at the start of the command)

 

Thanks

Tony

0 Likes
Message 9 of 23

Kent1Cooper
Consultant
Consultant
Accepted solution

I find Blocks much easier to deal with.  Attached is my take on it, Schematic.lsp with its Schematic command.

 

If the Circle Block it uses is not in the drawing, it makes both Circle and Rectangle Blocks [the only shapes already included, but see below].

 

It asks what shape you want at the start and at the finish, and what size [for a Circle, the diameter; for a Rectangle, the sizes in both the direction of the path end and perpendicular to that].  If the shape at the finish is the same as at the start, it doesn't ask for the size(s), but uses the same as the one at the start [it could be enhanced to allow different sizes, if needed].  It remembers your choices of shapes and size(s), and offers them as defaults on subsequent use.

 

You then draw the Polyline path, using any and all options available within the command, and when you finish, it puts the shapes at the ends.  The path can aim in any direction at either end [and can even be closed -- it's your responsibility not to do that], and that's why it has you draw the path before it puts in either end shape -- it needs the path there to determine from its start & end directions where to put the Block insertion points and what rotation angles to use.

 

These were drawn with it:

Kent1Cooper_0-1608665519939.png

 

It's all set up for the possibility of additional Block shapes, the making of which can be added into the Setup routine.  None of what it does uses (if) functions with only two choices [such as if-a-Circle, do the Circle thing, if-not, do the Rectangle thing], but it uses (cond) functions with specific conditions by shape, into which appropriate code for other shapes can be added.

 

Kent Cooper, AIA
Message 10 of 23

CADaSchtroumpf
Advisor
Advisor

@Homecad2007  a écrit :

I receive the following error

no function definition: VLAX-ENAME->VLA-OBJECT


Did you copy the instruction (vl-load-com) at the start of the code?

Otherwise try the vanilla lisp version, it's the same process.

(defun C:MY_pline ( / f_shp tbl_st ok_rect ok_circ start_pl end_pl dxf_ent lst_pt pt_start pt_snd pt_end pt_prv)
  (if (not (findfile "RECTANG.shp"))
    (progn
      (setq f_shp (open (strcat (getvar "ROAMABLEROOTPREFIX") "support\\RECTANG.shp") "w"))
      (write-line "*250,6,RECTANG" f_shp)
      (write-line "014,018,02C,010,014,0" f_shp)
      (close f_shp)
      (command "_.compile" (strcat (getvar "ROAMABLEROOTPREFIX") "support\\RECTANG.shp"))
    )
  )
  (if (not (findfile "CIRCLE.shp"))
    (progn
      (setq f_shp (open (strcat (getvar "ROAMABLEROOTPREFIX") "support\\CIRCLE.shp") "w"))
      (write-line "*250,4,CIRCLE" f_shp)
      (write-line "10,1,000,0" f_shp) 
      (close f_shp)
      (command "_.compile" (strcat (getvar "ROAMABLEROOTPREFIX") "support\\CIRCLE.shp"))
    )
  )
  (while (setq tbl_st (tblnext "STYLE" (not tbl_st)))
    (if (eq (cdr (assoc 3 tbl_st)) "support\\rectang.shx") (setq ok_rect T))
    (if (eq (cdr (assoc 3 tbl_st)) "support\\circle.shx") (setq ok_circ T))
  )
  (if (not ok_rect)
    (entmakex
      '(
        (0 . "STYLE")
        (100 . "AcDbSymbolTableRecord")
        (100 . "AcDbTextStyleTableRecord")
        (2 . "")
        (70 . 1)
        (40 . 0.0)
        (41 . 1.0)
        (50 . 0.0)
        (71 . 0)
        (42 . 2.5)
        (3 . "RECTANG.shx")
        (4 . "")
       )
    )
  )
  (if (not ok_circ)
    (entmakex
      '(
        (0 . "STYLE")
        (100 . "AcDbSymbolTableRecord")
        (100 . "AcDbTextStyleTableRecord")
        (2 . "")
        (70 . 1)
        (40 . 0.0)
        (41 . 1.0)
        (50 . 0.0)
        (71 . 0)
        (42 . 2.5)
        (3 . "CIRCLE.shx")
        (4 . "")
       )
    )
  )
  (initget 1 "Rectang Circle")
  (Setq start_pl (getkword "\nWhat you wont at start of pline [Rectang/Circle]; ?"))
  (initget 1 "Rectang Circle")
  (Setq end_pl (getkword "\nWhat you wont at end of pline [Rectang/Circle]; ?"))
  (command "_.pline"
    (while (not (zerop (getvar "cmdactive")))
      (command pause)
    )
  )
  (setq
    dxf_ent (entget (entlast))
    lst_pt
    (mapcar
      '(lambda (x) (trans x (cdr (assoc 210 dxf_ent)) 0))
      (mapcar '(lambda (x) (append x (list (cdr (assoc 38 dxf_ent)))))
        (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 10)) dxf_ent))
      )
    )
    pt_start (nth 0 lst_pt)
    pt_snd (nth 1 lst_pt)
    pt_end (nth (1- (cdr (assoc 90 dxf_ent))) lst_pt)
    pt_prv (nth (- (cdr (assoc 90 dxf_ent)) 2) lst_pt)
  )
  (entmake
    (list
      (cons 0 "SHAPE")
      (cons 100 "AcDbEntity")
      (assoc 67 dxf_ent)
      (assoc 410 dxf_ent)
      (assoc 8 dxf_ent)
      (if (assoc 62 dxf_ent) (assoc 62 dxf_ent) (cons 62 256))
      (if (assoc 6 dxf_ent) (assoc 6 dxf_ent) (cons 6 "BYLAYER"))
      (if (assoc 370 dxf_ent) (assoc 370 dxf_ent) (cons 370 -1))
      (cons 100 "AcDbShape")
      (cons 10 pt_start)
      (cons 40 1.0)
      (cons 2 (strcase start_pl))
      (cons 50 (angle pt_start pt_snd))
      (cons 41 1.0)
      (cons 51 0.0)
      (assoc 210 dxf_ent)
    )
  )
  (entmake
    (list
      (cons 0 "SHAPE")
      (cons 100 "AcDbEntity")
      (assoc 67 dxf_ent)
      (assoc 410 dxf_ent)
      (assoc 8 dxf_ent)
      (if (assoc 62 dxf_ent) (assoc 62 dxf_ent) (cons 62 256))
      (if (assoc 6 dxf_ent) (assoc 6 dxf_ent) (cons 6 "BYLAYER"))
      (if (assoc 370 dxf_ent) (assoc 370 dxf_ent) (cons 370 -1))
      (cons 100 "AcDbShape")
      (cons 10 pt_end)
      (cons 40 1.0)
      (cons 2 (strcase end_pl))
      (cons 50 (angle pt_end pt_prv))
      (cons 41 1.0)
      (cons 51 0.0)
      (assoc 210 dxf_ent)
    )
  )
  (prin1)
)

 

 

0 Likes
Message 11 of 23

Homecad2007
Enthusiast
Enthusiast

That would work great, thats pretty much what I am looking for, I am just getting the following error so not sure what I am doing wrong with the command

 

no function definition: VLAX-CURVE-GETSTARTPOINTSpecify insertion point or [Basepoint/Scale/X/Y/Z/Rotate]:
Point or option keyword required.
Specify insertion point or [Basepoint/Scale/X/Y/Z/Rotate]: *Cancel*

0 Likes
Message 12 of 23

Kent1Cooper
Consultant
Consultant

@Homecad2007 wrote:

....

no function definition: VLAX-CURVE-GETSTARTPOINT....


Here we go again....  There have been other recent threads in which people got that message even though the (vl-load-com) was included to load the (vl...) functions.  [Usually the cause is that (vl-load-com) has not been done, but it's in the code, both mine and @CADaSchtroumpf 's.]  I forget whether there was a solution other than something drastic like reloading AutoCAD [maybe Auditing was enough?], but I'll let you Search.

Kent Cooper, AIA
0 Likes
Message 13 of 23

Homecad2007
Enthusiast
Enthusiast
Accepted solution
So a reinstall of Autocad got this to work.  Thanks for the program it looks great and works great!  I also found another solution from Autodesk and I posted their notes below for anyone else who has this problem.

 

Thanks again Kent

  Causes:Missing or incorrect Registry entries:

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{A4081F53-974E-479E-A26E-E6DE9A5B2489}]
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{A4081F53-974E-479E-A26E-E6DE9A5B2489}\1.0]
@="Visual Lisp ActiveX module"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{A4081F53-974E-479E-A26E-E6DE9A5B2489}\1.0\0]
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{A4081F53-974E-479E-A26E-E6DE9A5B2489}\1.0\0\win32]
@="vl16.tlb"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{A4081F53-974E-479E-A26E-E6DE9A5B2489}\1.0\0\win64]
@="C:\\Program Files\\Autodesk\\<Latest installed version of AutoCAD>\\vl16.tlb"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{A4081F53-974E-479E-A26E-E6DE9A5B2489}\1.0\FLAGS]
@="2"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{A4081F53-974E-479E-A26E-E6DE9A5B2489}\1.0\HELPDIR]
@="C:\\Program Files\\Autodesk\\<Latest installed version of AutoCAD>"
Solution:Ensure the vl16.tlb file exists in path: C:\Program Files\Autodesk\<Latest installed version of AutoCAD>\vl16.tlb.

Download the attached lspfix.zip file and change its file extension from .zip to .reg. This registry file is configured for AutoCAD 2020 as the installed version. However, if running a different version, open the file in any text editor and adjust the paths accordingly. For example:

[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{A4081F53-974E-479E-A26E-E6DE9A5B2489}\1.0\0\win64]
@=" C:\\Program Files\\Autodesk\\AutoCAD 2018\\vl16.tlb"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{A4081F53-974E-479E-A26E-E6DE9A5B2489}\1.0\FLAGS]
@="2"
[HKEY_LOCAL_MACHINE\SOFTWARE\Classes\TypeLib\{A4081F53-974E-479E-A26E-E6DE9A5B2489}\1.0\HELPDIR]
@=" C:\\Program Files\\Autodesk\\AutoCAD 2018"

Save the file and then double-click it to update the registry keys.
0 Likes
Message 14 of 23

Sea-Haven
Mentor
Mentor

Hi Kent

 

Tried the code in Bricscad and got the error as reported not sure why as I write nearly everything in Bricscad, will try to track it down and post what I find. I know your code is always bullet proof. 

 

For me something like this as a front end would write the dcl as part of code.

 

screenshot310.png

 

 

 

0 Likes
Message 15 of 23

Sea-Haven
Mentor
Mentor

Just tried in Autocad works fine did notice one thing should line join at mid not cross ?

 

screenshot311.png

0 Likes
Message 16 of 23

Sea-Haven
Mentor
Mentor

It seems to be working in Bricscad now and rectang is from middle correct. I pasted (command-s "_.pline") and it worked as a single line very strange.

 

 ;(command-s "_.pline"); draw path
  (command "pline" )
       (while (> (getvar "cmdactive") 0 ) (command pause))

 

in code version 
(command-s "_.pline")
: _.pline
Select start of polyline or [Follow] <Last point>:_.insert
Unable to recognize entry. Please try again.
Select start of polyline or [Follow] <Last point>:SchCirc
Unable to recognize entry. Please try again.
Select start of polyline or [Follow] <Last point>:_non
0 Likes
Message 17 of 23

Kent1Cooper
Consultant
Consultant

@Sea-Haven wrote:

....

in code version 
(command-s "_.pline")
: _.pline
Select start of polyline or [Follow] <Last point>:_.insert
Unable to recognize entry. Please try again.
....

That's not what the PLINE prompt looks like for me.  I'm still using 2019 -- is this a difference in a newer version?

Kent Cooper, AIA
0 Likes
Message 18 of 23

Homecad2007
Enthusiast
Enthusiast

2020-12-26 10-38-29 AM.png

2020-12-26 10-38-44 AM.png

 

Is it possible to make the segment all one so that if you erase it the entire segment is selected.  Currently the rectangle and circle are separated

0 Likes
Message 19 of 23

Kent1Cooper
Consultant
Consultant

@Homecad2007 wrote:

Is it possible to make the segment all one so that if you erase it the entire segment is selected.  Currently the rectangle and circle are separated


It could be made to put the three pieces together into another Block [which could mean a lot Block names in a complex drawing, and keeping track of them to give an unused name to each one], or, probably better, into a Group [you wouldn't need to give them names, and you could still Stretch the configurations].  I am not on my AutoCAD computer right now, but I'll look into it next time.

Kent Cooper, AIA
0 Likes
Message 20 of 23

Sea-Haven
Mentor
Mentor

This is what is in your code (command-s "_.pline"); draw path for some reason the command-s does not work properly in Bricscad V19 as mentioned fine in Autocad 2020. Using cmd-active method works fine in both Bricscad and Autocad.

 

The command-s will work in Bricscad just struggling to find out why its not working in your code. Some small test code worked fine in Bricscad pline is being created.

 

 

0 Likes