Leaderboard
Popular Content
Showing content with the highest reputation since 08/26/2026 in Posts
-
In another post there was questions about changing Mline styles for existing Mlines. So answered that and thought what about adding fillets to a mline. Wel as we know you can not do that, so did it this way. Converting the individual mlines to plines then filleting the plines produced. The fillet radius changing matching the offsets. ; Convert mline to plines and add a rdius. ; By AlanH Aug 2026 (defun LWPoly (lst cls) (entmakex (append (list (cons 0 "LWPOLYLINE") (cons 100 "AcDbEntity") (cons 100 "AcDbPolyline") (cons 90 (length lst)) (cons 70 cls)) (mapcar (function (lambda (p) (cons 10 p))) lst))) ) (defun c:ml2plrad ( / oldsnap pt1 pt2 ent obj obj2 co-ords dict col lst x) (setq oldsnap (getvar 'osmode)) (setvar 'osmode 0) (setq pt1 (getpoint "\nPick 1st point for drag ")) (setq pt2 (getpoint pt1 "\nPick 2nd point ")) (setq pts (list pt1 pt2)) (setq ent (ssname (ssget "F" pts (list (cons 0 "Mline"))) 0)) (setq obj (vlax-ename->vla-object ent)) (setq styleName (vla-get-StyleName obj)) (setq lay (vlax-get obj 'layer)) (setvar 'clayer lay) (setq co-ords (vlax-get obj 'coordinates)) (vla-delete obj) (setq pts2 '() x 0) (repeat (/ (length co-ords) 3) (setq pts2 (cons (list (nth x co-ords)(nth (1+ x) co-ords)) pts2)) (setq x (+ x 3)) ) (setq dict (dictsearch (cdr (assoc -1 (dictsearch (namedobjdict) "ACAD_MLINESTYLE"))) styleName)) (setq offsets (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 49)) dict))) (setq col (mapcar 'cdr (vl-remove-if-not '(lambda (x) (= (car x) 62)) dict))) (setq col (cdr col)) ; ignore 1st color (setq lst '() x 0) (repeat (length col) (setq lst (cons (list (nth x offsets)(nth x col)) lst)) (setq x (1+ x)) ) (LWPoly pts2 0) (setvar 'filletrad (getreal "\nEnter Fillet radius for most outside offset ")) (command "fillet" "P" (entlast)) (setq x 1) (repeat (- (length col) 1) (setq obj2 (vlax-ename->vla-object (entlast))) (vlax-put obj2 'color (nth (1- x) col)) (vla-offset (vlax-ename->vla-object (entlast)) (- (nth x offsets)(nth (1- x) offsets))) (setq x (1+ x)) ) (setq obj2 (vlax-ename->vla-object (entlast))) (vlax-put obj2 'color (nth (1- x) col)) (setvar 'osmode oldsnap) (princ) ) (c:ml2plrad)3 points
-
Been playing quite a bit with Gilles Chanteau's kdtree lisp app published at theSwamp kd-tree (AutoLISP). So decided to turn it into a dll to use from autolisp. I am attaching the C# code below and a bat file to compile it for Autocad 2017. The dll will create the following function for autolisp: KDtreeLisp.dll Reference & Command SyntaxIn AutoLISP documentation standards, optional parameters are enclosed in square brackets [optional]. (KD-BUILD pointList [dimensions] [customHandle]) Builds a KD-Tree spatial index from a list of points. Arguments: pointList: LIST — List of 2D or 3D point lists ((x y z) ...). dimensions (optional): INT — 2 for 2D $(X,Y)$ or 3 for 3D $(X,Y,Z)$. Default is 2. customHandle (optional): STR — Custom string handle identifier. Returns: STR handle (e.g., "<KD-TREE-1>" or "<KD-TREE-SURVEY>"), or nil on failure. (KD-NEAREST handle targetPoint [count] [maxRadius]) Finds the nearest n points to a target point. Arguments: handle: STR — KD-Tree handle string. targetPoint: LIST — Target point (x y z). count (optional): INT — Number of nearest points to retrieve. Default is 1. maxRadius (optional): REAL or INT — Maximum search radius limit. Points farther than this distance are ignored. Returns:If count = 1 (or omitted): A single point (x y z). If count > 1: A list of points ((x1 y1 z1) (x2 y2 z2) ...). (KD-NEAREST-INFO handle targetPoint [count] [maxRadius]) Finds nearest points with detailed metadata. Arguments: handle: STR — KD-Tree handle string. targetPoint: LIST — Target point (x y z). count (optional): INT — Number of points to retrieve. Default is 1. maxRadius (optional): REAL or INT — Maximum search radius limit. Returns: A list of detailed entries (((x y z) index distance) ...). (KD-RANGE handle centerPoint radius) Finds all points inside a fixed search radius without a count limit. Arguments: handle: STR — KD-Tree handle string. centerPoint: LIST — Center search coordinate (x y z). radius: REAL or INT — Search radius. Returns: A list of all enclosed points ((x1 y1 z1) (x2 y2 z2) ...) sorted by distance, or nil if none are found. (KD-FREE [handle]) Frees tree memory. Arguments: handle (optional): STR — Tree handle to free. If omitted, clears all active trees. Returns: INT — Number of trees removed. Once you've compiled the C#, kdtreelisp.dll will be created and ready to use in Autocad. using System; using System.Collections.Generic; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; namespace KdTreeLisp { // ========================================== // 1. DATA STRUCTURES & TREE ENGINE // ========================================== public class KdItem { public Point3d Point { get; set; } public int Id { get; set; } public KdItem(Point3d pt, int id) { Point = pt; Id = id; } } public class KdNode { public Point3d Point { get; set; } public int Id { get; set; } public KdNode Left { get; set; } public KdNode Right { get; set; } public KdNode(Point3d point, int id) { Point = point; Id = id; } } public class NeighborResult : IComparable<NeighborResult> { public KdNode Node { get; set; } public double DistanceSq { get; set; } public NeighborResult(KdNode node, double distSq) { Node = node; DistanceSq = distSq; } public int CompareTo(NeighborResult other) { return other.DistanceSq.CompareTo(this.DistanceSq); } } public class KdTree { public KdNode Root { get; private set; } public int ActiveDimensions { get; private set; } public void Build(List<KdItem> items, int activeDimensions) { ActiveDimensions = Math.Max(1, Math.Min(3, activeDimensions)); Root = BuildRecursive(items, 0); } private KdNode BuildRecursive(List<KdItem> items, int depth) { if (items == null || items.Count == 0) return null; int axis = depth % ActiveDimensions; items.Sort(delegate(KdItem a, KdItem b) { return GetAxisValue(a.Point, axis).CompareTo(GetAxisValue(b.Point, axis)); }); int medianIndex = items.Count / 2; KdNode node = new KdNode(items[medianIndex].Point, items[medianIndex].Id); node.Left = BuildRecursive(items.GetRange(0, medianIndex), depth + 1); node.Right = BuildRecursive(items.GetRange(medianIndex + 1, items.Count - (medianIndex + 1)), depth + 1); return node; } public double CalculateDistanceSq(Point3d p1, Point3d p2) { double dx = p1.X - p2.X; double dy = p1.Y - p2.Y; if (ActiveDimensions == 2) { return dx * dx + dy * dy; } double dz = p1.Z - p2.Z; return dx * dx + dy * dy + dz * dz; } // K-Nearest Neighbor Search with Optional Maximum Radius Limit public List<NeighborResult> FindNearest(Point3d target, int count, double maxRadius = double.MaxValue) { List<NeighborResult> heap = new List<NeighborResult>(); if (Root == null || count <= 0) return heap; double maxDistSq = (maxRadius == double.MaxValue) ? double.MaxValue : maxRadius * maxRadius; SearchNearest(Root, target, count, maxDistSq, heap, 0); // Sort ascending by distance before returning heap.Sort(delegate(NeighborResult a, NeighborResult b) { return a.DistanceSq.CompareTo(b.DistanceSq); }); return heap; } private void SearchNearest(KdNode current, Point3d target, int count, double maxDistSq, List<NeighborResult> heap, int depth) { if (current == null) return; double distSq = CalculateDistanceSq(current.Point, target); // Accept point only if inside maximum distance threshold if (distSq <= maxDistSq) { if (heap.Count < count) { heap.Add(new NeighborResult(current, distSq)); heap.Sort(); } else if (distSq < heap[0].DistanceSq) { heap[0] = new NeighborResult(current, distSq); heap.Sort(); } } int axis = depth % ActiveDimensions; double diff = GetAxisValue(target, axis) - GetAxisValue(current.Point, axis); KdNode primary = diff < 0 ? current.Left : current.Right; KdNode secondary = diff < 0 ? current.Right : current.Left; SearchNearest(primary, target, count, maxDistSq, heap, depth + 1); // Pruning condition: check if secondary subtree could contain points closer than current worst candidate double currentSearchRadiusSq = (heap.Count < count) ? maxDistSq : Math.Min(heap[0].DistanceSq, maxDistSq); if (diff * diff < currentSearchRadiusSq) { SearchNearest(secondary, target, count, maxDistSq, heap, depth + 1); } } // Range Search: Retrieves ALL points within radius public List<NeighborResult> RangeSearch(Point3d center, double radius) { List<NeighborResult> results = new List<NeighborResult>(); if (Root == null || radius < 0) return results; double radiusSq = radius * radius; SearchRangeRecursive(Root, center, radiusSq, results, 0); results.Sort(delegate(NeighborResult a, NeighborResult b) { return a.DistanceSq.CompareTo(b.DistanceSq); }); return results; } private void SearchRangeRecursive(KdNode current, Point3d center, double radiusSq, List<NeighborResult> results, int depth) { if (current == null) return; double distSq = CalculateDistanceSq(current.Point, center); if (distSq <= radiusSq) { results.Add(new NeighborResult(current, distSq)); } int axis = depth % ActiveDimensions; double diff = GetAxisValue(center, axis) - GetAxisValue(current.Point, axis); if (diff < 0) { SearchRangeRecursive(current.Left, center, radiusSq, results, depth + 1); if (diff * diff <= radiusSq) { SearchRangeRecursive(current.Right, center, radiusSq, results, depth + 1); } } else { SearchRangeRecursive(current.Right, center, radiusSq, results, depth + 1); if (diff * diff <= radiusSq) { SearchRangeRecursive(current.Left, center, radiusSq, results, depth + 1); } } } private double GetAxisValue(Point3d pt, int axis) { switch (axis) { case 0: return pt.X; case 1: return pt.Y; default: return pt.Z; } } } // ========================================== // 2. AUTOLISP INTERFACE BRIDGE // ========================================== public class LispBridge { private static readonly Dictionary<string, KdTree> _trees = new Dictionary<string, KdTree>(); private static int _treeCounter = 1; // Signature: (KD-BUILD pointList [dimensions] [customHandle]) [LispFunction("KD-BUILD")] public static TypedValue BuildTree(ResultBuffer args) { if (args == null) return new TypedValue((int)LispDataType.Nil); TypedValue[] arr = args.AsArray(); List<KdItem> items = new List<KdItem>(); int idCounter = 0; int requestedDimensions = 2; string customHandle = null; foreach (TypedValue tv in arr) { if (tv.TypeCode == (int)LispDataType.Point3d) { items.Add(new KdItem((Point3d)tv.Value, idCounter++)); } else if (tv.TypeCode == (int)LispDataType.Point2d) { Point2d pt2 = (Point2d)tv.Value; items.Add(new KdItem(new Point3d(pt2.X, pt2.Y, 0.0), idCounter++)); } else if (tv.TypeCode == (int)LispDataType.Int16 || tv.TypeCode == (int)LispDataType.Int32) { requestedDimensions = Convert.ToInt32(tv.Value); } else if (tv.TypeCode == (int)LispDataType.Text) { customHandle = Convert.ToString(tv.Value); } } if (items.Count == 0) return new TypedValue((int)LispDataType.Nil); KdTree tree = new KdTree(); tree.Build(items, requestedDimensions); string handle = string.IsNullOrEmpty(customHandle) ? string.Format("<KD-TREE-{0}>", _treeCounter++) : string.Format("<KD-TREE-{0}>", customHandle.ToUpper()); _trees[handle] = tree; return new TypedValue((int)LispDataType.Text, handle); } // Signature: (KD-NEAREST handle targetPoint [count] [maxRadius]) [LispFunction("KD-NEAREST")] public static ResultBuffer FindNearest(ResultBuffer args) { if (args == null) return null; List<TypedValue> values = ExtractValues(args); if (values.Count < 2) return null; if (values[0].TypeCode != (int)LispDataType.Text) return null; string handle = Convert.ToString(values[0].Value); if (!_trees.ContainsKey(handle)) return null; KdTree tree = _trees[handle]; if (tree.Root == null) return null; Point3d target; if (values[1].TypeCode == (int)LispDataType.Point3d) { target = (Point3d)values[1].Value; } else if (values[1].TypeCode == (int)LispDataType.Point2d) { Point2d p2 = (Point2d)values[1].Value; target = new Point3d(p2.X, p2.Y, 0.0); } else { return null; } int count = 1; if (values.Count > 2 && (values[2].TypeCode == (int)LispDataType.Int16 || values[2].TypeCode == (int)LispDataType.Int32)) { count = Convert.ToInt32(values[2].Value); } double maxRadius = double.MaxValue; if (values.Count > 3) { TypedValue v = values[3]; if (v.TypeCode == (int)LispDataType.Double || v.TypeCode == (int)LispDataType.Int16 || v.TypeCode == (int)LispDataType.Int32) { maxRadius = Convert.ToDouble(v.Value); } } List<NeighborResult> results = tree.FindNearest(target, count, maxRadius); if (results.Count == 0) return null; ResultBuffer res = new ResultBuffer(); if (count == 1) { res.Add(new TypedValue((int)LispDataType.Point3d, results[0].Node.Point)); } else { res.Add(new TypedValue((int)LispDataType.ListBegin)); foreach (NeighborResult item in results) { res.Add(new TypedValue((int)LispDataType.Point3d, item.Node.Point)); } res.Add(new TypedValue((int)LispDataType.ListEnd)); } return res; } // Signature: (KD-NEAREST-INFO handle targetPoint [count] [maxRadius]) [LispFunction("KD-NEAREST-INFO")] public static ResultBuffer FindNearestInfo(ResultBuffer args) { if (args == null) return null; List<TypedValue> values = ExtractValues(args); if (values.Count < 2) return null; if (values[0].TypeCode != (int)LispDataType.Text) return null; string handle = Convert.ToString(values[0].Value); if (!_trees.ContainsKey(handle)) return null; KdTree tree = _trees[handle]; Point3d target; if (values[1].TypeCode == (int)LispDataType.Point3d) target = (Point3d)values[1].Value; else if (values[1].TypeCode == (int)LispDataType.Point2d) target = new Point3d(((Point2d)values[1].Value).X, ((Point2d)values[1].Value).Y, 0.0); else return null; int count = 1; if (values.Count > 2 && (values[2].TypeCode == (int)LispDataType.Int16 || values[2].TypeCode == (int)LispDataType.Int32)) count = Convert.ToInt32(values[2].Value); double maxRadius = double.MaxValue; if (values.Count > 3) { TypedValue v = values[3]; if (v.TypeCode == (int)LispDataType.Double || v.TypeCode == (int)LispDataType.Int16 || v.TypeCode == (int)LispDataType.Int32) maxRadius = Convert.ToDouble(v.Value); } List<NeighborResult> results = tree.FindNearest(target, count, maxRadius); if (results.Count == 0) return null; ResultBuffer res = new ResultBuffer(); res.Add(new TypedValue((int)LispDataType.ListBegin)); foreach (NeighborResult item in results) { res.Add(new TypedValue((int)LispDataType.ListBegin)); res.Add(new TypedValue((int)LispDataType.Point3d, item.Node.Point)); res.Add(new TypedValue((int)LispDataType.Int32, item.Node.Id)); res.Add(new TypedValue((int)LispDataType.Double, Math.Sqrt(item.DistanceSq))); res.Add(new TypedValue((int)LispDataType.ListEnd)); } res.Add(new TypedValue((int)LispDataType.ListEnd)); return res; } // Signature: (KD-RANGE handle centerPoint radius) [LispFunction("KD-RANGE")] public static ResultBuffer RangeSearch(ResultBuffer args) { if (args == null) return null; List<TypedValue> values = ExtractValues(args); if (values.Count < 3) return null; if (values[0].TypeCode != (int)LispDataType.Text) return null; string handle = Convert.ToString(values[0].Value); if (!_trees.ContainsKey(handle)) return null; KdTree tree = _trees[handle]; Point3d center; if (values[1].TypeCode == (int)LispDataType.Point3d) center = (Point3d)values[1].Value; else if (values[1].TypeCode == (int)LispDataType.Point2d) center = new Point3d(((Point2d)values[1].Value).X, ((Point2d)values[1].Value).Y, 0.0); else return null; double radius = 0.0; TypedValue rVal = values[2]; if (rVal.TypeCode == (int)LispDataType.Double || rVal.TypeCode == (int)LispDataType.Int16 || rVal.TypeCode == (int)LispDataType.Int32) { radius = Convert.ToDouble(rVal.Value); } else { return null; } List<NeighborResult> results = tree.RangeSearch(center, radius); if (results.Count == 0) return null; ResultBuffer res = new ResultBuffer(); res.Add(new TypedValue((int)LispDataType.ListBegin)); foreach (NeighborResult item in results) { res.Add(new TypedValue((int)LispDataType.Point3d, item.Node.Point)); } res.Add(new TypedValue((int)LispDataType.ListEnd)); return res; } // Signature: (KD-FREE [handle]) [LispFunction("KD-FREE")] public static TypedValue FreeTree(ResultBuffer args) { if (args == null) { int count = _trees.Count; _trees.Clear(); return new TypedValue((int)LispDataType.Int32, count); } List<TypedValue> values = ExtractValues(args); if (values.Count == 0 || values[0].TypeCode != (int)LispDataType.Text) { int count = _trees.Count; _trees.Clear(); return new TypedValue((int)LispDataType.Int32, count); } string handle = Convert.ToString(values[0].Value); bool removed = _trees.Remove(handle); return new TypedValue((int)LispDataType.Int32, removed ? 1 : 0); } private static List<TypedValue> ExtractValues(ResultBuffer resbuf) { List<TypedValue> list = new List<TypedValue>(); foreach (TypedValue tv in resbuf.AsArray()) { if (tv.TypeCode != (int)LispDataType.ListBegin && tv.TypeCode != (int)LispDataType.ListEnd) { list.Add(tv); } } return list; } } } ymg KDtreeLisp.cs Build.bat2 points
-
all you would need to do is edit the bat file to point at the target platform. AI says you can jut create a project file next to the .cs, then use “dotnet build -c Release” <Project Sdk="Microsoft.NET.Sdk"> <PropertyGroup> <!-- Use net48 for AutoCAD 2021-2024, or net8.0-windows for AutoCAD 2025+ --> <TargetFramework>net8.0-windows</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> <Platforms>x64</Platforms> </PropertyGroup> <!-- Reference your AutoCAD libraries --> <ItemGroup> <Reference Include="AcCoreMgd"> <HintPath>C:\Program Files\Autodesk\AutoCAD 2017\AcCoreMgd.dll</HintPath> <Private>False</Private> <!-- Prevents copying AutoCAD DLLs to your output folder --> </Reference> <Reference Include="AcDbMgd"> <HintPath>C:\Program Files\Autodesk\AutoCAD 2017\AcDbMgd.dll</HintPath> <Private>False</Private> </Reference> <Reference Include="AcMgd"> <HintPath>C:\Program Files\Autodesk\AutoCAD 2017\AcMgd.dll</HintPath> <Private>False</Private> </Reference> </ItemGroup> </Project>2 points
-
2 points
-
I don't know if there was ever another LISP/Program to do this type of get length at least I never found one, my original just did what I needed, I have since made it more generally useful (I hope). As per the drawing I will attach, I just need to get the length of the center between the inner and outer of the perimeter of guards, etc. to determine the unrolled length. Normally the guards are 3D and I create the profiles with SOLPROF which creates an anonymous block (I used to change these with UNANON) or sometimes in the past I have used SOLVIEW and SOLDRAW, the same issue arises that you just can't select them and get the profile length. So originally that's what this LISP was created to do (I still have some of the older basic versions). I have upgraded it to it's current state and also still working on another version, but only small enhancements. For inside a block that is scaled, you will need to multiply the results by the scale factor, working through a viewport the viewport needs to be active, so I might tackle those issues as well as make a more detailed CSV. I also will try to make sure it works in non-AutoCAD like BricsCAD, CMS IntelliCAD, nanoCAD, etc. when I get time. I lightly tested in most situations, I have no idea how it acts on non-uniformly scaled blocks, though. It handles gaps and slight overlaps, I have some settings at the top, hopefully with enough instructions to modify on your own. Where I work (except for the machine shop which uses decimal inches) they use Architectural units, I did not double check this in Metric, so if someone would report back on that it would help. GetLenTest.dwg GetLen.lsp1 point
-
1 point
-
Nice! I used Nanoflann for the python wrappers, Ge.Point2dTree, Ge.Point3dTree https://github.com/jlblancoc/nanoflann it builds the tree multi-threaded. Nanoflann can be made dynamic in that it can add or remove points, though I didn’t add that in to the python wrappers. I also created a wrapper for AutoLISP here https://github.com/CEXT-Dan/ads_geo Wrappers are limited though, in C++ you can create a payload I.e. { Point Data } Otherwise, you have to create a hashmap to link the point with the payload. A professional C# version might use an interface for X,Y,Z, so you can expand the tree to allow any class or structure that has the proper interface1 point
-
I am kind of a Green Horn when it comes to compiling. I don't even have vstudio. So I still use the legacy csc compiler. On top of that i only have access to acad 2017, so I am not aware of what would be needed to compile it for more recent version of Autocad.1 point
-
Yes outputting results as both may be the simplest way. Re make a dcl, I use say multi radio buttons.lsp as it only needs 3 lines of code to work, you comment out the vla-deletefile, so the dcl code remains, I then use the RLX convert dcl to lisp so paste the converted code into my programs, using the multi just saves typing to make the source dcl. Just another comment, I have a make a radio button dcl from a dwg. RLX was looking into doing similar. I have code also for Libreoffice Calc reading and writing plus more. Happy to post. Opening is not as straight forward as Excel. Where are the grand kids ? I am north of Sydney. Convert dcl 2 lisp rlx.lsp1 point
-
There can be a lot more to it than that. "A closed boundary could not be determined" when creating a hatch in AutoCAD It actually says for one option- "Zoom out until all boundaries are visible. Then specify a new pick point", but I have actually had to zoom way in. "Valid hatch boundary not found." when adding Hatches in AutoCAD Products Also AutoCAD has an issue sometimes Select Object works, even though you should be able to use Pick points. This is about Boundary, but affects Hatches as well... Read the entire thread. Also, you can read this thread, though also boundary related. So basically the issue, besides the obvious gaps, elevations, et al, is summed up by @eldon1 point
-
@SLW210 did a little bit of testing and works ok in Metric dwt. The only thing is the Architectural result. Limited Testing in Bricscad V25. made some shapes and inserted some blocks. A rectang 5000x4000 mm or decimal units. For metric don't need Architectural units. Curve length: 18000 Gaps: 0 Total: 18000 Architectural: 1500'-0" ?? For metric could do dwg is in mm but result is in metres to 3 decimals. You could use the Multi radio buttons.lsp to make choices. As its demand loaded you do not have to add it to your code. Re CSV your more than welcome to use the defuns in Alan Excel.lsp to write direct to Excel. Could demand load a lisp with just the defuns needed as don't need all that is in the lisp. Just a Ps a big file to screen copy maybe also post a file copy.1 point
-
I moved your thread to the AutoCAD 3D Modelling & Rendering Forum. Please start threads in the most appropriate forum.1 point
-
Google AI... (defun C:BBOX ( / ss index ent vlaObj minPt maxPt minExt maxExt pt1 pt2 ) (vl-load-com) (princ "\nSelect objects to enclose in a bounding box: ") ;; Prompt user to select objects (if (setq ss (ssget)) (progn (setq index 0) ;; Loop through all selected objects (repeat (sslength ss) (setq ent (ssname ss index)) (setq vlaObj (vlax-ename->vla-object ent)) ;; Safely catch objects that do not support a bounding box (if (not (vl-catch-all-error-p (vl-catch-all-apply 'vla-getboundingbox (list vlaObj 'minPt 'maxPt)))) (progn (setq pt1 (vlax-safearray->list minPt) pt2 (vlax-safearray->list maxPt)) ;; Initialize or update the overall minimum and maximum coordinates (if (not minExt) (setq minExt pt1 maxExt pt2) (setq minExt (mapcar 'min pt1 minExt) maxExt (mapcar 'max pt2 maxExt)) ) ) ) (setq index (1+ index)) ) ;; Draw the bounding box if valid coordinates were collected (if (and minExt maxExt) (progn ;; Deactivate Object Snap temporarily to ensure precision (setq oldOsmode (getvar "OSMODE")) (setvar "OSMODE" 0) ;; Draw a standard rectangle using the global coordinates (command "_.rectangle" minExt maxExt) ;; Restore original Object Snap settings (setvar "OSMODE" oldOsmode) (princ "\nBounding box successfully created!") ) (princ "\nError: Could not calculate bounding box for selected objects.") ) ) (princ "\nNo objects selected.") ) (princ) ) (princ "\nType BBOX to run the command.") (princ)1 point
-
Provided you have made custom sheet sizes in the PLOT dialog. There is no reason why you can not have a title block or rectangle that is used to define the sheet size. Wether it be PDF or plot direct to roll plotter. Using layouts is best as the overall size will be at 1:1 eg 297x2010. Basically the custom size must exist, There was a post about making custom sheet sizes on the fly but very difficult to achieve. Me like a lot of others here can read the layouts and plot, there is plenty of examples of plot lisp's.1 point
-
Always use a company DWT and problem does not occur.1 point
-
YIL (yesterday I learned) there's a Python interpreter in ArcGIS. It's just a shell, but if you want to dip your toe in the water, it will let you run some code. When I have some time, I'll take it for a spin and report back.1 point
-
As previously stated, used an install lisp, only a few minutes.1 point
