 
        
        - •Введение
- •1. Создание проектов прикладных библиотек
- •2. Работа с графическими объектами на плоскости
- •2.1. Функции для работы с графическими документами
- •2.2. Функции построения составных объектов
- •2.3. Функции ввода параметров
- •3. Методы и их составляющие для проведения вспомогательных построений
- •3.1. Математические функции
- •3.2. Функции вычисления пересечений
- •3.3. Функции вычисления длин, расстояний, углов
- •4. Работа с базами данных
- •5. Примеры проектирования библиотек в 2d
- •5.1. Построение графиков функций
- •5.2. Построение фигур
- •5.3. Построение эскизов
- •6. Твердотельное моделирование объектов в компас 3d
- •6.1. Построение твердотельных деталей посредством операций вращения и выдавливания
- •Элементы системы координат
- •Элементы детали
- •Конструктивные элементы
- •Операции
- •6.2. Построение фасок и скруглений в твердотельных моделях прикладных библиотек
- •6.3. Построение объектов в цвете
- •6.4. Работа со сборками
- •6.5. Включение в сборочные узлы твердотельных моделей без истории построения
- •6.6. Построение сборочных узлов и компонентов с параметрами посредством диалога
- •7. Пример Разработки твердотельных моделей компонентов и Сборочного узла направляющего патрубка
- •Заключение
- •Библиографический список
- •Оглавление
- •3 94026 Воронеж, Московский просп., 14
7. Пример Разработки твердотельных моделей компонентов и Сборочного узла направляющего патрубка
В данном разделе будут рассмотрены методы проектирования моделей деталей программным путем в системе Компас 3D. Проектирование моделей, предложенное авторами, имеет практичиский интерес в производственном процессе при создании прикладных библиотек, включащие в себя методы расчета и последующее твердотельное построение деталей и сборок. Рассматриваемый сборочный узел включает в себя три детали, эскизы которых предствлены на рисунках 45-47.
| 
 
			 Рис. 45. Элемент проектирования “насадка” | 
| 
			 
 Рис. 46. Элемент проектирования “штуцер” | 
| 
			 
 Рис. 47. Элемент проектирования “трубка” | 
Задачу проектирования целесообразнее провести с помощью специальных средств разработки. Например, с применением средств MFC-библиотеки на языке C++, разработанной Microsoft и призванной облегчить разработку GUI-приложений для Microsoft Windows путем использования значительного набора библиотечных классов. Проектирование начнем с создания интерфейса и объявления переменных для передачи в объект построения.
Для задания параметров детали типа “насадка” спроектируем диалог посредством визуальных средсв построения интегрированной среды. В диалоговое окно добавим элементы управления, которые позволяют менять значения (с присвоением идентификаторов IDC_SLIDER1 и IDC_SLIDER2), поля отображения меняющихся значений (присвоены идентификаторы IDC_EDIT1 и IDC_EDIT2) и кнопку (button), подтверждающую ввод параметров, требуемых для построения. Кроме того, в диалог внесены разного рода информационные строки и сообщения для однозначной интерпретации процесса проектирования (поля, содержащие строки IDC_STATIC, IDB_BITMAP1 и т.д.). Общий вид диалога построения детали показан на рисунке 48.
| 
			 Рис. 48. Проектирование интерфейса задания параметров модели “насадка” | 
В процессе построения диалога визуальными средствами в ресурсном файле проекта (имя_ресурсного_файла.rc) добавится следующий фрагмент текста, который можно впоследствии отредактировать.
 
	IDD_DIALOG2
	DIALOGEX 0, 0, 306, 170 STYLE
	DS_MODALFRAME | WS_POPUP | WS_CAPTION CAPTION
	"Определение параметров детали
	(насадка)" FONT
	8, "MS Sans Serif" BEGIN     DEFPUSHBUTTON
	  "Построить",IDOK,107,149,88,14     GROUPBOX
	       "Размерные
	характеристики",IDC_STATIC,7,7,292,133     LTEXT
	          "Внутренний диаметр,
	мм:",IDC_STATIC,37,29,88,14     LTEXT
	          "Высота детали,
	мм:",IDC_STATIC,37,90,68,8     EDITTEXT
	       IDC_EDIT1,140,26,40,14,ES_CENTER | ES_AUTOHSCROLL | 
	                     WS_DISABLED     EDITTEXT
	       IDC_EDIT2,140,86,40,14,ES_CENTER | ES_AUTOHSCROLL | 
	                     WS_DISABLED     GROUPBOX
	       "Вид модели",IDC_STATIC,200,14,91,118     CONTROL
	        "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH
	| 
	                     TBS_NOTICKS
	| WS_TABSTOP,20,56,173,15     CONTROL
	        "Slider2",IDC_SLIDER2,"msctls_trackbar32",TBS_BOTH
	| 
	                     TBS_NOTICKS
	| WS_TABSTOP,20,109,173,15     CONTROL
	        7016,IDC_STATIC,"Static",SS_BITMAP | SS_SUNKEN | 
	                    
	WS_BORDER,205,23,80,105,WS_EX_DLGMODALFRAME
	| 
	                     WS_EX_CLIENTEDGE END
Подготовим класс, который отвечает за диалог и интерфейс в целом, предусматривает обмен параметрами и вклчает программную реализацию элементов управления данными. Медоды и элементы класса для модели “насадка” показаны на рисунке 49.
- 
	  Рис. 49. Программная реализация диалогового класса “насадка” 
Как видно из предложенной реализации, в классе my_dialog() определен ряд методов (функций) и объявлено несколько переменных. Класс my_dialog() наследует свойства типовых диалоговых окон под Windows, поэтому ссылки на ряд органов управления выполнены в виде указателей.
Описание методов, которые вошли в состав класса:
void my_dialog2::DoDataExchange(CDataExchange* pDX)-метод реализует обмен данными в диалоговом окне, позволяет выполнить ассоциативную связь между переменной и ее визуальной составляющей. Для связи переменной и составляющей используются полученные ссылочные идентификаторы. Пример взаимосвязи приводится в следующем фрагменте:
		DDX_Text(pDX,
	IDC_EDIT1, ed1); 	DDX_Text(pDX,
	IDC_EDIT2, ed2); 	DDX_Control(pDX,
	IDC_SLIDER1, mSlider1); 	DDX_Control(pDX,
	IDC_SLIDER2, mSlider2);
my_dialog2::my_dialog2(CWnd* pParent /*=NULL*/): CDialog(my_dialog2::IDD, pParent) –представляет собой конструктор для класса my_dialog(). В конструкторе реализована часть, связанная с присвоением переменным начальных значений.
void my_dialog2::OnCustomdrawSlider1(NMHDR* pNMHDR, LRESULT* pResult) –позволяет реагировать на события, связанные со перемещением бегунка (Slider).
void my_dialog2::OnCustomdrawSlider2(NMHDR* pNMHDR, LRESULT* pResult)–функция производит действия, аналогчные предыдущей.
BOOL my_dialog2::OnInitDialog()-данный метод позволяет выполнить ряд процессов или задач до момента создания диалогового окна, тем самым частично повторив действия функции-конструктора.
void my_dialog2::OnOK()-данная функция является реакцией на действия, когда пользователем выбрана кнопка подтверждения (ОК). В диалоге указанная кнопка переименована и называется “Построить”. Внутри метода дополнительных действий не производится.
Все методы, приведенные в классе, кроме конструктора, зацищены (protected:) и могут быть вызваны только из унаследованных классов в дальнейшем. Кроме того класс содержит ряд переменных, значение которых будет передано основному модулю прикладной библиотеки после того, как диалоговое окно будет закрыто пользователем. Листинг класса диалогового окна для модели “насадка” и метода реализации данного класса приведены ниже.
	#if!defined(AFX_MY_DIALOG2_H__26B2A380_F40A_4710_AD2F_C1C706817754__INCLUDED_) #define
	AFX_MY_DIALOG2_H__26B2A380_F40A_4710_AD2F_C1C706817754__INCLUDED_ #if
	_MSC_VER > 1000 #pragma
	once #endif
	// _MSC_VER > 1000 //
	my_dialog2.h : header file #include
	"resource.h" //Для
	слайдера #include
	"afxcmn.h" //
	my_dialog2 dialog 
	 class
	my_dialog2 : public CDialog { 	//
	Construction public: 	my_dialog2(CWnd*
	pParent = NULL);   // standard constructor //
	Dialog Data 	//{{AFX_DATA(my_dialog2) 	enum
	{ IDD = IDD_DIALOG2 };     CSliderCtrl	mSlider1; 	CSliderCtrl	mSlider2; 	int		ed1; 	int
	    ed2; 	int
	pos1; 	CEdit	*edit1;     CEdit	*edit2; 	//}}AFX_DATA //
	Overrides 	//
	ClassWizard generated virtual function overrides 	//{{AFX_VIRTUAL(my_dialog2) 	protected: 	virtual
	void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support 	//}}AFX_VIRTUAL 
	 //
	Implementation protected: 	//
	Generated message map functions 	//{{AFX_MSG(my_dialog2) 	virtual
	void OnOK(); 	virtual
	BOOL OnInitDialog(); 	afx_msg
	void OnCustomdrawSlider1(NMHDR* pNMHDR, LRESULT* pResult); 	afx_msg
	void OnCustomdrawSlider2(NMHDR* pNMHDR, LRESULT* pResult); 	//}}AFX_MSG 	DECLARE_MESSAGE_MAP() };
	#include
	"stdafx.h" #include
	"my_dialog2.h" #ifdef
	_DEBUG #define
	new DEBUG_NEW #undef
	THIS_FILE static
	char THIS_FILE[] = __FILE__; #endif //Значение
	значение внутреннего диаметра #define
	min1  30 #define
	max1  80 //Значение
	длины #define
	min2  300 #define
	max2  500 //
	my_dialog2 dialog my_dialog2::my_dialog2(CWnd*
	pParent /*=NULL*/) 	:
	CDialog(my_dialog2::IDD, pParent) {	ed1
	= 0;} void
	my_dialog2::DoDataExchange(CDataExchange* pDX) { 	CDialog::DoDataExchange(pDX); 	DDX_Text(pDX,
	IDC_EDIT1, ed1); 	DDX_Text(pDX,
	IDC_EDIT2, ed2); 	DDX_Control(pDX,
	IDC_SLIDER1, mSlider1); 	DDX_Control(pDX,
	IDC_SLIDER2, mSlider2); } BEGIN_MESSAGE_MAP(my_dialog2,
	CDialog) 	ON_NOTIFY(NM_CUSTOMDRAW,
	IDC_SLIDER1, OnCustomdrawSlider1) 	ON_NOTIFY(NM_CUSTOMDRAW,
	IDC_SLIDER2, OnCustomdrawSlider2) END_MESSAGE_MAP() void
	my_dialog2::OnOK() 
	 {CDialog::OnOK(); } BOOL
	my_dialog2::OnInitDialog() 
	 {CDialog::OnInitDialog();	 //Определеяем
	максимум и минимум бегунка №1 и
	устанавливаем эти значения mSlider1.SetRangeMin(min1,TRUE);			 mSlider1.SetRangeMax(max1,TRUE);	
	   		 mSlider1.SetRange(min1,
	max1, TRUE); //Определеяем
	максимум и минимум бегунка №2 и
	устанавливаем эти значения mSlider2.SetRangeMin(min2,TRUE);			 mSlider2.SetRangeMax(max2,TRUE);	
	   		 mSlider2.SetRange(min2,
	max2, TRUE); return
	TRUE;  
	 } void
	my_dialog2::OnCustomdrawSlider1(NMHDR* pNMHDR, LRESULT* pResult) 
	 { int
	i=mSlider1.GetPos();	// получить
	позицию ed1=i; edit1=(CEdit*)GetDlgItem(IDC_EDIT1); UpdateData(FALSE); *pResult
	= 0; } void
	my_dialog2::OnCustomdrawSlider2(NMHDR* pNMHDR, LRESULT* pResult) 
	 { int
	i=mSlider2.GetPos();	// получить
	позицию ed2=i; edit2=(CEdit*)GetDlgItem(IDC_EDIT2); UpdateData(FALSE); *pResult
	= 0; }
На рисунке 50 показан диалоговый интерфейс для построения твердотельной модели. При этом пользователю предлагается изменить имеющиеся параметры в заданном диапазоне значений.
| 
			 
 Рис. 50. Определение параметров для построения твердотельной модели “насадки” | 
После создания диалогового интерфейса и определения ряда параметров необходимо подготовить в функции void WINAPI LIBRARYENTRY(UINT comm) вызов метода программного построения требуемой детали. В следующем фрагменте проиллюстрировано, как подготовить вызов диалогового окна, передать заданные параметры глобальным переменным, вызвать функцию построения насадки, а результат построения записать в файл под заданным именем в указанную директорию (сохраненный файл "Насадка.m3d" является документом КОМПАС 3D, относящимся к моделям).
	//Для
	задания параметров насадки //Внутренний
	диаметр int
	diam3; //Высота
	модели int
	hi1; //Номер
	исполнения int
	pos1; void
	Adjutage (IPartPtr& part); void
	WINAPI LIBRARYENTRY( UINT comm ) 
	 { switch
	( comm ) 	
	 { 	
	 case 1 : { 
	  EnableTaskAccess(
	0 );        // Закрыть
	доступ
	к
	компасу  my_dialog2
	 dlg2;	//
	создаем объект класса диалогового окна 
	  if
	(dlg2.DoModal()==IDOK)     {
	
	       diam3=dlg2.ed1;       hi1=dlg2.ed2;       pos1=dlg2.pos1;     }
	 		  
	  EnableTaskAccess(
	1 );        // Открыть доступ к компасу	 
	 IDocument3DPtr
	Doc3d1( ksGet3dDocument(), false ); 
	 Doc3d1->Create(
	false, true ); IPartPtr
	part( Doc3d1->GetPart( pNew_Part ), false ); Adjutage
	 (part); 
	 //Имя
	модели part->SetName(_T("Насадка.m3d")); part->SetStandardComponent(
	true ); Doc3d1->SetFileName(
	_T( "d:\\насадка.m3d" ) ); Doc3d1->UpdateDocumentParam();
	 
	 Doc3d1->Save(); //Doc3d1->Close(); break;
	//прекратить построение модели  }		
	 
	 }
Из приведенного листинга видно, что определены три глобальные переменные, отвечающие за высоту модели, внутренний диаметр (значения берутся из диалогового интерфейса) и номер исполнения. Исполнение для данной модели единственное, поэтому параметр является зарезервированным. В функции void Adjutage (IPartPtr& part); производятся необходимые геометрические построения. Выбор того или иного построения определен в разделе условноного оператора switch()-при указазанном значении 1 прозводится отображения диалогового окна проектирования насадки, а доступ к системе проектирования блокируется с помощью функции EnableTaskAccess(0). Для доступа к КОМПАСУ требуется вызвать функцию повторно с параметром 1- EnableTaskAccess(1). Работа с функциями системы возможна после того, как будет объявлен указатель на объект после вызова следующей функции IDocument3DPtr Doc3d1( ksGet3dDocument(), false ). Через объявленный указатель имеется возможность вызвать соответствующую функцию для создания детали и передать два параметра: первый- видимости объекта в процессе построения, а второй-типа объекта (сборка или деталь). В рассматриваемом случае значения следующие: Doc3d1->Create( false, true ). Компонент строится в прикладной библиотеке как стандартный, поэтому дерево построения отдельных элементов создано не будет. Задается указанная опция с помощью функции part->SetStandardComponent( true ). Прежде чем использовать указатель на объект рабочей детали, его необходимо объявить. Объявление имеет следующий вид IPartPtr part( Doc3d1->GetPart( pNew_Part ), false ). Обновление параметров активного в данный момент документа, его сохранения и закрытия производится следующими методами: Doc3d1->UpdateDocumentParam(); Doc3d1->Save(); //Doc3d1->Close(). Последний метод закомментирован ввиду того, что результат рекомендуется отобразить на экране. В процессе проектирования сборок компоненты построенных деталей перед добавлением в конструкцию требуется выгружать.
Функция построения насадки представлена разнообразными методами проектирования объекта - получение геометрии по сечениям, создание вспомогательных плоскостей проектирования, получение вырезов выдавливанием и т.д. Дейстия всех методов, которые используются при построении, подробно прокомментированы в листинге:
 
	//
	Построение насадки void
	Adjutage ( IPartPtr & part ) 
	 {  //
	Создаем
	новый
	эскиз   IEntityPtr
	entitySketch( part->NewEntity( o3d_sketch ), false );  
	   if
	(entitySketch )   {     //
	Получаем указатель на интерфейс
	параметров объектов и элементов     //
	Интерфейс
	свойств
	эскиза     ISketchDefinitionPtr
	sketchDefinition( IUnknownPtr( entitySketch->GetDefinition(),
	false ) );     if
	( sketchDefinition )     {       //
	Получаем
	интерфейс
	базовой
	плоскости
	XOY       IEntityPtr
	basePlane( part->GetDefaultEntity( o3d_planeXOY ), false );      
	  
	       //
	Установка
	параметров
	эскиза      
	sketchDefinition->SetPlane(
	basePlane ); // Установим
	плоскость
	XOY базовой
	для
	эскиза       //
	Создаем
	эскиз       entitySketch->Create();      
	entitySketch->SetHidden(false);       //
	Войти в режим редактирования эскиза       if
	( sketchDefinition->BeginEdit()
	)       { //
	выполняем построение контура LineSeg(-0.7*diam3,-0.2*diam3,0.7*diam3,-0.2*diam3,1); LineSeg(-0.7*diam3,0.2*diam3,0.7*diam3,0.2*diam3,1); LineSeg(-0.7*diam3,-0.2*diam3,-0.7*diam3,0.2*diam3,1); LineSeg(0.7*diam3,-0.2*diam3,0.7*diam3,0.2*diam3,1); //} //Используем
	в случае, когда в меню присутствует
	элемент "исполнение" //else
	{Circle( 0, 0, diam3+5, 1 );	         //
	Выйти из режима редактирования эскиза        
	sketchDefinition->EndEdit();       }
	} }   //
	Создадим смещенную плоскость ( для
	создания на ней эскиза )   IEntityPtr
	entityPlaneOffset2( part->NewEntity( o3d_planeOffset ), false  );   //
	Создаем
	новый
	эскиз   IEntityPtr
	entitySketch2( part->NewEntity( o3d_sketch ), false  );  
	   if
	( (bool)entityPlaneOffset2 && (bool)entitySketch2 )   {     //
	Получаем указатель на интерфейс
	параметров объектов и элементов     //
	Интерфейс свойств смещенной плоскости    
	IPlaneOffsetDefinitionPtr
	planeOffsetDefinition2(
	IUnknownPtr(
	entityPlaneOffset2->GetDefinition(),
	false
	 ) );     if
	( planeOffsetDefinition2 ) 
	     {      //
	Установка параметров смещенной плоскости      //
	Расстояние от базовой плоскости 
	 planeOffsetDefinition2->SetOffset(hi1*0.4
	);       //
	Получаем интерфейс базовой плоскости
	XOY       IEntityPtr
	basePlane(
	part->GetDefaultEntity(
	o3d_planeXOY
	), false
	);      
	planeOffsetDefinition2->SetPlane(
	basePlane
	);                     
	 //
	Установим плоскость XOY
	базовой для плоскости //
	Имя для смещенной плоскости entityPlaneOffset2->SetName(
	_bstr_t( _T("Вспомогательная плоскость
	№1") ) ); 
	
	      entityPlaneOffset2->SetHidden(
	true );    // Скрыть смещенную плоскость       //
	Создаем смещенную плоскость      
	entityPlaneOffset2->Create();
	                  
	       //
	Получаем указатель на интерфейс
	параметров объектов и элементов       //
	Интерфейс
	свойств
	эскиза       ISketchDefinitionPtr
	sketchDefinition2( IUnknownPtr( entitySketch2->GetDefinition(),
	false ) );       if
	( sketchDefinition2 )       {         //
	Установка
	параметров
	эскиза        
	sketchDefinition2->SetPlane(
	entityPlaneOffset2 ); // Установим
	смещенную
	плоскость
	базовой
	для
	эскиза         //
	Подготовим эскиз        
	entitySketch2->Create();         //
	Войти в режим редактирования эскиза         if
	( sketchDefinition2->BeginEdit() )         {   //
	Введем
	новый
	эскиз
	- эллипс EllipseParam
	par; par.xc
	= 0; par.yc
	= 0; 
	 par.a
	= 0.8*diam3; 
	 par.b
	= 0.4*diam3;  
	 par.ang
	= 0;  
	 par.style
	= 1;  
	 reference
	p = ksEllipse(&par);           //
	Выйти из режима редактирования эскиза          
	sketchDefinition2->EndEdit();         }       }     }   }   //
	Создаем смещенную плоскость ( для
	создания на ней эскиза )   IEntityPtr
	entityPlaneOffset3( part->NewEntity( o3d_planeOffset ), false );   //
	Создадим
	новый
	эскиз   IEntityPtr
	entitySketch3( part->NewEntity( o3d_sketch ), false  );  
	   if
	( (bool)entityPlaneOffset3 && (bool)entitySketch3 )   {     //
	Получаем указатель на интерфейс
	параметров объектов и элементов     //
	Интерфейс свойств смещенной плоскости    
	IPlaneOffsetDefinitionPtr
	planeOffsetDefinition3(
	IUnknownPtr(
	entityPlaneOffset3->GetDefinition(),
	false
	 ) );     if
	( planeOffsetDefinition3 ) 
	     {       //
	Установка параметров смещенной плоскости      //
	planeOffsetDefinition3->SetOffset( ((hi1/2)/2)*2 ); // Расстояние
	от базовой плоскости 
	      
	planeOffsetDefinition3->SetOffset(hi1*0.6);
	     
	       //
	Получаем интерфейс базовой плоскости
	XOY       IEntityPtr
	basePlane( part->GetDefaultEntity( o3d_planeXOY ), false  ); //
	Устанавливаем плоскость XOY
	базовой для плоскости      
	planeOffsetDefinition3->SetPlane(
	basePlane );            
	 //
	Имя
	для
	смещенной
	плоскости    
	entityPlaneOffset3->SetName(
	_bstr_t(_T("Вспомогательная
	плоскость
	№2")));                 
	 //
	Скрываем
	смещенную
	плоскость
	     
	     entityPlaneOffset3->SetHidden(
	true ); //
	Создаем
	смещенную
	плоскость     entityPlaneOffset3->Create();
	                
	
	      //
	Получаем указатель на интерфейс
	параметров объектов и элементов       //
	Интерфейс
	свойств
	эскиза       ISketchDefinitionPtr
	sketchDefinition3( IUnknownPtr( entitySketch3->GetDefinition(),
	false ) );       if
	( sketchDefinition3 )       {         //
	Установка
	параметров
	эскиза         sketchDefinition3->SetPlane(
	entityPlaneOffset3 );         //
	Создаем эскиз        
	entitySketch3->Create();         //
	Войти в режим редактирования эскиза         if
	( sketchDefinition3->BeginEdit() )         {          //
	Введем
	новый
	эскиз
	- окружность           Circle(0,
	0, diam3, 1);           //
	Выйти из режима редактирования эскиза          
	sketchDefinition3->EndEdit();         }       }     }   }  
	   //
	Создаем базовую операцию по сечениям   IEntityPtr
	entityBaseLoft( part->NewEntity( o3d_baseLoft ), false);   if
	( entityBaseLoft ) 
	   { IBaseLoftDefinitionPtr
	baseLoftDefinition( IUnknownPtr( entityBaseLoft->GetDefinition(),
	false) );     if
	( baseLoftDefinition ) 
	     {       IEntityCollectionPtr
	entityCollection( baseLoftDefinition->Sketchs(), false );       if
	( entityCollection ) 
	       {         entityCollection->Add(
	entitySketch );         entityCollection->Add(
	entitySketch2 );         entityCollection->Add(
	entitySketch3 );       } 	baseLoftDefinition->SetThinParam(true,0,5,0);      
	//entityBaseLoft->SetName(
	_bstr_t(_T("Переход"))
	); 
	       //
	Имя для операции по сечениям       //
	Изменяем параметры цвета и визуальных
	свойств объекта      
	entityBaseLoft->SetAdvancedColor(
	RGB (51,51,102),  // Цвет                        
	                0.8,
	      // Общий
	свет                        
	                0.8,
	      // Диффузия                        
	                0.8,
	      // Зеркальность                        
	                0.8,
	      // Блеск                        
	                1,
	        // Прозрачность                        
	                0.8
	);     // Излучение 
	       //
	Выполняем операцию построения по
	сечениям      
	entityBaseLoft->Create();
	
	       //MessageT(
	_T("Базовая операция по сечениям")
	);                       
	     }   }       //
	Приклеиваем выдавливанием объект IEntityPtr
	entityBossExtrusion(
	part->NewEntity(
	o3d_bossExtrusion
	), false
	 );               if
	( entityBossExtrusion ) 
	               {  
	
	//
	Получаем указатель на интерфейс
	параметров объектов и элементов //
	Интерфейс параметров приклеенного
	элемента выдавливания   
	IBossExtrusionDefinitionPtr
	bossExtrusionDefinition(
	IUnknownPtr(
	entityBossExtrusion->GetDefinition(),
	false
	 ) );        if
	( bossExtrusionDefinition
	) 
	                
	{IExtrusionParamPtr
	extrusionParam(
	bossExtrusionDefinition->ExtrusionParam(),
	false
	 ); // Интерфейс структуры параметров
	выдавливания  IThinParamPtr
	     thinParam(
	bossExtrusionDefinition->ThinParam(),
	false
	 );           // Интерфейс структуры параметров
	тонкой стенки  if
	( (bool)extrusionParam && (bool)thinParam ) 
	      { //
	Установка
	параметров
	элемента
	выдавливания  bossExtrusionDefinition->SetSketch(
	entitySketch3 ); 
	 //
	Эскиз
	операции
	выдавливания  extrusionParam->SetDirection(
	dtNormal ); 
	 //
	Направление выдавливания ( dtNormal	-
	прямое //
	направление, для тонкой стенки - наружу, //
	dtReverse	- обратное направление, для тонкой
	стенки - внутрь //
	dtBoth - в обе стороны, dtMiddlePlane от средней
	плоскости ) 
	extrusionParam->SetTypeNormal(
	etBlind ); 
	 //
	Тип выдавливания ( etBlind - строго на
	глубину, //
	etThroughAll - через всю деталь, etUpToVertexTo - на
	расстояние до вершины, //
	etUpToVertexFrom - на расстояние за вершину,
	etUpToSurfaceTo - на расстояние //
	до поверхности, etUpToSurfaceFrom - на расстояние
	за поверхность, //
	etUpToNearSurface - до ближайшей поверхности ) extrusionParam->SetDepthNormal(
	hi1*0.4 );    
	 //
	Глубина
	выдавливания bossExtrusionDefinition->SetThinParam(true,0,5,0);
	                                               
	 entityBossExtrusion->SetAdvancedColor(
	RGB (255,102,51),  // Цвет                        
	                0.8,
	      // Общий
	свет                        
	                0.8,
	      // Диффузия                        
	                0.8,
	      // Зеркальность                        
	                0.8,
	      // Блеск                        
	                1,
	        // Прозрачность                        
	                0.8
	);     // Излучение                    
	entityBossExtrusion->Create();
	// Приклеим выдавливанием          
	                   }              } 	}		
	
	   //
	Создаем смещенную плоскость ( для
	создания на ней эскиза )   IEntityPtr
	entityPlaneOffset4( part->NewEntity( o3d_planeOffset ), false );   //
	Создадим
	новый
	эскиз   IEntityPtr
	entitySketch4( part->NewEntity( o3d_sketch ), false  );  
	   if
	( (bool)entityPlaneOffset4 && (bool)entitySketch4 )   {     //
	Получаем указатель на интерфейс
	параметров объектов и элементов     //
	Интерфейс свойств смещенной плоскости    
	IPlaneOffsetDefinitionPtr
	planeOffsetDefinition4(
	IUnknownPtr(
	entityPlaneOffset4->GetDefinition(),
	false
	 ) );     if
	(planeOffsetDefinition4 ) 
	     {       //
	Установка параметров смещенной плоскости      
	planeOffsetDefinition4->SetOffset(hi1);	
	      
	       //
	Получаем интерфейс базовой плоскости
	XOY       IEntityPtr
	basePlane( part->GetDefaultEntity( o3d_planeXOY ), false  );      
	planeOffsetDefinition4->SetPlane(
	basePlane
	);         
	       
	 
	
 
	 entityPlaneOffset4->SetName(
	_bstr_t(_T("Вспомогательная плоскость
	№3")));                 // Имя для смещенной
	плоскости //
	Скрываем смещенную плоскость 
	entityPlaneOffset4->SetHidden(true
	);                
	 //
	Создаем смещенную плоскость 
	entityPlaneOffset4->Create();
	              
	  //
	Получаем указатель на интерфейс
	параметров объектов и элементов  //
	Интерфейс
	свойств
	эскиза  ISketchDefinitionPtr
	sketchDefinition4( IUnknownPtr( entitySketch4->GetDefinition(),
	false ) );  if
	( sketchDefinition4 )       {  //
	Установка
	параметров
	эскиза   sketchDefinition4->SetPlane(
	entityPlaneOffset4 ); 
	 //
	Устанавливаем смещенную плоскость
	базовой для эскиза  //
	Создаем эскиз        
	entitySketch4->Create();  //
	Войти в режим редактирования эскиза         if
	( sketchDefinition4->BeginEdit() )         { //
	Введем
	новый
	эскиз
	- окружность             Circle(0,
	0, diam3+2, 1); Circle(0, 0, diam3, 1);           //
	Выйти из режима редактирования эскиза          
	sketchDefinition4->EndEdit();         }       }     }   } //Выполняем
	операцию-вырезать выдавливанием IEntityPtr
	entityCutExtrusion( part->NewEntity( o3d_cutExtrusion ), false 
	); 
	      if
	(entityCutExtrusion ) 
	          {  //
	Получаем указатель на интерфейс
	параметров объектов и элементов  //
	Интерфейс параметров вырезанного
	элемента выдавливания ICutExtrusionDefinitionPtr
	cutExtrusionDefinition(
	IUnknownPtr(
	entityCutExtrusion->GetDefinition(),
	false
	 ) ); if
	( cutExtrusionDefinition ) 
	           { //
	Установка параметров операции
	выдавливания                    
	IEntityPtr
	entityCutExtrusion( part->NewEntity( o3d_cutExtrusion ), false 
	); 
	                     if
	(entityCutExtrusion ) 
	                     { //
	Получаем указатель на интерфейс
	параметров объектов и элементов //
	Интерфейс параметров вырезанного
	элемента выдавливания                      
	ICutExtrusionDefinitionPtr
	cutExtrusionDefinition(
	IUnknownPtr(
	entityCutExtrusion->GetDefinition(),
	false
	 ) );                      
	if
	(cutExtrusionDefinition ) 
	                       { //
	Установка параметров операции
	выдавливания 
	cutExtrusionDefinition->SetDirectionType(
	dtNormal );   
	 //
	Изменяем параметры выдавливания в
	одном направлении   
	cutExtrusionDefinition->SetSideParam(
	true,etBlind, 0.3*hi1,0,false); //
	Изменить
	параметры
	тонкой
	стенки 
	cutExtrusionDefinition->SetThinParam(
	
	 false,
	                // Признак тонкостенной операции    0,
	                 // Направление построения
	тонкой стенки    0,
	                 // Толщина стенки в прямом
	направлении    0
	);                // Толщина стенки в обратном
	направлении 
	
 
	cutExtrusionDefinition->SetSketch(
	entitySketch4 );          
	 //
	Эскиз
	операции
	выдавливания entityCutExtrusion->SetAdvancedColor(
	RGB (0,204,0),  // Цвет                        
	                0.8,
	      // Общий
	свет                        
	                0.8,
	      // Диффузия                        
	                0.8,
	      // Зеркальность                        
	                0.8,
	      // Блеск                        
	                1,
	        // Прозрачность                        
	                0.8
	);     // Излучение //
	Вырез выдавливанием entityCutExtrusion->Create();
	  
	           }      }   
	 }
Выполнение функции приведет к построению модели, которая приведена на рисунке 51. Для того, чтобы проследить последовательность выполнения операций в дереве моделей, в библиотеке был отключен метод построения обекта как стандартный компонент.
| 
			 Рис. 51. Программная реализация построения модели ”насадка” | 
Код, выполняющий аналогичные операции, выполненный на языке Object Pascal в среде Borland Delphi 7.0 представлен далее.
 
	procedure
	PartPaint(var d:real; h:real); var iKompasObject:
	KompasObject; iDocument3D:
	ksDocument3D; doc:
	ksDocument2D; iPart:ksPart; PlaneXOY:
	ksEntity; iSketchEntity:
	ksEntity; iSketchDef:
	ksSketchDefinition; iSketch2Entity:
	ksEntity; iSketch2Def:
	ksSketchDefinition; iSketch3Entity:
	ksEntity; iSketch3Def:
	ksSketchDefinition; iSketch4Entity:
	ksEntity; iSketch4Def:
	ksSketchDefinition; iOffsetPlaneEntity:
	ksEntity; iOffsetPlaneDef
	: ksPlaneOffsetDefinition; iBossLoftEntity:
	ksEntity; iBossLoftDef
	: ksBossLoftDefinition; iBossExtrusion:ksEntity; iBossExtrusionDef
	: ksBossExtrusionDefinition; iCutExtrusion:ksEntity; iCutExtrusionDef
	: ksCutExtrusionDefinition; Collect
	: ksEntityCollection; par:ksEllipseParam; ColorParam:ksColorParam; 
	 Begin 
	 iKompasObject
	:= KompasObject(CreateKompasObject); 
	   if
	iKompasObject <> nil then   begin     iDocument3D
	:= ksDocument3D(iKompasObject.Document3D);     if
	 idocument3d.Create(false,true) then       begin         if
	(iDocument3D <> nil) then           begin 
	             //
	получаем указатель на интерфейс детали             iPart
	:= ksPart(iDocument3D.GetPart(pNew_Part));             if
	(iPart <> nil) then             begin 
	               //
	интерфейс плоскости               PlaneXOY
	:= ksEntity(iPart.GetDefaultEntity(o3d_planeXOY)); 
	               //
	интерфейс эскиза (эскиз 1)               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                      
	doc.ksLineSeg(-0.7*d,-0.2*d,0.7*d,-0.2*d,1);                      
	doc.ksLineSeg(-0.7*d,0.2*d,0.7*d,0.2*d,1);                      
	doc.ksLineSeg(-0.7*d,-0.2*d,-0.7*d,0.2*d,1);                      
	doc.ksLineSeg(0.7*d,-0.2*d,0.7*d,0.2*d,1);                    
	end;                     //
	завершение редактирования эскиза                    
	iSketchDef.EndEdit;                   end;                 end;               end; 
	               //
	интерфейс смещенной плоскости iOffsetPlaneEntity
	:= ksEntity(iPart.NewEntity(o3d_planeOffset));               if
	(iOffsetPlaneEntity <> nil) then                 begin                 //
	интерфейс параметров смещенной плоскости                 iOffsetPlaneDef
	:=                
	ksPlaneOffsetDefinition(iOffsetPlaneEntity.GetDefinition);                 if
	(iOffsetPlaneDef <> nil) then                   begin 
	//
	величина, базовая плоскость и другие
	параметры смещения                   
	iOffsetPlaneDef.Offset
	:=0.4*h;                   
	iOffsetPlaneDef.SetPlane(PlaneXOY);                   
	iOffsetPlaneDef.direction
	:= true;                    //
	делаем плоскость скрытой                   
	iOffsetPlaneEntity.Hidden
	:= false;                    //
	создаем вспомогательную плоскость                   
	iOffsetPlaneEntity.Create;                   end;                 end; 
	               //
	интерфейс эскиза (эскиз 2)               iSketch2Entity
	:= ksEntity(iPart.NewEntity(o3d_sketch));               if
	(iSketch2Entity <> nil) then               begin                 //
	интерфейс параметров эскиза iSketch2Def
	:= ksSketchDefinition(iSketch2Entity.GetDefinition);                 if
	(iSketch2Def <> nil) then                 begin                   if
	(iOffsetPlaneEntity <> nil) then                   begin
 
	//
	устанавливаем плоскость,                     //
	на которой создается эскиз                    
	iSketch2Def.SetPlane(iOffsetPlaneEntity);                    
	iSketch2Entity.Create;                     //
	doc - указатель на интерфейс ksDocument2D                     doc
	:= ksDocument2D(iSketch2Def.BeginEdit);                     if
	(doc <> nil) then                     begin                       //
	вычерчиваем изображение эскиза                       //
	с помощью методов интерфейса ksDocument2D                      
	par:=ksEllipseParam(iKompasObject.GetParamStruct(22));                       par.Init;                       par.xc:=0;                       par.yc:=0;                       par.A:=0.8*d;                       par.B:=0.4*d;                       par.style:=1;                      
	doc.ksEllipse(par);                    
	end;                     //
	завершение редактирования эскиза                    
	iSketch2Def.EndEdit;                   end;                 end;               end; 
	               //
	интерфейс смещенной плоскости 2 iOffsetPlaneEntity
	:= ksEntity(iPart.NewEntity(o3d_planeOffset));               if
	(iOffsetPlaneEntity <> nil) then                 begin                 //
	интерфейс параметров смещенной плоскости                 iOffsetPlaneDef
	:=                
	ksPlaneOffsetDefinition(iOffsetPlaneEntity.GetDefinition);                 if
	(iOffsetPlaneDef <> nil) then                   begin                     //
	величина, базовая плоскость и другие
	параметры 
	                   
	iOffsetPlaneDef.Offset
	:=0.6*h;                   
	iOffsetPlaneDef.SetPlane(PlaneXOY);                   
	iOffsetPlaneDef.direction
	:= true;                    //
	делаем плоскость скрытой                   
	iOffsetPlaneEntity.Hidden
	:= false;                    //
	создаем вспомогательную плоскость                   
	iOffsetPlaneEntity.Create;                   end;                 end; 
	               //
	интерфейс эскиза (эскиз 3)               iSketch3Entity
	:= ksEntity(iPart.NewEntity(o3d_sketch));               if
	(iSketch3Entity <> nil) then               begin                 //
	интерфейс параметров эскиза 
	iSketch3Def
	:=
	ksSketchDefinition(iSketch3Entity.GetDefinition);                 if
	(iSketch3Def <> nil) then                 begin                   if
	(iOffsetPlaneEntity <> nil) then                   begin                     //
	устанавливаем плоскость,                     //
	на которой создается эскиз                    
	iSketch3Def.SetPlane(iOffsetPlaneEntity);                    
	iSketch3Entity.Create;                     //
	doc - указатель на интерфейс ksDocument2D                     doc
	:= ksDocument2D(iSketch3Def.BeginEdit);                     if
	(doc <> nil) then                     begin                       //
	вычерчиваем изображение эскиза                      
	//
	с помощью методов интерфейса ksDocument2D                      
	doc.ksCircle(0,
	0, d,
	1);                    
	end;                     //
	завершение редактирования эскиза                    
	iSketch3Def.EndEdit;                   end;                 end;               end;
 
	iSketch3Entity.Create;                     //
	doc - указатель на интерфейс ksDocument2D                     doc
	:= ksDocument2D(iSketch3Def.BeginEdit);                     if
	(doc <> nil) then                    
	begin                      
	//
	вычерчиваем изображение эскиза                      
	//
	с помощью методов интерфейса ksDocument2D                      
	doc.ksCircle(0,
	0, d, 1);                    
	end;                     //
	завершение редактирования эскиза                    
	iSketch3Def.EndEdit;                   end;                 end;               end; 
	 
	               //
	интерфейс
	операции
	по
	сечениям               iBossLoftEntity
	:= ksEntity(iPart.NewEntity(o3d_bossLoft));               if
	(iBossLoftEntity <> nil) then               begin                 //
	интерфейс
	параметров
	операции
	по
	сечениям iBossLoftDef
	:= ksBossLoftDefinition(iBossLoftEntity.GetDefinition);                 if
	(iBossLoftDef <> nil) then                 begin                   //
	интерфейс массива ksEntityCollection                   //
	коллекции эскизов для операции по
	сечениям                  
	Collect
	:= ksEntityCollection(iBossLoftDef.Sketchs);                   //
	добавляем эскизы в колекцию                  
	Collect.Add(iSketchEntity);                  
	Collect.Add(iSketch2Entity);                  
	Collect.Add(iSketch3Entity);                  
	//создаем
	тонкую
	стенку                  
	iBossLoftDef.SetThinParam(true,0,5,0);                   //
	создаем операцию по сечениям                  
	iBossLoftEntity.Create;                 end;               end; 
	               //
	интерфейс операции выдавливания iBossExtrusion
	:= ksEntity(iPart.NewEntity(o3d_bossExtrusion));               if
	(iBossExtrusion <> nil) then               begin                 //
	интерфейс
	параметров
	dвыдавливание                 iBossExtrusionDef
	:=                
	ksBossExtrusionDefinition(iBossExtrusion.GetDefinition);                 if
	(iBossExtrusionDef <> nil) then                 begin                   //
	настройка
	параметров                  
	iBossExtrusionDef.SetSketch(iSketch3Entity);                   //
	направление                  
	iBossExtrusionDef.directionType
	:= dtNormal;                   //
	величина
	выдавливания                  
	iBossExtrusionDef.SetSideParam 
	(true,
	etBlind, 0.4*h, 0, false);                  
	iBossExtrusionDef.SetThinParam(true,0,5,0);                   //
	создаем
	тело                  
	iBossExtrusion.Create;                 end;               end; 
	               //
	интерфейс смещенной плоскости 3              
	iOffsetPlaneEntity
	:= ksEntity(iPart.NewEntity(o3d_planeOffset));               if
	(iOffsetPlaneEntity <> nil) then                 begin                 //
	интерфейс
	параметров
	смещенной
	плоскости                 iOffsetPlaneDef
	:=                
	ksPlaneOffsetDefinition(iOffsetPlaneEntity.GetDefinition);                 if
	(iOffsetPlaneDef <> nil) then                   begin                     //
	величина, базовая плоскость и другие
	параметры смещения                   
	iOffsetPlaneDef.Offset
	:=h;                   
	iOffsetPlaneDef.SetPlane(PlaneXOY);                   
	iOffsetPlaneDef.direction
	:= true;                    //
	делаем
	плоскость
	скрытой                   
	iOffsetPlaneEntity.Hidden
	:= false;                    //
	создаем вспомогательную плоскость                   
	iOffsetPlaneEntity.Create;                   end;                 end;
 
	//
	интерфейс смещенной плоскости 3 
	iOffsetPlaneEntity
	:= ksEntity(iPart.NewEntity(o3d_planeOffset));               if
	(iOffsetPlaneEntity <> nil) then                 begin                 //
	интерфейс параметров смещенной плоскости                
	iOffsetPlaneDef
	:=                
	ksPlaneOffsetDefinition(iOffsetPlaneEntity.GetDefinition);                 if
	(iOffsetPlaneDef <> nil) then                   begin                     //
	величина, базовая плоскость и другие
	параметры 
	                   
	iOffsetPlaneDef.Offset
	:=h;                   
	iOffsetPlaneDef.SetPlane(PlaneXOY);                   
	iOffsetPlaneDef.direction
	:= true;                    //
	делаем
	плоскость
	скрытой                   
	iOffsetPlaneEntity.Hidden
	:= false;                    //
	создаем вспомогательную плоскость                   
	iOffsetPlaneEntity.Create;                   end;                 end; 
	               //
	интерфейс
	эскиза
	(эскиз
	4)               iSketch4Entity
	:= ksEntity(iPart.NewEntity(o3d_sketch));               if
	(iSketch4Entity <> nil) then               begin                 //
	интерфейс
	параметров
	эскиза iSketch4Def
	:= ksSketchDefinition(iSketch4Entity.GetDefinition);                 if
	(iSketch4Def <> nil) then                 begin                   if
	(iOffsetPlaneEntity <> nil) then                   begin                     //
	устанавливаем плоскость,                     //
	на которой создается эскиз                    
	iSketch4Def.SetPlane(iOffsetPlaneEntity);                    
	iSketch4Entity.Create;                     //
	doc - указатель
	на
	интерфейс
	ksDocument2D                     doc
	:= ksDocument2D(iSketch4Def.BeginEdit);                     if
	(doc <> nil) then                     begin                      
	//
	вычерчиваем
	изображение
	эскиза                      
	//
	с помощью методов интерфейса ksDocument2D                      
	doc.ksCircle(0,
	0, d+2, 1);                      
	doc.ksCircle(0,
	0, d, 1);                    
	end;                     //
	завершение редактирования эскиза                    
	iSketch4Def.EndEdit;                   end;                 end;               end; 
	               //
	интерфейс
	операции
	вырезания
	выдавливанием               iCutExtrusion
	:= ksEntity(iPart.NewEntity(o3d_cutExtrusion));               if
	(iCutExtrusion <> nil) then               begin                 //
	интерфейс
	параметров
	dвыдавливание                 iCutExtrusionDef
	:=                
	ksCutExtrusionDefinition(iCutExtrusion.GetDefinition);                 if
	(iCutExtrusionDef <> nil) then                 begin
 
	
	 
	//
	интерфейс параметров dвыдавливание                
	iCutExtrusionDef
	:=                
	ksCutExtrusionDefinition(iCutExtrusion.GetDefinition);                 if
	(iCutExtrusionDef <> nil) then                 begin                   //
	настройка
	параметров                  
	iCutExtrusionDef.SetSketch(iSketch4Entity);                   //
	направление                  
	iCutExtrusionDef.directionType
	:= dtNormal;                   //
	величина
	выдавливания                  
	iCutExtrusionDef.SetSideParam 
	(true,
	etBlind, 0.3*h, 0, false);                   //
	создаем
	вырез                  
	iCutExtrusion.Create;                 end;               end; 
	              
	//установим
	собственный цвет для детали              
	iPart.useColor:=0;               //создаем
	переменную параметров цвета детали              
	ColorParam:=ksColorParam(iPart.ColorParam);               //задаем
	цет              
	ColorParam.color:=$1845;              
	//зеркальность
	детали              
	ColorParam.specularity:=1000;               //блеск
	детали              
	ColorParam.shininess:=1000;              
	//излучение
	детали              
	ColorParam.emission:=1000;               //задаем
	параметры цвета детали              
	iPart.SetAdvancedColor(ColorParam.color,ColorParam.ambient, 
	СolorParam.diffuse,ColorParam.specularity, 
	ColorParam.shininess,              
	ColorParam.transparency,ColorParam.emission);              
	//обновляем
	деталь               iPart.Update; 
	             
	//сохранение
	файла               If
	 iDocument3D.IsDetail then 
	               begin                
	iDocument3D.fileName:='c:\nasadka.m3d';                
	iDocument3D.UpdateDocumentParam;                 iDocument3D.Save;               end; 
	              //от
	детали и выше             end;           end;       end;   end; end; 
	
Следующая программная модель (штуцер) строится аналогичным образом: проектирование интерфейса, взаимосвязь интефейса и основново модуля прикладной библиотеки, передача параметров из диалогового окна в функцию построения и вызов метода геометрического проектирования модели изделия. На рисунке 52 показана разработка диалогового окна в среде Visual Studio.
| 
			 Рис. 52. Проектирование диалогового окна под модель типа ”штуцер” | 
Фрагмент ресурсного файла представлен следующим листингом:
 
	IDD_DIALOG3
	DIALOGEX 0, 0, 258, 161 STYLE
	DS_MODALFRAME | WS_POPUP | WS_CAPTION CAPTION
	"Определение параметров детали
	(штуцер)"
 
	FONT
	8, "MS Sans Serif" BEGIN     DEFPUSHBUTTON
	  "Построить",IDOK,89,140,75,14     GROUPBOX
	       "Размерные
	характеристики",IDC_STATIC,7,7,244,130     EDITTEXT
	       IDC_EDIT1,126,50,40,14,ES_CENTER | ES_AUTOHSCROLL | 
	                     WS_DISABLED     CONTROL
	        "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH
	| 
	                     TBS_NOTICKS
	| WS_TABSTOP,14,95,162,15     LTEXT
	          "Внутренний диаметр,
	мм",IDC_STATIC,29,53,86,8     GROUPBOX
	       "Вид модели",IDC_STATIC,176,16,69,116     CONTROL
	        7018,IDC_STATIC,"Static",SS_BITMAP,179,24,62,105,                    
	WS_EX_DLGMODALFRAME
	| WS_EX_CLIENTEDGE | 
	                     WS_EX_STATICEDGE END
Из приведенного диалогового окна видно, что лишь один параметр будет являться управляющим. Управляющий класс для “штуцера” выглядит также как и для модели “насадки”, поэтому далее приводится лишь фрагмент кода для указанного класса без отображения методов реализации.
	#if
	!defined(AFX_MY_DIALOG3_H__2A6E7C4F_49DD_4A3E_B6D5_5B84DF2B965D__INCLUDED_) #define
	AFX_MY_DIALOG3_H__2A6E7C4F_49DD_4A3E_B6D5_5B84DF2B965D__INCLUDED_ #if
	_MSC_VER > 1000 #pragma
	once #endif
	// _MSC_VER > 1000 //
	my_dialog3.h : header file // #include
	"resource.h" //Для
	слайдера #include
	"afxcmn.h" //
	my_dialog3 dialog 
	 class
	my_dialog3 : public CDialog { //
	Construction public: 	my_dialog3(CWnd*
	pParent = NULL);   // standard constructor 
	 //
	Dialog Data 	//{{AFX_DATA(my_dialog3) 	enum
	{ IDD = IDD_DIALOG3 }; 	CSliderCtrl	mSlider1; 	int		ed1; 	CEdit	*edit1; 	//}}AFX_DATA //
	Overrides 	//
	ClassWizard generated virtual function overrides 	//{{AFX_VIRTUAL(my_dialog3) 	protected: 	virtual
	void DoDataExchange(CDataExchange* pDX);    // DDX/DDV support 	//}}AFX_VIRTUAL
	protected: 
	 	//
	Generated message map functions 	//{{AFX_MSG(my_dialog3) 	virtual
	void OnOK(); 	virtual
	BOOL OnInitDialog(); 	afx_msg
	void OnCustomdrawSlider1(NMHDR* pNMHDR, LRESULT* pResult); 	//}}AFX_MSG 	DECLARE_MESSAGE_MAP() }; 
	 //{{AFX_INSERT_LOCATION}} //
	Microsoft Visual C++ will insert additional declarations immediately
	before the previous line. 
	 #endif
	//
	!defined(AFX_MY_DIALOG3_H__2A6E7C4F_49DD_4A3E_B6D5_5B84DF2B965D__INCLUDED_)
В классе, кроме перечисленных методов, которые рассматривались в предыдущей модели, объявлены три переменные: одна отвечает за положение слайдера, вторая хранит целочисленное значение параметра, который будет передан в функцию построения модели, и третья относится к переменной поля для отображения значения в окне с идентификатором IDC_EDIT1. На рисунке 53 показана реализация диалога с определением внутреннего диаметра штуцера.
| 
			 Рис. 53. Диалоговое окно для определения параметра модели “штуцера” | 
Фрагмент кода для штуцера в прикладной библиотеке, где производится вызов диалогового окна, передача параметров в функцию проектирования, создание модели и записи результатов, выглядит следующим образом:
	//Для
	задания параметров штуцера //Внутренний
	диаметр int
	diam4; void
	Onpaths  (IPartPtr& part); switch
	( comm ) {  case
	2 : 
	 			
	     
	 EnableTaskAccess(
	0 );        // Закрыть
	доступ
	к
	компасу my_dialog3
	 dlg3;	//
	создаем объект класса дилогового окна 
	 	if
	(dlg3.DoModal()==IDOK) diam4=dlg3.ed1;  		
	 
	 EnableTaskAccess(
	1 );        // Открыть доступ к компасу	 
	 IDocument3DPtr
	Doc3d1( ksGet3dDocument(), false ); Doc3d1->Create(
	false, true ); IPartPtr
	part( Doc3d1->GetPart( pNew_Part ), false ); Onpaths
	 (part); //Имя
	модели part->SetName(_T("Штуцер.m3d")); part->SetStandardComponent(
	true ); Doc3d1->SetFileName(
	_T( "d:\\штуцер.m3d" ) ); Doc3d1->UpdateDocumentParam();
	 
	 Doc3d1->Save(); //Doc3d1->Close(); break;
	
	 }
Метод геометрического построения штуцера подробно прокомментирован в приведенном далее листинге.
	//
	Построение модели по траектории void
	Onpaths  (IPartPtr & part ) 
	 {  //
	Создаем
	эскиз
	1   IEntityPtr
	entitySketch1( part->NewEntity( o3d_sketch ), false );  
	   if
	( entitySketch1 )   {     //
	Получить указатель на интерфейс
	параметров объектов и элементов     //
	Интерфейс
	свойств
	эскиза     ISketchDefinitionPtr
	sketchDefinition( IUnknownPtr( entitySketch1->GetDefinition(),
	false ) );     if
	( sketchDefinition )     {
	// Получим интерфейсы на плоскости 
	       IEntityPtr
	PlaneXOY( part->GetDefaultEntity( o3d_planeXOY ), false );
	//
	Установка параметров эскиза     
	sketchDefinition->SetPlane(
	PlaneXOY ); // Установим плоскость XOY базовой
	для эскиза 
	       //
	Создаем
	эскиз       entitySketch1->Create();      
	entitySketch1->SetHidden(false); 
	       //
	Войти в режим редактирования эскиза       if
	( sketchDefinition->BeginEdit()
	)       { ////////////////////////////////// //
	подготавливаем изображение эскиза Circle(0,0,diam4,1); 	 //////////////////////////////////////         //
	Выйти из режима редактирования эскиза        
	sketchDefinition->EndEdit();       }     }   } 
	  //
	Создаем
	эскиз
	2   IEntityPtr
	entitySketch2( part->NewEntity( o3d_sketch ), false );  
	   if
	(  entitySketch2 )   {     //
	Получить указатель на интерфейс
	параметров объектов и элементов     //
	Интерфейс
	свойств
	эскиза     ISketchDefinitionPtr
	sketchDefinition( IUnknownPtr( entitySketch2->GetDefinition(),
	false ) );     if
	( sketchDefinition )     {       //
	Получаем интерфейсы на плоскости 
	       
	 	
	 IEntityPtr
	PlaneXOZ( part->GetDefaultEntity( o3d_planeXOZ ), false );  
	sketchDefinition->SetPlane(
	PlaneXOZ ); // Установим
	плоскость
	XOZ базовой
	для
	эскиза 
	       //
	Создаем
	эскиз       entitySketch2->Create();      
	entitySketch2->SetHidden(false); 
	       //
	Войти в режим редактирования эскиза       if
	( sketchDefinition->BeginEdit()
	)       { ////////////////////////////////// //
	строим изображение эскиза LineSeg(0,0,0,-200,1); ArcBy3Points(0,-200,-7,-237,-30,-271,1); LineSeg(-30,-271,-136,-377,1); 	 //////////////////////////////////////         //
	Выйти из режима редактирования эскиза        
	sketchDefinition->EndEdit();       }    } }
	//
	интерфейс кинематической операции
	выдавливания IEntityPtr
	Evolution (part->NewEntity( o3d_bossEvolution ),false); if
	(Evolution) { IBossEvolutionDefinitionPtr
	EvolutionDef( IUnknownPtr(Evolution->GetDefinition(),false));   if
	(EvolutionDef)   { //
	устанавливаем
	эскиз            
	EvolutionDef->SetSketch(entitySketch1);             //
	способ выдавливания           	//Тип
	движения сечения по траектории. 			//Значения
	свойства: 			//0-
	образующая переносится параллельно
	самой себе, 			//1-
	образующая при переносе сохраняет
	исходный угол с направляющей, 			//2-
	плоскость образующей выставляется и
	сохраняется ортогональной направляющей.
	
	 
				EvolutionDef->SetSketchShiftType
	(2);             //тонкая
	стенка            
	EvolutionDef->SetThinParam(true,0,5,0);             //
	указатель на колекцию объектов - кривых             //
	для кинематического выдавливания      //
	добавляем объекты - трехмерные кривые
	или эскизы, содержащие кривую 	
	      IEntityCollectionPtr
	entityCollection (IUnknownPtr(EvolutionDef->PathPartArray(),false));            entityCollection->Add
	( entitySketch2 );	           
	Evolution->SetAdvancedColor(
	RGB (204,153,102), // Цвет                        
	                0.2,
	      // Общий свет                        
	                0.8,
	      // Диффузия                        
	                0.8,
	      // Зеркальность                        
	                0.8,
	      // Блеск                        
	                1,
	        // Прозрачность                        
	                0.8
	);     // Излучение 		
	  		   
	 	
	  // создаем операцию...            
	Evolution->Create();   } } //Создаем
	плоскость
	под
	углом IEntityPtr
	entityAnglePlane(part->NewEntity( o3d_planeAngle),false); 
	  if
	(entityAnglePlane)  {  //
	интерфейс свойств плоскости под углом
	к другой плоскости 
	IPlaneAngleDefinitionPtr
	planeAngleDef (
	IUnknownPtr(entityAnglePlane->GetDefinition(),false));    if
	(planeAngleDef)    {    
	planeAngleDef->SetAngle
	(135);  // угол
	наклона
	к
	базовой
	плоскости 	IEntityPtr
	PlaneXOY( part->GetDefaultEntity( o3d_planeXOY ), false );     IEntityPtr
	axisOY( part->GetDefaultEntity( o3d_axisOY ), false );  
	    
	planeAngleDef->SetPlane(PlaneXOY);
	   // базовая
	плоскость 	planeAngleDef->SetAxis(
	axisOY ); // базовая
	ось    
	entityAnglePlane->Create();
	          // создать плоскость под углом    }  }
	
	   //
	Создадим смещенную плоскость ( для
	создания на ней эскиза )   IEntityPtr
	entityPlaneOffset( part->NewEntity( o3d_planeOffset ), false  );   
	   
	if(entityPlaneOffset)    { 	
	  // Интерфейс свойств смещенной плоскости    
	IPlaneOffsetDefinitionPtr
	planeOffsetDef( IUnknownPtr( entityPlaneOffset->GetDefinition(),
	false  ) );     if
	( planeOffsetDef
	) 
	 	{      //
	Установка параметров смещенной плоскости    	
	 planeOffsetDef->SetOffset(362.745779);       planeOffsetDef->SetPlane(
	 entityAnglePlane ); 	
	 planeOffsetDef->SetDirection(
	false
	); // Направление смещения от базовой
	плоскости ( TRUE
	- прямое направление, FALSE
	- обратное направление )      
	entityPlaneOffset->SetName(
	_bstr_t(
	_T("Вспомогательная
	плоскость №1") ) ); // Имя для смещенной
	плоскости      
	entityPlaneOffset->SetHidden(
	true
	);   // Скрыть смещенную плоскость      //
	Создать смещенную плоскость      
	entityPlaneOffset->Create();
	    
	 	}    
	    } 
	 //
	Создаем новый эскиз (эскиз 3)   IEntityPtr
	entitySketch3(
	part->NewEntity(
	o3d_sketch
	), false
	);  
	     if
	(entitySketch3) 	{        ISketchDefinitionPtr
	sketchDefinition( IUnknownPtr( entitySketch3->GetDefinition(),
	false ) );        if
	(sketchDefinition) 	
	  { 	//
	указываем плоскость,         //
	на которой строится эскиз 
	        
	sketchDefinition->SetPlane(entityPlaneOffset);         
	entitySketch3->Create();     
	 		
	//
	Войти в режим редактирования эскиза         if
	( sketchDefinition->BeginEdit()
	)         {         //
	Введем новый эскиз 
	        
	Circle(-170.415,0,diam4+1,1);        
	Circle(-170.415,0,diam4+8,1);         //
	Выйти из режима редактирования эскиза          
	sketchDefinition->EndEdit(); 		} 	
	  } 	} //операция
	выдавливание     IEntityPtr
	entityExtrusion( part->NewEntity( o3d_baseExtrusion  ), false  );
	
	     if
	( entityExtrusion ) 
	             {
	 IBaseExtrusionDefinitionPtr
	ExtrusionDef( IUnknownPtr( entityExtrusion->GetDefinition(),
	false  ) );                      
	if
	( ExtrusionDef ) 
	                       {      //
	Установка параметров операции
	выдавливания     
	ExtrusionDef->SetDirectionType(
	dtNormal );  
	      //
	Изменить параметры выдавливания в
	одном направлении     
	ExtrusionDef->SetSideParam(
	true, etBlind,100, 5, false );          
	      //
	Изменить параметры тонкой стенки     
	ExtrusionDef->SetThinParam(
	false, 0, 0, 0 ); // тонкая стенка отсутствует 	
	// Эскиз операции выдавливания    
	ExtrusionDef->SetSketch(
	entitySketch3
	);          
	    
	entityExtrusion->SetAdvancedColor(
	RGB (204,153,51), // Цвет                        
	                0.2,
	      // Общий
	свет                        
	                0.8,
	      // Диффузия                        
	                0.8,
	      // Зеркальность                        
	                0.8,
	      // Блеск                        
	                1,
	        // Прозрачность                        
	                0.8
	);     // Излучение 					    //
	создать операцию   
	entityExtrusion->Create();
	                  
	                       }                     } 
	 //
	Создаем
	 эскиз
	(эскиз
	4)   IEntityPtr
	entitySketch4( part->NewEntity( o3d_sketch ), false );  
	     if
	(entitySketch4) 	{        ISketchDefinitionPtr
	sketchDefinition( IUnknownPtr( entitySketch4->GetDefinition(),
	false ) );        if
	(sketchDefinition) 	
	  { 		//
	устанавливаем плоскость,         //
	на которой создается эскиз         IEntityPtr
	PlaneXOY( part->GetDefaultEntity( o3d_planeXOY ), false );        
	sketchDefinition->SetPlane(PlaneXOY);          entitySketch4->Create();     
	 		
	//
	Войти в режим редактирования эскиза         if
	( sketchDefinition->BeginEdit()
	)         {         //
	Проектируем  новый эскиз из примитивов         Circle(0,
	0, diam4, 1);         Circle(0,
	0, diam4+2, 1); 
	         //
	Выйти из режима редактирования эскиза          
	sketchDefinition->EndEdit(); 		}  
	 	
	  } 	} //
	Производим вырез выдавливанием	 	IEntityPtr
	CutExtrusion1( part->NewEntity( o3d_cutExtrusion ), false  ); 
	           if
	( CutExtrusion1 ) 
	                {
	//
	Интерфейс параметров вырезанного
	элемента выдавливания    
	ICutExtrusionDefinitionPtr
	cutExtrusionDefinition( IUnknownPtr( CutExtrusion1->GetDefinition(),
	false  ) );                if
	( cutExtrusionDefinition ) 
	                 {             //
	Установка параметров операции
	выдавливания            
	cutExtrusionDefinition->SetDirectionType(
	dtReverse );   
	             //
	Изменить параметры выдавливания в
	одном направлении            
	cutExtrusionDefinition->SetSideParam(
	false,etBlind,120,0,false );  
	             //
	Изменить
	параметры
	тонкой
	стенки            
	cutExtrusionDefinition->SetSketch(
	entitySketch4 );          // Эскиз
	операции
	выдавливания            
	CutExtrusion1->SetAdvancedColor(
	RGB (204,102,0),  // Цвет                        
	                0.2,
	      // Общий
	свет                        
	                0.8,
	      // Диффузия                        
	                0.8,
	      // Зеркальность                        
	                0.8,
	      // Блеск                        
	                1,
	        // Прозрачность                        
	                0.8
	);     // Излучение 						           
	CutExtrusion1->Create();
	          
	                       }                     } //
	Создаем
	 эскиз
	(эскиз
	5)   IEntityPtr
	entitySketch5( part->NewEntity( o3d_sketch ), false );  
	     if
	(entitySketch5) 	{        ISketchDefinitionPtr
	sketchDefinition( IUnknownPtr( entitySketch5->GetDefinition(),
	false ) );        if
	(sketchDefinition) 	
	  { 		//
	устанавливаем плоскость,         //
	на которой создается эскиз        
	        
	sketchDefinition->SetPlane(entityPlaneOffset);         
	entitySketch5->Create();     
	 		
	//
	Войти в режим редактирования эскиза         if
	( sketchDefinition->BeginEdit()
	)         {         //
	Введем новый эскиз 
	        
	Circle(-170.415,
	0, diam4, 1);         //
	Выйти из режима редактирования эскиза          
	sketchDefinition->EndEdit(); 		} 	
	  } 	} //
	Производим вырез выдавливанием 	IEntityPtr
	CutExtrusion2(
	part->NewEntity(
	o3d_cutExtrusion
	), false
	 ); 
	           if
	( CutExtrusion2
	) 
	                { //
	Интерфейс параметров вырезанного
	элемента выдавливания    
	ICutExtrusionDefinitionPtr
	cutExtrusionDefinition( IUnknownPtr( CutExtrusion2->GetDefinition(),
	false  ) );                if
	( cutExtrusionDefinition ) 
	                 {
	//
	Установка параметров операции
	выдавливания            
	cutExtrusionDefinition->SetDirectionType(
	dtReverse );   
	             //
	Изменить параметры выдавливания в
	одном направлении            
	cutExtrusionDefinition->SetSideParam(
	false,etBlind,120,0,false );  
	             //
	Изменить
	параметры
	тонкой
	стенки            
	cutExtrusionDefinition->SetSketch(
	entitySketch5 );          // Эскиз
	операции
	выдавливания            
	CutExtrusion2->SetAdvancedColor(
	RGB (204,102,51),  // Цвет                        
	                0.2,
	      // Общий
	свет                        
	                0.8,
	      // Диффузия                        
	                0.8,
	      // Зеркальность                        
	                0.8,
	      // Блеск                        
	                1,
	        // Прозрачность                        
	                0.8
	);     // Излучение 						 //
	Производим вырез выдавливанием           
	CutExtrusion2->Create();                        
		                  }         } }
Выполнение функции приведет к построению модели, которая приведена на рисунке 54. Для того, чтобы проследить последовательность выполнения операций в дереве моделей, в библиотеке был отключен метод построения обекта как стандартный компонент.
| 
			 Рис. 54. Программная реализация построения модели ”штуцер” | 
Код, выполняющий аналогичные операции, выполненный на языке Object Pascal в среде Borland Delphi 7.0 представлен далее.
 
	procedure
	PartPaint (var d:real); var iKompasObject:
	KompasObject; iDocument3D:
	ksDocument3D; doc:
	ksDocument2D; iPart:ksPart; PlaneXOY:
	ksEntity; PlaneXOZ:
	ksEntity; iSketchEntity:
	ksEntity; iSketchDef:
	ksSketchDefinition; iSketch1Entity:
	ksEntity; iSketch1Def:
	ksSketchDefinition; iSketch2Entity:
	ksEntity; iSketch2Def:
	ksSketchDefinition; Evolution:
	ksEntity; iBossEvolutionDef:
	ksBossEvolutionDefinition; Collect:
	ksEntityCollection; iOffsetPlaneEntity:
	ksEntity; iOffsetPlaneDef
	: ksPlaneOffsetDefinition; iBaseExtrusionEntity:
	ksEntity; iBaseExtrusionDef:
	ksBaseExtrusionDefinition; entityAnglePlane
	: ksEntity; planeAngleDef
	   : ksPlaneAngleDefinition; axisOY:
	ksEntity; iSketch4Entity:
	ksEntity; iSketch4Def:
	ksSketchDefinition; iCutExtrusion:ksEntity; iCutExtrusionDef
	: ksCutExtrusionDefinition; iSketch5Entity:
	ksEntity; iSketch5Def:
	ksSketchDefinition; iCutExtrusion1:ksEntity; iCutExtrusionDef1
	: ksCutExtrusionDefinition; ColorParam
	: ksColorParam; 
	 Begin 
	 iKompasObject
	:= KompasObject(CreateKompasObject); 
	   if
	iKompasObject <> nil then   begin     iDocument3D
	:= ksDocument3D(iKompasObject.Document3D);     if
	 idocument3d.Create(false,true) then       begin         if
	(iDocument3D <> nil) then           begin 
	             //
	получаем
	указатель
	на
	интерфейс
	детали             iPart
	:= ksPart(iDocument3D.GetPart(pNew_Part));             if
	(iPart <> nil) then             begin                 
	                
	
 
	//
	интерфейс плоскости               PlaneXOY
	:= ksEntity(iPart.GetDefaultEntity(o3d_planeXOY));               PlaneXOZ
	:= ksEntity(iPart.GetDefaultEntity(o3d_planeXOZ));               axisOY
	:= ksEntity(iPart.GetDefaultEntity(o3d_axisOY)); 
	               //
	интерфейс
	эскиза
	(эскиз
	1)               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                      
	doc.ksCircle(0,0,d,1); 
	                    
	end;                     //
	завершение редактирования эскиза                    
	iSketchDef.EndEdit;                   end;                 end;               end; 
	               //
	интерфейс
	эскиза
	(эскиз
	2)               iSketch1Entity
	:= ksEntity(iPart.NewEntity(o3d_sketch));               if
	(iSketch1Entity <> nil) then               begin                 //
	интерфейс
	параметров
	эскиза                 iSketch1Def
	:= ksSketchDefinition(iSketch1Entity.GetDefinition);                 if
	(iSketch1Def <> nil) then                 begin                   if
	(PlaneXOZ <> nil) then                   begin                     //
	устанавливаем плоскость,                     //
	на которой создается эскиз                    
	iSketch1Def.SetPlane(PlaneXOZ);                    
	iSketch1Entity.Create;                     //
	doc - указатель
	на
	интерфейс
	ksDocument2D                     doc
	:= ksDocument2D(iSketch1Def.BeginEdit);                     if
	(doc <> nil) then                     begin                      
	//
	вычерчиваем
	изображение
	эскиза                      
	//
	с помощью методов интерфейса ksDocument2D                      
	doc.ksLineSeg(0,0,0,-200,1);                      
	doc.ksArcBy3Points(0,-200,-7,-237,-30,-271,1);                      
	doc.ksLineSeg(-30,-271,-136,-377,1);                     end;               
	
 
	              	
	   // завершение редактирования эскиза                    
	iSketch1Def.EndEdit;                   end;                 end;               end; 
	     //
	интерфейс кинематической операции
	выдавливания     Evolution
	:= ksEntity(iPart.NewEntity( o3d_bossEvolution ));     if
	Evolution <> nil then       begin         //
	получаем
	definition интерфейса iBossEvolutionDef
	:= ksBossEvolutionDefinition(Evolution.GetDefinition);         if
	iBossEvolutionDef <> nil then           begin             //
	устанавливаем
	эскиз            
	iBossEvolutionDef.SetSketch(iSketchEntity);             //
	способ
	выдавливания            
	iBossEvolutionDef.sketchShiftType
	:= 2;             //тонкая
	стенка            
	iBossEvolutionDef.SetThinParam(true,0,5,0);             //
	указатель на колекцию объектов - кривых             //
	для кинематического выдавливания 
	Collect
	:= ksEntityCollection(iBossEvolutionDef.PathPartArray);             //
	добавляем объекты - трехмерные кривые             //
	или эскизы, содержащие кривую            
	Collect.Add(iSketch1Entity);             //
	создаем
	операцию...             Evolution.Create;           end;       end; 
	       //создаем
	поскость
	под
	углом       entityAnglePlane
	:= ksEntity( ipart.NewEntity(o3d_planeAngle) ); 			if
	( entityAnglePlane <> nil ) then         begin           //
	интерфейс свойств плоскости под углом
	к другой плоскости planeAngleDef
	:= ksPlaneAngleDefinition( entityAnglePlane.GetDefinition ); 	if
	( planeAngleDef <> nil ) then             begin               planeAngleDef.Angle
	:= 135;           
	 
	//
	угол
	наклона
	к
	базовой
	плоскости              
	planeAngleDef.SetPlane(PlaneXOY);
	   
	 
	//
	базовая
	плоскость 	planeAngleDef.SetAxis(
	axisOY ); 
	 
	//
	базовая ось		 
	entityAnglePlane.Create; 
	//
	создать плоскость под углом             end;         end; 
	               //
	интерфейс смещенной плоскости 
	iOffsetPlaneEntity
	:= ksEntity(iPart.NewEntity(o3d_planeOffset));               if
	(iOffsetPlaneEntity <> nil) then                 begin
 
	//
	величина, базовая плоскость и другие
	параметры смещения                   
	iOffsetPlaneDef.Offset
	:=362.745779;                   
	iOffsetPlaneDef.SetPlane(entityAnglePlane);                   
	iOffsetPlaneDef.direction
	:= false;                    //
	делаем
	плоскость
	скрытой                   
	iOffsetPlaneEntity.Hidden
	:= false;                    //
	создаем вспомогательную плоскость                   
	iOffsetPlaneEntity.Create;                   end;                 end; 
	               //
	интерфейс
	эскиза
	(эскиз
	3)               iSketch2Entity
	:= ksEntity(iPart.NewEntity(o3d_sketch));               if
	(iSketch2Entity <> nil) then               begin                 //
	интерфейс
	параметров
	эскиза iSketch2Def
	:= ksSketchDefinition(iSketch2Entity.GetDefinition);                 if
	(iSketch2Def <> nil) then                 begin                   if
	(iOffsetPlaneEntity <> nil) then                   begin                     //
	устанавливаем плоскость,                     //
	на которой создается эскиз                    
	iSketch2Def.SetPlane(iOffsetPlaneEntity);                    
	iSketch2Entity.Create;                     //
	doc - указатель
	на
	интерфейс
	ksDocument2D                     doc
	:= ksDocument2D(iSketch2Def.BeginEdit);                     if
	(doc <> nil) then                     begin                      
	//
	вычерчиваем
	изображение
	эскиза                      
	//
	с помощью методов интерфейса ksDocument2D                      
	doc.ksCircle(-170.415,0,d+1,1);                      
	doc.ksCircle(-170.415,0,D+8,1);                    
	end;                     //
	завершение редактирования эскиза                    
	iSketch2Def.EndEdit;                   end;                 end; 
	             //операция
	выдавливание             iBaseExtrusionEntity
	:= 
	 
	ksEntity(iPart.NewEntity(
	o3d_baseExtrusion ));             if
	iBaseExtrusionEntity <> nil then             begin               //
	интерфейс
	свойств
	базовой
	операции
	выдавливания      
	iBaseExtrusionDef
	:= ksBaseExtrusionDefinition 
	(iBaseExtrusionEntity.GetDefinition);               if
	iBaseExtrusionDef <> nil then               begin                
	iBaseExtrusionDef.DirectionType
	:= dtNormal; 
	 
	//
	направление
	выдавливания 
	iBaseExtrusionDef.SetSideParam(
	true{прямое
	направление},
	etBlind{строго
	на
	глубину},
	100, 5, false );                
	iBaseExtrusionDef.SetThinParam(
	false, 0, 0, 0 ); 
	 
	//
	тонкая
	стенка
	отсутствует                
	iBaseExtrusionDef.SetSketch(
	iSketch2Entity ); 
	 
	//
	эскиз
	операции
	выдавливания                
	iBaseExtrusionEntity.Create;
	// создать
	операцию               end;
	end; 
	
 
	//
	интерфейс эскиза (эскиз 4)              
	iSketch4Entity
	:= ksEntity(iPart.NewEntity(o3d_sketch));               if
	(iSketch4Entity <> nil) then               begin                 //
	интерфейс
	параметров
	эскиза iSketch4Def
	:= ksSketchDefinition(iSketch4Entity.GetDefinition);                 if
	(iSketch4Def <> nil) then                 begin                   if
	(PlaneXOY <> nil) then                   begin                     //
	устанавливаем плоскость,                     //
	на которой создается эскиз                    
	iSketch4Def.SetPlane(PlaneXOY);                    
	iSketch4Entity.Create;                     //
	doc - указатель
	на
	интерфейс
	ksDocument2D                     doc
	:= ksDocument2D(iSketch4Def.BeginEdit);                     if
	(doc <> nil) then                     begin                      
	//
	вычерчиваем
	изображение
	эскиза                      
	//
	с помощью методов интерфейса ksDocument2D                      
	doc.ksCircle(0,
	0, d, 1);                      
	doc.ksCircle(0,
	0, d+2, 1);                    
	end;                     //
	завершение редактирования эскиза                    
	iSketch4Def.EndEdit;                   end;                 end;               end; 
	 
	 
	               //
	интерфейс
	операции
	вырезания
	выдавливанием iCutExtrusion
	:= ksEntity(iPart.NewEntity(o3d_cutExtrusion));               if
	(iCutExtrusion <> nil) then               begin                 //
	интерфейс
	параметров
	dвыдавливание                 iCutExtrusionDef
	:=                
	ksCutExtrusionDefinition(iCutExtrusion.GetDefinition);                 if
	(iCutExtrusionDef <> nil) then                 begin                   //
	настройка
	параметров                  
	iCutExtrusionDef.SetSketch(iSketch4Entity);                   //
	направление                  
	iCutExtrusionDef.directionType
	:= dtReverse;                   //
	величина
	выдавливания                  
	iCutExtrusionDef.SetSideParam 
	(false,
	etBlind, 120, 0, false);                   //
	создаем
	вырез                  
	iCutExtrusion.Create;                 end;               end; 
	               //
	интерфейс
	эскиза
	(эскиз
	5)               iSketch5Entity
	:= ksEntity(iPart.NewEntity(o3d_sketch));               if
	(iSketch5Entity <> nil) then               begin
 
	//
	интерфейс
	параметров
	эскиза iSketch5Def
	:= ksSketchDefinition(iSketch5Entity.GetDefinition);                 if
	(iSketch5Def <> nil) then                 begin                   if
	(iOffsetPlaneEntity <> nil) then                   begin                     //
	устанавливаем плоскость,                     //
	на которой создается эскиз                    
	iSketch5Def.SetPlane(iOffsetPlaneEntity);                    
	iSketch5Entity.Create;                     //
	doc - указатель
	на
	интерфейс
	ksDocument2D                     doc
	:= ksDocument2D(iSketch5Def.BeginEdit);                     if
	(doc <> nil) then                     begin                      
	//
	вычерчиваем
	изображение
	эскиза                      
	//
	с помощью методов интерфейса ksDocument2D                      
	doc.ksCircle(-170.415,
	0, d, 1);                    
	end;                     //
	завершение редактирования эскиза                    
	iSketch5Def.EndEdit;                   end;                 end;               end;               end; 
	 
	               //
	интерфейс операции вырезания выдавливанием iCutExtrusion1
	:= ksEntity(iPart.NewEntity(o3d_cutExtrusion));               if
	(iCutExtrusion1 <> nil) then               begin                 //
	интерфейс
	параметров
	dвыдавливание                 iCutExtrusionDef1
	:=                
	ksCutExtrusionDefinition(iCutExtrusion1.GetDefinition);                 if
	(iCutExtrusionDef1 <> nil) then                 begin                   //
	настройка
	параметров                  
	iCutExtrusionDef1.SetSketch(iSketch5Entity);                   //
	направление                  
	iCutExtrusionDef1.directionType
	:= dtReverse;                   //
	величина
	выдавливания                  
	iCutExtrusionDef1.SetSideParam 
	(false,
	etBlind, 120, 0, false);                   //
	создаем
	вырез                  
	iCutExtrusion1.Create;                 end;               end; 
	              
	//установим
	собственный цвет для детали              
	iPart.useColor:=0;               //создаем
	переменную параметров цвета детали              
	ColorParam:=ksColorParam(iPart.ColorParam);               //задаем
	цет              
	ColorParam.color:=$00788845;               //задаем
	параметры цвета детали              
	iPart.SetAdvancedColor(ColorParam.color,ColorParam.ambient,               
	
 
	
	 ColorParam.diffuse,ColorParam.specularity,ColorParam.shininess,              
	ColorParam.transparency,ColorParam.emission);               //обновляем
	деталь               iPart.Update; 
	               //сохранение
	файла               If
	 iDocument3D.IsDetail then               begin                
	iDocument3D.fileName:='c:\shtuc.m3d';                
	iDocument3D.UpdateDocumentParam;                 iDocument3D.Save;               end; 
	              //от
	детали и выше             end;           end;       end;   end; end; 
	 
	 
	 
	 
	 procedure
	TForm1.Button1Click(Sender: TObject); var   d:real; begin 
	   d:=TrackBar1.Position-2;   PartPaint(d); 
	 end; 
	 
	 
	 
	 
	 
	 procedure
	TForm1.TrackBar1Change(Sender: TObject); begin Edit1.Text:=IntToStr(TrackBar1.Position); end; 
	 
	 end.
 
 
	IDD_DIALOG4
	DIALOGEX 0, 0, 374, 198 STYLE
	DS_MODALFRAME | WS_POPUP | WS_CAPTION CAPTION
	"Определение параметров детали
	(Трубка гофрированная)" FONT
	8, "MS Sans Serif" 
	 
	 BEGIN    
	     DEFPUSHBUTTON
	  "Построить",IDOK,155,176,65,14     GROUPBOX
	       "Размерные
	характеристики",IDC_STATIC,7,7,360,166     GROUPBOX
	       "Вид
	модели",IDC_STATIC,284,15,77,153     CONTROL
	        "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH
	| 
	                     TBS_NOTICKS
	| WS_TABSTOP,13,46,266,15     CONTROL
	        "Slider2",IDC_SLIDER2,"msctls_trackbar32",TBS_BOTH
	| 
	                     TBS_NOTICKS
	| WS_TABSTOP,13,92,266,15     CONTROL
	        "Slider3",IDC_SLIDER3,"msctls_trackbar32",TBS_BOTH
	| 
	                     TBS_NOTICKS
	| WS_TABSTOP,13,138,266,15     LTEXT
	          "Диаметр
	наружной
	гладкой
	части
	трубки,
	мм",IDC_STATIC,                    
	36,28,156,8     LTEXT
	          "Длина гладкой части трубки
	(на одну сторону), мм",                    
	IDC_STATIC,36,75,172,8 
	LTEXT
	          "Число сегментов гофрированной
	трубки, шт",IDC_STATIC,36,     122,152,8     EDITTEXT
	       IDC_EDIT1,211,24,40,14,ES_CENTER | ES_AUTOHSCROLL | 
	                     WS_DISABLED     EDITTEXT
	       IDC_EDIT2,211,72,40,14,ES_CENTER | ES_AUTOHSCROLL | 
	                     WS_DISABLED     EDITTEXT
	       IDC_EDIT3,211,117,40,14,ES_CENTER | ES_AUTOHSCROLL | 
	                     WS_DISABLED     CONTROL
	        7021,IDC_STATIC,"Static",SS_BITMAP,288,22,68,142,                    
	WS_EX_DLGMODALFRAME
	| WS_EX_CLIENTEDGE | 
	                    
	WS_EX_STATICEDGE 
	 END 
	
Проектирование гофрированной трубки не отличается от рассмотренных ранее моделях: интерфейсная часть преставлена диалоговым окном, реализована классом, похожим на предыдущие классы проектирования моделей штуцера и насадки. Фрагмент ресурсного файла представлен на листинге:
	IDD_DIALOG4
	DIALOGEX 0, 0, 374, 198 STYLE
	DS_MODALFRAME | WS_POPUP | WS_CAPTION CAPTION
	"Определение параметров детали
	(Трубка гофрированная)" FONT
	8, "MS Sans Serif" BEGIN     DEFPUSHBUTTON
	  "Построить",IDOK,155,176,65,14     GROUPBOX
	       "Размерные
	характеристики",IDC_STATIC,7,7,360,166     GROUPBOX
	       "Вид
	модели",IDC_STATIC,284,15,77,153     CONTROL
	        "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH
	| 
	                     TBS_NOTICKS
	| WS_TABSTOP,13,46,266,15     CONTROL
	        "Slider2",IDC_SLIDER2,"msctls_trackbar32",TBS_BOTH
	| 
	                     TBS_NOTICKS
	| WS_TABSTOP,13,92,266,15     CONTROL
	        "Slider3",IDC_SLIDER3,"msctls_trackbar32",TBS_BOTH
	| 
	                     TBS_NOTICKS
	| WS_TABSTOP,13,138,266,15     LTEXT
	          "Диаметр
	наружной
	гладкой
	части
	трубки,
	мм",IDC_STATIC,                    
	36,28,156,8     LTEXT
	          "Длина гладкой части трубки
	(на одну сторону), мм",                    
	IDC_STATIC,36,75,172,8     LTEXT
	          "Число сегментов гофрированной
	трубки, шт",IDC_STATIC,36,                    
	122,152,8     EDITTEXT
	       IDC_EDIT1,211,24,40,14,ES_CENTER | ES_AUTOHSCROLL | 
	                     WS_DISABLED     EDITTEXT
	       IDC_EDIT2,211,72,40,14,ES_CENTER | ES_AUTOHSCROLL | 
	                     WS_DISABLED     EDITTEXT
	       IDC_EDIT3,211,117,40,14,ES_CENTER | ES_AUTOHSCROLL | 
	                     WS_DISABLED     CONTROL
	        7021,IDC_STATIC,"Static",SS_BITMAP,288,22,68,142,                    
	WS_EX_DLGMODALFRAME
	| WS_EX_CLIENTEDGE | 
	                    
	WS_EX_STATICEDGE END
В спроектированном интерфейсе предусмотрено три управляющих параметра, которые будут востребованы в функции геометрического моделирования объекта: диаметр наружной части, не содержащий гофры, длина части трубки, не содержащей гофры и число сегментов, представляющих собой некоторый рельеф волновой поверхности. На рисунке 55 показан диалог и изменяемыми параметрами, выполняемый в среде Компаc3D V12.
| 
			 
 Рис. 55. Диалоговое окно для определения параметра модели “трубки гофрированной” | 
Фрагмент кода для трубки в прикладной библиотеке, где производится вызов диалогового окна, передача параметров в функцию проектирования, создание модели и записи результатов, выглядит следующим образом:
	//Для
	задания параметров трубки гофрированной //Внутренний
	диаметр int
	diam5; //Длина
	модели int
	hi2; //Число
	узлов int
	pos2; void
	Rotate (IPartPtr& part);    switch
	( comm ) 	
	 { 	
	 case 3: 		
	 { EnableTaskAccess(
	0 );        // Закрыть
	доступ
	к
	компасу my_dialog4
	 dlg4;	//
	создаем объект класса диалогового окна
	if
	(dlg4.DoModal()==IDOK) 	{
	diam5=dlg4.ed1;       hi2=dlg4.ed2;       pos2=dlg4.ed3; 
	 	}
	 		  
	  EnableTaskAccess(
	1 );        // Открыть доступ к компасу	 
	 IDocument3DPtr
	Doc3d1( ksGet3dDocument(), false ); Doc3d1->Create(
	false, true ); IPartPtr
	part( Doc3d1->GetPart( pNew_Part ), false ); Rotate
	 (part); 
	 //Имя
	модели part->SetName(_T("Трубка.m3d")); part->SetStandardComponent(
	true ); Doc3d1->SetFileName(
	_T( "d:\\трубка.m3d"
	) ); Doc3d1->UpdateDocumentParam();
	 
	 Doc3d1->Save(); //Doc3d1->Close(); break;
	//прекратить построение модели         }	
	 
	 }
Главная функция проектирования трубки представлена отдельным листингом с подробными пояснениями по ходу моделирования.
	void
	Rotate(
	IPartPtr
	& part
	) 
	 {
	  
	 //промежуточные
	переменные для построения эскиза: длины
	(l),
	диаметра (d)
	и кол-ва секций (k) 	
	 int
	k=pos2; 	
	 int l=hi2; 	
	 int d=diam5; 	
	 double n; 	 //
	Создаем
	новый эскиз   IEntityPtr
	entitySketch( part->NewEntity(o3d_sketch), false );   if
	( entitySketch
	)   {     //
	Получаем указатель на интерфейс
	параметров объектов и элементов     //
	Интерфейс свойств эскиза     ISketchDefinitionPtr
	sketchDefinition( IUnknownPtr( entitySketch->GetDefinition(),
	false  ) );     if
	( sketchDefinition )     {       //
	Получаем
	интерфейс плоскости 
	       IEntityPtr
	basePlane( part->GetDefaultEntity( o3d_planeXOZ ), false  );       //
	Установка параметров эскиза       sketchDefinition->SetPlane(
	basePlane ); // Установим плоскость базовой
	для эскиза  
	       //
	Создаем
	эскиз       entitySketch->Create();
	      //
	Войти в режим редактирования эскиза       if
	( sketchDefinition->BeginEdit() )       { 		
	// строим изображение эскиза                      
	for
	(int i=1;i<=k;i++)                       {
	
	                         n=i*-6.5-l;                        
	ArcByPoint(d,2.5+n,2.5,d,0+n,d,5+n,1,1);                        
	ArcByPoint(d-3,2.5+n,2.5,d-3,0+n,d-3,5+n,1,1);                        
	LineSeg(d,n+5,d,n+6.5,1);                        
	LineSeg(d-3,n+5,d-3,n+6.5,1); 		
	    }                        
	LineSeg(d-3,n,d-3,n-l,1);                        
	LineSeg(d-3,0,d-3,-l,1);                        
	LineSeg(d-3,n-l,d,n-l,1);                        
	LineSeg(d,n-l,d,n,1);                        
	LineSeg(d-3,0,d,0,1);                        
	LineSeg(d,0,d,-l,1);                        
	LineSeg(0,0,0,100,3); 		 		 		//
	Выйти из режима редактирования эскиза        
	sketchDefinition->EndEdit();       }       //
	Операции
	вращения       IEntityPtr
	entityRotate( part->NewEntity( o3d_baseRotated ), false );       if
	( entityRotate ) 
	       {         
	         //
	Интерфейс базовой операции вращения        
	IBaseRotatedDefinitionPtr
	baseRotatedDefinition( IUnknownPtr( entityRotate->GetDefinition(),
	false/*AddRef*/ ) ); 
	         if
	( baseRotatedDefinition ) 
	         {          
	baseRotatedDefinition->SetToroidShapeType(
	false );     
	          
	//baseRotatedDefinition->SetDirectionType(
	dtBoth );      
	           //
	Изменить
	параметры
	тонкой
	стенки          
	baseRotatedDefinition->SetThinParam(false,
	dtNormal, 1, 1);           
	           //
	Изменить
	параметры
	выдавливания
	в
	одном
	направлении          
	baseRotatedDefinition->SetSideParam(true,
	360);             
	                        
	          
	baseRotatedDefinition->SetSketch(
	entitySketch );                                                     
	               
	           //
	Создать
	операцию
	
	 		
	  entityRotate->SetAdvancedColor( RGB (102,102,51), // Цвет                        
	                0.2,
	      // Общий свет                        
	                0.8,
	      // Диффузия                        
	                0.8,
	      // Зеркальность                        
	                0.8,
	      // Блеск                        
	                1,
	        // Прозрачность                        
	                0.8
	);     // Излучение          
	entityRotate->Create();
	   
	                        
	    
	         }       }     }   }
	 
	 
	
	//интерфейс
	фаски №1 //
	Формирует массив объектов и возвращает
	указатель на его интерфейс - массив
	граней компонента        
	 IEntityCollectionPtr
	entityCollection1( part->EntityCollection( o3d_edge ), false  );  if
	((bool)entityCollection1 && 
	      
	entityCollection1->SelectByPoint(
	d, 0, -1*(n-l) ) && 
	 //
	Выбор
	по
	точке       entityCollection1->GetCount()
	)                  
	 //Получить
	количество элементов в массиве             { //Фаска
	
	     IEntityPtr
	entityChamfer( part->NewEntity( o3d_chamfer ), false );               if
	( entityChamfer ) 
	               {                  
	  //
	Получить указатель на интерфейс
	параметров объектов и элементов                
	IChamferDefinitionPtr
	chamferDefinition( IUnknownPtr( entityChamfer->GetDefinition(),
	false) );                 if
	( chamferDefinition ) 
	                 {  //
	Установка
	параметров
	фаски                  
	chamferDefinition->SetTangent(
	false );   
	 //
	Продолжить
	по
	касательной                  
	chamferDefinition->SetChamferParam(
	false, 
	 //
	Признак направления фаски                        
	                              2,
	  
	 //
	Размер первого катета фаски 
	                        
	                              2
	); 
	 //
	Размер
	второго
	катета
	фаски                  
	IEntityCollectionPtr
	arrayChamferDefinition( chamferDefinition->Array(), false); 
	 //
	Динамический массив объектов  
	    if
	( arrayChamferDefinition ) 
	                   { //
	Получение
	граней
	для
	фаски
	
	    for
	( int i = 0, count = entityCollection1->GetCount(); i < count;
	i++ ) 
	 					{   IEntityPtr
	ePtr (entityCollection1->GetByIndex( i ), false);                    
	arrayChamferDefinition->Add(
	ePtr );                     } entityChamfer->SetAdvancedColor(
	RGB (255,102,51), // Цвет                        
	                0.2,
	      // Общий свет                        
	                0.8,
	      // Диффузия                        
	                0.8,
	      // Зеркальность                        
	                0.8,
	      // Блеск                        
	                1,
	        // Прозрачность                        
	                0.8
	);     // Излучение                        
	//
	Создание фаски                    
	entityChamfer->Create();                   
	                   }                 }               }             }
	//интерфейс
	фаски №2 //
	Формирует массив объектов и возвращает
	указатель на его интерфейс - массив
	граней компонента        
	 IEntityCollectionPtr
	entityCollection2( part->EntityCollection( o3d_edge ), false  ); if
	( (bool)entityCollection2 && 
	 entityCollection2->SelectByPoint(
	d, 0, 0 ) && 
	 //
	Выбор
	по
	точке 
	entityCollection2->GetCount()
	)                  
	 //Получить
	количество элементов в массиве             { //
	Фаска
	
	 IEntityPtr
	entityChamfer( part->NewEntity( o3d_chamfer ), false );               if
	( entityChamfer ) 
	               { //
	Получить указатель на интерфейс
	параметров объектов и элементов  IChamferDefinitionPtr
	chamferDefinition( IUnknownPtr( entityChamfer->GetDefinition(),
	false) );                 if
	( chamferDefinition ) 
	                 { //
	Установка
	параметров
	фаски  chamferDefinition->SetTangent(
	false );   
	 //
	Продолжить
	по
	касательной chamferDefinition->SetChamferParam(
	false, 
	 //
	Признак направления фаски                        
	                             2,
	  
	 //
	Размер первого катета фаски 
	                        
	                              2);
	
	 //
	Размер
	второго
	катета
	фаски  IEntityCollectionPtr
	arrayChamferDefinition( chamferDefinition->Array(), false); 
	 //
	Динамический массив объектов  
	                   if
	(arrayChamferDefinition ) 
	                   { //
	Получение
	граней
	для
	фаски
	
	                     for
	( int i = 0, count = entityCollection2->GetCount(); i < count;
	i++ ) 
	 					{ IEntityPtr
	ePtr (entityCollection2->GetByIndex( i ), false);                      
	arrayChamferDefinition->Add(
	ePtr );                     } entityChamfer->SetAdvancedColor(
	RGB (255,102,51), // Цвет                        
	                0.2,
	      // Общий свет                        
	                0.8,
	      // Диффузия                        
	                0.8,
	      // Зеркальность                        
	                0.8,
	      // Блеск                        
	                1,
	        // Прозрачность                        
	                0.8
	);     // Излучение                        
	//
	Создание фаски                    
	entityChamfer->Create();                   
	                   }                 }               }             } 
	 } 
	
Соответствующий код на Object Pascal представлен в следующем листинге:
 
	procedure
	PartPaint(var d:real {диаметр внешний}; l:real {длина
	гладкой части}; k:integer {количество звеньев
	гофры}); var iKompasObject:
	KompasObject; iDocument3D:
	ksDocument3D; doc:
	ksDocument2D; iPart:ksPart; PlaneXOZ:
	ksEntity; iSketchEntity:
	ksEntity; iSketchDef:
	ksSketchDefinition; i:integer; n:real; iBaseRotatedEntity:
	ksEntity; iBaseRotatedDef
	: ksBaseRotatedDefinition; iEntityCollection
	: ksEntityCollection; iChamferEntity
	: ksEntity; iEntityArray
	: ksEntityCollection; iChamferDef
	: ksChamferDefinition; 
	 Begin 
	 iKompasObject
	:= KompasObject(CreateKompasObject); 
	   if
	iKompasObject <> nil then   begin     iDocument3D
	:= ksDocument3D(iKompasObject.Document3D);     if
	 idocument3d.Create(false,true) then       begin         if
	(iDocument3D <> nil) then           begin 
	             //
	получаем
	указатель
	на
	интерфейс
	детали             iPart
	:= ksPart(iDocument3D.GetPart(pNew_Part));             if
	(iPart <> nil) then             begin 
	               //
	интерфейс
	плоскости               PlaneXOZ
	:= ksEntity(iPart.GetDefaultEntity(o3d_planeXOZ)); 
	               //
	интерфейс
	эскиза
	(эскиз
	1)               iSketchEntity
	:= ksEntity(iPart.NewEntity(o3d_sketch));               if
	(iSketchEntity <> nil) then               begin                 //
	интерфейс
	параметров
	эскиза                 iSketchDef
	:= ksSketchDefinition(iSketchEntity.GetDefinition);                 if
	(iSketchDef <> nil) then                 begin                   if
	(PlaneXOZ <> nil) then                   begin                     //
	устанавливаем плоскость,                     //
	на которой создается эскиз                    
	iSketchDef.SetPlane(PlaneXOZ);                    
	iSketchEntity.Create;
 
	//
	doc - указатель на интерфейс ksDocument2D                     doc
	:= ksDocument2D(iSketchDef.BeginEdit);                     if
	(doc <> nil) then                    
	begin                      
	//
	вычерчиваем изображение эскиза                      
	//
	с
	помощью
	методов
	интерфейса
	ksDocument2D                       for
	i:=1 to k do                       begin                         n:=i*-6.5-l;                        
	doc.ksArcByPoint(d,2.5+n,2.5,d,0+n,d,5+n,1,1); doc.ksArcByPoint(d-3,2.5+n,2.5,d-3,0+n,d-3,5+n,1,1);                        
	doc.ksLineSeg(d,n+5,d,n+6.5,1);                        
	doc.ksLineSeg(d-3,n+5,d-3,n+6.5,1);                       end;                        
	doc.ksLineSeg(d-3,n,d-3,n-l,1);                        
	doc.ksLineSeg(d-3,0,d-3,-l,1);                        
	doc.ksLineSeg(d-3,n-l,d,n-l,1);                        
	doc.ksLineSeg(d,n-l,d,n,1);                        
	doc.ksLineSeg(d-3,0,d,0,1);                        
	doc.ksLineSeg(d,0,d,-l,1);                        
	doc.ksLineSeg(0,0,0,100,3);                    
	end;                     //
	завершение редактирования эскиза                    
	iSketchDef.EndEdit;                   end;                 end;               end; 
	             //
	интерфейс
	базовой
	операции
	вращения             iBaseRotatedEntity
	:= ksEntity(iPart.NewEntity(o3d_baseRotated));             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; 
	 
	             //интерфейс
	фаски             iEntityCollection:=
	
	 
	ksEntityCollection(iPart.EntityCollection(
	o3d_edge ));             if
	(iEntityCollection <> nil) and            
	(iEntityCollection.SelectByPoint(d,
	0, -1*(n-l))) and            
	(iEntityCollection.GetCount
	> 0 ) then             begin               
	
 
	iChamferEntity
	:= ksEntity(iPart.NewEntity( o3d_chamfer ));               if
	iChamferEntity <> nil then               begin iChamferDef
	:= ksChamferDefinition(iChamferEntity.GetDefinition);                 if
	iChamferDef <> nil then                 begin                  
	iChamferDef.Tangent
	:= false;                  
	iChamferDef.SetChamferParam(
	false, 2, 2); 
	iEntityArray:=
	ksEntityCollection( iChamferDef.Array_ ); // динамический
	массив
	объектов                   if
	iEntityArray <> nil then                   begin 
	                    
	iEntityArray.Add(
	iEntityCollection.GetByIndex(0) );                    
	iChamferEntity.Create; 
	                   end;                 end;               end;             end; 
	 
	             //интерфейс
	фаски
	2             iEntityCollection:=
	
	 
	ksEntityCollection(iPart.EntityCollection(
	o3d_edge ));             if
	(iEntityCollection <> nil) and            
	(iEntityCollection.SelectByPoint(d,
	0, 0)) and            
	(iEntityCollection.GetCount
	> 0 ) then             begin               iChamferEntity
	:= ksEntity(iPart.NewEntity( o3d_chamfer ));               if
	iChamferEntity <> nil then               begin iChamferDef
	:= ksChamferDefinition(iChamferEntity.GetDefinition);                 if
	iChamferDef <> nil then                 begin                  
	iChamferDef.Tangent
	:= false;                  
	iChamferDef.SetChamferParam(
	false, 2, 2); 
	iEntityArray:=
	ksEntityCollection( iChamferDef.Array_ ); // динамический
	массив
	объектов                   if
	iEntityArray <> nil then                   begin 
	                    
	iEntityArray.Add(
	iEntityCollection.GetByIndex(0) );                    
	iChamferEntity.Create; 
	                   end;                 end;               end;             end; 
	
 
	           
	 
	 //сохранение
	файла             If
	 iDocument3D.IsDetail then             begin              
	iDocument3D.fileName:='c:\gofr.m3d';              
	iDocument3D.UpdateDocumentParam;               iDocument3D.Save;             end; 
	              //от
	детали и выше             end;           end;       end;   end; end; 
	 
	 
	 
	 
	 procedure
	TForm1.Button1Click(Sender: TObject); var   d:real
	{диаметр
	внешний};
	l:real {длина
	гладкой
	части};
	k:integer {количество
	звеньев
	гофры}; begin 
	   d:=TrackBar1.Position;   l:=TrackBar2.Position;;   k:=TrackBar3.Position;   PartPaint(d,l,k); 
	 end; 
	 
	 
	 procedure
	TForm1.TrackBar1Change(Sender: TObject); begin Edit1.Text:=IntToStr(TrackBar1.Position); end; 
	 
	 
	 procedure
	TForm1.TrackBar2Change(Sender: TObject); begin Edit2.Text:=IntToStr(TrackBar2.Position); end; 
	 
	 
	 procedure
	TForm1.TrackBar3Change(Sender: TObject); begin Edit3.Text:=IntToStr(TrackBar3.Position); end; 
	 
	 
	 end.
Выполнение функции приведет к построению модели, которая приведена на рисунке 56. Для того, чтобы проследить последовательность выполнения операций в дереве моделей, в библиотеке был отключен метод построения обекта как стандартный компонент.
| 
			 
 Рис. 56. Программная реализация построения модели ”трубка гофрированная” | 
Сборочный узел содержит вышеперечисленные модели с управляемыми параметрами. Для получения требуемой реализации функции по построению геометрии рассмотренных моделей имеют входящие параметры, а интерфейсная часть для сборки имеет дополнительный элемент выбора, который отвечает за тип исполнения компонентов, реализованный посредствов выпадающего списка (имеет идентификатор IDC_COMBO1).
Фрагмент реализации рассматриваемого интерфейса содержится в ресурсном файле и выглядит следующим образом:
 
	IDD_DIALOG5
	DIALOGEX 0, 0, 293, 178 STYLE
	DS_MODALFRAME | WS_POPUP | WS_CAPTION CAPTION
	"Сборочная
	модель" FONT
	8, "MS Sans Serif" BEGIN     DEFPUSHBUTTON
	  "Построить",IDOK,98,157,92,14     GROUPBOX
	       "Размерные
	характеристики",IDC_STATIC,7,7,279,145     LTEXT
	          "Диаметр
	трубопровода,
	мм",IDC_STATIC,20,37,95,8     EDITTEXT
	       IDC_EDIT1,133,35,40,14,ES_CENTER | ES_AUTOHSCROLL | 
	                     WS_DISABLED     CONTROL
	        "Slider1",IDC_SLIDER1,"msctls_trackbar32",TBS_BOTH
	| 
	                     TBS_NOTICKS
	| WS_TABSTOP,15,64,185,15     GROUPBOX
	       "Вид
	модели",IDC_STATIC,202,14,80,128     LTEXT
	          "Исполнение
	трубопровода",IDC_STATIC,20,93,91,8     COMBOBOX
	       IDC_COMBO1,21,115,122,53,CBS_DROPDOWN | CBS_SORT | 
	                     WS_VSCROLL
	| WS_TABSTOP     CONTROL
	        7024,IDC_STATIC,"Static",SS_BITMAP,205,26,71,111,                    
	WS_EX_DLGMODALFRAME
	| WS_EX_CLIENTEDGE | 
	                    
	WS_EX_STATICEDGE END
Диалоговое окно по управлению сборкой в системе Компас 3D представлено на рисунке 57.
| 
			 Рис. 57. Диалог построения сборочного узла | 
Класс, содержащий компоненты интерфейса, представлен на листинге
	#include
	"stdafx.h" #include
	"my_dialog5.h" #ifdef
	_DEBUG #define
	new DEBUG_NEW #undef
	THIS_FILE static
	char THIS_FILE[] = __FILE__; #endif //Значение
	значение внутреннего диаметра #define
	min1
	 30 #define
	max1  80 //
	my_dialog5 dialog my_dialog5::my_dialog5(CWnd*
	pParent /*=NULL*/) 	:
	CDialog(my_dialog5::IDD, pParent) {} void
	my_dialog5::DoDataExchange(CDataExchange* pDX) { 	CDialog::DoDataExchange(pDX); 	//{{AFX_DATA_MAP(my_dialog5) 	DDX_Control(pDX,
	IDC_COMBO1, m_Variable); 	DDX_Control(pDX,
	IDC_SLIDER1, mSlider1); 	DDX_Text(pDX,
	IDC_EDIT1, ed1); } BEGIN_MESSAGE_MAP(my_dialog5,
	CDialog) 	ON_NOTIFY(NM_CUSTOMDRAW,
	IDC_SLIDER1, OnCustomdrawSlider1) END_MESSAGE_MAP() //
	my_dialog5 message handlers 
	 BOOL
	my_dialog5::OnInitDialog() 
	 { 	CDialog::OnInitDialog(); //Определеяем
	максимум и минимум бегунка №1 и
	устанавливаем значения mSlider1.SetRangeMin(min1,TRUE);			 mSlider1.SetRangeMax(max1,TRUE);	
	   		 mSlider1.SetRange(min1,
	max1, TRUE); //Построить
	в заданной конфигурации m_Variable.AddString(_T("Исполнение
	№1")); 
	 m_Variable.AddString(_T("Исполнение
	№2")); m_Variable.AddString(_T("Исполнение
	№3")); m_Variable.SetCurSel(0); m_Variable.SetFocus(); 	return
	TRUE;  
	 } void
	my_dialog5::OnCustomdrawSlider1(NMHDR* pNMHDR, LRESULT* pResult) 
	 { BYTE
	i=mSlider1.GetPos();	// получить позицию ed1=i; edit1=(CEdit*)GetDlgItem(IDC_EDIT1); UpdateData(FALSE); 	*pResult
	= 0; } void
	my_dialog5::OnOK() 
	 { 	pos1=m_Variable.GetCurSel(); 	CDialog::OnOK(); } 
	
Программное построение сборочного узла с вызовом ключевых функций по геометрическому проектированию, представлено на листинге. Функции приведены только в прототипах, их содержание было рассмотрено ранее. Ключевым моментом в сборке является заведомо установленные параметры по исполнению компонентов, которые встроены в прикладную библиотеки, но при необходимости эти параметры можно выгрузить в файл, а впоследствии считать из него имеющуюся информации или использовать заранее подготовленную БД для подключения к системе.
 
	#include
	"stdafx.h" #include
	<afxdllx.h> #include
	"resource.h" 
	 #include
	"afxwin.h" 
	 #ifdef
	_DEBUG #define
	new DEBUG_NEW #undef
	THIS_FILE static
	char THIS_FILE[] = __FILE__; #endif 
	 //Глобальные
	переменные double
	diam1; double
	diam2; int
	position; 
	 //Для
	задания параметров насадки //Внутренний
	диаметр int
	diam3; //Высота
	модели int
	hi1; //Номер
	исполнения int
	pos1; 
	 ////////////////////////////////////////////////////////////
	
	 
	 //Для
	задания параметров штуцера //Внутренний
	диаметр int
	diam4; 
	 //////////////////////////////////////////////////////////// 
	 //Для
	задания параметров трубки гофрированной //Внутренний
	диаметр int
	diam5; //Длина
	модели int
	hi2; //Число
	узлов int
	pos2;
	//Параметры
	для сборки int
	diam_all; int
	ispolnenie; int
	k;    //количество звеньев гофры int
	l1;   //расстояние между 1 и 2 дет. int
	l2;   //расстояние между 2 и 3 дет. int
	d;    //диаметр  трубопровода в сборке int
	d1;   //диаметр насадки и штуцера int
	h1;   //высота насадки int
	lg;   //длина гладкой части гофры double
	n; 
	 //
	Описания
	используемых
	функций void
	Part1Paint (int &d, int &h1); void
	Part2Paint  (int &d, int &lg,int &k); void
	Part3Paint(int &d); void
	Create3D (int &l1,int &l2); //
	Головная
	функция
	библиотеки void
	WINAPI LIBRARYENTRY( UINT comm ) {switch
	( comm ) 	
	 { 	
	 case 1 : {  EnableTaskAccess(
	0 );        // Закрыть
	доступ
	к
	компасу  my_dialog5
	 dlg5;	// создаем объект класса диалогового
	окна 	if
	(dlg5.DoModal()==IDOK) 	{
	diam_all=dlg5.ed1;     
	       ispolnenie=dlg5.pos1; 	}
	 		  
	 	EnableTaskAccess(
	1 );        // Открыть
	доступ
	к
	компасу	 switch
	(ispolnenie) {    case
	0 : 
	 	
	  { 		
	 lg=130; 		
	 k=50; 		
	 h1=300; 		
	 l1=210; 		
	 l2=675; 		
	 break; 	
	  }    case
	1 : 
	 	
	  { 	
	 	  lg=130; 		
	 k=70; 		
	 h1=335; 		
	 l1=260; 		
	 l2=840; 		
	 break; 	
	  }    case
	2 : 
	 	
	  { 		
	 lg=150; 		
	 k=100; 		
	 h1=360; 		
	 l1=252; 		
	 l2=1082; 		
	 break; 	
	  } 
	 } 
	
	Part1Paint
	(diam_all,h1); Part2Paint
	 (diam_all, lg, k); Part3Paint
	(diam_all); Create3D
	(l1,l2); break;
	//прекратить построение модели  
	 	}
	 
	     } } //Функция
	построения сборочного узла void
	Create3D (int &l1,int &l2) {   //создание
	сборки   IDocument3DPtr
	doc_assembly(ksGet3dDocument(), false);   doc_assembly->Create(false,
	false);   //сохранить
	сборку под именем на логическом разделе   if
	 ( doc_assembly)   {   //
	Имя файла Документа  
	doc_assembly->SetFileName(_T(
	"D:\\Sborka.a3d" ) );   //
	Обновить
	параметры
	Документа  
	doc_assembly->UpdateDocumentParam();   //
	Для каждой детали подготовим свой
	интерфейс   IPartPtr
	part1( doc_assembly->GetPart( pNew_Part ), false );   IPartPtr
	part2( doc_assembly->GetPart( pNew_Part ), false );   IPartPtr
	part3( doc_assembly->GetPart( pNew_Part ), false );   //вставляем
	насадку   //связываем
	добавляемую из файла деталь с
	файлом-источником  
	doc_assembly->SetPartFromFile(_T("D:\\nasadka.m3d"),
	part1, false);   //вводим
	переменную первой детали, задаем ее
	нулевым номером   part1->GetPart(0);    //запустить
	режим редактирования на месте для
	первой детали   part1->BeginEdit();   IPlacementPtr
	plac (part1->GetPlacement(), false ); 
	   //указываем
	координаты размещения насадки в сборке   plac->SetOrigin(0,
	0, 0 );   //изменяем
	местоположение компонента, заданное
	предыдущей строкой  
	part1->UpdatePlacement();   //обновляем
	свойства компонента   part1->Update();   //заканчиваем
	редактирование на месте  
	part1->EndEdit(false);   //фиксируем
	положение компонента  
	part1->SetFixedComponent(true); //добавляем
	гофрированную трубку  
	doc_assembly->SetPartFromFile(_T("D:\\gofr.m3d"),
	part2,
	false);   //вводим
	переменную первой детали, задаем ее
	нулевым номером   part2->GetPart(1);    //запустить
	режим редактирования на месте для
	первой детали   part2->BeginEdit();   IPlacementPtr
	plac2 (part2->GetPlacement(), false ); 
	   //указываем
	координаты размещения насадки в сборке   plac2->SetOrigin(0,
	0, l1 );   //изменяем
	местоположение компонента, заданное
	предыдущей строкой  
	part2->UpdatePlacement();   //обновляем
	свойства компонента   part2->Update();
	//заканчиваем
	редактирование на месте  
	part2->EndEdit(false);   //фиксируем
	положение компонента  
	part2->SetFixedComponent(true);  //добавляем
	штуцер  
	doc_assembly->SetPartFromFile(_T("D:\\shtuc.m3d"),
	part3, false);   //вводим
	переменную первой детали, задаем ее
	нулевым номером   part3->GetPart(2);    //запустить
	режим редактирования на месте для
	первой детали   part3->BeginEdit();   IPlacementPtr
	plac3 (part3->GetPlacement(), false ); 
	   //указываем
	координаты размещения насадки в сборке   plac3->SetOrigin(0,
	0, l2
	);   //изменяем
	местоположение компонента, заданное
	предыдущей строкой  
	part3->UpdatePlacement();   //обновляем
	свойства компонента   part3->Update();   //заканчиваем
	редактирование на месте  
	part3->EndEdit(false);   //фиксируем
	положение компонента  
	part3->SetFixedComponent(true);       //перестраиваем
	сборку     
	doc_assembly->RebuildDocument(); 
	       //сохранение
	полученной трехмерной модели        //
	Имя файла Документа  
	doc_assembly->SetFileName(_T(
	"d:\\Sborka.a3d" ) );       
	doc_assembly->UpdateDocumentParam();
	 
	         doc_assembly->Save(); 
	   } }
На рисунке 58 приведена конструкция, представленная спроектированным узлом полностью средствами API Компас 3D, состоящая из трех элементов. Для лучшего восприятия полученной конструкции компоненты представлены в разных цветах. С полученной твердотельной модели сборочного узла можно подготовить чертежи или применить конструцию как составную часть изделия крупной сбоки агрегата. Входящие в сборку компоненты в дереве моделей отображаются как стандартные изделия, т.е. не содержат истории построения.
В последующем листинге приведен код создания аналогичной сборки в среде Borland Delphi.
	//процедура
	создания 3Д сборки procedure
	CreateA3D (var l1,l2:real); var iKompasObject:
	KompasObject; iDocument3D:
	ksDocument3D; iPart1
	: ksPart; iPart2
	: ksPart; iPart3
	: ksPart; iPart4
	: ksPart; iPart5
	: ksPart; plac
	: ksPlacement; plac2
	: ksPlacement; plac3
	: ksPlacement; plac4
	: ksPlacement; plac5
	: ksPlacement; ColorParam:ksColorParam; ColorParam2:ksColorParam; begin 
	 iKompasObject
	:= KompasObject(CreateKompasObject); 
	 if
	iKompasObject <> nil then   begin   iDocument3D
	:= ksDocument3D(iKompasObject.Document3D);   if
	 idocument3d.Create(false,false) then     begin     if
	(iDocument3D <> nil) then       begin       iDocument3D.fileName
	:= 'Sborka.a3d';     
	 //
	Имя файла Документа      
	iDocument3D.UpdateDocumentParam();
	         
	 
	//
	Обновить параметры Документа       
	       //
	для каждой детали подготовим свой
	интерфейс       iPart1
	:= ksPart(iDocument3D.GetPart(pNew_Part));       iPart2
	:= ksPart(iDocument3D.GetPart(pNew_Part));       iPart3
	:= ksPart(iDocument3D.GetPart(pNew_Part)); 
	       //вставляем
	насадку       //связываем
	добавляемую из файла деталь с
	файлом-источником      
	iDocument3D.SetPartFromFile('c:\nasadka.m3d',ipart1,false);       //вводим
	переменную первой детали, задаем ее
	нулевым номером       iPart1
	:= ksPart(
	iDocument3D.GetPart(0)
	);       //запустить
	режим редактирования на месте для
	первой детали       iPart1.BeginEdit;       //задаем
	переменную кординирования детали       plac
	:= ksPlacement(ipart1.GetPlacement);       //указываем
	координаты размещения насадки в сборке       plac.SetOrigin(0,
	0, 0 );       //изменяем
	местоположение компонента, заданное
	предыдущей строкой      
	iPart1.UpdatePlacement;       //обновляем
	свойства компонента       iPart1.Update;       //заканчиваем
	редактирование на месте      
	iPart1.EndEdit(False);       //фиксируем
	положение компонента      
	iPart1.fixedComponent:=true;
| 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
				
				 //добавляем
				гофрированную трубку      
				iDocument3D.SetPartFromFile('c:\gofr.m3d',ipart2,false);       iPart2
				:= ksPart( iDocument3D.GetPart(1) );       iPart2.BeginEdit;       plac2
				:= ksPlacement(ipart2.GetPlacement);       plac2.SetOrigin(0,
				0, l1);       iPart2.UpdatePlacement;       iPart2.Update;       iPart2.EndEdit(False);      
				iPart2.fixedComponent:=true; 
				 
				       //задаем
				цвет вставляемой детали      
				iPart2:=ksPart(iDocument3D.GetPart(1));       iPart2.useColor:=0;      
				ColorParam2:=ksColorParam(iPart2.ColorParam);      
				ColorParam2.color:=$003521671;      
				iPart2.SetAdvancedColor(ColorParam2.color,ColorParam2.ambient,      
				ColorParam2.diffuse,ColorParam2.specularity,ColorParam2.shininess,      
				ColorParam2.transparency,ColorParam2.emission);       iPart2.Update; 
				 
				       //добавляем
				штуцер      
				iDocument3D.SetPartFromFile('c:\shtuc.m3d',ipart3,false);       iPart3
				:= ksPart( iDocument3D.GetPart(2) );       iPart3.BeginEdit;       plac3
				:= ksPlacement(ipart3.GetPlacement);       plac3.SetOrigin(0,
				0, l2);       iPart3.UpdatePlacement;       iPart3.Update;       iPart3.EndEdit(False);      
				iPart3.fixedComponent:=true; 
				 
				       //перестраиваем
				сборку      
				IDocument3D.RebuildDocument; 
				 
				       //сохранение
				полученной трехмерной модели       
				iDocument3D.fileName:='c:\sborka.a3d';       
				iDocument3D.UpdateDocumentParam;        iDocument3D.Save; 
				 
				       end;     end;   end; end; 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 Рис. 58. Сборочный узел, выполненный средствами Компас API | 

 
 
 
 
 
 
 
 
 
 
 
 
