Beispiel #1
0
Handle<Value> EnvWrap::ctor(const Arguments& args) {
    HandleScope scope;
    int rc;

    EnvWrap* wrapper = new EnvWrap();
    rc = mdb_env_create(&(wrapper->env));
    
    if (rc != 0) {
        mdb_env_close(wrapper->env);
        ThrowException(Exception::Error(String::New(mdb_strerror(rc))));
        return scope.Close(Undefined());
    }
    
    wrapper->Wrap(args.This());
    return args.This();
}
bool FilterScreenedPoissonPlugin::applyFilter( const QString& filterName,MeshDocument& md,EnvWrap& env, vcg::CallBackPos* cb)
{
  if (filterName == "Screened Poisson Surface Reconstruction")
  {
    MeshModel *mm =md.mm();
    MeshModel *pm =md.addNewMesh("","Poisson mesh",false);
    md.setVisible(pm->id(),false);

    pm->updateDataMask(MeshModel::MM_VERTQUALITY);
    PoissonParam<Scalarm> pp;

    MeshModelPointStream<Scalarm> meshStream(mm->cm);
    MeshDocumentPointStream<Scalarm> documentStream(md);

    pp.MaxDepthVal = env.evalInt("depth");
    pp.FullDepthVal = env.evalInt("fullDepth");
    pp.CGDepthVal= env.evalInt("cgDepth");
    pp.ScaleVal = env.evalFloat("scale");
    pp.SamplesPerNodeVal = env.evalFloat("samplesPerNode");
    pp.PointWeightVal = env.evalFloat("pointWeight");
    pp.ItersVal = env.evalInt("iters");
    pp.ConfidenceFlag = env.evalBool("confidence");
    pp.NormalWeightsFlag = env.evalBool("nWeights");
    pp.DensityFlag = true;
    if(env.evalBool("visibleLayer"))
    {
      MeshModel *m=0;
      while(m=md.nextVisibleMesh(m))
        PoissonClean(m->cm, (pp.ConfidenceFlag || pp.NormalWeightsFlag));

      Execute<Scalarm>(&documentStream,pm->cm,pp,cb);
    }
    else
    {
      PoissonClean(mm->cm, (pp.ConfidenceFlag || pp.NormalWeightsFlag));
      Execute<Scalarm>(&meshStream,pm->cm,pp,cb);
    }
    pm->UpdateBoxAndNormals();
    md.setVisible(pm->id(),true);

    return true;
  }
  return false;
}
bool SampleXMLFilterPlugin::applyFilter( const QString& filterName,MeshDocument& md,EnvWrap& env, vcg::CallBackPos* cb)
{
	if (filterName == "Random vertex displacement")
	{
		MeshModel &m=*md.mm();
		srand(time(NULL)); 
		const float max_displacement =env.evalFloat("Displacement");

		for(unsigned int i = 0; i< m.cm.vert.size(); i++)
		{
			// Typical usage of the callback for showing a nice progress bar in the bottom. 
		//	// First parameter is a 0..100 number indicating percentage of completion, the second is an info string.
			cb(100*i/m.cm.vert.size(), "Randomly Displacing...");

			float rndax = (float(2.0f*rand())/RAND_MAX - 1.0f ) *max_displacement;
			float rnday = (float(2.0f*rand())/RAND_MAX - 1.0f ) *max_displacement;
			float rndaz = (float(2.0f*rand())/RAND_MAX - 1.0f ) *max_displacement;
			m.cm.vert[i].P() += vcg::Point3f(rndax,rnday,rndaz);
			//if ( i % 1000 == 0)
			QList<int> meshlist;
			meshlist << m.id();
			md.updateRenderStateMeshes(meshlist,int(MeshModel::MM_VERTCOORD));
			if (intteruptreq)
				return true;
		}

		//// Log function dump textual info in the lower part of the MeshLab screen. 
		Log("Successfully displaced %i vertices",m.cm.vn);

		//// to access to the parameters of the filter dialog simply use the getXXXX function of the FilterParameter Class
		if(env.evalBool("UpdateNormals"))	
			vcg::tri::UpdateNormals<CMeshO>::PerVertexNormalizedPerFace(m.cm);
		
 		vcg::tri::UpdateBounding<CMeshO>::Box(m.cm);

		return true;
	}
	return false;
}
Beispiel #4
0
// Core Function doing the actual mesh processing.
bool FilterMeasurePlugin::applyFilter( const QString& filterName,MeshDocument& md,EnvWrap& env, vcg::CallBackPos * /*cb*/ )
{
    if (filterName == "Compute Topological Measures")
    {
        CMeshO &m=md.mm()->cm;
        tri::Allocator<CMeshO>::CompactFaceVector(m);
        tri::Allocator<CMeshO>::CompactVertexVector(m);
        md.mm()->updateDataMask(MeshModel::MM_FACEFACETOPO);
        md.mm()->updateDataMask(MeshModel::MM_VERTFACETOPO);

        int edgeManifNum = tri::Clean<CMeshO>::CountNonManifoldEdgeFF(m,true);
        int faceEdgeManif = tri::UpdateSelection<CMeshO>::FaceCount(m);
        tri::UpdateSelection<CMeshO>::VertexClear(m);
        tri::UpdateSelection<CMeshO>::FaceClear(m);

        int vertManifNum = tri::Clean<CMeshO>::CountNonManifoldVertexFF(m,true);
        tri::UpdateSelection<CMeshO>::FaceFromVertexLoose(m);
        int faceVertManif = tri::UpdateSelection<CMeshO>::FaceCount(m);
        int edgeNum=0,borderNum=0;
        tri::Clean<CMeshO>::CountEdges(m, edgeNum, borderNum);
        int holeNum;
        Log("V: %6i E: %6i F:%6i",m.vn,edgeNum,m.fn);
        int unrefVertNum = tri::Clean<CMeshO>::CountUnreferencedVertex(m);
        Log("Unreferenced Vertices %i",unrefVertNum);
        Log("Boundary Edges %i",borderNum);

        int connectedComponentsNum = tri::Clean<CMeshO>::CountConnectedComponents(m);
        Log("Mesh is composed by %i connected component(s)\n",connectedComponentsNum);

        if(edgeManifNum==0 && vertManifNum==0) {
            Log("Mesh is two-manifold ");
        }

        if(edgeManifNum!=0) Log("Mesh has %i non two manifold edges and %i faces are incident on these edges\n",edgeManifNum,faceEdgeManif);

        if(vertManifNum!=0) Log("Mesh has %i non two manifold vertexes and %i faces are incident on these vertices\n",vertManifNum,faceVertManif);

        // For Manifold meshes compute some other stuff
        if(vertManifNum==0 && edgeManifNum==0)
        {
            holeNum = tri::Clean<CMeshO>::CountHoles(m);
            Log("Mesh has %i holes",holeNum);

            int genus = tri::Clean<CMeshO>::MeshGenus(m.vn-unrefVertNum, edgeNum, m.fn, holeNum, connectedComponentsNum);
            Log("Genus is %i",genus);
        }
        else
        {
            Log("Mesh has a undefined number of holes (non 2-manifold mesh)");
            Log("Genus is undefined (non 2-manifold mesh)");
        }

        return true;
    }

    /************************************************************/
    if (filterName == "Compute Topological Measures for Quad Meshes")
    {
        CMeshO &m=md.mm()->cm;
        md.mm()->updateDataMask(MeshModel::MM_FACEFACETOPO);
        md.mm()->updateDataMask(MeshModel::MM_FACEQUALITY);

        if (! tri::Clean<CMeshO>::IsFFAdjacencyConsistent(m)) {
            this->errorMessage = "Error: mesh has a not consistent FF adjacency";
            return false;
        }
        if (! tri::Clean<CMeshO>::HasConsistentPerFaceFauxFlag(m)) {

            this->errorMessage = "QuadMesh problem: mesh has a not consistent FauxEdge tagging";
            return false;
        }

        int nQuads = tri::Clean<CMeshO>::CountBitQuads(m);
        int nTris = tri::Clean<CMeshO>::CountBitTris(m);
        int nPolys = tri::Clean<CMeshO>::CountBitPolygons(m);
        int nLargePolys = tri::Clean<CMeshO>::CountBitLargePolygons(m);
        if(nLargePolys>0) nQuads=0;

        Log("Mesh has %8i triangles \n",nTris);
        Log("         %8i quads \n",nQuads);
        Log("         %8i polygons \n",nPolys);
        Log("         %8i large polygons (with internal faux vertexes)",nLargePolys);

        if (! tri::Clean<CMeshO>::IsBitTriQuadOnly(m)) {
            this->errorMessage = "QuadMesh problem: the mesh is not TriQuadOnly";
            return false;
        }

        //
        //   i
        //
        //
        //   i+1     i+2
        tri::UpdateFlags<CMeshO>::FaceClearV(m);
        Distribution<float> AngleD; // angle distribution
        Distribution<float> RatioD; // ratio distribution
        tri::UpdateFlags<CMeshO>::FaceClearV(m);
        for(CMeshO::FaceIterator fi=m.face.begin(); fi!=m.face.end(); ++fi)
            if(!fi->IsV())
            {
                fi->SetV();
                // Collect the vertices
                Point3f qv[4];
                bool quadFound=false;
                for(int i=0; i<3; ++i)
                {
                    if((*fi).IsF(i) && !(*fi).IsF((i+1)%3) && !(*fi).IsF((i+2)%3) )
                    {
                        qv[0] = fi->V0(i)->P(),
                                qv[1] = fi->FFp(i)->V2( fi->FFi(i) )->P(),
                                        qv[2] = fi->V1(i)->P(),
                                                qv[3] = fi->V2(i)->P();
                        quadFound=true;
                    }
                }
                assert(quadFound);
                for(int i=0; i<4; ++i)
                    AngleD.Add(fabs(90-math::ToDeg(Angle(qv[(i+0)%4] - qv[(i+1)%4], qv[(i+2)%4] - qv[(i+1)%4]))));
                float edgeLen[4];

                for(int i=0; i<4; ++i)
                    edgeLen[i]=Distance(qv[(i+0)%4],qv[(i+1)%4]);
                std::sort(edgeLen,edgeLen+4);
                RatioD.Add(edgeLen[0]/edgeLen[3]);
            }

        Log("Right Angle Discrepancy  Avg %4.3f Min %4.3f Max %4.3f StdDev %4.3f Percentile 0.05 %4.3f percentile 95 %4.3f",
            AngleD.Avg(), AngleD.Min(), AngleD.Max(),AngleD.StandardDeviation(),AngleD.Percentile(0.05),AngleD.Percentile(0.95));

        Log("Quad Ratio   Avg %4.3f Min %4.3f Max %4.3f", RatioD.Avg(), RatioD.Min(), RatioD.Max());
        return true;
    }
    /************************************************************/
    if(filterName == "Compute Geometric Measures")
    {
        CMeshO &m=md.mm()->cm;
        tri::Inertia<CMeshO> I(m);
        float Area = tri::Stat<CMeshO>::ComputeMeshArea(m);
        float Volume = I.Mass();
        Log("Mesh Bounding Box Size %f %f %f", m.bbox.DimX(), m.bbox.DimY(), m.bbox.DimZ());
        Log("Mesh Bounding Box Diag %f ", m.bbox.Diag());
        Log("Mesh Volume  is %f", Volume);
        Log("Mesh Surface is %f", Area);
        Point3f bc=tri::Stat<CMeshO>::ComputeShellBarycenter(m);
        Log("Thin shell barycenter  %9.6f  %9.6f  %9.6f",bc[0],bc[1],bc[2]);

        if(Volume<=0) Log("Mesh is not 'solid', no information on barycenter and inertia tensor.");
        else
        {
            Log("Center of Mass  is %f %f %f", I.CenterOfMass()[0], I.CenterOfMass()[1], I.CenterOfMass()[2]);

            Matrix33f IT;
            I.InertiaTensor(IT);
            Log("Inertia Tensor is :");
            Log("    | %9.6f  %9.6f  %9.6f |",IT[0][0],IT[0][1],IT[0][2]);
            Log("    | %9.6f  %9.6f  %9.6f |",IT[1][0],IT[1][1],IT[1][2]);
            Log("    | %9.6f  %9.6f  %9.6f |",IT[2][0],IT[2][1],IT[2][2]);

            Matrix33f PCA;
            Point3f pcav;
            I.InertiaTensorEigen(PCA,pcav);
            Log("Principal axes are :");
            Log("    | %9.6f  %9.6f  %9.6f |",PCA[0][0],PCA[0][1],PCA[0][2]);
            Log("    | %9.6f  %9.6f  %9.6f |",PCA[1][0],PCA[1][1],PCA[1][2]);
            Log("    | %9.6f  %9.6f  %9.6f |",PCA[2][0],PCA[2][1],PCA[2][2]);

            Log("axis momenta are :");
            Log("    | %9.6f  %9.6f  %9.6f |",pcav[0],pcav[1],pcav[2]);
        }
        return true;
    }
    /************************************************************/
    if((filterName == "Per Vertex Quality Stat") || (filterName == "Per Face Quality Stat") )
    {
        CMeshO &m=md.mm()->cm;
        Distribution<float> DD;
        if(filterName == "Per Vertex Quality Stat")
            tri::Stat<CMeshO>::ComputePerVertexQualityDistribution(m, DD, false);
        else
            tri::Stat<CMeshO>::ComputePerFaceQualityDistribution(m, DD, false);

        Log("   Min %f Max %f",DD.Min(),DD.Max());
        Log("   Avg %f Med %f",DD.Avg(),DD.Percentile(0.5f));
        Log("   StdDev		%f",DD.StandardDeviation());
        Log("   Variance  %f",DD.Variance());
        return true;
    }

    if((filterName == "Per Vertex Quality Histogram") || (filterName == "Per Face Quality Histogram") )
    {
        CMeshO &m=md.mm()->cm;
        float RangeMin = env.evalFloat("HistMin");
        float RangeMax = env.evalFloat("HistMax");
        int binNum     = env.evalInt("binNum");

        Histogramf H;
        H.SetRange(RangeMin,RangeMax,binNum);
        if(filterName == "Per Vertex Quality Histogram")
        {
            for(CMeshO::VertexIterator vi = m.vert.begin(); vi != m.vert.end(); ++vi)
                if(!(*vi).IsD())
                {
                    assert(!math::IsNAN((*vi).Q()) && "You should never try to compute Histogram with Invalid Floating points numbers (NaN)");
                    H.Add((*vi).Q());
                }
        } else {
            for(CMeshO::FaceIterator fi = m.face.begin(); fi != m.face.end(); ++fi)
                if(!(*fi).IsD())
                {
                    assert(!math::IsNAN((*fi).Q()) && "You should never try to compute Histogram with Invalid Floating points numbers (NaN)");
                    H.Add((*fi).Q());
                }
        }
        Log("(         -inf..%15.7f) : %4.0f",RangeMin,H.BinCountInd(0));
        for(int i=1; i<=binNum; ++i)
            Log("[%15.7f..%15.7f) : %4.0f",H.BinLowerBound(i),H.BinUpperBound(i),H.BinCountInd(i));
        Log("[%15.7f..             +inf) : %4.0f",RangeMax,H.BinCountInd(binNum+1));
        return true;
    }
    return false;
}
Beispiel #5
0
XMLVec3Widget::XMLVec3Widget(const MLXMLPluginInfo::XMLMap& xmlWidgetTag,EnvWrap& envir,QWidget* p)
:XMLMeshLabWidget(xmlWidgetTag,envir,p)
{
	XMLStdParFrame* par = qobject_cast<XMLStdParFrame*>(p);
	if (par != NULL)
	{
		curr_gla = par->curr_gla;
		paramName = xmlWidgetTag[MLXMLElNames::paramName];
		//int row = gridLay->rowCount() - 1;

		descLab = new QLabel( xmlWidgetTag[MLXMLElNames::guiLabel],this);
		descLab->setToolTip(xmlWidgetTag[MLXMLElNames::paramHelpTag]);
		//gridLay->addWidget(descLab,row,0,Qt::AlignTop);

		hlay = new QHBoxLayout();

		for(int i =0;i<3;++i)
		{
			coordSB[i]= new QLineEdit(this);
			QFont baseFont=coordSB[i]->font();
			if(baseFont.pixelSize() != -1) baseFont.setPixelSize(baseFont.pixelSize()*3/4);
			else baseFont.setPointSize(baseFont.pointSize()*3/4);
			coordSB[i]->setFont(baseFont);
			//coordSB[i]->setMinimumWidth(coordSB[i]->sizeHint().width()/4);
			coordSB[i]->setMinimumWidth(0);
			coordSB[i]->setMaximumWidth(coordSB[i]->sizeHint().width()/2);
			//coordSB[i]->setSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::Fixed);
			coordSB[i]->setValidator(new QDoubleValidator(this));
			coordSB[i]->setAlignment(Qt::AlignRight);
			//this->addWidget(coordSB[i],1,Qt::AlignHCenter);
            coordSB[i]->setSizePolicy(QSizePolicy::MinimumExpanding,QSizePolicy::Preferred);
			hlay->addWidget(coordSB[i]);
		}
		vcg::Point3f def = envir.evalVec3(xmlWidgetTag[MLXMLElNames::paramDefExpr]);
		this->setPoint(paramName,def);
		if(curr_gla) // if we have a connection to the current glarea we can setup the additional button for getting the current view direction.
		{
			getPoint3Button = new QPushButton("Get",this);
			getPoint3Button->setMaximumWidth(getPoint3Button->sizeHint().width()/2);

			getPoint3Button->setFlat(true);
            getPoint3Button->setSizePolicy(QSizePolicy::Fixed,QSizePolicy::Preferred);

			hlay->addWidget(getPoint3Button);
			QStringList names;
			names << "View Dir";
			names << "View Pos";
			names << "Surf. Pos";
			names << "Camera Pos";

			getPoint3Combo = new QComboBox(this);
			getPoint3Combo->addItems(names);
			//getPoint3Combo->setMinimumWidth(getPoint3Combo->sizeHint().width());
			//this->addWidget(getPoint3Combo,0,Qt::AlignHCenter);
			hlay->addWidget(getPoint3Combo);

			connect(getPoint3Button,SIGNAL(clicked()),this,SLOT(getPoint()));
			connect(getPoint3Combo,SIGNAL(currentIndexChanged(int)),this,SLOT(getPoint()));
			connect(curr_gla,SIGNAL(transmitViewDir(QString,vcg::Point3f)),this,SLOT(setPoint(QString,vcg::Point3f)));
			connect(curr_gla,SIGNAL(transmitShot(QString,vcg::Shotf)),this,SLOT(setShot(QString,vcg::Shotf)));
			connect(curr_gla,SIGNAL(transmitSurfacePos(QString,vcg::Point3f)),this,SLOT(setPoint(QString,vcg::Point3f)));
			connect(this,SIGNAL(askViewDir(QString)),curr_gla,SLOT(sendViewDir(QString)));
			connect(this,SIGNAL(askViewPos(QString)),curr_gla,SLOT(sendMeshShot(QString)));
			connect(this,SIGNAL(askSurfacePos(QString)),curr_gla,SLOT(sendSurfacePos(QString)));
			connect(this,SIGNAL(askCameraPos(QString)),curr_gla,SLOT(sendCameraPos(QString)));
		}
		//gridLay->addLayout(hlay,row,1,Qt::AlignTop);
	}