Help to divide with a polyline autolisp

Help to divide with a polyline autolisp

Anonymous
Not applicable
2,456 Views
10 Replies
Message 1 of 11

Help to divide with a polyline autolisp

Anonymous
Not applicable
Hi, could you help me with a lisp that I have for a deliverable please, 
I have tried and it has not worked for me. It is to put a figure as a rectangle or similar,
then specify a side and that it is divided into new figures according to the cut,
according to the distances. For example, in a closed rectangle (polyline) choose a side
(which measures 7 for example) put 3 and that is divided into two rectangles with side 3 and one with side 1.
Likewise, an irregular figure with side 7 that if I select the side and the distance (for example 3) I divide it into two figures,
side 3 and one of the one. I have tried everything, but I no longer know what commands to use, since they have to be created and different
figures according to a measure that is entered
please I have tried it like 3 days and could not get results :(
 
 

please
Sin título.png      

 

0 Likes
Accepted solutions (3)
2,457 Views
10 Replies
Replies (10)
Message 2 of 11

ВeekeeCZ
Consultant
Consultant
Accepted solution

@Anonymous wrote:
Hi, could you help me with a lisp that I have for a deliverable please, I have tried and it has not worked for me. It is to put a figure as a rectangle or similar, then specify a side and that it is divided into new figures according to the cut, according to the distances. For example, in a closed rectangle (polyline) choose a side (which measures 7 for example) put 3 and that is divided into two rectangles with side 3 and one with side 1. Likewise, an irregular figure with side 7 that if I select the side and the distance (for example 3) I divide it into two figures, side 3 and one of the one. I have tried everything, but I no longer know what commands to use, since they have to be created and different figures according to a measure that is entered please I have tried it like 3 days and could not get results 😞

 

Post dwg.

 

We should set some boundaries...

- always closed polylines?

- always no arc segments?

- always rectangular... or mostly rectangular

- always placed orthogonally

- process one at the time? if not, post REAL figures... to see the scale.

 

Found THIS SplitArea routine, with some info HERE, worth a try.  

Message 3 of 11

Anonymous
Not applicable

Hi!!

- always closed polylines? yeah!! only closed!!

- always no arc segments? nope

- always rectangular... or mostly rectangular, yeah mostly but irregular rectangles

- always placed orthogonally, yes!!!! 

- process one at the time? if not, post REAL figures... to see the scale: If you can help me, please better if the lisp can divide a lot of figures at the same time, if not no problem, only one 😞 

0 Likes
Message 4 of 11

Sea-Haven
Mentor
Mentor
Accepted solution

A extra question you can pick a pline then get which section picked, so what if the section is not horizontal are you happy with 90 deg lines ?

 

SeaHaven_0-1626484585567.png

 

0 Likes
Message 5 of 11

ВeekeeCZ
Consultant
Consultant
Accepted solution

This should be enough for you to adjust the rest. What's missing is side selection (currently it goes just from Left to right). Also thought that it could remove the originals.. Maybe inherit layer or all properties... Hopefully, work for a couple of hours not days. Good luck!

 

(vl-load-com)

(defun c:PolygonDivide ( / s i o v xl yl xl x* xu h l its pts pls el eh)
  
  (or *ad-d* (setq *ad-d* 1.))
  (or *ad-s* (setq *ad-s* "Left"))
  
  (if (and (setq s (ssget "_:L" '((0 . "LWPOLYLINE") (-4 . "&=") (70 . 1))))
	   (setq *ad-d* (cond ((getdist (strcat "\nSpecify step distance <" (rtos *ad-d*) ">: "))) (*ad-d*)))
	   (not (initget "Right Left"))
	   (setq *ad-s* (cond ((getkword (strcat "\nStart from... [Left/Right] <" *ad-s* ">: "))) (*ad-s*))) ; not implemented yet
	   )
    (repeat (setq i (sslength s))
      (setq e (ssname s (setq i (1- i)))
	    o (vlax-ename->vla-object e)
	    v (mapcar 'cdr (vl-remove-if '(lambda (x) (/= 10 (car x))) (entget e)))
	    b (LM:boundingbox1 o)
	    xl (caar b)
	    yl (cadar b)
	    xr (caadr b)
	    yu (cadadr b)
	    h (abs (- yu yl))
	    yl (- yl (/ h 10))
	    yu (+ yu (/ h 10))
	    x* xl
	    el nil)
      
      (while x*
	(if (> (+ x* *ad-d*) xr)
	  (setq xh (/ (+ xr x*) 2)
		x* nil)
	  (setq xh (+ x* (/ *ad-d* 2))
		x* (+ x* *ad-d*)))
	(if x*
	  (setq el (cons (entmakex (list (cons 0 "LINE") (list 10 x* yl) (list 11 x* yu))) el))) ; boundary lines by step distance
	(setq eh (entmakex (list (cons 0 "LINE") (list 10 xh yl) (list 11 xh yu))))		 ; line for searching intersecting points (half of stepdist) to get "pick" point inside
	
	(if (and (setq its (LM:intersections o (vlax-ename->vla-object eh) acextendnone))
		 (setq its (vl-sort its '(lambda (e1 e2) (< (cadr e1) (cadr e2)))))
		 (zerop (rem (length its) 2))
		 )
	  (progn
	    (setq pls nil)
	    (repeat (/ (length its) 2)
	      (setq pts (cons (mapcar '/ (mapcar '+ (car its) (cadr its)) '(2 2)) pts)
		    its (cddr its)))
	    (entdel eh)
	    (foreach pt pts
	      (if (setq pl (bpoly pt))
		(if (vl-position T (mapcar '(lambda (p) (equal (apply '+ (mapcar '(lambda (x) (apply '+ x)) (vl-remove-if '(lambda (x) (/= 10 (car x))) (entget p))))
							       (apply '+ (mapcar '(lambda (x) (apply '+ x)) (vl-remove-if '(lambda (x) (/= 10 (car x))) (entget pl))))
							       1))
					   pls))
		  (entdel pl)
		  (setq pls (cons pl pls)))))
	    (setq pts nil))))
      
      (if el (mapcar 'entdel el))))
  (princ)
  )



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

(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)
  )

;; Bounding Box  -  Lee Mac
;; Returns the point list describing the rectangular frame bounding the supplied object.
;; obj - [vla] VLA-Object

(defun LM:boundingbox1 ( obj / a b lst )
  (if (and (vlax-method-applicable-p obj 'getboundingbox)
	   (not (vl-catch-all-error-p (vl-catch-all-apply 'vla-getboundingbox (list obj 'a 'b)))))
    (setq lst (mapcar 'vlax-safearray->list (list a b)))))

 

0 Likes
Message 6 of 11

hak_vz
Advisor
Advisor

@ВeekeeCZTest your code for Left Right option - it seams to me that it always draws tiles from leftmost point.

Miljenko Hatlak

EESignature

Did you find this post helpful? Feel free to Like this post.
Did your question get successfully answered? Then click on the ACCEPT SOLUTION button.
0 Likes
Message 7 of 11

Sea-Haven
Mentor
Mentor

Another way, over draw the lines at a spacing and use extrim all done. Yes need a left right offset choice and say line angle. 

0 Likes
Message 8 of 11

Anonymous
Not applicable

yeah we area happy, only its the divide the figure!! please

0 Likes
Message 9 of 11

Kent1Cooper
Consultant
Consultant

Here's another way to go about it, that spares you the need to calculate where to draw Lines [HATCH figures that out for you], and therefore also all the resulting (intersectwith) business.

It works on Polylines of any variety [if 3D, must be planar].  So far, the Polyline must be in, or in a plane parallel to, the current working plane; if it's parallel-to but not in, the results will be in the current plane, not that of the Polyline, but it could easily be made to set the UCS to match the Polyline, if needed.

The Polyline can have arc segments [if you pick it on one of them, the subdivisions will be parallel to, and their spacings generated from, its chord].

(defun C:SDPA ; = Sub-Divide Polyline Area
  (/ plsel pl dist minpt maxpt LL UR stepH stepV base pt pickpar prept hatch hdata lines)
  (if
    (and
      (setq plsel (entsel "\nSelect closed Polyline on edge divisions are to be parallel to: "))
      (wcmatch (cdr (assoc 0 (entget (setq pl (car plsel))))) "*POLYLINE")
      (vlax-curve-isClosed pl) (vlax-curve-isPlanar pl)
      (not (initget 7)); no Enter, no zero, no negative
      (setq dist (getreal "\nDistance between parallel divisions: "))
    ); and
    (progn ; then
      (vla-getboundingbox (vlax-ename->vla-object pl) 'minpt 'maxpt)
      (setq
        LL (vlax-safearray->list minpt)
        UR (vlax-safearray->list maxpt)
        stepH (/ (- (car UR) (car LL)) 100)
        stepV (/ (- (cadr UR) (cadr LL)) 100)
        base (polar LL (/ pi 2) stepV)
        pt base
        pickpar (vlax-curve-getParamAtPoint pl (osnap (cadr plsel) "_nea"))
        prept (vlax-curve-getPointAtParam pl (fix pickpar)); point at preceding vertex
      ); setq
      (command
        "_.isolateobjects" pl ""
        "_.hatch" "_user"
          prept (vlax-curve-getPointAtParam pl (1+ (fix pickpar))); angle
          dist "_no" pl ""
      ); command
      (setq
        hatch (entlast)
        hdata (entget hatch)
        hdata (subst (cons 43 (car prept)) (assoc 43 hdata) hdata); set origin X
        hdata (subst (cons 44 (cadr prept)) (assoc 44 hdata) hdata); & Y
      ); setq
      (entmod hdata)
      (command "_.explode" hatch)
        ; because somehow Hatch doesn't "go into effect" in time to affect Boundary
        ; command, even with (entupd), (redraw) and Regen; even though resulting
        ; Lines may not "appear" in the process, they do affect Boundary
      (setq lines (ssget "_P"))
      (command "_.boundary" "_advanced" "_island" "_no" "" "")
      (repeat 99
        (repeat 99 ; row of pick points
          (command (setq pt (polar pt 0 stepH)))          
        ); repeat
        (setq base (polar base (/ pi 2) stepV) pt base); move up for next row
      ); repeat
      (command
        "" ; end Boundary
        "_.erase" lines pl "" ; <-- omit  pl  here to retain original Polyline
        "_.unisolateobjects"
      ); command
    ); progn
    (prompt "\nNothing selected, or not a closed Polyline.")
  ); if
  (princ)
); defun

 

Kent Cooper, AIA
0 Likes
Message 10 of 11

Kent1Cooper
Consultant
Consultant

Improved version:

(defun C:SDPA ; = Sub-Divide Polyline Area
  (/ *error* doc svn svv plsel pl dist minpt maxpt LL UR
    stepH stepV base pt pickpar prept hatch hdata lines)
  (defun *error* (errmsg)
    (if (not (wcmatch errmsg "Function cancelled,quit / exit abort,console break"))
      (princ (strcat "\nError: " errmsg))
    ); if
    (mapcar 'setvar svn svv); reset System Variables
    (vla-endundomark doc)
    (princ)
  ); defun - *error*
  (vla-startundomark (setq doc (vla-get-activedocument (vlax-get-acad-object))))
  (setq ; System Variable saving/resetting without separate variables for each:
    svn '(osmode cmdecho blipmode)
    svv (mapcar 'getvar svn)
  ); setq
  (if
    (and
      (setq plsel (entsel "\nSelect closed Polyline on edge divisions are to be parallel to: "))
      (wcmatch (cdr (assoc 0 (entget (setq pl (car plsel))))) "*POLYLINE")
      (vlax-curve-isClosed pl) (vlax-curve-isPlanar pl)
      (not (initget 7)); no Enter, no zero, no negative
      (setq dist (getdist "\nDistance between parallel divisions: "))
    ); and
    (progn ; then
      (vla-getboundingbox (vlax-ename->vla-object pl) 'minpt 'maxpt)
      (setq
        LL (vlax-safearray->list minpt)
        UR (vlax-safearray->list maxpt)
        stepH (/ (- (car UR) (car LL)) 100)
        stepV (/ (- (cadr UR) (cadr LL)) 100)
        base (polar LL (/ pi 2) stepV)
        pt base
        pickpar (vlax-curve-getParamAtPoint pl (osnap (cadr plsel) "_nea"))
        prept (vlax-curve-getPointAtParam pl (fix pickpar)); point at preceding vertex
      ); setq
      (mapcar 'setvar svn '(0 0 0)); turn off Osnap, command echoing, blips
      (command
        "_.isolateobjects" pl ""
        "_.hatch" "_user"
          prept (vlax-curve-getPointAtParam pl (1+ (fix pickpar))); angle
          dist "_no" pl ""
      ); command
      (setq
        hatch (entlast)
        hdata (entget hatch)
        hdata (subst (cons 43 (car prept)) (assoc 43 hdata) hdata); set origin X
        hdata (subst (cons 44 (cadr prept)) (assoc 44 hdata) hdata); & Y
      ); setq
      (entmod hdata)
      (command "_.explode" hatch); to Lines for Boundary
      (setq lines (ssget "_P"))
      (command "_.boundary")
      (repeat 99
        (repeat 99 ; row of pick points
          (command (setq pt (polar pt 0 stepH)))          
        ); repeat
        (setq base (polar base (/ pi 2) stepV) pt base); move up for next row
      ); repeat
      (command
        "" ; end Boundary
        "_.erase" lines pl "" ; <-- omit  pl  here to retain original Polyline
        "_.unisolateobjects"
      ); command
      (mapcar 'setvar svn svv); reset
      (vla-endundomark doc)
    ); progn
    (prompt "\nNothing selected, or not a closed Polyline."); else
  ); if
  (princ)
); defun
(vl-load-com)
(prompt "\nType SDPA to SubDivide a Polyline Area.")

[Changed to (getdist) for division spacing; Undo begin/end wrapping; *error* handler; turns off Osnaps, command echoing and blips-if-you-use-them.  Still to be added: set UCS if Polyline isn't in current drawing plane.]

Kent Cooper, AIA
0 Likes
Message 11 of 11

ВeekeeCZ
Consultant
Consultant

@Anonymous 

 

Since I left some ideas unfinished let us know, whether the current solution works for you well and does not fail on too many figures. 

0 Likes