Page 1 of 1

CCLib::PointProjectionTools::computeTriangulation

Posted: Mon Mar 26, 2012 2:26 pm
by celineputsch
Hi,

I want to create a new plugin for CloudCompare. In this plugin, I would like to start with creating the triangulation of selectionned pointclouds. So I try to re-use the "MainWindow::doActionComputeMesh(CC_TRIANGULATION_TYPES type)" code.

Here is my code for the plugin.cpp:

Code: Select all

int qPluginIGN::doAction(std::vector<ccHObject*>& selectedEntities,
                            unsigned& uiModificationFlags,
                            ccProgressDialog* progressCb,
                            QWidget* parent)
{
    QString label = "Triangulation en cours...";
    QProgressDialog pDlg(label, QString(), 0, 0, 0);
	pDlg.show();

	QApplication::processEvents();

    unsigned i,selNum = selectedEntities.size();
    for (i=0;i<selNum;++i)
    {
        ccHObject* ent = selectedEntities[i];
        if (ent->isKindOf(CC_POINT_CLOUD))
        {
            ccGenericPointCloud* cloud = static_cast<ccGenericPointCloud*>(ent);
            CC_TRIANGULATION_TYPES type = GENERIC_BEST_LS_PLANE;
            CCLib::GenericIndexedMesh* dummyMesh = CCLib::PointProjectionTools::computeTriangulation(cloud,type);

            if (dummyMesh)
            {
                ccMesh* mesh = new ccMesh(dummyMesh, cloud);
                if (mesh)
                {
                    char buffer[1024];
                    sprintf(buffer,"%s.mesh",cloud->getName());
                    mesh->setName(buffer);
                    mesh->setDisplay(cloud->getDisplay());
					if (cloud->hasColors() && !cloud->hasNormals())
						mesh->showNormals(false);
                    cloud->setVisible(false);
                    cloud->addChild(mesh);
                    cloud->prepareDisplayForRefresh();
                    //addToDB(mesh,0,false,false);
                }
                else
                {
                    //ccConsole::Error("An error occured while computing mesh! (not enough memory?)");
                }
            }
            else
            {
                //ccConsole::Error("An error occured while computing mesh! (not enough memory?)");
            }
        }
    }

    //refreshAll();
	//updateUI();

    /*** HERE ENDS THE MAIN PLUGIN ACTION ***/

    //default return code: '1' = success
    return 1;
    //otherwise, define you own return codes (<0 or >1) and put the corresponding
    //error messages in 'getErrorMessage' (see below)
}
When I try to build this code, I have the following issues:

Code: Select all

||=== qPluginIGN, debug ===|
..\..\..\CC\lib\mingw\libCC_Dlld.a(Delaunay2dMesh.o):C:\CloudCompare\CC\src\Delaunay2dMesh.cpp|89|undefined reference to `triangulate(char const*, triangulateio*, triangulateio*, triangulateio*)'|
..\..\db\lib\mingw\libqCC_dbd.a(ccMesh.o):C:\CloudCompare\qCC\db\ccMesh.cpp|1141|undefined reference to `CCLib::ManualSegmentationTools::segmentMesh(CCLib::GenericIndexedMesh*, CCLib::ReferenceCloud*, bool, CCLib::GenericProgressCallback*, CCLib::GenericIndexedCloud*, unsigned int)'|
..\..\db\lib\mingw\libqCC_dbd.a(ccMesh.o):C:\CloudCompare\qCC\db\ccMesh.cpp|1141|undefined reference to `CCLib::ManualSegmentationTools::segmentMesh(CCLib::GenericIndexedMesh*, CCLib::ReferenceCloud*, bool, CCLib::GenericProgressCallback*, CCLib::GenericIndexedCloud*, unsigned int)'|
..\..\db\lib\mingw\libqCC_dbd.a(ccPointCloud.o):C:\CloudCompare\qCC\db\ccPointCloud.cpp|1227|undefined reference to `CCLib::GeometricalAnalysisTools::computeGravityCenter(CCLib::GenericCloud*)'|
..\..\db\lib\mingw\libqCC_dbd.a(ccPointCloud.o):C:\CloudCompare\qCC\db\ccPointCloud.cpp|1872|undefined reference to `CCLib::ManualSegmentationTools::segment(CCLib::GenericIndexedCloudPersist*, float, float)'|
||=== Build finished: 5 errors, 0 warnings ===|
So the issues seems to be in the classes already present in the CloudCompare sources.
For example, the first issue shows this part of code in ccLib\src\Delaunay2dMesh.cpp:

Code: Select all

//on utilise la librairie "externe" Triangle
	triangulateio in;
	memset(&in,0,sizeof(triangulateio));

	in.numberofpoints = the2dPoints.size();
	in.pointlist = (REAL*)(&the2dPoints[0]);

	try
	{
		triangulate("zQN",&in,&in,0);
	}
	catch (...)
	{
		//cerr << "Exception indéfinie." << endl;
		return false;
	}
What would be the cause of these issues?

Thanks a lot for your answer.

Céline

Re: CCLib::PointProjectionTools::computeTriangulation

Posted: Mon Mar 26, 2012 3:45 pm
by daniel
Hi,

In general you can't use the MainWindow methods directly. qCC is not a proper library and plugins shouldn't interact directly with its database or GUI (we do this in qHPR for convenience - and by pure laziness - but it's very dirty and dangerous ;).

You should better copy the code that makes what you want (i.e. the one that cast the incoming object into a ccGenericPointCloud then call "computeTriangulation" and eventually (if necessary) the conversion to a ccMesh:

Code: Select all

    unsigned i,selNum = selectedEntities.size();
    for (i=0;i<selNum;++i)
    {
        ccHObject* ent = selectedEntities[i];
        if (ent->isKindOf(CC_POINT_CLOUD))
        {
            ccGenericPointCloud* cloud = static_cast<ccGenericPointCloud*>(ent);

            CCLib::GenericIndexedMesh* dummyMesh = CCLib::PointProjectionTools::computeTriangulation(cloud,GENERIC_BEST_LS_PLANE/* or GENERIC*/);

            if (dummyMesh)
            {
                //only necessary if you want to use particular methods of ccMesh objects, or to output this mesh (= send it back to CC on plugins completion)
                ccMesh* mesh = new ccMesh(dummyMesh, cloud);
            
                //[...]

            }
            else
            {
                return ERROR_CODE_MESH_CREATION_FAILED; //reimplement the 'getErrorMessage' method to return corresponding message
            }
        }
    }
The rest is qCC internal stuff (db and GUI management) and this explains why you can't (and must not) call it directly. And the conversion to a ccMesh object is not necessarily required (it depends on what you want to do with this mesh). For instance, all algoritms from CCLib are directly applicable to GenericMesh or GenericIndexedMesh objects.

Feel free to ask for more precisions on CC internals if necessary (either on this forum or directly by email if you prefer).