|
2 | 2 |
|
3 | 3 | #include "polyscope/surface_mesh.h" |
4 | 4 |
|
5 | | -#include "glm/fwd.hpp" |
6 | 5 | #include "polyscope/combining_hash_functions.h" |
| 6 | +#include "polyscope/elementary_geometry.h" |
7 | 7 | #include "polyscope/pick.h" |
8 | 8 | #include "polyscope/polyscope.h" |
9 | 9 | #include "polyscope/render/engine.h" |
@@ -1170,6 +1170,11 @@ void SurfaceMesh::buildFaceInfoGui(const SurfaceMeshPickResult& result) { |
1170 | 1170 | size_t displayInd = fInd; |
1171 | 1171 | ImGui::TextUnformatted(("Face #" + std::to_string(displayInd)).c_str()); |
1172 | 1172 |
|
| 1173 | + if (result.baryCoords != glm::vec3{-1., -1., -1.}) { |
| 1174 | + ImGui::Text("selected barycoords = <%.3f, %.3f, %.3f>", result.baryCoords.x, result.baryCoords.y, |
| 1175 | + result.baryCoords.z); |
| 1176 | + } |
| 1177 | + |
1173 | 1178 | ImGui::Spacing(); |
1174 | 1179 | ImGui::Spacing(); |
1175 | 1180 | ImGui::Spacing(); |
@@ -1446,18 +1451,40 @@ SurfaceMeshPickResult SurfaceMesh::interpretPickResult(const PickResult& rawResu |
1446 | 1451 | result.index = rawResult.localIndex - facePickIndStart; |
1447 | 1452 |
|
1448 | 1453 | // TODO barycoords |
| 1454 | + size_t D = faceIndsStart[result.index + 1] - faceIndsStart[result.index]; |
| 1455 | + if (D == 3) { |
| 1456 | + |
| 1457 | + // gather values and project onto plane |
| 1458 | + size_t iStart = faceIndsStart[result.index]; |
| 1459 | + uint32_t vA = faceIndsEntries[iStart]; |
| 1460 | + uint32_t vB = faceIndsEntries[iStart + 1]; |
| 1461 | + uint32_t vC = faceIndsEntries[iStart + 2]; |
| 1462 | + glm::vec3 pA = vertexPositions.getValue(vA); |
| 1463 | + glm::vec3 pB = vertexPositions.getValue(vB); |
| 1464 | + glm::vec3 pC = vertexPositions.getValue(vC); |
| 1465 | + glm::vec3 normal = glm::normalize(glm::cross(pB - pA, pC - pA)); |
| 1466 | + glm::vec3 x = projectToPlane(rawResult.position, normal, pA); |
| 1467 | + |
| 1468 | + // compute barycentric coordinates as ratio of signed areas |
| 1469 | + float areaABC = signedTriangleArea(normal, pA, pB, pC); |
| 1470 | + float areaXBC = signedTriangleArea(normal, x, pB, pC); |
| 1471 | + float areaXCA = signedTriangleArea(normal, x, pC, pA); |
| 1472 | + float areaXAB = signedTriangleArea(normal, x, pA, pB); |
| 1473 | + glm::vec3 barycoord{areaXBC / areaABC, areaXCA / areaABC, areaXAB / areaABC}; |
| 1474 | + result.baryCoords = barycoord; |
| 1475 | + } |
| 1476 | + |
1449 | 1477 | } else if (rawResult.localIndex < halfedgePickIndStart) { |
1450 | 1478 | // Edge pick |
1451 | 1479 | result.elementType = MeshElement::EDGE; |
1452 | 1480 | result.index = rawResult.localIndex - edgePickIndStart; |
1453 | 1481 |
|
1454 | | - // TODO tEdge |
| 1482 | + |
1455 | 1483 | } else if (rawResult.localIndex < cornerPickIndStart) { |
1456 | 1484 | // Halfedge pick |
1457 | 1485 | result.elementType = MeshElement::HALFEDGE; |
1458 | 1486 | result.index = rawResult.localIndex - halfedgePickIndStart; |
1459 | 1487 |
|
1460 | | - // TODO tEdge |
1461 | 1488 | } else if (rawResult.localIndex < cornerPickIndStart + nCorners()) { |
1462 | 1489 | // Corner pick |
1463 | 1490 | result.elementType = MeshElement::CORNER; |
|
0 commit comments