GenericIndexedMesh* Neighbourhood::triangulateOnPlane(bool duplicateVertices/*=false*/, PointCoordinateType maxEdgeLength/*=0*/) { if (m_associatedCloud->size()<CC_LOCAL_MODEL_MIN_SIZE[TRI]) { //can't compute LSF plane with less than 3 points! return 0; } //project the points on this plane GenericIndexedMesh* mesh = 0; std::vector<CCVector2> points2D; if (projectPointsOn2DPlane<CCVector2>(points2D)) { Delaunay2dMesh* dm = new Delaunay2dMesh(); //triangulate the projected points if (!dm->build(points2D,0)) { delete dm; return 0; } //change the default mesh's reference if (duplicateVertices) { ChunkedPointCloud* cloud = new ChunkedPointCloud(); unsigned count = m_associatedCloud->size(); if (!cloud->reserve(count)) { delete dm; delete cloud; return 0; } for (unsigned i=0; i<count; ++i) cloud->addPoint(*m_associatedCloud->getPoint(i)); dm->linkMeshWith(cloud,true); } else { dm->linkMeshWith(m_associatedCloud,false); } //remove triangles with too long edges if (maxEdgeLength > 0) { dm->removeTrianglesLongerThan(maxEdgeLength); if (dm->size() == 0) { //no more triangles? delete dm; dm = 0; } } mesh = static_cast<GenericIndexedMesh*>(dm); } return mesh; }
GenericIndexedMesh* PointProjectionTools::computeTriangulation(GenericIndexedCloudPersist* theCloud, CC_TRIANGULATION_TYPES type) { if (!theCloud) return 0; GenericIndexedMesh* theMesh=0; switch(type) { case GENERIC: { unsigned i,n=theCloud->size(); CC2DPointsConainer the2DPoints; try { the2DPoints.resize(n); } catch (.../*const std::bad_alloc&*/) //out of memory { break; } theCloud->placeIteratorAtBegining(); CCVector3 P; for (i=0;i<n;++i) { theCloud->getPoint(i,P); the2DPoints[i].x = P.x; the2DPoints[i].y = P.y; } Delaunay2dMesh* dm = new Delaunay2dMesh(); if (!dm->build(the2DPoints)) { delete dm; return 0; } dm->linkMeshWith(theCloud,false); theMesh = (GenericIndexedMesh*)dm; } break; case GENERIC_BEST_LS_PLANE: { Neighbourhood Yk(theCloud); theMesh = Yk.triangulateOnPlane(); } break; case GENERIC_EMPTY: theMesh = new SimpleMesh(theCloud); break; } return theMesh; }
GenericIndexedMesh* PointProjectionTools::computeTriangulation( GenericIndexedCloudPersist* theCloud, CC_TRIANGULATION_TYPES type/*=GENERIC*/, PointCoordinateType maxEdgeLength/*=0*/, char* errorStr/*=0*/) { if (!theCloud) { if (errorStr) strcpy(errorStr, "Invalid input cloud"); return 0; } switch(type) { case GENERIC: { unsigned count = theCloud->size(); std::vector<CCVector2> the2DPoints; try { the2DPoints.resize(count); } catch (.../*const std::bad_alloc&*/) //out of memory { if (errorStr) strcpy(errorStr, "Not enough memory"); break; } theCloud->placeIteratorAtBegining(); CCVector3 P; for (unsigned i=0; i<count; ++i) { theCloud->getPoint(i,P); the2DPoints[i].x = P.x; the2DPoints[i].y = P.y; } Delaunay2dMesh* dm = new Delaunay2dMesh(); char triLibErrorStr[1024]; if (!dm->build(the2DPoints,0,false,triLibErrorStr)) { if (errorStr) strcpy(errorStr, triLibErrorStr); delete dm; return 0; } dm->linkMeshWith(theCloud,false); //remove triangles with too long edges if (maxEdgeLength > 0) { dm->removeTrianglesLongerThan(maxEdgeLength); if (dm->size() == 0) { //no more triangles? if (errorStr) strcpy(errorStr, "No triangle left after pruning"); delete dm; return 0; } } return static_cast<GenericIndexedMesh*>(dm); } break; case GENERIC_BEST_LS_PLANE: { Neighbourhood Yk(theCloud); GenericIndexedMesh* mesh = Yk.triangulateOnPlane(false,maxEdgeLength,errorStr); return mesh; } break; default: //shouldn't happen assert(false); break; } return 0; }