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 
00122 class InventorVoronoiWriter
00123 {
00124 protected:
00125 
00126     OutputFileHandler *mpOutputFileHandler; 
00127     std::string mBaseName; 
00129 public:
00130 
00138     InventorVoronoiWriter(const std::string& rDirectory,
00139                           const std::string& rBaseName,
00140                           const bool clearOutputDir=true);
00141 
00145     ~InventorVoronoiWriter();
00146 
00152     void Write(const VoronoiTessellation<3>& rTessellation);
00153 
00161     void ScaleAndWrite(VoronoiTessellation<3>& rTessellation, double scaleFactor);
00162 
00163 };
00164 
00165 
00167 // Implementation
00169 
00170 
00171 InventorVoronoiWriter::InventorVoronoiWriter(const std::string& rDirectory,
00172                                              const std::string& rBaseName,
00173                                              const bool clearOutputDir)
00174     : mBaseName(rBaseName)
00175 {
00176     mpOutputFileHandler = new OutputFileHandler(rDirectory, clearOutputDir);
00177 }
00178 
00179 InventorVoronoiWriter::~InventorVoronoiWriter()
00180 {
00181     delete mpOutputFileHandler;
00182 }
00183 
00184 void InventorVoronoiWriter::Write(const VoronoiTessellation<3>& rTessellation)
00185 {
00186     // Open inventor file
00187     std::string file_name = this->mBaseName + ".iv";
00188     out_stream p_file = this->mpOutputFileHandler->OpenOutputFile(file_name);
00189 
00190     // Write out header part of file
00191     *p_file << INVENTOR_HEADER;
00192 
00193     // Write out vertices and construct map from pointer to vertex to vertex number
00194     std::map< c_vector<double, 3>*, unsigned> vertex_number_map;
00195     for (unsigned vertex_number=0; vertex_number<rTessellation.GetNumVertices(); vertex_number++)
00196     {
00197         c_vector<double ,3>& vertex = *(rTessellation.mVertices[vertex_number]);
00198         *p_file << "        " << vertex(0) << " " << vertex(1) << " " << vertex(2) << ",\n";
00199 
00200         vertex_number_map[rTessellation.mVertices[vertex_number]] = vertex_number;
00201     }
00202 
00203     *p_file << INVENTOR_MID; //  CHANGE this to: *p_file << "\n";
00204 
00205     // Write out faces
00206     for (unsigned face_number=0; face_number<rTessellation.GetNumFaces(); face_number++)
00207     {
00208         *p_file << "        ";
00209         Face<3>& face = *(rTessellation.mFaces[face_number]);
00210         for (unsigned vertex_local_number = 0;
00211              vertex_local_number < face.GetNumVertices();
00212              vertex_local_number++)
00213         {
00214             // Note this assumes we can definitely find the vertex in the map
00215             unsigned vertex_number = vertex_number_map[&(face.rGetVertex(vertex_local_number))];
00216             *p_file << vertex_number << ", ";
00217         }
00218         *p_file << "\n";
00219     }
00220     *p_file << INVENTOR_FOOTER;
00221 }
00222 
00223 void InventorVoronoiWriter::ScaleAndWrite(VoronoiTessellation<3>& rTessellation, double scaleFactor)
00224 {
00225     if ((scaleFactor <= 0.0) || (scaleFactor > 1.0))
00226     {
00227         EXCEPTION("scaleFactor should be between 0 and 1");
00228     }
00229 
00230     // Open inventor file
00231     std::string file_name = this->mBaseName+".iv";
00232     out_stream p_file = this->mpOutputFileHandler->OpenOutputFile(file_name);
00233 
00234     // Write out header part of file
00235     *p_file << INVENTOR_HEADER;
00236 
00237     unsigned global_vertex_number = 0;
00238 
00239     // The face data which will be written to file afterwards
00240     std::vector<std::vector<unsigned> > new_faces_data;
00241     std::vector<unsigned> number_faces_per_cell;
00242 
00243     // Loop over cells and write out scaled vertices for each one, storing face info as we go
00244     for (unsigned cell_index=0; cell_index<rTessellation.mVoronoiCells.size(); cell_index++)
00245     {
00246         c_vector<double, 3>& r_cell_centre = rTessellation.mVoronoiCells[cell_index].rGetVoronoiCellCentre();
00247 
00248         // Map from position to (new) global vertex number, for this cell only
00249         std::map< c_vector<double, 3>*, unsigned> vertex_number_map;
00250 
00251         const VoronoiCell& r_cell = rTessellation.mVoronoiCells[cell_index];
00252 
00253         for (unsigned face_number=0; face_number<r_cell.GetNumFaces(); face_number++)
00254         {
00255             std::vector<unsigned> face_vertex_data;
00256 
00257             Face<3> face = r_cell.rGetFace(face_number);
00258 
00259             for (unsigned face_vertex_number=0; face_vertex_number<face.GetNumVertices(); face_vertex_number++)
00260             {
00261                 unsigned global_number_for_this_vertex;
00262 
00263                 // See if vertex is in the map
00264                 std::map<c_vector<double, 3>*, unsigned>::iterator iter = vertex_number_map.find(&(face.rGetVertex(face_vertex_number)));
00265 
00266                 if (iter != vertex_number_map.end())
00267                 {
00268                     global_number_for_this_vertex = iter->second;
00269                 }
00270                 else
00271                 {
00272                     global_number_for_this_vertex = global_vertex_number;
00273 
00274                     // Not in the map, so add it to map
00275                     vertex_number_map[&(face.rGetVertex(face_vertex_number))] = global_number_for_this_vertex;
00276                     global_vertex_number++;
00277 
00278                     // Scale the vertex and print out the new position
00279                     c_vector<double, 3> new_vertex = face.rGetVertex(face_vertex_number);
00280                     new_vertex = scaleFactor*(new_vertex - r_cell_centre) + r_cell_centre;
00281 
00282                     *p_file << "        " << new_vertex(0) << " " << new_vertex(1) << " " << new_vertex(2) << ",\n";
00283                 }
00284 
00285                 // Store this vertex's global number as a vertex for this face
00286                 face_vertex_data.push_back(global_number_for_this_vertex);
00287             }
00288 
00289             // Add the vertex data for this face to the store
00290             new_faces_data.push_back( face_vertex_data );
00291         }
00292 
00293         // Store how many faces were in this cell
00294         number_faces_per_cell.push_back(r_cell.GetNumFaces());
00295     }
00296 
00297     unsigned index = 0;
00298 
00299     // Write the face info
00300     // Loop over cells
00301     for (unsigned i=0; i<number_faces_per_cell.size(); i++)
00302     {
00303         if (number_faces_per_cell[i] > 0)
00304         {
00305             *p_file << INVENTOR_MID;
00306             // Loop over faces
00307             for (unsigned j=0; j<number_faces_per_cell[i]; j++)
00308             {
00309                 *p_file << "        ";
00310                 assert(index<new_faces_data.size());
00311                 if ( rTessellation.rGetCell(i).FaceIsOrientatedClockwise(j) )
00312                 {
00313                     for (unsigned k=0; k<new_faces_data[index].size(); k++)
00314                     {
00315                         *p_file << new_faces_data[index][k] << ", ";
00316                     }
00317                  }
00318                  else
00319                  {
00320                     for (unsigned k=0; k<new_faces_data[index].size(); k++)
00321                     {
00322                         unsigned l = new_faces_data[index].size() - k - 1;
00323                         *p_file << new_faces_data[index][l] << ", ";
00324                     }
00325                  }
00326                  *p_file << "\n";
00327                  index++;
00328             }
00329         }
00330     }
00331     *p_file << INVENTOR_FOOTER;
00332 }
00333 
00334 #endif /*INVENTORVORONOIWRITER_HPP_*/

Generated on Tue Aug 4 16:10:24 2009 for Chaste by  doxygen 1.5.5