Main Page   Class Hierarchy   Compound List   File List   Compound Members   File Members  

Writers.cc

Go to the documentation of this file.
00001 /*
00002     File:       Writers.cc
00003 
00004     Function:   Implements various scene writer functions
00005 
00006     Author:     Andrew Willmott
00007 
00008     Notes:      
00009 */
00010 
00011 #include "gcl/Writers.h"
00012 #include "gcl/SceneObjects.h"
00013 
00014 #define INFO_COUT cerr
00015 
00016 Int ObjWriter::pointsWritten;
00017 FILE *ObjWriter::file = 0;
00018 
00019 Void ObjWriter::HandlePoly(
00020         Int         numVertices,
00021         Int         vertices[],
00022         Int         changed
00023     )
00024 {
00025     Int         i;
00026 
00027     if (numVertices < 0) return;
00028             
00029     if (pointsWritten < pointsAcc->NumItems())
00030     {
00031         for (i = pointsWritten; i < pointsAcc->NumItems(); i++)
00032             fprintf(file, "v %g %g %g\n", (*pointsAcc)[i][0],
00033                 (*pointsAcc)[i][1],
00034                 (*pointsAcc)[i][2]
00035             );
00036         pointsWritten = pointsAcc->NumItems();
00037     }
00038 
00039     fprintf(file, "f");
00040     for (i = 0; i < numVertices; i++)
00041         fprintf(file, " %d", vertices[i] + 1);
00042     fprintf(file, "\n");
00043 }
00044 
00045 Void ObjWriter::SaveAs(scScenePtr scene, StrConst filename)
00046 {
00047     file = fopen(filename, "w");
00048 
00049     if (!file)
00050     {
00051         _Warning("(WriteObjFile) couldn't open output file for writing");
00052         return;
00053     }
00054 
00055     fprintf(file, "# GCL scene wavefront writer\n");
00056 
00057     fprintf(file, "\n");
00058 
00059     // dump points, colours, and texture coords if we have 'em.
00060 
00061     pointsWritten = 0;
00062     scene->Decimate(SELF, DecUseMaster);
00063 
00064     fclose(file);
00065 }
00066 
00067 // --- MGF format ----------------------------------------------------------------
00068 
00069 Int MGFWriter::vertNum;
00070 Int MGFWriter::pointsWritten;
00071 FILE *MGFWriter::file = 0;
00072 
00073 Void MGFWriter::HandlePoly(
00074         Int         numVertices,
00075         Int         vertices[],
00076         Int         changed
00077     )
00078 {
00079     Int         i;
00080 
00081     const Colour wtMGF(0.265, 0.670, 0.065);
00082 
00083     if (numVertices < 0) return;
00084             
00085     if (changed)
00086     // write out new material definition
00087     {
00088         Colour      *reflectancePtr = SC_GET(Colour), rdc;
00089         Colour      *emittancePtr = SC_GET(Emittance), edc;
00090         ClrReal     rd, ed;
00091         
00092         if (reflectancePtr)
00093             rdc = *reflectancePtr;  
00094         else
00095             rdc = scPrimitive::sDefaultColour;
00096 
00097         rd = dot(wtMGF, rdc);
00098         if (rd > 0.0)
00099             rdc /= rd;
00100         rdc *= wtMGF;
00101         
00102         if (emittancePtr)
00103         {
00104             edc = *emittancePtr;
00105             // MGF 'ed' is illuminance, i.e., photometric irradiance.
00106             // we are (currently) pure irradiance
00107             edc *= 179.0;
00108             ed = dot(wtMGF, edc);
00109             if (ed > 0.0)
00110                 edc /= ed;
00111             edc *= wtMGF;
00112         }
00113         else
00114             ed = 0.0;
00115 
00116         fprintf(file, "m\n");
00117         // MGF parser has problems with cmix 0 R 0 G 0 B...
00118         if (rd > 0.0)
00119             fprintf(file,
00120                 "\tc\n\t\tcmix %g R %g G %g B\n"
00121                 "\trd %g\n",
00122                 rdc[0], rdc[1], rdc[2],
00123                 rd
00124             );
00125         else
00126             fprintf(file, 
00127                 "\trd 0.0\n"
00128             );
00129         
00130         if (ed > 0.0)
00131             fprintf(file, 
00132                 "\tc\n\t\tcmix %g R %g G %g B\n"
00133                 "\ted %g\n",
00134                 edc[0], edc[1], edc[2],
00135                 ed
00136             );
00137         else
00138             fprintf(file, 
00139                 "\ted 0.0\n"
00140             );      
00141     }
00142     
00143     if (pointsWritten < pointsAcc->NumItems())
00144     {
00145         for (i = pointsWritten; i < pointsAcc->NumItems(); i++)
00146             fprintf(file, "v v%d = \n\tp %g %g %g\n",
00147                 vertNum++,
00148                 (*pointsAcc)[i][0],
00149                 (*pointsAcc)[i][1],
00150                 (*pointsAcc)[i][2]
00151             );
00152         pointsWritten = pointsAcc->NumItems();
00153     }
00154 
00155     fprintf(file, "f");
00156     for (i = 0; i < numVertices; i++)
00157         fprintf(file, " v%d", vertices[i]);
00158     fprintf(file, "\n");
00159 }
00160 
00161 Void MGFWriter::SaveAs(scScenePtr scene, StrConst filename)
00162 {
00163     file = fopen(filename, "w");
00164 
00165     if (!file)
00166     {
00167         _Warning("(WriteMGFFile) couldn't open output file for writing");
00168         return;
00169     }
00170 
00171     fprintf(file, "# GCL scene MGF format writer\n");
00172 
00173     fprintf(file, "\n");
00174     fprintf(file, "o test\n");
00175     // MGF files are generally zup, so 'correct' our usual yup
00176     fprintf(file, "xf -rx 90\n");
00177     fprintf(file, 
00178         "c R =\n"
00179         "   cxy 0.64 0.33\n"
00180         "c G =\n"
00181         "   cxy 0.29 0.6\n"
00182         "c B =\n"
00183         "   cxy 0.15 0.06\n\n");
00184 
00185     // dump points and colours
00186     // only attempt to write out polygon meshes at the moment, though
00187     // MGF can handle more.
00188     // need to add normals etc.
00189 
00190     pointsWritten = 0;
00191     vertNum = 0;
00192     
00193     scene->Decimate(SELF, DecUseMaster);
00194 
00195     fclose(file);
00196 }
00197 
00198 // --- Rad format ----------------------------------------------------------------
00199 
00200 // this is here 'cause mgf2rad dumps core on large (polygonal) scenes
00201 // quick & dirty
00202 // note: that bug's since been fixed by Greg; it was a problem with the hash
00203 // table code.
00204 
00205 Int RadWriter::matNum;
00206 Int RadWriter::polyNum;
00207 Int RadWriter::pointsWritten;
00208 FILE *RadWriter::file = 0;
00209 
00210 Void RadWriter::HandlePoly(
00211         Int         numVertices,
00212         Int         vertices[],
00213         Int         changed
00214     )
00215 {
00216     PointList   *points = SC_GET(Points);   
00217     Int         i;
00218 
00219     if (numVertices < 0 || points == 0) return;
00220             
00221     if (changed)
00222     {
00223         Colour      *reflectancePtr = SC_GET(Colour), rdc;
00224         Colour      *emittancePtr = SC_GET(Emittance), edc;
00225         
00226         matNum++;
00227 
00228         if (reflectancePtr)
00229             rdc = *reflectancePtr;  
00230         else
00231             rdc = cOrange;
00232         
00233         if (emittancePtr)
00234         {
00235             edc = *emittancePtr;
00236             // convert from irradiance to radiance necessary for the
00237             // .rad format.
00238             edc /= vl_pi;
00239         }
00240         else
00241             edc = cBlack;
00242 
00243         if (len(edc) > 0.0)
00244         {
00245             fprintf(file, "void light mat%d\n", matNum);
00246             fprintf(file, "0\n0\n3 %g %g %g\n\n", 
00247                 edc[0], edc[1], edc[2]);
00248         }
00249         else
00250         {
00251             fprintf(file, "void plastic mat%d\n", matNum);
00252             fprintf(file, "0\n0\n5 %g %g %g 0.0 0.0\n\n", 
00253                 rdc[0], rdc[1], rdc[2]);
00254         }
00255     }
00256     
00257     fprintf(file, "mat%d polygon f%d\n0\n0\n%d\n",
00258         matNum, polyNum++, numVertices * 3
00259     );
00260 
00261     for (i = 0; i < numVertices; i++)
00262     {
00263         Point p = (*points)[vertices[i]];
00264 
00265         p = xform(transAcc, p);
00266         
00267         fprintf(file, "%-20g %-20g %-20g\n",
00268             p[0], p[1], p[2]
00269         );
00270     }
00271 
00272     fprintf(file, "\n");
00273 }
00274 
00275 Void RadWriter::SaveAs(scScenePtr scene, StrConst filename)
00276 {
00277     file = fopen(filename, "w");
00278 
00279     if (!file)
00280     {
00281         _Warning("(WriteRadFile) couldn't open output file for writing");
00282         return;
00283     }
00284 
00285     fprintf(file, "# GCL scene Radiance format writer\n");
00286 
00287     fprintf(file, "\n");
00288 
00289     pointsWritten = 0;
00290     matNum = 0;
00291     polyNum = 1;
00292     
00293     scene->Decimate(SELF, 0);
00294 
00295     fclose(file);
00296 }
00297 
00298 // --- Generic writer -------------------------------------------------------------
00299 
00300 Void SceneWriter::Save(scScenePtr scene, FileName filename)
00301 {
00302     INFO_COUT << "Writing " << filename.GetPath() << endl;
00303 
00304     if (filename.GetExtension() == "mgf")
00305         MGFWriter().SaveAs(scene, filename.GetPath());
00306     else if (filename.GetExtension() == "obj")
00307         ObjWriter().SaveAs(scene, filename.GetPath());
00308     else if (filename.GetExtension() == "rad")
00309         RadWriter().SaveAs(scene, filename.GetPath());
00310     else if (filename.GetExtension() == "sl")
00311     {
00312         ofstream fout;
00313 
00314         fout.open(filename.GetPath());
00315         if (fout)
00316         {
00317             scene->Print(fout);
00318             fout.close();
00319         }
00320         else
00321             perror("Couldn't open output file");
00322     }
00323     else
00324     {
00325         INFO_COUT << "unknown scene file extension " << filename.GetExtension()
00326             << ": saving as default (obj)" << endl;
00327         filename.SetExtension("obj");
00328         ObjWriter().SaveAs(scene, filename.GetPath());
00329     }
00330 }
00331 
00332 static StrConst tSceneWriterFormats[] = 
00333 {
00334     "sl",           "GCL's scene language.",
00335     "obj",          "Wavefront .obj ascii format [default]",
00336     "mgf",          "material and geometry format",
00337     "rad",          "radiance format",
00338     "mrb",          "binary multi-resolution model(s)",
00339     0
00340 };
00341 
00342 Void SceneWriter::PrintSupportedFormats(ostream &s)
00343 {
00344     StrConst    *str = tSceneWriterFormats;
00345     Int         i;
00346     
00347     while (*str)
00348     {
00349         s << "  " << *str;
00350         for (i = 0; i < 4 - str->Length(); i++)
00351             s << ' ';
00352         str++;
00353         s << *str++ << endl;
00354     }
00355 }

Generated at Sat Aug 5 00:17:05 2000 for Graphics Class Library by doxygen 1.1.0 written by Dimitri van Heesch, © 1997-2000