КОМПАС-3D V10 на 100 %
Шрифт:
Программное построение модели колеса реализуем такой последовательностью трехмерных операций.
1. Сначала программно в плоскости XOY создается эскиз, содержащий контур половины сечения колеса (такой же, какой мы выполняли при моделировании вручную в гл. 3). На основании этого эскиза выполняется операция вращения, формирующая заготовку зубчатого колеса.
2. Далее в плоскости YOZ строится второй эскиз с четырьмя окружностями, над которыми выполняется операция вырезания в два направления. Таким образом, мы получим отверстия в диске.
3. Следующим шагом является выполнение выреза между зубьями в венце колеса. Для построения выреза воспользуемся первым из способов, предложенных в гл. 3. Напомню, этот способ заключается в построении выреза с помощью операции Вырезать по сечениям. При этом в модели колеса строится ряд эскизов-сечений, плоскости которых удалены от боковой поверхности колеса на величину l = i · b / (nс – 1) (где b – ширина колеса, nс – количество сечений или эскизов, i – порядковый номер эскиза). Для нашей библиотеки достаточно будет трех эскизов: по два на торцевых плоскостях колеса и один посредине – на плоскости YOZ. Это значит, что библиотека должна будет построить две вспомогательные плоскости, удаленные в обе стороны от плоскости YOZ на половину ширины венца зубчатого колеса. В каждой из трех плоскостей (двух вспомогательных и ортогональной YOZ) будет создано изображение
4. В завершении создается ось на пересечении плоскостей XOZ и XOY. Относительно этой оси формируется массив по концентрической сетке вырезов между зубьями колеса. Количество копий устанавливается равным количеству зубьев колеса.
Начнем с первого этапа реализации построения: расчета геометрических характеристик создаваемого колеса (листинг 6.12).
procedure TGearsForm.Button1Click(Sender: TObject);
var
// раздел объявления переменных
// все объекты приведенных интерфейсов используются при построении
doc3 : ksDocument3D;
iPart : ksPart;
PlaneXOY : ksEntity;
PlaneXOZ : ksEntity;
PlaneYOZ : ksEntity;
SketchEntity : ksEntity;
iSketchDef : ksSketchDefinition;
doc : ksDocument2D;
r : reference;
iBaseRotatedEntity : ksEntity;
Color : ksColorParam;
iBaseRotatedDef : ksBaseRotatedDefinition;
iSketch1Entity : ksEntity;
iSketch1Def : ksSketchDefinition;
iCutExtrusion : ksEntity;
iCutExtrusionDef : ksCutExtrusionDefinition;
iOffsetPlaneEntity : ksEntity;
iOffsetPlaneDef : ksPlaneOffsetDefinition;
iSketch2Entity : ksEntity;
iSketch2Def : ksSketchDefinition;
iSketch3Entity : ksEntity;
iSketch3Def : ksSketchDefinition;
iOffsetPlane1Entity : ksEntity;
iOffsetPlane1Def : ksPlaneOffsetDefinition;
iSketch4Entity : ksEntity;
iSketch4Def : ksSketchDefinition;
iCutLoftEntity : ksEntity;
iCutLoftDef : ksCutLoftDefinition;
Collect : ksEntityCollection;
iAxis : ksEntity;
iAxis2PlDef : ksAxis2PlanesDefinition;
iCircularCopy : ksEntity;
iCirCopyDef : ksCircularCopyDefinition;
Collect1 : ksEntityCollection;
// геометрические параметры колеса
module : double;
Lm, Dm : double;
Dv : double;
b_k, c : double;
d_k, d_fk, d_ak : double;
delta0 : double;
z : integer;
beta : double;
Dotv : double;
alfa1, alfa2 : double;
begin
Hide; // прячем диалоговое окно
// считываем параметры, введенные пользователем в окне
module := StrToFloat(Edit1.Text);
z := StrToInt(Edit2.Text);
Lm := StrToFloat(Edit3.Text);
beta := StrToFloat(Edit4.Text);
// диаметр отверстия под вал
Dv := round(Lm/1.4);
// ширину маточины и ширину колеса принимаем равными
b_k := Lm;
// диаметр маточины
Dm := 1.8*Dv;
// толщина диска, соединяющего маточину с ободом
c := round(0.35*b_k);
// толщина обода
delta0 := round(2.5*module/cos(DegToRad(beta)));
d_k := module*z; // делительный диаметр колеса
d_ak := d_k+2*module; // диаметр выступов
d_fk := d_k-2.5*module; // диаметр впадин
// диаметр размещения центров отверстий в диске
Dotv := (d_fk – 2*delta0 + Dm)/2;
// создание детали...
// построение модели...
Close; // закрываем форму
end;
Если сейчас собрать приложение и попробовать запустить библиотеку, ничего происходить не будет, потому что пока ничего не создается и не строится.
Следующий этап построения намного более интересен – он заключается в программном создании документа КОМПАС-Деталь (листинг 6.13). В данном листинге раздел описания переменных и расчет параметров колеса пропущен, а приведен только фрагмент кода, реализующий создание документа-детали. В процедуру построения (обработчик нажатия кнопки Построение) этот фрагмент должен быть вставлен сразу после расчетов.
// получаем указатель на интерфейс трехмерного документа
doc3 := ksDocument3D(ks.Document3D);
// создаем документ
// параметр false – в видимом режиме
// параметр true – документ-деталь
if doc3.Create(false, true) then
begin
// заполняем параметры документа
doc3.author := “Максим Кидрук”;
doc3.comment := “Зубчатое колесо”;
doc3.drawMode := 3;
doc3.perspective := true;
doc3.UpdateDocumentParam;
end else exit;
// проверяем, как прошла инициализация
if (doc3 = nil) then
begin
ks.ksMessage(“Не удалось создать документ!”);
exit;
end;
Откомпилировав и запустив приложение, вы сможете наблюдать, как после закрытия диалогового окна (нажатия кнопки Построение) программа сама создаст пустой документ КОМПАС-Деталь.
В листинге 6.14 приведен с небольшими сокращениями код построения трехмерной модели. Недостающие фрагменты кода вы можете взять из файла Examples\Глава 6\Delphi Programming\Gears3D\BuildUnit.pas на диске. Фрагмент кода содержит достаточно подробные комментарии, поэтому, полагаю, разобраться в нем будет несложно.
// получаем указатель на интерфейс детали
iPart := ksPart(doc3.GetPart(pNew_Part));
if (iPart <> nil) then
begin
// интерфейсы ортогональных плоскостей
PlaneXOY := ksEntity(iPart.GetDefaultEntity(o3d_planeXOY));
PlaneXOZ := ksEntity(iPart.GetDefaultEntity(o3d_planeXOZ));
PlaneYOZ := ksEntity(iPart.GetDefaultEntity(o3d_planeYOZ));
// интерфейс эскиза (половина контура сечения колеса)
iSketchEntity := ksEntity(iPart.NewEntity(o3d_sketch));
if (iSketchEntity <> nil) then
begin
// интерфейс параметров эскиза
iSketchDef := ksSketchDefinition(iSketchEntity.GetDefinition);
if (iSketchDef <> nil) then
begin
if (PlaneXOY <> nil) then
begin
// устанавливаем плоскость,
// на которой создается эскиз
iSketchDef.SetPlane(PlaneXOY);
iSketchEntity.Create;
// запускаем процесс редактирования эскиза
// doc – указатель на интерфейс ksDocument2D
doc := ksDocument2D(iSketchDef.BeginEdit);
if (doc <> nil) then
begin
// вычерчиваем изображение эскиза
// с помощью методов интерфейса ksDocument2D
// код пропущен
end;
// завершение редактирования эскиза
iSketchDef.EndEdit;
end;
end;
end;
// интерфейс базовой операции вращения
iBaseRotatedEntity := ksEntity(iPart.NewEntity(o3d_baseRotated));
// интерфейс параметров цвета и визуальных свойств
Color := ksColorParam(iBaseRotatedEntity.ColorParam);
Color.specularity := 0.8;
Color.shininess := 1;
if (iBaseRotatedEntity <> nil) then
begin
// интерфейс параметров вращения
iBaseRotatedDef :=
ksBaseRotatedDefinition(iBaseRotatedEntity.GetDefinition);
if (iBaseRotatedDef <> nil) then
begin
// настройка параметров вращения
iBaseRotatedDef.SetThinParam(false, dtNormal, 1, 1);
iBaseRotatedDef.SetSideParam(true, 360);
iBaseRotatedDef.toroidShapeType := false;
iBaseRotatedDef.SetSketch(iSketchEntity);
// создаем операцию вращения
// результат – заготовка зубчатого колеса
iBaseRotatedEntity.Create;
end;
end;
// интерфейс эскиза (отверстия в диске)
iSketch1Entity := ksEntity(iPart.NewEntity( o3d_sketch ));
if (iSketch1Entity <> nil) then
begin
iSketch1Def := ksSketchDefinition(iSketch1Entity.GetDefinition);
if (iSketch1Def <> nil) then
begin
if (PlaneYOZ <> nil) then
begin
// размещаем эскиз на плоскости YOZ
iSketch1Def.SetPlane(PlaneYOZ);
iSketch1Entity.Create;
doc := ksDocument2D(iSketch1Def.BeginEdit);
if (doc <> nil) then
begin
// изображение в эскизе – 4 окружности
// создаются вызовом метода ksDocument2D::ksCircle
doc.ksCircle(0, Dotv/2, 0.4*(d_fk/2-delta0-Dm/2), 1);
doc.ksCircle(0, -Dotv/2, 0.4*(d_fk/2-delta0-Dm/2), 1);
doc.ksCircle(Dotv/2, 0, 0.4*(d_fk/2-delta0-Dm/2), 1);
doc.ksCircle(-Dotv/2, 0, 0.4*(d_fk/2-delta0-Dm/2), 1);
end;
iSketch1Def.EndEdit;
end;
end;
end;
//
интерфейс операции Вырезать выдавливаниемiCutExtrusion := ksEntity(iPart.NewEntity(o3d_cutExtrusion));
if (iCutExtrusion <> nil) then
begin
// интерфейс параметров вырезания
iCutExtrusionDef :=
ksCutExtrusionDefinition(iCutExtrusion.GetDefinition);
if (iCutExtrusionDef <> nil) then
begin
// настройка параметров
iCutExtrusionDef.SetSketch(iSketch1Entity);
// направление
iCutExtrusionDef.directionType := dtBoth;
// величина вырезания по каждому из направлений
iCutExtrusionDef.SetSideParam(true, etBlind, c/2,
0, false);
iCutExtrusionDef.SetSideParam(false, etBlind, c/2,
0, false);
iCutExtrusionDef.SetThinParam(false, 0, 0, 0);
// создаем отверстия в диске
iCutExtrusion.Create;
end;
end;
// интерфейс смещенной плоскости
iOffsetPlaneEntity := ksEntity(iPart.NewEntity(o3d_planeOffset));
if (iOffsetPlaneEntity <> nil) then
begin
// интерфейс параметров смещенной плоскости
iOffsetPlaneDef :=
ksPlaneOffsetDefinition(iOffsetPlaneEntity.GetDefinition);
if (iOffsetPlaneDef <> nil) then
begin
// величина, базовая плоскость и другие параметры смещения
iOffsetPlaneDef.Offset := b_k/2;
iOffsetPlaneDef.SetPlane(PlaneYOZ);
iOffsetPlaneDef.direction := false;
// делаем плоскость скрытой
iOffsetPlaneEntity.Hidden := true;
// создаем вспомогательную плоскость
iOffsetPlaneEntity.Create;
end;
end;
// эскиз первого выреза между зубьями
iSketch2Entity := ksEntity(iPart.NewEntity(o3d_sketch));
if (iSketch2Entity <> nil) then
begin
iSketch2Def := ksSketchDefinition(iSketch2Entity.GetDefinition);
if (iSketch2Def <> nil) then
begin
// базовая плоскость – вспомогательная iOffsetPlaneEntity
iSketch2Def.SetPlane(iOffsetPlaneEntity);
iSketch2Entity.Create;
doc := ksDocument2D(iSketch2Def.BeginEdit);
alfa1 := 360/z;
doc.ksMtr(0, 0, 90, 1, 1);
// вычерчивание изображения эскиза
// вместо эвольвент для простоты
// берем обычные дуги по трем точкам
// код пропущен
doc.ksDeleteMtr;
iSketch2Def.EndEdit;
end;
end;
// интерфейс второго эскиза выреза между зубьями
iSketch3Entity := ksEntity(iPart.NewEntity(o3d_sketch));
if (iSketch3Entity <> nil) then
begin
iSketch3Def := ksSketchDefinition(iSketch3Entity.GetDefinition);
if (iSketch3Def <> nil) then
begin
// строим на плоскости YOZ
iSketch3Def.SetPlane(PlaneYOZ);
iSketch3Entity.Create;
doc := ksDocument2D(iSketch3Def.BeginEdit);
alfa2 := -RadToDeg(b_k*tan(DegToRad(beta))/d_k);
doc.ksMtr(0, 0, 90, 1, 1);
// вычерчивание изображения эскиза
// вместо эвольвент для простоты
// берем обычные дуги по трем точкам
// код пропущен
doc.ksDeleteMtr;
iSketch3Def.EndEdit;
end;
end;
// вторая смещенная плоскость
iOffsetPlane1Entity := ksEntity(iPart.NewEntity(o3d_planeOffset));
if (iOffsetPlane1Entity <> nil) then
begin
iOffsetPlane1Def :=
ksPlaneOffsetDefinition(iOffsetPlane1Entity.GetDefinition);
if (iOffsetPlane1Def <> nil) then
begin
// величина смещения та же
iOffsetPlane1Def.Offset := b_k/2;
// направление противоположное
iOffsetPlane1Def.direction := true;
iOffsetPlane1Def.SetPlane(PlaneYOZ);
// делаем плоскость скрытой
iOffsetPlane1Entity.Hidden := true;
// создаем смещенную плоскость
iOffsetPlane1Entity.Create;
end;
end;
// третий (последний) эскиз выреза между зубьями
iSketch4Entity := ksEntity(iPart.NewEntity(o3d_sketch));
if (iSketch4Entity <> nil) then
begin
iSketch4Def := ksSketchDefinition(iSketch4Entity.GetDefinition);
if (iSketch4Def <> nil) then
begin
// базовая плоскость – только что созданная смещенная
iSketch4Def.SetPlane(iOffsetPlane1Entity);
iSketch4Entity.Create;
doc := ksDocument2D(iSketch4Def.BeginEdit);
alfa2 := -RadToDeg(2*b_k*tan(DegToRad(beta))/d_k);
doc.ksMtr(0, 0, 90, 1, 1);
// вычерчивание изображения эскиза
// вместо эвольвент для простоты
// берем обычные дуги по трем точкам
// код пропущен
doc.ksDeleteMtr;
iSketch4Def.EndEdit;
end;
end;
// интерфейс операции Вырезать по сечениям
iCutLoftEntity := ksEntity(iPart.NewEntity(o3d_cutLoft));
if (iCutLoftEntity <> nil) then
begin
// интерфейс параметров операции по сечениям
iCutLoftDef := ksCutLoftDefinition(iCutLoftEntity.GetDefinition);
if (iCutLoftDef <> nil) then
begin
// интерфейс массива ksEntityCollection
// коллекции эскизов для вырезания по сечениям
Collect := ksEntityCollection(iCutLoftDef.Sketchs);
// добавляем эскизы в колекцию
Collect.Add(iSketch2Entity);
Collect.Add(iSketch3Entity);
Collect.Add(iSketch4Entity);
// создаем операцию по сечениям
// результат – первый вырез между зубьями в венце колеса
iCutLoftEntity.Create;
end;
end;
// интерфейс вспомогательной оси на пересечении двух плоскостей
iAxis := ksEntity(iPart.NewEntity(o3d_axis2Planes));
if (iAxis <> nil) then
begin
// интерфейс параметров вспомогательной оси
// на пересечении плоскостей
iAxis2PlDef := ksAxis2PlanesDefinition(iAxis.GetDefinition);
if (iAxis2PlDef <> nil) then
begin
// задаем плоскости
iAxis2PlDef.SetPlane(1, PlaneXOZ);
iAxis2PlDef.SetPlane(2, PlaneXOY);
// делаем ось невидимой
iAxis.hidden := true;
// создаем вспомогательную ось
iAxis.Create;
end;
end;
// интерфейс операции Массив по концентрической сетке
iCircularCopy := ksEntity(iPart.NewEntity(o3d_circularCopy));
if (iCircularCopy <> nil) then
begin
// интерфейс параметров операции копирования по массиву
iCirCopyDef :=
ksCircularCopyDefinition(iCircularCopy.GetDefinition);
if (iCirCopyDef <> nil) then
begin
// коллекция операций для копирования
Collect1 :=
ksEntityCollection(iCirCopyDef.GetOperationArray);
// операция всего лишь одна – вырезание зуба
Collect1.Add(iCutLoftEntity);
// количество копий, равно количеству зубьев
iCirCopyDef.count2 := z;
iCirCopyDef.factor2 := true;
// ось копирования
iCirCopyDef.SetAxis(iAxis);
// создаем концентрический массив – колесо готово!
iCircularCopy.Create;
end;
end;
end;
Если вы разобрались в приведенном фрагменте кода, добавьте его в создаваемый проект. Недостающие части скопируйте из файла модуля построения, который находится на прилагаемом к книге компакт-диске. В них нет ничего сложно, обычная последовательность ввода графических примитивов с помощью методов ksLineSeg, ksArcByAngle и ksCircle интерфейса ksDocument2D, просто они достаточно громоздки, чтобы приводить их полностью на страницах книги.
Вновь соберите (перекомпилируйте) библиотеку. Перейдите в окно КОМПАС и запустите приложение из менеджера библиотек. Введите исходные данные для зубчатого колеса (например, модуль – 3, 5 мм, количество зубьев – 56, ширина зубчатого венца – 60 мм и угол наклона линии зубьев – 15°) и нажмите кнопку Построение.
Внимание!
Чтобы избежать ошибок, вы должны сами следить за правильностью введенных данных, поскольку защита от некорректного ввода при разработке мини-САПР не предусматривалась. В частности, самостоятельно контролируйте, какой знак (точка или запятая) установлен в вашей системе в качестве разделителя целой и дробной части вещественного числа. При желании вы можете доработать библиотеку сами так, чтобы она обрабатывала различные внештатные ситуации.
Всего за несколько секунд программа построит по указанным данным 3D-модель косозубого зубчатого колеса (рис. 6.25).
Рис. 6.25. Трехмерная модель зубчатого колеса, созданная программно
С помощью такой небольшой утилиты вы можете создавать зубчатые колеса практически любых размеров, с произвольным углом наклона зубьев, а также прямозубые. Все исходные файлы проекта, а также сам файл библиотеки находятся на прилагаемом к книге компакт-диске в папке Examples\Глава 6\Delphi Programming\Gears3D. Если вы собираетесь рассматривать уже готовый проект, не забудьте после копирования его на жесткий диск изменить в настройках пути к подключаемым модулям КОМПАС API. Только после этого выполняйте компиляцию.
Немного усовершенствуем прикладную библиотеку так, чтобы формируемая модель не создавалась в документе-детали, а вставлялась в текущую сборку с помощью трехмерного фантома. Для этого выполните следующее.
1. В модуле BuildUnit в разделе public класса формы объявите новую переменную cancel типа boolean. Эта переменная будет служить индикатором действий пользователя: true – если пользователь прервал работу приложения и false – если построение зубчатого колеса было начато. После этого в обработчике события OnCreate создания формы присвойте данной переменной значение true (чтобы создать обработчик, достаточно дважды щелкнуть кнопкой мыши в любой точке формы, не занятой элементом управления).