Управляемая альтернатива ExplodeAllProxy

Андрей Бушман у себя на сайте опубликовал код, решающий те же задачи, что и знаменитый ExplodeAllProxy от Александра Ривилиса. Пользуясь выцыганенным у Андрея разрешением, публикую мои изменения его кода.

Прежде всего, хочу предупредить о следующем:

  1. Я не автор кода. Я не знаю и не понимаю, как он работает. Я не в силах его повторить. Все, что я могу сказать - это "обращайтесь на сайт Андрея"
  2. Ниже показан исправленный мною код. Я поменял код так, чтобы хоть что-то в нем понять (Андрей, прости!)
  3. После этого указаны ссылки со скомпилированными .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");
        }
      }
    }
  }
}

ZIP-архив

Ну и обертки: команды и лисп-функции

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;
    }
  }
}

ZIP-архив

Если читать все лень, то: библиотека прописывает в AutoCAD

Команда ProxyInfo Выводит в командную строку сообщение об обнаруженных прокси-объектах
Лисп-функция (ProxyInfo) То же
Команда ProxyExplode Разбивает все графические прокси-объекты
Лисп-функция (ProxyExplode) То же
Команда ProxyRemove Удаляет неразбитые и неграфические прокси-объекты
Лисп-функция (ProxyRemove) То же
Команда ProxyClear Совмещает разбиение и очистку прокси-объектов
Лисп-функция(ProxyClear) То же

Собственно архивы:
ACAD 2009
ACAD 2010
ACAD 2011
ACAD 2012
ACAD 2013
ACAD 2014
ACAD 2015
Все версии



Комментарии

Есть 8 коммент. к “Управляемая альтернатива ExplodeAllProxy”
  1. Андрей пишет:

    Судя по набору функционала, обозначенного в таблице, ты добавил обёртки, чтобы можно было пользоваться в Lisp... Однако использование этих функций в LISP коде сделает его зависимым от наличия соответствующей версии управляемой библиотеки. Чтобы минимизировать такие побочные эффекты, я поступаю следующим образом: http://bushman-andrey.blogspot.ru/2014/06/dll-autocad.html

  2. ElpanovEvgeniy пишет:

    Андрей, у тебя решение по выбору необходимой библиотеки на твоем языке, но все это можно делать и на лиспе.
    К примеру, я все необходимые arx итд файлы закидываю при компиляции в vlx, дальше отслеживаю необходимую для загрузки версию, записываю ее в папку и загружаю.
    ps. Если необходимо, могу выложить пример кода на лиспе.

  3. Андрей пишет:

    То, что я указал по ссылке, можно сделать на любом языке. Поскольку я писал это для своих .NET расширений, то и решение было на управляемом коде. Я думаю, что пример аналогичного кода на LISP был бы интересен значительно большему количеству людей, чем пример кода на .NET.

  4. Khasan Mamaev пишет:

    В общем принесли мне смежники, как знатоку Автокад, два своих файла, между которыми они не могли ничего скопировать, я прогнал эти файлы через все известные мне прокси клинеры, но без толку. Тогда, потратив два часа и отчаявшись я прибёг к помощи Ревита:) импортировал оба файла в Ревит и сделал экспорт, на выходе получил один файл. В чем была проблема не знаю, но Ревит ее разрешил:)

  5. Кулик Алексей aka kpblc пишет:

    demandload наверняка забыл поменять.

  6. Андрей пишет:

    >прогнал эти файлы через все известные мне прокси клинеры, но без толку
    Файлы в студию.

  7. skkkk пишет:

    Почему-то при использовании функций (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, но соответствующая функция в нем часто не находит прокси, хотя они есть и чистятся программой Александра Наумовича. Для чего? Использую свое меню очистки чертежа, и хотелось бы, чтобы в нем указывалось заранее наличие и количество всех прокси.

  8. Кулик Алексей aka kpblc пишет:

    Причину такого поведения я не знаю. Андрей говорил, что у него в оригинальном коде были какие-то доработки, но я не вникал - знаний не хватает..
    demandload я бы настраивал в 2, чтобы объекты считались действительными прокси, и не грузились для них ObjectEnabler'ы. proxynotice - фиолетово, а вот proxyshow в 1 надо бы. А то можно получить потерю графической информации.
    По поводу подсчета количества прокси - наверное, можно поменять код: вместо разбивания просто их подсчитывать, и все. Но я в этом не уверен.

Поделитесь своим мнением


Я не робот.