пятница, 23 сентября 2011 г.

Создание из объекта клонов в виде сферы


//*******************************
//Делает клоны в виде шара
//Выбрать объект и выделить его
var vDoc;
var ClonOb;
var NewNull;
var NewClonOb;
var i,j;//Индексы цикла
//********************
      var x,y,z;
      var f;//Увеличитель
      var Nu;// (итерации) по u
      var Nv;// (итерации) по v
      var du;        
      var dv;        
      var u,v;
      var zz;  
      var R;
 //**********************
FormClone(vDoc)//Функция отрисовки
{
//***************
     ClonOb=vDoc->GetActiveObject(); if (!ClonOb) println("Select object"); //Получить выделенный объект, если не выделен, прервать выполнение скрипта
     if (!ClonOb) return FALSE;//если не выделен, прервать выполнение скрипта
     NewNull = new(NullObject); // Создать новый Null объект
     NewNull->SetName("Clones");// Имя клонов
     vDoc->InsertObject( NewNull, NULL, NULL );//Ввести в Объект Менеджер

//**************
      var uMin = 0.0;
      var uMax = 6.283185307;
      var vMin = 0.0;
      var vMax = 6.283185307;
      f = 30;//Увеличитель
      Nu = 20;//Количество клонов по u
      Nv = 20;//Количество клонов по v
      R = 10.0;//Радиус (Увеличитель)
du=(uMax-uMin)/Nu;//ширина
dv=(vMax-vMin)/Nv;//длина
           zz=0;
              for (i=0;i<Nu;i++)//Колонны по u
             {
             for (j=0;j<Nv;j++)//Ряды по v
             {
                    u=uMin+i*du;//Ширина шага
                    v=vMin+j*dv;//Длина шага
x = R * sin(u) * cos(v); //Формула по x
y = R * cos(u);            //Формула по y
z = R * sin(u) * sin(v);  //Формула по z
                  zz=zz+1;
//*************************
NewClonOb = ClonOb->GetClone(0);// Сделать клон выделенного объекта
var sc = NewClonOb->GetContainer();//Получить контейнер для клонов
NewClonOb->SetContainer(sc);//Установить контейнер для клонов
NewClonOb->SetName("Object." + tostring(i));//Дать порядковое имя клонам
NewClonOb->SetPosition(vector(x*f,y*f,z*f));//Установить клон в новую позицию x, y, z
vDoc->InsertObject(NewClonOb,NewNull,NULL);//Добавить детку клона  к родителю NULL
            }
                 GeEventAdd(DOCUMENT_CHANGED);//Зафиксировать изменения в документе
            }
                 GeEventAdd(DOCUMENT_CHANGED);//Зафиксировать изменения в документе
}//конец FormClone(vDoc)
//*********************
main(doc,op)//Главная функция, начало работы скрипта
{
vDoc = GetActiveDocument();//Получить активный документ
FormClone(vDoc);//Нарисовать
}
//**************************

Создание клонов из объекта


//*****************************************
//Делает клоны в виде аттрактора
//Выбрать объект и выделить его
var vDoc;
var ClonOb;
var NewNull;
var NewClonOb;
var i,j;//Индексы цикла
//********************
         var x,y,z;
         var a=0.85;////Переменные аттрактора
         var b=0.90;////Переменные аттрактора
         var c=0.40;////Переменные аттрактора
         var d=9.00;////Переменные аттрактора
         var t,s,co;//Переменные формулы аттрактора
         var N=100;//Количество клонов
         var x0=0.0;//Старт x
         var y0=0.2;//Старт y (на радиус сферы=0.2)
         var xa;// x-АЛЬФА
         var ya;// y-АЛЬФА
         var Faktor=300;//Увеличитель
 //**********************
FormClone(vDoc)//Функция отрисовки
{
//***************
     ClonOb=vDoc->GetActiveObject(); if (!ClonOb) println("Select object"); //Получить выделенный объект, если не выделен, прервать выполнение скрипта
     if (!ClonOb) return FALSE;//если не выделен, прервать выполнение скрипта
     NewNull = new(NullObject); // Создать новый Null объект
     NewNull->SetName("Clones");// Имя клонов
     vDoc->InsertObject( NewNull, NULL, NULL );//Ввести в Объект Менеджер

//**************
xa=x0;//Это x-АЛЬФА-начальная - var x0=0.0;-Старт x
y=y0;// var y0=0.2;-Старт y (на радиус сферы=0.2)
ya=y0;
         for (j=0;j<N-1;j++)// от 0 до 999 (var N=1000;)
             {
                 t=c-d/(1+xa*xa+y*y);//Переменная t для аттрактора
                 s=sin(t);//Переменная s для аттрактора
                 co=cos(t);//Переменная co для аттрактора
            x=a+b*(xa*co-y*s);//Формула по x
            y=b*(xa*s+y*co);//Формула по y
            z = ya;//Формула по z
//*************************
NewClonOb = ClonOb->GetClone(0);// Сделать клон выделенного объекта
var sc = NewClonOb->GetContainer();//Получить контейнер для клонов
NewClonOb->SetContainer(sc);//Установить контейнер для клонов
NewClonOb->SetName("Object." + tostring(i));//Дать порядковое имя клонам
NewClonOb->SetPosition(vector(x*Faktor,y*Faktor,z*Faktor));//Установить клон в новую позицию x, y, z
vDoc->InsertObject(NewClonOb,NewNull,NULL);//Добавить детку клона  к родителю NULL
                 GeEventAdd(DOCUMENT_CHANGED);//Зафиксировать изменения в документе
                 xa=x;// x-АЛЬФА теперь с новой позиции
                 ya=y;// y-АЛЬФА теперь с новой позиции
             }
}//конец FormClone(vDoc)
//*********************
main(doc,op)//Главная функция, начало работы скрипта
{
vDoc = GetActiveDocument();//Получить активный документ
FormClone(vDoc);//Нарисовать
}
//**************************************

воскресенье, 18 сентября 2011 г.

Некоторые работы...

Все изображения сделаны при помощи K.O.F.F.E.E.

Око
Автопортрет
Ангел зла
Шлем ужаса
Боромеанские кольца
Кувшинки
Небесный волчок
Плетёный УНИ
Сквозь

суббота, 10 сентября 2011 г.

Считает расстояние между всеми соседними точками объекта + определяет чётные-нечётные точки объекта


//Взять любой объект, задивайдить (C) и выделить
//Считает расстояние между всеми соседними точками объекта
//Определяет чётные-нечётные точки объекта
var vDoc;//Активный документ
var vOp;//Активный операнд
var ponts;//количество точек в выделенном объекте(проверка дивайда), если "Member not found", то (С)
var P1,P2,P3,P4,P5;
var arr;//Массив для точек объекта
var tuda;//Пересчёт для обратного счёта
var gpcount;//Количество точек в объекте
var i;//индекс лупа
//*******************
distance(P1,P2)//Функция определения дистанции между двумя соседними точками // Calculates the length of the vector that goes from p1 to p2.
{
  return vlen(P2-P1);
}
//*******************
UstPol(vDoc)//Функция определения расстояния между соседними точками объекта+чёт-нечёт
{
vOp = vDoc->GetActiveObject(); //Gets the selected object
if(!vOp)return; //Ends the script if nothing is selected
arr = vOp->GetPoints(); if (!arr) return FALSE; // Массив с точками объекта
gpcount=vOp->GetPointCount();//Количество точек
for(i=0; i<gpcount-2; i++)
{
tuda=(gpcount-i);//Обратный счёт
//Посчитаем расстояние между точками:
  P1 = arr[tuda-2]; // Счёт в обратную сторону, от общего количества точек к точке №2
  P2 = arr[tuda-1]; // Счёт в обратную сторону
println("distance P",tuda-1," -","P",tuda," = ",distance(P1,P2)); // Вызов функции distance - Calculates the length of the vector that goes from p1 to p2.
//Чётное-нечётное
P3=2;
P5=abs(tuda-1);
P4= Modulo(P5, P3);//Модуль числа P5 по 2 (двойке)
if (P4==0) println(tuda-1," =chetnoe");//Если модуль = 0, то чётное, если =1 - нечётное
}
}
//*************************
main(doc,op)
{
vDoc = GetActiveDocument();
vOp=vDoc->GetActiveObject(); if (!vOp) println("Select object"); //Получить выделенный объект, если не выделен - то текст
if (!vOp) return FALSE;//если не выделен, прервать выполнение скрипта
ponts=vOp->GetPointCount(); if (!ponts) println("Devide object!");//Получить количество точек в выделенном объекте, если нет, то объект задивайдить! (C)
if (!ponts) return FALSE;//Прервать, если объект не дивайденный (C)
UstPol(vDoc);
}

воскресенье, 14 августа 2011 г.

Простой движок для построения параметрической поверхности


//**********************************************************
//Простой_парадвижок
//This Script was made by senior 14.08.11
      const var cPluginID =    1000001;
      const var cPlugName = "Piramida";//Имя плагина
      const var cObjName =  "Piramida";//Имя объекта
      var vObj;
      var i,j;//Индексы
      var x;// X
      var y;// Y
      var z;// Z
      var Wind=180;//Ширина текста в диалоге
      var cMaxFloat=1000000;//Диапазон float от + до -
      var cMaxInt=100000000;//Диапазон integer от + до -
      var uMin = 0.0;                  //Минимум по общей ширине
      var uMax =25.13274122;//Максимум по общей ширине=4*pi
      var vMin = 0.0;                  //Минимум по общей длине
      var vMax = 6.283185307;//Максимум по общей длине=2*pi
      var Nu = 164;//Субдивайдинг (количество итераций) по u
      var Nv=24;//Субдивайдинг (количество итераций) по v
         var globDial;//Запуск диалога
         var plos;//Объекты "детки" (плоскость)
         var traktor;//"Родительский" объект
         var vys=60;//Длина плоскости
         var shir=60;//Ширина плоскости
         var glub=0;//Ориентация плоскости +x=0,-x=1,+y=2,-y=3,+z=4.-z=5
         var u;//общая ширина поверхности
         var v;//общая длина поверхности
         var du;//Дельта (приращение) по u        
         var dv;//Дельта (приращение) по v
         var f = 100;//Увеличитель - Scale
         var a = 0.5;
         var n = 1.25;
         var R = 2.0;
         var r = 0.3;
 FormPara(vDoc)//Функция формулы параметрической поверхности
{
       traktor = new(NullObject);//Создание родительского нулевого  объекта
       traktor->SetName(cObjName);//Имя родительского нулевого  объекта
       vDoc->InsertObject(traktor,NULL,NULL);//Родителя (без детки - parent = NULL) вставить в сцену как ОПЕРАНД
du=(uMax-uMin)/Nu;//-ширина полигона-Дельта (приращение) по u =0.98      
dv=(vMax-vMin)/Nv;//-длина полигона-Дельта (приращение) по v    =0.19
             for (i=0;i<Nu;i++)//64 колонны
{
             for (j=0;j<Nv;j++)//32 ряда
{
              u=uMin+i*du;//64 колонны по ширине полигона
              v=vMin+j*dv;//32 ряда по длине полигона
                   x= r*cos(v)*cos(u)+R*cos(u)*(1+a*cos(n*u));//Формула по x
                    y= 2.5*(r*sin(v)+a*sin(n*u));                        //Формула по y
                    z= r*cos(v)*sin(u)+R*sin(u)*(1+a*cos(n*u)); //Формула по z
plos = new(PlaneObject);//Создание объекта "детки" (плоскость)
plos#ID_BASEOBJECT_REL_ROTATION:VECTOR_X=-0.803;//ротация
plos#PRIM_PLANE_SUBW=1;//один сегмент по ширине
plos#PRIM_PLANE_SUBH=1;//один сегмент по длине
plos#PRIM_PLANE_WIDTH=vys;//Ширина плоскости
plos#PRIM_PLANE_HEIGHT=shir;//Высота (длина) плоскости
plos#PRIM_AXIS=glub;//ориентация плоскости
//+x=0,-x=1,+y=2,-y=3,+z=4.-z=5
                 var sc = plos->GetContainer();//Получить контейнер для "деток" (плоскостей)
                 plos->SetContainer(sc);//Вставить в контейнер
                 plos->SetName("Para "+tostring(i+2));//Установить имена по порядку
                 plos->SetPosition(vector(x*f,y*f,z*f));//Установить объект в позицию X, Y, Z одновременно с увеличением f
                 vDoc->InsertObject(plos,traktor,NULL);//Добавить детку к родителю
                 GeEventAdd(DOCUMENT_CHANGED);//Something changed in the active document
}
}
}//конец функции формулы FormPara(vDoc)
  fRisuem(vDoc)//Рисуем! Функция отрисовки поверхности
   {
     FormPara(vDoc);
     traktor->SetBit(BIT_ACTIVE); ////Установка активного объекта (выбрать)
     GeEventAdd(DOCUMENT_CHANGED);
     return TRUE;
   }
class MyDialog : GeModalDialog//класс GeModalDialog предназначен специально для модальных диалогов.
//Это означает, что до тех пор, пока открыто диалоговое окно, остальная часть программы должна ждать,пока пользователь не закроет окно.
{
   public://Общий доступ
      CreateLayout();//определить расположение диалога
      Init();//диалог инициализирует GUI
      Command(vSob,vMess);//От каждого события, всякий раз, когда пользователь нажимает на кнопки или изменяет значения в окнах, будет вызываться  эта функция
}
   MyDialog::CreateLayout()//Создать диалог(определить расположение)
   {  
         SetTitle(cPlugName);//Установить имя плагина
         AddGroupBeginV(1000,BFH_CENTER,2,"",0);// Группа параметров объекта (id=1000, Выровнять по центру,cols=2 , rows=2 , title="", groupflags=0
      {
         AddStaticText(0,BFH_LEFT,Wind,0," Dlina ploskosti",0);
         AddEditNumber(2000,BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,Wind,0," Shirina ploskosti",0);
         AddEditNumber(2001,BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,Wind,0," Orientacia ploskosti",0);
         AddEditNumber(2002,BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,Wind,0," Scale Cube",0);
         AddEditNumber(2003,BFH_LEFT,100,0);
      }
         AddGroupEnd();//Вертикально ориентированную группу закрыть
         AddSeparatorH(0);//горизонтальная разделительная черта
         AddGroupBeginV(1001,BFH_CENTER,2,"",0);// Группа размеров поверхности
      {
         AddStaticText(0,BFH_LEFT,Wind,0," u - Min",0);
         AddEditNumber(2500,BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,Wind,0," u - Max",0);
         AddEditNumber(2501,BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,Wind,0," v - Min",0);
         AddEditNumber(2502,BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,Wind,0," v - Max",0);
         AddEditNumber(2503,BFH_LEFT,100,0);
       }
         AddGroupEnd();
         AddSeparatorH(0);
         AddGroupBeginV(1002,BFH_CENTER,2,"",0);// Группа количества итераций (субдивайдинг)
      {
         AddStaticText(0,BFH_LEFT,Wind,0," number U",0);
         AddEditNumber(2504,BFH_LEFT,100,0);
         AddStaticText(0,BFH_LEFT,Wind,0," number V",0);
         AddEditNumber(2505,BFH_LEFT,100,0);
      }
         AddGroupEnd();
         AddSeparatorH(0);
         AddDlgGroup(DR_DLGGROUP_OK);//Кнопка OK
         return TRUE;
   }
   MyDialog::Init()//диалог инициализирует GUI
   {
      SetFloat(2000,vys,-cMaxFloat,cMaxFloat,0);//id=2000-это vys,  -10000000000, +10000000000 значение float, step=0
      SetFloat(2001,shir,-cMaxFloat,cMaxFloat,0);
      SetFloat(2002,glub,-cMaxFloat,cMaxFloat,0);
      SetInt(2003,f,0,cMaxInt,0);//id=2003-это f, значение из f целое, int min, +10000000000, int step=0
      SetFloat(2500,uMin,-cMaxFloat,cMaxFloat,0);
      SetFloat(2501,uMax,-cMaxFloat,cMaxFloat,0);
      SetFloat(2502,vMin,-cMaxFloat,cMaxFloat,0);
      SetFloat(2503,vMax,-cMaxFloat,cMaxFloat,0);
      SetInt(2504,Nu,0,cMaxInt,0);
      SetInt(2505,Nv,0,cMaxInt,0);
      return TRUE;
   }
   MyDialog::Command(vSob,vMess)//От каждого события, всякий раз, когда пользователь нажимает на кнопки или изменяет значения в окнах, будет вызываться  эта функция
//id-идентификатор кнопок и окон сохраняется в vSob. кнопка OK (ID=1) запускает Command-всякий раз, когда пользователь нажимает на кнопки или изменяет значения в окнах

   {
       var vDoc;//Переменная активного документа
       StopAllThreads();//Приостановить все процессы перед исполнением
        switch (vSob)//Опрос ячеек диалога.
        //switch вычисляет значение vSob и идёт по case,(а vSob-это-id кнопок и окон) и если есть case, совпадающая с vSob, управление передаётся инструкции case
    {
      case 1 : // Start OK!
    {
                         vDoc = GetActiveDocument();//Получить активный документ
                         if (!vDoc) return FALSE;//Если его нет - return
                         fRisuem(vDoc);//Вызов функции отрисовки объекта
    }
        case 2000 : vys=GetFloat(2000);//Получить значение десятичного поля из идентификатора(2000)- вставить его в vys
//Заполняется сразу, по мере введения значений, но fRisuem(vDoc) запускается только после нажатия кнопки OK.
        case 2001 : shir=GetFloat(2001);
        case 2002 : glub=GetFloat(2002);
        case 2003 : f=GetInt(2003);
        case 2500 : uMin=GetFloat(2500);
        case 2501 : uMax=GetFloat(2501);
        case 2502 : vMin=GetFloat(2502);
        case 2503 : vMax=GetFloat(2503);
        case 2504 : Nu=GetInt(2504);
        case 2505 : Nv=GetInt(2505);
    }
        return TRUE;
    }
main(doc,op)//Главная функция, начало работы программы
{
     globDial=new(MyDialog);//Запустить диалог
     globDial->Open(-1,-1);//Запустить меню в позиции мыши
}
//*****************************************************************************End

четверг, 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.