void CSmoothingAlgorithm::BilateralSmooth(KW_Mesh& Mesh,vector<Vertex_handle>& vecVertexToSmooth,double dSigmaC,double dKernelSize,double dSigmaS,int iNormalRingNum) { //calculate the normal,just one-ring involved at present OBJHandle::UnitizeCGALPolyhedron(Mesh,false,false); if (dSigmaC==0) { dSigmaC=0.05; dKernelSize=dSigmaC*2; } assert(dKernelSize==2*dSigmaC); vector<Point_3> vecNewPos; for (unsigned int iVertex=0;iVertex<vecVertexToSmooth.size();iVertex++) { //get kernel vertices and their distances to the current vertex vector<Vertex_handle> vecKernelVertex; vector<double> vecDistance; GetKernelVertex(Mesh,vecVertexToSmooth.at(iVertex),dKernelSize,vecKernelVertex,vecDistance); //get offsets and derivation vector<double> vecOffset; GetOffsets(vecVertexToSmooth.at(iVertex),vecKernelVertex,vecOffset); double dDerivation=GeometryAlgorithm::GetDerivation(vecOffset); dSigmaS=dDerivation; //compute new positions double dSum,dNormalizer; dSum=dNormalizer=0; for (unsigned int iKernelVertex=0;iKernelVertex<vecKernelVertex.size();iKernelVertex++) { double dWC=exp(-vecDistance.at(iKernelVertex)*vecDistance.at(iKernelVertex)/(2*dSigmaC*dSigmaC)); double dWS=exp(-vecOffset.at(iKernelVertex)*vecOffset.at(iKernelVertex)/(2*dSigmaS*dSigmaS)); dSum=dSum+dWC*dWS*vecOffset.at(iKernelVertex); dNormalizer=dNormalizer+dWC*dWS; } Vector_3 VectorToMove=vecVertexToSmooth.at(iVertex)->normal()*(dSum/dNormalizer); if (dSum==0) { VectorToMove=Vector_3(0,0,0); } //DBWindowWrite("vertex: %d VectorToMove: %f %f %f\n",iVertex,VectorToMove.x(),VectorToMove.y(),VectorToMove.z()); Point_3 NewPos=vecVertexToSmooth.at(iVertex)->point()+VectorToMove; vecNewPos.push_back(NewPos); } //update vertex position for (unsigned int i=0;i<vecNewPos.size();i++) { //DBWindowWrite("old pos: %f %f %f\n",vecVertexToSmooth.at(i)->point().x(),vecVertexToSmooth.at(i)->point().y(),vecVertexToSmooth.at(i)->point().z()); //DBWindowWrite("new pos: %f %f %f\n",vecNewPos.at(i).x(),vecNewPos.at(i).y(),vecNewPos.at(i).z()); vecVertexToSmooth.at(i)->point()=vecNewPos.at(i); } OBJHandle::UnitizeCGALPolyhedron(Mesh,false,false); Mesh.SetRenderInfo(true,true,false,false,false); }
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(); }