WMWriteMesh.cpp 10.8 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
//---------------------------------------------------------------------------
//
// Project: OpenWalnut ( http://www.openwalnut.org )
//
// Copyright 2009 OpenWalnut Community, BSV-Leipzig and CNCF-CBS
// For more information see http://www.openwalnut.org/copying
//
// This file is part of OpenWalnut.
//
// OpenWalnut is free software: you can redistribute it and/or modify
// it under the terms of the GNU Lesser General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// OpenWalnut is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
// GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with OpenWalnut. If not, see <http://www.gnu.org/licenses/>.
//
//---------------------------------------------------------------------------

#include <string>

27 28 29
#include "core/common/math/WMath.h"
#include "core/common/WPathHelper.h"
#include "core/kernel/WKernel.h"
Alexander Wiebel's avatar
Alexander Wiebel committed
30
#include "WMWriteMesh.xpm"
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
#include "WMWriteMesh.h"

// This line is needed by the module loader to actually find your module. Do not remove. Do NOT add a ";" here.
W_LOADABLE_MODULE( WMWriteMesh )

WMWriteMesh::WMWriteMesh():
    WModule()
{
}

WMWriteMesh::~WMWriteMesh()
{
    // Cleanup!
}

boost::shared_ptr< WModule > WMWriteMesh::factory() const
{
    // See "src/modules/template/" for an extensively documented example.
    return boost::shared_ptr< WModule >( new WMWriteMesh() );
}

const char** WMWriteMesh::getXPMIcon() const
{
Alexander Wiebel's avatar
Alexander Wiebel committed
54
    return WMWriteMesh_xpm;
55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82
}
const std::string WMWriteMesh::getName() const
{
    // Specify your module name here. This name must be UNIQUE!
    return "WriteMesh";
}

const std::string WMWriteMesh::getDescription() const
{
    // Specify your module description here. Be detailed. This text is read by the user.
    // See "src/modules/template/" for an extensively documented example.
    return "Someone should add some documentation here. "
    "Probably the best person would be the modules's creator, i.e. \"wiebel\"";
}

void WMWriteMesh::connectors()
{
    m_meshInput = boost::shared_ptr< WModuleInputData < WTriangleMesh > >(
        new WModuleInputData< WTriangleMesh >( shared_from_this(), "mesh", "The mesh to save" )
        );

    addConnector( m_meshInput );

    WModule::connectors();
}

void WMWriteMesh::properties()
{
83
    m_propCondition = boost::shared_ptr< WCondition >( new WCondition() );
84
    m_savePropGroup = m_properties->addPropertyGroup( "Save Surface",  "" );
85
    m_saveTriggerProp = m_savePropGroup->addProperty( "Do Save",  "Press!", WPVBaseTypes::PV_TRIGGER_READY, m_propCondition );
86 87
    m_meshFile = m_savePropGroup->addProperty( "Mesh File", "", WPathHelper::getAppPath() );

88 89 90 91 92 93 94 95 96
    m_fileTypeSelectionsList = boost::shared_ptr< WItemSelection >( new WItemSelection() );
    m_fileTypeSelectionsList->addItem( "VTK ASCII", "" );
    m_fileTypeSelectionsList->addItem( "json", "" );

    m_fileTypeSelection = m_properties->addProperty( "File type",  "file type.", m_fileTypeSelectionsList->getSelectorFirst() );
       WPropertyHelper::PC_SELECTONLYONE::addTo( m_fileTypeSelection );

    m_writeColors = m_properties->addProperty( "Write colors", "", true, m_propCondition );

97 98 99 100 101 102 103 104
    WModule::properties();
}

void WMWriteMesh::moduleMain()
{
    // Put the code for your module's main functionality here.
    // See "src/modules/template/" for an extensively documented example.
    m_moduleState.add( m_meshInput->getDataChangedCondition() );
105
    m_moduleState.add( m_propCondition );
106 107 108 109 110 111 112

    // signal ready state
    ready();

    // loop until the module container requests the module to quit
    while( !m_shutdownFlag() )
    {
113 114 115 116 117
        // this waits for m_moduleState to fire. By default, this is only the m_shutdownFlag condition.
        // NOTE: you can add your own conditions to m_moduleState using m_moduleState.add( ... )
        m_moduleState.wait();

        if( m_triMesh != m_meshInput->getData() )
118
        {
119
            m_triMesh = m_meshInput->getData();
120 121
        }

122
        m_saveTriggerProp->set( WPVBaseTypes::PV_TRIGGER_READY, false );
123

124 125 126 127 128 129 130 131 132 133 134 135 136 137 138
        switch ( m_fileTypeSelection->get( true ).getItemIndexOfSelected( 0 ) )
        {
            case 0:
                debugLog() << "type VTK ASCII file selected";
                saveVTKASCII();
                break;
            case 1:
                debugLog() << "type json file selected";
                saveJson();
                break;
            default:
                debugLog() << "this shouldn't be reached";
                break;
        }
        m_saveTriggerProp->set( WPVBaseTypes::PV_TRIGGER_READY, true );
139 140 141
    }
}

142
bool WMWriteMesh::saveVTKASCII() const
143 144 145 146 147 148 149 150
{
    if( !m_triMesh )
    {
        return false;
    }

    if( m_triMesh->vertSize() == 0 )
    {
151
        WLogger::getLogger()->addLogMessage( "Will not write file that contains 0 vertices.", "Write Mesh", LL_ERROR );
152 153 154 155 156
        return false;
    }

    if( m_triMesh->triangleSize() == 0 )
    {
157
        WLogger::getLogger()->addLogMessage( "Will not write file that contains 0 triangles.", "Write Mesh", LL_ERROR );
158 159 160 161 162 163
        return false;
    }

    const char* c_file = m_meshFile->get().file_string().c_str();
    std::ofstream dataFile( c_file, std::ios_base::binary );

164
    if ( dataFile )
165
    {
166
        WLogger::getLogger()->addLogMessage( "opening file", "Write Mesh", LL_DEBUG );
167 168 169
    }
    else
    {
170
        WLogger::getLogger()->addLogMessage( "open file failed" + m_meshFile->get().file_string() , "Write Mesh", LL_ERROR );
171 172 173 174 175
        return false;
    }

    dataFile.precision( 16 );

176
    WLogger::getLogger()->addLogMessage( "start writing file", "Write Mesh", LL_DEBUG );
177 178 179 180 181
    dataFile << ( "# vtk DataFile Version 2.0\n" );
    dataFile << ( "generated using OpenWalnut\n" );
    dataFile << ( "ASCII\n" );
    dataFile << ( "DATASET UNSTRUCTURED_GRID\n" );

182
    WPosition point;
183
    dataFile << "POINTS " << m_triMesh->vertSize() << " float\n";
184
    for ( size_t i = 0; i < m_triMesh->vertSize(); ++i )
185 186
    {
        point = m_triMesh->getVertexAsPosition( i );
Mathias Goldau's avatar
Mathias Goldau committed
187
        if( !( myIsfinite( point[0] ) && myIsfinite( point[1] ) && myIsfinite( point[2] ) ) )
188
        {
189
            WLogger::getLogger()->addLogMessage( "Will not write file from data that contains NAN or INF.", "Write Mesh", LL_ERROR );
190 191 192 193 194 195
            return false;
        }
        dataFile << point[0] << " " << point[1] << " " << point[2] << "\n";
    }

    dataFile << "CELLS " << m_triMesh->triangleSize() << " " << m_triMesh->triangleSize() * 4 << "\n";
196
    for ( size_t i = 0; i < m_triMesh->triangleSize(); ++i )
197 198 199 200 201 202
    {
        dataFile << "3 " << m_triMesh->getTriVertId0( i ) << " "
                 <<  m_triMesh->getTriVertId1( i ) << " "
                 <<  m_triMesh->getTriVertId2( i ) << "\n";
    }
    dataFile << "CELL_TYPES "<< m_triMesh->triangleSize() <<"\n";
203
    for ( size_t i = 0; i < m_triMesh->triangleSize(); ++i )
204 205 206 207 208 209
    {
        dataFile << "5\n";
    }
    dataFile << "POINT_DATA " << m_triMesh->vertSize() << "\n";
    dataFile << "SCALARS scalars float\n";
    dataFile << "LOOKUP_TABLE default\n";
210
    for ( size_t i = 0; i < m_triMesh->vertSize(); ++i )
211 212 213 214 215 216 217
    {
        dataFile << "0\n";
    }
    dataFile.close();
    WLogger::getLogger()->addLogMessage( "saving done", "Write Mesh", LL_DEBUG );
    return true;
}
218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314

bool WMWriteMesh::saveJson() const
{
    if( !m_triMesh )
    {
        return false;
    }

    if( m_triMesh->vertSize() == 0 )
    {
        WLogger::getLogger()->addLogMessage( "Will not write file that contains 0 vertices.", "Write Mesh", LL_ERROR );
        return false;
    }

    if( m_triMesh->triangleSize() == 0 )
    {
        WLogger::getLogger()->addLogMessage( "Will not write file that contains 0 triangles.", "Write Mesh", LL_ERROR );
        return false;
    }

    const char* c_file = m_meshFile->get().file_string().c_str();
    std::ofstream dataFile( c_file, std::ios_base::binary );

    if ( dataFile )
    {
        WLogger::getLogger()->addLogMessage( "opening file", "Write Mesh", LL_DEBUG );
    }
    else
    {
        WLogger::getLogger()->addLogMessage( "open file failed" + m_meshFile->get().file_string() , "Write Mesh", LL_ERROR );
        return false;
    }

    dataFile.precision( 7 );

    WLogger::getLogger()->addLogMessage( "start writing file", "Write Mesh", LL_DEBUG );


    dataFile << ( "{\n" );
    dataFile << ( "    \"vertices\" : [" );
    WPosition point;
    for ( size_t i = 0; i < m_triMesh->vertSize() - 1; ++i )
    {
        point = m_triMesh->getVertexAsPosition( i );
        if( !( myIsfinite( point[0] ) && myIsfinite( point[1] ) && myIsfinite( point[2] ) ) )
        {
            WLogger::getLogger()->addLogMessage( "Will not write file from data that contains NAN or INF.", "Write Mesh", LL_ERROR );
            return false;
        }
        dataFile << point[0] << "," << point[1] << "," << point[2] << ",";
    }
    point = m_triMesh->getVertexAsPosition( m_triMesh->vertSize() - 1 );
    dataFile << point[0] << "," << point[1] << "," << point[2] << "],\n";

    dataFile << ( "    \"normals\" : [" );
    WPosition normal;
    for ( size_t i = 0; i < m_triMesh->vertSize() - 1; ++i )
    {
        normal = m_triMesh->getNormalAsPosition( i );
        if( !( myIsfinite( normal[0] ) && myIsfinite( normal[1] ) && myIsfinite( normal[2] ) ) )
        {
            WLogger::getLogger()->addLogMessage( "Will not write file from data that contains NAN or INF.", "Write Mesh", LL_ERROR );
            return false;
        }
        dataFile << normal[0] << "," << normal[1] << "," << normal[2] << ",";
    }
    normal = m_triMesh->getNormalAsPosition( m_triMesh->vertSize() - 1 );
    dataFile << normal[0] << "," << normal[1] << "," << normal[2] << "],\n";

    dataFile << ( "    \"indices\" : [" );
    for ( size_t i = 0; i < m_triMesh->triangleSize() - 1; ++i )
    {
        dataFile << m_triMesh->getTriVertId0( i ) << "," <<  m_triMesh->getTriVertId1( i ) << "," <<  m_triMesh->getTriVertId2( i ) << ",";
    }
    size_t i = m_triMesh->triangleSize() - 1;
    dataFile << m_triMesh->getTriVertId0( i ) << "," <<  m_triMesh->getTriVertId1( i ) << "," <<  m_triMesh->getTriVertId2( i ) << "]";


    if ( m_writeColors->get() )
    {
        dataFile << ",\n";
        dataFile << ( "    \"colors\" : [" );
        for ( size_t k = 0; k < m_triMesh->vertSize() - 1; ++k )
        {
            osg::Vec4 color = m_triMesh->getVertColor( k );

            dataFile << color[0] << "," <<  color[1] << "," <<  color[2] << "," <<  color[3] << ",";
        }
        osg::Vec4 color = m_triMesh->getVertColor( m_triMesh->vertSize() - 1 );
        dataFile << color[0] << "," <<  color[1] << "," <<  color[2] << "," <<  color[3] << "]";
    }
    dataFile <<  "\n}";

    dataFile.close();
    WLogger::getLogger()->addLogMessage( "saving done", "Write Mesh", LL_DEBUG );
    return true;
}