aboutsummaryrefslogtreecommitdiff
path: root/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.cpp')
-rwxr-xr-x[-rw-r--r--]sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.cpp2776
1 files changed, 1388 insertions, 1388 deletions
diff --git a/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.cpp b/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.cpp
index 74eee02..681e0b6 100644..100755
--- a/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.cpp
+++ b/sdk/extensions/authoring/source/NvBlastExtAuthoringBooleanTool.cpp
@@ -1,1388 +1,1388 @@
-// This code contains NVIDIA Confidential Information and is disclosed to you
-// under a form of NVIDIA software license agreement provided separately to you.
-//
-// Notice
-// NVIDIA Corporation and its licensors retain all intellectual property and
-// proprietary rights in and to this software and related documentation and
-// any modifications thereto. Any use, reproduction, disclosure, or
-// distribution of this software and related documentation without an express
-// license agreement from NVIDIA Corporation is strictly prohibited.
-//
-// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
-// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
-// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
-// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
-//
-// Information and code furnished is believed to be accurate and reliable.
-// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
-// information or for any infringement of patents or other rights of third parties that may
-// result from its use. No license is granted by implication or otherwise under any patent
-// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
-// This code supersedes and replaces all information previously supplied.
-// NVIDIA Corporation products are not authorized for use as critical
-// components in life support devices or systems without express written approval of
-// NVIDIA Corporation.
-//
-// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
-
-
-#include "NvBlastGlobals.h"
-#include "NvBlastExtAuthoringBooleanTool.h"
-#include "NvBlastExtAuthoringMeshImpl.h"
-#include "NvBlastExtAuthoringAccelerator.h"
-
-#include <math.h>
-#include <set>
-#include <algorithm>
-
-using physx::PxVec3;
-using physx::PxVec2;
-using physx::PxBounds3;
-
-
-namespace Nv
-{
-namespace Blast
-{
-
-/* Linear interpolation of vectors */
-
-NV_FORCE_INLINE void vec3Lerp(const PxVec3& a, const PxVec3& b, PxVec3& out, float t)
-{
- out.x = (b.x - a.x) * t + a.x;
- out.y = (b.y - a.y) * t + a.y;
- out.z = (b.z - a.z) * t + a.z;
-}
-
-NV_FORCE_INLINE void vec2Lerp(const PxVec2& a, const PxVec2& b, PxVec2& out, float t)
-{
- out.x = (b.x - a.x) * t + a.x;
- out.y = (b.y - a.y) * t + a.y;
-}
-
-NV_FORCE_INLINE int32_t BooleanEvaluator::addIfNotExist(Vertex& p)
-{
- mVerticesAggregate.push_back(p);
- return static_cast<int32_t>(mVerticesAggregate.size()) - 1;
-}
-
-NV_FORCE_INLINE void BooleanEvaluator::addEdgeIfValid(EdgeWithParent& ed)
-{
- mEdgeAggregate.push_back(ed);
-}
-
-/**
-Vertex level shadowing functions
-*/
-NV_FORCE_INLINE int32_t vertexShadowing(const PxVec3& a, const PxVec3& b)
-{
- return (b.x >= a.x) ? 1 : 0;
-}
-/**
-Vertex-edge status functions
-*/
-NV_FORCE_INLINE int32_t veStatus01(const PxVec3& sEdge, const PxVec3& eEdge, const PxVec3& p)
-{
- return vertexShadowing(p, eEdge) - vertexShadowing(p, sEdge);
-}
-
-NV_FORCE_INLINE int32_t veStatus10(const PxVec3& sEdge, const PxVec3& eEdge, const PxVec3& p)
-{
- return -vertexShadowing(eEdge, p) + vertexShadowing(sEdge, p);
-}
-
-bool shouldSwap(const PxVec3& a, const PxVec3& b)
-{
- if (a.x < b.x) return false;
- if (a.x > b.x) return true;
-
- if (a.y < b.y) return false;
- if (a.y > b.y) return true;
-
- if (a.z < b.z) return false;
- if (a.z > b.z) return true;
- return false;
-}
-
-
-/**
- Vertex-edge shadowing functions
-*/
-int32_t shadowing01(Vertex sEdge, Vertex eEdge, const PxVec3& p, Vertex& onEdgePoint, bool& hasOnEdge)
-{
-
- int32_t winding = veStatus01(sEdge.p, eEdge.p, p);
-
- if (sEdge.p.x > eEdge.p.x)
- {
- std::swap(sEdge, eEdge);
- }
-
- if (winding != 0)
- {
- float t = (p.x - sEdge.p.x) / (eEdge.p.x - sEdge.p.x);
- if (t >= 1)
- {
- onEdgePoint = eEdge;
- }
- else if (t <= 0)
- {
- onEdgePoint = sEdge;
- }
- else
- {
- vec3Lerp(sEdge.p, eEdge.p, onEdgePoint.p, t);
- vec3Lerp(sEdge.n, eEdge.n, onEdgePoint.n, t);
- vec2Lerp(sEdge.uv[0], eEdge.uv[0], onEdgePoint.uv[0], t);
- }
- hasOnEdge = true;
- if (onEdgePoint.p.y >= p.y)
- {
- return winding;
- }
- }
- else
- {
- hasOnEdge = false;
- }
- return 0;
-}
-int32_t shadowing10(Vertex sEdge, Vertex eEdge, const PxVec3& p, Vertex& onEdgePoint, bool& hasOnEdge)
-{
- int32_t winding = veStatus10(sEdge.p, eEdge.p, p);
-
- if (sEdge.p.x > eEdge.p.x)
- {
- std::swap(sEdge, eEdge);
- }
-
- if (winding != 0)
- {
- float t = (p.x - sEdge.p.x) / (eEdge.p.x - sEdge.p.x);
- if (t >= 1)
- {
- onEdgePoint = eEdge;
- }
- else if (t <= 0)
- {
- onEdgePoint = sEdge;
- }
- else
- {
- vec3Lerp(sEdge.p, eEdge.p, onEdgePoint.p, t);
- vec3Lerp(sEdge.n, eEdge.n, onEdgePoint.n, t);
- vec2Lerp(sEdge.uv[0], eEdge.uv[0], onEdgePoint.uv[0], t);
- }
- hasOnEdge = true;
- if (onEdgePoint.p.y < p.y)
- {
- return winding;
- }
- }
- else
- {
- hasOnEdge = false;
- }
- return 0;
-}
-
-int32_t shadowing01(PxVec3 sEdge, PxVec3 eEdge, const PxVec3& p)
-{
- int32_t winding = veStatus01(sEdge, eEdge, p);
-
- if (winding != 0)
- {
- if (sEdge.x > eEdge.x)
- {
- std::swap(sEdge, eEdge);
- }
- float t = ((p.x - sEdge.x) / (eEdge.x - sEdge.x));
- PxVec3 onEdgePoint;
- if (t >= 1)
- onEdgePoint = eEdge;
- else if (t <= 0)
- onEdgePoint = sEdge;
- else
- vec3Lerp(sEdge, eEdge, onEdgePoint, t);
- if (onEdgePoint.y >= p.y)
- {
- return winding;
- }
- }
- return 0;
-}
-
-int32_t shadowing10(PxVec3 sEdge, PxVec3 eEdge, const PxVec3& p)
-{
- int32_t winding = veStatus10(sEdge, eEdge, p);
- if (winding != 0)
- {
- if (sEdge.x > eEdge.x)
- {
- std::swap(sEdge, eEdge);
- }
-
- float t = ((p.x - sEdge.x) / (eEdge.x - sEdge.x));
- PxVec3 onEdgePoint;
- if (t >= 1)
- onEdgePoint = eEdge;
- else if (t <= 0)
- onEdgePoint = sEdge;
- else
- vec3Lerp(sEdge, eEdge, onEdgePoint, t);
- if (onEdgePoint.y < p.y)
- {
- return winding;
- }
- }
- return 0;
-}
-
-/**
-Vertex-facet shadowing functions
-*/
-
-int32_t vfStatus02(const PxVec3& p, const Vertex* points, const Edge* edges, int32_t edgesCount, Vertex* out)
-{
- int32_t val = 0;
- Vertex pnt;
- bool hasOnEdge = false;
- out[0].p.y = -MAXIMUM_EXTENT;
- out[1].p.y = MAXIMUM_EXTENT;
- for (int32_t i = 0; i < edgesCount; ++i)
- {
- val -= shadowing01(points[edges->s], points[edges->e], p, pnt, hasOnEdge);
- if (hasOnEdge != 0)
- {
- if (p.y > pnt.p.y && pnt.p.y > out[0].p.y)
- {
- out[0] = pnt;
- }
- if (p.y <= pnt.p.y && pnt.p.y < out[1].p.y)
- {
- out[1] = pnt;
- }
- }
- ++edges;
- }
- return val;
-}
-
-
-int32_t shadowing02(const PxVec3& p, const Vertex* points, const Edge* edges, int edgesCount, bool& hasOnFacetPoint, Vertex& onFacetPoint)
-{
- Vertex outp[2];
- int32_t stat = vfStatus02(p, points, edges, edgesCount, outp);
- float z = 0;
- hasOnFacetPoint = false;
- if (stat != 0)
- {
- Vertex& p1 = outp[0];
- Vertex& p2 = outp[1];
- PxVec3 vc = p2.p - p1.p;
- float t = 0;
- t = (std::abs(vc.x) > std::abs(vc.y)) ? (p.x - p1.p.x) / vc.x : (p.y - p1.p.y) / vc.y;
- t = PxClamp(t, 0.0f, 1.0f);
-
- z = t * vc.z + p1.p.z;
- hasOnFacetPoint = true;
- onFacetPoint.p.x = p.x;
- onFacetPoint.p.y = p.y;
- onFacetPoint.p.z = z;
- vec2Lerp(p1.uv[0], p2.uv[0], onFacetPoint.uv[0], t);
- vec3Lerp(p1.n, p2.n, onFacetPoint.n, t);
-
- if (z >= p.z)
- {
- return stat;
- }
- }
- return 0;
-}
-
-int32_t vfStatus20(const PxVec3& p, const Vertex* points, const Edge* edges, int32_t edgesCount, Vertex* out)
-{
- int32_t val = 0;
- Vertex pnt;
- bool hasOnEdge = false;
- out[0].p.y = -MAXIMUM_EXTENT;
- out[1].p.y = MAXIMUM_EXTENT;
-
- for (int32_t i = 0; i < edgesCount; ++i)
- {
- val += shadowing10(points[edges->s], points[edges->e], p, pnt, hasOnEdge);
- if (hasOnEdge != 0)
- {
- if (p.y > pnt.p.y && pnt.p.y > out[0].p.y)
- {
- out[0] = pnt;
- }
- if (p.y <= pnt.p.y && pnt.p.y < out[1].p.y)
- {
- out[1] = pnt;
- }
- }
- ++edges;
- }
- return val;
-}
-
-int32_t shadowing20(const PxVec3& p, const Vertex* points, const Edge* edges, int edgesCount, bool& hasOnFacetPoint, Vertex& onFacetPoint)
-{
- Vertex outp[2];
- int32_t stat = vfStatus20(p, points, edges, edgesCount, outp);
- hasOnFacetPoint = false;
- if (stat != 0)
- {
- Vertex& p1 = outp[0];
- Vertex& p2 = outp[1];
- PxVec3 vc = p2.p - p1.p;
- float t = 0;
- t = (std::abs(vc.x) > std::abs(vc.y)) ? (p.x - p1.p.x) / vc.x : (p.y - p1.p.y) / vc.y;
- t = PxClamp(t, 0.0f, 1.0f);
-
- hasOnFacetPoint = true;
- onFacetPoint.p.x = p.x;
- onFacetPoint.p.y = p.y;
-
- onFacetPoint.p.z = t * vc.z + p1.p.z;
-
- vec2Lerp(p1.uv[0], p2.uv[0], onFacetPoint.uv[0], t);
- vec3Lerp(p1.n, p2.n, onFacetPoint.n, t);
-
- if (onFacetPoint.p.z < p.z)
- {
- return stat;
- }
- }
- return 0;
-}
-
-
-NV_FORCE_INLINE int32_t edgesCrossCheck(const PxVec3& eAs, const PxVec3& eAe, const PxVec3& eBs, const PxVec3& eBe)
-{
- return shadowing01(eBs, eBe, eAe) - shadowing01(eBs, eBe, eAs) + shadowing10(eAs, eAe, eBe) - shadowing10(eAs, eAe, eBs);
-}
-
-
-
-int32_t edgesIntersection(const Vertex& eAs, const Vertex& eAe, const Vertex& eBs, const Vertex& eBe, Vertex& intersectionA, Vertex& intersectionB, bool& hasPoints)
-{
- int32_t status = edgesCrossCheck(eAs.p, eAe.p, eBs.p, eBe.p);
- hasPoints = false;
- if (status == 0)
- {
- return 0;
- }
-
- Vertex tempPoint;
- Vertex bShadowingPair[2];
- Vertex aShadowingPair[2];
- bool hasOnEdge = false;
- bool aShadowing = false;
- bool bShadowing = false;
-
- /**
- Search for two pairs where parts of A shadows B, and where B shadows are.
- Needed for search intersection point.
- */
-
- for (auto p : { &eBs, &eBe })
- {
- int32_t shadowingType = shadowing10(eAs, eAe, p->p, tempPoint, hasOnEdge);
- if (shadowingType == 0 && !aShadowing && hasOnEdge)
- {
- aShadowing = true;
- aShadowingPair[0] = *p;
- aShadowingPair[1] = tempPoint;
- }
- else
- {
- if ((shadowingType == 1 || shadowingType == -1) && !bShadowing)
- {
- bShadowing = true;
- bShadowingPair[0] = *p;
- bShadowingPair[1] = tempPoint;
- }
- }
- }
- if (!aShadowing || !bShadowing)
- {
- for (auto p : { &eAs, &eAe })
- {
- int32_t shadowingType = shadowing01(eBs, eBe, p->p, tempPoint, hasOnEdge);
-
- if (shadowingType == 0 && !aShadowing && hasOnEdge)
- {
- aShadowing = true;
- aShadowingPair[1] = *p;
- aShadowingPair[0] = tempPoint;
- }
- else
- {
- if ((shadowingType == 1 || shadowingType == -1) && !bShadowing)
- {
- bShadowing = true;
- bShadowingPair[1] = *p;
- bShadowingPair[0] = tempPoint;
- }
- }
- }
- }
-
- float deltaPlus = bShadowingPair[0].p.y - bShadowingPair[1].p.y;
- float deltaMinus = aShadowingPair[0].p.y - aShadowingPair[1].p.y;
- float div = 0;
- if (deltaPlus > 0)
- div = deltaPlus / (deltaPlus - deltaMinus);
- else
- div = 0;
-
- intersectionA.p = bShadowingPair[1].p - div * (bShadowingPair[1].p - aShadowingPair[1].p);
- intersectionA.n = bShadowingPair[1].n - div * (bShadowingPair[1].n - aShadowingPair[1].n);
- intersectionA.uv[0] = bShadowingPair[1].uv[0] - (bShadowingPair[1].uv[0] - aShadowingPair[1].uv[0]) * div;
- intersectionB.p = intersectionA.p;
- intersectionB.p.z = bShadowingPair[0].p.z - div * (bShadowingPair[0].p.z - aShadowingPair[0].p.z);
- intersectionB.n = bShadowingPair[0].n - div * (bShadowingPair[0].n - aShadowingPair[0].n);
- intersectionB.uv[0] = bShadowingPair[0].uv[0] - (bShadowingPair[0].uv[0] - aShadowingPair[0].uv[0]) * div;
-
- hasPoints = true;
- return status;
-}
-
-NV_FORCE_INLINE int32_t edgeEdgeShadowing(const Vertex& eAs, const Vertex& eAe, const Vertex& eBs, const Vertex& eBe, Vertex& intersectionA, Vertex& intersectionB, bool& hasPoints)
-{
- int32_t status = edgesIntersection(eAs, eAe, eBs, eBe, intersectionA, intersectionB, hasPoints);
- if (intersectionB.p.z >= intersectionA.p.z)
- {
- return status;
- }
- return 0;
-}
-
-int32_t edgeFacetIntersection12(const Vertex& edSt, const Vertex& edEnd, const Vertex* points, const Edge* edges, int edgesCount, Vertex& intersectionA, Vertex& intersectionB)
-{
- int32_t status = 0;
- Vertex p1, p2;
- Vertex bShadowingPair[2];
- Vertex aShadowingPair[2];
- bool hasPoint = false;
- bool aShadowing = false;
- bool bShadowing = false;
- int32_t mlt = -1;
- int32_t shadowingType;
- for (auto p : { &edEnd, &edSt })
- {
- shadowingType = shadowing02(p->p, points, edges, edgesCount, hasPoint, p1);
- status += mlt * shadowingType;
- if (shadowingType == 0 && !aShadowing && hasPoint)
- {
- aShadowing = true;
- aShadowingPair[0] = p1;
- aShadowingPair[1] = *p;
- }
- else
- {
- if ((shadowingType == 1 || shadowingType == -1) && !bShadowing)
- {
- bShadowing = true;
- bShadowingPair[0] = p1;
- bShadowingPair[1] = *p;
- }
- }
- mlt = 1;
- }
-
- for (int32_t ed = 0; ed < edgesCount; ++ed)
- {
- if (shouldSwap(points[edges[ed].s].p, points[edges[ed].e].p))
- {
- shadowingType = -edgeEdgeShadowing(edSt, edEnd, points[edges[ed].e], points[edges[ed].s], p1, p2, hasPoint);
- }
- else
- {
- shadowingType = edgeEdgeShadowing(edSt, edEnd, points[edges[ed].s], points[edges[ed].e], p1, p2, hasPoint);
- }
- status -= shadowingType;
- if (shadowingType == 0 && !aShadowing && hasPoint)
- {
- aShadowing = true;
- aShadowingPair[0] = p2;
- aShadowingPair[1] = p1;
- }
- else
- {
- if ((shadowingType == 1 || shadowingType == -1) && !bShadowing)
- {
- bShadowing = true;
- bShadowingPair[0] = p2;
- bShadowingPair[1] = p1;
- }
- }
- }
- if (!status || !bShadowing || !aShadowing)
- {
- return 0;
- }
-
- float deltaPlus = bShadowingPair[0].p.z - bShadowingPair[1].p.z;
- float div = 0;
- if (deltaPlus != 0)
- {
- float deltaMinus = aShadowingPair[0].p.z - aShadowingPair[1].p.z;
- div = deltaPlus / (deltaPlus - deltaMinus);
- }
- intersectionA.p = bShadowingPair[1].p - div * (bShadowingPair[1].p - aShadowingPair[1].p);
- intersectionA.n = bShadowingPair[1].n - div * (bShadowingPair[1].n - aShadowingPair[1].n);
- intersectionA.uv[0] = bShadowingPair[1].uv[0] - (bShadowingPair[1].uv[0] - aShadowingPair[1].uv[0]) * div;
-
- intersectionB.p = intersectionA.p;
- intersectionB.n = bShadowingPair[0].n - div * (bShadowingPair[0].n - aShadowingPair[0].n);
- intersectionB.uv[0] = bShadowingPair[0].uv[0] - (bShadowingPair[0].uv[0] - aShadowingPair[0].uv[0]) * div;
-
-
- return status;
-}
-
-
-int32_t edgeFacetIntersection21(const Vertex& edSt, const Vertex& edEnd, const Vertex* points, const Edge* edges, int edgesCount, Vertex& intersectionA, Vertex& intersectionB)
-{
- int32_t status = 0;
- Vertex p1, p2;
-
- Vertex bShadowingPair[2];
- Vertex aShadowingPair[2];
- bool hasPoint = false;
- bool aShadowing = false;
- bool bShadowing = false;
-
- int32_t shadowingType;
- int32_t mlt = 1;
- for (auto p : { &edEnd, &edSt })
- {
- shadowingType = shadowing20(p->p, points, edges, edgesCount, hasPoint, p1);
- status += mlt * shadowingType;
-
- if (shadowingType == 0 && !aShadowing && hasPoint)
- {
- aShadowing = true;
- aShadowingPair[0] = *p;
- aShadowingPair[1] = p1;
- }
- else
- {
- if ((shadowingType == 1 || shadowingType == -1) && !bShadowing)
- {
- bShadowing = true;
- bShadowingPair[0] = *p;
- bShadowingPair[1] = p1;
- }
- }
- mlt = -1;
- }
-
- for (int32_t ed = 0; ed < edgesCount; ++ed)
- {
- if (shouldSwap(points[edges[ed].s].p, points[edges[ed].e].p))
- {
- shadowingType = -edgeEdgeShadowing(points[edges[ed].e], points[edges[ed].s], edSt, edEnd, p1, p2, hasPoint);
- }
- else
- {
- shadowingType = edgeEdgeShadowing(points[edges[ed].s], points[edges[ed].e], edSt, edEnd, p1, p2, hasPoint);
- }
- status -= shadowingType;
- if (shadowingType == 0)
- {
- if (!aShadowing && hasPoint)
- {
- aShadowing = true;
- aShadowingPair[0] = p2;
- aShadowingPair[1] = p1;
- }
- }
- else
- {
- if ((shadowingType == 1 || shadowingType == -1) && !bShadowing)
- {
- bShadowing = true;
- bShadowingPair[0] = p2;
- bShadowingPair[1] = p1;
- }
- }
- }
- if (!status || !bShadowing || !aShadowing)
- {
- return 0;
- }
- float deltaPlus = bShadowingPair[0].p.z - bShadowingPair[1].p.z;
- float div = 0;
- if (deltaPlus != 0)
- {
- float deltaMinus = aShadowingPair[0].p.z - aShadowingPair[1].p.z;
- div = deltaPlus / (deltaPlus - deltaMinus);
- }
- intersectionA.p = bShadowingPair[1].p - div * (bShadowingPair[1].p - aShadowingPair[1].p);
- intersectionA.n = bShadowingPair[1].n - div * (bShadowingPair[1].n - aShadowingPair[1].n);
- intersectionA.uv[0] = bShadowingPair[1].uv[0] - (bShadowingPair[1].uv[0] - aShadowingPair[1].uv[0]) * div;
-
- intersectionB.p = intersectionA.p;
- intersectionB.n = bShadowingPair[0].n - div * (bShadowingPair[0].n - aShadowingPair[0].n);
- intersectionB.uv[0] = bShadowingPair[0].uv[0] - (bShadowingPair[0].uv[0] - aShadowingPair[0].uv[0]) * div;
-
- return status;
-}
-
-int32_t BooleanEvaluator::vertexMeshStatus03(const PxVec3& p, const Mesh* mesh)
-{
- int32_t status = 0;
- Vertex pnt;
- bool hasPoint = false;
- mAcceleratorB->setState(p);
- int32_t facet = mAcceleratorB->getNextFacet();
- while (facet != -1)
- {
- const Edge* ed = mesh->getEdges() + mesh->getFacet(facet)->firstEdgeNumber;
- status += shadowing02(p, mesh->getVertices(), ed, mesh->getFacet(facet)->edgesCount, hasPoint, pnt);
- facet = mAcceleratorB->getNextFacet();
- }
-
- //for (int32_t facet = 0; facet < mesh->getFacetCount(); ++facet)
- //{
- // Edge* ed = mesh->getEdges() + mesh->getFacet(facet)->firstEdgeNumber;
- // status += shadowing02(p, mesh->getVertices(), ed, mesh->getFacet(facet)->edgesCount, hasPoint, pnt);
- //};
- return status;
-}
-
-int32_t BooleanEvaluator::vertexMeshStatus30(const PxVec3& p, const Mesh* mesh)
-{
- int32_t status = 0;
- bool hasPoints = false;
- Vertex point;
- mAcceleratorA->setState(p);
- int32_t facet = mAcceleratorA->getNextFacet();
- while ( facet != -1)
- {
- const Edge* ed = mesh->getEdges() + mesh->getFacet(facet)->firstEdgeNumber;
- status -= shadowing20(p, mesh->getVertices(), ed, mesh->getFacet(facet)->edgesCount, hasPoints, point);
- facet = mAcceleratorA->getNextFacet();
- }
-
- //for (int32_t facet = 0; facet < mesh->getFacetCount(); ++facet)
- //{
- // Edge* ed = mesh->getEdges() + mesh->getFacet(facet)->firstEdgeNumber;
- // status -= shadowing20(p, mesh->getVertices(), ed, mesh->getFacet(facet)->edgesCount, hasPoints, point);
- //}
- return status;
-}
-
-NV_FORCE_INLINE int32_t inclusionValue03(BooleanConf& conf, int32_t xValue)
-{
- return conf.ca + conf.ci * xValue;
-}
-
-NV_FORCE_INLINE int32_t inclusionValueEdgeFace(BooleanConf& conf, int32_t xValue)
-{
- return conf.ci * xValue;
-}
-
-NV_FORCE_INLINE int32_t inclusionValue30(BooleanConf& conf, int32_t xValue)
-{
- return conf.cb + conf.ci * xValue;
-}
-
-struct VertexComparator
-{
- VertexComparator(PxVec3 base = PxVec3()) : basePoint(base) {};
- PxVec3 basePoint;
- bool operator()(const Vertex& a, const Vertex& b)
- {
- return (b.p - a.p).dot(basePoint) > 0.0;
- }
-};
-
-struct VertexPairComparator
-{
- VertexPairComparator(PxVec3 base = PxVec3()) : basePoint(base) {};
- PxVec3 basePoint;
- bool operator()(const std::pair<Vertex, Vertex>& a, const std::pair<Vertex, Vertex>& b)
- {
- return (b.first.p - a.first.p).dot(basePoint) > 0.0;
- }
-};
-
-int32_t BooleanEvaluator::isPointContainedInMesh(const Mesh* msh, const PxVec3& point)
-{
- if (msh == nullptr)
- {
- return 0;
- }
- DummyAccelerator dmAccel(msh->getFacetCount());
- mAcceleratorA = &dmAccel;
- return vertexMeshStatus30(point, msh);
-
-}
-
-int32_t BooleanEvaluator::isPointContainedInMesh(const Mesh* msh, SpatialAccelerator* spAccel, const PxVec3& point)
-{
- if (msh == nullptr)
- {
- return 0;
- }
- mAcceleratorA = spAccel;
- return vertexMeshStatus30(point, msh);
-}
-
-
-
-
-void BooleanEvaluator::buildFaceFaceIntersections(BooleanConf mode)
-{
- int32_t statusValue = 0;
- int32_t inclusionValue = 0;
-
- std::vector<std::pair<Vertex, Vertex> > retainedStarts;
- std::vector<std::pair<Vertex, Vertex>> retainedEnds;
- VertexPairComparator comp;
-
- Vertex newPointA;
- Vertex newPointB;
-
- const Vertex* meshAPoints = mMeshA->getVertices();
- const Vertex* meshBPoints = mMeshB->getVertices();
- EdgeWithParent newEdge;
- mEdgeFacetIntersectionData12.clear();
- mEdgeFacetIntersectionData21.clear();
-
- mEdgeFacetIntersectionData12.resize(mMeshA->getFacetCount());
- mEdgeFacetIntersectionData21.resize(mMeshB->getFacetCount());
-
- for (uint32_t facetB = 0; facetB < mMeshB->getFacetCount(); ++facetB)
- {
- mAcceleratorA->setState(mMeshB->getVertices(), mMeshB->getEdges(), *mMeshB->getFacet(facetB));
- int32_t facetA = mAcceleratorA->getNextFacet();
- while (facetA != -1)
- {
- const Edge* facetBEdges = mMeshB->getEdges() + mMeshB->getFacet(facetB)->firstEdgeNumber;
- const Edge* facetAEdges = mMeshA->getEdges() + mMeshA->getFacet(facetA)->firstEdgeNumber;
- const Edge* fbe = facetBEdges;
- const Edge* fae = facetAEdges;
- retainedStarts.clear();
- retainedEnds.clear();
- PxVec3 compositeEndPoint(0, 0, 0);
- PxVec3 compositeStartPoint(0, 0, 0);
- uint32_t facetAEdgeCount = mMeshA->getFacet(facetA)->edgesCount;
- uint32_t facetBEdgeCount = mMeshB->getFacet(facetB)->edgesCount;
- int32_t ic = 0;
- for (uint32_t i = 0; i < facetAEdgeCount; ++i)
- {
- if (shouldSwap(meshAPoints[fae->e].p, meshAPoints[fae->s].p))
- {
- statusValue = -edgeFacetIntersection12(meshAPoints[fae->e], meshAPoints[fae->s], mMeshB->getVertices(), facetBEdges, facetBEdgeCount, newPointA, newPointB);
- }
- else
- {
- statusValue = edgeFacetIntersection12(meshAPoints[fae->s], meshAPoints[fae->e], mMeshB->getVertices(), facetBEdges, facetBEdgeCount, newPointA, newPointB);
- }
-
- inclusionValue = -inclusionValueEdgeFace(mode, statusValue);
- if (inclusionValue > 0)
- {
- for (ic = 0; ic < inclusionValue; ++ic)
- {
- retainedEnds.push_back(std::make_pair(newPointA, newPointB));
- compositeEndPoint += newPointA.p;
- }
- mEdgeFacetIntersectionData12[facetA].push_back(EdgeFacetIntersectionData(i, statusValue, newPointA));
- }
- if (inclusionValue < 0)
- {
- for (ic = 0; ic < -inclusionValue; ++ic)
- {
- retainedStarts.push_back(std::make_pair(newPointA, newPointB));
- compositeStartPoint += newPointA.p;
- }
- mEdgeFacetIntersectionData12[facetA].push_back(EdgeFacetIntersectionData(i, statusValue, newPointA));
- }
- fae++;
- }
- for (uint32_t i = 0; i < facetBEdgeCount; ++i)
- {
- if (shouldSwap(meshBPoints[fbe->e].p, meshBPoints[fbe->s].p))
- {
- statusValue = -edgeFacetIntersection21(meshBPoints[(fbe)->e], meshBPoints[(fbe)->s], mMeshA->getVertices(), facetAEdges, facetAEdgeCount, newPointA, newPointB);
- }
- else
- {
- statusValue = edgeFacetIntersection21(meshBPoints[(fbe)->s], meshBPoints[(fbe)->e], mMeshA->getVertices(), facetAEdges, facetAEdgeCount, newPointA, newPointB);
- }
- inclusionValue = inclusionValueEdgeFace(mode, statusValue);
- if (inclusionValue > 0)
- {
- for (ic = 0; ic < inclusionValue; ++ic)
- {
- retainedEnds.push_back(std::make_pair(newPointA, newPointB));
- compositeEndPoint += newPointB.p;
- }
- mEdgeFacetIntersectionData21[facetB].push_back(EdgeFacetIntersectionData( i, statusValue, newPointB));
- }
- if (inclusionValue < 0)
- {
- for (ic = 0; ic < -inclusionValue; ++ic)
- {
- retainedStarts.push_back(std::make_pair(newPointA, newPointB));
- compositeStartPoint += newPointB.p;
- }
- mEdgeFacetIntersectionData21[facetB].push_back(EdgeFacetIntersectionData(i, statusValue, newPointB));
- }
- fbe++;
- }
- if (retainedStarts.size() != retainedEnds.size())
- {
- NVBLAST_LOG_ERROR("Not equal number of starting and ending vertices! Probably input mesh has open edges.");
- return;
- }
- if (retainedStarts.size() > 1)
- {
- comp.basePoint = compositeEndPoint - compositeStartPoint;
- std::sort(retainedStarts.begin(), retainedStarts.end(), comp);
- std::sort(retainedEnds.begin(), retainedEnds.end(), comp);
- }
- for (uint32_t rv = 0; rv < retainedStarts.size(); ++rv)
- {
- newEdge.s = addIfNotExist(retainedStarts[rv].first);
- newEdge.e = addIfNotExist(retainedEnds[rv].first);
- newEdge.parent = facetA;
- addEdgeIfValid(newEdge);
- newEdge.parent = facetB + mMeshA->getFacetCount();
- newEdge.e = addIfNotExist(retainedStarts[rv].second);
- newEdge.s = addIfNotExist(retainedEnds[rv].second);
- addEdgeIfValid(newEdge);
- }
- facetA = mAcceleratorA->getNextFacet();
- } // while (*iter != -1)
-
- } // for (uint32_t facetB = 0; facetB < mMeshB->getFacetCount(); ++facetB)
-
-
-
-}
-
-
-void BooleanEvaluator::buildFastFaceFaceIntersection(BooleanConf mode)
-{
- int32_t statusValue = 0;
- int32_t inclusionValue = 0;
-
- std::vector<std::pair<Vertex, Vertex> > retainedStarts;
- std::vector<std::pair<Vertex, Vertex>> retainedEnds;
- VertexPairComparator comp;
-
- Vertex newPointA;
- Vertex newPointB;
-
- const Vertex* meshAPoints = mMeshA->getVertices();
- EdgeWithParent newEdge;
-
- mEdgeFacetIntersectionData12.clear();
- mEdgeFacetIntersectionData21.clear();
-
- mEdgeFacetIntersectionData12.resize(mMeshA->getFacetCount());
- mEdgeFacetIntersectionData21.resize(mMeshB->getFacetCount());
-
- for (uint32_t facetA = 0; facetA < mMeshA->getFacetCount(); ++facetA)
- {
- const Edge* facetAEdges = mMeshA->getEdges() + mMeshA->getFacet(facetA)->firstEdgeNumber;
- int32_t facetB = 0;
- const Edge* facetBEdges = mMeshB->getEdges() + mMeshB->getFacet(facetB)->firstEdgeNumber;
- const Edge* fae = facetAEdges;
- retainedStarts.clear();
- retainedEnds.clear();
- PxVec3 compositeEndPoint(0, 0, 0);
- PxVec3 compositeStartPoint(0, 0, 0);
- uint32_t facetAEdgeCount = mMeshA->getFacet(facetA)->edgesCount;
- uint32_t facetBEdgeCount = mMeshB->getFacet(facetB)->edgesCount;
- int32_t ic = 0;
- for (uint32_t i = 0; i < facetAEdgeCount; ++i)
- {
- if (shouldSwap(meshAPoints[fae->e].p, meshAPoints[fae->s].p))
- {
- statusValue = -edgeFacetIntersection12(meshAPoints[fae->e], meshAPoints[fae->s], mMeshB->getVertices(), facetBEdges, facetBEdgeCount, newPointA, newPointB);
- }
- else
- {
- statusValue = edgeFacetIntersection12(meshAPoints[fae->s], meshAPoints[fae->e], mMeshB->getVertices(), facetBEdges, facetBEdgeCount, newPointA, newPointB);
- }
- inclusionValue = -inclusionValueEdgeFace(mode, statusValue);
- if (inclusionValue > 0)
- {
- for (ic = 0; ic < inclusionValue; ++ic)
- {
- retainedEnds.push_back(std::make_pair(newPointA, newPointB));
- compositeEndPoint += newPointA.p;
- }
- mEdgeFacetIntersectionData12[facetA].push_back(EdgeFacetIntersectionData(i, statusValue, newPointA));
- }
- if (inclusionValue < 0)
- {
- for (ic = 0; ic < -inclusionValue; ++ic)
- {
- retainedStarts.push_back(std::make_pair(newPointA, newPointB));
- compositeStartPoint += newPointA.p;
- }
- mEdgeFacetIntersectionData12[facetA].push_back(EdgeFacetIntersectionData(i, statusValue, newPointA));
- }
- fae++;
- }
- if (retainedStarts.size() != retainedEnds.size())
- {
- NVBLAST_LOG_ERROR("Not equal number of starting and ending vertices! Probably input mesh has open edges.");
- return;
- }
- if (retainedStarts.size() > 1)
- {
- comp.basePoint = compositeEndPoint - compositeStartPoint;
- std::sort(retainedStarts.begin(), retainedStarts.end(), comp);
- std::sort(retainedEnds.begin(), retainedEnds.end(), comp);
- }
- for (uint32_t rv = 0; rv < retainedStarts.size(); ++rv)
- {
- newEdge.s = addIfNotExist(retainedStarts[rv].first);
- newEdge.e = addIfNotExist(retainedEnds[rv].first);
- newEdge.parent = facetA;
- addEdgeIfValid(newEdge);
- newEdge.parent = facetB + mMeshA->getFacetCount();
- newEdge.e = addIfNotExist(retainedStarts[rv].second);
- newEdge.s = addIfNotExist(retainedEnds[rv].second);
- addEdgeIfValid(newEdge);
- }
- }
-
-}
-
-
-
-void BooleanEvaluator::collectRetainedPartsFromA(BooleanConf mode)
-{
-
- int32_t statusValue = 0;
- int32_t inclusionValue = 0;
- const Vertex* vertices = mMeshA->getVertices();
- Vertex newPoint;
- VertexComparator comp;
- const PxBounds3& bMeshBoudning = mMeshB->getBoundingBox();
- const Edge* facetEdges = mMeshA->getEdges();
- std::vector<Vertex> retainedStartVertices;
- std::vector<Vertex> retainedEndVertices;
- retainedStartVertices.reserve(255);
- retainedEndVertices.reserve(255);
- int32_t ic = 0;
- for (uint32_t facetId = 0; facetId < mMeshA->getFacetCount(); ++facetId)
- {
- retainedStartVertices.clear();
- retainedEndVertices.clear();
- for (uint32_t i = 0; i < mMeshA->getFacet(facetId)->edgesCount; ++i)
- {
- PxVec3 compositeEndPoint(0, 0, 0);
- PxVec3 compositeStartPoint(0, 0, 0);
-
- int32_t lastPos = static_cast<int32_t>(retainedEndVertices.size());
- /* Test start and end point of edge against mesh */
- if (bMeshBoudning.contains(vertices[facetEdges->s].p))
- {
- statusValue = vertexMeshStatus03(vertices[facetEdges->s].p, mMeshB);
- }
- else
- {
- statusValue = 0;
- }
- inclusionValue = -inclusionValue03(mode, statusValue);
-
- if (inclusionValue > 0)
- {
- for (ic = 0; ic < inclusionValue; ++ic)
- {
- retainedEndVertices.push_back(vertices[facetEdges->s]);
- compositeEndPoint += vertices[facetEdges->s].p;
- }
- }
- else
- {
- if (inclusionValue < 0)
- {
- for (ic = 0; ic < -inclusionValue; ++ic)
- {
- retainedStartVertices.push_back(vertices[facetEdges->s]);
- compositeStartPoint += vertices[facetEdges->s].p;
- }
- }
- }
-
- if (bMeshBoudning.contains(vertices[facetEdges->e].p))
- {
- statusValue = vertexMeshStatus03(vertices[facetEdges->e].p, mMeshB);
- }
- else
- {
- statusValue = 0;
- }
- inclusionValue = inclusionValue03(mode, statusValue);
- if (inclusionValue > 0)
- {
- for (ic = 0; ic < inclusionValue; ++ic)
- {
- retainedEndVertices.push_back(vertices[facetEdges->e]);
- compositeEndPoint += vertices[facetEdges->e].p;
- }
- }
- else
- {
- if (inclusionValue < 0)
- {
- for (ic = 0; ic < -inclusionValue; ++ic)
- {
- retainedStartVertices.push_back(vertices[facetEdges->e]);
- compositeStartPoint += vertices[facetEdges->e].p;
- }
- }
- }
- /* Test edge intersection with mesh*/
- for (uint32_t intrs = 0; intrs < mEdgeFacetIntersectionData12[facetId].size(); ++intrs)
- {
- EdgeFacetIntersectionData& intr = mEdgeFacetIntersectionData12[facetId][intrs];
- if (intr.edId != (int32_t)i)
- continue;
- newPoint = intr.intersectionPoint;
- inclusionValue = inclusionValueEdgeFace(mode, intr.intersectionType);
-
- if (inclusionValue > 0)
- {
- for (ic = 0; ic < inclusionValue; ++ic)
- {
- retainedEndVertices.push_back(newPoint);
- compositeEndPoint += newPoint.p;
- }
- }
- else
- {
- if (inclusionValue < 0)
- {
- for (ic = 0; ic < -inclusionValue; ++ic)
- {
- retainedStartVertices.push_back(newPoint);
- compositeStartPoint += newPoint.p;
- }
- }
- }
- }
- facetEdges++;
- if (retainedStartVertices.size() != retainedEndVertices.size())
- {
- NVBLAST_LOG_ERROR("Not equal number of starting and ending vertices! Probably input mesh has open edges.");
- return;
- }
- if (retainedEndVertices.size() > 1)
- {
- comp.basePoint = compositeEndPoint - compositeStartPoint;
- std::sort(retainedStartVertices.begin() + lastPos, retainedStartVertices.end(), comp);
- std::sort(retainedEndVertices.begin() + lastPos, retainedEndVertices.end(), comp);
- }
- }
-
-
- EdgeWithParent newEdge;
- for (uint32_t rv = 0; rv < retainedStartVertices.size(); ++rv)
- {
- newEdge.s = addIfNotExist(retainedStartVertices[rv]);
- newEdge.e = addIfNotExist(retainedEndVertices[rv]);
- newEdge.parent = facetId;
- addEdgeIfValid(newEdge);
- }
- }
-
- return;
-}
-
-void BooleanEvaluator::collectRetainedPartsFromB(BooleanConf mode)
-{
- int32_t statusValue = 0;
- int32_t inclusionValue = 0;
- const Vertex* vertices = mMeshB->getVertices();
- Vertex newPoint;
- VertexComparator comp;
- const PxBounds3& aMeshBoudning = mMeshA->getBoundingBox();
- const Edge* facetEdges = mMeshB->getEdges();
- std::vector<Vertex> retainedStartVertices;
- std::vector<Vertex> retainedEndVertices;
- retainedStartVertices.reserve(255);
- retainedEndVertices.reserve(255);
- int32_t ic = 0;
- for (uint32_t facetId = 0; facetId < mMeshB->getFacetCount(); ++facetId)
- {
- retainedStartVertices.clear();
- retainedEndVertices.clear();
- for (uint32_t i = 0; i < mMeshB->getFacet(facetId)->edgesCount; ++i)
- {
- PxVec3 compositeEndPoint(0, 0, 0);
- PxVec3 compositeStartPoint(0, 0, 0);
- int32_t lastPos = static_cast<int32_t>(retainedEndVertices.size());
- if (aMeshBoudning.contains(vertices[facetEdges->s].p))
- {
- statusValue = vertexMeshStatus30(vertices[facetEdges->s].p, mMeshA);
- }
- else
- {
- statusValue = 0;
- }
- inclusionValue = -inclusionValue30(mode, statusValue);
-
- if (inclusionValue > 0)
- {
- for (ic = 0; ic < inclusionValue; ++ic)
- {
- retainedEndVertices.push_back(vertices[facetEdges->s]);
- compositeEndPoint += vertices[facetEdges->s].p;
- }
-
- }
- else
- {
- if (inclusionValue < 0)
- {
- for (ic = 0; ic < -inclusionValue; ++ic)
- {
- retainedStartVertices.push_back(vertices[facetEdges->s]);
- compositeStartPoint += vertices[facetEdges->s].p;
- }
-
- }
- }
-
- if (aMeshBoudning.contains(vertices[facetEdges->e].p))
- {
- statusValue = vertexMeshStatus30(vertices[facetEdges->e].p, mMeshA);
- }
- else
- {
- statusValue = 0;
- }
- inclusionValue = inclusionValue30(mode, statusValue);
- if (inclusionValue > 0)
- {
- for (ic = 0; ic < inclusionValue; ++ic)
- {
- retainedEndVertices.push_back(vertices[facetEdges->e]);
- compositeEndPoint += vertices[facetEdges->e].p;
- }
-
- }
- else
- {
- if (inclusionValue < 0)
- {
- for (ic = 0; ic < -inclusionValue; ++ic)
- {
- retainedStartVertices.push_back(vertices[facetEdges->e]);
- compositeStartPoint += vertices[facetEdges->e].p;
- }
-
- }
- }
- for (uint32_t intrs = 0; intrs < mEdgeFacetIntersectionData21[facetId].size(); ++intrs)
- {
- EdgeFacetIntersectionData& intr = mEdgeFacetIntersectionData21[facetId][intrs];
- if (intr.edId != (int32_t)i)
- continue;
- newPoint = intr.intersectionPoint;
- inclusionValue = inclusionValueEdgeFace(mode, intr.intersectionType);
-
- if (inclusionValue > 0)
- {
- for (ic = 0; ic < inclusionValue; ++ic)
- {
- retainedEndVertices.push_back(newPoint);
- compositeEndPoint += newPoint.p;
- }
- }
- else
- {
- if (inclusionValue < 0)
- {
- for (ic = 0; ic < -inclusionValue; ++ic)
- {
- retainedStartVertices.push_back(newPoint);
- compositeStartPoint += newPoint.p;
- }
- }
- }
- }
- facetEdges++;
- if (retainedStartVertices.size() != retainedEndVertices.size())
- {
- NVBLAST_LOG_ERROR("Not equal number of starting and ending vertices! Probably input mesh has open edges.");
- return;
- }
- if (retainedEndVertices.size() - lastPos > 1)
- {
- comp.basePoint = compositeEndPoint - compositeStartPoint;
- std::sort(retainedStartVertices.begin() + lastPos, retainedStartVertices.end(), comp);
- std::sort(retainedEndVertices.begin() + lastPos, retainedEndVertices.end(), comp);
- }
- }
- EdgeWithParent newEdge;
- for (uint32_t rv = 0; rv < retainedStartVertices.size(); ++rv)
- {
- newEdge.s = addIfNotExist(retainedStartVertices[rv]);
- newEdge.e = addIfNotExist(retainedEndVertices[rv]);
- newEdge.parent = facetId + mMeshA->getFacetCount();
- addEdgeIfValid(newEdge);
- }
- }
- return;
-}
-
-bool EdgeWithParentSortComp(const EdgeWithParent& a, const EdgeWithParent& b)
-{
- return a.parent < b.parent;
-}
-
-
-void BooleanEvaluator::performBoolean(const Mesh* meshA, const Mesh* meshB, SpatialAccelerator* spAccelA, SpatialAccelerator* spAccelB, BooleanConf mode)
-{
- reset();
- mMeshA = meshA;
- mMeshB = meshB;
- mAcceleratorA = spAccelA;
- mAcceleratorB = spAccelB;
- buildFaceFaceIntersections(mode);
- collectRetainedPartsFromA(mode);
- collectRetainedPartsFromB(mode);
- mAcceleratorA = nullptr;
- mAcceleratorB = nullptr;
-}
-
-void BooleanEvaluator::performBoolean(const Mesh* meshA, const Mesh* meshB, BooleanConf mode)
-{
- reset();
- mMeshA = meshA;
- mMeshB = meshB;
- DummyAccelerator ac = DummyAccelerator(mMeshA->getFacetCount());
- DummyAccelerator bc = DummyAccelerator(mMeshB->getFacetCount());
- performBoolean(meshA, meshB, &ac, &bc, mode);
-}
-
-
-void BooleanEvaluator::performFastCutting(const Mesh* meshA, const Mesh* meshB, SpatialAccelerator* spAccelA, SpatialAccelerator* spAccelB, BooleanConf mode)
-{
- reset();
- mMeshA = meshA;
- mMeshB = meshB;
- mAcceleratorA = spAccelA;
- mAcceleratorB = spAccelB;
- buildFastFaceFaceIntersection(mode);
- collectRetainedPartsFromA(mode);
- mAcceleratorA = nullptr;
- mAcceleratorB = nullptr;
-}
-
-void BooleanEvaluator::performFastCutting(const Mesh* meshA, const Mesh* meshB, BooleanConf mode)
-{
- reset();
- mMeshA = meshA;
- mMeshB = meshB;
- DummyAccelerator ac = DummyAccelerator(mMeshA->getFacetCount());
- DummyAccelerator bc = DummyAccelerator(mMeshB->getFacetCount());
- performFastCutting(meshA, meshB, &ac, &bc, mode);
-}
-
-
-
-
-BooleanEvaluator::BooleanEvaluator()
-{
- mMeshA = nullptr;
- mMeshB = nullptr;
- mAcceleratorA = nullptr;
- mAcceleratorB = nullptr;
-}
-BooleanEvaluator::~BooleanEvaluator()
-{
- reset();
-}
-
-
-
-Mesh* BooleanEvaluator::createNewMesh()
-{
- if (mEdgeAggregate.size() == 0)
- {
- return nullptr;
- }
- std::sort(mEdgeAggregate.begin(), mEdgeAggregate.end(), EdgeWithParentSortComp);
- std::vector<Facet> newFacets;
- std::vector<Edge> newEdges(mEdgeAggregate.size());
- int32_t lastPos = 0;
- int32_t lastParent = mEdgeAggregate[0].parent;
- uint32_t collected = 0;
- int64_t userData = 0;
- int32_t materialId = 0;
- int32_t smoothingGroup = 0;
-
- for (uint32_t i = 0; i < mEdgeAggregate.size(); ++i)
- {
- if (mEdgeAggregate[i].parent != lastParent)
- {
- if (lastParent < (int32_t)mMeshA->getFacetCount())
- {
- userData = mMeshA->getFacet(lastParent)->userData;
- materialId = mMeshA->getFacet(lastParent)->materialId;
- smoothingGroup = mMeshA->getFacet(lastParent)->smoothingGroup;
-
- }
- else
- {
- userData = mMeshB->getFacet(lastParent - mMeshA->getFacetCount())->userData;
- materialId = mMeshB->getFacet(lastParent - mMeshA->getFacetCount())->materialId;
- smoothingGroup = mMeshB->getFacet(lastParent - mMeshA->getFacetCount())->smoothingGroup;
- }
- newFacets.push_back(Facet(lastPos, collected, materialId, userData, smoothingGroup));
- lastPos = i;
- lastParent = mEdgeAggregate[i].parent;
- collected = 0;
- }
- collected++;
- newEdges[i].s = mEdgeAggregate[i].s;
- newEdges[i].e = mEdgeAggregate[i].e;
- }
- int32_t pr = lastParent - mMeshA->getFacetCount();
- if (lastParent < (int32_t)mMeshA->getFacetCount())
- {
- userData = mMeshA->getFacet(lastParent)->userData;
- materialId = mMeshA->getFacet(lastParent)->materialId;
- smoothingGroup = mMeshA->getFacet(lastParent)->smoothingGroup;
- }
- else
- {
- userData = mMeshB->getFacet(pr)->userData;
- materialId = mMeshB->getFacet(pr)->materialId;
- smoothingGroup = mMeshB->getFacet(pr)->smoothingGroup;
- }
- newFacets.push_back(Facet(lastPos, collected, materialId, userData, smoothingGroup));
- return new MeshImpl(mVerticesAggregate.data(), newEdges.data(), newFacets.data(), static_cast<uint32_t>(mVerticesAggregate.size()), static_cast<uint32_t>(mEdgeAggregate.size()), static_cast<uint32_t>(newFacets.size()));
-}
-
-void BooleanEvaluator::reset()
-{
- mMeshA = nullptr;
- mMeshB = nullptr;
- mAcceleratorA = nullptr;
- mAcceleratorB = nullptr;
- mEdgeAggregate.clear();
- mVerticesAggregate.clear();
- mEdgeFacetIntersectionData12.clear();
- mEdgeFacetIntersectionData21.clear();
-}
-
-} // namespace Blast
-} // namespace Nv
+// This code contains NVIDIA Confidential Information and is disclosed to you
+// under a form of NVIDIA software license agreement provided separately to you.
+//
+// Notice
+// NVIDIA Corporation and its licensors retain all intellectual property and
+// proprietary rights in and to this software and related documentation and
+// any modifications thereto. Any use, reproduction, disclosure, or
+// distribution of this software and related documentation without an express
+// license agreement from NVIDIA Corporation is strictly prohibited.
+//
+// ALL NVIDIA DESIGN SPECIFICATIONS, CODE ARE PROVIDED "AS IS.". NVIDIA MAKES
+// NO WARRANTIES, EXPRESSED, IMPLIED, STATUTORY, OR OTHERWISE WITH RESPECT TO
+// THE MATERIALS, AND EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES OF NONINFRINGEMENT,
+// MERCHANTABILITY, AND FITNESS FOR A PARTICULAR PURPOSE.
+//
+// Information and code furnished is believed to be accurate and reliable.
+// However, NVIDIA Corporation assumes no responsibility for the consequences of use of such
+// information or for any infringement of patents or other rights of third parties that may
+// result from its use. No license is granted by implication or otherwise under any patent
+// or patent rights of NVIDIA Corporation. Details are subject to change without notice.
+// This code supersedes and replaces all information previously supplied.
+// NVIDIA Corporation products are not authorized for use as critical
+// components in life support devices or systems without express written approval of
+// NVIDIA Corporation.
+//
+// Copyright (c) 2016-2018 NVIDIA Corporation. All rights reserved.
+
+
+#include "NvBlastGlobals.h"
+#include "NvBlastExtAuthoringBooleanTool.h"
+#include "NvBlastExtAuthoringMeshImpl.h"
+#include "NvBlastExtAuthoringAccelerator.h"
+
+#include <math.h>
+#include <set>
+#include <algorithm>
+
+using physx::PxVec3;
+using physx::PxVec2;
+using physx::PxBounds3;
+
+
+namespace Nv
+{
+namespace Blast
+{
+
+/* Linear interpolation of vectors */
+
+NV_FORCE_INLINE void vec3Lerp(const PxVec3& a, const PxVec3& b, PxVec3& out, float t)
+{
+ out.x = (b.x - a.x) * t + a.x;
+ out.y = (b.y - a.y) * t + a.y;
+ out.z = (b.z - a.z) * t + a.z;
+}
+
+NV_FORCE_INLINE void vec2Lerp(const PxVec2& a, const PxVec2& b, PxVec2& out, float t)
+{
+ out.x = (b.x - a.x) * t + a.x;
+ out.y = (b.y - a.y) * t + a.y;
+}
+
+NV_FORCE_INLINE int32_t BooleanEvaluator::addIfNotExist(Vertex& p)
+{
+ mVerticesAggregate.push_back(p);
+ return static_cast<int32_t>(mVerticesAggregate.size()) - 1;
+}
+
+NV_FORCE_INLINE void BooleanEvaluator::addEdgeIfValid(EdgeWithParent& ed)
+{
+ mEdgeAggregate.push_back(ed);
+}
+
+/**
+Vertex level shadowing functions
+*/
+NV_FORCE_INLINE int32_t vertexShadowing(const PxVec3& a, const PxVec3& b)
+{
+ return (b.x >= a.x) ? 1 : 0;
+}
+/**
+Vertex-edge status functions
+*/
+NV_FORCE_INLINE int32_t veStatus01(const PxVec3& sEdge, const PxVec3& eEdge, const PxVec3& p)
+{
+ return vertexShadowing(p, eEdge) - vertexShadowing(p, sEdge);
+}
+
+NV_FORCE_INLINE int32_t veStatus10(const PxVec3& sEdge, const PxVec3& eEdge, const PxVec3& p)
+{
+ return -vertexShadowing(eEdge, p) + vertexShadowing(sEdge, p);
+}
+
+bool shouldSwap(const PxVec3& a, const PxVec3& b)
+{
+ if (a.x < b.x) return false;
+ if (a.x > b.x) return true;
+
+ if (a.y < b.y) return false;
+ if (a.y > b.y) return true;
+
+ if (a.z < b.z) return false;
+ if (a.z > b.z) return true;
+ return false;
+}
+
+
+/**
+ Vertex-edge shadowing functions
+*/
+int32_t shadowing01(Vertex sEdge, Vertex eEdge, const PxVec3& p, Vertex& onEdgePoint, bool& hasOnEdge)
+{
+
+ int32_t winding = veStatus01(sEdge.p, eEdge.p, p);
+
+ if (sEdge.p.x > eEdge.p.x)
+ {
+ std::swap(sEdge, eEdge);
+ }
+
+ if (winding != 0)
+ {
+ float t = (p.x - sEdge.p.x) / (eEdge.p.x - sEdge.p.x);
+ if (t >= 1)
+ {
+ onEdgePoint = eEdge;
+ }
+ else if (t <= 0)
+ {
+ onEdgePoint = sEdge;
+ }
+ else
+ {
+ vec3Lerp(sEdge.p, eEdge.p, onEdgePoint.p, t);
+ vec3Lerp(sEdge.n, eEdge.n, onEdgePoint.n, t);
+ vec2Lerp(sEdge.uv[0], eEdge.uv[0], onEdgePoint.uv[0], t);
+ }
+ hasOnEdge = true;
+ if (onEdgePoint.p.y >= p.y)
+ {
+ return winding;
+ }
+ }
+ else
+ {
+ hasOnEdge = false;
+ }
+ return 0;
+}
+int32_t shadowing10(Vertex sEdge, Vertex eEdge, const PxVec3& p, Vertex& onEdgePoint, bool& hasOnEdge)
+{
+ int32_t winding = veStatus10(sEdge.p, eEdge.p, p);
+
+ if (sEdge.p.x > eEdge.p.x)
+ {
+ std::swap(sEdge, eEdge);
+ }
+
+ if (winding != 0)
+ {
+ float t = (p.x - sEdge.p.x) / (eEdge.p.x - sEdge.p.x);
+ if (t >= 1)
+ {
+ onEdgePoint = eEdge;
+ }
+ else if (t <= 0)
+ {
+ onEdgePoint = sEdge;
+ }
+ else
+ {
+ vec3Lerp(sEdge.p, eEdge.p, onEdgePoint.p, t);
+ vec3Lerp(sEdge.n, eEdge.n, onEdgePoint.n, t);
+ vec2Lerp(sEdge.uv[0], eEdge.uv[0], onEdgePoint.uv[0], t);
+ }
+ hasOnEdge = true;
+ if (onEdgePoint.p.y < p.y)
+ {
+ return winding;
+ }
+ }
+ else
+ {
+ hasOnEdge = false;
+ }
+ return 0;
+}
+
+int32_t shadowing01(PxVec3 sEdge, PxVec3 eEdge, const PxVec3& p)
+{
+ int32_t winding = veStatus01(sEdge, eEdge, p);
+
+ if (winding != 0)
+ {
+ if (sEdge.x > eEdge.x)
+ {
+ std::swap(sEdge, eEdge);
+ }
+ float t = ((p.x - sEdge.x) / (eEdge.x - sEdge.x));
+ PxVec3 onEdgePoint;
+ if (t >= 1)
+ onEdgePoint = eEdge;
+ else if (t <= 0)
+ onEdgePoint = sEdge;
+ else
+ vec3Lerp(sEdge, eEdge, onEdgePoint, t);
+ if (onEdgePoint.y >= p.y)
+ {
+ return winding;
+ }
+ }
+ return 0;
+}
+
+int32_t shadowing10(PxVec3 sEdge, PxVec3 eEdge, const PxVec3& p)
+{
+ int32_t winding = veStatus10(sEdge, eEdge, p);
+ if (winding != 0)
+ {
+ if (sEdge.x > eEdge.x)
+ {
+ std::swap(sEdge, eEdge);
+ }
+
+ float t = ((p.x - sEdge.x) / (eEdge.x - sEdge.x));
+ PxVec3 onEdgePoint;
+ if (t >= 1)
+ onEdgePoint = eEdge;
+ else if (t <= 0)
+ onEdgePoint = sEdge;
+ else
+ vec3Lerp(sEdge, eEdge, onEdgePoint, t);
+ if (onEdgePoint.y < p.y)
+ {
+ return winding;
+ }
+ }
+ return 0;
+}
+
+/**
+Vertex-facet shadowing functions
+*/
+
+int32_t vfStatus02(const PxVec3& p, const Vertex* points, const Edge* edges, int32_t edgesCount, Vertex* out)
+{
+ int32_t val = 0;
+ Vertex pnt;
+ bool hasOnEdge = false;
+ out[0].p.y = -MAXIMUM_EXTENT;
+ out[1].p.y = MAXIMUM_EXTENT;
+ for (int32_t i = 0; i < edgesCount; ++i)
+ {
+ val -= shadowing01(points[edges->s], points[edges->e], p, pnt, hasOnEdge);
+ if (hasOnEdge != 0)
+ {
+ if (p.y > pnt.p.y && pnt.p.y > out[0].p.y)
+ {
+ out[0] = pnt;
+ }
+ if (p.y <= pnt.p.y && pnt.p.y < out[1].p.y)
+ {
+ out[1] = pnt;
+ }
+ }
+ ++edges;
+ }
+ return val;
+}
+
+
+int32_t shadowing02(const PxVec3& p, const Vertex* points, const Edge* edges, int edgesCount, bool& hasOnFacetPoint, Vertex& onFacetPoint)
+{
+ Vertex outp[2];
+ int32_t stat = vfStatus02(p, points, edges, edgesCount, outp);
+ float z = 0;
+ hasOnFacetPoint = false;
+ if (stat != 0)
+ {
+ Vertex& p1 = outp[0];
+ Vertex& p2 = outp[1];
+ PxVec3 vc = p2.p - p1.p;
+ float t = 0;
+ t = (std::abs(vc.x) > std::abs(vc.y)) ? (p.x - p1.p.x) / vc.x : (p.y - p1.p.y) / vc.y;
+ t = PxClamp(t, 0.0f, 1.0f);
+
+ z = t * vc.z + p1.p.z;
+ hasOnFacetPoint = true;
+ onFacetPoint.p.x = p.x;
+ onFacetPoint.p.y = p.y;
+ onFacetPoint.p.z = z;
+ vec2Lerp(p1.uv[0], p2.uv[0], onFacetPoint.uv[0], t);
+ vec3Lerp(p1.n, p2.n, onFacetPoint.n, t);
+
+ if (z >= p.z)
+ {
+ return stat;
+ }
+ }
+ return 0;
+}
+
+int32_t vfStatus20(const PxVec3& p, const Vertex* points, const Edge* edges, int32_t edgesCount, Vertex* out)
+{
+ int32_t val = 0;
+ Vertex pnt;
+ bool hasOnEdge = false;
+ out[0].p.y = -MAXIMUM_EXTENT;
+ out[1].p.y = MAXIMUM_EXTENT;
+
+ for (int32_t i = 0; i < edgesCount; ++i)
+ {
+ val += shadowing10(points[edges->s], points[edges->e], p, pnt, hasOnEdge);
+ if (hasOnEdge != 0)
+ {
+ if (p.y > pnt.p.y && pnt.p.y > out[0].p.y)
+ {
+ out[0] = pnt;
+ }
+ if (p.y <= pnt.p.y && pnt.p.y < out[1].p.y)
+ {
+ out[1] = pnt;
+ }
+ }
+ ++edges;
+ }
+ return val;
+}
+
+int32_t shadowing20(const PxVec3& p, const Vertex* points, const Edge* edges, int edgesCount, bool& hasOnFacetPoint, Vertex& onFacetPoint)
+{
+ Vertex outp[2];
+ int32_t stat = vfStatus20(p, points, edges, edgesCount, outp);
+ hasOnFacetPoint = false;
+ if (stat != 0)
+ {
+ Vertex& p1 = outp[0];
+ Vertex& p2 = outp[1];
+ PxVec3 vc = p2.p - p1.p;
+ float t = 0;
+ t = (std::abs(vc.x) > std::abs(vc.y)) ? (p.x - p1.p.x) / vc.x : (p.y - p1.p.y) / vc.y;
+ t = PxClamp(t, 0.0f, 1.0f);
+
+ hasOnFacetPoint = true;
+ onFacetPoint.p.x = p.x;
+ onFacetPoint.p.y = p.y;
+
+ onFacetPoint.p.z = t * vc.z + p1.p.z;
+
+ vec2Lerp(p1.uv[0], p2.uv[0], onFacetPoint.uv[0], t);
+ vec3Lerp(p1.n, p2.n, onFacetPoint.n, t);
+
+ if (onFacetPoint.p.z < p.z)
+ {
+ return stat;
+ }
+ }
+ return 0;
+}
+
+
+NV_FORCE_INLINE int32_t edgesCrossCheck(const PxVec3& eAs, const PxVec3& eAe, const PxVec3& eBs, const PxVec3& eBe)
+{
+ return shadowing01(eBs, eBe, eAe) - shadowing01(eBs, eBe, eAs) + shadowing10(eAs, eAe, eBe) - shadowing10(eAs, eAe, eBs);
+}
+
+
+
+int32_t edgesIntersection(const Vertex& eAs, const Vertex& eAe, const Vertex& eBs, const Vertex& eBe, Vertex& intersectionA, Vertex& intersectionB, bool& hasPoints)
+{
+ int32_t status = edgesCrossCheck(eAs.p, eAe.p, eBs.p, eBe.p);
+ hasPoints = false;
+ if (status == 0)
+ {
+ return 0;
+ }
+
+ Vertex tempPoint;
+ Vertex bShadowingPair[2];
+ Vertex aShadowingPair[2];
+ bool hasOnEdge = false;
+ bool aShadowing = false;
+ bool bShadowing = false;
+
+ /**
+ Search for two pairs where parts of A shadows B, and where B shadows are.
+ Needed for search intersection point.
+ */
+
+ for (auto p : { &eBs, &eBe })
+ {
+ int32_t shadowingType = shadowing10(eAs, eAe, p->p, tempPoint, hasOnEdge);
+ if (shadowingType == 0 && !aShadowing && hasOnEdge)
+ {
+ aShadowing = true;
+ aShadowingPair[0] = *p;
+ aShadowingPair[1] = tempPoint;
+ }
+ else
+ {
+ if ((shadowingType == 1 || shadowingType == -1) && !bShadowing)
+ {
+ bShadowing = true;
+ bShadowingPair[0] = *p;
+ bShadowingPair[1] = tempPoint;
+ }
+ }
+ }
+ if (!aShadowing || !bShadowing)
+ {
+ for (auto p : { &eAs, &eAe })
+ {
+ int32_t shadowingType = shadowing01(eBs, eBe, p->p, tempPoint, hasOnEdge);
+
+ if (shadowingType == 0 && !aShadowing && hasOnEdge)
+ {
+ aShadowing = true;
+ aShadowingPair[1] = *p;
+ aShadowingPair[0] = tempPoint;
+ }
+ else
+ {
+ if ((shadowingType == 1 || shadowingType == -1) && !bShadowing)
+ {
+ bShadowing = true;
+ bShadowingPair[1] = *p;
+ bShadowingPair[0] = tempPoint;
+ }
+ }
+ }
+ }
+
+ float deltaPlus = bShadowingPair[0].p.y - bShadowingPair[1].p.y;
+ float deltaMinus = aShadowingPair[0].p.y - aShadowingPair[1].p.y;
+ float div = 0;
+ if (deltaPlus > 0)
+ div = deltaPlus / (deltaPlus - deltaMinus);
+ else
+ div = 0;
+
+ intersectionA.p = bShadowingPair[1].p - div * (bShadowingPair[1].p - aShadowingPair[1].p);
+ intersectionA.n = bShadowingPair[1].n - div * (bShadowingPair[1].n - aShadowingPair[1].n);
+ intersectionA.uv[0] = bShadowingPair[1].uv[0] - (bShadowingPair[1].uv[0] - aShadowingPair[1].uv[0]) * div;
+ intersectionB.p = intersectionA.p;
+ intersectionB.p.z = bShadowingPair[0].p.z - div * (bShadowingPair[0].p.z - aShadowingPair[0].p.z);
+ intersectionB.n = bShadowingPair[0].n - div * (bShadowingPair[0].n - aShadowingPair[0].n);
+ intersectionB.uv[0] = bShadowingPair[0].uv[0] - (bShadowingPair[0].uv[0] - aShadowingPair[0].uv[0]) * div;
+
+ hasPoints = true;
+ return status;
+}
+
+NV_FORCE_INLINE int32_t edgeEdgeShadowing(const Vertex& eAs, const Vertex& eAe, const Vertex& eBs, const Vertex& eBe, Vertex& intersectionA, Vertex& intersectionB, bool& hasPoints)
+{
+ int32_t status = edgesIntersection(eAs, eAe, eBs, eBe, intersectionA, intersectionB, hasPoints);
+ if (intersectionB.p.z >= intersectionA.p.z)
+ {
+ return status;
+ }
+ return 0;
+}
+
+int32_t edgeFacetIntersection12(const Vertex& edSt, const Vertex& edEnd, const Vertex* points, const Edge* edges, int edgesCount, Vertex& intersectionA, Vertex& intersectionB)
+{
+ int32_t status = 0;
+ Vertex p1, p2;
+ Vertex bShadowingPair[2];
+ Vertex aShadowingPair[2];
+ bool hasPoint = false;
+ bool aShadowing = false;
+ bool bShadowing = false;
+ int32_t mlt = -1;
+ int32_t shadowingType;
+ for (auto p : { &edEnd, &edSt })
+ {
+ shadowingType = shadowing02(p->p, points, edges, edgesCount, hasPoint, p1);
+ status += mlt * shadowingType;
+ if (shadowingType == 0 && !aShadowing && hasPoint)
+ {
+ aShadowing = true;
+ aShadowingPair[0] = p1;
+ aShadowingPair[1] = *p;
+ }
+ else
+ {
+ if ((shadowingType == 1 || shadowingType == -1) && !bShadowing)
+ {
+ bShadowing = true;
+ bShadowingPair[0] = p1;
+ bShadowingPair[1] = *p;
+ }
+ }
+ mlt = 1;
+ }
+
+ for (int32_t ed = 0; ed < edgesCount; ++ed)
+ {
+ if (shouldSwap(points[edges[ed].s].p, points[edges[ed].e].p))
+ {
+ shadowingType = -edgeEdgeShadowing(edSt, edEnd, points[edges[ed].e], points[edges[ed].s], p1, p2, hasPoint);
+ }
+ else
+ {
+ shadowingType = edgeEdgeShadowing(edSt, edEnd, points[edges[ed].s], points[edges[ed].e], p1, p2, hasPoint);
+ }
+ status -= shadowingType;
+ if (shadowingType == 0 && !aShadowing && hasPoint)
+ {
+ aShadowing = true;
+ aShadowingPair[0] = p2;
+ aShadowingPair[1] = p1;
+ }
+ else
+ {
+ if ((shadowingType == 1 || shadowingType == -1) && !bShadowing)
+ {
+ bShadowing = true;
+ bShadowingPair[0] = p2;
+ bShadowingPair[1] = p1;
+ }
+ }
+ }
+ if (!status || !bShadowing || !aShadowing)
+ {
+ return 0;
+ }
+
+ float deltaPlus = bShadowingPair[0].p.z - bShadowingPair[1].p.z;
+ float div = 0;
+ if (deltaPlus != 0)
+ {
+ float deltaMinus = aShadowingPair[0].p.z - aShadowingPair[1].p.z;
+ div = deltaPlus / (deltaPlus - deltaMinus);
+ }
+ intersectionA.p = bShadowingPair[1].p - div * (bShadowingPair[1].p - aShadowingPair[1].p);
+ intersectionA.n = bShadowingPair[1].n - div * (bShadowingPair[1].n - aShadowingPair[1].n);
+ intersectionA.uv[0] = bShadowingPair[1].uv[0] - (bShadowingPair[1].uv[0] - aShadowingPair[1].uv[0]) * div;
+
+ intersectionB.p = intersectionA.p;
+ intersectionB.n = bShadowingPair[0].n - div * (bShadowingPair[0].n - aShadowingPair[0].n);
+ intersectionB.uv[0] = bShadowingPair[0].uv[0] - (bShadowingPair[0].uv[0] - aShadowingPair[0].uv[0]) * div;
+
+
+ return status;
+}
+
+
+int32_t edgeFacetIntersection21(const Vertex& edSt, const Vertex& edEnd, const Vertex* points, const Edge* edges, int edgesCount, Vertex& intersectionA, Vertex& intersectionB)
+{
+ int32_t status = 0;
+ Vertex p1, p2;
+
+ Vertex bShadowingPair[2];
+ Vertex aShadowingPair[2];
+ bool hasPoint = false;
+ bool aShadowing = false;
+ bool bShadowing = false;
+
+ int32_t shadowingType;
+ int32_t mlt = 1;
+ for (auto p : { &edEnd, &edSt })
+ {
+ shadowingType = shadowing20(p->p, points, edges, edgesCount, hasPoint, p1);
+ status += mlt * shadowingType;
+
+ if (shadowingType == 0 && !aShadowing && hasPoint)
+ {
+ aShadowing = true;
+ aShadowingPair[0] = *p;
+ aShadowingPair[1] = p1;
+ }
+ else
+ {
+ if ((shadowingType == 1 || shadowingType == -1) && !bShadowing)
+ {
+ bShadowing = true;
+ bShadowingPair[0] = *p;
+ bShadowingPair[1] = p1;
+ }
+ }
+ mlt = -1;
+ }
+
+ for (int32_t ed = 0; ed < edgesCount; ++ed)
+ {
+ if (shouldSwap(points[edges[ed].s].p, points[edges[ed].e].p))
+ {
+ shadowingType = -edgeEdgeShadowing(points[edges[ed].e], points[edges[ed].s], edSt, edEnd, p1, p2, hasPoint);
+ }
+ else
+ {
+ shadowingType = edgeEdgeShadowing(points[edges[ed].s], points[edges[ed].e], edSt, edEnd, p1, p2, hasPoint);
+ }
+ status -= shadowingType;
+ if (shadowingType == 0)
+ {
+ if (!aShadowing && hasPoint)
+ {
+ aShadowing = true;
+ aShadowingPair[0] = p2;
+ aShadowingPair[1] = p1;
+ }
+ }
+ else
+ {
+ if ((shadowingType == 1 || shadowingType == -1) && !bShadowing)
+ {
+ bShadowing = true;
+ bShadowingPair[0] = p2;
+ bShadowingPair[1] = p1;
+ }
+ }
+ }
+ if (!status || !bShadowing || !aShadowing)
+ {
+ return 0;
+ }
+ float deltaPlus = bShadowingPair[0].p.z - bShadowingPair[1].p.z;
+ float div = 0;
+ if (deltaPlus != 0)
+ {
+ float deltaMinus = aShadowingPair[0].p.z - aShadowingPair[1].p.z;
+ div = deltaPlus / (deltaPlus - deltaMinus);
+ }
+ intersectionA.p = bShadowingPair[1].p - div * (bShadowingPair[1].p - aShadowingPair[1].p);
+ intersectionA.n = bShadowingPair[1].n - div * (bShadowingPair[1].n - aShadowingPair[1].n);
+ intersectionA.uv[0] = bShadowingPair[1].uv[0] - (bShadowingPair[1].uv[0] - aShadowingPair[1].uv[0]) * div;
+
+ intersectionB.p = intersectionA.p;
+ intersectionB.n = bShadowingPair[0].n - div * (bShadowingPair[0].n - aShadowingPair[0].n);
+ intersectionB.uv[0] = bShadowingPair[0].uv[0] - (bShadowingPair[0].uv[0] - aShadowingPair[0].uv[0]) * div;
+
+ return status;
+}
+
+int32_t BooleanEvaluator::vertexMeshStatus03(const PxVec3& p, const Mesh* mesh)
+{
+ int32_t status = 0;
+ Vertex pnt;
+ bool hasPoint = false;
+ mAcceleratorB->setState(p);
+ int32_t facet = mAcceleratorB->getNextFacet();
+ while (facet != -1)
+ {
+ const Edge* ed = mesh->getEdges() + mesh->getFacet(facet)->firstEdgeNumber;
+ status += shadowing02(p, mesh->getVertices(), ed, mesh->getFacet(facet)->edgesCount, hasPoint, pnt);
+ facet = mAcceleratorB->getNextFacet();
+ }
+
+ //for (int32_t facet = 0; facet < mesh->getFacetCount(); ++facet)
+ //{
+ // Edge* ed = mesh->getEdges() + mesh->getFacet(facet)->firstEdgeNumber;
+ // status += shadowing02(p, mesh->getVertices(), ed, mesh->getFacet(facet)->edgesCount, hasPoint, pnt);
+ //};
+ return status;
+}
+
+int32_t BooleanEvaluator::vertexMeshStatus30(const PxVec3& p, const Mesh* mesh)
+{
+ int32_t status = 0;
+ bool hasPoints = false;
+ Vertex point;
+ mAcceleratorA->setState(p);
+ int32_t facet = mAcceleratorA->getNextFacet();
+ while ( facet != -1)
+ {
+ const Edge* ed = mesh->getEdges() + mesh->getFacet(facet)->firstEdgeNumber;
+ status -= shadowing20(p, mesh->getVertices(), ed, mesh->getFacet(facet)->edgesCount, hasPoints, point);
+ facet = mAcceleratorA->getNextFacet();
+ }
+
+ //for (int32_t facet = 0; facet < mesh->getFacetCount(); ++facet)
+ //{
+ // Edge* ed = mesh->getEdges() + mesh->getFacet(facet)->firstEdgeNumber;
+ // status -= shadowing20(p, mesh->getVertices(), ed, mesh->getFacet(facet)->edgesCount, hasPoints, point);
+ //}
+ return status;
+}
+
+NV_FORCE_INLINE int32_t inclusionValue03(BooleanConf& conf, int32_t xValue)
+{
+ return conf.ca + conf.ci * xValue;
+}
+
+NV_FORCE_INLINE int32_t inclusionValueEdgeFace(BooleanConf& conf, int32_t xValue)
+{
+ return conf.ci * xValue;
+}
+
+NV_FORCE_INLINE int32_t inclusionValue30(BooleanConf& conf, int32_t xValue)
+{
+ return conf.cb + conf.ci * xValue;
+}
+
+struct VertexComparator
+{
+ VertexComparator(PxVec3 base = PxVec3()) : basePoint(base) {};
+ PxVec3 basePoint;
+ bool operator()(const Vertex& a, const Vertex& b)
+ {
+ return (b.p - a.p).dot(basePoint) > 0.0;
+ }
+};
+
+struct VertexPairComparator
+{
+ VertexPairComparator(PxVec3 base = PxVec3()) : basePoint(base) {};
+ PxVec3 basePoint;
+ bool operator()(const std::pair<Vertex, Vertex>& a, const std::pair<Vertex, Vertex>& b)
+ {
+ return (b.first.p - a.first.p).dot(basePoint) > 0.0;
+ }
+};
+
+int32_t BooleanEvaluator::isPointContainedInMesh(const Mesh* msh, const PxVec3& point)
+{
+ if (msh == nullptr)
+ {
+ return 0;
+ }
+ DummyAccelerator dmAccel(msh->getFacetCount());
+ mAcceleratorA = &dmAccel;
+ return vertexMeshStatus30(point, msh);
+
+}
+
+int32_t BooleanEvaluator::isPointContainedInMesh(const Mesh* msh, SpatialAccelerator* spAccel, const PxVec3& point)
+{
+ if (msh == nullptr)
+ {
+ return 0;
+ }
+ mAcceleratorA = spAccel;
+ return vertexMeshStatus30(point, msh);
+}
+
+
+
+
+void BooleanEvaluator::buildFaceFaceIntersections(BooleanConf mode)
+{
+ int32_t statusValue = 0;
+ int32_t inclusionValue = 0;
+
+ std::vector<std::pair<Vertex, Vertex> > retainedStarts;
+ std::vector<std::pair<Vertex, Vertex>> retainedEnds;
+ VertexPairComparator comp;
+
+ Vertex newPointA;
+ Vertex newPointB;
+
+ const Vertex* meshAPoints = mMeshA->getVertices();
+ const Vertex* meshBPoints = mMeshB->getVertices();
+ EdgeWithParent newEdge;
+ mEdgeFacetIntersectionData12.clear();
+ mEdgeFacetIntersectionData21.clear();
+
+ mEdgeFacetIntersectionData12.resize(mMeshA->getFacetCount());
+ mEdgeFacetIntersectionData21.resize(mMeshB->getFacetCount());
+
+ for (uint32_t facetB = 0; facetB < mMeshB->getFacetCount(); ++facetB)
+ {
+ mAcceleratorA->setState(mMeshB->getVertices(), mMeshB->getEdges(), *mMeshB->getFacet(facetB));
+ int32_t facetA = mAcceleratorA->getNextFacet();
+ while (facetA != -1)
+ {
+ const Edge* facetBEdges = mMeshB->getEdges() + mMeshB->getFacet(facetB)->firstEdgeNumber;
+ const Edge* facetAEdges = mMeshA->getEdges() + mMeshA->getFacet(facetA)->firstEdgeNumber;
+ const Edge* fbe = facetBEdges;
+ const Edge* fae = facetAEdges;
+ retainedStarts.clear();
+ retainedEnds.clear();
+ PxVec3 compositeEndPoint(0, 0, 0);
+ PxVec3 compositeStartPoint(0, 0, 0);
+ uint32_t facetAEdgeCount = mMeshA->getFacet(facetA)->edgesCount;
+ uint32_t facetBEdgeCount = mMeshB->getFacet(facetB)->edgesCount;
+ int32_t ic = 0;
+ for (uint32_t i = 0; i < facetAEdgeCount; ++i)
+ {
+ if (shouldSwap(meshAPoints[fae->e].p, meshAPoints[fae->s].p))
+ {
+ statusValue = -edgeFacetIntersection12(meshAPoints[fae->e], meshAPoints[fae->s], mMeshB->getVertices(), facetBEdges, facetBEdgeCount, newPointA, newPointB);
+ }
+ else
+ {
+ statusValue = edgeFacetIntersection12(meshAPoints[fae->s], meshAPoints[fae->e], mMeshB->getVertices(), facetBEdges, facetBEdgeCount, newPointA, newPointB);
+ }
+
+ inclusionValue = -inclusionValueEdgeFace(mode, statusValue);
+ if (inclusionValue > 0)
+ {
+ for (ic = 0; ic < inclusionValue; ++ic)
+ {
+ retainedEnds.push_back(std::make_pair(newPointA, newPointB));
+ compositeEndPoint += newPointA.p;
+ }
+ mEdgeFacetIntersectionData12[facetA].push_back(EdgeFacetIntersectionData(i, statusValue, newPointA));
+ }
+ if (inclusionValue < 0)
+ {
+ for (ic = 0; ic < -inclusionValue; ++ic)
+ {
+ retainedStarts.push_back(std::make_pair(newPointA, newPointB));
+ compositeStartPoint += newPointA.p;
+ }
+ mEdgeFacetIntersectionData12[facetA].push_back(EdgeFacetIntersectionData(i, statusValue, newPointA));
+ }
+ fae++;
+ }
+ for (uint32_t i = 0; i < facetBEdgeCount; ++i)
+ {
+ if (shouldSwap(meshBPoints[fbe->e].p, meshBPoints[fbe->s].p))
+ {
+ statusValue = -edgeFacetIntersection21(meshBPoints[(fbe)->e], meshBPoints[(fbe)->s], mMeshA->getVertices(), facetAEdges, facetAEdgeCount, newPointA, newPointB);
+ }
+ else
+ {
+ statusValue = edgeFacetIntersection21(meshBPoints[(fbe)->s], meshBPoints[(fbe)->e], mMeshA->getVertices(), facetAEdges, facetAEdgeCount, newPointA, newPointB);
+ }
+ inclusionValue = inclusionValueEdgeFace(mode, statusValue);
+ if (inclusionValue > 0)
+ {
+ for (ic = 0; ic < inclusionValue; ++ic)
+ {
+ retainedEnds.push_back(std::make_pair(newPointA, newPointB));
+ compositeEndPoint += newPointB.p;
+ }
+ mEdgeFacetIntersectionData21[facetB].push_back(EdgeFacetIntersectionData( i, statusValue, newPointB));
+ }
+ if (inclusionValue < 0)
+ {
+ for (ic = 0; ic < -inclusionValue; ++ic)
+ {
+ retainedStarts.push_back(std::make_pair(newPointA, newPointB));
+ compositeStartPoint += newPointB.p;
+ }
+ mEdgeFacetIntersectionData21[facetB].push_back(EdgeFacetIntersectionData(i, statusValue, newPointB));
+ }
+ fbe++;
+ }
+ if (retainedStarts.size() != retainedEnds.size())
+ {
+ NVBLAST_LOG_ERROR("Not equal number of starting and ending vertices! Probably input mesh has open edges.");
+ return;
+ }
+ if (retainedStarts.size() > 1)
+ {
+ comp.basePoint = compositeEndPoint - compositeStartPoint;
+ std::sort(retainedStarts.begin(), retainedStarts.end(), comp);
+ std::sort(retainedEnds.begin(), retainedEnds.end(), comp);
+ }
+ for (uint32_t rv = 0; rv < retainedStarts.size(); ++rv)
+ {
+ newEdge.s = addIfNotExist(retainedStarts[rv].first);
+ newEdge.e = addIfNotExist(retainedEnds[rv].first);
+ newEdge.parent = facetA;
+ addEdgeIfValid(newEdge);
+ newEdge.parent = facetB + mMeshA->getFacetCount();
+ newEdge.e = addIfNotExist(retainedStarts[rv].second);
+ newEdge.s = addIfNotExist(retainedEnds[rv].second);
+ addEdgeIfValid(newEdge);
+ }
+ facetA = mAcceleratorA->getNextFacet();
+ } // while (*iter != -1)
+
+ } // for (uint32_t facetB = 0; facetB < mMeshB->getFacetCount(); ++facetB)
+
+
+
+}
+
+
+void BooleanEvaluator::buildFastFaceFaceIntersection(BooleanConf mode)
+{
+ int32_t statusValue = 0;
+ int32_t inclusionValue = 0;
+
+ std::vector<std::pair<Vertex, Vertex> > retainedStarts;
+ std::vector<std::pair<Vertex, Vertex>> retainedEnds;
+ VertexPairComparator comp;
+
+ Vertex newPointA;
+ Vertex newPointB;
+
+ const Vertex* meshAPoints = mMeshA->getVertices();
+ EdgeWithParent newEdge;
+
+ mEdgeFacetIntersectionData12.clear();
+ mEdgeFacetIntersectionData21.clear();
+
+ mEdgeFacetIntersectionData12.resize(mMeshA->getFacetCount());
+ mEdgeFacetIntersectionData21.resize(mMeshB->getFacetCount());
+
+ for (uint32_t facetA = 0; facetA < mMeshA->getFacetCount(); ++facetA)
+ {
+ const Edge* facetAEdges = mMeshA->getEdges() + mMeshA->getFacet(facetA)->firstEdgeNumber;
+ int32_t facetB = 0;
+ const Edge* facetBEdges = mMeshB->getEdges() + mMeshB->getFacet(facetB)->firstEdgeNumber;
+ const Edge* fae = facetAEdges;
+ retainedStarts.clear();
+ retainedEnds.clear();
+ PxVec3 compositeEndPoint(0, 0, 0);
+ PxVec3 compositeStartPoint(0, 0, 0);
+ uint32_t facetAEdgeCount = mMeshA->getFacet(facetA)->edgesCount;
+ uint32_t facetBEdgeCount = mMeshB->getFacet(facetB)->edgesCount;
+ int32_t ic = 0;
+ for (uint32_t i = 0; i < facetAEdgeCount; ++i)
+ {
+ if (shouldSwap(meshAPoints[fae->e].p, meshAPoints[fae->s].p))
+ {
+ statusValue = -edgeFacetIntersection12(meshAPoints[fae->e], meshAPoints[fae->s], mMeshB->getVertices(), facetBEdges, facetBEdgeCount, newPointA, newPointB);
+ }
+ else
+ {
+ statusValue = edgeFacetIntersection12(meshAPoints[fae->s], meshAPoints[fae->e], mMeshB->getVertices(), facetBEdges, facetBEdgeCount, newPointA, newPointB);
+ }
+ inclusionValue = -inclusionValueEdgeFace(mode, statusValue);
+ if (inclusionValue > 0)
+ {
+ for (ic = 0; ic < inclusionValue; ++ic)
+ {
+ retainedEnds.push_back(std::make_pair(newPointA, newPointB));
+ compositeEndPoint += newPointA.p;
+ }
+ mEdgeFacetIntersectionData12[facetA].push_back(EdgeFacetIntersectionData(i, statusValue, newPointA));
+ }
+ if (inclusionValue < 0)
+ {
+ for (ic = 0; ic < -inclusionValue; ++ic)
+ {
+ retainedStarts.push_back(std::make_pair(newPointA, newPointB));
+ compositeStartPoint += newPointA.p;
+ }
+ mEdgeFacetIntersectionData12[facetA].push_back(EdgeFacetIntersectionData(i, statusValue, newPointA));
+ }
+ fae++;
+ }
+ if (retainedStarts.size() != retainedEnds.size())
+ {
+ NVBLAST_LOG_ERROR("Not equal number of starting and ending vertices! Probably input mesh has open edges.");
+ return;
+ }
+ if (retainedStarts.size() > 1)
+ {
+ comp.basePoint = compositeEndPoint - compositeStartPoint;
+ std::sort(retainedStarts.begin(), retainedStarts.end(), comp);
+ std::sort(retainedEnds.begin(), retainedEnds.end(), comp);
+ }
+ for (uint32_t rv = 0; rv < retainedStarts.size(); ++rv)
+ {
+ newEdge.s = addIfNotExist(retainedStarts[rv].first);
+ newEdge.e = addIfNotExist(retainedEnds[rv].first);
+ newEdge.parent = facetA;
+ addEdgeIfValid(newEdge);
+ newEdge.parent = facetB + mMeshA->getFacetCount();
+ newEdge.e = addIfNotExist(retainedStarts[rv].second);
+ newEdge.s = addIfNotExist(retainedEnds[rv].second);
+ addEdgeIfValid(newEdge);
+ }
+ }
+
+}
+
+
+
+void BooleanEvaluator::collectRetainedPartsFromA(BooleanConf mode)
+{
+
+ int32_t statusValue = 0;
+ int32_t inclusionValue = 0;
+ const Vertex* vertices = mMeshA->getVertices();
+ Vertex newPoint;
+ VertexComparator comp;
+ const PxBounds3& bMeshBoudning = mMeshB->getBoundingBox();
+ const Edge* facetEdges = mMeshA->getEdges();
+ std::vector<Vertex> retainedStartVertices;
+ std::vector<Vertex> retainedEndVertices;
+ retainedStartVertices.reserve(255);
+ retainedEndVertices.reserve(255);
+ int32_t ic = 0;
+ for (uint32_t facetId = 0; facetId < mMeshA->getFacetCount(); ++facetId)
+ {
+ retainedStartVertices.clear();
+ retainedEndVertices.clear();
+ for (uint32_t i = 0; i < mMeshA->getFacet(facetId)->edgesCount; ++i)
+ {
+ PxVec3 compositeEndPoint(0, 0, 0);
+ PxVec3 compositeStartPoint(0, 0, 0);
+
+ int32_t lastPos = static_cast<int32_t>(retainedEndVertices.size());
+ /* Test start and end point of edge against mesh */
+ if (bMeshBoudning.contains(vertices[facetEdges->s].p))
+ {
+ statusValue = vertexMeshStatus03(vertices[facetEdges->s].p, mMeshB);
+ }
+ else
+ {
+ statusValue = 0;
+ }
+ inclusionValue = -inclusionValue03(mode, statusValue);
+
+ if (inclusionValue > 0)
+ {
+ for (ic = 0; ic < inclusionValue; ++ic)
+ {
+ retainedEndVertices.push_back(vertices[facetEdges->s]);
+ compositeEndPoint += vertices[facetEdges->s].p;
+ }
+ }
+ else
+ {
+ if (inclusionValue < 0)
+ {
+ for (ic = 0; ic < -inclusionValue; ++ic)
+ {
+ retainedStartVertices.push_back(vertices[facetEdges->s]);
+ compositeStartPoint += vertices[facetEdges->s].p;
+ }
+ }
+ }
+
+ if (bMeshBoudning.contains(vertices[facetEdges->e].p))
+ {
+ statusValue = vertexMeshStatus03(vertices[facetEdges->e].p, mMeshB);
+ }
+ else
+ {
+ statusValue = 0;
+ }
+ inclusionValue = inclusionValue03(mode, statusValue);
+ if (inclusionValue > 0)
+ {
+ for (ic = 0; ic < inclusionValue; ++ic)
+ {
+ retainedEndVertices.push_back(vertices[facetEdges->e]);
+ compositeEndPoint += vertices[facetEdges->e].p;
+ }
+ }
+ else
+ {
+ if (inclusionValue < 0)
+ {
+ for (ic = 0; ic < -inclusionValue; ++ic)
+ {
+ retainedStartVertices.push_back(vertices[facetEdges->e]);
+ compositeStartPoint += vertices[facetEdges->e].p;
+ }
+ }
+ }
+ /* Test edge intersection with mesh*/
+ for (uint32_t intrs = 0; intrs < mEdgeFacetIntersectionData12[facetId].size(); ++intrs)
+ {
+ EdgeFacetIntersectionData& intr = mEdgeFacetIntersectionData12[facetId][intrs];
+ if (intr.edId != (int32_t)i)
+ continue;
+ newPoint = intr.intersectionPoint;
+ inclusionValue = inclusionValueEdgeFace(mode, intr.intersectionType);
+
+ if (inclusionValue > 0)
+ {
+ for (ic = 0; ic < inclusionValue; ++ic)
+ {
+ retainedEndVertices.push_back(newPoint);
+ compositeEndPoint += newPoint.p;
+ }
+ }
+ else
+ {
+ if (inclusionValue < 0)
+ {
+ for (ic = 0; ic < -inclusionValue; ++ic)
+ {
+ retainedStartVertices.push_back(newPoint);
+ compositeStartPoint += newPoint.p;
+ }
+ }
+ }
+ }
+ facetEdges++;
+ if (retainedStartVertices.size() != retainedEndVertices.size())
+ {
+ NVBLAST_LOG_ERROR("Not equal number of starting and ending vertices! Probably input mesh has open edges.");
+ return;
+ }
+ if (retainedEndVertices.size() > 1)
+ {
+ comp.basePoint = compositeEndPoint - compositeStartPoint;
+ std::sort(retainedStartVertices.begin() + lastPos, retainedStartVertices.end(), comp);
+ std::sort(retainedEndVertices.begin() + lastPos, retainedEndVertices.end(), comp);
+ }
+ }
+
+
+ EdgeWithParent newEdge;
+ for (uint32_t rv = 0; rv < retainedStartVertices.size(); ++rv)
+ {
+ newEdge.s = addIfNotExist(retainedStartVertices[rv]);
+ newEdge.e = addIfNotExist(retainedEndVertices[rv]);
+ newEdge.parent = facetId;
+ addEdgeIfValid(newEdge);
+ }
+ }
+
+ return;
+}
+
+void BooleanEvaluator::collectRetainedPartsFromB(BooleanConf mode)
+{
+ int32_t statusValue = 0;
+ int32_t inclusionValue = 0;
+ const Vertex* vertices = mMeshB->getVertices();
+ Vertex newPoint;
+ VertexComparator comp;
+ const PxBounds3& aMeshBoudning = mMeshA->getBoundingBox();
+ const Edge* facetEdges = mMeshB->getEdges();
+ std::vector<Vertex> retainedStartVertices;
+ std::vector<Vertex> retainedEndVertices;
+ retainedStartVertices.reserve(255);
+ retainedEndVertices.reserve(255);
+ int32_t ic = 0;
+ for (uint32_t facetId = 0; facetId < mMeshB->getFacetCount(); ++facetId)
+ {
+ retainedStartVertices.clear();
+ retainedEndVertices.clear();
+ for (uint32_t i = 0; i < mMeshB->getFacet(facetId)->edgesCount; ++i)
+ {
+ PxVec3 compositeEndPoint(0, 0, 0);
+ PxVec3 compositeStartPoint(0, 0, 0);
+ int32_t lastPos = static_cast<int32_t>(retainedEndVertices.size());
+ if (aMeshBoudning.contains(vertices[facetEdges->s].p))
+ {
+ statusValue = vertexMeshStatus30(vertices[facetEdges->s].p, mMeshA);
+ }
+ else
+ {
+ statusValue = 0;
+ }
+ inclusionValue = -inclusionValue30(mode, statusValue);
+
+ if (inclusionValue > 0)
+ {
+ for (ic = 0; ic < inclusionValue; ++ic)
+ {
+ retainedEndVertices.push_back(vertices[facetEdges->s]);
+ compositeEndPoint += vertices[facetEdges->s].p;
+ }
+
+ }
+ else
+ {
+ if (inclusionValue < 0)
+ {
+ for (ic = 0; ic < -inclusionValue; ++ic)
+ {
+ retainedStartVertices.push_back(vertices[facetEdges->s]);
+ compositeStartPoint += vertices[facetEdges->s].p;
+ }
+
+ }
+ }
+
+ if (aMeshBoudning.contains(vertices[facetEdges->e].p))
+ {
+ statusValue = vertexMeshStatus30(vertices[facetEdges->e].p, mMeshA);
+ }
+ else
+ {
+ statusValue = 0;
+ }
+ inclusionValue = inclusionValue30(mode, statusValue);
+ if (inclusionValue > 0)
+ {
+ for (ic = 0; ic < inclusionValue; ++ic)
+ {
+ retainedEndVertices.push_back(vertices[facetEdges->e]);
+ compositeEndPoint += vertices[facetEdges->e].p;
+ }
+
+ }
+ else
+ {
+ if (inclusionValue < 0)
+ {
+ for (ic = 0; ic < -inclusionValue; ++ic)
+ {
+ retainedStartVertices.push_back(vertices[facetEdges->e]);
+ compositeStartPoint += vertices[facetEdges->e].p;
+ }
+
+ }
+ }
+ for (uint32_t intrs = 0; intrs < mEdgeFacetIntersectionData21[facetId].size(); ++intrs)
+ {
+ EdgeFacetIntersectionData& intr = mEdgeFacetIntersectionData21[facetId][intrs];
+ if (intr.edId != (int32_t)i)
+ continue;
+ newPoint = intr.intersectionPoint;
+ inclusionValue = inclusionValueEdgeFace(mode, intr.intersectionType);
+
+ if (inclusionValue > 0)
+ {
+ for (ic = 0; ic < inclusionValue; ++ic)
+ {
+ retainedEndVertices.push_back(newPoint);
+ compositeEndPoint += newPoint.p;
+ }
+ }
+ else
+ {
+ if (inclusionValue < 0)
+ {
+ for (ic = 0; ic < -inclusionValue; ++ic)
+ {
+ retainedStartVertices.push_back(newPoint);
+ compositeStartPoint += newPoint.p;
+ }
+ }
+ }
+ }
+ facetEdges++;
+ if (retainedStartVertices.size() != retainedEndVertices.size())
+ {
+ NVBLAST_LOG_ERROR("Not equal number of starting and ending vertices! Probably input mesh has open edges.");
+ return;
+ }
+ if (retainedEndVertices.size() - lastPos > 1)
+ {
+ comp.basePoint = compositeEndPoint - compositeStartPoint;
+ std::sort(retainedStartVertices.begin() + lastPos, retainedStartVertices.end(), comp);
+ std::sort(retainedEndVertices.begin() + lastPos, retainedEndVertices.end(), comp);
+ }
+ }
+ EdgeWithParent newEdge;
+ for (uint32_t rv = 0; rv < retainedStartVertices.size(); ++rv)
+ {
+ newEdge.s = addIfNotExist(retainedStartVertices[rv]);
+ newEdge.e = addIfNotExist(retainedEndVertices[rv]);
+ newEdge.parent = facetId + mMeshA->getFacetCount();
+ addEdgeIfValid(newEdge);
+ }
+ }
+ return;
+}
+
+bool EdgeWithParentSortComp(const EdgeWithParent& a, const EdgeWithParent& b)
+{
+ return a.parent < b.parent;
+}
+
+
+void BooleanEvaluator::performBoolean(const Mesh* meshA, const Mesh* meshB, SpatialAccelerator* spAccelA, SpatialAccelerator* spAccelB, BooleanConf mode)
+{
+ reset();
+ mMeshA = meshA;
+ mMeshB = meshB;
+ mAcceleratorA = spAccelA;
+ mAcceleratorB = spAccelB;
+ buildFaceFaceIntersections(mode);
+ collectRetainedPartsFromA(mode);
+ collectRetainedPartsFromB(mode);
+ mAcceleratorA = nullptr;
+ mAcceleratorB = nullptr;
+}
+
+void BooleanEvaluator::performBoolean(const Mesh* meshA, const Mesh* meshB, BooleanConf mode)
+{
+ reset();
+ mMeshA = meshA;
+ mMeshB = meshB;
+ DummyAccelerator ac = DummyAccelerator(mMeshA->getFacetCount());
+ DummyAccelerator bc = DummyAccelerator(mMeshB->getFacetCount());
+ performBoolean(meshA, meshB, &ac, &bc, mode);
+}
+
+
+void BooleanEvaluator::performFastCutting(const Mesh* meshA, const Mesh* meshB, SpatialAccelerator* spAccelA, SpatialAccelerator* spAccelB, BooleanConf mode)
+{
+ reset();
+ mMeshA = meshA;
+ mMeshB = meshB;
+ mAcceleratorA = spAccelA;
+ mAcceleratorB = spAccelB;
+ buildFastFaceFaceIntersection(mode);
+ collectRetainedPartsFromA(mode);
+ mAcceleratorA = nullptr;
+ mAcceleratorB = nullptr;
+}
+
+void BooleanEvaluator::performFastCutting(const Mesh* meshA, const Mesh* meshB, BooleanConf mode)
+{
+ reset();
+ mMeshA = meshA;
+ mMeshB = meshB;
+ DummyAccelerator ac = DummyAccelerator(mMeshA->getFacetCount());
+ DummyAccelerator bc = DummyAccelerator(mMeshB->getFacetCount());
+ performFastCutting(meshA, meshB, &ac, &bc, mode);
+}
+
+
+
+
+BooleanEvaluator::BooleanEvaluator()
+{
+ mMeshA = nullptr;
+ mMeshB = nullptr;
+ mAcceleratorA = nullptr;
+ mAcceleratorB = nullptr;
+}
+BooleanEvaluator::~BooleanEvaluator()
+{
+ reset();
+}
+
+
+
+Mesh* BooleanEvaluator::createNewMesh()
+{
+ if (mEdgeAggregate.size() == 0)
+ {
+ return nullptr;
+ }
+ std::sort(mEdgeAggregate.begin(), mEdgeAggregate.end(), EdgeWithParentSortComp);
+ std::vector<Facet> newFacets;
+ std::vector<Edge> newEdges(mEdgeAggregate.size());
+ int32_t lastPos = 0;
+ int32_t lastParent = mEdgeAggregate[0].parent;
+ uint32_t collected = 0;
+ int64_t userData = 0;
+ int32_t materialId = 0;
+ int32_t smoothingGroup = 0;
+
+ for (uint32_t i = 0; i < mEdgeAggregate.size(); ++i)
+ {
+ if (mEdgeAggregate[i].parent != lastParent)
+ {
+ if (lastParent < (int32_t)mMeshA->getFacetCount())
+ {
+ userData = mMeshA->getFacet(lastParent)->userData;
+ materialId = mMeshA->getFacet(lastParent)->materialId;
+ smoothingGroup = mMeshA->getFacet(lastParent)->smoothingGroup;
+
+ }
+ else
+ {
+ userData = mMeshB->getFacet(lastParent - mMeshA->getFacetCount())->userData;
+ materialId = mMeshB->getFacet(lastParent - mMeshA->getFacetCount())->materialId;
+ smoothingGroup = mMeshB->getFacet(lastParent - mMeshA->getFacetCount())->smoothingGroup;
+ }
+ newFacets.push_back(Facet(lastPos, collected, materialId, userData, smoothingGroup));
+ lastPos = i;
+ lastParent = mEdgeAggregate[i].parent;
+ collected = 0;
+ }
+ collected++;
+ newEdges[i].s = mEdgeAggregate[i].s;
+ newEdges[i].e = mEdgeAggregate[i].e;
+ }
+ int32_t pr = lastParent - mMeshA->getFacetCount();
+ if (lastParent < (int32_t)mMeshA->getFacetCount())
+ {
+ userData = mMeshA->getFacet(lastParent)->userData;
+ materialId = mMeshA->getFacet(lastParent)->materialId;
+ smoothingGroup = mMeshA->getFacet(lastParent)->smoothingGroup;
+ }
+ else
+ {
+ userData = mMeshB->getFacet(pr)->userData;
+ materialId = mMeshB->getFacet(pr)->materialId;
+ smoothingGroup = mMeshB->getFacet(pr)->smoothingGroup;
+ }
+ newFacets.push_back(Facet(lastPos, collected, materialId, userData, smoothingGroup));
+ return new MeshImpl(mVerticesAggregate.data(), newEdges.data(), newFacets.data(), static_cast<uint32_t>(mVerticesAggregate.size()), static_cast<uint32_t>(mEdgeAggregate.size()), static_cast<uint32_t>(newFacets.size()));
+}
+
+void BooleanEvaluator::reset()
+{
+ mMeshA = nullptr;
+ mMeshB = nullptr;
+ mAcceleratorA = nullptr;
+ mAcceleratorB = nullptr;
+ mEdgeAggregate.clear();
+ mVerticesAggregate.clear();
+ mEdgeFacetIntersectionData12.clear();
+ mEdgeFacetIntersectionData21.clear();
+}
+
+} // namespace Blast
+} // namespace Nv