Purge в nanoCAD 23+

Понадобилось мне тут поиграться с очисткой файла в нанике. Нуачо, стандартная достаточно вещь, думал я...

Для начала попробовал код от Андрея Бушмана. Только NC так почистил файл, что тупо развалился.

Да и черт с ним, пишу через настолько не любимый мною COM:

1
2
3
4
5
6
Document doc = Application.DocumentManager.MdiActiveDocument;
nanoCAD.Document comDoc = doc.AcadDocument as nanoCAD.Document;
for (int i = 0; i < 3; i++)
{
    comDoc.PurgeAll();
}

Ура? Фигушки! Этот подход не уничтожает пустые тексты и геометрию нулевой длины! Кстати, лисповой vla-purgeall тоже не убирает эту дрянь. Значит, надо проходить по всем описаниям блоков, исключая внешние ссылки, и смотреть что там внутри. На всякий случай: Trans - текущая транзакция, DBase - база текущего чертежа:

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
BlockTable blockTable = Trans.GetObject(DBase.BlockTableId, OpenMode.ForRead) as BlockTable;
foreach (ObjectId blockDefId in blockTable)
{
    BlockTableRecord blockDef = Trans.GetObject(blockDefId, OpenMode.ForRead) as BlockTableRecord;
    if (!blockDef.IsFromExternalReference)
    {
        foreach (ObjectId entId in blockDef)
        {
            Entity ent = Trans.GetObject(entId, OpenMode.ForRead, false, true) as Entity;
            if (ent != null)
            {
                if (ent is Curve curve)
                {
                    if (curve.GetDistanceAtParameter(curve.EndParam) < Tolerance.Global.EqualPoint)
                    {
                        EraseEntity(curve);
                    }
                }
                else if (ent is DBText dbText)
                {
                    if (string.IsNullOrWhiteSpace(dbText.TextString))
                    {
                        EraseEntity(dbText);
                    }
                }
                else if (ent is MText mText)
                {
                    if (string.IsNullOrWhiteSpace(mText.Text))
                    {
                        EraseEntity(mText);
                    }
                }
            }
        }
    }
}

Я почти выкатил код, но хвала богам, вовремя остановился. А что будет, если в чертеже вдруг окажется, к примеру, таблица nanoCAD? Правильно - ошибка. Потому как MultiCAD-объекты могут быть запросто скастованы в Curve, но при этом массы параметров и методов там не будет от слова совсем. В принципе, есть два варианта. Первый - получать ObjectName для обрабатываемого примитива и фильтровать. Второй - оборачивать все в try-catch.

Я провел несколько экспериментов, вроде бы (именно что вроде бы!) имена пользовательских объектов MultiCAD всегда начинаются с mcs. Но что будет дальше - не знает никто, даже, наверное, сами нанодевы. Так что, несмотря на гарантированные тормоза, я решил обернуть обработку в try-catch:

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
        private void PurgeCurrentDocument(Database DBase, Transaction Trans)
        {
            Document doc = Application.DocumentManager.MdiActiveDocument;
            Editor ed = doc.Editor;

            BlockTable blockTable = Trans.GetObject(DBase.BlockTableId, OpenMode.ForRead) as BlockTable;
            foreach (ObjectId blockDefId in blockTable)
            {
                BlockTableRecord blockDef = Trans.GetObject(blockDefId, OpenMode.ForRead) as BlockTableRecord;
                if (!blockDef.IsFromExternalReference)
                {
                    foreach (ObjectId entId in blockDef)
                    {
                        Entity ent = Trans.GetObject(entId, OpenMode.ForRead, false, true) as Entity;
                        if (ent != null)
                        {
                            try
                            {
                                if (ent is Curve curve)
                                {
                                    if (curve.GetDistanceAtParameter(curve.EndParam) < Tolerance.Global.EqualPoint)
                                    {
                                        EraseEntity(curve);
                                    }

                                    else if (ent is DBText dbText)
                                    {
                                        if (string.IsNullOrWhiteSpace(dbText.TextString))
                                        {
                                            EraseEntity(dbText);
                                        }
                                    }
                                    else if (ent is MText mText)
                                    {
                                        if (string.IsNullOrWhiteSpace(mText.Text
                                                .Replace("\\P", " ")
                                                .Replace('\r', ' ')
                                                .Replace('\n', ' ')))
                                        {
                                            EraseEntity(mText);
                                        }
                                    }
                                }
                            }
                            catch (Exception ex)
                            {
#if DEBUG
                                ed.WriteMessage(
                                    $"Handle "{ent.Handle.ToString()}" can't convert to curve : {ex.Message}");
#endif
                            }
                        }

                        nanoCAD.Document comDoc = doc.AcadDocument as nanoCAD.Document;
                        for (int i = 0; i < 3; i++)
                        {
                            comDoc.PurgeAll();
                        }
                    }
                }
            }
        }

        private void EraseEntity(Entity entity)
        {
            entity.UpgradeOpen();
            entity.Erase();
            entity.DowngradeOpen();
        }

P.S. Для работы с ActiveX надо подключать как минимум OdaX.dll (ну или как она там называется), болтается в каталоге установки NC, если я не ошибаюсь.

Размещено в .NET, nanoCAD, Разное · Метки: , , ,



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


Я не робот.