InventorVoronoiWriter.hpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2009
00004 
00005 University of Oxford means the Chancellor, Masters and Scholars of the
00006 University of Oxford, having an administrative office at Wellington
00007 Square, Oxford OX1 2JD, UK.
00008 
00009 This file is part of Chaste.
00010 
00011 Chaste is free software: you can redistribute it and/or modify it
00012 under the terms of the GNU Lesser General Public License as published
00013 by the Free Software Foundation, either version 2.1 of the License, or
00014 (at your option) any later version.
00015 
00016 Chaste is distributed in the hope that it will be useful, but WITHOUT
00017 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
00018 FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public
00019 License for more details. The offer of Chaste under the terms of the
00020 License is subject to the License being interpreted in accordance with
00021 English Law and subject to any action against the University of Oxford
00022 being under the jurisdiction of the English Courts.
00023 
00024 You should have received a copy of the GNU Lesser General Public License
00025 along with Chaste. If not, see <http://www.gnu.org/licenses/>.
00026 
00027 */
00028 
00029 
00030 #ifndef INVENTORVORONOIWRITER_HPP_
00031 #define INVENTORVORONOIWRITER_HPP_
00032 
00033 #include "VoronoiTessellation.hpp"
00034 #include "OutputFileHandler.hpp"
00035 
00036 
00037 const std::string INVENTOR_HEADER="#Inventor V2.0 ascii \n\
00038 \n\
00039 Separator { \n\
00040   Info { \n\
00041     string \"tetrahedron.iv generated by IVREAD.\" \n\
00042     string \"Original data in file tetrahedron.wrl.\" \n\
00043   } \n\
00044   Separator { \n\
00045     LightModel { \n\
00046       model BASE_COLOR \n\
00047     } \n\
00048 \n\
00049     Material { \n\
00050       ambientColor  0.2 0.2 0.2 \n\
00051 \n\
00052       emissiveColor 0.0 0.0 0.0 \n\
00053       specularColor 1.0 1.0 1.0 \n\
00054       shininess     0.2 \n\
00055 \n\
00056     } \n\
00057     ShapeHints { \n\
00058       vertexOrdering COUNTERCLOCKWISE \n\
00059       shapeType UNKNOWN_SHAPE_TYPE \n\
00060       faceType CONVEX \n\
00061       creaseAngle 6.28319 \n\
00062     } \n\
00063 \n\
00064     DrawStyle { \n\
00065         style           LINES \n\
00066         lineWidth           3 \n\
00067         linePattern       255 \n\
00068     } \n\
00069 \n\
00070     Coordinate3 { \n\
00071       point [ \n\
00072 ";
00073 
00074 
00076 //const std::string INVENTOR_HEADER="#Inventor V2.1 ascii \n
00077 //\n
00078 //Separator { \n
00079 //    IndexedFaceSet { \n
00080 //    vertexProperty      VertexProperty { \n
00081 //        vertex  [ \n
00082 //";
00083 //
00084 //const std::string INVENTOR_MID="                ] \n
00085 //                texCoord    [  ] \n
00086 //                orderedRGBA [  ] \n
00087 //                materialBinding PER_VERTEX \n
00088 //                normalBinding   PER_PART \n
00089 //    }  \n
00090 //      coordIndex [ \n
00091 //";
00092 //
00093 // const std::string INVENTOR_FOOTER="      ]   \n
00094 //      \n
00095 //  }   \n
00096 // Translation {  \n
00097 //    translation 3 0 0  \n
00098 //    }  \n
00099 //}   \n
00100 //";
00102 //
00103 //
00104 
00105 
00106 const std::string INVENTOR_MID="      ] \n\
00107     } \n\
00108     IndexedFaceSet { \n\
00109       coordIndex [ \n\
00110 ";
00111 
00112 const std::string INVENTOR_FOOTER="      ] \n\
00113     } \n\
00114   } \n\
00115 } \n\
00116 ";
00117 
00118 
00119 
00120 class InventorVoronoiWriter
00121 {
00122 protected:
00123     OutputFileHandler *mpOutputFileHandler; 
00124     std::string mBaseName; 
00126 public:
00128     InventorVoronoiWriter(const std::string &rDirectory,
00129                           const std::string &rBaseName,
00130                           const bool clearOutputDir=true)
00131             : mBaseName(rBaseName)
00132     {
00133         mpOutputFileHandler = new OutputFileHandler(rDirectory, clearOutputDir);
00134     }
00135 
00137     ~InventorVoronoiWriter()
00138     {
00139         delete mpOutputFileHandler;
00140     }
00141 
00145     void Write(const VoronoiTessellation<3>& rTessellation)
00146     {
00147         // open inventor file
00148         std::string file_name = this->mBaseName+".iv";
00149         out_stream p_file = this->mpOutputFileHandler->OpenOutputFile(file_name);
00150 
00151         // write out header part of file
00152 
00153         *p_file << INVENTOR_HEADER;
00154 
00155         // write out vertices
00156         // and construct map from pointer to vertex to vertex number
00157 
00158         std::map< c_vector<double, 3>*, unsigned> vertex_number_map;
00159         for ( unsigned vertex_number=0;
00160               vertex_number<rTessellation.mVertices.size();
00161               vertex_number++ )
00162         {
00163             c_vector<double ,3>& vertex=*(rTessellation.mVertices[vertex_number]);
00164             *p_file << "        " << vertex(0) << " " << vertex(1) << " " << vertex(2) << ",\n";
00165 
00166             vertex_number_map[rTessellation.mVertices[vertex_number]]=vertex_number;
00167         }
00168 
00169         *p_file << INVENTOR_MID; //  CHANGE this to: *p_file << "\n";
00170 
00171         // write out faces;
00172 
00173         for (unsigned face_number=0;
00174              face_number < rTessellation.mFaces.size();
00175              face_number++)
00176         {
00177             *p_file << "        ";
00178             Face<3>& face=*(rTessellation.mFaces[face_number]);
00179             for (unsigned vertex_local_number=0;
00180                  vertex_local_number < face.mVertices.size();
00181                  vertex_local_number++)
00182             {
00183                 // note this assumes we can definitely find the vertex in the map
00184                 unsigned vertex_number=vertex_number_map[face.mVertices[vertex_local_number]];
00185                 *p_file << vertex_number << ", ";
00186             }
00187             *p_file << "\n";
00188         }
00189         *p_file << INVENTOR_FOOTER;
00190     }
00191 
00196     void ScaleAndWrite(VoronoiTessellation<3>& rTessellation, double scaleFactor)
00197     {
00198         if ((scaleFactor <= 0.0) || (scaleFactor > 1.0))
00199         {
00200             EXCEPTION("scaleFactor should be between 0 and 1");
00201         }
00202 
00203         // open inventor file
00204         std::string file_name = this->mBaseName+".iv";
00205         out_stream p_file = this->mpOutputFileHandler->OpenOutputFile(file_name);
00206 
00207         // write out header part of file
00208         *p_file << INVENTOR_HEADER;
00209 
00210         unsigned global_vertex_number = 0;
00211 
00212         // the face data which will be written to file afterwards
00213         std::vector<std::vector<unsigned> > new_faces_data;
00214         std::vector<unsigned> number_faces_per_cell;
00215 
00216         // loop over cells and write out scaled vertices for each one, storing face info as we go
00217         for (unsigned cell_index = 0; cell_index<rTessellation.mVoronoiCells.size(); cell_index++)
00218         {
00219             c_vector<double, 3>& r_cell_centre = rTessellation.mVoronoiCells[cell_index].rGetVoronoiCellCentre();
00220 
00221             // map from position to (new) global vertex number, for this cell only
00222             std::map< c_vector<double, 3>*, unsigned> vertex_number_map;
00223 
00224             const VoronoiCell& r_cell = rTessellation.mVoronoiCells[cell_index];
00225 
00226             for (unsigned face_number=0; face_number<r_cell.mFaces.size(); face_number++)
00227             {
00228                 std::vector<unsigned> face_vertex_data;
00229 
00230                 Face<3>& r_face = *(r_cell.mFaces[face_number]);
00231                 for (unsigned face_vertex_number=0; face_vertex_number<r_face.mVertices.size(); face_vertex_number++)
00232                 {
00233                     unsigned global_number_for_this_vertex;
00234 
00235                     // see if vertex is in the map
00236                     std::map< c_vector<double,3>*,unsigned>::iterator iter = vertex_number_map.find(r_face.mVertices[face_vertex_number]);
00237                     if(iter!=vertex_number_map.end())
00238                     {
00239                         global_number_for_this_vertex = iter->second;
00240                     }
00241                     else
00242                     {
00243                         global_number_for_this_vertex = global_vertex_number;
00244 
00245                         // not in the map, so add it to map
00246                         vertex_number_map[r_face.mVertices[face_vertex_number]] = global_number_for_this_vertex;
00247                         global_vertex_number++;
00248 
00249                         // scale the vertex and print out the new position
00250                         c_vector<double,3> new_vertex = *(r_face.mVertices[face_vertex_number]);
00251                         new_vertex = scaleFactor*(new_vertex - r_cell_centre) + r_cell_centre;
00252 
00253                         *p_file << "        " << new_vertex(0) << " " << new_vertex(1) << " " << new_vertex(2) << ",\n";
00254                     }
00255 
00256                     // store this vertex's global number as a vertex for this face
00257                     face_vertex_data.push_back(global_number_for_this_vertex);
00258                 }
00259 
00260                 // add the vertex data for this face to the store
00261                 new_faces_data.push_back( face_vertex_data );
00262             }
00263 
00264             // store how many faces were in this cell
00265             number_faces_per_cell.push_back(r_cell.mFaces.size());
00266         }
00267 
00268         unsigned index=0;
00269 
00270         // write the face info
00271         // Loop over cells
00272         for(unsigned i=0; i<number_faces_per_cell.size(); i++)
00273         {
00274             if(number_faces_per_cell[i]>0)
00275             {
00276                 *p_file << INVENTOR_MID;
00277                 // Loop over faces
00278                 for(unsigned j=0; j<number_faces_per_cell[i]; j++)
00279                 {
00280                     *p_file << "        ";
00281                     assert(index<new_faces_data.size());
00282                     if ((rTessellation.rGetCell(i).mOrientations)[j])
00283                     {
00284                         for(unsigned k=0; k<new_faces_data[index].size(); k++)
00285                         {
00286                             *p_file << new_faces_data[index][k] << ", ";
00287                         }
00288                      }
00289                      else
00290                      {
00291                         for(unsigned k=0; k<new_faces_data[index].size(); k++)
00292                         {
00293                             unsigned l = new_faces_data[index].size() - k - 1;
00294                             *p_file << new_faces_data[index][l] << ", ";
00295                         }
00296                      }
00297                      *p_file << "\n";
00298                      index++;
00299                 }
00300             }
00301         }
00302 
00303         *p_file << INVENTOR_FOOTER;
00304     }
00305 };
00306 
00307 #endif /*INVENTORVORONOIWRITER_HPP_*/

Generated on Wed Mar 18 12:51:56 2009 for Chaste by  doxygen 1.5.5