Форум пользователей ПО АСКОН

Профессиональные вопросы => Программирование приложений => Тема начата: dosart от 10.02.15, 08:52:10

Название: Как извлечь объекты их сборки?
Отправлено: dosart от 10.02.15, 08:52:10
Требуется извлечь объекты из которых состоит сборка, для дальнейшей работы с ними.
Подскажите пожалуйста, как это можно сделать.
Название: Re: Как извлечь объекты их сборки?
Отправлено: Sabahs от 10.02.15, 08:55:52
IPart7.PartsEx - Массив SAFEARRAY компонентов.
Название: Re: Как извлечь объекты их сборки?
Отправлено: dosart от 10.02.15, 22:00:03
Sabahs, можно чуть более развёрнутый ответ?  Я не нашёл внятного описания описания IPart7.
Название: Re: Как извлечь объекты их сборки?
Отправлено: Sabahs от 10.02.15, 23:45:41
Воспользуйтесь поиском, да и в справке вроде подробно расписано.
http://forum.ascon.ru/index.php/topic,3771.msg20448.html#msg20448
Название: Re: Как извлечь объекты их сборки?
Отправлено: dosart от 16.02.15, 10:57:45
Sabahs, у меня совсем глупый вопрос -  если я хочу нарисовать, скажем, квадрат средствами API КОМПАСа в среде MVS, то что мне для этого нужно сделать.
Название: Re: Как извлечь объекты их сборки?
Отправлено: Sabahs от 16.02.15, 11:14:48
Смотрите пример Step3 и Step3a в SDK.
Название: Re: Как извлечь объекты их сборки?
Отправлено: dosart от 17.02.15, 09:49:23
Sabahs, насколько я понял, любое приложение использующее API КОМПАСа должно получить  указатель на базовый интерфейс KompasObject? Так ли это? Я смотрел примеры на С++ и С#, в частности step2. В С++ не происходит получение указателя на KompasObjec. Тогда как в C# это есть.

void ExternalRunCommand([In] short command, [In] short mode, [In, MarshalAs(UnmanagedType.IDispatch)] object kompas_).
Вот это строчка не понятна - MarshalAs(UnmanagedType.IDispatch) Не могли бы вы прокаментировать её.
Название: Re: Как извлечь объекты их сборки?
Отправлено: Sabahs от 17.02.15, 10:13:04
Так почитайте в SDK пункт "Оформление прикладных библиотек типа ActiveX", там подробно расписано про ExternalRunCommand.
Собственно там идёт приведение интерфейса к одному из интерфейсов API5 или API7, в зависимости от того, что будут указан в функции IsOnApplication7.
Если Вы имеете ввиду пример c:\Program Files\ASCON\KOMPAS-3D V15\SDK\C++\Visualc\step2\, то там используются экспортные функции из LibTool - из kAPI2D5.dll.
PS. Могу и ошибаться, т.к. я на Си не программирую.
Название: Re: Как извлечь объекты их сборки?
Отправлено: dosart от 18.02.15, 15:57:27
Sabahs, если у меня в приложении используется API5,   в частности, KompasObject и ksDocument3d то существует ли способ к этим объектам использовать API7 ?
Название: Re: Как извлечь объекты их сборки?
Отправлено: Sabahs от 18.02.15, 16:14:00
Вы в DLL можете использовать API5, API7 и экспортные функции из LibTool, как всё это получить есть в примерах SDK.
Название: Re: Как извлечь объекты их сборки?
Отправлено: dosart от 19.02.15, 10:46:39
Sabahs, из сборки можно вытащить имена файлов, в которых лежат компоненты? Причём вытащить нужно в иерархическом порядке, т.е провести декомпозиция сборки на компоненты, и из компоненты узнать имя файла.
Название: Re: Как извлечь объекты их сборки?
Отправлено: Sabahs от 19.02.15, 10:51:27
IPart7.FileName - Имя файла компонента.
Название: Re: Как извлечь объекты их сборки?
Отправлено: dosart от 24.02.15, 15:30:17
Sabahs, можно как нибудь извлечь данные в иерархическом порядке?
Из того, что есть сейчас вот:
public void AssemblyDecomposition()
       {
           if (doc != null)
           {
               //получить интерфейс на верхний компонент
               IPart7 TopComponent = doc.TopPart;
               if (TopComponent != null)
               {   
                   //получить интерфейс на коллекцию компонентов
                   IParts7 comCollection = TopComponent.Parts;
                   if (comCollection != null)
                   {

                       foreach (IPart7 element in comCollection)
                       {   
                           //если элемент деталь, то получаем имя детали
                           if (element.Detail)
                           {
                               string fileName = element.FileName;
                               Console.WriteLine(fileName);
                           }
                           //иначе если элемент сборка
                           else
                           {
                               //формируем коллекцию элементов сборки
                               IParts7 NewCollection = element.Parts;
                               foreach (IPart7 item in comCollection)
                               {
                                   string fileName = element.FileName;
                                   Console.WriteLine(fileName);
                               }


                           }
                           
                       }

                   }
               }
               
           }
Название: Re: Как извлечь объекты их сборки?
Отправлено: Sabahs от 24.02.15, 15:40:51
Вроде должна возвращать всё, вроде и иерархия сохраняется, хотя нужно проверять.
http://forum.ascon.ru/index.php/topic,27478.msg205429.html#msg205429
Название: Re: Как извлечь объекты их сборки?
Отправлено: dosart от 03.03.15, 13:12:59
Sabahs, вы не знаете, как использовать SAFEARRAY в C# ?
Название: Re: Как извлечь объекты их сборки?
Отправлено: Sabahs от 03.03.15, 13:26:41
Смотрите пример:
c:\Program Files\ASCON\KOMPAS-3D V16\SDK\C#\Automation\Step3_API7_2D\Step3_API7_2D.cs
Название: Re: Как извлечь объекты их сборки?
Отправлено: dosart от 03.03.15, 14:38:01
И всё же я не понимаю, какое значение(тип) мне должно вернуться, после использования PartsEx
Делаю так:
IKompasDocument3D doc;
IPart7 TopComponent = doc.TopPart;
TopComponent.PartsEx( ksPart7CollectionTypeEnum.ksAllParts);
Название: Re: Как извлечь объекты их сборки?
Отправлено: Sabahs от 03.03.15, 15:23:13
Пример не судьба посмотреть, я в C# полный ноль, но если верить примеру, то должно быть так:
Array arr = (Array)TopComponent.PartsEx( ksPart7CollectionTypeEnum.ksAllParts);
Название: Re: Как извлечь объекты их сборки?
Отправлено: dosart от 04.03.15, 14:29:18
Sabahs, если делать через PartsEx - всё хорошо(почти). Иерархия есть, компоненты сборки есть, файлы, в которых лежат компоненты есть(почти). Нет компонентов, которые в сборку должны входять, но физически  не присутствую. Например, на компьютере нет файлов, в которых эти компоненты присутсвуют.
Как это исправить?


Название: Re: Как извлечь объекты их сборки?
Отправлено: Sabahs от 04.03.15, 14:59:31
Из святого духа создать.
Название: Re: Как извлечь объекты их сборки?
Отправлено: dosart от 04.03.15, 15:07:25

Sabahs, если делать так, то будут все компоненты. но, без иерархии.
public void AssemblyDecomposition()
       {
           if (doc != null)
           {
               //получить интерфейс на верхний компонент
               IPart7 TopComponent = doc.TopPart;
               if (TopComponent != null)
               {   
                   //получить интерфейс на коллекцию компонентов
                   IParts7 comCollection = TopComponent.Parts;
                   if (comCollection != null)
                   {

                       foreach (IPart7 element in comCollection)
                       {   
                           //если элемент деталь, то получаем имя детали
                           if (element.Detail)
                           {
                               string fileName = element.FileName;
                               Console.WriteLine(fileName);
                           }
                           //иначе если элемент сборка
                           else
                           {
                               //формируем коллекцию элементов сборки
                               IParts7 NewCollection = element.Parts;
                               foreach (IPart7 item in comCollection)
                               {
                                   string fileName = item.FileName;
                                   Console.WriteLine(fileName);
                               }


                           }
                           
                       }

                   }
               }
               
           }
Название: Re: Как извлечь объекты их сборки?
Отправлено: Sabahs от 04.03.15, 15:21:29
Каким образом будут все компоненты, если их физически нет на компьютере?
Я так понял Вам нужны все компоненты кроме копий из операций копирования, то тогда так получите массив.
Array arr = (Array)TopComponent.PartsEx( ksPart7CollectionTypeEnum.ksUniqueParts);

Название: Re: Как извлечь объекты их сборки?
Отправлено: dosart от 04.03.15, 18:51:18
Каким образом будут все компоненты, если их физически нет на компьютере?
Они могут лежать в БД удалённо. Но если нет соединения с сетью, то такие компоненты могут быть недоступны.Насколько я понимаю, то в роли такой БД выступает ЛОЦМАН. 

Я так понял Вам нужны все компоненты кроме копий из операций копирования
Нет, мне нужно получить файлы(путь к ним), в которых лежат компоненты сборки в иерархическом порядке.

Если есть сборка, в который отсутствует компоненты, то в дереве модели, такие компоненты помечаются красным кружочком. Но Компас откуда то пытается "подтянуть" эти файлы!  У него есть что-то вроде ссылок на эти файлы. Если файлы лежат на локальном компьютере, то условная ссылка - путь к файлу. Если файлы лежат удалённо, это что другое. 
Как получить эту условную ссылку?
Название: Re: Как извлечь объекты их сборки?
Отправлено: Sabahs от 04.03.15, 19:24:49
Давайте в картинках, что имеем, что получаем.
Название: Re: Как извлечь объекты их сборки?
Отправлено: dosart от 09.03.15, 16:41:30
ЦитироватьДавайте в картинках, что имеем, что получаем.
уже ненужно.
Как разобрать сборку, если в ней есть ещё "подсборки"? Я пытался это сделать используя обход в глубину, но таким способом получается разобрать только  саму "подсборку". Как быть, если в самой "подсборк"е может быть ещё n сборок?
Название: Re: Как извлечь объекты их сборки?
Отправлено: Sabahs от 09.03.15, 22:21:54
Использовать рекурсию.
Название: Re: Как извлечь объекты их сборки?
Отправлено: dosart от 10.03.15, 18:58:51
ЦитироватьИспользовать рекурсию.
Это уже получилось.
Если использовать интерфейс  IFeature7 нельзя ли получить компоненты в иерархическом порядке?
Название: Re: Как извлечь объекты их сборки?
Отправлено: s_sergey от 29.03.15, 11:23:08
Добрый день!
Имею в настоящий момент такую-же задачку: перебрать все элементы из сборки и ее подсборок. Писать пробую на c#.

                appl = (IApplication)kompas.ksGetApplication7();
                if (appl == null) return;
                doc1 = (IKompasDocument3D)appl.ActiveDocument;
                if (doc1 != null)
                {
                    IPart7 TopComponent = doc1.TopPart;
                    if (TopComponent != null)
                    {
                        listBox1.Items.Add(TopComponent.Name);  //------------здесь выдает в listbox имя сборки, все ок
                        IParts7 comCollection = TopComponent.Parts;                     
                        if (comCollection != null)
                        {
                            listBox1.Items.Add(comCollection.Count);  //  а здесь выдает 0, хотя в сборке есть куча объектов...
                            foreach (IPart7 element in comCollection)
                            {
                                if (element.Detail)
                                {
                                    string fileName = element.Name;
                                    listBox1.Items.Add(fileName);
                                }
                                else
                                {
                                    IParts7 NewCollection = element.Parts;
                                    foreach (IPart7 item in comCollection);         // до этой строки не доходит, т.к. не видит объекты...
                                    {
                                        string fileName = element.Name;
                                        listBox1.Items.Add(fileName);
                                    }
                                }
                            }
                        }
                    }
                }

что я делаю не так и как сделать, что бы получить хотя бы имена объектов внутри подсборки?
голову сломал, но в объектной модели не разобрался... Помогите люди добрые!   :`(
Название: Re: Как извлечь объекты их сборки?
Отправлено: Sabahs от 30.03.15, 07:00:10
http://forum.ascon.ru/index.php/topic,27478.msg205429.html#msg205429
Название: Re: Как извлечь объекты их сборки?
Отправлено: Kamerton от 21.04.15, 23:23:45
Цитата: s_sergey от 29.03.15, 11:23:08
как сделать, что бы получить хотя бы имена объектов внутри подсборки?
голову сломал, но в объектной модели не разобрался... Помогите люди добрые!   :`(

Если у вас в именах файлов Спецификаций содержатся номера документов, то я такую стратегию могу посоветовать :)

Сам делаю так, ибо иного пока не освоил в аду API7 и авгиевых конюшнях SDK... Да и не гонят никуда...

Парсю "нулевую" Спецификацию на номера документов, а потом рекурсивно их обхожу :)

получаю var rows = IKompasDocument.SpecificationRows[0]
foreach(SpecificationColumn cell in rows[n])
{
   if(cell.Type = ksRowNumber)
   var number = cell.Text.Str;
}

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

Если нужны подробности - спрашивайте :)
Название: Re: Как извлечь объекты их сборки?
Отправлено: dosart от 22.04.15, 19:26:35
Если всё ещё актуально...
Моя задача была чуть сложней. Необходимо было не просто пройтись по элементам сборки, но и вытащить их в иерархическом порядке.
Решение такое - создадим класс Assembly. Класс имеет три параметра - имя сборки, путь к файлу в которой лежит сборка, тип, позволяющий понять является ли элемент сборкой или нет, а  также список, в котором храним элементы сборки.

public class Assembly
    {
        public string Name { get; set; }
        public string File { get; set; }
        public int asmType { get; set; }
   
        public List<Assembly> Subassembly { get; set; }

        public Assembly ( )
        {List = new ObservableCollection<Assembly> ( ); }
    }

Сам алгоритм разбора тривиален -  обход графа в глубину.

        public void AssemblyDecomposition()
        {
            if (doc != null)
            {

                // берём верхний компонент
                IPart7 TopComponent = doc.TopPart;
                if (TopComponent != null)
                {
                        assembly.File    = TopComponent.FileName;
                        assembly.Name    = TopComponent.Name;
                        //признак, что компонент сборка
                        assembly.asmType = 1;

                     
                         //получаем массив компонентов сборки
                        arrComponent = (Array)TopComponent.PartsEx[ksPart7CollectionTypeEnum.ksUniqueParts];
                        foreach (var i in arrComponent)
                        {

                            Decomposition((IPart7)i, assembly);
                        }     
                 }
            }
        }

private void Decomposition(IPart7 component, Assembly assembly)
        {
            Assembly tmp = new Assembly();
            if (component.Detail)
            {
                tmp.Name = component.Name;
                tmp.File = component.FileName;
                //признак, что деталь
                tmp.asmType = 0;
               
                 //добавляем деталь в сборку
                assembly.Subassembly.Add(tmp);

            }
            else
            {   
                //иначе если подсборка, то разложить её на составные части
                Array arrSubComponent = (Array)component.PartsEx[ksPart7CollectionTypeEnum.ksUniqueParts];
                tmp.Name = component.Name;
                tmp.File = component.FileName;
                tmp.asmType = 1;
               
                //добвим её в "большую сборку"
                assembly.Subassembly.Add(tmp);

                foreach (IPart7 newComponent in arrSubComponent)
                {
                    //будем "собирать" компоненты "подсборки"
                    Decomposition(newComponent, tmp);
                }
            }
        }

Код не идеален - есть дублирование кода, да и вообще.. но работает.