delete [] myVoxelData;
}
-#if defined (_WIN32) && defined (max)
- #undef max
-#endif
-
-#include <limits>
-
-#define BVH_DOT3(A, B) (A.x() * B.x() + A.y() * B.y() + A.z() * B.z())
-
namespace BVH
{
//=======================================================================
aNearestY * aNearestY +
aNearestZ * aNearestZ;
}
+}
- //=======================================================================
- //function : DirectionToNearestPoint
- //purpose : Computes squared distance from point to triangle
- // ======================================================================
- template<class T, int N>
- typename VectorType<T, N>::Type DirectionToNearestPoint (
- const typename VectorType<T, N>::Type& thePoint,
- const typename VectorType<T, N>::Type& theVertA,
- const typename VectorType<T, N>::Type& theVertB,
- const typename VectorType<T, N>::Type& theVertC)
- {
- Standard_STATIC_ASSERT (N == 3 || N == 4);
+#define BVH_DOT3(A, B) (A.x() * B.x() + A.y() * B.y() + A.z() * B.z())
- const typename VectorType<T, N>::Type aAB = theVertB - theVertA;
- const typename VectorType<T, N>::Type aAC = theVertC - theVertA;
- const typename VectorType<T, N>::Type aAP = thePoint - theVertA;
+//=======================================================================
+//function : directToTrg
+//purpose : Returns closest feature and direction to it
+// ======================================================================
+template<class T, int N>
+std::pair<typename BVH_DistanceField<T, N>::BVH_VecNt, typename BVH_DistanceField<T, N>::Feature>
+ BVH_DistanceField<T, N>::directToTrg (const BVH_VecNt& thePnt, const Standard_Integer theTrgIdx)
+{
+ Standard_STATIC_ASSERT (N == 3 || N == 4);
- const T aABdotAP = BVH_DOT3 (aAB, aAP);
- const T aACdotAP = BVH_DOT3 (aAC, aAP);
+ const BVH_Vec4i aTrg = myMesh->Elements[theTrgIdx];
- if (aABdotAP <= static_cast<T> (0) && aACdotAP <= static_cast<T> (0))
- {
- return aAP;
- }
+ const BVH_VecNt aVertA = myMesh->Vertices[aTrg.x()];
+ const BVH_VecNt aVertB = myMesh->Vertices[aTrg.y()];
+ const BVH_VecNt aVertC = myMesh->Vertices[aTrg.z()];
- const typename VectorType<T, N>::Type aBC = theVertC - theVertB;
- const typename VectorType<T, N>::Type aBP = thePoint - theVertB;
+ const BVH_VecNt aAB = aVertB - aVertA;
+ const BVH_VecNt aAC = aVertC - aVertA;
+ const BVH_VecNt aAP = thePnt - aVertA;
- const T aBAdotBP = -BVH_DOT3 (aAB, aBP);
- const T aBCdotBP = BVH_DOT3 (aBC, aBP);
+ const T aABdotAP = BVH_DOT3 (aAB, aAP);
+ const T aACdotAP = BVH_DOT3 (aAC, aAP);
- if (aBAdotBP <= static_cast<T> (0) && aBCdotBP <= static_cast<T> (0))
- {
- return aBP;
- }
+ if (aABdotAP <= static_cast<T> (0) && aACdotAP <= static_cast<T> (0))
+ {
+ return std::make_pair (aAP, Feature (VERT_ID, aTrg.x()));
+ }
- const typename VectorType<T, N>::Type aCP = thePoint - theVertC;
+ const BVH_VecNt aBC = aVertC - aVertB;
+ const BVH_VecNt aBP = thePnt - aVertB;
- const T aCBdotCP = -BVH_DOT3 (aBC, aCP);
- const T aCAdotCP = -BVH_DOT3 (aAC, aCP);
+ const T aBAdotBP = -BVH_DOT3 (aAB, aBP);
+ const T aBCdotBP = BVH_DOT3 (aBC, aBP);
- if (aCAdotCP <= static_cast<T> (0) && aCBdotCP <= static_cast<T> (0))
- {
- return aCP;
- }
+ if (aBAdotBP <= static_cast<T> (0) && aBCdotBP <= static_cast<T> (0))
+ {
+ return std::make_pair (aBP, Feature (VERT_ID, aTrg.y()));
+ }
- const T aACdotBP = BVH_DOT3 (aAC, aBP);
+ const BVH_VecNt aCP = thePnt - aVertC;
- const T aVC = aABdotAP * aACdotBP + aBAdotBP * aACdotAP;
+ const T aCBdotCP = -BVH_DOT3 (aBC, aCP);
+ const T aCAdotCP = -BVH_DOT3 (aAC, aCP);
- if (aVC <= static_cast<T> (0) && aABdotAP >= static_cast<T> (0) && aBAdotBP >= static_cast<T> (0))
- {
- return aAP - aAB * (aABdotAP / (aABdotAP + aBAdotBP));
- }
+ if (aCAdotCP <= static_cast<T> (0) && aCBdotCP <= static_cast<T> (0))
+ {
+ return std::make_pair (aCP, Feature (VERT_ID, aTrg.z()));
+ }
- const T aABdotCP = BVH_DOT3 (aAB, aCP);
+ const T aACdotBP = BVH_DOT3 (aAC, aBP);
- const T aVA = aBAdotBP * aCAdotCP - aABdotCP * aACdotBP;
+ const T aVC = aABdotAP * aACdotBP + aBAdotBP * aACdotAP;
- if (aVA <= static_cast<T> (0) && aBCdotBP >= static_cast<T> (0) && aCBdotCP >= static_cast<T> (0))
- {
- return aBP - aBC * (aBCdotBP / (aBCdotBP + aCBdotCP));
- }
+ if (aVC <= static_cast<T> (0) && aABdotAP >= static_cast<T> (0) && aBAdotBP >= static_cast<T> (0))
+ {
+ return std::make_pair (aAP - aAB * (aABdotAP / (aABdotAP + aBAdotBP)), Feature (aTrg.x(), aTrg.y()));
+ }
- const T aVB = aABdotCP * aACdotAP + aABdotAP * aCAdotCP;
+ const T aABdotCP = BVH_DOT3 (aAB, aCP);
- if (aVB <= static_cast<T> (0) && aACdotAP >= static_cast<T> (0) && aCAdotCP >= static_cast<T> (0))
- {
- return aAP - aAC * (aACdotAP / (aACdotAP + aCAdotCP));
- }
+ const T aVA = aBAdotBP * aCAdotCP - aABdotCP * aACdotBP;
- const T aNorm = static_cast<T> (1.0) / (aVA + aVB + aVC);
+ if (aVA <= static_cast<T> (0) && aBCdotBP >= static_cast<T> (0) && aCBdotCP >= static_cast<T> (0))
+ {
+ return std::make_pair (aBP - aBC * (aBCdotBP / (aBCdotBP + aCBdotCP)), Feature (aTrg.y(), aTrg.z()));
+ }
- const T aU = aVA * aNorm;
- const T aV = aVB * aNorm;
+ const T aVB = aABdotCP * aACdotAP + aABdotAP * aCAdotCP;
- return thePoint - (theVertA * aU + theVertB * aV + theVertC * (static_cast<T> (1.0) - aU - aV));
+ if (aVB <= static_cast<T> (0) && aACdotAP >= static_cast<T> (0) && aCAdotCP >= static_cast<T> (0))
+ {
+ return std::make_pair (aAP - aAC * (aACdotAP / (aACdotAP + aCAdotCP)), Feature (aTrg.x(), aTrg.z()));
}
- //=======================================================================
- //function : SquareDistanceToObject
- //purpose : Computes squared distance from point to BVH triangulation
- //=======================================================================
- template<class T, int N>
- T SquareDistanceToObject (BVH_Object<T, N>* theObject,
- const typename VectorType<T, N>::Type& thePnt, Standard_Boolean& theIsOutside)
- {
- Standard_STATIC_ASSERT (N == 3 || N == 4);
+ const T aNorm = static_cast<T> (1.0) / (aVA + aVB + aVC);
- T aMinDistance = std::numeric_limits<T>::max();
+ const T aU = aVA * aNorm;
+ const T aV = aVB * aNorm;
- BVH_Triangulation<T, N>* aTriangulation =
- dynamic_cast<BVH_Triangulation<T, N>*> (theObject);
+ const BVH_VecNt aDirect = thePnt - (aVertA * aU + aVertB * aV + aVertC * (static_cast<T> (1.0) - aU - aV));
- Standard_ASSERT_RETURN (aTriangulation != NULL,
- "Error: Unsupported BVH object (non triangulation)", aMinDistance);
+ return std::make_pair (aDirect, Feature (FACE_ID, theTrgIdx));
+}
- const NCollection_Handle<BVH_Tree<T, N> >& aBVH = aTriangulation->BVH();
+//=======================================================================
+//function : squareDistanceToMesh
+//purpose : Computes squared distance from point to BVH triangulation
+//=======================================================================
+template<class T, int N>
+T BVH_DistanceField<T, N>::squareDistanceToMesh (const BVH_VecNt& thePnt, Standard_Boolean& theIsOut)
+{
+ Standard_STATIC_ASSERT (N == 3 || N == 4);
- if (aBVH.IsNull())
- {
- return Standard_False;
- }
+ T aMinDist = std::numeric_limits<T>::max();
+
+ const NCollection_Handle<BVH_Tree<T, N> >& aBVH = myMesh->BVH();
+
+ if (aBVH.IsNull())
+ {
+ return Standard_False;
+ }
+
+ std::pair<Standard_Integer, T> aStack[32];
- std::pair<Standard_Integer, T> aStack[32];
+ Standard_Integer aHead = -1;
+ Standard_Integer aNode = 0; // root node
- Standard_Integer aHead = -1;
- Standard_Integer aNode = 0; // root node
+ for (;;)
+ {
+ BVH_Vec4i aData = aBVH->NodeInfoBuffer()[aNode];
- for (;;)
+ if (aData.x() == 0) // if inner node
{
- BVH_Vec4i aData = aBVH->NodeInfoBuffer()[aNode];
+ const T aDistToLft = BVH::DistanceToBox<T, N> (thePnt,
+ aBVH->MinPoint (aData.y()),
+ aBVH->MaxPoint (aData.y()));
- if (aData.x() == 0) // if inner node
- {
- const T aDistToLft = DistanceToBox<T, N> (thePnt,
- aBVH->MinPoint (aData.y()),
- aBVH->MaxPoint (aData.y()));
+ const T aDistToRgh = BVH::DistanceToBox<T, N> (thePnt,
+ aBVH->MinPoint (aData.z()),
+ aBVH->MaxPoint (aData.z()));
- const T aDistToRgh = DistanceToBox<T, N> (thePnt,
- aBVH->MinPoint (aData.z()),
- aBVH->MaxPoint (aData.z()));
+ const Standard_Boolean aHitLft = aDistToLft <= aMinDist;
+ const Standard_Boolean aHitRgh = aDistToRgh <= aMinDist;
- const Standard_Boolean aHitLft = aDistToLft <= aMinDistance;
- const Standard_Boolean aHitRgh = aDistToRgh <= aMinDistance;
+ if (aHitLft & aHitRgh)
+ {
+ aNode = (aDistToLft < aDistToRgh) ? aData.y() : aData.z();
- if (aHitLft & aHitRgh)
+ aStack[++aHead] = std::pair<Standard_Integer, T> (
+ aDistToLft < aDistToRgh ? aData.z() : aData.y(), Max (aDistToLft, aDistToRgh));
+ }
+ else
+ {
+ if (aHitLft | aHitRgh)
{
- aNode = (aDistToLft < aDistToRgh) ? aData.y() : aData.z();
-
- aStack[++aHead] = std::pair<Standard_Integer, T> (
- aDistToLft < aDistToRgh ? aData.z() : aData.y(), Max (aDistToLft, aDistToRgh));
+ aNode = aHitLft ? aData.y() : aData.z();
}
else
{
- if (aHitLft | aHitRgh)
- {
- aNode = aHitLft ? aData.y() : aData.z();
- }
- else
- {
- if (aHead < 0)
- return aMinDistance;
-
- std::pair<Standard_Integer, T>& anInfo = aStack[aHead--];
+ if (aHead < 0)
+ return aMinDist;
- while (anInfo.second > aMinDistance)
- {
- if (aHead < 0)
- return aMinDistance;
+ std::pair<Standard_Integer, T>& anInfo = aStack[aHead--];
- anInfo = aStack[aHead--];
- }
+ while (anInfo.second > aMinDist)
+ {
+ if (aHead < 0)
+ return aMinDist;
- aNode = anInfo.first;
+ anInfo = aStack[aHead--];
}
+
+ aNode = anInfo.first;
}
}
- else // if leaf node
+ }
+ else // if leaf node
+ {
+ for (Standard_Integer aTrgIdx = aData.y(); aTrgIdx <= aData.z(); ++aTrgIdx)
{
- for (Standard_Integer aTrgIdx = aData.y(); aTrgIdx <= aData.z(); ++aTrgIdx)
- {
- const BVH_Vec4i aTriangle = aTriangulation->Elements[aTrgIdx];
+ std::pair<BVH_VecNt, Feature> aDirToFeature = directToTrg (thePnt, aTrgIdx);
- const typename VectorType<T, N>::Type aVertex0 = aTriangulation->Vertices[aTriangle.x()];
- const typename VectorType<T, N>::Type aVertex1 = aTriangulation->Vertices[aTriangle.y()];
- const typename VectorType<T, N>::Type aVertex2 = aTriangulation->Vertices[aTriangle.z()];
+ const T aDistance = BVH_DOT3 (aDirToFeature.first,
+ aDirToFeature.first);
- const typename VectorType<T, N>::Type aDirection =
- DirectionToNearestPoint<T, N> (thePnt, aVertex0, aVertex1, aVertex2);
-
- const T aDistance = BVH_DOT3 (aDirection, aDirection);
+ if (aDistance < aMinDist)
+ {
+ aMinDist = aDistance;
- if (aDistance < aMinDistance)
+ if (myComputeSign)
{
- aMinDistance = aDistance;
-
- typename VectorType<T, N>::Type aTrgEdges[] = { aVertex1 - aVertex0,
- aVertex2 - aVertex0 };
+ const BVH_VecNt aNormal = normalToFeature (aDirToFeature.second);
- typename VectorType<T, N>::Type aTrgNormal;
-
- aTrgNormal.x() = aTrgEdges[0].y() * aTrgEdges[1].z() - aTrgEdges[0].z() * aTrgEdges[1].y();
- aTrgNormal.y() = aTrgEdges[0].z() * aTrgEdges[1].x() - aTrgEdges[0].x() * aTrgEdges[1].z();
- aTrgNormal.z() = aTrgEdges[0].x() * aTrgEdges[1].y() - aTrgEdges[0].y() * aTrgEdges[1].x();
-
- theIsOutside = BVH_DOT3 (aTrgNormal, aDirection) > 0;
+ theIsOut = BVH_DOT3 (aNormal, aDirToFeature.first) > T(0.0);
}
}
+ }
- if (aHead < 0)
- return aMinDistance;
-
- std::pair<Standard_Integer, T>& anInfo = aStack[aHead--];
+ if (aHead < 0)
+ return aMinDist;
- while (anInfo.second > aMinDistance)
- {
- if (aHead < 0)
- return aMinDistance;
+ std::pair<Standard_Integer, T>& anInfo = aStack[aHead--];
- anInfo = aStack[aHead--];
- }
+ while (anInfo.second > aMinDist)
+ {
+ if (aHead < 0)
+ return aMinDist;
- aNode = anInfo.first;
+ anInfo = aStack[aHead--];
}
+
+ aNode = anInfo.first;
}
}
+}
- //=======================================================================
- //function : SquareDistanceToGeomerty
- //purpose : Computes squared distance from point to BVH geometry
- //=======================================================================
- template<class T, int N>
- T SquareDistanceToGeomerty (BVH_Geometry<T, N>& theGeometry,
- const typename VectorType<T, N>::Type& thePnt, Standard_Boolean& theIsOutside)
- {
- Standard_STATIC_ASSERT (N == 3 || N == 4);
+#ifdef HAVE_TBB
- const BVH_Tree<T, N, BVH_BinaryTree>* aBVH = theGeometry.BVH().get();
+//! Tool object for parallel construction of distance field (uses Intel TBB).
+template<class T, int N>
+class BVH_ParallelDistanceFieldBuilder
+{
+private:
- if (aBVH == NULL)
- {
- return Standard_False;
- }
+ //! Output distance field.
+ BVH_DistanceField<T, N>* myOutField;
- std::pair<Standard_Integer, T> aStack[32];
+public:
- Standard_Integer aHead = -1;
- Standard_Integer aNode = 0; // root node
+ BVH_ParallelDistanceFieldBuilder (BVH_DistanceField<T, N>* theOutField)
+ : myOutField (theOutField)
+ {
+ //
+ }
- T aMinDistance = std::numeric_limits<T>::max();
+ void operator() (const tbb::blocked_range<Standard_Integer>& theRange) const
+ {
+ myOutField->buildSlices (theRange.begin(), theRange.end());
+ }
+};
- for (;;)
- {
- BVH_Vec4i aData = aBVH->NodeInfoBuffer()[aNode];
+#endif
- if (aData.x() == 0) // if inner node
- {
- const T aDistToLft = DistanceToBox<T, N> (thePnt,
- aBVH->MinPoint (aData.y()),
- aBVH->MaxPoint (aData.y()));
+//=======================================================================
+//function : normalToFeature
+//purpose : Computes the normal to the given triangle feature
+//=======================================================================
+template<class T, int N>
+typename BVH_DistanceField<T, N>::BVH_VecNt BVH_DistanceField<T, N>::normalToFeature (const Feature& theFeature)
+{
+ std::map<Feature, BVH_VecNt, SymmetricalPairComparator>::iterator aFeatureIt = myFeatureNormalMap.find (theFeature);
- const T aDistToRgh = DistanceToBox<T, N> (thePnt,
- aBVH->MinPoint (aData.z()),
- aBVH->MaxPoint (aData.z()));
+ Standard_ASSERT_RAISE (aFeatureIt != myFeatureNormalMap.end(), "Failed to retrieve feature normal");
- const Standard_Boolean aHitLft = aDistToLft <= aMinDistance;
- const Standard_Boolean aHitRgh = aDistToRgh <= aMinDistance;
+ return aFeatureIt->second;
+}
- if (aHitLft & aHitRgh)
- {
- aNode = (aDistToLft < aDistToRgh) ? aData.y() : aData.z();
+// =======================================================================
+// function : Build
+// purpose : Builds 3D distance field from BVH geometry
+// =======================================================================
+template<class T, int N>
+Standard_Boolean BVH_DistanceField<T, N>::Build (BVH_Triangulation<T, N>* theMesh)
+{
+ myMesh = theMesh;
- aStack[++aHead] = std::pair<Standard_Integer, T> (
- aDistToLft < aDistToRgh ? aData.z() : aData.y(), Max (aDistToLft, aDistToRgh));
- }
- else
- {
- if (aHitLft | aHitRgh)
- {
- aNode = aHitLft ? aData.y() : aData.z();
- }
- else
- {
- if (aHead < 0)
- return aMinDistance;
+ if (myMesh->Size() == 0)
+ {
+ return Standard_False;
+ }
- std::pair<Standard_Integer, T>& anInfo = aStack[aHead--];
+ //----------------------------------------------------------------------
+ // Compute pseudo-normals
+ //----------------------------------------------------------------------
- while (anInfo.second > aMinDistance)
- {
- if (aHead < 0)
- return aMinDistance;
+ myFeatureNormalMap.clear();
- anInfo = aStack[aHead--];
- }
+ if (myComputeSign)
+ {
+ std::map<Feature, std::set<Standard_Integer>, SymmetricalPairComparator> aConnectivityMap;
- aNode = anInfo.first;
- }
- }
- }
- else // if leaf node
- {
- Standard_Boolean isOutside = Standard_True;
+ for (size_t aTrgIdx = 0; aTrgIdx < myMesh->Elements.size(); ++aTrgIdx) // build connectivity map
+ {
+ const BVH_Vec4i aTrg = myMesh->Elements[aTrgIdx];
- const T aDistance = SquareDistanceToObject (
- theGeometry.Objects()(aNode).operator->(), thePnt, isOutside);
+ const BVH_VecNt aTrgVrt0 = myMesh->Vertices[aTrg.x()];
+ const BVH_VecNt aTrgVrt1 = myMesh->Vertices[aTrg.y()];
+ const BVH_VecNt aTrgVrt2 = myMesh->Vertices[aTrg.z()];
- if (aDistance < aMinDistance)
- {
- aMinDistance = aDistance;
- theIsOutside = isOutside;
- }
+ const BVH_VecNt aTrgEdges[] = { aTrgVrt1 - aTrgVrt0,
+ aTrgVrt2 - aTrgVrt0 };
- if (aHead < 0)
- return aMinDistance;
+ BVH_VecNt aNormal;
- std::pair<Standard_Integer, T>& anInfo = aStack[aHead--];
+ aNormal.x() = aTrgEdges[0].y() * aTrgEdges[1].z() - aTrgEdges[0].z() * aTrgEdges[1].y();
+ aNormal.y() = aTrgEdges[0].z() * aTrgEdges[1].x() - aTrgEdges[0].x() * aTrgEdges[1].z();
+ aNormal.z() = aTrgEdges[0].x() * aTrgEdges[1].y() - aTrgEdges[0].y() * aTrgEdges[1].x();
- while (anInfo.second > aMinDistance)
- {
- if (aHead < 0)
- return aMinDistance;
+ myFeatureNormalMap[std::make_pair (FACE_ID, aTrgIdx)] = aNormal / std::sqrt (BVH_DOT3 (aNormal, aNormal));
- anInfo = aStack[aHead--];
- }
+ for (Standard_Integer aVrtStart = 0, aVrtEnd = 1; aVrtStart < 3; ++aVrtStart, aVrtEnd = (aVrtEnd + 1) % 3)
+ {
+ aConnectivityMap[Feature (aTrg[aVrtStart], aTrg[aVrtEnd])].insert (aTrgIdx);
+ }
- aNode = anInfo.first;
+ for (Standard_Integer aVrtIdx = 0; aVrtIdx < 3; ++aVrtIdx)
+ {
+ aConnectivityMap[Feature (VERT_ID, aTrg[aVrtIdx])].insert (aTrgIdx);
}
}
+
+ std::map<Feature, std::set<Standard_Integer>, SymmetricalPairComparator>::iterator aFeatureIter;
+
+ for (aFeatureIter = aConnectivityMap.begin(); aFeatureIter != aConnectivityMap.end(); ++aFeatureIter)
+ {
+ BVH_VecNt aNormal;
+
+ for (std::set<Standard_Integer>::iterator aTrgIt = aFeatureIter->second.begin(); aTrgIt != aFeatureIter->second.end(); ++aTrgIt)
+ {
+ aNormal += myFeatureNormalMap[std::make_pair (FACE_ID, *aTrgIt)];
+ }
+
+ myFeatureNormalMap[aFeatureIter->first] = aNormal;
+ }
}
-}
-#undef BVH_DOT3
+ //----------------------------------------------------------------------
+ // Adjust parameters of voxel set
+ //----------------------------------------------------------------------
-#ifdef HAVE_TBB
+ const BVH_VecNt aBoxSize = myMesh->Box().Size();
-//! Tool object for parallel construction of distance field (uses Intel TBB).
-template<class T, int N>
-class BVH_ParallelDistanceFieldBuilder
-{
-private:
+ const T aMaxBoxSide = Max (Max (aBoxSize.x(), aBoxSize.y()), aBoxSize.z());
- //! Input BVH geometry.
- BVH_Geometry<T, N>* myGeometry;
+ myDimensionX = static_cast<Standard_Integer> (myMaximumSize * aBoxSize.x() / aMaxBoxSide);
+ myDimensionY = static_cast<Standard_Integer> (myMaximumSize * aBoxSize.y() / aMaxBoxSide);
+ myDimensionZ = static_cast<Standard_Integer> (myMaximumSize * aBoxSize.z() / aMaxBoxSide);
- //! Output distance field.
- BVH_DistanceField<T, N>* myOutField;
+ myDimensionX = Min (myMaximumSize, Max (myDimensionX, 16));
+ myDimensionY = Min (myMaximumSize, Max (myDimensionY, 16));
+ myDimensionZ = Min (myMaximumSize, Max (myDimensionZ, 16));
-public:
+ const BVH_VecNt aGlobalBoxMin = myMesh->Box().CornerMin();
+ const BVH_VecNt aGlobalBoxMax = myMesh->Box().CornerMax();
- BVH_ParallelDistanceFieldBuilder (BVH_DistanceField<T, N>* theOutField, BVH_Geometry<T, N>* theGeometry)
- : myGeometry (theGeometry),
- myOutField (theOutField)
- {
- //
- }
+ const Standard_Integer aVoxelOffset = 2;
- void operator() (const tbb::blocked_range<Standard_Integer>& theRange) const
- {
- myOutField->BuildSlices (*myGeometry, theRange.begin(), theRange.end());
- }
-};
+ myCornerMin.x() = aGlobalBoxMin.x() - aVoxelOffset * aBoxSize.x() / (myDimensionX - 2 * aVoxelOffset);
+ myCornerMin.y() = aGlobalBoxMin.y() - aVoxelOffset * aBoxSize.y() / (myDimensionY - 2 * aVoxelOffset);
+ myCornerMin.z() = aGlobalBoxMin.z() - aVoxelOffset * aBoxSize.z() / (myDimensionZ - 2 * aVoxelOffset);
+
+ myCornerMax.x() = aGlobalBoxMax.x() + aVoxelOffset * aBoxSize.x() / (myDimensionX - 2 * aVoxelOffset);
+ myCornerMax.y() = aGlobalBoxMax.y() + aVoxelOffset * aBoxSize.y() / (myDimensionY - 2 * aVoxelOffset);
+ myCornerMax.z() = aGlobalBoxMax.z() + aVoxelOffset * aBoxSize.z() / (myDimensionZ - 2 * aVoxelOffset);
+
+ myVoxelSize.x() = (myCornerMax.x() - myCornerMin.x()) / myDimensionX;
+ myVoxelSize.y() = (myCornerMax.y() - myCornerMin.y()) / myDimensionY;
+ myVoxelSize.z() = (myCornerMax.z() - myCornerMin.z()) / myDimensionZ;
+ //----------------------------------------------------------------------
+ // Perform calculations
+ //----------------------------------------------------------------------
+
+#ifdef HAVE_TBB
+ tbb::parallel_for (
+ tbb::blocked_range<Standard_Integer> (0, myDimensionZ), BVH_ParallelDistanceFieldBuilder<T, N> (this));
+#else
+ buildSlices (0, myDimensionZ);
#endif
+ return Standard_True;
+}
+
+#undef BVH_DOT3
+
// =======================================================================
-// function : BuildSlices
+// function : buildSlices
// purpose : Performs building of distance field for the given Z slices
// =======================================================================
template<class T, int N>
-void BVH_DistanceField<T, N>::BuildSlices (BVH_Geometry<T, N>& theGeometry,
- const Standard_Integer theStartSlice, const Standard_Integer theFinalSlice)
+void BVH_DistanceField<T, N>::buildSlices (Standard_Integer theStartSlice, Standard_Integer theFinalSlice)
{
for (Standard_Integer aZ = theStartSlice; aZ < theFinalSlice; ++aZ)
{
Standard_Boolean isOutside = Standard_True;
- const T aDistance = sqrt (
- BVH::SquareDistanceToGeomerty<T, N> (theGeometry, aCenter, isOutside));
+ const T aDistance = std::sqrt (squareDistanceToMesh (aCenter, isOutside));
Voxel (aX, aY, aZ) = (!myComputeSign || isOutside) ? aDistance : -aDistance;
}
}
+
+ std::cout << "*";
}
}
// =======================================================================
-// function : Build
-// purpose : Builds 3D distance field from BVH geometry
+// function : Calculate
+// purpose : Calculates distance at the given point
// =======================================================================
template<class T, int N>
-Standard_Boolean BVH_DistanceField<T, N>::Build (BVH_Geometry<T, N>& theGeometry)
+T BVH_DistanceField<T, N>::Calculate (const BVH_VecNt& thePoint)
{
- if (theGeometry.Size() == 0)
- {
- return Standard_False;
- }
-
- const BVH_VecNt aGlobalBoxSize = theGeometry.Box().Size();
-
- const T aMaxBoxSide = Max (Max (aGlobalBoxSize.x(), aGlobalBoxSize.y()), aGlobalBoxSize.z());
-
- myDimensionX = static_cast<Standard_Integer> (myMaximumSize * aGlobalBoxSize.x() / aMaxBoxSide);
- myDimensionY = static_cast<Standard_Integer> (myMaximumSize * aGlobalBoxSize.y() / aMaxBoxSide);
- myDimensionZ = static_cast<Standard_Integer> (myMaximumSize * aGlobalBoxSize.z() / aMaxBoxSide);
-
- myDimensionX = Min (myMaximumSize, Max (myDimensionX, 16));
- myDimensionY = Min (myMaximumSize, Max (myDimensionY, 16));
- myDimensionZ = Min (myMaximumSize, Max (myDimensionZ, 16));
+ const BVH_VecNt aLocalPnt = thePoint.cwiseMin (myCornerMax).cwiseMax (myCornerMin) - myCornerMin;
- const BVH_VecNt aGlobalBoxMin = theGeometry.Box().CornerMin();
- const BVH_VecNt aGlobalBoxMax = theGeometry.Box().CornerMax();
+ const T aGridPntX = aLocalPnt.x() / myVoxelSize.x() - static_cast<T> (0.5);
+ const T aGridPntY = aLocalPnt.y() / myVoxelSize.y() - static_cast<T> (0.5);
+ const T aGridPntZ = aLocalPnt.z() / myVoxelSize.z() - static_cast<T> (0.5);
- const Standard_Integer aVoxelOffset = 2;
+ const Standard_Integer aCellX = static_cast<Standard_Integer> (std::floor (aGridPntX));
+ const Standard_Integer aCellY = static_cast<Standard_Integer> (std::floor (aGridPntY));
+ const Standard_Integer aCellZ = static_cast<Standard_Integer> (std::floor (aGridPntZ));
- myCornerMin.x() = aGlobalBoxMin.x() - aVoxelOffset * aGlobalBoxSize.x() / (myDimensionX - 2 * aVoxelOffset);
- myCornerMin.y() = aGlobalBoxMin.y() - aVoxelOffset * aGlobalBoxSize.y() / (myDimensionY - 2 * aVoxelOffset);
- myCornerMin.z() = aGlobalBoxMin.z() - aVoxelOffset * aGlobalBoxSize.z() / (myDimensionZ - 2 * aVoxelOffset);
+ const T aRatioX = aGridPntX - aCellX;
+ const T aRatioY = aGridPntY - aCellY;
+ const T aRatioZ = aGridPntZ - aCellZ;
- myCornerMax.x() = aGlobalBoxMax.x() + aVoxelOffset * aGlobalBoxSize.x() / (myDimensionX - 2 * aVoxelOffset);
- myCornerMax.y() = aGlobalBoxMax.y() + aVoxelOffset * aGlobalBoxSize.y() / (myDimensionY - 2 * aVoxelOffset);
- myCornerMax.z() = aGlobalBoxMax.z() + aVoxelOffset * aGlobalBoxSize.z() / (myDimensionZ - 2 * aVoxelOffset);
-
- myVoxelSize.x() = (myCornerMax.x() - myCornerMin.x()) / myDimensionX;
- myVoxelSize.y() = (myCornerMax.y() - myCornerMin.y()) / myDimensionY;
- myVoxelSize.z() = (myCornerMax.z() - myCornerMin.z()) / myDimensionZ;
+ const T aInterpValueMinYMinZ =
+ Voxel (aCellX + 0, aCellY + 0, aCellZ + 0) * (T(1.0) - aRatioX) + Voxel (aCellX + 1, aCellY + 0, aCellZ + 0) * aRatioX;
+ const T aInterpValueMaxYMinZ =
+ Voxel (aCellX + 0, aCellY + 1, aCellZ + 0) * (T(1.0) - aRatioX) + Voxel (aCellX + 1, aCellY + 1, aCellZ + 0) * aRatioX;
+ const T aInterpValueMinYMaxZ =
+ Voxel (aCellX + 0, aCellY + 0, aCellZ + 1) * (T(1.0) - aRatioX) + Voxel (aCellX + 1, aCellY + 0, aCellZ + 1) * aRatioX;
+ const T aInterpValueMaxYMaxZ =
+ Voxel (aCellX + 0, aCellY + 1, aCellZ + 1) * (T(1.0) - aRatioX) + Voxel (aCellX + 1, aCellY + 1, aCellZ + 1) * aRatioX;
-#ifdef HAVE_TBB
-
- tbb::parallel_for (tbb::blocked_range<Standard_Integer> (0, myDimensionZ),
- BVH_ParallelDistanceFieldBuilder<T, N> (this, &theGeometry));
+ const T aInterpValueMinZ = aInterpValueMinYMinZ * (T(1.0) - aRatioY) + aInterpValueMaxYMinZ * aRatioY;
+ const T aInterpValueMaxZ = aInterpValueMinYMaxZ * (T(1.0) - aRatioY) + aInterpValueMaxYMaxZ * aRatioY;
-#else
-
- BuildSlices (theGeometry, 0, myDimensionZ);
-
-#endif
-
- return Standard_True;
+ return aInterpValueMinZ * (T(1.0) - aRatioZ) + aInterpValueMaxZ * aRatioZ;
}
--- /dev/null
+#include <BVH_MarchingCubes.hxx>
+
+namespace BVH
+{
+ int MarchingCubeTables::myEdgeTable[256] = {
+ 0x0 , 0x109, 0x203, 0x30a, 0x406, 0x50f, 0x605, 0x70c,
+ 0x80c, 0x905, 0xa0f, 0xb06, 0xc0a, 0xd03, 0xe09, 0xf00,
+ 0x190, 0x99 , 0x393, 0x29a, 0x596, 0x49f, 0x795, 0x69c,
+ 0x99c, 0x895, 0xb9f, 0xa96, 0xd9a, 0xc93, 0xf99, 0xe90,
+ 0x230, 0x339, 0x33 , 0x13a, 0x636, 0x73f, 0x435, 0x53c,
+ 0xa3c, 0xb35, 0x83f, 0x936, 0xe3a, 0xf33, 0xc39, 0xd30,
+ 0x3a0, 0x2a9, 0x1a3, 0xaa , 0x7a6, 0x6af, 0x5a5, 0x4ac,
+ 0xbac, 0xaa5, 0x9af, 0x8a6, 0xfaa, 0xea3, 0xda9, 0xca0,
+ 0x460, 0x569, 0x663, 0x76a, 0x66 , 0x16f, 0x265, 0x36c,
+ 0xc6c, 0xd65, 0xe6f, 0xf66, 0x86a, 0x963, 0xa69, 0xb60,
+ 0x5f0, 0x4f9, 0x7f3, 0x6fa, 0x1f6, 0xff , 0x3f5, 0x2fc,
+ 0xdfc, 0xcf5, 0xfff, 0xef6, 0x9fa, 0x8f3, 0xbf9, 0xaf0,
+ 0x650, 0x759, 0x453, 0x55a, 0x256, 0x35f, 0x55 , 0x15c,
+ 0xe5c, 0xf55, 0xc5f, 0xd56, 0xa5a, 0xb53, 0x859, 0x950,
+ 0x7c0, 0x6c9, 0x5c3, 0x4ca, 0x3c6, 0x2cf, 0x1c5, 0xcc ,
+ 0xfcc, 0xec5, 0xdcf, 0xcc6, 0xbca, 0xac3, 0x9c9, 0x8c0,
+ 0x8c0, 0x9c9, 0xac3, 0xbca, 0xcc6, 0xdcf, 0xec5, 0xfcc,
+ 0xcc , 0x1c5, 0x2cf, 0x3c6, 0x4ca, 0x5c3, 0x6c9, 0x7c0,
+ 0x950, 0x859, 0xb53, 0xa5a, 0xd56, 0xc5f, 0xf55, 0xe5c,
+ 0x15c, 0x55 , 0x35f, 0x256, 0x55a, 0x453, 0x759, 0x650,
+ 0xaf0, 0xbf9, 0x8f3, 0x9fa, 0xef6, 0xfff, 0xcf5, 0xdfc,
+ 0x2fc, 0x3f5, 0xff , 0x1f6, 0x6fa, 0x7f3, 0x4f9, 0x5f0,
+ 0xb60, 0xa69, 0x963, 0x86a, 0xf66, 0xe6f, 0xd65, 0xc6c,
+ 0x36c, 0x265, 0x16f, 0x66 , 0x76a, 0x663, 0x569, 0x460,
+ 0xca0, 0xda9, 0xea3, 0xfaa, 0x8a6, 0x9af, 0xaa5, 0xbac,
+ 0x4ac, 0x5a5, 0x6af, 0x7a6, 0xaa , 0x1a3, 0x2a9, 0x3a0,
+ 0xd30, 0xc39, 0xf33, 0xe3a, 0x936, 0x83f, 0xb35, 0xa3c,
+ 0x53c, 0x435, 0x73f, 0x636, 0x13a, 0x33 , 0x339, 0x230,
+ 0xe90, 0xf99, 0xc93, 0xd9a, 0xa96, 0xb9f, 0x895, 0x99c,
+ 0x69c, 0x795, 0x49f, 0x596, 0x29a, 0x393, 0x99 , 0x190,
+ 0xf00, 0xe09, 0xd03, 0xc0a, 0xb06, 0xa0f, 0x905, 0x80c,
+ 0x70c, 0x605, 0x50f, 0x406, 0x30a, 0x203, 0x109, 0x0
+ };
+
+ char MarchingCubeTables::myTriTable[256][16] = {
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 8, 3, 9, 8, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 8, 3, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 2, 10, 0, 2, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 2, 8, 3, 2, 10, 8, 10, 9, 8, -1, -1, -1, -1, -1, -1, -1},
+ { 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 11, 2, 8, 11, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 9, 0, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 11, 2, 1, 9, 11, 9, 8, 11, -1, -1, -1, -1, -1, -1, -1},
+ { 3, 10, 1, 11, 10, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 10, 1, 0, 8, 10, 8, 11, 10, -1, -1, -1, -1, -1, -1, -1},
+ { 3, 9, 0, 3, 11, 9, 11, 10, 9, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 4, 3, 0, 7, 3, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, 9, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 4, 1, 9, 4, 7, 1, 7, 3, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 2, 10, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 3, 4, 7, 3, 0, 4, 1, 2, 10, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 2, 10, 9, 0, 2, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
+ { 2, 10, 9, 2, 9, 7, 2, 7, 3, 7, 9, 4, -1, -1, -1, -1},
+ { 8, 4, 7, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {11, 4, 7, 11, 2, 4, 2, 0, 4, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 0, 1, 8, 4, 7, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
+ { 4, 7, 11, 9, 4, 11, 9, 11, 2, 9, 2, 1, -1, -1, -1, -1},
+ { 3, 10, 1, 3, 11, 10, 7, 8, 4, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 11, 10, 1, 4, 11, 1, 0, 4, 7, 11, 4, -1, -1, -1, -1},
+ { 4, 7, 8, 9, 0, 11, 9, 11, 10, 11, 0, 3, -1, -1, -1, -1},
+ { 4, 7, 11, 4, 11, 9, 9, 11, 10, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 5, 4, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 5, 4, 1, 5, 0, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 8, 5, 4, 8, 3, 5, 3, 1, 5, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 2, 10, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 3, 0, 8, 1, 2, 10, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
+ { 5, 2, 10, 5, 4, 2, 4, 0, 2, -1, -1, -1, -1, -1, -1, -1},
+ { 2, 10, 5, 3, 2, 5, 3, 5, 4, 3, 4, 8, -1, -1, -1, -1},
+ { 9, 5, 4, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 11, 2, 0, 8, 11, 4, 9, 5, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 5, 4, 0, 1, 5, 2, 3, 11, -1, -1, -1, -1, -1, -1, -1},
+ { 2, 1, 5, 2, 5, 8, 2, 8, 11, 4, 8, 5, -1, -1, -1, -1},
+ {10, 3, 11, 10, 1, 3, 9, 5, 4, -1, -1, -1, -1, -1, -1, -1},
+ { 4, 9, 5, 0, 8, 1, 8, 10, 1, 8, 11, 10, -1, -1, -1, -1},
+ { 5, 4, 0, 5, 0, 11, 5, 11, 10, 11, 0, 3, -1, -1, -1, -1},
+ { 5, 4, 8, 5, 8, 10, 10, 8, 11, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 7, 8, 5, 7, 9, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 3, 0, 9, 5, 3, 5, 7, 3, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 7, 8, 0, 1, 7, 1, 5, 7, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 7, 8, 9, 5, 7, 10, 1, 2, -1, -1, -1, -1, -1, -1, -1},
+ {10, 1, 2, 9, 5, 0, 5, 3, 0, 5, 7, 3, -1, -1, -1, -1},
+ { 8, 0, 2, 8, 2, 5, 8, 5, 7, 10, 5, 2, -1, -1, -1, -1},
+ { 2, 10, 5, 2, 5, 3, 3, 5, 7, -1, -1, -1, -1, -1, -1, -1},
+ { 7, 9, 5, 7, 8, 9, 3, 11, 2, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 5, 7, 9, 7, 2, 9, 2, 0, 2, 7, 11, -1, -1, -1, -1},
+ { 2, 3, 11, 0, 1, 8, 1, 7, 8, 1, 5, 7, -1, -1, -1, -1},
+ {11, 2, 1, 11, 1, 7, 7, 1, 5, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 5, 8, 8, 5, 7, 10, 1, 3, 10, 3, 11, -1, -1, -1, -1},
+ { 5, 7, 0, 5, 0, 9, 7, 11, 0, 1, 0, 10, 11, 10, 0, -1},
+ {11, 10, 0, 11, 0, 3, 10, 5, 0, 8, 0, 7, 5, 7, 0, -1},
+ {11, 10, 5, 7, 11, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 8, 3, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 0, 1, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 8, 3, 1, 9, 8, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 6, 5, 2, 6, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 6, 5, 1, 2, 6, 3, 0, 8, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 6, 5, 9, 0, 6, 0, 2, 6, -1, -1, -1, -1, -1, -1, -1},
+ { 5, 9, 8, 5, 8, 2, 5, 2, 6, 3, 2, 8, -1, -1, -1, -1},
+ { 2, 3, 11, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {11, 0, 8, 11, 2, 0, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, 9, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1, -1, -1, -1},
+ { 5, 10, 6, 1, 9, 2, 9, 11, 2, 9, 8, 11, -1, -1, -1, -1},
+ { 6, 3, 11, 6, 5, 3, 5, 1, 3, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 8, 11, 0, 11, 5, 0, 5, 1, 5, 11, 6, -1, -1, -1, -1},
+ { 3, 11, 6, 0, 3, 6, 0, 6, 5, 0, 5, 9, -1, -1, -1, -1},
+ { 6, 5, 9, 6, 9, 11, 11, 9, 8, -1, -1, -1, -1, -1, -1, -1},
+ { 5, 10, 6, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 4, 3, 0, 4, 7, 3, 6, 5, 10, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 9, 0, 5, 10, 6, 8, 4, 7, -1, -1, -1, -1, -1, -1, -1},
+ {10, 6, 5, 1, 9, 7, 1, 7, 3, 7, 9, 4, -1, -1, -1, -1},
+ { 6, 1, 2, 6, 5, 1, 4, 7, 8, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 2, 5, 5, 2, 6, 3, 0, 4, 3, 4, 7, -1, -1, -1, -1},
+ { 8, 4, 7, 9, 0, 5, 0, 6, 5, 0, 2, 6, -1, -1, -1, -1},
+ { 7, 3, 9, 7, 9, 4, 3, 2, 9, 5, 9, 6, 2, 6, 9, -1},
+ { 3, 11, 2, 7, 8, 4, 10, 6, 5, -1, -1, -1, -1, -1, -1, -1},
+ { 5, 10, 6, 4, 7, 2, 4, 2, 0, 2, 7, 11, -1, -1, -1, -1},
+ { 0, 1, 9, 4, 7, 8, 2, 3, 11, 5, 10, 6, -1, -1, -1, -1},
+ { 9, 2, 1, 9, 11, 2, 9, 4, 11, 7, 11, 4, 5, 10, 6, -1},
+ { 8, 4, 7, 3, 11, 5, 3, 5, 1, 5, 11, 6, -1, -1, -1, -1},
+ { 5, 1, 11, 5, 11, 6, 1, 0, 11, 7, 11, 4, 0, 4, 11, -1},
+ { 0, 5, 9, 0, 6, 5, 0, 3, 6, 11, 6, 3, 8, 4, 7, -1},
+ { 6, 5, 9, 6, 9, 11, 4, 7, 9, 7, 11, 9, -1, -1, -1, -1},
+ {10, 4, 9, 6, 4, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 4, 10, 6, 4, 9, 10, 0, 8, 3, -1, -1, -1, -1, -1, -1, -1},
+ {10, 0, 1, 10, 6, 0, 6, 4, 0, -1, -1, -1, -1, -1, -1, -1},
+ { 8, 3, 1, 8, 1, 6, 8, 6, 4, 6, 1, 10, -1, -1, -1, -1},
+ { 1, 4, 9, 1, 2, 4, 2, 6, 4, -1, -1, -1, -1, -1, -1, -1},
+ { 3, 0, 8, 1, 2, 9, 2, 4, 9, 2, 6, 4, -1, -1, -1, -1},
+ { 0, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 8, 3, 2, 8, 2, 4, 4, 2, 6, -1, -1, -1, -1, -1, -1, -1},
+ {10, 4, 9, 10, 6, 4, 11, 2, 3, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 8, 2, 2, 8, 11, 4, 9, 10, 4, 10, 6, -1, -1, -1, -1},
+ { 3, 11, 2, 0, 1, 6, 0, 6, 4, 6, 1, 10, -1, -1, -1, -1},
+ { 6, 4, 1, 6, 1, 10, 4, 8, 1, 2, 1, 11, 8, 11, 1, -1},
+ { 9, 6, 4, 9, 3, 6, 9, 1, 3, 11, 6, 3, -1, -1, -1, -1},
+ { 8, 11, 1, 8, 1, 0, 11, 6, 1, 9, 1, 4, 6, 4, 1, -1},
+ { 3, 11, 6, 3, 6, 0, 0, 6, 4, -1, -1, -1, -1, -1, -1, -1},
+ { 6, 4, 8, 11, 6, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 7, 10, 6, 7, 8, 10, 8, 9, 10, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 7, 3, 0, 10, 7, 0, 9, 10, 6, 7, 10, -1, -1, -1, -1},
+ {10, 6, 7, 1, 10, 7, 1, 7, 8, 1, 8, 0, -1, -1, -1, -1},
+ {10, 6, 7, 10, 7, 1, 1, 7, 3, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 2, 6, 1, 6, 8, 1, 8, 9, 8, 6, 7, -1, -1, -1, -1},
+ { 2, 6, 9, 2, 9, 1, 6, 7, 9, 0, 9, 3, 7, 3, 9, -1},
+ { 7, 8, 0, 7, 0, 6, 6, 0, 2, -1, -1, -1, -1, -1, -1, -1},
+ { 7, 3, 2, 6, 7, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 2, 3, 11, 10, 6, 8, 10, 8, 9, 8, 6, 7, -1, -1, -1, -1},
+ { 2, 0, 7, 2, 7, 11, 0, 9, 7, 6, 7, 10, 9, 10, 7, -1},
+ { 1, 8, 0, 1, 7, 8, 1, 10, 7, 6, 7, 10, 2, 3, 11, -1},
+ {11, 2, 1, 11, 1, 7, 10, 6, 1, 6, 7, 1, -1, -1, -1, -1},
+ { 8, 9, 6, 8, 6, 7, 9, 1, 6, 11, 6, 3, 1, 3, 6, -1},
+ { 0, 9, 1, 11, 6, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 7, 8, 0, 7, 0, 6, 3, 11, 0, 11, 6, 0, -1, -1, -1, -1},
+ { 7, 11, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 3, 0, 8, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, 9, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 8, 1, 9, 8, 3, 1, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
+ {10, 1, 2, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 2, 10, 3, 0, 8, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
+ { 2, 9, 0, 2, 10, 9, 6, 11, 7, -1, -1, -1, -1, -1, -1, -1},
+ { 6, 11, 7, 2, 10, 3, 10, 8, 3, 10, 9, 8, -1, -1, -1, -1},
+ { 7, 2, 3, 6, 2, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 7, 0, 8, 7, 6, 0, 6, 2, 0, -1, -1, -1, -1, -1, -1, -1},
+ { 2, 7, 6, 2, 3, 7, 0, 1, 9, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 6, 2, 1, 8, 6, 1, 9, 8, 8, 7, 6, -1, -1, -1, -1},
+ {10, 7, 6, 10, 1, 7, 1, 3, 7, -1, -1, -1, -1, -1, -1, -1},
+ {10, 7, 6, 1, 7, 10, 1, 8, 7, 1, 0, 8, -1, -1, -1, -1},
+ { 0, 3, 7, 0, 7, 10, 0, 10, 9, 6, 10, 7, -1, -1, -1, -1},
+ { 7, 6, 10, 7, 10, 8, 8, 10, 9, -1, -1, -1, -1, -1, -1, -1},
+ { 6, 8, 4, 11, 8, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 3, 6, 11, 3, 0, 6, 0, 4, 6, -1, -1, -1, -1, -1, -1, -1},
+ { 8, 6, 11, 8, 4, 6, 9, 0, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 4, 6, 9, 6, 3, 9, 3, 1, 11, 3, 6, -1, -1, -1, -1},
+ { 6, 8, 4, 6, 11, 8, 2, 10, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 2, 10, 3, 0, 11, 0, 6, 11, 0, 4, 6, -1, -1, -1, -1},
+ { 4, 11, 8, 4, 6, 11, 0, 2, 9, 2, 10, 9, -1, -1, -1, -1},
+ {10, 9, 3, 10, 3, 2, 9, 4, 3, 11, 3, 6, 4, 6, 3, -1},
+ { 8, 2, 3, 8, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 4, 2, 4, 6, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 9, 0, 2, 3, 4, 2, 4, 6, 4, 3, 8, -1, -1, -1, -1},
+ { 1, 9, 4, 1, 4, 2, 2, 4, 6, -1, -1, -1, -1, -1, -1, -1},
+ { 8, 1, 3, 8, 6, 1, 8, 4, 6, 6, 10, 1, -1, -1, -1, -1},
+ {10, 1, 0, 10, 0, 6, 6, 0, 4, -1, -1, -1, -1, -1, -1, -1},
+ { 4, 6, 3, 4, 3, 8, 6, 10, 3, 0, 3, 9, 10, 9, 3, -1},
+ {10, 9, 4, 6, 10, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 4, 9, 5, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 8, 3, 4, 9, 5, 11, 7, 6, -1, -1, -1, -1, -1, -1, -1},
+ { 5, 0, 1, 5, 4, 0, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
+ {11, 7, 6, 8, 3, 4, 3, 5, 4, 3, 1, 5, -1, -1, -1, -1},
+ { 9, 5, 4, 10, 1, 2, 7, 6, 11, -1, -1, -1, -1, -1, -1, -1},
+ { 6, 11, 7, 1, 2, 10, 0, 8, 3, 4, 9, 5, -1, -1, -1, -1},
+ { 7, 6, 11, 5, 4, 10, 4, 2, 10, 4, 0, 2, -1, -1, -1, -1},
+ { 3, 4, 8, 3, 5, 4, 3, 2, 5, 10, 5, 2, 11, 7, 6, -1},
+ { 7, 2, 3, 7, 6, 2, 5, 4, 9, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 5, 4, 0, 8, 6, 0, 6, 2, 6, 8, 7, -1, -1, -1, -1},
+ { 3, 6, 2, 3, 7, 6, 1, 5, 0, 5, 4, 0, -1, -1, -1, -1},
+ { 6, 2, 8, 6, 8, 7, 2, 1, 8, 4, 8, 5, 1, 5, 8, -1},
+ { 9, 5, 4, 10, 1, 6, 1, 7, 6, 1, 3, 7, -1, -1, -1, -1},
+ { 1, 6, 10, 1, 7, 6, 1, 0, 7, 8, 7, 0, 9, 5, 4, -1},
+ { 4, 0, 10, 4, 10, 5, 0, 3, 10, 6, 10, 7, 3, 7, 10, -1},
+ { 7, 6, 10, 7, 10, 8, 5, 4, 10, 4, 8, 10, -1, -1, -1, -1},
+ { 6, 9, 5, 6, 11, 9, 11, 8, 9, -1, -1, -1, -1, -1, -1, -1},
+ { 3, 6, 11, 0, 6, 3, 0, 5, 6, 0, 9, 5, -1, -1, -1, -1},
+ { 0, 11, 8, 0, 5, 11, 0, 1, 5, 5, 6, 11, -1, -1, -1, -1},
+ { 6, 11, 3, 6, 3, 5, 5, 3, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 2, 10, 9, 5, 11, 9, 11, 8, 11, 5, 6, -1, -1, -1, -1},
+ { 0, 11, 3, 0, 6, 11, 0, 9, 6, 5, 6, 9, 1, 2, 10, -1},
+ {11, 8, 5, 11, 5, 6, 8, 0, 5, 10, 5, 2, 0, 2, 5, -1},
+ { 6, 11, 3, 6, 3, 5, 2, 10, 3, 10, 5, 3, -1, -1, -1, -1},
+ { 5, 8, 9, 5, 2, 8, 5, 6, 2, 3, 8, 2, -1, -1, -1, -1},
+ { 9, 5, 6, 9, 6, 0, 0, 6, 2, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 5, 8, 1, 8, 0, 5, 6, 8, 3, 8, 2, 6, 2, 8, -1},
+ { 1, 5, 6, 2, 1, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 3, 6, 1, 6, 10, 3, 8, 6, 5, 6, 9, 8, 9, 6, -1},
+ {10, 1, 0, 10, 0, 6, 9, 5, 0, 5, 6, 0, -1, -1, -1, -1},
+ { 0, 3, 8, 5, 6, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {10, 5, 6, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {11, 5, 10, 7, 5, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {11, 5, 10, 11, 7, 5, 8, 3, 0, -1, -1, -1, -1, -1, -1, -1},
+ { 5, 11, 7, 5, 10, 11, 1, 9, 0, -1, -1, -1, -1, -1, -1, -1},
+ {10, 7, 5, 10, 11, 7, 9, 8, 1, 8, 3, 1, -1, -1, -1, -1},
+ {11, 1, 2, 11, 7, 1, 7, 5, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 8, 3, 1, 2, 7, 1, 7, 5, 7, 2, 11, -1, -1, -1, -1},
+ { 9, 7, 5, 9, 2, 7, 9, 0, 2, 2, 11, 7, -1, -1, -1, -1},
+ { 7, 5, 2, 7, 2, 11, 5, 9, 2, 3, 2, 8, 9, 8, 2, -1},
+ { 2, 5, 10, 2, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1},
+ { 8, 2, 0, 8, 5, 2, 8, 7, 5, 10, 2, 5, -1, -1, -1, -1},
+ { 9, 0, 1, 5, 10, 3, 5, 3, 7, 3, 10, 2, -1, -1, -1, -1},
+ { 9, 8, 2, 9, 2, 1, 8, 7, 2, 10, 2, 5, 7, 5, 2, -1},
+ { 1, 3, 5, 3, 7, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 8, 7, 0, 7, 1, 1, 7, 5, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 0, 3, 9, 3, 5, 5, 3, 7, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 8, 7, 5, 9, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 5, 8, 4, 5, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1},
+ { 5, 0, 4, 5, 11, 0, 5, 10, 11, 11, 3, 0, -1, -1, -1, -1},
+ { 0, 1, 9, 8, 4, 10, 8, 10, 11, 10, 4, 5, -1, -1, -1, -1},
+ {10, 11, 4, 10, 4, 5, 11, 3, 4, 9, 4, 1, 3, 1, 4, -1},
+ { 2, 5, 1, 2, 8, 5, 2, 11, 8, 4, 5, 8, -1, -1, -1, -1},
+ { 0, 4, 11, 0, 11, 3, 4, 5, 11, 2, 11, 1, 5, 1, 11, -1},
+ { 0, 2, 5, 0, 5, 9, 2, 11, 5, 4, 5, 8, 11, 8, 5, -1},
+ { 9, 4, 5, 2, 11, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 2, 5, 10, 3, 5, 2, 3, 4, 5, 3, 8, 4, -1, -1, -1, -1},
+ { 5, 10, 2, 5, 2, 4, 4, 2, 0, -1, -1, -1, -1, -1, -1, -1},
+ { 3, 10, 2, 3, 5, 10, 3, 8, 5, 4, 5, 8, 0, 1, 9, -1},
+ { 5, 10, 2, 5, 2, 4, 1, 9, 2, 9, 4, 2, -1, -1, -1, -1},
+ { 8, 4, 5, 8, 5, 3, 3, 5, 1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 4, 5, 1, 0, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 8, 4, 5, 8, 5, 3, 9, 0, 5, 0, 3, 5, -1, -1, -1, -1},
+ { 9, 4, 5, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 4, 11, 7, 4, 9, 11, 9, 10, 11, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 8, 3, 4, 9, 7, 9, 11, 7, 9, 10, 11, -1, -1, -1, -1},
+ { 1, 10, 11, 1, 11, 4, 1, 4, 0, 7, 4, 11, -1, -1, -1, -1},
+ { 3, 1, 4, 3, 4, 8, 1, 10, 4, 7, 4, 11, 10, 11, 4, -1},
+ { 4, 11, 7, 9, 11, 4, 9, 2, 11, 9, 1, 2, -1, -1, -1, -1},
+ { 9, 7, 4, 9, 11, 7, 9, 1, 11, 2, 11, 1, 0, 8, 3, -1},
+ {11, 7, 4, 11, 4, 2, 2, 4, 0, -1, -1, -1, -1, -1, -1, -1},
+ {11, 7, 4, 11, 4, 2, 8, 3, 4, 3, 2, 4, -1, -1, -1, -1},
+ { 2, 9, 10, 2, 7, 9, 2, 3, 7, 7, 4, 9, -1, -1, -1, -1},
+ { 9, 10, 7, 9, 7, 4, 10, 2, 7, 8, 7, 0, 2, 0, 7, -1},
+ { 3, 7, 10, 3, 10, 2, 7, 4, 10, 1, 10, 0, 4, 0, 10, -1},
+ { 1, 10, 2, 8, 7, 4, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 4, 9, 1, 4, 1, 7, 7, 1, 3, -1, -1, -1, -1, -1, -1, -1},
+ { 4, 9, 1, 4, 1, 7, 0, 8, 1, 8, 7, 1, -1, -1, -1, -1},
+ { 4, 0, 3, 7, 4, 3, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 4, 8, 7, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 10, 8, 10, 11, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 3, 0, 9, 3, 9, 11, 11, 9, 10, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 1, 10, 0, 10, 8, 8, 10, 11, -1, -1, -1, -1, -1, -1, -1},
+ { 3, 1, 10, 11, 3, 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 2, 11, 1, 11, 9, 9, 11, 8, -1, -1, -1, -1, -1, -1, -1},
+ { 3, 0, 9, 3, 9, 11, 1, 2, 9, 2, 11, 9, -1, -1, -1, -1},
+ { 0, 2, 11, 8, 0, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 3, 2, 11, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 2, 3, 8, 2, 8, 10, 10, 8, 9, -1, -1, -1, -1, -1, -1, -1},
+ { 9, 10, 2, 0, 9, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 2, 3, 8, 2, 8, 10, 0, 1, 8, 1, 10, 8, -1, -1, -1, -1},
+ { 1, 10, 2, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 1, 3, 8, 9, 1, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 9, 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ { 0, 3, 8, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1},
+ {-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1}
+ };
+
+ //==============================================================================
+ //function : EdgeTable
+ //purpose :
+ //==============================================================================
+ int (&MarchingCubeTables::EdgeTable())[256]
+ {
+ return myEdgeTable;
+ }
+
+ //==============================================================================
+ //function : TriTable
+ //purpose :
+ //==============================================================================
+ char (&MarchingCubeTables::TriTable())[256][16]
+ {
+ return myTriTable;
+ }
+}
\ No newline at end of file