API7 - работа с динамическими массивами

Автор p3452, 21.12.20, 14:07:08

« назад - далее »

0 Пользователи и 1 гость просматривают эту тему.

p3452

Коллеги, поделитесь опытом, кто как работает с массивами SAFEARRAY под API7?

Допустим не примере свойства IFeature7.ResultBodies:
ЦитироватьСвойство позволяет получить массив SAFEARRAY всех тел, входящих в дерево. Если возвращается один объект, то тип VARIANT-а будет VT_DISPATCH, если возвращается не­сколько объектов, то тип VARIANT-а будет VT_ARRAY | VT_DISPATCH.
Мой код во вложении, как это можно сделать по другому?
/// <summary> ТЕЛА дерева построения </summary>
/// <param name="_f"> IFeature7</param>
/// <returns>string</returns> Строка с перечнем описания Тел
internal static string testBody(IFeature7 _f)
{
string st = "";       
    if (_f == null) return "_f == null";

    try
    {
    Object[] arrBody = (Object[])_f.ResultBodies;
    if (arrBody != null)
    {
    IBody7 curBodi = null;    // текущее тело
           
    //+ перебираем ТЕЛА дерева
            for(int n=0; n<arrBody.Rank; n++)
{
for(int i=arrBody.GetLowerBound(n); i<=arrBody.GetUpperBound(n); i++)
{
st = st+ "n = "+ n.ToString()+ "   i = "+ i.ToString();
//+ получаем текущее Тело
                curBodi = (IBody7)arrBody[i];
                if (curBodi == null)
                {
                st = st+ "curBodi == null\n";
                break;
                }  
                st = st+ "    Наименование = ["+ curBodi.Name+ "]\n";  // Наименование тела
                st = st+ "Объект спецификации - "+ (curBodi.CreateSpcObjects ? "Да" : "Нет")+ "\n";              
}
}
    }
    else
    st =  "arrBodi == null";
    } catch //(Exception)
    {
    IBody7 bodi = (IBody7)_f.ResultBodies;
    if (bodi != null)
    st = "Наименование = ["+ bodi.Name+ "]\n";  // Наименование тела
else           
    st =  "bodi == null";
    }
    return st;
}
testBody.png

Вират Лакх

Пример на выделенных объектах чертежа, если нужно их перебрать (python):
sObjects = API7.IKompasDocument2D1(iKompasDocument2D).SelectionManager.SelectedObjects
if sObjects:
for sObject in sObjects if isinstance(sObjects, tuple) else (sObjects,):
otype = API7.IKompasAPIObject(sObject).Type
Если тип пришел не кортеж, а один элемент в виде его интерфейса, то превращаем его в кортеж с одним элементом.

p3452

Цитата: Вират Лакх от 22.12.20, 04:35:45Если тип пришел не кортеж, а один элемент в виде его интерфейса, то превращаем его в кортеж с одним элементом.

Если заменить модуль try...catch на
if (_f.ResultBodies.GetType().IsArray)
{
 ...
}
else
{
 ...
}
то код будет аналогичен Python-овскому...

Может, все-таки, есть другие варианты кода???

Вират Лакх

Цитата: p3452 от 22.12.20, 10:14:43то код будет аналогичен Python-овскому...
Может, все-таки, есть другие варианты кода???
Ваш код выше не аналогичен питоновскому. У меня одно тело цикла, а у вас два раза писать приходится одно и то же. Или функцию писать, которую надо вставить после if и после else. Вы же хотите от этого избавиться? Я перевожу интерфейс в кортеж из одного элемента, и цикл получает всегда последовательность.

p3452

Код аналогичен..., с учетом особенностей языка С# - собственно, целю вопроса и было - увидеть другие варианты кода на языке C#!
О достоинствах и недостатках Python спорить не будем - выбор давно уже сделан и, как понимаете, не в пользу Python.

Итак:
- Если кто-то знает другие варианты работы с динамическими массивами, под API7 Компаса на языке C#, поделитесь!

VirRus77

Займёмся некрофилией постов.
Вот расширение:
/// <summary>
/// Расширение для <see cref="IFeature7"/>.
/// </summary>
// ReSharper disable once InconsistentNaming
public static class IFeature7Extensions
{
    /// <summary>
    /// Объекты, входящие в состав данного объекта (грани, ребра, вершины).
    /// </summary>
    /// <param name="feature7">Интерфейс объекта Дерева построения.</param>
    /// <param name="type">Типы объектов документа-модели; соответствие интерфейсов API 5 и API 7.</param>
    /// <returns>Массив.</returns>
    public static Array ModelObjects(this IFeature7 feature7, ksObj3dTypeEnum type)
    {
        return (Array)feature7.ModelObjects[(int)type];
    }

    /// <summary>
    /// Объекты, входящие в состав данного объекта (грани, ребра, вершины).
    /// </summary>
    /// <param name="feature7">Интерфейс объекта Дерева построения.</param>
    /// <param name="type">Типы объектов документа-модели; соответствие интерфейсов API 5 и API 7.</param>
    /// <returns>Массив T.</returns>
    public static T[] ModelObjects<T>(this IFeature7 feature7, ksObj3dTypeEnum type)
    {
        return feature7.ModelObjects(type)
            .Cast<T>()
            .ToArray();
    }

    /// <summary>
    /// Получить массив тел.
    /// </summary>
    /// <param name="feature7">Интерфейс объекта Дерева построения.</param>
    /// <returns>Массив тел.</returns>
    public static IBody7[] ResultBodies(this IFeature7 feature7)
    {
        var bodiesObject = feature7.ResultBodies;

        if (bodiesObject == null)
        {
            return Array.Empty<IBody7>();
        }

        if(bodiesObject is Array array)
        {
            return array
                .Cast<IBody7>()
                .ToArray();
        }

        return new[] { (IBody7)bodiesObject };
    }
}
Как использовать:
var bodies = topFeature.ResultBodies();
var singleBody = bodies.Single();
+ Благодарностей: 2

p3452

А вот к ЭТОМУ стоило вернутся!
(Старая схема работает отлично, но, почему бы не перейти и на новую..., учитывая НОВЫЕ возможности C# и NET)
Надо будет опробовать...
+ Благодарностей: 1