All Activity
- Past hour
-
I have this almost finished, but currently have a separate DCL for it, looks to work very well for all units and recognizes the drawing units for Metric, Imperial by using Insertunits. I'll try to post next week, Tuesday or Wednesday if I get a chance to get it like I want it. I need to look into the option for MS Excel and LibreOffice Calc vs CSV I may or may not bother. So far... ;;; ============================================================ ;;; GetLen.lsp ;;; PROFILE / CENTERLINE LENGTH ;;; ;;; VERSION: 2026-09-03 ;;; ;;; Supports: ;;; LINE ;;; ARC ;;; CIRCLE ;;; LWPOLYLINE ;;; POLYLINE ;;; SPLINE ;;; ELLIPSE ;;; ;;; If PELLIPSE=1: ;;; Heavy Polyline (a.k.a. Old Style or 2D Polylines) made from bulged VERTEX records. ;;; These can be converted with CONVERTPOLY command, I chose to work with the Heavy Polylines. ;;; ;;; Supports: ;;; - Model Space ;;; - Paper Space ;;; - Blocks ;;; - Nested blocks ;;; - Anonymous/dynamic blocks (*U...) ;;; - Uniform block scaling ;;; - Single profile ;;; - Two-profile average / centerline ;;; - Batch (Sends output to CSV for perimeters of multiple selected entities.) ;;; - Screen output ;;; - CSV output ;;; - Multiple output unit formats ;;; * Metric - Millimeters ;;; * Metric - Meters ;;; * Architectural - Feet/Inches ;;; * Imperial - Fractional Inches ;;; * Imperial - Decimal Feet ;;; * Imperial - Decimal Inches ;;; - Automatic drawing-unit detection from INSUNITS ;;; - Endpoint tolerance ;;; - Optional gap measurement
-
I'm pretty sure that's something that AutoCAD cannot do out of the box. You posted this in the AutoCAD 3D Modelling & Rendering Forum, were intending to post in the AutoLISP, Visual LISP & DCL Forum?
- Today
-
lsp Free LISP to clean up and shrink heavy DWG files (DWGCLEAN)
SLW210 replied to Engineer Atlas's topic in AutoLISP, Visual LISP & DCL
Those methods only address a small portion of what can cause file bloat, it's a good start, but sometimes more needs to be done to truly clean up a drawing. In the other thread you posted in, there are other methods to clean drawings mentioned. As always, thanks for posting your version, I am sure many will find it useful. -
VicoWang started following Free LISP to clean up and shrink heavy DWG files (DWGCLEAN)
-
lsp Free LISP to clean up and shrink heavy DWG files (DWGCLEAN)
VicoWang replied to Engineer Atlas's topic in AutoLISP, Visual LISP & DCL
Welcome You can try distributing plugins using the VedaCAD method, which supports LSP, FAS, VLX, ARX, and DLL format plugins. There's no need to configure paths or copy code anymore; on the user side, a 6-digit VCID = a certain plugin function, and it is directly available. -
PDF Plot Shaded Visual Style = Sawtooth Edge
SLW210 replied to lamensterms's topic in AutoCAD Drawing Management & Output
What are the differences in the computers? Graphics Card and/or drivers? Are those images of the PDFs? AutoCAD 2014? Did you try the default DWGtoPDF? -
This will be a flat array which looks like a 3d. Essentially a number of lines/splines.
-
Are these 3D objects of some type? Splines? 3D Polylines?
-
lsp Free LISP to clean up and shrink heavy DWG files (DWGCLEAN)
SLW210 replied to Engineer Atlas's topic in AutoLISP, Visual LISP & DCL
I have moved your thread to the AutoLISP, Visual LISP & DCL Forum. Welcome to CADTutor! -
Why does my 3D solid look correct but fail when I try to UNION it?
indiancad posted a topic in AutoCAD 3D Modelling & Rendering
Have you ever had two 3D solids that look connected, but UNION does not combine them? One common reason is that the solids are only touching at an edge or face, rather than overlapping. A simple check is to move one solid slightly and use INTERFERE to see whether the two solids actually occupy the same space. If they need to become one solid, make sure they have a proper intersection and then run UNION again. How many of you have faced this problem? What was stopping the solids from joining? -
Why does my block move to the wrong place when I insert it?
indiancad replied to indiancad's topic in AutoCAD 2D Drafting, Object Properties & Interface
That’s a fair point. A base point being far from the block isn’t always wrong; it depends on how the block is meant to be used. I was referring to cases where the base point was set incorrectly. Thanks for pointing that out. -
Cleaning up the file
Engineer Atlas replied to Discus84's topic in AutoCAD 2D Drafting, Object Properties & Interface
Hello I follow this workflow to reduce the size of dwg files. Type -PURGE, choose Regapps, enter * for all, No to "verify each" Type -PURGE, choose All, * , No. Run this 3 or 4 times so nested blocks and styles clear out Type AUDIT, answer Yes to fix any errors Type WBLOCK, select the entire drawing, and save it to a new file name. Open that new file and check it Hope this helps. Open for discussion You can also use OVERKILL after step 3 if you feel like, to delete duplicate lines. -
Engineer Atlas started following Free LISP to clean up and shrink heavy DWG files (DWGCLEAN)
-
lsp Free LISP to clean up and shrink heavy DWG files (DWGCLEAN)
Engineer Atlas posted a topic in AutoLISP, Visual LISP & DCL
Hi all, I kept running into drawings that had ballooned to tens of MB, slow to open and painful to share. So I put together a small routine, DWGCLEAN, that runs the full cleanup in one command. Sharing it here in case it saves someone else the hassle. What it does, in order: Purges orphaned RegApp records (the hidden junk third-party and exported objects leave behind) Runs a full PURGE several times, to catch nested items that only become purgeable after their parent is gone Runs AUDIT with fix, to repair database errors WBLOCKs the whole drawing into a fresh file, which is the step that actually rebuilds and shrinks it It writes a new file with a _clean suffix and never touches your original. It also prints the before/after size and the percent saved when it finishes. Here is the code: (vl-load-com) ;; ---- helper: bytes -> whole-KB string ------------------------------------ (defun ea:kb (bytes) (itoa (fix (/ (float bytes) 1024.0)))) (defun c:DWGCLEAN ( / *error* old-cmdecho old-filedia old-expert src-dir src-name src-path base target n pass size-before size-after saved pct ) ;; ---- error handler: always restore system variables -------------------- (defun *error* (msg) (if old-cmdecho (setvar "CMDECHO" old-cmdecho)) (if old-filedia (setvar "FILEDIA" old-filedia)) (if old-expert (setvar "EXPERT" old-expert)) (if (and msg (not (member msg '("Function cancelled" "quit / exit abort")))) (princ (strcat "\nDWGCLEAN error: " msg))) (princ) ) ;; ---- make sure the drawing is saved to disk ---------------------------- (setq src-dir (getvar "DWGPREFIX") src-name (getvar "DWGNAME")) (setq src-path (strcat src-dir src-name)) (if (or (= src-dir "") (not (wcmatch (strcase src-name) "*.DWG")) (not (findfile src-path))) (progn (princ "\n*** Save the drawing to a folder first, then run DWGCLEAN again. ***") (exit)) ) (setq size-before (vl-file-size src-path)) ;; ---- save current sysvars, then set a clean automation state ----------- (setq old-cmdecho (getvar "CMDECHO") old-filedia (getvar "FILEDIA") old-expert (getvar "EXPERT")) (setvar "CMDECHO" 0) (setvar "FILEDIA" 0) (setvar "EXPERT" 5) ; suppress overwrite / confirmation prompts (princ "\n================ Engineer Atlas :: DWGCLEAN ================") ;; ---- STEP 1: remove RegApps ------------------------------------------- (princ "\n[1/4] Removing RegApps ...") (command "_.-PURGE" "_Regapps" "*" "_No") ;; ---- STEP 2: purge all unused, several passes for nested items -------- (princ "\n[2/4] Purging unused layers, blocks, linetypes, styles ...") (setq pass 0) (while (< pass 4) (command "_.-PURGE" "_All" "*" "_No") (setq pass (1+ pass))) ;; ---- STEP 3: audit and fix -------------------------------------------- (princ "\n[3/4] Auditing and fixing database errors ...") (command "_.AUDIT" "_Yes") ;; ---- STEP 4: WBLOCK the entire drawing into a fresh file --------------- (setq base (vl-filename-base src-path)) (setq target (strcat src-dir base "_clean.dwg")) (setq n 1) (while (findfile target) ; never overwrite an existing file (setq target (strcat src-dir base "_clean_" (itoa n) ".dwg")) (setq n (1+ n))) (princ (strcat "\n[4/4] Writing clean file: " (vl-filename-base target) ".dwg ...")) (command "_.-WBLOCK" target "*") ;; ---- restore sysvars --------------------------------------------------- (setvar "CMDECHO" old-cmdecho) (setvar "FILEDIA" old-filedia) (setvar "EXPERT" old-expert) ;; ---- report before / after -------------------------------------------- (setq size-after (if (findfile target) (vl-file-size target) nil)) (princ "\n-----------------------------------------------------------") (if (and size-before size-after (> size-before 0)) (progn (setq saved (- size-before size-after)) (setq pct (fix (* 100.0 (/ (float saved) size-before)))) (princ (strcat "\nOriginal : " (ea:kb size-before) " KB")) (princ (strcat "\nCleaned : " (ea:kb size-after) " KB")) (princ (strcat "\nSaved : " (ea:kb saved) " KB (" (itoa pct) "%)"))) (princ "\nClean file written.")) (princ (strcat "\nNew file : " target)) (princ "\nOpen the *_clean.dwg and verify it before replacing your original.") (princ) ) (princ "\nDWGCLEAN loaded. Type DWGCLEAN to reduce your DWG file size. (Engineer Atlas)") (princ) Load it with APPLOAD (or drag it into the drawing), then type DWGCLEAN. I have also attached the file if you would rather load the file directly, since forum copy-paste sometimes mangles the formatting. If you would rather do it by hand without the LISP, here is the same workflow manually: Type -PURGE, choose Regapps, enter * for all, No to "verify each" Type -PURGE, choose All, * , No. Run this 3 or 4 times so nested blocks and styles clear out Type AUDIT, answer Yes to fix any errors Type WBLOCK, select the entire drawing, and save it to a new file name. Open that new file and check it One safety note: always work on a copy of anything important, and open the _clean file to verify it before you replace the original. The routine is deliberately non-destructive (no OVERKILL, no xref detach, no exploding of objects), so it will not alter your geometry. Hope it is useful. Feedback welcome if anyone spots an edge case. DWGCLEAN.lsp -
Engineer Atlas joined the community -
RDU joined the community
-
VicoWang started following [LISP plugin] Smart Break-a tool for quickly breaking line objects
-
[LISP plugin] Smart Break-a tool for quickly breaking line objects
VicoWang posted a topic in AutoLISP, Visual LISP & DCL
A smarter break command for Line, Polyline, Circle, Arc, Ellipse, and Spline objects. Supports both single-point and two-point break operations. PS: This is a super simple feature requirement from a real beginner user, so it's also shared. Installation method (upgradable in the future): [Smart Break] VCID: D86938 @ VedaCAD Note: To install via VCID, you need to install VedaCAD in advance and log in to a free account (or PRO account). Tips: Welcome developers to publish their plugins on VedaCAD and obtain their plugin's VCID for plugin sharing (even free accounts can publish) Smart Break.mov -
lamensterms started following PDF Plot Shaded Visual Style = Sawtooth Edge
-
PDF Plot Shaded Visual Style = Sawtooth Edge
lamensterms posted a topic in AutoCAD Drawing Management & Output
Hey Got a small issue with some PDFs I am plotting on one of my ACAD PCs. I am plotting PDFs with Shaded visual style and one machine plots OK and the other has some sawtooth effect on the edges. Just wondering if anyone knows what setting or variable I can adjust to improve. It's not FACETRES, I have tried that a few times and not much improvement. it's almost as if it's JPEG compression or something. You can see image below the WORK PC has slightly better results Plot settings are the same for both machines, PC3 settings are the same for both machines -
Why does my block move to the wrong place when I insert it?
Paul Li replied to indiancad's topic in AutoCAD 2D Drafting, Object Properties & Interface
I would also like to add that users should first set UCS to World, then PLAN to World and then set BASE. -
Paul Li changed their profile photo
-
birdpeace23 joined the community
- Yesterday
-
Dimensioning in paper space
Discus84 replied to Discus84's topic in AutoCAD 2D Drafting, Object Properties & Interface
I used to only work in model space and I would never have switched possibly if not for the new office that uses paper space templates.. I see only one advantage of this : publishing automatically all selected pages at once vs plot windows from model space. -
Back in the early 90s I had this letter size digitizer tablet by Calcomp called the WIZ. I was able to reduce the typical 12x12 AutoCAD digitizer tablet menu and map it on. Major advantages of this over the typical larger tablets being sold at the time was it's a lot smaller and light weight and cost less too. But after AutoCAD dropped support for DOS and went all out with running on Windows, Calcomp also dropped support for the WIZ and I had to give it up to go with a mouse. I actually wrote about this awhile back in an article I called "What Happened To The Digitizer?"
-
dcl Share the most elegant interface design under DCL limitations
Paul Li replied to VicoWang's topic in AutoLISP, Visual LISP & DCL
Not sure if this is considered elegant but sure takes advantage of the number of image tiles that can be spread onto a giant custom dialog to preview slide files. This is a screen capture of SMV (SMVslide) which is one of the commands included in my free Script Magician App:- 1 reply
-
- 1
-
-
I wish Autodesk would add the following features to DCL: 1) Expand and Shrink the size of custom dialog boxes 2) Floating dialog while command line is active 3) Horizontal slide bar to list box 4) Edit box that supports multiple lines of Text 5) Image tile & image button tile to support not only sld but also typical raster file types like jpg, png, bmp, dwg 6) A select file dialog box that supports dwg/txt/jpg/png/bmp file thumbnail previews 7) A multiple file selection, window style looking getfiled dialog box (which currently can be done using PowerShell)
-
Dimensioning in paper space
CyberAngel replied to Discus84's topic in AutoCAD 2D Drafting, Object Properties & Interface
I've never dimensioned in paper space. Too many things to go wrong. Also dimensions are weird, it's like they wanted to please everybody but wound up disappointing everybody. -
LainiStudio3D joined the community
-
ymg3 started following Simplifying Polyline With Visvalingham-Whyatt Method + Zhou - Jones Effective Weight Area.
-
Here's another Net app to facilitate the simplification of polyline with lots of segments. I am including the code and a bat file to compile it for Autocad 2017. Once you've compiled VWSimplifyInteractive.cs into VWSimplifyInteractive.dll, Netload it into autocad. New comand VWSimplifyInteractive will now be available to trhe command line or Autolisp. If you run the command you will be asked to select a polyline. The selected poly will be copied in Magenta,then a dialog box with 3 sliders will appear to let you vary the parameter of the simplification. The polyline is simplified in real-time and you can adjust the parameters until you Accept or Cancel. Note that your original polyline remains untouched and that the simplified one is place on layer "Simplified Poly" with color Green. once you press Accept. Here's the C# code: // VWSimplifyInteractive.cs // Interactive Visvalingam + Zhou-Jones for AutoCAD 2017 using System; using System.Collections.Generic; using System.Drawing; using System.Windows.Forms; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Geometry; using Autodesk.AutoCAD.Runtime; using AcApp = Autodesk.AutoCAD.ApplicationServices.Application; [assembly: CommandClass(typeof(VWSimplify.InteractiveCommands))] namespace VWSimplify { public class InteractiveCommands { [CommandMethod("VWSimplifyInteractive", CommandFlags.Modal | CommandFlags.Session)] public void Run() { Document doc = AcApp.DocumentManager.MdiActiveDocument; if (doc == null) return; Editor ed = doc.Editor; PromptEntityOptions peo = new PromptEntityOptions("\nSelect polyline to simplify: "); peo.SetRejectMessage("\nOnly LWPOLYLINE allowed."); peo.AddAllowedClass(typeof(Polyline), true); PromptEntityResult per = ed.GetEntity(peo); if (per.Status != PromptStatus.OK) return; ObjectId srcId = per.ObjectId; // Create and show the modeless form var form = new SimplifyForm(srcId); AcApp.ShowModelessDialog(form); } } public class SimplifyForm : Form { private ObjectId _srcId; private ObjectId _previewId = ObjectId.Null; private TrackBar tbPercent; private CheckBox chkFlat, chkSkew, chkConv; private TrackBar tbFlat, tbSkew, tbConv; private Label lblPercent, lblVertices, lblFlat, lblSkew, lblConv; private Button btnAccept, btnCancel; // Current parameters private double _percent = 15.0; private bool _useFlat = true; private bool _useSkew = false; private bool _useConv = true; private double _flatStrength = 1.5; // reasonable start private double _skewStrength = 1.0; private double _convStrength = 2.5; // reasonable start public SimplifyForm(ObjectId srcId) { _srcId = srcId; InitializeComponent(); this.Shown += SimplifyForm_Shown; } private void SimplifyForm_Shown(object sender, EventArgs e) { UpdatePreview(); // First preview once form is displayed } private void InitializeComponent() { this.Text = "VW Simplify – Interactive"; this.Size = new Size(380, 445); this.FormBorderStyle = FormBorderStyle.FixedDialog; this.MaximizeBox = false; this.StartPosition = FormStartPosition.CenterScreen; int y = 15; // Percentage lblPercent = new Label() { Left = 15, Top = y, Width = 330, Text = "Target Ratio: 15%" }; tbPercent = new TrackBar() { Left = 15, Top = y + 20, Width = 330, Minimum = 1, Maximum = 100, Value = 15, TickFrequency = 5 }; tbPercent.ValueChanged += (s, e) => { _percent = tbPercent.Value; lblPercent.Text = "Target Ratio: " + _percent + "%"; UpdatePreview(); }; y += 65; // Vertex Counter Label lblVertices = new Label() { Left = 15, Top = y, Width = 330, Text = "Vertices: Original: - | Current: - (-%)", ForeColor = Color.DarkBlue }; y += 25; // Flatness chkFlat = new CheckBox() { Left = 15, Top = y, Text = "Use Flatness weight", Checked = true, Width = 200 }; chkFlat.CheckedChanged += (s, e) => { _useFlat = chkFlat.Checked; tbFlat.Enabled = _useFlat; UpdatePreview(); }; y += 25; lblFlat = new Label() { Left = 30, Top = y, Width = 300, Text = "Flatness strength: 1.5" }; tbFlat = new TrackBar() { Left = 30, Top = y + 20, Width = 300, Minimum = 10, Maximum = 40, Value = 15, // 1.0 – 4.0 TickFrequency = 5 }; tbFlat.ValueChanged += (s, e) => { _flatStrength = tbFlat.Value / 10.0; lblFlat.Text = "Flatness strength: " + _flatStrength.ToString("0.0"); UpdatePreview(); }; y += 65; // Skewness chkSkew = new CheckBox() { Left = 15, Top = y, Text = "Use Skewness weight", Checked = false, Width = 200 }; chkSkew.CheckedChanged += (s, e) => { _useSkew = chkSkew.Checked; tbSkew.Enabled = _useSkew; UpdatePreview(); }; y += 25; lblSkew = new Label() { Left = 30, Top = y, Width = 300, Text = "Skewness strength: 1.0" }; tbSkew = new TrackBar() { Left = 30, Top = y + 20, Width = 300, Minimum = 10, Maximum = 30, Value = 10, Enabled = false }; tbSkew.ValueChanged += (s, e) => { _skewStrength = tbSkew.Value / 10.0; lblSkew.Text = "Skewness strength: " + _skewStrength.ToString("0.0"); UpdatePreview(); }; y += 65; // Convexity chkConv = new CheckBox() { Left = 15, Top = y, Text = "Use Convexity weight", Checked = true, Width = 200 }; chkConv.CheckedChanged += (s, e) => { _useConv = chkConv.Checked; tbConv.Enabled = _useConv; UpdatePreview(); }; y += 25; lblConv = new Label() { Left = 30, Top = y, Width = 300, Text = "Convexity strength: 2.5" }; tbConv = new TrackBar() { Left = 30, Top = y + 20, Width = 300, Minimum = 10, Maximum = 50, Value = 25, // 1.0 – 5.0 TickFrequency = 5 }; tbConv.ValueChanged += (s, e) => { _convStrength = tbConv.Value / 10.0; lblConv.Text = "Convexity strength: " + _convStrength.ToString("0.0"); UpdatePreview(); }; y += 70; // Buttons btnAccept = new Button() { Text = "Accept", Left = 80, Top = y, Width = 90 }; btnCancel = new Button() { Text = "Cancel", Left = 190, Top = y, Width = 90 }; btnAccept.Click += BtnAccept_Click; btnCancel.Click += BtnCancel_Click; this.Controls.AddRange(new Control[] { lblPercent, tbPercent, lblVertices, chkFlat, lblFlat, tbFlat, chkSkew, lblSkew, tbSkew, chkConv, lblConv, tbConv, btnAccept, btnCancel }); this.FormClosing += (s, e) => CleanupPreview(false); } private void UpdatePreview() { Document doc = AcApp.DocumentManager.MdiActiveDocument; if (doc == null) return; int originalCount = 0; int simplifiedCount = 0; using (DocumentLock dl = doc.LockDocument()) using (Transaction tr = doc.TransactionManager.StartTransaction()) { Polyline src = tr.GetObject(_srcId, OpenMode.ForRead) as Polyline; if (src == null) { tr.Commit(); return; } originalCount = src.NumberOfVertices; List<Point2d> simplified = Simplify(src, _percent, _useFlat, _useSkew, _useConv, _flatStrength, _skewStrength, _convStrength); if (simplified == null || simplified.Count < 2) { tr.Commit(); return; } simplifiedCount = simplified.Count; BlockTableRecord btr = (BlockTableRecord)tr.GetObject(doc.Database.CurrentSpaceId, OpenMode.ForWrite); // Erase old preview polyline if it exists if (!_previewId.IsNull && !_previewId.IsErased) { DBObject oldObj = tr.GetObject(_previewId, OpenMode.ForWrite, false); if (oldObj != null) { oldObj.Erase(); } _previewId = ObjectId.Null; } // Construct new polyline Polyline preview = new Polyline(); for (int i = 0; i < simplified.Count; i++) { preview.AddVertexAt(i, simplified[i], 0, 0, 0); } preview.Closed = src.Closed && simplified.Count >= 3; preview.ColorIndex = 6; // Magenta preview.ConstantWidth = 0; btr.AppendEntity(preview); tr.AddNewlyCreatedDBObject(preview, true); _previewId = preview.ObjectId; tr.Commit(); } // Update UI vertex stats if (originalCount > 0) { double reduction = 100.0 * (1.0 - ((double)simplifiedCount / originalCount)); lblVertices.Text = string.Format("Vertices: Original: {0} | Current: {1} ({2:0.0}% reduced)", originalCount, simplifiedCount, reduction); } AcApp.DocumentManager.MdiActiveDocument.Editor.Regen(); } private void BtnAccept_Click(object sender, EventArgs e) { Document doc = AcApp.DocumentManager.MdiActiveDocument; if (doc == null) return; using (DocumentLock dl = doc.LockDocument()) using (Transaction tr = doc.TransactionManager.StartTransaction()) { if (!_previewId.IsNull && !_previewId.IsErased) { Polyline preview = tr.GetObject(_previewId, OpenMode.ForWrite) as Polyline; if (preview != null) { // Ensure layer exists LayerTable lt = (LayerTable)tr.GetObject(doc.Database.LayerTableId, OpenMode.ForRead); ObjectId layerId; if (!lt.Has("Simplified Poly")) { lt.UpgradeOpen(); LayerTableRecord ltr = new LayerTableRecord(); ltr.Name = "Simplified Poly"; ltr.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex( Autodesk.AutoCAD.Colors.ColorMethod.ByAci, 3); // green layerId = lt.Add(ltr); tr.AddNewlyCreatedDBObject(ltr, true); } else layerId = lt["Simplified Poly"]; preview.LayerId = layerId; preview.Color = Autodesk.AutoCAD.Colors.Color.FromColorIndex( Autodesk.AutoCAD.Colors.ColorMethod.ByLayer, 256); // Add XData with parameters AddXData(preview, tr, doc.Database); _previewId = ObjectId.Null; // prevent cleanup from erasing it } } tr.Commit(); } this.Close(); } private void BtnCancel_Click(object sender, EventArgs e) { CleanupPreview(true); this.Close(); } private void CleanupPreview(bool erase) { if (_previewId.IsNull || _previewId.IsErased) return; Document doc = AcApp.DocumentManager.MdiActiveDocument; if (doc == null) return; using (DocumentLock dl = doc.LockDocument()) using (Transaction tr = doc.TransactionManager.StartTransaction()) { if (erase) { DBObject obj = tr.GetObject(_previewId, OpenMode.ForWrite, false); if (obj != null) obj.Erase(); } tr.Commit(); } _previewId = ObjectId.Null; } private void AddXData(Polyline pl, Transaction tr, Database db) { RegAppTable rat = (RegAppTable)tr.GetObject(db.RegAppTableId, OpenMode.ForRead); if (!rat.Has("VW_SIMPLIFY")) { rat.UpgradeOpen(); RegAppTableRecord reg = new RegAppTableRecord(); reg.Name = "VW_SIMPLIFY"; rat.Add(reg); tr.AddNewlyCreatedDBObject(reg, true); } ResultBuffer rb = new ResultBuffer( new TypedValue(1001, "VW_SIMPLIFY"), new TypedValue(1000, "Visvalingam-ZhouJones"), new TypedValue(1040, _percent), new TypedValue(1071, _useFlat ? 1 : 0), new TypedValue(1040, _flatStrength), new TypedValue(1071, _useSkew ? 1 : 0), new TypedValue(1040, _skewStrength), new TypedValue(1071, _useConv ? 1 : 0), new TypedValue(1040, _convStrength) ); pl.XData = rb; } //-------------------------------------------------------------------- // Simplification core with Zhou-Jones weights //-------------------------------------------------------------------- private List<Point2d> Simplify(Polyline src, double percent, bool useFlat, bool useSkew, bool useConv, double flatStr, double skewStr, double convStr) { int n = src.NumberOfVertices; if (n < 3) return null; List<Point2d> pts = new List<Point2d>(n); for (int i = 0; i < n; i++) pts.Add(src.GetPoint2dAt(i)); bool closed = src.Closed; if (closed && !pts[0].IsEqualTo(pts[pts.Count - 1], new Tolerance(1e-10, 1e-10))) pts.Add(pts[0]); int target = (int)Math.Max(2, Math.Round(n * percent / 100.0)); if (closed) target = Math.Max(target, 3); return VisvalingamZhouJones(pts, target, useFlat, useSkew, useConv, flatStr, skewStr, convStr); } private List<Point2d> VisvalingamZhouJones(List<Point2d> pts, int target, bool useFlat, bool useSkew, bool useConv, double flatStr, double skewStr, double convStr) { int n = pts.Count; if (n <= target) return new List<Point2d>(pts); Point2d[] points = pts.ToArray(); double[] areas = new double[n]; bool[] alive = new bool[n]; int[] prev = new int[n]; int[] next = new int[n]; for (int i = 0; i < n; i++) { alive[i] = true; prev[i] = i - 1; next[i] = i + 1; areas[i] = double.MaxValue; } prev[0] = -1; next[n - 1] = -1; var heap = new SortedSet<HeapItem>(); for (int i = 1; i < n - 1; i++) { double a = WeightedArea(points, i, prev, next, useFlat, useSkew, useConv, flatStr, skewStr, convStr); areas[i] = a; heap.Add(new HeapItem(a, i)); } double lastArea = 0.0; int live = n; while (heap.Count > 0 && live > target) { HeapItem item = heap.Min; heap.Remove(item); int idx = item.Index; if (!alive[idx] || Math.Abs(item.Area - areas[idx]) > 1e-12) continue; double a = Math.Max(item.Area, lastArea); lastArea = a; areas[idx] = a; alive[idx] = false; live--; int p0 = prev[idx]; int p2 = next[idx]; if (p0 >= 0) next[p0] = p2; if (p2 >= 0) prev[p2] = p0; if (p0 >= 0 && alive[p0] && prev[p0] >= 0) { double na = WeightedArea(points, p0, prev, next, useFlat, useSkew, useConv, flatStr, skewStr, convStr); if (na < lastArea) na = lastArea; areas[p0] = na; heap.Add(new HeapItem(na, p0)); } if (p2 >= 0 && alive[p2] && next[p2] >= 0) { double na = WeightedArea(points, p2, prev, next, useFlat, useSkew, useConv, flatStr, skewStr, convStr); if (na < lastArea) na = lastArea; areas[p2] = na; heap.Add(new HeapItem(na, p2)); } } List<Point2d> res = new List<Point2d>(); for (int i = 0; i < n; i++) if (alive[i]) res.Add(points[i]); return res; } private double WeightedArea(Point2d[] pts, int i, int[] prev, int[] next, bool useFlat, bool useSkew, bool useConv, double flatStr, double skewStr, double convStr) { Point2d a = pts[prev[i]]; Point2d b = pts[i]; Point2d c = pts[next[i]]; double ea = TriangleArea(a, b, c); if (ea < 1e-20) return 0.0; double wFlat = 1.0, wSkew = 1.0, wConv = 1.0; // Base length and height double baseLen = a.GetDistanceTo(c); if (baseLen < 1e-12) return ea; // Height double area2 = Math.Abs((b.X - a.X) * (c.Y - a.Y) - (b.Y - a.Y) * (c.X - a.X)); double height = area2 / baseLen; // ---- Flatness ---- if (useFlat) { double ratio = height / baseLen; wFlat = Math.Pow(Math.Max(ratio, 1e-6), flatStr); } // ---- Skewness (prefer isosceles) ---- if (useSkew) { double d1 = a.GetDistanceTo(b); double d2 = b.GetDistanceTo(c); double maxd = Math.Max(d1, d2); double mind = Math.Min(d1, d2); double skewRatio = (maxd > 1e-12) ? mind / maxd : 1.0; wSkew = Math.Pow(skewRatio, skewStr); } // ---- Convexity ---- if (useConv) { // Cross product sign to determine turn direction double cross = (b.X - a.X) * (c.Y - a.Y) - (b.Y - a.Y) * (c.X - a.X); if (cross > 0) wConv = convStr; // boost convex else wConv = 1.0; // concave stays normal } return ea * wFlat * wSkew * wConv; } private double TriangleArea(Point2d a, Point2d b, Point2d c) { return 0.5 * Math.Abs(a.X * (b.Y - c.Y) + b.X * (c.Y - a.Y) + c.X * (a.Y - b.Y)); } private class HeapItem : IComparable<HeapItem> { public double Area; public int Index; public HeapItem(double area, int index) { Area = area; Index = index; } public int CompareTo(HeapItem other) { int cmp = Area.CompareTo(other.Area); return cmp != 0 ? cmp : Index.CompareTo(other.Index); } } } } Bat file to compile for Acad 2017, From a powershell prompt issue: .\Build VWSimplifyInteractive @echo off if "%~1"=="" ( echo Error: No source file specified. echo Usage: build.bat SourceFileName exit /b 1 ) :: 1. Define Compiler and Directory Paths set CSC="C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe" set NETFRAMEWORK=C:\Windows\Microsoft.NET\Framework64\v4.0.30319 set NETWPF=C:\Windows\Microsoft.NET\Framework64\v4.0.30319\WPF set ACAD=C:\Program Files\Autodesk\AutoCAD 2017 :: 2. Search Paths for /lib set LIBPATHS=/lib:"%NETFRAMEWORK%","%NETWPF%","%ACAD%" :: 3. Standard & Core .NET Assemblies set SYS_REFS=/r:System.dll /r:System.Core.dll /r:System.Data.dll /r:System.Drawing.dll /r:System.Xml.dll /r:System.Xml.Linq.dll :: 4. WPF, UI, & Windows Interop Assemblies set UI_REFS=/r:WindowsBase.dll /r:PresentationCore.dll /r:PresentationFramework.dll /r:System.Xaml.dll /r:System.Windows.Forms.dll :: 5. AutoCAD Assemblies set ACAD_REFS=/r:AcCoreMgd.dll /r:AcDbMgd.dll /r:AcMgd.dll :: 6. Optional Third-Party/Local DLLs in current folder set LOCAL_REFS= if exist "*.dll" ( set LOCAL_REFS=/lib:"%CD%" ) :: Execute Compilation %CSC% /target:library /platform:x64 /out:"%~1.dll" %LIBPATHS% %LOCAL_REFS% %SYS_REFS% %UI_REFS% %ACAD_REFS% "%~1.cs" if %ERRORLEVEL% equ 0 ( echo. echo Successfully built %~1.dll ) else ( echo. echo Compilation failed. ) VWSimplifyInteractive.cs Build.bat-
- 2
-
-
Dimensioning in paper space
Discus84 posted a topic in AutoCAD 2D Drafting, Object Properties & Interface
Hi, I always annotate in model space-it complicates changes to the model as there is more objects to encapsulate in stretch frames. What is more effective - model or paperspace dimesioning -keeping annotations away from the model.? -
Why does a 3D object sometimes rotate in the wrong direction?
indiancad posted a topic in AutoCAD 3D Modelling & Rendering
Have you ever selected a 3D object, used 3DROTATE, and found that it rotates around an unexpected axis? This can happen when the UCS is not aligned with the object. In 3D work, the UCS controls the direction of the X, Y, and Z axes. A simple fix is to use UCS → Face and select the face you want to work on. You can then use 3DROTATE or other 3D commands with the correct orientation. I’ve found this much easier than trying to guess which axis to rotate around. How many of you have had a 3D object rotate in the wrong direction? What was your fix? -
I'd like to be able to create this effect but specify min/max distance between lines. Any ideas appreciated. Thanks!
-
Why does my block move to the wrong place when I insert it?
CyberAngel replied to indiancad's topic in AutoCAD 2D Drafting, Object Properties & Interface
Not sure how it happens, but some blocks seem to have insertion points at the origin or just some random point. Something to do with the way they were defined, I suppose. One problem is, many of these blocks define a location. They are useless if the insertion point isn't at a specific coordinate, such as the nut on a fire hydrant, which is where you typically measure from. Another problem is, if you want to locate them properly, you may not be able to redefine them with the right point and then move them all at once. A block that's been rotated, for instance, will not go where you want it to. Once again, we see what happens when you come across a problem and don't fix it as soon as possible; it just causes more problems.
