Sunday, 7 December 2014

V-HACD 2.0 vs. HACD


Below some approximate convex decomposition results comparing V-HACD 2.0 and HACD.

Parameters:
  • testVHACD.exe %%i 8000000 20 0.003 4 4 0.05 0.05 0.0015 0 0 256 0.0 %%i.wrl log_%%i.txt
  • testHACD.exe %%i  2 50 0 0 1 30 2000
Score:
  • +1: V-HACD provides better decomposition than HACD
  • -1: HACD provides better decomposition than V-HACD
  • 0: V-HACD and HACD provide comparable results


V-HACD 2.0 HACD Score
18 convex-hulls


66 convex-hulls

1
18 convex-hulls

26 convex-hulls

1
16 convex-hulls

12 convex-hulls

-1
30 convex-hulls

28 convex-hulls

0
46 convex-hulls

54 convex-hulls

1
18 convex-hulls

26 convex-hulls

1
16 convex-hulls

19 convex-hulls

0
18 convex-hulls

22 convex-hulls

0
34 convex-hulls

17 convex-hulls


1
18 convex-hulls

13 convex-hulls


-1
25 convex-hulls

28 convex-hulls


1
20 convex-hulls

15 convex-hulls

-1
22 convex-hulls


16 convex-hulls


-1
42 convex-hulls

42 convex-hulls

0
9 convex-hulls

7 convex-hulls

-1
16 convex-hulls

15 convex-hulls

1

35 convex-hulls



37 convex-hulls

0
17 convex-hulls

17 convex-hulls

0
18 convex-hulls

18 convex-hulls

0
36 convex-hulls

34 convex-hulls

0
13 convex-hulls

10 convex-hulls

-1
11 convex-hulls

5 convex-hulls

-1
24 convex-hulls

20 convex-hulls

1
35 convex-hulls

36 convex-hulls

0
21 convex-hulls

13 convex-hulls

-1
15 convex-hulls

16 convex-hulls

0
9 convex-hulls
10 convex-hulls

0
41 convex-hulls

71 convex-hulls

0
22 convex-hulls

27 convex-hulls

0
47 convex-hulls

51 convex-hulls

0
23 convex-hulls

28 convex-hulls

0

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); 

Tuesday, 11 November 2014

V-HACD V2.0 is here!






V-HACD V2.0 is here and it kicks ass. It works with any triangular mesh (i.e., open or closed, manifold or not, oriented or not...) and it gives cleaner and more consistent results than V-HACD 1.0 and HACD.

The source code is available here https://github.com/kmammou/v-hacd

You can also download binaries:
Example of command line (lower quality but faster):
testVHACD.exe input.obj 100000 20 0.0025 4 4 0.05 0.05 0.00125 0 0 64 0.0 output.wrl log.txt

Example of command line (high quality but slow):
testVHACD.exe input.obj 8000000 20 0.0025 4 4 0.05 0.05 0.00125 0 0 64 0.0 output.wrl log.txt


Below some convex decomposition results generated with V-HACD 2.0.