Esempio n. 1
0
SurfaceMeshModel *SurfaceMeshModel::clone(std::vector<Surface_mesh::Face> subset)
{
    /// Remove possible duplicates
    std::sort( subset.begin(), subset.end() );
    subset.erase( unique( subset.begin(), subset.end() ), subset.end() );

    SurfaceMeshModel * m = new SurfaceMeshModel("clone.obj", this->name + "_clone");

    Vector3VertexProperty points = vertex_coordinates();

    QSet<int> vertSet;
    QMap<Vertex,Vertex> vmap;
    foreach(Face f, subset){
        if(!is_valid(f)) continue;
        Surface_mesh::Vertex_around_face_circulator vit = vertices(f),vend=vit;
        do{ vertSet.insert(Vertex(vit).idx()); } while(++vit != vend);
    }
    foreach(int vidx, vertSet){
        vmap[Vertex(vidx)] = Vertex(vmap.size());
        m->add_vertex( points[Vertex(vidx)] );
    }
Esempio n. 2
0
void filter_depthscan::applyFilter(RichParameterSet* /*pars*/){
    glEnable(GL_DEPTH_TEST);

    /// Window size
    int w = drawArea()->width();
    int h = drawArea()->height();

    /// Create a model to store scans & add it
    SurfaceMeshModel* model = new SurfaceMeshModel();
    document()->addModel(model);   
    
#if 0
    /// Query buffer precision
    QGLFormat format = drawArea()->format();
    format.setDepthBufferSize(32);
    drawArea()->setFormat(format);
    GLint bits;
    glGetIntegerv(GL_DEPTH_BITS, &bits);
    qDebug() << "depth buffer precision" << bits;
#endif 
    
#if 0
    drawArea()->updateGL();
#else
    /// Render essentials
    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
    glPushMatrix();
        glMultMatrixd( document()->transform.data() );
        foreach(StarlabModel* model, document()->models())
            if(model->isVisible && model->renderer()!=NULL ){ 
                drawArea()->qglColor(model->color);
                model->renderer()->render();
            }
    glPopMatrix();
#endif
    
/// QGLViewer version will take ****ages**** to give you something
#if 0
    for(int winX=0; winX<w; winX++){
        for(int winY=0; winY<h; winY++){
            qDebug() << winX << winY;
            bool found=false;
            qglviewer::Vec p = drawArea()->camera()->pointUnderPixel(QPoint(winX, winY),found);
            if(found) model->add_vertex( Vector3(p[0], p[1], p[2]) );
        }
    }

/// Pure OpenGL version
#else
    /// Fetch the depth buffer (BOTTLENECK!!!!)
    /// http://stackoverflow.com/questions/516778/get-depth-buffer-from-qglpixelbuffer
    std::vector<GLfloat> winZv(w*h);
    GLfloat* winZ = winZv.data();
    glReadPixels(0, 0, w, h, GL_DEPTH_COMPONENT, GL_FLOAT, winZ);
    
    /// Fetch view matrices 
    GLint viewport[4];
    GLdouble modelview[16];
    GLdouble projection[16];
    glGetDoublev( GL_MODELVIEW_MATRIX, modelview );
    glGetDoublev( GL_PROJECTION_MATRIX, projection );
    glGetIntegerv( GL_VIEWPORT, viewport );
    
    /// Position of point in 3D space
    GLdouble posX, posY, posZ;
       
    /// Unproject depth buffer
    for(int winX=0; winX<w; winX++){
        for(int winY=0; winY<h; winY++){
            float depth = winZ[w*winY + winX];
            if(depth<1){
                gluUnProject(winX, winY, depth, modelview, projection, viewport, &posX, &posY, &posZ);
                model->add_vertex( Vector3(posX, posY, posZ) );
            }
        }
    }
   
    /// Don't affect visualization
    drawArea()->updateGL();    
#endif
}
Esempio n. 3
0
void filter_depthscan::applyFilter(RichParameterSet* pars){
    typedef qglviewer::Vec QGLVec;
    /// Window size
    int w = drawArea()->width();
    int h = drawArea()->height();
   
    /// Create query octree
    SurfaceMeshModel* selection = SurfaceMesh::safe_cast( model() );
    Octree octree( selection );

    if(selection->n_faces()==0)
        throw StarlabException("Cannot scan a point cloud, need n_faces()>0");
    
    /// Need face normals for angle rejection
    if(!selection->has_face_normals())
        SurfaceMesh::NormalsHelper(selection).compute_face_normals();
    Vector3FaceProperty fnormals = selection->face_normals();
    
    /// Create a model to store scans & add it
    SurfaceMeshModel* scan = new SurfaceMeshModel("","Scan");
    document()->addModel(scan);   
    drawArea()->setRenderer(scan,"Flat Shading");
    scan->color = QColor(125,0,0);

    /// assert( step>1 )
    int step = qMax( pars->getInt("density"),1 );
    
    /// angle: [0,90]
    double angle = qBound(0.0, (double) pars->getFloat("maxangle"), 90.0);
    double mincosangle = cos( angle * M_PI / 180 );
    
    /// scan noise
    double znoise = pars->getFloat("znoise");
    
    /// Fetch normals?
    // bool getNormals = pars->getBool("getnormal");
    

    /// Size of matrices
    int nrows = std::floor( double(h) / step );
    int ncols = std::floor( double(w) / step );
    
    /// Layers containing point coordinates
    Matrix<XYZ_View, Dynamic, Dynamic> X(ncols,nrows);

    /// Perform scan
    for(int winX=0,i=0; i<ncols; winX+=step, i++){
        for(int winY=0,j=0; j<nrows; winY+=step, j++){
            QGLVec _orig, _dir;
            drawArea()->camera()->convertClickToLine( QPoint(winX, winY), _orig, _dir );
            Vector3 orig(_orig[0],_orig[1],_orig[2]);
            Vector3 dir(_dir[0],_dir[1],_dir[2]);
            dir.normalize(); ///< just to be sure
            int isectHit = -1;
            Eigen::Vector3d ipoint = octree.closestIntersectionPoint( Ray(orig, dir), &isectHit );
            
            X(i,j).xyz[0] = std::numeric_limits<Scalar>::quiet_NaN();
            if(isectHit>=0){
                Vector3 fnormal = fnormals[ Face(isectHit) ];
                double cosangle = std::abs(dot( fnormal, dir ));
                if(cosangle>mincosangle){
                    ipoint += dir*randn(0.0,znoise);
                    
                    /// Save point
                    X(i,j).xyz = ipoint;
                    X(i,j).view = dir;
                }
            }
        }
    }

    DepthTriangulator(scan).execute(X, mincosangle);
    scan->update_vertex_normals();
    
    /// Inform user
    showMessage("Scanned #P=%d points", scan->n_vertices());
}
void filter::applyFilter(RichParameterSet* pars){
    /// Draw the input vertices if overlay was required
    if(pars->getBool(overlayInput)){
        Vector3VertexProperty points = mesh()->get_vertex_property<Vector3>(VPOINT);
        foreach(Vertex v, mesh()->vertices())
            drawArea()->drawPoint(points[v],1,Qt::red);
    }
    QElapsedTimer timer;
            
#ifdef MATLAB
    /// Compute voronoi mapping and measures
    MatlabVoronoiHelper mat(mesh, drawArea);
    timer.start(); // Don't count matlab startup in timing
    mat.createVertexIndexes();
    mat.meshVerticesToVariable("points");
    mat.meshNormalsToVariable("normals");
    mat.computeVoronoiDiagramOf("points");
    mat.searchVoronoiPoles("poleof","scorr");
    mat.getMedialSpokeAngleAndRadii("Vangle","Vradii");
    
    /// Export angle/radii from medial to surface
    mat.eval("vangle=Vangle(poleof);");
    mat.eval("vradii=Vradii(poleof);");   
    mat.variableToVertexScalarProperty("vangle",VANGLE);
    mat.variableToVertexScalarProperty("vradii",VRADII);
    mat.eval("points = loci(poleof,:);");
    
    /// Should we apply the transform?
    string propname = pars->getBool(embedVertices)?VPOINT:VPOLE;
    mat.variableToVector3VertexProperty("points",propname);
#endif

#if 1
    bool isEmbed = pars->getBool(embedVertices);

    timer.start();

    VoronoiHelper h(mesh(), drawArea());
    h.computeVoronoiDiagram();
    h.searchVoronoiPoles();
    h.getMedialSpokeAngleAndRadii();
    h.setToMedial(isEmbed);
#endif

    qDebug() << "[VOROMAT]" << timer.elapsed() << "ms";
            
    /// Colorize one of the exposed properties
    if( pars->getBool(colorizeRadii) || pars->getBool(colorizeAngle) ){
        drawArea()->setRenderer(mesh(),"Smooth");
        string propname;
        if( pars->getBool(colorizeRadii) ) propname = VRADII;
        if( pars->getBool(colorizeAngle) ) propname = VANGLE;
        ColorizeHelper(mesh(),unsignedColorMap).vscalar_to_vcolor(propname);
        // qDebug() << ScalarStatisticsHelper(mesh).statistics(propname);
    }
    
#if 1
    Vector3VertexProperty points = mesh()->get_vertex_property<Vector3>(VPOINT);
    ScalarVertexProperty  vradii = mesh()->get_vertex_property<Scalar>(VRADII);
    SurfaceMeshModel* model = new SurfaceMeshModel("", "cloud");
    document()->addModel(model);
    foreach(Vertex v, mesh()->vertices()){
        if(vradii[v]<3.14*.9)
            model->add_vertex( points[v] );
    }
#endif
}