Пример #1
0
void U3DIOPlugin::saveParameters(const RichParameterSet &par)
{
        vcg::Point3f from_target_to_camera = vcg::Point3f(par.getPoint3f(QString("position_val")) - par.getPoint3f(QString("target_val")));
	vcg::tri::io::u3dparametersclasses::Movie15Parameters::CameraParameters* sw = _param._campar;
	//vcg::Point3f p = avoidExponentialNotation(sw->_obj_pos,_param._campar->_obj_bbox_diag);
	vcg::Point3f p = sw->_obj_pos;
	_param._campar = new vcg::tri::io::u3dparametersclasses::Movie15Parameters::CameraParameters(
		par.getFloat(QString("fov_val")),0.0f,from_target_to_camera,from_target_to_camera.Norm(),sw->_obj_bbox_diag,p);
	_param.positionQuality = par.getInt(QString("compression_val"));

	delete sw;
}
Пример #2
0
// The Real Core Function doing the actual mesh processing.
// Move Vertex of a random quantity
bool ExtraSamplePlugin::applyFilter(QAction *action, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos *cb)
{
    switch(ID(action))	 {

    case FP_DECOMPOSER :
    {
        CMeshO &m = md.mm()->cm;
        CutMesh cm;
        vcg::tri::Append<CutMesh,CMeshO>::MeshCopy(cm,m);
        vcg::tri::Allocator<CutMesh>::CompactEveryVector(cm);
        vcg::tri::UpdateTopology<CutMesh>::FaceFace(cm);
        vcg::tri::UpdateTopology<CutMesh>::VertexFace(cm);
        vcg::tri::UpdateNormal<CutMesh>::PerFace(cm);

        //Get Parameters
        vcg::Point3f upperPoint = par.getPoint3f("upperPoint");
        vcg::Point3f lowerPoint = par.getPoint3f("lowerPoint");
        float dihedral = par.getDynamicFloat("dihedral");
        float ambient = par.getDynamicFloat("ambient");
        float geodesic = par.getDynamicFloat("geodesic");
        float geomin = par.getDynamicFloat("geo-factor-min");
        float geomax = par.getDynamicFloat("geo-factor-max");
        float elength = par.getDynamicFloat("e-length");
        CutMesh::FacePointer startFace = NULL;
        CutMesh::FacePointer endFace = NULL;



        //getting the closest faces to the passed point parameters
        TriMeshGrid grid;
        grid.Set(cm.face.begin(),cm.face.end());
        vcg::Point3<CutMesh::ScalarType> closest;
        float maxDist = cm.bbox.Diag();
        float minDist;
        startFace = vcg::tri::GetClosestFaceBase(cm, grid, upperPoint, maxDist, minDist, closest);
        endFace = vcg::tri::GetClosestFaceBase(cm, grid, lowerPoint, maxDist, minDist, closest);

        assert(startFace!=NULL && endFace!=NULL);

        std::vector<CutVertex::VertexPointer> seedVec;
        for(int i=0; i<3; i++)
            seedVec.push_back(startFace->V(i));

        //getting the geodesic distance from the start/end face and some other data
        //that will be used in the weight computation
        typename  CutMesh::template PerFaceAttributeHandle <float>  gfH1
                = vcg::tri::Allocator<CutMesh>::template AddPerFaceAttribute<float>(cm, std::string("GeoDis1"));
        vcg::tri::Geodesic<CutMesh>::Compute(cm, seedVec);

        float max1=0.0f;
        float maxq=0.0f;
        //getting also the maximum perFaceQuality value
        for(CutMesh::FaceIterator fit= cm.face.begin(); fit!=cm.face.end(); fit++){
            if(fit->Q()>=maxq)
                maxq=fit->Q();
            gfH1[fit] = (fit->V(0)->Q()+fit->V(1)->Q()+fit->V(2)->Q())/3.0f;
            if(gfH1[fit]>=max1)
                max1=gfH1[fit];
        }


        //this functor will be used to compute edge weights on the dual graph
        WeightFunctor<CutMesh> wf(ambient, dihedral, geodesic, elength, startFace, endFace, gfH1, max1, geomin, geomax, maxq);
        //start actual computation
        vcg::tri::GraphBuilder<CutMesh, WeightFunctor<CutMesh> >::Compute(cm, wf, startFace, endFace);
        vcg::tri::Allocator<CutMesh>::DeletePerFaceAttribute(cm,gfH1);
        vcg::tri::Append<CMeshO,CutMesh>::MeshCopy(m,cm);
        return true;
    }
    }
    return false;
}
Пример #3
0
bool FilterGeodesic::applyFilter(QAction *filter, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos * /*cb*/)
{
    MeshModel &m=*(md.mm());
    CMeshO::FaceIterator fi;
    CMeshO::VertexIterator vi;
    switch (ID(filter)) {
        case FP_QUALITY_POINT_GEODESIC:
            {
                m.updateDataMask(MeshModel::MM_VERTFACETOPO);
                m.updateDataMask(MeshModel::MM_VERTMARK);
                m.updateDataMask(MeshModel::MM_VERTQUALITY);
                m.updateDataMask(MeshModel::MM_VERTCOLOR);
                tri::UpdateFlags<CMeshO>::FaceBorderFromVF(m.cm);
                tri::UpdateFlags<CMeshO>::VertexBorderFromFace(m.cm);
                Point3f startPoint = par.getPoint3f("startPoint");
                // first search the closest point on the surface;
                CMeshO::VertexPointer startVertex=0;
                float minDist= std::numeric_limits<float>::max();

                for(vi=m.cm.vert.begin();vi!=m.cm.vert.end();++vi) if(!(*vi).IsD())
                    if(SquaredDistance(startPoint,(*vi).P()) < minDist) {
                        startVertex=&*vi;
                        minDist=SquaredDistance(startPoint,(*vi).P());
                        }


                Log("Input point is %f %f %f Closest on surf is %f %f %f",startPoint[0],startPoint[1],startPoint[2],startVertex->P()[0],startVertex->P()[1],startVertex->P()[2]);

                // Now actually compute the geodesic distnace from the closest point
                float dist_thr = par.getAbsPerc("maxDistance");
                tri::EuclideanDistance<CMeshO> dd;
                tri::Geodesic<CMeshO>::Compute(m.cm, vector<CVertexO*>(1,startVertex),dd,dist_thr);

                // Cleaning Quality value of the unrefernced vertices
                // Unreached vertexes has a quality that is maxfloat
                int unreachedCnt=0;
                float unreached  = std::numeric_limits<float>::max();
                for(vi=m.cm.vert.begin();vi!=m.cm.vert.end();++vi) if(!(*vi).IsD())
                    if((*vi).Q() == unreached) {
                            unreachedCnt++;
                            (*vi).Q()=0;
                        }
                if(unreachedCnt >0 )
                        Log("Warning: %i vertices were unreacheable from the borders, probably your mesh has unreferenced vertices",unreachedCnt);

                tri::UpdateColor<CMeshO>::PerVertexQualityRamp(m.cm);

            }
            break;
        case FP_QUALITY_BORDER_GEODESIC:
            {
                m.updateDataMask(MeshModel::MM_VERTFACETOPO);
                m.updateDataMask(MeshModel::MM_VERTMARK);
                m.updateDataMask(MeshModel::MM_VERTQUALITY);
                m.updateDataMask(MeshModel::MM_VERTCOLOR);
                tri::UpdateFlags<CMeshO>::FaceBorderFromVF(m.cm);
                tri::UpdateFlags<CMeshO>::VertexBorderFromFace(m.cm);

                bool ret = tri::Geodesic<CMeshO>::DistanceFromBorder(m.cm);

                // Cleaning Quality value of the unrefernced vertices
                // Unreached vertexes has a quality that is maxfloat
                int unreachedCnt=0;
                float unreached  = std::numeric_limits<float>::max();
                for(vi=m.cm.vert.begin();vi!=m.cm.vert.end();++vi) if(!(*vi).IsD())
                    if((*vi).Q() == unreached) {
                            unreachedCnt++;
                            (*vi).Q()=0;
                        }
                if(unreachedCnt >0 )
                        Log("Warning: %i vertices were unreacheable from the borders, probably your mesh has unreferenced vertices",unreachedCnt);

                if(!ret) Log("Mesh Has no borders. No geodesic distance computed");
                    else tri::UpdateColor<CMeshO>::PerVertexQualityRamp(m.cm);
                }

            break;
        default: assert(0);
            break;
    }
return true;
}
Пример #4
0
// The Real Core Function doing the actual mesh processing.
bool FilterHarmonicPlugin::applyFilter(QAction * action, MeshDocument & md, RichParameterSet & par, vcg::CallBackPos * cb)
{
	switch(ID(action))
	{
	case FP_SCALAR_HARMONIC_FIELD :
	{
		typedef vcg::GridStaticPtr<CMeshO::VertexType, CMeshO::ScalarType> VertexGrid;

		typedef double                           CoeffScalar; // TODO, when moving the code to a class make it a template (CoeffScalar = double)

		typedef CMeshO::ScalarType               ScalarType;
		typedef CMeshO::CoordType                CoordType;
		typedef CMeshO::VertexType               VertexType;
		typedef CMeshO::FaceType                 FaceType;

		typedef Eigen::Triplet<CoeffScalar>      T;
		typedef Eigen::SparseMatrix<CoeffScalar> SpMat; //sparse matrix type of double


		CMeshO & m = md.mm()->cm;

		vcg::tri::Allocator<CMeshO>::CompactFaceVector(m);
		vcg::tri::Allocator<CMeshO>::CompactVertexVector(m);

		md.mm()->updateDataMask(MeshModel::MM_FACEFACETOPO | MeshModel::MM_VERTMARK);
		vcg::tri::UpdateBounding<CMeshO>::Box(m);
		vcg::tri::UpdateTopology<CMeshO>::FaceFace(m);

		int n  = m.VN();
		int fn = m.FN();

		std::vector<T>             coeffs; // coefficients of the system
		std::map<size_t,CoeffScalar> sums; // row sum of the coefficient

		SpMat laplaceMat; // the system to be solved
		laplaceMat.resize(n, n);

		Log("Generating coefficients.`");
		cb(0, "Generating coefficients...");
		vcg::tri::UpdateFlags<CMeshO>::FaceClearV(m);
		// Iterate over the faces
		for (size_t i = 0; i < m.face.size(); ++i)
		{
			CMeshO::FaceType & f = m.face[i];

			if (f.IsD())
			{
				assert(int(i) == fn);
				break; // TODO FIX the indexing of vertices
			}

			assert(!f.IsV());
			f.SetV();

			// Generate coefficients for each edge
			for (int idx = 0; idx < 3; ++idx)
			{
				CoeffScalar weight;
				WeightInfo res = ComputeWeight<FaceType, CoeffScalar>(f, idx, weight);

				switch (res)
				{
				case EdgeAlreadyVisited : continue;
				case Success            : break;
				case BorderEdge         :
					this->errorMessage = "Mesh not closed, cannot compute harmonic field on mesh containing holes or borders";
					return false;
				default: assert(0);
				}

//				if (weight < 0) weight = 0; // TODO check if negative weight may be an issue

				// Add the weight to the coefficients vector for both the vertices of the considered edge
				size_t v0_idx = vcg::tri::Index(m, f.V0(idx));
				size_t v1_idx = vcg::tri::Index(m, f.V1(idx));

				coeffs.push_back(T(v0_idx, v1_idx, -weight));
				coeffs.push_back(T(v1_idx, v0_idx, -weight));

				// Add the weight to the row sum
				sums[v0_idx] += weight;
				sums[v1_idx] += weight;
			}

			f.SetV();
		}

		// Fill the system matrix
		Log("Fill the system matrix");
		cb(10, "Filling the system matrix...");
		laplaceMat.reserve(coeffs.size());
		for (std::map<size_t,CoeffScalar>::const_iterator it = sums.begin(); it != sums.end(); ++it)
		{
			coeffs.push_back(T(it->first, it->first, it->second));
		}
		laplaceMat.setFromTriplets(coeffs.begin(), coeffs.end());

		// Get the two vertices with value set
		VertexGrid vg;
		vg.Set(m.vert.begin(), m.vert.end());

		vcg::vertex::PointDistanceFunctor<ScalarType> pd;
		vcg::tri::Tmark<CMeshO, VertexType> mv;
		mv.SetMesh(&m);
		mv.UnMarkAll();
		CoordType  closestP;
		ScalarType minDist = 0;
		VertexType * vp0 = vcg::GridClosest(vg, pd, mv, par.getPoint3f("point1"), m.bbox.Diag(), minDist, closestP);
		VertexType * vp1 = vcg::GridClosest(vg, pd, mv, par.getPoint3f("point2"), m.bbox.Diag(), minDist, closestP);
		if (vp0 == NULL || vp1 == NULL || vp0 == vp1)
		{
			this->errorMessage = "Error occurred for selected points.";
			return false;
		}

		size_t v0_idx = vcg::tri::Index(m, vp0);
		size_t v1_idx = vcg::tri::Index(m, vp1);

		// Add penalty factor alpha
		Log("Setting up the system matrix");
		const CoeffScalar alpha = pow(10, 8);

		Eigen::Matrix<CoeffScalar, Eigen::Dynamic, 1> b, x; // Unknown and known terms vectors
		b.setZero(n);
		b(v0_idx) = alpha * par.getFloat("value1");
		b(v1_idx) = alpha * par.getFloat("value2");

		laplaceMat.coeffRef(v0_idx, v0_idx) += alpha;
		laplaceMat.coeffRef(v1_idx, v1_idx) += alpha;

		// Solve system laplacianMat x = b
		Log("System matrix decomposition...");
		cb(20, "System matrix decomposition...");
		Eigen::SimplicialLDLT<Eigen::SparseMatrix<CoeffScalar> > solver; // TODO eventually use another solver
		solver.compute(laplaceMat);
		if(solver.info() != Eigen::Success)
		{
			// decomposition failed
			this->errorMessage = "System matrix decomposition failed: ";
			if (solver.info() == Eigen::NumericalIssue)
				this->errorMessage += "numerical issue.";
			else if (solver.info() == Eigen::NoConvergence)
				this->errorMessage += "no convergence.";
			else if (solver.info() == Eigen::InvalidInput)
				this->errorMessage += "invalid input.";

			return false;
		}

		Log("Solving the system...");
		cb(85, "Solving the system...");
		x = solver.solve(b);
		if(solver.info() != Eigen::Success)
		{
			// solving failed
			this->errorMessage = "System solving failed.";
			return false;
		}

		// Colorize bands for the 0-1 interval
		if (par.getBool("colorize"))
		{
			float steps = 20.0f;
			for (size_t i = 0; int(i) < n; ++i)
			{
				bool on = (int)(x[i]*steps)%2 == 1;
				if (on)
				{
					m.vert[i].C() = vcg::Color4b::ColorRamp(0,2,x[i]);
				}
				else
				{
					m.vert[i].C() = vcg::Color4b::White;
				}
			}
		}

		// Set field value into vertex quality attribute
		for (size_t i = 0; int(i) < n; ++i)
		{
			m.vert[i].Q() = x[i];
		}

		cb(100, "Done.");

		return true;
	}
	default : assert(0);
	}
	return false;
}
Пример #5
0
bool AmbientOcclusionPlugin::applyFilter(QAction *filter, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos *cb)
{
    MeshModel &m=*(md.mm());
    if(ID(filter)==FP_FACE_AMBIENT_OCCLUSION ) perFace=true;
	else perFace = false;
	
	useGPU = par.getBool("useGPU");
	useVBO = par.getBool("useVBO");
	depthTexSize = par.getInt("depthTexSize");
	depthTexArea = depthTexSize*depthTexSize;
	numViews = par.getInt("reqViews");
	errInit = false;
	float dirBias = par.getFloat("dirBias");
	Point3f coneDir = par.getPoint3f("coneDir");
	float coneAngle = par.getFloat("coneAngle");
	
	if(perFace) 
	  m.updateDataMask(MeshModel::MM_FACEQUALITY | MeshModel::MM_FACECOLOR);
	else 
		m.updateDataMask(MeshModel::MM_VERTQUALITY | MeshModel::MM_VERTCOLOR);

	
	std::vector<Point3f> unifDirVec;
	GenNormal<float>::Uniform(numViews,unifDirVec);
	
	std::vector<Point3f> coneDirVec;
	GenNormal<float>::UniformCone(numViews, coneDirVec, math::ToRad(coneAngle), coneDir);
	
	std::random_shuffle(unifDirVec.begin(),unifDirVec.end());
	std::random_shuffle(coneDirVec.begin(),coneDirVec.end());

	int unifNum = floor(unifDirVec.size() * (1.0 - dirBias ));
	int coneNum = floor(coneDirVec.size() * (dirBias ));
									
	
	viewDirVec.clear();
	viewDirVec.insert(viewDirVec.end(),unifDirVec.begin(),unifDirVec.begin()+unifNum);
	viewDirVec.insert(viewDirVec.end(),coneDirVec.begin(),coneDirVec.begin()+coneNum);
	
	numViews = viewDirVec.size();


	this->glContext->makeCurrent();
	this->initGL(cb,m.cm.vn);
	unsigned int widgetSize = std::min(maxTexSize, depthTexSize);
	QSize fbosize(widgetSize,widgetSize);
	QGLFramebufferObjectFormat frmt;
	frmt.setInternalTextureFormat(GL_RGBA);
	frmt.setAttachment(QGLFramebufferObject::Depth);
	QGLFramebufferObject fbo(fbosize,frmt);
	qDebug("Start Painting window size %i %i", fbo.width(), fbo.height());
	GLenum err = glGetError();
	fbo.bind();
	processGL(m,viewDirVec);
	fbo.release();
	err = glGetError();
	const GLubyte* errname = gluErrorString(err);
	qDebug("End Painting");
	this->glContext->doneCurrent();
	return !errInit;
}