Кол-во деталей в сборке

Автор А8208, 29.11.11, 16:16:19

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

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

А8208

Здравствуйте.
Скажу сразу програмированием занимаюсь на уровне любительском. Только когда вижу явную возможность автоматизации некоторых операций выполняемых конструкторами в ручном режиме.
На данном этапе есть необходимость составления таблицы содержащей обозначение, наименование, сортамент, длина, ширина, кол-во деталей (сборок) в обрабатываемой сборке.
Возник вопрос с кол-вом деталей одного наименования (обозначения) в сборке.

Module Module1
    Sub Main()

        Dim PathFolder_1 As String
        Dim coll As System.Collections.ObjectModel.ReadOnlyCollection(Of String)
        Dim kompas As Kompas6API5.Application



        Form1.FolderBrowserDialog1.SelectedPath = "W:\Архив\Типовые элементы (3D)\ТМСР (ТМ)" 'System.AppDomain.CurrentDomain.BaseDirectory
        Form1.FolderBrowserDialog1.ShowDialog()
        PathFolder_1 = Form1.FolderBrowserDialog1.SelectedPath

        'список моделей сборочных единиц в указанной папке
        coll = Microsoft.VisualBasic.FileIO.FileSystem.GetFiles(PathFolder_1, FileIO.SearchOption.SearchAllSubDirectories, "*.a3d")

        'запуск Компас

        If kompas Is Nothing Then
            kompas = CreateObject("KOMPAS.Application.5")
            If Not Kompas Is Nothing Then
                Kompas.Visible = True
                'начало цикла обработки сборочных единиц
                For i = 0 To coll.Count
                    'Kompas.ksYesNo(1)
                    Dim Document As Document3D
                    Document = kompas.Document3D
                    Document.Open(coll(i))

                    Dim iPart As ksPart
                    Dim doc3D As ksDocument3D
                    Dim kompas_1 As KompasObject
                    Dim j As Integer
                    Dim ll As String
                    Dim jj As Integer
                    Dim PColl As ksPartCollection
                    Dim PathList() As String

                    kompas_1 = kompas

                    doc3D = kompas_1.ActiveDocument3D


                    PColl = doc3D.PartCollection(True)
                    'PathList = StringUnit.Create

                    jj = PColl.GetCount

                    For j = 0 To PColl.GetCount - 1
ПЫТАЮСЬ ВЫТАЩИТЬ ЭТИ ДАННЫЕ В ЭТОМ МЕСТЕ ИЗ iPart
                        iPart = doc3D.GetPart(j)
                        ReDim Preserve PathList(j)
                        PathList(j) = iPart.fileName
                        ll = iPart.name
             Next j
                Next i
            End If
        End If

    End Sub
End Module


Есть ещё функция создать отчёт от куда вроде то-же можно достать кол-во деталей, но в СДК я про это ни чего не нашёл.

Интерфейс для управления процессом Создать отчет IReportProcess

А8208

Т.е. создать ещё один документ и проанализировать уже его.
Но в процессе создания отчёта данные по кол-ву одинаковых деталей берутся же откуда-то. Значит они уже есть в самой сборке.
И в дереве построения компас пишет, в конце наименования детали в скобках их кол-во в сборке.
Через какой интерфейс можно получить эти данные?

chelkar

Для анализа сборки я использую функцию IPart7::PartsEx.
Она может возвращать все компоненты, включая массивы, макросы и пр. объединения, а может только оригиналы.
Для анализа всей сборки, нужно сделать рекурсивный разбор - сборка/подсборка/подподсборка и т.д.
Во вложении макрос на Питоне с таким разбором.

Еще, в справке на SDK, есть пример для функции IPart7::PartsEx.
Как раз считает количество.
+ Благодарностей: 1

А8208


А8208

Добрый день!
Возник ещё один вопрос.
Не выводит обозначение детали.
Где что я сделал не так?
Dim Document As IDocuments
                    Document = kompas.Documents
                    Document.Open(coll(i))
                    Dim doc3D As IKompasDocument3D
                    Dim name_SB, oboznach_SB As String
                    Dim name_detal, oboznach_detal As String
                    Dim i_detal As Integer
                    Dim iTopPart As IPart7
                    Dim Massive_detalei As System.Object

                    doc3D = kompas.ActiveDocument

                    iTopPart = doc3D.TopPart 'верхний элемент дерева сборочного чертежа
                    name_SB = iTopPart.Name 'наименование сборочного чертежа
                    oboznach_SB = iTopPart.Marking 'обозначение сборочного чертежа
                    'Обработка элементов содержащихся в сборке
                    Massive_detalei = iTopPart.PartsEx(1) ' Массив оригинальных деталей (сборок) сборки
                    For j = 0 To Massive_detalei.length() - 1


                        name_detal = Massive_detalei(j).name 'наименование детали
                        oboznach_detal = Massive_detalei(j).Marking ' обозначение детали НЕ ПОЛУЧАЕТ ЭТОТ ПАРАМЕТР
                        i_detal = iTopPart.InstanceCount(Massive_detalei(j)) 'кол-во деталей в сборке
                       
                    Next j

chelkar

Тут такое дело.
У компонента сборки есть несколько свойств.
1. Имя компонента во вставке, это то что мы видем в Дереве сборки. По умолчанию, при вставке, оно берется из имени в файле-источнике.
2. Имя и Обозначение в самом источнике.
Вам нужно получить свойства по п.2.
Для этого надо перейти к доп. интерфейсу ISourcePart7Params и у него получить:
- обозначение ISourcePart7Params::SourceMarking
- наименование ISourcePart7Params::SourceName



А8208


EasyComeEasyGo

Цитата: chelkar от 02.12.11, 10:50:31Для этого надо перейти к доп. интерфейсу ISourcePart7Params и у него получить:
- обозначение ISourcePart7Params::SourceMarking
- наименование ISourcePart7Params::SourceName
Покажите, как сделать это на Питоне.

В документации сказано, что ISourcePart7Params можно получить от IPart7 через QueryInterface, но она в Python'овском SDK к Компасу не определена, вместо неё, как я понимаю, KompasObject.TransferInterface.

Попытки использовать TransferInterface так и сяк пока ни к чему не привели. Если последним параметром задаю то, что вроде как требуется по документации (хотя формулировка и малопонятная - "тип объекта в интерфейсе, к которому преобразуется исходный объект"), т.е. пишу так:

srcpart = KompasObject.TransferInterface( toppart,
                                    ksConstants.constants.ksAPI7Dual,
                                    Kompas10API7.ISourcePart7Params )
или даже так:

srcpart = KompasObject.TransferInterface( toppart,
                                    ksConstants.constants.ksAPI7Dual,
                                    Kompas10API7.ISourcePart7Params.CLSID )

- то Компас в обоих случаях выдаёт ошибку:
File "Kompas10API5.pyc", line 169, in TransferInterface
TypeError: int() argument must be a string or a number



Если же ставлю ноль (хотя и не понятно, что это значит), как советовали на форуме, оно ошибку не выдаёт, но и ничего не делает.

toppart = iDoc3D.GetPart( ksConstants3D.constants.pTop_Part )
srcpart = CAD.API.KompasObject.TransferInterface( toppart, ksConstants.constants.ksAPI7Dual, 0 )
pname = srcpart.SourceName

Вылетает ошибка AttributeError: 'IPart7' object has no attibute 'SourceName'. В принципе логично, поскольку здесь нигде не упоминается тип 'ISourcePart7Params'. Принудительное приведение ни до, ни после TransferInterface не помогает - поля 'SourceName' и 'SourceMarking' пустые (хотя в сборке они, разумеется, заполнены).

Вот мой код, исправьте его до рабочего:
def Give_SourceData( part ):
    pcount = iTopPart.InstanceCount( part )   

    try:
        iDoc3D = iKompasObject.Document3D()
        iDoc3D.Open( part.FileName, True )
        toppart = iDoc3D.GetPart( ksConstants3D.constants.pTop_Part )

        ???
        srcpart = ... #получить ISourcePart7Params
        ???

        pname = srcpart.SourceName
        pmarking = srcpart.SourceMarking

    finally:
        iDoc3D.close()

    return pname, pmarking, pcount

На входе - ksPart, полученный путём обхода TopPart.PartsEx(1).

EasyComeEasyGo

Попробовал ещё такой вариант:

srcpart = toppart._oleobj_.QueryInterface( toppart.CLSID, Kompas10API7.ISourcePart7Params.CLSID )

Получил ошибку:
TypeError: There is no interface object registered that supports this IID.

16.04.12, 10:04:15 #10 Последнее редактирование: 16.04.12, 10:24:57 от Sabahs
Можно попробовать, работоспособность не гарантирую и toppart должен быть IPart7, а не ksPart.
toppart._oleobj_.QueryInterface(Kompas10API7.ISourcePart7Params.CLSID,srcpart)
или
toppart._oleobj_.QueryInterface(IID_ISourcePart7Params,srcpart)

EasyComeEasyGo

05.05.12, 09:56:07 #11 Последнее редактирование: 05.05.12, 10:14:33 от EasyComeEasyGo
Вообще ничего не получается. Никак. Нужно всего-то-навсего получить наименование и обозначение каждой детали, заданное при её вычерчивании. Они существуют в документе. Пользователь Компаса их видит. Компас имеет программный API. Как это так надо постараться, чтобы при живом API невозможно было программно получить живые данные???



toppart._oleobj_.QueryInterface(Kompas10API7.ISourcePart7Params.CLSID,srcpart)
или
toppart._oleobj_.QueryInterface(IID_ISourcePart7Params,srcpart)

Такая структура API рассчитана на наличие в языке возможности создать пустой мутабельный объект и передать ссылку на него. API должен быть универсальным, COM вообще придумывался как средство сокрытия языка реализации, но в грамотных языках не существует ни изменяемого состояния, ни операции выделения памяти под объект в принципе, так что результат должен возвращаться лишь классическим способом. В Питоне подобный трюк в принципе может быть вывернут - явно сконструировать объект класса, а потом в функции динамически приклеить к нему новые свойства. В данном случае это должно выглядеть, видимо, так:

srcpart = Kompas10API7.ISourcePart7Params()
toppart._oleobj_.QueryInterface( Kompas10API7.ISourcePart7Params.CLSID, srcpart )
pname = srcpart.marking
pmarking = srcpart.marking

Но работоспособность этого трюка зависит в данном случае от Аскона, а не от меня, приведённый код результата не дал. Вы это всё придумали, так научите всё это эффективно использовать! Хелп из поставки не помогает совершенно.

Цитировать
toppart должен быть IPart7, а не ksPart.
А, ну да, он и есть - его же вернул IPart7.PartsEx(). Я просто никак не могу понять закономерностей, согласно которым должны приниматься решения о выборе того или иного префикса при попытке достучаться до Компаса. Всякий раз, переходя по перекрёстным ссылкам в хелпе, вспоминаю "Историю программных революций от Microsoft", в том смысле, что меня любезно избавили от DLL Hell. И уж тем более не понятно, почему 'i???' и 'ks???' не дублируются на 100%.

EasyComeEasyGo

А техподдержка работает? Или я адресом ошибся?

Посмотрите тему http://forum.ascon.ru/index.php/topic,22220.0.html там есть рабочий пример с использованием функции QueryInterface, сделайте у себя аналогично применительно к интерфейсу ISourcePart7Params.
IFeature7 = Part._oleobj_.QueryInterface(KAPI7.NamesToIIDMap['IFeature7'], pythoncom.IID_IDispatch)
IFeature7 = KAPI7.IFeature7 (IFeature7)

На счет технической поддержки, то здесь она не отвечает, поэтому обращайтесь сюда http://support.ascon.ru/request/

EasyComeEasyGo

О, виноват, я думал тут и есть техподдержка. Благодарю за посильную помощь!

EasyComeEasyGo

Цитировать
srcpart = toppart._oleobj_.QueryInterface( Kompas10API7.NamesToIIDMap['ISourcePart7Params'], pythoncom.IID_IDispatch )
Я и так тоже пробовал. Точнее, я писал так:
Цитировать
srcpart = toppart._oleobj_.QueryInterface( Kompas10API7.ISourcePart7Params.CLSID, pythoncom.IID_IDispatch )
- ибо это ровно одно и то же: 'NamesToIIDMap' - ни больше ни меньше - отображает имя в кавычках на CLSID. Но использование идентификатора гораздо больше похоже на выражение мысли непосредственно (сиречь декларативное программирование), так что этот словарь видимо реализован для перректального доступа к тому же содержимому.

Так или иначе, в лучшем случае после запуска скрипта из Компаса я получаю сообщение "интерфейс не поддерживается" либо "класс не зарегистрирован" (точнее, я получаю набор зюков типа "\xc8\xed\xf2\xe5\xf0\xf4\xe5\xe9\xf1...", которые приходится вскрывать самостоятельно путём вбивания вручную в Штирлиц, т.е. я ещё криптографом подрабатываю по совместительству). В файле 'Kompas10API7' этот класс описан, и в словаре 'NamesToIIDMap' он тоже упоминается, но Компас, который эти файлы тащил с собой при установке, на это плевал. Буду штурмовать техподдержку.

Компас V12.