Browse Source

blobtree

master
gjj 6 months ago
parent
commit
0747ce10bd
  1. 21
      algoim/organizer/blobtree.hpp
  2. 115
      algoim/organizer/organizer.hpp
  3. 35
      algoim/organizer/primitive.hpp
  4. 14
      algoim/quadrature_multipoly.hpp
  5. 106
      gjj/primitiveDebug.hpp

21
algoim/organizer/blobtree.hpp

@ -37,6 +37,21 @@ public:
std::vector<unsigned int> primitiveNodeIdx; // 由primitive数组下标指向node中对应leaf的下标
BlobTree(const BlobTree& other)
{
structure = other.structure;
primitiveNodeIdx = other.primitiveNodeIdx;
}
BlobTree& operator=(const BlobTree& other)
{
if (this != &other) {
structure = other.structure;
primitiveNodeIdx = other.primitiveNodeIdx;
}
return *this;
}
BlobTree() {}
};
@ -44,7 +59,11 @@ void propagate(BlobTree& tree, unsigned int nodeIdx, bool in)
{
const std::size_t rootIdx = tree.structure.size() - 1;
auto& node = tree.structure[nodeIdx];
assert(node.inOut == 0);
// if (node.inOut != NODE_IN_OUT_UNKNOWN) {
// int aaa = 1;
// int bb = 1;
// }
assert(node.inOut == NODE_IN_OUT_UNKNOWN);
node.inOut = in ? NODE_IN : NODE_OUT;
for (unsigned int nowIdx = nodeIdx; nowIdx != rootIdx;) {
const auto& nowNode = tree.structure[nowIdx];

115
algoim/organizer/organizer.hpp

@ -93,41 +93,21 @@ int findFirst(const uvector<int, N>& v, int val, int startIdx = 0)
return -1;
}
std::pair<uvector<real, 3>, uvector<real, 3>> getOneEightCellAABB(const uvector3& min,
const uvector3& max,
const uvector<int, 3> side,
int negativeRep = -1)
AABB getOneEightCellAABB(const AABB& fatherAABB, const uvector<int, 3> side, int negativeRep = -1)
{
std::pair<uvector<real, 3>, uvector<real, 3>> res = {min, max};
uvector3 mid = (min + max) / 2;
AABB res = fatherAABB;
uvector3 mid = res.center();
for (int i = 0; i < 3; ++i) {
if (side(i) == negativeRep) {
res.second(i) = mid(i);
res.max(i) = mid(i);
} else {
res.first(i) = mid(i);
res.min(i) = mid(i);
}
}
return res;
}
} // namespace detail
// TODO: delete it
bool isPointInside(const std::vector<tensor3>& originTensors, const uvector3& originPt)
{
for (auto& t : originTensors) {
if (evalPower(t, originPt) >= 0) { return false; }
}
return true;
}
// bool isPointInside(const std::vector<CompleteTensorRep>& completeTensorReps, const uvector3& originPt)
// {
// for (auto& completeTensorRep : completeTensorReps) {
// if (isPointInside(completeTensorRep.originalPower, originPt)) { return false; }
// }
// return true;
// }
// 这里blobTree是拷贝传参
bool keepQuadraturePoint(const Scene& scene,
organizer::BlobTree blobTree,
@ -138,7 +118,7 @@ bool keepQuadraturePoint(const Scene& scene,
const auto& polyIntersectIndices = ocTreeNode.polyIntersectIndices;
std::vector<bool> primitiveInOuts(polyIntersectIndices.size());
for (int i = 0; i < ocTreeNode.polyIntersectIndices.size(); ++i) {
primitiveInOuts[i] = isPointInside(scene.polys[polyIntersectIndices[i]].rawPower, originPt);
primitiveInOuts[i] = isInsidePowers(scene.polys[polyIntersectIndices[i]].rawPower, originPt);
}
int res = organizer::traverse(blobTree, ocTreeNode.polyIntersectIndices, primitiveInOuts);
assert(res == organizer::NODE_IN || res == organizer::NODE_OUT);
@ -149,7 +129,6 @@ bool keepQuadraturePoint(const Scene& scene,
// BasicTask(std::vector<std::shared_ptr<PrimitiveDesc>> ps) {};
const std::array<int, 2> sides = {-1, 1};
struct BasicTaskRes {
@ -174,11 +153,11 @@ void visitSubcellOnBothSidesOfDir(const uvector3& nodeMid,
algoim_spark_alloc(real, halfCellPoly);
int subIdx = detail::binaryToDecimal(mark, -1);
auto& subNode = subNodes[subIdx];
bernstein::deCasteljau(poly, subNode.min, subNode.max, halfCellPoly); // 求1/8空间下的表达
bernstein::deCasteljau(poly, subNode.aabb.min, subNode.aabb.max, halfCellPoly); // 求1/8空间下的表达
if (bernstein::uniformSign(halfCellPoly) != 1) {
subNode.polyIntersectIndices.emplace_back(polyIntersectIndex);
} else {
organizer::traverse(subNode.blobTree, polyIntersectIndex, organizer::NODE_OUT);
organizer::traverse(subNode.blobTree, polyIntersectIndex, false);
}
} else {
for (auto side : sides) {
@ -199,19 +178,15 @@ void buildOcTreeV1(const Scene& scene, const OcTreeNode& node, std::vector<OcTre
leaves.emplace_back(node);
return;
}
const uvector3& nowNodeMin = node.min;
const uvector3& nowNodeMax = node.max;
std::vector<OcTreeNode> subNodes(CHILD_NUM);
// std::array<OcTreeNode, CHILD_NUM> subNodes;
// intermediateNodes.resize(lastIdx + 8);
int subIdx = 0;
for (MultiLoop<3> j(0, 2); ~j; ++j, ++subIdx) {
auto nodeAABB = detail::getOneEightCellAABB(node.min, node.max, j(), 0);
subNodes[subIdx].min = nodeAABB.first;
subNodes[subIdx].max = nodeAABB.second;
subNodes[subIdx].aabb = detail::getOneEightCellAABB(node.aabb, j(), 0);
subNodes[subIdx].blobTree = node.blobTree;
}
uvector3 nodeMid = (nowNodeMin + nowNodeMax) / 2;
uvector3 nodeMid = node.aabb.center();
for (int i = 0; i < polyIntersectIndices.size(); ++i) {
const int polyIntersectIndex = polyIntersectIndices[i];
const auto& poly = scene.polys[polyIntersectIndex];
@ -229,18 +204,18 @@ void buildOcTreeV1(const Scene& scene, const OcTreeNode& node, std::vector<OcTre
} else if (signOnHalfPlane == 1) {
// primitive intersects either side or both sides of the centerface
// deCasteljau to transformation
uvector3 halfCellMin = nowNodeMin, halfCellMax = nowNodeMax;
halfCellMax(faceAxis) = nodeMid(faceAxis);
AABB halfCell = node.aabb;
halfCell.max(faceAxis) = nodeMid(faceAxis);
tensor3 halfCellPoly(nullptr, poly.compositedBernstein.ext());
algoim_spark_alloc(real, halfCellPoly);
bernstein::deCasteljau(poly.compositedBernstein, halfCellMin, halfCellMax, halfCellPoly);
bernstein::deCasteljau(poly.compositedBernstein, halfCell.min, halfCell.max, halfCellPoly);
if (bernstein::uniformSign(halfCellPoly) != 1) {
// 负空间有
mark(faceAxis) = -1;
}
halfCellMax(faceAxis) = nowNodeMax(faceAxis);
halfCellMin(faceAxis) = nodeMid(faceAxis);
bernstein::deCasteljau(poly.compositedBernstein, halfCellMin, halfCellMax, halfCellPoly);
halfCell.max(faceAxis) = node.aabb.max(faceAxis);
halfCell.min(faceAxis) = nodeMid(faceAxis);
bernstein::deCasteljau(poly.compositedBernstein, halfCell.min, halfCell.max, halfCellPoly);
if (bernstein::uniformSign(halfCellPoly) != 1) {
// 正空间有
mark(faceAxis) += 1; // 当正负空间都有,记0
@ -253,10 +228,10 @@ void buildOcTreeV1(const Scene& scene, const OcTreeNode& node, std::vector<OcTre
// fully containing cases
for (int i = 0; i < CHILD_NUM; ++i) {
tensor3 subPoly(nullptr, poly.compositedBernstein.ext());
bernstein::deCasteljau(poly.compositedBernstein, subNodes[i].min, subNodes[i].max, subPoly);
bernstein::deCasteljau(poly.compositedBernstein, subNodes[i].aabb.min, subNodes[i].aabb.max, subPoly);
if (bernstein::uniformSign(subPoly) == -1) {
// subNodes[i].polyFullyContainedIndices.emplace_back(polyIntersectIndex);
organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, organizer::NODE_IN);
organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, true);
} else {
subNodes[i].polyIntersectIndices.emplace_back(polyIntersectIndex);
}
@ -277,7 +252,7 @@ void buildOcTreeV1(const Scene& scene, const OcTreeNode& node, std::vector<OcTre
if (subIdx == markIdx)
subNodes[subIdx].polyIntersectIndices.emplace_back(polyIntersectIndex);
else
organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, organizer::NODE_OUT);
organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, false);
}
} else if (zeroCount == 1) {
// poly related to 2 subcells
@ -290,7 +265,7 @@ void buildOcTreeV1(const Scene& scene, const OcTreeNode& node, std::vector<OcTre
subNodes[sideIdx2].polyIntersectIndices.emplace_back(polyIntersectIndex);
for (int subIdx = 0; subIdx < CHILD_NUM; ++subIdx) {
if (subIdx != sideIdx1 && subIdx != sideIdx2) {
organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, organizer::NODE_OUT);
organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, false);
}
}
} else {
@ -311,39 +286,44 @@ void buildOcTreeV1(const Scene& scene, const OcTreeNode& node, std::vector<OcTre
void buildOcTreeV0(const Scene& scene, const OcTreeNode& node, std::vector<OcTreeNode>& leaves)
{
int a = 0;
const std::vector<int>& polyIntersectIndices = node.polyIntersectIndices;
if (polyIntersectIndices.size() <= 4) {
if (polyIntersectIndices.size() <= 3) {
leaves.emplace_back(node);
return;
}
const uvector3& nowNodeMin = node.min;
const uvector3& nowNodeMax = node.max;
// std::array<OcTreeNode, CHILD_NUM> subNodes;
std::vector<OcTreeNode> subNodes(CHILD_NUM);
// intermediateNodes.resize(lastIdx + 8);
int subIdx = 0;
for (MultiLoop<3> j(0, 2); ~j; ++j, ++subIdx) {
auto nodeAABB = detail::getOneEightCellAABB(node.min, node.max, j(), 0);
subNodes[subIdx].min = nodeAABB.first;
subNodes[subIdx].max = nodeAABB.second;
subNodes[subIdx].aabb = detail::getOneEightCellAABB(node.aabb, j(), 0);
subNodes[subIdx].blobTree = node.blobTree;
subNodes[subIdx].polyIntersectIndices = std::vector<int>();
}
uvector3 nodeMid = (nowNodeMin + nowNodeMax) / 2;
uvector3 nodeMid = node.aabb.center();
for (int i = 0; i < polyIntersectIndices.size(); ++i) {
const int polyIntersectIndex = polyIntersectIndices[i];
const auto& poly = scene.polys[polyIntersectIndex];
subIdx = 0;
for (MultiLoop<3> j(0, 2); ~j; ++j, ++subIdx) {
if (!poly.aabb.intersect(subNodes[subIdx].aabb)) {
// out of the subcell
organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, false);
continue;
}
tensor3 subcellPoly(nullptr, poly.compositedBernstein.ext());
algoim_spark_alloc(real, subcellPoly);
bernstein::deCasteljau(poly.compositedBernstein, subNodes[subIdx].min, subNodes[subIdx].max, subcellPoly);
bernstein::deCasteljau(poly.compositedBernstein, subNodes[subIdx].aabb.min, subNodes[subIdx].aabb.max, subcellPoly);
int sign = bernstein::uniformSign(subcellPoly);
if (sign == 1) {
organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, organizer::NODE_OUT);
organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, false);
} else if (sign == -1) {
organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, organizer::NODE_IN);
// 采样一个点,带入所有原始primitive看是否是冗余部分
uvector3 sampleX = subNodes[subIdx].aabb.center() * scene.boundary.size() + scene.boundary.min;
if (isInsidePowers(poly.rawPower, sampleX))
organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, true);
else
organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, false);
} else {
subNodes[subIdx].polyIntersectIndices.emplace_back(polyIntersectIndex);
}
@ -479,7 +459,7 @@ void basicTask(const std::vector<std::shared_ptr<PrimitiveDesc>>& primitives, in
ipquad.integrate(AutoMixed, q, [&](const uvector<real, 3>& x, real w) {
auto realX = x * range + xmin;
if (isPointInside(originTensors, realX)) volume += w * integrand(realX);
if (isInsidePowers(originTensors, realX)) volume += w * integrand(realX);
});
volume *= pow(xmax - xmin, 3);
std::cout << "Volume xxx: " << volume << std::endl;
@ -489,18 +469,18 @@ void basicTask(const std::vector<std::shared_ptr<PrimitiveDesc>>& primitives, in
for (auto& p : originTensorStacks) delete p;
};
BasicTaskRes basicTask(const Scene& scene, const organizer::BlobTree& blobTree, const OcTreeNode& node, int q = 20)
BasicTaskRes basicTask(const Scene& scene, const organizer::BlobTree& blobTree, const OcTreeNode& node, int q = 10)
{
auto integrand = [](const uvector<real, 3>& x) { return 1.0; };
real volume = 0., surf = 0.;
auto range = node.max - node.min;
ImplicitPolyQuadrature<3> ipquad(scene.polys);
auto range = node.aabb.size();
ImplicitPolyQuadrature<3> ipquad(scene.polys, node.polyIntersectIndices);
ipquad.integrate(AutoMixed, q, [&](const uvector<real, 3>& x, real w) {
auto realX = x * range + node.min;
auto realX = x * range + node.aabb.min;
if (keepQuadraturePoint(scene, blobTree, node, realX)) { volume += w * integrand(realX); }
});
ipquad.integrate_surf(AutoMixed, q, [&](const uvector<real, 3>& x, real w, const uvector<real, 3>& wn) {
surf += w * integrand(x * range + node.min);
surf += w * integrand(x * range + node.aabb.min);
});
return {volume, surf};
}
@ -534,6 +514,7 @@ void quadratureScene(const std::vector<std::shared_ptr<PrimitiveDesc>>& primitiv
AABB aabb;
makeSphere(*pt, originTensor, aabb);
detail::powerTransformation(range, xmin, originTensor, transformedTensor);
aabb.normalize(range, xmin);
real testEvaOri = evalPower(originTensor, testX);
@ -553,7 +534,9 @@ void quadratureScene(const std::vector<std::shared_ptr<PrimitiveDesc>>& primitiv
algoim_spark_alloc(real, compositeTensor);
AABB aabb;
makeMesh(*pt, compositeTensor, planeTensors, aabb);
detail::powerTransformation(range, xmin, compositeTensor);
aabb.normalize(range, xmin);
real testEvalPower = evalPower(compositeTensor, testX);
@ -576,6 +559,8 @@ void quadratureScene(const std::vector<std::shared_ptr<PrimitiveDesc>>& primitiv
AABB aabb;
makeCylinder(*pt, compositeTensor, rawTensors, aabb);
detail::powerTransformation(range, xmin, compositeTensor);
aabb.normalize(range, xmin);
real testEvalPower = evalPower(compositeTensor, testX);
detail::power2BernsteinTensor(compositeTensor, phi);
@ -595,6 +580,8 @@ void quadratureScene(const std::vector<std::shared_ptr<PrimitiveDesc>>& primitiv
AABB aabb;
makeCone(*pt, compositeTensor, rawTensors, aabb);
detail::powerTransformation(range, xmin, compositeTensor);
aabb.normalize(range, xmin);
real testEvalPower = evalPower(compositeTensor, testX);
detail::power2BernsteinTensor(compositeTensor, phi);
@ -605,14 +592,14 @@ void quadratureScene(const std::vector<std::shared_ptr<PrimitiveDesc>>& primitiv
}
}
Scene scene{completeTensorReps, blobTree};
Scene scene{completeTensorReps, AABB(xmin, xmax)};
OcTreeNode rootNode(0, 1, blobTree);
for (int i = 0; i < completeTensorReps.size(); ++i) { rootNode.polyIntersectIndices.emplace_back(i); }
buildOcTreeV0(scene, rootNode, leaves);
for (const auto& leaf : leaves) {
auto basicRes = basicTask(scene, blobTree, leaf, q);
volume += basicRes.volume * prod(leaf.max - leaf.min);
volume += basicRes.volume * prod(leaf.aabb.max - leaf.aabb.min);
}
volume *= prod(xmax - xmin);

35
algoim/organizer/primitive.hpp

@ -171,6 +171,11 @@ real evalBernstein(const xarray<real, N>& phi, const uvector<real, N>& x)
return bernstein::evalBernsteinPoly(phi, x);
}
void inverseTensor(tensor3& tensor)
{
for (auto i = tensor.loop(); ~i; ++i) { tensor.l(i) = -tensor.l(i); }
}
// class PowerTensor : public Primitive
// {
// public:
@ -603,7 +608,8 @@ public:
}
};
struct AABB {
class AABB
{
public:
uvector3 min = uvector3(std::numeric_limits<real>::max());
uvector3 max = uvector3(std::numeric_limits<real>::lowest());
@ -630,6 +636,20 @@ public:
uvector3 center() const { return (min + max) / 2; }
uvector3 size() const { return max - min; }
bool intersect(const AABB& aabb) const
{
for (int i = 0; i < 3; ++i) {
if (min(i) > aabb.max(i) || max(i) < aabb.min(i)) { return false; }
}
return true;
}
void normalize(const uvector3& scale, const uvector3& boundaryMin)
{
min = (min - boundaryMin) / scale;
max = (max - boundaryMin) / scale;
}
};
void makeMesh(const MeshDesc& mesh, xarray<real, 3>& tensor, std::vector<xarray<real, 3>>& planeTensors, AABB& aabb)
@ -663,7 +683,7 @@ void makeMesh(const MeshDesc& mesh, xarray<real, 3>& tensor, std::vector<xarray<
}
}
detail::compositePower(planeTensors, 0, 0, 1, tensor);
if (mesh.indexInclusiveScan.size() % 2 == 0) { inverseTensor(tensor); }
// AABB
for (const auto& v : mesh.vertices) { aabb.extend(v); }
};
@ -785,7 +805,8 @@ struct CompleteTensorRep {
struct Scene {
std::vector<CompleteTensorRep> polys;
organizer::BlobTree blobTree;
// organizer::BlobTree blobTree;
AABB boundary;
// uvector3 min, max;
};
@ -795,21 +816,21 @@ struct OcTreeNode {
std::vector<int> polyIntersectIndices; // 同一poly会出现在不同node的polyIndices中
// std::vector<int> polyFullyContainedIndices; // 完全包含该node的poly, 同样会出现在不同node的polyIndices中
// std::array<int, CHILD_NUM> children; // octree
uvector3 min, max;
AABB aabb;
organizer::BlobTree blobTree; // 部分遍历过的octree,那些不属于该node的primitive的out信息已经在该blobtree种尽可能地向上传递
// Node() { children.fill(-1); }
OcTreeNode() = default;
OcTreeNode(const uvector3& min_, const uvector3& max_, const organizer::BlobTree& blobTree_)
: min(min_), max(max_), blobTree(blobTree_) {};
: aabb(min_, max_), blobTree(blobTree_) {};
OcTreeNode(const AABB& aabb_, const organizer::BlobTree& blobTree_) : aabb(aabb_), blobTree(blobTree_) {};
// 深拷贝
OcTreeNode(const OcTreeNode& node)
: polyIntersectIndices(node.polyIntersectIndices),
// polyFullyContainedIndices(node.polyFullyContainedIndices),
min(node.min),
max(node.max),
aabb(node.aabb),
blobTree(node.blobTree)
{
int a = 1;

14
algoim/quadrature_multipoly.hpp

@ -569,15 +569,25 @@ struct ImplicitPolyQuadrature {
build(true, false);
}
ImplicitPolyQuadrature(const std::vector<Organizer::CompleteTensorRep>& completeTensorRes)
ImplicitPolyQuadrature(const std::vector<Organizer::CompleteTensorRep>& completeTensorReps)
{
for (const auto& ctr : completeTensorRes) {
for (const auto& ctr : completeTensorReps) {
auto mask = detail::nonzeroMask(ctr.compositedBernstein, booluarray<N, ALGOIM_M>(true));
if (!detail::maskEmpty(mask)) phi.push_back(ctr.compositedBernstein, mask);
}
build(true, false);
}
ImplicitPolyQuadrature(const std::vector<Organizer::CompleteTensorRep>& completeTensorReps,
const std::vector<int>& polyIndices)
{
for (auto i : polyIndices) {
auto mask = detail::nonzeroMask(completeTensorReps[i].compositedBernstein, booluarray<N, ALGOIM_M>(true));
if (!detail::maskEmpty(mask)) phi.push_back(completeTensorReps[i].compositedBernstein, mask);
}
build(true, false);
}
// Build quadrature hierarchy for a given domain implicitly defined by two polynomials with user-defined masks
ImplicitPolyQuadrature(const xarray<real, N>& p,
const booluarray<N, ALGOIM_M>& pmask,

106
gjj/primitiveDebug.hpp

@ -15,6 +15,7 @@
#include "binomial.hpp"
#include "real.hpp"
#include "sparkstack.hpp"
#include "uvector.hpp"
#include "vector"
#include "xarray.hpp"
@ -122,13 +123,28 @@ void casePolyhedronSphere()
basicTask(primitiveDescriptions);
}
void caseTwoCube()
{
auto phi0 = std::make_shared<CuboidDesc>(CuboidDesc(0.2, 0.6));
auto phi1 = std::make_shared<CuboidDesc>(CuboidDesc(-0.2, 0.6));
basicTask({phi0, phi1});
}
void caseCubeSphere()
{
auto phi0 = std::make_shared<CuboidDesc>(CuboidDesc(0.2, 0.6));
auto phi1 = std::make_shared<SphereDesc>(SphereDesc(0.6, -0.2, 1.));
basicTask({phi0, phi1});
}
void caseScene()
{
const int PRIMITIVE_CNT = 6;
std::vector<std::shared_ptr<PrimitiveDesc>> primitiveDescriptions(PRIMITIVE_CNT);
primitiveDescriptions[2] = std::make_shared<CuboidDesc>(CuboidDesc(0., 1.6));
primitiveDescriptions[1] = std::make_shared<CuboidDesc>(CuboidDesc(uvector3(0.6, 0.6, -0.6), 2.));
primitiveDescriptions[0] = std::make_shared<SphereDesc>(SphereDesc(0.7, uvector3(0.8, 0.8, 0.8), 1.));
primitiveDescriptions[0] = std::make_shared<CuboidDesc>(CuboidDesc(0., 1.6));
// primitiveDescriptions[1] = std::make_shared<CuboidDesc>(CuboidDesc(uvector3(0.6, 0.6, -0.6), 2.));
primitiveDescriptions[1] = std::make_shared<SphereDesc>(SphereDesc(1., uvector3(0.6, 0.6, -0.6), 1.));
primitiveDescriptions[2] = std::make_shared<SphereDesc>(SphereDesc(0.7, uvector3(0.8, 0.8, 0.8), 1.));
primitiveDescriptions[3] = std::make_shared<SphereDesc>(SphereDesc(0.5, uvector3(-0.3, -0.8, 0.8), 1.));
std::vector<uvector3> pyramidBottomVertices = {
uvector3{-1, -1, 0},
@ -166,7 +182,8 @@ void testDeCasteljau()
auto phiDesc = std::make_shared<SphereDesc>(SphereDesc(0.8, uvector3(0), 1.));
tensor3 tensor(nullptr, 3), tensor01(nullptr, 3), tensorBernstein(nullptr, 3), transformedTensorBernstein(nullptr, 3);
algoim_spark_alloc(real, tensor, tensor01, tensorBernstein, transformedTensorBernstein);
makeSphere(*phiDesc, tensor);
AABB aabb;
makeSphere(*phiDesc, tensor, aabb);
uvector3 xmax = 1, xmin = -1, range = xmax - xmin;
Organizer::detail::powerTransformation(range, xmin, tensor, tensor01);
Organizer::detail::power2BernsteinTensor(tensor01, tensorBernstein);
@ -193,7 +210,8 @@ void testSubDivideWithDeCasteljau()
auto phiDesc = std::make_shared<SphereDesc>(SphereDesc(0.7, uvector3(0.8), 1.));
tensor3 tensor(nullptr, 3), tensor01(nullptr, 3), tensorBernstein(nullptr, 3), transformedTensorBernstein(nullptr, 3);
algoim_spark_alloc(real, tensor, tensor01, tensorBernstein, transformedTensorBernstein);
makeSphere(*phiDesc, tensor);
AABB aabb;
makeSphere(*phiDesc, tensor, aabb);
uvector3 xmin = uvector3(-1., -1.3, -1.6), xmax = uvector3(1.6, 1.6, 2.3), range = xmax - xmin;
Organizer::detail::powerTransformation(range, xmin, tensor, tensor01);
Organizer::detail::power2BernsteinTensor(tensor01, tensorBernstein);
@ -202,27 +220,44 @@ void testSubDivideWithDeCasteljau()
// bernstein::deCasteljau(tensorBernstein, uvector3(0), uvector3(0.2690598923241497 + 0.0000001),
// transformedTensorBernstein);
for (MultiLoop<3> j(0, 2); ~j; ++j) {
if (all(j() == uvector3i(1, 0, 0))) {
int aaa = 1;
int bbb = 1;
}
auto aabb = Organizer::detail::getOneEightCellAABB(xmin, xmax, j(), 0);
bernstein::deCasteljau(tensorBernstein, aabb.first, aabb.second, transformedTensorBernstein);
int sign = bernstein::uniformSign(transformedTensorBernstein);
auto aabbSub = Organizer::detail::getOneEightCellAABB(AABB{xmin, xmax}, j(), 0);
bernstein::deCasteljau(tensorBernstein, aabbSub.min, aabbSub.max, transformedTensorBernstein);
auto transformedTensorVec = xarray2StdVector(transformedTensorBernstein);
int sign = bernstein::uniformSign(transformedTensorBernstein);
std::cout << "j(): (" << j(0) << ", " << j(1) << ", " << j(2) << "), sign: " << sign << std::endl;
if (all(j() == uvector3i(0, 0, 1))) {
for (MultiLoop<3> k(0, 2); ~k; ++k) {
auto aabbSubSub = Organizer::detail::getOneEightCellAABB(aabbSub, k(), 0);
bernstein::deCasteljau(tensorBernstein, aabbSubSub.min, aabbSubSub.max, transformedTensorBernstein);
int sign = bernstein::uniformSign(transformedTensorBernstein);
std::cout << "k(): (" << k(0) << ", " << k(1) << ", " << k(2) << "), sign: " << sign << std::endl;
}
}
}
uvector3 testX = uvector3(0.5);
bernstein::deCasteljau(tensorBernstein, uvector3(-1., -1.3, 0.35), uvector3(0.3, 0.15, 2.3), transformedTensorBernstein);
int sign = bernstein::uniformSign(transformedTensorBernstein);
real evalX = evalPower(tensor, testX);
uvector3 testX = uvector3(0.5);
real evalX = evalPower(tensor, testX);
std::cout << "evalX original rep = " << evalX << std::endl;
evalX = evalPower(tensor01, testX);
std::cout << "evalX power within 0-1 = " << evalX << std::endl;
evalX = bernstein::evalBernsteinPoly(tensorBernstein, testX);
std::cout << "evalX bernstein within 0-1 = " << evalX << std::endl;
evalX = bernstein::evalBernsteinPoly(transformedTensorBernstein, testX);
std::cout << "evalX bernstein after Decasteljau = " << evalX << std::endl;
std::cout << "sign = " << sign << std::endl;
// 切比雪夫
xmin = uvector3(-1., -1.3, -1.6), xmax = uvector3(1.6, 1.6, 2.3);
auto phi = [](const uvector<real, 3> &x) {
return (x(0) - 0.8) * (x(0) - 0.8) + (x(1) - 0.8) * (x(1) - 0.8) + (x(2) - 0.8) * (x(2) - 0.8) - 0.1 * 0.1;
};
xarray<real, 3> phipoly(nullptr, 3), subPhiPoly(nullptr, 3);
algoim_spark_alloc(real, phipoly, subPhiPoly);
bernstein::bernsteinInterpolate<3>([&](const uvector<real, 3> &x) { return phi(xmin + x * (xmax - xmin)); }, phipoly);
xmin = 0, xmax = 1;
for (MultiLoop<3> j(0, 2); ~j; ++j) {
auto aabbSub = Organizer::detail::getOneEightCellAABB(AABB{xmin, xmax}, j(), 0);
bernstein::deCasteljau(phipoly, aabbSub.min, aabbSub.max, subPhiPoly);
int sign = bernstein::uniformSign(subPhiPoly);
std::cout << "j(): (" << j(0) << ", " << j(1) << ", " << j(2) << "), sign: " << sign << std::endl;
}
}
void testBlob()
@ -238,16 +273,23 @@ void testBlob()
std::cout << sizeof(int) << std::endl;
}
void vectorDebug()
void testTensorInverse()
{
struct A {
std::vector<real> data;
A() = default;
};
A a;
int s = a.data.size();
std::cout << "size: " << s << std::endl;
auto phiDesc = std::make_shared<CuboidDesc>(uvector3(0.2, 0.3, 0.5), uvector3(0.8, 1.1, 0.9));
const int faceCnt = 6;
std::vector<tensor3> tensors(faceCnt, tensor3(nullptr, 2));
std::vector<SparkStack<real> *> sparkStackPtrs(faceCnt);
tensor3 tensor(nullptr, 1 + faceCnt);
algoimSparkAllocHeapVector(sparkStackPtrs, tensors);
algoim_spark_alloc(real, tensor);
AABB aabb;
makeMesh(*phiDesc, tensor, tensors, aabb);
uvector3 testX(0.5, 0.7, 0.2);
real evalX = evalPower(tensor, testX);
std::cout << "before inverse, evalX = " << evalX << std::endl;
inverseTensor(tensor);
evalX = evalPower(tensor, testX);
std::cout << "after inverse, evalX = " << evalX << std::endl;
}
void testPrimitive()
@ -256,6 +298,8 @@ void testPrimitive()
// casePolyhedronSphere();
// testSubDivideWithDeCasteljau();
// testBlob();
caseScene();
// vectorDebug();
// caseScene();
caseCubeSphere();
// caseTwoCube();
// testTensorInverse();
}
Loading…
Cancel
Save