当前位置: 首页>>代码示例>>C++>>正文


C++ MyMesh::VN方法代码示例

本文整理汇总了C++中MyMesh::VN方法的典型用法代码示例。如果您正苦于以下问题:C++ MyMesh::VN方法的具体用法?C++ MyMesh::VN怎么用?C++ MyMesh::VN使用的例子?那么, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在MyMesh的用法示例。


在下文中一共展示了MyMesh::VN方法的14个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的C++代码示例。

示例1: refine

  char* refine(int num)
  {
    MyMesh m;
    int t0=clock();
    int loadmask;

    printf("Buffer ptr is '%i'\n",buf);
    printf("Buffer[0] is '%c'\n",buf[0]);

    int ret = tri::io::ImporterOFF<MyMesh>::OpenMem(m,buf,strlen(buf),loadmask);
    int t1=clock();
    if(ret != 0)
    {
      printf("Error in opening file\n");
      exit(-1);
    }
    int t2=clock();
    printf("Read mesh %i %i\n",m.FN(),m.VN());
    tri::UpdateTopology<MyMesh>::FaceFace(m);
    tri::EdgeLen<MyMesh,float> edgePred(0);
    tri::MidPoint<MyMesh> midFun(&m);
    tri::RefineE(m,midFun,edgePred);
    int t3=clock();
    printf("Refined mesh %i %i\n",m.FN(),m.VN());
    printf("Opening time %5.2f \n Refinement time %5.2f",float(t1-t0)/CLOCKS_PER_SEC,float(t3-t2)/CLOCKS_PER_SEC);
    char *bufMeshOut = tri::io::ExporterOFF<MyMesh>::SaveStream(m);
    return bufMeshOut;
  }
开发者ID:MarcoLoddo,项目名称:meshlabjs,代码行数:28,代码来源:refine.cpp

示例2: getVertexVector

 inline uintptr_t getVertexVector() {
   float * v = new float[m.VN()*3];
   int k=0;
   for (int i = 0; i < m.VN(); i++){
     for (int j = 0; j < 3; j++){
       v[k] = m.vert[i].cP()[j];
       k++;
     }
   }
   return (uintptr_t)v;
 }
开发者ID:vvidal,项目名称:meshlabjs,代码行数:11,代码来源:CppMesh.cpp

示例3: main

int main( int /*argc*/, char **/*argv*/ )
{
  MyMesh m;
  vcg::tri::Torus(m,30,10);
  vcg::tri::io::ExporterOFF<MyMesh>::Save(m,"torus.off");

  vcg::tri::UpdateTopology<MyMesh>::FaceFace(m);
//  vcg::tri::UpdateCurvature<MyMesh>::VertexCurvature(m);
  vcg::tri::UpdateCurvature<MyMesh>::MeanAndGaussian(m);
  vcg::tri::UpdateCurvature<MyMesh>::PrincipalDirections(m);
  //vcg::tri::UpdateCurvature<MyMesh>::PrincipalDirectionsNormalCycles(m);
  vcg::tri::UpdateCurvature<MyMesh>::PrincipalDirectionsPCA(m,m.bbox.Diag()/100);

  vcg::tri::UpdateNormal<MyMesh>::PerVertexNormalized(m);
  printf("Input mesh  vn:%i fn:%i\n",m.VN(),m.FN());
  printf( "Mesh has %i vert and %i faces\n", m.VN(), m.FN() );

  return 0;
}
开发者ID:Quantza,项目名称:opengl-base,代码行数:19,代码来源:trimesh_curvature.cpp

示例4: SmoothPlugin

void SmoothPlugin(uintptr_t _m, int step)
{
    MyMesh *n = (MyMesh*) _m;
    int t2=clock();    
    tri::UpdateTopology<MyMesh>::VertexFace(*n);        
    tri::Smooth<MyMesh>::VertexCoordLaplacian(*n, step, false, true);
    tri::UpdateNormal<MyMesh>::PerVertexPerFace(*n);
    int t3=clock();
    printf("Smooth mesh %i vert - %i face \n",n->VN(),n->FN());
    printf("Smooth time %5.2f\n",float(t3-t2)/CLOCKS_PER_SEC);
}
开发者ID:MarcoLoddo,项目名称:meshlabjs,代码行数:11,代码来源:Smooth.cpp

示例5: openMesh

    int openMesh() {
        int loadmask;

        int ret = tri::io::ImporterOFF<MyMesh>::OpenMem(m,buf,strlen(buf),loadmask);
        if(ret != 0)
        {
            printf("Error in opening file\n");
            exit(-1);
        }
        printf("Read mesh %i %i\n",m.FN(),m.VN());
        return ret;
    }
开发者ID:vvidal,项目名称:meshlabjs,代码行数:12,代码来源:open.cpp

示例6: main

int main( int argc, char **argv )
{
  if(argc<2)
  {
    printf("Usage trimesh_base <meshfilename.obj>\n");
    return -1;
  }
  /*!
    */
  MyMesh m;

  if(vcg::tri::io::ImporterOFF<MyMesh>::Open(m,argv[1])!=vcg::tri::io::ImporterOFF<MyMesh>::NoError)
  {
    printf("Error reading file  %s\n",argv[1]);
    exit(0);
  }

  vcg::tri::RequirePerVertexNormal(m);
  vcg::tri::UpdateNormal<MyMesh>::PerVertexNormalized(m);
  printf("Input mesh  vn:%i fn:%i\n",m.VN(),m.FN());
  printf( "Mesh has %i vert and %i faces\n", m.VN(), m.FN() );

  return 0;
}
开发者ID:GuoXinxiao,项目名称:meshlab,代码行数:24,代码来源:trimesh_base.cpp

示例7: mySmooth

void mySmooth(int step)
{
    int t2=clock();
    
  tri::RequirePerVertexNormal(*n);
  tri::UpdateTopology<MyMesh>::VertexFace(*n);
    
    
  tri::Smooth<MyMesh>::VertexCoordLaplacian(*n, step, false, true);
  
  tri::UpdateNormal<MyMesh>::PerVertexPerFace(*n);
    int t3=clock();
    printf("Smooth mesh %i vert - %i face \n",n->VN(),n->FN());
    printf("Smooth time %5.2f\n",float(t3-t2)/CLOCKS_PER_SEC);

}
开发者ID:MarcoLoddo,项目名称:meshlabjs,代码行数:16,代码来源:Smooth.cpp

示例8: main

int main( int argc, char **argv )
{
  if(argc<3)
  {
    printf("Usage trimesh_base <meshfilename> radius (as perc) (\n");
    return -1;
  }

  MyMesh m;
  MyMesh subM;
  MyMesh cluM;
  MyMesh rndM;

  tri::MeshSampler<MyMesh> mps(subM);
  tri::MeshSampler<MyMesh> mrs(rndM);

  if(tri::io::Importer<MyMesh>::Open(m,argv[1])!=0)
  {
    printf("Error reading file  %s\n",argv[1]);
    exit(0);
  }
  tri::SurfaceSampling<MyMesh,tri::TrivialSampler<MyMesh> >::SamplingRandomGenerator().initialize(time(0));
  float perc = atof(argv[2]);

  float radius = m.bbox.Diag() * perc;
  printf("Subsampling a PointCloud of %i vert with %f radius\n",m.VN(),radius);
  tri::SurfaceSampling<MyMesh,tri::MeshSampler<MyMesh> >::PoissonDiskParam pp;
  tri::SurfaceSampling<MyMesh,tri::MeshSampler<MyMesh> >::PoissonDiskParam::Stat pds; pp.pds=&pds;
  pp.bestSampleChoiceFlag=false;
  tri::SurfaceSampling<MyMesh,tri::MeshSampler<MyMesh> >::PoissonDiskPruning(mps, m, radius, pp);
  tri::io::ExporterPLY<MyMesh>::Save(subM,"PoissonMesh.ply");
  printf("Sampled %i vertices in %5.2f\n",subM.VN(), float(pds.pruneTime+pds.gridTime)/float(CLOCKS_PER_SEC));

  int t0=clock();
  tri::Clustering<MyMesh, vcg::tri::AverageColorCell<MyMesh> > ClusteringGrid;
  ClusteringGrid.Init(m.bbox,100000,radius*sqrt(2.0f));
  ClusteringGrid.AddPointSet(m);
  ClusteringGrid.ExtractMesh(cluM);
  int t1=clock();
  tri::io::ExporterPLY<MyMesh>::Save(cluM,"ClusterMesh.ply");
  printf("Sampled %i vertices in %5.2f\n",cluM.VN(), float(t1-t0)/float(CLOCKS_PER_SEC));

  int t2=clock();
  int sampleNum = (cluM.VN()+subM.VN())/2;
  tri::SurfaceSampling<MyMesh,tri::MeshSampler<MyMesh> >::VertexUniform(m, mrs,sampleNum);
  int t3=clock();
  tri::io::ExporterPLY<MyMesh>::Save(rndM,"RandomMesh.ply");
  printf("Sampled %i vertices in %5.2f\n",rndM.VN(), float(t3-t2)/float(CLOCKS_PER_SEC));


  return 0;
}
开发者ID:Quantza,项目名称:opengl-base,代码行数:52,代码来源:trimesh_pointcloud_sampling.cpp

示例9: getVertexNumber

 int getVertexNumber() {
     return m.VN();
 }
开发者ID:vvidal,项目名称:meshlabjs,代码行数:3,代码来源:open.cpp

示例10: Sampling

void MasterPly::Sampling (char* input, char* output) {

	MyMesh m;
	MyMesh subM;
	float rad = 0.f;
	if(tri::io::ImporterPLY<MyMesh>::Open(m,input)!=0)
	{
		cout << "Error reading file  %s\n" << endl;
		return;
	}

	MyMesh vcgMesh;
    int verticeCount;
    int triangleCount;


    vcgMesh.Clear();
    verticeCount=m.VN();
    vcg::tri::Allocator<MyMesh>::AddVertices(vcgMesh,verticeCount);
    for(int i=0;i<verticeCount;i++){
        vcgMesh.vert[i].P()=vcg::Point3f(m.vert[i].P()[0],m.vert[i].P()[1],m.vert[i].P()[2]);

    }


    tri::UpdateBounding<MyMesh>::Box(vcgMesh);
	// calculate radius
	rad = tri::SurfaceSampling<MyMesh,tri::TrivialSampler<MyMesh> >::ComputePoissonDiskRadius(vcgMesh, 100000);
	tri::SurfaceSampling<MyMesh,tri::TrivialSampler<MyMesh> >::SamplingRandomGenerator().initialize((unsigned int)time(0));

	//sample point cloud
	std::vector<Point3f> sampleVec;
	tri::TrivialSampler<MyMesh> mps(sampleVec);

	// sampling
	tri::SurfaceSampling<MyMesh,tri::TrivialSampler<MyMesh> >::PoissonDiskParam pp;
	tri::SurfaceSampling<MyMesh,tri::TrivialSampler<MyMesh> >::PoissonDiskParam::Stat pds;
	pp.preGenMesh = &subM;
	//pp.pds=&pds;
	pp.bestSampleChoiceFlag=false;

	// start poisson disk prunning
	sampleVec.clear();
	tri::SurfaceSampling<MyMesh,tri::TrivialSampler<MyMesh> >::PoissonDiskPruning(mps, vcgMesh, rad, pp);
	tri::Build(subM,sampleVec);

	// sample
	std::stringstream sample;
	sample << "sampled_" << output;

	//Build surface
	vcg::tri::UpdateBounding<MyMesh>::Box(subM);
	vcg::tri::UpdateNormal<MyMesh>::PerVertex(subM);

	//Initialization
	tri::BallPivoting<MyMesh> pivot(subM);

	//the main processing
	pivot.BuildMesh();

	tri::io::ExporterPLY<MyMesh>::Save(subM,output,true);

}
开发者ID:rodrigoalvarez,项目名称:camarasheterogeneas,代码行数:63,代码来源:masterPly.cpp

示例11: VN

 int VN() { return m.VN();}
开发者ID:vvidal,项目名称:meshlabjs,代码行数:1,代码来源:CppMesh.cpp

示例12: Sampling

MyMesh* MasterPly::Sampling (string input) {

	MyMesh m;
	float rad = 0.f;
	tri::io::ImporterPLY<MyMesh>::Open(m,input.c_str());

	MyMesh vcgMesh;
    int verticeCount;
    int triangleCount;
    /*MyMesh::VertexIterator vi = vcg::tri::Allocator<MyMesh>::AddVertices(vcgMesh,3);
    MyMesh::FaceIterator fi = vcg::tri::Allocator<MyMesh>::AddFaces(vcgMesh,1);
    MyMesh::VertexPointer ivp[4];
    ivp[0]=&*vi; vi->P()=MyMesh::CoordType ( 0.0, 0.0, 0.0); ++vi;
    ivp[1]=&*vi; vi->P()=MyMesh::CoordType ( 1.0, 0.0, 0.0); ++vi;
    ivp[2]=&*vi; vi->P()=MyMesh::CoordType ( 0.0, 1.0, 0.0); ++vi;
    fi->V(0)=ivp[0];
    fi->V(1)=ivp[1];
    fi->V(2)=ivp[2];*/


    vcgMesh.Clear();
    verticeCount=m.VN();
    vcg::tri::Allocator<MyMesh>::AddVertices(vcgMesh,verticeCount);
    for(int i=0;i<verticeCount;i++){
        vcgMesh.vert[i].P()=vcg::Point3f(m.vert[i].P()[0],m.vert[i].P()[1],m.vert[i].P()[2]);

    }
/*
    triangleCount=m.FN();
    vcg::tri::Allocator<MyMesh>::AddFaces(vcgMesh, triangleCount);
    for(int i=0;i<triangleCount;i++){
        vcgMesh.face[i].V(0)=m.face[i].V(0);
        vcgMesh.face[i].V(1)=m.face[i].V(0);
        vcgMesh.face[i].V(2)=m.face[i].V(0);
    }*/


    tri::UpdateBounding<MyMesh>::Box(vcgMesh);
	// calculate radius
	rad = tri::SurfaceSampling<MyMesh,tri::TrivialSampler<MyMesh> >::ComputePoissonDiskRadius(vcgMesh, 100000);
	tri::SurfaceSampling<MyMesh,tri::TrivialSampler<MyMesh> >::SamplingRandomGenerator().initialize((unsigned int)time(0));

	//sample point cloud
	std::vector<Point3f> sampleVec;
	tri::TrivialSampler<MyMesh> mps(sampleVec);

	// sampling
	cout << "Subsampling a PointCloud" << endl;
	tri::SurfaceSampling<MyMesh,tri::TrivialSampler<MyMesh> >::PoissonDiskParam pp;
	tri::SurfaceSampling<MyMesh,tri::TrivialSampler<MyMesh> >::PoissonDiskParam::Stat pds;
	pp.preGenMesh = &subM;
	//pp.pds=&pds;
	pp.bestSampleChoiceFlag=false;

	// start poisson disk prunning
	sampleVec.clear();
	tri::SurfaceSampling<MyMesh,tri::TrivialSampler<MyMesh> >::PoissonDiskPruning(mps, vcgMesh, rad, pp);
	tri::Build(subM,sampleVec);

	// sample
	std::stringstream sample;

	//Build surface
	vcg::tri::UpdateBounding<MyMesh>::Box(subM);
	vcg::tri::UpdateNormal<MyMesh>::PerVertex(subM);

	//Initialization
	tri::BallPivoting<MyMesh> pivot(subM);


	cout << "Antes " << (unsigned int)time(0) <<endl;

	//the main processing
	pivot.BuildMesh();

	//output the result
	//tri::io::ExporterSTL<MyMesh>::Save(subM,output);

	cout << "Despues " << subM.VN() <<endl;

	tri::io::ExporterPLY<MyMesh>::Save(subM,"pruebaaaaaaa.ply",true);

	cout << "Fin!!!!" << endl;
	return &subM;
}
开发者ID:rodrigoalvarez,项目名称:camarasheterogeneas,代码行数:85,代码来源:masterPly.cpp

示例13: main

int main( int argc, char **argv )
{
  if(argc<2)
  {
    printf("Usage trimesh_base <meshfilename.obj> radius\n");
    return -1;
  }

  MyMesh m;

  if(tri::io::ImporterOFF<MyMesh>::Open(m,argv[1])!=0)
  {
    printf("Error reading file  %s\n",argv[1]);
    exit(0);
  }
  tri::SurfaceSampling<MyMesh,tri::TrivialSampler<MyMesh> >::SamplingRandomGenerator().initialize(time(0));

  //----------------------------------------------------------------------
  // Basic Sample,
  // Build a point cloud with points with a plain poisson disk distribution
  int t0=clock();
  vector<Point3f> pointVec;
  float rad;
  if(argc>2) rad=atof(argv[2]);
  int sampleNum=rad?0:1000;
  tri::PoissonSampling<MyMesh>(m,pointVec,sampleNum,rad);
  int t1=clock();
  MyMesh BasicPoissonMesh;
  tri::Build(BasicPoissonMesh,pointVec);

  tri::io::ExporterOFF<MyMesh>::Save(BasicPoissonMesh,"BasicPoissonMesh.off");
  printf("Computed a basic poisson disk distribution of %i vertices radius is %6.3f in %5.2f sec\n",BasicPoissonMesh.VN(),rad,float(t1-t0)/CLOCKS_PER_SEC);

  //----------------------------------------------------------------------
  // Advanced Sample
  // Make a feature dependent Poisson Disk sampling
  MyMesh MontecarloSurfaceMesh;
  MyMesh MontecarloEdgeMesh;
  MyMesh PoissonEdgeMesh;
  MyMesh PoissonMesh;

  std::vector<Point3f> sampleVec;
  tri::TrivialSampler<MyMesh> mps(sampleVec);
  tri::UpdateTopology<MyMesh>::FaceFace(m);
  tri::UpdateNormal<MyMesh>::PerFace(m);
  tri::UpdateFlags<MyMesh>::FaceFauxCrease(m,math::ToRad(40.0f));
  tri::SurfaceSampling<MyMesh,tri::TrivialSampler<MyMesh> >::EdgeMontecarlo(m,mps,10000,false);
  tri::Build(MontecarloEdgeMesh,sampleVec);
  tri::io::ExporterOFF<MyMesh>::Save(MontecarloEdgeMesh,"MontecarloEdgeMesh.off");

  sampleVec.clear();
  tri::SurfaceSampling<MyMesh,tri::TrivialSampler<MyMesh> >::VertexCrease(m, mps);
  tri::Build(PoissonEdgeMesh,sampleVec);
  tri::io::ExporterOFF<MyMesh>::Save(PoissonEdgeMesh,"CreaseMesh.off");

  tri::SurfaceSampling<MyMesh,tri::TrivialSampler<MyMesh> >::PoissonDiskParam pp;
  pp.preGenMesh = &PoissonEdgeMesh;
  pp.preGenFlag=true;
  sampleVec.clear();
  tri::SurfaceSampling<MyMesh,tri::TrivialSampler<MyMesh> >::PoissonDiskPruning(mps, MontecarloEdgeMesh, rad, pp);
  tri::Build(PoissonEdgeMesh,sampleVec);
  tri::io::ExporterOFF<MyMesh>::Save(PoissonEdgeMesh,"PoissonEdgeMesh.off");

  sampleVec.clear();
  tri::SurfaceSampling<MyMesh,tri::TrivialSampler<MyMesh> >::Montecarlo(m,mps,50000);
  tri::Build(MontecarloSurfaceMesh,sampleVec);
  tri::io::ExporterOFF<MyMesh>::Save(MontecarloSurfaceMesh,"MontecarloSurfaceMesh.off");

  pp.preGenMesh = &PoissonEdgeMesh;
  pp.preGenFlag=true;
  sampleVec.clear();
  tri::SurfaceSampling<MyMesh,tri::TrivialSampler<MyMesh> >::PoissonDiskPruning(mps, MontecarloSurfaceMesh, rad, pp);
  tri::Build(PoissonMesh,sampleVec);
  tri::io::ExporterOFF<MyMesh>::Save(PoissonMesh,"PoissonMesh.off");
  printf("Computed a feature aware poisson disk distribution of %i vertices radius is %6.3f\n",PoissonMesh.VN(),rad);

  return 0;
}
开发者ID:GuoXinxiao,项目名称:meshlab,代码行数:78,代码来源:trimesh_sampling.cpp

示例14: main


//.........这里部分代码省略.........
    printf("       <filename>        Mesh model for which to compute the sdf (PLY format).\n");
    printf("       angle             the wideness (degree) of the cone of ray that must be shot from each vertex (default 45)\n");
    printf("       samplenum         the oversampling factor (0 -> one ray, 1, 9 ray, 2-> 25 rays (default 2)\n");

		return 0;
	}

	MyMesh m;
 int t0=clock();
	// open a mesh
	int err = tri::io::Importer<MyMesh>::Open(m,argv[1]);
  if(err) {
		printf("Error in reading %s: '%s'\n",argv[1],tri::io::Importer<MyMesh>::ErrorMsg(err));
		exit(-1);  
	}
 // the other parameters
  float widenessRad = math::ToRad(20.0);

  if(argc>2) {
    widenessRad = math::ToRad(atof(argv[2]));
    printf("Setting wideness to %f degree\n",atof(argv[2]));
  }
  int n_samples=2;
  if(argc>3) n_samples = atoi(argv[3]);
  int samplePerVert = (n_samples*2+ 1)*(n_samples*2+ 1);
  printf("Using oversampling to %i  (%i sample per vertex)\n",n_samples,samplePerVert);


  // some cleaning to get rid of bad stuff
	int dup = tri::Clean<MyMesh>::RemoveDuplicateVertex(m);
	int unref =  tri::Clean<MyMesh>::RemoveUnreferencedVertex(m);

	if (dup > 0 || unref > 0)
		printf("Removed %i duplicate and %i unreferenced vertices from mesh %s\n",dup,unref,argv[1]);

  // updating
  tri::UpdateBounding<MyMesh>::Box(m);
  tri::UpdateNormal<MyMesh>::PerFaceNormalized(m);
  tri::UpdateNormal<MyMesh>::PerVertexAngleWeighted(m);
  tri::UpdateNormal<MyMesh>::NormalizePerVertex(m);
	// Create a static grid (for fast indexing) and fill it
	TriMeshGrid static_grid;
	static_grid.Set(m.face.begin(), m.face.end());

  typedef MyMesh::ScalarType ScalarType;
  int t1=clock();
  float t;
  MyMesh::FaceType *rf;
  MyMesh::VertexIterator vi;
  float maxDist=m.bbox.Diag();
  float offset= maxDist / 10000.0;
  int totRay=0;

  ScalarType deltaRad=widenessRad/(ScalarType)(n_samples*2);
  if(n_samples==0) deltaRad=0;

  tri::UpdateQuality<MyMesh>::VertexConstant(m,0);
  for(vi=m.vert.begin();vi!=m.vert.end();++vi)
  {
    vcg::Ray3f ray;
    ray.SetOrigin((*vi).cP()-((*vi).cN()*offset));
    Point3f dir0 = -(*vi).cN();
    int cnt=0;
    ScalarType theta_init,phi_init,ro;
    dir0.ToPolarRad(ro,theta_init,phi_init);
    for (int x=-n_samples;x<=n_samples;x++)
      for (int y=-n_samples;y<=n_samples;y++)
      {
        ScalarType theta=theta_init+x*deltaRad;
        ScalarType phi=phi_init+y*deltaRad;

        if (theta<0) theta=2.0*M_PI+theta;

        Point3f dir;
        dir.FromPolarRad(ro,theta,phi);
        dir.Normalize();
        ray.SetDirection(dir);

        rf = tri::DoRay<MyMesh,TriMeshGrid>(m,static_grid,ray,maxDist,t);
        if(rf)
        {
          (*vi).Q()+=t;
          cnt++;
        }
      }
    if(cnt>0){
      (*vi).Q()/=cnt;
      totRay+=cnt;
    }
  }
  int t2 = clock();
  tri::UpdateColor<MyMesh>::PerVertexQualityRamp(m);
  tri::io::ExporterPLY<MyMesh>::Save(m,"SDF.ply",tri::io::Mask::IOM_VERTCOLOR+tri::io::Mask::IOM_VERTQUALITY);

  printf("Initializated in %i msec\n",t1-t0);
  printf("Completed in %i msec\n",t2-t1);
  printf("Shoot %i rays and found %i intersections\n",m.VN()*samplePerVert,totRay);

return 0;
}
开发者ID:Quantza,项目名称:opengl-base,代码行数:101,代码来源:trimesh_ray.cpp


注:本文中的MyMesh::VN方法示例由纯净天空整理自Github/MSDocs等开源代码及文档管理平台,相关代码片段筛选自各路编程大神贡献的开源项目,源码版权归原作者所有,传播和使用请参考对应项目的License;未经允许,请勿转载。