Работа с API компас в C#. Получение размеров детали.

Автор D.I.R.W., 10.11.15, 13:35:37

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

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

Vi2

Цитата: Denis78 от 31.05.22, 13:50:46PS. Вообще, мне кажется, должен быть способ проще. Что я имею ввиду.
Если написать так:
IUnknownPtr vd(kompas->TransferInterface(obj1, ksAPI3DCom, o3d_vertex));
то vd - валидный указатель. Но на что? Казалось бы, ответ очевиден, на IVertexDefinition, но нет. Если написать так:
IVertexDefinitionPtr vd(kompas->TransferInterface(obj2, ksAPI3DCom, o3d_vertex));
vd будет равным NULL. То есть вместо IVertexDefinitionPtr нужно что-то иное.
Я же тебе предлагал проверить интерфейс IEntity:
IEntityPtr vdentity(kompas->TransferInterface(obj1, ksAPI3DCom, o3d_vertex), false);
IVertexDefinitionPtr vd(vdentity->GetDefinition(), false);
Я сам не могу проверить, но вроде так должно быть.

PS
TransferInterface возвращает интерфейс с увеличенной ссылкой, поэтому нужно правильно инициализировать умный указатель.
+ Благодарностей: 1

Denis78

#21
Попробовал и так

IEntityPtr vdentity(kompas->TransferInterface(obj1, ksAPI3DCom, o3d_entity));

и так:

IEntityPtr vdentity(kompas->TransferInterface(obj1, ksAPI3DCom, o3d_vertex));

К сожалению, в обоих случаях vdentity равен NULL.

Кстати, а для чего false вторым параметром?
Я его когда добавляю, у меня ошибка генерится:
error C2664: '_com_ptr_t<_com_IIID<IEntity,& _GUID_7aa0e540_0301_11d4_a30e_00c026ee094f>>::_com_ptr_t(LPCSTR,IUnknown *,DWORD)': cannot convert argument 1 from 'IUnknownPtr' to 'IEntity *'

Vi2

Цитата: Denis78 от 31.05.22, 15:46:27Попробовал и так

IEntityPtr vdentity(kompas->TransferInterface(obj1, ksAPI3DCom, o3d_entity));

и так:

IEntityPtr vdentity(kompas->TransferInterface(obj1, ksAPI3DCom, o3d_vertex));

К сожалению, в обоих случаях vdentity равен NULL.
Ничего не могу сказать, если будет время, попробую поисследовать, если к тому времени p3452 не разродится кодом.

Цитата: Denis78 от 31.05.22, 15:46:27Кстати, а для чего false вторым параметром?
Я его когда добавляю, у меня ошибка генерится:
error C2664: '_com_ptr_t<_com_IIID<IEntity,& _GUID_7aa0e540_0301_11d4_a30e_00c026ee094f>>::_com_ptr_t(LPCSTR,IUnknown *,DWORD)': cannot convert argument 1 from 'IUnknownPtr' to 'IEntity *'
Посмотрел свой код, я бы написал так, чтобы иметь ненулевой указатель и дальше от него плясать:
IEntityPtr vdentity(IUnknownPtr(kompas->TransferInterface(obj1, ksAPI3DCom, 0)), false);
IVertexDefinitionPtr vd(IUnknownPtr(kompas->TransferInterface(obj1, ksAPI3DCom, 0)), false);
Если всё вертится вокруг o3d_vertex в объекте obj1, то либо IEntity, либо IVertexDefinition. Другого же вроде не должно быть?!

Vi2

Цитата: p3452 от 31.05.22, 22:02:17Vi2...
Если ты приводишь скрины работы некоего кода, то мог бы и сам код выложить. Для тебя это может быть тривиальной задачей, а для других - раздумье на распутье.

Я лично отвечаю, только глядя на приводимый код. Зачем нужно приводить к ksAPI3DCom, если вроде там непосредственно АПИ7 IModelObject, который имеет и тип, и приводится к нужному по типу интерфейсу того же АПИ7, т.е. IVertex. Вроде бы так, нет?

PS
У меня на домашнем компе только "Справка по АПИ Компаса".

Toptotal

Просьба программистов или те кто тренируется или студенты. Мне нужна программа или макрос, ну так чтоб запустил ее и все папку с библиотекой файлов /архивов,  просканировать и проставить значения в свойствах файла.
Мне нужна запись в свойствах файла
#01 Имя конфигурации
#01 Lx=***mm
#01 Ly=***mm
#01 Lz=***mm
#01 Тип материала (ЛИСТ 5мм/труба 60х60) ну или просто что это листовой материал развертка 
----------------------------------------------------------------------------------------
#02 Имя конфигурации
#02 Lx=***mm
#02 Ly=***mm
#02 Lz=***mm
#02 Тип материала (ЛИСТ 5мм/труба 60х60) ну или просто что это листовой материал развертка 
=========================================================================================

и так далие по конфигурациям.

Если возможно то куда входит в какие файлы и в каких количествах он присутствует , если возможно. Ну не как не хочу я всякие ПДМ ставить и мучится с их настройкой.
Возможно что то добавлять еще. Я только за чем больше инфы  фаил запишется тем лучше. Можно имя файла или обозначение и обозначение сборки и файла.
Мне это нужно для организации сортировки/поиска/геометрического поиска, переименования фалов библиотек и тд.
Есть желающие сделать такое и потренироваться?

Михаил88

#25
Линейный размер от точки до отрезка

iSymbols3DContainer = kompas_api7_module.ISymbols3DContainer(iPart7)
iLineDimensions3D = iSymbols3DContainer.LineDimensions3D

iBaseLineDimension3D = iLineDimensions3D.LineDimension3D(0)
print(iBaseLineDimension3D.ModelObjectType) #  80 - Линейный размер 3D (от отрезка до точки)

object1 = iBaseLineDimension3D.Object1
print(object1)
print(object1.ModelObjectType) #o3d_vertex - вершина - 8
iVertex = kompas_api7_module.IVertex(object1)
print(iVertex)
rez = iVertex.GetPoint()
print(rez)

object2 = iBaseLineDimension3D.Object2
print(object2)
print(object2.ModelObjectType) #o3d_edge - ребро - 7
iEdge = kompas_api7_module.IEdge(object2)

#TRUE - начальная вершина
#FALSE - конечная вершина

start_1 = True # Вершина
vertex_1 = iEdge.Vertex(start_1)
print(vertex_1)
rez1 = vertex_1.GetPoint()
print(rez1)

start_2 = False # Вершина
vertex_2 = iEdge.Vertex(start_2)
print(vertex_2)
rez2 = vertex_2.GetPoint()
print(rez2)

Screenshot_4.png
Screenshot_3.png
+ Благодарностей: 2

p3452

Во-о-от!  Михаил88 +++

Для остальных:
- смотрим пост №4, первые 4 строчки это и есть код Михаил88
- следующие 4 строчки это решение второй задачи из озвученных ТС, (Михаил88 ее не затронул) - нахождение координат самой размерной линии...

Denis78

#27
Небольшой апдейт.

Я добавил в чертеж еще 3 размера, итого 4, поскольку один уже был. Вот они:
Размер "229" я построил по грани и точке (она на чертеже идет параллельно размерной линии 229, выделена зеленым)
Размер "38,5" по двум граням (тоже выделены зеленым)
Размер "1-8229-3" тоже по двум граням (тоже выделены зеленым, но видна только одна из них)
Размер "40" по трем точкам: две на окружностях (соответствуют углу в 270 градусов, или координатам x = 0; y = -R)

И добавил функцию. Весь код приводить не буду (он есть в одном из моих предыдущих постов), только основное:

ILineDimensions3DPtr dims3d = s3d->GetLineDimensions3D();
for (long i = 0; i < dims3d->GetCount(); i++)
{
    IModelObjectPtr obj1 = dim->GetObject1();
    PrintMoAsEntity("obj1", obj1);            // Здесь, первый параметр - строка "obj1" - просто для полноты логирования
    IModelObjectPtr obj2 = dim->GetObject2();
    PrintMoAsEntity("obj2", obj2);
    IModelObjectPtr plane = dim->GetPlane();
    PrintMoAsEntity("plane", plane);
}

void PrintMoAsEntity(string pref, IModelObjectPtr mo)
{
    ksEntityPtr entity = IUnknownPtr(kompas->TransferInterface(mo, ksAPI5Auto, o3d_entity));
    if (entity)
    {
        ksFaceDefinitionPtr face = entity->GetDefinition();
        ksEdgeDefinitionPtr edge = entity->GetDefinition();
        ksVertexDefinitionPtr vx = entity->GetDefinition();

        if (face)    // [1]
        {
            ksEdgeCollectionPtr edgeCol = face->EdgeCollection();
            long cnt = edgeCol->GetCount();
            Dbg("======= PrintMoAsEntity: ", pref, ": ", cnt, " ========");
            for (long j = 0; j < cnt; ++j)
            {
                ksEdgeDefinitionPtr edge = edgeCol->GetByIndex(j);
                ksVertexDefinitionPtr vxs = edge->GetVertex(true);
                ksVertexDefinitionPtr vxe = edge->GetVertex(false);
                double x1, y1, z1;
                double x2, y2, z2;
                bool res = vxs->GetPoint(&x1, &y1, &z1);
                res = vxe->GetPoint(&x2, &y2, &z2);
                Dbg("vxPoint1: ", x1, ", ", y1, ", ", z1);
                Dbg("vxPoint2: ", x2, ", ", y2, ", ", z2);
            }
        }
        else if (edge)   // [2]
        {
            Dbg("======= PrintMoAsEntity: ", pref, ": EDGE ========");
            ksVertexDefinitionPtr vxs = edge->GetVertex(true);
            ksVertexDefinitionPtr vxe = edge->GetVertex(false);
            double x1, y1, z1;
            double x2, y2, z2;
            bool res = vxs->GetPoint(&x1, &y1, &z1);
            res = vxe->GetPoint(&x2, &y2, &z2);
            Dbg("Edge Start: ", x1, ", ", y1, ", ", z1);
            Dbg("Edge End: ", x2, ", ", y2, ", ", z2);
        }
        else if (vx)    // [3]
        {
            Dbg("======= PrintMoAsEntity: ", pref, ": VERTEX ========");
            double x1, y1, z1;
            bool res = vx->GetPoint(&x1, &y1, &z1);
            Dbg("Vertex: ", x1, ", ", y1, ", ", z1);
        }
    }
}

Если мы попадаем в условие [2] и [3], то всё хорошо. Вывод будет выглядеть примерно так:
Цитата: undefined======= PrintMoAsEntity:  obj1 : VERTEX ========
Vertex:  62.550000 ,  36.000000 ,  -60.000000
Dim Len:  -17.431224
======= PrintMoAsEntity:  obj2 : VERTEX ========
Vertex:  62.550000 ,  36.000000 ,  -100.000000
Это был размер "40", а условие, соответственно [3].

А так выглядит вывод по условию [2], размер 229:
Цитата: undefined======= PrintMoAsEntity:  obj1 : EDGE ========
Edge Start:  68.000000 ,  36.000000 ,  -114.500000
Edge End:  68.000000 ,  36.000000 ,  114.500000
Dim Len:  72.333513

Хуже дела с размером 8229 (на чертеже обозначен красным) и 38.5, поскольку obj1 и obj2 - плоскости, и вывод для данного случая, будут состоять из 8 точек для obj1, 8 точек для obj2 и 75 точек(!) для plane. Итого 83 точки. Как говорилось в старом анекдоте: "Где будем делать талию, мадам?". Т.е. откуда откладывать размерные линии? И ведь, если приглядеться, на чертеже есть отрезки, обозначенные штрихпунктирной линией с двумя точками, но вот как получить координаты этих линий - не ясно.

P.S. Еще минус такого подхода, это то, что программа не знает, как был построен размер, поэтому и присутствует в коде вот этот кусок:
ksFaceDefinitionPtr face = entity->GetDefinition();
ksEdgeDefinitionPtr edge = entity->GetDefinition();
ksVertexDefinitionPtr vx = entity->GetDefinition();
А уже потом смотрим, кто из указателей не null.
Было бы лучше, если бы можно было написать что-то вроде:
Obj3dType type = (Obj3dType)doc3D->GetObjectType(mo);
if (type == o3d_face)
{
    ksFaceDefinitionPtr face = entity->GetDefinition();
    // код соответствующий face
}
else if (type == o3d_edge)
{
    ksEdgeDefinitionPtr edge = entity->GetDefinition();
    // код соответствующий edge
}
else if (type == o3d_vertex)
{
    ksVertexDefinitionPtr vx = entity->GetDefinition();
   ...
}

Но это не прокатит, type всегда будет -1
Хотя, это уже, конечно, мелочи

Михаил88

Вторую часть тоже можно, я просто не стал ее писать.

Denis78

#29
Цитата: Михаил88 от 01.06.22, 17:54:59Вторую часть тоже можно, я просто не стал ее писать.

Спасибо, кажись, понял, сейчас попробую.

Михаил88


Михаил88

Мой код даёт координаты точек привязки размера, а можно ещё получить координаты размерной линии
+ Благодарностей: 1

Vi2

Цитата: Denis78 от 01.06.22, 17:42:57А уже потом смотрим, кто из указателей не null.
Было бы лучше, если бы можно было написать что-то вроде:
Код Выделить Expand
Obj3dType type = (Obj3dType)doc3D->GetObjectType(mo);
if (type == o3d_face)
{...}
else if (type == o3d_edge)
{...}
else if (type == o3d_vertex)
{...}
Но это не прокатит, type всегда будет -1
Хотя, это уже, конечно, мелочи
У тебя mo->ModelObjectType и есть этот type! Т.е.
Obj3dType type = (Obj3dType)mo->ModelObjectType;
+ Благодарностей: 1

Denis78

Цитата: Михаил88 от 01.06.22, 18:22:46Мой код даёт координаты точек привязки размера, а можно ещё получить координаты размерной линии

Это да, что-то такое у меня получилось. Но только не в случае когда размер проставляется по двум поверхностям и плоскости.
Поэтому, буду весьма благодарен, если получится координаты размерных линии получить

Михаил88

Цитата: Denis78 от 02.06.22, 12:01:10Это да, что-то такое у меня получилось. Но только не в случае когда размер проставляется по двум поверхностям и плоскости.
Поэтому, буду весьма благодарен, если получится координаты размерных линии получить

посмотрю, как время будет

Михаил88

Цитата: Denis78 от 02.06.22, 12:01:10Но только не в случае когда размер проставляется по двум поверхностям и плоскости.

Это тоже решается. У плоскостей есть общие точки соприкосновения.

Denis78

Цитата: Михаил88 от 02.06.22, 16:02:01Это тоже решается. У плоскостей есть общие точки соприкосновения.

Есть. И их много, какие выбирать?
На моем чертеже, тот что выше, красным выделено 3 размерных линии. Неужели невозможно получить координаты начала/конца этих линий?

Михаил88

Цитата: Denis78 от 02.06.22, 16:06:39Есть. И их много, какие выбирать?
На моем чертеже, тот что выше, красным выделено 3 размерных линии. Неужели невозможно получить координаты начала/конца этих линий?

вы прям на картинке выделите точки координаты которых нужно получить. Там нет 3 размерных линий. Она одна и две выносных.

Screenshot_1.bmp

Denis78

Цитата: Михаил88 от 02.06.22, 16:23:07вы прям на картинке выделите точки координаты которых нужно получить. Там нет 3 размерных линий. Она одна и две выносных.

1-2, 3-4 две выносных
 5-6 размерная

Михаил88

Хорошо, теперь понятно. Я посмотрю. Как будет результат напишу.