Monday, August 29, 2011

procedural primitives


O Renderman tem formas simples para adicionar programas dentro do RIB sem ter que literalmente fazer plugin via DSO .. . basicamente voce chama um programa em qualquer
linguagem no meio do processo de render .. e o programa envia chamadas de API ou simples
comandos de RIB via stdout streams( no caso o stdout stream usado eh o prompt do sistema).
o Renderman entende essas chamadas como c elas tivessem vindo do maya ou do RIB.
Voce pode usar qualquer linguagem pra isso .. basta saber usar a saida e entrada padrao de stream da linguagem escolhida.

existem muitos exemplos na internet de como fazer isso usando python , tcl ou "C" ,
mas eu resolvi fazer isso usando um pouco de c++OOP approach : ) ; logico que isso deixa tudo um pouco mais complicado do realmente deveria .. ja que os muitos exemplos que vi em "C" sem OOP eram ridiculos de simples e faceis : ) .. mas como a intencao eh aprender a experiencia valeu : )....meu exemplo tbm eh simples .. fazer uma esfera no meio da tela : ) usando chamadas ao meu programa sem ter essa esfera na cena do maya .. bem segue os codigos

main:

#include iostream

#include string

#include vector

#include algorithm


#include "RibBox.h"



int main (int argc, char * const argv[])

{

RibBox ribBoxObj;

while(1)

{

ribBoxObj.getRibBoxPar();

ribBoxObj.setRibBox();

}

}


header:

/*

* RibBox.h

* classExerc

*

* Created by chrysl666 on 8/27/11.

* Copyright 2011 none. All rights reserved.

*

*/


#ifndef RIBBOX_H

#define RIBBOX_H


#include

#include




class RibBox

{

public:

//constructor

RibBox();


//variaveis

std::string parFromMaya ; //sent by renderman

std::string details; // got from splited[0]

std::string scaleSize ;// got from splited[1]

//funcoes

void setRibBox(); // insert commands at render stream

void getRibBoxPar(); // get par from renderman

void Tokenize(const std::string& ,

std::vectorstring>& ,

const std::string& ); //tokenize

};


#endif


implementacao da classe:


/*

* RibBox.cpp

* classExerc

*

* Created by chrysl666 on 8/27/11.

* Copyright 2011 none. All rights reserved.

*

*/


#include

#include

#include


#include "RibBox.h"




RibBox::RibBox()

{

}



// tokenize function // precisa ser implementado antes de ser usado

void RibBox::Tokenize(const std::string& str,

std::vectorstring>& tokens,

const std::string& delimiters = " ")

{

// pula o delimitadores no inicio

std::string::size_type lastPos = str.find_first_not_of(delimiters, 0);

// acha o primeiro nao delimitador

std::string::size_type pos = str.find_first_of(delimiters, lastPos);

while (std::string::npos != pos || std::string::npos != lastPos)

{

// achou um token , add no vetor.

tokens.push_back(str.substr(lastPos, pos - lastPos));

// pula delimitadores. Note o "nao_de"

lastPos = str.find_first_not_of(delimiters, pos);

// procura proximo "nao-delimitador"

pos = str.find_first_of(delimiters, lastPos);

}

}




void RibBox::getRibBoxPar()

{

std::vectorstring> tokens; // um vector de string temporario


std::getline(std::cin,parFromMaya);

Tokenize(parFromMaya ,tokens);

details = tokens[0];

scaleSize = tokens[1];

}



void RibBox::setRibBox()

{

std::cout<<"AttributeBegin\n";

std::cout<<"Scale "<" "<" "<"\n";

std::cout<< "Sphere [3 -3 3 360]\n";

std::cout<<"AttributeEnd\n";

std::cout<<"\377"<

}


bem . depois de compilar voce vai ter um programa chamado "classExerc"
que recebe uma parametro float qualquer que representa o tamanho da esfera que voce quer criar. .. mas pro render chamar esse programa eh preciso definiar algumas coisas no maya

no meu caso eu criei um box no {0,0,0} do grid do maya e adicionei alguns attributos
do 3delight .. um Geometry , com a opcao OutPutGeometry desligado .. para esse cubo nao
ser exportado para o render . esse cubo so serve como proxy para inserir os comando que eu preciso para chamar o programa ... o segundo atributo que eu inseri foi o Mel Script - PreGeoMel -- e adicionei o seguinte comando na caixa de dialogo

RiProcedural -pn "/Users/chrysl666/Desktop/devBook/classExerc/build/Debug/classExerc" -p "0.3" -b -1e38 1e38 -1e38 1e38 -1e38 1e38;


isso diz ao render " rode o programa procedural classExerc e envie o parametro 0.3 para o stream de saida .. e reserve um espaco de bound de box de tamanho "1e38" para o objeto que o programa vai criar !


bem .. eh isso .. ao render voce vai ter uma sphere de tamanho 0.3 na tela . ao invez de um cubo.


bem .. sei que o exemplo como disse eh bem simples .. mas espero que tenha ajudado a entender como esse mecanismo funciona usando OOP .. vou tentar criar alguns exemplos mais legais no proximo post : ) .


No comments: