TheSwamp

Code Red => AutoLISP (Vanilla / Visual) => Topic started by: well20152016 on December 05, 2018, 12:53:38 AM

Title: Acquisition of three-point coordinates of a mpolygon
Post by: well20152016 on December 05, 2018, 12:53:38 AM
Acquisition of three-point coordinates of a mpolygon
Title: Re: Acquisition of three-point coordinates of a mpolygon
Post by: kirby on December 05, 2018, 01:31:29 PM

Refer to DXF manual on Hatch / MPolygon entity and Bounadry Path Data

Relevant Dxf codes are as follows:

91 is the number of loops for the entire Mpolygon.  You have 1 'loop'. Note Mpolygon is very similar to hatch, can have separate 'loops' or 'regions' or holes, or holes with islands.

92 is the boundary type (2=polyline)

93 is number of edges

10 are transformed coordinates
The orientation of the DXF 10 coordinates determine if the molygon boundary is an Outer boundary (counter-clockwise, normal acad/cartesian angular measurement) or Inner (Clockwise).  caution - this sometimes isn't true!?!

11 is the basepoint coordinate (or 'offset vector').  Add this vector to each of the DXF 10 coordinates to calculate the 'real' WCS coordinate. 
Having this coordinate permits the DXF 10 values to be smaller numbers.  Reducing memory can be a big deal for hatch pattern fills (and mpolygons with hatch pattern) where each pattern line segment must be stored.

72 'has bulge' >0 indicates that polyarcs are present.

73 > 0 indicated polyline used to create mpolygon is closed (vs. force closed, where last coordinate = first coordinate).  Mpolygons are always closed by default (unlike polylines)

70 is solid fill (1 = solid fill)

76 is hatch style (1 = predefined)

63 is pattern fill colour as Acad Colour Index (1 = red)

Also note that mpoly can have arc segments similar to a polyline.  If this is the case, a DXF code 42 (bulge) follows each DXF 10 coordinate (even for the straight line segments)
eg.
10 x y z
42 bulge or 0.0
10 x y z
42 bulge or 0.0
etc...

partial DXF extract of your triangular shaped mpolygon is as follows:
Code: [Select]
(71 . 1)
 (91 . 1)
 (92 . 2)
 (73 . 0)
 (72 . 0)
 (93 . 3)
 (10 -169.233 -15.2715 0.0)
 (10 169.233 -253.277 0.0)
 (10 157.309 253.277 0.0)
 (76 . 1)
 (63 . 1)
 (11 -27170.6 305.577 0.0)


Unfortunately, unlike Region entities, Boolean operations (Union, Intersect, Subtract) will not work with Mpolygons.
Title: Re: Acquisition of three-point coordinates of a mpolygon
Post by: kdub_nz on December 05, 2018, 01:37:59 PM
Looks like a well researched response Kirby
Title: Re: Acquisition of three-point coordinates of a mpolygon
Post by: kirby on December 05, 2018, 03:05:55 PM
Thanks.

My context is a rural drainage guideline / study to simplify a bunch of rural land cover polygons (agricultural, prairie, forest, marsh, etc), clip them to a polyline catchment boundary, then work out the fraction of each land cover type within the catchment boundary.  This would be used to estimate average hydrologic properties for the catchment based on the individual land cover characteristics.

Converting complex mpolygons to regions for the Boolean operations then back to mpolygons is this week's mental exercise...
Title: Re: Acquisition of three-point coordinates of a mpolygon
Post by: ribarm on December 24, 2018, 08:22:38 AM
I don't know, but you can temporarily explode MPOLYGON to LWPOLYLINE and get vertices data from there...

Code - Auto/Visual Lisp: [Select]
  1. (defun c:mpolygonvertlst ( / mpolygonvertlst mpolygon )
  2.  
  3.   (defun mpolygonvertlst ( mpolygon / pl el )
  4.     (vl-cmdf "_.EXPLODE" mpolygon)
  5.     (while (< 0 (getvar 'cmdactive))
  6.       (vl-cmdf "")
  7.     )
  8.     (setq el (entlast))
  9.     (setq pl (mapcar '(lambda ( p ) (list (car p) (cadr p) (cdr (assoc 38 (entget el))))) (mapcar 'cdr (vl-remove-if '(lambda ( x ) (/= (car x) 10)) (entget el)))))
  10.     (setq pl (mapcar '(lambda ( p ) (trans p el 0)) pl))
  11.     (vl-cmdf "_.UNDO" "1")
  12.     (setq *pl* pl)
  13.   )
  14.  
  15.   (while
  16.     (or
  17.       (not (setq mpolygon (car (entsel "\nPick MPOLYGON to get its vertices WCS coordinates..."))))
  18.       (if mpolygon
  19.         (or
  20.           (/= (cdr (assoc 0 (entget mpolygon))) "MPOLYGON")
  21.           (= 4 (logand 4 (cdr (assoc 70 (tblsearch "LAYER" (cdr (assoc 8 (entget mpolygon))))))))
  22.         )
  23.       )
  24.     )
  25.     (prompt "\nMissed or picked wrong entity type or picked MPOLYGON on locked layer...")
  26.   )
  27.   (princ "\n")
  28.   (princ (mpolygonvertlst mpolygon))
  29.   (princ "\nPoint list is stored in global variable \"*pl*\"... You can call it with !*pl*...")
  30.   (princ)
  31. )
  32.  

HTH., M.R.
Title: Re: Acquisition of three-point coordinates of a mpolygon
Post by: well20152016 on December 24, 2018, 09:43:16 AM
Thank you, ribarm.
Is there any way?

(10 0.0 0.0 -51.9042)
(210 -0.134866 -0.198512 0.970775)
(11 -27170.6 305.577 0.0)

(10 -169.233 -15.2715 0.0)
 (10 169.233 -253.277 0.0)
 (10 157.309 253.277 0.0)
Result:
(-22299.0 15226.1 -37.8358)
 (-22032.5 15639.5 83.7329)
 (-22449.1 15607.4 19.2835)





(setq nor (cdr (assoc 210 ent))
          p11 (cdr (assoc 11 ent))
          p10s (mapcar 'cdr  (vl-remove-if-not'(lambda(x)(=(car x)10)) ent))
          po (mapcar '(lambda (p)(trans p  nor 0)) (cdr p10s))
          ppp (mapcar '(lambda(x)(list (+ (car x)(car p11)) (+ (cadr x)(cadr p11)) (+ (caddr x)(caddar p10s)))) po);Error here
          )
Title: Re: Acquisition of three-point coordinates of a mpolygon
Post by: ribarm on December 24, 2018, 10:30:09 AM
Here you are...

Code - Auto/Visual Lisp: [Select]
  1. (defun c:mpolygonvertlst ( / mpolygon mpolygonx dxf10 dxf11 dxf210 pl )
  2.   (while
  3.     (or
  4.       (not (setq mpolygon (car (entsel "\nPick MPOLYGON to get its vertices WCS coordinates..."))))
  5.       (if mpolygon
  6.         (/= (cdr (assoc 0 (entget mpolygon))) "MPOLYGON")
  7.       )
  8.     )
  9.     (prompt "\nMissed or picked wrong entity type...")
  10.   )
  11.   (setq mpolygonx (entget mpolygon))
  12.   (setq dxf10 (cdr (assoc 10 mpolygonx)) dxf11 (cdr (assoc 11 mpolygonx)) dxf210 (cdr (assoc 210 mpolygonx)))
  13.   (setq pl (cdr (mapcar 'cdr (vl-remove-if '(lambda ( x ) (/= (car x) 10)) mpolygonx))))
  14.   (setq *pl* (mapcar '(lambda ( x ) (trans (mapcar '+ dxf10 dxf11 x) dxf210 0)) pl))
  15.   (princ "\n")
  16.   (princ *pl*)
  17.   (princ "\nPoint list is stored in global variable \"*pl*\"... You can call it with !*pl*...")
  18.   (princ)
  19. )
  20.  

HTH., M.R.
Title: Re: Acquisition of three-point coordinates of a mpolygon
Post by: well20152016 on December 24, 2018, 10:42:38 AM
Thank you, ribarm.
Title: Re: Acquisition of three-point coordinates of a mpolygon
Post by: ribarm on December 24, 2018, 11:31:06 AM
OK... Now tell me it seems that MPOLYGON isn't standard AutoCAD entity... BTW. dumping data from VLA-OBJECT - MPOLYGON gives data where there are no Coordinates property... So my question : How did you get (create) MPOLYGON when there is no such entity under DRAW menu of AutoCAD?
Title: Re: Acquisition of three-point coordinates of a mpolygon
Post by: well20152016 on December 24, 2018, 11:36:47 AM
MPOLYGON is a professional software generated, I want to post-processing.
Title: Re: Acquisition of three-point coordinates of a mpolygon
Post by: didier on December 26, 2018, 08:13:45 AM
Coucou

Mpolygon is a native object drawing with Acad MAP

Amicalement
Title: Re: Acquisition of three-point coordinates of a mpolygon
Post by: gile on December 26, 2018, 09:51:14 AM
You can 'entmake' MPolygon entities in AutoCAD Vanilla (requires acMPolygonObjXX.dbx to be loaded), see the following example.

Code - Auto/Visual Lisp: [Select]
  1. (defun c:makeMPolygon (/ filename)
  2.   (setq filename (strcat "acMPolygonObj"
  3.                          (substr (getvar "ACADVER") 1 2)
  4.                          ".dbx"
  5.                  )
  6.   )
  7.   (or (member filename (arx))
  8.       (arxload filename)
  9.   )
  10.   (entmake '((0 . "MPOLYGON")
  11.              (100 . "AcDbEntity")
  12.              (100 . "AcDbMPolygon")
  13.              (70 . 1)
  14.              (10 0.0 0.0 0.0)
  15.              (210 0.0 0.0 1.0)
  16.              (2 . "ANSI31")
  17.              (71 . 0)
  18.              (91 . 2)
  19.              (92 . 2)
  20.              (73 . 0)
  21.              (72 . 0)
  22.              (93 . 5)
  23.              (10 62.6859 18.6225 0.0)
  24.              (10 120.0 60.2636 0.0)
  25.              (10 177.314 18.6225 0.0)
  26.              (10 155.422 -48.7543 0.0)
  27.              (10 84.5779 -48.7543 0.0)
  28.              (92 . 2)
  29.              (73 . 0)
  30.              (72 . 0)
  31.              (93 . 4)
  32.              (10 20.0 100.0 0.0)
  33.              (10 20.0 -100.0 0.0)
  34.              (10 220.0 -100.0 0.0)
  35.              (10 220.0 100.0 0.0)
  36.              (76 . 1)
  37.              (52 . 0.0)
  38.              (41 . 2.0)
  39.              (77 . 0)
  40.              (78 . 1)
  41.              (53 . 0.785398)
  42.              (43 . 0.0)
  43.              (44 . 0.0)
  44.              (45 . -4.49013)
  45.              (46 . 4.49013)
  46.              (79 . 0)
  47.              (11 0.0 0.0 0.0)
  48.              (99 . 0)
  49.              (450 . 0)
  50.              (451 . 0)
  51.              (460 . 0.0)
  52.              (461 . 0.0)
  53.              (452 . 0)
  54.              (462 . 0.0)
  55.              (453 . 0)
  56.              (470 . "")
  57.             )
  58.   )
  59.   (princ)
  60. )

Some times ago I tried to write some .NET custom command (http://www.theswamp.org/index.php?topic=29152.msg347035#msg347035) to convert Vanilla curves to MPolygons.
Title: Re: Acquisition of three-point coordinates of a mpolygon
Post by: ribarm on December 26, 2018, 11:01:55 AM
Thanks gile, it works...
Title: Re: Acquisition of three-point coordinates of a mpolygon
Post by: Grrr1337 on December 26, 2018, 11:15:21 AM
Gile, I also have this sub thanks to you -
Code - Auto/Visual Lisp: [Select]
  1. ;;; MakeWipeout creates a "wipeout" from a points list and the normal vector of the object - Gile
  2. (defun MakeWipeout (pt_lst nor / dxf10 max_dist cen dxf_14)
  3.   (if (not (member "acismui.arx" (arx))) (arxload "acismui.arx") )
  4.   (setq dxf10 (list (apply 'min (mapcar 'car pt_lst)) (apply 'min (mapcar 'cadr pt_lst)) (caddar pt_lst) ) )
  5.   (setq max_dist (float (apply 'max (mapcar '- (apply 'mapcar (cons 'max pt_lst)) dxf10))))
  6.   (setq cen (mapcar '+ dxf10 (list (/ max_dist 2) (/ max_dist 2) 0.0)))
  7.   (setq dxf14 (mapcar '(lambda (p) (mapcar '/ (mapcar '- p cen) (list max_dist (- max_dist) 1.0))) pt_lst) )
  8.   (setq dxf14 (reverse (cons (car dxf14) (reverse dxf14))))
  9.     (append
  10.       (list
  11.         '(0 . "WIPEOUT")
  12.         '(100 . "AcDbEntity")
  13.         '(100 . "AcDbWipeout")
  14.         '(90 . 0)
  15.         (cons 10 (trans dxf10 nor 0))
  16.         (cons 11 (trans (list max_dist 0.0 0.0) nor 0))
  17.         (cons 12 (trans (list 0.0 max_dist 0.0) nor 0))
  18.         '(13 1.0 1.0 0.0)
  19.         '(70 . 7)
  20.         '(280 . 1)
  21.         '(71 . 2)
  22.         (cons 91 (length dxf14))
  23.       )
  24.       (mapcar '(lambda (p) (cons 14 p)) dxf14)
  25.     )
  26.   )
  27. ); defun MakeWipeout
Title: Re: Acquisition of three-point coordinates of a mpolygon
Post by: well20152016 on December 27, 2018, 08:17:49 AM
 :smitten: