InventorVoronoiWriter.cpp

00001 /*
00002 
00003 Copyright (C) University of Oxford, 2005-2010
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 #include "UblasIncludes.hpp"
00030 
00031 #include <map>
00032 
00033 #include "InventorVoronoiWriter.hpp"
00034 
00035 #include "Exception.hpp"
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 const std::string INVENTOR_MID="      ] \n\
00075     } \n\
00076     IndexedFaceSet { \n\
00077       coordIndex [ \n\
00078 ";
00079 
00080 const std::string INVENTOR_FOOTER="      ] \n\
00081     } \n\
00082   } \n\
00083 } \n\
00084 ";
00085 
00086 
00087 
00088 InventorVoronoiWriter::InventorVoronoiWriter(const std::string& rDirectory,
00089                                              const std::string& rBaseName,
00090                                              const bool clearOutputDir)
00091     : mBaseName(rBaseName)
00092 {
00093     mpOutputFileHandler = new OutputFileHandler(rDirectory, clearOutputDir);
00094 }
00095 
00096 InventorVoronoiWriter::~InventorVoronoiWriter()
00097 {
00098     delete mpOutputFileHandler;
00099 }
00100 
00101 void InventorVoronoiWriter::Write(const VoronoiTessellation<3>& rTessellation)
00102 {
00103     // Open inventor file
00104     std::string file_name = this->mBaseName + ".iv";
00105     out_stream p_file = this->mpOutputFileHandler->OpenOutputFile(file_name);
00106 
00107     // Write out header part of file
00108     *p_file << INVENTOR_HEADER;
00109 
00110     // Write out vertices and construct map from pointer to vertex to vertex number
00111     std::map< c_vector<double, 3>*, unsigned> vertex_number_map;
00112     for (unsigned vertex_number=0; vertex_number<rTessellation.GetNumVertices(); vertex_number++)
00113     {
00114         c_vector<double ,3>& vertex = *(rTessellation.mVertices[vertex_number]);
00115         *p_file << "        " << vertex(0) << " " << vertex(1) << " " << vertex(2) << ",\n";
00116 
00117         vertex_number_map[rTessellation.mVertices[vertex_number]] = vertex_number;
00118     }
00119 
00120     *p_file << INVENTOR_MID; //  CHANGE this to: *p_file << "\n";
00121 
00122     // Write out faces
00123     for (unsigned face_number=0; face_number<rTessellation.GetNumFaces(); face_number++)
00124     {
00125         *p_file << "        ";
00126         Face<3>& face = *(rTessellation.mFaces[face_number]);
00127         for (unsigned vertex_local_number = 0;
00128              vertex_local_number < face.GetNumVertices();
00129              vertex_local_number++)
00130         {
00131             // Note this assumes we can definitely find the vertex in the map
00132             unsigned vertex_number = vertex_number_map[&(face.rGetVertex(vertex_local_number))];
00133            * p_file << vertex_number << ", ";
00134         }
00135         *p_file << "\n";
00136     }
00137     *p_file << INVENTOR_FOOTER;
00138 }
00139 
00140 void InventorVoronoiWriter::ScaleAndWrite(VoronoiTessellation<3>& rTessellation, double scaleFactor)
00141 {
00142     if ((scaleFactor <= 0.0) || (scaleFactor > 1.0))
00143     {
00144         EXCEPTION("scaleFactor should be between 0 and 1");
00145     }
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     *p_file << INVENTOR_HEADER;
00153 
00154     unsigned global_vertex_number = 0;
00155 
00156     // The face data which will be written to file afterwards
00157     std::vector<std::vector<unsigned> > new_faces_data;
00158     std::vector<unsigned> number_faces_per_cell;
00159 
00160     // Loop over cells and write out scaled vertices for each one, storing face info as we go
00161     for (unsigned cell_index=0; cell_index<rTessellation.mVoronoiCells.size(); cell_index++)
00162     {
00163         c_vector<double, 3>& r_cell_centre = rTessellation.mVoronoiCells[cell_index].rGetVoronoiCellCentre();
00164 
00165         // Map from position to (new) global vertex number, for this cell only
00166         std::map< c_vector<double, 3>*, unsigned> vertex_number_map;
00167 
00168         const VoronoiCell& r_cell = rTessellation.mVoronoiCells[cell_index];
00169 
00170         for (unsigned face_number=0; face_number<r_cell.GetNumFaces(); face_number++)
00171         {
00172             std::vector<unsigned> face_vertex_data;
00173 
00174             Face<3> face = r_cell.rGetFace(face_number);
00175 
00176             for (unsigned face_vertex_number=0; face_vertex_number<face.GetNumVertices(); face_vertex_number++)
00177             {
00178                 unsigned global_number_for_this_vertex;
00179 
00180                 // See if vertex is in the map
00181                 std::map<c_vector<double, 3>*, unsigned>::iterator iter = vertex_number_map.find(&(face.rGetVertex(face_vertex_number)));
00182 
00183                 if (iter != vertex_number_map.end())
00184                 {
00185                     global_number_for_this_vertex = iter->second;
00186                 }
00187                 else
00188                 {
00189                     global_number_for_this_vertex = global_vertex_number;
00190 
00191                     // Not in the map, so add it to map
00192                     vertex_number_map[&(face.rGetVertex(face_vertex_number))] = global_number_for_this_vertex;
00193                     global_vertex_number++;
00194 
00195                     // Scale the vertex and print out the new position
00196                     c_vector<double, 3> new_vertex = face.rGetVertex(face_vertex_number);
00197                     new_vertex = scaleFactor*(new_vertex - r_cell_centre) + r_cell_centre;
00198 
00199                     *p_file << "        " << new_vertex(0) << " " << new_vertex(1) << " " << new_vertex(2) << ",\n";
00200                 }
00201 
00202                 // Store this vertex's global number as a vertex for this face
00203                 face_vertex_data.push_back(global_number_for_this_vertex);
00204             }
00205 
00206             // Add the vertex data for this face to the store
00207             new_faces_data.push_back( face_vertex_data );
00208         }
00209 
00210         // Store how many faces were in this cell
00211         number_faces_per_cell.push_back(r_cell.GetNumFaces());
00212     }
00213 
00214     unsigned index = 0;
00215 
00216     // Write the face info
00217     // Loop over cells
00218     for (unsigned i=0; i<number_faces_per_cell.size(); i++)
00219     {
00220         if (number_faces_per_cell[i] > 0)
00221         {
00222             *p_file << INVENTOR_MID;
00223             // Loop over faces
00224             for (unsigned j=0; j<number_faces_per_cell[i]; j++)
00225             {
00226                 *p_file << "        ";
00227                 assert(index<new_faces_data.size());
00228                 if ( rTessellation.rGetCell(i).FaceIsOrientatedClockwise(j) )
00229                 {
00230                     for (unsigned k=0; k<new_faces_data[index].size(); k++)
00231                     {
00232                         *p_file << new_faces_data[index][k] << ", ";
00233                     }
00234                  }
00235                  else
00236                  {
00237                     for (unsigned k=0; k<new_faces_data[index].size(); k++)
00238                     {
00239                         unsigned l = new_faces_data[index].size() - k - 1;
00240                         *p_file << new_faces_data[index][l] << ", ";
00241                     }
00242                  }
00243                  *p_file << "\n";
00244                  index++;
00245             }
00246         }
00247     }
00248     *p_file << INVENTOR_FOOTER;
00249 }

Generated by  doxygen 1.6.2