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 Remesh::selectClosest_tmp() { int i=0; FILE *select = fopen("select.dat", "w"); Vertex_handle vdst; for (Vertex_iterator vi = dst_mesh.p.vertices_begin(); vi != dst_mesh.p.vertices_end(); vi++) { vi->id = -1; } for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { Kernel::Point_3 closest_point = dst_mesh.closestPoint(vi->point()); cerr << i << ": " << vi->point() << " closest to " << closest_point << endl; if(v_norm(closest_point - vi->point()) < dst_mesh.edge_avg*alg_smoothing) { vdst = dst_mesh.vertex_mapping[closest_point]; cerr << "whose id is " << vdst->id; vdst->weight = 2; vdst->id = i; cerr << " changed to " << vdst->id << endl; } i++; } i=0; for (Vertex_iterator vi = dst_mesh.p.vertices_begin(); vi != dst_mesh.p.vertices_end(); vi++) { if(vi->weight == 2) { fprintf(select, "%d\t%d\n", i,vi->id); } i++; } fclose(select); cerr << "Done with printing out stuff ! Exiting " << endl; exit(0); }
void CGALPolyhedronToVTKPolydata_converter(Polyhedron *polyhedron, vtkSmartPointer<vtkPolyData> polydata) { //convert from cgal polyhedron to vtk poly data //first the points vtkSmartPointer<vtkPoints> points = vtkSmartPointer<vtkPoints>::New(); vtkSmartPointer<vtkCellArray> faces = vtkSmartPointer<vtkCellArray>::New(); //iterator over all vertices in polyhedron, add them as points std::map<Vertex_handle, vtkIdType> V; vtkIdType inum = 0; for ( Vertex_iterator v = polyhedron->vertices_begin(); v != polyhedron->vertices_end(); ++v) { points->InsertNextPoint(v->point()[0],v->point()[1],v->point()[2]); V[v] = inum++; } //now iterate over all faces in polyhedron for ( Facet_iterator i = polyhedron->facets_begin(); i != polyhedron->facets_end(); ++i) { Halfedge_around_facet_circulator j = i->facet_begin(); faces->InsertNextCell(CGAL::circulator_size(j)); do { //get indice of vertex, insert new cell point into faces faces->InsertCellPoint(V[j->vertex()]); } while(++j != i->facet_begin()); } // Set the points and faces of the polydata polydata->SetPoints(points); polydata->SetPolys(faces); }
void transformMesh( Polyhedron & poly, Transformation3 & map ) { for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) { Point3 store = vi->point().transform( map ); vi->point() = store; } }
void Mesh::compute_bounding_box() { if (size_of_vertices() == 0) return; float xmin, xmax, ymin, ymax, zmin, zmax; Vertex_iterator pVertex = vertices_begin(); xmin = xmax = pVertex->point().x; ymin = ymax = pVertex->point().y; zmin = zmax = pVertex->point().z; for(;pVertex != vertices_end();pVertex++) { const Vec3& p = pVertex->point(); xmin = qMin(xmin,p.x); ymin = qMin(ymin,p.y); zmin = qMin(zmin,p.z); xmax = qMax(xmax,p.x); ymax = qMax(ymax,p.y); zmax = qMax(zmax,p.z); } m_min = Vec3(xmin, ymin, zmin); m_max = Vec3(xmax, ymax, zmax); m_diagLength = Vec3::distance(m_min, m_max); m_axisLength = Vec3(m_min, m_max); m_minMaxCenter = (m_min + m_max) / 2.0f; }
void smoothMesh( Polyhedron & poly, unsigned int nTimes ) { int nV = poly.size_of_vertices(); const double lambda = SMOOTHING_LAMBDA; const double mu = SMOOTHING_MU; vector< Point3 > shrink ( nV ); vector< Point3 > expand ( nV ); for ( unsigned int k = 0; k < nTimes; ++k ) { // copy the vertex coordinates for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) { shrink [ vi->id() ] = vi->point(); } // shrinking stage for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) { moveVertex( vi, shrink[ vi->id() ], lambda ); } // copy back the vertex coordinates for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) { vi->point() = shrink[ vi->id() ]; expand[ vi->id() ] = shrink[ vi->id() ]; } // expanding stage for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) { moveVertex( vi, expand[ vi->id() ], mu ); } // copy back the vertex coordinates for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) { vi->point() = expand[ vi->id() ]; } } }
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::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 DegradeAnObject::changeAllPoints() { for(std::vector<Polyhedron>::iterator P = polys.begin() ; P != polys.end() ; ++P) { for ( Vertex_iterator v = P->vertices_begin(); v != P->vertices_end(); ++v) { Point_3 p(v->point().x()+((double) rand() / (RAND_MAX)),v->point().y()+((double) rand() / (RAND_MAX)),v->point().z()+((double) rand() / (RAND_MAX))); v->point() = p; std::cout << v->point() << std::endl; } std::cout << "--" << std::endl; } }
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++; } }
/** * Gets the list of points from the mesh * @param points Stores the list of points */ void StoneWeatherer::getPoints( vector<Point> & points ) const { for ( Vertex_iterator it = newDT->finite_vertices_begin(); it != newDT->finite_vertices_end(); ++it ) { points.push_back( it->point() ); } }
void modify_vertex_position() { Polyhedron P; Halfedge_handle h = P.make_tetrahedron(); if ( P.is_tetrahedron(h)) { int i(0); for(Vertex_iterator vi = P.vertices_begin(); vi != P.vertices_end(); ++vi,++i) { std::cout << "before changing vertex " << i << ": " << vi->point().x() << vi->point().y() << vi->point().z() << endl; Point_3 pt(1, 0, 0); vi->point() = pt; std::cout << "after changing vertex " << i << ": " << vi->point().x() << vi->point().y() << vi->point().z() << endl; } } }
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; }
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::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; } } } }
//------------------------------------------------------------------------------ // Normalize the 3D triangulated mesh with the display window //------------------------------------------------------------------------------ void normalizeMesh( Polyhedron & poly, vector< Segment3 > & bone ) { Vector3 sum, ave; for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) { sum = sum + ( vi->point() - CGAL::ORIGIN ); } ave = sum / ( double )poly.size_of_vertices(); for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) { vi->point() = vi->point() - ave; } cerr << " ave = " << ave << endl; Transformation3 translate( CGAL::TRANSLATION, -ave ); // fabs:absolute values-no negative values double sideMax = 0.0; for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) { if ( fabs( vi->point().x() ) > sideMax ) sideMax = fabs( vi->point().x() ); if ( fabs( vi->point().y() ) > sideMax ) sideMax = fabs( vi->point().y() ); if ( fabs( vi->point().z() ) > sideMax ) sideMax = fabs( vi->point().z() ); } // sideMax: the largest number for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) { vi->point() = CGAL::ORIGIN + ( vi->point() - CGAL::ORIGIN ) / sideMax; } Transformation3 scale( CGAL::SCALING, 1.0/sideMax ); Transformation3 composite = scale * translate; for ( unsigned int k = 0; k < bone.size(); ++k ) { bone[ k ] = bone[ k ].transform( composite ); } }
void vertex_node(Vertex_iterator vitr, Point& pt) { double R[] = {0.0, 0.0, 0.0}; Point& S = vitr->point(); Halfedge_around_vertex_circulator vcir = vitr->vertex_begin(); std::size_t n = circulator_size(vcir); for (std::size_t i = 0; i < n; i++, ++vcir) { Point& p = vcir->opposite()->vertex()->point(); R[0] += p[0]; R[1] += p[1]; R[2] += p[2]; } if (n == 6) { pt = Point((10*S[0]+R[0])/16, (10*S[1]+R[1])/16, (10*S[2]+R[2])/16); } else if (n == 3) { double B = (5.0/8.0 - std::sqrt(3+2*std::cos(6.283/n))/64.0)/n; double A = 1-n*B; pt = Point((A*S[0]+B*R[0]), (A*S[1]+B*R[1]), (A*S[2]+B*R[2])); } else { double B = 3.0/8.0/n; double A = 1-n*B; pt = Point((A*S[0]+B*R[0]), (A*S[1]+B*R[1]), (A*S[2]+B*R[2])); } }
void alignMesh( Polyhedron & poly ) { int num = poly.size_of_vertices(); // initialization here is very important!! Point3 ave( 0.0, 0.0, 0.0 ); for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) { ave = ave + ( vi->point() - CGAL::ORIGIN ); } ave = CGAL::ORIGIN + ( ave - CGAL::ORIGIN )/( double )num; unsigned int dim = 3; double * data = new double [ num*dim ]; int nPoints = 0; for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) { data[ nPoints * dim + 0 ] = vi->point().x() - ave.x(); data[ nPoints * dim + 1 ] = vi->point().y() - ave.y(); data[ nPoints * dim + 2 ] = vi->point().z() - ave.z(); nPoints++; } assert( nPoints == ( int )num ); /***************************************** analyze the engenstructure of X^T X *****************************************/ /* define the matrix X */ gsl_matrix_view X = gsl_matrix_view_array( data, num, dim ); /* memory reallocation */ // proj = ( double * )realloc( proj, sizeof( double ) * PDIM * num ); /* calculate the covariance matrix B */ gsl_matrix * B = gsl_matrix_alloc( dim, dim ); gsl_blas_dgemm( CblasTrans, CblasNoTrans, 1.0, &(X.matrix), &(X.matrix), 0.0, B ); /* divided by the number of samples */ gsl_matrix_scale( B, 1.0/(double)num ); gsl_vector * eVal = gsl_vector_alloc( dim ); gsl_matrix * eVec = gsl_matrix_alloc( dim, dim ); gsl_eigen_symmv_workspace * w = gsl_eigen_symmv_alloc( dim ); // eigenanalysis of the matrix B gsl_eigen_symmv( B, eVal, eVec, w ); // release the memory of w gsl_eigen_symmv_free( w ); // sort eigenvalues in a descending order gsl_eigen_symmv_sort( eVal, eVec, GSL_EIGEN_SORT_VAL_DESC ); // #ifdef MYDEBUG for ( unsigned int i = 0; i < dim; ++i ) { cerr << "Eigenvalue No. " << i << " = " << gsl_vector_get( eVal, i ) << endl; cerr << "Eigenvector No. " << i << endl; double length = 0.0; for ( unsigned int j = 0; j < dim; ++j ) { cerr << gsl_matrix_get( eVec, i, j ) << " "; length += gsl_matrix_get( eVec, i, j )*gsl_matrix_get( eVec, i, j ); } cerr << " length = " << length << endl; } // #endif // MYDEBUG // 0 1 2, 0 2 1, Transformation3 map; map = Transformation3( gsl_matrix_get(eVec,1,0), gsl_matrix_get(eVec,0,0), gsl_matrix_get(eVec,2,0), gsl_matrix_get(eVec,1,1), gsl_matrix_get(eVec,0,1), gsl_matrix_get(eVec,2,1), gsl_matrix_get(eVec,1,2), gsl_matrix_get(eVec,0,2), gsl_matrix_get(eVec,2,2) ); if ( map.is_odd() ) { cerr << " Transformation matrix reflected" << endl; map = Transformation3( gsl_matrix_get(eVec,1,0), gsl_matrix_get(eVec,0,0), -gsl_matrix_get(eVec,2,0), gsl_matrix_get(eVec,1,1), gsl_matrix_get(eVec,0,1), -gsl_matrix_get(eVec,2,1), gsl_matrix_get(eVec,1,2), gsl_matrix_get(eVec,0,2), -gsl_matrix_get(eVec,2,2) ); } for ( unsigned int i = 0; i < dim; ++i ) { cerr << "| "; for ( unsigned int j = 0; j < dim; ++j ) { cerr << map.cartesian( i, j ) << " "; } cerr << "|" << endl; } transformMesh( poly, map ); return; }
//------------------------------------------------------------------------------ // Align the mesh //------------------------------------------------------------------------------ Vector3 principalAxis( Polyhedron & poly ) { int num = poly.size_of_vertices(); // initialization here is very important!! Point3 ave( 0.0, 0.0, 0.0 ); for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) { ave = ave + ( vi->point() - CGAL::ORIGIN ); } ave = CGAL::ORIGIN + ( ave - CGAL::ORIGIN )/( double )num; unsigned int dim = 3; double * data = new double [ num*dim ]; int nPoints = 0; for ( Vertex_iterator vi = poly.vertices_begin(); vi != poly.vertices_end(); ++vi ) { data[ nPoints * dim + 0 ] = vi->point().x() - ave.x(); data[ nPoints * dim + 1 ] = vi->point().y() - ave.y(); data[ nPoints * dim + 2 ] = vi->point().z() - ave.z(); nPoints++; } assert( nPoints == ( int )num ); /***************************************** analyze the engenstructure of X^T X *****************************************/ /* define the matrix X */ gsl_matrix_view X = gsl_matrix_view_array( data, num, dim ); /* memory reallocation */ // proj = ( double * )realloc( proj, sizeof( double ) * PDIM * num ); /* calculate the covariance matrix B */ gsl_matrix * B = gsl_matrix_alloc( dim, dim ); gsl_blas_dgemm( CblasTrans, CblasNoTrans, 1.0, &(X.matrix), &(X.matrix), 0.0, B ); /* divided by the number of samples */ gsl_matrix_scale( B, 1.0/(double)num ); gsl_vector * eVal = gsl_vector_alloc( dim ); gsl_matrix * eVec = gsl_matrix_alloc( dim, dim ); gsl_eigen_symmv_workspace * w = gsl_eigen_symmv_alloc( dim ); // eigenanalysis of the matrix B gsl_eigen_symmv( B, eVal, eVec, w ); // release the memory of w gsl_eigen_symmv_free( w ); // sort eigenvalues in a descending order gsl_eigen_symmv_sort( eVal, eVec, GSL_EIGEN_SORT_VAL_DESC ); #ifdef MYDEBUG for ( unsigned int i = 0; i < dim; ++i ) { cerr << "Eigenvalue No. " << i << " = " << gsl_vector_get( eVal, i ) << endl; cerr << "Eigenvector No. " << i << endl; for ( unsigned int j = 0; j < dim; ++j ) { length += gsl_matrix_get( eVec, i, j )*gsl_matrix_get( eVec, i, j ); } cerr << " length = " << length << endl; } #endif // MYDEBUG Vector3 ref( gsl_matrix_get( eVec, 0, 0 ), gsl_matrix_get( eVec, 0, 1 ), gsl_matrix_get( eVec, 0, 2 ) ); return ref; #ifdef DEBUG gsl_vector_view eachVec = gsl_matrix_column( eigenVec, 0 ); double cosRot = gsl_matrix_get( eigenVec, 0, 1 ); double sinRot = gsl_matrix_get( eigenVec, 1, 1 ); #ifdef DEBUG cerr << " 2nd axis : " << cosRot << " , " << sinRot << endl; #endif // DEBUG Transformation2 rotate( CGAL::ROTATION, -sinRot, cosRot ); for ( unsigned int i = 0; i < subpatch.size(); ++i ) { subpatch[ i ]->triangle() = subpatch[ i ]->triangle().transform( rotate ); } #endif // DEBUG }
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; } }
////////////////////////////////////////////////////////////////////////////////////////////////////// // run a step float Remesh::RunColorStep() { cur_iter++; cerr << "ITERATION ( " << cur_iter << ") " << endl; // COMPUTE THE MESH DISPLACEMENT for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { vi->delta = Kernel::Vector_3(0,0,0); vi->delta_tmp = Kernel::Vector_3(0,0,0); } // from current to the closest destination point for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { #if MOVE_THE_MESH Kernel::Point_3 closest_point = dst_mesh.closestColorPoint(vi->point(), (float *)(vi->color)); //Kernel::Point_3 closest_point = dst_mesh.closestPoint(vi->point()); #else Kernel::Point_3 tmp_point = vi->point() + vi->motion_vec; Kernel::Point_3 closest_point = dst_mesh.closestColorPoint(tmp_point, (float *)(vi->color)); #endif //cerr << "closest_point (" << closest_point << ") has ID " << dst_mesh.vertex_mapping[closest_point]->id << endl; //Kernel::Vector_3 closest_normal = dst_mesh.vertex_mapping[closest_point]->normal(); //Kernel::Vector_3 closest_normal = dst_mesh.vertexMapping(closest_point)->normal(); /* vi->delta = closest_point - vi->point(); bool is_outside = v_norm((closest_point + closest_normal*v_norm(vi->delta)) - vi->point()) < v_norm(vi->delta); // bool is_outside = v_norm(v_normalized(closest_normal) + v_normalized(vi->delta)) < 1.4142; // bool is_outside = v_angle(closest_normal, vi->delta) > PI/2; double dist_sign = (is_outside?1:-1); vi->delta = vi->normal()*v_norm(vi->delta)*(-1)*dist_sign; */ vi->delta = closest_point- (vi->point() + vi->motion_vec); //vi->delta = vi->normal()* (closest_normal*(closest_point-vi->point())); // vi->delta == v_normalized(data->mesh.computeVectorComponent(vi->normal(),vi->delta,1))*v_norm(vi->delta); // vi->delta = v_normalized(vi->delta)*data->mesh.computeVertexStatistics(*vi,1)*0.05; // vi->delta = vi->normal(); //*alg_dt } // NORMALIZE the movements float total_movement = 0; int total_elements = 0; double max_delta = data->mesh.edge_avg*alg_dt; for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { //vi->delta = v_normalized(vi->delta)*data->mesh.computeVertexStatistics(*vi,1)*0.1; // double max_delta = data->mesh.computeVertexStatistics(*vi,1)*alg_dt; // double min_delta = data->mesh.edge_avg/5; // vi->delta = vi->delta; // vi->delta = vi->delta + v_normalized(vi->delta)*(RAND_MAX/2-std::rand())*1.0/RAND_MAX*data->mesh.edge_avg/2*alg_smoothing; // vi->delta = v_normalized(vi->delta)*max_delta; double the_norm = v_norm(vi->delta); if (the_norm > max_delta) { vi->delta = v_normalized(vi->delta)*max_delta; } // if (the_norm < min_delta) vi->delta = v_normalized(vi->delta)*min_delta; the_norm = v_norm(vi->delta); if (! MOVE_THE_MESH || the_norm > max_delta*0.5) { total_elements++; total_movement += v_norm(vi->delta); } //vi->delta = vi->delta + Kernel::Vector_3((RAND_MAX/2-std::rand())*1.0/RAND_MAX, (RAND_MAX/2-std::rand())*1.0/RAND_MAX, (RAND_MAX/2-std::rand())*1.0/RAND_MAX)*data->mesh.computeVertexStatistics(*vi,1)*alg_smoothing; // vi->delta = vi->delta + data->mesh.computeVectorComponent(vi->normal(),vi->laplacian()*alg_dt,0); //vi->delta = vi->delta + vi->laplacian()*alg_smoothing; } data->mesh.diffuse(alg_smoothing, 0); #if ADD_LENGTH_CONSTRAINT for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { // Add a cost for preserving the smoothness and the geometry of the mesh HV_circulator h = vi->vertex_begin(); double geom_vx = 0 ; double geom_vy = 0 ; double geom_vz = 0 ; int order=0; do { const float xx = TO_FLOAT ( vi->point().x() ); const float yy = TO_FLOAT ( vi->point().y() ); const float zz = TO_FLOAT ( vi->point().z() ); const float xxx = TO_FLOAT ( h->opposite()->vertex()->point().x()) ; const float yyy = TO_FLOAT ( h->opposite()->vertex()->point().y()) ; const float zzz = TO_FLOAT ( h->opposite()->vertex()->point().z()) ; double d = (xx - xxx) * (xx - xxx) + (yy - yyy) * (yy - yyy) + (zz - zzz) * (zz - zzz) ; #if MOVE_THE_MESH double t_d2x = (xx + vi->delta[0]) - (xxx + h->opposite()->vertex()->delta[0]) ; double t_d2y = (yy + vi->delta[1]) - (yyy + h->opposite()->vertex()->delta[1]) ; double t_d2z = (zz + vi->delta[2]) - (zzz + h->opposite()->vertex()->delta[2]) ; #else double t_d2x = (xx + vi->motion_vec[0] + vi->delta[0]) - (xxx + h->opposite()->vertex()->motion_vec[0] + h->opposite()->vertex()->delta[0]) ; double t_d2y = (yy + vi->motion_vec[1] + vi->delta[1]) - (yyy + h->opposite()->vertex()->motion_vec[1] + h->opposite()->vertex()->delta[1]) ; double t_d2z = (zz + vi->motion_vec[2] + vi->delta[2]) - (zzz + h->opposite()->vertex()->motion_vec[2] + h->opposite()->vertex()->delta[2]) ; #endif double d2 = t_d2x * t_d2x + t_d2y * t_d2y + t_d2z * t_d2z; geom_vx += t_d2x * (sqrt(d2) - sqrt(d)) / sqrt(d2) ; geom_vy += t_d2y * (sqrt(d2) - sqrt(d)) / sqrt(d2) ; geom_vz += t_d2z * (sqrt(d2) - sqrt(d)) / sqrt(d2) ; order++; } while ( ++h != vi->vertex_begin() ); geom_vx /= order ; geom_vy /= order ; geom_vz /= order ; double alpha = 1 ; vi->delta_tmp = alpha * Vector(-geom_vx, -geom_vy, -geom_vz) ; #if 0 if(v_norm(vi->delta_tmp) > 0.001) std::cout << vi->delta << " + " << geom_vx << " " << geom_vy << " " << geom_vz <<std::endl ; #endif } for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { double alpha1 = 0.9, alpha2 = 0.1 ; if(v_norm(vi->delta)<0.01) { alpha2 = 0.9; alpha1 = 0.1; } vi->delta = alpha1 * vi->delta + alpha2 * vi->delta_tmp; } #endif // MOVE THE MESH OpenGLContext::mutex.lock(); data->mesh.lock(); for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { if (alg_keepVerticesConstant) vi->delta = vi->normal()*(vi->delta*vi->normal()); vi->prev_delta = vi->delta; #if MOVE_THE_MESH vi->move ( vi->delta ); #else vi->motion_vec = vi->motion_vec + vi->delta; #endif } data->mesh.unlock(); #if MOVE_THE_MESH data->mesh.updateMeshData(); #else //for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { // vi->motion_vec = vi->motion_vec + vi->laplacian() * alg_smoothing; // smooth the motion vectors //} #endif OpenGLContext::mutex.unlock(); //saveOutput if (alg_saveOutput) { char filename[300]; sprintf(filename,"%s/output_%04d.off",alg_saveOutputPrefix,cur_iter); data->mesh.saveFormat(filename,"off"); sprintf(filename,"%s/output_%04d.diff",alg_saveOutputPrefix,cur_iter); data->mesh.saveVectorField(filename); sprintf(filename,"%s/output_%04d.idx",alg_saveOutputPrefix,cur_iter); data->mesh.saveVertexIndices(filename); } emit stepFinished(); return total_movement; //return total_elements; // return (++cur_iter < iter); }
// 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; }
float Remesh::RunStep() { cur_iter++; // COMPUTE THE MESH DISPLACEMENT for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) vi->delta = Kernel::Vector_3(0,0,0); // from current to the closest destination point for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { Kernel::Point_3 closest_point = dst_mesh.closestPoint(vi->point()); //cerr << "closest_point (" << closest_point << ") has ID " << dst_mesh.vertex_mapping[closest_point]->id << endl; Kernel::Vector_3 closest_normal = dst_mesh.vertex_mapping[closest_point]->normal(); //Kernel::Vector_3 closest_normal = dst_mesh.vertexMapping(closest_point)->normal(); /* vi->delta = closest_point - vi->point(); bool is_outside = v_norm((closest_point + closest_normal*v_norm(vi->delta)) - vi->point()) < v_norm(vi->delta); // bool is_outside = v_norm(v_normalized(closest_normal) + v_normalized(vi->delta)) < 1.4142; // bool is_outside = v_angle(closest_normal, vi->delta) > PI/2; double dist_sign = (is_outside?1:-1); vi->delta = vi->normal()*v_norm(vi->delta)*(-1)*dist_sign; */ vi->delta = vi->normal()* (closest_normal*(closest_point-vi->point())); // vi->delta == v_normalized(data->mesh.computeVectorComponent(vi->normal(),vi->delta,1))*v_norm(vi->delta); // vi->delta = v_normalized(vi->delta)*data->mesh.computeVertexStatistics(*vi,1)*0.05; // vi->delta = vi->normal(); //*alg_dt } // NORMALIZE the movements float total_movement = 0; int total_elements = 0; double max_delta = data->mesh.edge_avg*alg_dt; for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { //vi->delta = v_normalized(vi->delta)*data->mesh.computeVertexStatistics(*vi,1)*0.1; // double max_delta = data->mesh.computeVertexStatistics(*vi,1)*alg_dt; // double min_delta = data->mesh.edge_avg/5; // vi->delta = vi->delta; // vi->delta = vi->delta + v_normalized(vi->delta)*(RAND_MAX/2-std::rand())*1.0/RAND_MAX*data->mesh.edge_avg/2*alg_smoothing; // vi->delta = v_normalized(vi->delta)*max_delta; double the_norm = v_norm(vi->delta); if (the_norm > max_delta) { vi->delta = v_normalized(vi->delta)*max_delta; } // if (the_norm < min_delta) vi->delta = v_normalized(vi->delta)*min_delta; the_norm = v_norm(vi->delta); if (the_norm > max_delta*0.5) { total_elements++; total_movement += v_norm(vi->delta); } //vi->delta = vi->delta + Kernel::Vector_3((RAND_MAX/2-std::rand())*1.0/RAND_MAX, (RAND_MAX/2-std::rand())*1.0/RAND_MAX, (RAND_MAX/2-std::rand())*1.0/RAND_MAX)*data->mesh.computeVertexStatistics(*vi,1)*alg_smoothing; // vi->delta = vi->delta + data->mesh.computeVectorComponent(vi->normal(),vi->laplacian()*alg_dt,0); if (vi->border()==false) vi->delta = vi->delta + vi->laplacian()*alg_smoothing; } // MOVE THE MESH OpenGLContext::mutex.lock(); data->mesh.lock(); for (Vertex_iterator vi = data->mesh.p.vertices_begin(); vi!=data->mesh.p.vertices_end(); vi++) { if (alg_keepVerticesConstant) vi->delta = vi->normal()*(vi->delta*vi->normal()); vi->prev_delta = vi->delta; vi->border()=false; vi->move ( vi->delta ); } data->mesh.unlock(); data->mesh.updateMeshData(); OpenGLContext::mutex.unlock(); //saveOutput if (alg_saveOutput) { char filename[300]; sprintf(filename,"%s/output_%04d.off",alg_saveOutputPrefix,cur_iter); data->mesh.saveFormat(filename,"off"); sprintf(filename,"%s/output_%04d.diff",alg_saveOutputPrefix,cur_iter); data->mesh.saveVectorField(filename); sprintf(filename,"%s/output_%04d.idx",alg_saveOutputPrefix,cur_iter); data->mesh.saveVertexIndices(filename); } emit stepFinished(); return total_elements; // return (++cur_iter < iter); }
// 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(); }
/** * Executes one custom timestep * @param averageEdgeLength The function to compute the average edge length for a given vertex * @param getOffsetPoint Computes the new location of the given point * @return The results of running the timestep */ stepResults StoneWeatherer::doOneCustomStep( double ( *averageEdgeLength )( const Vertex_handle & v ), Point( *getOffsetPoint )( const Point & p, const VertexData & d, const StoneWeatherer * caller ) ) { CGAL::Timer timestamp; stepResults result; result.secondsTotal = 0.0; timestamp.start(); timestamp.reset(); /** * Maps circumcenters to where they really came from */ map<Point,Point> pointMap; // Generate the correct-resolution offset points vector<Point> newPoints; int n; int i; int j; Vertex_handle vhi; Vertex_handle vhj; double dist2; Point a; Point b; Point c; VertexData d; // Put in midPoints of edges as needed, and flag redundant vertices for ( Cell_iterator it = newDT->finite_cells_begin(); it != newDT->finite_cells_end(); ++it ) { if ( it->info() != AIR ) { for ( n = 0; n < 4; ++n ) { if ( it->neighbor( n )->info() != it->info() || newDT->is_infinite( it->neighbor( n ) ) ) { for ( i = 1; i < 4; ++i ) { Vertex_handle vhi = it->vertex( n ^ i ); for ( j = i + 1; j < 4; ++j ) { Vertex_handle vhj = it->vertex( n ^ j ); // Only check each edge once... if ( vhi < vhj ) { dist2 = ( vhi->point() - vhj->point() ).squared_length(); if ( dist2 > maxSquareDistance( averageEdgeLength, vhi, vhj ) ) { // Don't split non-live edges a = vhi->point(); b = vhj->point(); if ( !live( a.x(), a.y(), a.z() ) && !live( b.x(), b.y(), b.z() ) ) { continue; } // Split edge a = CGAL::ORIGIN + ( ( a - CGAL::ORIGIN ) + ( b - CGAL::ORIGIN ) ) * 0.5; d = VertexData::midPoint( vhi->info(), vhj->info() ); //// If the vertex is shared by both objects, split it //if ( ( d.flag & ROCK ) && ( d.flag & MORE_ROCK ) ) { // VertexData d1; // VertexData d2; // splitVertexData( d, d1, d2 ); // // Point a1 = jitterPoint( a ); // Point a2 = jitterPoint( a ); // // c = getOffsetPoint( a1, d1, this ); // newPoints.push_back( c ); // pointMap.insert( pair<Point,Point>( c, a1 ) ); // c = getOffsetPoint( a2, d2, this ); // newPoints.push_back( c ); // pointMap.insert( pair<Point,Point>( c, a2 ) ); //} //else { c = getOffsetPoint( a, d, this ); newPoints.push_back( c ); pointMap.insert( pair<Point,Point>( c, a ) ); //} } else if ( vhi->info().kill != TOO_CLOSE && dist2 < minSquareDistance( averageEdgeLength, vhi, vhj ) ) { // The higher-address endpoint vhj->info().kill = TOO_CLOSE; } } } } } } } } double bound[ 3 ][ 2 ] = { { 1.0e30, -1.0e30 }, { 1.0e30, -1.0e30 }, { 1.0e30, -1.0e30 } }; // Put in all the border vertices for ( Vertex_iterator it = newDT->finite_vertices_begin(); it != newDT->finite_vertices_end(); ++it ) { if ( it->point().x() < bound[ 0 ][ 0 ] ) { bound[ 0 ][ 0 ] = it->point().x(); } else if ( it->point().x() > bound[ 0 ][ 1 ] ) { bound[ 0 ][ 1 ] = it->point().x(); } if ( it->point().y() < bound[ 1 ][ 0 ] ) { bound[ 1 ][ 0 ] = it->point().y(); } else if ( it->point().y() > bound[ 1 ][ 1 ] ) { bound[ 1 ][ 1 ] = it->point().y(); } if ( it->point().z() < bound[ 2 ][ 0 ] ) { bound[ 2 ][ 0 ] = it->point().z(); } else if ( it->point().z() > bound[ 2 ][ 1 ] ) { bound[ 2 ][ 1 ] = it->point().z(); } if ( !live( it->point().x(), it->point().y(), it->point().z() ) ) { newPoints.push_back( it->point() ); pointMap.insert( pair<Point,Point>( it->point(), it->point() ) ); } else if ( it->info().kill == BORDER ) { VertexData d = it->info(); Point a = it->point(); Point c; //// If the vertex is shared by both objects, split it //if ( ( d.flag & ROCK ) && ( d.flag & MORE_ROCK ) ) { // VertexData d1; // VertexData d2; // splitVertexData( d, d1, d2 ); // // Point a1 = jitterPoint( a ); // Point a2 = jitterPoint( a ); // // c = getOffsetPoint( a1, d1, this ); // newPoints.push_back( c ); // pointMap.insert( pair<Point,Point>( c, a1 ) ); // c = getOffsetPoint( a2, d2, this ); // newPoints.push_back( c ); // pointMap.insert( pair<Point,Point>( c, a2 ) ); //} //else { c = getOffsetPoint( a, d, this ); newPoints.push_back( c ); pointMap.insert( pair<Point,Point>( c, a ) ); //} } } result.secondsTotal += ( result.secondsMotion = timestamp.time() ); timestamp.reset(); // Create the new mesh swapDT(); newDT->clear(); newDT->insert( newPoints.begin(), newPoints.end() ); result.secondsTotal += ( result.secondsCGAL = timestamp.time() ); //secondsTotal += result.secondsCGAL; //secondsCGAL += result.secondsCGAL; timestamp.reset(); // Update the inside-outside flags of new tetrahedrons setContentFlags( result.midPoint, pointMap ); result.midPoint[ 0 ] = ( bound[ 0 ][ 0 ] + bound[ 0 ][ 1 ] ) * 0.5; result.midPoint[ 1 ] = ( bound[ 1 ][ 0 ] + bound[ 1 ][ 1 ] ) * 0.5; result.midPoint[ 2 ] = ( bound[ 2 ][ 0 ] + bound[ 2 ][ 1 ] ) * 0.5; result.secondsTotal += ( result.secondsLabeling = timestamp.time() ); //secondsTotal += result.secondsLabeling; //secondsLabeling += result.secondsLabeling; timestamp.reset(); // Update vertex information setVertexInfo(); result.secondsTotal += ( result.secondsAnalysis = timestamp.time() ); timestamp.reset(); timestamp.stop(); result.numVertices = newDT->number_of_vertices(); result.numTetrahedrons = newDT->number_of_cells(); cumulativeResults.secondsTotal += result.secondsTotal; cumulativeResults.secondsMotion += result.secondsMotion; cumulativeResults.secondsCGAL += result.secondsCGAL; cumulativeResults.secondsLabeling += result.secondsLabeling; cumulativeResults.secondsAnalysis += result.secondsAnalysis; return result; }
void MSDM2_Component::ProcessMSDM2_per_vertex( Vertex_iterator pVertex,double radius,std::vector<double> & TabDistance1,std::vector<double>& TabDistance2,std::vector<Point3d> &TabPoint1,std::vector<Point3d> &TabPoint2) { std::set<int> vertices ; std::stack<Vertex_iterator> S ; Point3d O = pVertex->point() ; S.push(pVertex) ; vertices.insert(pVertex->tag()) ; TabDistance1.push_back(pVertex->KmaxCurv); TabPoint1.push_back(pVertex->point()); TabDistance2.push_back(pVertex->curvmatch); TabPoint2.push_back(pVertex->match); int NbSommetInSphere=0; //double SommeDistance=0; // MT while(!S.empty()) { Vertex_iterator v = S.top() ; S.pop() ; Point3d P = v->point() ; Halfedge_around_vertex_circulator h = v->vertex_begin(); Halfedge_around_vertex_circulator pHalfedgeStart = h; CGAL_For_all(h,pHalfedgeStart) { Point3d p1 = h->vertex()->point(); Point3d p2 = h->opposite()->vertex()->point(); Point3d p1m = h->vertex()->match; Point3d p2m = h->opposite()->vertex()->match; Vector V = (p2-p1); Vector Vm = (p2m-p1m); if(v==pVertex || V * (P - O) > 0.0) { double len_old = std::sqrt(V*V); bool isect = sphere_clip_vector_MSDM2(O, radius, P, V) ; double len_edge = std::sqrt(V*V); NbSommetInSphere++; double WeightedCurv1,WeightedCurv2; Point3d WeightedP1,WeightedP2; bool IsAlreadyIntegrated=false; if(!isect) { Vertex_iterator w=h->opposite()->vertex(); if(vertices.find(w->tag()) == vertices.end()) { vertices.insert(w->tag()) ; S.push(w) ; } else IsAlreadyIntegrated=true; } if (IsAlreadyIntegrated==false) { if(len_old!=0) { if(isect) { WeightedCurv1=(1-len_edge/len_old)*h->vertex()->KmaxCurv+len_edge/len_old*h->opposite()->vertex()->KmaxCurv; WeightedP1=p1+V; WeightedCurv2=(1-len_edge/len_old)*h->vertex()->curvmatch+len_edge/len_old*h->opposite()->vertex()->curvmatch; WeightedP2=p1m+(len_edge/len_old)*Vm; } else { WeightedCurv1=h->opposite()->vertex()->KmaxCurv; WeightedCurv2=h->opposite()->vertex()->curvmatch; WeightedP1=p2; WeightedP2=p2m; } } else { WeightedCurv1=h->opposite()->vertex()->KmaxCurv; WeightedCurv2=h->opposite()->vertex()->curvmatch; WeightedP1=p2; WeightedP2=p2m; } TabDistance1.push_back(WeightedCurv1); TabPoint1.push_back(WeightedP1); TabDistance2.push_back(WeightedCurv2); TabPoint2.push_back(WeightedP2); } } } }