Jump to content

Place attributed blocks along lwpolyline length with Tharwat "CATCH PIT" lisp


Cezar Barbalho

Recommended Posts

Hi,

 

i am no autolisper, and i am having trouble to adapt this excellent lisp made by Tharwat to my use... My problem is with the attributes upon insertion, after the command, no attribute appear on the drawing. I will not post my attempts on doing so, (for they are really messy...) but the original code and the description of what i inttend to do.

 

My block has 3 attribs, ID, KM and M.

 

ID must be prompted by user upon inserction;

KM must be taken from the lwspline length (variable l), i.e.: if swpline is 350120,00 m long, then KM is 350, if swpline is 120,00m long, then KM is 000;

M must be treated the same way as KM, but in 350120,00, M is 120 and so on...

 

The text output format on the drawing is "km 350+120"

 

sample insert.PNG

 

Test.lsp

 

[ATTACH]58954[/ATTACH]

Link to comment
Share on other sites

  • Replies 27
  • Created
  • Last Reply

Top Posters In This Topic

  • Cezar Barbalho

    14

  • Tharwat

    12

  • Lee Mac

    2

Top Posters In This Topic

Posted Images

I am lost with that drawing , just upload an example with BEFORE & AFTER which means old and final result and there is no need for all the other objects in the drawing at the mean time to allow me to get what you want to do.

Link to comment
Share on other sites

I am lost with that drawing , just upload an example with BEFORE & AFTER which means old and final result and there is no need for all the other objects in the drawing at the mean time to allow me to get what you want to do.

 

Sorry, i think the next one is adequate...

SAMPLE 2.dwg

Link to comment
Share on other sites

The program did not work because it is written for regular blocks and not for attributed blocks.;)

 

But for the sample drawing you provided the length of the polyline is 100.8675 and what to do in this case?

 

Sorry I did not get what you mean by the following sentence ? what is if polyline is in different lengths?

KM must be taken from the lwspline length (variable l), i.e.: if swpline is 350120,00 m long, then KM is 350, if swpline is 120,00m long, then KM is 000;

Link to comment
Share on other sites

I see... i always join the polylines in one, for i am a railroad engineer and the polyline represents an railroad aligntment. Usually the drawing is in meters, and is kilometers long, in order to do my job manually, i have to measure the inserction point and write it down, this is really a big time consumer since there are hundreds of objects to be placed along kilometers of railroad at irregular intervals... it would save time if the placement and placement information where put via lisp.

 

In that sentence, i tried to explain in "Lisp terms" what i do manually, in railroad drawing i can't supress the leading zeroes, if an item is placed at 120 meters from the start of the railroad, the correct information is that this item is placed at "kilometer 000 plus 120 meters" (km 000+120). Other example location could be that an item is located at "kilometer 350 plus 012 meters" (km 350+012). Eventually different project phases require centimeters input as if after the comma as "km 350+012,50", but this is not an so common case on my job...

 

Sorry if i don't seem to express myself clearly, i am not used to english conversations, only english technical reading... Thanks for being comprehensive.

 

I dont' mind in working with a regular block... but can i automatize the text insertion in another way?

Link to comment
Share on other sites

Oh... I'm sorry, maybe you was talking about an polyline METERS long... in such a case, i would do the job manually. By the other hand, if the drawing units are in km, meters or unitless i would change it accordingly to adapt to the lisp functionalities.

Link to comment
Share on other sites

I guess you still did not answer my question.

 

You said that when the length of the polyline is 350120,00 m long, then KM is 350, if polyline is 120,00m long, then KM is 000 s what to do with the other lengths of selected polylines?

 

Have a look at the last uploaded drawing and measure the length of the polyline to get what I am indicating to.

Link to comment
Share on other sites

In the example the polyline is 100 meters long (Legth 100,8675 on acad properties display), so i need to show something like "km 000+100", if the length was multiplied by one thousand resulting in 100 km ( if it was Length 100867,500 on acad properties display), it should show something like "km 100+867".

 

Again, sorry if i am not being clear, it's my fault because i am not fluent in english.

 

In other terms, what i want is that this block have a text with it's position in a text formated to look like "km XXX + YYY" automatically.

Link to comment
Share on other sites

This is really exhausting :lol:

 

Try it and let me know.

 

(defun c:Test (/ *error* blk bk atts sp s e l d v km m lng)
 ;; Tharwat 11.Aug.2016 ;;
 (defun *error* (msg)
   (if atts
     (mapcar 'setvar '(ATTREQ ATTDIA) atts)
   )
   (and msg
        (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*"))
        (princ (strcat "\nError => " msg))
   )
   (princ)
 )
 (setq blk "BLOCO SINALEIRO")
 ;; Block name
 (if (and (tblsearch "BLOCK" blk)
          (princ "\nSelect LWpolyline :")
          (setq s (ssget "_+.:S:E" '((0 . "LWPOLYLINE"))))
          (setq l (vlax-curve-getdistatpoint
                    (setq e (ssname s 0))
                    (vlax-curve-getendpoint e)
                  )
          )
     )
   (progn
     (setq atts (mapcar 'getvar '(ATTREQ ATTDIA))
           sp   (vlax-get (vla-get-activelayout
                            (vla-get-activedocument (vlax-get-acad-object))
                          )
                          'Block
                )
           km   (if (= (setq lng (length (vl-string->list (rtos l 2 0)))) 3)
                  "000"
                  (strcat (nth (- lng 3) '("" "00" "0"))
                          (substr (rtos l 2 0) 1 (- lng 3))
                  )
                )
           m    (if (= lng 3)
                  (substr (rtos l 2 2) 1 3)
                  (substr (rtos l 2 2) (1+ (- lng 3)) 3)
                )
     )
     (mapcar 'setvar '(ATTREQ ATTDIA) '(1 0))
     (while
       (and (setq d (getdist (strcat "\nSpecify distance less than "
                                     (rtos l 2 2)
                                     " > :"
                             )
                    )
            )
            (< d l)
            (/= "" (setq v (getstring t "\nSpecify Attribute Value :")))
            (setq bk (vla-insertblock
                       sp
                       (vlax-3d-point (vlax-curve-getpointatdist e d))
                       blk
                       1.0
                       1.0
                       1.0
                       (+ (* pi 0.5)
                          (angle '(0. 0. 0.)
                                 (vlax-curve-getfirstderiv
                                   e
                                   (vlax-curve-getparamatpoint
                                     e
                                     (vlax-curve-getpointatdist e d)
                                   )
                                 )
                          )
                       )
                     )
            )
       )
        (mapcar
          '(lambda (a)
             (vla-put-textstring
               a
               (nth (vl-position (vla-get-tagstring a) '("ID" "KM" "M"))
                    (list v km m)
               )
             )
           )
          (vlax-invoke bk 'getattributes)
        )
     )
   )
 )
 (if (> d l)
   (alert "\nLong distance entered !")
 )
 (*error* nil)
 (princ)
)(vl-load-com)

Link to comment
Share on other sites

Ipressive mr Tharwat!

 

But i think when i was trying to explain myself, i mistook variable "l" for variable "d"... because variable "d" is the insert point in distance, thus is the source for the information "km XXX+YYY"... I am trying to correct this, but i am not having much luck... sorry, but what do you think?

Link to comment
Share on other sites

I think that if i put the SETQ d on the start, it would work, then i pass onto the SETQ km, m and so on... can you tell me if i am on the right course?

 

Thanks

 

 (PROGN (SETQ d    (GETDIST
		(STRCAT "\nSpecify distance less than " (RTOS l 2 2) " > :")
	      )
	 atts (MAPCAR 'GETVAR '(attreq attdia))
	 sp   (VLAX-GET	(VLA-GET-ACTIVELAYOUT
			  (VLA-GET-ACTIVEDOCUMENT (VLAX-GET-ACAD-OBJECT))
			)
			'block
	      )
	 km   (IF (= (SETQ lng (LENGTH (VL-STRING->LIST (RTOS d 2 0)))) 3)
		"000"
		(IF (< lng 3 (STRCAT (NTH (- 3 lng) '("" "00" "0"))
			       (SUBSTR (RTOS d 2 0) 1 (- lng 3))
		       )
		    )
		)
	      )
	 m    (IF (= lng 3)
		(SUBSTR (RTOS d 2 2) 1 3)
		(SUBSTR (RTOS d 2 2) (1+ (- lng 3)) 3)
	      )
   )
   ) 

Link to comment
Share on other sites

Hi Cezar,

 

It is okay, and don't worry I will modify the codes to suit your needs regardless of your mistake.

So just explain your needs clearly compared to my final posted program in post# 11.

Link to comment
Share on other sites

Hi Tharwat,

 

compared to the previous version, I want to switch the variable "l" by the variable "d" on

 

km   (if (= (setq lng (length (vl-string->list (rtos l 2 0)))) 3)
                  "000"
                  (strcat (nth (- lng 3) '("" "00" "0"))
                          (substr (rtos l 2 0) 1 (- lng 3))
                  )
                )
           m    (if (= lng 3)
                  (substr (rtos l 2 2) 1 3)
                  (substr (rtos l 2 2) (1+ (- lng 3)) 3)
                )  

 

I think that way, the attributes will show the information of the insertion point of the block.

 

As it is now, it show me the total length of the polyline, not the location of the block relative to polyline length.

 

In my attempt, I was trying to do this, first I put the SETQ "d" before the others, then I received error messages about the NTH function, so I was trying to understand it, I think I have learned much more in one day exchanging messages here than reading for one month. Am I on the right track?

Link to comment
Share on other sites

Hi Cezar,

The variable 'd' represents distance value which means real number ( decimal number ) and not block position.

 

Show me an example with a drawing as you have did before to allow me to modify the program in one go.

Link to comment
Share on other sites

Hope this would work as expected, try it and let me know;

 

(defun c:Test (/ *error* blk bk atts sp s e l d v km m lng)
 ;; Tharwat 11.Aug.2016 ;;
 (defun *error* (msg)
   (if atts
     (mapcar 'setvar '(ATTREQ ATTDIA) atts)
   )
   (and msg
        (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*"))
        (princ (strcat "\nError => " msg))
   )
   (princ)
 )
 (setq blk "BLOCO SINALEIRO")
 ;; Block name
 (if (and (tblsearch "BLOCK" blk)
          (princ "\nSelect LWpolyline :")
          (setq s (ssget "_+.:S:E" '((0 . "LWPOLYLINE"))))
          (setq l (vlax-curve-getdistatpoint
                    (setq e (ssname s 0))
                    (vlax-curve-getendpoint e)
                  )
          )
     )
   (progn
     (setq atts (mapcar 'getvar '(ATTREQ ATTDIA))
           sp   (vlax-get (vla-get-activelayout
                            (vla-get-activedocument (vlax-get-acad-object))
                          )
                          'Block
                )
     )
     (mapcar 'setvar '(ATTREQ ATTDIA) '(1 0))
     (while
       (and (setq d (getdist (strcat "\nSpecify distance less than "
                                     (rtos l 2 2)
                                     " > :"
                             )
                    )
            )
            (< d l)
            (/= "" (setq v (getstring t "\nSpecify Attribute Value :")))
            (setq km (if
                       (<= (setq lng (length (vl-string->list (rtos l 2 0))))
                           3
                       )
                        "000"
                        (strcat (nth (- lng 3) '("" "00" "0" "" ""))
                                (substr (rtos l 2 0) 1 (- lng 3))
                        )
                     )
                  m  (if
                       (<= (setq lng (length (vl-string->list (rtos d 2 0))))
                           3
                       )
                        (substr (rtos d 2 2) 1 3)
                        (substr (rtos d 2 2) (1+ (- lng 3)) 3)
                     )
                  bk (vla-insertblock
                       sp
                       (vlax-3d-point (vlax-curve-getpointatdist e d))
                       blk
                       1.0
                       1.0
                       1.0
                       (+ (* pi 0.5)
                          (angle '(0. 0. 0.)
                                 (vlax-curve-getfirstderiv
                                   e
                                   (vlax-curve-getparamatpoint
                                     e
                                     (vlax-curve-getpointatdist e d)
                                   )
                                 )
                          )
                       )
                     )
            )
       )
        (mapcar
          '(lambda (a)
             (vla-put-textstring
               a
               (nth (vl-position (vla-get-tagstring a) '("ID" "KM" "M"))
                    (list v km m)
               )
             )
           )
          (vlax-invoke bk 'getattributes)
        )
     )
   )
 )
 (if (> d l)
   (alert "\nLong distance entered !")
 )
 (*error* nil)
 (princ)
)(vl-load-com)

Edited by Tharwat
Link to comment
Share on other sites

Hi Tharwat,

 

it's working, but i have found a limitation on the polyline length, if i try to use a polyline longer than 100 kilometers, it freezes the program.

This issue is something easy to work around?

Link to comment
Share on other sites

Sorry, this is the third time you are talking about something different than what you have asked from your first post in this thread.

I am confused about these different inputs and what you exactly want to do.

 

I have spent too much time on this thread, and sorry I am not able to continue endlessly.

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