The library OpenCTM can be used to compress 3D data files. The new compressed file has only about 1/10 size compared with the original file.
We can use vertex property to store the model’s color which is often PointData’s scalar in VTK.
The following code snippet shows how to use OpenCTM to store polydata and color.

CMakeLists.txt

cmake_minimum_required(VERSION 2.8)

project(ctmExcise)

find_package( VTK REQUIRED )
include( ${VTK_USE_FILE} )

set( OPENCTM_LIB_DIR "/Users/weiyang/Downloads/OpenCTM-1.0.3/lib" )
include_directories( ${OPENCTM_LIB_DIR} )
link_directories( ${OPENCTM_LIB_DIR} )
message( "======>    OPENCTM_LIB_DIR: ${OPENCTM_LIB_DIR}" )

add_executable( ${PROJECT_NAME}  "main.cpp" "tool.h" )

# we need libopenctm.dylib
target_link_libraries( ${PROJECT_NAME} ${VTK_LIBRARIES} openctm )

main.cpp

#include <iostream>
#include <stdio.h>
#include <vtkSmartPointer.h>
#include <vtkSTLReader.h>
#include <vtkActor.h>
#include <vtkConeSource.h>
#include <vtkRenderer.h>
#include <vtkRenderWindow.h>
#include <vtkPolyDataMapper.h>
#include <vtkProperty.h>
#include <vtkRenderWindowInteractor.h>
#include <vtkCamera.h>
#include <vtkPolyData.h>
#include <string>
#include <vtkTriangleFilter.h>
#include <vtkSTLWriter.h>
#include <time.h>
#include <vtkSphereSource.h>
#include <vtkPointData.h>
#include <vtkDoubleArray.h>

#include "tool.h"
#include "openctmpp.h"

using namespace std;

void MySaveFile(CTMuint aVertCount, CTMuint aTriCount, CTMfloat * aVertices,
   CTMuint * aIndices, const char * aFileName,
   const CTMfloat * aAttribValues, const char * aName)
{
    try
    {
        // Create a new OpenCTM exporter object
        CTMexporter ctm;

        // Define our mesh representation to OpenCTM (store references to it in
        // the context)
        ctm.DefineMesh(aVertices, aVertCount, aIndices, aTriCount, NULL);
        ctm.AddAttribMap( aAttribValues, aName );

        // Save the OpenCTM file
        ctm.Save(aFileName);
    }
    catch(exception &e)
    {
        fprintf( stderr, "[%s, %d]: Error => %s\n", __FILE__, __LINE__, e.what( ) );
    }
}

int main()
{
    // -------------- OpenCTM save data ---------------    
    vtkSmartPointer<vtkSphereSource> sphereSource =
            vtkSmartPointer<vtkSphereSource>::New();
    sphereSource->SetThetaResolution( 50 );
    sphereSource->SetPhiResolution( 50 );
    sphereSource->Update();

    vtkPolyData *pd = sphereSource->GetOutput();
    vtkPoints *points = pd->GetPoints();
    vtkSmartPointer<vtkDoubleArray> scalars =
            vtkSmartPointer<vtkDoubleArray>::New();
    scalars->SetNumberOfTuples( points->GetNumberOfPoints() );
    for(vtkIdType i = 0; i < points->GetNumberOfPoints(); ++i)
    {
        scalars->SetTuple1(i, 1.0 * i / points->GetNumberOfPoints());
    }
    pd->GetPointData()->SetScalars( scalars );

    CTMuint aVertCount = static_cast<unsigned int>( points->GetNumberOfPoints() );
    CTMfloat *aVertices = new CTMfloat[3*aVertCount];
    for( CTMuint i = 0; i < aVertCount; ++i )
    {
        PointStruct pt( points->GetPoint( i ) );
        for( CTMuint j = 0; j < 3; ++j )
        {
            aVertices[3*i+j] = static_cast<CTMfloat>( pt[j] );
        }
    }
    CTMuint aTriCount = static_cast<CTMuint>( pd->GetNumberOfCells() );
    CTMuint *aIndices = new CTMuint[3*aTriCount];
    for( CTMuint i = 0; i < aTriCount; ++i )
    {
        vtkIdList *ids = pd->GetCell( i )->GetPointIds();
        for( CTMuint j = 0; j < 3; ++j )
        {
            aIndices[3*i+j] = static_cast<CTMuint>( ids->GetId( j ) );
        }
    }
    CTMfloat *aScalars = new CTMfloat[aVertCount*4];
    for( CTMuint i = 0; i < aVertCount; ++i )
    {
        aScalars[i*4] = scalars->GetValue( i );
    }
    string fileName = "./sphere.ctm";
    MySaveFile( aVertCount, aTriCount, aVertices, aIndices, fileName.c_str(), aScalars, "aScalar" );

    delete [] aVertices;
    aVertices = nullptr;
    delete [] aIndices;
    aIndices = nullptr;
    // -------------- Finish: OpenCTM save data ---------------

    vtkSmartPointer<vtkPolyData> newPd = vtkSmartPointer<vtkPolyData>::New();
    vtkSmartPointer<vtkPoints> newPoints = vtkSmartPointer<vtkPoints>::New();
    vtkSmartPointer<vtkCellArray> newCells = vtkSmartPointer<vtkCellArray>::New();
    vtkSmartPointer<vtkDoubleArray> newScalars = vtkSmartPointer<vtkDoubleArray>::New();

    CTMimporter ctm;
    ctm.Load( fileName.c_str() );

    CTMuint vertCount = ctm.GetInteger(CTM_VERTEX_COUNT);
    const CTMfloat *vertices = ctm.GetFloatArray(CTM_VERTICES);
    CTMuint triCount = ctm.GetInteger(CTM_TRIANGLE_COUNT);
    const CTMuint *indices = ctm.GetIntegerArray(CTM_INDICES);
    const CTMfloat *ctmScalars = ctm.GetFloatArray( CTM_ATTRIB_MAP_1 );
    for( CTMuint i = 0; i < vertCount; ++i )
    {
        PointStruct pt;
        for( int j = 0; j < 3; ++j )
        {
            pt[j] = vertices[3*i+j];
        }
        newPoints->InsertNextPoint( pt.point );
    }
    for( CTMuint i = 0; i < triCount; ++i )
    {
        vtkIdType cell[3];
        for( int j = 0; j < 3; ++j )
        {
            cell[j] = indices[3*i+j];
        }
        newCells->InsertNextCell( 3, cell );
    }
    for( CTMuint i = 0; i < vertCount; ++i )
    {
        newScalars->InsertNextTuple1( ctmScalars[4*i] );
    }
    newPd->SetPoints( newPoints );
    newPd->SetPolys( newCells );
    newPd->GetPointData()->SetScalars( newScalars );

    vtkSmartPointer<vtkPolyDataMapper> mapper =
            vtkSmartPointer<vtkPolyDataMapper>::New();
    mapper->SetInputData( newPd );

    vtkSmartPointer<vtkActor> actor =
            vtkSmartPointer<vtkActor>::New();
    actor->SetMapper( mapper );

    vtkSmartPointer<vtkRenderer> renderer =
            vtkSmartPointer<vtkRenderer>::New();
    renderer->AddActor(actor);
    renderer->SetBackground( 0.1, 0.1, 0.1 );

    vtkSmartPointer<vtkRenderWindow> renderWindow =
            vtkSmartPointer<vtkRenderWindow>::New();
    renderWindow->AddRenderer( renderer );

    vtkSmartPointer<vtkRenderWindowInteractor> renderWindowInteractor =
            vtkSmartPointer<vtkRenderWindowInteractor>::New();
    renderWindowInteractor->SetRenderWindow( renderWindow );

    renderer->ResetCamera();
    renderWindow->Render();
    renderWindowInteractor->Start();
    return 0;
}
Categories: ToolVTK

0 0 vote
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments
A prohibited operation
0
Would love your thoughts, please comment.x
()
x