A new way to parsing file rib (a little bit of graphics state it's implemented).

Now the scene made with Mosaic 0.4 are well interpreted (still needed some test and refactoring)
This commit is contained in:
Paolo Cignoni cignoni 2010-02-25 23:45:09 +00:00
parent 37533b35c1
commit af7c7a5cd3
3 changed files with 369 additions and 56 deletions

View File

@ -93,16 +93,22 @@ private:
//parser_rib.cpp
int numberOfDummies, numOfObject;
struct ObjValues {
/*struct ObjValues {
vcg::Matrix44f objectMatrix;
float objectBound[6]; // xmin, xmax, ymin, ymax, zmin, zmax
QStringList objectShader;
QString objectId;
QString objectDisplacementbound;
};
};*/
QStack<vcg::Matrix44f> transfMatrix;
QStack<QString> surfaceShader;
float objectBound[6]; // xmin, xmax, ymin, ymax, zmin, zmax
bool makeScene(MeshModel* m, QStringList* textureList, RichParameterSet &par, QString templatePath, QString destDirString, QStringList* shaderDirs, QStringList* textureDirs, QStringList* proceduralDirs, QStringList* imagesRendered);
QString parseObject(RibFileStack* files, QString destDir, int currentFrame, MeshModel* m, RichParameterSet &par, QStringList* textureList);
bool convertObject(FILE* fout, QString destDir, MeshModel* m, RichParameterSet &par, QStringList* textureList, ObjValues* dummyValues);
//QString parseObject(RibFileStack* files, QString destDir, int currentFrame, MeshModel* m, RichParameterSet &par, QStringList* textureList);
QString convertObject(int currentFrame, QString destDir, MeshModel* m, RichParameterSet &par, QStringList* textureList);
bool resetBound();
bool resetGraphicsState();
int writeMatrix(FILE* fout, const vcg::Matrix44f* matrix, bool transposed = true);
vcg::Matrix44f getMatrix(const QString* matrixString) const;
enum searchType{ ERR, ARCHIVE, SHADER, TEXTURE, PROCEDURAL };

View File

@ -3,7 +3,302 @@
using namespace UtilitiesHQR;
bool FilterHighQualityRender::resetBound() {
// xmin, xmax, ymin, ymax, zmin, zmax
//default RIS bound is infinite
for(int i=0; i< 6; i=i+2)
objectBound[i] = std::numeric_limits<float>::min();
for(int i=1; i<6; i=i+2)
objectBound[i] = std::numeric_limits<float>::max();
return true;
}
bool FilterHighQualityRender::resetGraphicsState() {
//graphics state initialization (only interesting things)
transfMatrix = QStack<vcg::Matrix44f>();
transfMatrix << vcg::Matrix44f::Identity();
surfaceShader = QStack<QString>();
surfaceShader << ""; //nothing to set implementation-dependent default surface shader
resetBound();
return true;
}
//read source files and write to destination file
//if it's found the attribute name with value "dummy", the following geometry statement
//are replaced with a current mesh conversion
bool FilterHighQualityRender::makeScene(MeshModel* m,
QStringList* textureList,
RichParameterSet &par,
QString templatePath,
QString destDirString,
QStringList* shaderDirs,
QStringList* textureDirs,
QStringList* proceduralDirs,
QStringList* imagesRendered)
{
//rib file structure
RibFileStack files(getDirFromPath(&templatePath)); //constructor
//open file and stream
if(!files.pushFile(&templatePath)) {
this->errorMessage = "Template path is wrong: " + templatePath;
return false;
}
//output file
FILE* fout;
fout = fopen(qPrintable(destDirString + QDir::separator() + mainFileName()),"wb");
if(fout==NULL) {
this->errorMessage = "Impossible to create file: " + destDirString + QDir::separator() + mainFileName();
return false;
}
qDebug("Starting to write rib file into %s",qPrintable(destDirString + QDir::separator() + mainFileName()));
FILE* fmain = fout; //if change the output file, the main is saved here
convertedGeometry = false; //if the mesh is already converted
int currentFrame = 0; //frame counter
bool stop = false;
bool currentDisplayTypeIsFile = false;
bool anyOtherDisplayType = false;
numberOfDummies = 0; //the dummy object could be than one (e.g. for ambient occlusion passes)
QString newFormat = "Format " +
QString::number(par.getInt("FormatX")) + " " +
QString::number(par.getInt("FormatY")) + " " +
QString::number(par.getFloat("PixelAspectRatio"));
numOfWorldBegin = 0; //the number of world begin statement found (for progress bar)
numOfObject = 0;
bool foundDummy = false;
bool solidBegin = false; //true only if define a dummy object
bool writeLine = true; //true if the line has to be write to final file
resetGraphicsState(); //transformation matrix, bound, surface shader
//reading cycle
while(!files.hasNext() && !stop) {
if(!solidBegin)
writeLine = true;
int statementType = 0; //type of statement
QString line = files.nextStatement(&statementType); //current line
switch(statementType) {
//declare other directory for the template
case ribParser::OPTION: {
QStringList token = ribParser::splitStatement(&line);
if(token[2] == "searchpath") {
int type = 0;
QStringList dirList = readSearchPath(&token,&type);
switch(type) {
case FilterHighQualityRender::ARCHIVE:
files.addSubDirs(dirList);
break;
case FilterHighQualityRender::SHADER:
*shaderDirs = dirList;
break;
case FilterHighQualityRender::TEXTURE:
*textureDirs = dirList;
break;
case FilterHighQualityRender::PROCEDURAL:
*proceduralDirs = dirList;
break;
case FilterHighQualityRender::ERR:
//ignore: maybe an error or another searchpath type (not in RISpec3.2)
break;
}
}
break;
}
//make a map (create the path if needed)
case ribParser::MAKE:
case ribParser::MAKECUBEFACEENVIRONMENT:
{
QStringList token = ribParser::splitStatement(&line);
QString path = token[2]; //for MakeTexture, MakeShadow, MakeLatLongEnvironment
if(statementType == ribParser::MAKECUBEFACEENVIRONMENT)
path = token[7];
path = getDirFromPath(&path);
//qDebug("check dir! line: %s\npath: %s",qPrintable(line),qPrintable(path));
checkDir(&destDirString,&path);
break;
}
//begin a new frame
case ribParser::FRAMEBEGIN:
{
QStringList token = ribParser::splitStatement(&line);
bool isNum;
int i = token[1].toInt(&isNum);
if(isNum)
currentFrame = i;
break;
}
//set output type (create the path if needed)
case ribParser::DISPLAY:
{
//if output is not a file the format must be the same!! framebuffer is ignored and commented
QStringList token = ribParser::splitStatement(&line);
//create the path if needed
QString path = token[2];
path = getDirFromPath(&path);
//qDebug("check dir! line: %s\npath: %s",qPrintable(line),qPrintable(path));
checkDir(&destDirString,&path);
//if there's more "Display" statement with one that's "file" is not considered a final image
if(token[5] != "framebuffer")
if (!anyOtherDisplayType && token[5] == "file") {
currentDisplayTypeIsFile = true;
QString img = token[2];
if(img.startsWith('+'))
img = img.mid(1,img.size());
*imagesRendered << img;
}
else
anyOtherDisplayType = true;
else
line = "#" + line; //if there's a framebuffer will be open pqsl automatically
break;
}
//a new world description (reset graphics state)
case ribParser::WORLDBEGIN:
{
numOfWorldBegin++;
//if there's another type of display the format is not change
if(!anyOtherDisplayType && currentDisplayTypeIsFile) {
fprintf(fout,"%s\n", qPrintable(newFormat));
}
currentDisplayTypeIsFile = false;
anyOtherDisplayType = false;
//is right?yes,because before the next WorldBegin will there be a new Display statement
resetGraphicsState(); //reset the graphics state
break;
}
//set transform in graphics state
case ribParser::TRANSFORM:
{
transfMatrix.pop();
transfMatrix.push(getMatrix(&line));
break;
}
//set surface in graphics state
case ribParser::SURFACE:
{
//the surface shader remain the same of template
surfaceShader.pop();
surfaceShader.push(line);
break;
}
//set bound in graphics state
case ribParser::BOUND:
{
//take the transformation bound
QStringList token = ribParser::splitStatement(&line);
int index = 1;
if(token[index] == "[")
index++;
for(int i=0; i<6; i++) {
bool isNumber;
float number = token[index+i].toFloat(&isNumber);
if(isNumber)
objectBound[i] = number;
}
break;
}
//looking for a dummy
case ribParser::ATTRIBUTE:
{
QStringList token = ribParser::splitStatement(&line);
//RISpec3.2 not specify what and how many attributes are there in renderman
//we take care of name only
if(token[2] == "identifier") {
//Attribute "identifier" "string name" [ "object name" ]
if(token[5] == "string name" || token[5] == "name") {
int index = 7;
if(token[index] == "[")
index++;
if(token[index] == "\"")
index++;
if(token[index].trimmed().toLower() == "dummy") {//found a dummy object?
foundDummy = true;
}
}
}
break;
}
//the begin of a set of statement to define a solid
case ribParser::SOLIDBEGIN: {
if(foundDummy) {
solidBegin = true;
writeLine = false;
}
}
//the end of solid definition
case ribParser::SOLIDEND: {
if(solidBegin) {
QString filename = convertObject(currentFrame, destDirString, m, par, textureList);
qDebug("dummy conversion, filename: %s",qPrintable(filename));
if(filename == "") { //error in parseObject
fclose(fmain);
return false;
}
fprintf(fout,"ReadArchive \"%s\"\n",qPrintable(filename));
solidBegin = false;
foundDummy = false;
}
//reset bound (and surface?)
resetBound();
break;
}
//there's a geometric statement...if there was a dummy too, replace geometry
case ribParser::GEOMETRIC: {
if(foundDummy) {
QString filename = convertObject(currentFrame, destDirString, m, par, textureList);
qDebug("dummy conversion, filename: %s",qPrintable(filename));
if(filename == "") { //error in parseObject
fclose(fmain);
return false;
}
fprintf(fout,"ReadArchive \"%s\"\n",qPrintable(filename));
writeLine = false;
foundDummy = false;
}
//reset bound (and surface?)
resetBound();
break;
}
//add a new graphics state "level"
case ribParser::ATTRIBUTEBEGIN:
{
transfMatrix.push(transfMatrix.top());
surfaceShader.push(surfaceShader.top());
break;
}
//remove a "level" to graphics state stack
case ribParser::ATTRIBUTEEND:
{
transfMatrix.pop();
surfaceShader.pop();
break;
}
//the end of scene is reached
case ribParser::NOMORESTATEMENT:
{
qDebug("Stack empty");
stop = true;
writeLine = false;
}
}
if(writeLine) {
//copy the same line in file
fprintf(fout,"%s\n",qPrintable(line));
}
}
fclose(fout);
return true;
}
/*bool FilterHighQualityRender::makeScene(MeshModel* m,
QStringList* textureList,
RichParameterSet &par,
QString templatePath,
@ -32,7 +327,7 @@ bool FilterHighQualityRender::makeScene(MeshModel* m,
FILE* fmain = fout; //if change the output file, save the main
convertedGeometry = false; //if the mesh is already converted
int currentFrame = 0;
vcg::Matrix44f transfCamera = vcg::Matrix44f::Identity();
vcg::Matrix44f transfObject = vcg::Matrix44f::Identity();
bool stop = false;
bool currentDisplayTypeIsFile = false;
bool anyOtherDisplayType = false;
@ -100,10 +395,10 @@ bool FilterHighQualityRender::makeScene(MeshModel* m,
currentFrame = i;
break;
}
case ribParser::FRAMEEND:
{
break;
}
//case ribParser::FRAMEEND:
//{
// break;
//}
case ribParser::DISPLAY:
{
//if output is not a file the format must be the same!! framebuffer is ignored and commented
@ -131,8 +426,9 @@ bool FilterHighQualityRender::makeScene(MeshModel* m,
}
case ribParser::TRANSFORM:
{
transfObject = getMatrix(&line);
break;
}
}
case ribParser::WORLDBEGIN:
{
numOfWorldBegin++;
@ -143,15 +439,16 @@ bool FilterHighQualityRender::makeScene(MeshModel* m,
currentDisplayTypeIsFile = false;
anyOtherDisplayType = false;
//is right?yes,because before the next WorldBegin will there be a new Display statement
transfObject = vcg::Matrix44f::Identity(); //reset the graphics state
break;
}
case ribParser::WORLDEND:
{
break;
}
//case ribParser::WORLDEND:
//{
// break;
//}
case ribParser::ATTRIBUTEBEGIN:
{
//is an object
//is an object (peraphs)
//write it (o convert it if it's named dummy) to another file
QString filename = parseObject(&files, destDirString, currentFrame, m, par, textureList);
qDebug("fuori: %s",qPrintable(filename));
@ -178,9 +475,10 @@ bool FilterHighQualityRender::makeScene(MeshModel* m,
}
fclose(fout);
return true;
}
}*/
//object is a sequence beetwen the statement AttributeBegin and AttributeEnd
/*
QString FilterHighQualityRender::parseObject(RibFileStack* files, QString destDirString, int currentFrame, MeshModel* m, RichParameterSet &par, QStringList* textureList) {
QString name = "object" + QString::number(numOfObject) + ".rib";
FILE* fout = fopen(qPrintable(destDirString + QDir::separator() + name),"wb");
@ -308,22 +606,30 @@ QString FilterHighQualityRender::parseObject(RibFileStack* files, QString destDi
delete current;
return name;
}
*/
//write to an opened file the attribute of object entity
//write on a opened file the attribute of object entity
bool FilterHighQualityRender::convertObject(FILE* fout, QString destDir, MeshModel* m, RichParameterSet &par, QStringList* textureList, ObjValues* dummyValues)
QString FilterHighQualityRender::convertObject(int currentFrame, QString destDir, MeshModel* m, RichParameterSet &par, QStringList* textureList)//, ObjValues* dummyValues)
{
fprintf(fout,"AttributeBegin\n");
QString name = "meshF" + QString::number(currentFrame) + "O" + QString::number(numberOfDummies) + ".rib";
numberOfDummies++;
FILE *fout = fopen(qPrintable(destDir + QDir::separator() + name),"wb");
if(fout == NULL) {
this->errorMessage = "Impossible to create the file: " + destDir + QDir::separator() + name;
return "";
}
fprintf(fout,"AttributeBegin\n");
//name
fprintf(fout,"Attribute \"identifier\" \"string name\" [ \"dummy\" ]\n");
fprintf(fout,"Attribute \"identifier\" \"string name\" [ \"meshlabMesh\" ]\n");
//id
if(dummyValues->objectId != "")
/*if(dummyValues->objectId != "")
fprintf(fout,"%s\n",qPrintable(dummyValues->objectId.trimmed()));
*/
//modify the transformation matrix
vcg::Matrix44f scaleMatrix = vcg::Matrix44f::Identity();
float dummyX = dummyValues->objectBound[1] - dummyValues->objectBound[0];
float dummyY = dummyValues->objectBound[3] - dummyValues->objectBound[2];
float dummyZ = dummyValues->objectBound[5] - dummyValues->objectBound[4];
float dummyX = objectBound[1] - objectBound[0];
float dummyY = objectBound[3] - objectBound[2];
float dummyZ = objectBound[5] - objectBound[4];
//autoscale
float scale = 1.0;
@ -365,14 +671,14 @@ bool FilterHighQualityRender::convertObject(FILE* fout, QString destDir, MeshMod
}
vcg::Matrix44f alignMatrix;
alignMatrix = alignMatrix.SetTranslate(dx,dy,dz);
vcg::Matrix44f templateMatrix = dummyValues->objectMatrix; //by default is identity
vcg::Matrix44f templateMatrix = transfMatrix.top(); //by default is identity
vcg::Matrix44f result = templateMatrix * alignMatrix * scaleMatrix * translateBBMatrix;
//write transformation matrix (after transpose it)
writeMatrix(fout, &result);
QString bound = "Bound";
for(int i=0; i<6; i++)
bound += " " + QString::number(dummyValues->objectBound[i]);
bound += " " + QString::number(objectBound[i]);
/*fprintf(fout,"Bound %g %g %g %g %g %g",
m.cm.trBB().min.X(), m.cm.trBB().max.X(),
m.cm.trBB().min.Y(), m.cm.trBB().max.Y(),
@ -384,12 +690,10 @@ bool FilterHighQualityRender::convertObject(FILE* fout, QString destDir, MeshMod
//force the shading interpolation to smooth
fprintf(fout,"ShadingInterpolation \"smooth\"\n");
//displacementBound
if(dummyValues->objectDisplacementbound != "")
fprintf(fout,"%s\n",qPrintable(dummyValues->objectDisplacementbound.trimmed()));
/*if(dummyValues->objectDisplacementbound != "")
fprintf(fout,"%s\n",qPrintable(dummyValues->objectDisplacementbound.trimmed()));*/
//shader
foreach(QString line, dummyValues->objectShader) {
fprintf(fout,"%s\n",qPrintable(line.trimmed()));
}
fprintf(fout,"%s\n",qPrintable(surfaceShader.top()));
//texture mapping (are TexCoord needed for texture mapping?)
if(!textureList->empty() > 0 && (m->cm.HasPerWedgeTexCoord() || m->cm.HasPerVertexTexCoord())) {
//multi-texture don't work!I need ad-hoc shader and to read the texture index for vertex..
@ -410,14 +714,14 @@ bool FilterHighQualityRender::convertObject(FILE* fout, QString destDir, MeshMod
if(res != vcg::tri::io::ExporterRIB<CMeshO>::E_NOERROR) {
fclose(fout);
this->errorMessage = QString(vcg::tri::io::ExporterRIB<CMeshO>::ErrorMsg(res));
return false;
return "";
}
else
Log(GLLogStream::FILTER,"Successfully converted mesh");
}
fprintf(fout,"AttributeEnd\n");
fclose(fout);
return true;
return name;
}
//return an a list of directory (separated by ':' character)

View File

@ -12,10 +12,13 @@ public:
DISPLAY,
FRAMEBEGIN,
FRAMEEND,
GEOMETRIC, //Pag. 201 RISpec3.2
MAKE,
MAKECUBEFACEENVIRONMENT,
OPTION,
READARCHIVE,
SOLIDBEGIN,
SOLIDEND,
SURFACE,
TRANSFORM,
WORLDBEGIN,
@ -35,25 +38,25 @@ public:
proc->insert("AttributeEnd", ribParser::ATTRIBUTEEND);
proc->insert("Basis", ribParser::OTHER);
proc->insert("Begin", ribParser::OTHER);
proc->insert("Blobby", ribParser::OTHER);
proc->insert("Blobby", ribParser::GEOMETRIC);
proc->insert("Bound", ribParser::BOUND);
proc->insert("Clipping", ribParser::OTHER);
proc->insert("ClippingPlane", ribParser::OTHER);
proc->insert("Color", ribParser::OTHER);
proc->insert("ColorSamples", ribParser::OTHER);
proc->insert("ConcatTransform", ribParser::OTHER);
proc->insert("Cone", ribParser::OTHER);
proc->insert("Cone", ribParser::GEOMETRIC);
proc->insert("Context", ribParser::OTHER);
proc->insert("CoordinateSystem", ribParser::OTHER);
proc->insert("CoordSysTransform", ribParser::OTHER);
proc->insert("CropWindow", ribParser::OTHER);
proc->insert("Curves", ribParser::OTHER);
proc->insert("Cylinder", ribParser::OTHER);
proc->insert("Curves", ribParser::GEOMETRIC);
proc->insert("Cylinder", ribParser::GEOMETRIC);
proc->insert("Declare", ribParser::OTHER);
proc->insert("DepthOfField", ribParser::OTHER);
proc->insert("Detail", ribParser::OTHER);
proc->insert("DetailRange", ribParser::OTHER);
proc->insert("Disk", ribParser::OTHER);
proc->insert("Disk", ribParser::GEOMETRIC);
proc->insert("Displacement", ribParser::OTHER);
proc->insert("Display", ribParser::DISPLAY);
proc->insert("End", ribParser::OTHER);
@ -64,12 +67,12 @@ public:
proc->insert("FrameAspectRatio", ribParser::OTHER);
proc->insert("FrameBegin", ribParser::FRAMEBEGIN);
proc->insert("FrameEnd", ribParser::FRAMEEND);
proc->insert("GeneralPolygon", ribParser::OTHER);
proc->insert("GeneralPolygon", ribParser::GEOMETRIC);
proc->insert("GeometricApproximation", ribParser::OTHER);
proc->insert("Geometry", ribParser::OTHER);
proc->insert("Geometry", ribParser::GEOMETRIC);
proc->insert("GetContext", ribParser::OTHER);
proc->insert("Hider", ribParser::OTHER);
proc->insert("Hyperboloid", ribParser::OTHER);
proc->insert("Hyperboloid", ribParser::GEOMETRIC);
proc->insert("Identity", ribParser::OTHER);
proc->insert("Illuminate", ribParser::OTHER);
proc->insert("Imager", ribParser::OTHER);
@ -82,24 +85,24 @@ public:
proc->insert("Matte", ribParser::OTHER);
proc->insert("MotionBegin", ribParser::OTHER);
proc->insert("MotionEnd", ribParser::OTHER);
proc->insert("NuPatch", ribParser::OTHER);
proc->insert("NuPatch", ribParser::GEOMETRIC);
proc->insert("ObjectBegin", ribParser::OTHER);
proc->insert("ObjectEnd", ribParser::OTHER);
proc->insert("ObjectInstance", ribParser::OTHER);
proc->insert("Opacity", ribParser::OTHER);
proc->insert("Option", ribParser::OPTION);
proc->insert("Orientation", ribParser::OTHER);
proc->insert("Paraboloid", ribParser::OTHER);
proc->insert("Patch", ribParser::OTHER);
proc->insert("PatchMesh", ribParser::OTHER);
proc->insert("Paraboloid", ribParser::GEOMETRIC);
proc->insert("Patch", ribParser::GEOMETRIC);
proc->insert("PatchMesh", ribParser::GEOMETRIC);
proc->insert("Perspective", ribParser::OTHER);
proc->insert("PixelFilter", ribParser::OTHER);
proc->insert("PixelSamples", ribParser::OTHER);
proc->insert("PixelVariance", ribParser::OTHER);
proc->insert("Points", ribParser::OTHER);
proc->insert("PointsGeneralPolygons", ribParser::OTHER);
proc->insert("PointsPolygons", ribParser::OTHER);
proc->insert("Polygon", ribParser::OTHER);
proc->insert("Points", ribParser::GEOMETRIC);
proc->insert("PointsGeneralPolygons", ribParser::GEOMETRIC);
proc->insert("PointsPolygons", ribParser::GEOMETRIC);
proc->insert("Polygon", ribParser::GEOMETRIC);
proc->insert("Procedural", ribParser::OTHER);
proc->insert("Projection", ribParser::OTHER);
proc->insert("Quantize", ribParser::OTHER);
@ -114,19 +117,19 @@ public:
proc->insert("Shutter", ribParser::OTHER);
proc->insert("Sides", ribParser::OTHER);
proc->insert("Skew", ribParser::OTHER);
proc->insert("SolidBegin", ribParser::OTHER);
proc->insert("SolidEnd", ribParser::OTHER);
proc->insert("Sphere", ribParser::OTHER);
proc->insert("SubdivisionMesh", ribParser::OTHER);
proc->insert("SolidBegin", ribParser::SOLIDBEGIN);
proc->insert("SolidEnd", ribParser::SOLIDEND);
proc->insert("Sphere", ribParser::GEOMETRIC);
proc->insert("SubdivisionMesh", ribParser::GEOMETRIC);
proc->insert("Surface", ribParser::SURFACE);
proc->insert("TextureCoordinates", ribParser::OTHER);
proc->insert("Torus", ribParser::OTHER);
proc->insert("Torus", ribParser::GEOMETRIC);
proc->insert("Transform", ribParser::TRANSFORM);
proc->insert("TransformBegin", ribParser::OTHER);
proc->insert("TransformEnd", ribParser::OTHER);
proc->insert("TransformPoints", ribParser::OTHER);
proc->insert("Translate", ribParser::OTHER);
proc->insert("TrimCurve", ribParser::OTHER);
proc->insert("TrimCurve", ribParser::GEOMETRIC);
proc->insert("version", ribParser::OTHER); //not a procedure, but a keyword
proc->insert("WorldBegin", ribParser::WORLDBEGIN);
proc->insert("WorldEnd", ribParser::WORLDEND);