void Various_Processing_Component::LaplacianSmoothing (PolyhedronPtr pMesh, double deformFactor, int iteraNum, bool preserveBoundaries) { Vertex_iterator pVertex; int numVertex = pMesh->size_of_vertices(); Vector * newPositions = new Vector[numVertex]; for (int i=0; i<iteraNum; i++) { int n = 0; for (pVertex = pMesh->vertices_begin(); pVertex != pMesh->vertices_end(); pVertex++) { Vector currentVector = pVertex->point() - CGAL::ORIGIN; // do not smooth the boundary vertices if demanded by user bool is_border_vertex = false; bool stopFlag = false; Halfedge_around_vertex_circulator hav = (*pVertex).vertex_begin(); do { if (hav->is_border()==true) { is_border_vertex = true; stopFlag = true; } hav++; } while ((hav!=(*pVertex).vertex_begin())&&(stopFlag==false)); if ((preserveBoundaries==true)&&(is_border_vertex==true)) { newPositions[n] = currentVector; n++; continue; } std::size_t degree = (*pVertex).vertex_degree(); double alpha = 1.0/degree; Vector vectemp = Point3d(0,0,0) - CGAL::ORIGIN; Halfedge_around_vertex_circulator h = (*pVertex).vertex_begin(); do { vectemp = vectemp+(h->opposite()->vertex()->point()-CGAL::ORIGIN-currentVector)*alpha; ++h; } while (h != (*pVertex).vertex_begin()); newPositions[n] = currentVector + deformFactor*vectemp; n++; } n = 0; for (pVertex = pMesh->vertices_begin(); pVertex != pMesh->vertices_end(); pVertex++) { pVertex->point() = Point3d(0,0,0) + newPositions[n]; n++; } } delete [] newPositions; newPositions = 0; pMesh->compute_normals(); }
void MSDM2_Component::ConstructColorMap(PolyhedronPtr P, int MetricOrHausdorff) { if(MetricOrHausdorff==1) { if(P->IsDistanceComputed==true) { double R; int indiceLut; Vertex_iterator pVertex = NULL; if(MaxMSDM2>MinMSDM2) { for (pVertex = P->vertices_begin(); pVertex != P->vertices_end(); pVertex++) { R=(pVertex->MSDM2_Local-MinMSDM2)/(MaxMSDM2-MinMSDM2)*255; indiceLut=floor(R); pVertex->color(LUT_CourbureClust[3*indiceLut],LUT_CourbureClust[3*indiceLut+1],LUT_CourbureClust[3*indiceLut+2]); } } } } else { if(P->IsDistanceComputed==true) { double R; int indiceLut; Vertex_iterator pVertex = NULL; if(MaxMSDM2>MinMSDM2) { for (pVertex = P->vertices_begin(); pVertex != P->vertices_end(); pVertex++) { float d=sqrt((pVertex->point()-pVertex->match)*(pVertex->point()-pVertex->match)); R=(d-MinMSDM2)/(MaxMSDM2-MinMSDM2)*255; indiceLut=floor(R); pVertex->color(LUT_CourbureClust[3*indiceLut],LUT_CourbureClust[3*indiceLut+1],LUT_CourbureClust[3*indiceLut+2]); } } } } }
void Various_Processing_Component::NoiseAdditionUniform (PolyhedronPtr pMesh, double noiseIntensity, bool preserveBoundaries) { // mesh centre calculation based on discrete "moment". //TODO: maybe in the future it will be based on volume moment. int numVertex = pMesh->size_of_vertices();; Vector centroid = Point3d(0,0,0) - CGAL::ORIGIN; double distancetoCentroid = 0.0; Vertex_iterator pVertex; for (pVertex = pMesh->vertices_begin(); pVertex != pMesh->vertices_end(); pVertex++) { Vector vectemp = pVertex->point() - CGAL::ORIGIN; centroid = centroid + vectemp; } centroid = centroid/numVertex; // calculate the average distance from vertices to mesh centre for (pVertex = pMesh->vertices_begin(); pVertex!= pMesh->vertices_end(); pVertex++) { Vector vectemp = pVertex->point() - CGAL::ORIGIN; distancetoCentroid = distancetoCentroid + (double)std::sqrt((vectemp - centroid) * (vectemp - centroid)); } distancetoCentroid = distancetoCentroid/numVertex; // add random uniform-distributed (between [-noiseLevel, +noiseLevel]) srand((unsigned)time(NULL)); double noisex, noisey, noisez; double noiseLevel = distancetoCentroid * noiseIntensity; for (pVertex = pMesh->vertices_begin(); pVertex!= pMesh->vertices_end(); pVertex++) { // keep boundaries untouched if demanded by user bool is_border_vertex = false; bool stopFlag = false; Halfedge_around_vertex_circulator hav = (*pVertex).vertex_begin(); do { if (hav->is_border()==true) { is_border_vertex = true; stopFlag = true; } hav++; } while ((hav!=(*pVertex).vertex_begin())&&(stopFlag==false)); if ((preserveBoundaries==true)&&(is_border_vertex==true)) continue; noisex = noiseLevel * (1.0*rand()/RAND_MAX-0.5)*2; noisey = noiseLevel * (1.0*rand()/RAND_MAX-0.5)*2; noisez = noiseLevel * (1.0*rand()/RAND_MAX-0.5)*2; Vector temp = Point3d(noisex, noisey, noisez) - CGAL::ORIGIN; pVertex->point() = pVertex->point() + temp; } // for correct rendering, we need to update the mesh normals pMesh->compute_normals(); }
void MSDM2_Component::Matching_Multires_Init(PolyhedronPtr m_PolyDegrad, PolyhedronPtr m_PolyOriginal , Facet * _TabMatchedFacet) { // constructs AABB tree AABB_Tree tree(m_PolyOriginal->facets_begin(),m_PolyOriginal->facets_end()); tree.accelerate_distance_queries(); //Searching for the closest point and facet for each vertex int ind=0; for(Vertex_iterator pVertex = m_PolyDegrad->vertices_begin(); pVertex != m_PolyDegrad->vertices_end(); pVertex++) { pVertex->MSDM2_Local=0; // computes closest point and primitive id Point_and_primitive_id pp = tree.closest_point_and_primitive(pVertex->point()); Point3d Nearest=pp.first; Facet_iterator f_Nearest = pp.second; // closest primitive id pVertex->match=Nearest; _TabMatchedFacet[ind]=*f_Nearest; ind++; } }
void MSDM2_Component::ComputeMaxMin(PolyhedronPtr P, int MetricOrHausdorff) { if(MetricOrHausdorff==1) { if(P->IsDistanceComputed==true) { MinMSDM2=1000; MaxMSDM2=0; for(Vertex_iterator pVertex = P->vertices_begin();pVertex!= P->vertices_end();pVertex++) { if(pVertex->MSDM2_Local>MaxMSDM2) MaxMSDM2=pVertex->MSDM2_Local; if(pVertex->MSDM2_Local<MinMSDM2) MinMSDM2=pVertex->MSDM2_Local; } } } else { if(P->IsDistanceComputed==true) { MinMSDM2=1000; MaxMSDM2=0; for(Vertex_iterator pVertex = P->vertices_begin();pVertex!= P->vertices_end();pVertex++) { float d=sqrt((pVertex->point()-pVertex->match)*(pVertex->point()-pVertex->match)); if(d>MaxMSDM2) MaxMSDM2=d; if(d<MinMSDM2) MinMSDM2=d; } } } }
void MSDM2_Component::KmaxKmean(PolyhedronPtr polyhedron_ptr,double coef) { for(Vertex_iterator pVertex = polyhedron_ptr->vertices_begin();pVertex!= polyhedron_ptr->vertices_end();pVertex++) { double kmax=pVertex->KmaxCurv*coef; double kmin=fabs(pVertex->KminCurv*coef); pVertex->KmaxCurv=(kmax+kmin)/2.; } }
string Various_Tools_Component::printClickedVertices(PolyhedronPtr pMesh,double x,double y,int tolerance) { GLdouble *model;GLdouble *proj;GLint *view; view = new GLint[4]; proj = new GLdouble[16]; model = new GLdouble[16]; glGetIntegerv(GL_VIEWPORT,view); glGetDoublev(GL_MODELVIEW_MATRIX,model); glGetDoublev(GL_PROJECTION_MATRIX,proj); y = view[3] - y; GLdouble wx,wy,wz; char szInfoVertex[256]; string sInfoVertex = ""; int vertexID = 0; //VertexID + 4就是该顶点在.obj文件中的行数 for(Vertex_iterator pVertex = pMesh->vertices_begin();pVertex != pMesh->vertices_end();pVertex++) { gluProject(pVertex->point().x(),pVertex->point().y (),pVertex->point().z(),model,proj,view,&wx,&wy,&wz); if (wz > 0.0 && wz < 1.0) { if (x > floor(wx)-tolerance && x < floor(wx)+tolerance) { if (y > floor(wy) - tolerance && y < floor(wy)+tolerance) { sprintf(szInfoVertex, "Vertex: %u - (%lf, %lf, %lf)", vertexID, pVertex->point().x(), pVertex->point().y(), pVertex->point().z()); sInfoVertex.assign(szInfoVertex); } } } vertexID++; } delete [] view; delete [] model; delete [] proj; return sInfoVertex; }
// Description : Initialize all flags -verticeces and facets- to FREE and give order to vertices // This function is called within every conquest. void Init(PolyhedronPtr pMesh) { int i = 0; // vertices flags initialization Vertex_iterator pVertex = NULL; for(pVertex = pMesh->vertices_begin(); pVertex != pMesh->vertices_end(); i++,pVertex++) { pVertex->Vertex_Flag_S = FREE; pVertex->Vertex_Number_S = i; pVertex->Vertex_Sign_S = NOSIGN; } // facets flag initialization. Facet_iterator pFace = NULL; for(pFace = pMesh->facets_begin(); pFace != pMesh->facets_end(); pFace++) { pFace->Facet_Flag_S = FREE; } }
void mepp_component_Boolean_Operations_plugin::New_Position() { QApplication::setOverrideCursor(Qt::WaitCursor); // active viewer if (mw->activeMdiChild() != 0) { float x, y, z; double a, b, c, w; Viewer* viewer = (Viewer *)mw->activeMdiChild(); ScenePtr S = viewer->getScenePtr(); for(int i = 0; i<viewer->getScenePtr()->get_nb_polyhedrons(); i++) { Vertex_iterator pVertex = NULL; PolyhedronPtr P = S->get_polyhedron(i); viewer->frame(i)->getPosition(x,y,z); viewer->frame(i)->getOrientation(a,b,c,w); Vec T(x, y, z); Quaternion Q(a, b, c, w); for (pVertex = P->vertices_begin(); pVertex != P->vertices_end(); pVertex++) { Vec V = Q * Vec(pVertex->point().x(), pVertex->point().y(), pVertex->point().z()) + T; pVertex->point() = CGAL::ORIGIN + Vector(V[0], V[1], V[2]); } viewer->frame(i)->setPosition(0,0,0); viewer->frame(i)->setOrientation(0,0,0,1); } viewer->show(); viewer->recreateListsAndUpdateGL(); } QApplication::restoreOverrideCursor(); }
void MSDM2_Component::Matching_Multires_Update(PolyhedronPtr m_PolyDegrad, Facet * _TabMatchedFacet) { int ind=0; for(Vertex_iterator pVertex = m_PolyDegrad->vertices_begin(); pVertex != m_PolyDegrad->vertices_end(); pVertex++) { //Point3d Nearest=pVertex->match; // MT Facet* f_Nearest=&_TabMatchedFacet[ind]; pVertex->tag(ind); ind++; //for debug //pVertex->point()=Nearest; ///calculation of the nearest point curvature value using vertices of the Nearest triangle //we use linear interpolation using barycentric coordinates Point3d x1=f_Nearest->halfedge()->vertex()->point(); Point3d x2=f_Nearest->halfedge()->next()->vertex()->point(); Point3d x3=f_Nearest->halfedge()->next()->next()->vertex()->point(); double l1=sqrt((x3-x2)*(x3-x2)); double l2=sqrt((x1-x3)*(x1-x3)); double l3=sqrt((x1-x2)*(x1-x2)); Vector v1=f_Nearest->halfedge()->vertex()->point()-pVertex->point(); Vector v2=f_Nearest->halfedge()->next()->vertex()->point()-pVertex->point(); Vector v3=f_Nearest->halfedge()->next()->next()->vertex()->point()-pVertex->point(); double t1=sqrt(v1*v1); double t2=sqrt(v2*v2); double t3=sqrt(v3*v3); double p1=(l1+t2+t3)/2; double p2=(t1+l2+t3)/2; double p3=(t1+t2+l3)/2; double A1=(p1*(p1-l1)*(p1-t3)*(p1-t2)); double A2=(p2*(p2-l2)*(p2-t3)*(p2-t1)); double A3=(p3*(p3-l3)*(p3-t1)*(p3-t2)); if(A1>0) A1=sqrt(A1); else A1=0; if(A2>0) A2=sqrt(A2); else A2=0; if(A3>0) A3=sqrt(A3); else A3=0; double c1=f_Nearest->halfedge()->vertex()->KmaxCurv; double c2=f_Nearest->halfedge()->next()->vertex()->KmaxCurv; double c3=f_Nearest->halfedge()->next()->next()->vertex()->KmaxCurv; if((A1+A2+A3)>0) pVertex->curvmatch=(A1*c1+A2*c2+A3*c3)/(A1+A2+A3); else pVertex->curvmatch=(c1+c2+c3)/3; } }
double MSDM2_Component::ProcessMSDM2_Multires(PolyhedronPtr m_PolyOriginal, PolyhedronPtr m_PolyDegrad,int NbLevel, double maxdim,double & FastMSDM, Curvature_ComponentPtr component_ptr_curvature) { double somme_MSDM2=0; int NbVertex=0; Facet * TabMatchedFacet=new Facet[m_PolyDegrad->size_of_vertices()]; Matching_Multires_Init(m_PolyDegrad, m_PolyOriginal,TabMatchedFacet); double RadiusCurvature=0.002; for (int i=0;i<NbLevel;i++) { m_PolyDegrad->set_index_vertices(); component_ptr_curvature->principal_curvature(m_PolyOriginal,true,RadiusCurvature*maxdim); component_ptr_curvature->principal_curvature(m_PolyDegrad,true,RadiusCurvature*maxdim); KmaxKmean(m_PolyOriginal,maxdim); KmaxKmean(m_PolyDegrad,maxdim); Matching_Multires_Update(m_PolyDegrad,TabMatchedFacet); for(Vertex_iterator pVertex = m_PolyDegrad->vertices_begin(); pVertex != m_PolyDegrad->vertices_end(); pVertex++) { std::vector<double> TabDistance1;std::vector<double> TabDistance2; TabPoint1.clear(); TabPoint2.clear(); ProcessMSDM2_per_vertex(pVertex,RadiusCurvature*5*maxdim,TabDistance1,TabDistance2,TabPoint1,TabPoint2); ComputeStatistics((&(*pVertex)), 0.5,TabDistance1,TabDistance2,TabPoint1,TabPoint2,RadiusCurvature*5*maxdim,maxdim); } RadiusCurvature+=0.001; } for(Vertex_iterator pVertex = m_PolyDegrad->vertices_begin(); pVertex != m_PolyDegrad->vertices_end(); pVertex++) { somme_MSDM2+=pow(pVertex->MSDM2_Local/NbLevel,3); NbVertex++; } FastMSDM=pow(somme_MSDM2/(double)NbVertex,0.33333); delete [] TabMatchedFacet; m_PolyDegrad->IsDistanceComputed=true; return 0; }
// TODO: fixing after quantization the potentially introduced degeneracies, such as removing the null surface facet void Various_Processing_Component::CoordinateQuantization (PolyhedronPtr pMesh, int bitDepth) { Vertex_iterator pVertex; double quantizationLevel = std::pow(2.0,bitDepth); pVertex = pMesh->vertices_begin(); Point3d point = pVertex->point(); double xmax = double(point.x()); double xmin = xmax; double ymax = double(point.y()); double ymin = ymax; double zmax = double(point.z()); double zmin = zmax; pVertex++; for (; pVertex != pMesh->vertices_end(); pVertex++) { point = pVertex->point(); double x = double(point.x()); double y = double(point.y()); double z = double(point.z()); if (x>xmax) xmax = x; if (x<xmin) xmin = x; if (y>ymax) ymax = y; if (y<ymin) ymin = y; if (z>zmax) zmax = z; if (z<zmin) zmin = z; } double xstep = (xmax-xmin)/quantizationLevel; double ystep = (ymax-ymin)/quantizationLevel; double zstep = (zmax-zmin)/quantizationLevel; for (pVertex = pMesh->vertices_begin(); pVertex != pMesh->vertices_end();pVertex++) { point = pVertex->point(); double x = double(point.x()); double y = double(point.y()); double z = double(point.z()); double xquantified, yquantified, zquantified; double xint = 1.0*std::floor((x-xmin)/xstep)*xstep + xmin; double xfrac = x - xint; if (xfrac<=(0.5*xstep)) xquantified = xint; else xquantified = xint + xstep; double yint = 1.0*std::floor((y-ymin)/ystep)*ystep + ymin; double yfrac = y - yint; if (yfrac<=(0.5*ystep)) yquantified = yint; else yquantified = yint +ystep; double zint = 1.0*std::floor((z-zmin)/zstep)*zstep + zmin; double zfrac = z - zint; if (zfrac<=(0.5*zstep)) zquantified = zint; else zquantified = zint + zstep; pVertex->point() = Point3d(xquantified,yquantified,zquantified); } pMesh->compute_normals(); }
// this time, we add Gaussian-distributed additive noise to the mesh vertex coordinates // the standard deviation of the Gaussian distribution is "noiseLevel = distancetoCentroid * noiseIntensity" void Various_Processing_Component::NoiseAdditionGaussian (PolyhedronPtr pMesh, double noiseIntensity, bool preserveBoundaries) { int numVertex = pMesh->size_of_vertices();; Vector centroid = Point3d(0,0,0) - CGAL::ORIGIN; double distancetoCentroid = 0.0; Vertex_iterator pVertex; for (pVertex = pMesh->vertices_begin(); pVertex != pMesh->vertices_end(); pVertex++) { Vector vectemp = pVertex->point() - CGAL::ORIGIN; centroid = centroid + vectemp; } centroid = centroid/numVertex; for (pVertex = pMesh->vertices_begin(); pVertex!= pMesh->vertices_end(); pVertex++) { Vector vectemp = pVertex->point() - CGAL::ORIGIN; distancetoCentroid = distancetoCentroid + (double)std::sqrt((vectemp - centroid) * (vectemp - centroid)); } distancetoCentroid = distancetoCentroid/numVertex; srand((unsigned)time(NULL)); double noisex, noisey, noisez; double * gaussNumbers = new double[3]; double noiseLevel = distancetoCentroid * noiseIntensity; for (pVertex = pMesh->vertices_begin(); pVertex!= pMesh->vertices_end(); pVertex++) { bool is_border_vertex = false; bool stopFlag = false; Halfedge_around_vertex_circulator hav = (*pVertex).vertex_begin(); do { if (hav->is_border()==true) { is_border_vertex = true; stopFlag = true; } hav++; } while ((hav!=(*pVertex).vertex_begin())&&(stopFlag==false)); if ((preserveBoundaries==true)&&(is_border_vertex==true)) continue; // pseudo-random Gaussian-distributed numbers generation from uniformly-distributed pseudo-random numbers double x, y, r2; for (int i=0; i<3; i++) { do { x = -1.0 + 2.0 * 1.0*rand()/RAND_MAX; y = -1.0 + 2.0 * 1.0*rand()/RAND_MAX; r2 = x * x + y * y; } while ((r2>1.0)||(r2==0.0)); gaussNumbers[i] = y * sqrt(-2.0 * log(r2) / r2); } noisex = noiseLevel * gaussNumbers[0]; noisey = noiseLevel * gaussNumbers[1]; noisez = noiseLevel * gaussNumbers[2]; Vector temp = Point3d(noisex, noisey, noisez) - CGAL::ORIGIN; pVertex->point() = pVertex->point() + temp; } pMesh->compute_normals(); delete [] gaussNumbers; gaussNumbers = 0; }