Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation since 10/30/2026 in Posts

  1. A couple of points to make: The need to create thousands of variables on-the-fly typically points to poor program design; in almost every case, a list is more suitable. Setting all such variables to nil at the end of the program does clear them from the document namespace, but consider that you are essentially creating & clearing global variables that are not local to the scope of your program, and as such, the variable names could potentially clash with identically named variables in the document namespace - this is generally considered bad practice.
    4 points
  2. and yet here's another version that should run in LT pl_GetDir.lsp
    2 points
  3. I work with 2D CAD drawings for protective foam packaging and CNC, so overlapping geometry is something I pay attention to. Duplicate lines can create problems downstream, especially when preparing closed profiles for cutting. I think it's worth teaching beginners to check their geometry early instead of waiting until export.
    2 points
  4. Every design revision, I have to circle changes with revision clouds for submission. I kept missing things or marking the wrong spots, so I wrote a LISP to do it automatically. What it does: 1. Select Region A (old version) 2. Select Region B (revised version) 3. Red revision clouds appear around every difference It works inside the same DWG — no need for two separate files like DWG Compare. Uses signature-based object comparison with sorted merge, so it handles 1400+ objects in seconds. Features: - Automatic spatial alignment (consensus voting) - Nearby changes merged into grouped clouds - Giant objects (title blocks, borders) auto-filtered - Manual 2-point alignment fallback if auto fails - Configurable tolerance, arc size, merge distance Supports: LINE, CIRCLE, ARC, LWPOLYLINE, TEXT/MTEXT, INSERT, DIMENSION Skips: HATCH (too many false positives) AutoCAD 2014+ compatible. Free / MIT: https://github.com/beastt1992/DiffCheck Feedback welcome
    2 points
  5. These are ones I use: To record the current zoom: (setq currentzoom (list (getvar 'viewctr) (getvar 'viewsize))) .. zoom as you want And this returns you to where you were. (vla-ZoomCenter (vlax-get-acad-object) (vlax-3d-point (car currentzoom)) (cadr currentzoom)) Never tried with viewports but some ssget types need the entities to be selected to be in view, maybe viewports are the same
    2 points
  6. Here's another without command calls: (defun c:zal (/ a d c tabs) ;; RJP » 2020-07-08 (setq c (getvar 'ctab)) (vlax-for x (vla-get-layouts (setq d (vla-get-activedocument (setq a (vlax-get-acad-object))))) (setq tabs (cons (list (vla-get-name x) (vla-get-taborder x)) tabs)) ) ;; The sort makes sure that the tabs step left to right (foreach x (cdr (vl-sort tabs '(lambda (r j) (< (cadr r) (cadr j))))) (setvar 'ctab (car x)) (vlax-put d 'mspace 0) (vla-zoomextents a) ) (setvar 'ctab c) (princ) )
    2 points
  7. I have a Zoom Extents in Modelspace and Zooms Extents, then .9x in all layouts, it helps with the offset AutoCAD puts on some drawings when opening them, plus works for finding odd paperspace items, zooms just a little more to show the edges. Still trying to determine what is wrong with Lee Mac VPOUTLINE LISP? Are you looking for a count of true viewports? I have a LISP that gives this report of true viewports in all layouts, as well as places a border in modelspace and creates/checks for my viewport layer. ====================================== AutoVPBrdr REPORT ====================================== True layout viewports: 5 Viewport layer assignments: 5 Layer assignment failures: 0 Modelspace borders created: 5 Viewports skipped: 0 -------------------------------------- Layer: Viewport Color: 45 Plot: OFF ====================================== It only places a border for a viewport referencing Top/Plan view.
    2 points
  8. Frustratingly I think it has a couple of VLAX functions but not all of them - for LT I'd be finding another way if possible (in my example above bypassing the functionality completely)
    1 point
  9. @BIGAL you're correct...in fact functions attempting to access 3rd party apps like Excel are all not supported: https://help.autodesk.com/view/ACDLT/2024/ENU/?guid=GUID-037BF4D4-755E-4A5C-8136-80E85CCEDF3E
    1 point
  10. The other important one missing is Vlax-get-application it allows you to talk to Excel via lisp.
    1 point
  11. @indiancad here's a thread that you might find interesting regarding twist relative to a spline. Note that the first derivative of a curve is a vector tangent to the spline at a specifed point on the spline. The second derivative is a vector thet is the direction and magnitude of the change in the tangent vector at a point. The cross product of these two vetors, also know as the transverse vector, point to the instantaneous center of curvature for the curve at a specfied point along a curve. I wrote the following program to display graphically the radius of curvature (the ends of the generated lines are the center of curvature) or the curvature of a spline (short lines indicate almost flat segments of a spline). Try the program on a spline and answer Yes when prompted. (defun C:DOCL (/ path inc n osm par der1 der2 curva p perp normv p2 sf curveType ans) ; = Degree Of Curvature - Lines ; Creates curvature lines or radius-of-curvature lines ; normal to a spline. ; LRM 8/18/2022 edited to place curvature vectors outside (setq path (car (entsel)) inc (/ (vlax-curve-getEndParam path) 100) n 0 osm (getvar 'osmode) ) (setvar 'osmode 0) (setvar "cmdecho" 0) (initget "y n") (setq ans (getkword "Do you want radius-of-curvature instead of curvature? [y/n] <n>: ")) (if (= ans "y") (setq curveType 1) (setq curveType 2 sf (getdist "Enter scale factor.") ) ) (repeat 100 (setq par (* inc n)) (setq der1 (vlax-curve-getfirstDeriv path par) der2 (vlax-curve-getSecondDeriv path par) ) ; calculate curvature at point par (setq d (distance '(0 0 0) (cross der1 der2))) (if (> (abs d) 1.0e-15) (progn (setq curva (/ (expt (distance '(0 0 0) der1) 3) d)) (if (= curveType 2) (setq curva (* -1. (* sf (/ 1. curva)))) ) (princ "\n") (princ n) (princ " curvature = ") (princ curva) (setq p (vlax-curve-getPointAtParam path par) perp (unitv (cross der1 (cross der2 der1))) normv (mapcar '* perp (list curva curva curva)) p2 (mapcar '+ p normv) ) (command "_.line" p p2 "") ) ; end progn ) (setq n (1+ n)) ) (setvar 'osmode osm) (setvar "cmdecho" 1) (princ) ) ;;; Compute the cross product of 2 vectors a and b (defun cross (a b / crs) (setq crs (list (- (* (nth 1 a) (nth 2 b)) (* (nth 1 b) (nth 2 a)) ) (- (* (nth 0 b) (nth 2 a)) (* (nth 0 a) (nth 2 b)) ) (- (* (nth 0 a) (nth 1 b)) (* (nth 0 b) (nth 1 a)) ) ) ;end list ) ;end setq c ) ;end cross (defun unitV ( v / d) (setq d (distance '(0 0 0) v) d (mapcar '/ v (list d d d)))) blocks_on_spline.lsp spline curvature.lsp
    1 point
  12. FYI: LT 2024+ does support vlax functions but not vlax-create-object
    1 point
  13. Besides checking the related settings, I have had to rotate and position the shape as well, though most of my SWEEP experience is with piping, so no worries if a circle twists.
    1 point
  14. I still try to think about LT usage when redoing an old LISP and creating new LISP, but it's not a real priority. If those that use LT around here need something done with a LISP and we can't find one that runs on LT, I can see if it's adjustable to be made to work or I can just do it for them. I originally asked this because an engineer with AutoCAD LT needed to convert a bunch of DGNs, I did end up converting a lot of folders with my LISP, but in the end the company that sent us the DGNs sent the exported from Autoplant .dwgs, etc., the DGNs we had converted okay, but IIRC some information was missing here and there for some of the files.
    1 point
  15. I was looking for something quick and simple yesterday - thanks. Now the not so quick part, I decided to make the DCL file as 'create on demand' style, and then tweak it a touch.... and then sent it through Al... a bit updated does what I want now. (Al was reasonably competent in it saved me about an hour copy-paste from my reference LISPs) Edit: Oh, for LT... forgetting the reason I was looking - shortcut links use VLAX code and I think the desktop part needs amending too - shortcuts are bypassed - won't work in LT - desktop I'll come back to (defun c:gf ( / DriveList CurDrive SubfolderList CurSubfolder GetFolderOldErr GetFolderDcl CurPath PathHistoryList MyResult) (defun GetFolder_init ( / MyDrawingDrive ) (setq GetFolderDcl (load_dialog "GetFolder")) (setq GetFolderOldErr *error*) (setq *error* GetFolderErr) (MakeDriveList) (setq CurPath (getvar "DWGPREFIX")) ;; Current drawing folder (setq DrawingDrive (substr CurPath 1 2)) ;; Drive (setq CurDrive (vl-position DrawingDrive DriveList)) (if (null CurDrive) (setq CurDrive 0)) ; End If (setq PathHistoryList (list CurPath)) (MakeSubfolderList CurPath) ) ; End GetFolder_init (defun GetFolder_exit ( / ) (setq CurPath CurPath) ) ; End GetFolder_exit (defun GetFolderErr ( s / ) (GetFolder_exit) (if GetFolderOldErr (setq *error* GetFolderOldErr) (setq *error* '()) ) ; End If ) ; End GetFolderErr (defun MakeDriveList ( / ascii-code drive ) (setq DriveList '()) (setq ascii-code 67) ;; ASCII code C = 67, Z = 90 (while (<= ascii-code 90) (setq drive (strcat (chr ascii-code) ":") ) (if (vl-file-directory-p drive) (setq DriveList (append DriveList (list drive))) ) ; End If (setq ascii-code (1+ ascii-code)) ) ; End While ) ; End MakeDriveList (defun MakeSubfolderList ( dir / MyFolderList MyShortcutList ) (if (and dir (= (type dir) 'STR) (vl-file-directory-p dir) ) ; End And (progn (setq MyFolderList (vl-directory-files dir nil -1) ) ;; Folders (if (= (getvar 'program) "LT") (setq SubfolderList (append (list "<-") MyFolderList )) ;;LT vl-dirctoryfiles might not work (progn (setq MyShortcutList (vl-directory-files dir "*.lnk" 1) ) ;; Shortcuts (setq SubfolderList (append (list "<-") MyFolderList MyShortcutList )) ) ; end progn ) ; end if ) ; End Progn (setq SubfolderList (list "<-")) ) ; End If (setq SubfolderList (vl-remove "." SubfolderList) ) (setq SubfolderList (vl-remove ".." SubfolderList)) (if (wcmatch CurPath "@`:") (setq SubfolderList (vl-remove "<-" SubfolderList)) ) ; End If ) ; End MakeSubfolderList (defun UpdateSubfolder ( $value / MyShortcut MyTarget MyShell ) (setq CurSubfolder (nth (atoi $value) SubfolderList )) (cond ((equal CurSubfolder "<-") ;; Back to previous folder (if (= (length PathHistoryList) 1) ;; top level (progn (setq CurPath (car PathHistoryList)) ) (progn (setq CurPath (cadr PathHistoryList)) (setq PathHistoryList (cdr PathHistoryList)) ) ; end progn ) ; end if ) ; end cond ((wcmatch (strcase CurSubfolder) "*.LNK") ;; shortcut (if (= (getvar 'program) "LT") ;; LT doesn't do VLAX (progn ) (progn (setq MyShell (vlax-create-object "WScript.Shell")) (setq MyShortcut (vlax-invoke-method MyShell 'CreateShortcut (strcat CurPath "\\" CurSubfolder))) (setq MyTarget (vlax-get-property MyShortcut 'TargetPath)) (vlax-release-object MyShortcut) (vlax-release-object MyShell) (if (and ;; if lnk is a folder MyTarget (vl-file-directory-p MyTarget) ) ; End And (progn (setq PathHistoryList (append (list CurPath) PathHistoryList )) (setq CurPath MyTarget) ;; Jump to shortcut target ) ; End Progn ;; (alert "Shortcut does not point to a folder.") ) ; End If ) ; end progn lnk ) ; end if ) ; end cond (T ;; Normal folder (setq PathHistoryList (append (list CurPath) PathHistoryList )) (setq CurPath (strcat CurPath "\\" CurSubfolder) ) ;; Enter selected folder ) ; end cond T ) ; End Conds (MakeSubfolderList CurPath) ;; Rebuild folders and shortcuts for the new location ;; Replace existing DCL list contents (start_list "subfolder" 3) (mapcar 'add_list SubfolderList) (end_list) (set_tile "subfolder" "0") ;; Select first item in refreshed list (set_tile "path" CurPath) ;; Display new path ) ; End UpdateSubfolder (defun InitDialog ( / ) (start_list "drive") (mapcar 'add_list DriveList) (end_list) (set_tile "drive" (itoa CurDrive)) ;; Select the drive containing the current drawing (start_list "subfolder") (mapcar 'add_list SubfolderList) (end_list) (set_tile "path" CurPath) ;; Display the current drawing folder ) ; End InitDialog (defun GetFolder_dialog ( / fname GF drv MyDclFile dcl_id MyFile) ;; Create DCL file ;;Start DCL (setq GF (open (setq fname (vl-filename-mktemp "GetFolder" (getvar "TEMPPREFIX") ".dcl")) "w")) ;;Header (write-line "SelLays : dialog {" GF) (write-line " key = \"Folder\";" GF) (write-line " label = \"GetFolder (RLX-10/04)\";" GF) (write-line " spacer;" GF) ;;Stuff (write-line " :row {alignment = top;" GF) (write-line " :column { width = 5; fixed_width = true; " GF) (write-line " : popup_list {key = \"drive\"; label = \"Drive\"; edit_width = 7; }" GF) (write-line " }" GF) ; end column (write-line " :column { width = 38; fixed_width = true; " GF) (write-line " }" GF) ; end column (write-line " }" GF) ; end row (write-line " :row {alignment = top;" GF) (write-line " :column { width = 6; fixed_width = true; " GF) (write-line " }" GF) ; end column (write-line " :column { width = 12; fixed_width = true; " GF) (write-line " :row {alignment = top;" GF) (write-line " : button { key = \"uplevel\"; label = \"↑ Last level\"; width = 5; }" GF) (write-line " : button { key = \"desktop\"; label = \"Desktop\"; width = 5; }" GF) (write-line " }" GF) ; end row (write-line " }" GF) ; end column (write-line " :column { width = 32; fixed_width = true; " GF) (write-line " }" GF) ; end column (write-line " }" GF) ; end row (write-line " :row {alignment = top;" GF) (write-line " : list_box { key = \"subfolder\"; label = \"Subfolders\"; height = 12; width = 25; }" GF) (write-line " }" GF) ; end row (write-line " :row {alignment = top;" GF) (write-line " : edit_box { key = \"path\"; label = \"Path\"; width = 25; }" GF) (write-line " }" GF) ; end row (write-line " ok_cancel;" GF) (write-line "}" GF) ; end dialog (close GF) (setq dcl_id (load_dialog fname)) (if (and dcl_id (new_dialog "SelLays" dcl_id) ) ; End And (progn (InitDialog) (action_tile "drive" " (UpdateDrive $value)" ) (action_tile "desktop" "(UpdateDesktop)" ) (action_tile "uplevel" "(UpdateUpLevel)" ) (action_tile "subfolder" "(UpdateSubfolder $value)" ) (action_tile "path" "(UpdatePath $value)" ) (action_tile "accept" "(done_dialog 1)" ) (action_tile "cancel" "(done_dialog 0)" ) (setq drv (start_dialog)) (cond ((= drv 0) (setq CurPath nil) ) ((= drv 1) (setq CurPath CurPath) ) ) ; End Cond ) ; End Progn ) ; End If (if dcl_id (unload_dialog dcl_id) ) ) ; End GetFolder_dialog (defun UpdateDrive ( $value / ) (setq CurDrive (atoi $value) ) (setq CurPath (nth CurDrive DriveList) ) (MakeSubfolderList CurPath) (start_list "subfolder") (mapcar 'add_list SubfolderList) (end_list) (setq PathHistoryList (list CurPath) ) (set_tile "path" CurPath) ) ; End UpdateDrive (defun UpdatePath ( dir / ) (if (and dir (= (type dir) 'STR) (vl-file-directory-p dir) ) ; End And (setq CurPath dir) (alert "Invalid Path") ) ; End If ) ; End UpdatePath (defun UpdateUpLevel ( / MyParentPath ) ;; Remove trailing slash if present (if (or (= (substr CurPath (strlen CurPath) 1) "\\") (= (substr CurPath (strlen CurPath) 1) "/") ) ; Endor (setq CurPath (substr CurPath 1 (1- (strlen CurPath))) ) ) ; End If (setq MyParentPath (vl-filename-directory CurPath)) ;; parent folder (if MyParentPath (progn (setq CurPath MyParentPath) (MakeSubfolderList CurPath) ;; Refresh subfolder list (start_list "subfolder") (mapcar 'add_list SubfolderList) (end_list) (set_tile "path" CurPath) ;; Update displayed path (setq PathHistoryList (list CurPath)) ;; Reset history from new location ) ; End Progn ) ; End If ) ; End UpdateUpLevel (defun UpdateDesktop ( / MyShell MyDesktop ) ;;Double check for none VLAX for LT (if (= (getvar 'program) "LT") (progn ) (progn (setq MyShell (vlax-create-object "WScript.Shell") ) (setq MyDesktop (vlax-invoke-method (vlax-get-property MyShell 'SpecialFolders) 'Item "Desktop")) (vlax-release-object MyShell) ) ) (if (and MyDesktop (vl-file-directory-p MyDesktop) ) ; End And (progn (setq CurPath MyDesktop) (MakeSubfolderList CurPath) (start_list "subfolder") (mapcar 'add_list SubfolderList) (end_list) (set_tile "path" CurPath) (setq PathHistoryList (list CurPath)) ) ; End Progn (alert "Desktop folder not found.") ) ; End If ) (GetFolder_init) (GetFolder_dialog) (setq MyResult (GetFolder_exit)) MyResult )
    1 point
  16. Hi all, I am in the early stages of developing (vibe coding) something I have been thinking about for a minute: a videogame where you CAD. It's called CADcade and I've got a whole vision for it and everything. Right now it's just some beginner lessons, a sandbox mode, and an arcade mode with 36 drafting challenges of varying difficulties. It runs in your computer browser, and one of the goals is to help students and beginners learn the basics of navigating CAD products and spatial thinking for free online. This is kind of a demo of it that I would like to get feedback on (not selling or monetizing anything). I just wanted to share it here and see what you guys think. How does it feel? Ai slop? Not enough commands? Dumb concept? Every reply helps. cadcade.net Thank you!
    1 point
  17. That depends on the LISP. Check my GETLEN.lsp. as an example. A new get length LISP - AutoLISP, Visual LISP & DCL - AutoCAD Forums It gets perimeters and accounts for gaps and overlaps even in anonymous blocks. I made that due to SOLPROF profiles being a pain with the overlaps, etc.. So, sometimes a cleanup isn't required to get correct information, just a LISP or other code. I have one somewhere, but there are a few online "OVERKILL" type LISPs that work on blocks and sometimes better cleanup, something OVERKILL doesn't do all of the time. But, OVERKILL does under normal circumstances do fairly well, so a first run with that, or a second run if the drawing needs a real flattening, best to do that first. The waterjet/plasma cutter person at work does a lot of the work for those machines now, but I used to do all of it when those were first purchased. So I have done lots of cleanups for cutting. Luckily, most things I start are pretty clean except the SOLPROF and SOLVIEW/SOLDRAW objects. The software that came with the waterjet also can do some cleaning. So I have that as well.
    1 point
  18. Create sections (green) at several points along the object. Explode the sections then set a UCS to the plane of a section and create offset curves (red) with a distance equal to the desired fillet radius. I used 0.2. Add a circle of the fillet radus at the intersection of the offset curves and then trim the circle. Create a polyline (yelllow) to form a closed shape that includes the "fillet" arc (cyan). With pedit create closed polylines for the fillet sections then use loft to create the fillet solid. Union the two solids together.
    1 point
  19. import traceback from pyrx import Ap, Db, Ed, Ge _index = 1 def makeBoundary(db: Db.Database, pnt: Ge.Point3d, tr: Db.Transparency): ids = [] plines = Ed.Editor.traceBoundary(pnt, False) for pline in plines: pline.setColorIndex(_index) # Uses the global integer pline.setTransparency(tr) ids.append(db.addToModelspace(pline)) return ids @Ap.Command() def doit(): global _index try: db = Db.curDb() tr = Db.Transparency(0.5) #50% ps, pnt = Ed.Editor.getPoint("\nSelect internal point: ") if ps != Ed.PromptStatus.eOk: return # 1. Generate the boundary polylines ids = makeBoundary(db, pnt, tr) if not ids: print("\nNo boundary found.") return # 2. Create and configure the Hatch object hat = Db.Hatch() hat.setPattern(Db.HatchPatternType.kPreDefined, "SOLID") hat.setColorIndex(_index) hat.setTransparency(tr) # 3. Add hatch to model space BEFORE appending loops (AutoCAD requirement) db.addToModelspace(hat) # 4. Establish associativity and evaluate hat.setAssociative(True) hat.appendLoop(Db.HatchLoopType.kDefault, ids) hat.evaluateHatch(True) print(f"\nCreated boundary and hatch with Color Index: {_index}") # 5. Increment color index (Cycle back to 1 if it exceeds standard ACI 255) _index += 1 if _index > 255: _index = 1 except Exception as e: print("Error encountered:") traceback.print_exc()
    1 point
  20. Db.Transparency in ARX (and Python) is overloaded to take an alpha 0-255 or alphaPercent 0.0 – 1.0, so you can use either. 0.5 is the same as 127 in this case. In this case traceBoundary was called with detect islands = False. Of course one might like to have a different transparency between the boundary and hatch, this just illustrates one
    1 point
  21. The key is to make the Hatch entity itself see-through not the boundary lines that get drawn. The hatch must also be checked after each boundary loop is added. The main fix is the transparency value. For 50% see‑through use an alpha value 127 instead of 0.5 because Db.Transparency uses a 0–255 scale. Set it directly on the hatch for example: hat.setTransparency(Db.Transparency(127)). Also if traceBoundary returns loops find the outer loop and any inner islands separately before you call appendLoop. If you do not do this the hatch might fill spots that should stay open.
    1 point
  22. For commercial AutoLISP applications I would not trust FAS VLX compilation alone. It makes looking at the source code but it should not be seen as full protection from people trying to figure out how it works. A better way is to put parts about licenses and checks into a compiled.NET component. Use a server to check licenses and connect activations to a mix of computer details. I also suggest using signed license answers storing information in a way on the computer checking online now and then and allowing a short time without internet. Do not depend on hardware IDs because changes in hardware can cause real problems with activation. One key thing to remember: no protection on the computer side is completely safe. The aim is to make it hard for people to copy and change the software while making sure real users can activate and renew easily. It would be interesting to find out if people here have done this with their licensing server or, with a company that offers licensing services.
    1 point
  23. In the draw window it's for multi story buildings so size can be different for every window. There is not a problem matching properties with a dcl. You can make better descriptions, in the code is default values you set or it can remember previous values. Just have the tools to make the dcl. If you look at the window DCL in movie on right side is edge controls these do just that a corner or a multi panel join and so on. So in your comments you talk a bit about this. Yes it's drawn via objects Plines etc. You can have shapes like the V notch. The dimensioning is just part of a program. I believe it will be easier than trying to make a dynamic block work. Given how much post time has occurred in this forum, a program would be done by now. But it is for your company only so a cost may be relevant. But you can add more shapes quickly. Will see if can find time to do some form of example. Step 1
    1 point
  24. As well as spend time making full instructions and even some videos of them in action.
    1 point
  25. FYI: my (67 . 1) filters out model space vports so only paper space vports will be selected.
    1 point
  26. Post a description about what they do something like this. Then people may get interested. Lisp files DEC 2025.docx
    1 point
  27. Like @Danielm103, I was also going to suggest Autodesk Store and/or what @BIGAL stated would be my choices. It really depends on what you are comfortable/familiar with. Personally, unless your LISPs are really making difficult and/or complicated work easy and a lot faster, I wouldn't believe they would be big sellers since they seem targeted at AutoCAD MEP, I haven't looked at any numbers lately, but a lot of those users are slowly rolling over to Revit, I was using AutoCAD MEP occasionally, but haven't had any of that type work to do in a good while, perhaps an occasional user such as myself would be a potential customer, I am not sure what percentage of AutoCAD users "do a little of everything" like I do. That is not meant to deter you, just to give an insight on what $$$ and effort you need to spend getting them secure and keeping them up. What future plans do you have on providing support? I see a lot of for purchase apps that end up having the publisher lose interest or other issues and the support goes away.
    1 point
  28. There was a time when I generated lisp files using dcl and image buttons to visually insert some typical block categories
    1 point
  29. As I have said many times I use POP menus for block libraries, you can select internal or external blocks for insertion. Pop menus should be fine in LT even earlier versions.
    1 point
×
×
  • Create New...