OCCT 8.0 Update Part 2

This commit is contained in:
Frozen Forest Reality Technologies
2026-06-24 18:58:26 +03:00
committed by Thomas Krijnen
parent 6318610bdb
commit 81f71e6418
23 changed files with 231 additions and 207 deletions
+62 -62
View File
@@ -43,7 +43,7 @@ bool is_intersect_ray_box(const struct ray *ray, const struct box *box) {
// More reading: https://en.wikipedia.org/wiki/M%C3%B6ller%E2%80%93Trumbore_intersection_algorithm
bool intersectRayTriangle( const gp_Vec& orig, const gp_Vec& dir,
const gp_Vec& vert0, const gp_Vec& vert1, const gp_Vec& vert2,
Standard_Real& at, Standard_Real& au, Standard_Real& av,
double& at, double& au, double& av,
bool cull, float enlarge) {
// Find vectors for two edges sharing vert0
const gp_Vec edge1 = vert1 - vert0;
@@ -53,7 +53,7 @@ bool intersectRayTriangle( const gp_Vec& orig, const gp_Vec& dir,
const gp_Vec pvec = dir.Crossed(edge2); // error ~ |v2-v0|
// If determinant is near zero, ray lies in plane of triangle
const Standard_Real det = edge1.Dot(pvec); // error ~ |v2-v0|*|v1-v0|
const double det = edge1.Dot(pvec); // error ~ |v2-v0|*|v1-v0|
if(cull)
{
@@ -64,11 +64,11 @@ bool intersectRayTriangle( const gp_Vec& orig, const gp_Vec& dir,
const gp_Vec tvec = orig - vert0;
// Calculate U parameter and test bounds
const Standard_Real u = tvec.Dot(pvec);
const double u = tvec.Dot(pvec);
const Standard_Real enlargeCoeff = enlarge*det;
const Standard_Real uvlimit = -enlargeCoeff;
const Standard_Real uvlimit2 = det + enlargeCoeff;
const double enlargeCoeff = enlarge*det;
const double uvlimit = -enlargeCoeff;
const double uvlimit2 = det + enlargeCoeff;
if(u<uvlimit || u>uvlimit2)
return false;
@@ -77,14 +77,14 @@ bool intersectRayTriangle( const gp_Vec& orig, const gp_Vec& dir,
const gp_Vec qvec = tvec.Crossed(edge1);
// Calculate V parameter and test bounds
const Standard_Real v = dir.Dot(qvec);
const double v = dir.Dot(qvec);
if(v<uvlimit || (u+v)>uvlimit2)
return false;
// Calculate t, scale parameters, ray intersects triangle
const Standard_Real t = edge2.Dot(qvec);
const double t = edge2.Dot(qvec);
const Standard_Real inv_det = 1.0f / det;
const double inv_det = 1.0f / det;
at = t*inv_det;
au = u*inv_det;
av = v*inv_det;
@@ -95,26 +95,26 @@ bool intersectRayTriangle( const gp_Vec& orig, const gp_Vec& dir,
if(std::abs(det)<GU_CULLING_EPSILON_RAY_TRIANGLE)
return false;
const Standard_Real inv_det = 1.0f / det;
const double inv_det = 1.0 / det;
// Calculate distance from vert0 to ray origin
const gp_Vec tvec = orig - vert0; // error ~ |orig-v0|
// Calculate U parameter and test bounds
const Standard_Real u = tvec.Dot(pvec) * inv_det;
if(u<-enlarge || u>1.0f+enlarge)
const double u = tvec.Dot(pvec) * inv_det;
if(u<-enlarge || u>1.0+enlarge)
return false;
// prepare to test V parameter
const gp_Vec qvec = tvec.Crossed(edge1);
// Calculate V parameter and test bounds
const Standard_Real v = dir.Dot(qvec) * inv_det;
if(v<-enlarge || (u+v)>1.0f+enlarge)
const double v = dir.Dot(qvec) * inv_det;
if(v<-enlarge || (u+v)>1.0+enlarge)
return false;
// Calculate t, ray intersects triangle
const Standard_Real t = edge2.Dot(qvec) * inv_det;
const double t = edge2.Dot(qvec) * inv_det;
at = t;
au = u;
@@ -142,45 +142,45 @@ void edgeEdgeDist(gp_Vec& x, gp_Vec& y, // closest points
// u parameterizes ray (q, b)
// Compute t for the closest point on ray (p, a) to ray (q, b)
const Standard_Real Denom = ADotA*BDotB - ADotB*ADotB;
const double Denom = ADotA*BDotB - ADotB*ADotB;
Standard_Real t; // We will clamp result so t is on the segment (p, a)
if(Denom!=0.0f)
double t; // We will clamp result so t is on the segment (p, a)
if(Denom!=0.0)
t = ios_clamp((ADotT*BDotB - BDotT*ADotB) / Denom, 0.0, 1.0);
else
t = 0.0f;
t = 0.0;
// find u for point on ray (q, b) closest to point at t
Standard_Real u;
if(BDotB!=0.0f)
double u;
if(BDotB!=0.0)
{
u = (t*ADotB - BDotT) / BDotB;
// if u is on segment (q, b), t and u correspond to closest points, otherwise, clamp u, recompute and clamp t
if(u<0.0f)
if(u<0.0)
{
u = 0.0f;
if(ADotA!=0.0f)
u = 0.0;
if(ADotA!=0.0)
t = ios_clamp(ADotT / ADotA, 0.0, 1.0);
else
t = 0.0f;
t = 0.0;
}
else if(u > 1.0f)
else if(u > 1.0)
{
u = 1.0f;
if(ADotA!=0.0f)
u = 1.0;
if(ADotA!=0.0)
t = ios_clamp((ADotB + ADotT) / ADotA, 0.0, 1.0);
else
t = 0.0f;
t = 0.0;
}
}
else
{
u = 0.0f;
if(ADotA!=0.0f)
u = 0.0;
if(ADotA!=0.0)
t = ios_clamp(ADotT / ADotA, 0.0, 1.0);
else
t = 0.0f;
t = 0.0;
}
x = p + a * t;
@@ -191,7 +191,7 @@ void edgeEdgeDist(gp_Vec& x, gp_Vec& y, // closest points
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/LICENSE.md
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/physx/source/geomutils/src/distance/GuDistanceTriangleTriangle.cpp
// With minor modifications to use gp_Vec type.
float distanceTriangleTriangleSquared(gp_Vec& cp, gp_Vec& cq, const std::array<gp_Vec, 3> p, const std::array<gp_Vec, 3> q)
double distanceTriangleTriangleSquared(gp_Vec& cp, gp_Vec& cq, const std::array<gp_Vec, 3> p, const std::array<gp_Vec, 3> q)
{
std::array<gp_Vec, 3> Sv;
Sv[0] = p[1] - p[0];
@@ -206,7 +206,7 @@ float distanceTriangleTriangleSquared(gp_Vec& cp, gp_Vec& cq, const std::array<g
gp_Vec minP, minQ;
bool shown_disjoint = false;
float mindd = PX_MAX_F32;
double mindd = PX_MAX_F32;
for(int i=0;i<3;i++)
{
@@ -214,7 +214,7 @@ float distanceTriangleTriangleSquared(gp_Vec& cp, gp_Vec& cq, const std::array<g
{
edgeEdgeDist(cp, cq, p[i], Sv[i], q[j], Tv[j]);
const gp_Vec V = cq - cp;
const float dd = V.Dot(V);
const double dd = V.Dot(V);
if(dd<=mindd)
{
@@ -226,12 +226,12 @@ float distanceTriangleTriangleSquared(gp_Vec& cp, gp_Vec& cq, const std::array<g
if(id>=3)
id-=3;
gp_Vec Z = p[id] - cp;
float a = Z.Dot(V);
double a = Z.Dot(V);
id = j+2;
if(id>=3)
id-=3;
Z = q[id] - cq;
float b = Z.Dot(V);
double b = Z.Dot(V);
if((a<=0.0f) && (b>=0.0f))
return V.Dot(V);
@@ -246,7 +246,7 @@ float distanceTriangleTriangleSquared(gp_Vec& cp, gp_Vec& cq, const std::array<g
}
gp_Vec Sn = Sv[0].Crossed(Sv[1]);
float Snl = Sn.Dot(Sn);
double Snl = Sn.Dot(Sn);
if(Snl>1e-15f)
{
@@ -294,7 +294,7 @@ float distanceTriangleTriangleSquared(gp_Vec& cp, gp_Vec& cq, const std::array<g
}
gp_Vec Tn = Tv[0].Crossed(Tv[1]);
float Tnl = Tn.Dot(Tn);
double Tnl = Tn.Dot(Tn);
if(Tnl>1e-15f)
{
@@ -359,8 +359,8 @@ float distanceTriangleTriangleSquared(gp_Vec& cp, gp_Vec& cq, const std::array<g
namespace {
struct Interval
{
Standard_Real min;
Standard_Real max;
double min;
double max;
gp_Vec minPoint;
gp_Vec maxPoint;
@@ -395,7 +395,7 @@ namespace {
return result;
}
void include(Standard_Real d, const gp_Vec& p)
void include(double d, const gp_Vec& p)
{
if (d < min) { min = d; minPoint = p; }
if (d > max) { max = d; maxPoint = p; }
@@ -407,7 +407,7 @@ namespace {
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/LICENSE.md
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/physx/source/geomutils/src/intersection/GuIntersectionTriangleTriangle.cpp
// With minor modifications to use gp_Vec type.
static Interval computeInterval(Standard_Real distanceA, Standard_Real distanceB, Standard_Real distanceC, const gp_Vec& a, const gp_Vec& b, const gp_Vec& c, const gp_Vec& dir)
static Interval computeInterval(double distanceA, double distanceB, double distanceC, const gp_Vec& a, const gp_Vec& b, const gp_Vec& c, const gp_Vec& dir)
{
Interval i;
@@ -441,7 +441,7 @@ static Interval computeInterval(Standard_Real distanceA, Standard_Real distanceB
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/LICENSE.md
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/physx/source/geomutils/src/intersection/GuIntersectionTriangleTriangle.cpp
// With minor modifications to use gp_Vec type.
Standard_Real orient2d(const gp_Vec& a, const gp_Vec& b, const gp_Vec& c, PxU32 x, PxU32 y)
double orient2d(const gp_Vec& a, const gp_Vec& b, const gp_Vec& c, PxU32 x, PxU32 y)
{
return (a.Coord(y) - c.Coord(y)) * (b.Coord(x) - c.Coord(x)) - (a.Coord(x) - c.Coord(x)) * (b.Coord(y) - c.Coord(y));
}
@@ -450,11 +450,11 @@ Standard_Real orient2d(const gp_Vec& a, const gp_Vec& b, const gp_Vec& c, PxU32
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/LICENSE.md
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/physx/source/geomutils/src/intersection/GuIntersectionTriangleTriangle.cpp
// With minor modifications to use gp_Vec type.
Standard_Real pointInTriangle(const gp_Vec& a, const gp_Vec& b, const gp_Vec& c, const gp_Vec& point, PxU32 x, PxU32 y)
double pointInTriangle(const gp_Vec& a, const gp_Vec& b, const gp_Vec& c, const gp_Vec& point, PxU32 x, PxU32 y)
{
const Standard_Real ab = orient2d(a, b, point, x, y);
const Standard_Real bc = orient2d(b, c, point, x, y);
const Standard_Real ca = orient2d(c, a, point, x, y);
const double ab = orient2d(a, b, point, x, y);
const double bc = orient2d(b, c, point, x, y);
const double ca = orient2d(c, a, point, x, y);
if ((ab >= 0) == (bc >= 0) && (ab >= 0) == (ca >= 0))
return true;
@@ -466,16 +466,16 @@ Standard_Real pointInTriangle(const gp_Vec& a, const gp_Vec& b, const gp_Vec& c,
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/LICENSE.md
// https://github.com/NVIDIA-Omniverse/PhysX/blob/main/physx/source/geomutils/src/intersection/GuIntersectionTriangleTriangle.cpp
// With minor modifications to use gp_Vec type.
Standard_Real linesIntersect(const gp_Vec& startA, const gp_Vec& endA, const gp_Vec& startB, const gp_Vec& endB, PxU32 x, PxU32 y)
double linesIntersect(const gp_Vec& startA, const gp_Vec& endA, const gp_Vec& startB, const gp_Vec& endB, PxU32 x, PxU32 y)
{
const Standard_Real aaS = orient2d(startA, endA, startB, x, y);
const Standard_Real aaE = orient2d(startA, endA, endB, x, y);
const double aaS = orient2d(startA, endA, startB, x, y);
const double aaE = orient2d(startA, endA, endB, x, y);
if ((aaS >= 0) == (aaE >= 0))
return false;
const Standard_Real bbS = orient2d(startB, endB, startA, x, y);
const Standard_Real bbE = orient2d(startB, endB, endA, x, y);
const double bbS = orient2d(startB, endB, startA, x, y);
const double bbE = orient2d(startB, endB, endA, x, y);
if ((bbS >= 0) == (bbE >= 0))
return false;
@@ -521,7 +521,7 @@ bool trianglesIntersectCoplanar(const gp_Vec& p1_n, const gp_Vec& a1, const gp_V
PxU32 y = 0;
getProjectionIndices(p1_n, x, y);
const Standard_Real third = (1.0f / 3.0f);
const double third = (1.0 / 3.0);
//A bit of the computations done inside the following functions could be shared but it's kept simple since the
//difference is not very big and the coplanar case is not expected to be the most common case
@@ -541,14 +541,14 @@ bool trianglesIntersectCoplanar(const gp_Vec& p1_n, const gp_Vec& a1, const gp_V
// Also with minor modification to return intersection points.
bool trianglesIntersect(const gp_Vec& a1, const gp_Vec& b1, const gp_Vec& c1, const gp_Vec& a2, const gp_Vec& b2, const gp_Vec& c2/*, Segment* intersection*/, gp_Vec& int1, gp_Vec& int2, bool ignoreCoplanar)
{
const Standard_Real tolerance = 1e-8f;
const double tolerance = 1e-8f;
gp_Vec p1_n((b1 - a1).Crossed(c1 - a1).Normalized());
double p1_d = -a1.Dot(p1_n);
// const PxPlane p1(a1, b1, c1);
const Standard_Real p1ToA = a2.Dot(p1_n) + p1_d;
const Standard_Real p1ToB = b2.Dot(p1_n) + p1_d;
const Standard_Real p1ToC = c2.Dot(p1_n) + p1_d;
const double p1ToA = a2.Dot(p1_n) + p1_d;
const double p1ToB = b2.Dot(p1_n) + p1_d;
const double p1ToC = c2.Dot(p1_n) + p1_d;
if(std::abs(p1ToA) < tolerance && std::abs(p1ToB) < tolerance &&std::abs(p1ToC) < tolerance)
return ignoreCoplanar ? false : trianglesIntersectCoplanar(p1_n, a1, b1, c1, a2, b2, c2); //Coplanar triangles
@@ -559,15 +559,15 @@ bool trianglesIntersect(const gp_Vec& a1, const gp_Vec& b1, const gp_Vec& c1, co
gp_Dir p2_n((b2 - a2).Crossed(c2 - a2).Normalized());
double p2_d = -a2.Dot(p2_n);
// const PxPlane p2(a2, b2, c2);
const Standard_Real p2ToA = a1.Dot(p2_n) + p2_d;
const Standard_Real p2ToB = b1.Dot(p2_n) + p2_d;
const Standard_Real p2ToC = c1.Dot(p2_n) + p2_d;
const double p2ToA = a1.Dot(p2_n) + p2_d;
const double p2ToB = b1.Dot(p2_n) + p2_d;
const double p2ToC = c1.Dot(p2_n) + p2_d;
if ((p2ToA > 0) == (p2ToB > 0) && (p2ToA > 0) == (p2ToC > 0))
return false; //All points of triangle 1 on same side of triangle 2 -> no intersection
gp_Vec intersectionDirection = p1_n.Crossed(p2_n);
const Standard_Real l2 = intersectionDirection.SquareMagnitude();
const double l2 = intersectionDirection.SquareMagnitude();
intersectionDirection *= 1.0f / std::sqrt(l2);
const Interval i1 = computeInterval(p2ToA, p2ToB, p2ToC, a1, b1, c1, intersectionDirection);