int main(int argc, char* argv[])
{
    // --input camel.off --output camel_acd.wrl --log log.txt --resolution 1000000 --depth 20 --concavity 0.0025 --planeDownsampling 4 --convexhullDownsampling 4 --alpha 0.05 --beta 0.05 --gamma 0.00125 --pca 0 --mode 0 --maxNumVerticesPerCH 256 --minVolumePerCH 0.0001 --convexhullApproximation 1 --oclDeviceID 2
    {
        // set parameters
        Parameters params;
        ParseParameters(argc, argv, params);
        MyCallback myCallback;
        MyLogger myLogger(params.m_fileNameLog);
        params.m_paramsVHACD.m_logger = &myLogger;
        params.m_paramsVHACD.m_callback = &myCallback;
        Usage(params);
        if (!params.m_run) {
            return 0;
        }

        std::ostringstream msg;
#ifdef CL_VERSION_1_1
        msg << "+ OpenCL (ON)" << std::endl;
        OCLHelper oclHelper;
        if (params.m_paramsVHACD.m_oclAcceleration) {
            bool res = InitOCL(params.m_oclPlatformID,
                               params.m_oclDeviceID,
                               oclHelper,
                               msg);
            if (!res) {
                myLogger.Log(msg.str().c_str());
                return -1;
            }
        }
#else //CL_VERSION_1_1
        msg << "+ OpenCL (OFF)" << std::endl;
#endif //CL_VERSION_1_1

#ifdef _OPENMP
        msg << "+ OpenMP (ON)" << std::endl;
#else
        msg << "+ OpenMP (OFF)" << std::endl;
#endif
        msg << "+ Parameters" << std::endl;
        msg << "\t input                                       " << params.m_fileNameIn << endl;
        msg << "\t resolution                                  " << params.m_paramsVHACD.m_resolution << endl;
        msg << "\t max. depth                                  " << params.m_paramsVHACD.m_depth << endl;
        msg << "\t max. concavity                              " << params.m_paramsVHACD.m_concavity << endl;
        msg << "\t plane down-sampling                         " << params.m_paramsVHACD.m_planeDownsampling << endl;
        msg << "\t convex-hull down-sampling                   " << params.m_paramsVHACD.m_convexhullDownsampling << endl;
        msg << "\t alpha                                       " << params.m_paramsVHACD.m_alpha << endl;
        msg << "\t beta                                        " << params.m_paramsVHACD.m_beta << endl;
        msg << "\t maxhulls                                    " << params.m_paramsVHACD.m_maxConvexHulls << endl;
        msg << "\t pca                                         " << params.m_paramsVHACD.m_pca << endl;
        msg << "\t mode                                        " << params.m_paramsVHACD.m_mode << endl;
        msg << "\t max. vertices per convex-hull               " << params.m_paramsVHACD.m_maxNumVerticesPerCH << endl;
        msg << "\t min. volume to add vertices to convex-hulls " << params.m_paramsVHACD.m_minVolumePerCH << endl;
        msg << "\t convex-hull approximation                   " << params.m_paramsVHACD.m_convexhullApproximation << endl;
        msg << "\t OpenCL acceleration                         " << params.m_paramsVHACD.m_oclAcceleration << endl;
        msg << "\t OpenCL platform ID                          " << params.m_oclPlatformID << endl;
        msg << "\t OpenCL device ID                            " << params.m_oclDeviceID << endl;
        msg << "\t output                                      " << params.m_fileNameOut << endl;
        msg << "\t log                                         " << params.m_fileNameLog << endl;
        msg << "+ Load mesh" << std::endl;
        myLogger.Log(msg.str().c_str());

        cout << msg.str().c_str();

        // load mesh
        vector<float> points;
        vector<int> triangles;
        string fileExtension;
        GetFileExtension(params.m_fileNameIn, fileExtension);
        //cout<<"params.m_fileNameIn="<<params.m_fileNameIn<<" and fileExtension="<<fileExtension<<endl;
        if (fileExtension == ".OFF") {
            if (!LoadOFF(params.m_fileNameIn, points, triangles, myLogger)) {
                cout<<"load OFF file error"<<endl;
                return -1;
            }
        }
        else if (fileExtension == ".OBJ") {
            if (!LoadOBJ(params.m_fileNameIn, points, triangles, myLogger)) {
                cout<<"load OBJ file error"<<endl;
                return -1;
            }
        }
        else {
            myLogger.Log("Format not supported!\n");
            return -1;
        }

        // run V-HACD
        IVHACD* interfaceVHACD = CreateVHACD();

#ifdef CL_VERSION_1_1
        if (params.m_paramsVHACD.m_oclAcceleration) {
            bool res = interfaceVHACD->OCLInit(oclHelper.GetDevice(), &myLogger);
            if (!res) {
                params.m_paramsVHACD.m_oclAcceleration = false;
            }
        }
#endif //CL_VERSION_1_1
        bool res = interfaceVHACD->Compute(&points[0], 3, (unsigned int)points.size() / 3,
                &triangles[0], 3, (unsigned int)triangles.size() / 3, params.m_paramsVHACD);
        if (res) {
            std::string ext;
            if (params.m_fileNameOut.length() > 4) {
                ext = params.m_fileNameOut.substr(params.m_fileNameOut.length()-4);
            }
            std::transform(ext.begin(), ext.end(), ext.begin(), ::tolower);
            if (ext != ".obj") {
                // save output
                unsigned int nConvexHulls = interfaceVHACD->GetNConvexHulls();
                msg.str("");
                msg << "+ Generate output: " << nConvexHulls << " convex-hulls " << endl;
                myLogger.Log(msg.str().c_str());
                ofstream foutCH(params.m_fileNameOut.c_str());
                IVHACD::ConvexHull ch;
                if (foutCH.is_open()) {
                    /******* Phuc : Save nb of convex part decomposition *******/
                    ofstream outFile;
                    std::string filename;
                    filename=params.m_fileNameOut.substr(0,params.m_fileNameOut.length()-4);//../../results/egea_acd_0.dat
                    ///filename=params.m_fileNameIn.substr(0,params.m_fileNameOut.length()-4);
                    filename=filename+".txt";
                    outFile.open(filename.c_str());
                    if (!outFile.is_open()) {
                        cerr<<"! ERROR: can NOT open file : "<<filename<<endl;
                        exit(1);
                    }
                    outFile<<nConvexHulls<<endl;
                    outFile.close();
                    /******* Phuc : Save nb of convex part decomposition *******/
                    Material mat;
                    for (unsigned int p = 0; p < nConvexHulls; ++p) {
                        interfaceVHACD->GetConvexHull(p, ch);
                        ComputeRandomColor(mat);
                        SaveVRML2(foutCH, ch.m_points, ch.m_triangles, ch.m_nPoints, ch.m_nTriangles, mat, myLogger);
                        msg.str("");
                        msg << "\t CH[" << setfill('0') << setw(5) << p << "] " << ch.m_nPoints << " V, " << ch.m_nTriangles << " T" << endl;
                        myLogger.Log(msg.str().c_str());
#ifdef SAVE_PART
                        /****** Phuc : Save convex-part decomposition *********/
                        filename=params.m_fileNameOut.substr(0,params.m_fileNameOut.length()-4);//../../results/egea_acd_0.dat
                        ///filename=params.m_fileNameIn.substr(0,params.m_fileNameIn.length()-4);//../../data/egea_0.dat
                        filename=filename+"_"+std::to_string(p)+".dat";
                        //cout<<filename<<endl;
                        ofstream fpart(filename.c_str());
                        if (fpart.is_open()) {
                            size_t nV = ch.m_nPoints * 3;
                            for (size_t v = 0; v < nV; v += 3) {
                                fpart << ch.m_points[v + 0] << " "
                                                            << ch.m_points[v + 1] << " "
                                                            << ch.m_points[v + 2] << std::endl;
                            }
                            fpart.close();
                        }
                        else
                            std::cout<<"Can't open file\n"<<std::endl;
                        /****** Phuc : Save convex-part decomposition *********/
#endif
                    }
                    foutCH.close();
                }
            }
            else {
                unsigned int nConvexHulls = interfaceVHACD->GetNConvexHulls();
                msg.str("");
                msg << "+ Generate output: " << nConvexHulls << " convex-hulls " << endl;
                myLogger.Log(msg.str().c_str());
                ofstream foutCH(params.m_fileNameOut.c_str());
                IVHACD::ConvexHull ch;
                if (foutCH.is_open()) {
                    /******* Phuc : Save nb of convex part decomposition *******/
                    ofstream outFile;
                    std::string filename;
                    filename=params.m_fileNameOut.substr(0,params.m_fileNameOut.length()-4);//../../results/egea_acd_0.dat
                    ///filename=params.m_fileNameIn.substr(0,params.m_fileNameIn.length()-4);
                    filename=filename+".txt";
                    outFile.open(filename.c_str());
                    if (!outFile.is_open()) {
                        cerr<<"! ERROR: can NOT open file : "<<filename<<endl;
                        exit(1);
                    }
                    outFile<<nConvexHulls<<endl;
                    outFile.close();
                    /******* Phuc : Save nb of convex part decomposition *******/

                    Material mat;
                    int vertexOffset = 1;//obj wavefront starts counting at 1...
                    for (unsigned int p = 0; p < nConvexHulls; ++p) {
                        interfaceVHACD->GetConvexHull(p, ch);
                        SaveOBJ(foutCH, ch.m_points, ch.m_triangles, ch.m_nPoints, ch.m_nTriangles, mat, myLogger, p, vertexOffset);
                        vertexOffset+=ch.m_nPoints;
                        msg.str("");
                        msg << "\t CH[" << setfill('0') << setw(5) << p << "] " << ch.m_nPoints << " V, " << ch.m_nTriangles << " T" << endl;
                        myLogger.Log(msg.str().c_str());
#ifdef SAVE_PART
                        /****** Phuc : Save convex-part decomposition *********/
                        filename=params.m_fileNameOut.substr(0,params.m_fileNameOut.length()-4);//../../results/egea_acd_0.dat
                        ///filename=params.m_fileNameIn.substr(0,params.m_fileNameIn.length()-4);//../../data/egea_0.dat
                        filename=filename+"_"+std::to_string(p)+".dat";
                        ofstream fpart(filename.c_str());
                        if (fpart.is_open()) {
                            size_t nV = ch.m_nPoints * 3;
                            for (size_t v = 0; v < nV; v += 3) {
                                fpart << ch.m_points[v + 0] << " "
                                                            << ch.m_points[v + 1] << " "
                                                            << ch.m_points[v + 2] << std::endl;
                            }
                            fpart.close();
                        }
                        else
                            std::cout<<"Can't open file\n"<<std::endl;
                        /****** Phuc : Save convex-part decomposition *********/
#endif
                    }
                    foutCH.close();
                }
            }
        }
        else {
            myLogger.Log("Decomposition cancelled by user!\n");
        }

#ifdef CL_VERSION_1_1
        if (params.m_paramsVHACD.m_oclAcceleration) {
            bool res = interfaceVHACD->OCLRelease(&myLogger);
            if (!res) {
                assert(-1);
            }
        }
#endif //CL_VERSION_1_1

        interfaceVHACD->Clean();
        interfaceVHACD->Release();
    }
#ifdef _CRTDBG_MAP_ALLOC
    _CrtDumpMemoryLeaks();
#endif // _CRTDBG_MAP_ALLOC
    return 0;
}
Exemple #2
0
int main(int argc, char* argv[])
{
    // --input camel.off --output camel_acd.obj --log log.txt --resolution 1000000 --depth 20 --concavity 0.0025 --planeDownsampling 4 --convexhullDownsampling 4 --alpha 0.05 --beta 0.05 --gamma 0.00125 --pca 0 --mode 0 --maxNumVerticesPerCH 256 --minVolumePerCH 0.0001 --convexhullApproximation 1 --oclDeviceID 2
    {
        // set parameters
        Parameters params;
        ParseParameters(argc, argv, params);
        MyCallback myCallback;
        MyLogger myLogger(params.m_fileNameLog);
        params.m_paramsVHACD.m_logger = &myLogger;
        params.m_paramsVHACD.m_callback = &myCallback;
        Usage(params);
        if (!params.m_run) {
            return 0;
        }

        std::ostringstream msg;

        msg << "+ OpenCL (OFF)" << std::endl;

        msg << "+ Parameters" << std::endl;
        msg << "\t input                                       " << params.m_fileNameIn << endl;
        msg << "\t resolution                                  " << params.m_paramsVHACD.m_resolution << endl;
        msg << "\t max. depth                                  " << params.m_paramsVHACD.m_depth << endl;
        msg << "\t max. concavity                              " << params.m_paramsVHACD.m_concavity << endl;
        msg << "\t plane down-sampling                         " << params.m_paramsVHACD.m_planeDownsampling << endl;
        msg << "\t convex-hull down-sampling                   " << params.m_paramsVHACD.m_convexhullDownsampling << endl;
        msg << "\t alpha                                       " << params.m_paramsVHACD.m_alpha << endl;
        msg << "\t beta                                        " << params.m_paramsVHACD.m_beta << endl;
        msg << "\t gamma                                       " << params.m_paramsVHACD.m_gamma << endl;
        msg << "\t pca                                         " << params.m_paramsVHACD.m_pca << endl;
        msg << "\t mode                                        " << params.m_paramsVHACD.m_mode << endl;
        msg << "\t max. vertices per convex-hull               " << params.m_paramsVHACD.m_maxNumVerticesPerCH << endl;
        msg << "\t min. volume to add vertices to convex-hulls " << params.m_paramsVHACD.m_minVolumePerCH << endl;
        msg << "\t convex-hull approximation                   " << params.m_paramsVHACD.m_convexhullApproximation << endl;
        msg << "\t OpenCL acceleration                         " << params.m_paramsVHACD.m_oclAcceleration << endl;
        msg << "\t OpenCL platform ID                          " << params.m_oclPlatformID << endl;
        msg << "\t OpenCL device ID                            " << params.m_oclDeviceID << endl;
        msg << "\t output                                      " << params.m_fileNameOut << endl;
        msg << "\t log                                         " << params.m_fileNameLog << endl;
        msg << "+ Load mesh" << std::endl;
        myLogger.Log(msg.str().c_str());

        cout << msg.str().c_str();

        // load mesh
        vector<float> points;
        vector<int> triangles;
        string fileExtension;
        GetFileExtension(params.m_fileNameIn, fileExtension);
        if (fileExtension == ".OFF") {
            if (!LoadOFF(params.m_fileNameIn, points, triangles, myLogger)) {
                return -1;
            }
        }
        else if (fileExtension == ".OBJ") {
            if (!LoadOBJ(params.m_fileNameIn, points, triangles, myLogger)) {
                return -1;
            }
        }
        else {
            myLogger.Log("Format not supported!\n");
            return -1;
        }

        // run V-HACD
        IVHACD* interfaceVHACD = CreateVHACD();

#ifdef CL_VERSION_1_1
        if (params.m_paramsVHACD.m_oclAcceleration) {
            bool res = interfaceVHACD->OCLInit(oclHelper.GetDevice(), &myLogger);
            if (!res) {
                params.m_paramsVHACD.m_oclAcceleration = false;
            }
        }
#endif //CL_VERSION_1_1
        bool res = interfaceVHACD->Compute(&points[0], 3, (unsigned int)points.size() / 3,
            &triangles[0], 3, (unsigned int)triangles.size() / 3, params.m_paramsVHACD);
        if (res) {
            // save output
            unsigned int nConvexHulls = interfaceVHACD->GetNConvexHulls();
            msg.str("");
            msg << "+ Generate output: " << nConvexHulls << " convex-hulls " << endl;
            myLogger.Log(msg.str().c_str());
            ofstream foutCH(params.m_fileNameOut.c_str());
            IVHACD::ConvexHull ch;
            if (foutCH.is_open()) {
                Material mat;
				int vertexOffset = 1;//obj wavefront starts counting at 1...
                for (unsigned int p = 0; p < nConvexHulls; ++p) {
                    interfaceVHACD->GetConvexHull(p, ch);
					
					
                    SaveOBJ(foutCH, ch.m_points, ch.m_triangles, ch.m_nPoints, ch.m_nTriangles, mat, myLogger, p, vertexOffset);
					vertexOffset+=ch.m_nPoints;
                    msg.str("");
                    msg << "\t CH[" << setfill('0') << setw(5) << p << "] " << ch.m_nPoints << " V, " << ch.m_nTriangles << " T" << endl;
                    myLogger.Log(msg.str().c_str());
                }
                foutCH.close();
            }
        }
        else {
            myLogger.Log("Decomposition cancelled by user!\n");
        }

#ifdef CL_VERSION_1_1
        if (params.m_paramsVHACD.m_oclAcceleration) {
            bool res = interfaceVHACD->OCLRelease(&myLogger);
            if (!res) {
                assert(-1);
            }
        }
#endif //CL_VERSION_1_1

        interfaceVHACD->Clean();
        interfaceVHACD->Release();
    }
#ifdef _CRTDBG_MAP_ALLOC
    _CrtDumpMemoryLeaks();
#endif // _CRTDBG_MAP_ALLOC
    return 0;
}
Exemple #3
0
btCollisionShape* BulletSim::BuildVHACDHullShapeFromMesh2(btCollisionShape* mesh, HACDParams* parms)
{
#if defined(USEVHACD)

	int* triangles;	// array of indesex
	float* points;	// array of coordinates

	// copy the mesh into the structures
	btStridingMeshInterface* meshInfo = ((btTriangleMeshShape*)mesh)->getMeshInterface();

	const unsigned char* vertexBase;	// base of the vertice array
	int numVerts;						// the num of vertices
	PHY_ScalarType vertexType;			// the data type representing the vertices
	int vertexStride;					// bytes between each vertex
	const unsigned char* indexBase;		// base of the index array
	int indexStride;					// bytes between the index values
	int numFaces;						// the number of triangles specified by the indexes
	PHY_ScalarType indicesType;			// the data type of the indexes
	meshInfo->getLockedReadOnlyVertexIndexBase(&vertexBase, numVerts, vertexType, vertexStride, &indexBase, indexStride, numFaces, indicesType);

	if (vertexType != PHY_FLOAT || indicesType != PHY_INTEGER)
	{
		// If an odd data structure, we cannot hullify
		m_worldData.BSLog("VHACD: triangle mesh not of right types");	// DEBUG DEBUG
		return NULL;
	}

	// Create pointers to the vertices and indices as the PHY types that they are
	float* tVertex = (float*)vertexBase;
	int tVertexStride = vertexStride / sizeof(float);
	int* tIndices = (int*) indexBase;
	int tIndicesStride = indexStride / sizeof(int);
	m_worldData.BSLog("VHACD: nVertices=%d, nIndices=%d", numVerts, numFaces*3);	// DEBUG DEBUG

	// Copy the vertices/indices into the HACD data structures
	points = new float[numVerts * 3];
	triangles = new int[numFaces * 3];

	int pp = 0;
	for (int ii=0; ii < (numVerts * tVertexStride); ii += tVertexStride)
	{
		points[pp+0] = tVertex[ii+0];
		points[pp+1] = tVertex[ii+1];
		points[pp+2] = tVertex[ii+2];
		pp += 3;
	}
	pp = 0;
	for(int ii=0; ii < (numFaces * tIndicesStride); ii += tIndicesStride ) 
	{
		triangles[pp+0] = tIndices[ii+0];
		triangles[pp+1] = tIndices[ii+1];
		triangles[pp+2] = tIndices[ii+2];
		pp += 3;
	}

	meshInfo->unLockReadOnlyVertexBase(0);
	m_worldData.BSLog("VHACD: structures copied");	// DEBUG DEBUG

	IVHACD::Parameters vParams;
	vParams.m_resolution              = (unsigned int)parms->vHACDresolution;
    vParams.m_depth                   = (int)parms->vHACDdepth;
    vParams.m_concavity               = (double)parms->vHACDconcavity;
    vParams.m_planeDownsampling       = (int)parms->vHACDplaneDownsampling;
    vParams.m_convexhullDownsampling  = (int)parms->vHACDconvexHullDownsampling;
    vParams.m_alpha                   = (double)parms->vHACDalpha;
    vParams.m_beta                    = (double)parms->vHACDbeta;
	vParams.m_delta                   = (double)parms->vHACDdelta;
    vParams.m_gamma                   = (double)parms->vHACDgamma;
    vParams.m_pca                     = (int)parms->vHACDpca;
    vParams.m_mode                    = (int)parms->vHACDmode;
    vParams.m_maxNumVerticesPerCH     = (unsigned int)parms->vHACDmaxNumVerticesPerCH;
    vParams.m_minVolumePerCH          = (double)parms->vHACDminVolumePerCH;
	vParams.m_callback                = new VHACDProgressLog(&m_worldData);
    // vParams.m_logger                  =
    vParams.m_convexhullApproximation = (parms->vHACDconvexHullApprox == ParamTrue);
    vParams.m_oclAcceleration         = (parms->vHACDoclAcceleration == ParamTrue);

	IVHACD* interfaceVHACD = CreateVHACD();

	bool res = interfaceVHACD->Compute(points, 1, numFaces * 3, triangles, 3, numVerts, vParams);

	unsigned int nConvexHulls = interfaceVHACD->GetNConvexHulls();
	m_worldData.BSLog("VHACD: After compute. nHulls=%d", nConvexHulls);	// DEBUG DEBUG

	// Create the compound shape all the hulls will be added to
	btCompoundShape* compoundShape = new btCompoundShape(true);
	compoundShape->setMargin(m_worldData.params->collisionMargin);

	// Convert each of the built hulls into btConvexHullShape objects and add to the compoundShape
	IVHACD::ConvexHull ch;
	for (unsigned int hul = 0; hul < nConvexHulls; hul++)
	{
		interfaceVHACD->GetConvexHull(hul, ch);
		size_t nPoints = ch.m_nPoints;
		size_t nTriangles = ch.m_nTriangles;
		m_worldData.BSLog("VHACD: Add hull %d. nPoints=%d, nTriangles=%d", hul, nPoints, nTriangles);	// DEBUG DEBUG

		// Average the location of all the vertices to create a centriod for the hull.
		btAlignedObjectArray<btVector3> vertices;
		vertices.reserve(nTriangles);
		btVector3 centroid;
		centroid.setValue(0,0,0);

		/*
		int pp = 0;
		for (int ii=0; ii < nPoints; ii++)
		{
			btVector3 vertex(ch.m_points[pp + 0], ch.m_points[pp + 1], ch.m_points[pp + 2] );
			vertices.push_back(vertex);
			centroid += vertex;
			pp += 3;
			m_worldData.BSLog("VHACD: Hull %d, vertex %d:<%f,%f,%f>", hul, ii, vertex.getX(), vertex.getY(), vertex.getZ());	// DEBUG DEBUG
		}
		// centroid *= 1.f/((float)(nPoints));

		// Move the vertices to have the common centroid
		for (int ii=0; ii < nPoints; ii++)
		{
			vertices[ii] -= centroid;
		}
		*/

		for (int ii=0; ii < nTriangles; ii++)
		{
			int tri = ch.m_triangles[ii] * 3;
			btVector3 vertex(ch.m_points[tri+0], ch.m_points[tri+1], ch.m_points[tri+2]);
			vertices.push_back(vertex);
		}

		btConvexHullShape* convexShape;
		// Optionally compress the hull a little bit to account for the collision margin.
		if (parms->shouldAdjustCollisionMargin == ParamTrue)
		{
			float collisionMargin = 0.01f;
			
			btAlignedObjectArray<btVector3> planeEquations;
			btGeometryUtil::getPlaneEquationsFromVertices(vertices, planeEquations);

			btAlignedObjectArray<btVector3> shiftedPlaneEquations;
			for (int p=0; p<planeEquations.size(); p++)
			{
				btVector3 plane = planeEquations[p];
				plane[3] += collisionMargin;
				shiftedPlaneEquations.push_back(plane);
			}
			btAlignedObjectArray<btVector3> shiftedVertices;
			btGeometryUtil::getVerticesFromPlaneEquations(shiftedPlaneEquations,shiftedVertices);
			
			convexShape = new btConvexHullShape(shiftedVertices[0], shiftedVertices.size(), sizeof(btVector3));
		}
		else
		{
			convexShape = new btConvexHullShape(vertices[0], vertices.size(), sizeof(btVector3));
		}
		convexShape->setMargin(m_worldData.params->collisionMargin);

		// Add the hull shape to the compound shape
		btTransform childTrans;
		childTrans.setIdentity();
		childTrans.setOrigin(centroid);
		m_worldData.BSLog("HACD: Add child shape %d", hul);	// DEBUG DEBUG
		compoundShape->addChildShape(childTrans, convexShape);
	}

	// The params structure doesn't have a destructor to get rid of logging and progress callbacks
	if (vParams.m_callback)
	{
		delete vParams.m_callback;
		vParams.m_callback = 0;
	}

	delete [] points;
	delete [] triangles;

	interfaceVHACD->Clean();
	interfaceVHACD->Release();

	return compoundShape;
#else
	return NULL;
#endif
}