Esempio n. 1
0
int main( )
{
  MyMesh m;
  vcg::tri::Icosahedron(m);
  vcg::tri::UpdateNormal<MyMesh>::PerVertexNormalizedPerFaceNormalized(m);
  vcg::tri::UpdateBounding<MyMesh>::Box(m);

  // As a simple test we get a few random points on a mesh,
  // we rot and trans them
  // and we fit them

  std::vector<vcg::Point3f> ExactVec;
  std::vector<vcg::Point3f> PerturbVec;
  tri::MontecarloSampling(m,ExactVec,10);
  PerturbVec=ExactVec;

  Matrix44f RotM;
  Matrix44f TraM;
  Point3f dir;
  vcg::math::MarsenneTwisterRNG rnd;

  vcg::math::GeneratePointInUnitBallUniform<float>(rnd);
  RotM.SetRotateDeg(rand()%360,dir);
  TraM.SetTranslate(1,2,3);
  Matrix44f RigidM = RotM*TraM;

  for(size_t i=0;i<ExactVec.size();++i)
    PerturbVec[i]=RigidM*ExactVec[i];

  Quaternionf q;
  Point3f tr;
  Matrix44f res;
  ComputeRigidMatchMatrix(PerturbVec,ExactVec,res);

  res.print();
  RigidM.print();

  return 0;
}
Esempio n. 2
0
// The Real Core Function doing the actual mesh processing.
bool FilterFunctionPlugin::applyFilter(QAction *filter, MeshDocument &md, RichParameterSet & par, vcg::CallBackPos *cb)
{
  if(this->getClass(filter) == MeshFilterInterface::MeshCreation)
       md.addNewMesh("",this->filterName(ID(filter)));
  MeshModel &m=*(md.mm());
	Q_UNUSED(cb);
	switch(ID(filter)) {
		case FF_VERT_SELECTION :
			{
				std::string expr = par.getString("condSelect").toStdString();
			
				// muparser initialization and explicitely define parser variables
				Parser p;
        setPerVertexVariables(p,m.cm);

				// set expression inserted by user as string (required by muparser)
				p.SetExpr(expr);

				int numvert = 0;
				time_t start = clock();

				// every parser variables is related to vertex coord and attributes.
				CMeshO::VertexIterator vi;
				for(vi = m.cm.vert.begin(); vi != m.cm.vert.end(); ++vi)if(!(*vi).IsD())
				{
					setAttributes(vi,m.cm);

					bool selected = false;

					// use parser to evaluate boolean function specified above
					// in case of fail, error dialog contains details of parser's error
					try { 
						selected = p.Eval();
					} catch(Parser::exception_type &e) {
						errorMessage = e.GetMsg().c_str();
  						return false;
					}

					// set vertex as selected or clear selection
					if(selected) { 
						(*vi).SetS();
						numvert++;
					} else (*vi).ClearS();
				}

				// strict face selection
				if(par.getBool("strictSelect"))
						tri::UpdateSelection<CMeshO>::FaceFromVertexStrict(m.cm); 
				else  
						tri::UpdateSelection<CMeshO>::FaceFromVertexLoose(m.cm); 
		
				// if succeded log stream contains number of vertices and time elapsed
				Log( "selected %d vertices in %.2f sec.", numvert, (clock() - start) / (float) CLOCKS_PER_SEC);
					
				return true;
			}
		break;

		case FF_FACE_SELECTION :
			{
				QString select = par.getString("condSelect");
			
				// muparser initialization and explicitely define parser variables
				Parser p;
        setPerFaceVariables(p,m.cm);

				// set expression inserted by user as string (required by muparser)
				p.SetExpr(select.toStdString());

				int numface = 0;
				time_t start = clock();

				// every parser variables is related to face attributes.
				CMeshO::FaceIterator fi;
				for(fi = m.cm.face.begin(); fi != m.cm.face.end(); ++fi)if(!(*fi).IsD())
				{
					setAttributes(fi,m.cm);

					bool selected = false;

					// use parser to evaluate boolean function specified above
					// in case of fail, error dialog contains details of parser's error
					try { 
						selected = p.Eval();
					} catch(Parser::exception_type &e) {
						errorMessage = e.GetMsg().c_str();
  						return false;
					}

					// set face as selected or clear selection
					if(selected) { 
						(*fi).SetS();
						numface++;
					} else (*fi).ClearS();
				}

				// if succeded log stream contains number of vertices and time elapsed
				Log( "selected %d faces in %.2f sec.", numface, (clock() - start) / (float) CLOCKS_PER_SEC);
					
				return true;
			}
		break;

		case FF_GEOM_FUNC :
		case FF_VERT_COLOR:
    case FF_VERT_NORMAL:
			{
        std::string func_x,func_y,func_z,func_a;
				// FF_VERT_COLOR : x = r, y = g, z = b
        // FF_VERT_NORMAL : x = r, y = g, z = b
        func_x = par.getString("x").toStdString();
        func_y = par.getString("y").toStdString();
        func_z = par.getString("z").toStdString();
        if(ID(filter) == FF_VERT_COLOR) func_a = par.getString("a").toStdString();

				// muparser initialization and explicitely define parser variables
				// function for x,y and z must use different parser and variables
        Parser p1,p2,p3,p4;

        setPerVertexVariables(p1,m.cm);
        setPerVertexVariables(p2,m.cm);
        setPerVertexVariables(p3,m.cm);
        setPerVertexVariables(p4,m.cm);

				p1.SetExpr(func_x);
				p2.SetExpr(func_y);
				p3.SetExpr(func_z);
        p4.SetExpr(func_a);

        double newx=0,newy=0,newz=0,newa=255;
				errorMessage = "";

				time_t start = clock();

				// every parser variables is related to vertex coord and attributes.
				CMeshO::VertexIterator vi;
				for(vi = m.cm.vert.begin(); vi != m.cm.vert.end(); ++vi)if(!(*vi).IsD())
				{
					setAttributes(vi,m.cm);

					// every function is evaluated by different parser.
					// errorMessage dialog contains errors for func x, func y and func z
          try { newx = p1.Eval(); }  catch(Parser::exception_type &e) { showParserError("1st func : ",e); }
          try { newy = p2.Eval(); }  catch(Parser::exception_type &e) { showParserError("2nd func : ",e); }
          try { newz = p3.Eval(); }  catch(Parser::exception_type &e) { showParserError("3rd func : ",e); }
          if(ID(filter) == FF_VERT_COLOR)
          {
            try { newa = p4.Eval(); } catch(Parser::exception_type &e) { showParserError("4th func : ",e); }
          }
          if(errorMessage != "") return false;

          if(ID(filter) == FF_GEOM_FUNC)  // set new vertex coord for this iteration
						(*vi).P() = Point3f(newx,newy,newz); 
          if(ID(filter) == FF_VERT_COLOR) // set new color for this iteration
            (*vi).C() = Color4b(newx,newy,newz,newa);
          if(ID(filter) == FF_VERT_NORMAL) // set new color for this iteration
            (*vi).N() = Point3f(newx,newy,newz);
          }

				if(ID(filter) == FF_GEOM_FUNC) {
					// update bounding box, normalize normals
					tri::UpdateNormals<CMeshO>::PerVertexNormalizedPerFace(m.cm);
					tri::UpdateNormals<CMeshO>::NormalizeFace(m.cm);
					tri::UpdateBounding<CMeshO>::Box(m.cm);
				}

				// if succeded log stream contains number of vertices processed and time elapsed
				Log( "%d vertices processed in %.2f sec.", m.cm.vn, (clock() - start) / (float) CLOCKS_PER_SEC);

				return true;
			}
		break;
		
		case FF_VERT_QUALITY:
			{
				std::string func_q = par.getString("q").toStdString();
				m.updateDataMask(MeshModel::MM_VERTQUALITY);
				
				// muparser initialization and define custom variables
				Parser p;
        setPerVertexVariables(p,m.cm);

				// set expression to calc with parser
				p.SetExpr(func_q);

				// every parser variables is related to vertex coord and attributes.
				time_t start = clock();
				CMeshO::VertexIterator vi;
        for(vi = m.cm.vert.begin(); vi != m.cm.vert.end(); ++vi)
        if(!(*vi).IsD())
				{
					setAttributes(vi,m.cm);

					// use parser to evaluate function specified above
					// in case of fail, errorMessage dialog contains details of parser's error
					try { 
						(*vi).Q() = p.Eval();
					} catch(Parser::exception_type &e) {
						errorMessage = e.GetMsg().c_str();
  						return false;
					}
				}

				// normalize quality with values in [0..1] 
        if(par.getBool("normalize")) tri::UpdateQuality<CMeshO>::VertexNormalize(m.cm);
				
				// map quality into per-vertex color
        if(par.getBool("map")) tri::UpdateColor<CMeshO>::VertexQualityRamp(m.cm);

				// if succeded log stream contains number of vertices and time elapsed
				Log( "%d vertices processed in %.2f sec.", m.cm.vn, (clock() - start) / (float) CLOCKS_PER_SEC);

				return true;
			}
		break;

		case FF_FACE_COLOR:
			{
				std::string func_r = par.getString("r").toStdString();
				std::string func_g = par.getString("g").toStdString();
				std::string func_b = par.getString("b").toStdString();
        std::string func_a = par.getString("a").toStdString();

				// muparser initialization and explicitely define parser variables
				// every function must uses own parser and variables
        Parser p1,p2,p3,p4;

        setPerFaceVariables(p1,m.cm);
        setPerFaceVariables(p2,m.cm);
        setPerFaceVariables(p3,m.cm);
        setPerFaceVariables(p4,m.cm);

				p1.SetExpr(func_r);
				p2.SetExpr(func_g);
				p3.SetExpr(func_b);
        p4.SetExpr(func_a);

				// RGB is related to every face
				CMeshO::FaceIterator fi;
        double newr=0,newg=0,newb=0,newa=255;
				errorMessage = "";

				time_t start = clock();

				// every parser variables is related to face attributes.
				for(fi = m.cm.face.begin(); fi != m.cm.face.end(); ++fi)if(!(*fi).IsD())
				{
					setAttributes(fi,m.cm);

					// evaluate functions to generate new color
					// in case of fail, error dialog contains details of parser's error
          try { newr = p1.Eval(); } catch(Parser::exception_type &e) { showParserError("func r: ",e); }
          try { newg = p2.Eval(); } catch(Parser::exception_type &e) { showParserError("func g: ",e); }
          try { newb = p3.Eval(); } catch(Parser::exception_type &e) { showParserError("func b: ",e); 	}
          try { newa = p4.Eval(); } catch(Parser::exception_type &e) { showParserError("func a: ",e); 	}

					if(errorMessage != "") return false;

					// set new color for this iteration
          (*fi).C() = Color4b(newr,newg,newb,newa);
				}

				// if succeded log stream contains number of vertices processed and time elapsed
				Log( "%d faces processed in %.2f sec.", m.cm.fn, (clock() - start) / (float) CLOCKS_PER_SEC);

				return true;

			}
		break;

		case FF_FACE_QUALITY:
			{
				std::string func_q = par.getString("q").toStdString();
				m.updateDataMask(MeshModel::MM_FACEQUALITY);

				// muparser initialization and define custom variables
				Parser pf;
        setPerFaceVariables(pf,m.cm);
					
				// set expression to calc with parser
          pf.SetExpr(func_q);

				time_t start = clock();
				errorMessage = "";

				// every parser variables is related to face attributes.
				CMeshO::FaceIterator fi;
				for(fi = m.cm.face.begin(); fi != m.cm.face.end(); ++fi)if(!(*fi).IsD())
				{
					setAttributes(fi,m.cm);

					// evaluate functions to generate new quality
					// in case of fail, error dialog contains details of parser's error
					try { (*fi).Q() = pf.Eval(); }
					catch(Parser::exception_type &e) {
						showParserError("func q: ",e);
					}
					if(errorMessage != "") return false;
				}

				// normalize quality with values in [0..1]
        if(par.getBool("normalize")) tri::UpdateQuality<CMeshO>::FaceNormalize(m.cm);

				// map quality into per-vertex color
        if(par.getBool("map")) tri::UpdateColor<CMeshO>::FaceQualityRamp(m.cm);

				// if succeded log stream contains number of faces processed and time elapsed
				Log( "%d faces processed in %.2f sec.", m.cm.fn, (clock() - start) / (float) CLOCKS_PER_SEC);

				return true;
			}
		break;

		case FF_DEF_VERT_ATTRIB :
			{
				std::string name = par.getString("name").toStdString();
				std::string expr = par.getString("expr").toStdString();

				// add per-vertex attribute with type float and name specified by user
        CMeshO::PerVertexAttributeHandle<float> h;
        if(tri::HasPerVertexAttribute(m.cm,name))
				{
          h = tri::Allocator<CMeshO>::GetPerVertexAttribute<float>(m.cm, name);
              if(!tri::Allocator<CMeshO>::IsValidHandle<float>(m.cm,h))
          {
          errorMessage = "attribute already exists with a different type";
					return false;
          }
				}
        else
          h = tri::Allocator<CMeshO>::AddPerVertexAttribute<float> (m.cm,name);

        std::vector<std::string> AllVertexAttribName;
        tri::Allocator<CMeshO>::GetAllPerVertexAttribute< float >(m.cm,AllVertexAttribName);
        qDebug("Now mesh has %i vertex float attribute",AllVertexAttribName.size());
				Parser p;
        setPerVertexVariables(p,m.cm);
				p.SetExpr(expr);

				time_t start = clock();

				// perform calculation of attribute's value with function specified by user
				CMeshO::VertexIterator vi;
				for(vi = m.cm.vert.begin(); vi != m.cm.vert.end(); ++vi)if(!(*vi).IsD())
				{
					setAttributes(vi,m.cm);

					// add new user-defined attribute
					try {
						h[vi] = p.Eval();
					} catch(Parser::exception_type &e) {
						errorMessage = e.GetMsg().c_str();
  						return false;
					}
				}

				// add string, double and handler to vector.
				// vectors keep tracks of new attributes and let muparser use explicit variables
				// it's possibile to use custom attributes in other filters
				v_attrNames.push_back(name);
				v_attrValue.push_back(0);
        v_handlers.push_back(h);

				// if succeded log stream contains number of vertices processed and time elapsed
				Log( "%d vertices processed in %.2f sec.", m.cm.vn, (clock() - start) / (float) CLOCKS_PER_SEC);

				return true;
			}
		break;

		case FF_DEF_FACE_ATTRIB :
			{
				std::string name = par.getString("name").toStdString();
				std::string expr = par.getString("expr").toStdString();
				
				// add per-face attribute with type float and name specified by user
        // add per-vertex attribute with type float and name specified by user
        CMeshO::PerFaceAttributeHandle<float> h;
        if(tri::HasPerFaceAttribute(m.cm,name))
        {
          h = tri::Allocator<CMeshO>::GetPerFaceAttribute<float>(m.cm, name);
          if(!tri::Allocator<CMeshO>::IsValidHandle<float>(m.cm,h))
          {
          errorMessage = "attribute already exists with a different type";
          return false;
          }
        }
        else
          h = tri::Allocator<CMeshO>::AddPerFaceAttribute<float> (m.cm,name);
				Parser p;
        setPerFaceVariables(p,m.cm);
				p.SetExpr(expr);

				time_t start = clock();

				// every parser variables is related to face attributes.
				CMeshO::FaceIterator fi;
				for(fi = m.cm.face.begin(); fi != m.cm.face.end(); ++fi)if(!(*fi).IsD())
				{
					setAttributes(fi,m.cm);

					// add new user-defined attribute
					try {
						h[fi] = p.Eval();
					} catch(Parser::exception_type &e) {
						errorMessage = e.GetMsg().c_str();
  						return false;
					}
				}

//				// add string, double and handler to vector.
//				// vectors keep tracks of new attributes and let muparser use explicit variables
//				// it's possibile to use custom attributes in other filters
//				f_attrNames.push_back(name);
//				f_attrValue.push_back(0);
//				fhandlers.push_back(h);

				// if succeded log stream contains number of vertices processed and time elapsed
				Log( "%d faces processed in %.2f sec.", m.cm.fn, (clock() - start) / (float) CLOCKS_PER_SEC);

				return true;
			}
		break;

		case FF_GRID : 
			{
				// obtain parameters to generate 2D Grid
				int w = par.getInt("numVertX");		 
				int h = par.getInt("numVertY");		 
				float wl = par.getFloat("absScaleX");	 
				float hl = par.getFloat("absScaleY");

				if(w <= 0 || h <= 0) {
					errorMessage = "number of vertices must be positive";
					return false;
				}

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

				// if "centered on origin" is checked than move generated Grid in (0,0,0)
				if(par.getBool("center")) 
				{
					// 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)
					{
						(*vi).P()[0] = (*vi).P()[0] - (wld * halfw);
						(*vi).P()[1] = (*vi).P()[1] - (hld * halfh);
					}
				}
				// update bounding box, normals
        Matrix44f rot; rot.SetRotateDeg(180,Point3f(0,1,0));
        tri::UpdatePosition<CMeshO>::Matrix(m.cm,rot,false);
				tri::UpdateNormals<CMeshO>::PerVertexNormalizedPerFace(m.cm);	
				tri::UpdateNormals<CMeshO>::NormalizeFace(m.cm);
				tri::UpdateBounding<CMeshO>::Box(m.cm);
				
				return true;
			}
		break;
		case FF_ISOSURFACE :
			{
					SimpleVolume<SimpleVoxel> 	volume;
		
					typedef vcg::tri::TrivialWalker<CMeshO, SimpleVolume<SimpleVoxel> >	MyWalker;
					typedef vcg::tri::MarchingCubes<CMeshO, MyWalker>	MyMarchingCubes;
					MyWalker walker;
		
					Box3d rbb;
					rbb.min[0]=par.getFloat("minX");
					rbb.min[1]=par.getFloat("minY");
					rbb.min[2]=par.getFloat("minZ");
					rbb.max[0]=par.getFloat("maxX");
					rbb.max[1]=par.getFloat("maxY");
					rbb.max[2]=par.getFloat("maxZ");
					double step=par.getFloat("voxelSize");
					Point3i siz= Point3i::Construct((rbb.max-rbb.min)*(1.0/step));
					
					Parser p;
					double x,y,z;
					p.DefineVar("x", &x);
					p.DefineVar("y", &y);
					p.DefineVar("z", &z);
					std::string expr = par.getString("expr").toStdString();
					p.SetExpr(expr);
					Log("Filling a Volume of %i %i %i",siz[0],siz[1],siz[2]);
					volume.Init(siz);
					for(double i=0;i<siz[0];i++)
						for(double j=0;j<siz[1];j++)
							for(double k=0;k<siz[2];k++)
							{
							 x = rbb.min[0]+step*i;
							 y = rbb.min[1]+step*j;
							 z = rbb.min[2]+step*k;
							 	try {
										volume.Val(i,j,k)=p.Eval();
										} catch(Parser::exception_type &e) {
												errorMessage = e.GetMsg().c_str();
												return false;
											}
							}
		
		// MARCHING CUBES
		Log("[MARCHING CUBES] Building mesh...");
		MyMarchingCubes					mc(m.cm, walker);
		walker.BuildMesh<MyMarchingCubes>(m.cm, volume, mc, 0);
		Matrix44f tr; tr.SetIdentity(); tr.SetTranslate(rbb.min[0],rbb.min[1],rbb.min[2]);
		Matrix44f sc; sc.SetIdentity(); sc.SetScale(step,step,step);
		tr=tr*sc;
		
		tri::UpdatePosition<CMeshO>::Matrix(m.cm,tr);
		tri::UpdateNormals<CMeshO>::PerVertexNormalizedPerFace(m.cm);																																			 
		tri::UpdateBounding<CMeshO>::Box(m.cm);					// updates bounding box		
		return true;

			}
		break;

		case FF_REFINE :
			{
				std::string condSelect = par.getString("condSelect").toStdString();
				
				std::string expr1 = par.getString("x").toStdString();
				std::string expr2 = par.getString("y").toStdString();
				std::string expr3 = par.getString("z").toStdString();

				bool errorMidPoint = false;
				bool errorEdgePred = false;
				std::string msg = "";

				// check parsing errors while creating two func obj
				// display error message
				MidPointCustom<CMeshO> mid = MidPointCustom<CMeshO>(m.cm,expr1,expr2,expr3,errorMidPoint,msg);
				CustomEdge<CMeshO> edge = CustomEdge<CMeshO>(condSelect,errorEdgePred,msg);
				if(errorMidPoint || errorEdgePred) 
				{
					errorMessage = msg.c_str();
					return false;
				}

				// Refine current mesh.
				// Only edge specified with CustomEdge pred are selected
				//  and the new vertex is choosen with MidPointCustom created above
				RefineE<CMeshO, MidPointCustom<CMeshO>, CustomEdge<CMeshO> >
					(m.cm, mid, edge, false, cb);

				m.clearDataMask( MeshModel::MM_VERTMARK);
				vcg::tri::UpdateNormals<CMeshO>::PerVertexNormalizedPerFace(m.cm);

				return true;
			}
		break;

		default : assert (0);
	}
	return false;
}
Esempio n. 3
0
void EditArc3DPlugin::exportShotsToRasters()
{
	int subSampleVal = arc3DDialog->ui.subsampleSpinBox->value();
	float scalingFactor = arc3DDialog->ui.scaleLineEdit->text().toFloat();
	int minCountVal= arc3DDialog->ui.minCountSpinBox->value();
	MeshModel* m=md->mm();
	CMeshO mm;
	QTableWidget *qtw=arc3DDialog->ui.imageTableWidget;
	v3dImportDialog::ExportShots saveSelected=v3dImportDialog::ExportShots(arc3DDialog->ui.saveShotCombo->currentIndex());
	for(int i=0; i<er.modelList.size(); ++i)
	{
		if ((saveSelected==v3dImportDialog::EXPORT_ALL) || (qtw->isItemSelected(qtw->item(i,0))))
		{
			er.modelList[i].cam.Open(er.modelList[i].cameraName.toUtf8().data());
			mm.Clear();
			Point3f corr=er.modelList[i].TraCorrection(mm,subSampleVal*2,minCountVal,0);
			er.modelList[i].shot.Extrinsics.SetTra(er.modelList[i].shot.Extrinsics.Tra()-corr);
			md->setBusy(true);
			RasterModel* rm=md->addNewRaster();
			rm->addPlane(new Plane(er.modelList[i].textureName,Plane::RGBA));
			rm->setLabel(er.modelList[i].textureName);
			rm->shot=er.modelList[i].shot;
			rm->shot.RescalingWorld(scalingFactor, false);

			//// Undistort
			if (arc3DDialog->ui.shotDistortion->isChecked())
			{
				QImage originalImg=rm->currentPlane->image;
				//originalImg.load(imageName);
				QFileInfo qfInfo(rm->currentPlane->fullPathFileName);
				QString suffix = "." + qfInfo.completeSuffix();
				QString path = qfInfo.absoluteFilePath().remove(suffix);
				path.append("Undist" + suffix);
				qDebug(path.toLatin1());

				QImage undistImg(originalImg.width(),originalImg.height(),originalImg.format());
				undistImg.fill(qRgba(0,0,0,255));

				vcg::Camera<float> &cam = rm->shot.Intrinsics;


				QRgb value;
				for(int x=0; x<originalImg.width();x++)
					for(int y=0; y<originalImg.height();y++){
						value = originalImg.pixel(x,y);
						///////

						Point3d m_temp = er.modelList[i].cam.Kinv * Point3d(x,y,1);

						double oldx, oldy;
						er.modelList[i].cam.rd.ComputeOldXY(m_temp[0] / m_temp[2], m_temp[1] / m_temp[2], oldx, oldy);
						/////////////
						m_temp=er.modelList[i].cam.K * Point3d(oldx,oldy,1);
						vcg::Point2<float> newPoint(m_temp.X(),m_temp.Y());

						if((newPoint.X()- (int)newPoint.X())>0,5)
							newPoint.X()++;
						if((newPoint.Y()- (int)newPoint.Y())>0,5)
							newPoint.Y()++;
						if(newPoint.X()>=0 && newPoint.X()<undistImg.width() && newPoint.Y()>=0 && newPoint.Y()< undistImg.height())
							undistImg.setPixel((int)newPoint.X(),(int)newPoint.Y(),qRgba(qRed(value),qGreen(value),qBlue(value), qAlpha(value)));
					}



					PullPush(undistImg,qRgba(0,0,0,255));
					undistImg.save(path);
					rm->currentPlane->image= undistImg;
					rm->currentPlane->fullPathFileName=path;
					QString newLabel = rm->label();
					newLabel.remove(suffix);
					newLabel.append("Undist" + suffix);
					rm->setLabel(newLabel);
					md->setBusy(false);

			}
			Matrix44f transf;
			transf.SetRotateDeg(180,Point3f(1.0,0.0,0.0));
			rm->shot.ApplyRigidTransformation(transf);
			//// end undistort
		}
	}
}
Esempio n. 4
0
void EditArc3DPlugin::ExportPly()
{
	md->setBusy(true);
	md->addNewMesh("",er.name,true);
	MeshModel* m=md->mm();

	// Options collection

	int t0=clock();

	int subSampleVal = arc3DDialog->ui.subsampleSpinBox->value();
	int minCountVal= arc3DDialog->ui.minCountSpinBox->value();
	float maxCCDiagVal= arc3DDialog->ui.maxCCDiagSpinBox->value();
	int smoothSteps=arc3DDialog->ui.smoothSpinBox->value();
	bool closeHole = arc3DDialog->ui.holeCheckBox->isChecked();
	int maxHoleSize = arc3DDialog->ui.holeSpinBox->value();

	CMeshO mm;
	QTableWidget *qtw=arc3DDialog->ui.imageTableWidget;
	float MinAngleCos=cos(vcg::math::ToRad(arc3DDialog->ui.qualitySpinBox->value()));
	bool removeSmallCC=arc3DDialog->ui.removeSmallCCCheckBox->isChecked();
	//vcg::tri::Clustering<CMeshO, vcg::tri::AverageColorCell<CMeshO> > Grid;

	int selectedNum=0,selectedCount=0;
	int i;
	 for(i=0;i<qtw->rowCount();++i) if(qtw->isItemSelected(qtw->item(i,0))) ++selectedNum;

	bool dilationFlag = arc3DDialog->ui.dilationCheckBox->isChecked();
	int dilationN = arc3DDialog->ui.dilationNumPassSpinBox->value();
	int dilationSz = arc3DDialog->ui.dilationSizeSlider->value() * 2 + 1;
	bool erosionFlag = arc3DDialog->ui.erosionCheckBox->isChecked();
	int erosionN = arc3DDialog->ui.erosionNumPassSpinBox->value();
	int erosionSz = arc3DDialog->ui.erosionSizeSlider->value() * 2 + 1;
	float scalingFactor = arc3DDialog->ui.scaleLineEdit->text().toFloat();
	std::vector<string> savedMeshVector;

// Generating a mesh for each selected image

	bool firstTime=true;
	QList<Arc3DModel>::iterator li;
	for(li=er.modelList.begin(), i=0;li!=er.modelList.end();++li,++i)
	{
			if(qtw->isItemSelected(qtw->item(i,0)))
			{
				++selectedCount;
				mm.Clear();
				int tt0=clock();
				(*li).BuildMesh(mm,subSampleVal,minCountVal,MinAngleCos,smoothSteps,
					dilationFlag, dilationN, dilationSz, erosionFlag, erosionN, erosionSz,scalingFactor);
				int tt1=clock();
				this->Log(GLLogStream::SYSTEM,"** Mesh %i : Build in %i\n",selectedCount,tt1-tt0);
				m->cm.Clear();
				tri::Append<CMeshO,CMeshO>::Mesh(m->cm,mm); // append mesh mr to ml

				int tt2=clock();
				this->Log(GLLogStream::SYSTEM,"** Mesh %i : Append in %i\n",selectedCount,tt2-tt1);
			}
	}

	int t1=clock();
	this->Log(GLLogStream::SYSTEM,"Extracted %i meshes in %i\n",selectedCount,t1-t0);

///// Removing connected components

	if(removeSmallCC)
	{
		m->updateDataMask(MeshModel::MM_FACEFACETOPO | MeshModel::MM_FACEMARK);
		tri::Clean<CMeshO>::RemoveSmallConnectedComponentsDiameter(m->cm,m->cm.bbox.Diag()*maxCCDiagVal/100.0);
	}

	int t2=clock();
	this->Log(GLLogStream::SYSTEM,"Topology and removed CC in %i\n",t2-t1);

	vcg::tri::UpdateBounding<CMeshO>::Box(m->cm);					// updates bounding box

// Hole filling

	if(closeHole)
	{
		m->updateDataMask(MeshModel::MM_FACEFACETOPO | MeshModel::MM_FACEMARK);
		tri::UpdateNormal<CMeshO>::PerVertexNormalizedPerFace(m->cm);
		vcg::tri::Hole<CMeshO>::EarCuttingFill<vcg::tri::MinimumWeightEar< CMeshO> >(m->cm,maxHoleSize,false);
	}

	m->updateDataMask(MeshModel::MM_VERTCOLOR);

	Matrix44f transf;
	transf.SetRotateDeg(180,Point3f(1.0,0.0,0.0));

	m->cm.Tr=transf;
	tri::UpdatePosition<CMeshO>::Matrix(m->cm, m->cm.Tr);
	tri::UpdateNormal<CMeshO>::PerVertexMatrix(m->cm,m->cm.Tr);
	tri::UpdateNormal<CMeshO>::PerFaceMatrix(m->cm,m->cm.Tr);
	tri::UpdateBounding<CMeshO>::Box(m->cm);
	m->cm.Tr.SetIdentity();
	m->cm.shot.ApplyRigidTransformation(transf);

	int t3=clock();
	this->Log(GLLogStream::SYSTEM,"---------- Total Processing Time%i\n\n\n",t3-t0);

	vcg::tri::UpdateBounding<CMeshO>::Box(m->cm);					// updates bounding box
	tri::UpdateNormal<CMeshO>::PerVertexNormalizedPerFace(m->cm);

// Final operations

	md->mm()->visible=true;
	md->setBusy(false);
	gla->rm.colorMode=GLW::CMPerVert;
	emit this->resetTrackBall();
	gla->update();

}