コード例 #1
0
ファイル: filter_topo.cpp プロジェクト: openpattreco/3rdParty
//
// Filter interface start up
//
void FilterTopoPlugin::initParameterSet(QAction *action, MeshDocument & md, RichParameterSet & parlst) 
{
	MeshModel *target= md.mm();
	foreach (target, md.meshList) 
		if (target != md.mm())  break;

	doc = &md;

	 switch(ID(action))	 {
		case FP_RE_TOPO :  
			// Iterations editbox
			parlst.addParam(new RichInt(	"it", 
							4,
							"Number of refinement iterations used to build the new mesh", 
							"As higher is this value, as well defined will be the new mesh. Consider that more than 5 iterations may slow down your system"));
			// Distance editbox
			parlst.addParam(new RichAbsPerc(	"dist", 0.3f, 0.01f, 0.99f, 
								"Incremental distance %", 
								"This param represents the % distance for the local search algorithm used for new vertices allocation. Generally, 0.25-0.30 is a good value"));
			// Topology mesh list
			parlst.addParam(new RichMesh(	"userMesh", md.mm(), 
							"Topology mesh",
							"This mesh will be used as the new base topology, and will be replaced by the new mesh"));
			// Original mesh list
			parlst.addParam(new RichMesh( "inMesh", target,
							"Original mesh",
							"The new mesh will be elaborated using this model"));
		break;
											
		default : assert(0); 
	}
}
コード例 #2
0
ファイル: filter_ssynth.cpp プロジェクト: GuoXinxiao/meshlab
bool FilterSSynth::applyFilter(QAction*  filter, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos *cb)
{
    md.addNewMesh("",this->filterName(ID(filter)));
    QWidget *  parent=(QWidget*)this->parent();
    RichParameter* grammar=par.findParameter(QString("grammar"));
    RichParameter* seed=par.findParameter(QString("seed"));
    int sphereres=par.findParameter("sphereres")->val->getInt();
    this->renderTemplate=GetTemplate(sphereres);
    if(this->renderTemplate!=QString::Null()){
    QString path=ssynth(grammar->val->getString(),-50,seed->val->getInt(),cb);
    if(QFile::exists(path)){
    QFile file(path);
    int mask;
     QString name(file.fileName());
        openX3D(name,*(md.mm()),mask,cb);
    file.remove();
    return true;
        }
        else{
            QString message=QString("An error occurred during the mesh generation:" ).append(path);
            QMessageBox::critical(parent,"Error",message);
                return false;
        }
    }
    else{
        QMessageBox::critical(parent,"Error","Sphere resolution must be between 1 and 4"); return false;
    }
}
コード例 #3
0
 bool FilterCreateIso::applyFilter(QAction *filter, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos * cb)
 {
   md.addNewMesh("",this->filterName(ID(filter)));
   MeshModel &m=*(md.mm());
   if(filter->text() == filterName(FP_CREATEISO) )
   {

     SimpleVolume<SimpleVoxel<Scalarm> > 	volume;

     typedef vcg::tri::TrivialWalker<CMeshO, SimpleVolume<SimpleVoxel<Scalarm> >	> MyWalker;
     typedef vcg::tri::MarchingCubes<CMeshO, MyWalker>	MyMarchingCubes;
     MyWalker walker;

     const int gridSize=par.getInt("Resolution");
     // Simple initialization of the volume with some cool perlin noise
     volume.Init(Point3i(gridSize,gridSize,gridSize), Box3m(Point3m(0,0,0),Point3m(1,1,1)));
     for(int i=0;i<gridSize;i++)
       for(int j=0;j<gridSize;j++)
         for(int k=0;k<gridSize;k++)
           volume.Val(i,j,k)=(j-gridSize/2)*(j-gridSize/2)+(k-gridSize/2)*(k-gridSize/2) + i*gridSize/5*(float)math::Perlin::Noise(i*.2,j*.2,k*.2);

     printf("[MARCHING CUBES] Building mesh...");
     MyMarchingCubes mc(m.cm, walker);
     walker.BuildMesh<MyMarchingCubes>(m.cm, volume, mc, (gridSize*gridSize)/10,cb);
     m.UpdateBoxAndNormals();
   }
   return true;
 }
コード例 #4
0
void EditVirtualScanPlugin::go( void )
{
    assert( glArea && inputMeshModel );
    CMeshO* firstCloud = 0, *secondCloud = 0;
    MeshDocument* mDoc = glArea->meshDoc;
    MeshModel* tmpModel = 0;

    if( unifyClouds )
    {
        tmpModel = mDoc->addNewMesh( "VS Point Cloud", 0, false );
        firstCloud = &( tmpModel->cm );
        secondCloud = firstCloud;
    }
    else
    {
        tmpModel = mDoc->addNewMesh( "VS Uniform Samples", 0, false );
        firstCloud = &( tmpModel->cm );
        tmpModel = mDoc->addNewMesh( "VS Feature Samples", 0, false );
        secondCloud = &( tmpModel->cm );
    }

    MyGLWidget* tmpWidget = new MyGLWidget
                            ( &params, inputMeshModel, firstCloud, secondCloud, glArea );
    bool ok = tmpWidget->result;
    if( !ok )
    {
        QString errorMessage = tmpWidget->errorString;
        Log( errorMessage.toStdString().c_str() );
    }
    delete tmpWidget;
}
コード例 #5
0
bool MeshGridPlugin::applyFilter(QAction *algo, MeshDocument &md,
                                 RichParameterSet & par, vcg::CallBackPos *cb)
{

    int cols = par.getInt("numVertX");
    int rows = par.getInt("numVertY");

    float totalw = 1.0;
    float totalh = 1.0;
    int w = cols+1;
    int h = rows+1;
    float wl = 1.0/cols;
    float hl = 1.0/rows;

    qDebug("w %d h %d",w,h);
    if(w <= 0 || h <= 0) {
        return false;
    }

    md.addNewMesh("",QString("%1_%2").arg(rows).arg(cols));
    MeshModel &m=*(md.mm());



    // use Grid function to generate Grid
    std::vector<float> data(w*h,0);
    tri::Grid<CMeshO>(m.cm, w, h, 1, 1, &data[0]);


    {
        // move x and y
        double halfw = double(w-1)/2;
        double halfh = double(h-1)/2;
        double wld = wl/double(w);
        double hld = hl/float(h);


//      CMeshO::VertexIterator vi;
//      for(vi = m.cm.vert.begin(); vi != m.cm.vert.end(); ++vi)
//      {
//         // qDebug("pos x: %f y: %f",(*vi).P()[0],(*vi).P()[1]);
//        //(*vi).P()[0] = (*vi).P()[0] - (wld * halfw);
//        //(*vi).P()[1] = (*vi).P()[1] - (hld * halfh);
//        //  (*vi).P()[0] = (*vi).P()[0] - totalw/2;
//        //  (*vi).P()[1] = (*vi).P()[1] - totalh/2;
//         // qDebug("after pos x: %f y: %f",(*vi).P()[0],(*vi).P()[1]);
//      }
    }
    // update bounding box, normals
//   Matrix44f rot; rot.SetRotateDeg(180,Point3f(0,1,0));
//   tri::UpdatePosition<CMeshO>::Matrix(m.cm,rot,false);
    tri::UpdateNormal<CMeshO>::PerVertexNormalizedPerFace(m.cm);
    tri::UpdateNormal<CMeshO>::NormalizePerFace(m.cm);
    tri::UpdateBounding<CMeshO>::Box(m.cm);

    CMeshO::VertexIterator vi;


    return true;
}
コード例 #6
0
ファイル: DynamicMeshSubFilter.cpp プロジェクト: Booley/nbis
bool DynamicMeshSubFilter::configurationHasChanged(MeshDocument& md, RichParameterSet& par){
    bool changed = m_seconds != par.getInt("seconds");
    changed |= m_fps != par.getInt("fps");
    changed |= m_iterations != par.getInt("iterations");
    changed |= m_contacts != par.getInt("contacts");
    changed |= m_bounciness != par.getFloat("bounciness");
    changed |= m_gravity != par.getFloat("gravity");
    changed |= m_friction != par.getFloat("friction");

    if(unsigned(md.size()) == m_files.size())
        for(unsigned i = 0; i < m_files.size(); i++)
            changed |= m_files.at(i) != md.getMesh(i)->fileName;
    else
        changed = true;

    m_files.clear();
    for(int i = 0; i < md.size(); i++)
        m_files.push_back(md.getMesh(i)->fileName);

    m_seconds = par.getInt("seconds");
    m_fps = par.getInt("fps");
    m_iterations = par.getInt("iterations");
    m_contacts = par.getInt("contacts");
    m_bounciness = par.getFloat("bounciness");
    m_gravity = par.getFloat("gravity");
    m_friction = par.getFloat("friction");
    return changed;
}
コード例 #7
0
bool AlgoDemoPlugin::applyFilter(QAction *algo, MeshDocument &md,
                             RichParameterSet & par, vcg::CallBackPos *cb)
{

   MeshModel* pm  = md.mm();
   if(pm == NULL) return false;
   
   /*
   MainWindow* mainwindow;
    foreach (QWidget *widget, QApplication::topLevelWidgets())
    {
        MainWindow* mainwindow = dynamic_cast<MainWindow*>(widget);
        if (mainwindow)
        {
            break;
        }
    }
	if (mainwindow == NULL)
        {
            return false;
        }
		
    MeshModel* prm = mainwindow->newProjectAddMesh("resultant mesh","resultant mesh");
		

    GLArea* newGLA = mainwindow->newProject("resultant mesh");

    MeshModel* prm = newGLA->md()->addNewMesh("","resultant mesh",true);
	*/

   MeshModel* prm = md.addNewMesh("","resultant mesh",true);

    pm->cm.vert;         //vertics
    pm->cm.face;            //faces
    pm->cm.selVertVector;   //landmarks


    vcg::tri::Append<CMeshO,CMeshO>::MeshCopy(prm->cm,pm->cm);

    CMeshO::VertexIterator vi;
    for(vi = pm->cm.vert.begin(); vi != pm->cm.vert.end(); ++vi)
    {
        //prm->cm.addVertex (/*const aol::Vec3< RealType > &coords*/);
     // qDebug("pos x: %f y: %f",(*vi).P()[0],(*vi).P()[1]);
    //(*vi).P()[0] = (*vi).P()[0] - (wld * halfw);
    //(*vi).P()[1] = (*vi).P()[1] - (hld * halfh);
    //  (*vi).P()[0] = (*vi).P()[0] - totalw/2;
    //  (*vi).P()[1] = (*vi).P()[1] - totalh/2;
     // qDebug("after pos x: %f y: %f",(*vi).P()[0],(*vi).P()[1]);
    }
    CMeshO::FaceIterator vf;
    for(vf = pm->cm.face.begin(); vf!= pm->cm.face.end(); ++vf)
    {
				//(*vf).V()
    }

    
    return true;
}
コード例 #8
0
void DecorateBackgroundPlugin::decorateDoc(QAction *a, MeshDocument &m, RichParameterSet * parset,GLArea *gla, QPainter *, GLLogStream &)
{
  static QString lastname("unitialized");
	switch(ID(a))
	{
	  case DP_SHOW_CUBEMAPPED_ENV :
		{
      if(!cm.IsValid() || (lastname != cubemapFileName ) )
      {
        qDebug( "Current CubeMapPath Dir: %s ",qPrintable(cubemapFileName));
        glewInit();
        bool ret = cm.Load(qPrintable(cubemapFileName));
        lastname=cubemapFileName;
        if(! ret ) return;
        //QMessageBox::warning(gla,"Cubemapped background decoration","Warning unable to load cube map images: " + cubemapFileName );
        cm.radius=10;
      }
			if(!cm.IsValid()) return;

      Matrix44f tr;
			glGetv(GL_MODELVIEW_MATRIX,tr);			
			// Remove the translation from the current matrix by simply padding the last column of the matrix
      tr.SetColumn(3,Point4f(0,0,0,1.0));
			//Remove the scaling from the the current matrix by adding an inverse scaling matrix
			float scale = 1.0/pow(tr.Determinant(),1.0f/3.0f);
			Matrix44f Scale; 
			Scale.SetDiagonal(scale);
			tr=tr*Scale;

			glMatrixMode(GL_PROJECTION);
			glPushMatrix();
			glMatrixMode(GL_MODELVIEW);
			glPushMatrix();
				cm.DrawEnvCube(tr);
			glPopMatrix();
			glMatrixMode(GL_PROJECTION);
			glPopMatrix();
			glMatrixMode(GL_MODELVIEW);
    } break;
  case DP_SHOW_GRID :
    {
      emit this->askViewerShot("me");
      Box3f bb=m.bbox();
      float scaleBB = parset->getFloat(BoxRatioParam());
      float majorTick = parset->getFloat(GridMajorParam());
      float minorTick = parset->getFloat(GridMinorParam());
      bool gridSnap = parset->getBool(GridSnapParam());
      bool backFlag = parset->getBool(GridBackParam());
      bool shadowFlag = parset->getBool(ShowShadowParam());
      Color4b backColor = parset->getColor4b(GridColorBackParam());
      Color4b frontColor = parset->getColor4b(GridColorFrontParam());
      bb.Offset((bb.max-bb.min)*(scaleBB-1.0));
      DrawGriddedCube(*m.mm(),bb,majorTick,minorTick,gridSnap,backFlag,shadowFlag,backColor,frontColor,gla);
    } break;
  }
}
コード例 #9
0
void AlignTools::buildParameterSet(MeshDocument &md,RichParameterSet & parlst)
{
	vcg::AlignPair::Param ICPParameters;
	AlignParameter::buildRichParameterSet(ICPParameters, parlst);

	parlst.addParam(new RichBool(UseMarkers, true, "Use Markers for Alignment","if true (default), then use the user picked markers to do an alignment (or pre alignment if you also use ICP)."));
	parlst.addParam(new RichBool(AllowScaling, false, "Scale the mesh","if true (false by default), in addition to the alignment, scale the mesh based on the points picked"));
	
	parlst.addParam(new RichBool(UseICP, true, "Use ICP for Alignment","if true (default), then use the ICP to align the two meshes."));
	
	parlst.addParam(new RichMesh (StuckMesh, md.mm(), &md,"Stuck Mesh",
			"The mesh that will not move."));
	parlst.addParam(new RichMesh (MeshToMove, md.mm(), &md, "Mesh to Move",
			"The mesh that will move to fit close to the Stuck Mesh."));
}
コード例 #10
0
ファイル: filter_fractal.cpp プロジェクト: GuoXinxiao/meshlab
void FilterFractal::initParameterSetForFractalDisplacement(QAction *filter, MeshDocument &md, RichParameterSet &par)
{
    bool terrain_filter = (ID(filter) == CR_FRACTAL_TERRAIN);

    if(terrain_filter) {
        par.addParam(new RichInt("steps", 8, "Subdivision steps:", "Defines the detail of the generated terrain. Allowed values are in range [2,9]. Use values from 6 to 9 to obtain reasonable results."));
        par.addParam(new RichDynamicFloat("maxHeight", 0.2, 0, 1, "Max height:", "Defines the maximum perturbation height as a fraction of the terrain's side."));
    } else {
        float diag = md.mm()->cm.bbox.Diag();
        par.addParam(new RichAbsPerc("maxHeight", 0.02 * diag, 0, 0.5*diag, "Max height:", "Defines the maximum height for the perturbation."));
    }

    par.addParam(new RichDynamicFloat("scale", 1, 0, 10, "Scale factor:", "Scales the fractal perturbation in and out. Values larger than 1 mean zoom out; values smaller than one mean zoom in."));
    if (!terrain_filter)
    {
        par.addParam(new RichInt("smoothingSteps", 5, "Normals smoothing steps:", "Face normals will be smoothed to make the perturbation more homogeneous. This parameter represents the number of smoothing steps." ));
    }
    par.addParam(new RichFloat("seed", 2, "Seed:", "By varying this seed, the terrain morphology will change.\nDon't change the seed if you want to refine the current terrain morphology by changing the other parameters."));

    QStringList algList;
    algList << "fBM (fractal Brownian Motion)" << "Standard multifractal" << "Heterogeneous multifractal" << "Hybrid multifractal terrain" << "Ridged multifractal terrain";
    par.addParam(new RichEnum("algorithm", 4, algList, "Algorithm", "The algorithm with which the fractal terrain will be generated."));
    par.addParam(new RichDynamicFloat("octaves", 8.0, 1.0, 20.0, "Octaves:", "The number of Perlin noise frequencies that will be used to generate the terrain. Reasonable values are in range [2,9]."));
    par.addParam(new RichFloat("lacunarity", 4.0, "Lacunarity:", "The gap between noise frequencies. This parameter is used in conjunction with fractal increment to compute the spectral weights that contribute to the noise in each octave."));
    par.addParam(new RichFloat("fractalIncrement", terrain_filter? 0.5 : 0.2, "Fractal increment:", "This parameter defines how rough the generated terrain will be. The range of reasonable values changes according to the used algorithm, however you can choose it in range [0.2, 1.5]."));
    par.addParam(new RichFloat("offset", 0.9, "Offset:", "This parameter controls the multifractality of the generated terrain. If offset is low, then the terrain will be smooth."));
    par.addParam(new RichFloat("gain", 2.5, "Gain:", "Ignored in all the algorithms except the ridged one. This parameter defines how hard the terrain will be."));
    par.addParam(new RichBool("saveAsQuality", false, "Save as vertex quality", "Saves the perturbation value as vertex quality."));
}
コード例 #11
0
ファイル: samplefilter.cpp プロジェクト: GuoXinxiao/meshlab
// The Real Core Function doing the actual mesh processing.
// Move Vertex of a random quantity
bool ExtraSamplePlugin::applyFilter(QAction */*filter*/, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos *cb)
{
	CMeshO &m = md.mm()->cm;
	srand(time(NULL)); 
	const float max_displacement =par.getAbsPerc("Displacement");

	for(unsigned int i = 0; i< m.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.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.vert[i].P() += vcg::Point3f(rndax,rnday,rndaz);
	}
	
	// Log function dump textual info in the lower part of the MeshLab screen. 
	Log("Successfully displaced %i vertices",m.vn);
	
	// to access to the parameters of the filter dialog simply use the getXXXX function of the FilterParameter Class
	if(par.getBool("UpdateNormals"))	
			vcg::tri::UpdateNormal<CMeshO>::PerVertexNormalizedPerFace(m);
	
	vcg::tri::UpdateBounding<CMeshO>::Box(m);
  
	return true;
}
コード例 #12
0
ファイル: RandomFillFilter.cpp プロジェクト: Booley/nbis
void RandomFillFilter::addRandomObject(MeshDocument& md, MeshModel* filler, const vcg::Point3<float>& origin, int meshID){
    ostringstream meshName;
    meshName << "randomFillMesh" << meshID;
    MeshModel* meshCopy = md.addNewMesh(meshName.str().c_str());
    vcg::tri::Append<CMeshO,CMeshO>::Mesh(meshCopy->cm, filler->cm, false, true);
    meshCopy->cm.Tr = filler->cm.Tr;
    meshCopy->cm.Tr.SetColumn(3, meshCopy->cm.Tr.GetColumn3(3) + origin);
}
コード例 #13
0
ファイル: filter_fractal.cpp プロジェクト: GuoXinxiao/meshlab
void FilterFractal::initParameterSetForCratersGeneration(MeshDocument &md, RichParameterSet &par)
{
    int meshCount = md.meshList.size();

    // tries to detect the target mesh
    MeshModel* target = md.mm();
    MeshModel* samples = md.mm();
    MeshModel* tmpMesh;
    if (samples->cm.fn != 0){ // this is probably not the samples layer
        for(int i=0; i<meshCount; i++)
        {
            tmpMesh = md.meshList.at(i);
            if (tmpMesh->cm.fn == 0)
            {
                samples = tmpMesh;
                break;
            }
        }
    }

    par.addParam(new RichMesh("target_mesh", target, &md, "Target mesh:", "The mesh on which craters will be generated."));
    par.addParam(new RichMesh("samples_mesh", samples, &md, "Samples layer:", "The samples that represent the central points of craters."));
    par.addParam(new RichInt("seed", 0, "Seed:", "The seed with which the random number generator is initialized. The random generator generates radius and depth for each crater into the given range."));
    par.addParam(new RichInt("smoothingSteps", 5, "Normals smoothing steps:", "Vertex normals are smoothed this number of times before generating craters."));

    QStringList algList;
    algList << "f1 (Gaussian)" << "f2 (Multiquadric)" << "f3";
    par.addParam(new RichEnum("rbf", 1, algList, "Radial function:", "The radial function used to generate craters."));

    par.addParam(new RichDynamicFloat("min_radius", 0.1, 0, 1, "Min crater radius:", "Defines the minimum radius of craters in range [0, 1]. Values near 0 mean very small craters."));
    par.addParam(new RichDynamicFloat("max_radius", 0.35, 0, 1, "Max crater radius:", "Defines the maximum radius of craters in range [0, 1]. Values near 1 mean very large craters."));
    par.addParam(new RichDynamicFloat("min_depth", 0.05, 0, 1, "Min crater depth:", "Defines the minimum depth of craters in range [0, 1]."));
    par.addParam(new RichDynamicFloat("max_depth", 0.15, 0, 1, "Max crater depth:", "Defines the maximum depth of craters in range [0, 1]. Values near 1 mean very deep craters."));
    par.addParam(new RichDynamicFloat("elevation", 0.4, 0, 1, "Elevation:", "Defines how much the crater rise itself from the mesh surface, giving an \"impact-effect\"."));

    QStringList blendList;
    blendList << "Exponential blending" << "Linear blending" << "Gaussian blending" << "f3 blending";
    par.addParam(new RichEnum("blend", 3, blendList, "Blending algorithm:", "The algorithm that is used to blend the perturbation towards the mesh surface."));
    par.addParam(new RichDynamicFloat("blendThreshold", 0.8, 0, 1, "Blending threshold:", "The fraction of craters radius beyond which the radial function is replaced with the blending function."));
    par.addParam(new RichBool("successiveImpacts", true, "Successive impacts", "If not checked, the impact-effects of generated craters will be superimposed with each other."));
    par.addParam(new RichBool("ppNoise", true, "Postprocessing noise", "Slightly perturbates the craters with a noise function."));
    par.addParam(new RichBool("invert", false, "Invert perturbation", "If checked, inverts the sign of radial perturbation to create bumps instead of craters."));
    par.addParam(new RichBool("save_as_quality", false, "Save as vertex quality", "Saves the perturbation as vertex quality."));
    return;
}
コード例 #14
0
bool MeshDocumentFromNvm(MeshDocument &md, QString filename_nvm, QString model_filename)
{
  md.addNewMesh(model_filename,QString("model"));
  std::vector<vcg::Shotf> shots;
  const QString path = QFileInfo(filename_nvm).absolutePath();
  //const QString path_im = QFileInfo(image_list_filename).absolutePath()+QString("/");

  std::vector<std::string>   image_filenames;
  vcg::tri::io::ImporterNVM<CMeshO>::Open(md.mm()->cm,shots,image_filenames,qPrintable(filename_nvm));
  md.mm()->updateDataMask(MeshModel::MM_VERTCOLOR);

  QString curr_path = QDir::currentPath();
  //QFileInfo imi(image_list_filename);

  //QDir::setCurrent(imi.absoluteDir().absolutePath());
  QStringList image_filenames_q;
  for(unsigned int i  = 0; i < image_filenames.size(); ++i)
    image_filenames_q.push_back(QString::fromStdString(image_filenames[i]));

	for(size_t i=0 ; i<shots.size() ; i++){
			md.addNewRaster();
                        const QString fullpath_image_filename = image_filenames_q[i];
			md.rm()->addPlane(new Plane(fullpath_image_filename,Plane::RGBA));
			md.rm()->setLabel(image_filenames_q[i].section('/',1,2));
			md.rm()->shot = shots[i];
			/*md.rm()->shot.Intrinsics.ViewportPx[0]=md.rm()->currentPlane->image.width();
			md.rm()->shot.Intrinsics.ViewportPx[1]=md.rm()->currentPlane->image.height();
			md.rm()->shot.Intrinsics.CenterPx[0]=(int)((double)md.rm()->shot.Intrinsics.ViewportPx[0]/2.0f);
			md.rm()->shot.Intrinsics.CenterPx[1]=(int)((double)md.rm()->shot.Intrinsics.ViewportPx[1]/2.0f);*/

	}
        QDir::setCurrent(curr_path);

  return true;
}
コード例 #15
0
// Core 
bool FilterWebExportVMustPlugin::applyFilter(QAction *filter, MeshDocument &md, RichParameterSet & /*parent*/, vcg::CallBackPos * cb)
{
	if (ID(filter) == FP_WEB_EXPORT)
	{
		CMeshO &m=md.mm()->cm;

		QNetworkAccessManager NAManager;

		// STEP 1: check if the server works (by requesting the list of application templates)
		// (note that this list is not used)
		QUrl urlTest ("http://pipeline.v-must.net/api/v1/bundles");

		QNetworkRequest request1(urlTest);

		QNetworkReply *reply1 = NAManager.get(request1);
		QTimer timer;
		timer.setSingleShot(true);
		timer.start(5000);

		QEventLoop eventLoop;
		connect(reply1, SIGNAL(finished()), &eventLoop, SLOT(quit()));
		connect(&timer, SIGNAL(timeout()), &eventLoop, SLOT(quit()));
		eventLoop.exec();   // block the http request for 5 seconds

		delete reply1;

		if (timer.isActive())
		{
			timer.stop();

			// STEP 2: preparing the bucket for the processing

			QUrl urlBucket("http://pipeline.v-must.net/api/v1/buckets");
			QNetworkRequest request2(urlBucket);
			request2.setRawHeader("Accept", "application/json");
			request2.setRawHeader("Accept-Encoding", "gzip, deflate, compress");
			request2.setRawHeader("Content-Type", "application/octet-stream");
			request2.setRawHeader("Host", "pipelineserver.ltd");
			request2.setRawHeader("X-Filename", "test.ply");

			QNetworkReply *reply2 = NAManager.get(request2);
			connect(reply2, SIGNAL(finished()), &eventLoop, SLOT(quit()));
			eventLoop.exec();   // block the http request

			// STEP 3: launch the processing according to the selected template
		}
		else
		{
			QMessageBox::warning(0, tr("V-Must CIF API"), tr("Server is time out. Please, re-try later."));
		}



	}

	return true;
}
コード例 #16
0
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;
}
コード例 #17
0
ファイル: filter_rangemap.cpp プロジェクト: CKehl/meshlab
// Core Function doing the actual mesh processing.
bool RangeMapPlugin::applyFilter(QAction *filter, MeshDocument &m, FilterParameterSet & par, vcg::CallBackPos *cb)
{
	CMeshO::FaceIterator   fi;

	switch(ID(filter))
  {
		case FP_SELECTBYANGLE : 
		{
			bool usecam = par.getBool("usecamera");
			Point3f viewpoint = par.getPoint3f("viewpoint");	

			// if usecamera but mesh does not have one
			if( usecam && !m.mm()->hasDataMask(MeshModel::MM_CAMERA) ) 
			{
				errorMessage = "Mesh has not a camera that can be used to compute view direction. Please set a view direction."; // text
				return false;
			}
			if(usecam)
			{
				viewpoint = m.mm()->cm.shot.GetViewPoint();
			}

			// angle threshold in radians
			float limit = cos( math::ToRad(par.getDynamicFloat("anglelimit")) );
			Point3f viewray;

			for(fi=m.mm()->cm.face.begin();fi!=m.mm()->cm.face.end();++fi)
				if(!(*fi).IsD())
				{
					viewray = viewpoint - Barycenter(*fi);
					viewray.Normalize();

					if((viewray.dot((*fi).N().Normalize())) < limit)
						fi->SetS();
				}

		}
		break;

	}

	return true;
}
コード例 #18
0
ファイル: cleanfilter.cpp プロジェクト: yuhan120483/dcba
void CleanFilter::initParameterSet(QAction *action,MeshDocument &md, RichParameterSet & parlst)
{ 
	pair<float,float> qualityRange;
  switch(ID(action))
  {
    case FP_BALL_PIVOTING :
		  parlst.addParam(new RichAbsPerc("BallRadius",(float)maxDiag1,0,md.mm()->cm.bbox.Diag(),"Pivoting Ball radius (0 autoguess)","The radius of the ball pivoting (rolling) over the set of points. Gaps that are larger than the ball radius will not be filled; similarly the small pits that are smaller than the ball radius will be filled."));
		  parlst.addParam(new RichFloat("Clustering",20.0f,"Clustering radius (% of ball radius)","To avoid the creation of too small triangles, if a vertex is found too close to a previous one, it is clustered/merged with it."));		  
		  parlst.addParam(new RichFloat("CreaseThr", 90.0f,"Angle Threshold (degrees)","If we encounter a crease angle that is too large we should stop the ball rolling"));
		  parlst.addParam(new RichBool("DeleteFaces",false,"Delete intial set of faces","if true all the initial faces of the mesh are deleted and the whole surface is rebuilt from scratch, other wise the current faces are used as a starting point. Useful if you run multiple times the algorithm with an incrasing ball radius."));
		  break;
    case FP_REMOVE_ISOLATED_DIAMETER:	 
		  parlst.addParam(new RichAbsPerc("MinComponentDiag",md.mm()->cm.bbox.Diag()/10.0,0,md.mm()->cm.bbox.Diag(),"Enter max diameter of isolated pieces","Delete all the connected components (floating pieces) with a diameter smaller than the specified one"));
		  break;
    case FP_REMOVE_ISOLATED_COMPLEXITY:	 
		  parlst.addParam(new RichInt("MinComponentSize",(int)minCC,"Enter minimum conn. comp size:","Delete all the connected components (floating pieces) composed by a number of triangles smaller than the specified one"));
		  break;
    case FP_REMOVE_WRT_Q:
          qualityRange=tri::Stat<CMeshO>::ComputePerVertexQualityMinMax(md.mm()->cm);
		  parlst.addParam(new RichAbsPerc("MaxQualityThr",(float)val1, qualityRange.first, qualityRange.second,"Delete all vertices with quality under:"));
		  break;
	case FP_MERGE_CLOSE_VERTEX :
		  parlst.addParam(new RichAbsPerc("Threshold",md.mm()->cm.bbox.Diag()/10000.0,0,md.mm()->cm.bbox.Diag()/100.0,"Merging distance","All the vertices that closer than this threshold are merged together. Use very small values, default values is 1/10000 of bounding box diagonal. "));
		  break;
    case FP_SNAP_MISMATCHED_BORDER:
    parlst.addParam(new RichFloat("EdgeDistRatio",1/100.0f,"Edge Distance Ratio", "Collapse edge when the edge / distance ratio is greater than this value. E.g. for default value 1000 two straight border edges are collapsed if the central vertex dist from the straight line composed by the two edges less than a 1/1000 of the sum of the edges lenght. Larger values enforce that only vertexes very close to the line are removed."));
    parlst.addParam(new RichBool("UnifyVertices",true,"UnifyVertices","if true the snap vertices are weld together."));
      break;
    case FP_REMOVE_TVERTEX_COLLAPSE :
    case FP_REMOVE_TVERTEX_FLIP :
       parlst.addParam(new RichFloat(
               "Threshold", 40, "Ratio", "Detects faces where the base/height ratio is lower than this value"));
       parlst.addParam(new RichBool(
               "Repeat", true, "Iterate until convergence", "Iterates the algorithm until it reaches convergence"));
       break;
    case FP_REMOVE_NON_MANIF_VERT :
       parlst.addParam(new RichFloat("VertDispRatio", 0, "Vertex Displacement Ratio", "When a vertex is split it is moved along the average vector going from its position to the baricyenter of the FF connected faces sharing it"));
       break;
  default: break; // do not add any parameter for the other filters
  }
}
コード例 #19
0
ファイル: filter_csg.cpp プロジェクト: yuhan120483/dcba
void FilterCSG::initParameterSet(QAction *action, MeshDocument & md, RichParameterSet & parlst)
{
    switch (ID(action)) {
    case FP_CSG:
        {
            MeshModel *target = md.mm();
            foreach (target, md.meshList)
                if (target != md.mm())
                    break;

            CMeshO::ScalarType mindim = min(md.mm()->cm.bbox.Dim().V(md.mm()->cm.bbox.MinDim()),
                                            target->cm.bbox.Dim().V(target->cm.bbox.MinDim()));

            parlst.addParam(new RichMesh("FirstMesh", md.mm(), &md, "First Mesh",
                                         "The first operand of the CSG operation"));
            parlst.addParam(new RichMesh("SecondMesh", target, &md, "Second Mesh",
                                         "The second operand of the CSG operation"));
            parlst.addParam(new RichAbsPerc("Delta", mindim / 100.0, 0, mindim,
                                            "Spacing between sampling lines",
                                            "This parameter controls the accuracy of the result and the speed of the computation."
                                            "The time and memory needed to perform the operation usually scale as the reciprocal square of this value."
                                            "For optimal results, this value should be at most half the the smallest feature (i.e. the highest frequency) you want to reproduce."));
            parlst.addParam(new RichInt("SubDelta", 32, "Discretization points per sample interval",
                                        "This is the number of points between the sampling lines to which the vertices can be rounded."
                                        "Increasing this can marginally increase the precision and decrease the speed of the operation."));
            parlst.addParam(new RichEnum("Operator", 0,
                                         QStringList() << "Intersection" << "Union" << "Difference", "Operator",
                                         "Intersection takes the volume shared between the two meshes; "
                                         "Union takes the volume included in at least one of the two meshes; "
                                         "Difference takes the volume included in the first mesh but not in the second one"));
            parlst.addParam(new RichBool("Extended", false, "Extended Marching Cubes",
                                         "Use extended marching cubes for surface reconstruction. "
                                         "It tries to improve the quality of the mesh by reconstructing the sharp features "
                                         "using the information in vertex normals"));
        }
        break;

    default:
        assert(0);
    }
}
コード例 #20
0
ファイル: filter_autoalign.cpp プロジェクト: Jerdak/meshlab
// This function define the needed parameters for each filter. Return true if the filter has some parameters
// it is called every time, so you can set the default value of parameters according to the mesh
// For each parmeter you need to define,
// - the name of the parameter,
// - the string shown in the dialog
// - the default value
// - a possibly long string describing the meaning of that parameter (shown as a popup help in the dialog)
void FilterAutoalign::initParameterSet(QAction *action,MeshDocument & md/*m*/, RichParameterSet & parlst)
{
   MeshModel *target;
   switch(ID(action))	 {
    case FP_AUTOALIGN :
        target= md.mm();
        foreach (target, md.meshList)
            if (target != md.mm())  break;

        parlst.addParam(new RichMesh ("FirstMesh", md.mm(),&md, "First Mesh",
                        "The mesh were the coplanar bases are sampled (it will contain the trasformation)"));
        parlst.addParam(new RichMesh ("SecondMesh", target,&md, "Second Mesh",
                        "The mesh were similar coplanar based are searched."));
        parlst.addParam(new RichFloat("overlapping",0.5f,"Estimated fraction of the\n first mesh overlapped by the second"));
        parlst.addParam(new RichFloat("tolerance [0.0,1.0]",0.3f,"Error tolerance"));
     break;
       case FP_BEST_ROTATION :
       target= md.mm();
       foreach (target, md.meshList)
       if (target != md.mm())  break;

       parlst.addParam(new RichMesh ("FirstMesh", md.mm(),&md, "First Mesh",
                       "The mesh that will be moved"));
       parlst.addParam(new RichMesh ("SecondMesh", target,&md, "Second Mesh",
                       "The mesh that will be kept fixed."));
       parlst.addParam(new RichInt("GridSize",10,"Grid Size", "The size of the uniform grid that is used for searching the best translation for a given rotation"));
       parlst.addParam(new RichInt("Rotation Num",64,"RotationNumber", "sss"));
       break;

   default: break; // do not add any parameter for the other filters
  }
}
コード例 #21
0
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;
}
コード例 #22
0
// This function define the needed parameters for each filter. Return true if the filter has some parameters
// it is called every time, so you can set the default value of parameters according to the mesh
// For each parameter you need to define, 
// - the name of the parameter, 
// - the string shown in the dialog 
// - the default value
// - a possibly long string describing the meaning of that parameter (shown as a popup help in the dialog)
void FilterPerceptualMetric::initParameterSet(QAction *action, MeshDocument & md, FilterParameterSet & parlst) 
{
	switch(ID(action))	 
	{
		case FP_ROUGHNESS_MULTISCALE :
		{
			MeshModel *refmesh = md.mm();
			foreach (refmesh, md.meshList) 
				if (refmesh != md.mm())  break;

			parlst.addMesh("ReferenceMesh", refmesh, "Reference Mesh",
				"The original mesh.");
			parlst.addMesh("InputMesh", md.mm(), "Mesh",
				"The mesh where the perceptual impairment of the processing is evaluated.");
		} break;
		
		case FP_ROUGHNESS_SMOOTHING :
		{
			MeshModel *refmesh = md.mm();
			foreach (refmesh, md.meshList) 
				if (refmesh != md.mm())  break;

			parlst.addMesh("ReferenceMesh", refmesh, "Reference Mesh",
				"The original mesh.");
			parlst.addMesh("InputMesh", md.mm(), "Mesh",
				"The mesh where the perceptual impairment of the processing is evaluated.");
		} break;

		case FP_STRAIN_ENERGY :  
		{
			MeshModel *refmesh = md.mm();
			foreach (refmesh, md.meshList) 
				if (refmesh != md.mm())  break;
		
			parlst.addMesh("ReferenceMesh", refmesh, "Reference Mesh",
				"The original mesh.");
			parlst.addMesh("InputMesh", md.mm(), "Mesh",
				"The mesh where the perceptual impairment of the processing is evaluated.");
		} break;

		default : assert(0); 
	}
}
コード例 #23
0
ファイル: filter_measure.cpp プロジェクト: Booley/nbis
// This function define the needed parameters for each filter. 
void FilterMeasurePlugin::initParameterSet(QAction *action, MeshDocument &m, RichParameterSet & par)
{
	 switch(ID(action))	 
	 {
   case FP_MEASURE_FACE_QUALITY_HISTOGRAM :
   case FP_MEASURE_VERTEX_QUALITY_HISTOGRAM:
         {
         pair<float,float> minmax = tri::Stat<CMeshO>::ComputePerVertexQualityMinMax(m.mm()->cm);
         par.addParam(new RichFloat("minVal",minmax.first,"Min","The value that is used as a lower bound for the set of bins (all the value smaller this one will be put in the first bin)"));
         par.addParam(new RichFloat("maxVal",minmax.second,"Max","The value that is used as a upper bound for the set of bins (all the value over this one will be put in the last bin)"));
         par.addParam(new RichInt("binNum",20,"Number of bins","Number of bins in which the range of values is subdivided"));
        } break;
	}
}
コード例 #24
0
bool MeshDocumentFromBundler(MeshDocument &md, QString filename_out,QString image_list_filename, QString model_filename)
{
    md.addNewMesh(model_filename,QString("model"));
    std::vector<Shotm> shots;
    const QString path = QFileInfo(filename_out).absolutePath();
    const QString path_im = QFileInfo(image_list_filename).absolutePath()+QString("/");

    std::vector<std::string>   image_filenames;
    vcg::tri::io::ImporterOUT<CMeshO>::Open(md.mm()->cm,shots,image_filenames, qUtf8Printable(filename_out), qUtf8Printable(image_list_filename));
    md.mm()->updateDataMask(MeshModel::MM_VERTCOLOR);

    QString curr_path = QDir::currentPath();
    QFileInfo imi(image_list_filename);

    //
    QStringList image_filenames_q;
    for(unsigned int i  = 0; i < image_filenames.size(); ++i)
    {
        QImageReader sizeImg(QString::fromStdString(image_filenames[i]));
        if(sizeImg.size()==QSize(-1,-1))
            image_filenames_q.push_back(path_im+QString::fromStdString(image_filenames[i]));
        else
            image_filenames_q.push_back(QString::fromStdString(image_filenames[i]));
    }
    QDir::setCurrent(imi.absoluteDir().absolutePath());

    for(size_t i=0 ; i<shots.size() ; i++)
    {
        md.addNewRaster();
        const QString fullpath_image_filename = image_filenames_q[int(i)];
        md.rm()->addPlane(new Plane(fullpath_image_filename,Plane::RGBA));
        int count=fullpath_image_filename.count('\\');
        if (count==0)
        {
            count=fullpath_image_filename.count('/');
            md.rm()->setLabel(fullpath_image_filename.section('/',count,1));
        }
        else
            md.rm()->setLabel(fullpath_image_filename.section('\\',count,1));
        md.rm()->shot = shots[i];
    }
    QDir::setCurrent(curr_path);

    return true;
}
コード例 #25
0
ファイル: filter_sdfgpu.cpp プロジェクト: laiyinping/meshlab
void SdfGpuPlugin::setupMesh(MeshDocument& md, ONPRIMITIVE onPrimitive )
{
    MeshModel* mm = md.mm();
    CMeshO& m     = mm->cm;


    //If on vertices, do some cleaning first
    if( onPrimitive == ON_VERTICES )
    {
      int dup = tri::Clean<CMeshO>::RemoveDuplicateVertex(m);
      int unref =  tri::Clean<CMeshO>::RemoveUnreferencedVertex(m);
      if (dup > 0 || unref > 0) Log("Removed %i duplicate and %i unreferenced vertices\n",dup,unref);
    }

    //Updating mesh metadata
    tri::UpdateBounding<CMeshO>::Box(m);
    vcg::tri::Allocator<CMeshO>::CompactVertexVector(m);
    vcg::tri::Allocator<CMeshO>::CompactFaceVector(m);
    vcg::tri::UpdateNormals<CMeshO>::PerVertexAngleWeighted(m);


    //Enable & Reset the necessary attributes
    switch(onPrimitive)
    {
      case ON_VERTICES:
        mm->updateDataMask(MeshModel::MM_VERTQUALITY);
        tri::UpdateQuality<CMeshO>::VertexConstant(m,0);
        break;
      case ON_FACES:
        mm->updateDataMask(MeshModel::MM_FACEQUALITY);
        mm->updateDataMask(MeshModel::MM_FACENORMAL);
        mm->updateDataMask(MeshModel::MM_FACECOLOR);
        tri::UpdateQuality<CMeshO>::FaceConstant(m,0);
        break;
    }

 if(!vcg::tri::HasPerVertexAttribute(m,"maxQualityDir") && onPrimitive == ON_VERTICES)
       mMaxQualityDirPerVertex = vcg::tri::Allocator<CMeshO>::AddPerVertexAttribute<Point3f>(m,std::string("maxQualityDir"));
  else if(!vcg::tri::HasPerFaceAttribute(m,"maxQualityDir") && onPrimitive == ON_FACES)
        mMaxQualityDirPerFace = vcg::tri::Allocator<CMeshO>::AddPerFaceAttribute<Point3f>(m,std::string("maxQualityDir"));


}
コード例 #26
0
ファイル: filter_create.cpp プロジェクト: Booley/nbis
// The Real Core Function doing the actual mesh processing.
bool FilterCreate::applyFilter(QAction *filter, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos * /*cb*/)
{
    MeshModel &m=(*md.mm());
  switch(ID(filter))	 {
    case CR_TETRAHEDRON :
      vcg::tri::Tetrahedron<CMeshO>(m.cm);
      break;
    case CR_ICOSAHEDRON:
      vcg::tri::Icosahedron<CMeshO>(m.cm);
      break;
    case CR_DODECAHEDRON:
      vcg::tri::Dodecahedron<CMeshO>(m.cm);
			m.updateDataMask(MeshModel::MM_POLYGONAL);
      break;
    case CR_OCTAHEDRON:
      vcg::tri::Octahedron<CMeshO>(m.cm);
      break;
    case CR_SPHERE:
      vcg::tri::Sphere<CMeshO>(m.cm);
      break;
    case CR_BOX:
    {
      float sz=par.getFloat("size");
      vcg::Box3f b(vcg::Point3f(1,1,1)*(sz/2),vcg::Point3f(1,1,1)*(-sz/2));
      vcg::tri::Box<CMeshO>(m.cm,b);
			m.updateDataMask(MeshModel::MM_POLYGONAL);

      break;
    }
    case CR_CONE:
      float r0=par.getFloat("r0");
      float r1=par.getFloat("r1");
      float h=par.getFloat("h");
      int subdiv=par.getInt("subdiv");
      vcg::tri::Cone<CMeshO>(m.cm,r0,r1,h,subdiv);
      break;
   }
 	 vcg::tri::UpdateBounding<CMeshO>::Box(m.cm);
   vcg::tri::UpdateNormals<CMeshO>::PerVertexNormalizedPerFaceNormalized(m.cm);
	return true;
}
コード例 #27
0
void ShadowMapping::renderingFromLightSetup(MeshDocument& md, GLArea* gla){
    Box3m bb = md.bbox();
    Point3m center = bb.Center();
    Scalarm diag = bb.Diag();

    GLfloat lP[4];
    glGetLightfv(GL_LIGHT0, GL_POSITION, lP);
    vcg::Point3f light = -vcg::Point3f(lP[0],lP[1],lP[2]);

    vcg::Matrix44f tm = gla->trackball.Matrix();

    glMatrixMode(GL_PROJECTION);

    glPushMatrix();

        glLoadIdentity();
        glOrtho(-(diag/2),
                 diag/2,
                 -(diag/2),
                 diag/2,
                 -(diag/2),
                 diag/2);

    glMatrixMode(GL_MODELVIEW);

    glPushMatrix();
        vcg::Point3f u, v;
        //mi seleziona automaticamente un upvector che mi eviti casi degeneri...nel caso vada bene 010 sceglie quello
        vcg::GetUV(light, u, v, vcg::Point3f(0,-1,0));
        glLoadIdentity();
        gluLookAt(0, 0, 0, light[0], light[1], light[2], v[0], v[1], v[2]);

        //get the rotation matrix from the trackball
        vcg::Matrix44f rotation;
        vcg::Similarityf track = gla->trackball.track;
        track.rot.ToMatrix(rotation);
        glMultMatrixf(rotation.transpose().V());

        //traslate the model in the center
        glTranslatef(-center[0],-center[1],-center[2]);
}
コード例 #28
0
// This function define the needed parameters for each filter. Return true if the filter has some parameters
// it is called every time, so you can set the default value of parameters according to the mesh
// For each parameter you need to define, 
// - the name of the parameter, 
// - the string shown in the dialog 
// - the default value
// - a possibly long string describing the meaning of that parameter (shown as a popup help in the dialog)
void FilterWebExportVMustPlugin::initParameterSet(QAction *action, MeshDocument &md, RichParameterSet & parlst) 
{
	int meshCount = md.meshList.size();

	// tries to detect the target mesh
	MeshModel* target = md.mm();
  
	parlst.addParam(new RichMesh("target_mesh", target, &md, "Target mesh:", "The mesh to export."));

	templateNamesHR << "Basic Viewer" << "Standard Viewer" << "Fullsize Viewer" << "Radiance Scaling" <<
		"Walk Through" << "POP Geometry" << "Nexus conversion";
	parlst.addParam(new RichEnum("template", 1, templateNamesHR, "Web Template:", "Web template to use."));
	parlst.addParam(new RichString("notification_email", "*****@*****.**", "Notification email:", 
		"A link to download the exported model will be send at this email address."));

	// names to be used with the CIF API
	templateNames << "basic" << "standard" << "fullsize" << "radianceScaling" << "walkthrough" 
		<< "pop" << "nexus";

	return;
}
コード例 #29
0
// This function define the needed parameters for each filter. Return true if the filter has some parameters
// it is called every time, so you can set the default value of parameters according to the mesh
// For each parmeter you need to define,
// - the name of the parameter,
// - the string shown in the dialog
// - the default value
// - a possibly long string describing the meaning of that parameter (shown as a popup help in the dialog)
void FilterAutoalign::initParameterSet(QAction *action,MeshDocument & md/*m*/, RichParameterSet & parlst)
{
   MeshModel *target;
   switch(ID(action))	 {
    case FP_ALIGN_4PCS :
        target= md.mm();
        foreach (target, md.meshList)
            if (target != md.mm())  break;

        parlst.addParam(new RichMesh ("fixMesh", md.mm(),&md, "Fixed Mesh",
                        "The mesh were the coplanar bases are sampled (it will contain the trasformation)"));
        parlst.addParam(new RichMesh ("movMesh", target,&md, "Moving Mesh",
                        "The mesh were similar coplanar based are searched."));
        parlst.addParam(new RichFloat("overlap",0.5f,"Overlap %","Estimated fraction of the\n first mesh overlapped by the second"));
        parlst.addParam(new RichInt("sampleNum",1000,"Sample Num"));
        parlst.addParam(new RichFloat("tolerance",0.3f,"Error tolerance",""));
        parlst.addParam(new RichBool("showSample",true,"show subsamples",""));
        parlst.addParam(new RichInt("randSeed",0,"Random Seed","0 means the random generator it is intializised with internal clock to guarantee different result every time"));
     break;

       case FP_BEST_ROTATION :
       target= md.mm();
       foreach (target, md.meshList)
       if (target != md.mm())  break;

       parlst.addParam(new RichMesh ("fixMesh", md.mm(),&md, "Fix Mesh",
                       "The mesh that will be moved"));
       parlst.addParam(new RichMesh ("movMesh", target,&md, "Mov Mesh",
                       "The mesh that will be kept fixed."));
       parlst.addParam(new RichInt("searchRange",6,"Search Range", "The size of the uniform grid that is used for searching the best translation for a given rotation"));
       parlst.addParam(new RichInt("sampleSize",5000,"Sample Size", "The size of the uniform grid that is used for searching the best translation for a given rotation"));
       parlst.addParam(new RichInt("gridSize",100000,"Grid Size", "The size of the uniform grid that is used for searching the best translation for a given rotation"));
       parlst.addParam(new RichInt("RotationNumber",64,"Rotation Number", "sss"));
       break;

   default: break; // do not add any parameter for the other filters
  }
}
コード例 #30
0
ファイル: filter_measure.cpp プロジェクト: mylxiaoyi/meshlab
// 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;
}