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