четверг, 20 декабря 2012 г.

На этом функции заканчиваются. В следующий раз попробуем собрать всё вместе.
А пока несколько источников по программированию COFFEE:
*************
_COFFEE BIBLE - скрипты для книги
_COFFEE_R_13_SDK_CHM.chm
_COFFEE_R12_SDK_CHM_2010_09_08.chm
COFFEE_Book_sample.pdf
CoffeeBible_Updated 11-13-10.pdf
DevKitchen_R_11_2009.pdf
R12Development.pdf
Coffee ID's_R12.txt
Render Settings.txt
ViewSetting.txt
***************
Всё это в файле _COFFEE BIBLE.ZIP по адресу:
http://narod.ru/disk/64639356001.bf76c4448ae0dde52e18466795e5363f/_COFFEE%20BIBLE.ZIP.html

Функция изменения позиции объекта

Функция изменения позиции объекта:
Иногда требуется изменить положение объекта и вызывается эта функция.

//**************************

PosObj(vDoc)//Функция изменения позиции объекта (позиция по Y,Z, и поворот на 90 градусов по Z) окончательная
{
para#ID_BASEOBJECT_REL_POSITION:VECTOR_X=paraPX;//Позиция по X (paraPX)
para#ID_BASEOBJECT_REL_POSITION:VECTOR_Y=paraPY;//Позиция по Y (paraPY)
para#ID_BASEOBJECT_REL_POSITION:VECTOR_Z=paraPZ;//Позиция по Z (paraPZ) (paraPX)
para#ID_BASEOBJECT_REL_ROTATION:VECTOR_X=paraRX;//Поворот на 90 градусов (paraRX) (paraRY) (paraRZ)
para#ID_BASEOBJECT_REL_ROTATION:VECTOR_Y=paraRY;//Поворот на 90 градусов (paraRX) (paraRY) (paraRZ)
para#ID_BASEOBJECT_REL_ROTATION:VECTOR_Z=paraRZ;//Поворот на 90 градусов (paraRX) (paraRY) (paraRZ)
}
//**********************

Функция конца рисования и установки плоскости и света

Функция конца рисования и установки плоскости и света:
Эта функция производит визуальные изменения в документе, то есть устанавливает сцену и объект в центре её.

//**************************

fPara(vDoc)//Функция конца рисования и установки плоскости и света
{
 fSetActiveObject(vDoc,para);//Вызов функции fSetActiveObject
 GeEventAdd(DOCUMENT_CHANGED);//Вызов функции GeEventAdd с аргументом NEW_ACTIVE_OBJECT с изменением в активном документе
  para->Message(MSG_UPDATE);

  return TRUE;
   }
//*********************

Функция активизации объекта

Функция активизации объекта:
Здесь мы устанавливаем "сцену".

  1. Делаем наш объект активным - vObj->SetBit(BIT_AOBJ);
  2. Вызываем Функцию создания фонга для материалов
  3. Вызов функцию проверки наличия 3х материалов, если они остались от предыдущего объекта, стираем их.
  4. Вызываем Функцию создания нового материала и деактивируем его
  5. Вызываем функцию создания плоскости, над которой будет находиться объект.
  6. Вызываем функцию создания Sky primitive (небо).
  7. Вызываем функцию создания Light primitive (свет)
  8. Деактивируем объект


//*****************************

fSetActiveObject(vDoc,vObj)//Функция активизации объекта
   {
       var vAObj = GetActiveObject(vDoc);
        if (vAObj) vAObj->DelBit(BIT_AOBJ);
        vObj->SetBit(BIT_AOBJ);
        GeEventAdd(NEW_ACTIVE_OBJECT);

CreaPhong(vDoc);//Функция создания фонга
ProvMat(vDoc);//Вызов функции проверки наличия 3х материалов
CreaMat(vDoc);//Функция создания нового материала
vObj->DelBit(BIT_ACTIVE); //Unselect the object in the hierarchy
CreaPlane(vDoc);//Вызов функции создания плоскости
CreaSky(vDoc); // Вызов функции создания Sky primitive
CreaLight(vDoc);  // Вызов функции создания Light primitive
//vOp = vDoc->GetActiveObject();
//vOp->DelBit(BIT_ACTIVE); //Unselect the object in the hierarchy
}//конец Функции активизации объекта
//***************************

Дополнительный рисователь полигонов по x,y,z

Дополнительный рисователь полигонов по x,y,z:
Иногда, при сложной форме объекта, из-за допусков точности возникают "дырки" в объекте. Чтобы их компенсировать, применяется эта функция.

//************************

RisPolDop(vDoc)//Дополнительный рисователь полигонов по x,y,z (кое-где он не нужен)
{
             for (j=0;j<Nv;j++)
{
             P1=j;
             P2=j+1;
             P4=Nv*(Nu-1)+j;
             P3=Nv*(Nu-1)+j+1;
             para->SetPolygon(zz,P4,P3,P2,P1);
             zz=zz+1;
}
             P1=0;
             P2=Nv-1;
             P3=Nv*Nu-1;
             P4=Nv*(Nu-1);
             para->SetPolygon(zz,P1,P2,P3,P4);
}
//Конец дополнительного рисователя полигонов по x,y,z

Главный рисователь полигонов по x,y,z-координатам.

Главный рисователь полигонов по x,y,z-координатам:
Здесь мы просто вычисляем порядковые номера четырёх точек каждого полигона, то есть именно здесь привязываем вычисленные 3D точки к конкретным полигонам. Это делает "цикл" по рядам и колоннам полигонов.
Точки сохраняются в массиве переменной SetPolygon
zz - номер полигона по порядку.
Второй "цикл", это закрытие шва нашей "простыни".
//*************************

RisPol(vDoc)//Главный рисователь полигонов по x,y,z-координатам
{
                  zz=0;
                  for (i=0;i<Nu-1;i++)
{
                  for (j=0;j<Nv-1;j++)
{
                    P1=i*Nv+j;
                    P2=i*Nv+j+1;
                    P4=(i+1)*Nv+j;
                    P3=(i+1)*Nv+j+1;
                    para->SetPolygon(zz,P1,P2,P3,P4);
                    zz=zz+1;
}
}
            for (i=0;i<Nu-1;i++)
{
             P1=i*Nv;
             P2=(i+1)*Nv-1;
             P4=(i+1)*Nv;
             P3=(i+2)*Nv-1;
             para->SetPolygon(zz,P4,P3,P2,P1);
             zz=zz+1;
}
}
//**************************

среда, 19 декабря 2012 г.

Функция формулы объекта

Функция формулы объекта:
Немного теории.
Чтобы построить трёхмерный объект, надо вычислить его точки в пространстве и по этим точкам установить полигоны (плоскости).
Проще всего представить себе простыню, которой мы обернём объект. Так, как мы оборачиваем объект по кругу, мы должны применить число ПИ (3,14), оно наиболее точно сводит концы с концами. Итак у нас имеется простына шириной =U и длиной равной V.
Протяженность по U будет равна от uMin до uMax, в данном случае от 0 до 4ПИ.
Протяженность по V будет равна от vMin до vMax, в данном случае от 0 до 2ПИ.
Ещё одна важная вещь. Количество полигонов. Чем меньше полигонов (плоскостей, построенных по точкам), тем грубее форма объекта, чем больше полигонов, тем глаже форма, но время на расчёты увеличивается. То есть полигоны на нашей простыне будут выглядеть, как квадраты. По стороне V это будут ряды Nv=300, по стороне U это будут колонны Nu=300. Ширина и длина каждого полигона будет равна:

du=(uMax-uMin)/Nu;//-ширина полигона
dv=(vMax-vMin)/Nv;//-длина полигона
В данной функции мы начинаем вычислять положения точек объекта в 3D пространстве. То есть каждая точка должна получить значения по оси X, Y и Z. Эти значения будут вычисляться по следующей формуле:

                x= r*cos(v)*cos(u)+R*cos(u)*(1+a*cos(n*u));
                 y= 2.5*(r*sin(v)+a*sin(n*u));
                 z= r*cos(v)*sin(u)+R*sin(u)*(1+a*cos(n*u));
Чтобы вычислить все точки объекта, мы делаем так называемый "цикл", то есть по очереди вычисляем точки рядов полигонов и двигаемся по  их колоннам.
Все три координаты будут запоминаться в виде вектора в конце каждого цикла в переменной SetPoint:
para->SetPoint(zz,vector(x*f,y*f,z*f));
var f = Увеличение-Scale


var zz = номер каждой точки по порядку.
//*************************

 Form1(vDoc)//Функция формулы №1-Endless
{
      var uMin = 0.0;
      var uMax = 25.13274122;
      var vMin = 0.0;
      var vMax = 6.283185307;
du=(uMax-uMin)/Nu;//-ширина полигона
dv=(vMax-vMin)/Nv;//-длина полигона
             zz=0;
             for (i=0;i<Nu;i++)//300 колонн
{
             for (j=0;j<Nv;j++)//300 рядов
{
              u=uMin+i*du;//Идём по колоннам через ширину полигона
              v=vMin+j*dv;//Идём по рядам через длину полигона
var f = 75;//Увеличение-Scale
      var a = .5;//Общий диаметр .5
      var n = 2.25;//Количество 2.25
      var R = 2.0;//Увеличение 7,8,9,
      var r = 0.3;//Удлинение 0.3-шар
                 x= r*cos(v)*cos(u)+R*cos(u)*(1+a*cos(n*u));
                 y= 2.5*(r*sin(v)+a*sin(n*u));
                 z= r*cos(v)*sin(u)+R*sin(u)*(1+a*cos(n*u));
                para->SetPoint(zz,vector(x*f,y*f,z*f));
                zz=zz+1;
}
}
}//конец функции формулы №1
//**************************************

Функция установки документа.

Продолжаю...
__________________
Функция установки документа:

  1. Даём имя объекту, которое будет видно в Менеджере - para->SetName(cObjName).
  2. Все шаги отмены должны быть собраны в одном месте, иначе, как пишут разработчики "смешные вещи будут происходить" -      vDoc->StartUndo();      vDoc->AddUndo(UNDO_OBJECT_NEW,para);      vDoc->EndUndo();.
  3. Создаём конструкторы переменных и тагов:
     vVarChanged = new(VariableChanged); 
    vBackupTags = new(BackupTags);

    Создаём переменную и массив для точек объекта:

         SP=Nu*Nv;      
          vPointAry = new(array, SP);
          para->SetPoints(vPointAry);
    Создаём переменную и массив для полигонов объекта:

         SQ=Nu*Nv+1;
         vPolyAry = new(array, SQ*4);
          para->SetPolygons(vPolyAry);
    Сохраняем и обнуляем переменные и таги объекта:

    vBackupTags->Init(para);
          vVarChanged->Init(0, SP);

    vBackupTags->Init(para);//Init-Бэкапит таги para(предохранитель нехватки памяти)
          vVarChanged->Init(0, SQ);//Init-Бэкапит все точки SQ(предохранитель нехватки памяти).
    vBackupTags->Restore();
    Вставляем Объект в ОбъектИерархию, как родителя:
    vDoc->InsertObject(para,NULL,NULL);
    Зафиксировать изменения в документе:
    GeEventAdd(DOCUMENT_CHANGED);





//**************************

 UstDoc(vDoc)//Функция установки документа
{
     DelOldObj(vDoc);
     var vVarChanged,vBackupTags;
      para=new(PolygonObject);
      if (!para) return NULL;
      para->SetName(cObjName);
      vDoc->StartUndo();
      vDoc->AddUndo(UNDO_OBJECT_NEW,para);
      vDoc->EndUndo();
 vVarChanged = new(VariableChanged);
      vBackupTags = new(BackupTags);
      Nv=Nv05*2;
      SP=Nu*Nv;
      SQ=Nu*Nv+1;
      vPointAry = new(array, SP);
      para->SetPoints(vPointAry);
      vBackupTags->Init(para);
      vVarChanged->Init(0, SP);
      if (!para->Message(MSG_POINTS_CHANGED, vVarChanged))
   {
 vBackupTags->Restore();
      return NULL;
      }
      vPolyAry = new(array, SQ*4);
      para->SetPolygons(vPolyAry);
      vBackupTags->Init(para);//Init-Бэкапит таги para(предохранитель нехватки памяти)
      vVarChanged->Init(0, SQ);//Init-Бэкапит все точки SQ(предохранитель нехватки памяти)
      if (!para->Message(MSG_POLYGONS_CHANGED, vVarChanged))//Если нет изменений в para-возврат
      {
      vBackupTags->Restore();
      return NULL;//(это нуль, но в адресном пространстве)
      }
   // Вставить Объект в ОбъектИерархию
      vDoc->InsertObject(para,NULL,NULL);
       GeEventAdd(DOCUMENT_CHANGED);
     
}//конец функции установки документа
//****************************************

пятница, 14 декабря 2012 г.

Работа с командной функцией.

Работа с командной функцией Command(vID,vMSG).
Здесь мы строим выбранный в диалоге объект.

  1. Приостановливаем все процессы перед исполнением StopAllThreads().
  2. Начинаем опрашивать ячейки диалога case 1, у нас одна ячейки и она срабатывает от нажатия кнопки ОК.
  3. Получить значение из переменной комбобокса, сравнить с 1, так, как он первый (вообще будет до ста объектов).
  4. Войдём в активный документ GetActiveDocument().
  5. Вызовем функцию установки документа UstDoc(vDoc), позже будет о ней речь.
  6. Вызовем функцию формулы первого объекта Form1(vDoc).
  7. Вызовем функцию главного рисователя полигонов по x,y,z координатам RisPol(vDoc).
  8. Вызовем функцию дополнительного рисователя полигонов по x,y,z (кое-где он не нужен) RisPolDop(vDoc).
  9. Вызовем функцию начала рисования fPara(vDoc).
  10. Вызовем функцию изменения позиции объекта (позиция по Y,Z, и поворот на 90 градусов по Z) PosObj(vDoc).


//***************************

MyDialog::Command(vID,vMSG)
{
      var vDoc;//Переменная vDoc
      StopAllThreads();//Приостановить все процессы перед исполнением
      switch (vID)//Опрос ячеек диалога,
{
       case 1 : // нажатие кнопки OK!
{
       var x0 = GetItem(2001);//Получить значение подобъекта из id=2001 (комбобокс) - 1 в нашем случае, вообще будет до 100
       if (x0==1)//Сравнить это значение с 1 (подобъекта №1)
{
                         vDoc = GetActiveDocument();
                         if (!vDoc) return FALSE;
                         UstDoc(vDoc); //Вызов функции установки документа
                         Form1(vDoc);//Вызов функции формулы
                         RisPol(vDoc); //Вызов функции главного рисователя полигонов по x,y,z, координатам.
                         RisPolDop(vDoc); //Вызов функции дополнительного рисователя полигонов по x,y,z (кое-где он не нужен)
                         fPara(vDoc);//Функция начала рисования
                         paraRX=2;
                         PosObj(vDoc);//Функция изменения позиции объекта (позиция по Y,Z, и поворот на 90 градусов по Z)
                         return TRUE;
         break;    //Прервать
}

}
           return TRUE;
}

//****************************

Функция определения структуры диалога.

Функция определения структуры диалога.

  1. Установливаем имя диалога плагина.
  2. Инициируем первую вертикальную группу, ставим разделитель.
  3. Добавляем комбобокс с переменной (2001), параметрами и координатами
  4. Вставляем в бокс имя нашего первого объекта ("1. Endless") и делаем его первым показываемым в диалоге SetItem(2001,  1).
  5. Ставим разделитель и конец первой вертикальной группы.
  6. Инициируем вторую вертикальную группу.
  7. Добавляем в диалог кнопку ОК - AddDlgGroup(DR_DLGGROUP_OK)
  8. Ставим конец второй вертикальной группы.


//***************************

MyDialog::CreateLayout()
{    
     SetTitle(cPlugName);    //  Установить имя диалога плагина
AddGroupBeginV(1001, BFH_SCALEFIT,1,"group",0);//Начало группы V-вертикальная
AddSeparatorH(0);//Разделитель
AddComboBox(2001,  BFH_SCALEFIT|BFV_CENTER, 250, 0);//КомбоБокс
AddItem(2001, 1, "1. Endless");          //ParaObject №1

SetItem(2001,  1);//Установить в комбобоксе по умолчанию Подобъект №1
AddSeparatorH(0);//Разделитель
AddGroupEnd();//Конец группы
AddGroupBeginV(1004, BFH_SCALEFIT,1,"group",0);//Начало группы V-вертикальная
AddSeparatorH(0);//Разделитель
AddDlgGroup(DR_DLGGROUP_OK);
AddGroupEnd();//Конец группы
     return TRUE;//Возвращает значение=1
}
//******************************

Вызов функции диалога.

Вызов функции диалога.
GeModalDialog - означает, что диалог вызывается и постоянно находится на экране, пока мы вводим данные. СИНЕМА находится в ожидании, пока мы не нажмём кнопку OK или CANCEL.

//*****************************

class MyDialog :GeModalDialog
{
   public:
   CreateLayout();//Вызвать функцию определения структуры диалога.
   Command(vID,vMSG);//Всякий раз, когда пользователь изменяет данные внутри диалога, вызывается эта функция, чтобы зафиксировать изменения.
}
//*************************

Главная функция, с которой начинается работа программы

Если мы хотим проследить работу всей программы, мы должны найти первым делом функцию main(doc,op). В данном случае мы видим, что первой запускается функция (подпрограмма) диалога (MyDialog), которая отрисовывается в позиции мыши Open(-1,-1). По умолчанию это правый нижний угол экрана в двенадцатой СИНЕМе, В тринадцатой это, почему-то левый верхний угол.
//******************************

 main(doc,op)//Это главная функция, с которой начинается работа программы
{
           var d = new(MyDialog);//Вызвать меню диалога
           d->Open(-1,-1);//Запустить меню в позиции мыши
}
//*******************************

воскресенье, 9 декабря 2012 г.

Это будет первый объект, который появится на сцене:

Дальше будет интереснее. Собственно само создание объекта и создание диалога для выбора различных объектов.
Создание источника света "небо".
//*****************

CreaSky(vDoc)
{
sky = new(SkyObject);  // creates a LightObject primitive
vDoc->InsertObject(sky,NULL,NULL);//Add it to the scene
sky->SetBit(BIT_ACTIVE); //Сделать небо активным (выбрать)
CreaPhong(vDoc);//Вызов функции создания фонга
CreaMat(vDoc);//Вызов функции создания нового материала
}
//*****************
Создание источника света.
//********************

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=526.4;//позиция по X
lait#ID_BASEOBJECT_REL_POSITION:VECTOR_Y=314;//позиция по Y
lait#ID_BASEOBJECT_REL_POSITION:VECTOR_Z=-410.1;//позиция по Z
CallCommand(12520);//вызов SpotLight плюс Light.Target.1
}
//*********************
Создание плоскости, на которой будут находиться объекты.
//***********************************

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);//Вызов функции создания нового материала
//mat#MATERIAL_USE_REFLECTION=TRUE;
vOp=vDoc->GetActiveObject(); //Load Selected object into memory
var pos = vOp->GetPosition();//Получить текущую позицию плоскости
plo->SetPosition(vector(pos.x= 9.9, pos.y=-204.7.3, pos.z =17.4)); //Опустить плоскость по Y на 150 (1,5 метра)
plo#ID_BASEOBJECT_REL_SCALE:VECTOR_X=1.8;//Увеличить по Х до 18 метров
plo#ID_BASEOBJECT_REL_SCALE:VECTOR_Z=1.8;//Увеличить по Z до 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
}
//***********************************
Создание нового материала и тагтекстуры.
//***********************************

CreaMat(vDoc)//Функция создания нового материала
{
mat = new(Material); //Create a new material in memory
mat->SetName("par"); // Имя материала
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 field
vOp=vDoc->GetActiveObject(); //Load Selected object into memory
vOp->InsertTag(texTag , NULL); //Add it to the scene
}
//***********************************
Проверим, также наличие двух предыдущих материалов и сотрём их.
//***********************************

ProvMat(vDoc)//функция проверки наличия 2х предыдущих материалов
{
fmat = vDoc->GetFirstMaterial();
 if (!fmat) return;
fmat = vDoc->GetFirstMaterial()->GetName();
if(fmat=="par")
{
fmat = vDoc->GetFirstMaterial();
fmat->Remove();
fmat = vDoc->GetFirstMaterial();
 if (!fmat) return;
fmat->Remove();
fmat = vDoc->GetFirstMaterial();
 if (!fmat) return;
fmat->Remove();
}
//***********************************
Чтобы при каждом запуске не оставались хвосты в виде предыдущих объектов, необходимо предварительно проверить их наличие и стереть их.
//***********************************

DelOldObj(vDoc)//функция проверки наличия и стирания 5 предыдущих объектов (свет, свет, плоскость, параобъект, нуль)
{
fobj = vDoc->GetFirstObject();
 if (!fobj) return;
fobj->Remove();
fobj = vDoc->GetFirstObject();
 if (!fobj) return;
fobj->Remove();
fobj = vDoc->GetFirstObject();
 if (!fobj) return;
fobj->Remove();
fobj = vDoc->GetFirstObject();
 if (!fobj) return;
fobj->Remove();
fobj = vDoc->GetFirstObject();
 if (!fobj) return;
fobj->Remove();
fobj = vDoc->GetFirstObject();
 if (!fobj) return;
fobj->Remove();
}
//***********************************
Создание тега Фонга для того, чтобы был виден цвет.
//***********************************

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
}
//***********************************
Выбор случайного цвета. Каждый раз цвета сцены и объекта будут разные.

//***********************************

RandCol(vDoc)//Функция выбора случайного цвета
{
starttime = time();//Возвращает время от старта работы CINEMA_4D
random = new(Random);//Переменная со значением от Random-псевдо-случайная функция
random->Init(starttime);//Инициализация Random-псевдо-случайной функции
rd=(random->Get01());//Инициализация красного цвета
gr=(random->Get01());//Инициализация зелёного цвета
bl=(random->Get01());//Инициализация синего цвета
}
//***********************************
Вначале запускаем список констант:

//***********************************

  const var cPluginID = 1000777;
       const var cPlugName = "ParaObject";
       const var cPlugHelp = "ParaObject";
       const var cObjName = "ParaObject";
      var Breite=200;
      var cMaxFloat=10000000000;
      var cMaxInt=100000000;
      var para;
      var gDial;
      var uMin = 0.0;
      var uMax = 6.283185307;//pi2
      var vMin = 0.0;
      var vMax = 6.283185307;//pi2
      var R = 10.0;//Внешний радиус
      var r = 2.0;//Внутренний радиус
      var f = 2;//Увеличение-Scale
      var Nu = 300;//Субдивайдинг (итерации) по u
      var Nv05 = 150;//Субдивайдинг (итерации) по v, уменьшенные в два раза
      var Nv;//Субдивайдинг (итерации) по v
      var i,j;        
      var zz;        
      var du;        
      var dv;        
      var SP;        
      var SQ;        
      var x,y,z;      
      var u,v;        
      var P1,P2,P3,P4;
      var vObj,        
      vSP,              
      vPointAry,        
      vSQ,            
      vPolyAry;
//Переменные для сцены***********************
var lait;//свет
var starttime;// время от старта работы CINEMA_4D
var plo;//плоскость
var texTag;//таг текстуры
var mat;//материал
var tph;//таг фонга
var vOp;//операнд активного документа
var vDoc;//активный документ
var random;//случайная
var rd;//красного цвета
var gr;//зелёного цвета
var bl;//синего цвета
CreaPhong(vDoc);//Функция создания фонга
CreaMat(vDoc);//Функция создания нового материала
var fmat;//первый материал
var nmat;//следующий материал
var fobj;//первый объект
var paraPX=0;//Позиция по X
var paraPY=50;//Позиция по Y
var paraPZ=-120;//Позиция по Z
var paraRX=0;//Поворот по X
var paraRY=0;//Поворот по Y
var paraRZ=1.5708;//Поворот на 90 градусов по Z
var paraSX=1.6;//Увеличение по X
var paraSY=1.6;//Увеличение по Y
var paraSZ=1.6;//Увеличение по Z
var sky;
//***********************************

Я начинаю публикацию своего нового скрипта.

Я начинаю публикацию своего нового скрипта. Запускаться он будет в Скрипт Менеджере. Называется будет: "FREETTER". Это будет такая сцена или арена, где будут появляться различные интересные параметрические объекты. Параметрические, это значит построенные по математическим формулам. Например такие:

Состоит ФРИТТЕР из подпрограмм. Каждая подпрограмма будет напечатана в отдельном сообщении и в конце мы попробуем их собрать вместе.

понедельник, 16 июля 2012 г.

Вот ещё один интересный скрипт:

Нажимаем кнопку "Execute", потом кнопку " ОК"
Проверено в 12 и 13 версии СИНЕМЫ.

Вот, если что, ссылка на сам файл:
http://narod.ru/disk/56658972001.b159b8caa9e6ce5c386376f340d34fdd/My_Tri_Spline.CSC.html

Называется он: 
My_Tri_Spline.CSC (в имени файла не должно быть русских букв)
Ввести его через File/Open в 13 версии или File/Import в 12 версии в самом Менеджере скриптов.


//************************


      const var cPluginID = 0000077;
      const var cPlugName = "Knots";
      const var cPlugHelp = "Knots";
      var i,k,m,p;
      var x,y,z;
      var N=300;//Количество кругов
var NTri=100;//Количество итераций у кругов
      var qObj;
      var gDial;
      var t,dt,tTri,dtTri;//Шаги количества и итераций
var qSplin;
var vPointAry;
var f;
var vOp;
var vDoc;
var Trix;
var Triy;
var Triz;
var qSplinTri;
var vPointAryTri;
//*******************
UstDoc(vDoc)
{
qSplin = AllocObject(Ospline); // Creates the empty spline object
vPointAry = new(array,N); //New array to store the spline points info
qSplin->SetPoints(vPointAry);// Execute the changes to the spline points
var vc = new(VariableChanged); // *Important. Must be used for splines
vc->Init(0,N);  // *Important. Must be used for splines
qSplin->Message(MSG_POINTS_CHANGED,vc); // *Important. Must be used for splines
qSplin#SPLINEOBJECT_TYPE = 4; // make it a Bezier type
qSplin->SetName("Spline ");//Установить имена по порядку
vDoc->InsertObject(qSplin,NULL,NULL); // Insert it into the Object Manager
qSplin->SetBit(BIT_ACTIVE); //Сделать qSplin активной (выбрать)
}
//*******************
UstTriDoc(vDoc)
{
qSplinTri = AllocObject(Ospline); // Creates the empty spline object
vPointAryTri = new(array,N); //New array to store the spline points info
qSplinTri->SetPoints(vPointAryTri);// Execute the changes to the spline points
var vcTri = new(VariableChanged); // *Important. Must be used for splines
vcTri->Init(0,NTri);  // *Important. Must be used for splines
qSplinTri->Message(MSG_POINTS_CHANGED,vcTri); // *Important. Must be used for splines
qSplinTri#SPLINEOBJECT_TYPE = 4; // make it a Bezier type
qSplinTri->SetName("SplineTri ");//Установить имена по порядку
vDoc->InsertObject(qSplinTri,NULL,NULL); // Insert it into the Object Manager
qSplinTri->SetBit(BIT_ACTIVE); //Сделать qSplin активной (выбрать)
}
//******************
pipeit(obj, vDoc)
{
var sweep = AllocObject(5118);// Создать пустой Sweep NURBS (5118) объект
vDoc->InsertObject(sweep ,qSplin, vDoc->GetActiveObject());//Вставить Sweep NURBS в документ "родителем" к пипеитируемому активному объекту
vDoc->AddUndo(UNDO_NEW, sweep);//Включить в UNDO
vDoc->SetActiveObject(sweep);// Активировать Sweep NURBS
    var tag = AllocTag(5612);// Создать пустой (5612) тэг
    sweep->InsertTag(tag);//Вставить в Sweep NURBS тэг 5612
    var name=obj->GetName();//Получить имя сплайна
    sweep->SetName(name+"_pipe");//Изменить имя Sweep NURBS
   var objpos   = obj->GetMg();//Получить глобальную матрицу и вставить её в  объект сплайн (Matrix global)
   sweep->SetMg(objpos);//Вставить  глобальную матрицу в Sweep NURBS
obj#ID_BASEOBJECT_POSITION:VECTOR_X=0;
obj#ID_BASEOBJECT_POSITION:VECTOR_Y=-200;
obj#ID_BASEOBJECT_POSITION:VECTOR_Z=0;
//obj#ID_BASEOBJECT_ROTATION:VECTOR_X=1.571;
//obj#ID_BASEOBJECT_ROTATION:VECTOR_Y=1.571;
obj#ID_BASEOBJECT_ROTATION:VECTOR_Z=1.571;
object()#CAP_START=1;// Заделать концы 0-None, 1=Cap, 2=Fillet, 3=Fillet Cap
object()#CAP_END=1;// Заделать концы  0-None, 1=Cap, 2=Fillet, 3=Fillet Cap
   var circle = AllocObject(5179);//Создать пустой объект n-Side, сплайновый шестиугольник
vDoc->InsertObject(circle, null, vDoc->GetActiveObject());//Вставить n-Side, как "детку" к активному объекту Sweep NURBS
vDoc->AddUndo(UNDO_NEW, circle);//Включить в UNDO
vDoc->SetActiveObject(circle);//Сделать n-Side активным
object()#PRIM_NSIDE_RADIUS = 2; // Радиус трубы
object()#PRIM_PLANE = 0;//Ориентация xy=0-труба, zy=1-плоско, xz=2-плоско
object()#PRIM_NSIDE_SIDES = 12; // Профиль-сабдивайдинг трубы
    object()#SPLINEOBJECT_INTERPOLATION=0;//Intermediate Points 0-None, 1=Natural, 2=Uniform, 3=Adaptive, 4=Subdivided
obj->Remove();//Стереть старый наш сплайн, (использовать Remove () сначала, если объект уже вставлена ​​в другую иерархию.)
obj->InsertUnder(sweep);//Вставить сплайн как "детку"
circle->Remove();//Стереть трубу,( использовать Remove () сначала, если объект уже вставлена ​​в другую иерархию.)
circle->InsertUnder(sweep);//Вставить трубу как "детку"
}
//*******************
SerchMassiv(vDoc)
{
var m = 0;
var selected = new(array, N*N); // Количество наших сплайнов (массив)
var obj = object();//Это первый наш активированный объект
if(!obj) return;
while(obj->SearchNext(BIT_AOBJ))//Выяснить сколько объектов всего начиная с нашего
{
selected[m] = obj;// i-объекты в массив
m++;
obj = obj->SearchNext(BIT_AOBJ);//Считать следующие объекты пока они не кончатся
}
selected[m++] = obj;//Кончились? Последний внести в конец массива, i-будет означать количество объектов
//DeselectAll();//Сбросить все последующие не наши (кроме тех которые мы выбрали)
    pipeit(qSplin,vDoc);//Пипеитировать сплайны!
}
//********************************
//*******************************
RisTriSpline(vDoc)
{
         //dtTri=2.1*PI/NTri;//ширина шага, 2,1 - круг
   dtTri=4*PI/NTri;//ширина шага, 2,1 - круг
         tTri=0;

         for (k=0;k<NTri;k++)//N - количество итераций
{
              tTri=tTri+dtTri;//ширина шага dt
f=250;
                  x = (cos(tTri));
                   y = (sin(tTri));
                   z =0;

            qSplinTri->SetPoint(k,vector(x*f,z*f,y*f));
}
qSplinTri#ID_BASEOBJECT_REL_POSITION:VECTOR_X=Trix;
qSplinTri#ID_BASEOBJECT_REL_POSITION:VECTOR_Y=Triy;
qSplinTri#ID_BASEOBJECT_REL_POSITION:VECTOR_Z=Triz;
//qSplinTri#ID_BASEOBJECT_REL_ROTATION:VECTOR_X=0.785;
//qSplinTri#ID_BASEOBJECT_REL_ROTATION:VECTOR_Y=1.571;
//qSplinTri#ID_BASEOBJECT_REL_ROTATION:VECTOR_Z=1.571;
 pipeit(qSplinTri,vDoc);//Пипеитировать сплайны!
}
//*******************************
RisSpline(vDoc)
{
f=250;
         dt=4*PI/N;//ширина шага, 2,1 - круг
         t=0;
         for (i=0;i<N;i++)//N - количество итераций
{
              t=t+dt;//ширина шага dt
             
                   x = (cos(t));
                   y =(sin(t));
                   z =0;
              //qSplin->SetPoint(i,vector(x*f,z*f,y*f));
//*************************
UstTriDoc(vDoc);
Trix=x*f;
Triy=y*f;
Triz=z*f;
RisTriSpline(vDoc);
}
}
// ******************************************************************
class MyDialog : GeModalDialog
{
   public:
      CreateLayout();
      Command(vID,vMSG);
}
  MyDialog::CreateLayout()
   {  
       SetTitle(cPlugName);
       AddDlgGroup(DR_DLGGROUP_OK);
      return TRUE;
   }
   MyDialog::Command(vID,vMSG)
   {
     StopAllThreads();
      switch (vID)
    {
      case 1 : // Start OK
    {
                       vDoc = GetActiveDocument();
                       if (!vDoc) return FALSE;
UstDoc(vDoc);
RisSpline(vDoc);
//SerchMassiv(vDoc);
   }
   }
      return TRUE;
   }
//***************
main(doc,op)
{
gDial=new(MyDialog);
gDial->Open(-1,-1);
}
//*****************************

суббота, 14 июля 2012 г.

Читает ли кто-нибудь этот блог, нужно ли мне его вести? Материала у меня много, но надо ли это кому-нибудь? На русском языке, вообще-то мало кто пишет о коффее, может и читать некому? А какие замечательные графические скрипты у меня есть...Пальчики оближешь!
Например такой:

Этот скрипт создаёт красивую параметрическую фигуру из нескольких параллельных "узлов".
Скрипт работает только в Скрипт-менеджере, так, как главная функция main(doc,op) содержит операнды "doc" и "op".
Проверено на 12 и 13 версии СИНЕМЫ.
После нажатия на кнопку "Execute", должна под курсором мыши появиться кнопка "OK", надо её нажать, появится картинка.
В 13 версии СИНЕМЫ кнопка "ОК" появляется в левом, верхнем углу экрана.
Если процессор слабый, то надо подождать пока идут расчёты, у меня это длится секунды три.

//*************************************
//This Script was made by senior 14.07.12


       const var cPluginID = 1000777;
       const var cPlugName = "ParaObject";
       const var cPlugHelp = "ParaObject";
       const var cObjName = "ParaObject";
      var cMaxFloat=10000000000;
      var cMaxInt=100000000;
      var para;
      var gDial;
      var Nu = 100;//Субдивайдинг (итерации) по u -Количество полигонов
      var Nv = 100;//Субдивайдинг (итерации) по v -Количество полигоно
      var i,j,k,m;//Индексы      
      var zz;        
      var du;        
      var dv;      
      var SP;      
      var SQ;      
      var x,y,z;      
      var u,v;      
      var P1,P2,P3,P4;
      var vObj,        
      vSP,            
      vPointAry,      
      vSQ,            
      vPolyAry;
//****************************
var Tri;    //Количество групп
var Quart;//Количество итераций в группе
var Trii;//Индекс
var Trij;//Индекс
var Trix=0;//Смещение объекта по x
var Triy=0;//Смещение объекта по y
var Triz=0;//Смещение объекта по z
var TriNu=8;//Субдивайдинг (ширина шага) по u
var TriNv=8;//Субдивайдинг (длина шага) по v
var povtor;//"родитель"
var fTri;
//***************
var mat;
var texTag;
var starttime;//Возвращает время от старта работы CINEMA_4D
var random;//Переменная со значением от Random-псевдо-случайная функция
var rd;//Инициализация красного цвета
var gr;//Инициализация зелёного цвета
var bl;//Инициализация синего цвета
var vOp;
var vDoc;
//Функции:************************************
//*************
RandCol(vDoc)//Функция выбора случайного цвета
{
starttime = time();//Возвращает время от старта работы CINEMA_4D
random = new(Random);//Переменная со значением от Random-псевдо-случайная функция
random->Init(starttime);//Инициализация Random-псевдо-случайной функции
rd=(random->Get01());//Инициализация красного цвета
gr=(random->Get01());//Инициализация зелёного цвета
bl=(random->Get01());//Инициализация синего цвета
}
//*************
CreaMat(vDoc)//Функция создания нового материала
{
mat = new(Material); //Create a new material in memory
mat->SetName("par"); // Имя материала
RandCol(vDoc);//Вызов Random-псевдо-случайной функции
mat#MATERIAL_COLOR_COLOR = vector(rd,gr,bl); // Установка цвета в red-green-blue
vDoc->InsertMaterial( mat, NULL ); // Установка нового материала в Material Manager

//mat#MATERIAL_USE_REFLECTION=TRUE;
//mat#MATERIAL_USE_REFLECTION = COLOR, vector(rd,gr,bl) ; // Установка цвета в red-green-blue

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 field
vOp=vDoc->GetActiveObject(); //Load Selected object into memory
vOp->InsertTag(texTag , NULL); //Add it to the scene
}
//*************
RisPol(vDoc)//Главный рисователь полигонов по x,y,z
{
                  zz=0;
                  for (i=0;i<Nu-1;i++)
{
                  for (j=0;j<Nv-1;j++)
{
                    P1=i*Nv+j;
                    P2=i*Nv+j+1;
                    P4=(i+1)*Nv+j;
                    P3=(i+1)*Nv+j+1;
                    para->SetPolygon(zz,P1,P2,P3,P4);
                    zz=zz+1;
}
}
            for (i=0;i<Nu-1;i++)
{
             P1=i*Nv;
             P2=(i+1)*Nv-1;
             P4=(i+1)*Nv;
             P3=(i+2)*Nv-1;
             para->SetPolygon(zz,P4,P3,P2,P1);
             zz=zz+1;
}
}
//*******************************Конец Главного рисователя полигонов по x,y,z, координатам 2048 точек!
            RisPolDop(vDoc)//Дополнительный рисователь полигонов по x,y,z.(кое-где он не нужен)
{
             for (j=0;j<Nv;j++)
{
             P1=j;
             P2=j+1;
             P4=Nv*(Nu-1)+j;
             P3=Nv*(Nu-1)+j+1;
             para->SetPolygon(zz,P4,P3,P2,P1);
             zz=zz+1;
}
             P1=0;
             P2=Nv-1;
             P3=Nv*Nu-1;
             P4=Nv*(Nu-1);
             para->SetPolygon(zz,P1,P2,P3,P4);
}
//*************************************Конец дополнительного рисователя полигонов по x,y,z
    UstDoc(vDoc)//Функция установки документа
{
      var vVarChanged,vBackupTags;
      para=new(PolygonObject);
      if (!para) return NULL;
      para->SetName(cObjName);
      vDoc->StartUndo();
      vDoc->AddUndo(UNDO_OBJECT_NEW,para);
      vDoc->EndUndo();
 vVarChanged = new(VariableChanged);
      vBackupTags = new(BackupTags);
      SP=Nu*Nv;
      SQ=Nu*Nv+1;
      vPointAry = new(array, SP);
      para->SetPoints(vPointAry);
      vBackupTags->Init(para);
      vVarChanged->Init(0, SP);
      if (!para->Message(MSG_POINTS_CHANGED, vVarChanged))
   {
 vBackupTags->Restore();
      return NULL;
      }
      vPolyAry = new(array, SQ*4);
      para->SetPolygons(vPolyAry);
      vBackupTags->Init(para);//Init-Бэкапит таги para(предохранитель нехватки памяти)
      vVarChanged->Init(0, SQ);//Init-Бэкапит все точки SQ(предохранитель нехватки памяти)
      if (!para->Message(MSG_POLYGONS_CHANGED, vVarChanged))//Если нет изменений в para-возврат
      {
      vBackupTags->Restore();
      return NULL;//(это нуль, но в адресном пространстве)
      }
      vDoc->InsertObject(para,povtor,NULL);// Вставить объект "детку"в "родителя"
      GeEventAdd(DOCUMENT_CHANGED);
}//****************************конец функции установки документа
   fSetActiveObject(vDoc,vObj)//Функция активирования (выделения) объекта
{
        var vAObj = GetActiveObject(vDoc);
        if (vAObj) vAObj->DelBit(BIT_AOBJ);
        vObj->SetBit(BIT_AOBJ);
        GeEventAdd(NEW_ACTIVE_OBJECT);
}//************************************************
         fPara(vDoc)
{
        fSetActiveObject(vDoc,para);//Вызов функции fSetActiveObject //Функция активирования (выделения) объекта
        GeEventAdd(DOCUMENT_CHANGED);//Вызов функции GeEventAdd с аргументом NEW_ACTIVE_OBJECT с изменением в активном документе
        para->Message(MSG_UPDATE);//Принять изменения в документе
        return TRUE;
}//***********************************************
             Form(vDoc)//Функция формулы объекта
{
      var uMin = 0.0;
      var uMax = pi2;
      var vMin = 0.0;
      var vMax = pi2;
var f = .5;//Увеличение-Scale
var r=10;
du=(uMax-uMin)/Nu;//-ширина полигона
dv=(vMax-vMin)/Nv;//-длина полигона
             zz=0;
             for (i=0;i<Nu;i++)//64 колонны
{
             for (j=0;j<Nv;j++)//32 ряда
{
              u=uMin+i*du;//64 колонны по ширине полигона
              v=vMin+j*dv;//32 ряда по длине полигона
var t=u;
                   x = 88*cos(t) + 115*sin(t) - 475*cos(2*t) - 127*sin(2*t) - 87*cos(3*t) + 36*sin(3*t) + 11*cos(4*t) - 19*sin(4*t);
                   y = 89*cos(t) - 32*sin(t) - 172*cos(2*t) + 294*sin(2*t) + 76*cos(3*t) + 102*sin(3*t) - 61*cos(4*t) + 113*sin(4*t);
                   z = r*cos(v) - 69*sin(t) + 34*cos(2*t) + 223*sin(2*t) + 16*cos(3*t)+ 120*sin(3*t) + 42*cos(4*t) - 125*sin(4*t);
x = x+Trix;
y = y+Triy ;
z = z+Triz;
//println("x = ",x);
                para->SetPoint(zz,vector(x*f,y*f,z*f));
                zz=zz+1;
}
}
}//конец функции формулы объекта
//*****************************************
Povtor(vDoc)//Функция изменения положения объекта
{
var Quart=35;//Количество итераций, 35=круг
var TriNu=8;//Сужение между кольцами после=8 - расширение по u до =8
var TriNv=8;//Сужение между кольцами после=8 - расширение по v до =8
var fTri = 400;//Увеличитель расстояния между шагами (объектами))
var TriuMin = -pi2;
var TriuMax = pi2;
var TrivMin = -pi/9;
var TrivMax = pi/9;
var Tridu=(TriuMax-TriuMin)/TriNu;//-ширина полигона
var Tridv=(TrivMax-TrivMin)/TriNv;//-длина полигона
k=1;
for (m=0;m<Quart;m++)// //Количество итераций
{
u=TriuMin+k*Tridu;//-ширина полигона
v=TrivMin+m*Tridv;//-длина полигона
                    x= sin(u)*cos(v);//Формула перемещения объекта по x
//x= cos(v);
                    y= pow((sin(u)),2);         //Формула перемещения объекта по y
                    //z= sin(u)*sin(v); //Формула перемещения объекта по z
 z= cos(v/2)*sin(v);
//z=0;
Trix=x*fTri;  //Координата повтора по x
Triy=y*fTri; //Координата повтора по y
Triz=z*fTri; //Координата повтора по z

                         UstDoc(vDoc);//Установка объекта повтора в документ
                         Form(vDoc);//Функция формулы повтора
                         RisPol(vDoc);//Главный рисователь полигонов повтора по x,y,z
                         RisPolDop(vDoc);//Дополнительный рисователь полигонов повтора по x,y,z.(кое-где он не нужен)
//fPara(vDoc);//Активировать объект
//CreaMat(vDoc);//Функция создания нового материала
}
}
//**********************Коней функции изменения положения объекта
         class MyDialog :GeModalDialog
{
         public:
         CreateLayout();// определить расположение диалога.
         Command(vID,vMSG);//Всякий раз, когда пользователь нажимает на гаджет, и / или изменяет его значения эта функция будет вызвана.
}
         MyDialog::CreateLayout()
{  
        SetTitle(cPlugName);  //Установить имя диалога плагина
        AddDlgGroup(DR_DLGGROUP_OK); //  Кнопка OK, начало Расчета (Старт)
         return TRUE;//Возвращает значение=1
}
        MyDialog::Command(vID,vMSG)
{
        var vDoc;//Переменная vDoc
       StopAllThreads();//Приостановить все процессы перед исполнением
        switch (vID)//Опрос ячеек диалога,
{
        case 1 : // нажатие кнопки OK (Start)
{
                         vDoc = GetActiveDocument();
                         if (!vDoc) return FALSE;
povtor=new(PolygonObject);//Создать "родительский" объект
vDoc->InsertObject(povtor,NULL,NULL);//Вставить "родительский" объект в документ
povtor#ID_BASEOBJECT_REL_POSITION:VECTOR_X=34;
povtor#ID_BASEOBJECT_REL_POSITION:VECTOR_Y=-136;
povtor#ID_BASEOBJECT_REL_POSITION:VECTOR_Z=-185;
povtor#ID_BASEOBJECT_REL_ROTATION:VECTOR_X=0.284;
povtor#ID_BASEOBJECT_REL_ROTATION:VECTOR_Y=0;
povtor#ID_BASEOBJECT_REL_ROTATION:VECTOR_Z=0;
Povtor(vDoc);
}
}
                          return TRUE;
}
    main(doc,op)//Это главная функция, с которой начинается работа программы-Главпродукт
{
     gDial=new(MyDialog);//Вызвать меню диалога
     gDial->Open(-1,-1);//Запустить меню в позиции мыши
}

     
//***************************************