float ImplicitMesh::DistanceToPoint(float x, float y, float z, const SimpleMesh & mesh) const{ // just loop over all faces and take the min distance. // uses normals to determine direction and resulting sign (negative inside) std::pair<float, bool> pr((std::numeric_limits<float>::max)(), true); const std::vector<SimpleMesh::Vertex>& verts = mesh.GetVerts(); const std::vector<SimpleMesh::Face>& faces = mesh.GetFaces(); Vector3<float> p(x,y,z); for(unsigned int i=0; i<faces.size(); i++){ const SimpleMesh::Vertex &v1 = verts.at(faces.at(i).v1); const SimpleMesh::Vertex &v2 = verts.at(faces.at(i).v2); const SimpleMesh::Vertex &v3 = verts.at(faces.at(i).v3); std::pair<float, bool> pt = DistanceSquared(p, v1.pos, v2.pos, v3.pos); if(pt.first < pr.first) pr = pt; } pr.first = std::sqrt(pr.first); return pr.first; //pr.second ? pr.first : -pr.first; }
void Implicit::Update() { if (mVisualizationMode == Curvature) { if(typeid(*mMesh) == typeid(SimpleMesh)) { SimpleMesh * ptr = static_cast<SimpleMesh*>(mMesh); std::vector<SimpleMesh::Vertex>& verts = ptr->GetVerts(); Matrix4x4<float> M = GetTransform().Transpose(); // Compute curvature of implicit geometry and assign to the vertex property for(unsigned int i=0; i < verts.size(); i++){ const Vector3<float> vObject = verts.at(i).pos; // Transform vertex position to world space Vector4<float> vWorld = GetTransform() * Vector4<float>(vObject[0],vObject[1],vObject[2],1); // Get curvature in world space verts.at(i).curvature = GetCurvature(vWorld[0], vWorld[1], vWorld[2]); // Get gradient in world space (used for lighting) Vector3<float> nWorld = GetGradient(vWorld[0], vWorld[1], vWorld[2]); // Transform gradient to object space Vector4<float> nObject = M * Vector4<float>(nWorld[0],nWorld[1],nWorld[2],0); verts.at(i).normal = Vector3<float>(nObject[0], nObject[1], nObject[2]).Normalize(); } ptr->mAutoMinMax = mAutoMinMax; ptr->mMinCMap = mMinCMap; ptr->mMaxCMap = mMaxCMap; ptr->SetVisualizationMode(Mesh::CurvatureVertex); ptr->Update(); } else { std::cerr << "No Curvature visualization mode implemented for mesh type: " << typeid(*mMesh).name() << std::endl; } } }
void Implicit::Render() { // Draw bounding box for debugging Bbox b = GetBoundingBox(); Vector3<float> & v0 = b.pMin; Vector3<float> & v1 = b.pMax; if(mSelected) { glLineWidth(2.0f); glColor3f(0.8f,0.8f,0.8f); } else glColor3f(0.1f,0.1f,0.1f); glBegin(GL_LINE_STRIP); glVertex3f(v0[0], v0[1], v0[2]); glVertex3f(v1[0], v0[1], v0[2]); glVertex3f(v1[0], v1[1], v0[2]); glVertex3f(v0[0], v1[1], v0[2]); glVertex3f(v0[0], v0[1], v0[2]); glEnd(); glBegin(GL_LINE_STRIP); glVertex3f(v0[0], v0[1], v1[2]); glVertex3f(v1[0], v0[1], v1[2]); glVertex3f(v1[0], v1[1], v1[2]); glVertex3f(v0[0], v1[1], v1[2]); glVertex3f(v0[0], v0[1], v1[2]); glEnd(); glBegin(GL_LINES); glVertex3f(v0[0], v0[1], v0[2]); glVertex3f(v0[0], v0[1], v1[2]); glVertex3f(v1[0], v0[1], v0[2]); glVertex3f(v1[0], v0[1], v1[2]); glVertex3f(v0[0], v1[1], v0[2]); glVertex3f(v0[0], v1[1], v1[2]); glVertex3f(v1[0], v1[1], v0[2]); glVertex3f(v1[0], v1[1], v1[2]); glEnd(); glLineWidth(1.0f); glPushMatrix(); glMultMatrixf(mTransform.ToGLMatrix().GetArrayPtr()); Geometry * mesh = dynamic_cast<Geometry *>(mMesh); if (mesh == NULL) std::cerr << "Error: implicit geometry not triangulated, add call to triangulate()" << std::endl; else { mesh->SetShowNormals(mShowNormals); mesh->SetWireframe(mWireframe); mesh->SetOpacity(mOpacity); mesh->Render(); } if (mVisualizationMode == Gradients) { if(typeid(*mMesh) == typeid(SimpleMesh)){ SimpleMesh * ptr = static_cast<SimpleMesh*>(mMesh); const std::vector<SimpleMesh::Vertex>& verts = ptr->GetVerts(); glDisable(GL_LIGHTING); Matrix4x4<float> M = GetTransform().Transpose(); glColor3f(0, 0, 1); glBegin(GL_LINES); for(unsigned int i=0; i < verts.size(); i++){ const Vector3<float> vObject = verts.at(i).pos; // Transform vertex position to world space Vector4<float> vWorld = GetTransform() * Vector4<float>(vObject[0],vObject[1],vObject[2],1); // Get gradient in world space Vector3<float> nWorld = GetGradient(vWorld[0], vWorld[1], vWorld[2]); // Transform gradient to object space Vector4<float> nObject = M * Vector4<float>(nWorld[0],nWorld[1],nWorld[2],0); Vector3<float> n = Vector3<float>(nObject[0], nObject[1], nObject[2]); glVertex3fv(vObject.GetArrayPtr()); glVertex3fv((vObject + n*0.1).GetArrayPtr()); } glEnd(); } else { std::cerr << "No Gradient visualization mode implemented for mesh type: " << typeid(*mMesh).name() << std::endl; } } glPopMatrix(); GLObject::Render(); }