void CModel::Normalize(){ double xmax, xmin, ymax, ymin, zmax, zmin; double x, y, z; double xcentre = 0.0, ycentre = 0.0, zcentre = 0.0; double scale = 0.0; xmax = plist[0].x(); xmin = plist[0].x(); ymax = plist[0].y(); ymin = plist[0].y(); zmax = plist[0].z(); zmin = plist[0].z(); for(int i =0; i < p_no; ++i){ xcentre += plist[i].x(); ycentre += plist[i].y(); zcentre += plist[i].z(); if(xmax < plist[i].x()) xmax = plist[i].x(); if(xmin > plist[i].x()) xmin = plist[i].x(); if(ymax < plist[i].y()) ymax = plist[i].y(); if(ymin > plist[i].y()) ymin = plist[i].y(); if(zmax < plist[i].z()) zmax = plist[i].z(); if(zmin > plist[i].z()) zmin = plist[i].z(); } xcentre /= p_no; ycentre /= p_no; zcentre /= p_no; if(scale<fabs(xmax-xmin)) scale = fabs(xmax-xmin); if(scale<fabs(ymax-ymin)) scale = fabs(ymax-ymin); if(scale<fabs(zmax-zmin)) scale = fabs(zmax-zmin); scale = 2.0/scale; for(int i =0; i < p_no; ++i){ plist[i] = Point_3(plist[i].x()-xcentre, plist[i].y()-ycentre, plist[i].z()-zcentre); x = plist[i].x()*scale ; y = plist[i].y()*scale ; z = plist[i].z()*scale ; plist[i] = Point_3(x, y, z); } }
static std::vector<SupportFunctionDataItem> extractSupportFunctionDataItems( SContour *contour, SupportFunctionDataItemExtractor *extractor) { /* Check that the input contour is correct. */ ASSERT(contour); ASSERT(contour->sides); ASSERT(contour->ns > 0); ASSERT(!!contour->plane.norm); /* Check that normal != 0 */ ASSERT(fabs(contour->plane.norm.z) < EPS_MIN_DOUBLE); std::vector<SupportFunctionDataItem> items; /* Iterate through the array of sides of current contour. */ for (int iSide = 0; iSide < contour->ns; ++iSide) { SideOfContour *side = &contour->sides[iSide]; SupportFunctionDataItem item = extractor->run(side); item.info = SupportFunctionDataItemInfoPtr(new SupportFunctionDataItemInfo()); item.info->iContour = contour->id; item.info->numSidesContour = contour->ns; item.info->iSide = iSide; item.info->segment = Segment_3(Point_3(side->A1), Point_3(side->A2)); item.info->normalShadow = contour->plane.norm; items.push_back(item); } DEBUG_END; return items; }
// Calcule une moyenne d'un vecteur de plusieurs points Point_3 DegradeAnObject::meanPoints(std::vector<Point_3> points) { Point_3 pt(0.0, 0.0, 0.0); int size = points.size(); for(int i = 0 ; i < size ; i++) { pt = Point_3(pt.x() + points[i].x(), pt.y() + points[i].y(), pt.z() + points[i].z()); } pt = Point_3(pt.x()/size, pt.y()/size, pt.z()/size); return pt; }
void gnu() { SM sm; CGAL::make_triangle(Point_3(0,0,0), Point_3(1,0,0), Point_3(1,1,0),sm); halfedge_descriptor hd = *(halfedges(sm).first); hd = next(hd,sm); std::cout << hd; }
void extract_segments_from_vtkPointSet(vtkPointSet* poly_data, std::vector< std::vector<Point_3> >& segments) { // get nb of points and cells vtkIdType nb_points = poly_data->GetNumberOfPoints(); vtkIdType nb_cells = poly_data->GetNumberOfCells(); //extract points std::vector<Point_3> point_map(nb_points); for (vtkIdType i = 0; i<nb_points; ++i) { double coords[3]; poly_data->GetPoint(i, coords); point_map[i]=Point_3(coords[0], coords[1], coords[2]); } //extract segments for (vtkIdType i = 0; i<nb_cells; ++i) { if(poly_data->GetCellType(i) != 3 && poly_data->GetCellType(i) != 4) continue; vtkCell* cell_ptr = poly_data->GetCell(i); vtkIdType nb_vertices = cell_ptr->GetNumberOfPoints(); segments.push_back( std::vector<Point_3>() ); for(int j = 0; j < nb_vertices; ++j) { segments.back().push_back(point_map[cell_ptr->GetPointId(j)]); } } }
void Ctr2SufManager::addContourFromVec(vector<CurveNetwork> vecCurveNetwork,float* fPreSetBBox,vector<vector<Point_3>>& MeshBoundingProfile3D) { ContourHandler::readContourFromVec(vecCurveNetwork,param, ctrvers, ctredges, bbox, bboxset); //kw: set the bbox to the preset value,instead of the one calculated memcpy(bbox,fPreSetBBox,sizeof(float)*6); resize(); for( int i = 0; i < planenum; i ++) { int iVerIndBase=0; vector<Point_3> CurrentProfile3D; for( int j = 0;j < showctredgenum[ i ]; j++) { int v1 = showctredges[ i ][ 2*j ]; int v2 = showctredges[ i ][ 2*j + 1 ]; CurrentProfile3D.push_back(Point_3(showctrvers[ i ][ v1* 3], showctrvers[ i ][ v1* 3+1], showctrvers[ i ][ v1* 3+2])); if (v2==iVerIndBase) { iVerIndBase=iVerIndBase+CurrentProfile3D.size(); MeshBoundingProfile3D.push_back(CurrentProfile3D); CurrentProfile3D.clear(); } } } }
void CModel::LoadModel(char * fname){ int i; double x,y,z; char buffer[30]; FILE *fp1 = fopen(fname,"r"); gettoken(buffer, fp1); gettoken(buffer, fp1); p_no = atoi(buffer); gettoken(buffer, fp1); f_no = atoi(buffer); gettoken(buffer, fp1); if(plist!=NULL) delete [] plist; if(flist!=NULL) delete [] flist; plist = new Point_3[p_no]; flist = new int[3*f_no]; for(i = 0; i < p_no; i++){ gettoken(buffer, fp1); x = atof(buffer); gettoken(buffer, fp1); y = atof(buffer); gettoken(buffer, fp1); z = atof(buffer); plist[i] = Point_3(x,y,z); } for(i = 0; i < f_no; i++){ gettoken(buffer, fp1); // read the number 3 gettoken(buffer, fp1); flist[3*i+0] = atoi(buffer); gettoken(buffer, fp1); flist[3*i+1] = atoi(buffer); gettoken(buffer, fp1); flist[3*i+2] = atoi(buffer); } }
void KW_CS2Surf::GetSSCenter(int iSubspaceId,Point_3& SSCenter) { set<int> setVerId; //get the id of the vertices of the subspace for (int i=0;i<vecSSspacefacenum.at(iSubspaceId);i++) { int iFaceId=vecvecSSspace.at(iSubspaceId).at(i); for (int j=0;j<vecSSfaceedgenum.at(iFaceId);j++) { int iEdgeInd=vecvecSSface.at(iFaceId).at(j); int iVerBeginInd=vecSSedge.at(2*iEdgeInd); int iVerEndInd=vecSSedge.at(2*iEdgeInd+1); setVerId.insert(iVerBeginInd); setVerId.insert(iVerEndInd); } } //compute the center vector<Point_3> vecVerPoint; for (set<int>::iterator SetIter=setVerId.begin();SetIter!=setVerId.end();SetIter++) { vecVerPoint.push_back(Point_3(vecSSver.at(3*(*SetIter)), vecSSver.at(3*(*SetIter)+1), vecSSver.at(3*(*SetIter)+2))); } SSCenter=CGAL::centroid(vecVerPoint.begin(),vecVerPoint.end()); }
bool Scene_polyhedron_shortest_path_item::get_mouse_ray(QMouseEvent* mouseEvent, Ray_3& outRay) { bool found = false; QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); qglviewer::Camera* camera = viewer->camera(); const qglviewer::Vec point = camera->pointUnderPixel(mouseEvent->pos(), found); if(found) { const qglviewer::Vec orig = camera->position(); outRay = Ray_3(Point_3(orig.x, orig.y, orig.z), Point_3(point.x, point.y, point.z)); } return found; }
double errorOfLineInPlane(Segment_3 &l, Eigen::Vector3d& point, Eigen::Vector3d& normal) { Plane_3 plane( Point_3(point.x(), point.y(), point.z()), Vector_3(normal.x(), normal.y(), normal.z()) ); double dist1 = squared_distance(plane, l.point(0)); double dist2 = squared_distance(plane, l.point(1)); return 0.5*(sqrt(dist1)+sqrt(dist2)); }
double errorOfCoplanar(Eigen::Vector3d &pt1, Eigen::Vector3d &normal1, Eigen::Vector3d &pt2, Eigen::Vector3d &normal2) { double err1 = 1-std::abs(normal1.dot(normal2)); Point_3 point(pt1.x(), pt1.y(), pt1.z()); Plane_3 p2(Point_3(pt2.x(), pt2.y(), pt2.z()), Vector_3(normal2.x(), normal2.y(), normal2.z())); double dist1 = squared_distance(p2, point); return err1 + sqrt(dist1); }
Point_3 scene_point (const Point_2& p) const { QGLViewer* viewer = *QGLViewer::QGLViewerPool().begin(); qglviewer::Camera* camera = viewer->camera(); qglviewer::Vec vp (p.x(), p.y(), 0.1); qglviewer::Vec vsp = camera->unprojectedCoordinatesOf (vp); return Point_3 (vsp.x, vsp.y, vsp.z); }
vector<Point_3> sm_vertices(const cvcraw_geometry::cvcgeom_t& geom) { const cvcraw_geometry::cvcgeom_t::points_t& points = geom.points(); const int n = points.size(); vector<Point_3> ret(n); for (int i = 0; i < n; ++i) { const cvcraw_geometry::cvcgeom_t::point_t& p = points[i]; ret[i] = Point_3(p[0], p[1], p[2]); } return ret; }
Polyhedra generate_polyhedra_from_points(const std::vector<std::array<double,3> >& vertices) { std::vector<Point_3> points(vertices.size()); for(int i=0;i<(int)vertices.size();i++) points[i] = Point_3(vertices[i][0],vertices[i][1],vertices[i][2]); Polyhedron_3 poly; CGAL::convex_hull_3(points.begin(), points.end(), poly); std::transform(poly.facets_begin(), poly.facets_end(), poly.planes_begin(), Plane_from_facet()); for(Halfedge_iterator half=poly.halfedges_begin();half!=poly.halfedges_end();++half) { Point_3 v1 = half->vertex()->point(); Point_3 v2 = half->next()->vertex()->point(); Point_3 v3 = half->next()->next()->vertex()->point(); Point_3 v4 = half->opposite()->vertex()->point(); Point_3 v5 = half->opposite()->next()->vertex()->point(); Point_3 v6 = half->opposite()->next()->next()->vertex()->point(); if(coplanar_handmade(v1,v2,v3,v4)&&coplanar_handmade(v1,v2,v3,v5)&&coplanar_handmade(v1,v2,v3,v6)&& coplanar_handmade(v1,v2,v4,v5)&&coplanar_handmade(v1,v2,v4,v6)&&coplanar_handmade(v1,v2,v5,v6)&& coplanar_handmade(v1,v3,v4,v5)&&coplanar_handmade(v1,v3,v4,v6)&&coplanar_handmade(v1,v4,v5,v6)&& coplanar_handmade(v2,v3,v4,v5)&&coplanar_handmade(v2,v3,v4,v6)&&coplanar_handmade(v2,v3,v5,v6)&& coplanar_handmade(v2,v4,v5,v6)&&coplanar_handmade(v1,v3,v5,v6)&&coplanar_handmade(v3,v4,v5,v6)) { poly.join_facet(half); half=poly.halfedges_begin(); } } int cur = 0; for(auto it=poly.points_begin(); it!=poly.points_end(); it++, cur++) points[cur] = *it; cur = 0; std::vector<std::vector<int> > faces; for(Facet_iterator i=poly.facets_begin(); i!=poly.facets_end(); i++) { faces.push_back(std::vector<int>()); Halfedge_facet_circulator j = i->facet_begin(); do {faces[cur].push_back(std::distance(poly.vertices_begin(), j->vertex()));} while (++j != i->facet_begin()); cur++; } return Polyhedra{points,faces}; }
// Réalise un impact sur la face fs à partir d'une liste de points à déplacer, répartis par couronne (pts[0] = première couronne intérieure, pts[0][0] = premier point de la première couronne) void DegradeAnObject::impactTheFacetArea(std::vector< std::vector<Point_3> > pts, Facet fs, double ray, int index) { double str = 0.02; Vector_3 normal = normalizeVector(getNormalOfFacet(fs)); Kernel::Plane_3 pl(fs.halfedge()->vertex()->point(), normal); for(int i = 0 ; i < pts.size() ; i++) { for(int j = 0 ; j < pts[i].size() ; j++) { bool chk = false; Point_iterator pi = polys[index].points_begin(); while(!chk) { ++pi; if(*pi == pts[i][j]) { *pi = Point_3(pi->x() - (impactStrengh(str, i))*normal.x(), pi->y() - (impactStrengh(str, i))*normal.y(), pi->z() - (impactStrengh(str, i))*normal.z()); chk = true; } } } } }
void CModel::FacetHarmonics(int fh, int bw, double r, gsl_complex *coeff){ int i, j, sign; gsl_complex err; Triangle_3 tr; tr = Triangle_3(plist[flist[fh*3+0]],plist[flist[fh*3+1]],plist[flist[fh*3+2]]); Tetrahedron_3 tetr; tetr = Tetrahedron_3(Point_3(0.0, 0.0, 0.0),plist[flist[fh*3+0]],plist[flist[fh*3+1]],plist[flist[fh*3+2]]); if(tetr.is_degenerate()) return; sign = (tetr.volume()<0 ? -1 : 1); for(i=0; i<bw; i++){ for(j=0; j<=i; j++){ Integrate(i, j, r, tetr, &coeff[i*bw+j], &err); coeff[i*bw+j] = gsl_complex_mul_real(coeff[i*bw+j], (double)sign); } } }
void Ctr2SufManager::SaveMAInfo(int majptnum,float* majpt,int maseamnum,int* maseam) { //bounding points of MA planes vector<Point_3> vecNewMAPoint; for (int i=0;i<majptnum;i++) { vecNewMAPoint.push_back(Point_3(majpt[3*i]*DIM/PROCSIZE+this->OldCenter.x(), majpt[3*i+1]*DIM/PROCSIZE+this->OldCenter.y(), majpt[3*i+2]*DIM/PROCSIZE+this->OldCenter.z())); } this->vecvecMAPoint.push_back(vecNewMAPoint); //seams of MA planes vector<Int_Int_Pair> vecNewMASeam; for (int i=0;i<maseamnum;i++) { vecNewMASeam.push_back(make_pair(maseam[2*i],maseam[2*i+1])); } this->vecvecMASeam.push_back(vecNewMASeam); assert(this->vecvecMAPoint.size()==this->vecvecMASeam.size()); }
void CMeshCutting::Init(CKWResearchWorkDoc* pDataIn) { this->pDoc=pDataIn; this->CurvePoint2D.clear(); this->iDrawingCurveType=NONE_SELECTED; this->hCuttingClosedCurveVertex3d.clear(); this->SidePoint=Point_3(0,0,0); this->vecTestPoint.clear(); //reference plane this->Plane_spin=0.0; this->dAccumulatedAngleX=0.0; //this->Tunel.clear(); //init control panel CControlPanel* pCP=(CControlPanel*)(pDoc->GetView(RUNTIME_CLASS(CControlPanel))); if (pCP->GetCPCutting()!=NULL) { pCP->GetCPCutting()->Init(); } }
void MainWindow::newPoints(int n) { scene.periodic_triangulation.clear(); scene.points.clear(); CGAL::Random rnd(std::time(NULL)); CGAL::Random_points_in_cube_3<Point_3, Creator> in_cube(1,rnd); for (int i=0 ; i<n ; i++) if (scene.two_dimensional) { Point_3 rdpt = *in_cube++; scene.points.push_back(Point_3(rdpt.x(),rdpt.y(),0.)); } else scene.points.push_back(*in_cube++); Iso_cuboid_3 dom(-1,-1,-1,1,1,1); scene.periodic_triangulation.set_domain(dom); scene.periodic_triangulation.insert(scene.points.begin(), scene.points.end()); FT cx(0),cy(0),cz(0); for (int i=0 ; i<8 ; i++) { cx += dom[i].x(); cy += dom[i].y(); cy += dom[i].y(); } qglviewer::Vec center(cx/8.,cy/8.,cz/8.); viewer->setSceneCenter(center); viewer->setSceneRadius(std::sqrt( ((dom.xmax()-dom.xmin())*(dom.xmax()-dom.xmin())) + ((dom.xmax()-dom.xmin())*(dom.xmax()-dom.xmin())) + ((dom.xmax()-dom.xmin())*(dom.xmax()-dom.xmin())))); speedSlider->setRange(0,100); speedSlider->setSliderPosition(100); emit (sceneChanged()); }
void Ctr2SufManager::readContourFromFile(char* fnames,vector<vector<Point_3>>& MeshBoundingProfile3D) { clearOldContour(); //clear mesh delete mesh; mesh = NULL; ContourHandler::readContourFromFile(fnames, param, ctrvers, ctredges, bbox, bboxset); resize(); for( int i = 0; i < planenum; i ++) { int iVerIndBase=0; vector<Point_3> CurrentProfile3D; for( int j = 0;j < showctredgenum[ i ]; j++) { int v1 = showctredges[ i ][ 2*j ]; int v2 = showctredges[ i ][ 2*j + 1 ]; CurrentProfile3D.push_back(Point_3(showctrvers[ i ][ v1* 3], showctrvers[ i ][ v1* 3+1], showctrvers[ i ][ v1* 3+2])); //kw noted: one closed cross section is totally read //may have problem for non-self-defined data if (v2==iVerIndBase) { iVerIndBase=iVerIndBase+CurrentProfile3D.size(); MeshBoundingProfile3D.push_back(CurrentProfile3D); CurrentProfile3D.clear(); } } } }
Point_3 xz_swap_pos(const Point_3& p) { return Point_3(-p.z(), p.y(), p.x()); }
void CMeshCutting::Conver2DCurveTo3D(KW_Mesh& Mesh) { if (this->CurvePoint2D.empty()) { return; } CKWResearchWorkView* pView=(CKWResearchWorkView*)this->pDoc->GetView(RUNTIME_CLASS(CKWResearchWorkView)); GLdouble* modelview=pView->GetModelview(); GLdouble* projection=pView->GetProjection(); GLint* viewport=pView->GetViewport(); if (!this->hCuttingClosedCurveVertex3d.empty()) { this->iDrawingCurveType=CUTTING_BITE_CURVE; } else { this->iDrawingCurveType=CUTTING_ACROSS_CURVE; } if (iDrawingCurveType==CUTTING_ACROSS_CURVE) { GeometryAlgorithm compute; compute.ProcessCurverPoint(this->CurvePoint2D,10.0); //convert UCP into opengl coordinate(on Znear) vector<Point_3> UserCurvePoint; for (unsigned int i=0;i<this->CurvePoint2D.size();i++) { GLdouble winX, winY, winZ; GLdouble posX, posY, posZ; winX =this->CurvePoint2D.at(i).x; winY = viewport[3] - (float)this->CurvePoint2D.at(i).y; glReadPixels((int)winX, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ); gluUnProject(winX, winY, 0.0, modelview, projection, viewport, &posX, &posY, &posZ); Point_3 CurrentPoint(posX,posY,posZ); UserCurvePoint.push_back(CurrentPoint); } vector<Vertex_handle> CuttingClosedCurveVertex3d; CPaintingOnMesh Painting; if(Painting.PaintingClosedStrokeOnFrontalAndRearMesh(Mesh,UserCurvePoint,modelview, CuttingClosedCurveVertex3d)) { this->hCuttingClosedCurveVertex3d=CuttingClosedCurveVertex3d; //get the plane for judging which part to cut Point_3 Point0=UserCurvePoint.front(); Point_3 Point1=this->hCuttingClosedCurveVertex3d.front()->point(); Point_3 Point2=this->hCuttingClosedCurveVertex3d.back()->point(); this->SidePlane=Plane_3(Point0,Point1,Point2); } } else if (iDrawingCurveType==CUTTING_BITE_CURVE) { if (this->hCuttingClosedCurveVertex3d.empty()) { this->CurvePoint2D.clear(); return; } //convert UCP into opengl coordinate(on Znear) GLdouble winX, winY, winZ; GLdouble posX, posY, posZ; winX =this->CurvePoint2D.front().x; winY = viewport[3] - (float)this->CurvePoint2D.front().y; glReadPixels((int)winX, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ); gluUnProject(winX, winY, 0.0, modelview, projection, viewport, &posX, &posY, &posZ); this->SidePoint=Point_3(posX,posY,posZ); CPaintingOnMesh Painting; Facet_handle temp; if(Painting.PaintingPointOnFrontalMesh(Mesh,this->SidePoint,temp,modelview)) { CutMesh(Mesh); OBJHandle::UnitizeCGALPolyhedron(Mesh,false,false); Mesh.SetRenderInfo(true,true,true,true,true); this->hCuttingClosedCurveVertex3d.clear(); } else { AfxMessageBox("Invalid Curve,could not judge which part to cut!"); } } //else if (iDrawingCurveType==3) //{ // if (this->Tunel.GetTunVer().size()<2) // { // GeometryAlgorithm compute; // compute.ProcessCurverPoint(this->CurvePoint2D); // compute.MakeClosedStroke2d(this->CurvePoint2D); // //convert UCP into opengl coordinate(on Znear) // vector<Point_3> UserCurvePoint; // for (unsigned int i=0;i<this->CurvePoint2D.size();i++) // { // GLdouble winX, winY, winZ; // GLdouble posX, posY, posZ; // winX =this->CurvePoint2D.at(i).x; // winY = viewport[3] - (float)this->CurvePoint2D.at(i).y; // glReadPixels((int)winX, (int)winY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &winZ); // gluUnProject(winX, winY, 0.0, modelview, projection, viewport, &posX, &posY, &posZ); // Point_3 CurrentPoint(posX,posY,posZ); // UserCurvePoint.push_back(CurrentPoint); // } // vector<Vertex_handle> TunnelCurve3d; // CPaintingOnMesh Painting; // if(Painting.PaintingClosedStrokeOnFrontalMesh(Mesh,UserCurvePoint,modelview,TunnelCurve3d)) // { // if (this->Tunel.GetTunVer().size()==0) // { // this->Tunel.InputTunVer(TunnelCurve3d); // } // else if (this->Tunel.GetTunVer().size()==1)//remesh to get the two sketched circles // { // //the result curve is always ccw on screen,so reverse the second curve // //and make it the same direction with the first one // reverse(TunnelCurve3d.begin(),TunnelCurve3d.end()); // this->Tunel.InputTunVer(TunnelCurve3d); // this->Tunel.CorrespondTunCircles(); // this->Tunel.SetRefPlane(this->BestFittingPlane,this->PlaneBoundaryPoints, // this->RotateXAxisStartPoint,this->RotateXAxisEndPoint); // } // OBJHandle::UnitizeCGALPolyhedron(Mesh,false,false); // Mesh.SetRenderInfo(true,true,true,true,true); // } // } // else if (this->Tunel.GetTunVer().size()==2)//make tunnel along the sketched curve // { // GeometryAlgorithm compute; // compute.ProcessCurverPoint(this->CurvePoint2D,15.0); // vector<Point_3> vecTempPoints; // CPaintingOnMesh PaintingOnMesh; // int iResult=PaintingOnMesh.PaintingOnBFPlane(this->BestFittingPlane,modelview,projection,viewport, // this->CurvePoint2D,vecTempPoints); // if (iResult) // { // this->Tunel.SetTunnelDirectCurve(vecTempPoints); // } // //dig the hole // this->Tunel.Tunnel(pDoc->GetMesh(),this->vecTestPoint); // this->Tunel.clear(); // OBJHandle::UnitizeCGALPolyhedron(Mesh,false,false); // Mesh.SetRenderInfo(true,true,true,true,true); // } //} else { //do nothing } this->iDrawingCurveType=NONE_SELECTED; this->CurvePoint2D.clear(); }
Point_3 Origin::operator-(const Vector_3& v) const {return Point_3( CGAL::ORIGIN-v.get_data() ); }
void CRSRCellDeform::RSRCellDeform(double dLamda,int iType,int iIterNum,KW_Mesh& Mesh, vector<HandlePointStruct>& vecHandlePoint,vector<Vertex_handle>& vecHandleNb, vector<Vertex_handle>& ROIVertices,vector<Vertex_handle>& vecAnchorVertices, vector<Point_3>& vecDeformCurvePoint3d) { SparseMatrix LaplacianMatrix(vecHandleNb.size()+ROIVertices.size()); CDeformationAlgorithm::ComputeLaplacianMatrix(iType,Mesh,vecHandleNb,ROIVertices,vecAnchorVertices,LaplacianMatrix); SparseMatrix AnchorConstraintMatrix(vecAnchorVertices.size()),HandleConstraintMatrix(vecHandlePoint.size()); CDeformationAlgorithm::GetConstraintsMatrixToNaiveLaplacian(vecHandlePoint,vecHandleNb,ROIVertices,vecAnchorVertices, AnchorConstraintMatrix,HandleConstraintMatrix); SparseMatrix LeftHandMatrixA=LaplacianMatrix; LeftHandMatrixA.insert(LeftHandMatrixA.end(),AnchorConstraintMatrix.begin(),AnchorConstraintMatrix.end()); LeftHandMatrixA.insert(LeftHandMatrixA.end(),HandleConstraintMatrix.begin(),HandleConstraintMatrix.end()); CMath TAUCSSolver; SparseMatrix AT(LeftHandMatrixA.NCols()); TAUCSSolver.TAUCSFactorize(LeftHandMatrixA,AT); //the anchor constraints must keep fixed during iterations,so store them first vector<Point_3> AnchorPosConstraints; for (unsigned int i=0; i<vecAnchorVertices.size(); i++) { AnchorPosConstraints.push_back(vecAnchorVertices.at(i)->point()); } for (int iCurrent=0; iCurrent<=iIterNum; iCurrent++) { vector<vector<double> > LaplacianRightHandSide,AnchorRightHandSide,HandleRightHandSide; if (iCurrent==0) { CDeformationAlgorithm::BackUpEdgeVectorsForRigidDeform(Mesh,vecHandleNb,ROIVertices,vecAnchorVertices); CDeformationAlgorithm::ComputeNaiveLaplacianRightHandSide(iType,vecHandleNb,ROIVertices,vecAnchorVertices, vecDeformCurvePoint3d,LaplacianRightHandSide,AnchorRightHandSide,HandleRightHandSide); } else { ComputeRSRRightHandSide(dLamda,iType,vecHandleNb,ROIVertices,AnchorPosConstraints,//vecAnchorVertices, vecDeformCurvePoint3d,LaplacianRightHandSide,AnchorRightHandSide,HandleRightHandSide); } vector<vector<double> > RightHandSide=LaplacianRightHandSide; for (int i=0; i<3; i++) { RightHandSide.at(i).insert(RightHandSide.at(i).end(),AnchorRightHandSide.at(i).begin(), AnchorRightHandSide.at(i).end()); RightHandSide.at(i).insert(RightHandSide.at(i).end(),HandleRightHandSide.at(i).begin(), HandleRightHandSide.at(i).end()); } vector<vector<double> > Result; // bool bResult=CMath::ComputeLSE(LeftHandMatrixA,RightHandSide,Result); bool bResult=TAUCSSolver.TAUCSComputeLSE(AT,RightHandSide,Result); if (bResult) { //vecDeformCurvePoint3d.clear(); //calculated result of handle for (unsigned int i=0; i<vecHandleNb.size(); i++) { vecHandleNb.at(i)->point()=Point_3(Result.at(0).at(i),Result.at(1).at(i),Result.at(2).at(i)); } //calculated result of ROI for (unsigned int i=0; i<ROIVertices.size(); i++) { ROIVertices.at(i)->point()=Point_3(Result.at(0).at(vecHandleNb.size()+i), Result.at(1).at(vecHandleNb.size()+i), Result.at(2).at(vecHandleNb.size()+i)); } //calculated result of anchor for (unsigned int i=0; i<vecAnchorVertices.size(); i++) { vecAnchorVertices.at(i)->point()=Point_3(Result.at(0).at(vecHandleNb.size()+ROIVertices.size()+i), Result.at(1).at(vecHandleNb.size()+ROIVertices.size()+i), Result.at(2).at(vecHandleNb.size()+ROIVertices.size()+i)); } } //compute Rotation for Handle+ROI+Anchor if (iCurrent!=iIterNum) { CDeformationAlgorithm::ComputeRotationForRigidDeform(iType,Mesh,vecHandleNb,ROIVertices,vecAnchorVertices); ComputeScaleFactor(iType,Mesh,vecHandleNb,ROIVertices,vecAnchorVertices); CDeformationAlgorithm::ComputeSecondRotationForRigidDeform(iType,Mesh,vecHandleNb,ROIVertices,vecAnchorVertices); ComputeRSRMatrixForDeform(Mesh,vecHandleNb,ROIVertices,vecAnchorVertices); } } TAUCSSolver.TAUCSClear(); }
/* FIXME: Copied from Polyhedron_io.cpp with slight modifications. */ static std::shared_ptr<Polyhedron> convertWithAssociation(Polyhedron_3 p, const Point_3 &C, const std::vector<Plane_3> &initPlanes) { /* Check for non-emptiness. */ ASSERT(p.size_of_vertices()); ASSERT(p.size_of_facets()); int numVertices = p.size_of_vertices(); int numFacets = p.size_of_facets(); /* Allocate memory for arrays. */ Vector3d *vertices = new Vector3d[numVertices]; Facet *facets = new Facet[numFacets]; /* Transform vertexes. */ int iVertex = 0; for (auto vertex = p.vertices_begin(); vertex != p.vertices_end(); ++vertex) { Point_3 point = C + vertex->point(); vertices[iVertex++] = Vector3d(point.x(), point.y(), point.z()); } /* * Transform facets. * This algorithm is based on example kindly provided at CGAL online user * manual. See example Polyhedron/polyhedron_prog_off.cpp */ int iFacet = 0; auto plane = p.planes_begin(); auto facet = p.facets_begin(); /* Iterate through the std::lists of planes and facets. */ do { int id = p.indexPlanes_[iFacet]; facets[id].id = id; /* Transform current plane. */ Plane_3 pi = centerizePlane(*plane, Point_3(-C.x(), -C.y(), -C.z()), signedDist(initPlanes[id], C)); facets[id].plane = Plane(Vector3d(pi.a(), pi.b(), pi.c()), pi.d()); /* * Iterate through the std::list of halfedges incident to the curent CGAL * facet. */ auto halfedge = facet->facet_begin(); /* Facets in polyhedral surfaces are at least triangles. */ CGAL_assertion(CGAL::circulator_size(halfedge) >= 3); facets[id].numVertices = CGAL::circulator_size(halfedge); facets[id].indVertices = new int[3 * facets[id].numVertices + 1]; /* * TODO: It's too unsafe architecture if we do such things as setting * the size of internal array outside the API functions. Moreover, it * can cause us to write memory leaks. * indFacets and numFacets should no be public members. */ int iFacetVertex = 0; do { facets[id].indVertices[iFacetVertex++] = std::distance(p.vertices_begin(), halfedge->vertex()); } while (++halfedge != facet->facet_begin()); /* Add cycling vertex to avoid assertion during printing. */ facets[id].indVertices[facets[id].numVertices] = facets[id].indVertices[0]; ASSERT(facets[id].correctPlane()); /* Increment the ID of facet. */ ++iFacet; } while (++plane != p.planes_end() && ++facet != p.facets_end()); return std::make_shared<Polyhedron>(numVertices, numFacets, vertices, facets); }
// Calcule une moyenne de deux points Point_3 DegradeAnObject::meanPoints(Point_3 p1, Point_3 p2) { Point_3 pt(p2.x() + p1.x(), p2.y() + p1.y(), p2.z() + p1.z()); pt = Point_3(pt.x()/2, pt.y()/2, pt.z()/2); return pt; }
void Ctr2SufManager::ctr2sufProc(vector<vector<Point_3> >& MeshBoundingProfile3D,vector<Point_3>& vecTestPoint) { clock_t start = clock(); struct __timeb64 timebuffer; char *timeline; _ftime64( &timebuffer ); timeline = _ctime64( & ( timebuffer.time ) ); printf( "The time is %.19s.%hu %s", timeline, timebuffer.millitm, &timeline[20] ); //common line case //compute the common line if( isComnCase ) { float tempparam[ 8 ]; for( int i = 0; i < 8; i ++) { tempparam[ i ] = pparam[ i ]; } ////////////////////////////////////////////////////////////////////////// /*for( int i = 0 ; i < 8; i ++ ) { cout<<tempparam[ i ]<<","; } cout<<endl;*/ ////////////////////////////////////////////////////////////////////////// computeComnLine( tempparam, tempparam + 4, comndir, comnpt); ////////////////////////////////////////////////////////////////////////// /*for( int i = 0 ; i < 8; i ++ ) { cout<<tempparam[ i ]<<","; } cout<<endl;*/ ////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////// //writeComnLineDB( tempparam, tempparam + 4, comndir, comnpt); ////////////////////////////////////////////////////////////////////////// } ////////////////////////////////////////////////////////////////////////// /*for( int i = 0; i < planenum + 4; i ++ ) { cout<<pparam[ 4* i ]<<"," <<pparam[ 4*i + 1]<<"," <<pparam[ 4*i + 2]<<"," <<pparam[ 4*i + 3]<<endl; } cout<<endl;*/ ////////////////////////////////////////////////////////////////////////// //preprocess data first int** pctrvermark; if( !ispreproced || isComnCase) { pctrvermark = preProcData(isComnCase); //reset showcontourvers for( int i = 0; i < showplanenum; i ++) delete []showctrvers[ i ]; delete []showctrvers; //copy the data from processed data, and reset size showplanenum = planenum; showctrvers = new float*[ showplanenum ]; showctredgenum = new int[ showplanenum ]; showctredges = new int*[ showplanenum ]; for( int i = 0; i < showplanenum; i++ ) { int versize = pctrvernum[ i ]*3; showctrvers[ i ] = new float[ versize ]; for( int j = 0 ; j < versize; j ++ ) showctrvers[ i ][ j ] = pctrvers[ i ][ j ]*DIM/PROCSIZE; showctredgenum[ i ] = pctredgenum[ i ]; int edgesize = pctredgenum[ i ] * 2; showctredges[ i ] = new int[ edgesize ]; for( int j = 0; j < showctredgenum[ i ]; j ++) { showctredges[ i ][ 2*j ] = pctredges[ i ][ 4*j ]; showctredges[ i ][ 2*j + 1 ] = pctredges[ i ][ 4*j + 1]; } } for( int i = 0; i < planenum; i ++) { int iVerIndBase=0; vector<Point_3> CurrentProfile3D; for( int j = 0;j < showctredgenum[ i ]; j++) { int v1 = showctredges[ i ][ 2*j ]; int v2 = showctredges[ i ][ 2*j + 1 ]; CurrentProfile3D.push_back(Point_3(showctrvers[ i ][ v1* 3], showctrvers[ i ][ v1* 3+1], showctrvers[ i ][ v1* 3+2])); if (v2==iVerIndBase) { iVerIndBase=iVerIndBase+CurrentProfile3D.size(); MeshBoundingProfile3D.push_back(CurrentProfile3D); CurrentProfile3D.clear(); } } } //for( int i = 0; i < planenum; i ++) //{ // vector<Point_3> CurrentProfile3D; // for( int j = 0;j < showctredgenum[ i ]; j++) // { // int v1 = showctredges[ i ][ 2*j ]; // glVertex3fv( &showctrvers[ i ][ v1* 3] ); // CurrentProfile3D.push_back(Point_3(showctrvers[ i ][ v1* 3], // showctrvers[ i ][ v1* 3+1], // showctrvers[ i ][ v1* 3+2])); // } // MeshBoundingProfile3D.push_back(CurrentProfile3D); //} } ////////////////////////////////////////////////////////////////////////// //for( int i = 0; i < planenum + 4; i ++ ) //{ // cout<<pparam[ 4* i ]<<"," // <<pparam[ 4*i + 1]<<"," // <<pparam[ 4*i + 2]<<"," // <<pparam[ 4*i + 3]<<endl; //} //cout<<endl; ////////////////////////////////////////////////////////////////////////// //partition // cout<<"------------------ PARTITION ------------------"<<endl; // cout<<"Starting............"<<endl; partition(); ///////////////////////////////////////////////////////////B/////////////// /*writePartitionOut("mmdebug/partition.txt");*/ ////////////////////////////////////////////////////////////////////////// // cout<<"DONE!"<<endl<<endl; //process data // cout<<"------------------ PUT CONTOUR INTO FACE ------------------"<<endl; putContourIntoFace( pctrvermark ); //SaveCtr2FaceInfo(); if( isComnCase ) { for( int i = 0; i < planenum; i ++ ) delete []pctrvermark[ i ]; delete []pctrvermark; } ////////////////////////////////////////////////////////////////////////// // ContourHandler::writeContourInFace( ssfacenum, ctrfvernum, ctrfverpos, ctrfvertype, // ctrfverval, ctrfedgenum, ctrfedge, ctrfedgetype, ctrfedgeval ); ////////////////////////////////////////////////////////////////////////// // cout<<"DONE!"<<endl<<endl; //go through each subspace to generate mesh // cout<<"-------- GENERATING MESH IN EACH SUBSPACE ------------"<<endl; //kw noted: vertices, edges and faces in each subspace //stitch them together finally floatvector* subMeshVer; intvector* subMeshEdge; intvector* subMeshFace; subMeshVer = new floatvector[ ssspacenum ]; subMeshEdge = new intvector[ ssspacenum ]; subMeshFace = new intvector[ ssspacenum ]; //initialize registration informaiton for stitching sverreg = new intvector[ ssvernum ]; sedgereg = new vector<intvector>[ ssedgenum ]; sedgesubedgemark = new intvector[ ssedgenum ]; sfacectrei = new intset[ ssfacenum ]; sfacespaci = new int[ ssfacenum * 2 ]; sfaceregface = new vector<intvector>[ ssfacenum ]; sfaceregver = new intvector[ ssfacenum ]; sfaceregedgever = new intvector[ ssfacenum ]; for( int i = 0; i < ssfacenum*2; i ++) { sfacespaci[ i ] = -1; } for( int spacei = 0; spacei < ssspacenum; spacei ++) { for( int facej = 0; facej < ssspacefacenum[ spacei ]; facej ++) { int facei = ssspace[ spacei ][ facej ]; if( sfacespaci[ 2 * facei ] == -1) sfacespaci[ 2 * facei ] = spacei; else sfacespaci[ 2*facei + 1 ] = spacei; } } ////////////////////////////////////////////////////////////////////////// /*ancestorlist.resize( ssfacenum * 2 ); ancestorlist_split.resize( ssfacenum * 2 );*/ ////////////////////////////////////////////////////////////////////////// //return; dbSpaceNum = ssspacenum; if( dbOneSpaceMode ) { if( dbCurSpace < dbSpaceNum ) { ctr2sufSubspaceProc( dbCurSpace, subMeshVer[ dbCurSpace ], subMeshEdge[ dbCurSpace ], subMeshFace[ dbCurSpace ]); //submeshedge is useless for stitching! subMeshEdge[ dbCurSpace ].clear(); } } //kw: here can use multi-thread to compute each submesh in parallel else{ // for( int i = 7; i< 8; i ++) for( int i = 0; i < ssspacenum; i ++) // for( int i = 2; i < 3; i ++) // for( int i = 54; i < 55; i ++) // for(int i = 0; i < 12; i ++) // for( int i = 14; i < 15; i ++) { cout<<"--- subspace " << i <<endl; ctr2sufSubspaceProc( i, subMeshVer[ i ], subMeshEdge[ i ], subMeshFace[ i ]); //submeshedge is useless for stitching! subMeshEdge[ i ].clear(); } } delete []subMeshEdge; ////////////////////////////////////////////////////////////////////////// //cout<<"before splitting, ancestors:"<<endl; //for( int i = 0; i < ssfacenum*2; i +=2 ) //{ // if( ancestorlist[ i ].size() == 0 ) // { // if( ancestorlist[ i + 1].size() == 0 ) // continue; // } // intset::iterator iter = ancestorlist[ i ].begin(); //// intset::iterator iter2 = ancestorlist[ i + 1].begin(); // while( iter != ancestorlist[ i ].end() ) // { // cout<<*iter<<" "; // iter++; // } // cout<<endl; // iter = ancestorlist[ i+1 ].begin(); // while( iter != ancestorlist[ i + 1 ].end() ) // { // cout<<*iter <<" "; // iter ++; // } // cout<<endl; // cout<<"\n"; //} //cout<<"=============================\n"; //cout<<"after splitting ancestors:"<<endl; //for( int i= 0; i < ssfacenum*2; i += 2 ) //{ // if( ancestorlist_split[ i ].size() == 0 ) // { // if( ancestorlist_split[ i + 1].size() == 0) // continue; // } // intset::iterator iter = ancestorlist_split[ i ].begin(); // while( iter != ancestorlist_split[ i ].end() ) // { // cout<<*iter <<" "; // iter++; // // cout<<endl; // } // cout<<endl; // iter = ancestorlist_split[ i + 1].begin(); // while( iter != ancestorlist_split[ i + 1].end() ) // { // cout<<*iter <<" "; // iter ++; // } // cout<<endl<<endl; //} ////////////////////////////////////////////////////////////////////////// //cout the faces registered on the contour edges /*for( int i = 0; i < ssfacenum; i ++ ) { int ctrnum = sfaceregface[ i ].size()/2; if( ctrnum == 0 ) continue; intset::iterator iter = ancestorlist_split[2* i ].begin(); for( int j = 0; j < ctrnum; j ++ ) { cout<<"("<<*iter<<":"<<sfaceregface[ i ][ 2*j ] .size()<<","<< sfaceregface[ i ][ 2*j +1 ].size()<<") "; iter++; } cout<<endl; }*/ ////////////////////////////////////////////////////////////////////////// //for( int i = 0; i < ssfacenum; i ++) //{ // ancestorlist[ i].clear(); // ancestorlist_split[ i ].clear(); //} //ancestorlist_split.clear(); //ancestorlist.clear(); ////////////////////////////////////////////////////////////////////////// //stitch all the subspaces together stitchMesh(subMeshVer,subMeshFace); clock_t endt = clock(); cout<<"time difference is:"<<endt - start<<endl; // struct __timeb64 timebuffer; // char *timeline; _ftime64( &timebuffer ); timeline = _ctime64( & ( timebuffer.time ) ); printf( "The time is %.19s.%hu %s", timeline, timebuffer.millitm, &timeline[20] ); // FaceGenerator::writeSubMeshOut( mver, mface, 99); //clear all the allocated space //for( int i = 0; i < ssspacenum; i ++) //{ // //subMeshVer[ i ].clear(); //// subMeshEdge[ i ].clear(); // subMeshFace[ i ].clear(); //} ////delete []subMeshVer; ////delete []subMeshEdge; //delete []subMeshFace; /*subMeshFace = NULL; subMeshVer = NULL;*/ //clear the registration information for subspace vertex, edge and face //sverreg for( int i = 0; i < ssvernum; i ++) sverreg[ i ].clear(); delete []sverreg; sverreg = NULL; //sedgereg for( int i= 0; i < ssedgenum; i ++) { for(unsigned int j = 0; j < sedgereg[ i ].size(); j ++) sedgereg[ i ][ j ].clear(); sedgereg[ i ].clear(); } delete []sedgereg; sedgereg = NULL; //sfacectrei, sfacespaci, sfaceregface, sfaceregver for( int i= 0; i < ssfacenum; i ++) { sfacectrei[ i ].clear(); // for( int j = 0; j < sfaceregface[ i ].size(); j ++ ) // sfaceregface[ i ][ j ].clear(); // sfaceregface[ i ].clear(); sfaceregver[ i ].clear(); } delete []sfacectrei; delete []sfacespaci; //delete []sfaceregface; delete []sfaceregver; sfacectrei = NULL; sfacespaci = NULL; //sfaceregface = NULL; sfaceregver = NULL; //set the mesh //clear if( mesh!= NULL ) delete mesh; //set mesh = new Mesh( mver, mface, ctrmedge, center, unitlen, PROCSIZE ); ////kw: get constrained vertices //set<int> ConstrVer; //for (unsigned int i=0;i<ctrmedge.size();i++) //{ // ConstrVer.insert(ctrmedge.at(i)); //} //for (set<int>::iterator SetIter=ConstrVer.begin();SetIter!=ConstrVer.end();SetIter++) //{ // vecTestPoint.push_back(Point_3(mver.at(3*(*SetIter))*DIM/PROCSIZE,mver.at(3*(*SetIter)+1)*DIM/PROCSIZE, // mver.at(3*(*SetIter)+2)*DIM/PROCSIZE)); //} mesh->setGLParam( width, height, nearplane, farplane); //clear mver.clear(); mface.clear(); ctrmedge.clear(); }
void Polyhedron_triangulation::extract_CAT() { std::for_each(cat_cells.begin(), cat_cells.end(), std::mem_fun_ref(&std::list<CAT_facet>::clear)); int *tetra_vtx_ptr = tetra_mesh.tetrahedronlist; int *marker = tetra_mesh.pointmarkerlist; REAL *pnt_tbl = tetra_mesh.pointlist; std::function<Point_3(int)> cgal_pnt = [=](int idx) { return Point_3(pnt_tbl[idx*3], pnt_tbl[idx*3+1], pnt_tbl[idx*3+2]); }; for (int i = 0; i < tetra_mesh.numberoftetrahedra; i++, tetra_vtx_ptr += 4) { std::set<int> group_no; std::multimap<int, int> group_no_vidx; typedef std::multimap<int, int>::const_iterator Iter; for (int j = 0; j < 4; j++) { int vid = tetra_vtx_ptr[j]; int gid = marker[vid]; group_no.insert(gid); group_no_vidx.insert(std::make_pair(gid, vid)); } if (group_no.size() == 2) { std::set<int>::const_iterator gid0 = group_no.begin(), gid1 = group_no.begin(); ++gid1; if (group_no_vidx.count(*gid0) == 1 && group_no_vidx.count(*gid1) == 3) { std::pair<Iter, Iter> i0 = group_no_vidx.equal_range(*gid0); std::pair<Iter, Iter> i1 = group_no_vidx.equal_range(*gid1); std::list<Point_3> mid_tri; for (Iter it = i1.first; it != i1.second; ++it) mid_tri.push_back(CGAL::midpoint(cgal_pnt(i0.first->second), cgal_pnt(it->second))); if (*gid0 >= 0) cat_cells[*gid0].push_back(CAT_facet(cgal_pnt(i0.first->second), mid_tri)); if (*gid1 >= 0) for (Iter it = i1.first; it != i1.second; ++it) cat_cells[*gid1].push_back(CAT_facet(cgal_pnt(it->second), mid_tri)); } else if (group_no_vidx.count(*gid0) == 3 && group_no_vidx.count(*gid1) == 1) { std::pair<Iter, Iter> i0 = group_no_vidx.equal_range(*gid0); std::pair<Iter, Iter> i1 = group_no_vidx.equal_range(*gid1); std::list<Point_3> mid_tri; for (Iter it = i0.first; it != i0.second; ++it) mid_tri.push_back(CGAL::midpoint(cgal_pnt(i1.first->second), cgal_pnt(it->second))); if (*gid1 >= 0) cat_cells[*gid1].push_back(CAT_facet(cgal_pnt(i1.first->second), mid_tri)); if (*gid0 >= 0) for (Iter it = i0.first; it != i0.second; ++it) cat_cells[*gid0].push_back(CAT_facet(cgal_pnt(it->second), mid_tri)); } else { std::pair<Iter, Iter> i0 = group_no_vidx.equal_range(*gid0); std::pair<Iter, Iter> i1 = group_no_vidx.equal_range(*gid1); Iter it = i0.first; Point_3 p00(cgal_pnt(it->second)); ++it; Point_3 p01(cgal_pnt(it->second)); it = i1.first; Point_3 p10(cgal_pnt(it->second)); ++it; Point_3 p11(cgal_pnt(it->second)); Point_3 midpnt[4] = {CGAL::midpoint(p00, p10), CGAL::midpoint(p00, p11), CGAL::midpoint(p01, p10), CGAL::midpoint(p01, p11)}; std::list<Point_3> mid_pm; // the middle parallelogram mid_pm.push_back(midpnt[0]); mid_pm.push_back(midpnt[1]); if (Vector_3(midpnt[0], midpnt[1])*Vector_3(midpnt[2], midpnt[3]) < 0) { mid_pm.push_back(midpnt[2]); mid_pm.push_back(midpnt[3]); } else { mid_pm.push_back(midpnt[3]); mid_pm.push_back(midpnt[2]); } if (*gid0 >= 0) { cat_cells[*gid0].push_back(CAT_facet(p00, mid_pm)); cat_cells[*gid0].push_back(CAT_facet(p01, mid_pm)); } if (*gid1 >= 0) { cat_cells[*gid1].push_back(CAT_facet(p10, mid_pm)); cat_cells[*gid1].push_back(CAT_facet(p11, mid_pm)); } } } else if (group_no.size() == 3) { // the two vertices in the same group int smgp[2]; // the two vertices in the other two different groups int dfgp[2]; int gi, gj, gk; std::vector< std::pair<int, int> > tmpv(group_no_vidx.begin(), group_no_vidx.end()); if (tmpv[0].first == tmpv[1].first) { smgp[0] = tmpv[0].second; smgp[1] = tmpv[1].second; gi = tmpv[0].first; dfgp[0] = tmpv[2].second; dfgp[1] = tmpv[3].second; gj = tmpv[2].first; gk = tmpv[3].first; } else if (tmpv[1].first == tmpv[2].first) { smgp[0] = tmpv[1].second; smgp[1] = tmpv[2].second; gi = tmpv[1].first; dfgp[0] = tmpv[0].second; dfgp[1] = tmpv[3].second; gj = tmpv[0].first; gk = tmpv[3].first; } else { smgp[0] = tmpv[2].second; smgp[1] = tmpv[3].second; gi = tmpv[2].first; dfgp[0] = tmpv[0].second; dfgp[1] = tmpv[1].second; gj = tmpv[0].first; gk = tmpv[1].first; } Point_3 pi[2] = {cgal_pnt(smgp[0]), cgal_pnt(smgp[1])}; Point_3 pj(cgal_pnt(dfgp[0])), pk(cgal_pnt(dfgp[1])); Point_3 tri_cent[2] = {CGAL::centroid(pi[0], pj, pk), CGAL::centroid(pi[1], pj, pk)}; Point_3 edge_mid[5] = {CGAL::midpoint(pi[0], pj), CGAL::midpoint(pi[0], pk), CGAL::midpoint(pi[1], pj), CGAL::midpoint(pi[1], pk), CGAL::midpoint(pj, pk)}; //std::list<Point_3> quad_i0i1j, quad_i0i1k, tri_i0i1jk; std::array<Point_3, 4> quad_i0i1j = {edge_mid[0], edge_mid[2], tri_cent[1], tri_cent[0]}; std::array<Point_3, 4> quad_i0i1k = {edge_mid[1], edge_mid[3], tri_cent[1], tri_cent[0]}; std::array<Point_3, 3> tri_i0i1jk = {edge_mid[4], tri_cent[1], tri_cent[0]}; if (gi >= 0) { cat_cells[gi].push_back(CAT_facet(pi[0], quad_i0i1j.begin(), quad_i0i1j.end())); cat_cells[gi].push_back(CAT_facet(pi[0], quad_i0i1k.begin(), quad_i0i1k.end())); cat_cells[gi].push_back(CAT_facet(pi[1], quad_i0i1j.begin(), quad_i0i1j.end())); cat_cells[gi].push_back(CAT_facet(pi[1], quad_i0i1k.begin(), quad_i0i1k.end())); } if (gj >= 0) { cat_cells[gj].push_back(CAT_facet(pj, quad_i0i1j.begin(), quad_i0i1j.end())); cat_cells[gj].push_back(CAT_facet(pj, tri_i0i1jk.begin(), tri_i0i1jk.end())); } if (gk >= 0) { cat_cells[gk].push_back(CAT_facet(pk, quad_i0i1k.begin(), quad_i0i1k.end())); cat_cells[gk].push_back(CAT_facet(pk, tri_i0i1jk.begin(), tri_i0i1jk.end())); } } else if (group_no.size() == 4) { std::array<Point_3, 4> vs; std::array<int, 4> groupid; for (int j = 0; j < 4; j++) { vs[j] = cgal_pnt(tetra_vtx_ptr[j]); groupid[j] = marker[tetra_vtx_ptr[j]]; } Point_3 tetra_cent = CGAL::centroid(vs.begin(), vs.end(), CGAL::Dimension_tag<0>()); for (int j = 0; j < 4; j++) { if (groupid[j] < 0) continue; for (int k = 0; k < 4; k++) { if (j == k) continue; for (int l = 0; l < 4; l++) { if (l == j || l == k) continue; Point_3 mpnt = CGAL::midpoint(vs[j], vs[k]); int m; for (m = 0; m < 4; m++) if (m != j && m != k && m != l) break; Point_3 tri_cent[2] = { CGAL::centroid(vs[j], vs[k], vs[l]), CGAL::centroid(vs[j], vs[k], vs[m]) }; std::list<Point_3> tri; tri.push_back(mpnt); tri.push_back(tri_cent[0]); tri.push_back(tri_cent[1]); cat_cells[groupid[j]].push_back(CAT_facet(vs[j], tri)); tri.pop_front(); tri.push_back(tetra_cent); cat_cells[groupid[j]].push_back(CAT_facet(vs[j], tri)); } } } } } }
bool MeshEx::findClosestIntersection( const math::Vec3f &position, const math::Vec3f &p1, const math::Vec3f &p2, math::Vec3f &intersection, math::Vec3f &normal, Triangle *&t ) { int count = 0; struct IntersectionHelper { IntersectionHelper( math::Vec3f intersection, Triangle *triangle, float sqDistance ) : m_intersection(intersection), m_triangle(triangle), m_sqDistance(sqDistance) { } // used for sorting bool operator<( const IntersectionHelper &rhs ) { return m_sqDistance < rhs.m_sqDistance; } math::Vec3f m_intersection; // point of intersection Triangle *m_triangle; // triangle in which the intersection point lies float m_sqDistance; // distance to the near point }; std::vector<IntersectionHelper> intersections; // test every triangle (TODO: do some spatial subdivision) for( std::vector<Triangle *>::iterator it = m_triangles.begin(); it != m_triangles.end(); ++it ) { Triangle *tri = *it; Triangle_3 cgalTri( Point_3(tri->v0->position), Point_3(tri->v1->position), Point_3(tri->v2->position) ); Segment_3 seg( Point_3(p1), Point_3(p2) ); if( CGAL::do_intersect( cgalTri, seg ) ) { CGAL::Point_3<K> tempIntersection; CGAL::Object o = CGAL::intersection(CGAL::Plane_3<K>( Point_3(tri->v0->position), Point_3(tri->v1->position), Point_3(tri->v2->position) ), seg); if( CGAL::assign(tempIntersection, o) ) { float sd = CGAL::squared_distance( Point_3(position), tempIntersection ); // intersection results in a point intersections.push_back( IntersectionHelper( math::Vec3f(tempIntersection.x(), tempIntersection.y(), tempIntersection.z()), tri, sd ) ); }else { // segment! printf( "error : intersection during vertex movement is a line\n" ); } //printf( "intersection\n" ); } } // if we have found any intersection if( intersections.size() ) { std::sort( intersections.begin(), intersections.end() ); // find the closest one intersection = intersections[0].m_intersection; t = intersections[0].m_triangle; normal = t->normal; // and indicate success return true; } return false; }
Point_3 xz_swap_neg(const Point_3& p) { return Point_3(p.z(), p.y(), -p.x()); }