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