Jump to content

Leaderboard

  1. BIGAL

    BIGAL

    Trusted Member


    • Points

      27

    • Posts

      20,131


  2. mhupp

    mhupp

    Trusted Member


    • Points

      23

    • Posts

      2,257


  3. Steven P

    Steven P

    Trusted Member


    • Points

      14

    • Posts

      3,011


  4. pkenewell

    pkenewell

    Community Member


    • Points

      13

    • Posts

      798


Popular Content

Showing content with the highest reputation since 06/01/2026 in all areas

  1. I've now updated this program to support resetting components of the incrementing string back to a given value with a given frequency - the latest version can be downloaded from my site: https://lee-mac.com/numinc.html
    7 points
  2. @masao_8 Here is a solution for a simple single selection add and SHIFT-Select to remove. Perhaps this will give you a basis for starting: ;; Function to do a simple Select/Deselect using grread. ;; By PJK - 6/16/2026 (defun pjk-grread-Select (/ done en grl grc grv ss) (if acet-load-expresstools (acet-load-expresstools)) (setq ss (ssadd)) (princ "\nSelect to add objects or SHIFT+Select to remove from selection set: ") (while (not done) (setq grl (grread T 15 2) grc (car grl) grv (cadr grl) ) (cond ((= grc 3) (if (setq en (car (nentselp grv))) (if (acet-sys-shift-down) (progn (if (ssmemb en ss)(ssdel en ss)) (redraw en 4) ) (progn (ssadd en ss) (redraw en 3) ) ) ) ) ((= grc 2) (setq done (if (vl-position grv '(13 32)) T nil)) ) ((= grc 25)(setq done T)) ) ) (if (> (sslength ss) 0) (progn (foreach i (mapcar 'cadr (ssnamex ss))(redraw i 4)) ss ) nil ) )
    4 points
  3. Just to add something more from me, as I did try to understand this problem as much as I could back then when I was working on my solution. Boundary command probably uses Pixel-Based Areas (Boundary Fill) method, that's why you have to see whole area on your screen. You can google what that is and how it works, but it makes sense to me considering there is a precision problem depending on "zoom" level. As for Hatch, it works the same for "pick points" method (boundary command + add hatch for that polyline), but if you choose "select objects" then it works as completely different method (just math without graphics part) and that's why its more accurate in this example. It all depends what you have as starting variables and what you need in the end. If you can, and its not a problem to select all lines, then CBoundray function from post above will work okay. This works like the Hatch by selecting objects... Of course clicking just one point inside area is simpler and faster, but can give wrong result because of its limitation. And I don't think its an issue with Autocad, its just a method that has its limitation. And it actually works really good otherwise, if you think about it, considering how much zoomed out you have to be and have a short segment to get the error. For example I work with topology, and have area centroids, and I needed to work some analysis with polylines for certain areas. In 99% cases boundary command was good, but with large areas with small boundary segments (like in OP example) I had this problem and needed to avoid it.
    4 points
  4. What are you trying to accomplish with this code? First and foremost vla-CopyObjects doesn't support Layouts in the manner you are attempting, AFAIK. You need to use -LAYOUT command or pretty much need to use LeeMac's Steal or at least determine the method he uses for Layouts, which if I am looking at it correctly uses the Block Table record maybe more as I quickly glanced at it.
    3 points
  5. I think there’s other reasons too! CAD, VisualLISP, have been around for more than a quarter century, AutoLISP, like 40 years, either people have moved on to other software packages, or use an already existing solution People at stack overflow started to complain about it being toxic, people downvote legitimate questions where the question was a bit hard to understand, i.e. where the OP’s first language isn’t English. I use the heck out of AI though; I even run local models. The issue is, people expect LLMs to “one shot” solutions, it’s unlikely to happen. If you spend time and find a system to work with the models, they are amazing.
    3 points
  6. ;;;You can call Master Leemac's code, but do not modify it (defun c:ttt(/ CPB NEW-PT OBJ PT) (c:cb) (setq cpb (entlast)) (setq pt (cdr(assoc 10 (entget cpb)))) (setq obj (vlax-ename->vla-object cpb)) (setq new-pt (vlax-3d-point (getpoint pt "\n Specify the new location"))) (vla-move obj (vlax-3d-point pt) new-pt) (princ) )
    3 points
  7. This has been talked before if I understood the problem correctly: https://www.cadtutor.net/forum/topic/61468-boundary-precision/ To create a boundary you have to have the whole area visible in your model, everything needs to be visible in display area So it has to do something with your "viewing resolution" (zoom), that's how command works. What is the limit I don't know, I never did tests like they did in topic mentioned above. But I also had the same problems with large areas like you posted, when I have one short line, or polyline segment, one of the boundary vertices would be wrong (bad precision). The solution for me was to create lisp working with regions, then convert region to polyline. When creating regions you don't need to see the whole area on your screen, you select the lines and its just pure math from there
    3 points
  8. @darshjalal Thanks for your program contribution. I don't want to take away for your obvious hard work, but I somewhat agree with @BIGAL. I have read the extensive comments that are very detailed and technical, but there is no summary of what it is used for, or how it is useful. For the casual LISP user, they would not understand the value in such a program. I think a simple paragraph would be help instead of blindly evaluating it. Your title does explain the purpose of the program, but it's too vague and some plain language on how the features are helpful would be nice - just a friendly critique
    3 points
  9. @masao_8 The Express tools must be installed with AutoCAD. If you mean just loading it, it's in my code above: (if acet-load-expresstools (acet-load-expresstools)) To make a grread loop work exactly like ssget. it's a huge ask. There is a ton of options to emulate. Could you explain EXACTLY what you want the function to do? What you're asking for has seemed to shift, or you weren't explaining it well enough. Below is an update to my code to add just the auto window and crossing selection: ;; Function to do a simple Select/Deselect using grread. ;; By PJK - 6/16/2026 ;; Updated 6/29/2026 to add window selection emulation (defun pjk-grread-Select (/ done en grl grc grv ss ss->elst sx wp1 wp2) (defun ss->elst (ss / i r) (if ss (repeat (setq i (sslength ss))(setq r (cons (ssname ss (setq i (1- i))) r))) ) ) (if acet-load-expresstools (acet-load-expresstools)) (setq ss (ssadd)) (princ "\nSelect to add objects or SHIFT+Select to remove from selection set: ") (while (not done) (setq grl (grread T 15 (if wp1 0 2)) grc (car grl) grv (cadr grl) ) (cond ((= grc 5) (redraw) (if wp1 (progn (grdraw wp1 (list (car grv) (cadr wp1) (caddr wp1)) -1 (if (< (car grv) (car wp1)) 1 0)) (grdraw wp1 (list (car wp1) (cadr grv) (caddr wp1)) -1 (if (< (car grv) (car wp1)) 1 0)) ) ) ) ((= grc 3) (if (acet-sys-shift-down) (if (setq en (car (nentselp grv))) (progn (if (ssmemb en ss)(ssdel en ss)) (redraw en 4) ) (if (not wp1) (progn (setq wp1 grv) (princ "\rSelect opp corner: ") ) (progn (redraw) (setq wp2 grv) (if (< (car wp2) (car wp1)) (mapcar '(lambda (a)(ssdel a ss)(redraw a 4)) (setq sx (ss->elst (ssget "C" wp1 wp2))) ) (mapcar '(lambda (a)(ssdel a ss)(redraw a 4)) (setq sx (ss->elst (ssget "W" wp1 wp2))) ) ) (princ (strcat "\n(" (itoa (length sx) ) ") Objects found and Removed from selection. " ) ) (setq wp1 nil wp2 nil) ) ) ) (if (setq en (car (nentselp grv))) (progn (ssadd en ss) (redraw en 3) ) (if (not wp1) (progn (setq wp1 grv) (princ "\rSelect opp corner: ") ) (progn (redraw) (setq wp2 grv) (if (< (car wp2) (car wp1)) (mapcar '(lambda (a)(ssadd a ss)(redraw a 3)) (setq sx (ss->elst (ssget "C" wp1 wp2))) ) (mapcar '(lambda (a)(ssadd a ss)(redraw a 3)) (setq sx (ss->elst (ssget "W" wp1 wp2))) ) ) (princ (strcat "\n(" (itoa (length sx)) ") Objects found and added to selection. " ) ) (setq wp1 nil wp2 nil) ) ) ) ) ) ((= grc 2) (setq done (if (vl-position kcode '(13 32)) T nil)) ) ((= grc 25)(setq done T)) ) ) (if (> (sslength ss) 0) (progn (foreach i (mapcar 'cadr (ssnamex ss))(redraw i 4)) ss ) nil ) )
    2 points
  10. Perhaps it's easier than it seems. If it is an integrated receiver and Windows is able to obtain location data from it, then you should be able to access that data through the 'Windows Location API'. In that case, it should be possible to write a script to be executed from PowerShell that creates a loop to poll the receiver and write the data to a file. That loop would run in parallel with AutoCAD, allowing Lisp to read the new data as it is written. This method would be "intrusive", since it would occupy AutoCAD's command stream for as long as the command is running. However, there is another, less intrusive option that could operate in the "background": write the data to a system variable ('USERS#') and create a reactor that responds to changes in that variable: 'vlr-sysvar-reactor'. If the script is executed in a background PowerShell instance, you would also need to write a Lisp command capable of closing that instance when necessary. Once the script has been debugged, it could be incorporated into the Lisp code itself, making the whole solution completely self-contained. I haven't had much free time lately, but I'll try to investigate all of this a bit further.
    2 points
  11. I have noticed the drop in posts in forums like Lisp, here, Autodesk and Theswamp, I think it's because people are using AI more to write code. Even I try AI now and again when stuck, it is successful some times. The most obvious here is when the AI code does not work help is asked for here. Maybe Admin could comment about number of posts say compared to 1 or 2 years ago ? Or is it that a lot of new users just don't ask for help ? I know I push for process improvement and have often tried to influence people into saving time but the majority just don't care. Any body else want to comment ?
    2 points
  12. I worry that information will become like entertainment. We used to have a few TV channels, they were free, and we trusted their information. Then came cable, which grew into a mess of garbage that came through one provider, so you paid for things you mostly didn't want. Then came streaming, which is turning into a handful of providers with even more garbage, and you pay for each provider. AI may turn out like that: a few providers, with answers of questionable quality, at prices we can't afford. What would make sense to me is to create repositories of knowledge, curated by an AI. As it is, you have to ask similar questions, and the AI starts from scratch every time. Wouldn't it make more sense to treat the AI like someone with institutional knowledge? If you had a repository for AutoLISP code, for instance, all of us could contribute to it and maintain it. You might have to pay for your answer, but you would know it was correct and useful.
    2 points
  13. Like @Steven P How do you look at the data now ? Is it just displayed when you run a program ? If so what is the program ? Some one must have written it.
    2 points
  14. I think you would need Python, .NET, or ObjectARX as Autolisp does not have an on idle event that I can see. According to AI, you can read the input stream in a background thread, then use AutoCAD’s on idle event to update geometry in AutoCAD. I asked AI about using PyRx and it spit out a bunch of code converting $GPGGA $GNGGA to Lat/Log and stuff, I attached it. scratch.txt
    2 points
  15. Like @mhupp may need to run an external program that writes current location to a file, then you can read that file and update say text. Depending on the program may run a BAT file or run the program or use powershell to run. I think can look at a file date has changed via reactor but manual much easier. I did a Google and did start to find hints of save to a txt or csv file but that is as far as I went. It is something you need to do, yje googling. Talk to who you bought the device from they may have something.
    2 points
  16. Would need a Reactor and connect to some type of database.
    2 points
  17. Not sure, can the GNSS write / overwrite or updated a text file continuously? Reading a text file is easy with CAD, copy that to a block and the rest is all possible - not sure the interface yet. BigAl might know something later today.
    2 points
  18. I think the issue is more generational than anything else. In the forums I keep up with, including here, theswamp.org, and MikeHolt.com, I've noticed that most of the core group have been Boomers. As a whole, younger generations have seemed to visit to get help, but not stay to help others. [There are notable exceptions like Lee.] AI is being oversold. I've tried both Claude and ChatGPT for programming help with LISP. Neither has produced code that worked on the first pass for anything more than a trivial case. We're about even on times when I've had to point out syntax errors in AI code and times AI has found syntax errors in my code. AI is a great replacement for most search engines, but it is not all that great at writing code, at least on the free tiers. AI output is only as good as the instructions it is given. Writing good instructions is hard. AI and the dot com bubble have a lot in common. In five years I expect we will have fewer AI companies, mostly paid tiers, and lots of empty data centers.
    2 points
  19. I have mixed feelings about Clippy the AI , at least the one from Google , sure its fast and it can give some relevant answers but you have to double check everything. I am trying to create a dcl editor. Wasn't sure where to start so asked Clippy and it gave me some good ideas on where to begin. But as things got complexer it really started to mess things up. And every time you use it you need to explain every thing all over again because at least the free / unregistered version remembers (saves) nothing . But I learned from my mistakes and started to write a very extensive manual so next time I can upload that so we can better pick up from where we started. My biggest concern is that it creates a black box. You ask something , it gives you something back and you paste and test the code , great , moving on to next part. After a while you end up with a bunch of working code until it doesn't any more and that's where the trouble begins and you notice you have lost your grip on the code because Clippy did it all for you. Like your daddy did all your homework for you and you have to take the exam and ...oops , daddy aint around now is he?
    2 points
  20. There is no doubt that AI is replacing (and will do so even more in the future) the need to interact with something or someone in order to find ideas and the motivation to pursue them. I don’t know which AI tools are the best for programming (I’ve only used Chatgpt so far), but my experience has been positive in terms of how stimulating it is to have someone to discuss ideas with and refine them while solving problems. This was something that, in the past, could only be found in forums like this one. However, the code suggested by Chatgpt is almost always lengthy and often fails. I suppose that will change over time.
    2 points
  21. I also think that its AI, especially for new users. I mean AI is good at coding or spotting errors and asking an AI often gets you an answer way faster than starting a forum post. For example here is a chart of stack overflows posts
    2 points
  22. Perhaps you could use the undocumented (acet-sys-shift-down) express tools function within the grread loop? Then you would have to manipulate highlighting with (redraw [3/4]) and use (ssadd) and (ssdel) to update the selection set.
    2 points
  23. Isn't that how CAD works already? you select something either by mouse clicke or window it will be highlighted hold shift to deselect it the same way. I know if you have to many things selected they are no longer highlighted.
    2 points
  24. I think you would need to test for 'shift' being pressed and the test for a left mouse entity selection. Do a 'princ' on your grread loop to display what you are doing, shift and select something - which should give you what you want to test for.
    2 points
  25. I would maybe start again, if you look at this https://www.lee-mac.com/polyinfo.html it will find arcs etc in plines So if you want to label Lines, Arcs, Circles and Plines, you may need different code that looks at each entiity and correctly labels. I had a quick google and found a few programs I know that Kent Cooper has something similar to Lee's, but labels each segment. Search also "forums/autodesk".
    2 points
  26. @mhupp I use Bricscad V25 and it did not work ? Old name stayed there did I miss a step. I tried old fashioned method, it may not be the best solution, if block has attributes then could add a extra sub function to copy the existing values to the new inserted block. Also wants a "Does block exist check". ; https://www.cadtutor.net/forum/topic/99155-insert-a-copy-of-the-block-at-the-specified-point-copyrenameblockv1-5lsp-lee-mac/ ; rename a existing block to a new name ; By AlanH June 2026 (defun c:AHRenblk ( / attreqold bname ent entg inspt oldangdir oldangunits rot scx scy) (setq attreqold (getvar 'attreq)) (setq attreq 0) (setq oldangunits (getvar 'aunits)) (setvar 'aunits 3) (setq oldangdir (getvar 'angdir)) (setvar 'angdir 0) (setq ent (car (entsel "\nPick block to rename "))) (setq entg (entget ent)) (setq bname (cdr (assoc 2 entg))) (setq inspt (cdr (assoc 10 entg))) (setq scx (cdr (assoc 41 entg))) (setq scy (cdr (assoc 42 entg))) (setq rot (cdr (assoc 50 entg))) (setq newname (getstring T "\nenter new block name ")) (command "Bedit" bname "Bsaveas" newname "N" "Bclose" "S") (command "erase" ent "") (command "-insert" newname inspt scx scy rot) (setvar 'aunits oldangunits) (setvar 'angdir oldangdir) (princ) ) (c:AHRenblk) Yes will see flash on screen as Bedit is called.
    2 points
  27. A few i had laying around ;;----------------------------------------------------------------------------;; ;; ZOOM TO OBJECT AND OUT 5% (defun C:ZZ (/ SS) (if (setq SS (ssget)) (progn (vl-cmdf "_.Zoom" "OB" SS "") (vl-cmdf "_.Zoom" "0.95x") ) ) ) ;;----------------------------------------------------------------------------;; ;; ZOOM TO OBJECT THEN OUT 25% (defun C:ZX (/ SS) (if (setq SS (ssget)) (progn (vl-cmdf "_.Zoom" "OB" SS "") (vl-cmdf "_.Zoom" "0.75x") ) ) )
    2 points
  28. Yes, I tend to zoom object then zoom out another 10%, catches most things
    2 points
  29. If it can be fixed with zooms then you can record the current zoom, zoom object, make the boundary and zoom back 'current' zoom - I think that method is online somewhere to copy / paste else can find it on Monday if needed.
    2 points
  30. Idk about that this is a super simple lisp that will allow you to select multiple entites. But if they aren't within the fuzz distance of each other they wont connect. ;;----------------------------------------------------------------------------;; ;; Copy Boundary Entities to join as a single polyline fuzz is 0.1 units ;; https://www.cadtutor.net/forum/topic/99146-boundary-command/ mhupp:06/04/26 (defun C:CBoundray (/ ss ss1 obj) (setq ss1 (ssadd)) (while (setq ss (ssget '((-4 . "<OR") (0 . "LINE") (0 . "ARC") (0 . "LWPOLYLINE") (-4 . "OR>")))) (foreach obj (mapcar 'vlax-ename->vla-object (vl-remove-if 'listp (mapcar 'cadr (ssnamex ss)))) (vla-copy obj) ) (command "_.PEDIT" "_M" ss "" "_J" "0.1" "W" "0" "") ) (princ) )
    2 points
  31. It's supposed to use the HPGAPTOL as far as I know. This has been an issue for sometime, now that I looked back into from a few years ago, this problem also occurs with Hatch command. I just tried Boundary and Hatch on a closed polyline object at Zoom Extents and got ... And despite the first instruction, Zooming In resolved the issue. I normally resolve this with Hatch by using Select Object, maybe Hatch, Select Object, delete the Hatch and keep the Boundary could work for the OP. @lastknownuser's post brought it back to my memory. There is a thread around from a while back on this issue and needing to use Select Object option for Hatch.
    2 points
  32. Was reading up on this too. apparently AutoCAD boundary command doesn't have a tolerance setting but BricsCAD does. That is why people opt to use hatching and then you can create the boundary from the hatch. and then delete the hatch. I'm confused since their isn't a gap/vertex at that location.
    2 points
  33. There was a post a couple of years ago now, if it is a closed shape without crossing lines, hatching the area then recreate the boundary and delete the hatch leaves the boundary... as a last resort since it is long winded way to go. I haven't had time this week to look at this properly - you're in safe hands with the other posters though... (The post I am thinking about was using LISP to do something, click in the area to get boundary, might have been to measure area, perimeter or something but that was the idea behind it, LISP is ok if it is a bit long winded, fractions of a second longer process)
    2 points
  34. @Danielm103, I'm on rev. 8.9.3 so does not apply to me. Thanks for the warning nonetheless. ymg
    2 points
  35. if Nothing else it would show up in peoples searches. just posting a file even tho it has great documentation will not show up in searches. if you take all the time to write things up and share here make it so people can find your lisp files. or just copy all the ;; lines. someone in 6 months to a year will post looking for a divide lisp with points and I won't be able to find this post. -Edit like you did here
    2 points
  36. If your offering something a good idea is to provide images or a movie about what the program does, else the "Why bother" will occur. Just attaching a lisp is not really describing why you should download the program. Think of it as if I was selling the program how would I get people interested.
    2 points
  37. @rlx Your Kung-Fu is Strong! Nice work!
    2 points
  38. Incremental Numbering Suite Version 4.0 Released. The main feature of the new version is the introduction of a dedicated 'Content Builder' to facilitate the construction of an incrementing string from an arbitrary number of incrementing and/or static components. With this feature, the user now has the ability to independently control the increment amount and increment frequency for each component of the string, enabling multiple sections of the string to increment by different amounts and at different rates to one another. The new version also introduces the ability to load & save application configurations, streamlining the operation of the program for multiple numbering systems.
    2 points
  39. Having a bit of spare time, I thought I would make a hatch pattern similar to the OS marsh block marsh1.pat
    2 points
  40. DIVCURVES-INSERTING POINTS AS SPECIFIC DISTANCE.LSP I am so sorry for not giving more details about the code. Please read the following for more details: ;;; =========================================================================== ;;; Routine Name: DIVCURVES ;;; Logic & Concept: Mostafa Jalal ;;; Developer: Gemini + Grok ;;; Date: June 2026 ;;; =========================================================================== ;;; ;;; DIVCURVES_V10.lsp - Enhancements: ;;; 1. Dedicated Feature Line Support (Option 6) with segment-by-segment processing. ;;; 2. Interactive Short Segment Logic [Middle/Vertices/Skip/All] for lines and curves. ;;; 3. Specialized Circle Division by Pieces for short circles. ;;; 4. Persistence of user choices for short segment handling. ;;; 5. Added [Skip] option for Curve/Line distance prompts to isolate processing. ;;; 6. Added [All] option to bypass repetitive prompting on multiple short segments. ;;; 7. FIX V10: Curve vs straight detection on AECC_FEATURE_LINE segments uses ;;; a midpoint-sag test (chord-mid vs curve-mid) because the ActiveX curve ;;; interface on Feature Lines reports chord length, making the old ;;; arc-vs-chord length test always evaluate to "straight". ;;; Curved feature-line segmentLen is also replaced with a 2-chord ;;; approximation so division by distance follows the real arc. ;;; =========================================================================== (vl-load-com) ;; Global variables for persistence of short segment choices (if (not *div_short_arc_choice*) (setq *div_short_arc_choice* "Middle")) (if (not *div_short_line_choice*) (setq *div_short_line_choice* "Vertices")) (if (not *div_short_circ_choice*) (setq *div_short_circ_choice* "Middle")) (if (not *div_short_circ_pieces*) (setq *div_short_circ_pieces* 4)) (defun c:DIVCURVES (/ ss dist i ent obj endParam pIdx segmentLen k divDist entType totalLen tempDist mainChoice filter mainMode circleMode numSlices isArc opt lastMain lastCircMode lastNumSlices lastDist lastDistLine temp oldDynPrompt p-list distLine startPt endPt chordLen curveLen isCurveSegment shortSegChoice shortCircPieces bulk_arc bulk_line bulk_circ midPt chordMid sagTol) ;; --- Environment Setup --- (setq oldDynPrompt (getvar "DYNPROMPT")) (setvar "DYNPROMPT" 0) (setq p-list nil) ;; Reset bulk choices per run (setq bulk_arc nil bulk_line nil bulk_circ nil) ;; --- Memory Retrieval --- (setq lastMain (getenv "DIV_MainChoice")) (if (or (null lastMain) (= lastMain "")) (setq lastMain "7")) (setq lastCircMode (getenv "DIV_CircMode")) (if (or (null lastCircMode) (= lastCircMode "")) (setq lastCircMode "Distance")) (setq lastNumSlices (getenv "DIV_NumSlices")) (if (or (null lastNumSlices) (= lastNumSlices "")) (setq lastNumSlices "4")) (setq lastDist (getenv "DIV_Dist")) (if (or (null lastDist) (= lastDist "")) (setq lastDist "0.50")) (setq lastDistLine (getenv "DIV_DistLine")) (if (or (null lastDistLine) (= lastDistLine "")) (setq lastDistLine "1.00")) ;; Retrieve short segment choices (setq *div_short_arc_choice* (getenv "DIV_ShortArcChoice")) (if (or (null *div_short_arc_choice*) (= *div_short_arc_choice* "")) (setq *div_short_arc_choice* "Middle")) (setq *div_short_line_choice* (getenv "DIV_ShortLineChoice")) (if (or (null *div_short_line_choice*) (= *div_short_line_choice* "")) (setq *div_short_line_choice* "Vertices")) (setq *div_short_circ_choice* (getenv "DIV_ShortCircChoice")) (if (or (null *div_short_circ_choice*) (= *div_short_circ_choice* "")) (setq *div_short_circ_choice* "Middle")) (setq *div_short_circ_pieces* (getenv "DIV_ShortCircPieces")) (if (or (null *div_short_circ_pieces*) (= *div_short_circ_pieces* "")) (setq *div_short_circ_pieces* 4) (setq *div_short_circ_pieces* (atoi *div_short_circ_pieces*))) ;; --- 1. MAIN MENU --- (initget "1 2 3 4 5 6 7 1-Polylines 2-Lines 3-Arcs 4-Circles 5-Splines 6-FeatureLines 7-All") (setq opt (getkword (strcat "\nSelect: [1-Polylines/2-Lines/3-Arcs/4-Circles/5-Splines/6-FeatureLines/7-All] <" lastMain ">: "))) (if (not opt) (setq opt lastMain)) (cond ((wcmatch (strcase opt) "*6*,*FEAT*") (setq opt "6")) ((wcmatch (strcase opt) "*1*,*POLY*") (setq opt "1")) ((wcmatch (strcase opt) "*2*,*LINE*") (setq opt "2")) ((wcmatch (strcase opt) "*3*,*ARC*") (setq opt "3")) ((wcmatch (strcase opt) "*4*,*CIRC*") (setq opt "4")) ((wcmatch (strcase opt) "*5*,*SPLI*") (setq opt "5")) ((wcmatch (strcase opt) "*7*,*ALL*") (setq opt "7")) ) (setenv "DIV_MainChoice" opt) (setq mainChoice opt) ;; --- 2. SUB-PROMPTS --- (if (or (= mainChoice "4") (= mainChoice "7")) (progn (initget "Distance Pieces") (setq temp (getkword (strcat "\nCircle Mode [Distance/Pieces] <" lastCircMode ">: "))) (if (not temp) (setq circleMode lastCircMode) (progn (setq circleMode temp) (setenv "DIV_CircMode" temp))) (if (= circleMode "Pieces") (progn (setq temp (getint (strcat "\nEnter number of slices <" lastNumSlices ">: "))) (if (not temp) (setq numSlices (atoi lastNumSlices)) (progn (setq numSlices temp) (setenv "DIV_NumSlices" (itoa temp)))))))) ;; --- 3. INPUT ROUTINES --- ;; Curve Distance (if (member mainChoice '("1" "3" "4" "5" "6" "7")) (progn (setq temp (getstring t (strcat "\nCurve distance [Middle/Skip] <" lastDist ">: "))) (if (= temp "") (setq temp lastDist)) (cond ((wcmatch (strcase temp) "M*") (setq dist "Middle")) ((wcmatch (strcase temp) "S*") (setq dist "Skip")) (t (setq dist (distof temp)))) (if (not dist) (setq dist lastDist)) (setenv "DIV_Dist" (if (numberp dist) (rtos dist 2 4) dist)))) ;; Line Distance (if (member mainChoice '("1" "2" "5" "6" "7")) (progn (setq temp (getstring t (strcat "\nLine distance [Middle/Vertices/Skip] <" lastDistLine ">: "))) (if (= temp "") (setq temp lastDistLine)) (cond ((wcmatch (strcase temp) "M*") (setq distLine "Middle")) ((wcmatch (strcase temp) "V*") (setq distLine "Vertices")) ((wcmatch (strcase temp) "S*") (setq distLine "Skip")) (t (setq distLine (distof temp)))) (if (not distLine) (setq distLine lastDistLine)) (setenv "DIV_DistLine" (if (numberp distLine) (rtos distLine 2 4) distLine)))) ;; --- 4. FILTER --- (cond ((= opt "1") (setq filter '((0 . "*POLYLINE")) mainMode "Polylines")) ((= opt "2") (setq filter '((0 . "LINE")) mainMode "Lines")) ((= opt "3") (setq filter '((0 . "ARC")) mainMode "Arcs")) ((= opt "4") (setq filter '((0 . "CIRCLE")) mainMode "Circles")) ((= opt "5") (setq filter '((0 . "SPLINE")) mainMode "Splines")) ((= opt "6") (setq filter '((0 . "AECC_FEATURE_LINE")) mainMode "FeatureLines")) (t (setq filter '((0 . "LINE,*POLYLINE,ARC,CIRCLE,SPLINE,AECC_FEATURE_LINE")) mainMode "All")) ) (princ (strcat "\nSelect " mainMode " objects: ")) (setq ss (ssget filter)) ;; --- 5. PROCESSING --- (if ss (progn (setq i 0) (repeat (sslength ss) (setq ent (ssname ss i) entType (cdr (assoc 0 (entget ent))) obj (if (= entType "AECC_FEATURE_LINE") ent (vlax-ename->vla-object ent)) endParam (vlax-curve-getEndParam obj) totalLen (vlax-curve-getDistAtParam obj endParam) p-list nil) (cond ;; Handle Polylines and Feature Lines ((or (wcmatch entType "*POLYLINE*") (= entType "AECC_FEATURE_LINE")) (setq pIdx 0) (while (< pIdx endParam) (setq startPt (vlax-curve-getPointAtParam obj pIdx)) (setq endPt (vlax-curve-getPointAtParam obj (1+ pIdx))) (setq segmentLen (- (vlax-curve-getDistAtParam obj (1+ pIdx)) (vlax-curve-getDistAtParam obj pIdx))) (setq chordLen (distance startPt endPt)) ;; --- V10 FIX: midpoint-sag test (works for polylines AND feature lines) --- (setq midPt (vlax-curve-getPointAtParam obj (+ pIdx 0.5))) (setq chordMid (mapcar '(lambda (a b) (/ (+ a b) 2.0)) startPt endPt)) (setq sagTol (max 1e-3 (* 1e-4 chordLen))) (setq isCurveSegment (> (distance midPt chordMid) sagTol)) ;; For AECC_FEATURE_LINE the API returns chord length on curved ;; segments. Approximate true arc length with 2 sub-chords so the ;; "short segment" test and divide-by-distance follow the real arc. (if (and isCurveSegment (= entType "AECC_FEATURE_LINE")) (setq segmentLen (+ (distance startPt midPt) (distance midPt endPt)))) (setq tempDist (if isCurveSegment dist distLine)) (if (not (= tempDist "Skip")) (progn (DIV:SafeMark obj startPt) (DIV:SafeMark obj endPt) ;; Interactive short segment logic (if (and (numberp tempDist) (> tempDist 0) (< segmentLen tempDist)) (progn (setq shortSegChoice (if isCurveSegment bulk_arc bulk_line)) (if (null shortSegChoice) (progn (initget "Middle Vertices Skip All") (setq shortSegChoice (getkword (strcat "\nShort segment (Len: " (rtos segmentLen 2 3) ") [Middle/Vertices/Skip/All] <" (if isCurveSegment *div_short_arc_choice* *div_short_line_choice*) ">: "))) (if (null shortSegChoice) (setq shortSegChoice (if isCurveSegment *div_short_arc_choice* *div_short_line_choice*))) (if (= shortSegChoice "All") (progn (setq shortSegChoice (if isCurveSegment *div_short_arc_choice* *div_short_line_choice*)) (if isCurveSegment (setq bulk_arc shortSegChoice) (setq bulk_line shortSegChoice)))) (if isCurveSegment (setenv "DIV_ShortArcChoice" shortSegChoice) (setenv "DIV_ShortLineChoice" shortSegChoice)) ) ) (cond ((= shortSegChoice "Middle") (process-segment-fixed obj pIdx segmentLen "Middle")) ((= shortSegChoice "Vertices") nil) ((= shortSegChoice "Skip") nil) ) ) (if tempDist (process-segment-fixed obj pIdx segmentLen tempDist)) ) ) ) (setq pIdx (1+ pIdx)))) ;; Handle Splines ((= entType "SPLINE") (if (not (= dist "Skip")) (progn (DIV:SafeMark obj (vlax-curve-getStartPoint obj)) (if (not (vlax-curve-isClosed obj)) (DIV:SafeMark obj (vlax-curve-getEndPoint obj))) (process-standalone-fixed obj totalLen dist 0 numSlices circleMode)))) ;; Handle standalone Lines, Arcs, Circles (t (setq tempDist (if (or (= entType "ARC") (= entType "CIRCLE")) dist distLine)) (if (not (= tempDist "Skip")) (progn (DIV:SafeMark obj (vlax-curve-getStartPoint obj)) (if (not (vlax-curve-isClosed obj)) (DIV:SafeMark obj (vlax-curve-getEndPoint obj))) (if (and (numberp tempDist) (> tempDist 0) (< totalLen tempDist)) (progn (cond ((= entType "CIRCLE") (if bulk_circ (setq shortSegChoice bulk_circ) (progn (initget "Middle Pieces Skip All") (setq shortSegChoice (getkword (strcat "\nShort Circle (Len: " (rtos totalLen 2 3) ") [Middle/Pieces/Skip/All] <" *div_short_circ_choice* ">: "))) (if (null shortSegChoice) (setq shortSegChoice *div_short_circ_choice*)) (if (= shortSegChoice "All") (progn (setq shortSegChoice *div_short_circ_choice*) (setq bulk_circ shortSegChoice))) (setenv "DIV_ShortCircChoice" shortSegChoice) ) ) (cond ((= shortSegChoice "Middle") (process-standalone-fixed obj totalLen "Middle" 0 numSlices circleMode)) ((= shortSegChoice "Pieces") (setq temp (getint (strcat "\nEnter number of slices <" (itoa *div_short_circ_pieces*) ">: "))) (if (not temp) (setq shortCircPieces *div_short_circ_pieces*) (setq shortCircPieces temp)) (setenv "DIV_ShortCircPieces" (itoa shortCircPieces)) (process-standalone-fixed obj totalLen "Distance" 0 shortCircPieces "Pieces")) ((= shortSegChoice "Skip") nil) ) ) ((= entType "ARC") (if bulk_arc (setq shortSegChoice bulk_arc) (progn (initget "Middle Vertices Skip All") (setq shortSegChoice (getkword (strcat "\nShort Arc (Len: " (rtos totalLen 2 3) ") [Middle/Vertices/Skip/All] <" *div_short_arc_choice* ">: "))) (if (null shortSegChoice) (setq shortSegChoice *div_short_arc_choice*)) (if (= shortSegChoice "All") (progn (setq shortSegChoice *div_short_arc_choice*) (setq bulk_arc shortSegChoice))) (setenv "DIV_ShortArcChoice" shortSegChoice) ) ) (cond ((= shortSegChoice "Middle") (process-standalone-fixed obj totalLen "Middle" 0 numSlices circleMode)) ((= shortSegChoice "Vertices") nil) ((= shortSegChoice "Skip") nil) ) ) ((= entType "LINE") (if bulk_line (setq shortSegChoice bulk_line) (progn (initget "Middle Vertices Skip All") (setq shortSegChoice (getkword (strcat "\nShort Line (Len: " (rtos totalLen 2 3) ") [Middle/Vertices/Skip/All] <" *div_short_line_choice* ">: "))) (if (null shortSegChoice) (setq shortSegChoice *div_short_line_choice*)) (if (= shortSegChoice "All") (progn (setq shortSegChoice *div_short_line_choice*) (setq bulk_line shortSegChoice))) (setenv "DIV_ShortLineChoice" shortSegChoice) ) ) (cond ((= shortSegChoice "Middle") (process-standalone-fixed obj totalLen "Middle" 0 numSlices circleMode)) ((= shortSegChoice "Vertices") nil) ((= shortSegChoice "Skip") nil) ) ) ) ) (if tempDist (process-standalone-fixed obj totalLen tempDist 0 numSlices circleMode)) ) ) ) ) ) (setq i (1+ i))) (princ (strcat "\nProcessed " (itoa (sslength ss)) " objects.")))) (setvar "DYNPROMPT" oldDynPrompt) (princ) ) ;; ====================== HELPER FUNCTIONS ====================== (defun DIV:SafeMark (obj pt / checkPt) (if (and pt (listp pt)) (progn (setq checkPt (vlax-curve-getClosestPointTo obj pt)) (if (and (equal pt checkPt 1e-4) (not (vl-some '(lambda (x) (equal pt x 1e-3)) p-list))) (progn (entmake (list '(0 . "POINT") (cons 10 pt))) (setq p-list (cons pt p-list))))))) (defun process-segment-fixed (obj pIdx segmentLen tempDist / k divDist) (cond ((= tempDist "Vertices") nil) ((= tempDist "Middle") (DIV:SafeMark obj (vlax-curve-getPointAtParam obj (+ pIdx 0.5)))) ((and (numberp tempDist) (> tempDist 0)) (if (> tempDist segmentLen) (DIV:SafeMark obj (vlax-curve-getPointAtParam obj (+ pIdx 0.5))) (progn (setq k 1) (while (< (* k tempDist) (- segmentLen 0.001)) (setq divDist (+ (vlax-curve-getDistAtParam obj pIdx) (* k tempDist))) (DIV:SafeMark obj (vlax-curve-getPointAtDist obj divDist)) (setq k (1+ k)))))))) (defun process-standalone-fixed (obj totalLen tempDist offset numSlices circleMode / k) (cond ((= tempDist "Vertices") nil) ((= tempDist "Middle") (DIV:SafeMark obj (vlax-curve-getPointAtDist obj (+ offset (* totalLen 0.5))))) ((and (= circleMode "Pieces") (numberp numSlices) (> numSlices 1)) (setq k 1) (repeat (1- numSlices) (DIV:SafeMark obj (vlax-curve-getPointAtDist obj (* k (/ totalLen (float numSlices))))) (setq k (1+ k)))) ((and (numberp tempDist) (> tempDist 0)) (if (> tempDist totalLen) (DIV:SafeMark obj (vlax-curve-getPointAtDist obj (+ offset (* totalLen 0.5)))) (progn (setq k 1) (while (< (* k tempDist) (- totalLen 0.001)) (DIV:SafeMark obj (vlax-curve-getPointAtDist obj (+ offset (* k tempDist)))) (setq k (1+ k)))))))) When executed, the utility launches an interactive keyword configuration: Menu: [1-Polylines/2-Lines/3-Arcs/4-Circles/5-Splines/6-FeatureLines/7-All] --- OPTION 1: Polylines --- - Target: Native 2D LWPolylines and 3D Heavy Polylines (*POLYLINE). - Sub-Prompts: Asks for both "Curve distance" and "Line distance". - Workflow Logic: Polylines frequently alternate between straight tangents and arced bulges. The engine runs through each sub-segment parameter, applying the Curve interval on loops returning a non-zero bulge and the Line interval on zero-bulge vectors. Critical for tracking centerlines. --- OPTION 2: Lines --- - Target: Standalone native LINE entities (completely ignores curves). - Sub-Prompts: Triggers only "Line distance [Middle/Vertices]". - Workflow Logic: * Absolute Number: Measures out fixed structural intervals from start. * "Middle": Drops a single layout node at exactly Total Length / 2. * "Vertices": Flags only the absolute start and endpoints, bypassing any segment division calculations. Perfect for boundary box indexing. --- OPTION 3: Arcs --- - Target: Standalone open circular ARC elements. - Sub-Prompts: Triggers only "Curve distance [Middle]". - Workflow Logic: Uses true structural arc-length path calculations (not straight-line chord spacing). Entering "Middle" isolates the exact apex mid-curve station node. Excellent for curb returns or radius layout. --- OPTION 4: Circles --- - Target: Full, closed 360-degree CIRCLE elements. - Sub-Prompts: 1. Circle Mode [Distance/Pieces] 2. Curve Distance (if Distance Mode) 3. Number of Slices (if Pieces Mode) - Workflow Logic: * Pieces Mode: Divides the 360° rim into perfectly equal pie sections. Ideal for setting layout coordinates for manholes or foundation piles. * Distance Mode: Steps linearly around the outer circumference. --- OPTION 5: Splines --- - Target: Non-uniform smooth organic SPLINE curve strings. - Sub-Prompts: Triggers "Curve distance" and "Line distance". - Workflow Logic: Utilizes Visual LISP curve projection vectors to step smoothly through changing multi-radius landscape or contour paths, automatically trapping and marking the true start/end index boundaries. --- OPTION 6: FeatureLines --- - Target: Native Autodesk Civil 3D Feature Lines (AECC_FEATURE_LINE). - Sub-Prompts: Triggers "Curve distance" and "Line distance". - Workflow Logic: Tailored for civil infrastructure models. The engine interrogates the 3D string, locks all critical grade breaks and site vertices, and overlays intermediate interval layout points that retain design model accuracy. --- OPTION 7: All --- - Target: Simultaneous mixed selection set of all supported geometries. - Sub-Prompts: Sequential configuration parameters for all curves/lines. - Workflow Logic: Scans the entire cross-window selection. For every object trapped, it reads its DXF Group 0 type, dynamically assigns your preset rules, avoids duplicate coordinate overlaps, and populates the entire site plan layer in a single execution click. SHORT SEGMENT OVERRIDE LOGIC: If an entity length or sub-segment is shorter than the interval distance specified, the script halts and prompts: [Middle/All/SkipAll] - "Middle": Drops a layout node exactly at the center of that specific short segment. - "All": Converts the current short vector and all subsequent short vectors discovered during the current command run into midpoints automatically. - "SkipAll": Ignores short segments entirely for the rest of the execution, leaving them clean and checking only major length spans. SHORT SEGMENT OVERRIDE LOGIC: If an entity length or sub-segment is shorter than the interval distance specified, the script halts and prompts: [Middle/All/SkipAll] - "Middle": Drops a layout node exactly at the center of that specific short segment. - "All": Converts the current short vector and all subsequent short vectors discovered during the current command run into midpoints automatically. - "SkipAll": Ignores short segments entirely for the rest of the execution, leaving them clean and checking only major length spans.
    1 point
  41. Off the top of my head, could you use polar coordinates to split the site into slices? With 60-degree increments, you have six slices. When you process a borehole, you use the distance from the center of the site to place the table at a proportional distance in the outer area. By setting the placement angle to a clamped fraction of the slice, you get a fixed number of places for the tables, so there's no chance of overlap. That way you don't have a lot of edge cases, and the tables correspond roughly to the boreholes. I'm probably not explaining this clearly. I can put together a diagram and maybe some code if you need them.
    1 point
  42. Yes, 2000i fails when zoomed out as well.
    1 point
  43. I reversed all the polylines see if that does anything. -Edit Might fix it on the bottom but then mess it up on the top. Rervers Boundary.dwg
    1 point
  44. I exploded the polylines into lines. I also reduced the lineweight to 0, but in both cases the result remains the same. A colleague who still has an old PC with Autodesk Map 5 (= AutoCAD 2002) also confirmed that the same error occurs. If I’m not mistaken, AutoCAD 2002 is basically the same as AutoCAD 2000, so @SLW210’s statement that the "boundary" command works correctly in that version intrigues me.
    1 point
  45. Welcome aboard, post a sample dwg with your block, then people can have a look at what you have done.
    1 point
  46. Why the error occurs The PAUSE limitation: In AutoLISP, pause only stops the command to let the user interact (e.g., click a point). It does not return the string value to the command sequence. When you reach the attribute part, AutoCAD expects a string, but since pause doesn't provide one, the sequence breaks.Multiline Attribute Format: Multiline attributes in a command-line sequence require specific formatting. If there are line breaks, they must be represented by \P. In Lisp, you must escape the backslash: \\P .Command vs -Command: When using Lisp, it is safer to use the hyphenated version (e.g., -INSERT ) to force the command-line interface and bypass dialog boxes entirely. The Corrected Lisp Routine This routine replaces your DIESEL script. It captures the date automatically (matching your DIESEL format) and prompts for the initials and notes. (defun c:REVNOTE (/ insPt dateStr userInitials revNote) ;; Save current ATTDIA and turn it off (setq oldAttdia (getvar "ATTDIA")) (setvar "ATTDIA" 0) ;; 1. Get Insertion Point (setq insPt (getpoint "\nSpecify insertion point: ")) ;; 2. Get Date (Mimicking your Diesel formatting) ;; This uses a Lisp trick to call the Diesel 'edtime' function directly (setq dateStr (menucmd "M=(edtime,$(getvar,date),DD.MO.YYYY)")) ;; 3. Get User Initials (getstring T allows spaces) (setq userInitials (getstring T "\nEnter Initials: ")) ;; 4. Get Revision Note (for the multiline attribute) (setq revNote (getstring T "\nEnter Revision Note: ")) ;; 5. Execute the Insert command ;; Sequence: BlockName, Point, ScaleX, ScaleY, Rotation, Attr1, Attr2, Attr3, Attr4 (command "-INSERT" "REVNOTE" ; Block name insPt ; User picked point "1" "1" "0" ; Scale and Rotation "P01" ; Attribute 1: Rev Index dateStr ; Attribute 2: Date userInitials ; Attribute 3: Initials revNote ; Attribute 4: Multiline Note ) ;; Restore ATTDIA and Regen (setvar "ATTDIA" oldAttdia) (command "REGEN") (princ "\nRevision inserted successfully.") (princ) ) Key Differences & Improvements: menucmd: This is the best way to get the exact edtime format you used in DIESEL without writing a complex date-parsing routine in Lisp. getstring T: The T flag allows the user to enter spaces (e.g., if the user wants to type "First issue - revised"). Without it, pressing the Spacebar would finish the command. -INSERT: Using the hyphen ensures that AutoCAD doesn't try to pop up a browser window for the block file.Multiline Support: If your revNote contains multiple lines, make sure to type \P where you want the line break, or modify the code to join multiple strings with \\P.
    1 point
  47. Updated first post , added a few new options and killed a little bug in the get-subfolders routine.
    1 point
  48. Another way to get the text from a pdf is the AI option 'OCR text & table from Microsoft PC manager, normally just available in the US store. But if you have VPN or are a really good singer (Queen : Oh...yes , I'm the great pretender lalala.. applause , oh thank you , you're so kind) you should be able to get it. Open pdf , use button et voila... but its still manual labor
    1 point
  49. Before I used this : (defun GetFolder ( m / f s) (if (and (setq s (vlax-create-object "Shell.Application")) (setq f (vlax-invoke s 'browseforfolder 0 m 65536 "")))(setq f (vlax-get-property (vlax-get-property f 'self) 'path)) (setq f nil))(vl-catch-all-apply 'vlax-release-object (list s)) f) (defun wait (sec / stop)(setq stop (+ (getvar "DATE") (/ sec 86400.0)))(while (> stop (getvar "DATE")))) (defun findstring ( / a b c d e) (setq a (GetFolder "Select folder for string search")) (setq b (getstring "\nEnter string to search for : " T)) (setq c (getstring "\nFile extension (lsp) : ")) (if (eq c "") (setq c "lsp")) (setq d (strcat a "\\result.txt")) (setq e (strcat "findstr /i /s \"" b "\" " a "\\*." c " > " d)) (command "shell" e) (gc)(gc) ;;; natural delay for system to clear cache and write file to disk (alert "search completed") (startapp "notepad" d) (princ) ) (defun c:dfs ()(findstring)) (defun c:t1 ()(findstring)(princ)) This code only works for text based files. Have updated code in my first post with Excel support. Valid extensions are now lsp , txt , dwg , xls and xlsx I have a license for able2extract on my home computer and also written something that uses pdfattach and import for readable pdf's. Though I can take that route, it's not like shoot & forget , often more than one step is needed. But it is what it is... most pdf's I get are pretty poor quality , some by accident and some not because a 3rd party wants you as a returning client if you know what I mean.
    1 point
×
×
  • Create New...