Управляемая альтернатива ExplodeAllProxy
Андрей Бушман у себя на сайте опубликовал код, решающий те же задачи, что и знаменитый ExplodeAllProxy от Александра Ривилиса. Пользуясь выцыганенным у Андрея разрешением, публикую мои изменения его кода.
Прежде всего, хочу предупредить о следующем:
- Я не автор кода. Я не знаю и не понимаю, как он работает. Я не в силах его повторить. Все, что я могу сказать - это "обращайтесь на сайт Андрея"
- Ниже показан исправленный мною код. Я поменял код так, чтобы хоть что-то в нем понять (Андрей, прости!)
- После этого указаны ссылки со скомпилированными .NET-сборками для AutoCAD 2009-2015. Компилировалось в условиях 64-разрядной ОС. На 32-битных Windows / ACAD работу библиотек не проверял. Загрузка и работа проверены на ACAD2009, 2013, 2015
Итак, собственно класс, выполняющий саму работу:
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 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 | using System; using System.Collections.Generic; using System.Linq; using System.Diagnostics; using System.IO; using cad = Autodesk.AutoCAD.ApplicationServices.Application; using Ap = Autodesk.AutoCAD.ApplicationServices; using Db = Autodesk.AutoCAD.DatabaseServices; using Ed = Autodesk.AutoCAD.EditorInput; using Rt = Autodesk.AutoCAD.Runtime; using Gm = Autodesk.AutoCAD.Geometry; namespace gunipcProxy { public delegate void WriteMessage(String format, params Object[] args); public static class ExtensionMethods { static Rt.RXClass proxyObjectRXType = Rt.RXClass.GetClass(typeof( Db.ProxyObject)); static Rt.RXClass proxyEntityRXType = Rt.RXClass.GetClass(typeof( Db.ProxyEntity)); public static Db.ObjectId[] GetDBObjectIds(this Db.Database db) { Db.ObjectId[] ids = GetDBObjectIds(db, (n => true)); return ids; } public static Db.ObjectId[] GetDBObjectIds(this Db.Database db, Func<Db.ObjectId, Boolean> filter) { // Check arguments if (null == db) throw new ArgumentNullException("null == db"); if (null == filter) throw new ArgumentNullException("null == filter"); if (db.IsDisposed) throw new ArgumentException("true == db.IsDisposed"); // ------------------- Int32 approxNum = db.ApproxNumObjects; List<Db.ObjectId> ids = new List<Db.ObjectId>(); for (Int64 i = db.BlockTableId.Handle.Value; i < db.Handseed.Value && approxNum > 0; ++i) { Db.Handle h = new Db.Handle(i); Db.ObjectId id = Db.ObjectId.Null; Boolean parseResult = db.TryGetObjectId(h, out id); if (parseResult) { --approxNum; if (filter(id)) { ids.Add(id); } } } return ids.ToArray(); } public static Db.ObjectId[] GetEntityIds(this Db.Database db) { Db.ObjectId[] ids = GetEntityIds(db, (n => true)); return ids; } public static Db.ObjectId[] GetEntityIds(this Db.Database db, Func<Db.ObjectId, Boolean> filter) { // Check arguments if (null == db) throw new ArgumentNullException("null == db"); if (null == filter) throw new ArgumentNullException("null == filter"); if (db.IsDisposed) throw new ArgumentException("true == db.IsDisposed"); // ------------------- List<Db.ObjectId> ids = new List<Db.ObjectId>(); // Entity items can be located in the BlockTableRecord instances // only. using (Db.Transaction tr = db.TransactionManager.StartTransaction() ) { Db.BlockTable bt = tr.GetObject(db.BlockTableId, Db.OpenMode.ForRead) as Db.BlockTable; // Skip erased BlockTableRecord instances. IEnumerable<Db.ObjectId> btrIds = bt.Cast<Db.ObjectId>() .Where(n => !n.IsErased); foreach (Db.ObjectId btrId in btrIds) { Db.BlockTableRecord btr = tr.GetObject(btrId, Db.OpenMode.ForRead) as Db.BlockTableRecord; foreach (Db.ObjectId id in btr) { if (filter(id)) { ids.Add(id); } } } tr.Commit(); } return ids.ToArray(); } public static Db.ObjectId[] ExplodeProxyEntity(Db.ObjectId proxyEntityId, out Boolean handOverTo_called, out Int64 explodedCount, WriteMessage writeErrorMessage) { // Check arguments if (null == proxyEntityId) throw new ArgumentException("null == proxyEntityId"); if (proxyEntityId.IsErased) throw new ArgumentException("true == proxyEntityId.IsErased"); if (null == proxyEntityId.Database) throw new ArgumentException("null == proxyEntityId.Database"); if (proxyEntityId.Database.IsDisposed) throw new ArgumentException( "true == proxyEntityId.Database.IsDisposed"); if (!proxyEntityId.ObjectClass.IsDerivedFrom(proxyEntityRXType)) throw new ArgumentException("false == proxyEntityId." + "ObjectClass.IsDerivedFrom(proxyEntityRXType)"); explodedCount = 0; // ------------------- using (Db.DBObjectCollection newDBObjects = new Db.DBObjectCollection()) { Db.Database db = proxyEntityId.Database; List<Db.ObjectId> result = new List<Db.ObjectId>(); using (Db.Transaction tr = db.TransactionManager .StartOpenCloseTransaction()) { Db.ProxyEntity proxyEntity = tr.GetObject( proxyEntityId, Db.OpenMode.ForWrite, false, true) as Db.ProxyEntity; if (proxyEntity.GraphicsMetafileType == Db.GraphicsMetafileType.FullGraphics) { try { proxyEntity.Explode(newDBObjects); ++explodedCount; } catch (Exception ex) { #if !DEBUG writeErrorMessage( "ObjectId: {0}. Error message: {1}\n", proxyEntity.ObjectId, ex.Message); #endif } } else if (proxyEntity.GraphicsMetafileType == Db.GraphicsMetafileType.BoundingBox) { Db.Extents3d ext = proxyEntity.GeometricExtents; Gm.Point3dCollection arr = new Gm.Point3dCollection(); arr.Add(ext.MinPoint); arr.Add(new Gm.Point3d(ext.MinPoint.X, ext.MaxPoint.Y, ext.MinPoint.Z)); arr.Add(new Gm.Point3d(ext.MaxPoint.X, ext.MaxPoint.Y, ext.MinPoint.Z)); arr.Add(new Gm.Point3d(ext.MaxPoint.X, ext.MinPoint.Y, ext.MinPoint.Z)); Db.Polyline3d pline = new Db.Polyline3d( Db.Poly3dType.SimplePoly, arr, true); pline.LayerId = proxyEntity.LayerId; pline.LinetypeId = proxyEntity.LinetypeId; pline.Color = proxyEntity.Color; newDBObjects.Add(pline); } Db.BlockTableRecord btr = tr.GetObject( proxyEntity.BlockId, Db.OpenMode.ForWrite, false) as Db.BlockTableRecord; // ---------------- Boolean canBeErased = (proxyEntity.ProxyFlags & 0x1) != 0; if (canBeErased) { proxyEntity.Erase(); handOverTo_called = false; } else { using (Db.Line tmp = new Db.Line()) { proxyEntity.HandOverTo(tmp, false, false); tmp.Erase(); proxyEntity.Dispose(); handOverTo_called = true; } } if (newDBObjects.Count > 0) { foreach (Db.DBObject item in newDBObjects) { if (item is Db.Entity) { Db.Entity _ent = item as Db.Entity; btr.AppendEntity(_ent); tr.AddNewlyCreatedDBObject(item, true); result.Add(item.ObjectId); } } } Db.ObjectIdCollection idsRef = btr.GetBlockReferenceIds(true, true); foreach (Db.ObjectId id in idsRef) { Db.BlockReference br = tr.GetObject(id, Db.OpenMode.ForWrite, false) as Db.BlockReference; br.RecordGraphicsModified(true); } tr.Commit(); } return result.ToArray(); } } public static void RemoveDBObject(Db.ObjectId id, out Boolean handOverTo_called) { // Check arguments if (null == id) throw new ArgumentException("null == id"); if (id.IsErased) throw new ArgumentException("true == id.IsErased"); if (null == id.Database) throw new ArgumentException("null == id.Database"); if (id.Database.IsDisposed) throw new ArgumentException("true == id.Database.IsDisposed"); // ------------------- Db.Database db = id.Database; using (Db.Transaction tr = db.TransactionManager .StartOpenCloseTransaction()) { Db.DBObject obj = tr.GetObject(id, Db.OpenMode.ForWrite, false, true); EraseDBObject(obj, out handOverTo_called); tr.Commit(); } } private static void EraseDBObject(Db.DBObject obj, out Boolean handOverTo_called) { // Check argument if (null == obj) throw new ArgumentNullException("null == obj"); if (obj.IsErased) throw new ArgumentException("true == obj.IsErased"); if (obj.IsDisposed) throw new ArgumentException("true == obj.IsDisposed"); if (null == obj.Database) throw new ArgumentException("null == obj.Database"); if (obj.Database.IsDisposed) throw new ArgumentException("true == obj.Database.IsDisposed"); // ---------------- Boolean canBeErased = true; // AcDbProxyEntity::kEraseAllowed = 0x1 if (obj is Db.ProxyObject) { Db.ProxyObject proxy = obj as Db.ProxyObject; canBeErased = (proxy.ProxyFlags & 0x1) != 0; } else if (obj is Db.ProxyEntity) { Db.ProxyEntity proxy = obj as Db.ProxyEntity; canBeErased = (proxy.ProxyFlags & 0x1) != 0; } if (canBeErased) { obj.Erase(true); handOverTo_called = false; } else { using (Db.DBObject tmp = obj is Db.Entity ? (Db.DBObject)new Db.Line() : new Db.DBDictionary()) { obj.HandOverTo(tmp, false, false); tmp.Erase(true); obj.Dispose(); handOverTo_called = true; } } } public static Db.ObjectId[] GetFreeAnnotativeScaleIds(this Db.Database db) { // Check argument if (null == db) throw new ArgumentNullException("null == db"); if (db.IsDisposed) throw new ArgumentException("true == db.IsDisposed"); // ---------------- using (Db.ObjectIdCollection ids = new Db.ObjectIdCollection()) { Db.ObjectContextManager ocMng = db.ObjectContextManager; if (null != ocMng) { Db.ObjectContextCollection ocItems = ocMng.GetContextCollection("ACDB_ANNOTATIONSCALES"); if (null != ocItems) { foreach (Db.ObjectContext item in ocItems) { // This check is necessary for BricsCAD older // than v15.1.02: if (item is Db.AnnotationScale && String.Compare( item.Name, db.Cannoscale.Name) != 0) { ids.Add(new Db.ObjectId(item.UniqueIdentifier) ); } } db.Purge(ids); } } return ids.Cast<Db.ObjectId>().Where(n => !n.IsErased && !n.IsEffectivelyErased).ToArray(); } } public static void RemoveFreeAnnotativeScales(this Db.Database db) { // Check argument if (null == db) throw new ArgumentNullException("null == db"); if (db.IsDisposed) throw new ArgumentException("true == db.IsDisposed"); // ----------------- Db.ObjectId[] ids = db.GetFreeAnnotativeScaleIds(); using (Db.Transaction tr = db.TransactionManager.StartTransaction() ) { foreach (Db.ObjectId id in ids) { try { Db.DBObject obj = tr.GetObject(id, Db.OpenMode .ForWrite, false); obj.Erase(); } catch { } } tr.Commit(); } } } public static class ProxyFunctionality { public static void Proxy_ShowInfo() { Ap.Document doc = cad.DocumentManager.MdiActiveDocument; if (null == doc) return; Ed.Editor ed = doc.Editor; Db.Database db = doc.Database; using (doc.LockDocument()) { // Proxy types Rt.RXClass proxyObjectRXType = Rt.RXClass.GetClass(typeof(Db.ProxyObject)); Rt.RXClass proxyEntityRXType = Rt.RXClass.GetClass(typeof(Db.ProxyEntity)); // Filters Func<Db.ObjectId, Boolean> proxyEntityFilter = n => !n.IsErased && !n.IsEffectivelyErased && n.ObjectClass.IsDerivedFrom(proxyEntityRXType); Func<Db.ObjectId, Boolean> proxyObjectFilter = n => !n.IsErased && !n.IsEffectivelyErased && n.ObjectClass.IsDerivedFrom(proxyObjectRXType); // Filtered ids Db.ObjectId[] proxyEntityIds = db.GetEntityIds(proxyEntityFilter); Db.ObjectId[] proxyObjectIds = db.GetDBObjectIds(proxyObjectFilter); ed.WriteMessage("{0} ProxyEntity and {1} ProxyObject items found.\n", proxyEntityIds.Length.ToString(), proxyObjectIds.Length.ToString()); } } public static void Proxy_ExplodeAllProxyEntities(Boolean ShowReport) { Ap.Document doc = cad.DocumentManager.MdiActiveDocument; if (null == doc) return; Ed.Editor ed = doc.Editor; Db.Database db = doc.Database; using (doc.LockDocument()) { Rt.RXClass proxyEntityRXType = Rt.RXClass.GetClass(typeof(Db.ProxyEntity)); Func<Db.ObjectId, Boolean> proxyEntityFilter = n => !n.IsErased && !n.IsEffectivelyErased && n.ObjectClass.IsDerivedFrom(proxyEntityRXType); Db.ObjectId[] proxyEntityIds = db.GetEntityIds(proxyEntityFilter); Int64 newEntityCount = 0; Int64 handOverTo_entity_count = 0; Int64 explodedCount = 0; foreach (Db.ObjectId id in proxyEntityIds) { Boolean handOverTo_called = false; Int64 tmp_explodedCount = 0; Db.ObjectId[] newEntityIds = gunipcProxy.ExtensionMethods.ExplodeProxyEntity(id, out handOverTo_called, out tmp_explodedCount, ed.WriteMessage); newEntityCount += newEntityIds.Length; explodedCount += tmp_explodedCount; if (handOverTo_called) ++handOverTo_entity_count; } try { /* Remove erased objects from memory. * An exception occurs if erasedIds contain ids which was * removed from memory already. There is no method to check * it in advance. */ Db.ObjectId[] erasedIds = db.GetDBObjectIds(n => n.IsErased ); /* This checking is neccessary, bacause if erasedIds * .Length == 0 we get an exception in the * ObjectIdCollection initialization. */ if (erasedIds.Length > 0) { using (Db.ObjectIdCollection ids = new Db.ObjectIdCollection(erasedIds)) { db.ReclaimMemoryFromErasedObjects(ids); } } } catch {/* nothing here */ } if (ShowReport) { ed.WriteMessage("{0} ProxyEntity items found.\n", proxyEntityIds.Length.ToString()); ed.WriteMessage("{0} ProxyEntity items exloded.\n", explodedCount); ed.WriteMessage("{0} new DBObjects created.\n", newEntityCount.ToString()); ed.WriteMessage("Count of 'HandOverTo' operations: {0}.\n", handOverTo_entity_count.ToString()); ed.WriteMessage("Run the _AUDIT command with the _Y option, " + "please.\n"); } } } public static void Proxy_RemoveAllProxyObjests(Boolean ShowReport) { Ap.Document doc = cad.DocumentManager.MdiActiveDocument; if (null == doc) return; Ed.Editor ed = doc.Editor; Db.Database db = doc.Database; using (doc.LockDocument()) { Rt.RXClass proxyObjectRXType = Rt.RXClass.GetClass(typeof( Db.ProxyObject)); Rt.RXClass proxyEntityRXType = Rt.RXClass.GetClass(typeof( Db.ProxyEntity)); Func<Db.ObjectId, Boolean> proxyObjectFilter = n => !n.IsErased && !n.IsEffectivelyErased && n.ObjectClass.IsDerivedFrom(proxyObjectRXType); Func<Db.ObjectId, Boolean> proxyEntityFilter = n => !n.IsErased && !n.IsEffectivelyErased && n.ObjectClass.IsDerivedFrom(proxyEntityRXType); Db.ObjectId[] proxyObjectIds = db.GetDBObjectIds(proxyObjectFilter); Db.ObjectId[] proxyEntityIds = db.GetEntityIds(proxyEntityFilter); Int64 handOverTo_object_count = 0; Int64 handOverTo_entity_count = 0; foreach (Db.ObjectId id in proxyObjectIds) { Boolean handOverTo_called = false; gunipcProxy.ExtensionMethods.RemoveDBObject(id, out handOverTo_called); if (handOverTo_called) ++handOverTo_object_count; } if (ShowReport) { ed.WriteMessage("{0} ProxyObject items found and removed.\n", proxyObjectIds.Length.ToString()); ed.WriteMessage("Count of 'HandOverTo' operations: {0}.\n\n", handOverTo_object_count.ToString()); } foreach (Db.ObjectId id in proxyEntityIds) { Boolean handOverTo_called = false; gunipcProxy.ExtensionMethods.RemoveDBObject(id, out handOverTo_called); if (handOverTo_called) ++handOverTo_entity_count; } try { /* Remove erased objects from memory. * An exception occurs if erasedIds contain ids which was * removed from memory already. There is no method to check * it in advance. */ Db.ObjectId[] erasedIds = db.GetDBObjectIds(n => n.IsErased ); /* This checking is neccessary, bacause if erasedIds * .Length == 0 we get an exception in the * ObjectIdCollection initialization. */ if (erasedIds.Length > 0) { using (Db.ObjectIdCollection ids = new Db.ObjectIdCollection(erasedIds)) { db.ReclaimMemoryFromErasedObjects(ids); } } } catch {/* nothing here */ } if (ShowReport) { ed.WriteMessage("{0} ProxyEntity items found and removed.\n", proxyEntityIds.Length.ToString()); ed.WriteMessage("Count of 'HandOverTo' operations: {0}.\n\n", handOverTo_entity_count.ToString()); ed.WriteMessage("Run the _AUDIT command with the _Y option, " + "please.\n"); } } } } } |
Ну и обертки: команды и лисп-функции
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 | using System; using System.Collections.Generic; using System.Linq; using System.Text; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Runtime; using Autodesk.AutoCAD.Geometry; // [assembly: Rt.CommandClass(typeof(gunipcProxy.ProxyCommands))] namespace ProxyObjectsClear { public class ProxyCommands { [CommandMethod("ProxyInfo", CommandFlags.Modal)] public static void cmd_ProxyShow() { gunipcProxy.ProxyFunctionality.Proxy_ShowInfo(); } [LispFunction("ProxyInfo")] public static ResultBuffer lisp_ProxyShow() { gunipcProxy.ProxyFunctionality.Proxy_ShowInfo(); return null; } [CommandMethod("ProxyExplode", CommandFlags.Modal)] public static void cmd_ProxyExplode() { gunipcProxy.ProxyFunctionality.Proxy_ExplodeAllProxyEntities(true); } [LispFunction("ProxyExplode")] public static ResultBuffer lisp_ProxyExplode() { gunipcProxy.ProxyFunctionality.Proxy_ExplodeAllProxyEntities(true); return null; } [CommandMethod("ProxyRemove", CommandFlags.Modal)] public static void cmd_ProxyRemove() { gunipcProxy.ProxyFunctionality.Proxy_RemoveAllProxyObjests(true); } [LispFunction("ProxyRemove")] public static ResultBuffer lisp_ProxyRemove() { gunipcProxy.ProxyFunctionality.Proxy_RemoveAllProxyObjests(true); return null; } [CommandMethod("ProxyClear", CommandFlags.Modal)] public static void cmd_ProxyClear() { gunipcProxy.ProxyFunctionality.Proxy_ExplodeAllProxyEntities(false); gunipcProxy.ProxyFunctionality.Proxy_RemoveAllProxyObjests(true); } [LispFunction("_ProxyClear")] public static ResultBuffer lisp_ProxyClear(ResultBuffer buffer) { gunipcProxy.ProxyFunctionality.Proxy_ExplodeAllProxyEntities(false); gunipcProxy.ProxyFunctionality.Proxy_RemoveAllProxyObjests(false); return null; } } } |
Если читать все лень, то: библиотека прописывает в AutoCAD
Команда ProxyInfo |
Выводит в командную строку сообщение об обнаруженных прокси-объектах |
Лисп-функция (ProxyInfo) |
То же |
Команда ProxyExplode |
Разбивает все графические прокси-объекты |
Лисп-функция (ProxyExplode) |
То же |
Команда ProxyRemove |
Удаляет неразбитые и неграфические прокси-объекты |
Лисп-функция (ProxyRemove) |
То же |
Команда ProxyClear |
Совмещает разбиение и очистку прокси-объектов |
Лисп-функция(ProxyClear) |
То же |
Собственно архивы:
ACAD 2009
ACAD 2010
ACAD 2011
ACAD 2012
ACAD 2013
ACAD 2014
ACAD 2015
Все версии
Судя по набору функционала, обозначенного в таблице, ты добавил обёртки, чтобы можно было пользоваться в Lisp... Однако использование этих функций в LISP коде сделает его зависимым от наличия соответствующей версии управляемой библиотеки. Чтобы минимизировать такие побочные эффекты, я поступаю следующим образом: http://bushman-andrey.blogspot.ru/2014/06/dll-autocad.html
Андрей, у тебя решение по выбору необходимой библиотеки на твоем языке, но все это можно делать и на лиспе.
К примеру, я все необходимые arx итд файлы закидываю при компиляции в vlx, дальше отслеживаю необходимую для загрузки версию, записываю ее в папку и загружаю.
ps. Если необходимо, могу выложить пример кода на лиспе.
То, что я указал по ссылке, можно сделать на любом языке. Поскольку я писал это для своих .NET расширений, то и решение было на управляемом коде. Я думаю, что пример аналогичного кода на LISP был бы интересен значительно большему количеству людей, чем пример кода на .NET.
В общем принесли мне смежники, как знатоку Автокад, два своих файла, между которыми они не могли ничего скопировать, я прогнал эти файлы через все известные мне прокси клинеры, но без толку. Тогда, потратив два часа и отчаявшись я прибёг к помощи Ревита:) импортировал оба файла в Ревит и сделал экспорт, на выходе получил один файл. В чем была проблема не знаю, но Ревит ее разрешил:)
demandload наверняка забыл поменять.
>прогнал эти файлы через все известные мне прокси клинеры, но без толку
Файлы в студию.
Почему-то при использовании функций (ACAD2011) выдается такое сообщение:
System.ArgumentException: Ошибка при связывании с конечным методом.
в System.Delegate.CreateDelegate(Type type, Object firstArgument, MethodInfo
method, Boolean throwOnBindFailure)
в Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorker(MethodInfo mi, Object
commandObject, Boolean bLispFunction)
в
Autodesk.AutoCAD.Runtime.CommandClass.InvokeWorkerWithExceptionFilter(MethodInfo
mi, Object commandObject, Boolean bLispFunction)
в Autodesk.AutoCAD.Runtime.CommandClass.CommandThunk.InvokeLisp(); ошибка:
ошибка запроса ADS
С командами же все в порядке. Почему бы?
И есть еще пару вопросов:
1. При использовании данных команд, я так понимаю, необязательно "настраивать" DEMANDLOAD, PROXYNOTICE и проч.?
2. Никто ли случайно не знает функций для лиспа вроде ProxyInfo, но которые бы возвращали количества прокси-объектов и примитивов не в командную строку, а в переменную? Графические прокси можно найти с помощью ssget с фильтром, а вот неграфические? Знаю о DOSLIB, но соответствующая функция в нем часто не находит прокси, хотя они есть и чистятся программой Александра Наумовича. Для чего? Использую свое меню очистки чертежа, и хотелось бы, чтобы в нем указывалось заранее наличие и количество всех прокси.
Причину такого поведения я не знаю. Андрей говорил, что у него в оригинальном коде были какие-то доработки, но я не вникал - знаний не хватает..
demandload я бы настраивал в 2, чтобы объекты считались действительными прокси, и не грузились для них ObjectEnabler'ы. proxynotice - фиолетово, а вот proxyshow в 1 надо бы. А то можно получить потерю графической информации.
По поводу подсчета количества прокси - наверное, можно поменять код: вместо разбивания просто их подсчитывать, и все. Но я в этом не уверен.