Jump to content

Closed polyline from entity selection


Recommended Posts

Posted

Hello. Does anyone know of a routine that makes it possible to generate a closed polyline from a boundary based on a selection of entities, even if separate from each other?

Somehow it will have some similarity to the fantastic Lee Mac routine "Outline" but it's different so my help request.

Sample attachment for better understanding of what I intend. I appreciate your help.

 

Tanks!

example_cadtutor.dwg

Posted

PEDIT/ multiple / select objects / join / fuzz distance / ENTER

Posted

@guran

I appreciate the suggestion.
It is not practical, because the fuzz value can be very variable. In addition it is intended to keep the selected entities unchanged.
And, of course, as simply and automatically as possible.

Thanks.

Posted

There is a commercial product out there it is not free but sounds like what you want usually find with Google "Boundary objects" or similar search.

Posted (edited)

I made something.  It's not finished, it doesn't make the arcs in the closed polyline, instead it connects them with a line.

 

Does anybody have a entmakex for polyline with arcs?  Then I can make this work.

 

What my routine does: the user must supply a point inside the closed polyline (to be).  Pick that point nicely in the middle!

Imaginary lines are drawn from that point to the midpoints of the lines and arcs, like a spider web.  These get sorted by their angle.  Then, 1 by one I search for intersect points of consecutive lines/arcs, both extended.

 

In the end I draw a polyline with the list of those intersect points.

 

Command CPLA (then select objects, then give a point inside)

 


(vl-load-com)

;; midpoint of 2 given points
(defun mid ( pt1 pt2 / )
  (mapcar '(lambda (x y) (+ (* 0.5 x) (* 0.5 y)))
  pt1
  pt2
  )
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Intersections  -  Lee Mac
;; Returns a list of all points of intersection between two objects
;; for the given intersection mode.
;; ob1,ob2 - [vla] VLA-Objects
;;     mod - [int] acextendoption enum of intersectwith method
;;   acextendnone     Do not extend either object
;;   acextendthisentity     Extend obj1 to meet obj2
;;   acextendotherentity     Extend obj2 to meet obj1
;;   acextendboth     Extend both objects

(defun LM:intersections ( ob1 ob2 mod / lst rtn )
    (if (and (vlax-method-applicable-p ob1 'intersectwith)
             (vlax-method-applicable-p ob2 'intersectwith)
             (setq lst (vlax-invoke ob1 'intersectwith ob2 mod))
        )
        (repeat (/ (length lst) 3)
            (setq rtn (cons (list (car lst) (cadr lst) (caddr lst)) rtn)
                  lst (cdddr lst)
            )
        )
    )
    (reverse rtn)
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun drawLWPoly (lst cls)
  (entmakex (append (list (cons 0 "LWPOLYLINE")
                          (cons 100 "AcDbEntity")
                          (cons 100 "AcDbPolyline")
                          (cons 90 (length lst))
                          (cons 70 cls))
                    (mapcar (function (lambda (p) (cons 10 p))) lst)))
)

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

(defun sortby_midpt_angle (pt ss / i angles angles_sorted midp ss2)
  (setq i 0)
  (setq angles (list))
  (repeat (sslength ss)
    ;; LINES: let's take the midpoint between start and end
    (if (= "LINE" (cdr (assoc 0 (entget (ssname ss i)))))
      (progn
        (setq midp (mid
          (cdr (assoc 10 (entget (ssname ss i))))
          (cdr (assoc 11 (entget (ssname ss i))))
        ))
      )
    )
    ;; CIRCLES, ARCS: let's take the centerppoint
    (if
      (or (= "CIRCLE" (cdr (assoc 0 (entget (ssname ss i))))) (= "ARC" (cdr (assoc 0 (entget (ssname ss i))))) )
      (progn
        (setq midp (cdr (assoc 10 (entget (ssname ss i)))))
      )
    )
    (setq angles (append angles (list
      (angle pt midp)
    )))
    (setq i (+ i 1))
  )
  (princ angles)
  (setq angles_sorted (vl-sort-i angles '<))
  (princ angles_sorted)
  (setq ss2 (ssadd))  
  (foreach i angles_sorted
    (ssadd (ssname ss i) ss2)
  )
  ss2
)

(defun closest_insertpoint (pt inspts / dst ind i)
  (setq i 0)
  (setq dst nil)
  (setq ind 0)
 
  (repeat (length inspts)
    (if (or
        (not dst)
        (< (distance pt (nth i inspts)) dst)
      )
      (progn
        (setq dst (distance pt (nth i inspts)))
        (setq ind i)
      )
    )
    (setq i (+ i 1))
  )
  (nth ind inspts)
)

;; test for closest_insertpoint
(defun c:test_closest_insertpoint ( / pt inspts)
  (setq pt (getpoint "\nPoint: "))
  (setq inspts (LM:intersections (vlax-ename->vla-object (car (entsel "\nObj1: " ))) (vlax-ename->vla-object (car (entsel "\nObj2: " ))) acextendboth))
  (princ inspts)
  (closest_insertpoint pt inspts)
)

;; draw Closed Polyline from Lines and Arcs
(defun c:cpla ( / ss i pt inspts pline_pts)
  (princ "\nSelect objects to close: ")
  (setq ss (ssget (list (cons 0 "LINE,ARC,CIRCLE"))))
  (setq pt (getpoint "\nGive a point in the center: "))
  (setq ss (sortby_midpt_angle pt ss))
 
  (setq i 0)
  (setq pline_pts (list))
  (repeat (- (sslength ss) 1)
    (setq inspts (LM:intersections (vlax-ename->vla-object (ssname ss i)) (vlax-ename->vla-object (ssname ss (+ i 1))) acextendboth))
    (setq pline_pts (append pline_pts (list (closest_insertpoint pt inspts))))
    (setq i (+ i 1))
  )
  ;; last
  (setq inspts (LM:intersections (vlax-ename->vla-object (ssname ss (- (sslength ss) 1) )) (vlax-ename->vla-object (ssname ss 0)) acextendboth))
  (setq pline_pts (append pline_pts (list (closest_insertpoint pt inspts))))
 
  (drawLWPoly pline_pts 1)
)

 

 

Edited by Emmanuel Delay
Posted

@Emmanuel Delay

Thank you for your interest and effort. From what I have experienced, it works in some situations and generally corresponds to what I need. And yes, it still does not work with arcs and circles but also in some other situations, as in the example that I attach.

 

Thanks!

example_cadtutor_2.dwg

Posted

@ronjonp

In my work, with Autocad 2009 (yes, still) I need to calculate the areas of dozens of compartments (bedrooms, living rooms, kitchens, warehouses, etc). Therefore, using the normal method of calculating area (point to point) takes a long time. The proposed routine allows this process to be streamlined.

 

Tanks!

Posted
37 minutes ago, teknomatika said:

@ronjonp

In my work, with Autocad 2009 (yes, still) I need to calculate the areas of dozens of compartments (bedrooms, living rooms, kitchens, warehouses, etc). Therefore, using the normal method of calculating area (point to point) takes a long time. The proposed routine allows this process to be streamlined.

 

Tanks!

You should post a sample of the actual drawings you're using. I don't correlate rooms to your posted examples. Most rooms I know of have walls / doors / windows ??

Posted
3 hours ago, ronjonp said:

You should post a sample of the actual drawings you're using. I don't correlate rooms to your posted examples. Most rooms I know of have walls / doors / windows ??

@ronjonp

I understand the question. I know that in normal situations it will be enough to use the commands that lead to the obtaining of area, including the command "Boundary". But most of the time the boundary elements that define the compartments are diverse and interrupted and with other elements that are not part of the walls but furniture, infrastructures, etc.

Most of the time the work comes to me with the defined compartments but with many elements of different categories and without layer organization which makes it difficult to use the most conventional commands to get the area quickly. In the simple example that I attach, it is clear that a routine like the one I want to facilitate will only involve the selection of a few entities to create a closed polyline.

cadtutor_example_3.dwg

Posted
3 hours ago, rlx said:

Master Lee has many outline routines, have you also seen this one? http://www.lee-mac.com/ssboundingbox.html

 

and else if it is that important to you , like Bigal said , pay for it : http://www.totalboundary.com/order.html  $19 is peanuts

 

and one more for the road : https://www.cadtutor.net/forum/topic/22887-boundary-creation-lisp-a-request/

@rlx

I appreciate the suggestions. The TotalBoundary tool is great but doesn't match what I need. Also, I know and use Master Lee Mac's excellent routine, "Outline," which is similar.

Posted (edited)

seeing your example drawing I get what you want but I.M.H.O. you will allways have the need for some kind of devine , excuse me , manual intervention because how would any routine know which inside wall you want to be included and which one not. So you would choose the lisp that does 90% of what you want and you do the other 10%... you would still have a profit of 90% 😁

 

what you could do is find the lisp routine that comes closest to your wishes and add option to first erase the objects that you dont need or want , then you make your selection , app creates boundary and then use oops or similar to restore erased objects,

Edited by rlx

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