TeklaAPI FAQ как удалить элементы подрезки

tekla structures api remove boolean parts scriptВ рамках TeklaAPI FAQ, и расширения базы готовых решений в сети Интернет публикую небольшое решение для программного удаления элементов подрезки с деталей модели, с фильтрацией по максимально допустимому размеру удаляемого объекта. Зачем нужно? Пришли модели с огромным количеством миниатюрных подрезок. Подрядчик по неизвестной причине решил прорезать отверстия с помощью малюсеньких  плиток: четыре точки со скруглениями = одно отверстие.

Хотя решение, мягко скажем, — неоднозначное, но нельзя сказать, что сильно оригинальное. Всякое в практике встречалось. Тут однако важен масштаб — тысячи элементов с десятками вот таких вырезов. И главное, что эти мелкие плиточки-подрезки после экспорта модели в WebView подвешивают TeklaWebViewer наглухо. А это уже совсем нехорошо. Надо что-то делать.

Соответственно удалять все эти подрезки вручную, отфильтровав нужные парты, и выделив все каты — теоретически возможно, но кроме небольших элементов, так же в деле участвуют и более серьезные — технические отверстия для инженерных коммуникаций, а это в корне меняет дело.

Итак, для корректного экспорта нам необходимо удалить все Каты с выделенных элементов в модели, максимальные размеры которых не превышают некоторого порогового значения — 20мм (отверстие под болт 16мм +2 мм плюс еще не много).

Чтобы не переживать по поводу совместимости с используемыми версиями Tekla решим задачу в виде скрипта:

Ну и собственно код. В нем сразу скажу есть минус — расстояние между точками можно вычислить с помощью встроенного в текла апи функционала, но мне показалось быстрее написать эту функцию с нуля, и сразу натравить её сразу на ContourPoint, вместо того чтобы подключать нужные библиотеки Теклы, и приводить Tekla.Structures.Model.ContourPoints к Tekla.Structures.Geometry.Points.

Tekla Script для удаления полигональных катов.

namespace Tekla.Technology.Akit.UserScript
{
    using TSM = Tekla.Structures.Model;
    using System; 
    
    public class Script
    {
        public static void Run(Tekla.Technology.Akit.IScript akit)
        {
            DeleteCutsLessThan(100);
        }


    public static void DeleteCutsLessThan(double MaximumAvailableDelta)
    {
            TSM.Model M = new TSM.Model();
            Tekla.Structures.Model.UI.ModelObjectSelector selected = new Tekla.Structures.Model.UI.ModelObjectSelector();
            Tekla.Structures.Model.ModelObjectEnumerator manyO = (selected.GetSelectedObjects() as TSM.ModelObjectEnumerator);

            while (manyO.MoveNext())
            {
                if ((manyO.Current as TSM.ContourPlate) != null)
                {
                    TSM.ContourPlate plate = manyO.Current as TSM.ContourPlate;
                    TSM.ModelObjectEnumerator Children = plate.GetChildren();
                    while (Children.MoveNext())
                    {
                        if ((Children.Current as TSM.BooleanPart) !=null)
                        {
                            TSM.BooleanPart BP = (Children.Current as TSM.BooleanPart);

                            if ((BP.OperativePart as TSM.ContourPlate)!=null)
                            {
                                TSM.ContourPlate CP = BP.OperativePart as TSM.ContourPlate;
                                TSM.ContourPoint BasePoint = CP.Contour.ContourPoints[0] as TSM.ContourPoint;
                                double delta = 0; 

                                for (int i=1; i<CP.Contour.ContourPoints.Count; i++)
                                {
                                    double GP = TwoContoutPointDistance(BasePoint, CP.Contour.ContourPoints[i] as TSM.ContourPoint);
                                    if (delta < GP)
                                        delta = GP;
                                }

                                if (delta < MaximumAvailableDelta)
                                {
                                    BP.OperativePart.Delete();
                                    BP.Delete();
                                }
                            }
                        }
                    }
                }
           }            
            M.CommitChanges();
    }

    private static double TwoContoutPointDistance(TSM.ContourPoint Base, TSM.ContourPoint Check)
        {
            double xx = Check.X - Base.X;
            double yy = Check.Y - Base.Y;
            double zz = Check.Z - Base.Z;
            double GP = xx*xx + yy*yy + zz*zz;
            return Math.Sqrt(GP);
        }
    }
}

PS

Если вдруг кому интересно, отвечу на повисший в воздухе вопрос: а как же следовало подрядчику проделывать эту титаническую работу?

Такие небольшие отверстия значительно удобнее и технологичнее выполнять с помощью болтов без болта. Примерно как на скриншоте.

tekla-structures-bolts-instead-cuts-to-emulate-holes

  • В таком варианте не надо создавать собственно подрезающий элемент — плитку, или балку.
  • Не придется копировать элементы вручную много, много, много… очень много раз.
  • На чертеже этим элементам в таком варианте можно спокойно задать марку с диаметром отверстий, без шаманства.
  • Посчитать эти отверстия с помощью Репорта тоже можно, в отличии от
  • Есть не плохой шанс, что на кат-эскизах (single part drawings) Текла выдаст годные размеры для сверловки.
  • Как минимум будет привязка к центру отверстия.

Кстати, изменив скрипт выше, можно не только удалить некорректные элементы, но и заменить их, к примеру, на те же болтовые отверстия. Но это уже совсем другая история.