Как определить длину полки на линии-выноске?

Автор lavgirb, 29.11.25, 20:29:00

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

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

lavgirb

Как определить длину полки на линии-выноске? В том числе и на линии-выноске для номеров позиций.
И второй вопрос. Как вычислить ширину текста? В том числе и на линии-выноске для номеров позиций.
Спасибо.

p3452

По первому вопросу - не отвечу (как-то делал, но как не помню, а "ковырятся" сегодня лень :embarrassed: ).
По второму вопросу - нормально можно вычислить только для моноширного шрифта, по ширине одного символа, для непропорциональных шрифтов - достаточно НЕ ПРОСТО и затратно по коду...).

p3452

#2
По первому вопросу - использовал "Строительные обозначения". Есть пример - Step1_API7_2D (Delphi)...
(Есть пример для обычных выносок - STEP9)
И там, и там есть координаты "начала полки", ну а далее - математика...

lavgirb

#3
Цитата: p3452 от 01.12.25, 13:55:05По первому вопросу - использовал "Строительные обозначения". Есть пример - Step1_API7_2D (Delphi)...
(Есть пример для обычных выносок - STEP9)
И там, и там есть координаты "начала полки", ну а далее - математика...
p3452, спасибо.
Начало полки не трудно получить. Вот с ее длиной...
Начал подумывать о разрушении линии-выноски для номера позиции.
Потом измерение длины отрезка с известными координатами одного конца.
Потом Ctrl+Z для возврата в исходное состояние.
Правда, разрушать программно пока не  пробовал)
Есть один положительный момент: все полки одной линии-выноски для номеров позиций в КОМПАС одинаковой длины.
Измерив одну, будешь уже знать и другие.

В этом случае ширина шрифта на полке уже не будет нужна.

p3452

А как, вообще, возникла такая задача?
- Зачем (для чего), в Ваших задачах, нужна ширина полки?

lavgirb

Цитата: p3452 от 01.12.25, 15:01:58А как, вообще, возникла такая задача?
- Зачем (для чего), в Ваших задачах, нужна ширина полки?
Придумал наносить временный текст для проверки номеров позиций.
Длина полки нужна для отступа текста, чтоб не загораживал номер(а) позиций.

text.jpg

СВ

#6
Ну так если позиций не более 199, то достаточно отступить на длину полки под две цифры и голову не ломать. (А если не более 999, то ...) При таких длинных надписях какой смысл выгадывать несколько миллиметров. Причём выгадывание ВСЕГО ЛИШЬ с позиции 1 до позиции 9. Просто смешно вкладывать столько труда в такую мизерную отдачу ...

Kolos

Цитата: СВ от 01.12.25, 15:48:18Ну так если позиций не более 199, то достаточно отступить на длину полки под две цифры и голову не ломать. (А если не более 999, то ...) При таких длинных надписях какой смысл выгадывать несколько миллиметров.
Не всё так просто.
Полуфабрикат - нужен?
SearchForObjects.zip

lavgirb

Цитата: Kolos от 01.12.25, 16:33:18Не всё так просто.
Полуфабрикат - нужен?
SearchForObjects.zip
Для приложений на форуме есть специальный раздел:
Форум пользователей ПО АСКОН ► Профессиональные вопросы ► Программирование приложений ► Биржа прикладных разработок

Kolos

Цитата: lavgirb от 01.12.25, 16:54:06Для приложений на форуме есть специальный раздел:
Форум пользователей ПО АСКОН ► Профессиональные вопросы ► Программирование приложений ► Биржа прикладных разработок
Это - Полуфабрикат, когда будет вещь, будете на ► Биржа прикладных разработок.
PS. И, я не Вам писал.

p3452

Теоретически (не проверял):
1 - Из PosLeaderParam или LeaderParam получаем
1.1 - x, y - координаты базовой точки (начало первой полки, точка выхода из нее "ножки"),
1.2 - pText - динамический массив строк.
2 - Из pText - определяем строку наибольшей длинны.
3 - Для нее, из ParagraphParam, определяем
3.1 - x, y координаты точки привязки текста,
3.2 - width - ширина блока форматирования ("блоком" будет вся строка).
4. Разница 3.1 и 1.1 - даст "ОТСТУП" текста.
5. Тогда, для варианта горизонтального расположения полки,
"Ширина полки" = width(из п.3.2) + 2*ОТСТУП(из п.4)

lavgirb

Цитата: p3452 от 01.12.25, 17:04:44Теоретически (не проверял):
1 - Из PosLeaderParam или LeaderParam получаем
1.1 - x, y - координаты базовой точки (начало первой полки, точка выхода из нее "ножки"),
1.2 - pText - динамический массив строк.
2 - Из pText - определяем строку наибольшей длинны.
3 - Для нее, из ParagraphParam, определяем
3.1 - x, y координаты точки привязки текста,
3.2 - width - ширина блока форматирования ("блоком" будет вся строка).
4. Разница 3.1 и 1.1 - даст "ОТСТУП" текста.
5. Тогда, для варианта горизонтального расположения полки,
"Ширина полки" = width(из п.3.2) + 2*ОТСТУП(из п.4)
Свойство Width есть у интерфейса IDrawingText.
Но IDrawingText мне не удалось получить у номера позиции от интерфейса IText.
Появляется ошибка. В API7.
Возможно, в API5 будет тоже самое. Не пробовал. Может, соберусь попробовать.

Вариант с разрушением для меня проще) Времени много не должен занять. Во время выполнения.
Буду пробовать

lavgirb

Цитата: СВ от 01.12.25, 15:48:18Просто смешно вкладывать столько труда в такую мизерную отдачу ...
Все более или менее приличное состоит из мелочей.
Если Вы не проставляете возле номера позиции количество в скобках, то Вам не понять, на сколько разными могут быть по длине полки у КОМПАС.
И да. Жаль, что Вы не понимаете, что на форуме задают вопросы для их решения, а не для комментариев не по теме.

СВ

 Ну почему ТОЛЬКО комментариев, гораздо больше буков потрачено на ПРЕДЛОЖЕНИЕ, очень простое (простейшее!) в реализации и достаточно эффективное. По нему длина строки получается точно такой же как у вас - в 94% случаев, и на 6 мм длиннее - в оставшихся 6%.
Цитата: СВ от 01.12.25, 15:48:18Ну так если позиций не более 199, то достаточно отступить на длину полки под две цифры и голову не ломать. (А если не более 999, то ...) При таких длинных надписях какой смысл выгадывать несколько миллиметров. Причём выгадывание ВСЕГО ЛИШЬ с позиции 1 до позиции 9.
Единственный недостаток - оно совсем другое, чем вы сами задумали. Соответственно - не нужное. Понимаю. (Подумал - вдруг вы его не поняли. Вряд ли!)

lavgirb

p3452, разрушить не удалось.
В V23 Home не срабатывает метод DestroyObjects. Хотя и возвращает Истину, "обозначение позиции" не разрушается.

destroy.jpg

Но попутно обнаружил как из гиперссылки в номере позиции получить данные компонента: Обозначение, Наименование и другие свойства компонента сборки.
Это плюс.)

p3452

Сам, смогу попробовать, только завтра после 17 часов...

p3452

Оба метода рабочие, хотя метод с "разрушением" проще по коду...
"Разрушить" можно посредством:
- экспортной функции (API5) - ksDestroyObjects ,
// Разрушить объект заданный Reference
if (ksDoc2D.ksDestroyObjects(iDrawingObject.Reference) == 0)
    iDrawingObject.Update();
- команды Компаса (API7) - ExecuteKompasCommand
iDrawingObject.Application.ExecuteKompasCommand((int)ksKompasCommandEnum.ksCMDestroyMacro, false);
- для v22 и старше - приведенного интерфейса IKompasDocument2D1 от документа
iKompasDocument2D1.DestroyObjects(obj)
+ Благодарностей: 1

lavgirb

p3452, спасибо за сообщение.

// Разрушить объект заданный Reference
if (ksDoc2D.ksDestroyObjects(iDrawingObject.Reference) == 0)
    iDrawingObject.Update();
У линии-выноски для номера позиции я не нашел свойства  Reference.  :(

iKompasDocument2D1.DestroyObjects(obj)
У меня не разрушает (V23 Home). Может есть какие-то особенности.

iDrawingObject.Application.ExecuteKompasCommand((int)ksKompasCommandEnum.ksCMDestroyMacro, false);
Это попробую.


p3452

Пример создания и РАЗРУШЕНИЯ Линейной выноски, на базе STEP9:
Разрушение лин_выноски.png
//using Kompas6API5;
//using KAPITypes;
//using Kompas6Constants;

//private KompasObject kompas;
//private ksDocument2D doc;

//+ 04 Линейная выноска
int DrawLeader()
{ int ret = -1;
ksLeaderParam lead = (ksLeaderParam)kompas.GetParamStruct((short)StructType2DEnum.ko_LeaderParam);
ksTextLineParam tLinePar = (ksTextLineParam)kompas.GetParamStruct((short)StructType2DEnum.ko_TextLineParam);
ksTextItemParam ItemPar = (ksTextItemParam)kompas.GetParamStruct((short)StructType2DEnum.ko_TextItemParam);
ksTextItemFont tFont = (ksTextItemFont)ItemPar.GetItemFont();
ksMathPointParam tMathPoint = (ksMathPointParam)kompas.GetParamStruct((short)StructType2DEnum.ko_MathPointParam);
if (lead != null && tLinePar != null && ItemPar != null && tFont != null && tMathPoint != null)
{
lead.Init();
tLinePar.Init();
ItemPar.Init();
tFont.Init();
tMathPoint.Init();

tFont.SetBitVectorValue(ldefin2d.NEW_LINE, true);
tLinePar.style = 0;

ksDynamicArray pText = (ksDynamicArray)lead.GetpTextline();
ksDynamicArray TextItemArr = (ksDynamicArray)tLinePar.GetTextItemArr();
if (TextItemArr == null || pText == null)
return -1;

ItemPar.s = "1";
TextItemArr.ksAddArrayItem(-1, ItemPar);
pText.ksAddArrayItem(-1, tLinePar);

ksDynamicArray pPolyLin = (ksDynamicArray)lead.GetpPolyline();
ksDynamicArray pMathPoint = (ksDynamicArray)kompas.GetDynamicArray(ldefin2d.POINT_ARR);
if (pPolyLin == null || pMathPoint == null)
return -1;

tMathPoint.x = 10;   // Точка первой выноски
tMathPoint.y = 10;

pMathPoint.ksAddArrayItem(-1, tMathPoint);
pPolyLin.ksAddArrayItem(-1, pMathPoint);

lead.SetpPolyline(pPolyLin);

//заполним параметры
lead.x = 50; // координаты базовой точки (начало полки)
lead.y = 50;
lead.arrowType = 1; // тип стрелки
lead.dirX = 1; // направление полки по X (1 - вправо -1 - влево)
lead.signType = 0; // тип знака
lead.around = 0; // знак обработки по контуру 0 - выключен 1 - включен
lead.cText0 = 1; // количество строк текста над полкой 0 - текст отсутствует
lead.cText1 = 0;
lead.cText2 = 0; // количество строк текста над ножкой (не более 1 строки) 0 - текст отсутствует
lead.cText3 = 0;

int obj = doc.ksLeader(lead);
if (obj != 0)
{
doc.ksGetObjParam(obj, lead, ldefin2d.ALLPARAM);
ret = obj;
}
}
return ret;
}


//+ 41 Создать Линейную выноску и РАЗРУШИТЬ ее - DrawLeaderDestroy()
void DrawLeaderDestroy()
{ int obj = -1;
obj = DrawLeader();
if (obj != 0)
{ doc.ksDestroyObjects(obj);
}
}