Jump to content

Parse text information into a pasteclip routine


wing

Recommended Posts

I've got an idea for an autolisp routine. I'd like to select text or mtext objects with bearing and distance (in metric units of course) and generate a paste_clip that I can paste into.

 

i.e.:

 

  1. I click on a text that has 12%%d01'10" as its text content.
  2. I click on a text that has 10.01 as its text content.
  3. repeat for other segments
  4. I press on c or esc to end the input.
  5. I get a "nice" paste_clip on my mouse cursor where I specify the insertion point (The first line segment being 12°01'10" orientation and 10.01 for its length.)

 

Being a novice autolisp programmer, can somebody point me in the right direction please? I have some experience with outputting text, lines and points but this is a bit tougher. A polyline would be nicer to have but I don't mind a series of lines too at this stage.

Link to comment
Share on other sites

hi wing, welcome to forum :)

so you are going to click & paste one by one?

also where to paste? notepad?

parse means replace %%d with degrees symbol?

(defun %%d (str)
(vl-string-subst (chr 176)
(substr str (1+ (vl-string-search "%" str)) 3)
str))

argument string

(%%d "12%%d01'10")
;retval= "12°01'10" 

my suggestion is using (ssget) selection faster

Edited by hanhphuc
Link to comment
Share on other sites

A couple of ways. Its probably easier to write a temp file and read a file than to play with copy paste. The 2nd is to create a two pair list and just loop through them writing line after line or strcat them then save as one long list.

 

(("12°01'10" 10.01)("15°01'10" 22.12))

("12°01'10 10.01" "15°01'10 22.12")

 

3rd if you have drawn the lines correct why bother with the text just pick lines or plines etc.

Link to comment
Share on other sites

Thanks for the replies. Judging on the replies I don't think I made myself clear. I apologize for that. What I meant was the text or mtext objects carrying the bearing and distance information are already existing on the cad drawing.

 

Lines are not necessarily drawn to scale or even in the right orientation. Historical, rounding, plan legibility and legal reasons. Don't ask me why. I am in the same boat. All I am going to say is, the textual information is what is legally significant. Which is why, a lot of cadastral work is checking and redrawing what the textual information says it is.

 

By creating lines just based on clicking the mtext object I hope to save time on line/pline/arc command entry. I hope this helps on the context of why I want to write this.

Link to comment
Share on other sites

If I understood correctly, and as a starting point:

(defun c:demo (/ A ANG B C D S)
 (if (setq c (getpoint "\nEnter the line startpoint: "))
   (while (and (princ "\nSelect the text with the direction: ")
               (setq a (ssget "_+.:E:S" '((0 . "TEXT,MTEXT"))))
               (princ "\nSelect the text with the distance: ")
               (setq b (ssget "_+.:E:S" '((0 . "TEXT,MTEXT"))))
          )
     (if (and (setq s (strcase (cdr (assoc 1 (entget (ssname a 0))))))
              (setq ang (angtof (strcat (substr (vl-string-subst "d" "%%D" s) 1 (- (strlen s) 1)))
                                3
                        )
              )
         )
       (if (setq d (atof (cdr (assoc 1 (entget (ssname b 0))))))
         (entmake (list (cons 0 "LINE")
                        (cons 10 c)
                        (cons 11
                              (setq c (polar c ang d))
                        )
                  )
         )
       )
     )
   )
 )
 (princ)
)

 

Hope that helps

Henrique

Link to comment
Share on other sites

If you pick manually it is possible human error which selecting wrong text etc.. unless can reverse action/undo.

your 1st post item #5 insertion of text? or you can attach dwg?

Thanx BIGAL's idea better can be output to csv or table.

Link to comment
Share on other sites

Presuming user would only be selecting 2 text entities, and only 1 would contain %%d you could preclude the need to manually select each, one-at-a-time, instead letting the code-behind filter for SSLENGTH = 2, followed by WCMATCH or VL-STRING-SEARCH query for %%d.

 

My $0.02

 

 

 

Cheers

Link to comment
Share on other sites

Presuming user would only be selecting 2 text entities, and only 1 would contain %%d you could preclude the need to manually select each, one-at-a-time, instead letting the code-behind filter for SSLENGTH = 2, followed by WCMATCH or VL-STRING-SEARCH query for %%d.

My $0.02

Cheers

Well thought out!

(defun c:demo1 (/ _test a b lst pt ss)

 (defun _test (x y / ang d)
   (if (and (wcmatch x "*%%D*")
            (setq ang
                   (angtof (strcat (substr (vl-string-subst "d" "%%D" x) 1 (- (strlen x) 1)))
                           3
                   )
            )
            (setq d (atof y))
            (/= d 0.0)
       )
     (list ang d)
   )
 )

 (if (setq pt (getpoint "\nEnter the line startpoint: "))
   (while (and (princ "\nSelect the texts with the direction and the distance: ")
               (setq ss (ssget '((0 . "TEXT,MTEXT"))))
               (= 2 (sslength ss))
               (setq a (strcase (cdr (assoc 1 (entget (ssname ss 0))))))
               (setq b (strcase (cdr (assoc 1 (entget (ssname ss 1))))))
               (or (setq lst (_test a b))
                   (setq lst (_test b a))
               )
          )
     (entmake (list (cons 0 "LINE")
                    (cons 10 pt)
                    (cons 11
                          (setq pt (polar pt (car lst) (cadr lst)))
                    )
              )
     )
   )
 )
 (princ)
)

 

Cheers

Henrique

Link to comment
Share on other sites

Well thought out!

 

That is kind of you to say, Henrique; thank you.

 

One could also instead use the Count Property of the ActiveDocument's ActiveSelectionSet Object in lieu of SSLENGTH, and VLAX-FOR on same, instead of SSNAME, which would already provide the Object needed for VLA-*UNDOMARK calls as well.

 

Cheers

Link to comment
Share on other sites

That is kind of you to say, Henrique; thank you.

One could also instead use the Count Property of the ActiveDocument's ActiveSelectionSet Object in lieu of SSLENGTH, and VLAX-FOR on same, instead of SSNAME, which would already provide the Object needed for VLA-*UNDOMARK calls as well.

Cheers

Would be a good approach.

But as the OP said:

Being a novice autolisp programmer, can somebody point me in the right direction please?

I think it will be better to keep the code as simple as possible for easier understanding...

 

 

Cheers

Henrique

Link to comment
Share on other sites

I think it will be better to keep the code as simple as possible for easier understanding...

 

If they're so new, they don't understand your code either, or they would have written/posted it already... Besides, the OP requested to be pointed in the right direction. :thumbsup:

 

 

 

... Just kidding. :rofl:

 

Cheers

Link to comment
Share on other sites

If I understood correctly, and as a starting point:

[\CODE]

Hope that helps

Henrique

great mr. hmsilva i think you got the right direction for the OP's request :)

initially i thought OP wanted to collect the text insertion in pasteclip, until you figured out it by "redrawing". thank you.

 

 

Presuming user would only be selecting 2 text entities, and only 1 would contain %%d you could preclude the need to manually select each, one-at-a-time, instead letting the code-behind filter for SSLENGTH = 2, followed by WCMATCH or VL-STRING-SEARCH query for %%d.

My $0.02

Cheers

Thank you sir for the guide, but i'll try to minimize hitting [Enter] without ssget.

 

(defun c:test (/ p au l) ;
;hanhphuc 10/01/2014
 (setq	p  (getpoint "\nNew base point..")
au (mapcar 'getvar '("angbase" "angdir" "aunits"))
) ;_ end of setq
 (mapcar 'setvar [color="red"] '("angbase" "angdir" "aunits") [/color] (list (* pi 0.5) 1 1)) ; edit: v1.1
 (while (and p
      (vl-every	''((ss) (and ss (atof ss)))
		(setq l	(mapcar	''((x)
				   (if
				    x
				    (cdr (assoc 1 (entget (car x))))
				    )
				   )
				(list (entsel "\nPick Bearing text: ") (entsel "\nPick Distance text: "))
				) ;_ end of mapcar
		      ) ;_ end of mapcar
		) ;_ end of vl-every
      (wcmatch (car l) "*%%*")
      (not (zerop (atof (cadr l))))
      (setq l (vl-list*
		(subst ('((%) (vl-string-subst (chr 176) (substr % (1+ (vl-string-search "%" %)) 3) %)) (car l))
		       (car l)
		       l
		       ) ;_ end of subst
		) ;_ end of vl-list*
	    ) ;_ end of setq
      ) ;_ end of and
   (entmakex
     (list '(0 . "LINE")
    (cons 10 p)
    (cons 11 (setq p (apply 'polar (vl-list* p (list (angtof (car l) 1) (atof (cadr l)))))))
    ) ;_ end of list
     ) ;_ end of entmake
   ) ;_ end of defun
 (mapcar 'setvar '("angbase" "angdir" "aunits") au)
 (princ)
 ) ;_ end of defun

Edited by hanhphuc
Link to comment
Share on other sites

great mr. hmsilva i think you got the right direction for the OP's request :)

 

FWIW - I was sincerely kidding with hmsilva.

 

 

 

Thank you sir for the guide, but i'll try to minimize hitting [Enter] without ssget.

 

... I'd personally prefer to hit [Enter] (or right click), than have to select the text entities in order. :thumbsup:

 

 

 

(defun c:test (/ p au l) ;
;hanhphuc 10/01/2014
 (setq	p  (getpoint "\nNew base point..")
au (mapcar 'getvar '("angbase" "angdir" "aunits"))
) ;_ end of setq
 (mapcar 'setvar au (list (* pi 0.5) 1 1))
 (while (and p
      (vl-every	''((ss) (and ss (atof ss)))
		(setq l	(mapcar	''((x)
				   (if
				    x
				    (cdr (assoc 1 (entget (car x))))
				    )
				   )
				(list (entsel "\nPick Bearing text: ") (entsel "\nPick Distance text: "))
				) ;_ end of mapcar
		      ) ;_ end of mapcar
		) ;_ end of vl-every
      (wcmatch (car l) "*%%*")
      (not (zerop (atof (cadr l))))
      (setq l (vl-list*
		(subst ('((%) (vl-string-subst (chr 176) (substr % (1+ (vl-string-search "%" %)) 3) %)) (car l))
		       (car l)
		       l
		       ) ;_ end of subst
		) ;_ end of vl-list*
	    ) ;_ end of setq
      ) ;_ end of and
   (entmakex
     (list '(0 . "LINE")
    (cons 10 p)
    (cons 11 (setq p (apply 'polar (vl-list* p (list (angtof (car l) 1) (atof (cadr l)))))))
    ) ;_ end of list
     ) ;_ end of entmake
   ) ;_ end of defun
 (mapcar 'setvar '("angbase" "angdir" "aunits") au)
 (princ)
 ) ;_ end of defun

 

I sure hope user doesn't miss, and that they select the right objects on first try. o:)

 

Cheers

Link to comment
Share on other sites

If they're so new, they don't understand your code either, or they would have written/posted it already... Besides, the OP requested to be pointed in the right direction. :thumbsup:

I must agree with you!

The right direction was pointed out.... 8)

 

... Just kidding.

Cheers

Really?

I've been flying all night and couldn't sleep thinking about this... :x

 

Cheers, my friend! :notworthy:

Henrique

Link to comment
Share on other sites

Fantastic Henrique!

 

Is there any way to use that code to radius and distance too?

 

I'm attaching a example.

 

Thank you

 

example.dwg

Edited by Madruga_SP
Link to comment
Share on other sites

I must agree with you!

The right direction was pointed out.... 8)

 

:lol:

 

 

Really?

I've been flying all night and couldn't sleep thinking about this... :x

 

Cheers, my friend! :notworthy:

 

Sinto muito, meu amigo. Tenha cuidado, calças Mentiroso em chamas. :thumbsup: :rofl:

Link to comment
Share on other sites

Presuming user would only be selecting 2 text entities, and only 1 would contain %%d you could preclude the need to manually select each, one-at-a-time, instead letting the code-behind filter for SSLENGTH = 2, followed by WCMATCH or VL-STRING-SEARCH query for %%d.

 

My $0.02

 

 

 

Cheers

Thanks BlackBox, just to clarify, I would like to use this to check for misclosure errors as well as redrawing. So, it will have to be pairs of angles and distances and not just one pair. I guess there must be some sort of "end" input so the program stops asking for further text entity input and generates the linework.

 

This webpage explains misclosure well. Bottom half of the page with two figures.

 

http://www.gvec.net/txsurvey/fn.html

(but of course, I like my metric units so no imperial units! :oops:)

 

 

The "polyline" linework might close properly to form a "polygon" but the text says it doesn't due to rounding. The text label will have to be rounded down to a certain precision (e.g.: nearest 10 seconds in angle and nearest centimetre).

 

Thank you all so much for your efforts, I like the idea of writing into a temp file or list of lists. I think the starting point should be defined later but that's something I can adjust from the codes you guys have written. I prefer that the "ghost" shape of the entire linework be visible before I define starting point, like in cut and pasteclip. Is this possible with autolisp?

Link to comment
Share on other sites

No worries; I've not seen an image or drawing of what you're working with, but assuming the four text entities are generally collocated about the respective pairs, it's a relatively simple task to also evaluate which are nearest the other prior to performing the same task of identifying which contains %%d.

 

Cheers

 

 

 

[Edit] - as for drawing the individual line segments, you can either use transient graphics, or PLINE Command, with a common CMDACTIVE SysVar check for PAUSE.

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