четверг, 28 июля 2011 г.

Создание сцены со сферой и плоскостью. Присоединение фонга, цвета материала и света.


//****************************************************
//Создание сцены со сферой и плоскостью. Присоединение фонга, цвета материала и света.
//Created by senior 29.07.11
var lait;//свет
var starttime;// время от старта работы CINEMA_4D
var plo;//плоскость
var texTag;//таг текстуры
var mat;//материал
var tph;//таг фонга
var spho;//сфера
var vOp;//операнд активного документа
var vDoc;//активный документ
var random;//случайная
var rd;//красного цвета
var gr;//зелёного цвета
var bl;//синего цвета
RandCol(vDoc)//Функция Random- для псевдо-случайного выбора цвета
{
starttime = time();//Возвращает время от старта работы CINEMA_4D
random = new(Random);//Переменная со значением от Random-псевдо-случайная функция
random->Init(starttime);//Инициализация Random-псевдо-случайной функции
rd=(random->Get01());//Инициализация красного цвета
gr=(random->Get01());//Инициализация зелёного цвета
bl=(random->Get01());//Инициализация синего цвета
}
CreaPhong(vDoc)//Функция создания фонга
{
vOp=vDoc->GetActiveObject(); //Load Selected object into memory
tph = AllocTag(Tphong); //Assign the phong tag to variable named tph
vOp->InsertTag(tph); //add the phong tag to currently selected object
}
CreaMat(vDoc)//Функция создания нового материала
{
mat = new(Material); //Create a new material in memory
mat->SetName("Mat"); // Имя материала
RandCol(vDoc);//Вызов Random-псевдо-случайной функции
mat#MATERIAL_COLOR_COLOR = vector(rd,gr,bl); // Установка цвета в red-green-blue
vDoc->InsertMaterial( mat, NULL ); // Установка нового материала в Material Manager
mat#MATERIAL_PREVIEWSIZE=10; // Higher number=higher editor resolution setting
texTag = AllocTag( Ttexture ); //Create a texture tag for the new sphere
texTag#TEXTURETAG_MATERIAL = mat; //links the newly created material to the texture's Material input ield
vOp=vDoc->GetActiveObject(); //Load Selected object into memory
vOp->InsertTag(texTag , NULL); //Add it to the scene
}
CreaSphere(vDoc)//Функция создания сферы
{
spho = new(SphereObject); //Create a new Sphere Object
spho#PRIM_SPHERE_RAD = 150; // Sets the radius
spho#PRIM_SPHERE_SUB = 100; // Sets the number of segments
spho#PRIM_SPHERE_TYPE = 0; // Sets the type to standard
vDoc->InsertObject(spho,NULL,NULL); //Add it to the scene
spho->SetBit(BIT_ACTIVE); //Make it selected
CreaPhong(vDoc);//Вызов функции создания фонга
CreaMat(vDoc);//Вызов функции создания нового материала
vDoc->AddUndo(UNDO_NEW, spho); // Undo the creation of the Sphere object
vDoc->AddUndo(UNDO_NEW, mat); // Undo the creation of the material
spho->DelBit(BIT_ACTIVE); //Unselect the object in the hierarchy
}
CreaPlane(vDoc)//Функция создания плоскости
{
plo = new(PlaneObject);  // создать плоскость
plo#PRIM_PLANE_WIDTH = 1000; // ширина=10 м
plo#PRIM_PLANE_HEIGHT = 1000; // длина=10 м
plo#PRIM_PLANE_SUBW=1;//единица по ширине (субдивайд)
plo#PRIM_PLANE_SUBH=1;//единица по длине (субдивайд)
vDoc->InsertObject(plo,NULL,NULL);//Add it to the scene
plo->SetBit(BIT_ACTIVE); //Сделать плоскость активной (выбрать)
CreaPhong(vDoc);//Вызов функции создания фонга
CreaMat(vDoc);//Вызов функции создания нового материала
vOp=vDoc->GetActiveObject(); //Load Selected object into memory
var pos = vOp->GetPosition();//Получить текущую позицию плоскости
plo->SetPosition(vector(pos.x, pos.y-150, pos.z)); //Опустить плоскость по Y на 150 (1,5 метра)
plo#ID_BASEOBJECT_REL_SCALE:VECTOR_X=1.8;//Увеличить до 18 метров
plo#ID_BASEOBJECT_REL_SCALE:VECTOR_Z=1.8;//Увеличить до 18 метров
vDoc->AddUndo(UNDO_NEW, plo); // Undo the creation of the Plane object
vDoc->AddUndo(UNDO_NEW, mat); // Undo the creation of the material
plo->DelBit(BIT_ACTIVE); //Unselect the object in the hierarchy
}
CreaLight(vDoc)
{
lait = new(LightObject);  // creates a LightObject primitive
vDoc->InsertObject(lait,NULL,NULL);//Add it to the scene
lait#ID_BASEOBJECT_REL_POSITION:VECTOR_X=471.5;//позиция по X
lait#ID_BASEOBJECT_REL_POSITION:VECTOR_Y=265.5;//позиция по Y
lait#ID_BASEOBJECT_REL_POSITION:VECTOR_Z=-400.4;//позиция по Z
CallCommand(12520);//вызов SpotLight плюс Light.Target.1
}
main(doc,op)
{
vDoc = GetActiveDocument();// в vDoc-активный документ
CreaSphere(vDoc);//Вызов функции создания сферы
CreaPlane(vDoc);//Вызов функции создания плоскости
CreaLight(vDoc);  // Вызов функции создания Light primitive
}
//**************************************************************

вторник, 26 июля 2011 г.

Создание нового случайного материала в менеджере MM


//***********************************************
//Create by senior 27.07.11
//Создание нового случайного материала в менеджере MM.
var starttime = time();//Возвращает время от старта работы CINEMA_4D
var random = new(Random);//Переменная со значением от Random-псевдо-случайная функция
random->Init(starttime);//Инициализация Random-псевдо-случайной функции
var rd=(random->Get01());//Инициализация красного цвета
var gr=(random->Get01());//Инициализация зелёного цвета
var bl=(random->Get01());//Инициализация синего цвета
var mat = new(Material); //Create a new material in memory
mat->SetName("Mat"); // Имя материала
mat#MATERIAL_COLOR_COLOR = vector(rd,gr,bl); // Установка цвета в red-green-blue
doc->InsertMaterial( mat, NULL ); // Установка нового материала в Material Manager
mat#MATERIAL_PREVIEWSIZE=10; // Higher number=higher editor resolution setting
//*************************************************

среда, 20 июля 2011 г.

Работа со значениями Комбобокса в Диалоговом меню.

Работа со значениями Комбобокса в Диалоговом меню: (от звёздочек до звёздочек)


//****************************************
//This Script was made by senior 20.07.11
//Установка переменных
var x0;
var y0;
var z0;
var x1 = "Red";
var y1;
var z1;
const var txtx1="Red";      // X-1
const var txtx2="Blue";     // X-2
const var txtx3="Yellow";   // X-3
const var txtx4="Green";    // X-4
const var txtx5="Black";    // X-5

class MyDialog : GeModalDialog //модальный GeModalDialog
////Это означает, что до тех пор, пока открыто диалоговое окно, остальная часть программы должна ждать,
//пока пользователь не закроет окно. Так что этот тип диалога соответствует 90% всех плагинов.
//Кроме того, он обрабатывает кнопки ОК и Cancel
 {
 public:
  MyDialog();//Декларация конструктора
     CreateLayout();//Объявление метода создания диалога
  Command(id, msg);//Получение значений из полей диалога
 }
  MyDialog::MyDialog() {super();}//Конструктор для вызова родительского класса
  MyDialog::CreateLayout()//Создать диалог(определить расположение объектов диалога)
 {
SetTitle("ALL_Menu");//Имя диалога
AddEditText(104, 0, 350, 0);//Окно для получения и введения текста, id=104, центр, ширина=350, высота в одну букву.
AddGroupBeginV(1001, BFH_SCALEFIT,1,"group",0);//Начало группы V-вертикальная
AddSeparatorH(0);//Разделитель
AddComboBox(2001,  BFH_SCALEFIT|BFV_CENTER, 64, 0);//КомбоБокс
AddItem(2001, 1, "Set-1");//Подобъект №1
AddItem(2001, 2, "Set-2");//Подобъект №2
AddItem(2001, 3, "Set-3");//Подобъект №3
AddItem(2001, 4, "Set-4");//Подобъект №4
        AddItem(2001, 5, "Set-5");//Подобъект №5
SetItem(2001,  1);//Установить в комбобоксе по умолчанию Подобъект №1
AddSeparatorH(0);//Разделитель
AddGroupEnd();//Конец группы
AddGroupBeginV(1004, BFH_SCALEFIT,1,"group",0);//Начало группы V-вертикальная
  AddButton (3000,BFH_CENTER,200,0,"Set_in_ComboBox");//Кнопка "Set_in_ComboBox"
AddSeparatorH(0);//Разделитель
AddDlgGroup(DR_DLGGROUP_OK | DR_DLGGROUP_CANCEL);//Кнопки OK и Cancel
AddGroupEnd();//Конец группы
 }
  MyDialog::Command(id, msg)//Отслеживает нажатие кнопок и выдачу сообщений,
//срабатывает от каждого события, то есть каждый раз, как нажимается любая кнопка, с выдачей id каждого события
{
switch(id)//Взять id нажатия
{
case 3000: // Если это (id=3000)="Set_in_ComboBox", то...
{
x0 = GetItem(2001);//Получить значение подобъекта из id=2001 (комбобокс) - 1, 2, 3, или 4
if (x0==1)//Сравнить это значение с 1 (подобъекта №1)
{
x1=txtx1;// то x1 = "Red"
}
if (x0==2)//Сравнить это значение с 2 (подобъекта №2)
{
x1=txtx2;// то x1 = "Blue"
}
if (x0==3)//Сравнить это значение с 3 (подобъекта №3)
{
x1=txtx3;// то x1 = "Yellow"
}
if (x0==4)//Сравнить это значение с 4 (подобъекта №4)
{
x1=txtx4;// то x1 = "Green"
}
if (x0==5)//Сравнить это значение с 5 (подобъекта №5)
{
x1=txtx5;// то x1 = "Black"
}
println("Set = ", x1);//Напечатать в консоли значение комбобокса
SetString(104, x1);//Вставить текст в id=104 (текстовое окошко)
var message = stradd("Set =  ",tostring(x1));
TextDialog(message,DLG_OK);//Напечатать значение комбобокса во всплывающем окошке
return TRUE;
break;//Прервать
}
case 1: //Если это (id=1)=OK, то...
{
println("OK!");//Напечатать в консоли
 TextDialog("OK!",DLG_OK);//Напечатать в отдельном окошке
return TRUE;
break;//Прервать
}
case 2: //Если это (id=2)=Cancel, то...
{
println("CANCEL");//Напечатать в консоли
 TextDialog("CANCEL",DLG_OK);//Напечатать в отдельном окошке
return FALSE;
break;//Прервать
}
}
}
  main(doc, op)//Главная функция, с которой начинается работа
 {
var d = new(MyDialog);//Запуск функции модального диалога GeModalDialog
         d->Open(1650, 700);//После того, как все кнопки определены, запустить диолог в позиции 1650 на 700
  var result = d->GetResult();   // GetResult показывает, что нажато OK или Cancel, (OK-TRUE, CANCEL-FALSE)
  if(result==FALSE) return;      //Выйти, если нажата CANCEL
 TextDialog("END",DLG_OK);  //Продолжить, если нажата OK
 }
//****************************************

пятница, 15 июля 2011 г.

Вставить и получить стринг-значение в диалоговом текстовом окошке.

Этот код вставит и получит стринг-значение в диалоговое текстовое окошко:


//*************************************************************
//This Script was made by senior 15.07.11
var text;
class MyDialog : GeModalDialog //модальный GeModalDialog
////Это означает, что до тех пор, пока открыто диалоговое окно, остальная часть программы должна ждать,
//пока пользователь не закроет окно. Так что этот тип диалога соответствует 90% всех плагинов.
//Кроме того, он обрабатывает кнопки ОК и Cancel
 {
 public:
  MyDialog();//Декларация конструктора
     CreateLayout();//Объявление метода создания диалога
  Command(id, msg);//Получение значений из полей диалога
 }
  MyDialog::MyDialog() {super();}//Конструктор для вызова родительского класса
  MyDialog::CreateLayout()//Создать диалог(определить расположение причиндалов диалога)
 {
SetTitle("ALL_Menu");//Имя диалога
AddEditText(104, 0, 200, 0);//Окно для получения и введения текста, id=104, центр, ширина=200, высота в одну букву.
AddGroupBeginV(1001, BFH_SCALEFIT,1,"group",0);//Начало группы
   AddButton (3000,BFH_CENTER,200,0,"Set");//Кнопка Set
AddSeparatorH(0);//Разделитель
  AddButton(102, 0, 200, 0, "Get");//Кнопка Get
AddSeparatorH(0);//Разделитель
AddDlgGroup(DR_DLGGROUP_OK | DR_DLGGROUP_CANCEL);////Кнопки OK и Cancel
AddGroupEnd();//Конец группы
 }
  MyDialog::Command(id, msg)//Отслеживает нажатие кнопок и выдачу сообщений, срабатывает каждый раз, как нажимается любая кнопка
{
switch(id)//Взять id нажатия
{
case 102: // Если это (id=102)=Get, то...
{
text = GetString(104);//Получить текст из id=104 (текстовое окошко)
println("Get = ",text);//Напечатать в консоли, то, что получено
var message = stradd("There are ",tostring(text)," items.");//Перевести текст в стринг
TextDialog(message,DLG_OK);//Напечатать в отдельном окошке, то, что получено
return TRUE;//Успешно
break;//Прервать
}
case 3000: //Если это (id=3000)=Set, то...
{
text = "sin(1)=Good Luck!";//Вставляемый текст
SetString(104, text);//Вставить текст в id=104 (текстовое окошко)
println("Set = ",text);//Напечатать в консоли, то, что вставлено
 var message = stradd("There are ",tostring(text)," items.");//Перевести текст в стринг
TextDialog(message,DLG_OK);//Напечатать в отдельном окошке, то, что вставлено
return TRUE;
break;//Прервать
}
case 1: //Если это (id=1)=OK, то...
{
println("OK!");//Напечатать в консоли
 TextDialog("OK!",DLG_OK);//Напечатать в отдельном окошке
return TRUE;
break;//Прервать
}
case 2: //Если это (id=2)=Cancel, то...
{
println("CANCEL");//Напечатать в консоли
 TextDialog("CANCEL",DLG_OK);//Напечатать в отдельном окошке
return FALSE;
break;//Прервать
}
}
}
  main(doc, op)//Главная функция, с которой начинается работа
 {
var d = new(MyDialog);//Запуск функции модального диалога GeModalDialog
         d->Open(1650, 700);//После того, как все кнопки определены, запустить диолог в позиции 1650 на 700
  var result = d->GetResult();   // GetResult показывает, что нажато OK или Cancel, (OK-TRUE, CANCEL-FALSE)
  if(result==FALSE) return;      //Выйти, если нажата CANCEL  
 TextDialog("END",DLG_OK);  //Продолжить, если нажата OK
 }
//****************************************

воскресенье, 10 июля 2011 г.

Структура скрипта. 2. Интерфейс (Меню, кнопки, окна).

Этот код скрипта показывает всевозможные меню, кнопки и окна. Всё пустое, кроме кнопок Start, Button, OK и Cancel.
Copy-Paste в Script Manager от звёздочек до звёздочек:

//*********************************************
//This Script was made by senior 10.07.11
class MyDialog : GeModalDialog
 {
 public:
  MyDialog();
    CreateLayout();
  Command(id, msg);
 }
  MyDialog::MyDialog() {super();}
  MyDialog::CreateLayout()
 {
SetTitle("ALL_Menu");
  AddGroupBeginV(1001, BFH_SCALEFIT,1,"group",0);
  AddButton (3000,BFH_CENTER,200,0,"Start");
  AddSeparatorH(0);
  AddStaticText(0,BFH_LEFT,200,0,"That's_ Rock!",0);
  AddSeparatorH(0);
  AddComboBox(2011, BFH_CENTER, 0, 0);
AddItem(2011, 1, "up");
AddItem(2011, 2, "left");
AddItem(2011, 3, "right");
AddItem(2011, 4, "down");
AddSeparatorH(0);
   AddEditNumber(2503,BFH_LEFT,250,0);
   AddSeparatorH(0);
   AddArrowButton(101, 0,0, 0, ARROW_RIGHT);
   AddSeparatorH(0);
   AddButton(102, 0, 0, 0, "Button");
   AddCheckbox(103, 0, 0, 0, "CheckBox");
   AddSeparatorH(0);
   AddEditText(104, 0, 100, 0);
   AddSeparatorH(0);
   AddMultiLineEditText(105, 0, 0, 0, 0);
   AddSeparatorH(0);
   AddEditNumber(106, 0, 100, 0);
   AddSeparatorH(0);
   AddEditNumberArrows(107, 0, 0, 0);
   AddSeparatorH(0);
   AddSlider(108, 0, 0, 0);
   AddSeparatorH(0);
   AddEditSlider(109, 0, 0, 0);
   AddSeparatorH(0);
   AddColorField(110, 0, 130, 20);
   AddSeparatorH(0);
   AddColorChooser(111, 0, 0, 0, 20);
   AddSeparatorH(0);
   AddStaticText(113, 0, 0, 0, "static text", 0);
   AddSeparatorH(0);
   AddPopupButton(114, 0, 30, 0);
AddItem(114, 1, "test 1");
AddItem(114, 1, "test 2");
AddItem(114, 1, "test 3");
   AddSeparatorH(0);
   AddDlgGroup(DR_DLGGROUP_OK | DR_DLGGROUP_CANCEL);
   AddGroupEnd();
 }
  MyDialog::Command(id, msg)
{
switch(id)
{
case 102: // Button
{
println("Button");
 TextDialog("Button",DLG_OK);
return TRUE;
break;
}
case 3000: // Start
{
println("Start");
 TextDialog("Start",DLG_OK);
return TRUE;
break;
}
case 1: // OK
{
println("OK!");
 TextDialog("OK!",DLG_OK);
return TRUE;
break;
}
case 2: // Cancel
{
println("CANCEL");
 TextDialog("CANCEL",DLG_OK);
return FALSE;
break;
}
}
}
  main(doc, op)
 {
var d = new(MyDialog);
         d->Open(1650, 700);
  var result = d->GetResult();   // Get the result of dialog input, OK-TRUE, CANCEL-FALSE
  if(result==FALSE) return;      //Exit if press CANCEL  
 TextDialog("END",DLG_OK);  //Continue if press OK
 }
//****************************************

Структура скрипта. 1. Регистрация скрипта.

Вот код для регистрации плагина, который приходит извне, в виде файла *.cof (в папке plugins):

//*************************************************************************
//This Script was made by senior 10.07.11
// Глобальные переменные и константы
         const var PluginID = 1000001;// идентификационный номер плагина, берётся на сайте MAXON
         const var PlugName = "My_Plugin";// Pluginname
         const var PlugHelp = "My_Plugin";// Плагин текст справки
         const var ObjName = "My_Plugin";// Objektname
         var Dial;
// Производные класса MyPlugin
   class MyPlugin : MenuPlugin//MenuPlugin-производные класса для регистрации и вывода меню плагинов
   {  public:
          MyPlugin();//Декларация конструктора
          GetID();   //Получить ID плагина(Устанавливает идентификатор контейнера в ID)
          GetName(); //Получить имя плагина(Должны возвращать пункты меню для плагина)
          GetHelp(); //Получить текст справки для меню
          Execute(doc);//Создать диалог(Вызывается, когда плагин выбран.)
          RestoreLayout(secret);//Восстановить диалог повторно
   }
// Декларация конструктора
   MyPlugin::MyPlugin()
   //C.O.F.F.E.E. позволяет определять функции внутри класса (что позволяет иметь одинаковые имена функции в разных классах).
   //Это делается оператором - "::"-определение функций-членов(имя_класса::имя_функции(список_аргументов){инструкции}
   {
      super();//Вызывает конструктор родительского класса.
 //супер () должен быть вызван в первую строку конструктора производного класса для запуска конструктора родительского класса.
  }
//Объявление метода GetID
   MyPlugin::GetID()//Возвращает ID плагина.
//Убедитесь, что используется уникальный идентификатор из http://www.plugincafe.com.
   {
      return PluginID;//const var PluginID = 1000001
   }
// Объявление метода GetName - это то, что показывается в Plugins.
   MyPlugin::GetName()//Должен вернуть имя меню для плагина.
   {
       return PlugName;//const var PlugName = "My_Plugin";
   }
// Объявление метода getHelper
   MyPlugin::GetHelp()//Должен вернуть текст справки для меню. Это будет показано в команд менеджере, подсказке и строке состояния.
   {
       return PlugHelp;//const var PlugHelp = "My_Plugin";
   }
// объявление метода Execute
   MyPlugin::Execute(doc)//Вызывается для создания диалога
   {
     //Dial=new(MyDialog);//new-создает новый объект, заданный его параметром(MyDialog), затем сохраняет этот новый объект в переменную gDial
     //Dial->Open(TRUE,-1,-1);//Открываетcz диалоговое окно в указанную позицию.
//Если async имеет значение TRUE, открывается немодальное (асинхронное) окно.
//Вызов функций или использование переменных внутри класса осуществляется с помощью оператора члена(member operator) (->)
//Если XPos =- 1 и YPos =- 1 диалог будет открыт в текущем положении мыши.
//Если XPos =1525, и YPos =475/ async=FALSE диалог будет открыт в этом положении. gDial->Open(FALSE,1525,475);
   }
// Объявление метода восстановления макета
   MyPlugin::RestoreLayout(secret)//Если одно из меню плагина вызывает асинхронный диалог следует перегрузить эту функцию.
   //Она будет вызвана когда C4D необходимо открыть диалог снова, например, если он был добавлен в макет пользователей
//и Программа была перезапущена.
   {
      //if (!Dial)//Если диалога нет, то
     //Dial=new(MyDialog);//создаётся
     //Dial->RestoreLayout(secret);//Восстановление диалога
 //Вызов функций или использование переменных внутри класса осуществляется с помощью оператора члена(member operator) (->)
   }
//1. Декларируется конструктор
//2. Возвращается ID плагина
//3. Возвращается имя плагина
//4. Возвращается текст справки для меню
//5. Вызывается для создания диалога
//6. Вызывается когда необходимо открыть диалог снова, повторно
main()
{
    Register(MyPlugin);//Bool Register(LONG id, LONG flags) - registers the serial number.
//В COFFEE внутри C4D это не нужно, только если .cof заходит снаружи
}
//************************************************************************
А это код для регистрации плагина внутри программы, в Script Manager`е:
//**************************************************************
//This Script was made by senior 10.07.11
      const var PluginID = 1000001;  // Plugin ID Nummer
      const var PlugName = "My_Plug";  // Pluginname
      const var PlugHelp = "My_Plug_NEW"; // Pluginhilfstext
      const var ObjName = "My_Plug"; // Objektname

   class MyPlugin : MenuPlugin
   {  public:
          MyPlugin();
          GetID();
          GetName();
          GetHelp();
          Execute(doc);
          RestoreLayout(secret);
   }
   MyPlugin::MyPlugin(){super();}
   MyPlugin::GetID(){return PluginID;}
   MyPlugin::GetName(){return PlugName;}
   MyPlugin::GetHelp(){return PlugHelp;}
   MyPlugin::Execute(doc) {}
   MyPlugin::RestoreLayout(secret){}

   main(doc,op){Register(MyPlugin);}
//*********************************************************************

суббота, 9 июля 2011 г.

Два пути запуска скриптов в CINEMA 4D

В CINEMA 4D существует два вида запуска скриптов COFFEE. Один статический, другой динамический. Статический, это Script Manager, динамический - Expression Editor. В SM скрипт запускается один раз, исполняется и останавливается, в EE скрипт запускается от каждого события, происходящего на экране, то есть находится постоянно, динамически в работе.
Посмотрим на примере. Вот код:
//******************************************************
//This Script was made by senior 09.07.11
//Manager Script code!
main(doc,op)
{
var a = new(SphereObject);  // creates a Sphere primitive class instance
doc->InsertObject(a,NULL,NULL);  //Add it to the scene
var frst=doc->GetFirstObject();  //Get First object
frst->SetBit(BIT_ACTIVE);  //Set object active
CallCommand(12236); // Make Editable

//Expression code!
var frame = doc->GetTime()->GetFrame(doc->GetFps());// Gets FPS
var obj = doc->GetActiveObject(); //Gets the selected object
var pos=obj->GetRelPos();//Gets position of object
pos.x=5*sin(frame/15)*40;// X position
pos.z=5*cos(frame/15)*40;//Z position
obj->SetRelPos(pos);// Set new position of object
}
//******************************************************
Сделаем Copy-Paste (от звёздочек до звёздочек) в Script Manager и запустим. На экране появится сфера и на этом работа скрипта закончится.
Скопируем теперь этот же код в Expression Editor (за исключением создания сферы):
//**************************************************
//This Script was made by senior 09.07.11
main(doc,op)
{
//Expression code!
var frame = doc->GetTime()->GetFrame(doc->GetFps());// Gets FPS
var obj = doc->GetActiveObject(); //Gets the selected object
var pos=obj->GetRelPos();//Gets position of object
pos.x=5*sin(frame/15)*40;// X position
pos.z=5*cos(frame/15)*40;//Z position
obj->SetRelPos(pos);// Set new position of object
}
//*****************************************************
Чтобы попасть в EE, нажмём правой кнопкой мыши на объект Sphere в Object Manager`е, выберем CINEMA 4D Tags, там выберем C.O.F.F.E.E. Возле объекта Sphere появился значок "чашка с кофе", два раза по нему кликнем левой кнопкой, появится редактор Expression Editor. Скопируем в него код. Нажмём Compile в EE. Код скомпилирован и если всё нормально, то в самом низу появится надпись "No Errors!". Нажмём F8, сфера начнёт двигаться по экрану, то есть каждое изменение позиции FPS запускает код в EE.

Простой путь программирования в CINEMA 4D

Разработчики CINEMA 4D предоставили нам возможность пользоваться Командами, это такие большие макросы, которые производят действия определённого направления. Сборник всех Команд находится в Windows->Layout->Command Manager (Shift+F12). Любую команду можно перетащить мышью в Script Manager и там запустить.
В принципе, КАЖДОЕ ДЕЙСТВИЕ, КОТОРОЕ МЫ ПРОИЗВОДИМ НА ЭКРАНЕ, есть команда и существует возможность записать серию команд в супер большой макрос. Запись всех команд производится в окне Script Log и чтобы открыть его, в Command Manager, в окошке Name Filter, пишем Script Log, он появляется, кликаем два раза и видим окно Script Log. Здесь будут записываться все команды по мере их исполнения, нам только остаётся сделать их Copy-Paste в  Script Manager и там запустить.
Конечно, использование команд, это очень простой способ программирования, но иногда, если запрограммировать что-либо слишком сложно, он помогает.

Запуск ScriptManager`а

Запуск ScriptManager`а.

ScriptManager служит для написания кода сценария COFFEE внутри программы CINEMA 4D. Для его запуска находим в самом верхнем меню пункт Window и кликаем в нём на ScriptManager (Shift+F11). Здесь нажимаем на кнопку New, даём имя, жмём OK. Самое нижнее окно служит для написания кода, остальные вверху для информации. После написания кода нажимаем Save All (сохранить всё). Пункты Load Icon и Render Icon для присоединения иконки к скрипту. Запуск скрипта производится кнопкой Execute в самом низу справа.
Ещё один момент. Все системные сообщения при запуске скрипта проходят через системное окно под названием Console, поэтому тоже запускаем его: меню Windows, там Console (Shift+F10). В Console находим пункт File->Clear и очищаем окно. Здесь же есть пункт Plugins->Reload COFFEE Plugins, который подключает внешние плагины .cof. Это удобно, не надо каждый раз перезапускать CINEMA, после редактирования внешнего плагина .cof.
И это всё по запуску ScriptManager`а.


пятница, 8 июля 2011 г.

Запуск сценариев

Запуск сценариев COFFEE возможен из двух мест:
1. Посредством запуска написанного кода из внутреннего редактора Script Menager.
2. И снаружи, путём записи файла с расширением .cof в директорию c:/Program Files/Maxon/CINEMA 4D R12 Demo/plugins.
Эти два пути маркируются по разному. Главная функция main() даётся либо с пустыми аргументами (для файла .cof), либо с аргументами main(doc,op) для Script Menager`а, это означает, что запуск скрипта происходит внутри активного документа (doc), в окружении параметрических объектов (op).

четверг, 7 июля 2011 г.

C.O.F.F.E.E

Совсем другое отношение разработчиков CINEMA 4D к внутреннему языку COFFEE. Отношение , как к близкому родственнику. Во-первых для COFFEE есть внутренний редактор (Script Menager) с подсветкой синтаксиса. Этим же редактором производится компиляция и исполнение написанного кода. Результат мгновенно виден на экране.
Это касается ввода плагинов внутри программы. Если же плагин вводится снаружи, в виде файла, то разработчики предлагают самый простой вариант: в директорию plugins записывается простой текстовый файл с написанным в любом текстовом редакторе кодом плагина.

понедельник, 4 июля 2011 г.

C++

Возникает законный вопрос, а почему же не использовать сам C++, тем более, что он прекрасно поддерживается "синькой" (CINEMой 4D)? Ответ - достаточно сложно и неудобно. Такое впечатление, что разработчики сделали всё, чтобы юзеры не использовали C++. Вот, например требования к плагину, написанному на C++:


myPlugin/             //Это папка плагина
    myPlugin.cdl     //Это сам файл
       ...
    res/                     //Это директория в папке плагина
      c4d_symbols.h //где должен находится этот файл
      description/       //Это поддиректория в директории
        myDescription.h  //где должен находится этот файл
        myDescription.res//и этот
        ...
      dialogs/                  //Это тоже директория в папке плагина
        myDialog.res       //где должен находится этот файл 
        ...
      strings_us/               //Это тоже директория в папке плагина
        c4d_strings.str        //где должен находится этот файл
        description/             //Это поддиректория в директории
          myDescription.str  //где должен находится этот файл
          ...
        dialogs/                  //Это поддиректория в директории
          myDialog.str        //где должен находится этот файл
          ...
      strings_de/              //и этот
      strings_jp/               //и этот
      ...
      myIcon.tif              //а это иконка плагина
      myWhatever.any    //ну и ещё что-нибудь, в общем ни в чём себе не отказывай!


А вот страшное предупреждение:


Опции компилятора Pointer-to-member должны быть установлены в "General-Purpose Always" и "Point to Single-Inheritance Classes" в C + + tab / С + + языках (/ VMG / VMS). Если они не установлены, плагин рухнет мгновенно!


Короче, рыба не ездит на велосипеде.

воскресенье, 3 июля 2011 г.

Введение

C.O.F.F.E.E, это внутренний язык программирования 3D приложения CINEMA 4D. По принадлежности это почти чистый C++ язык, только без-типовой или вернее все-типовой. Из-за этого его не понимают компиляторы C++. Ещё одна особенность языка в том, что C.O.F.F.E.E,  язык для управления графическими событиями внутри программы CINEMA 4D, прикладной язык. Это выражается в том, что большинство функций языка, это графические подпрограммы CINEMA 4D. По большому счёту, это C++, заточенный под графику. И этим он интересен. Через него предоставляется доступ к очень мощному (самому мощному в мире, по моему) 3D графическому движку CINEMA 4D.