Leaderboard
Popular Content
Showing content with the highest reputation since 02/10/2026 in all areas
-
3 points
-
I implemented astar using a heap instead of the dictionnary proposed by @GLAVCVS. Safearray is used to simulate the heap. Was done with prompt in Google AI. Results the heap is faster specially if the graph is bigger. ;; ; ;; c:A* by ymg ; ;; Astar implemented with a Heap instead of a dictionnary ; ;; Edges of the Graph are drawn on layer identified by Golbal #Edgeslay ; ;; ; ;; Edges can be lines, lpolylines or 3dpolylines ; ;; You select Start and End points. Shortest is then found and drawn as a ; ;; 3D Polylines on layer, color and lineweight chosen via Global vars ; ;; found at beginning of this routine ; ;; ; ;; Heap has a faster running time than the dictionnary and list approach ; ;; as the size of the graph grows. ; ;; ; (defun c:A* (/ ss graph openH gScore cameFrom found cur curPt curK sNode sKey neighbor nKey t_g val oldG oldCF Startp Endp d minD en param endpar p1 p2 path k link pt i ti) (vl-load-com) (or #acdoc (setq #acdoc (vla-get-activedocument (vlax-get-acad-object)))) (set_errhandler '("CLAYER" "OSMODE" "CMDECHO" "DIMZIN")) (setvar 'CMDECHO 0) (setvar 'OSMODE 1) (setq #Edgelay "Edges" #Pathlay "Path" #Pathcol 1 #Pathlwt 70 #Hptr 0 ) ;; Selecting set of entities defining edges of graph. (if (not (setq ss (ssget "X" (list '(0 . "LINE,LWPOLYLINE,POLYLINE") (cons 8 #Edgelay))))) (progn (alert (strcat "\nError: No entities found on layer " #Edgelay)) (exit) ) ) ;; Geting Start and End points. (Use snap to endpoint) (setq Startp (getpoint "\nPick Start Point: ")) (setq Endp (getpoint "\nPick End Point: ")) (vla-startundomark #acdoc) (setq ti (getvar 'MILLISECS)) ;Timer for execution time ; Building Graph... (setq graph nil i 0) (repeat (sslength ss) (setq en (ssname ss i) param 0 endpar (vlax-curve-getEndParam en) i (1+ i) ) (while (< param endpar) (setq p1 (vlax-curve-getPointAtParam en param) p2 (vlax-curve-getPointAtParam en (setq param (1+ param))) k1 (pt->key p1) k2 (pt->key p2) graph (update-g graph k1 p1 p2) graph (update-g graph k2 p2 p1) ) ) ) (setq minD 1.7e308) ; Initialize to infinity (foreach entry graph (if (< (setq d (distance (cadr entry) Startp)) minD) (setq minD d sNode entry) ) ) (setq sKey (car sNode) openH (heap:new (length graph)) gScore (list (cons sKey 0.0)) cameFrom nil found nil ) (heap:push openH (distance (cadr sNode) Endp) (cadr sNode)) (princ (strcat "\n Graph Size: " (itoa (length graph)) " nodes")) (princ (strcat "\n Graph Building Time: " (itoa (setq gbti (- (getvar 'MILLISECS) ti))) " ms.")) ;Start of Pathfinding... (while (and (> #Hptr 0) (not found)) (setq cur (heap:pop openH) curPt (cdr cur) curK (pt->key curPt) ) (if (< (distance curPt Endp) 0.1) (setq found T) (foreach neighbor (cddr (assoc curK graph)) (setq nKey (pt->key neighbor) val (assoc curK gScore) t_g (+ (cdr val) (distance curPt neighbor)) ) (if (or (null (setq oldG (assoc nKey gScore))) (< t_g (cdr oldG))) (progn (if oldG (setq gScore (vl-remove oldG gScore))) (setq gScore (cons (cons nKey t_g) gScore)) (if (setq oldCF (assoc nKey cameFrom)) (setq cameFrom (subst (cons nKey curPt) oldCF cameFrom)) (setq cameFrom (cons (cons nKey curPt) cameFrom)) ) (heap:push openH (+ t_g (distance neighbor Endp)) neighbor) ) ) ) ) ) ;; Result Handling (if found (progn (setq path (list curPt) k curK ) (while (setq link (assoc k cameFrom)) (setq pt (cdr link) k (pt->key pt) path (cons pt path) ) ) (mk_3dp path) ) (princ "\nNo path found.") ) (vla-endundomark #acdoc) (setq totaltime (- (getvar 'MILLISECS) ti)) (princ (strcat "\n Pathfinding Time: " (itoa (- totaltime gbti)) " ms.")) (princ (strcat "\nTotal Execution time: " (itoa totaltime) " ms.")) (*error* nil) ) ;; ; ;; ERROR HANDLING & SYSTEM UTILITIES ; ;; ; ;; ; ;; set_errhandler by Elpanov Evgenyi ; ;; Captures system variable states into global #varl. ; ;; Argument 'l': List of strings naming system variables. ; ;; ; (defun set_errhandler (l) (setq #varl (mapcar (function (lambda (a) (list 'setvar a (getvar a)))) l)) ) ;; ; ;; *error* by Elpanov Evgenyi ; ;; Redefines the *error* function and display an error message. ; ;; Restores system variables and handles exit messages. ; ;; ; (defun *error* (msg) (mapcar 'eval #varl) (if (and msg (not (wcmatch (strcase msg) "*BREAK*,*CANCEL*,*EXIT*"))) (princ (strcat "\nError: " msg)) ) (princ) ) ;; ; ;; Heap Abstraction Utilities Using Safearray ; ;; ; ;; ; ;; heap:new ; ;; ; ;; Initializes a Variant Safearray as a Minimum-Heap and set the Heap pointer ; ;; Global Var #Hptr to 0 ; ;; ; ;; Argument: size, Total capacity for the Heap. ; ;; ; ;; Return : Safearray Object ; ;; ; (defun heap:new (size) (setq #Hptr 0) (vlax-make-safearray vlax-vbVariant (cons 0 (max 1 (1- size))) '(0 . 1)) ) ;; ; ;; heap:get ; ;; ; ;; Fetch node data at given index in the heap ; ;; ; ;; Arguments: h, Heap name as a safearray object ; ;; idx, Index of the node ; ;; ; ;; Returns: A dotted pair, (Priority . Point) ; ;; ; (defun heap:get (h idx) (cons (vlax-variant-value (vlax-safearray-get-element h idx 0)) (vlax-safearray->list (vlax-variant-value (vlax-safearray-get-element h idx 1))) ) ) ;; ; ;; heap:set ; ;; ; ;; Writes priority and point into heap at index. ; ;; Arguments: h, heap name ; ;; i, index ; ;; prio, double ; ;; p, point. ; ;; ; (defun heap:set (h i prio p / arr) (setq arr (vlax-make-safearray vlax-vbDouble '(0 . 2))) (vlax-safearray-fill arr (mapcar 'float p)) (vlax-safearray-put-element h i 0 (vlax-make-variant prio vlax-vbDouble)) (vlax-safearray-put-element h i 1 arr) ) ;; ; ;; heap:swap ; ;; ; ;; Swaps two elements the heap ; ;; ; ;; Arguments: h, heap name ; ;; i, index of first element ; ;; j, index of second element ; ;; ; (defun heap:swap (h i j / tp tv) (setq tp (vlax-safearray-get-element h i 0) tv (vlax-safearray-get-element h i 1) ) (vlax-safearray-put-element h i 0 (vlax-safearray-get-element h j 0)) (vlax-safearray-put-element h i 1 (vlax-safearray-get-element h j 1)) (vlax-safearray-put-element h j 0 tp) (vlax-safearray-put-element h j 1 tv) ) ;; ; ;; heap:push ; ;; Adds a node, re-sorts heap via sift-up and adjust the heap pointer ; ;; ; ;; Arguments: h, heap name ; ;; prio, priority ; ;; pt, point ; ;; ; ;; Returns: Value of heap pointer ; ;; ; (defun heap:push (h prio pt / i p) (heap:set h #Hptr prio pt) (setq i #Hptr) (while (and (> i 0) (< prio (car (heap:get h (setq p (/ (1- i) 2)))))) (heap:swap h i p) (setq i p) ) (setq #Hptr (1+ #Hptr)) ) ;; ; ;; heap:pop ; ;; ; ;; Removes root node, re-sorts the heap by sift-down updates #Hptr ; ;; ; ;; Argument: h, heap name ; ;; ; ;; Return: root node as dotted pair (Priority . Point) ; ;; ; (defun heap:pop (h / root size i l r s i-prio l-prio r-prio) (if (> #Hptr 0) (progn (setq root (heap:get h 0) #Hptr (1- #Hptr)) (if (> #Hptr 0) (progn (heap:swap h 0 #Hptr) (setq i 0 size #Hptr) (while (< (setq l (1+ (* i 2))) size) (setq r (1+ l) ;; Get priorities once to avoid redundant safearray lookups i-prio (vlax-variant-value (vlax-safearray-get-element h i 0)) l-prio (vlax-variant-value (vlax-safearray-get-element h l 0)) s l ) ;; Check if right child exists and is smaller than left (if (and (< r size) (< (setq r-prio (vlax-variant-value (vlax-safearray-get-element h r 0))) l-prio)) (setq s r l-prio r-prio)) ;; Update smallest index and priority ;; If smallest child is smaller than current, swap (if (< l-prio i-prio) (progn (heap:swap h i s) (setq i s)) (setq i size)) ;; Else, heap property restored ) ) ) root ) ) ) ;; ; ;; GRAPH & DRAWING UTILITIES ; ;; ; ;; ; ;; pt->key ; ;; Converts 3D point to a string key "X,Y,Z". ; ;; Argument 'p': 3D point list. ; ;; ; (defun pt->key (p) (strcat (rtos (car p) 2 2) "," (rtos (cadr p) 2 2) "," (rtos (caddr p) 2 2))) ;; ; ;; update-g ; ;; Links nodes in graph association list. ; ;; ; ;; Arguments: g, graph list ; ;; k, key ; ;; p, point ; ;; n, neighbor. ; ; ;; ; (defun update-g (g k p n / ex) (if (setq ex (assoc k g)) (subst (append ex (list n)) ex g) (cons (list k p n) g) ) ) ;; ; ;; mk_3dp by Alan J Thompson ; ;; ; ;; Entmakes a 3D Polyline. Global Vars #Pathlay, #Pathcol and #Pathlwt have ; ;; to be set in calling program. ; ;; ; ;; Argument: lst, List of 3D points. ; ;; ; ;; Returns: Entity Name of Polyline ; ;; ; (defun mk_3dp (lst / vtx) (if (and lst (> (length lst) 1)) (progn (entmakex (list '(0 . "POLYLINE") '(10 0. 0. 0.) (cons 8 #Pathlay) (cons 62 #Pathcol) (cons 370 #Pathlwt) '(70 . 8) ) ) (foreach vtx lst (entmakex (list '(0 . "VERTEX") (cons 10 vtx) '(70 . 32) ) ) ) (entmakex '((0 . "SEQEND"))) ) ) ) (princ "\nCommand A* loaded.") (princ) ;|«Visual LISP© Format Options» (150 3 1 2 nil "end of " 100 9 0 0 1 nil T nil T) ;*** DO NOT add text below the comment! ***|; Astar3dHeap.LSP2 points
-
We talk a lot about speed but does it matter, if it take seconds or a minute, a task I worked on could take up to 3 hours manually it takes 2 minutes now. I improved the speed 3 times by recoding. Yes if have thousands of lines go get a coffee. still faster than having a go manually. I guess what I am saying are we talking seconds, minutes or hours ? 13 seconds for 5000, I would call that fantastic. If worried about time add a progress bar it's a Acet function. The task above started at like 25 minutes to do, so 2 minutes as final version is considered acceptable by me. Yes talking thousands of changes.2 points
-
2 points
-
I think code can be made easier, yes LT does support VL just not a full set but should support "getattributes" an easier way of getting attribute values or you may be able to use the getpropertyvalue method even easier. Have a look at Lee-mac ssget functions. you should use "E" to select block. https://www.lee-mac.com/ssget.html If the desired result is to plot ";; 6. Launch Plot Command" say a PDF with a known filename please say so, no need for a clipboard. There are plenty of plot lisps out there. You need to provide more details, is the title block true size or scaled, what device for output, PDF, A3, A1, plotter names and so on. Is it in model or a layout ? A couple of test code just try them. Property would be easiest, please let me know if it works in LT. (DEFUN C:test ( / ) (setq ent (car (entsel "\npick block "))) (setq dwgno (strcase (getpropertyvalue ent "DRAWING_NO.") T))) (princ) ) ; Wrapper the entsel in a while is it a BLOCK with attributes so if wrong pick do again. A enter check would be exit. ; in this test looks for one attribute but can redo as look for multiple atts and save value in varaibles. (defun c:test ( / ) (setq obj (vlax-ename->vla-object (car (entsel "\nPick block with attributes ")))) (setq atts (vlax-invoke obj 'Getattributes)) (vlax-for att atts (if (= (vlax-get att 'textstring) "DRAWING_NO.") (setq dwgno (strcase (getpropertyvalue ent "DRAWING_NO.") T))) ) ) (princ) )2 points
-
Resetting to default definitely works as a 'nuclear' option, but for anyone else finding this thread who doesn't want to lose their UI setup, definitely check PICKFIRST and PICKADD first. If those variables get flipped to 0 by a glitch or a rogue LISP routine, it causes exactly this behavior where the Properties palette won't 'see' your selection.1 point
-
I think a custom DCL front end would be good. Will have a think about it. The extend option is easy just set the default length to 0.0 so any other value means yes. Nikon the dynamic block is a nice idea.1 point
-
Like @Steven P "Generally I save to the same folder as the CAD file" In the attached file is a plot a range of pdf's a DCL pops up for the range then the plots are done. In the code you will see a command Mk-dir that is used to make a PDF directory. I think we have discussed previously about making menu's as the simplest way of click on a choice and it happens. See image above, keep adding options for users, they don't need to worry about appload or (load."????") I had 8 users, our menu was on a server so would auto update for end users. You will need to change the code to suit your title block and pdf settings have a go. It is set up for title block at 0,0. It is possible to have one lisp but it uses different variables for different output devices and title blocks. A version I have for a client looks at title block name and sets the correct plot size settings. Come back if have a problem, you have my Email ? plotA3Pdfrange.lsp Multi GETVALS.lsp1 point
-
You need to understand what is a OEM version it is used by software providers as a means to get an Autocad but with their software as the essential item. Refering to OEM document "Deliver products with scaled feature sets at scaled price points and provide an AutoCAD-based platform that cannot be customized or extended by end users." So any outside program lisp or .NET etc can not be ran by you. But you can add programs using the OEM key that is held by the software developer. You would have to go back to them to add. What program did you buy ?1 point
-
A small modification of the DZ code for convenience. The Break lines can be lengthen by the specified distance (Fixed) or proportionally (by 1/3) or None. [Fixed/Proportional/None] ;;; Lisp to draw Single or Double "Z" Break Lines ;;; © A.Henderson 2002 ;;; Modified By Charles Alan Butler 10/06/2004 ;;; To allow any angle and to trim lines that ;;; do not run through both break symbols ;;; Modified 12/02/26 ;;; The Break lines can be lengthen by the specified distance (Fixed) ;;; or proportionally (by 1/3) or None (defun c:dz-mod (/ oldlay oldotho oldosmode ztype dist ang extOpt extLen dist0 segLen e1 e2 p1 p2 p3 p4 p5 p6 p7 p8 p9 p10) ;; return vertex list by MP (defun cdrs (key lst / pair rtn) (while (setq pair (assoc key lst)) (setq rtn (cons (cdr pair) rtn) lst (cdr (member pair lst)) ) ) (reverse rtn) ) ; defun ;; set osnaps ON/OFF (defun setosnaps (value) ; value = "ON" or default to "OFF" (if value (setq value (strcase value)) ) (cond ((or (and (= value "ON") (>= (getvar "osmode") 16383)) (and (/= value "ON") (<= (getvar "osmode") 16383)) ) (setvar "osmode" (boole 6 (getvar "osmode") 16384)) ) ) ); defun ;; Start of routine ================================== ;; Save settings (setq oldlay (getvar "clayer") oldortho (getvar "orthomode") oldosmode (getvar "osmode") ) ;_ end of setq ;; I use current layer - CAB ;;(command "_.layer" "_make" "Z-Line" "_Colour" "41" "" "") (initget "S D") ;(setq ztype (getkword "\n Single or Double -^v-^v- ? (S or D) <S>")) (setq ztype (getkword "\n Single or Double -^v-^v- ? [S/D] <S>")) (setosnaps "ON") ; force on ;;=========================================== (if (and (setq p1 (getpoint "Starting point of break line : ")) (setq p6 (getpoint p1 "End point of break line : ")) ) (progn;=========================================== ;;; --- EXT --- calculate the base length/angle based on the selected points (setq dist0 (distance p1 p6)) ;;; --- EXT --- elongation mode (Fixed = 50 by default) (initget "F P N") (setq extOpt (getkword "\nExtend beyond picked points? [Fixed/Proportional/None] <Fixed>: ")) (cond ((or (not extOpt) (= extOpt "F")) (setq extLen (getdist "\nExtension length <50>: ")) (if (null extLen) (setq extLen 50.0)) ) ((= extOpt "P") ;; 1/3 of the straight section (straight section = 0.4167*dist for S, and 0.4167*(dist/2) for D) (setq segLen (* 0.4167 (if (= ztype "D") (/ dist0 2.0) dist0))) (setq extLen (/ segLen 3.0)) ) (T (setq extLen 0.0)) ) (setvar "plinewid" 0) (command "._undo" "_begin") (cond ((/= ztype "D") ; default to single (setq dist (distance p1 p6) ang (angle p1 p6) p2 (polar p1 ang (* 0.4167 dist)) p5 (polar p1 ang (* 0.5833 dist)) p3 (polar p2 (+ 1.25664 ang) (* 0.1667 dist)) p4 (polar p5 (+ 4.39824 ang) (* 0.1667 dist)) ) ;_ end of setq ;;; --- EXT --- we only lengthen the ends (the symbol remains at the base points) (setq p1 (polar p1 (+ ang pi) extLen) p6 (polar p6 ang extLen) ) (setosnaps "OFF") ; force off (command "_.pline" p1 p2 p3 p4 p5 p6 "") ; Draw the Z-Line ) ;_ end cond "S" ;;=========================================== ((= ztype "D") (setq p10 p6 dist (/ (distance p1 p6) 2.0) ang (angle p1 p6) p2 (polar p1 ang (* 0.4167 dist)) p5 (polar p1 ang (* 0.5833 dist)) p3 (polar p2 (+ 1.25664 ang) (* 0.1667 dist)) p4 (polar p5 (+ 4.39824 ang) (* 0.1667 dist)) p6 (polar p5 ang (* 0.8334 dist)) p9 (polar p6 ang (* 0.1661 dist)) p7 (polar p6 (+ 1.25664 ang) (* 0.1667 dist)) p8 (polar p9 (+ 4.39824 ang) (* 0.1667 dist)) ) ;_ end of setq ;;; --- EXT --- we extend the start and the very end (p10), we do not touch the inside (setq p1 (polar p1 (+ ang pi) extLen) p10 (polar p10 ang extLen) ) (setosnaps "OFF") ; force off (command "_.pline" p1 p2 p3 p4 p5 p6 p7 p8 p9 p10 "") ; Draw the Z-Line ) ;_ end cond ) ; end cond stmt ;; Position the second break line (setq e1 (entlast)) (command "_.pedit" e1 "_L" "_ON" "") (command "_.copy" e1 "" (getvar "lastpoint") pause) (setq e2 (entlast)) (setq plast (getvar "lastpoint")) ;; trim function (initget "Y N") (setq ans (getkword " Do you wish to trim the lines now ? [Y/N] <Y>")) (if (or (= ans "Y") (not ans)) (progn (setq lst '() dist (/ dist 140.0) ; trim distance ) ;; create trim lines (command "._offset" dist e1 plast "") (setq evl1 (cdrs 10 (entget (entlast)))) ; ent vertex list (entdel (entlast)) (command "._offset" dist e2 p1 "") (setq evl2 (cdrs 10 (entget (entlast)))) (entdel (entlast)) (setq lst (append evl1 (reverse evl2))) (setosnaps "OFF") ; force off (command "_.trim" e1 e2 "" "_F") (apply 'command lst) (command "" "") (command "_.trim" e1 e2 "" "_F") (apply 'command lst) (command "" "") ) ; progn ) ;_ endif (command "._undo" "_end") ) ; progn ) ; endif ;;================ ;; Exit sequence ;;================\ ;; Restore settings ;; I use current layer - CAB ;;(command "_.layer" "set" oldlay "") (setvar "orthomode" oldortho) (setvar "osmode" oldosmode) (princ) ) ;_ end of defun (prompt "\nDouble Break Symbol Creator loaded. Type DZ to run it." ) (princ) (setfunhelp "c:dz" "acadtools.chm" "dz")1 point
-
Hi @BIGAL I have tried the getpropertyvalue and it works in LT! Which is good news as that means the lisp can be reduced. @Saxlle that could be a solution, but the whole point is to automate it as much as possible. I had a think about it before and the most effective way for out team is to just type print me and then the drawing name gets generated and saved on the clipboard and then when they setup the plot settings they can paste the name in the dialogbox. So pausing to copy the name, will add extra steps which I am trying to reduce. @Steven P that would be the final step making sure that it is completely automated. But fearing some might not be comfortable with it yet, I just want to slowly introduce these little automations. With your suggestion, how does it work in terms of where to save the pdf file?1 point
-
@bigal, Reminds me of the days of HP9830, used to work on preliminay studies in the James Bay area. I would start calculating a long polygon in geodetic coordinates then go in the tent where we had a pool table and shoot two racks. Go back to the office tent still had to wait some. The hp9830 had but 8k core memory and a cassette tape. So the need for speed depends on the situation. For the basic A* it's all about it and the hack proposed by @GLAVCVS is totally worth it. The polygon making not so much, but I tend to be biased in favor of vanilla autolisp.1 point
-
Like @Steven P my Autoload.lsp has around 35 defuns in it plus some setvar's and uses the Appload add to Startup suite, Acad or Bricscad works.1 point
-
Generally if I am plotting it is much quicker to get a LISP to do all the 'hard' work going through the dialogue box - more so with PDFs where it wants you to select folders to plot to. If these are all standard 90% of the time like BigAl says, go straight to plot. Might be that the most efficient way would be 4 functions to plot to PDF: 'PlotPdf' 'PlotPdfTr' - Transparency 'PlotPdfLW' - Lineweight 'PlotPdfTrLw' - Transparency and lineweight, (or 5th one PlotPDFLwTr to cover it going the options entered in reverse) All call the same basic function passing the required data for example: (defun c:plotpdf ( / )(plotPDF (list 0 0))) ;; List: TR, LW (defun c:plotpdfTr ( / )(plotPDF (list 1 0))) ;; List: TR, LW (defun c:plotpdfLw ( / )(plotPDF (list 0 1))) ;; List: TR, LW (defun c:plotpdfTrLW ( / )(plotPDF (list 1 1))) ;; List: TR, LW (defun c:plotpdfLWTr ( / )(plotPDF (list 1 1))) ;; List: TR, LW (defun PlotPDF ( MyControls / .....) .... ... (if (= (nth 0 MyControls) 1) (setq DoTransparency "Yes")) ... (if (= (nth 1 MyControls) 1) (setq DoLineWeight "Yes")) .... ) I use a similar thing: PlotA0, PlotA1.... for different papersizes, plotpdfmsc (plot PDF Mono Save Close) as examples, easy to remember (can do the 'code' part of the functions backwards too, eg, PLotPDFCS - Close Shave) I tend to pass the controls as a list so that if you want to add more functions later you only need to change the main function and anything new afterwards, for example c:plotpdfPr where Pr might be 'show preview' and that list might be (plotPDF (list 0 0 1)) noting that shorter lists will just return a 'nil' in the if statements / conds so have no effect1 point
-
Why not just use princ to write the text in command line, then select it, ctrl+c and ctrl+v? For e.g. (setq a "213" b "abs" c "ddd") (princ (strcat a " " b " " c)) (princ) ------------------------------- result: 213 abs ddd (select then in command line and paste it)1 point
-
"OEM environment." If you are using a OEM version then a possible way to run other lisp programs is to go back to the developer who could add your lisps to their package then they should work.1 point
-
I've finished with "lw_orth.lsp"... Take it, or leave it... It's up to you OP... I've found some lacks in latest updates - in 3d with ucs aligned in 3d with lwpolylines (grread-mult) versions produced unwanted behaviour... Hopefully now fixed... Also, added (vl-cmdf "_.undo" "_m") as first line at each command function, so upon finished execution, you can just use UNDO (Back) to return before running command... There was 5 downloads till I reattached fixed version... Sorry for inconvenience - it happens from time to time... Regards, M.R. orthogonalize_lwpolyline-ucs3D.dwg lw_orth.lsp1 point
-
It will probably be next week before I can check out QGIS solutions. From the user's perspective, even if off in a few spots, several of these LISP solutions here are faster (maybe more accurate), even including time to adjust manually than most of the other solutions for GIS, though I am no speed demon in GIS. Just look at all of the prep work on the Whitebox Tools, though if I had all of those branches and islands as well as a few oxbows, thin connections, etc. like the example, that would be the way to go as far as I can tell, I do believe it also works on vector, IIRC. It looks like part of that is free as a Python toolset, I'll try to read up some more on that. As I mentioned long ago in this thread, my daughter's co-workers are using AutoCAD to create the centerlines and manually adjusting if needed even though they have ArcGIS, though they may not have the extra tools that have the easy centerline tools. From what I looked up, ArcGIS made some tools a higher priced tier. Maybe asking a few questions on some GIS forums might yield more information.1 point
-
Hi marco . You can add the previous created object by the use of function ssadd to add to the current selection set . Example . (setq ss (ssadd)) (command "_.line" '(0. 0. 0.) '(1. 0. 0.) "") (ssadd (entlast) ss) And so on .... Hope this what you mean Tharwat1 point
