AutoCAD Architecture Customization
Welcome to Autodesk’s AutoCAD Architecture Customization Forums. Share your knowledge, ask questions, and explore popular AutoCAD Architecture Customization topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Extract Vertices out of an AEC_PolyGon

13 REPLIES 13
SOLVED
Reply
Message 1 of 14
mdhutchinson
823 Views, 13 Replies

Extract Vertices out of an AEC_PolyGon

I can get the Vertices of an AEC_Space obejct (see lisp below)... but for some reason I can't see what I need to do with the AEC_PolyGon vertices to transform them so they actually match up with the verts.

 

Could some one take a look at my code.  I think there is both a Location as well as a Rotation that has to be figured in.

AEC_Space  

 

(defun MEPObjVertices ()
 (setq Obj (car (entsel "\nSelect an AEC_PolyGon or an AEC_Space: ")))
 (setq Vla-Obj (vlax-ename->vla-object Obj))
 (setq Vla-BasePro (cond ((wcmatch (cdr (assoc '0 (entget Obj))) "AEC_POLYGON")
          (vlax-get-property Vla-Obj 'Profile)
          )
          ((wcmatch (cdr (assoc '0 (entget Obj))) "AEC_SPACE")
          (vlax-get-property Vla-Obj 'BaseProfile)
          )
          )
    )
 (setq Vla-Base (vlax-get-property Vla-Obj 'Location))
 (setq BasePnt (vlax-safearray->list (vlax-variant-value Vla-Base)))
 (setq coords (vlax-safearray->list (vlax-variant-value (vlax-get-property Vla-BasePro 'Coordinates))))
 (setq xylist (lst2lists coords 2))
 (setq xylist (move (list 0 0) BasePnt xylist))
 (setq xylist (LM:UniqueFuzz xylist 0.09))
 xylist
)
(defun LM:UniqueFuzz ( l f / x r )
    (while l
        (setq x (car l)
              l (vl-remove-if (function (lambda ( y ) (equal x y f))) (cdr l))
              r (cons x r)
        )
    )
    (reverse r)
)
(defun move (FROMPNT TOPNT PNTLIST / DIST)
  (setq PNTLIST (reverse PNTLIST))
  (setq DIST (distance FROMPNT TOPNT))
  (reverse (mapcar '(lambda (X)
           (polar X (angle FROMPNT TOPNT) DIST)
          )
          PNTLIST
      )
 )
)
(defun lst2lists (LST     ; LiST to DIVide into list of lists
                  DIV /   ; integer qnt of elements to put in each list
                  INC     ; INCrement
              LSTPART     ; LiST PART length of which = DIV
               RETLST)    ; the RETurned LiST of lists
  (setq INC 0)
  (while (setq LSTPART (sublst LST INC DIV))
     (setq RETLST (cons LSTPART RETLST)
              INC (+ INC DIV))
  )
  (reverse RETLST)
)
(defun sublst (LST     ; LiST to operate on
                 N     ; "N"th atom to start with - 0 being the first one
             NUM /     ; NUMber of atoms to get in sequence
                L)     ; sub List
    (if (and NUM (< (+ N NUM)(length LST))) 
      (repeat NUM
         (setq L (cons (nth N LST) L) N (1+ N)))
      (repeat (- (length LST) N)
         (setq L (cons (nth N LST) L) N (1+ N)))
    )
  (setq L (reverse L))
)

 

13 REPLIES 13
Message 2 of 14
Gary_J_Orr
in reply to: mdhutchinson

Hopefully you have figured this out by now but... At first glance, you're probably facing the same issue as with any "complex entity" when it comes to point storage...

Translating from the OCS (Object Based Coordinate system) to either the WCS or the UCS (as is appropriate), then back again if needed for direct entity manipulation.

Trans function in pure lisp, to translate to UCS:  

(setq newpoint (trans origpoint entity 1))

there's a similar function for ActiveX but I can't remember how to access it off the top of my head...

Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)
Message 3 of 14
mdhutchinson
in reply to: Gary_J_Orr

nope... applying the jist of your suggestion... (setq newpoint (trans origpoint entity 1))... returns the same list un-altered.

 

If I move and rotate the AecPolyGon... getting the list of points with or without the trans, the first point lines up... but the rest of the points are unrotated.

 

Message 4 of 14
Gary_J_Orr
in reply to: mdhutchinson

I guess I don't understand enough of what you are trying to do...

When I run your functions as you posted them I get a return of a modified list of the coordinates even without translating (when in the same coordinate system as the AEC_Polygon was drawn in):

xylist Before mods:

((1690.13 0.0) (1551.86 1249.54) (162.323 1319.49) (-457.327 682.138) (0.0 0.0))

xylist after move and fuzz:

((2706.88 727.062) (2568.61 1976.6) (1179.07 2046.55) (559.423 1409.2) (1016.75 727.062))

 

What are you trying to do with the modified list?

 

If you are trying to use those points to modify the coordinate values directly on the profile then you will run into a bit of a problem as the coodrinates of the profile are readonly and are actually further defined by the "rings" within the profile...

 

This from a dump object on the profile:

; IAecProfile: Provides access to a 2D profile object within the database
; Property values:
;   Area (RO) = 2.33544e+006
;   Bounds (RO) = (-457.327 1319.49 1690.13 0.0)
;   Centroid (RO) = (699.254 628.561)
;   Coordinates (RO) = (1690.13 0.0 1551.86 1249.54 162.323 1319.49 ... )
;   Perimeter (RO) = 6048.77
;   Rings (RO) = #<VLA-OBJECT IAecRings 20ea3450>
;   SelfIntersects (RO) = 0
;   Valid (RO) = -1
; Methods supported:
;   Add (1)
;   Clear ()
;   CopyFrom (1)
;   Intersect (1)
;   ScaleXY (2)
;   Subtract (1)

 

So I guess it goes back to: what are you trying to do?

Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)
Message 5 of 14
mdhutchinson
in reply to: Gary_J_Orr

I was previously using a light-weight polyline... my function works fine for this case. But the users had to also create matching AecPolyGons to get schedule data to use a location property. I was hoping to dump having to create a lwpolyline and use only the AecPolyGon.

I am using the points for a window polygon with which to programatically select objects that lay within the AecPolyGons.

I would have thought I could get rid of the move function... and use the trans function instead... but the resulting points don't seem to adjust at all to account for rotation of the AecPolyGon or for a differing user coordinate system. I think what is happening is that trans function only works with native AutoCAD objects, especially since a couple releases ago, Autodesk moved the top level object data out of the MEP objects in order to improve performance. I think I will have to do resort to matrices math to do the transilation. 

 

Message 6 of 14
Gary_J_Orr
in reply to: mdhutchinson

Give this a try (and looks like the trans function isn't required for the point collection as the location property always seems to return WCS coordinates... of course, if what you're passing the point list to uses UCS for input it may still be required to trans from WCS to UCS).

Short of it is: you were correct in needing the rotation of the primary object... and the translation of the points (your move function which I just incorporated into the main function) needed a little twisting.

 

(defun MEPObjVertices ( / Ent Obj BaseProfObj ObjBasePt OBJRot coords Returnlist)
  (setq Ent (car (entsel "\nSelect an AEC_PolyGon or an AEC_Space: ")))
  (setq Obj (vlax-ename->vla-object Ent))
  (setq BaseProfObj
	 (cond
	   ((= (vla-get-objectname Obj) "AecDbPolygon")
	    (vlax-get-property Obj "Profile")
	    );cond 1 AEC_Polygon
	   ((= (vla-get-objectname Obj) "AecDbSpace")
	    (vlax-get-property Obj "BaseProfile")
	    );cond 2 AEC_Space
	   );cond stmt
	);setq
  (setq OBJRot (vlax-get-property Obj "Rotation"))
  (setq ObjBasePt (vlax-safearray->list
		    (vlax-variant-value
		      (vlax-get-property Obj "Location")
		      )
		    )
	);basept
  (setq coords (vlax-safearray->list
		 (vlax-variant-value
		   (vlax-get-property BaseProfObj "Coordinates")
		   )
		 )
	);coords
  (setq Returnlist
	 (mapcar '(lambda (pt)
		    (polar (list (car ObjBasePt) (cadr ObjBasePt))
			   (+ (angle (list 0 0) pt) OBJRot)
			   (distance (list 0 0) pt)
			   )
		    )
		 (lst2lists coords 2)
		 )
	)
  (setq Returnlist (LM:UniqueFuzz Returnlist 0.09))
  )

 Happy Lisping

-Gary

Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)
Message 7 of 14
mdhutchinson
in reply to: Gary_J_Orr

yep it works... I see you incorporated move function (as you mentions) and applied a rotate also. This does work...

I would like to get the trans in there just in case the user has a ucs that is not aligned with the wcs.

 

I added this to the end of what you did... it continues to work for WCS, but it seems to also apply a move on the points with a vector calculated from WCS origin to UCS origin. (I wonder if the move code needs to come out and use trans instead). Rotation seems correct in all cases.

 

(mapcar (function (lambda (x)
           (trans x 0 1 0)
          )
     )
     Returnlist
 )

 

Were you in agreement with trans doesn't seem to work to transilate from OCS since autodesk pulled the top level data from all mep object types?

 

I really appreciate your help on this!

Message 8 of 14
Gary_J_Orr
in reply to: mdhutchinson


@mdhutchinson wrote:

yep it works... I see you incorporated move function (as you mentions) and applied a rotate also. This does work...

I would like to get the trans in there just in case the user has a ucs that is not aligned with the wcs.

 

I added this to the end of what you did... it continues to work for WCS, but it seems to also apply a move on the points with a vector calculated from WCS origin to UCS origin. (I wonder if the move code needs to come out and use trans instead). Rotation seems correct in all cases.

 

(mapcar (function (lambda (x)
           (trans x 0 1 0)
          )
     )
     Returnlist
 )

 

Were you in agreement with trans doesn't seem to work to transilate from OCS since autodesk pulled the top level data from all mep object types?

 

I really appreciate your help on this!


 

I'm not sure as to what you mean by "pulled top level data..." What I do know from playing with this is that the position returned for the space/polygon object is always in WCS (as is the rotation value) and not in the form of an OCS as I had originally thought would be the case (before actually looking into it). This can be seen by stepping into the function with WCS current, then again with a UCS current.

 

but yes, you should include the trans function to convert the return list from WCS to UCS only without the "displacement" flag:

(trans x 0 1)

 

to remove the conversion of the points from the profile coords (the part previously in your "move" function) would require building your own conversion matrix and using the vlax-tmatrix to do the conversion... that idea just made my head hurt... and simply isn't needed. It was just a matter of figuring out the relationship of the profile coords to the container object (I went through a several approaches, which is why I integrated the sub... it made it easier to pass different aspects into the lambda expression until I found the correct track). But no matter what you do, the trans function alone will not do the complete conversion due to the embedded relationships (I even tried using trans from profile enty OCS to space/polygon enty OCS without success since neither have an actual OCS... they simply pass through to the WCS)

 

With your addition of trans at the end of my suggestion you take care of any UCS issues.

 

load the function then run either one of these (first in WCS then with a UCS) where the obj in question has entities within it (although with this simplified example it will at least return the original space/polygon)...

(setq ptlist (MEPObjVertices))

(setq ss (ssget "_CP" ptlist))

(sslength ss)

 

or:

(setq ptlist (MEPObjVertices))  

(command "._pline")  

(foreach pt ptlist    

(command pt)    

)  

(command "close")

 

the only other possible suggestion (for performance if nothing else) would be to check to see if the current UCS IS the WCS prior to translating the points if WCS is current, just return the original returnlist, otherwise translate the return list as the return value). in doing so you can also check for more complicated issues such as viewport DCS... but odds are that is going beyond practical need.

-G

Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)
Message 9 of 14
mdhutchinson
in reply to: Gary_J_Orr

Thanks... that worked...

 

concerning "I'm not sure as to what you mean by 'pulled top level data...'  "

I mean the data in the parent object... see the attached image...

Message 10 of 14
Gary_J_Orr
in reply to: mdhutchinson

I get ya now... yeah, they're doing away with a lot of the dictionary references that used to give us access to the AEC data and properties...

The math would have been just as bad though as the relationships would have still needed to have been worked out.

 

Thankfully they didn't nix the dict and xdata stuff until after they had exposed most to ActiveX (although there are still limitations)... they believed that they were securing their data (and for many they were since a single misstep in the dict trees needed to track info down and modify it would corrupt an AEC entity, sometimes even to the point of making a drawing unstable).

 

Anyway... you should now have a working function (I do at least, complete with a quick check on the UCS...)

 

(defun MEPObjVertices ( / Ent Obj BaseProfObj ObjBasePt OBJRot coords Returnlist)
  (setq Ent (car (entsel "\nSelect an AEC_PolyGon or an AEC_Space: ")))
  (setq Obj (vlax-ename->vla-object Ent))
  (setq OBJRot (vlax-get-property Obj "Rotation"))
  (setq ObjBasePt (vlax-safearray->list
		    (vlax-variant-value
		      (vlax-get-property Obj "Location")
		      )
		    )
	);basept
  (setq BaseProfObj
	 (cond
	   ((= (vla-get-objectname Obj) "AecDbPolygon")
	    (vlax-get-property Obj "Profile")
	    );cond 1 AEC_Polygon
	   ((= (vla-get-objectname Obj) "AecDbSpace")
	    (vlax-get-property Obj "BaseProfile")
	    );cond 2 AEC_Space
	   );cond stmt
	);setq
  (setq coords (vlax-safearray->list
		 (vlax-variant-value
		   (vlax-get-property BaseProfObj "Coordinates")
		   )
		 )
	);coords
  (setq Returnlist
	 (mapcar '(lambda (pt)
		    (polar ObjBasePt
			   (+ (angle (list 0 0) pt) OBJRot)
			   (distance (list 0 0) pt)
			   );polar
		    );lambda
		 (lst2lists coords 2)
		 );mapcar
	);returnlist
  (setq Returnlist (LM:UniqueFuzz Returnlist 0.09))
  (if (= 0 (getvar "WorldUCS"))
    (mapcar (function (lambda (x)
			(trans x 0 1)
			)
		      )
	    Returnlist
	    );mapcar
    Returnlist
    );if not WCS
  )

 

see, my help was a matter of selfishness... now I have a function that I was thinking about anyway as part of an exporting function for asset management, a bit of tweaking and I'm all set 😉

*ReallyBigGrin*

-G

 

Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)
Message 11 of 14
mdhutchinson
in reply to: Gary_J_Orr

thanks for your latest reply... !

 

ooh ... 'asset managment' ? 

I am curious now.  you care to share this?

Message 12 of 14
Gary_J_Orr
in reply to: mdhutchinson

Currently it's in the form of a vba app that I built for a client a few years ago... They were an Interior design/furniture procurement/facility Asset Management firm.

It functioned on Acad using plines as room boundaries (they had a mission critical plug-in for their furnishings that didn't play well with ACA or Revit and many of their clients were on Core ACAD so...), exporting data about assets to Access where they could generate reports (which had it's own VBA code), and further an Excell app that generated budgets for new work/remodels from that same data source...

And it was all roundtrip, they could use the access forms to input data in the field of existing assets, then call on those assets from acad to create as builts/existing conditions, then call on them again and assign them to new locations for move management during remodelling and the like, adding new items as required, dumping it all back to Access along the way.

I've been thinking about building something new and less "client specific" using some of the general concepts... but "share" it... I've been out of work for so long that I'm losing my home so, no, sorry, if I do it I'll be selling it.
Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)
Message 13 of 14
mdhutchinson
in reply to: Gary_J_Orr

out of work for sooo long?  With your skillset?... this is hard to believe.

 

Were do you live?

Message 14 of 14
Gary_J_Orr
in reply to: mdhutchinson

I currently live in St. Louis... for now at any rate...
A few years ago AUGI did a report on CAD/BIM managers... reported that the majority of the good ones had degrees in the discipline that they are serving... now everyone requires a degree in a specific field, and, since most resumes are now taken through automated means or via "hiring agencies"  mine gets ruled out immediately since I don't have such a degree... my skills (developed over 15 years of doing the job with 15 years of prior experience in commercial/industrial construction giving me first hand knowledge of the requirements and realities of putting a building together) mean nothing to a computer or recruiter that will recieve a hundred apps that will match their requirements.
...
but oh well, enough griping, that's life I reckon
-G

Gary J. Orr
(Your Friendly Neighborhood) CADD/BIM/VDC Applications Manager
http://www.linkedin.com/in/garyorr

aka (current and past user names):
Gary_J_Orr (GOMO Stuff 2008-Present); OrrG (Forum Studio 2005-2008); Gary J. Orr (LHB Inc 2002-2005); Orr, Gary J. (Gossen Livingston 1997-2002)

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report

”Boost