воскресенье, 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