broncos15 Posted July 6, 2017 Share Posted July 6, 2017 I am trying to write a routine that would draw polylines to all the local depressions in a surface. The way that I currently find the local depressions is by doing a watershed analysis, changing my surface style to show local depressions as node points, and then just manually going around and verifying that the local depressions are correct. On very large sites (20+ acres) it is time consuming to go make sure that you didn't miss any local depressions when you go through and check each one. That is why I want to have a routine that would let me select the surface after a watershed analysis is performed and draw polylines to every local depression node. The issue is that I cannot find where that information is stored. I have done a dump of the vla information and dxf information and cannot find anything. Does anyone have any suggestions? Quote Link to comment Share on other sites More sharing options...
broncos15 Posted July 6, 2017 Author Share Posted July 6, 2017 I found this information on how the vb code works for the watershed analysis, but I'm still unsure how to get the results. https://knowledge.autodesk.com/support/autocad-civil-3d/learn-explore/caas/CloudHelp/cloudhelp/2017/ENU/Civil3D-DevGuide/files/GUID-CF359595-EF4A-4A74-A7DD-C86F8758DE3E-htm.html Quote Link to comment Share on other sites More sharing options...
ronjonp Posted July 6, 2017 Share Posted July 6, 2017 Sounds like a fun problem. Can you post your file? ( you'll have to bear with me though, I'm fairly C3D illiterate ) Quote Link to comment Share on other sites More sharing options...
broncos15 Posted July 6, 2017 Author Share Posted July 6, 2017 Thank you so much for being able to look at this! This is just a really quick example. Depression test.dwg Quote Link to comment Share on other sites More sharing options...
ronjonp Posted July 6, 2017 Share Posted July 6, 2017 I'll take a look in the morning. Quote Link to comment Share on other sites More sharing options...
lrm Posted July 7, 2017 Share Posted July 7, 2017 Just curious, can you use the surface analysis function ANALYSISCURVATURE on C3D surfaces? Quote Link to comment Share on other sites More sharing options...
ronjonp Posted July 7, 2017 Share Posted July 7, 2017 (edited) Thank you so much for being able to look at this! This is just a really quick example. No knowing exactly what you're trying to accomplish from the example drawing, maybe this will give you a start. It draws a line from a picked point to all drain locations ( which I assume are depressions? ) (defun c:sa (/ _getsurfaceanalysis a anlsys drains out p p2 wshed x) ;; https://www.theswamp.org/index.php?topic=50877.msg559985#msg559985 ;; RJP modified for surface analysis 07.07.2017 (defun _getsurfaceanalysis (/ c3d civdb civdoc out) (if (and (setq c3d (strcat "HKEY_LOCAL_MACHINE\\" (if vlax-user-product-key (vlax-user-product-key) (vlax-product-key) ) ) ) (setq c3d (vl-registry-read c3d "Release")) (setq c3d (substr c3d 1 (vl-string-search "." c3d (+ (vl-string-search "." c3d) 1)))) (setq c3d (vla-getinterfaceobject (vlax-get-acad-object) (strcat "AeccXUiLand.AeccApplication." c3d) ) ) (setq civdoc (vlax-get c3d 'activedocument)) (setq civdb (vlax-get civdoc 'database)) ) (vlax-for x (vlax-get civdb 'surfaces) (setq out (cons (vlax-get x 'surfaceanalysis) out))) ) out ) (if (and (setq a (_getsurfaceanalysis)) (setq anlsys (mapcar '(lambda (x) (vlax-get x 'watershedanalysis)) a)) (setq wshed (mapcar '(lambda (x) (vlax-get x 'watershedregions)) anlsys)) (or (foreach shed wshed (vlax-for shed2 shed (if (vlax-property-available-p shed2 'drains) (setq drains (cons (vlax-get shed2 'drains) drains)) ) ) ) drains ) (foreach drain drains (vlax-for drain2 drain (setq out (cons drain2 out)))) (setq p (getpoint "\nPick a point away from the surface: ")) ) (foreach x out (if (setq p2 (vlax-get x 'location)) (entmakex (list '(0 . "line") (cons 10 p) (cons 11 p2))) ) ) ) (princ) ) Edited July 10, 2017 by ronjonp Quote Link to comment Share on other sites More sharing options...
BIGAL Posted July 8, 2017 Share Posted July 8, 2017 (edited) Nice one Ronjop once you know what your looking for in terms of database names you can get a lot of info as per the link. I have the Version check as a Library defun, I use the check in a number of surface routines. Getting the info via the registery is a good idea. For any one using the other ways of finding the version numbers. ((vl-string-search "R20.0" vrsn)(setq appstr "10.4"));;2015 ((vl-string-search "R20.1" vrsn)(setq appstr "10.5"));;2016 ((vl-string-search "R21.0" vrsn)(setq appstr "11.0"));;2017 ((vl-string-search "R22.0" vrsn)(setq appstr "12.0"));;2018 You may be interested in this Chcontourstoolbar.zip Edited July 8, 2017 by BIGAL Quote Link to comment Share on other sites More sharing options...
broncos15 Posted July 10, 2017 Author Share Posted July 10, 2017 Ron, thank you so much for the help with this! When I try running the function, I get the following error: ActiveX Server returned the error: unknown name: "DRAINS". I know that this means that the function drains doesn't exist, but what should I replace that with? Quote Link to comment Share on other sites More sharing options...
ronjonp Posted July 10, 2017 Share Posted July 10, 2017 Ron, thank you so much for the help with this! When I try running the function, I get the following error: ActiveX Server returned the error: unknown name: "DRAINS". I know that this means that the function drains doesn't exist, but what should I replace that with? The error is probably on this line: (vlax-for shed2 shed (setq drains (cons [b](vlax-get shed2 'drains)[/b] drains))) You're going to have to troubleshoot this as the code works on my computer, but I'm also using C3D 2017. Quote Link to comment Share on other sites More sharing options...
broncos15 Posted July 10, 2017 Author Share Posted July 10, 2017 Ah, that makes sense. I am using 2015, so I will have to see if this function exists for 2015, or if there is an equivalent function. Quote Link to comment Share on other sites More sharing options...
broncos15 Posted July 10, 2017 Author Share Posted July 10, 2017 So I have been looking through the developer’s guide for 2013 and 2015 and it states “The .NET API does not implement an equivalent to the COM API AeccSurfaceAnalysisWatershed.CalculateWatersheds() method, but you can use the SurfaceAnalysis.Ge****ershedData() method to access watershed data from an existing analysis, and change properties (such as AreaColor) of watershed regions.” After running through each line of code, the anlsys variable (which finds the watershed analysis) and the wshed, which finds the watershedregions, both give valid responses. I’m confused why they won’t give the drains value (for a local depression) after looking through the developer’s guide. Does anyone have any suggestions/advice on what I can try to look into? Quote Link to comment Share on other sites More sharing options...
ronjonp Posted July 10, 2017 Share Posted July 10, 2017 (edited) Can you post the drawing you're trying the code out on? Here's an object dump on: IAeccWatershedRegionDepression ; IAeccWatershedRegionDepression: Watershed Region Depression interface; Property values: ; Area (RO) = 80.0 ; BoundaryLine (RO) = multi dimension safearray not supported ; Drains (RO) = # ; Id (RO) = 1 ; Type (RO) = 2 ; No methods Edited July 10, 2017 by ronjonp Quote Link to comment Share on other sites More sharing options...
broncos15 Posted July 10, 2017 Author Share Posted July 10, 2017 Attached is a portion of my surface. I had to trim it down because it is so large. Local Depression.dwg Quote Link to comment Share on other sites More sharing options...
ronjonp Posted July 10, 2017 Share Posted July 10, 2017 I updated the original code. The reason it was erroring out is because there are different types of objects embedded within the 'wshed'. _$ (# # # # # # # # # # # # # # # # # # # # # # # # # # ) Quote Link to comment Share on other sites More sharing options...
broncos15 Posted July 10, 2017 Author Share Posted July 10, 2017 That works nearly perfectly, thank you so much for your help! The lines are being drawn to the lowest the lowest points on the depressions region edge where this overflow may take place, rather than the actual lowest point within the watershed depression (i.e. the local depression). I am going to try and see if I can figure out where that information is located within the watershed depression. Quote Link to comment Share on other sites More sharing options...
ronjonp Posted July 10, 2017 Share Posted July 10, 2017 I don't see anything within 'wsched' objects that will draw lines to the red drains on your last example drawing. Here's another version that does a bit more .. maybe you can figure out what you need (defun c:sa (/ _getsurfaceanalysis a anlsys drains drainpt out p p2 wshed x) ;; https://www.theswamp.org/index.php?topic=50877.msg559985#msg559985 ;; RJP modified for surface analysis 07.07.2017 (defun _getsurfaceanalysis (/ c3d civdb civdoc out) (if (and (setq c3d (strcat "HKEY_LOCAL_MACHINE\\" (if vlax-user-product-key (vlax-user-product-key) (vlax-product-key) ) ) ) (setq c3d (vl-registry-read c3d "Release")) (setq c3d (substr c3d 1 (vl-string-search "." c3d (+ (vl-string-search "." c3d) 1)))) (setq c3d (vla-getinterfaceobject (vlax-get-acad-object) (strcat "AeccXUiLand.AeccApplication." c3d) ) ) (setq civdoc (vlax-get c3d 'activedocument)) (setq civdb (vlax-get civdoc 'database)) ) (vlax-for x (vlax-get civdb 'surfaces) (setq out (cons (vlax-get x 'surfaceanalysis) out))) ) out ) (if (and (setq a (_getsurfaceanalysis)) (setq anlsys (mapcar '(lambda (x) (vlax-get x 'watershedanalysis)) a)) (setq wshed (mapcar '(lambda (x) (vlax-get x 'watershedregions)) anlsys)) (or (foreach shed wshed (vlax-for shed2 shed (cond ((vlax-property-available-p shed2 'drains) (setq drains (cons (vlax-get shed2 'drains) drains)) ) ((vlax-property-available-p shed2 'drainpoint) (setq drainpt (cons (vlax-get shed2 'drainpoint) drainpt)) ) ((vlax-property-available-p shed2 'boundarydrainpoint) (setq drainpt (cons (vlax-get shed2 'boundarydrainpoint) drainpt)) ) ((vlax-property-available-p shed2 'boundarydrainsegment) (setq drainpt (cons (vlax-get shed2 'boundarydrainsegment) drainpt)) ) ) ) ) drains ) (foreach drain drains (vlax-for drain2 drain (setq out (cons (vlax-get drain2 'location) out))) ) (setq p (getpoint "\nPick a point away from the surface: ")) ) (foreach x (append out drainpt) (setq p2 x) (if (= 3 (length p2)) (entmakex (list '(0 . "line") (cons 10 p) (cons 11 p2))) (while p2 (entmakex (list '(0 . "line") (cons 10 p) (cons 11 (list (car p2) (cadr p2) (caddr p2))))) (setq p2 (cdddr p2)) ) ) ) ) (princ) ) Quote Link to comment Share on other sites More sharing options...
broncos15 Posted July 10, 2017 Author Share Posted July 10, 2017 I don't see anything within 'wsched' objects that will draw lines to the red drains on your last example drawing. Here's another version that does a bit more .. maybe you can figure out what you need (defun c:sa (/ _getsurfaceanalysis a anlsys drains drainpt out p p2 wshed x) ;; https://www.theswamp.org/index.php?topic=50877.msg559985#msg559985 ;; RJP modified for surface analysis 07.07.2017 (defun _getsurfaceanalysis (/ c3d civdb civdoc out) (if (and (setq c3d (strcat "HKEY_LOCAL_MACHINE\\" (if vlax-user-product-key (vlax-user-product-key) (vlax-product-key) ) ) ) (setq c3d (vl-registry-read c3d "Release")) (setq c3d (substr c3d 1 (vl-string-search "." c3d (+ (vl-string-search "." c3d) 1)))) (setq c3d (vla-getinterfaceobject (vlax-get-acad-object) (strcat "AeccXUiLand.AeccApplication." c3d) ) ) (setq civdoc (vlax-get c3d 'activedocument)) (setq civdb (vlax-get civdoc 'database)) ) (vlax-for x (vlax-get civdb 'surfaces) (setq out (cons (vlax-get x 'surfaceanalysis) out))) ) out ) (if (and (setq a (_getsurfaceanalysis)) (setq anlsys (mapcar '(lambda (x) (vlax-get x 'watershedanalysis)) a)) (setq wshed (mapcar '(lambda (x) (vlax-get x 'watershedregions)) anlsys)) (or (foreach shed wshed (vlax-for shed2 shed (cond ((vlax-property-available-p shed2 'drains) (setq drains (cons (vlax-get shed2 'drains) drains)) ) ((vlax-property-available-p shed2 'drainpoint) (setq drainpt (cons (vlax-get shed2 'drainpoint) drainpt)) ) ((vlax-property-available-p shed2 'boundarydrainpoint) (setq drainpt (cons (vlax-get shed2 'boundarydrainpoint) drainpt)) ) ((vlax-property-available-p shed2 'boundarydrainsegment) (setq drainpt (cons (vlax-get shed2 'boundarydrainsegment) drainpt)) ) ) ) ) drains ) (foreach drain drains (vlax-for drain2 drain (setq out (cons (vlax-get drain2 'location) out))) ) (setq p (getpoint "\nPick a point away from the surface: ")) ) (foreach x (append out drainpt) (setq p2 x) (if (= 3 (length p2)) (entmakex (list '(0 . "line") (cons 10 p) (cons 11 p2))) (while p2 (entmakex (list '(0 . "line") (cons 10 p) (cons 11 (list (car p2) (cadr p2) (caddr p2))))) (setq p2 (cdddr p2)) ) ) ) ) (princ) ) I will mess around with this updated code and see what I can do. Thank you again for all of your help! Quote Link to comment Share on other sites More sharing options...
broncos15 Posted July 10, 2017 Author Share Posted July 10, 2017 So I think I figured out how to get the point, it will be the centroid of the boundary line of the watershed region. The point values of the boundary lines are in an array, which I am not very good at. I have tried to mess with code and do (foreach shed wshed (vlax-for shed2 shed (if (vlax-property-available-p shed2 'boundaryline) (setq drains (cons (vlax-SafeArray->List (vlax-get-property shed2 'boundaryline)) drains)) ) ) ) Quote Link to comment Share on other sites More sharing options...
ronjonp Posted July 11, 2017 Share Posted July 11, 2017 So I think I figured out how to get the point, it will be the centroid of the boundary line of the watershed region. The point values of the boundary lines are in an array, which I am not very good at. I have tried to mess with code and do (foreach shed wshed (vlax-for shed2 shed (if (vlax-property-available-p shed2 'boundaryline) (setq drains (cons (vlax-SafeArray->List (vlax-get-property shed2 'boundaryline)) drains)) ) ) ) You might be out of luck: Command: SA; error: multi dimension safearray not supported ; reset after error Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.