Jump to content

Prevent boundary creation around MTEXT.


AbdRF

Recommended Posts

Hello,

I have a lisp which draw internal boundary based on the text/mtext  inside enclosed areas (such as rooms,etc). But one issue I am facing is that if there is mtext ,it draws boundary around mtext also which I don't want. Refer below image for details
image.thumb.png.2af8386e74b976263a98c2ffd0843c84.png
Also, guys the lisp is somewhat very slow in most cases and I can't figure out why it is so? 
Please find the attached lisp file and sample drawing.

Thanks !!

Boundary_Sam_CT.dwg

CB.lsp
 

Link to comment
Share on other sites

(command "BOUNDARY" ) is the last thing you want to use. (command) is normally a very slow process, especially if you have tons of texts.

 

Below is my attempt with the help of Lee's Selection Set Bounding Box. The user will be prompted to select polylines instead of texts, and uses the vertices of those polylines to automatically create a window selection of the texts.

 

My attempt won't create diagonal boundaries as it uses vla-getboundingbox to return the lower left and upper right coordinates of the texts no matter how they are oriented.

 

(defun c:txtbound ( / acadobj adoc corn ent i maxpt minpt sp ss)
  (setq acadobj (vlax-get-acad-object)
	adoc (vla-get-ActiveDocument acadobj)
	)

  (vla-StartUndoMark adoc)
  (if (setq ss (ssget '((0 . "LWPOLYLINE"))))
    (repeat (setq i (sslength ss))
      (vla-GetBoundingBox (vlax-ename->vla-object (setq ent (ssname ss (setq i (1- i))))) 'minpt 'maxpt)
      (vla-ZoomWindow acadobj minpt maxpt)
      (setq sp (ssget "_WP" (JH:RemoveAdjacentDuplicates (mapcar 'cdr (append (vl-remove-if-not '(lambda (x) (= (car x) 10)) (entget ent)) (list (assoc 10 (entget ent)))))) '((0 . "TEXT,MTEXT"))))
      (vla-ZoomPrevious acadobj)
      (if sp
	(progn
	  (setq corn (apply 'JH:rectcorner (LM:ssboundingbox sp)))
	  (entmake
	    (append
	      '(
		(0 . "LWPOLYLINE")
		(100 . "AcDbEntity")
		(100 . "AcDbPolyline")
		(90 . 4)
		(70 . 1)
		(62 . 1)   ; <--- Color set to red. Remove line to set to default
		(43 . 10)  ; <--- Thickness set to 10. Remove if desired to set to 0
		(38 . 0)
		(39 . 0)
		)
	      (apply 'append
		     (mapcar '(lambda (x)
				(list
				  (cons 10 x)
				  '(42 . 0)
				  '(91 . 0)
				  )
				)
			     corn
			     )
		     )
	      )
	    )
	  )
	)
      )
    )
  (vla-EndUndoMark adoc)
  (princ)
  )


;; Selection Set Bounding Box  -  Lee Mac
;; Returns a list of the lower-left and upper-right WCS coordinates of a
;; rectangular frame bounding all objects in a supplied selection set.
;; sel - [sel] Selection set for which to return bounding box

(defun LM:ssboundingbox ( sel / idx llp ls1 ls2 obj urp )
    (repeat (setq idx (sslength sel))
        (setq obj (vlax-ename->vla-object (ssname sel (setq idx (1- idx)))))
        (if (and (vlax-method-applicable-p obj 'getboundingbox)
                 (not (vl-catch-all-error-p (vl-catch-all-apply 'vla-getboundingbox (list obj 'llp 'urp))))
            )
            (setq ls1 (cons (vlax-safearray->list llp) ls1)
                  ls2 (cons (vlax-safearray->list urp) ls2)
            )
        )
    )
    (if (and ls1 ls2)
        (mapcar '(lambda ( a b ) (apply 'mapcar (cons a b))) '(min max) (list ls1 ls2))
    )
)

;; JH:rectcorner --> Jonathan Handojo
;; Returns the four vertices of the rectangle given the corner points a and b

(defun JH:rectcorner (a b / )
  (mapcar '(lambda (x)
	     (list
	       (apply (car x) (mapcar 'car (list a b)))
	       (apply (last x) (mapcar 'cadr (list a b)))
	       )
	     )
	  '(
	    (min min)
	    (max min)
	    (max max)
	    (min max)
	    )
	  )
  )

;; JH:RemoveAdjacentDuplicates --> Jonathan Handojo
;; Removes points that gives zero-lengths between them
;; Example call: JH:RemoveAdjacentDuplicates (a b c c d e e f a a g) ---> (a b c d e f a g)
;; Doing ssget F, WP, CP, or other requiring list of point will return nil if zero-length segments are found
;; lst - list of points

(defun JH:RemoveAdjacentDuplicates (lst / tst)
  (setq tst lst)
  (vl-remove nil (mapcar '(lambda (x) (if (null (equal x (car (setq tst (cdr tst))) 1e-8)) x)) lst))
  )

 

Edited by Jonathan Handojo
Link to comment
Share on other sites

Jonathan there was a post about best fit for an object that was calculating a bounding box including on an angle, pretty sure Lee has something not sure though if it will work with text.

 

;; Minimum Bounding Box  -  Lee Mac
;; Returns the WCS coordinates describing the minimum bounding rectangle

 

Try tol 0.01

Edited by BIGAL
Link to comment
Share on other sites

2 hours ago, BIGAL said:

Jonathan there was a post about best fit for an object that was calculating a bounding box including on an angle, pretty sure Lee has something not sure though if it will work with text.

 

;; Minimum Bounding Box  -  Lee Mac
;; Returns the WCS coordinates describing the minimum bounding rectangle

 

Try tol 0.01

 

Haha, how careless of me, I never knew that existed. It seems it's an iterative approach and can be a bit slower, though I haven't tried it yet. But by looking at that routine, the smaller your tol, the slower the command will run (not that we can probably note the difference, but...)

Link to comment
Share on other sites

13 hours ago, Jonathan Handojo said:

 

Below is my attempt with the help of Lee's Selection Set Bounding Box. The user will be prompted to select polylines instead of texts, and uses the vertices of those polylines to automatically create a window selection of the texts.


@Jonathan Handojo first of all ,I would like to appreciate your helping nature with everyone on the forum and you seems to be very down to earth 😇
I would like to mention that I don't want to create boundary/box around mtext ,that is the main issue in the above lisp.So let me give you more detail regarding my case.
Here we go- 
I want to draw internal boundary across the rooms on the floorplan layout.The room layout may be made up of many elements such as lines,polylines,arc and even blocks (for doors,windows) in actual cases. and not simple closed polyline. So the above lisp is based on BPOLY command and Island detection, since in my case every room has text or mtext , it uses the insertion point of text/mtext and should draw the internal boundary across room (but in case of mtext it also draws boundary around text object which I don't want) . My intention behind using the text/mtext insertion point is that boundaries can be drawn for multiple rooms simultaneously.

I want output something like below Image (see it should not create boundary around text/mtext )
image.thumb.png.c719f8ffea071ca7f197fc8b39e6cb1f.png
I know this BPOLY approach is not so perfect and have some issues like if there is gap somewhere in the room layout,  it gives error "VALID BOUNDARY NOT FOUND" but it didn't highlight or specify exactly which gap is resulting in this error.But somehow I have to work with it.

You are welcome to suggest some another approach/ideas or improvement in the current approach.
Here I am attaching a sample plan (dwg) and the rooms around which boundaries are required to be created (similar to above image) are named as "Room-A1,Room-A2 and so on"

Please have a look and give your valuable feedback!

sample plan.dwg


  

Link to comment
Share on other sites

Hmm... that seems too hard a request from me. Other than the boundary command , I'm not sure if there's any other approach. One hint I can give you is simply on issuing (command "-BOUNDARY"), you can choose "Boundary Set" and don't include the text as well. Unfortunately it's the end of the road for me with other ideas. Perhaps someone can answer to your request 

Link to comment
Share on other sites

1 hour ago, Jonathan Handojo said:

One hint I can give you is simply on issuing (command "-BOUNDARY"), you can choose "Boundary Set" and don't include the text as well.


@Jonathan Handojo yes I have tried this for above attached lisp but failed.Can you help me with this?

 

1 hour ago, Jonathan Handojo said:

Unfortunately it's the end of the road for me with other ideas.

No worries mate.You have always extended helping hands to everybody on the forum 🤗

Link to comment
Share on other sites

20 hours ago, AbdRF said:

Hello,

I have a lisp which draw internal boundary based on the text/mtext  inside enclosed areas (such as rooms,etc). But one issue I am facing is that if there is mtext ,it draws boundary around mtext also which I don't want. Refer below image for details
image.thumb.png.2af8386e74b976263a98c2ffd0843c84.png
Also, guys the lisp is somewhat very slow in most cases and I can't figure out why it is so? 
Please find the attached lisp file and sample drawing.

Thanks !!

Boundary_Sam_CT.dwg

CB.lsp
 

 

You only need to set Island detection off.

 

(defun C:CB (/)
  (setvar "CMDECHO" 0)
  (princ "\nSelect the Text/Mtext Inside the Closed Area : ")
  (setq selectionset (ssget '((0 . "*TEXT"))))
  (repeat (setq N (sslength selectionset))
    (setq Data (ssname selectionset (setq N (- N 1))))
    (setq EntityData (entget Data))
    (setq IP_Text (cdr (assoc 10 EntityData)))
    (command "_-BOUNDARY" "_A" "_I" "_N" "" "" IP_Text "")
  )
  (setvar "CMDECHO" 1)
  (princ)
)

 

  • Thanks 1
Link to comment
Share on other sites

5 hours ago, AbdRF said:


@Jonathan Handojo first of all ,I would like to appreciate your helping nature with everyone on the forum and you seems to be very down to earth 😇
I would like to mention that I don't want to create boundary/box around mtext ,that is the main issue in the above lisp.So let me give you more detail regarding my case.
Here we go- 
I want to draw internal boundary across the rooms on the floorplan layout.The room layout may be made up of many elements such as lines,polylines,arc and even blocks (for doors,windows) in actual cases. and not simple closed polyline. So the above lisp is based on BPOLY command and Island detection, since in my case every room has text or mtext , it uses the insertion point of text/mtext and should draw the internal boundary across room (but in case of mtext it also draws boundary around text object which I don't want) . My intention behind using the text/mtext insertion point is that boundaries can be drawn for multiple rooms simultaneously.

I want output something like below Image (see it should not create boundary around text/mtext )
image.thumb.png.c719f8ffea071ca7f197fc8b39e6cb1f.png
I know this BPOLY approach is not so perfect and have some issues like if there is gap somewhere in the room layout,  it gives error "VALID BOUNDARY NOT FOUND" but it didn't highlight or specify exactly which gap is resulting in this error.But somehow I have to work with it.

You are welcome to suggest some another approach/ideas or improvement in the current approach.
Here I am attaching a sample plan (dwg) and the rooms around which boundaries are required to be created (similar to above image) are named as "Room-A1,Room-A2 and so on"

Please have a look and give your valuable feedback!

sample plan.dwg


  


@dlanorh you seems to be quite experienced in the lisp. I request you to go through this and give your insight.Thanks
I am attaching the plan saved in 2010 autocad format for you.

sample plan_v2010.dwg

Link to comment
Share on other sites

On 4/8/2020 at 11:05 AM, Jonathan Handojo said:

(defun JH:RemoveAdjacentDuplicates (lst / tst) (setq tst lst) (vl-remove nil (mapcar '(lambda (x) (if (null (equal x (car (setq tst (cdr tst))) 1e-8)) x)) lst)) )

@Jonathan Handojo Food for thought:

;; vl-remove-if instead of mapcar and then remove nil
(defun jh:removeadjacentduplicates (lst)
  (vl-remove-if '(lambda (x) (equal x (car (setq lst (cdr lst))) 1e-8)) lst)
)
;; Or vanilla version
(defun _rad (l p / a r)
  (while (setq a (car l))
    (setq r (cons a r))
    (setq l (cdr l))
    (while (equal a (car l) p) (setq l (cdr l)))
  )
  (reverse r)
)
(setq l '(1 1 1 2 2 3 4 5 6 6 6 6 6 7 7 8  9 9 9 10 10 10 10 11 12 12 13))
(jh:removeadjacentduplicates l)
(_rad l 1e-8)

 

Link to comment
Share on other sites

12 hours ago, ronjonp said:

@Jonathan Handojo Food for thought:


;; vl-remove-if instead of mapcar and then remove nil
(defun jh:removeadjacentduplicates (lst)
  (vl-remove-if '(lambda (x) (equal x (car (setq lst (cdr lst))) 1e-8)) lst)
)
;; Or vanilla version
(defun _rad (l p / a r)
  (while (setq a (car l))
    (setq r (cons a r))
    (setq l (cdr l))
    (while (equal a (car l) p) (setq l (cdr l)))
  )
  (reverse r)
)
(setq l '(1 1 1 2 2 3 4 5 6 6 6 6 6 7 7 8  9 9 9 10 10 10 10 11 12 12 13))
(jh:removeadjacentduplicates l)
(_rad l 1e-8)

 

 

Hey, thanks for that @ronjonp. I didn't knew that would work since I've never actually tried that before. Not sure how vl-remove-if processes lst, so I didn't thought that was gonna work. Nice one

Link to comment
Share on other sites

21 hours ago, AbdRF said:


@dlanorh you seems to be quite experienced in the lisp. I request you to go through this and give your insight.Thanks
I am attaching the plan saved in 2010 autocad format for you.

sample plan_v2010.dwg

 

What are you trying to accomplish?

Link to comment
Share on other sites

5 hours ago, Jonathan Handojo said:

 

Hey, thanks for that @ronjonp. I didn't knew that would work since I've never actually tried that before. Not sure how vl-remove-if processes lst, so I didn't thought that was gonna work. Nice one

Glad to help :)

 

Link to comment
Share on other sites

On 4/9/2020 at 12:04 PM, AbdRF said:


@Jonathan Handojo first of all ,I would like to appreciate your helping nature with everyone on the forum and you seems to be very down to earth 😇
I would like to mention that I don't want to create boundary/box around mtext ,that is the main issue in the above lisp.So let me give you more detail regarding my case.
Here we go- 
I want to draw internal boundary across the rooms on the floorplan layout.The room layout may be made up of many elements such as lines,polylines,arc and even blocks (for doors,windows) in actual cases. and not simple closed polyline. So the above lisp is based on BPOLY command and Island detection, since in my case every room has text or mtext , it uses the insertion point of text/mtext and should draw the internal boundary across room (but in case of mtext it also draws boundary around text object which I don't want) . My intention behind using the text/mtext insertion point is that boundaries can be drawn for multiple rooms simultaneously.

I want output something like below Image (see it should not create boundary around text/mtext )
image.thumb.png.c719f8ffea071ca7f197fc8b39e6cb1f.png
I know this BPOLY approach is not so perfect and have some issues like if there is gap somewhere in the room layout,  it gives error "VALID BOUNDARY NOT FOUND" but it didn't highlight or specify exactly which gap is resulting in this error.But somehow I have to work with it.

You are welcome to suggest some another approach/ideas or improvement in the current approach.
Here I am attaching a sample plan (dwg) and the rooms around which boundaries are required to be created (similar to above image) are named as "Room-A1,Room-A2 and so on"

Please have a look and give your valuable feedback!

sample plan.dwg


  

 

@dlanorh Please go through this post of mine.I have mentioned the details regarding what I am trying to achieve.

 

Thanks

Link to comment
Share on other sites

The problem seems to be your door block, The architrave doesnt meet the wall polyline and is not seen as closing the gap. How have you constructed the polyline on layer floor? It's gone midnight here so I'm off to bed.:sleeping:

Link to comment
Share on other sites

I would have thought the room size is wrong it should be calculated without the door arc This is a big amount if talking flooring material I have not seen carpet missing at the doorway.

 

Looking at the drawing  need a line drawn across the doorway on a no plot layer, then turn the layer doors off.

 

image.thumb.png.23b5f1e7eb354a9808bc0ec2bc719b70.png

  • Thanks 1
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...