Jump to content

Select polylines by text inside them (long shot)


rdp

Recommended Posts

Hello all

 

This is probably not possible, but I thought I'd ask you experts :)

 

I have a huge site plan with the building boundaries (polylines) on a layers, and inside them, a text object indicating the height on another layer. What I would like to do is separate those polylines by building height, so I can extrude them separately and make a 3d of my site. Doing it one by one is going to take me many hours.

 

I wonder if there is any way to select polylines (and them put them on separate layers) by the text inside them, knowing that polyline and text are not linked in any way.

 

As I said, this is probably a long shot, but maybe there is a magical script out there?

 

Many thanks for any help

 

:)

Link to comment
Share on other sites

  • Replies 27
  • Created
  • Last Reply

Top Posters In This Topic

  • rdp

    12

  • lrm

    11

  • Dadgad

    2

  • BIGAL

    1

Top Posters In This Topic

Posted Images

Welcome to CADTutor rdp. :)

 

I am sorry that I can't help you with this, but no doubt one who is lisperate could devise a way.

The forum tends to be a bit slow on the weekends, so be a bit patient.

 

Are the polylines all closed?

Are they all independent of one another, meaning no overlap?

How big is the site?

 

Could you post a screenshot of a typical portion of your drawing, as it might shed some light, for anyone who is capable of, or inclined to try and help you with this?

Link to comment
Share on other sites

Hello Dadgad. Thanks for your reply and your welcome!

 

Here is a screenshot of my drawing.

 

The polylines are all closed and they do not overlap (well the boundaries do overlap, but they do not cross each other, if that is what you mean). The drawing looks pretty clean and tidy overall.

The text in the screenshot seems to fall outside the lines in some cases, but the insertion point is always inside the polys (I'm guessing that would be important)

The drawing has around 50000 (!) polys, but surely I can break it up in smaller pieces. I probably won't need to extrude the whole thing anyway.

 

I hope someone can help with this. It would really help me in this project and future ones.

 

Thanks again!attachment.php?attachmentid=60742&cid=1&stc=1

capture.jpg

Link to comment
Share on other sites

A mere 50,000 polylines, and you think doing them old school would bore you? :huh:

 

Certainly seems like a safe assumption that if available, such a lisp might save you more than a little time.

Link to comment
Share on other sites

If I understand the drawing, the closed polylines that surrounds any of the "P's" do not lie within the polyline defined by "II".

PolylineText.jpg

Would the following programming strategy work?

 

The user selects a text string and the program sends a ray in the +x, -x, +y, and -y direction from the text node and looks to see if and odd number of intersections are found in each of the four directions. If so, you have found the polyline associated with that text string and it should be moved to a new layer (or do whatever action you want). Rays that pass exactly through a vertex should be considered as one intersection.

Link to comment
Share on other sites

Hello Irm,

 

 

Yes, you understood it right, that is how the drawing is made. Unfortunately, I know nothing about programming, and wouldnt even begin to know where to start. I was hoping such a lisp existed already, by any chance..

Regardless of that, I don't really follow the odd number logic (doesn't the p in the middle rectangle have 4 intersections around it?), but I trust you programming experts :)

 

Maybe someone feels like giving it a go!

 

p.s. I am having trouble posting. Do the posts need validation or something? I don't see them right after I submit them, I've had to rewrite them a couple of times..

 

Thanks a lot for your reply :)

Link to comment
Share on other sites

... I don't really follow the odd number logic (doesn't the p in the middle rectangle have 4 intersections around it?),...

 

Look at the vertical line going up from the "II" label. It has 5 intersections with the boundary (yellow dots). The ray to the left has 1 intersection. The image is cropped in the other directions but if there were an odd number of intersections in those directions as well then the polyline would be the boundary for the text "II". Notice if the "II" label were moved up slightly there would be 3 intersections to the left. Still an odd number.

 

PolylineText2.jpg

Link to comment
Share on other sites

I have limited lisp experience but am willing to give it a try. Please post a sample file of a dozen or so polygons (not 50,000). Some of the polylines should have unusual shapes not just rectangles.

 

WHat action do want to happen when the polyline matching the selected text is found?

 

~Lee

Link to comment
Share on other sites

A simple selection would be enough. But if they can be automatically moved to a layer with the name of the text string it would be perfect!!

 

(I don't want to thank you in every single post, but thank you!)

Link to comment
Share on other sites

Here's a preliminary version of my "FindPoly" program. I did a little testing on the file you provided and it works most of the time. I still need to do a little debugging.

 

The program works by creating a line from the node of the selected text to a point 10,000 units to the right. If your drawings have geometry that far out in x I would need to increase the value. It then counts the number of intersection with the line and all polylines in the drawing (that are not on a frozen layer). If there are an odd number of intersections the text and the qualifying polyline are moved to the layer with a name defined by the selected text.

 

As I mentioned I have limited experience with Autolisp. The program could be more robust. More experienced programmers may want to improve upon it.

 

There is one known bug. The code I use to determine the intersections considers a line passing exactly through a vertex of the polyline as one intersection instead of two. As a result, polylines with vertices with the same y coordinate of the text node will not be correctly identified. I plan to fix this bug. Perhaps by sending another line at an angle to evaluate intersections.

 

Try out the program and let me know what you think.

 

~Lee

 

;;;;;;;;;;
;; User selects a text object and the program finds the all polylines on
;; unfrozen layers that the node of the text string is inside.
;; It then move the text and polyline to a layer  defined by the name of
;; the text string.
;; It is assumed that the text string is a valid layer name but it need
;; not exist in the drawing.
;;--------------
;; Author: Lee Minardi
;;-------------
;; Version 1.0  - 2/28/2017  known bug- error if polyline vertex has same
;;                            y coordinate as text node
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun C:FindPoly ()
 (setq sspl (ssget "_A" '((0 . "LWPOLYLINE")))) ; get all polylines
 (setq numss (sslength sspl))		; number in selection set
 (princ "\nNumber of polylines evaluated: ")
 (princ numss)
 (princ "\nSelect text");  get text ---
 (setq stxt (ssget))
 (setq entxt (ssname stxt 0))		;entity name text
 (setq ed (entget entxt))		;create list of entity data
 (if (equal (cdr (assoc 0 ed)) "TEXT") ;check if selected object is text
   (progn
     (setq gotText T)			;true
     (setq TextLabel (cdr (assoc 1 ed)))
   )
   (progn
     (setq gotText nil)		;false
     (princ "\nText not selected."
     )
     (exit)
   )
 )
 (setq txtnode (cdr (assoc 10 ed)))
 (setq	xp (list (+ 10000 (nth 0 txtnode)) ; point +x direction 
	 (nth 1 txtnode)
	 (nth 2 txtnode)
   )
 )
 (command "_line" txtnode xp "")
 (setq aline (ssget txtnode))
 (setq enl (ssname aline 0))		;enl = line name
 (setq i 0)
;;; start of polyline search loop -----------------------------------------
 (while (< i numss)
   (setq enp (ssname sspl i))

   (setq IList (InterTwoObject enl enp acExtendNone))
   ;;;(princ TheList)			; list of intersection coordinates
   (setq ni (/ (length TheList) 3)
   )
;;;
;;; Number of intersections incorrect if ray passes exactly through vertex
;;; Need to fix this!! Result is even, should be odd.  Vertex only counted once.
;;;
   (setq OddIntr (rem ni 2.))		; if 1 then odd, if 0.0 the even
   (if	(> OddIntr 0.0)
     (progn				; we have an odd number of intersections
(setq lay TextLabel)
(entmod	(subst (cons 8 lay)	; change layer of polyline
	       (assoc 8 (entget enp))
	       (entget enp)
	)
)
(entmod	(subst (cons 8 lay)	; change layer of text
	       (assoc 8 (entget entxt))
	       (entget entxt)
	)
)
     )
     (progn				; not an odd number, do nothing

     )
   )
   (setq i (1+ i))
 )					; end while
 (setq xpp (list (+ (nth 0 xp) 0.1) (+ (nth 1 xp) 0.1) 0.1))
 (command "_erase" enl "")		; erase temporary line
 (princ)
)					; end defun FindPoly


;;; from  Lupo76 - finds intersection of line and polyline
;;; https://forums.autodesk.com/t5/visual-lisp-autolisp-and-general/vertices-of-a-polyline-segment/td-p/3267324
(defun InterTwoObject (ogg1 ogg2 Mde / )
 (vl-load-com)
 (setq	IntLst (vlax-invoke
	 (vlax-ename->vla-object ogg1)
	 'IntersectWith
	 (vlax-ename->vla-object ogg2)
	 Mde
       )
 )
(setq TheList IntLst)  ; lrm edit to function
 (cond
   (IntLst
    (repeat (/ (length IntLst) 3)
      (setq PntLst (cons
	      (list
		(car IntLst)
		(cadr IntLst)
		(caddr IntLst)
	      )
	      PntLst
	    )
     IntLst (cdddr IntLst)
      )
    )
    (reverse PntLst)
   )
   (T nil)
 )
)

FindPoly-v1.0.lsp

Link to comment
Share on other sites

An alternative go in opposite direction its easy to get a pline retrieve its co-ords and just use ssget with "WP" within polygon check the text if found and you have your answer. Its an old post here.

 

; find text inside a pline 
; by Alan H march 2013
(defun getcoords (ent)
 (vlax-safearray->list
   (vlax-variant-value
     (vlax-get-property
   (vlax-ename->vla-object ent)
   "Coordinates"
     )
   )
 )
)

(defun co-ords2xy ()
; convert now to a list of xy as co-ords are x y x y x y if 3d x y z x y z
(setq numb (/ (length co-ords) 2))
(setq I 0)
(repeat numb
(setq xy (list (nth I co-ords)(nth (+ I 1) co-ords) ))
(setq coordsxy (cons xy coordsxy))
(setq I (+ I 2))
) ; end repeat
) ; end defun
; program starts here
; choose output file change acdatemp to what you want
(setq fname (strcat "c:/acadtemp/" (getstring "\nEnter file name ")))
(setq fout (open fname "w"))
(setq plobjs (ssget (list (cons 0 "lwpolyline"))))
(setq numb1 (sslength plobjs))
(setq x numb1)
(repeat numb1
(setq obj (ssname plobjs (setq x (- x 1))))
(setq co-ords (getcoords obj))
(co-ords2xy)
; write pline co-ords here
(setq numb3 (length co-ords))
(setq z numb3)
(setq ansco-ords "")
(repeat numb3 
(setq ansco-ords (strcat ansco-ords (rtos (nth (setq z (- z 1)) co-ords) 2 3 ) " " ))
)
(setq ans (strcat "Pline " ansco-ords))
(write-line ans fout)
(setq ansco-ords "")
(setq ss (ssget "WP" coordsxy (list (cons 0 "Text,Mtext")))) ; selection set of text within polygon
(if (= ss nil) 
(princ "\nnothing inside")
(progn 
(setq coordsxy nil) ; reset for next time
(setq numb2 (sslength ss))
(setq y numb2)
(repeat numb2
(setq anstext (vlax-get-property (vlax-ename->vla-object (ssname ss (setq y (- y 1)))) "Textstring"))
(princ anstext) ; change to write text to file
(write-line (strcat "text " anstext) fout)
(princ "\n")
) ; end repeat2
(setq ss nil) ; reset for next poly
)
)
) ; end repeat1
(close fout)
(princ)

Link to comment
Share on other sites

Hello Irm, I'm sorry I couldn't reply before. Thanks so much for the program.

 

Unfortunately It does not seem to work here. When I run it, it draws the line, but then I get the following error:

 

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

 

I've searched and apparently it has to do with a faulty install, and the only solution is a fresh reinstall :ouch: I'm going to try it in another computer, and I'll get back to you.

 

Thanks again SO MUCH for your help. You too, BIGAL. I get the same error with that code. I'll test it too.

Link to comment
Share on other sites

BIGAL, thank you for the suggestion. I often find that a good problem solving tactic is to turn the problem upside down. My strategy was to start with the text location and then examine all the polygons. The program you reference looks at each polygon and then looks at the text to see if it is inside the polygon. The advantage with the second approach is that it uses an AutoCAD feature to determine whether a point is inside a polygon or not where I have constructed my own routine to do that. I do not know how robust the "WP" feature is but I will assume it is better than mine. After some feedback from the OP I plan to fix the known bug in my routine rather than rewrite it to use the "WP" feature but if necessary, I will give that a go.

Link to comment
Share on other sites

Hey Irm,

 

I went ahead and reinstalled Autocad. Now the error is gone :)

 

However, either the script is not working or I'm failing to understand it. I run it, select a text object and then it finds only the polyline around that specific object. (which defeats the purpose..)

I have tried filtering by text value, placing all instances of the desired text in a new layer and then freezing the general text layer, so it only finds text with that string when I select. But then it does not work, it finds some other, apparently random, polylines that are not around those text objects..

 

As for BIGAL's approach, I don't really know how to make it work. I run the script, select everything (or just some polys), and get a "bad ssget mode string" error.

Maybe I am not running it correctly, have you tried it?

Link to comment
Share on other sites

rdp,

 

I took your statement "...I wonder if there is any way to select polylines (and them put them on separate layers) by the text inside them, knowing that polyline and text are not linked in any way." to mean that you wanted to be able to select a text string and then have the program find the polyline that the text is inside of. That is what FindPoly does. It also changes the layer of the text and the polyline.

 

If this is not what you want then please give detailed steps of what you, the user does, and what you expect the program to do.

Link to comment
Share on other sites

Hi Irm,

 

Sorry, I probably didn't explain myself clearly. What I would like is exactly what you have accomplished, but in batch (is that the righ word?). Meaning, I select a text object and then the program finds all the polys around all the objects that match the string of the selected text object.

 

But since what you have done is really close, maybe there is a way to tell the program to do what it's doing but keep at it, with every instance that contains that text string.. Or even, as I tried unsuccessfully, let me select many text objects at once (since I can move the text to different layers by their value)

 

Sorry again, and thanks for your help. I wish I could buy you a beer :)

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