Добрый день!
Есть необходимость в создании своего САПР на базе КОМПАС для типовых деталей - железнодорожные колеса.
Задумка следующая по чертежу заказчика в созданную оболочку вводятся основные параметры детали, а Компас отстраивает деталь в середине поля допуска. Реализация на Borland C++ и Компас 13 home.
Подскажите как окно Компаса использовать в своем окне?
Какие функции использовать для сопряжения двух кривых и как сделать выбор сопрягать прямые углом или закруглять радиусом?
Буду очень признателен светлым мыслям!
Спасибо!
Не проще начертить параметризованную 3D модель? В Компас V14 можно перестраивать с учётом поля допуска, также есть исполнения, какой смысл делать свой САПР, если это можно реализовать непосредственно в Компасе.
Ознакомится с новинками Компас V14 можно здесь http://kompas.ru/webinar/
Во первых это дипломный проект. Во вторых смысл есть, далее будет писаться модуль для формирования УП для станков с ЧПУ.
Указываешь мышкой элементы которые обрабатывать соотносишь к инструменту. Просчитается время на обработку этого участка и прочее все еще не продумал. На выходе готовая программа. Ну вот так как-то планирую.
Поработать с параметрической моделью тоже хороший вариант, попробую отстроить вручную посмотрю что получиться.
Цитата: Mihonius от 14.03.13, 14:21:15
...
Подскажите как окно Компаса использовать в своем окне?
...
Есть несколько вариантов:
- использовать ActiveX компонент KGAX,
- или функции о которых можете почитать в SDK.
Помогите найти пересечение контуров, уже почти все заново отстроил и результата ноль! (
И критика параметризации модели приветствуется, что улучшить, что добавить!
Благодарю!
два разрыва было
Кто знает как подключить форму к обычной библиотеке вот только на С++. На Делфи есть примеры там все понятно, а вот под С++ Builder нет ничего. Пример в SDK гайка вообще не помогла, так такое накручено.
Может чем поможет http://forum.ascon.ru/index.php/topic,5841.msg80841.html#msg80841
При компиляции примера из SDK ksActivex появляется ошибка:
[C++ Fatal Error] KGAXLib_OCX.h(43): F1003 Error directive: "This file requires a newer version of the header UTILCLS.H"
"You need to apply an update/patch to your copy of C++Builder"
Обновление устанавливал Update 4, KGAX библиотеку импортировал. Подскажите?
Ошибка связана с проверкой версии UTILCLS.H.
В KGAXLib_OCX.h написано так #if !defined(__UTILCLS_H_VERSION) || (__UTILCLS_H_VERSION < 0x0700)
то есть версия 0x0700, а в распоряжении Borland только 0x0600
Как быть?
Подскажите? Не пойму причину?
Пишу так, язык Delphi, среда Embarcadero XE2:
procedure TMainForm.MakeDrawingClick(Sender: TObject);
var
iKompas : KompasObject;
iDoc : ksDocument2D;
iMathematic2D : ksMathematic2D;
vpx : LongInt;
vpy : LongInt;
D_otv_st : Extended;
Vil : Extended;
L_st : Extended;
D_st_vs : Extended;
pol_h_oboda : Extended;
l_osi : Extended;
b_disk_st : Extended;
Ugol_st_vs : Extended;
R_st_vs : Double;
D_st_ns : Extended;
Ugol_st_ns : Extended;
R_st_ns : Extended;
iCON: ksCON;
i: Integer;
begin
Vil:=StrToFloat(List_Detal.Cells[1, 1]);
L_st:=StrToFloat(List_Detal.Cells[1, 2]);
D_otv_st:= StrToFloat(List_Detal.Cells[1, 3]);
pol_h_oboda:= StrToFloat(List_Detal.Cells[1, 4]);
l_osi:= StrToFloat(List_Detal.Cells[1, 5]);
b_disk_st:= StrToFloat(List_Detal.Cells[1, 6]);
D_st_vs:=StrToFloat(List_Detal.Cells[1, 7]);
Ugol_st_vs:=StrToFloat(List_Detal.Cells[1, 8]);
R_st_vs:=StrToFloat(List_Detal.Cells[1, 9]);
D_st_ns:=StrToFloat(List_Detal.Cells[1, 10]);
Ugol_st_ns:=StrToFloat(List_Detal.Cells[1, 11]);
R_st_ns:=StrToFloat(List_Detal.Cells[1, 12]);
iKompas := KompasObject(KGAX1.GetKompasObject);
iDoc := ksDocument2D( iKompas.ActiveDocument2D );
vpx := idoc.ksLine( 0, 0, 0 );
vpy := idoc.ksLine( 0, 0, 90 );
iCON := ksCON(iKompas.GetParamStruct( ko_CON ));
if iCON <> nil then
begin
iMathematic2D.ksCouplingLineLine( D_st_vs/2, -Vil, 90-Ugol_st_vs, 0, pol_h_oboda+l_osi-b_disk_st/2, 0, R_st_vs, iCON );
idoc.ksLine(D_st_vs/2, -Vil, 90-Ugol_st_vs); ..Точно не ноль исключая сопряжение все рисует!
idoc.ksLine(0, pol_h_oboda+l_osi-b_disk_st/2, 0);
for i := 0 to 3 do
begin
idoc.ksCircle( iCON.GetXc(i), iCON.GetYc(i), R_st_vs, 2 );
idoc.ksPoint( iCON.GetX1(i), iCON.GetY1(i), i );
idoc.ksPoint( iCON.GetX2(i), iCON.GetY2(i), i );
end;
end;
iDoc.ksZoomPrevNextOrAll(2);
end;
end.
Ругается на ko_CON, [DCC Error] WForm.pas(102): E2003 Undeclared identifier: 'ko_CON'
В примере Step2 DelphiAUTO точно так же но ошибку не выдает. Что может быть?
Ещё и вылет будет на этой строчке:
iMathematic2D.ksCouplingLineLine( D_st_vs/2, -Vil, 90-Ugol_st_vs, 0, pol_h_oboda+l_osi-b_disk_st/2, 0, R_st_vs, iCON );
Где Вы указатель получили на iMathematic2D?
Возможен вылет здесь vpx := idoc.ksLine( 0, 0, 0 );
idoc - может оказаться nil.
ЦитироватьРугается на ko_CON, [DCC Error] WForm.pas(102): E2003 Undeclared identifier: 'ko_CON'
Объявите модуль ksTLB.
в коде пометил где взялся iMathematic2D
Без сопряжения все рисует!
Сделайте активным 3D документ и обратитесь к процедуре - это я о idoc.
iMathematic2D объявить мало, со временем Ваш САПР ляжет.
iMathematic2D := ksMathematic2D(iKompas.GetMathematic2D()); добавил
iDoc := ksDocument2D( iKompas.ActiveDocument2D ); объявлен!
Иначе сопряжение двух прямых радиусом можно выполнить?
iDoc := ksDocument2D( iKompas.ActiveDocument2D ); объявлен!
Но не проверен.
ЦитироватьИначе сопряжение двух прямых радиусом можно выполнить?
Можно используя математику LibTool.pas.
if (iDoc <> nil) and (iMathematic2D <> nil) then
begin
.......
end;
проверен )
эффект тотже
А теперь, в отладчике смотрите сколько массивов координат точек сопряжения Вы получили и какие конкретно нужны Вам.
Похоже iMathematic2D дает ноль
Смотрите условия, что Вы посылаете в функцию ksCouplingLineLine, с этим я разбираться не буду, а ещё лучше постройте руками и найдите возможные варианты, тогда легче будет ошибку найти.
Для переменных нужно использовать тип Double - 8 байт, а Extended - 10 байт, надеюсь разницу понимаете.
Все стало работать без проблем после установки lidtool.pas и libtool.h из 14 Компаса! ))) Нашел на форуме Ваш совет на счет них! ) Спасибо!
Помогите разобраться!
Написал вот такую процедуру. Ошибок вроде бы нет, но не выполняется?
procedure CouplLineLine(const ox1, oy1, ug1, ox2, oy2, ug2, rad : double; usl1, usl2 :boolean); overload;
var
i: Integer;
cir : LongInt;
c_par : ksCircleParam;
t : Integer;
buf : string;
begin
if (iDoc <> nil) and (iMathematic2D <> nil) then
begin
iCON := ksCON(iKompas.GetParamStruct( ko_CON ));
if iCON <> nil then
begin
iMathematic2D.ksCouplingLineLine( ox1, oy1, ug1, ox2, oy2, ug2, rad, iCON );
for i := 0 to 3 do
begin
cir:=idoc.ksCircle( iCON.GetXc(i), iCON.GetYc(i), rad, 1 );
c_par := ksCircleParam( ikompas.GetParamStruct(ko_CircleParam) );
if ( c_par <> nil ) then
begin
t := idoc.ksGetObjParam( cir, c_par, ALLPARAM );
buf := Format( 't = %d, xc = %4.1f, yc = %4.1f, rad = %4.1f, tl = %d', [t, c_par.xc, c_par.yc, c_par.rad, c_par.style] );
ikompas.ksMessage( buf );
end;
if (usl1) or (usl2) then
begin
idoc.ksLightObj(cir,1);
idoc.ksDeleteObj(cir);
end
else
begin
idoc.ksTrimmCurve(cir, iCON.GetX1(i), iCON.GetY1(i), iCON.GetX2(i), iCON.GetY2(i), iCON.GetX2(i)-10, iCON.GetY2(i), 1);
//idoc.ksLineSeg(iCON_vs.GetX1(i), iCON_vs.GetY1(i), D_st_vs/2, -Vil, 1);
end;
end;
end;
end;
end;
Вызываю так:
usl11:= (c_par.xc)<(D_st_vs/2);
usl12:= (c_par.yc)>(pol_h_oboda+l_osi-b_disk_st/2);
CouplLineLine(D_st_vs/2, -Vil, 90-Ugol_st_vs, 0, pol_h_oboda+l_osi-b_disk_st/2, 0, R_st_vs, usl11, usl12);
Пробовал содержимое usl11 и usl12 сразу заганять в параметры результат тот же, программа доходит до процедуры и выдает ошибку Access violation at adress 004A7BAD in module ****.exe
если исключить выделенную жирным часть работает!
А отладчик для чего?
Вообще в этой процедуре смысла не вижу, нашли точки сопряжения, затем нашли нужные прочитав координаты из структуры iCON и сравнив с условием, далее построили дугу.
У Вас условие вне функции и проверки не все, поэтому не удивительно, что пытаетесь прочитать несуществующую переменную.
спотыкается здесь
usl11:= (c_par.xc)<(D_st_vs/2);
usl12:= (c_par.yc)>(pol_h_oboda+l_osi-b_disk_st/2);
CouplLineLine(D_st_vs/2, -Vil, 90-Ugol_st_vs, 0, pol_h_oboda+l_osi-b_disk_st/2, 0, R_st_vs, c_par.xc<D_st_vs/2, c_par.yc>pol_h_oboda+l_osi-b_disk_st/2); при таком вызове тоже вылетает здесь
как по другому задать выражение в if со знаком?
if (usl1) or (usl2) then вместо usl1 - c_par.xc<D_st_vs/2
вместо usl2 - c_par.yc>pol_h_oboda+l_osi-b_disk_st/2)
if((c_par.yc)>(pol_h_oboda+l_osi-b_disk_st/2))or((c_par.xc)<(D_st_vs/2))then ...
Поставьте точку останова внутри функции и посмотрите конкретно, где вылетает.
ошибку нашел! спасибо!
но мою задумку не решает (
if ((c_par.xc) < (usl1)) or ((c_par.yc) > (usl2)) then суть задумки что бы в этом месте была возможность менять знаки по необходимости, а процедура была бы общей для всех случаев
begin
idoc.ksLightObj(cir,1);
idoc.ksDeleteObj(cir);
end
else
begin
idoc.ksTrimmCurve(cir, iCON.GetX1(i), iCON.GetY1(i), iCON.GetX2(i), iCON.GetY2(i), iCON.GetX2(i)-10, iCON.GetY2(i), 1);
end;
В таком виде все работает но расположение знаков (< или >) подходит только для одного случая для другого нужно по другому
можно и знаки (<) и (>) вносить как параметр?
Умножением на переменную равную 1 или -1, получите положительное или отрицательное число.
Придётся Вам все возможные варианты проверять, операцию в виде переменной задать нельзя.
Посоветуйте как логичней всего отстроить сопряжения на картинке. Язык Delphi. Я то уже написал так: отстроил центральную окружность, установил сопряжение с окружностями по сторонам, проверкой откинул лишние, внутри цикла обрезал лишнее у окружностей по сторонам, потом ели выудив точки касания центральной окружности с боковыми обрезал центральную. Получилось работает, но код километровый, а мне еще два похожих фрагмента делать. Может есть по логичней методы?
Если хотите можете использовать тригонометрические функции, тогда циклы, обрезания будут не нужны, найдёте точки сопряжения и центры, а затем по этим координатам построите три дуги.
Хм, спасибо за идею попробую! Есть еще идея искать точки пересечения используя ksintersect и загонять найденные точки в массив, вопрос для прямых это будет одна точка, для окружности и двух прямых уже 8, как выбирать нужные?
IntersectCirLin - Получить координаты точек пересечения окружности и прямой.
- число пересечений (от 0 до 2)
Цитата: Mihonius от 25.03.13, 14:53:52
... как выбирать нужные?
По известным Вам признакам.
Уважаемый Борис Николаевич! Расскажите по какому принципу Вы строили крановое колесо, мне бы очень помогло! Спасибо
Не люблю длинных рассказов, особенно "войну и мир", с чем у Вас проблемы конкретно в техническом плане.
Для кранового колеса достаточно учебника Геометрия 6-10 класс, помню учили меня по этому бестселлеру, причем дочитать достаточно до 7-го класса.
Все размеры пляшут от габаритов в которые вписываются сопряжения, варианты которых быть не может не рассматриваются, фактически всё раскладывается на треугольники и решается.
Не особо получается построить середину диска, ось диска построил там три радиуса по 80 мм, теперь нужен верхний и нижний контур диска и тут проблемы, центральный радиус можно вычислить (80+толщина диска/2) а справа и слева, во первых они разные, во вторых желательно было бы сопрягать с радиусами, но радиус сопряжения неизвестен. подскажите?
Здравствуйте!
Помогите реализовать следующее: таблица stringgrid в ней 3 столбца "X", "Y", "R", из таблицы читаем координаты X,Y, если R пустое поле рисуем линию с первой точки во вторую, если R есть рисуем дугу с первой точки во вторую радиусом R.
Пробовал так:
procedure DrawKK;
var
i : Integer;
sg1 : TStringGrid;
begin
iDoc := ksDocument2D( iKompas.ActiveDocument2D );
for i := 1 to sg1.RowCount - 1 do
begin
if (sg1.Cells[0, i] <> '') and (sg1.Cells[2,i]='') then begin
idoc.ksLineSeg(StrToFloat(sg1.Cells[0,i]),StrToFloat(sg1.Cells[1,i]),StrToFloat(sg1.Cells[0,i+1]),StrToFloat(sg1.Cells[1,i+1]),1);
end
else
begin
//здесь будет дуга
end;
end;
не работает
Здесь for i := 1 to sg1.RowCount - 1 do, как минимум должен быть for i := 1 to sg1.RowCount - 2 do, иначе при i=sg1.RowCount - 1 в строке idoc.ksLineSeg(StrToFloat(sg1.Cells[0,i]),StrToFloat(sg1.Cells[1,i]),StrToFloat(sg1.Cells[0,i+1]),StrToFloat(sg1.Cells[1,i+1]),1); будет вылет, не считая, что StrToFloat возвращает тип Extended, а входные параметры ksLineSeg - Double, http://forum.ascon.ru/index.php/topic,24036.msg171971.html#msg171971
sg1 : TStringGrid; - внутри функции определена, но не создана.
Спасибо!
sg1:= TStringGrid.Create(Application); создал
Создать нужно вне функции и инициализировать первоначальные значения, а перед выгрузкой Dll не забыть уничтожить.
не очень получается во время проверки условия ячейки пустые, что не так?
Уже все перепробовал. Подскажите!?
Я кода инициализации значения ячеек не вижу, что я могу сказать, я же не экстрасенс.
unit DrawingKK;
interface
uses
Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes, Vcl.Graphics,
Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.Grids, Vcl.OleCtrls, KGAXLib_TLB, Vcl.StdCtrls, KsTLB, ksConstTLB, ks2DCOM_TLB;
type
TForm1 = class(TForm)
KGAX1: TKGAX;
SG1: TStringGrid;
Button1: TButton;
procedure Button1Click(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
procedure FormCreate(Sender: TObject);
private
{ Private declarations }
public
{ Public declarations }
end;
var
Form1: TForm1;
iKompas : KompasObject;
iDoc : ksDocument2D;
implementation
{$R *.dfm}
procedure TForm1.FormClose(Sender: TObject; var Action: TCloseAction);
begin
if iKompas <> nil then
begin
KGAX1.CloseAll;
iKompas.Quit;
sg1.Destroy;
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
begin
sg1.Cells[0,0]:='Коорд. X';
sg1.Cells[1,0]:='Коорд. Y';
sg1.Cells[2,0]:='Радиус R';
sg1.Cells[0,1]:='100';
sg1.Cells[1,1]:='100';
sg1.Cells[0,2]:='300';
sg1.Cells[1,2]:='300';
sg1.Cells[0,3]:='500';
sg1.Cells[1,3]:='500';
end;
procedure DrawKK;
var
i, j : Integer;
sg1 : TStringGrid;
begin
iDoc := ksDocument2D( iKompas.ActiveDocument2D );
for i := 1 to sg1.RowCount - 2 do
begin
iKompas.ksMessage(sg1.Cells[0, i]);
if sg1.Cells[0, i]<>'' then
begin
idoc.ksLineSeg(StrToFloat(sg1.Cells[0,i]),StrToFloat(sg1.Cells[1,i]),StrToFloat(sg1.Cells[0,i+1]),StrToFloat(sg1.Cells[1,i+1]),1);
end
else
iKompas.ksMessage('дуга');
end;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
iKompas := KompasObject(KGAX1.GetKompasObject);
iDoc := ksDocument2D( iKompas.ActiveDocument2D );
sg1:= TStringGrid.Create(Form1);
if (iDoc <> nil) then
begin
Drawkk; //вызов рисования
//idoc.ksLineSeg(StrToFloat(sg1.Cells[0,1]),StrToFloat(sg1.Cells[1,1]),StrToFloat(sg1.Cells[0,2]),StrToFloat(sg1.Cells[1,2]),1);
idoc.ksLine(0,0,0);
iDoc.ksZoomPrevNextOrAll(2);
end;
iDoc := nil;
iKompas := nil;
end;
end.
Инициализацию нужно сделать не вовремя создания формы, когда TStringGrid ещё сам в неопределённом состоянии, а в момент, когда окно станет видимым и все дочерние компоненты будут инициализированы своими стандартными конструкторами.
Используя FormShow эффект тот же!
procedure DrawKK;
var
i, j : Integer;
sg1 : TStringGrid; - лишняя строка, уже на форме создана SG1: TStringGrid;
if iKompas <> nil then
begin
KGAX1.CloseAll;
iKompas.Quit;
sg1.Destroy; - лишняя строка.
end;
sg1:= TStringGrid.Create(Form1); - лишняя
Выкиньте лишние и сделайте инициализацию TStringGrid в FormShow.
sg1:= TStringGrid.Create(Form1); без этого выдает что SG1 - nil
Вы компонент TStringGrid на форму положили в дизайнере форм или вручную добавили в коде?
В дизайнере форм! Приложил архив, вся программа.
Выше выделил лишние, но учебник Вам рекомендую полистать.
procedure TForm1.FormCreate(Sender: TObject);
begin
sg1 - здесь он ещё равен nil
sg1.Cells[0,0]:='Коорд. X';
sg1.Cells[1,0]:='Коорд. Y';
sg1.Cells[2,0]:='Радиус R';
sg1.Cells[0,1]:='100';
sg1.Cells[1,1]:='100';
sg1.Cells[0,2]:='300';
sg1.Cells[1,2]:='300';
sg1.Cells[0,3]:='500';
sg1.Cells[1,3]:='500';
end;
Хз, не выходит ничего, или SG1 равен nil или таблица пустая при проверке!
В книжках все просто в formshow или formcreate записывают значения, в теле программы работаю, циклом перебирают, очищают и прочее..
понять не могу почему не работает в моем случаи???
Всё работает.
Спасибо огромное! А почему обращение к ячейке в таком виде Form1.SG1.Cells[0, i], таблица же находится на той же форме?
Потому, что procedure DrawKK; к объекту формы не относится.
А эти вопросы точно помогают сделать "свой САПР на базе КОМПАС"?
Добрый день! Чертеж отстроен. По чертежу создана заготовка, по тому же принципу. Все более менее адекватно работает. Есть еще пара вопросов:
1) как лучше организовать работу с чертежем детали и заготовки, пока сделал отдельный KGAX, может лучше в одном фрагменте создать разные слои.
2) Как по Вашему лучше реализовывать создание чпу программы, как я это вижу: есть список инструментов, кликом мышки выбираем нужный инструмент и выделяем те элементы которые им обрабатываются, подверждаем выбор и переходим к следующему.
3) для создания кода чпу необходимо будет вытягивать параметры выделенных объектов?
4) как организовуеться вывод сгенерированного кода в текстовый редактор, простым выводом в файл?
Цитата: Николай от 04.04.13, 16:43:37
А эти вопросы точно помогают сделать "свой САПР на базе КОМПАС"?
Вопросы возникают в процессе создания, а так как работа с апи компас в первые и опыт программирования на делфи маленький осваиваюсь по мере необходимости. Хорощо что есть еще добрые, знающие люди, спасибо Вам!
Зачем второй KGAX?
У компонента KGAX есть свойства и методы для управления документами, слои не нужны, достаточно динамически управлять временной группой объектов, актуальной для текущего состояния интерфейса Вашей программы, если Вы поменяете какой либо размер, то всё остальные слои станут неактуальными со старым значением.
P.S. Всё остальное к API Компаса не относится, а начать нужно с технологии.
Прошу создавать для разнородных вопросов отдельные темы с информативными названиями.
Данную тему закрываю, т.к. её неинформативное название провоцирует сваливать в одну кучу много не относящихся друг к другу вопросов.