Saturday 6 December 2014

Using the V-HACD library in your project


I have lately worked on re-factoring the V-HACD code to make it easier to integrate. An example of code using V-HACD would look like this.

 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
27
28
29
30
31
32
33
34
35
36
#include <stdio.h>
#include "VHACD.h"
int main(int argc, char * argv[])
{
    int * triangles; // array of indexes
    float * points;  // array of coordinates 
    ...
    // load the mesh 
    ...
    IVHACD::Parameters    params; // V-HACD parameters
    IVHACD * interfaceVHACD = CreateVHACD(); // create interface

    // compute approximate convex decomposition
    bool res = interfaceVHACD->Compute(points, 3, nPoints, triangles, 3, nTriangles, params);

    // read results
    unsigned int nConvexHulls = interfaceVHACD->GetNConvexHulls(); // Get the number of convex-hulls
    IVHACD::ConvexHull ch;
    for (unsigned int p = 0; p < nConvexHulls; ++p)
    {
        interfaceVHACD->GetConvexHull(p, ch); // get the p-th convex-hull information
        for (unsigned int v = 0, idx = 0; v < ch.m_nPoints; ++v, idx+=3)
        {
             printf("x=%f, y=%f, z=%f", ch.m_points[idx], ch.m_points[idx+1], ch.m_points[idx+2])
        }
        for (unsigned int t = 0, idx = 0; t < ch.m_nTriangles; ++t, idx +=3)
        {
             printf("i=%f, j=%f, k=%f", ch.m_triangles[idx], ch.m_triangles[idx+1], ch.m_triangles[idx+2])
        }            
    }

    // release memory
    interfaceVHACD->Clean();
    interfaceVHACD->Release();   
    return 0;
}

All the magic happens at line 14 where the IVHACD::Compute() function is called. In order to cancel the decomposition process, the function IVHACD::Cancel() could be called from any other thread.

V-HACD offers the user the possibility to track progress and get access to logging information. The only thing the user needs to do is to provide his implementation of the two abstract classes IUserCallback and IUserLogger.

Below, an example of implementation of IUserCallback.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
class MyCallback : public IVHACD::IUserCallback 
{
public:
    MyCallback(void) {}
    ~MyCallback() {};
    void Update(const double          overallProgress,
                const double          stageProgress,
                const double          operationProgress,
                const char * const    stage,
                const char * const    operation) 
    {
        cout << setfill(' ') << setw(3) << (int)(overallProgress  +0.5) << "% " 
             << "[ " << stage     << " " << setfill(' ') << setw(3) << (int)(stageProgress    +0.5) << "% ] " 
                     << operation << " " << setfill(' ') << setw(3) << (int)(operationProgress+0.5) << "%" << endl;
    };
};

The Update() callback is called regularly during the decomposition process to report:
  • The overall progress,
  • The progress of the current stage, and
  • The progress of the current operation.
Notice that the progress is always reported as a percentage. The decomposition process is composed of a set of stages, which are composed of operations.

An example of implementation of IUserLogger may look as follows.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
class MyLogger : public IVHACD::IUserLogger 
{
public:
 MyLogger(void){}
 MyLogger(const string & fileName){ OpenFile(fileName);  }
 ~MyLogger() {};
 void Log(const char * const msg)
 {
  if (m_file.is_open())
  {
   m_file << msg;
   m_file.flush();
  }
 };
 void OpenFile(const string & fileName) { m_file.open(fileName.c_str()); }
private:
 ofstream m_file;
};

MyCallback and MyLogger are hooked to the IVHACD object by updating encode parameters as follows.


 1
 2
 3
 4
 5
 6
 7
 8
 9
10
IVHACD::Parameters    params; // V-HACD parameters
IVHACD * interfaceVHACD = CreateVHACD(); // create interface

MyCallback myCallback;
MyLogger   myLogger(fileNameLog);
params.m_logger = &myLogger;
params.m_callback = &myCallback;
 
// compute approximate convex decomposition
bool res = interfaceVHACD->Compute(points, 3, nPoints, triangles, 3, nTriangles, params); 

No comments:

Post a Comment