{"action":"opened","issue":{"url":"https://api.github.com/repos/embree/embree/issues/174","repository_url":"https://api.github.com/repos/embree/embree","labels_url":"https://api.github.com/repos/embree/embree/issues/174/labels{/name}","comments_url":"https://api.github.com/repos/embree/embree/issues/174/comments","events_url":"https://api.github.com/repos/embree/embree/issues/174/events","html_url":"https://github.com/embree/embree/issues/174","id":299531800,"number":174,"title":"Ray fails to intersect with watertight surface.","user":{"login":"loopless","id":9222687,"avatar_url":"https://avatars3.githubusercontent.com/u/9222687?v=4","gravatar_id":"","url":"https://api.github.com/users/loopless","html_url":"https://github.com/loopless","followers_url":"https://api.github.com/users/loopless/followers","following_url":"https://api.github.com/users/loopless/following{/other_user}","gists_url":"https://api.github.com/users/loopless/gists{/gist_id}","starred_url":"https://api.github.com/users/loopless/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/loopless/subscriptions","organizations_url":"https://api.github.com/users/loopless/orgs","repos_url":"https://api.github.com/users/loopless/repos","events_url":"https://api.github.com/users/loopless/events{/privacy}","received_events_url":"https://api.github.com/users/loopless/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-02-22T22:28:08Z","updated_at":"2018-02-22T22:28:08Z","closed_at":null,"author_association":"NONE","body":"If a ray is cast towards a watertight surface, and the ray would intersect the surface exactly at a \"triangle vertex \", it may not record an intersection.\r\n\r\nThe following illustrates the issue, tested with 2.17.2\r\n\r\nThe fix , as suggested, is to modify the file .\\kernels\\geometry\\triangle_intersector_pluecker.h to include an epsilon\r\n\r\n`          //vbool<M> valid = (minUVW >= 0.0f) | (maxUVW <= 0.0f);\r\n\t\t  const float eps = 1.0e-6;\r\n\t\t  vbool<M> valid = (minUVW >= -eps) | (maxUVW <= eps);\r\n`\r\n\r\n\r\n[half_sphere.txt](https://github.com/embree/embree/files/1749777/half_sphere.txt)\r\n\r\n`// emreee_test.cpp : Defines the entry point for the console application.\r\n//\r\n#include <stdio.h>\r\n#include <map>\r\n#include <vector>\r\n#include <assert.h>\r\n#include \"embree2/rtcore_ray.h\"\r\n#include <iostream>\r\n\r\nstruct Triangle { int v0, v1, v2; };\r\nstruct Vec3fa { float x, y, z, w; };\r\nint main(int argc, char *argv[])\r\n{\r\n\tif (argc > 1) {\r\n\r\n\t\tFILE *f = fopen(argv[1], \"r+\");\r\n\t\tif (f) {\r\n\t\t\tauto rtcdevice = rtcNewDevice(nullptr);\r\n\t\t\tauto rtcscene = rtcDeviceNewScene(rtcdevice, RTC_SCENE_STATIC | RTC_SCENE_ROBUST, RTC_INTERSECT1);\r\n\r\n\t\t\tint nVerts;\r\n\t\t\tfscanf(f, \"%d\", &nVerts);\r\n\t\t\tstd::vector<Vec3fa> verts(nVerts);\r\n\t\t\tstd::map<int, int> lookup;\r\n\t\t\tfor (int i = 0; i < nVerts; i++) {\r\n\t\t\t\tfloat x, y, z;\r\n\t\t\t\tint id;\r\n\t\t\t\tint nScan=fscanf(f, \"%d %f %f %f\",&id, &x, &y, &z);\r\n\t\t\t\tassert(nScan == 4);\r\n\t\t\t\tverts[i].x = x;\r\n\t\t\t\tverts[i].y = y;\r\n\t\t\t\tverts[i].z = z;\r\n\t\t\t\tlookup[id] = i;\r\n\t\t\t}\r\n\t\t\tint nTris;\r\n\t\t\tfscanf(f, \"%d\", &nTris);\r\n\r\n\t\t\tauto rtcmesh = rtcNewTriangleMesh(rtcscene, RTC_GEOMETRY_STATIC, nTris, nVerts);\r\n\t\t\tauto vertices = (Vec3fa*)rtcMapBuffer(rtcscene, rtcmesh, RTC_VERTEX_BUFFER);\r\n\t\t\tauto triangles = (Triangle*)rtcMapBuffer(rtcscene, rtcmesh, RTC_INDEX_BUFFER);\r\n\r\n\t\t\tint node_index = 0;\r\n\t\t\tfor (auto v : verts) {\r\n\t\t\t\tvertices[node_index].x = v.x;\r\n\t\t\t\tvertices[node_index].y = v.y;\r\n\t\t\t\tvertices[node_index].z = v.z;\r\n\t\t\t\tnode_index++;\r\n\t\t\t}\r\n\r\n\t\t\tfor (int tri_index = 0; tri_index < nTris; tri_index++) {\r\n\t\t\t\tint id1,id2,id3;\r\n\t\t\t\tint nScan = fscanf(f, \"%d %d %d\", &id1, &id2, &id3);\r\n\t\t\t\tassert(nScan == 3);\r\n\t\t\t\ttriangles[tri_index].v0 = lookup[id1];\r\n\t\t\t\ttriangles[tri_index].v1 = lookup[id2];\r\n\t\t\t\ttriangles[tri_index].v2 = lookup[id3];\r\n\t\t\t}\r\n\r\n\t\t\trtcUnmapBuffer(rtcscene, rtcmesh, RTC_VERTEX_BUFFER);\r\n\t\t\trtcUnmapBuffer(rtcscene, rtcmesh, RTC_INDEX_BUFFER);\r\n\t\t\trtcCommit(rtcscene);\r\n\r\n\r\n\r\n\t\t\tRTCRay rtc_ray;\r\n\t\t\trtc_ray.tnear = 0;\r\n\t\t\trtc_ray.tfar = 100000;\r\n\t\t\trtc_ray.instID = RTC_INVALID_GEOMETRY_ID;\r\n\t\t\trtc_ray.geomID = RTC_INVALID_GEOMETRY_ID;\r\n\t\t\trtc_ray.primID = RTC_INVALID_GEOMETRY_ID;\r\n\t\t\trtc_ray.mask = 0xFFFFFFFF;\r\n\t\t\trtc_ray.time = 0.0f;\r\n\t\t\trtc_ray.org[0] = 0;\r\n\t\t\trtc_ray.org[1] = 0;\r\n\t\t\trtc_ray.org[2] = 0;\r\n\t\t\t//Direction -0.000000028097142    0.642787635000000    0.766044438000000\r\n\t\t\trtc_ray.dir[0] = -0.000000028097142;\r\n\t\t\trtc_ray.dir[1] = 0.642787635000000;\r\n\t\t\trtc_ray.dir[2] = 0.766044438000000;\r\n\t\t\trtcIntersect(rtcscene, rtc_ray);\r\n\t\t\tbool hitSomething = rtc_ray.primID != RTC_INVALID_GEOMETRY_ID;\r\n\t\t\tif(hitSomething){\r\n\t\t\t\tstd::cout << \"Ray hit \" << rtc_ray.primID << std::endl;\r\n\t\t\t}else{\r\n\t\t\t\tstd::cout << \"Ray missed \" << std::endl;\r\n\t\t\t}\r\n\r\n\t\t\trtcDeleteScene(rtcscene);\r\n\t\t\trtcDeleteDevice(rtcdevice);\r\n\t\t}\r\n\r\n\t}\r\n}\r\n\r\n`"}}
{"actor":{"display_login":"loopless"}}