Browse Source

octree debug

master
gjj 6 months ago
parent
commit
1c4d06f102
  1. 147
      algoim/organizer/organizer.hpp
  2. 159
      algoim/organizer/primitive.hpp
  3. 11
      algoim/uvector.hpp
  4. 93
      gjj/primitiveDebug.hpp

147
algoim/organizer/organizer.hpp

@ -37,7 +37,7 @@ void restrictToInnerFace(const tensor3& phi, int k, real facePos, tensor2& res)
{
assert(0 <= k && k < 3);
assert(all(res.ext() == remove_component(phi.ext(), k)));
assert(0 < facePos && facePos < 1);
// assert(0 < facePos && facePos < 1);
real* basisAlongK;
int P = phi.ext(k);
algoim_spark_alloc(real, &basisAlongK, P);
@ -93,13 +93,13 @@ int findFirst(const uvector<int, N>& v, int val, int startIdx = 0)
return -1;
}
std::pair<uvector<int, 3>, uvector<int, 3>> getOneEightCellAABB(const uvector3& min,
const uvector3& max,
const uvector<int, 3> side,
int negativeRep = -1)
std::pair<uvector<real, 3>, uvector<real, 3>> getOneEightCellAABB(const uvector3& min,
const uvector3& max,
const uvector<int, 3> side,
int negativeRep = -1)
{
std::pair<uvector<int, 3>, uvector<int, 3>> res = {min, max};
uvector3 mid = (min + max) / 2;
std::pair<uvector<real, 3>, uvector<real, 3>> res = {min, max};
uvector3 mid = (min + max) / 2;
for (int i = 0; i < 3; ++i) {
if (side(i) == negativeRep) {
res.second(i) = mid(i);
@ -138,15 +138,11 @@ 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]].originalPower, originPt);
primitiveInOuts[i] = isPointInside(scene.polys[polyIntersectIndices[i]].rawPower, originPt);
}
int res = organizer::traverse(blobTree, ocTreeNode.polyIntersectIndices, primitiveInOuts);
assert(res == organizer::NODE_IN || res == organizer::NODE_OUT);
if (res == organizer::NODE_OUT) {
return false;
} else {
return true;
}
return res == organizer::NODE_IN;
}
// std::vector<std::shared_ptr<PrimitiveDesc>> primitives;
@ -167,15 +163,16 @@ void visitSubcellOnBothSidesOfDir(const uvector3& nodeMid,
const int polyIntersectIndex,
const tensor3& poly,
std::array<OcTreeNode, CHILD_NUM>& subNodes,
int startIdxToCheck,
uvector<int, 3>& mark)
// std::array<OcTreeNode, CHILD_NUM>& subNodes,
std::vector<OcTreeNode>& subNodes,
int startIdxToCheck,
uvector<int, 3>& mark)
{
int zeroIdx = detail::findFirst(mark, 0, startIdxToCheck);
if (zeroIdx == -1) {
tensor3 halfCellPoly(nullptr, poly.ext());
algoim_spark_alloc(real, halfCellPoly);
int subIdx = detail::binaryToDecimal(mark);
int subIdx = detail::binaryToDecimal(mark, -1);
auto& subNode = subNodes[subIdx];
bernstein::deCasteljau(poly, subNode.min, subNode.max, halfCellPoly); // 求1/8空间下的表达
if (bernstein::uniformSign(halfCellPoly) != 1) {
@ -195,18 +192,19 @@ void visitSubcellOnBothSidesOfDir(const uvector3& nodeMid,
// 叶节点单独存在leaves中,是因为最后只需要叶节点信息,没有自顶向下/自底向上遍历
// 所以树结构是不需要的记录的
// void buildOcTree(const Scene& scene, std::vector<Node>& intermediateNodes, std::vector<Node> leaves, int nowNodeIdx)
void buildOcTree(const Scene& scene, const OcTreeNode& node, std::vector<OcTreeNode>& leaves)
void buildOcTreeV1(const Scene& scene, const OcTreeNode& node, std::vector<OcTreeNode>& leaves)
{
const std::vector<int>& polyIntersectIndices = node.polyIntersectIndices;
if (polyIntersectIndices.size() <= 4) {
leaves.emplace_back(node);
return;
}
const uvector3& nowNodeMin = node.min;
const uvector3& nowNodeMax = node.max;
std::array<OcTreeNode, CHILD_NUM> subNodes;
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;
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;
@ -274,7 +272,7 @@ void buildOcTree(const Scene& scene, const OcTreeNode& node, std::vector<OcTreeN
if (zeroCount == 0) {
// mark has -1 or 1 only
real nodeMidVal = bernstein::evalBernsteinPoly(poly.compositedBernstein, nodeMid);
int markIdx = detail::binaryToDecimal(mark);
int markIdx = detail::binaryToDecimal(mark, -1);
for (int subIdx = 0; subIdx < CHILD_NUM; ++subIdx) {
if (subIdx == markIdx)
subNodes[subIdx].polyIntersectIndices.emplace_back(polyIntersectIndex);
@ -307,10 +305,55 @@ void buildOcTree(const Scene& scene, const OcTreeNode& node, std::vector<OcTreeN
// subNodes[subIdx].polyFullyContainedIndices.insert(subNodes[subIdx].polyFullyContainedIndices.end(),
// node.polyFullyContainedIndices.begin(),
// node.polyFullyContainedIndices.end());
buildOcTree(scene, subNodes[subIdx], leaves);
buildOcTreeV1(scene, subNodes[subIdx], leaves);
}
}
void buildOcTreeV0(const Scene& scene, const OcTreeNode& node, std::vector<OcTreeNode>& leaves)
{
const std::vector<int>& polyIntersectIndices = node.polyIntersectIndices;
if (polyIntersectIndices.size() <= 4) {
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].blobTree = node.blobTree;
subNodes[subIdx].polyIntersectIndices = std::vector<int>();
}
uvector3 nodeMid = (nowNodeMin + nowNodeMax) / 2;
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) {
tensor3 subcellPoly(nullptr, poly.compositedBernstein.ext());
algoim_spark_alloc(real, subcellPoly);
bernstein::deCasteljau(poly.compositedBernstein, subNodes[subIdx].min, subNodes[subIdx].max, subcellPoly);
int sign = bernstein::uniformSign(subcellPoly);
if (sign == 1) {
// organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, organizer::NODE_OUT);
} else if (sign == -1) {
// organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, organizer::NODE_IN);
} else {
subNodes[subIdx].polyIntersectIndices.emplace_back(polyIntersectIndex);
}
}
uvector3 testX(0.5);
real evalX = bernstein::evalBernsteinPoly(poly.compositedBernstein, testX);
// std::cout << "evalX bernstein within 0-1 = " << evalX << std::endl;
}
for (subIdx = 0; subIdx < CHILD_NUM; ++subIdx) { buildOcTreeV0(scene, subNodes[subIdx], leaves); }
}
/** single object quadrature */
void basicTask(const std::shared_ptr<PrimitiveDesc>& p, int q = 20, real xmin = -1, real xmax = 1)
{
@ -465,16 +508,15 @@ void quadratureScene(const std::vector<std::shared_ptr<PrimitiveDesc>>& primitiv
const organizer::BlobTree& blobTree,
const real q = 10)
{
OcTreeNode rootNode(xmin, xmax, blobTree);
std::vector<OcTreeNode> leaves;
std::vector<SparkStack<real>*> tensorStacks;
std::vector<CompleteTensorRep> completeTensorReps;
real volume;
real volume = 0;
auto integrand = [](const uvector<real, 3>& x) { return 1.0; };
uvector3 range = xmax - xmin;
uvector<real, 3> testX(0., 0.75, 0.2);
uvector<real, 3> testX(0.8, 0.8, 0.8);
for (int i = 0; i < primitives.size(); i++) {
if (auto pt = std::dynamic_pointer_cast<SphereDesc>(primitives[i])) {
tensor3 originTensor(nullptr, 3);
@ -487,9 +529,10 @@ void quadratureScene(const std::vector<std::shared_ptr<PrimitiveDesc>>& primitiv
algoim_spark_alloc(real, transformedTensor);
makeSphere(*pt, originTensor);
detail::powerTransformation(range, xmin, originTensor, transformedTensor);
real testEvaOri = evalPower(originTensor, testX);
detail::power2BernsteinTensor(transformedTensor, phi);
completeTensorReps.emplace_back(CompleteTensorRep{phi, {originTensor}});
} else if (auto pt = std::dynamic_pointer_cast<MeshDesc>(primitives[i])) {
@ -514,14 +557,54 @@ void quadratureScene(const std::vector<std::shared_ptr<PrimitiveDesc>>& primitiv
real testEvalBernstein = bernstein::evalBernsteinPoly(phi, testX);
completeTensorReps.emplace_back(CompleteTensorRep{phi, planeTensors});
} else if (auto pt = std::dynamic_pointer_cast<CylinderDesc>(primitives[i])) {
std::vector<tensor3> rawTensors(3, tensor3(nullptr, 2));
rawTensors[0].ext_ = 3;
rawTensors[0].ext_(pt->alignAxis) = 1;
algoimSparkAllocHeapVector(tensorStacks, rawTensors);
uvector3i resExt = detail::getCompositeExt(rawTensors);
tensor3 phi(nullptr, resExt);
tensorStacks.emplace_back(algoim_spark_alloc_heap(real, phi));
tensor3 compositeTensor(nullptr, resExt);
algoim_spark_alloc(real, compositeTensor);
makeCylinder(*pt, compositeTensor, rawTensors);
detail::powerTransformation(range, xmin, compositeTensor);
real testEvalPower = evalPower(compositeTensor, testX);
detail::power2BernsteinTensor(compositeTensor, phi);
completeTensorReps.emplace_back(CompleteTensorRep{phi, rawTensors});
} else if (auto pt = std::dynamic_pointer_cast<ConeDesc>(primitives[i])) {
tensor3 originTensor(nullptr, 3);
tensor3 transformedTensor(nullptr, 3);
std::vector<tensor3> rawTensors(3, tensor3(nullptr, 2));
rawTensors[0].ext_ = 3;
algoimSparkAllocHeapVector(tensorStacks, rawTensors);
uvector<int, 3> resExt = 2 + 1 + 1 + 1;
tensor3 phi(nullptr, resExt);
tensorStacks.emplace_back(algoim_spark_alloc_heap(real, phi));
tensor3 compositeTensor(nullptr, resExt);
algoim_spark_alloc(real, compositeTensor);
makeCone(*pt, compositeTensor, rawTensors);
detail::powerTransformation(range, xmin, compositeTensor);
real testEvalPower = evalPower(compositeTensor, testX);
detail::power2BernsteinTensor(compositeTensor, phi);
completeTensorReps.emplace_back(CompleteTensorRep{phi, rawTensors});
} else {
std::cerr << "unrecognized primitive type." << std::endl;
}
}
Scene scene{completeTensorReps, blobTree};
buildOcTree(scene, rootNode, leaves);
Scene scene{completeTensorReps, blobTree};
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);

159
algoim/organizer/primitive.hpp

@ -112,19 +112,21 @@ void powerTransformation(const uvector<real, 3>& scale, const uvector<real, 3>&
}
}
static void compositePower(const std::vector<xarray<real, 3>>& powers,
int powerIdx,
uvector<int, 3> powerSum,
real factor,
xarray<real, 3>& res)
uvector3i getCompositeExt(const std::vector<tensor3>& tensors)
{
uvector3i resExt = 1;
for (const auto& t : tensors) { resExt += t.ext() - 1; }
return resExt;
}
void compositePower(const std::vector<xarray<real, 3>>& powers,
int powerIdx,
uvector<int, 3> powerSum,
real factor,
xarray<real, 3>& res)
{
if (powerIdx == 0) {
{
uvector3 ext(1, 1, 1);
for (auto& t : powers) { ext += t.ext() - 1; }
assert(all(ext == res.ext()));
}
assert(all(res.ext() == getCompositeExt(powers)));
xarrayInit(res);
}
if (powerIdx == powers.size()) {
@ -498,17 +500,19 @@ class CylinderDesc : virtual public PrimitiveDesc
public:
const static PrimitiveType type = Cylinder;
uvector3 node1;
uvector3 node2;
// uvector3 node2;
real height;
real radius;
int alignAxis;
// CylinderDesc(const uvector3& n1_, const uvector3& n2_, real r_) : PrimitiveDesc(), node1(n1_), node2(n2_), radius(r_) {}
// 现在是只支持轴对齐x,y,z的圆柱
// TODO: 实现张量积的旋转后换成支持任意方向的
CylinderDesc(const uvector3& n1, real r, real h, int alignAxis) : PrimitiveDesc(), node1(n1), radius(r)
CylinderDesc(const uvector3& n1, real r, real h, int ax) : PrimitiveDesc(), node1(n1), radius(r), height(h), alignAxis(ax)
{
assert(alignAxis >= 0 && alignAxis <= 2);
node2 = node1;
node2(alignAxis) += h;
// node2 = node1;
// node2(alignAxis) += h;
}
void print() override { std::cout << "Cylinder Description" << std::endl; }
@ -519,10 +523,15 @@ class ConeDesc : virtual public PrimitiveDesc
public:
const static PrimitiveType type = Cone;
uvector3 node1;
uvector3 node2;
// uvector3 node2;
real radius;
real height;
int alignAxis;
ConeDesc(const uvector3& n1_, const uvector3& n2_, real r_) : PrimitiveDesc(), node1(n1_), node2(n2_), radius(r_) {}
ConeDesc(const uvector3& n1, real r, real h, int ax) : PrimitiveDesc(), node1(n1), radius(r), height(h), alignAxis(ax)
{
assert(alignAxis >= 0 && alignAxis <= 2);
}
void print() override { std::cout << "Cone Description" << std::endl; }
};
@ -594,7 +603,36 @@ public:
}
};
void makeMesh(const MeshDesc& mesh, xarray<real, 3>& tensor, std::vector<xarray<real, 3>>& planeTensors)
struct AABB {
public:
uvector3 min = uvector3(std::numeric_limits<real>::max());
uvector3 max = uvector3(std::numeric_limits<real>::lowest());
AABB() = default;
AABB(const uvector3& min_, const uvector3& max_) : min(min_), max(max_) {}
void extend(const uvector3& p)
{
for (int i = 0; i < 3; ++i) {
min(i) = std::min(min(i), p(i));
max(i) = std::max(max(i), p(i));
}
}
void extend(const AABB& aabb)
{
for (int i = 0; i < 3; ++i) {
min(i) = std::min(min(i), aabb.min(i));
max(i) = std::max(max(i), aabb.max(i));
}
}
uvector3 center() const { return (min + max) / 2; }
uvector3 size() const { return max - min; }
};
void makeMesh(const MeshDesc& mesh, xarray<real, 3>& tensor, std::vector<xarray<real, 3>>& planeTensors, AABB& aabb)
{
uvector3 ext(1 + mesh.indexInclusiveScan.size());
@ -625,10 +663,12 @@ void makeMesh(const MeshDesc& mesh, xarray<real, 3>& tensor, std::vector<xarray<
}
}
detail::compositePower(planeTensors, 0, 0, 1, tensor);
// return PowerTensorComplex(planeTensors, tensor);
// AABB
for (const auto& v : mesh.vertices) { aabb.extend(v); }
};
void makeSphere(const SphereDesc& sphereDesc, xarray<real, 3>& tensor)
void makeSphere(const SphereDesc& sphereDesc, xarray<real, 3>& tensor, AABB& aabb)
{
uvector<int, 3> ext = 3;
assert(all(ext == tensor.ext()));
@ -642,27 +682,84 @@ void makeSphere(const SphereDesc& sphereDesc, xarray<real, 3>& tensor)
tensor.m(idx) = sphereDesc.amplitude(dim) * sphereDesc.amplitude(dim);
}
tensor.m(0) -= sphereDesc.radius * sphereDesc.radius;
// return PowerTensor(tensor);
// TODO consider the amplitude
aabb.min = sphereDesc.center - sphereDesc.radius;
aabb.max = sphereDesc.center + sphereDesc.radius;
};
void makeCylinder(const CylinderDesc& cylinder, xarray<real, 3>& tensor, std::vector<tensor3>& rawTensors)
void makeCylinder(const CylinderDesc& cylinderDesc, xarray<real, 3>& tensor, std::vector<tensor3>& rawTensors)
{
assert(rawTensors.size() == 3
&& (all(rawTensors[0].ext() == uvector3(3, 3, 1)) || all(rawTensors[0].ext() == uvector3(3, 3, 1))
|| all(rawTensors[0].ext() == uvector3(3, 3, 1)))
&& all(rawTensors[1].ext() == uvector3(2)) && all(rawTensors[1].ext() == uvector3(2)));
uvector<int, 3> ext = 5;
assert(all(ext == tensor.ext()));
auto & cylinderSrf = rawTensors[0], plane1 = rawTensors[1], plane2 = rawTensors[2];
int alignAxis = cylinderDesc.alignAxis;
uvector<int, 3> cylinderExt = 3;
cylinderExt(alignAxis) = 1;
assert(rawTensors.size() == 3 && all(cylinderSrf.ext() == cylinderExt) && all(plane1.ext() == uvector3(2))
&& all(plane2.ext() == uvector3(2)));
assert(all(detail::getCompositeExt(rawTensors) == tensor.ext()));
int dimA = (alignAxis + 1) % 3, dimB = (alignAxis + 2) % 3;
real a = cylinderDesc.node1(dimA), b = cylinderDesc.node1(dimB), c = cylinderDesc.node1(alignAxis), r = cylinderDesc.radius;
uvector<int, 3> idx = 0;
plane1.m(idx) = c;
plane2.m(idx) = -c - cylinderDesc.height;
cylinderSrf.m(idx) = a * a + b * b - r * r;
idx(alignAxis) = 1;
plane1.m(idx) = -1;
plane2.m(idx) = 1;
idx(alignAxis) = 0;
idx(dimA) = 1;
cylinderSrf.m(idx) = -2 * a;
idx(dimA) = 2;
cylinderSrf.m(idx) = 1;
idx = 0;
idx(dimB) = 1;
cylinderSrf.m(idx) = -2 * b;
idx(dimB) = 2;
cylinderSrf.m(idx) = 1;
detail::compositePower(rawTensors, 0, 0, 1, tensor);
}
void makeCone(const CylinderDesc& cone, tensor3& tensor)
void makeCone(const ConeDesc& coneDesc, tensor3& tensor, std::vector<tensor3>& rawTensors)
{
// TODO:
assert(rawTensors.size() == 3 && all(rawTensors[0].ext() == 3) && all(rawTensors[1].ext() == 2)
&& all(rawTensors[2].ext() == 2));
assert(all(tensor.ext() == detail::getCompositeExt(rawTensors)));
auto &coneSrf = rawTensors[0], &plane1 = rawTensors[1], &plane2 = rawTensors[2];
int alignAxis = coneDesc.alignAxis;
int dimA = (alignAxis + 1) % 3, dimB = (alignAxis + 2) % 3;
real a = coneDesc.node1(dimA), b = coneDesc.node1(dimB), c = coneDesc.node1(alignAxis);
real scale = coneDesc.height / coneDesc.radius, scaleSquare = scale * scale;
// f = (scale(x-a))^2 + (scale(y-b))^2 - (z-c)^2
uvector<int, 3> idx = 0;
plane1.m(idx) = c;
plane2.m(idx) = -c - coneDesc.height;
coneSrf.m(idx) = scaleSquare * (a * a + b * b) - c * c;
idx(alignAxis) = 1;
plane1.m(idx) = -1;
plane2.m(idx) = 1;
coneSrf.m(idx) = 2 * c;
idx(alignAxis) = 2;
coneSrf.m(idx) = -1;
idx(alignAxis) = 0;
idx(dimA) = 1;
coneSrf.m(idx) = scaleSquare * (-2 * a);
idx(dimA) = 2;
coneSrf.m(idx) = scaleSquare;
idx = 0;
idx(dimB) = 1;
coneSrf.m(idx) = scaleSquare * (-2 * b);
idx(dimB) = 2;
coneSrf.m(idx) = scaleSquare;
detail::compositePower(rawTensors, 0, 0, 1, tensor);
}
struct CompleteTensorRep {
tensor3 compositedBernstein; // 合法输入在[0,1]^3
std::vector<tensor3> originalPower; // 合法输入在场景<min, max>
std::vector<tensor3> rawPower; // 合法输入在场景<min, max>
};
struct Scene {
@ -694,6 +791,8 @@ struct OcTreeNode {
max(node.max),
blobTree(node.blobTree)
{
int a = 1;
int b = 2;
}
};

11
algoim/uvector.hpp

@ -71,8 +71,7 @@ using extent = std::integral_constant<int, extent_of<std::decay_t<T>>::value>;
// binary uvector expressions
#define algoim_decl_binary_op(op) \
template <typename E1, \
typename E2, \
template <typename E1, typename E2, \
std::enable_if_t<(detail::extent<E1>::value > 0) || (detail::extent<E2>::value > 0), bool> = true> \
auto operator op(E1&& e1, E2&& e2) \
{ \
@ -162,8 +161,12 @@ public:
#undef algoim_decl_assign_op
};
using uvector3 = uvector<real, 3>;
using uvector2 = uvector<real, 2>;
using uvector3f = uvector<real, 3>;
using uvector2f = uvector<real, 2>;
using uvector3i = uvector<int, 3>;
using uvector2i = uvector<int, 2>;
using uvector3 = uvector3f;
using uvector2 = uvector2f;
// some methods, particularly those which remove components of a vector, benefit
// from having a zero-length uvector; it is simply an empty class

93
gjj/primitiveDebug.hpp

@ -124,21 +124,41 @@ void casePolyhedronSphere()
void caseScene()
{
std::vector<std::shared_ptr<PrimitiveDesc>> primitiveDescriptions(7);
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[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.));
primitiveDescriptions[4] = std::make_shared<ConeDesc>(ConeDesc(uvector3(0., -0.2, 0.), uvector3(0., -0.9, 0.), 0.4));
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[3] = std::make_shared<SphereDesc>(SphereDesc(0.5, uvector3(-0.3, -0.8, 0.8), 1.));
std::vector<uvector3> pyramidBottomVertices = {
uvector3{-1, -1, 0},
uvector3{1, -1, 0},
uvector3{1, 1, 0},
uvector3{-1, 1, 0}
};
primitiveDescriptions[5] = std::make_shared<PyramidDesc>(pyramidBottomVertices, uvector3{0, 0, 1});
primitiveDescriptions[4] = std::make_shared<CylinderDesc>(CylinderDesc(uvector3(-0.3, 0.3, 2.3), 0.4, 3.6, 1));
quadratureScene(primitiveDescriptions, uvector3(-1., -1.3, -1.6), uvector3(1.6, 1.6, 2.3), organizer::BlobTree());
primitiveDescriptions[4] = std::make_shared<PyramidDesc>(pyramidBottomVertices, uvector3{0, 0, 1});
primitiveDescriptions[5] = std::make_shared<ConeDesc>(ConeDesc(uvector3(0., -0.2, 0.), -0.7, 0.4, 1));
// primitiveDescriptions[6] = std::make_shared<CylinderDesc>(CylinderDesc(uvector3(-0.3, 0.3, 2.3), 0.4, 3.6, 1));
organizer::BlobTree blobTree;
blobTree.structure.resize(PRIMITIVE_CNT * 2 - 1);
blobTree.primitiveNodeIdx.resize(PRIMITIVE_CNT);
blobTree.structure[0] = {1, 0, 0, 0, 1, 2}; // cube1
blobTree.structure[1] = {1, 0, 0, 0, 0, 0}; // cube2
blobTree.structure[2] = {0, 0, 0, 0, 1, 6}; // Union of cubes = opNode1
blobTree.structure[3] = {1, 0, 0, 0, 1, 5}; // sphere1
blobTree.structure[4] = {1, 0, 0, 0, 0, 0}; // sphere2
blobTree.structure[5] = {0, 0, 0, 0, 0, 0}; // Union of spheres = opNode2
blobTree.structure[6] = {0, 2, 0, 0, 1, 10}; // Difference of opNode1 and sphere2 = opNode3
blobTree.structure[7] = {1, 0, 0, 0, 1, 9}; // Pyramid
blobTree.structure[8] = {1, 0, 0, 0, 0, 0}; // Cone
blobTree.structure[9] = {0, 1, 0, 0, 0, 0}; // Intersection of Pyramid and Cone = opNode4
blobTree.structure[10] = {0, 0, 0, 0, 1, 12}; // Union of opNode3 and opNode4 = opNode5
// blobTree.structure[11] = {1, 0, 0, 0, 0, 0}; // Cylinder
// blobTree.structure[12] = {0, 2, 0, 0, 1, 0}; // Difference of opNode5 and Cylinder
// blobTree.primitiveNodeIdx = {0, 1, 3, 4, 7, 8, 11};
// quadratureScene(primitiveDescriptions, uvector3(-1., -1.3, -1.6), uvector3(1.6, 1.6, 2.3), blobTree);
blobTree.primitiveNodeIdx = {0, 1, 3, 4, 7, 8};
quadratureScene(primitiveDescriptions, uvector3(-1., -1.3, -1.6), uvector3(1.6, 1.6, 1.5), blobTree);
}
void testDeCasteljau()
@ -168,6 +188,43 @@ void testDeCasteljau()
std::cout << "sign = " << sign << std::endl;
}
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);
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);
xmin = 0, xmax = 1;
// 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);
std::cout << "j(): (" << j(0) << ", " << j(1) << ", " << j(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);
std::cout << "evalX original rep = " << 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;
}
void testBlob()
{
organizer::Blob blob = {5, 3, 4, 5, 6};
@ -181,10 +238,24 @@ void testBlob()
std::cout << sizeof(int) << std::endl;
}
void vectorDebug()
{
struct A {
std::vector<real> data;
A() = default;
};
A a;
int s = a.data.size();
std::cout << "size: " << s << std::endl;
}
void testPrimitive()
{
// casePolyhedron1();
// casePolyhedronSphere();
// testDeCasteljau();
testBlob();
// testSubDivideWithDeCasteljau();
// testBlob();
caseScene();
// vectorDebug();
}
Loading…
Cancel
Save