├── .gitignore
├── AutoCADCommands.sln
├── AutoCADCommands
├── Algorithms.cs
├── App.cs
├── AutoCADCommands.R18.csproj
├── AutoCADCommands.R19.csproj
├── AutoCADCommands.csproj
├── AutoCADCommands.ruleset
├── Commands.cs
├── DbHelper.cs
├── FlexDataStore.cs
├── GUIs
│ ├── DictionaryViewer.xaml
│ ├── DictionaryViewer.xaml.cs
│ ├── InputBox.xaml
│ ├── InputBox.xaml.cs
│ ├── MultiInputs.xaml
│ ├── MultiInputs.xaml.cs
│ ├── TaskProgressWindow.xaml
│ ├── TaskProgressWindow.xaml.cs
│ ├── TextReport.xaml
│ └── TextReport.xaml.cs
├── Gui.cs
├── Interaction.cs
├── Internal
│ ├── CustomDictionary.cs
│ └── JigDrag.cs
├── Layouts.cs
├── Properties
│ └── AssemblyInfo.cs
├── QuickSelection.cs
├── SymbolPack.cs
├── Test.cs
├── Tuples.cs
└── packages.config
├── LICENSE
├── README.md
└── Reference
└── AutoCAD
├── r18
├── AcCui.dll
├── AcCui.xml
├── AcTcMgd.dll
├── AcWindows.dll
├── AdWindows.dll
├── acdbmgd.dll
├── acdbmgd.xml
├── acmgd.dll
└── acmgd.xml
└── r19
├── AcCoreMgd.dll
├── AcCui.dll
├── AcDbMgd.dll
├── AcMgd.dll
├── AcTcMgd.dll
├── AcWindows.dll
└── AdWindows.dll
/.gitignore:
--------------------------------------------------------------------------------
1 | ## Ignore Visual Studio temporary files, build results, and
2 | ## files generated by popular Visual Studio add-ons.
3 |
4 | # User-specific files
5 | *.suo
6 | *.user
7 | *.userosscache
8 | *.sln.docstates
9 |
10 | # User-specific files (MonoDevelop/Xamarin Studio)
11 | *.userprefs
12 |
13 | # Build results
14 | [Dd]ebug/
15 | [Dd]ebugPublic/
16 | [Rr]elease/
17 | [Rr]eleases/
18 | x64/
19 | x86/
20 | bld/
21 | [Bb]in/
22 | [Oo]bj/
23 | [Ll]og/
24 |
25 | # Visual Studio 2015 cache/options directory
26 | .vs/
27 | # Uncomment if you have tasks that create the project's static files in wwwroot
28 | #wwwroot/
29 |
30 | # MSTest test Results
31 | [Tt]est[Rr]esult*/
32 | [Bb]uild[Ll]og.*
33 |
34 | # NUNIT
35 | *.VisualState.xml
36 | TestResult.xml
37 |
38 | # Build Results of an ATL Project
39 | [Dd]ebugPS/
40 | [Rr]eleasePS/
41 | dlldata.c
42 |
43 | # DNX
44 | project.lock.json
45 | artifacts/
46 |
47 | *_i.c
48 | *_p.c
49 | *_i.h
50 | *.ilk
51 | *.meta
52 | *.obj
53 | *.pch
54 | *.pdb
55 | *.pgc
56 | *.pgd
57 | *.rsp
58 | *.sbr
59 | *.tlb
60 | *.tli
61 | *.tlh
62 | *.tmp
63 | *.tmp_proj
64 | *.log
65 | *.vspscc
66 | *.vssscc
67 | .builds
68 | *.pidb
69 | *.svclog
70 | *.scc
71 |
72 | # Chutzpah Test files
73 | _Chutzpah*
74 |
75 | # Visual C++ cache files
76 | ipch/
77 | *.aps
78 | *.ncb
79 | *.opendb
80 | *.opensdf
81 | *.sdf
82 | *.cachefile
83 | *.VC.db
84 | *.VC.VC.opendb
85 |
86 | # Visual Studio profiler
87 | *.psess
88 | *.vsp
89 | *.vspx
90 | *.sap
91 |
92 | # TFS 2012 Local Workspace
93 | $tf/
94 |
95 | # Guidance Automation Toolkit
96 | *.gpState
97 |
98 | # ReSharper is a .NET coding add-in
99 | _ReSharper*/
100 | *.[Rr]e[Ss]harper
101 | *.DotSettings.user
102 |
103 | # JustCode is a .NET coding add-in
104 | .JustCode
105 |
106 | # TeamCity is a build add-in
107 | _TeamCity*
108 |
109 | # DotCover is a Code Coverage Tool
110 | *.dotCover
111 |
112 | # NCrunch
113 | _NCrunch_*
114 | .*crunch*.local.xml
115 | nCrunchTemp_*
116 |
117 | # MightyMoose
118 | *.mm.*
119 | AutoTest.Net/
120 |
121 | # Web workbench (sass)
122 | .sass-cache/
123 |
124 | # Installshield output folder
125 | [Ee]xpress/
126 |
127 | # DocProject is a documentation generator add-in
128 | DocProject/buildhelp/
129 | DocProject/Help/*.HxT
130 | DocProject/Help/*.HxC
131 | DocProject/Help/*.hhc
132 | DocProject/Help/*.hhk
133 | DocProject/Help/*.hhp
134 | DocProject/Help/Html2
135 | DocProject/Help/html
136 |
137 | # Click-Once directory
138 | publish/
139 |
140 | # Publish Web Output
141 | *.[Pp]ublish.xml
142 | *.azurePubxml
143 | # TODO: Comment the next line if you want to checkin your web deploy settings
144 | # but database connection strings (with potential passwords) will be unencrypted
145 | *.pubxml
146 | *.publishproj
147 |
148 | # Microsoft Azure Web App publish settings. Comment the next line if you want to
149 | # checkin your Azure Web App publish settings, but sensitive information contained
150 | # in these scripts will be unencrypted
151 | PublishScripts/
152 |
153 | # NuGet Packages
154 | *.nupkg
155 | # The packages folder can be ignored because of Package Restore
156 | **/packages/*
157 | # except build/, which is used as an MSBuild target.
158 | !**/packages/build/
159 | # Uncomment if necessary however generally it will be regenerated when needed
160 | #!**/packages/repositories.config
161 | # NuGet v3's project.json files produces more ignoreable files
162 | *.nuget.props
163 | *.nuget.targets
164 |
165 | # Microsoft Azure Build Output
166 | csx/
167 | *.build.csdef
168 |
169 | # Microsoft Azure Emulator
170 | ecf/
171 | rcf/
172 |
173 | # Windows Store app package directories and files
174 | AppPackages/
175 | BundleArtifacts/
176 | Package.StoreAssociation.xml
177 | _pkginfo.txt
178 |
179 | # Visual Studio cache files
180 | # files ending in .cache can be ignored
181 | *.[Cc]ache
182 | # but keep track of directories ending in .cache
183 | !*.[Cc]ache/
184 |
185 | # Others
186 | ClientBin/
187 | ~$*
188 | *~
189 | *.dbmdl
190 | *.dbproj.schemaview
191 | *.pfx
192 | *.publishsettings
193 | node_modules/
194 | orleans.codegen.cs
195 |
196 | # Since there are multiple workflows, uncomment next line to ignore bower_components
197 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
198 | #bower_components/
199 |
200 | # RIA/Silverlight projects
201 | Generated_Code/
202 |
203 | # Backup & report files from converting an old project file
204 | # to a newer Visual Studio version. Backup files are not needed,
205 | # because we have git ;-)
206 | _UpgradeReport_Files/
207 | Backup*/
208 | UpgradeLog*.XML
209 | UpgradeLog*.htm
210 |
211 | # SQL Server files
212 | *.mdf
213 | *.ldf
214 |
215 | # Business Intelligence projects
216 | *.rdl.data
217 | *.bim.layout
218 | *.bim_*.settings
219 |
220 | # Microsoft Fakes
221 | FakesAssemblies/
222 |
223 | # GhostDoc plugin setting file
224 | *.GhostDoc.xml
225 |
226 | # Node.js Tools for Visual Studio
227 | .ntvs_analysis.dat
228 |
229 | # Visual Studio 6 build log
230 | *.plg
231 |
232 | # Visual Studio 6 workspace options file
233 | *.opt
234 |
235 | # Visual Studio LightSwitch build output
236 | **/*.HTMLClient/GeneratedArtifacts
237 | **/*.DesktopClient/GeneratedArtifacts
238 | **/*.DesktopClient/ModelManifest.xml
239 | **/*.Server/GeneratedArtifacts
240 | **/*.Server/ModelManifest.xml
241 | _Pvt_Extensions
242 |
243 | # Paket dependency manager
244 | .paket/paket.exe
245 | paket-files/
246 |
247 | # FAKE - F# Make
248 | .fake/
249 |
250 | # JetBrains Rider
251 | .idea/
252 | *.sln.iml
253 |
--------------------------------------------------------------------------------
/AutoCADCommands.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28307.572
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoCADCommands", "AutoCADCommands\AutoCADCommands.csproj", "{C5F6C326-952B-43E8-9830-311F190BAB11}"
7 | EndProject
8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoCADCommands.R18", "AutoCADCommands\AutoCADCommands.R18.csproj", "{EDA1D1A6-3204-4B82-8D5F-4F59815F072E}"
9 | EndProject
10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AutoCADCommands.R19", "AutoCADCommands\AutoCADCommands.R19.csproj", "{77B9F8FE-F75B-48C8-8249-6859E8D347E1}"
11 | EndProject
12 | Global
13 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
14 | Debug|Any CPU = Debug|Any CPU
15 | Release|Any CPU = Release|Any CPU
16 | EndGlobalSection
17 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
18 | {C5F6C326-952B-43E8-9830-311F190BAB11}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
19 | {C5F6C326-952B-43E8-9830-311F190BAB11}.Debug|Any CPU.Build.0 = Debug|Any CPU
20 | {C5F6C326-952B-43E8-9830-311F190BAB11}.Release|Any CPU.ActiveCfg = Release|Any CPU
21 | {C5F6C326-952B-43E8-9830-311F190BAB11}.Release|Any CPU.Build.0 = Release|Any CPU
22 | {EDA1D1A6-3204-4B82-8D5F-4F59815F072E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
23 | {EDA1D1A6-3204-4B82-8D5F-4F59815F072E}.Debug|Any CPU.Build.0 = Debug|Any CPU
24 | {EDA1D1A6-3204-4B82-8D5F-4F59815F072E}.Release|Any CPU.ActiveCfg = Release|Any CPU
25 | {EDA1D1A6-3204-4B82-8D5F-4F59815F072E}.Release|Any CPU.Build.0 = Release|Any CPU
26 | {77B9F8FE-F75B-48C8-8249-6859E8D347E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
27 | {77B9F8FE-F75B-48C8-8249-6859E8D347E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
28 | {77B9F8FE-F75B-48C8-8249-6859E8D347E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
29 | {77B9F8FE-F75B-48C8-8249-6859E8D347E1}.Release|Any CPU.Build.0 = Release|Any CPU
30 | EndGlobalSection
31 | GlobalSection(SolutionProperties) = preSolution
32 | HideSolutionNode = FALSE
33 | EndGlobalSection
34 | GlobalSection(ExtensibilityGlobals) = postSolution
35 | SolutionGuid = {9516FD57-86E1-498D-BC03-D6EFC30A7DE6}
36 | EndGlobalSection
37 | EndGlobal
38 |
--------------------------------------------------------------------------------
/AutoCADCommands/App.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.AutoCAD.ApplicationServices;
2 | using Autodesk.AutoCAD.DatabaseServices;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.IO;
6 | using System.Linq;
7 | using System.Text;
8 | using System.Reflection;
9 | using System.Runtime.InteropServices;
10 |
11 | namespace Dreambuild.AutoCAD
12 | {
13 | ///
14 | /// Application and multi-docs.
15 | ///
16 | public static class App
17 | {
18 | ///
19 | /// Gets the current folder.
20 | ///
21 | public static string CurrentFolder
22 | {
23 | get
24 | {
25 | string s = Assembly.GetCallingAssembly().Location;
26 | return s.Remove(s.LastIndexOf('\\') + 1);
27 | }
28 | }
29 |
30 | ///
31 | /// Gets the document folder.
32 | ///
33 | public static string DocumentFolder
34 | {
35 | get
36 | {
37 | string s = Application.DocumentManager.MdiActiveDocument.Name;
38 | if (s.Contains(':'))
39 | {
40 | return s.Remove(s.LastIndexOf('\\') + 1);
41 | }
42 | else
43 | {
44 | return string.Empty;
45 | }
46 | }
47 | }
48 |
49 | ///
50 | /// Loads another assembly.
51 | ///
52 | /// The assembly file name (relative path).
53 | public static void LoadDll(string dllName)
54 | {
55 | try
56 | {
57 | Assembly.LoadFrom(Path.Combine(App.CurrentFolder, dllName));
58 | }
59 | catch
60 | {
61 | }
62 | }
63 |
64 | #region multi doc
65 |
66 | ///
67 | /// Determines if a document is newly created.
68 | ///
69 | /// The document.
70 | /// The result.
71 | public static bool IsDocumentNew(Document doc = null) // newly 20140730
72 | {
73 | return !App.IsDocumentSaved(doc ?? Application.DocumentManager.MdiActiveDocument);
74 | }
75 |
76 | ///
77 | /// Determines if a document is saved.
78 | ///
79 | /// The document.
80 | /// The result.
81 | public static bool IsDocumentSaved(Document doc = null) // newly 20140730
82 | {
83 | doc = doc ?? Application.DocumentManager.MdiActiveDocument;
84 | return doc.Name != null && doc.Name.Contains(":");
85 | }
86 |
87 | private static IEnumerable GetAllOpenedDocInternal()
88 | {
89 | foreach (Document doc in Application.DocumentManager)
90 | {
91 | yield return doc;
92 | }
93 | }
94 |
95 | ///
96 | /// Gets all opened documents.
97 | ///
98 | /// All opened documents.
99 | public static List GetAllOpenedDocuments()
100 | {
101 | return App.GetAllOpenedDocInternal().ToList();
102 | }
103 |
104 | ///
105 | /// Locks the current document and do things.
106 | ///
107 | /// The things to do.
108 | public static void LockAndExecute(Action action)
109 | {
110 | using (var doclock = Application.DocumentManager.MdiActiveDocument.LockDocument())
111 | {
112 | action();
113 | }
114 | }
115 |
116 | ///
117 | /// Locks a specified document and do things.
118 | ///
119 | /// The document to lock.
120 | /// Then things to do.
121 | public static void LockAndExecute(Document doc, Action action)
122 | {
123 | using (var doclock = doc.LockDocument())
124 | {
125 | action();
126 | }
127 | }
128 |
129 | ///
130 | /// Locks the current document and do things.
131 | ///
132 | /// The type of the return value.
133 | /// The things to do.
134 | /// The value returned by the action.
135 | public static T LockAndExecute(Func function)
136 | {
137 | using (var doclock = Application.DocumentManager.MdiActiveDocument.LockDocument())
138 | {
139 | return function();
140 | }
141 | }
142 |
143 | ///
144 | /// Sets the active document.
145 | ///
146 | /// The document to be set as active.
147 | public static void SetActiveDocument(Document doc)
148 | {
149 | Application.DocumentManager.MdiActiveDocument = doc;
150 | HostApplicationServices.WorkingDatabase = doc.Database;
151 | }
152 |
153 | ///
154 | /// Sets the working database.
155 | ///
156 | /// The database to be set as the working database.
157 | public static void SetWorkingDatabase(Database db)
158 | {
159 | HostApplicationServices.WorkingDatabase = db;
160 | }
161 |
162 | ///
163 | /// Opens a file as a document.
164 | ///
165 | /// The file name.
166 | /// The opened document.
167 | public static Document OpenDocument(string file)
168 | {
169 | return Application.DocumentManager.Open(file, false);
170 | }
171 |
172 | ///
173 | /// Opens or activates a file as a document.
174 | ///
175 | /// The file name.
176 | /// The opened document.
177 | public static Document OpenOrActivateDocument(string file)
178 | {
179 | var doc = App.FindOpenedDocument(file);
180 | if (doc != null)
181 | {
182 | App.SetActiveDocument(doc);
183 | return doc;
184 | }
185 |
186 | return App.OpenDocument(file);
187 | }
188 |
189 | ///
190 | /// Finds an opened document by file name.
191 | ///
192 | /// The file name.
193 | /// The document found.
194 | public static Document FindOpenedDocument(string file)
195 | {
196 | return Application.DocumentManager
197 | .Cast()
198 | .FirstOrDefault(document => document.Name == file);
199 | }
200 |
201 | #endregion
202 | }
203 |
204 | ///
205 | /// The polyline needs cleanup exception.
206 | ///
207 | public class PolylineNeedsCleanupException : Exception
208 | {
209 | ///
210 | /// Initializes a new instance of the exception.
211 | ///
212 | public PolylineNeedsCleanupException()
213 | {
214 | }
215 |
216 | ///
217 | /// Initializes a new instance of the exception.
218 | ///
219 | /// The message.
220 | public PolylineNeedsCleanupException(string message) : base(message)
221 | {
222 | }
223 |
224 | ///
225 | /// Initializes a new instance of the exception.
226 | ///
227 | /// The message.
228 | /// The inner exception.
229 | public PolylineNeedsCleanupException(string message, Exception innerException) : base(message, innerException)
230 | {
231 | }
232 |
233 | ///
234 | /// Shows a message dialog of this exception.
235 | ///
236 | public void ShowMessage()
237 | {
238 | Interaction.TaskDialog("Polyline needs a clean-up", "Go to clean it up.", "Go to clean it up.", "AutoCAD", "Please run `PolyClean`.");
239 | }
240 | }
241 |
242 | ///
243 | /// The log manager.
244 | ///
245 | public static class LogManager
246 | {
247 | ///
248 | /// The log file name.
249 | ///
250 | public const string LogFile = "C:\\AcadCodePack.log";
251 |
252 | ///
253 | /// Writes object to logs.
254 | ///
255 | /// The object.
256 | public static void Write(object o)
257 | {
258 | using (var sw = new StreamWriter(LogFile, append: true))
259 | {
260 | sw.WriteLine($"[{DateTime.Now.ToShortDateString()} {DateTime.Now.ToLongTimeString()}] {o}");
261 | }
262 | }
263 |
264 | ///
265 | /// Writes object to logs.
266 | ///
267 | /// The note.
268 | /// The object.
269 | public static void Write(string note, object o)
270 | {
271 | using (var sw = new StreamWriter(LogFile, append: true))
272 | {
273 | sw.WriteLine($"[{DateTime.Now.ToShortDateString()} {DateTime.Now.ToLongTimeString()}] {note}: {o}");
274 | }
275 | }
276 |
277 | ///
278 | /// Gets a time based name.
279 | ///
280 | /// The name.
281 | public static string GetTimeBasedName()
282 | {
283 | string timeString = DateTime.Now.ToShortDateString() + "-" + DateTime.Now.ToLongTimeString();
284 | return new string(timeString.Where(c => char.IsDigit(c)).ToArray());
285 | }
286 |
287 | ///
288 | /// The log table.
289 | ///
290 | public class LogTable
291 | {
292 | private readonly int[] _colWidths;
293 |
294 | ///
295 | /// The tab width.
296 | ///
297 | public const int TabWidth = 8;
298 |
299 | ///
300 | /// Initializes a new instance.
301 | ///
302 | /// The column widths. The values should be multiples of the tab width.
303 | public LogTable(params int[] colWidths)
304 | {
305 | _colWidths = colWidths;
306 | }
307 |
308 | ///
309 | /// Gets the string representation of a row.
310 | ///
311 | /// The contents.
312 | /// The result.
313 | public string GetRow(params object[] contents)
314 | {
315 | var sb = new StringBuilder();
316 | for (int i = 0; i < contents.Length; i++)
317 | {
318 | string content = contents[i].ToString();
319 | sb.Append(content);
320 | int nTab = (int)Math.Ceiling((double)(_colWidths[i] - GetStringWidth(content)) / TabWidth);
321 | for (int j = 0; j < nTab; j++)
322 | {
323 | sb.Append('\t');
324 | }
325 | }
326 | return sb.ToString();
327 | }
328 |
329 | ///
330 | /// Gets string width: ASCII as 1, others as 2.
331 | ///
332 | /// The string.
333 | /// The width.
334 | public static int GetStringWidth(string content)
335 | {
336 | return content.Sum(c => c > 255 ? 2 : 1);
337 | }
338 | }
339 | }
340 |
341 | ///
342 | /// ObjectARX C functions wrapper.
343 | ///
344 | public static class Arx
345 | {
346 | [DllImport("acad.exe", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl, EntryPoint = "acedCmd")]
347 | public static extern int acedCmd(IntPtr vlist);
348 |
349 | [DllImport("acad.exe", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl)]
350 | public static extern int ads_queueexpr(string strExpr);
351 |
352 | [DllImport("acad.exe", CharSet = CharSet.Auto, CallingConvention = CallingConvention.Cdecl, EntryPoint = "?acedPostCommand@@YAHPB_W@Z")]
353 | public static extern int acedPostCommand(string strExpr);
354 | }
355 | }
356 |
--------------------------------------------------------------------------------
/AutoCADCommands/AutoCADCommands.R18.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {EDA1D1A6-3204-4B82-8D5F-4F59815F072E}
9 | Library
10 | Properties
11 | AutoCADCommands
12 | AutoCADCommands
13 | v3.5
14 | 512
15 | true
16 |
17 |
18 | true
19 | full
20 | false
21 | ..\bin\r18\
22 | TRACE;DEBUG;R18
23 | prompt
24 | 4
25 | ..\bin\r18\AutoCADCommands.xml
26 | false
27 | AutoCADCommands.ruleset
28 | true
29 |
30 |
31 | pdbonly
32 | true
33 | ..\bin\Release\r18\
34 | TRACE;R18
35 | prompt
36 | 4
37 | false
38 | AutoCADCommands.ruleset
39 |
40 |
41 |
42 | ..\Reference\AutoCAD\r18\acdbmgd.dll
43 | False
44 |
45 |
46 | ..\Reference\AutoCAD\r18\acmgd.dll
47 | False
48 |
49 |
50 | ..\Reference\AutoCAD\r18\AdWindows.dll
51 | False
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 | DictionaryViewer.xaml
72 |
73 |
74 |
75 | InputBox.xaml
76 |
77 |
78 | TaskProgressWindow.xaml
79 |
80 |
81 |
82 |
83 |
84 | MultiInputs.xaml
85 |
86 |
87 |
88 |
89 |
90 |
91 | TextReport.xaml
92 |
93 |
94 |
95 |
96 |
97 | Designer
98 | MSBuild:Compile
99 |
100 |
101 | Designer
102 | MSBuild:Compile
103 |
104 |
105 | Designer
106 | MSBuild:Compile
107 |
108 |
109 | MSBuild:Compile
110 | Designer
111 |
112 |
113 | Designer
114 | MSBuild:Compile
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
129 |
--------------------------------------------------------------------------------
/AutoCADCommands/AutoCADCommands.R19.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {77B9F8FE-F75B-48C8-8249-6859E8D347E1}
9 | Library
10 | Properties
11 | AutoCADCommands
12 | AutoCADCommands
13 | v4.5
14 | 512
15 | true
16 |
17 |
18 | true
19 | full
20 | false
21 | ..\bin\r19\
22 | TRACE;DEBUG;R19
23 | prompt
24 | 4
25 | ..\bin\r19\AutoCADCommands.xml
26 | false
27 | AutoCADCommands.ruleset
28 | true
29 |
30 |
31 | pdbonly
32 | true
33 | ..\bin\Release\r19\
34 | TRACE;R19
35 | prompt
36 | 4
37 | false
38 | AutoCADCommands.ruleset
39 |
40 |
41 |
42 | ..\Reference\AutoCAD\r19\accoremgd.dll
43 | False
44 |
45 |
46 | ..\Reference\AutoCAD\r19\acdbmgd.dll
47 | False
48 |
49 |
50 | ..\Reference\AutoCAD\r19\acmgd.dll
51 | False
52 |
53 |
54 | ..\Reference\AutoCAD\r19\AdWindows.dll
55 | False
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 | DictionaryViewer.xaml
77 |
78 |
79 |
80 | InputBox.xaml
81 |
82 |
83 | TaskProgressWindow.xaml
84 |
85 |
86 |
87 |
88 |
89 | MultiInputs.xaml
90 |
91 |
92 |
93 |
94 |
95 |
96 | TextReport.xaml
97 |
98 |
99 |
100 |
101 | Designer
102 | MSBuild:Compile
103 |
104 |
105 | Designer
106 | MSBuild:Compile
107 |
108 |
109 | Designer
110 | MSBuild:Compile
111 |
112 |
113 | MSBuild:Compile
114 | Designer
115 |
116 |
117 | Designer
118 | MSBuild:Compile
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
133 |
--------------------------------------------------------------------------------
/AutoCADCommands/AutoCADCommands.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Debug
5 | AnyCPU
6 | 8.0.30703
7 | 2.0
8 | {C5F6C326-952B-43E8-9830-311F190BAB11}
9 | Library
10 | Properties
11 | AutoCADCommands
12 | AutoCADCommands
13 | v4.7.1
14 | 512
15 | true
16 |
17 |
18 | true
19 | full
20 | false
21 | ..\bin\r23\
22 | TRACE;DEBUG;R23
23 | prompt
24 | 4
25 | ..\bin\r23\AutoCADCommands.xml
26 | false
27 | AutoCADCommands.ruleset
28 | true
29 |
30 |
31 | pdbonly
32 | true
33 | ..\bin\Release\r23\
34 | TRACE;R23
35 | prompt
36 | 4
37 | false
38 | AutoCADCommands.ruleset
39 |
40 |
41 |
42 | ..\packages\AutoCAD.NET.Core.23.0.0\lib\net47\AcCoreMgd.dll
43 | False
44 |
45 |
46 | ..\packages\AutoCAD.NET.23.0.0\lib\net47\AcCui.dll
47 | False
48 |
49 |
50 | ..\packages\AutoCAD.NET.Model.23.0.0\lib\net47\AcDbMgd.dll
51 | False
52 |
53 |
54 | ..\packages\AutoCAD.NET.Model.23.0.0\lib\net47\acdbmgdbrep.dll
55 | False
56 |
57 |
58 | ..\packages\AutoCAD.NET.23.0.0\lib\net47\AcDx.dll
59 | False
60 |
61 |
62 | ..\packages\AutoCAD.NET.23.0.0\lib\net47\AcMgd.dll
63 | False
64 |
65 |
66 | ..\packages\AutoCAD.NET.23.0.0\lib\net47\AcMr.dll
67 | False
68 |
69 |
70 | ..\packages\AutoCAD.NET.23.0.0\lib\net47\AcSeamless.dll
71 | False
72 |
73 |
74 | ..\packages\AutoCAD.NET.23.0.0\lib\net47\AcTcMgd.dll
75 | False
76 |
77 |
78 | ..\packages\AutoCAD.NET.23.0.0\lib\net47\AcWindows.dll
79 | False
80 |
81 |
82 | ..\packages\AutoCAD.NET.23.0.0\lib\net47\AdUIMgd.dll
83 | False
84 |
85 |
86 | ..\packages\AutoCAD.NET.23.0.0\lib\net47\AdUiPalettes.dll
87 | False
88 |
89 |
90 | ..\packages\AutoCAD.NET.23.0.0\lib\net47\AdWindows.dll
91 | False
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 | DictionaryViewer.xaml
113 |
114 |
115 |
116 | InputBox.xaml
117 |
118 |
119 | TaskProgressWindow.xaml
120 |
121 |
122 |
123 |
124 |
125 | MultiInputs.xaml
126 |
127 |
128 |
129 |
130 |
131 |
132 | TextReport.xaml
133 |
134 |
135 |
136 |
137 | Designer
138 | MSBuild:Compile
139 |
140 |
141 | Designer
142 | MSBuild:Compile
143 |
144 |
145 | Designer
146 | MSBuild:Compile
147 |
148 |
149 | MSBuild:Compile
150 | Designer
151 |
152 |
153 | Designer
154 | MSBuild:Compile
155 |
156 |
157 |
158 |
159 |
160 |
161 |
162 |
169 |
--------------------------------------------------------------------------------
/AutoCADCommands/AutoCADCommands.ruleset:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 |
70 |
71 |
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 |
81 |
82 |
83 |
84 |
85 |
86 |
87 |
88 |
89 |
90 |
91 |
92 |
93 |
94 |
95 |
96 |
97 |
98 |
99 |
100 |
101 |
102 |
103 |
104 |
105 |
106 |
107 |
108 |
109 |
110 |
111 |
112 |
113 |
114 |
115 |
116 |
117 |
118 |
119 |
120 |
121 |
122 |
123 |
124 |
125 |
126 |
--------------------------------------------------------------------------------
/AutoCADCommands/DbHelper.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.AutoCAD.DatabaseServices;
2 | using Autodesk.AutoCAD.Geometry;
3 | using Dreambuild.AutoCAD.Internal;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 |
8 | namespace Dreambuild.AutoCAD
9 | {
10 | ///
11 | /// Database operation helpers.
12 | ///
13 | public static class DbHelper
14 | {
15 | #region symbol tables & dictionaries
16 |
17 | ///
18 | /// Gets all records of a symbol table.
19 | ///
20 | /// The symbol table ID.
21 | /// The record IDs.
22 | public static ObjectId[] GetSymbolTableRecords(ObjectId symbolTableId)
23 | {
24 | using (var trans = symbolTableId.Database.TransactionManager.StartTransaction())
25 | {
26 | var table = (SymbolTable)trans.GetObject(symbolTableId, OpenMode.ForRead);
27 | return table.Cast().ToArray();
28 | }
29 | }
30 |
31 | ///
32 | /// Gets all record names of a symbol table.
33 | ///
34 | /// The symbol table ID.
35 | /// The record names.
36 | public static string[] GetSymbolTableRecordNames(ObjectId symbolTableId)
37 | {
38 | return DbHelper
39 | .GetSymbolTableRecords(symbolTableId)
40 | .QOpenForRead()
41 | .Select(record => record.Name)
42 | .ToArray();
43 | }
44 |
45 | ///
46 | /// Gets a symbol table record by name.
47 | ///
48 | /// The symbol table ID.
49 | /// The record name.
50 | /// The default value if not found.
51 | /// The factory method if not found.
52 | /// The record ID.
53 | public static ObjectId GetSymbolTableRecord(ObjectId symbolTableId, string name, ObjectId? defaultValue = null, Func create = null)
54 | {
55 | using (var trans = symbolTableId.Database.TransactionManager.StartTransaction())
56 | {
57 | var table = (SymbolTable)trans.GetObject(symbolTableId, OpenMode.ForRead);
58 | if (table.Has(name))
59 | {
60 | return table[name];
61 | }
62 |
63 | if (create != null)
64 | {
65 | var record = create();
66 | table.UpgradeOpen();
67 | var result = table.Add(record);
68 | trans.AddNewlyCreatedDBObject(record, true);
69 | trans.Commit();
70 | return result;
71 | }
72 | }
73 |
74 | return defaultValue.Value;
75 | }
76 |
77 | ///
78 | /// Gets layer ID by name. Creates new if not found.
79 | ///
80 | /// The layer name.
81 | /// The database.
82 | /// The layer ID.
83 | public static ObjectId GetLayerId(string layerName, Database db = null)
84 | {
85 | return DbHelper.GetSymbolTableRecord(
86 | symbolTableId: (db ?? HostApplicationServices.WorkingDatabase).LayerTableId,
87 | name: layerName,
88 | create: () => new LayerTableRecord { Name = layerName });
89 | }
90 |
91 | ///
92 | /// Gets all layer IDs.
93 | ///
94 | /// The database.
95 | /// The layer IDs.
96 | public static ObjectId[] GetAllLayerIds(Database db = null)
97 | {
98 | return DbHelper.GetSymbolTableRecords((db ?? HostApplicationServices.WorkingDatabase).LayerTableId);
99 | }
100 |
101 | ///
102 | /// Gets all layer names.
103 | ///
104 | /// The database.
105 | /// The layer names.
106 | public static string[] GetAllLayerNames(Database db = null)
107 | {
108 | return DbHelper.GetSymbolTableRecordNames((db ?? HostApplicationServices.WorkingDatabase).LayerTableId);
109 | }
110 |
111 | ///
112 | /// Ensures a layer is visible.
113 | ///
114 | /// The layer name.
115 | public static void EnsureLayerOn(string layerName)
116 | {
117 | var id = DbHelper.GetLayerId(layerName);
118 | id.QOpenForWrite(layer =>
119 | {
120 | layer.IsFrozen = false;
121 | layer.IsHidden = false;
122 | layer.IsOff = false;
123 | });
124 | }
125 |
126 | ///
127 | /// Gets block table record ID by block name.
128 | ///
129 | /// The block name.
130 | /// The database.
131 | /// The block table ID.
132 | public static ObjectId GetBlockId(string blockName, Database db = null)
133 | {
134 | return DbHelper.GetSymbolTableRecord(
135 | symbolTableId: (db ?? HostApplicationServices.WorkingDatabase).BlockTableId,
136 | name: blockName,
137 | defaultValue: ObjectId.Null);
138 | }
139 |
140 | ///
141 | /// Gets all block table record IDs.
142 | ///
143 | /// The database.
144 | /// The object ID array.
145 | public static ObjectId[] GetAllBlockIds(Database db = null)
146 | {
147 | return DbHelper.GetSymbolTableRecords((db ?? HostApplicationServices.WorkingDatabase).BlockTableId);
148 | }
149 |
150 | ///
151 | /// Gets all block names.
152 | ///
153 | /// The database.
154 | /// The block name array.
155 | public static string[] GetAllBlockNames(Database db = null)
156 | {
157 | return DbHelper.GetSymbolTableRecordNames((db ?? HostApplicationServices.WorkingDatabase).BlockTableId);
158 | }
159 |
160 | ///
161 | /// Gets linetype ID by name. Returns the continuous linetype as default if not found.
162 | ///
163 | /// The linetype name.
164 | /// The database.
165 | /// The linetype ID.
166 | public static ObjectId GetLinetypeId(string linetypeName, Database db = null)
167 | {
168 | db = db ?? HostApplicationServices.WorkingDatabase;
169 | return DbHelper.GetSymbolTableRecord(
170 | symbolTableId: db.LinetypeTableId,
171 | name: linetypeName,
172 | defaultValue: db.ContinuousLinetype);
173 | }
174 |
175 | ///
176 | /// Gets text style ID by name. Returns the current TEXTSTYLE as default if not found.
177 | ///
178 | /// The text style name.
179 | /// Whether to create new if not found.
180 | /// The database.
181 | /// The text style ID.
182 | public static ObjectId GetTextStyleId(string textStyleName, bool createIfNotFound = false, Database db = null)
183 | {
184 | db = db ?? HostApplicationServices.WorkingDatabase;
185 | return DbHelper.GetSymbolTableRecord(
186 | symbolTableId: db.TextStyleTableId,
187 | name: textStyleName,
188 | create: () => new TextStyleTableRecord { Name = textStyleName },
189 | defaultValue: db.Textstyle);
190 | }
191 |
192 | ///
193 | /// Gets dimension style ID by name. Returns the current DIMSTYLE as default if not found.
194 | ///
195 | /// The dimension style name.
196 | /// The database.
197 | /// The dimension style ID.
198 | public static ObjectId GetDimstyleId(string dimStyleName, Database db = null)
199 | {
200 | db = db ?? HostApplicationServices.WorkingDatabase;
201 | return DbHelper.GetSymbolTableRecord(
202 | symbolTableId: db.DimStyleTableId,
203 | name: dimStyleName,
204 | defaultValue: db.Dimstyle);
205 | }
206 |
207 | ///
208 | /// Gets a dictionary object.
209 | ///
210 | /// The dictionary ID.
211 | /// The entry name.
212 | /// The default value if not found.
213 | /// The factory method if not found.
214 | /// The object ID.
215 | public static ObjectId GetDictionaryObject(ObjectId dictionaryId, string name, ObjectId? defaultValue = null, Func create = null)
216 | {
217 | using (var trans = dictionaryId.Database.TransactionManager.StartTransaction())
218 | {
219 | var dictionary = (DBDictionary)trans.GetObject(dictionaryId, OpenMode.ForRead);
220 | if (dictionary.Contains(name))
221 | {
222 | return dictionary.GetAt(name);
223 | }
224 |
225 | if (create != null)
226 | {
227 | var dictObject = create();
228 | dictionary.UpgradeOpen();
229 | var result = dictionary.SetAt(name, dictObject);
230 | trans.AddNewlyCreatedDBObject(dictObject, true);
231 | trans.Commit();
232 | return result;
233 | }
234 | }
235 |
236 | return defaultValue.Value;
237 | }
238 |
239 | ///
240 | /// Gets group ID by name.
241 | ///
242 | /// The group name.
243 | /// The database.
244 | /// The group ID.
245 | public static ObjectId GetGroupId(string groupName, Database db = null)
246 | {
247 | return DbHelper.GetDictionaryObject(
248 | dictionaryId: (db ?? HostApplicationServices.WorkingDatabase).GroupDictionaryId,
249 | name: groupName,
250 | defaultValue: ObjectId.Null);
251 | }
252 |
253 | ///
254 | /// Gets group ID by entity ID.
255 | ///
256 | /// The entity ID.
257 | /// The group ID.
258 | public static ObjectId GetGroupId(ObjectId entityId)
259 | {
260 | var groupDict = entityId.Database.GroupDictionaryId.QOpenForRead();
261 | var entity = entityId.QOpenForRead();
262 | try
263 | {
264 | return groupDict
265 | .Cast()
266 | .First(entry => entry.Value.QOpenForRead().Has(entity))
267 | .Value;
268 | }
269 | catch
270 | {
271 | return ObjectId.Null;
272 | }
273 | }
274 |
275 | ///
276 | /// Gets all entity IDs in a group.
277 | ///
278 | /// The group ID.
279 | /// The entity IDs.
280 | public static IEnumerable GetEntityIdsInGroup(ObjectId groupId)
281 | {
282 | var group = groupId.QOpenForRead();
283 | if (group != null)
284 | {
285 | return group.GetAllEntityIds();
286 | }
287 |
288 | return new ObjectId[0];
289 | }
290 |
291 | #endregion
292 |
293 | #region xdata
294 |
295 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
296 | public static string GetFirstXData(this DBObject dbo, string appName)
297 | {
298 | var xdataForApp = dbo.GetXDataForApplication(appName);
299 | if (xdataForApp == null)
300 | {
301 | return string.Empty;
302 | }
303 | foreach (var value in xdataForApp.AsArray())
304 | {
305 | if (value.TypeCode != (int)DxfCode.ExtendedDataRegAppName)
306 | {
307 | return value.Value.ToString();
308 | }
309 | }
310 | return string.Empty;
311 | }
312 |
313 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
314 | public static object GetFirstXDataT(this DBObject dbo, string appName)
315 | {
316 | var xdataForApp = dbo.GetXDataForApplication(appName);
317 | if (xdataForApp == null)
318 | {
319 | return null;
320 | }
321 | foreach (var value in xdataForApp.AsArray())
322 | {
323 | if (value.TypeCode != (int)DxfCode.ExtendedDataRegAppName)
324 | {
325 | return value.Value;
326 | }
327 | }
328 | return null;
329 | }
330 |
331 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
332 | public static void SetFirstXData(this DBObject dbo, string appName, string value)
333 | {
334 | dbo.XData = new ResultBuffer(new[]
335 | {
336 | new TypedValue((int)DxfCode.ExtendedDataRegAppName, appName),
337 | new TypedValue((int)DxfCode.ExtendedDataAsciiString, value)
338 | });
339 | }
340 |
341 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
342 | public static void SetFirstXDataT(this DBObject dbo, string appName, object value) // newly 20111207
343 | {
344 | var typeCode = value is Int16
345 | ? (int)DxfCode.ExtendedDataInteger16
346 | : value is Int32
347 | ? (int)DxfCode.ExtendedDataInteger32
348 | : value is Double
349 | ? (int)DxfCode.ExtendedDataReal
350 | : (int)DxfCode.ExtendedDataAsciiString;
351 |
352 | dbo.XData = new ResultBuffer(new[]
353 | {
354 | new TypedValue((int)DxfCode.ExtendedDataRegAppName, appName),
355 | new TypedValue(typeCode, value)
356 | });
357 | }
358 |
359 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
360 | public static string GetFirstXData(this ObjectId dboId, string appName)
361 | {
362 | return dboId.QOpenForRead().GetFirstXData(appName);
363 | }
364 |
365 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
366 | public static void SetFirstXData(this ObjectId dboId, string appName, string value)
367 | {
368 | dboId.QOpenForWrite(dbo => dbo.SetFirstXData(appName, value));
369 | }
370 |
371 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
372 | public static void SetFirstXDataT(this ObjectId dboId, string appName, object value) // newly 20111207
373 | {
374 | dboId.QOpenForWrite(dbo => dbo.SetFirstXDataT(appName, value));
375 | }
376 |
377 | ///
378 | /// Makes sure app names are registered.
379 | ///
380 | /// The app names.
381 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
382 | public static void AffirmRegApp(params string[] appNames) // newly 20130122
383 | {
384 | DbHelper.AffirmRegApp(HostApplicationServices.WorkingDatabase, appNames);
385 | }
386 |
387 | ///
388 | /// Makes sure app names are registered.
389 | ///
390 | /// The database to register to.
391 | /// The app names.
392 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
393 | public static void AffirmRegApp(Database db, params string[] appNames) // newly 20130122
394 | {
395 | using (var trans = db.TransactionManager.StartTransaction())
396 | {
397 | var table = trans.GetObject(db.RegAppTableId, OpenMode.ForRead) as RegAppTable;
398 | foreach (string appName in appNames)
399 | {
400 | if (!table.Has(appName))
401 | {
402 | table.UpgradeOpen();
403 | var record = new RegAppTableRecord
404 | {
405 | Name = appName
406 | };
407 | table.Add(record);
408 | trans.AddNewlyCreatedDBObject(record, true);
409 | }
410 | }
411 | trans.Commit();
412 | }
413 | }
414 |
415 | #endregion
416 |
417 | #region code
418 |
419 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
420 | public static void SetCode(this Entity entity, string code)
421 | {
422 | entity.XData = new ResultBuffer(new[]
423 | {
424 | new TypedValue((int)DxfCode.ExtendedDataRegAppName, Consts.AppNameForCode),
425 | new TypedValue((int)DxfCode.ExtendedDataAsciiString, code)
426 | });
427 | }
428 |
429 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
430 | public static void SetCode(this ObjectId entityId, string code)
431 | {
432 | using (var trans = entityId.Database.TransactionManager.StartTransaction())
433 | {
434 | var entity = (Entity)trans.GetObject(entityId, OpenMode.ForWrite);
435 | DbHelper.SetCode(entity, code);
436 | trans.Commit();
437 | }
438 | }
439 |
440 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
441 | public static string GetCode(this Entity entity)
442 | {
443 | var resBuf = entity.GetXDataForApplication(Consts.AppNameForCode);
444 | if (resBuf == null)
445 | {
446 | return null;
447 | }
448 | foreach (var tValue in resBuf.AsArray())
449 | {
450 | if (tValue.TypeCode == (int)DxfCode.ExtendedDataAsciiString)
451 | {
452 | return tValue.Value.ToString();
453 | }
454 | }
455 | return null;
456 | }
457 |
458 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
459 | public static string GetCode(this ObjectId entityId)
460 | {
461 | using (var trans = entityId.Database.TransactionManager.StartTransaction())
462 | {
463 | var entity = (Entity)trans.GetObject(entityId, OpenMode.ForRead);
464 | return DbHelper.GetCode(entity);
465 | }
466 | }
467 |
468 | #endregion
469 |
470 | #region block attribute
471 |
472 | ///
473 | /// Returns a dictionary of a block reference's block attribute names and ObjectIds.
474 | ///
475 | /// The block reference.
476 | /// The result.
477 | public static Dictionary GetBlockAttributeIds(this BlockReference blockReference)
478 | {
479 | var attrs = new Dictionary();
480 | foreach (ObjectId attrId in blockReference.AttributeCollection)
481 | {
482 | // if block reference is already write enabled, trying to OpenForRead will throw.
483 | if (blockReference.IsWriteEnabled)
484 | {
485 | attrId.QOpenForWrite(attr =>
486 | {
487 | attrs.Add(attr.Tag, attrId);
488 | });
489 | }
490 | else
491 | {
492 | var attr = attrId.QOpenForRead();
493 | attrs.Add(attr.Tag, attrId);
494 |
495 | }
496 | }
497 | return attrs;
498 | }
499 |
500 | ///
501 | /// Gets block attributes.
502 | ///
503 | /// The block reference.
504 | /// The result.
505 | public static Dictionary GetBlockAttributes(this BlockReference blockReference)
506 | {
507 | var attrs = new Dictionary();
508 | foreach (ObjectId attrId in blockReference.AttributeCollection)
509 | {
510 | // if block reference is already write enabled, trying to OpenForRead will throw.
511 | if (blockReference.IsWriteEnabled)
512 | {
513 | attrId.QOpenForWrite(attr =>
514 | {
515 | attrs.Add(attr.Tag, attr.TextString);
516 | });
517 | }
518 | else
519 | {
520 | var attr = attrId.QOpenForRead();
521 | attrs.Add(attr.Tag, attr.TextString);
522 | }
523 | }
524 | return attrs;
525 | }
526 |
527 | ///
528 | /// Get block attribute.
529 | ///
530 | /// The block reference.
531 | /// The tag.
532 | /// The value.
533 | public static string GetBlockAttribute(this BlockReference blockReference, string tag)
534 | {
535 | var attrs = DbHelper.GetBlockAttributes(blockReference);
536 | if (attrs.ContainsKey(tag))
537 | {
538 | return attrs[tag];
539 | }
540 |
541 | return null;
542 | }
543 |
544 | ///
545 | /// Defines a block attribute.
546 | ///
547 | /// The block name.
548 | /// The tag.
549 | /// The value.
550 | /// The prompt.
551 | /// The position.
552 | /// The style.
553 | public static void DefineBlockAttribute(string blockName, string tag, string value, string prompt, Point3d position, ObjectId style)
554 | {
555 | var ad = new AttributeDefinition(position, value, tag, prompt, style);
556 | using (var trans = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
557 | {
558 | var block = trans.GetObject(DbHelper.GetBlockId(blockName), OpenMode.ForWrite) as BlockTableRecord;
559 | block.AppendEntity(ad);
560 | trans.AddNewlyCreatedDBObject(ad, true);
561 | trans.Commit();
562 | }
563 | }
564 |
565 | ///
566 | /// Appends an attribute to a block reference. This extends the native AppendAttribute Method.
567 | ///
568 | /// The block reference.
569 | /// The attribute definition.
570 | /// Overwrite if the attribute already exists.
571 | /// Create the attribute if it doesn't already exist.
572 | public static void AppendAttribute(this BlockReference blockReference, AttributeReference attributeReference, bool overwrite = true, bool createIfMissing = true)
573 | {
574 | using (var trans = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
575 | {
576 | var attrs = blockReference.GetBlockAttributes();
577 | if (!attrs.ContainsKey(attributeReference.Tag))
578 | {
579 | if (createIfMissing)
580 | {
581 | blockReference.AttributeCollection.AppendAttribute(attributeReference);
582 | }
583 | }
584 | else
585 | {
586 | if (overwrite)
587 | {
588 | blockReference.AttributeCollection.AppendAttribute(attributeReference);
589 | }
590 | }
591 | trans.Commit();
592 | }
593 | }
594 |
595 | #endregion
596 |
597 | #region ezdata
598 |
599 | public static string GetData(this ObjectId id, string dict, string key)
600 | {
601 | return CustomObjectDictionary.GetValue(id, dict, key);
602 | }
603 |
604 | public static void SetData(this ObjectId id, string dict, string key, string value)
605 | {
606 | CustomObjectDictionary.SetValue(id, dict, key, value);
607 | }
608 |
609 | #endregion
610 |
611 | #region tags
612 |
613 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
614 | public static bool HasTag(this DBObject dbo, string tag)
615 | {
616 | var buffer = dbo.GetXDataForApplication(Consts.AppNameForTags);
617 | return buffer.AsArray().Any(typedValue => typedValue.TypeCode == (int)DxfCode.ExtendedDataAsciiString
618 | && typedValue.Value == tag);
619 | }
620 |
621 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
622 | public static bool HasTag(this ObjectId id, string tag)
623 | {
624 | using (var trans = id.Database.TransactionManager.StartTransaction())
625 | {
626 | var dbo = (DBObject)trans.GetObject(id, OpenMode.ForWrite);
627 | return DbHelper.HasTag(dbo, tag);
628 | }
629 | }
630 |
631 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
632 | public static void AddTag(this DBObject dbo, string tag)
633 | {
634 | var buffer = dbo.GetXDataForApplication(Consts.AppNameForTags);
635 | buffer.Add(new TypedValue((int)DxfCode.ExtendedDataAsciiString, tag));
636 | dbo.XData = buffer;
637 | }
638 |
639 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
640 | public static void AddTag(this ObjectId id, string tag)
641 | {
642 | using (var trans = id.Database.TransactionManager.StartTransaction())
643 | {
644 | var dbo = (DBObject)trans.GetObject(id, OpenMode.ForWrite);
645 | DbHelper.AddTag(dbo, tag);
646 | trans.Commit();
647 | }
648 | }
649 |
650 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
651 | public static void RemoveTag(this DBObject dbo, string tag)
652 | {
653 | var buffer = dbo.GetXDataForApplication(Consts.AppNameForTags);
654 | var data = buffer.AsArray().Where(typedValue => typedValue.TypeCode == (int)DxfCode.ExtendedDataAsciiString
655 | && typedValue.Value != tag).ToArray();
656 | dbo.XData = new ResultBuffer(data);
657 | }
658 |
659 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
660 | public static void RemoveTag(this ObjectId id, string tag)
661 | {
662 | using (var trans = id.Database.TransactionManager.StartTransaction())
663 | {
664 | var dbo = (DBObject)trans.GetObject(id, OpenMode.ForWrite);
665 | DbHelper.RemoveTag(dbo, tag);
666 | trans.Commit();
667 | }
668 | }
669 |
670 | #endregion
671 |
672 | ///
673 | /// Initializes the database.
674 | ///
675 | ///
676 | /// Call this at the launch of your app and each time you create new doc.
677 | ///
678 | [Obsolete("Legacy data store mechanism. Use FlexDataStore instead.")]
679 | public static void InitializeDatabase(Database db = null)
680 | {
681 | DbHelper.AffirmRegApp(db ?? HostApplicationServices.WorkingDatabase, new[]
682 | {
683 | Consts.AppNameForCode,
684 | Consts.AppNameForID,
685 | Consts.AppNameForName,
686 | Consts.AppNameForTags
687 | });
688 | }
689 |
690 | internal static Database GetDatabase(IEnumerable objectIds)
691 | {
692 | return objectIds.Select(id => id.Database).Distinct().Single();
693 | }
694 | }
695 | }
696 |
--------------------------------------------------------------------------------
/AutoCADCommands/FlexDataStore.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.AutoCAD.DatabaseServices;
2 | using System.Linq;
3 |
4 | namespace Dreambuild.AutoCAD
5 | {
6 | ///
7 | /// Flexible data store. FDS is our v3 data store mechanism. Old ways FXD (v1) and CD (v2) should be deprecated.
8 | ///
9 | public class FlexDataStore
10 | {
11 | private ObjectId DictionaryId { get; }
12 |
13 | internal FlexDataStore(ObjectId dictionaryId)
14 | {
15 | this.DictionaryId = dictionaryId;
16 | }
17 |
18 | ///
19 | /// Gets a value.
20 | ///
21 | /// The key.
22 | /// The value.
23 | public string GetValue(string key)
24 | {
25 | var dictionary = this.DictionaryId.QOpenForRead();
26 | if (dictionary.Contains(key))
27 | {
28 | var record = dictionary.GetAt(key).QOpenForRead();
29 | return record.Data.AsArray().First().Value.ToString();
30 | }
31 |
32 | return null;
33 | }
34 |
35 | ///
36 | /// Sets a value.
37 | ///
38 | /// The key.
39 | /// The value.
40 | /// The flex data store.
41 | public FlexDataStore SetValue(string key, string value)
42 | {
43 | using (var trans = this.DictionaryId.Database.TransactionManager.StartTransaction())
44 | {
45 | var dictionary = trans.GetObject(this.DictionaryId, OpenMode.ForWrite) as DBDictionary;
46 | if (dictionary.Contains(key))
47 | {
48 | trans.GetObject(dictionary.GetAt(key), OpenMode.ForWrite).Erase();
49 | }
50 |
51 | var record = new Xrecord
52 | {
53 | Data = new ResultBuffer(new TypedValue((int)DxfCode.ExtendedDataAsciiString, value))
54 | };
55 |
56 | dictionary.SetAt(key, record);
57 | trans.AddNewlyCreatedDBObject(record, true);
58 | trans.Commit();
59 | }
60 |
61 | return this;
62 | }
63 | }
64 |
65 | ///
66 | /// The flex data store extensions.
67 | ///
68 | public static class FlexDataStoreExtensions
69 | {
70 | internal const string DwgGlobalStoreName = "FlexDataStore";
71 |
72 | ///
73 | /// Gets the DWG global flex data store.
74 | ///
75 | /// The database.
76 | /// The flex data store.
77 | public static FlexDataStore FlexDataStore(this Database db)
78 | {
79 | using (var trans = db.TransactionManager.StartTransaction())
80 | {
81 | var namedObjectsDict = trans.GetObject(db.NamedObjectsDictionaryId, OpenMode.ForRead) as DBDictionary;
82 | if (!namedObjectsDict.Contains(FlexDataStoreExtensions.DwgGlobalStoreName))
83 | {
84 | namedObjectsDict.UpgradeOpen();
85 | var dwgGlobalStore = new DBDictionary();
86 | var storeId = namedObjectsDict.SetAt(FlexDataStoreExtensions.DwgGlobalStoreName, dwgGlobalStore);
87 | trans.AddNewlyCreatedDBObject(dwgGlobalStore, true);
88 | trans.Commit();
89 | return new FlexDataStore(storeId);
90 | }
91 |
92 | trans.Abort();
93 | return new FlexDataStore(namedObjectsDict.GetAt(FlexDataStoreExtensions.DwgGlobalStoreName));
94 | }
95 | }
96 |
97 | ///
98 | /// Gets an object's flex data store.
99 | ///
100 | /// The object ID.
101 | /// The flex data store.
102 | public static FlexDataStore FlexDataStore(this ObjectId id)
103 | {
104 | using (var trans = id.Database.TransactionManager.StartTransaction())
105 | {
106 | var dbo = trans.GetObject(id, OpenMode.ForRead);
107 | if (dbo.ExtensionDictionary == ObjectId.Null)
108 | {
109 | dbo.UpgradeOpen();
110 | dbo.CreateExtensionDictionary();
111 | trans.Commit();
112 | return new FlexDataStore(dbo.ExtensionDictionary);
113 | }
114 |
115 | trans.Abort();
116 | return new FlexDataStore(dbo.ExtensionDictionary);
117 | }
118 | }
119 | }
120 | }
121 |
--------------------------------------------------------------------------------
/AutoCADCommands/GUIs/DictionaryViewer.xaml:
--------------------------------------------------------------------------------
1 |
7 |
8 |
9 |
10 |
11 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
--------------------------------------------------------------------------------
/AutoCADCommands/GUIs/DictionaryViewer.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Windows;
6 | using System.Windows.Controls;
7 | using System.Windows.Data;
8 | using System.Windows.Documents;
9 | using System.Windows.Input;
10 | using System.Windows.Media;
11 | using System.Windows.Media.Imaging;
12 | using System.Windows.Navigation;
13 | using System.Windows.Shapes;
14 |
15 | namespace Dreambuild.AutoCAD
16 | {
17 | ///
18 | /// DictionaryViewer.xaml code behind.
19 | ///
20 | public partial class DictionaryViewer : Window
21 | {
22 | private readonly Func> _getDictNames;
23 | private readonly Func> _getEntryNames;
24 | private readonly Func _getValue;
25 | private readonly Action _setValue;
26 |
27 | public DictionaryViewer()
28 | {
29 | InitializeComponent();
30 | }
31 |
32 | public DictionaryViewer(
33 | Func> getDictNames,
34 | Func> getEntryNames,
35 | Func getValue,
36 | Action setValue)
37 | {
38 | InitializeComponent();
39 |
40 | _getDictNames = getDictNames;
41 | _getEntryNames = getEntryNames;
42 | _getValue = getValue;
43 | _setValue = setValue;
44 | }
45 |
46 | public void DictionaryViewer_Loaded(object sender, RoutedEventArgs e)
47 | {
48 | _getDictNames().ForEach(name => this.DictionaryList.Items.Add(name));
49 | this.DictionaryList.SelectedIndex = 0;
50 | }
51 |
52 | private void DictionaryList_SelectionChanged(object sender, SelectionChangedEventArgs e)
53 | {
54 | this.EntryList.Items.Clear();
55 | string dict = this.DictionaryList.SelectedItem.ToString();
56 | _getEntryNames(dict)
57 | .OrderBy(name => name)
58 | .Select(name => new
59 | {
60 | Key = name,
61 | Value = _getValue(dict, name)
62 | })
63 | .ForEach(entry => this.EntryList.Items.Add(entry));
64 | }
65 |
66 | private void EntryList_MouseDoubleClick(object sender, MouseButtonEventArgs e)
67 | {
68 | if (this.DictionaryList.SelectedIndex == -1 || this.EntryList.SelectedIndex == -1)
69 | {
70 | return;
71 | }
72 |
73 | string dict = this.DictionaryList.SelectedItem.ToString();
74 | string key = _getEntryNames(dict).OrderBy(name => name).ToList()[this.EntryList.SelectedIndex];
75 | string oldValue = _getValue(dict, key);
76 |
77 | var inputBox = new InputBox(oldValue)
78 | {
79 | Owner = this
80 | };
81 |
82 | if (inputBox.ShowDialog() == true)
83 | {
84 | _setValue(dict, key, inputBox.Value);
85 | }
86 |
87 | // Update ListView
88 | this.DictionaryList_SelectionChanged(null, null);
89 | }
90 | }
91 | }
92 |
--------------------------------------------------------------------------------
/AutoCADCommands/GUIs/InputBox.xaml:
--------------------------------------------------------------------------------
1 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/AutoCADCommands/GUIs/InputBox.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Windows;
6 | using System.Windows.Controls;
7 | using System.Windows.Data;
8 | using System.Windows.Documents;
9 | using System.Windows.Input;
10 | using System.Windows.Media;
11 | using System.Windows.Media.Imaging;
12 | using System.Windows.Navigation;
13 | using System.Windows.Shapes;
14 |
15 | namespace Dreambuild.AutoCAD
16 | {
17 | ///
18 | /// InputBox.xaml code behind.
19 | ///
20 | public partial class InputBox : Window
21 | {
22 | public string Value => this.InputTextBox.Text;
23 |
24 | public InputBox()
25 | {
26 | InitializeComponent();
27 | }
28 |
29 | public InputBox(string defaultValue)
30 | {
31 | InitializeComponent();
32 |
33 | this.InputTextBox.Text = defaultValue;
34 | }
35 |
36 | public InputBox(string tip, string defaultValue)
37 | {
38 | InitializeComponent();
39 |
40 | this.Title = tip;
41 | this.InputTextBox.Text = defaultValue;
42 | }
43 |
44 | private void OkButton_Click(object sender, RoutedEventArgs e)
45 | {
46 | this.DialogResult = true;
47 | }
48 |
49 | private void CancelButton_Click(object sender, RoutedEventArgs e)
50 | {
51 | this.DialogResult = false;
52 | }
53 | }
54 | }
55 |
--------------------------------------------------------------------------------
/AutoCADCommands/GUIs/MultiInputs.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
--------------------------------------------------------------------------------
/AutoCADCommands/GUIs/MultiInputs.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Windows;
6 | using System.Windows.Controls;
7 | using System.Windows.Data;
8 | using System.Windows.Documents;
9 | using System.Windows.Input;
10 | using System.Windows.Media;
11 | using System.Windows.Media.Imaging;
12 | using System.Windows.Navigation;
13 | using System.Windows.Shapes;
14 |
15 | namespace Dreambuild.AutoCAD
16 | {
17 | ///
18 | /// MultiInputs.xaml code behind.
19 | ///
20 | public partial class MultiInputs : Window
21 | {
22 | public Dictionary Values { get; private set; }
23 |
24 | public MultiInputs()
25 | {
26 | InitializeComponent();
27 | }
28 |
29 | public void Ready(Dictionary entries, string title = "Inputs")
30 | {
31 | this.Values = entries;
32 | foreach (var entry in entries)
33 | {
34 | var lable = new TextBlock
35 | {
36 | Text = entry.Key,
37 | ToolTip = entry.Key,
38 | Width = 150,
39 | VerticalAlignment = VerticalAlignment.Center
40 | };
41 | var text = new TextBox
42 | {
43 | Text = entry.Value
44 | };
45 | var row = new DockPanel
46 | {
47 | Tag = entry
48 | };
49 | row.Children.Add(lable);
50 | row.Children.Add(text);
51 | DockPanel.SetDock(lable, Dock.Left);
52 | this.PropertyList.Children.Add(row);
53 | }
54 | this.Title = title;
55 | }
56 |
57 | private void OkButton_Click(object sender, RoutedEventArgs e)
58 | {
59 | foreach (DockPanel row in this.PropertyList.Children)
60 | {
61 | var entry = (KeyValuePair)row.Tag;
62 | var text = row.Children[1] as TextBox;
63 | this.Values[entry.Key] = text.Text;
64 | }
65 | this.DialogResult = true;
66 | }
67 |
68 | private void CancelButton_Click(object sender, RoutedEventArgs e)
69 | {
70 | this.DialogResult = false;
71 | }
72 | }
73 | }
74 |
--------------------------------------------------------------------------------
/AutoCADCommands/GUIs/TaskProgressWindow.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/AutoCADCommands/GUIs/TaskProgressWindow.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Windows;
6 | using System.Windows.Controls;
7 | using System.Windows.Data;
8 | using System.Windows.Documents;
9 | using System.Windows.Input;
10 | using System.Windows.Media;
11 | using System.Windows.Media.Imaging;
12 | using System.Windows.Shapes;
13 |
14 | namespace Dreambuild.AutoCAD
15 | {
16 | ///
17 | /// TaskProgressWindow.xaml code behind.
18 | ///
19 | public partial class TaskProgressWindow : Window
20 | {
21 | public TaskProgressWindow()
22 | {
23 | InitializeComponent();
24 | }
25 | }
26 | }
27 |
--------------------------------------------------------------------------------
/AutoCADCommands/GUIs/TextReport.xaml:
--------------------------------------------------------------------------------
1 |
5 |
6 |
7 |
8 |
9 |
--------------------------------------------------------------------------------
/AutoCADCommands/GUIs/TextReport.xaml.cs:
--------------------------------------------------------------------------------
1 | using System;
2 | using System.Collections.Generic;
3 | using System.Linq;
4 | using System.Text;
5 | using System.Windows;
6 | using System.Windows.Controls;
7 | using System.Windows.Data;
8 | using System.Windows.Documents;
9 | using System.Windows.Input;
10 | using System.Windows.Media;
11 | using System.Windows.Media.Imaging;
12 | using System.Windows.Navigation;
13 | using System.Windows.Shapes;
14 |
15 | namespace Dreambuild.AutoCAD
16 | {
17 | ///
18 | /// TextReport.xaml code behind.
19 | ///
20 | public partial class TextReport : Window
21 | {
22 | public TextReport()
23 | {
24 | InitializeComponent();
25 | }
26 | }
27 | }
28 |
--------------------------------------------------------------------------------
/AutoCADCommands/Gui.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.AutoCAD.Windows;
2 | using System;
3 | using System.Collections.Generic;
4 | using System.ComponentModel;
5 | using System.Linq;
6 | using System.Windows;
7 | using System.Windows.Controls;
8 | using AcadApplication = Autodesk.AutoCAD.ApplicationServices.Application;
9 | using WinFormsPropertyGrid = System.Windows.Forms.PropertyGrid;
10 | using WpfWindow = System.Windows.Window;
11 |
12 | namespace Dreambuild.AutoCAD
13 | {
14 | ///
15 | /// The GUI component gallery.
16 | ///
17 | public static class Gui
18 | {
19 | ///
20 | /// Shows a GetOption window.
21 | ///
22 | /// The tip.
23 | /// The options.
24 | /// The choice.
25 | public static int GetOption(string tip, params string[] options)
26 | {
27 | var window = new WpfWindow
28 | {
29 | Width = 300,
30 | SizeToContent = SizeToContent.Height,
31 | WindowStartupLocation = WindowStartupLocation.CenterScreen,
32 | ShowInTaskbar = false,
33 | WindowStyle = WindowStyle.ToolWindow,
34 | Title = "Options"
35 | };
36 |
37 | var stackPanel = new StackPanel
38 | {
39 | Margin = new Thickness(5)
40 | };
41 |
42 | var textBlock = new TextBlock
43 | {
44 | Text = (tip == string.Empty ? "Please choose one..." : tip),
45 | TextWrapping = TextWrapping.Wrap
46 | };
47 |
48 | int result = -1;
49 | var buttons = options
50 | .Select((option, index) => new Button
51 | {
52 | Content = option,
53 | Tag = index
54 | })
55 | .ToList();
56 |
57 | buttons.ForEach(button => button.Click += (s, args) =>
58 | {
59 | result = (int)button.Tag;
60 | window.DialogResult = true;
61 | });
62 |
63 | stackPanel.Children.Add(textBlock);
64 | buttons.ForEach(button => stackPanel.Children.Add(button));
65 | window.Content = stackPanel;
66 |
67 | AcadApplication.ShowModalWindow(window);
68 | return result;
69 | }
70 |
71 | ///
72 | /// Shows a GetChoice window.
73 | ///
74 | /// The tip.
75 | /// The choices.
76 | /// The choice.
77 | public static string GetChoice(string tip, params string[] choices)
78 | {
79 | var window = new WpfWindow
80 | {
81 | Width = 300,
82 | SizeToContent = SizeToContent.Height,
83 | WindowStartupLocation = WindowStartupLocation.CenterScreen,
84 | ShowInTaskbar = false,
85 | WindowStyle = WindowStyle.ToolWindow,
86 | Title = "Choices"
87 | };
88 |
89 | var stackPanel = new StackPanel
90 | {
91 | Margin = new Thickness(10)
92 | };
93 |
94 | var textBlock = new TextBlock
95 | {
96 | Text = (tip == string.Empty ? "Please choose one..." : tip),
97 | TextWrapping = TextWrapping.Wrap
98 | };
99 |
100 | var listBox = new ListBox
101 | {
102 | Height = 200
103 | };
104 |
105 | choices.ForEach(choice => listBox.Items.Add(new ListBoxItem
106 | {
107 | Content = choice
108 | }));
109 |
110 | var okButton = new Button
111 | {
112 | Content = "OK",
113 | Margin = new Thickness(5)
114 | };
115 |
116 | okButton.Click += (s, args) => window.DialogResult = true;
117 | stackPanel.Children.Add(textBlock);
118 | stackPanel.Children.Add(listBox);
119 | stackPanel.Children.Add(okButton);
120 | window.Content = stackPanel;
121 |
122 | AcadApplication.ShowModalWindow(window);
123 | return listBox.SelectedItem == null
124 | ? string.Empty
125 | : (listBox.SelectedItem as ListBoxItem).Content.ToString();
126 | }
127 |
128 | ///
129 | /// Shows a GetChoices window.
130 | ///
131 | /// The tip.
132 | /// The choices.
133 | /// The final choices.
134 | public static string[] GetChoices(string tip, params string[] choices)
135 | {
136 | var window = new WpfWindow
137 | {
138 | Width = 300,
139 | SizeToContent = SizeToContent.Height,
140 | WindowStartupLocation = WindowStartupLocation.CenterScreen,
141 | ShowInTaskbar = false,
142 | WindowStyle = WindowStyle.ToolWindow,
143 | Title = "Choices"
144 | };
145 |
146 | var stackPanel = new StackPanel
147 | {
148 | Margin = new Thickness(10)
149 | };
150 |
151 | var textBlock = new TextBlock
152 | {
153 | Text = (tip == string.Empty ? "Please check items..." : tip),
154 | TextWrapping = TextWrapping.Wrap
155 | };
156 |
157 | var listBox = new ListBox
158 | {
159 | Height = 200
160 | };
161 |
162 | choices.ForEach(choice => listBox.Items.Add(new CheckBox
163 | {
164 | Content = choice
165 | }));
166 |
167 | var okButton = new Button
168 | {
169 | Content = "OK",
170 | Margin = new Thickness(5)
171 | };
172 |
173 | okButton.Click += (s, args) => window.DialogResult = true;
174 | stackPanel.Children.Add(textBlock);
175 | stackPanel.Children.Add(listBox);
176 | stackPanel.Children.Add(okButton);
177 | window.Content = stackPanel;
178 |
179 | AcadApplication.ShowModalWindow(window);
180 | return listBox.Items
181 | .Cast()
182 | .Where(checkBox => checkBox.IsChecked == true)
183 | .Select(checkBox => checkBox.Content.ToString())
184 | .ToArray();
185 | }
186 |
187 | ///
188 | /// Shows a text report window.
189 | ///
190 | /// The title.
191 | /// The content.
192 | /// The width.
193 | /// The height.
194 | /// Modal or not.
195 | public static void TextReport(string title, string content, double width, double height, bool modal = false)
196 | {
197 | var tr = new TextReport
198 | {
199 | Width = width,
200 | Height = height,
201 | Title = title
202 | };
203 | tr.ContentArea.Text = content;
204 | if (modal)
205 | {
206 | AcadApplication.ShowModalWindow(tr);
207 | }
208 | else
209 | {
210 | AcadApplication.ShowModelessWindow(tr);
211 | }
212 | }
213 |
214 | ///
215 | /// Shows a multi-inputs window.
216 | ///
217 | /// The title.
218 | /// The input entries.
219 | public static void MultiInputs(string title, Dictionary entries)
220 | {
221 | var mi = new MultiInputs();
222 | mi.Ready(entries, title);
223 | AcadApplication.ShowModalWindow(mi);
224 | }
225 |
226 | ///
227 | /// Shows an input box.
228 | ///
229 | /// The tip.
230 | /// The default value.
231 | /// The input.
232 | public static string InputBox(string tip, string defaultValue = "")
233 | {
234 | var input = new InputBox(tip, defaultValue);
235 | if (AcadApplication.ShowModalWindow(input) == true)
236 | {
237 | return input.Value;
238 | }
239 | return string.Empty;
240 | }
241 |
242 | ///
243 | /// Shows a busy indicator.
244 | ///
245 | ///
246 | ///
247 | public static void BusyIndicator(string title, BackgroundWorker worker)
248 | {
249 | // todo: BusyIndicator
250 | throw new NotImplementedException();
251 | }
252 |
253 | ///
254 | /// Shows a progress indicator.
255 | ///
256 | /// The title.
257 | /// The background worker.
258 | public static void ProgressIndicator(string title, BackgroundWorker worker)
259 | {
260 | var tpw = new TaskProgressWindow
261 | {
262 | Title = title + " (0%)"
263 | };
264 | tpw.CancelButton.Click += (s, args) =>
265 | {
266 | tpw.CancelButton.IsEnabled = false;
267 | worker.CancelAsync();
268 | };
269 | worker.ProgressChanged += (s, args) =>
270 | {
271 | tpw.ProgressBar.Value = args.ProgressPercentage;
272 | tpw.Title = $"{title} ({args.ProgressPercentage}%)";
273 | };
274 | worker.RunWorkerCompleted += (s, args) => tpw.Close();
275 | AcadApplication.ShowModalWindow(tpw);
276 | }
277 |
278 | private static PaletteSet propertyPalette = new PaletteSet("Properties");
279 | private static WinFormsPropertyGrid propertyGrid = new WinFormsPropertyGrid();
280 |
281 | ///
282 | /// Shows a property palette.
283 | ///
284 | /// The property object.
285 | public static void PropertyPalette(object obj) // newly 20140529
286 | {
287 | if (!propertyPalette.Visible)
288 | {
289 | if (propertyPalette.Count == 0)
290 | {
291 | propertyPalette.Add("Properties", propertyGrid);
292 | propertyPalette.Dock = DockSides.Left;
293 | }
294 | propertyPalette.Visible = true;
295 | }
296 | propertyGrid.SelectedObject = obj;
297 | }
298 | }
299 | }
300 |
--------------------------------------------------------------------------------
/AutoCADCommands/Internal/CustomDictionary.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.AutoCAD.ApplicationServices;
2 | using Autodesk.AutoCAD.DatabaseServices;
3 | using System.Collections.Generic;
4 | using System.Linq;
5 |
6 | namespace Dreambuild.AutoCAD.Internal
7 | {
8 | ///
9 | /// DWG global flexible data storage.
10 | ///
11 | ///
12 | /// A simple way to store data in DWG. The global data entries are saved in "CustomDictionaries" in the named object dictionary.
13 | ///
14 | public static class CustomDictionary
15 | {
16 | private const string DictionaryRoot = "CustomDictionaries";
17 |
18 | ///
19 | /// Gets value.
20 | ///
21 | /// The dictionary name.
22 | /// The key.
23 | /// The value.
24 | public static string GetValue(string dictionary, string key)
25 | {
26 | return CustomDictionary.GetEntry(CustomDictionary.GetDictionaryId(dictionary), key);
27 | }
28 |
29 | ///
30 | /// Sets value.
31 | ///
32 | /// The dictionary name.
33 | /// The key.
34 | /// The value.
35 | public static void SetValue(string dictionary, string key, string value)
36 | {
37 | CustomDictionary.SetEntry(CustomDictionary.GetDictionaryId(dictionary), key, value);
38 | }
39 |
40 | ///
41 | /// Gets all dictionary names.
42 | ///
43 | /// The names.
44 | public static IEnumerable GetDictionaryNames()
45 | {
46 | using (var trans = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
47 | {
48 | var nod = trans.GetObject(HostApplicationServices.WorkingDatabase.NamedObjectsDictionaryId, OpenMode.ForRead) as DBDictionary;
49 | if (!nod.Contains(CustomDictionary.DictionaryRoot))
50 | {
51 | yield break;
52 | }
53 | else
54 | {
55 | var dictRoot = trans.GetObject(nod.GetAt(CustomDictionary.DictionaryRoot), OpenMode.ForRead) as DBDictionary;
56 | foreach (var entry in dictRoot)
57 | {
58 | yield return entry.Key;
59 | }
60 | }
61 | }
62 | }
63 |
64 | internal static IEnumerable GetEntryNames(ObjectId dictId)
65 | {
66 | var dict = dictId.QOpenForRead();
67 | foreach (var entry in dict)
68 | {
69 | yield return entry.Key;
70 | }
71 | }
72 |
73 | internal static void SetEntry(ObjectId dictId, string key, string value)
74 | {
75 | using (var trans = dictId.Database.TransactionManager.StartTransaction())
76 | {
77 | var dict = trans.GetObject(dictId, OpenMode.ForWrite) as DBDictionary;
78 | if (dict.Contains(key))
79 | {
80 | trans.GetObject(dict.GetAt(key), OpenMode.ForWrite).Erase();
81 | }
82 | var entry = new Xrecord
83 | {
84 | Data = new ResultBuffer(new TypedValue((int)DxfCode.ExtendedDataAsciiString, value))
85 | };
86 | var entryId = dict.SetAt(key, entry);
87 | trans.AddNewlyCreatedDBObject(entry, true);
88 | trans.Commit();
89 | }
90 | }
91 |
92 | internal static string GetEntry(ObjectId dictId, string key)
93 | {
94 | using (var trans = dictId.Database.TransactionManager.StartTransaction())
95 | {
96 | var dict = trans.GetObject(dictId, OpenMode.ForRead) as DBDictionary;
97 | if (dict.Contains(key))
98 | {
99 | var entryId = dict.GetAt(key);
100 | var entry = trans.GetObject(entryId, OpenMode.ForRead) as Xrecord;
101 | if (entry != null)
102 | {
103 | return entry.Data.AsArray().First().Value.ToString();
104 | }
105 | }
106 |
107 | return string.Empty;
108 | }
109 | }
110 |
111 | ///
112 | /// Removes entry from dictionary.
113 | ///
114 | /// The dictionary name.
115 | /// The key.
116 | public static void RemoveEntry(string dictName, string key) // newly 20111206
117 | {
118 | using (var trans = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
119 | {
120 | var dict = trans.GetObject(GetDictionaryId(dictName), OpenMode.ForWrite) as DBDictionary;
121 | if (dict.Contains(key))
122 | {
123 | dict.Remove(key);
124 | }
125 | trans.Commit();
126 | }
127 | }
128 |
129 | ///
130 | /// Gets all keys from a dictionary.
131 | ///
132 | /// The dictionary name.
133 | /// The keys.
134 | public static IEnumerable GetEntryNames(string dictionary)
135 | {
136 | return CustomDictionary.GetEntryNames(CustomDictionary.GetDictionaryId(dictionary));
137 | }
138 |
139 | private static ObjectId GetDictionaryId(string dictionaryName)
140 | {
141 | using (var doclock = Application.DocumentManager.MdiActiveDocument.LockDocument())
142 | {
143 | using (var trans = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction())
144 | {
145 | var nod = trans.GetObject(HostApplicationServices.WorkingDatabase.NamedObjectsDictionaryId, OpenMode.ForRead) as DBDictionary;
146 | DBDictionary dictRoot;
147 | if (!nod.Contains(DictionaryRoot))
148 | {
149 | dictRoot = new DBDictionary();
150 | nod.UpgradeOpen();
151 | nod.SetAt(DictionaryRoot, dictRoot);
152 | trans.AddNewlyCreatedDBObject(dictRoot, true);
153 | }
154 | else
155 | {
156 | dictRoot = trans.GetObject(nod.GetAt(DictionaryRoot), OpenMode.ForWrite) as DBDictionary;
157 | }
158 | if (!dictRoot.Contains(dictionaryName))
159 | {
160 | var dictEntry = new DBDictionary();
161 | dictRoot.SetAt(dictionaryName, dictEntry);
162 | trans.AddNewlyCreatedDBObject(dictEntry, true);
163 | }
164 | trans.Commit();
165 | return dictRoot.GetAt(dictionaryName);
166 | }
167 | }
168 | }
169 | }
170 |
171 | ///
172 | /// DB object flexible data storage.
173 | ///
174 | ///
175 | /// A simple way to attach data to DB objects. The DB object entries are stored in the object's XData.
176 | ///
177 | public static class CustomObjectDictionary
178 | {
179 | ///
180 | /// Gets value.
181 | ///
182 | /// The object ID.
183 | /// The dictionary name.
184 | /// The key.
185 | /// The value.
186 | public static string GetValue(ObjectId id, string dictionary, string key)
187 | {
188 | return CustomDictionary.GetEntry(CustomObjectDictionary.GetDictionaryId(id, dictionary), key);
189 | }
190 |
191 | ///
192 | /// Sets value.
193 | ///
194 | /// The object ID.
195 | /// The dictionary name.
196 | /// The key.
197 | /// The value.
198 | public static void SetValue(ObjectId id, string dictionary, string key, string value)
199 | {
200 | CustomDictionary.SetEntry(CustomObjectDictionary.GetDictionaryId(id, dictionary), key, value);
201 | }
202 |
203 | ///
204 | /// Removes entry from dictionary.
205 | ///
206 | /// The object ID.
207 | /// The dictionary name.
208 | /// The key.
209 | public static void RemoveEntry(ObjectId id, string dictName, string key) // newly 20111206
210 | {
211 | using (var trans = id.Database.TransactionManager.StartTransaction())
212 | {
213 | var dict = trans.GetObject(GetDictionaryId(id, dictName), OpenMode.ForWrite) as DBDictionary;
214 | if (dict.Contains(key))
215 | {
216 | dict.Remove(key);
217 | }
218 | trans.Commit();
219 | }
220 | }
221 |
222 | ///
223 | /// Gets all dictionary names.
224 | ///
225 | /// The object ID.
226 | /// The names.
227 | public static IEnumerable GetDictionaryNames(ObjectId id)
228 | {
229 | using (var trans = id.Database.TransactionManager.StartTransaction())
230 | {
231 | var dbo = trans.GetObject(id, OpenMode.ForRead);
232 | var dictRoot = trans.GetObject(dbo.ExtensionDictionary, OpenMode.ForRead) as DBDictionary;
233 | foreach (var entry in dictRoot)
234 | {
235 | yield return entry.Key;
236 | }
237 | }
238 | }
239 |
240 | ///
241 | /// Gets all keys from a dictionary.
242 | ///
243 | /// The object ID.
244 | /// The dictionary name.
245 | /// The keys.
246 | public static IEnumerable GetEntryNames(ObjectId id, string dictionary)
247 | {
248 | return CustomDictionary.GetEntryNames(CustomObjectDictionary.GetDictionaryId(id, dictionary));
249 | }
250 |
251 | private static ObjectId GetDictionaryId(ObjectId id, string dictionaryName)
252 | {
253 | using (var doclock = Application.DocumentManager.MdiActiveDocument.LockDocument())
254 | {
255 | using (var trans = id.Database.TransactionManager.StartTransaction())
256 | {
257 | var dbo = trans.GetObject(id, OpenMode.ForRead);
258 | if (dbo.ExtensionDictionary == ObjectId.Null)
259 | {
260 | dbo.UpgradeOpen();
261 | dbo.CreateExtensionDictionary();
262 | }
263 | var dictRoot = trans.GetObject(dbo.ExtensionDictionary, OpenMode.ForRead) as DBDictionary;
264 | if (!dictRoot.Contains(dictionaryName))
265 | {
266 | dictRoot.UpgradeOpen();
267 | var dictEntry = new DBDictionary();
268 | dictRoot.SetAt(dictionaryName, dictEntry);
269 | trans.AddNewlyCreatedDBObject(dictEntry, true);
270 | }
271 | trans.Commit();
272 | return dictRoot.GetAt(dictionaryName);
273 | }
274 | }
275 | }
276 | }
277 | }
278 |
--------------------------------------------------------------------------------
/AutoCADCommands/Internal/JigDrag.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.AutoCAD.DatabaseServices;
2 | using Autodesk.AutoCAD.EditorInput;
3 | using Autodesk.AutoCAD.GraphicsInterface;
4 | using System;
5 |
6 | namespace Dreambuild.AutoCAD.Internal
7 | {
8 | internal class FlexEntityJig : EntityJig
9 | {
10 | protected JigPromptOptions Options { get; }
11 |
12 | protected Func UpdateAction { get; }
13 |
14 | protected PromptResult JigResult { get; set; }
15 |
16 | protected string JigResultValue { get; set; }
17 |
18 | public FlexEntityJig(
19 | JigPromptOptions options,
20 | Entity entity,
21 | Func updateAction)
22 | : base(entity)
23 | {
24 | this.Options = options;
25 | this.UpdateAction = updateAction;
26 | }
27 |
28 | protected override SamplerStatus Sampler(JigPrompts prompts)
29 | {
30 | string jigResultValue = null;
31 |
32 | if (this.Options is JigPromptPointOptions pointOptions)
33 | {
34 | var result = prompts.AcquirePoint(pointOptions);
35 | this.JigResult = result;
36 | jigResultValue = result.Value.ToString();
37 | }
38 | else if (this.Options is JigPromptDistanceOptions distanceOptions)
39 | {
40 | var result = prompts.AcquireDistance(distanceOptions);
41 | this.JigResult = result;
42 | jigResultValue = result.Value.ToString();
43 | }
44 | else if (this.Options is JigPromptAngleOptions angleOptions)
45 | {
46 | var result = prompts.AcquireAngle(angleOptions);
47 | this.JigResult = result;
48 | jigResultValue = result.Value.ToString();
49 | }
50 | else if (this.Options is JigPromptStringOptions stringOptions)
51 | {
52 | var result = prompts.AcquireString(stringOptions);
53 | this.JigResult = result;
54 | jigResultValue = result.StringResult;
55 | }
56 |
57 | if (jigResultValue == null)
58 | {
59 | return SamplerStatus.Cancel;
60 | }
61 | else if (jigResultValue != this.JigResultValue)
62 | {
63 | this.JigResultValue = jigResultValue;
64 | return SamplerStatus.OK;
65 | }
66 |
67 | return SamplerStatus.NoChange;
68 | }
69 |
70 | protected override bool Update()
71 | {
72 | return this.UpdateAction(base.Entity, this.JigResult);
73 | }
74 | }
75 |
76 | internal class FlexDrawJig : DrawJig
77 | {
78 | protected JigPromptOptions Options { get; }
79 |
80 | protected Func UpdateAction { get; }
81 |
82 | protected PromptResult JigResult { get; set; }
83 |
84 | protected string JigResultValue { get; set; }
85 |
86 | public FlexDrawJig(
87 | JigPromptOptions options,
88 | Func updateAction)
89 | {
90 | this.Options = options;
91 | this.UpdateAction = updateAction;
92 | }
93 |
94 | protected override SamplerStatus Sampler(JigPrompts prompts)
95 | {
96 | string jigResultValue = null;
97 |
98 | if (this.Options is JigPromptPointOptions pointOptions)
99 | {
100 | var result = prompts.AcquirePoint(pointOptions);
101 | this.JigResult = result;
102 | jigResultValue = result.Value.ToString();
103 | }
104 | else if (this.Options is JigPromptDistanceOptions distanceOptions)
105 | {
106 | var result = prompts.AcquireDistance(distanceOptions);
107 | this.JigResult = result;
108 | jigResultValue = result.Value.ToString();
109 | }
110 | else if (this.Options is JigPromptAngleOptions angleOptions)
111 | {
112 | var result = prompts.AcquireAngle(angleOptions);
113 | this.JigResult = result;
114 | jigResultValue = result.Value.ToString();
115 | }
116 | else if (this.Options is JigPromptStringOptions stringOptions)
117 | {
118 | var result = prompts.AcquireString(stringOptions);
119 | this.JigResult = result;
120 | jigResultValue = result.StringResult;
121 | }
122 |
123 | if (jigResultValue == null)
124 | {
125 | return SamplerStatus.Cancel;
126 | }
127 | else if (jigResultValue != this.JigResultValue)
128 | {
129 | this.JigResultValue = jigResultValue;
130 | return SamplerStatus.OK;
131 | }
132 |
133 | return SamplerStatus.NoChange;
134 | }
135 |
136 | protected override bool WorldDraw(WorldDraw draw)
137 | {
138 | return draw.Geometry.Draw(this.UpdateAction(this.JigResult));
139 | }
140 | }
141 | }
142 |
--------------------------------------------------------------------------------
/AutoCADCommands/Layouts.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.AutoCAD.DatabaseServices;
2 | using Autodesk.AutoCAD.Geometry;
3 | using System.Collections.Generic;
4 | using System.Collections.ObjectModel;
5 |
6 | namespace Dreambuild.AutoCAD
7 | {
8 | ///
9 | /// Layout operations.
10 | ///
11 | public static class Layouts
12 | {
13 | ///
14 | /// Default plotter.
15 | ///
16 | public const string Device_DWF6 = "DWF6 ePlot.pc3";
17 | ///
18 | /// A3 full landscape.
19 | ///
20 | public const string Media_A3_Full_Landscape = "ISO_full_bleed_A3_(297.00_x_420.00_MM)";
21 | ///
22 | /// A3 expand landscape.
23 | ///
24 | public const string Media_A3_Expand_Landscape = "ISO_expand_A3_(297.00_x_420.00_MM)";
25 |
26 | ///
27 | /// The supported scales.
28 | ///
29 | public static ReadOnlyCollection Scales { get; } = new ReadOnlyCollection(new List { 50, 100, 200, 250 });
30 |
31 | ///
32 | /// Sets viewport parameters.
33 | ///
34 | /// The viewport ID.
35 | /// The width.
36 | /// The height.
37 | /// The center.
38 | /// The look at direction.
39 | /// Thew view height.
40 | public static void SetViewport(ObjectId viewportId, double width, double height, Point3d center, Point3d lookAt, double viewHeight)
41 | {
42 | viewportId.QOpenForWrite(vPort =>
43 | {
44 | vPort.Height = height;
45 | vPort.Width = width;
46 | vPort.CenterPoint = center;
47 | vPort.ViewHeight = viewHeight;
48 | vPort.ViewCenter = new Point2d(lookAt.X, lookAt.Y); //new Point2d(0, 0);
49 | vPort.ViewTarget = Point3d.Origin; //lookAt;
50 | vPort.ViewDirection = Vector3d.ZAxis;
51 | vPort.Locked = true;
52 | vPort.On = true;
53 | });
54 | }
55 |
56 | ///
57 | /// Sets layout configuration.
58 | ///
59 | /// The layout ID.
60 | /// The plotter.
61 | /// The media.
62 | public static void SetConfiguration(ObjectId layoutId, string device, string media)
63 | {
64 | layoutId.QOpenForWrite(layout =>
65 | {
66 | PlotSettingsValidator.Current.SetPlotConfigurationName(layout, device, media);
67 | });
68 | }
69 |
70 | ///
71 | /// Gets model space coordinates.
72 | ///
73 | /// The layout coordinates.
74 | /// The center.
75 | /// The look at direction.
76 | /// The scale.
77 | /// The model space coordinates.
78 | public static Point3d GetModelCoord(this Point3d layoutCoord, Point3d center, Point3d lookAt, double scale)
79 | {
80 | return lookAt + (layoutCoord - center) * scale;
81 | }
82 |
83 | ///
84 | /// Gets layout coordinates.
85 | ///
86 | /// The model space coordinates.
87 | /// The center.
88 | /// The look at direction.
89 | /// The scale.
90 | /// The layout coordintes.
91 | public static Point3d GetLayoutCoord(this Point3d modelCoord, Point3d center, Point3d lookAt, double scale)
92 | {
93 | return center + (modelCoord - lookAt) / scale;
94 | }
95 | }
96 | }
97 |
--------------------------------------------------------------------------------
/AutoCADCommands/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | [assembly: AssemblyTitle("AutoCADCommands")]
5 | [assembly: AssemblyDescription("")]
6 | [assembly: AssemblyConfiguration("")]
7 | [assembly: AssemblyCompany("Microsoft")]
8 | [assembly: AssemblyProduct("AutoCADCommands")]
9 | [assembly: AssemblyCopyright("Copyright © Microsoft 2011")]
10 | [assembly: AssemblyTrademark("")]
11 | [assembly: AssemblyCulture("")]
12 |
13 | [assembly: ComVisible(false)]
14 | [assembly: Guid("c6783d73-7c70-455d-a952-6ee574581a94")]
15 |
16 | [assembly: AssemblyVersion("1.0.0.0")]
17 | [assembly: AssemblyFileVersion("1.0.0.0")]
18 |
--------------------------------------------------------------------------------
/AutoCADCommands/QuickSelection.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.AutoCAD.ApplicationServices;
2 | using Autodesk.AutoCAD.DatabaseServices;
3 | using Autodesk.AutoCAD.EditorInput;
4 | using System;
5 | using System.Collections.Generic;
6 | using System.Linq;
7 |
8 | namespace Dreambuild.AutoCAD
9 | {
10 | ///
11 | /// Quick selection toolbox.
12 | ///
13 | public static class QuickSelection
14 | {
15 | // TODO: remove all obsolete methods.
16 |
17 | #region QWhere|QPick|QSelect
18 |
19 | ///
20 | /// QLinq Where.
21 | ///
22 | /// The object IDs.
23 | /// The filter.
24 | /// Filtered IDs.
25 | public static IEnumerable QWhere(this IEnumerable ids, Func filter)
26 | {
27 | return ids
28 | .QOpenForRead()
29 | .Where(filter)
30 | .Select(entity => entity.ObjectId);
31 | }
32 |
33 | [Obsolete("Use QOpenForRead().")]
34 | public static ObjectId QPick(this IEnumerable ids, Func filter)
35 | {
36 | // TODO: verify that the default works.
37 | return ids
38 | .QOpenForRead()
39 | .FirstOrDefault()
40 | .ObjectId;
41 | }
42 |
43 | ///
44 | /// QLinq Select.
45 | ///
46 | /// The object IDs.
47 | /// The mapper.
48 | /// Mapped results.
49 | public static IEnumerable QSelect(this IEnumerable ids, Func mapper)
50 | {
51 | return ids
52 | .QOpenForRead()
53 | .Select(mapper);
54 | }
55 |
56 | [Obsolete("Use QOpenForRead().")]
57 | public static TResult QSelect(this ObjectId entId, Func mapper)
58 | {
59 | var ids = new List { entId };
60 | return ids.QSelect(mapper).First();
61 | }
62 |
63 | #endregion
64 |
65 | #region QOpenForRead
66 |
67 | ///
68 | /// Opens object for read.
69 | ///
70 | /// The object ID.
71 | /// The opened object.
72 | public static DBObject QOpenForRead(this ObjectId id)
73 | {
74 | using (var trans = id.Database.TransactionManager.StartOpenCloseTransaction())
75 | {
76 | return trans.GetObject(id, OpenMode.ForRead);
77 | }
78 | }
79 |
80 | ///
81 | /// Opens object for read.
82 | ///
83 | /// The type of object.
84 | /// The object ID.
85 | /// The opened object.
86 | public static T QOpenForRead(this ObjectId id) where T : DBObject // newly 20130122
87 | {
88 | return id.QOpenForRead() as T;
89 | }
90 |
91 | ///
92 | /// Opens objects for read.
93 | ///
94 | /// The object IDs.
95 | /// The opened object.
96 | public static DBObject[] QOpenForRead(this IEnumerable ids) // newly 20120915
97 | {
98 | using (var trans = DbHelper.GetDatabase(ids).TransactionManager.StartTransaction())
99 | {
100 | return ids.Select(id => trans.GetObject(id, OpenMode.ForRead)).ToArray();
101 | }
102 | }
103 |
104 | ///
105 | /// Opens objects for read.
106 | ///
107 | /// The type of object.
108 | /// The object IDs.
109 | /// The opened object.
110 | public static T[] QOpenForRead(this IEnumerable ids) where T : DBObject // newly 20130122
111 | {
112 | using (var trans = DbHelper.GetDatabase(ids).TransactionManager.StartTransaction())
113 | {
114 | return ids.Select(id => trans.GetObject(id, OpenMode.ForRead) as T).ToArray();
115 | }
116 | }
117 |
118 | #endregion
119 |
120 | #region QOpenForWrite
121 |
122 | ///
123 | /// Opens object for write.
124 | ///
125 | /// The object ID.
126 | /// The action.
127 | public static void QOpenForWrite(this ObjectId id, Action action)
128 | {
129 | using (var trans = id.Database.TransactionManager.StartTransaction())
130 | {
131 | action(trans.GetObject(id, OpenMode.ForWrite));
132 | trans.Commit();
133 | }
134 | }
135 |
136 | ///
137 | /// Opens object for write.
138 | ///
139 | /// The type of object.
140 | /// The object ID.
141 | /// The action.
142 | public static void QOpenForWrite(this ObjectId id, Action action) where T : DBObject // newly 20130411
143 | {
144 | using (var trans = id.Database.TransactionManager.StartTransaction())
145 | {
146 | action(trans.GetObject(id, OpenMode.ForWrite) as T);
147 | trans.Commit();
148 | }
149 | }
150 |
151 | ///
152 | /// Opens object for write.
153 | ///
154 | /// The type of object.
155 | /// The object ID.
156 | /// The action.
157 | public static void QOpenForWrite(this ObjectId id, Func action) where T : DBObject
158 | {
159 | using (var trans = id.Database.TransactionManager.StartTransaction())
160 | {
161 | var newObjects = action(trans.GetObject(id, OpenMode.ForWrite) as T).ToList();
162 | newObjects.ForEach(newObject => trans.AddNewlyCreatedDBObject(newObject, true));
163 | trans.Commit();
164 | }
165 | }
166 |
167 | ///
168 | /// Opens objects for write.
169 | ///
170 | /// The object IDs.
171 | /// The action.
172 | public static void QOpenForWrite(this IEnumerable ids, Action action) // newly 20120908
173 | {
174 | using (var trans = DbHelper.GetDatabase(ids).TransactionManager.StartTransaction())
175 | {
176 | var list = ids.Select(id => trans.GetObject(id, OpenMode.ForWrite)).ToArray();
177 | action(list);
178 | trans.Commit();
179 | }
180 | }
181 |
182 | ///
183 | /// Opens objects for write.
184 | ///
185 | /// The type of object.
186 | /// The object IDs.
187 | /// The action.
188 | public static void QOpenForWrite(this IEnumerable ids, Action action) where T : DBObject // newly 20130411
189 | {
190 | using (var trans = DbHelper.GetDatabase(ids).TransactionManager.StartTransaction())
191 | {
192 | var list = ids.Select(id => trans.GetObject(id, OpenMode.ForWrite) as T).ToArray();
193 | action(list);
194 | trans.Commit();
195 | }
196 | }
197 |
198 | ///
199 | /// Opens objects for write.
200 | ///
201 | /// The type of object.
202 | /// The object IDs.
203 | /// The action.
204 | public static void QOpenForWrite(this IEnumerable ids, Func action) where T : DBObject
205 | {
206 | using (var trans = DbHelper.GetDatabase(ids).TransactionManager.StartTransaction())
207 | {
208 | var list = ids.Select(id => trans.GetObject(id, OpenMode.ForWrite) as T).ToArray();
209 | var newObjects = action(list).ToList();
210 | newObjects.ForEach(newObject => trans.AddNewlyCreatedDBObject(newObject, true));
211 | trans.Commit();
212 | }
213 | }
214 |
215 | ///
216 | /// Opens objects for write (for each).
217 | ///
218 | /// The object IDs.
219 | /// The action.
220 | public static void QForEach(this IEnumerable ids, Action action)
221 | {
222 | using (var trans = DbHelper.GetDatabase(ids).TransactionManager.StartTransaction())
223 | {
224 | ids.Select(id => trans.GetObject(id, OpenMode.ForWrite)).ToList().ForEach(action);
225 | trans.Commit();
226 | }
227 | }
228 |
229 | ///
230 | /// Opens objects for write (for each).
231 | ///
232 | /// The type of object.
233 | /// The object IDs.
234 | /// The action.
235 | public static void QForEach(this IEnumerable ids, Action action) where T : DBObject // newly 20130520
236 | {
237 | using (var trans = DbHelper.GetDatabase(ids).TransactionManager.StartTransaction())
238 | {
239 | ids.Select(id => trans.GetObject(id, OpenMode.ForWrite) as T).ToList().ForEach(action);
240 | trans.Commit();
241 | }
242 | }
243 |
244 | #endregion
245 |
246 | #region Aggregation: QCount|QMin|QMax
247 |
248 | [Obsolete("Use QOpenForRead().")]
249 | public static int QCount(this IEnumerable ids, Func filter)
250 | {
251 | return ids
252 | .QOpenForRead()
253 | .Count(filter);
254 | }
255 |
256 | [Obsolete("Use QOpenForRead().")]
257 | public static double QMin(this IEnumerable ids, Func mapper)
258 | {
259 | return ids
260 | .QOpenForRead()
261 | .Min(mapper);
262 | }
263 |
264 | [Obsolete("Use QOpenForRead().")]
265 | public static double QMax(this IEnumerable ids, Func mapper)
266 | {
267 | return ids
268 | .QOpenForRead()
269 | .Max(mapper);
270 | }
271 |
272 | [Obsolete("Use QOpenForRead().")]
273 | public static ObjectId QMinEntity(this IEnumerable ids, Func mapper)
274 | {
275 | // Bad implementation.
276 | using (var trans = DbHelper.GetDatabase(ids).TransactionManager.StartOpenCloseTransaction())
277 | {
278 | var entities = ids.Select(id => trans.GetObject(id, OpenMode.ForRead) as Entity).ToList();
279 | double value = entities.Min(mapper);
280 | return entities.First(entity => mapper(entity) == value).ObjectId;
281 | }
282 | }
283 |
284 | [Obsolete("Use QOpenForRead().")]
285 | public static ObjectId QMaxEntity(this IEnumerable ids, Func mapper)
286 | {
287 | // Bad implementation.
288 | using (var trans = DbHelper.GetDatabase(ids).TransactionManager.StartOpenCloseTransaction())
289 | {
290 | var entities = ids.Select(id => trans.GetObject(id, OpenMode.ForRead) as Entity).ToList();
291 | double value = entities.Max(mapper);
292 | return entities.First(entity => mapper(entity) == value).ObjectId;
293 | }
294 | }
295 |
296 | #endregion
297 |
298 | #region Factory methods
299 |
300 | ///
301 | /// Selects all entities with specified DXF type in current editor.
302 | ///
303 | /// The DXF type.
304 | /// The object IDs.
305 | public static ObjectId[] SelectAll(string dxfType)
306 | {
307 | return QuickSelection.SelectAll(new TypedValue((int)DxfCode.Start, dxfType));
308 | }
309 |
310 | ///
311 | /// Selects all entities with specified filters in current editor.
312 | ///
313 | /// The filter list.
314 | /// The object IDs.
315 | public static ObjectId[] SelectAll(FilterList filterList)
316 | {
317 | return QuickSelection.SelectAll(filterList.ToArray());
318 | }
319 |
320 | ///
321 | /// Selects all entities with specified filters in current editor.
322 | ///
323 | /// The filter list.
324 | /// The object IDs.
325 | public static ObjectId[] SelectAll(params TypedValue[] filterList)
326 | {
327 | var ed = Application.DocumentManager.MdiActiveDocument.Editor;
328 | var selRes = filterList != null && filterList.Any()
329 | ? ed.SelectAll(new SelectionFilter(filterList))
330 | : ed.SelectAll();
331 |
332 | if (selRes.Status == PromptStatus.OK)
333 | {
334 | return selRes.Value.GetObjectIds();
335 | }
336 |
337 | return new ObjectId[0];
338 | }
339 |
340 | private static IEnumerable SelectAllInternal(this Database db, string block)
341 | {
342 | using (var trans = db.TransactionManager.StartOpenCloseTransaction())
343 | {
344 | var bt = trans.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;
345 | var modelSpace = trans.GetObject(bt[block], OpenMode.ForRead) as BlockTableRecord;
346 | foreach (ObjectId id in modelSpace)
347 | {
348 | yield return id;
349 | }
350 | }
351 | }
352 |
353 | ///
354 | /// Selects all entities in specified database's model space.
355 | ///
356 | /// The database.
357 | /// The object IDs.
358 | public static ObjectId[] SelectAll(this Database db)
359 | {
360 | return db.SelectAllInternal(BlockTableRecord.ModelSpace).ToArray();
361 | }
362 |
363 | ///
364 | /// Selects all entities in specified database's specified block.
365 | ///
366 | /// The database.
367 | /// The block.
368 | /// The object IDs.
369 | public static ObjectId[] SelectAll(this Database db, string block)
370 | {
371 | return db.SelectAllInternal(block).ToArray();
372 | }
373 |
374 | #endregion
375 | }
376 |
377 | ///
378 | /// Filter list helper.
379 | ///
380 | public class FilterList
381 | {
382 | private readonly List Cache = new List();
383 |
384 | ///
385 | /// Creates a new filter list.
386 | ///
387 | /// The result.
388 | public static FilterList Create()
389 | {
390 | return new FilterList();
391 | }
392 |
393 | ///
394 | /// Gets the TypedValue array representation.
395 | ///
396 | /// The array.
397 | public TypedValue[] ToArray()
398 | {
399 | return this.Cache.ToArray();
400 | }
401 |
402 | ///
403 | /// Adds a DXF type filter.
404 | ///
405 | /// The DXF types.
406 | /// The helper.
407 | public FilterList DxfType(params string[] dxfTypes)
408 | {
409 | this.Cache.Add(new TypedValue((int)DxfCode.Start, string.Join(",", dxfTypes)));
410 | return this;
411 | }
412 |
413 | ///
414 | /// Adds a layer filter.
415 | ///
416 | /// The layers.
417 | /// The helper.
418 | public FilterList Layer(params string[] layers)
419 | {
420 | this.Cache.Add(new TypedValue((int)DxfCode.LayerName, string.Join(",", layers)));
421 | return this;
422 | }
423 |
424 | ///
425 | /// Adds an arbitrary filter.
426 | ///
427 | /// The type code.
428 | /// The value.
429 | /// The helper.
430 | public FilterList Filter(int typeCode, string value)
431 | {
432 | this.Cache.Add(new TypedValue(typeCode, value));
433 | return this;
434 | }
435 | }
436 | }
437 |
--------------------------------------------------------------------------------
/AutoCADCommands/SymbolPack.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.AutoCAD.DatabaseServices;
2 | using Autodesk.AutoCAD.Geometry;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Linq;
6 |
7 | namespace Dreambuild.AutoCAD
8 | {
9 | ///
10 | /// The symbol pack.
11 | ///
12 | public static class SymbolPack
13 | {
14 | public static ObjectId Arrow(Point3d end, Point3d head, ArrowOption opt)
15 | {
16 | var body = Draw.Line(end, head);
17 | body.QOpenForWrite(line => line.ColorIndex = opt.ColorIndex);
18 | var arrow = Modify.Group(new[] { body });
19 |
20 | if (opt.HeadStyle == ArrowHeadStyle.ClockHand)
21 | {
22 | var dir = head - end;
23 | dir = dir.GetNormal();
24 | var nor = new Vector3d(dir.Y, -dir.X, 0);
25 | var headBase = head - opt.HeadLength * dir;
26 | var left = headBase - opt.HeadWidth / 2 * nor;
27 | var right = headBase + opt.HeadWidth / 2 * nor;
28 | var leftLine = Draw.Line(head, left);
29 | var rightLine = Draw.Line(head, right);
30 | leftLine.QOpenForWrite(line => line.ColorIndex = opt.ColorIndex);
31 | rightLine.QOpenForWrite(line => line.ColorIndex = opt.ColorIndex);
32 | Modify.AppendToGroup(arrow, new[] { leftLine, rightLine });
33 | }
34 |
35 | return arrow;
36 | }
37 |
38 | public static ObjectId BridgeEar(Point3d pos, Vector3d dir, bool right, double size)
39 | {
40 | var angle = right ? -Math.PI / 4 : Math.PI / 4;
41 | var earDir = dir.GetNormal().RotateBy(angle, Vector3d.ZAxis);
42 | var start = pos;
43 | var end = start + size * earDir;
44 | return Draw.Pline(start, end);
45 | }
46 |
47 | public static Tuple BridgeEarFor(Curve cv, bool right, double size)
48 | {
49 | var startDir = -cv.GetFirstDerivative(cv.StartParam);
50 | var endDir = cv.GetFirstDerivative(cv.EndParam);
51 | var startRight = right ? false : true;
52 | var endRight = right ? true : false;
53 | var startEar = BridgeEar(cv.StartPoint, startDir, startRight, size);
54 | var endEar = BridgeEar(cv.EndPoint, endDir, endRight, size);
55 | return Tuple.Create(startEar, endEar);
56 | }
57 |
58 | public static ObjectId[] Stairs(Point3d p1, Point3d p2, Point3d p3, double step)
59 | {
60 | var line1 = NoDraw.Pline(p1, p2);
61 | var width = line1.GetDistToPoint(p3, true);
62 | var line21 = line1.GetOffsetCurves(width)[0] as Polyline;
63 | var line22 = line1.GetOffsetCurves(-width)[0] as Polyline;
64 | var line2 = line21.GetDistToPoint(p3) < line22.GetDistToPoint(p3) ? line21 : line22;
65 | var length = line1.Length;
66 | var lines = Algorithms
67 | .Range(step, length, step)
68 | .Select(pos => NoDraw.Pline(line1.GetPointAtDistX(pos), line2.GetPointAtDistX(pos)))
69 | .ToList();
70 | lines.Add(line1);
71 | lines.Add(line2);
72 | return lines.ToArray().AddToCurrentSpace();
73 | }
74 |
75 | public static ObjectId[] LineBundle(Polyline alignment, LineBundleElement[] bundle)
76 | {
77 | var ids = new List();
78 | bundle.ForEach(bundleElement =>
79 | {
80 | var poly = alignment.GetOffsetCurves(bundleElement.Offset)[0] as Polyline;
81 | poly.ConstantWidth = bundleElement.Width;
82 | if (bundleElement.DashArray == null || bundleElement.DashArray.Length == 0)
83 | {
84 | ids.Add(poly.AddToCurrentSpace());
85 | }
86 | else
87 | {
88 | ids.AddRange(DashedLine(poly, bundleElement.DashArray));
89 | }
90 | });
91 | return ids.ToArray();
92 | }
93 |
94 | public static ObjectId[] DashedLine(Curve cv, double[] dashArray)
95 | {
96 | var cvs = new List();
97 | double dist = 0;
98 | int i = 0;
99 | bool dash = false;
100 | while (dist < cv.GetDistAtParam(cv.EndParam))
101 | {
102 | double length = dashArray[i];
103 | if (!dash)
104 | {
105 | cvs.Add(cv.GetSubCurve(new Interv(dist, dist + length)));
106 | }
107 | i = (i + 1) % dashArray.Length;
108 | dist += length;
109 | dash = !dash;
110 | }
111 | return cvs.ToArray().AddToCurrentSpace();
112 | }
113 | }
114 |
115 | ///
116 | /// The line bundle element.
117 | ///
118 | public class LineBundleElement
119 | {
120 | public double Width;
121 | public double[] DashArray;
122 | public double Offset;
123 | }
124 |
125 | ///
126 | /// The arrow option.
127 | ///
128 | public class ArrowOption
129 | {
130 | public byte ColorIndex = 0;
131 | public double HeadLength = 5;
132 | public double HeadWidth = 5;
133 | public ArrowHeadStyle HeadStyle = ArrowHeadStyle.ClockHand;
134 | }
135 |
136 | ///
137 | /// The arrow head style.
138 | ///
139 | public enum ArrowHeadStyle
140 | {
141 | RosePink,
142 | ClockHand,
143 | BlackTriangle,
144 | WhiteTriangle,
145 | Diamond
146 | }
147 |
148 | ///
149 | /// The (math function) graph plotter.
150 | ///
151 | public class GraphPlotter
152 | {
153 | private GraphOption Option { get; }
154 |
155 | private Interv XRange { get; set; }
156 |
157 | private Interv YRange { get; set; } // Original, without ratio applied.
158 |
159 | private List> Curves { get; } = new List>();
160 |
161 | private double RealRatio => this.Option.yRatio * (this.XRange.Length * this.Option.xRedundanceFactor) / (this.YRange.Length * this.Option.yRedundanceFactor);
162 |
163 | public GraphPlotter()
164 | {
165 | this.Option = new GraphOption();
166 | }
167 |
168 | public GraphPlotter(GraphOption opt)
169 | {
170 | this.Option = opt;
171 | this.XRange = opt.xRange;
172 | this.YRange = opt.yRange;
173 | }
174 |
175 | public void Plot(IEnumerable points, int color = -1)
176 | {
177 | this.Curves.Add(Tuple.Create(points.OrderBy(point => point.X).ToArray(), color));
178 |
179 | var xRange = new Interv(points.Min(point => point.X), points.Max(point => point.X));
180 | var yRange = new Interv(points.Min(point => point.Y), points.Max(point => point.Y));
181 | if (this.XRange == null)
182 | {
183 | this.XRange = xRange;
184 | }
185 | else
186 | {
187 | this.XRange = this.XRange.AddInterval(xRange);
188 | }
189 | if (this.YRange == null)
190 | {
191 | this.YRange = yRange;
192 | }
193 | else
194 | {
195 | this.YRange = this.YRange.AddInterval(yRange);
196 | }
197 | }
198 |
199 | public void Plot(Func function, Interv xRange, int color = -1)
200 | {
201 | double delta = xRange.Length / this.Option.SampleCount;
202 | var points = Enumerable
203 | .Range(0, this.Option.SampleCount + 1)
204 | .Select(index =>
205 | {
206 | double coord = xRange.Start + index * delta;
207 | return new Point2d(coord, function(coord));
208 | })
209 | .ToArray();
210 |
211 | this.Plot(points, color);
212 | }
213 |
214 | public ObjectId GetGraphBlock()
215 | {
216 | if (this.XRange == null || this.YRange == null)
217 | {
218 | throw new Exception("Plot undefined.");
219 | }
220 |
221 | var entIds = new List();
222 |
223 | // Ranges cannot be less than epsilon.
224 | if (this.XRange.Length < Consts.Epsilon)
225 | {
226 | this.XRange = new Interv(this.XRange.Start - Consts.Epsilon, this.XRange.End + Consts.Epsilon);
227 | }
228 | if (this.YRange.Length < Consts.Epsilon)
229 | {
230 | this.YRange = new Interv(this.YRange.Start - Consts.Epsilon, this.YRange.End + Consts.Epsilon);
231 | }
232 |
233 | // Stops
234 | double[] xStops = GraphPlotter.GetDivStops(this.Option.xDelta, this.XRange, this.Option.xRedundanceFactor);
235 | double[] yStops = GraphPlotter.GetDivStops(this.Option.yDelta, this.YRange, this.Option.yRedundanceFactor);
236 |
237 | // Grid lines
238 | var gridLines = new List();
239 | foreach (var xStop in xStops)
240 | {
241 | gridLines.Add(Draw.Line(new Point3d(xStop, this.RealRatio * yStops.First(), 0), new Point3d(xStop, this.RealRatio * yStops.Last(), 0)));
242 | }
243 | foreach (var yStop in yStops)
244 | {
245 | gridLines.Add(Draw.Line(new Point3d(xStops.First(), this.RealRatio * yStop, 0), new Point3d(xStops.Last(), this.RealRatio * yStop, 0)));
246 | }
247 | gridLines.QForEach(line => line.ColorIndex = this.Option.GridColor);
248 | entIds.AddRange(gridLines);
249 |
250 | // Labels
251 | var labels = new List();
252 | double txtHeight = this.XRange.Length / 50;
253 | foreach (var xStop in xStops)
254 | {
255 | labels.Add(Draw.MText(xStop.ToString("0.###"), txtHeight, new Point3d(xStop, this.RealRatio * yStops.First() - 2 * txtHeight, 0), 0, true));
256 | }
257 | foreach (var yStop in yStops)
258 | {
259 | labels.Add(Draw.MText(yStop.ToString("0.###"), txtHeight, new Point3d(xStops.First() - 2 * txtHeight, this.RealRatio * yStop, 0), 0, true));
260 | }
261 | labels.QForEach(mt => mt.ColorIndex = this.Option.LabelColor);
262 | entIds.AddRange(labels);
263 |
264 | // Curves
265 | foreach (var curve in this.Curves)
266 | {
267 | var plineId = Draw.Pline(curve.Item1.OrderBy(point => point.X).Select(point => new Point3d(point.X, this.RealRatio * point.Y, 0)));
268 | int color1 = curve.Item2 == -1 ? this.Option.CurveColor : curve.Item2;
269 | plineId.QOpenForWrite(pline => pline.ColorIndex = color1);
270 | entIds.Add(plineId);
271 | }
272 |
273 | // Returns a block.
274 | var result = Draw.Block(entIds, "tjGraph" + LogManager.GetTimeBasedName(), entIds.GetCenter());
275 | entIds.QForEach(entity => entity.Erase());
276 | entIds.Clear();
277 | return result;
278 | }
279 |
280 | private static double[] GetDivStops(double delta, Interv range, double redundanceFactor = 1)
281 | {
282 | var result = new List();
283 | double redundance = (redundanceFactor - 1) / 2 * range.Length;
284 | result.Add(range.Start - redundance);
285 | double start = Math.Ceiling((range.Start - redundance) / delta) * delta;
286 | for (double t = start; t < range.End + redundance; t += delta)
287 | {
288 | result.Add(t);
289 | }
290 | result.Add(range.End + redundance);
291 | return result.ToArray();
292 | }
293 | }
294 |
295 | ///
296 | /// The graph option.
297 | ///
298 | public class GraphOption
299 | {
300 | //public int xDivs = 5;
301 | //public int yDivs = 5;
302 | public double xDelta = 10;
303 | public double yDelta = 10;
304 | public double yRatio = 1;
305 | public double xRedundanceFactor = 1;
306 | public double yRedundanceFactor = 1.5;
307 | public Interv xRange = null;
308 | public Interv yRange = null;
309 | public int SampleCount = 100;
310 | public byte GridColor = 0;
311 | public byte CurveColor = 2;
312 | public byte LabelColor = 1;
313 | }
314 |
315 | public class TablePlotter
316 | {
317 | // TODO: implement this.
318 | }
319 | }
320 |
--------------------------------------------------------------------------------
/AutoCADCommands/Test.cs:
--------------------------------------------------------------------------------
1 | using Autodesk.AutoCAD.ApplicationServices;
2 | using Autodesk.AutoCAD.DatabaseServices;
3 | using Autodesk.AutoCAD.EditorInput;
4 | using Autodesk.AutoCAD.Geometry;
5 | using Autodesk.AutoCAD.Runtime;
6 | using Dreambuild.AutoCAD.Internal;
7 | using System;
8 | using System.Collections.Generic;
9 | using System.Linq;
10 |
11 | namespace Dreambuild.AutoCAD
12 | {
13 | ///
14 | /// Tests and samples
15 | ///
16 | public class CodePackTest
17 | {
18 | #region Commands that you can provide out of the box in your application
19 |
20 | ///
21 | /// View or edit custom dictionaries of DWG.
22 | ///
23 | [CommandMethod("ViewGlobalDict")]
24 | public static void ViewGlobalDict()
25 | {
26 | var dv = new DictionaryViewer(
27 | CustomDictionary.GetDictionaryNames,
28 | CustomDictionary.GetEntryNames,
29 | CustomDictionary.GetValue,
30 | CustomDictionary.SetValue
31 | );
32 | Application.ShowModalWindow(dv);
33 | }
34 |
35 | ///
36 | /// View or edit custom dictionaries of entity.
37 | ///
38 | [CommandMethod("ViewObjectDict")]
39 | public static void ViewObjectDict()
40 | {
41 | var id = Interaction.GetEntity("\nSelect entity");
42 | if (id == ObjectId.Null)
43 | {
44 | return;
45 | }
46 | var dv = new DictionaryViewer( // Currying
47 | () => CustomObjectDictionary.GetDictionaryNames(id),
48 | dict => CustomObjectDictionary.GetEntryNames(id, dict),
49 | (dict, key) => CustomObjectDictionary.GetValue(id, dict, key),
50 | (dict, key, value) => CustomObjectDictionary.SetValue(id, dict, key, value)
51 | );
52 | Application.ShowModalWindow(dv);
53 | }
54 |
55 | ///
56 | /// Eliminates zero-length polylines.
57 | ///
58 | [CommandMethod("PolyClean0", CommandFlags.UsePickSet)]
59 | public static void PolyClean0()
60 | {
61 | var ids = Interaction.GetSelection("\nSelect polyline", "LWPOLYLINE");
62 | int n = 0;
63 | ids.QForEach(poly =>
64 | {
65 | if (poly.Length == 0)
66 | {
67 | poly.Erase();
68 | n++;
69 | }
70 | });
71 | Interaction.WriteLine("{0} eliminated.", n);
72 | }
73 |
74 | ///
75 | /// Removes duplicate vertices on polyline.
76 | ///
77 | [CommandMethod("PolyClean", CommandFlags.UsePickSet)]
78 | public static void PolyClean()
79 | {
80 | var ids = Interaction.GetSelection("\nSelect polyline", "LWPOLYLINE");
81 | int m = 0;
82 | int n = 0;
83 | ids.QForEach(poly =>
84 | {
85 | int count = Algorithms.PolyClean_RemoveDuplicatedVertex(poly);
86 | if (count > 0)
87 | {
88 | m++;
89 | n += count;
90 | }
91 | });
92 | Interaction.WriteLine("{1} vertex removed from {0} polyline.", m, n);
93 | }
94 |
95 | private static double _polyClean2Epsilon = 1;
96 |
97 | ///
98 | /// Removes vertices close to others on polyline.
99 | ///
100 | [CommandMethod("PolyClean2", CommandFlags.UsePickSet)]
101 | public static void PolyClean2()
102 | {
103 | double epsilon = Interaction.GetValue("\nEpsilon", _polyClean2Epsilon);
104 | if (double.IsNaN(epsilon))
105 | {
106 | return;
107 | }
108 | _polyClean2Epsilon = epsilon;
109 |
110 | var ids = Interaction.GetSelection("\nSelect polyline", "LWPOLYLINE");
111 | int m = 0;
112 | int n = 0;
113 | ids.QForEach(poly =>
114 | {
115 | int count = Algorithms.PolyClean_ReducePoints(poly, epsilon);
116 | if (count > 0)
117 | {
118 | m++;
119 | n += count;
120 | }
121 | });
122 | Interaction.WriteLine("{1} vertex removed from {0} polyline.", m, n);
123 | }
124 |
125 | ///
126 | /// Fits arc segs of polyline with line segs.
127 | ///
128 | [CommandMethod("PolyClean3", CommandFlags.UsePickSet)]
129 | public static void PolyClean3()
130 | {
131 | double value = Interaction.GetValue("\nNumber of segs to fit an arc, 0 for smart determination", 0);
132 | if (double.IsNaN(value))
133 | {
134 | return;
135 | }
136 | int n = (int)value;
137 |
138 | var ids = Interaction.GetSelection("\nSelect polyline", "LWPOLYLINE");
139 | var entsToAdd = new List();
140 | ids.QForEach(poly =>
141 | {
142 | var pts = poly.GetPolylineFitPoints(n);
143 | var poly1 = NoDraw.Pline(pts);
144 | poly1.Layer = poly.Layer;
145 | try
146 | {
147 | poly1.ConstantWidth = poly.ConstantWidth;
148 | }
149 | catch
150 | {
151 | }
152 | poly1.XData = poly.XData;
153 | poly.Erase();
154 | entsToAdd.Add(poly1);
155 | });
156 | entsToAdd.ToArray().AddToCurrentSpace();
157 | Interaction.WriteLine("{0} handled.", entsToAdd.Count);
158 | }
159 |
160 | ///
161 | /// Regulates polyline direction.
162 | ///
163 | [CommandMethod("PolyClean4", CommandFlags.UsePickSet)]
164 | public static void PolyClean4()
165 | {
166 | double value = Interaction.GetValue("\nDirection:1-R to L;2-B to T;3-L to R;4-T to B");
167 | if (double.IsNaN(value))
168 | {
169 | return;
170 | }
171 | int n = (int)value;
172 | if (!new int[] { 1, 2, 3, 4 }.Contains(n))
173 | {
174 | return;
175 | }
176 | Algorithms.Direction dir = (Algorithms.Direction)n;
177 |
178 | var ids = Interaction.GetSelection("\nSelect polyline", "LWPOLYLINE");
179 | int m = 0;
180 | ids.QForEach(poly =>
181 | {
182 | if (Algorithms.PolyClean_SetTopoDirection(poly, dir))
183 | {
184 | m++;
185 | }
186 | });
187 | Interaction.WriteLine("{0} handled.", m);
188 | }
189 |
190 | ///
191 | /// Removes unnecessary colinear vertices on polyline.
192 | ///
193 | [CommandMethod("PolyClean5", CommandFlags.UsePickSet)]
194 | public static void PolyClean5()
195 | {
196 | Interaction.WriteLine("Not implemented yet");
197 | var ids = Interaction.GetSelection("\nSelect polyline", "LWPOLYLINE");
198 | ids.QForEach(poly =>
199 | {
200 | Algorithms.PolyClean_RemoveColinearPoints(poly);
201 | });
202 | }
203 |
204 | ///
205 | /// Breaks polylines at their intersecting points.
206 | ///
207 | [CommandMethod("PolySplit", CommandFlags.UsePickSet)]
208 | public static void PolySplit()
209 | {
210 | var ids = Interaction.GetSelection("\nSelect polyline", "LWPOLYLINE");
211 | var newPolys = new List();
212 | var pm = new ProgressMeter();
213 | pm.Start("Processing...");
214 | pm.SetLimit(ids.Length);
215 | ids.QOpenForWrite(list =>
216 | {
217 | foreach (var poly in list)
218 | {
219 | var intersectPoints = new Point3dCollection();
220 | foreach (var poly1 in list)
221 | {
222 | if (poly1 != poly)
223 | {
224 | poly.IntersectWith3264(poly1, Intersect.OnBothOperands, intersectPoints);
225 | }
226 | }
227 | var ipParams = intersectPoints
228 | .Cast()
229 | .Select(ip => poly.GetParamAtPointX(ip))
230 | .OrderBy(param => param)
231 | .ToArray();
232 | if (intersectPoints.Count > 0)
233 | {
234 | var curves = poly.GetSplitCurves(new DoubleCollection(ipParams));
235 | foreach (var curve in curves)
236 | {
237 | newPolys.Add(curve as Polyline);
238 | }
239 | }
240 | else // mod 20130227 Add to newPolys regardless of whether an intersection exists, otherwise dangling lines would be gone.
241 | {
242 | newPolys.Add(poly.Clone() as Polyline);
243 | }
244 | pm.MeterProgress();
245 | }
246 | });
247 | pm.Stop();
248 | if (newPolys.Count > 0)
249 | {
250 | newPolys.ToArray().AddToCurrentSpace();
251 | ids.QForEach(entity => entity.Erase());
252 | }
253 | Interaction.WriteLine("Broke {0} to {1}.", ids.Length, newPolys.Count);
254 | }
255 |
256 | private static double _polyTrimExtendEpsilon = 20;
257 |
258 | ///
259 | /// Handles polylines that are by a small distance longer than, shorter than, or mis-intersecting with each other.
260 | ///
261 | [CommandMethod("PolyTrimExtend", CommandFlags.UsePickSet)]
262 | public static void PolyTrimExtend() // mod 20130228
263 | {
264 | double epsilon = Interaction.GetValue("\nEpsilon", _polyTrimExtendEpsilon);
265 | if (double.IsNaN(epsilon))
266 | {
267 | return;
268 | }
269 | _polyTrimExtendEpsilon = epsilon;
270 |
271 | var visibleLayers = DbHelper
272 | .GetAllLayerIds()
273 | .QOpenForRead()
274 | .Where(layer => !layer.IsHidden && !layer.IsFrozen && !layer.IsOff)
275 | .Select(layer => layer.Name)
276 | .ToList();
277 |
278 | var ids = Interaction
279 | .GetSelection("\nSelect polyline", "LWPOLYLINE")
280 | .QWhere(pline => visibleLayers.Contains(pline.Layer) && pline.Visible)
281 | .ToArray(); // newly 20130729
282 |
283 | var pm = new ProgressMeter();
284 | pm.Start("Processing...");
285 | pm.SetLimit(ids.Length);
286 | ids.QOpenForWrite(list =>
287 | {
288 | foreach (var poly in list)
289 | {
290 | int[] indices = { 0, poly.NumberOfVertices - 1 };
291 | foreach (int index in indices)
292 | {
293 | var end = poly.GetPoint3dAt(index);
294 | foreach (var poly1 in list)
295 | {
296 | if (poly1 != poly)
297 | {
298 | var closest = poly1.GetClosestPointTo(end, false);
299 | double dist = closest.DistanceTo(end);
300 | double dist1 = poly1.StartPoint.DistanceTo(end);
301 | double dist2 = poly1.EndPoint.DistanceTo(end);
302 |
303 | double distance = poly1.GetDistToPoint(end);
304 | if (poly1.GetDistToPoint(end) > 0)
305 | {
306 | if (dist1 <= dist2 && dist1 <= dist && dist1 < epsilon)
307 | {
308 | poly.SetPointAt(index, new Point2d(poly1.StartPoint.X, poly1.StartPoint.Y));
309 | }
310 | else if (dist2 <= dist1 && dist2 <= dist && dist2 < epsilon)
311 | {
312 | poly.SetPointAt(index, new Point2d(poly1.EndPoint.X, poly1.EndPoint.Y));
313 | }
314 | else if (dist <= dist1 && dist <= dist2 && dist < epsilon)
315 | {
316 | poly.SetPointAt(index, new Point2d(closest.X, closest.Y));
317 | }
318 | }
319 | }
320 | }
321 | }
322 | pm.MeterProgress();
323 | }
324 | });
325 | pm.Stop();
326 | }
327 |
328 | ///
329 | /// Saves selection for later use.
330 | ///
331 | [CommandMethod("SaveSelection", CommandFlags.UsePickSet)]
332 | public static void SaveSelection()
333 | {
334 | var ids = Interaction.GetPickSet();
335 | if (ids.Length == 0)
336 | {
337 | Interaction.WriteLine("No entity selected.");
338 | return;
339 | }
340 | string name = Interaction.GetString("\nSelection name");
341 | if (name == null)
342 | {
343 | return;
344 | }
345 | if (CustomDictionary.GetValue("Selections", name) != string.Empty)
346 | {
347 | Interaction.WriteLine("Selection with the same name already exists.");
348 | return;
349 | }
350 | var handles = ids.QSelect(entity => entity.Handle.Value.ToString()).ToArray();
351 | string dictValue = string.Join("|", handles);
352 | CustomDictionary.SetValue("Selections", name, dictValue);
353 | }
354 |
355 | ///
356 | /// Loads previously saved selection.
357 | ///
358 | [CommandMethod("LoadSelection")]
359 | public static void LoadSelection()
360 | {
361 | string name = Gui.GetChoice("Which selection to load?", CustomDictionary.GetEntryNames("Selections").ToArray());
362 | if (name == string.Empty)
363 | {
364 | return;
365 | }
366 | string dictValue = CustomDictionary.GetValue("Selections", name);
367 | var handles = dictValue.Split('|').Select(value => new Handle(Convert.ToInt64(value))).ToList();
368 | var ids = new List();
369 | handles.ForEach(value =>
370 | {
371 | var id = ObjectId.Null;
372 | if (HostApplicationServices.WorkingDatabase.TryGetObjectId(value, out id))
373 | {
374 | ids.Add(id);
375 | }
376 | });
377 | Interaction.SetPickSet(ids.ToArray());
378 | }
379 |
380 | ///
381 | /// Converts MText to Text.
382 | ///
383 | [CommandMethod("MT2DT", CommandFlags.UsePickSet)]
384 | public static void MT2DT() // newly 20130815
385 | {
386 | var ids = Interaction.GetSelection("\nSelect MText", "MTEXT");
387 | var mts = ids.QOpenForRead().Select(mt =>
388 | {
389 | var dt = NoDraw.Text(mt.Text, mt.TextHeight, mt.Location, mt.Rotation, false, mt.TextStyleName);
390 | dt.Layer = mt.Layer;
391 | return dt;
392 | }).ToArray();
393 | ids.QForEach(mt => mt.Erase());
394 | mts.AddToCurrentSpace();
395 | }
396 |
397 | ///
398 | /// Converts Text to MText.
399 | ///
400 | [CommandMethod("DT2MT", CommandFlags.UsePickSet)]
401 | public static void DT2MT() // newly 20130815
402 | {
403 | var ids = Interaction.GetSelection("\nSelect Text", "TEXT");
404 | var dts = ids.QOpenForRead().Select(dt =>
405 | {
406 | var mt = NoDraw.MText(dt.TextString, dt.Height, dt.Position, dt.Rotation, false);
407 | mt.Layer = dt.Layer;
408 | return mt;
409 | }).ToArray();
410 | ids.QForEach(dt => dt.Erase());
411 | dts.AddToCurrentSpace();
412 | }
413 |
414 | ///
415 | /// Shows a rectangle indicating the extents of selected entities.
416 | ///
417 | [CommandMethod("ShowExtents", CommandFlags.UsePickSet)]
418 | public static void ShowExtents() // newly 20130815
419 | {
420 | var ids = Interaction.GetSelection("\nSelect entity");
421 | var extents = ids.GetExtents();
422 | var rectId = Draw.Rectang(extents.MinPoint, extents.MaxPoint);
423 | Interaction.GetString("\nPress ENTER to exit...");
424 | rectId.QOpenForWrite(rect => rect.Erase());
425 | }
426 |
427 | ///
428 | /// Closes a polyline by adding a vertex at the same position as the start rather than setting IsClosed=true.
429 | ///
430 | [CommandMethod("ClosePolyline", CommandFlags.UsePickSet)]
431 | public static void ClosePolyline()
432 | {
433 | var ids = Interaction.GetSelection("\nSelect polyline", "LWPOLYLINE");
434 | if (ids.Length == 0)
435 | {
436 | return;
437 | }
438 | if (Interaction.TaskDialog(
439 | mainInstruction: ids.Count().ToString() + " polyline(s) selected. Make sure what you select is correct.",
440 | yesChoice: "Yes, I promise.",
441 | noChoice: "No, I want to double check.",
442 | title: "AutoCAD",
443 | content: "All polylines in selection will be closed.",
444 | footer: "Abuse can mess up the drawing.",
445 | expanded: "Commonly used before export."))
446 | {
447 | //polys.QForEach(poly => LogManager.Write((poly as Polyline).Closed));
448 | ids.QForEach(poly =>
449 | {
450 | if (poly.StartPoint.DistanceTo(poly.EndPoint) > 0)
451 | {
452 | poly.AddVertexAt(poly.NumberOfVertices, poly.StartPoint.ToPoint2d(), 0, 0, 0);
453 | }
454 | });
455 | }
456 | }
457 |
458 | ///
459 | /// Detects non-simple polylines that intersect with themselves.
460 | ///
461 | [CommandMethod("DetectSelfIntersection")]
462 | public static void DetectSelfIntersection() // mod 20130202
463 | {
464 | var ids = QuickSelection.SelectAll("LWPOLYLINE").ToArray();
465 | var meter = new ProgressMeter();
466 | meter.Start("Detecting...");
467 | meter.SetLimit(ids.Length);
468 | var results = ids.QWhere(pline =>
469 | {
470 | bool result = (pline as Polyline).IsSelfIntersecting();
471 | meter.MeterProgress();
472 | System.Windows.Forms.Application.DoEvents();
473 | return result;
474 | }).ToList();
475 | meter.Stop();
476 | if (results.Count() > 0)
477 | {
478 | Interaction.WriteLine("{0} detected.", results.Count());
479 | Interaction.ZoomHighlightView(results);
480 | }
481 | else
482 | {
483 | Interaction.WriteLine("0 detected.");
484 | }
485 | }
486 |
487 | ///
488 | /// Finds entity by handle value.
489 | ///
490 | [CommandMethod("ShowObject")]
491 | public static void ShowObject()
492 | {
493 | var ids = QuickSelection.SelectAll().ToArray();
494 | double handle1 = Interaction.GetValue("Handle of entity");
495 | if (double.IsNaN(handle1))
496 | {
497 | return;
498 | }
499 | long handle2 = Convert.ToInt64(handle1);
500 | var id = HostApplicationServices.WorkingDatabase.GetObjectId(false, new Handle(handle2), 0);
501 | var col = new ObjectId[] { id };
502 | Interaction.HighlightObjects(col);
503 | Interaction.ZoomObjects(col);
504 | }
505 |
506 | ///
507 | /// Shows the shortest line to link given point to existing lines, polylines, or arcs.
508 | ///
509 | [CommandMethod("PolyLanding")]
510 | public static void PolyLanding()
511 | {
512 | var ids = QuickSelection.SelectAll("*LINE,ARC").ToArray();
513 | var landingLineIds = new List();
514 | while (true)
515 | {
516 | var p = Interaction.GetPoint("\nSpecify a point");
517 | if (p.IsNull())
518 | {
519 | break;
520 | }
521 | var landings = ids.QSelect(entity => (entity as Curve).GetClosestPointTo(p, false)).ToArray();
522 | double minDist = landings.Min(point => point.DistanceTo(p));
523 | var landing = landings.First(point => point.DistanceTo(p) == minDist);
524 | Interaction.WriteLine("Shortest landing distance of point ({0:0.00},{1:0.00}) is {2:0.00}.", p.X, p.Y, minDist);
525 | landingLineIds.Add(Draw.Line(p, landing));
526 | }
527 | landingLineIds.QForEach(entity => entity.Erase());
528 | }
529 |
530 | ///
531 | /// Shows vertics info of a polyline.
532 | ///
533 | [CommandMethod("PolylineInfo")]
534 | public static void PolylineInfo() // mod by WY 20130202
535 | {
536 | var id = Interaction.GetEntity("\nSpecify a polyline", typeof(Polyline));
537 | if (id == ObjectId.Null)
538 | {
539 | return;
540 | }
541 | var poly = id.QOpenForRead();
542 | for (int i = 0; i <= poly.EndParam; i++)
543 | {
544 | Interaction.WriteLine("[Point {0}] coord: {1}; bulge: {2}", i, poly.GetPointAtParameter(i), poly.GetBulgeAt(i));
545 | }
546 | var txtIds = new List();
547 | double height = poly.GeometricExtents.MaxPoint.DistanceTo(poly.GeometricExtents.MinPoint) / 50.0;
548 | for (int i = 0; i < poly.NumberOfVertices; i++)
549 | {
550 | txtIds.Add(Draw.MText(i.ToString(), height, poly.GetPointAtParameter(i), 0, true));
551 | }
552 | Interaction.GetString("\nPress ENTER to exit");
553 | txtIds.QForEach(mt => mt.Erase());
554 | }
555 |
556 | ///
557 | /// Selects entities on given layer.
558 | ///
559 | [CommandMethod("SelectByLayer")]
560 | public static void SelectByLayer()
561 | {
562 | var availableLayerNames = DbHelper.GetAllLayerNames();
563 | var selectedLayerNames = Gui.GetChoices("Specify layers", availableLayerNames);
564 | if (selectedLayerNames.Length < 1)
565 | {
566 | return;
567 | }
568 |
569 | var ids = QuickSelection
570 | .SelectAll(FilterList.Create().Layer(selectedLayerNames))
571 | .ToArray();
572 |
573 | Interaction.SetPickSet(ids);
574 | }
575 |
576 | ///
577 | /// Marks layer names of selected entities on the drawing by MText.
578 | ///
579 | [CommandMethod("ShowLayerName")]
580 | public static void ShowLayerName()
581 | {
582 | double height = 10;
583 | string[] range = { "By entities", "By layers" };
584 | int result = Gui.GetOption("Choose one way", range);
585 | if (result == -1)
586 | {
587 | return;
588 | }
589 | ObjectId[] ids;
590 | if (result == 0)
591 | {
592 | ids = Interaction.GetSelection("\nSelect entities");
593 | ids
594 | .QWhere(entity => !entity.Layer.Contains("_Label"))
595 | .QSelect(entity => entity.Layer)
596 | .Distinct()
597 | .Select(layer => $"{layer}_Label")
598 | .ForEach(labelLayer => DbHelper.GetLayerId(labelLayer));
599 | }
600 | else
601 | {
602 | var layers = DbHelper.GetAllLayerNames().Where(layer => !layer.Contains("_Label")).ToArray();
603 | string layerName = Gui.GetChoice("Select a layer", layers);
604 | ids = QuickSelection
605 | .SelectAll(FilterList.Create().Layer(layerName))
606 | .ToArray();
607 |
608 | DbHelper.GetLayerId($"{layerName}_Label");
609 | }
610 | var texts = new List();
611 | ids.QForEach(entity =>
612 | {
613 | string layerName = entity.Layer;
614 | if (!layerName.Contains("_Label"))
615 | {
616 | var center = entity.GetCenter();
617 | var text = NoDraw.MText(layerName, height, center, 0, true);
618 | text.Layer = $"{layerName}_Label";
619 | texts.Add(text);
620 | }
621 | });
622 | texts.ToArray().AddToCurrentSpace();
623 | }
624 |
625 | ///
626 | /// Inspects object in property palette.
627 | ///
628 | [CommandMethod("InspectObject")]
629 | public static void InspectObject()
630 | {
631 | var id = Interaction.GetEntity("\nSelect objects");
632 | if (id.IsNull)
633 | {
634 | return;
635 | }
636 | Gui.PropertyPalette(id.QOpenForRead());
637 | }
638 |
639 | #endregion
640 |
641 | #region Commands just for showing API usage
642 |
643 | [CommandMethod("TestBasicDrawing")]
644 | public void TestBasicDrawing()
645 | {
646 | // TODO: author this test.
647 | }
648 |
649 | [CommandMethod("TestTransform")]
650 | public void TestTransform()
651 | {
652 | // TODO: author this test.
653 | }
654 |
655 | [CommandMethod("TestBlock")]
656 | public void TestBlock()
657 | {
658 | var bId = Draw.Block(QuickSelection.SelectAll(), "test");
659 | // TODO: complete this test.
660 | }
661 |
662 | [CommandMethod("TestCustomDictionary")]
663 | public void TestCustomDictionary()
664 | {
665 | CustomDictionary.SetValue("dict1", "A", "apple");
666 | CustomDictionary.SetValue("dict1", "B", "orange");
667 | CustomDictionary.SetValue("dict1", "A", "banana");
668 | CustomDictionary.SetValue("dict2", "A", "peach");
669 | foreach (var dict in CustomDictionary.GetDictionaryNames())
670 | {
671 | Interaction.WriteLine(dict);
672 | }
673 | Interaction.WriteLine(CustomDictionary.GetValue("dict1", "A"));
674 | }
675 |
676 | [CommandMethod("TestDimension")]
677 | public void TestDimension()
678 | {
679 | var a = Interaction.GetPoint("\nPoint 1");
680 | var b = Interaction.GetPoint("\nPoint 2");
681 | var c = Interaction.GetPoint("\nPoint of label");
682 | Draw.Dimlin(a, b, c);
683 | }
684 |
685 | [CommandMethod("TestTaskDialog")]
686 | public void TestTaskDialog()
687 | {
688 | if (Interaction.TaskDialog("I prefer", "Work", "Life", "WLB poll", "You have to choose one...", "...and only choose one.", "No other choices."))
689 | {
690 | Interaction.WriteLine("You are promoted.");
691 | }
692 | else
693 | {
694 | Interaction.WriteLine("You are fired.");
695 | }
696 | }
697 |
698 | [CommandMethod("TestZoom")]
699 | public void TestZoom()
700 | {
701 | Interaction.ZoomExtents();
702 | }
703 |
704 | [CommandMethod("TestWipe")]
705 | public void TestWipe()
706 | {
707 | var id = Interaction.GetEntity("\nEntity");
708 | Draw.Wipeout(id);
709 | }
710 |
711 | [CommandMethod("TestRegion")]
712 | public void TestRegion()
713 | {
714 | var id = Interaction.GetEntity("\nEntity");
715 | Draw.Region(id);
716 | var point = Interaction.GetPoint("\nPick one point");
717 | Draw.Boundary(point, BoundaryType.Region);
718 | }
719 |
720 | [CommandMethod("TestOffset")]
721 | public void TestOffset()
722 | {
723 | var id = Interaction.GetEntity("\nPolyline");
724 | var poly = id.QOpenForRead();
725 | double value = Interaction.GetValue("\nOffset");
726 | poly.OffsetPoly(Enumerable.Range(0, poly.NumberOfVertices).Select(index => value).ToArray()).AddToCurrentSpace();
727 | }
728 |
729 | [CommandMethod("TestSelection")]
730 | public void TestSelection()
731 | {
732 | var point = Interaction.GetPoint("\nPoint");
733 | double value = Interaction.GetDistance("\nSize");
734 | var size = new Vector3d(value, value, 0);
735 | var ids = Interaction.GetWindowSelection(point - size, point + size);
736 | Interaction.WriteLine("{0} entities selected.", ids.Count());
737 | }
738 |
739 | [CommandMethod("TestGraph")]
740 | public void TestGraph()
741 | {
742 | var option = new GraphOption { xDelta = 20, yDelta = 0.5, yRatio = 0.5, SampleCount = 500 };
743 | var graphPlotter = new GraphPlotter(option);
744 | graphPlotter.Plot(Math.Sin, new Interv(5, 102));
745 | graphPlotter.Plot(x => Math.Cos(x) + 1, new Interv(10, 90), 3);
746 | var graph = graphPlotter.GetGraphBlock();
747 | var blockReference = new BlockReference(Point3d.Origin, graph);
748 | var first = Interaction.GetPoint("\nSpecify extent point 1");
749 | Interaction.InsertScalingEntity(blockReference, first, "\nSpecify extent point 2");
750 | }
751 |
752 | [CommandMethod("TestJigDrag")]
753 | public void TestJigDrag()
754 | {
755 | var circle = new Circle(new Point3d(), Vector3d.ZAxis, 10.0);
756 | var promptResult = Interaction.StartDrag("\nCenter:", result =>
757 | {
758 | circle.Center = result.Value;
759 | return circle;
760 | });
761 | if (promptResult.Status != PromptStatus.OK)
762 | {
763 | return;
764 | }
765 | promptResult = Interaction.StartDrag(new JigPromptDistanceOptions("\nRadius:"), (PromptDoubleResult result) =>
766 | {
767 | circle.Radius = result.Value == 0.0 ? 1e-6 : result.Value;
768 | return circle;
769 | });
770 | if (promptResult.Status == PromptStatus.OK)
771 | {
772 | circle.AddToCurrentSpace();
773 | }
774 | }
775 |
776 | [CommandMethod("TestQOpen")]
777 | public void TestQOpen()
778 | {
779 | var ids = QuickSelection.SelectAll("LWPOLYLINE").QWhere(pline => pline.GetCode() == "parcel").ToArray();
780 | ids.QForEach(poly =>
781 | {
782 | poly.ConstantWidth = 2;
783 | poly.ColorIndex = 0;
784 | });
785 | }
786 |
787 | [CommandMethod("TestSetLayer")]
788 | public void TestSetLayer()
789 | {
790 | var lineId = Draw.Line(Point3d.Origin, Point3d.Origin + Vector3d.XAxis);
791 | lineId.SetLayer("aaa");
792 | }
793 |
794 | [CommandMethod("TestGroup")]
795 | public void TestGroup()
796 | {
797 | var ids = Interaction.GetSelection("\nSelect entities");
798 | ids.Group();
799 | var groupDict = HostApplicationServices.WorkingDatabase.GroupDictionaryId.QOpenForRead();
800 | Interaction.WriteLine("{0} groups", groupDict.Count);
801 | }
802 |
803 | [CommandMethod("TestUngroup")]
804 | public void TestUngroup()
805 | {
806 | var ids = Interaction.GetSelection("\nSelect entities");
807 | Modify.Ungroup(ids);
808 | var groupDict = HostApplicationServices.WorkingDatabase.GroupDictionaryId.QOpenForRead();
809 | Interaction.WriteLine("{0} groups.", groupDict.Count);
810 | }
811 |
812 | [CommandMethod("TestHatch")]
813 | public void TestHatch()
814 | {
815 | Draw.Hatch(new[] { new Point3d(0, 0, 0), new Point3d(100, 0, 0), new Point3d(0, 100, 0) });
816 | }
817 |
818 | [CommandMethod("TestHatch2")]
819 | public void TestHatch2()
820 | {
821 | var ids = Interaction.GetSelection("\nSelect entities");
822 | Draw.Hatch(ids);
823 | }
824 |
825 | [CommandMethod("TestArc")]
826 | public void TestArc()
827 | {
828 | var point1 = Interaction.GetPoint("\nStart");
829 | Draw.Circle(point1, 5);
830 | var point2 = Interaction.GetPoint("\nMid");
831 | Draw.Circle(point2, 5);
832 | var point3 = Interaction.GetPoint("\nEnd");
833 | Draw.Circle(point3, 5);
834 | Draw.Arc3P(point1, point2, point3);
835 | }
836 |
837 | [CommandMethod("TestArc2")]
838 | public void TestArc2()
839 | {
840 | var start = Interaction.GetPoint("\nStart");
841 | Draw.Circle(start, 5);
842 | var center = Interaction.GetPoint("\nCenter");
843 | Draw.Circle(center, 5);
844 | double angle = Interaction.GetValue("\nAngle");
845 | Draw.ArcSCA(start, center, angle);
846 | }
847 |
848 | [CommandMethod("TestEllipse")]
849 | public void TestEllipse()
850 | {
851 | var center = Interaction.GetPoint("\nCenter");
852 | Draw.Circle(center, 5);
853 | var endX = Interaction.GetPoint("\nEnd of one axis");
854 | Draw.Circle(endX, 5);
855 | double radiusY = Interaction.GetValue("\nRadius of another axis");
856 | Draw.Ellipse(center, endX, radiusY);
857 | }
858 |
859 | [CommandMethod("TestSpline")]
860 | public void TestSpline()
861 | {
862 | var points = new List();
863 | while (true)
864 | {
865 | var point = Interaction.GetPoint("\nSpecify a point");
866 | if (point.IsNull())
867 | {
868 | break;
869 | }
870 | points.Add(point);
871 | Draw.Circle(point, 5);
872 | }
873 | Draw.SplineCV(points.ToArray(), true);
874 | }
875 |
876 | [CommandMethod("TestPolygon")]
877 | public void TestPolygon()
878 | {
879 | int n;
880 | while (true)
881 | {
882 | double d = Interaction.GetValue("\nNumber of edges");
883 | if (double.IsNaN(d))
884 | {
885 | return;
886 | }
887 | n = (int)d;
888 | if (n > 2)
889 | {
890 | break;
891 | }
892 | }
893 | var center = Interaction.GetPoint("\nCenter");
894 | Draw.Circle(center, 5);
895 | var end = Interaction.GetPoint("\nOne vertex");
896 | Draw.Circle(end, 5);
897 | Draw.Polygon(n, center, end);
898 | }
899 |
900 | [CommandMethod("ViewSpline")]
901 | public void ViewSpline()
902 | {
903 | var id = Interaction.GetEntity("\nSelect a spline", typeof(Spline));
904 | var spline = id.QOpenForRead();
905 | var knots = spline.NurbsData.GetKnots();
906 | var knotPoints = knots.Cast().Select(k => spline.GetPointAtParam(k)).ToList();
907 | knotPoints.ForEach(p => Draw.Circle(p, 5));
908 | }
909 |
910 | [CommandMethod("TestText")]
911 | public void TestText()
912 | {
913 | Modify.TextStyle("Tahoma", 100, 5 * Math.PI / 180, 0.8);
914 | Draw.Text("FontAbc", 100, Point3d.Origin, 0, true);
915 | }
916 |
917 | [CommandMethod("TestTable")]
918 | public void TestTable()
919 | {
920 | var contents = new List>
921 | {
922 | new List{ "1", "4", "9" },
923 | new List{ "1", "8", "27" },
924 | new List{ "1", "16", "81" },
925 | };
926 | Draw.Table(Point3d.Origin, "Numbers", contents, 5, 20, 2.5);
927 | }
928 |
929 | //[CommandMethod("PythonConsole")]
930 | //public void PythonConsole()
931 | //{
932 | // var pcw = new PyConsole();
933 | // pcw.Show();
934 | //}
935 |
936 | [CommandMethod("TestLayout")]
937 | public void TestLayout()
938 | {
939 | // TODO: verify the layout API change.
940 | var layout = LayoutManager.Current.CreateLayout("TestLayout").QOpenForRead();
941 | LayoutManager.Current.CurrentLayout = "TestLayout";
942 | var vps = layout.GetViewports();
943 | if (vps.Count > 1)
944 | {
945 | var vpId = vps[1];
946 | Layouts.SetViewport(vpId, 100, 100, new Point3d(80, 80, 0), Point3d.Origin, 1000);
947 | }
948 | }
949 |
950 | [CommandMethod("TestMeasure")]
951 | public void TestMeasure()
952 | {
953 | var id = Interaction.GetEntity("\nSelect curve");
954 | var cv = id.QOpenForRead();
955 | double length = Interaction.GetValue("\nInterval");
956 | Draw.Measure(cv, length, new DBPoint());
957 | }
958 |
959 | [CommandMethod("TestDivide")]
960 | public void TestDivide()
961 | {
962 | var id = Interaction.GetEntity("\nSelect curve");
963 | var cv = id.QOpenForRead();
964 | int num = (int)Interaction.GetValue("\nNumbers");
965 | Draw.Divide(cv, num, new DBPoint());
966 | }
967 |
968 | [CommandMethod("TestBoundary")]
969 | public void TestBoundary()
970 | {
971 | var point = Interaction.GetPoint("\nPick one point");
972 | Draw.Boundary(point, BoundaryType.Polyline);
973 | }
974 |
975 | [CommandMethod("TestHatch3")]
976 | public void TestHatch3()
977 | {
978 | var seed = Interaction.GetPoint("\nPick one point");
979 | Draw.Hatch("SOLID", seed);
980 | }
981 |
982 | [CommandMethod("TestHatch4")]
983 | public void TestHatch4()
984 | {
985 | var ids = Interaction.GetSelection("\nSelect entities");
986 | var ents = ids.QSelect(entity => entity).ToArray();
987 | Draw.Hatch("SOLID", ents);
988 | }
989 |
990 | [CommandMethod("TestPolygonMesh")]
991 | public void TestPolygonMesh()
992 | {
993 | int m = 100;
994 | int n = 100;
995 | double f(double x, double y) => 10 * Math.Cos((x * x + y * y) / 1000);
996 |
997 | var points = new List();
998 | for (int i = 0; i < m; i++)
999 | {
1000 | for (int j = 0; j < n; j++)
1001 | {
1002 | double x = 10 * i + 10;
1003 | double y = 10 * j + 10;
1004 | double z = f(x, y);
1005 | points.Add(new Point3d(x, y, z));
1006 | }
1007 | }
1008 |
1009 | Draw.PolygonMesh(points, m, n);
1010 | }
1011 |
1012 | [CommandMethod("TestAddAttribute")]
1013 | public void TestAppendAttribute()
1014 | {
1015 | var id = Draw.Insert("test", Point3d.Origin);
1016 | var attribute = new AttributeReference
1017 | {
1018 | Tag = "test",
1019 | TextString = "test value",
1020 | Position = Point3d.Origin
1021 | };
1022 |
1023 | id.QOpenForWrite(br =>
1024 | {
1025 | // using default overwrite and createIfMissing
1026 | br.AppendAttribute(attribute);
1027 | });
1028 | }
1029 |
1030 | [CommandMethod("TestKeywords")]
1031 | public void TestKeywords()
1032 | {
1033 | string[] keys = { "A", "B", "C", "D" };
1034 | var key = Interaction.GetKeywords("\nChoose an option", keys, 3);
1035 | Interaction.WriteLine("You chose {0}.", key);
1036 | }
1037 |
1038 | #endregion
1039 | }
1040 | }
1041 |
--------------------------------------------------------------------------------
/AutoCADCommands/Tuples.cs:
--------------------------------------------------------------------------------
1 | namespace Dreambuild.AutoCAD
2 | {
3 | public class Tuple
4 | {
5 | public T1 Item1 { get; }
6 | public T2 Item2 { get; }
7 |
8 | public Tuple(T1 item1, T2 item2)
9 | {
10 | Item1 = item1;
11 | Item2 = item2;
12 | }
13 | }
14 |
15 | public class Tuple
16 | {
17 | public T1 Item1 { get; }
18 | public T2 Item2 { get; }
19 | public T3 Item3 { get; }
20 |
21 | public Tuple(T1 item1, T2 item2, T3 item3)
22 | {
23 | Item1 = item1;
24 | Item2 = item2;
25 | Item3 = item3;
26 | }
27 | }
28 |
29 | public class Tuple
30 | {
31 | public T1 Item1 { get; }
32 | public T2 Item2 { get; }
33 | public T3 Item3 { get; }
34 | public T4 Item4 { get; }
35 |
36 | public Tuple(T1 item1, T2 item2, T3 item3, T4 item4)
37 | {
38 | Item1 = item1;
39 | Item2 = item2;
40 | Item3 = item3;
41 | Item4 = item4;
42 | }
43 | }
44 |
45 | public class Tuple
46 | {
47 | public T1 Item1 { get; }
48 | public T2 Item2 { get; }
49 | public T3 Item3 { get; }
50 | public T4 Item4 { get; }
51 | public T5 Item5 { get; }
52 |
53 | public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
54 | {
55 | Item1 = item1;
56 | Item2 = item2;
57 | Item3 = item3;
58 | Item4 = item4;
59 | Item5 = item5;
60 | }
61 | }
62 |
63 | public class Tuple
64 | {
65 | public T1 Item1 { get; }
66 | public T2 Item2 { get; }
67 | public T3 Item3 { get; }
68 | public T4 Item4 { get; }
69 | public T5 Item5 { get; }
70 | public T6 Item6 { get; }
71 |
72 | public Tuple(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
73 | {
74 | Item1 = item1;
75 | Item2 = item2;
76 | Item3 = item3;
77 | Item4 = item4;
78 | Item5 = item5;
79 | Item6 = item6;
80 | }
81 | }
82 |
83 | public static class Tuple
84 | {
85 | public static Tuple Create(T1 item1, T2 item2)
86 | {
87 | return new Tuple(item1, item2);
88 | }
89 |
90 | public static Tuple Create(T1 item1, T2 item2, T3 item3)
91 | {
92 | return new Tuple(item1, item2, item3);
93 | }
94 |
95 | public static Tuple Create(T1 item1, T2 item2, T3 item3, T4 item4)
96 | {
97 | return new Tuple(item1, item2, item3, item4);
98 | }
99 |
100 | public static Tuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5)
101 | {
102 | return new Tuple(item1, item2, item3, item4, item5);
103 | }
104 |
105 | public static Tuple Create(T1 item1, T2 item2, T3 item3, T4 item4, T5 item5, T6 item6)
106 | {
107 | return new Tuple(item1, item2, item3, item4, item5, item6);
108 | }
109 | }
110 | }
--------------------------------------------------------------------------------
/AutoCADCommands/packages.config:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Jan Kozik
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # AutoCAD Code Pack
2 |
3 | *Previously hosted on [CodePlex](https://acadcodepack.codeplex.com/). *
4 |
5 | `AutoCAD Code Pack` is a powerful library that helps you to develop AutoCAD plugins using the AutoCAD .NET API. It re-encapsulates the over-designed and old-fashioned classes and methods into easy-to-use static modules and functions. It also brings modern C# syntax like LINQ and lambdas (functional programming) to AutoCAD development. With all the features it provides, you can save over half the lines of your code.
6 |
7 | The library was originally developed for AutoCAD R18 (2010, 2011, 2012) and .NET 3.5. We recently updated it to target AutoCAD R23 (2019) and .NET 4.7.1, thanks to the contribution from [@lavantgarde](https://github.com/lavantgarde). Due to the popularity of old AutoCAD versions, we also provide compatibility projects for R18 and R19.
8 |
9 | View [Test.cs](https://github.com/jankozik/AutoCAD_CodePack/blob/master/AutoCADCommands/Test.cs) for API usage examples.
10 |
11 | Don't forget to star us! If you think this library is helpful, please tell others to have a try too. We can't wait to hear all your feedbacks.
12 |
13 | ## Modules
14 |
15 | The library consists of the following modules:
16 |
17 | * `Draw` to directly draw entities (with AutoCAD-command-like functions)
18 | * `NoDraw` to create in-memory entities
19 | * `Modify` to edit entities (with AutoCAD-command-like functions)
20 | * `Annotation` to draw annotations
21 | * `DbHelper` to manipulate the DWG database
22 | * `QuickSelection` to simplify entity manipulation with LINQ style coding experience (like jQuery, if you know some Web)
23 | * `Interaction` to handle user interactions
24 | * `Algorithms` to offer some mathematical helpers
25 | * `MultiDoc` to process cross-document scenarios
26 | * `CustomDictionary` to help you attach data to entities
27 | * `SymbolPack` to help you draw symbols like arrows, etc.
28 | * `IronPython` to allow you use IronPython in AutoCAD
29 |
30 | ## A Quick Look
31 |
32 | You may write this elegant code with the code pack. Let's say you want a command to clean up all 0-length polylines.
33 |
34 | ```csharp
35 | [CommandMethod("PolyClean0", CommandFlags.UsePickSet)]
36 | public static void PolyClean0()
37 | {
38 | var ids = Interaction.GetSelection("\nSelect polyline", "LWPOLYLINE");
39 | int n = 0;
40 | ids.QForEach(poly =>
41 | {
42 | if (poly.Length == 0)
43 | {
44 | poly.Erase();
45 | n++;
46 | }
47 | });
48 | Interaction.WriteLine("{0} eliminated.", n);
49 | }
50 | ```
51 |
52 | Crazy simple, right? Can you imagine how much extra code you would have to write using the original API:
53 |
54 | ```csharp
55 | [CommandMethod("PolyClean0_Old", CommandFlags.UsePickSet)]
56 | public static void PolyClean0_Old()
57 | {
58 | string message = "\nSelect polyline";
59 | string allowedType = "LWPOLYLINE";
60 | Editor ed = Application.DocumentManager.MdiActiveDocument.Editor;
61 | PromptSelectionOptions opt = new PromptSelectionOptions
62 | {
63 | MessageForAdding = message
64 | };
65 | ed.WriteMessage(message);
66 | SelectionFilter filter = new SelectionFilter(
67 | new TypedValue[]
68 | {
69 | new TypedValue(0, allowedType)
70 | });
71 | PromptSelectionResult res = ed.GetSelection(opt, filter);
72 | if (res.Status != PromptStatus.OK)
73 | {
74 | return;
75 | }
76 | ObjectId[] ids = res.Value.GetObjectIds();
77 | int n = 0;
78 | Database db = HostApplicationServices.WorkingDatabase;
79 | using (Transaction trans = db.TransactionManager.StartTransaction())
80 | {
81 | foreach (ObjectId id in ids)
82 | {
83 | Polyline poly = trans.GetObject(id, OpenMode.ForWrite) as Polyline;
84 | if (poly.Length == 0)
85 | {
86 | poly.Erase();
87 | n++;
88 | }
89 | }
90 | trans.Commit();
91 | }
92 | ed.WriteMessage("{0} eliminated.", n);
93 | }
94 | ```
95 |
96 | ## Examples
97 |
98 | View [Test.cs](https://github.com/luanshixia/AutoCADCodePack/blob/master/AutoCADCommands/Test.cs) for detailed API usage examples.
99 |
100 | ## PS: A useful tool for those who have a lot of huge DWGs and VS projects on disk
101 |
102 | [SharpDiskSweeper](https://github.com/luanshixia/SharpDiskSweeper) can help you find the point in disk to start cleaning up.
103 |
--------------------------------------------------------------------------------
/Reference/AutoCAD/r18/AcCui.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jankozik/AutoCAD_CodePack/0ac7a998b05cabd92daa11c1ef28f98fa5831340/Reference/AutoCAD/r18/AcCui.dll
--------------------------------------------------------------------------------
/Reference/AutoCAD/r18/AcTcMgd.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jankozik/AutoCAD_CodePack/0ac7a998b05cabd92daa11c1ef28f98fa5831340/Reference/AutoCAD/r18/AcTcMgd.dll
--------------------------------------------------------------------------------
/Reference/AutoCAD/r18/AcWindows.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jankozik/AutoCAD_CodePack/0ac7a998b05cabd92daa11c1ef28f98fa5831340/Reference/AutoCAD/r18/AcWindows.dll
--------------------------------------------------------------------------------
/Reference/AutoCAD/r18/AdWindows.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jankozik/AutoCAD_CodePack/0ac7a998b05cabd92daa11c1ef28f98fa5831340/Reference/AutoCAD/r18/AdWindows.dll
--------------------------------------------------------------------------------
/Reference/AutoCAD/r18/acdbmgd.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jankozik/AutoCAD_CodePack/0ac7a998b05cabd92daa11c1ef28f98fa5831340/Reference/AutoCAD/r18/acdbmgd.dll
--------------------------------------------------------------------------------
/Reference/AutoCAD/r18/acmgd.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jankozik/AutoCAD_CodePack/0ac7a998b05cabd92daa11c1ef28f98fa5831340/Reference/AutoCAD/r18/acmgd.dll
--------------------------------------------------------------------------------
/Reference/AutoCAD/r19/AcCoreMgd.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jankozik/AutoCAD_CodePack/0ac7a998b05cabd92daa11c1ef28f98fa5831340/Reference/AutoCAD/r19/AcCoreMgd.dll
--------------------------------------------------------------------------------
/Reference/AutoCAD/r19/AcCui.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jankozik/AutoCAD_CodePack/0ac7a998b05cabd92daa11c1ef28f98fa5831340/Reference/AutoCAD/r19/AcCui.dll
--------------------------------------------------------------------------------
/Reference/AutoCAD/r19/AcDbMgd.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jankozik/AutoCAD_CodePack/0ac7a998b05cabd92daa11c1ef28f98fa5831340/Reference/AutoCAD/r19/AcDbMgd.dll
--------------------------------------------------------------------------------
/Reference/AutoCAD/r19/AcMgd.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jankozik/AutoCAD_CodePack/0ac7a998b05cabd92daa11c1ef28f98fa5831340/Reference/AutoCAD/r19/AcMgd.dll
--------------------------------------------------------------------------------
/Reference/AutoCAD/r19/AcTcMgd.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jankozik/AutoCAD_CodePack/0ac7a998b05cabd92daa11c1ef28f98fa5831340/Reference/AutoCAD/r19/AcTcMgd.dll
--------------------------------------------------------------------------------
/Reference/AutoCAD/r19/AcWindows.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jankozik/AutoCAD_CodePack/0ac7a998b05cabd92daa11c1ef28f98fa5831340/Reference/AutoCAD/r19/AcWindows.dll
--------------------------------------------------------------------------------
/Reference/AutoCAD/r19/AdWindows.dll:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/jankozik/AutoCAD_CodePack/0ac7a998b05cabd92daa11c1ef28f98fa5831340/Reference/AutoCAD/r19/AdWindows.dll
--------------------------------------------------------------------------------