Tuesday, August 30, 2011

Procedural Primitives 2


Depois de brigar um pouco com o c++ consegui "traduzir" mais um exemplo de procedural
primitives que vi em python para a linguagem c++ , dessa vez usando um exemplo de como gerar esferas dispostas aleatoriamente ao redor de uma esfera maior .
o codigo praticamente o mesmo
do exemplo anterior . com a diferenca
da adicao de funcoes para sortear posicoes aleatorias e normalizacao dessas posicoes para chegar no formato da esfera maior , segue abaixo o codigo

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


int const VECTOR_SIZE = 3;



class RibBox

{

public:

//constructor

RibBox();

//variaveis

std::string parFromMaya ;// sent by renderman

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

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

std::string width ;// got from splited[2]

std::string radius ;// got from splited[3]

double point[VECTOR_SIZE];// ponto aleatorio

double normPoint[VECTOR_SIZE];// ponto apos normalizado

double scalePnt[VECTOR_SIZE];// ponto apos scalado

//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

void randomPoint(double rangeMin, double rangeMax );

std::string formatTuple(std::string theTuple);

void scalePoint();

void normalize();

double randWidth(std::string max);

};


#endif


cpp:


/*

* RibBox.cpp

* classExerc

*

* Created by chrysl666 on 8/27/11.

* Copyright 2011 none. All rights reserved.

*

*/


#include

#include

#include

#include

#include


#include "RibBox.h"




RibBox::RibBox()

{

// construtor da classe

//incializa o array point

for(int i=0;i<3;i++)

{

point[i]=0;

}


}



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

std::vectorstring>& tokens,

const std::string& delimiters = " ")

{

// tokenize function para separar as informacoes em strings

// 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()

{

//parsing comandos vindos dos renderman

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

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

Tokenize(parFromMaya ,tokens);

details = tokens[0];

number = tokens[1];

width = tokens[2];

radius = tokens[3];

}



void RibBox::setRibBox()

{

//formatacao dos comandos de saida para o stream

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

std::cout<<"Points \"P\" [";

for (int i=0; i< (atoi(number.c_str())); i++)

{

randomPoint(-1, 1);

normalize();

scalePoint();

std::cout<0]<<" "<1]<<" "<2]<<" ";

}

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

std::cout<<"\"width\" [";

for (int i=0; i< (atoi(number.c_str())); i++)

{

std::cout<<randWidth(width)<<" ";

}

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

std::cout<<"\"Cs\" [";

for (int i=0; i< (atoi(number.c_str())); i++)

{

std::cout<<randWidth("1")<<" "<<randWidth("1")<<" "<<randWidth("1")<<" " ;

}

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

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

std::cout<<"\377"<

}



void RibBox::randomPoint(double rangeMin, double rangeMax )

{

//cria um valor aleatorio entre rangeMin e rangeMax para o arrayPoint

double step = rangeMax - rangeMin ;

for (int i=0; i<VECTOR_SIZE; i++)

{

point[i] = (step * static_cast <double> (rand ()) / static_cast <double> (RAND_MAX) -1);

}

}



void RibBox::normalize()

{

double mag = sqrt(point[0] * point[0] + point[1] * point[1] + point[2] * point[2]);

for (int i=0; i<VECTOR_SIZE; i++)

{

normPoint[i] = point[i]/mag;

}

}



void RibBox::scalePoint()

{


int radiusInt = atoi(radius.c_str());

for (int i=0; i<VECTOR_SIZE; i++)

{

scalePnt[i] = normPoint[i] * radiusInt;

}

}



double RibBox::randWidth(std::string max)

{

double maxInt = atof(max.c_str());

return (maxInt * static_cast <double> (rand ()) / static_cast <double> (RAND_MAX));

}

e o main.cpp :


#include

#include

#include

#include

#include "RibBox.h"



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

{

RibBox ribBoxObj;



while(1)

{

ribBoxObj.getRibBoxPar();

ribBoxObj.setRibBox();

}


}

e o comando de insercao no maya :

RiProcedural -pn "/Users/chrysl666/Desktop/devBook/classExerc02/build/Debug/classExerc02" -p "1000000 0.05 10" -b -1e38 1e38 -1e38 1e38 -1e38 1e38;




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 : ) .


Friday, August 26, 2011


Fiz um teste de raytracing ( reflex e refrax ) para um trabalho . onde tinha que produzir alguns blocos de gelo ... como no final o shader nao foi usado . resolvi postar o teste .. o shader eh um simples archshader que ja vem com o 3delight .. bem util por sinal . um pouco lento porcausa dos samples .. quem sabe um dia eu tente programar um mais leve so pra essa finalidade de fazer gelo :P ... no momento ele me serviu bem .. pena que meu shader nao foi usado no final .. mas valeu a experiencia : ) ..

Wednesday, August 10, 2011

3delight e photons

Andei testando um pouco os photons do 3delight .. mas nao gostei muito do processo .. mas acho que eh um problema na minha copia de 3delight ( ou versao ) ... pelo que parece ela nao esta gerando o arquivo de photons pra reutilizacao como deveria . deixando meus renders muito lento pra uso de photons .. mas o engracado eh que testes feitos numa versao de 3DL anterior funcionou muito bem ... bem .. segue a imagem de teste .. uma caverna feita com algumas caixas e mapas de displace . !