Browse Source

case scene of 30 objs

master
gjj 6 months ago
parent
commit
4914ecdfc1
  1. 9
      algoim/factorial.hpp
  2. 12
      algoim/organizer/organizer.hpp
  3. 10
      algoim/organizer/primitive.hpp
  4. 135
      gjj/primitiveDebug.hpp

9
algoim/factorial.hpp

@ -9,21 +9,16 @@ class Factorial
public:
static std::vector<real> cache;
Factorial()
{
if (cache.empty()) cache.push_back(1);
}
static real calculate(int n)
{
if (n == 0) return 1;
if (cache.size() <= n) {
for (int i = cache.size(); i <= n; ++i) cache.push_back(cache.back() * i);
for (int i = cache.size(); i <= n; ++i) cache.push_back(cache[i - 1] * i);
}
return cache[n];
}
};
std::vector<real> Factorial::cache; // 。
std::vector<real> Factorial::cache = {1}; // 。
} // namespace algoim

12
algoim/organizer/organizer.hpp

@ -61,7 +61,7 @@ int numOfZero(const uvector<int, N>& v)
}
template <int N>
int binaryToDecimal(const uvector<int, N>& v, int zeroRep = 0)
int binary2Decimal(const uvector<int, N>& v, int zeroRep = 0)
{
int res = 0;
int base = 1;
@ -160,7 +160,7 @@ void visitSubcellOnBothSidesOfDir(const uvector3& nodeMid,
if (zeroIdx == -1) {
tensor3 halfCellPoly(nullptr, poly.ext());
algoim_spark_alloc(real, halfCellPoly);
int subIdx = detail::binaryToDecimal(mark, -1);
int subIdx = detail::binary2Decimal(mark, -1);
auto& subNode = subNodes[subIdx];
bernstein::deCasteljau(poly, subNode.aabb.min, subNode.aabb.max, halfCellPoly); // 求1/8空间下的表达
if (bernstein::uniformSign(halfCellPoly) != 1) {
@ -256,7 +256,7 @@ void buildOcTreeV1(const Scene& scene, const OcTreeNode& node, std::vector<OcTre
if (zeroCount == 0) {
// mark has -1 or 1 only
real nodeMidVal = bernstein::evalBernsteinPoly(poly, nodeMid);
int markIdx = detail::binaryToDecimal(mark, -1);
int markIdx = detail::binary2Decimal(mark, -1);
for (int subIdx = 0; subIdx < CHILD_NUM; ++subIdx) {
if (subIdx == markIdx)
subNodes[subIdx].polyIntersectIndices.emplace_back(polyIntersectIndex);
@ -267,9 +267,9 @@ void buildOcTreeV1(const Scene& scene, const OcTreeNode& node, std::vector<OcTre
// poly related to 2 subcells
uvector<int, 3> sideMark = mark;
int zeroIdx = detail::replaceFirst(sideMark, 0, 1);
int sideIdx1 = detail::binaryToDecimal(sideMark, -1);
int sideIdx1 = detail::binary2Decimal(sideMark, -1);
sideMark(zeroIdx) = -1;
int sideIdx2 = detail::binaryToDecimal(sideMark, -1);
int sideIdx2 = detail::binary2Decimal(sideMark, -1);
subNodes[sideIdx1].polyIntersectIndices.emplace_back(polyIntersectIndex);
subNodes[sideIdx2].polyIntersectIndices.emplace_back(polyIntersectIndex);
for (int subIdx = 0; subIdx < CHILD_NUM; ++subIdx) {
@ -306,7 +306,7 @@ void buildOcTreeV0(const Scene& scene, const OcTreeNode& node, std::vector<OcTre
int bbb = 1;
}
const std::vector<int>& polyIntersectIndices = node.polyIntersectIndices;
if (polyIntersectIndices.size() <= 3) {
if (polyIntersectIndices.size() <= 4) {
leaves.emplace_back(node);
return;
}

10
algoim/organizer/primitive.hpp

@ -152,8 +152,8 @@ void powerTransformation(const uvector<real, 3>& scale, const uvector<real, 3>&
// Note: 旋转张量似乎会提高结果张量的阶次,需要旋转后再降阶
void powerRotation(const uvector3& vec, const real theta, const tensor3& originalPower, tensor3& res)
{
int maxDegree = sum(originalPower.ext()) - 3 + 1;
assert(all(res.ext() == maxDegree));
// int maxDegree = sum(originalPower.ext()) - 3 + 1;
// assert(all(res.ext() == maxDegree));
// 获得旋转矩阵
tensor2 rotation(nullptr, uvector2(3, 3));
algoim_spark_alloc(real, rotation);
@ -178,11 +178,11 @@ void powerRotation(const uvector3& vec, const real theta, const tensor3& origina
item *= pow(rotation.m(uvector2(1, dim)), jy(dim));
item *= pow(rotation.m(uvector2(2, dim)), jz(dim));
}
item *= Factorial::calculate(exp(0))
item *= Factorial::calculate(exps(0))
/ (Factorial::calculate(jx(0)) * Factorial::calculate(jx(1)) * Factorial::calculate(jx(2)));
item *= Factorial::calculate(exp(1))
item *= Factorial::calculate(exps(1))
/ (Factorial::calculate(jy(0)) * Factorial::calculate(jy(1)) * Factorial::calculate(jy(2)));
item *= Factorial::calculate(exp(2))
item *= Factorial::calculate(exps(2))
/ (Factorial::calculate(jz(0)) * Factorial::calculate(jz(1)) * Factorial::calculate(jz(2)));
assert(sumExps(0) < res.ext(0) && sumExps(1) < res.ext(1) && sumExps(2) < res.ext(2));
res.m(sumExps) += item;

135
gjj/primitiveDebug.hpp

@ -1,5 +1,6 @@
#include <array>
#include <bitset>
#include <cassert>
#include <iostream>
#include <booluarray.hpp>
@ -10,6 +11,7 @@
#include <fstream>
#include <vector>
#include "bernstein.hpp"
#include "factorial.hpp"
#include "multiloop.hpp"
#include "quadrature_multipoly.hpp"
#include "binomial.hpp"
@ -203,6 +205,109 @@ void caseScene()
quadratureScene(primitiveDescriptions, uvector3(-0.8, -1.3, -1.6), uvector3(1.6, 1.6, 1.5), blobTree);
}
void caseScene30Objs()
{
const int PRIMITIVE_CNT = 30;
std::vector<std::shared_ptr<PrimitiveDesc>> primitiveDescriptions(PRIMITIVE_CNT);
uvector3 sceneSize = 0.8, sceneCenter = 0.;
for (MultiLoop<3> i(0, 2); ~i; ++i) {
uvector3 center = sceneSize * i() - 0.5 * sceneSize + sceneCenter;
int idx = organizer::detail::binary2Decimal(i());
primitiveDescriptions[2 * idx] = std::make_shared<CuboidDesc>(CuboidDesc(center, 0.16));
primitiveDescriptions[2 * idx + 1] = std::make_shared<SphereDesc>(SphereDesc(0.15, center, 1.));
} // 16 primitives
for (int dim = 0; dim < 3; ++dim) {
for (MultiLoop<2> i(0, 2); ~i; ++i) {
uvector3 bottomCenter = add_component(i(), dim, 0) * sceneSize - 0.5 * sceneSize + sceneCenter;
primitiveDescriptions[organizer::detail::binary2Decimal(i()) + 4 * dim + 16] =
std::make_shared<CylinderDesc>(CylinderDesc(bottomCenter, 0.1, sceneSize(dim), dim));
}
} // 12 primitives
uvector3 coneBottom = uvector3(1, 0, 0) * sceneSize - 0.5 * sceneSize + sceneCenter;
primitiveDescriptions[28] = std::make_shared<ConeDesc>(coneBottom, 0.2, 0.5, 1);
uvector3 pyramidBottom = uvector3(0, 0, 1) * sceneSize - 0.5 * sceneSize + sceneCenter;
std::vector<uvector3> pyramidBottomVertices = {
0.2 * pyramidBottom + uvector3{-1, 0, -1},
0.2 * pyramidBottom + uvector3{1, 0, -1},
0.2 * pyramidBottom + uvector3{1, 0, 1 },
0.2 * pyramidBottom + uvector3{-1, 0, 1 }
};
primitiveDescriptions[29] = std::make_shared<PyramidDesc>(pyramidBottomVertices, pyramidBottom + uvector3{0, 0.7, 0});
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}; // sphere1
blobTree.structure[2] = {0, OP_DIFFERENCE, 0, 0, 1, 6 - 2}; // Dif of = opNode1
blobTree.structure[3] = {1, 0, 0, 0, 1, 5 - 3}; // cube2
blobTree.structure[4] = {1, 0, 0, 0, 0, 0}; // sphere2
blobTree.structure[5] = {0, OP_DIFFERENCE, 0, 0, 0, 0}; // Dif of = opNode2
blobTree.structure[6] = {0, OP_UNION, 0, 0, 1, 14 - 6}; // Union of = opNode3
blobTree.structure[7] = {1, 0, 0, 0, 1, 9 - 7}; // cube3
blobTree.structure[8] = {1, 0, 0, 0, 0, 0}; // sphere3
blobTree.structure[9] = {0, OP_DIFFERENCE, 0, 0, 1, 13 - 9}; // Dif of = opNode4
blobTree.structure[10] = {1, 0, 0, 0, 1, 12 - 10}; // cube4
blobTree.structure[11] = {1, 0, 0, 0, 0, 0}; // sphere4
blobTree.structure[12] = {0, OP_DIFFERENCE, 0, 0, 0, 0}; // Dif of = opNode5
blobTree.structure[13] = {0, OP_UNION, 0, 0, 0, 0}; // Union of = opNode6
blobTree.structure[14] = {0, OP_UNION, 0, 0, 1, 30 - 14}; // Union of = opNode7
blobTree.structure[15] = {1, 0, 0, 0, 1, 17 - 15}; // cube5
blobTree.structure[16] = {1, 0, 0, 0, 0, 0}; // sphere5
blobTree.structure[17] = {0, OP_DIFFERENCE, 0, 0, 1, 21 - 17}; // Dif of = opNode8
blobTree.structure[18] = {1, 0, 0, 0, 1, 20 - 18}; // cube6
blobTree.structure[19] = {1, 0, 0, 0, 0, 0}; // sphere6
blobTree.structure[20] = {0, OP_DIFFERENCE, 0, 0, 0, 0}; // Dif of = opNode9
blobTree.structure[21] = {0, OP_UNION, 0, 0, 1, 29 - 21}; // Union of = opNode10
blobTree.structure[22] = {1, 0, 0, 0, 1, 24 - 22}; // cube7
blobTree.structure[23] = {1, 0, 0, 0, 0, 0}; // sphere7
blobTree.structure[24] = {0, OP_DIFFERENCE, 0, 0, 1, 28 - 24}; // Dif of = opNode11
blobTree.structure[25] = {1, 0, 0, 0, 1, 27 - 25}; // cube8
blobTree.structure[26] = {1, 0, 0, 0, 0, 0}; // sphere8
blobTree.structure[27] = {0, OP_DIFFERENCE, 0, 0, 0, 0}; // Dif of = opNode12
blobTree.structure[28] = {0, OP_UNION, 0, 0, 0, 0}; // Union of = opNode13
blobTree.structure[29] = {0, OP_UNION, 0, 0, 0, 0}; // Union of = opNode14
blobTree.structure[30] = {0, OP_UNION, 0, 0, 1, 32 - 30}; // Dif of = opNode15
blobTree.structure[31] = {1, 0, 0, 0, 1, 33 - 31}; // cylinder1
blobTree.structure[32] = {1, 0, 0, 0, 0, 0}; // cylinder2
blobTree.structure[33] = {0, OP_UNION, 0, 0, 1, 37 - 33}; // Union of = opNode16
blobTree.structure[34] = {1, 0, 0, 0, 1, 36 - 34}; // cylinder3
blobTree.structure[35] = {1, 0, 0, 0, 0, 0}; // cylinder4
blobTree.structure[36] = {0, OP_UNION, 0, 0, 0, 0}; // Union of = opNode17
blobTree.structure[37] = {0, OP_UNION, 0, 0, 1, 45 - 37}; // Union of = opNode18
blobTree.structure[38] = {1, 0, 0, 0, 1, 40 - 38}; // cylinder5
blobTree.structure[39] = {1, 0, 0, 0, 0, 0}; // cylinder6
blobTree.structure[40] = {0, OP_UNION, 0, 0, 1, 44 - 40}; // Union of = opNode19
blobTree.structure[41] = {1, 0, 0, 0, 1, 43 - 41}; // cylinder7
blobTree.structure[42] = {1, 0, 0, 0, 0, 0}; // cylinder8
blobTree.structure[43] = {0, OP_UNION, 0, 0, 0, 0}; // Union of = opNode20
blobTree.structure[44] = {0, OP_UNION, 0, 0, 0, 0}; // Union of = opNode21
blobTree.structure[45] = {0, OP_UNION, 0, 0, 1, 53 - 45}; // Union of = opNode22
blobTree.structure[46] = {1, 0, 0, 0, 1, 48 - 46}; // cylinder9
blobTree.structure[47] = {1, 0, 0, 0, 0, 0}; // cylinder10
blobTree.structure[48] = {0, OP_UNION, 0, 0, 1, 52 - 48}; // Union of = opNode23
blobTree.structure[49] = {1, 0, 0, 0, 1, 51 - 49}; // cylinder11
blobTree.structure[50] = {1, 0, 0, 0, 0, 0}; // cylinder12
blobTree.structure[51] = {0, OP_UNION, 0, 0, 0, 0}; // Union of = opNode24
blobTree.structure[52] = {0, OP_UNION, 0, 0, 0, 0}; // Union of = opNode25
blobTree.structure[53] = {0, OP_UNION, 0, 0, 0, 0}; // Union of = opNode26
blobTree.structure[54] = {0, OP_UNION, 0, 0, 1, 58 - 54}; // UNION of = opNode27
blobTree.structure[55] = {1, 0, 0, 0, 1, 57 - 55}; // cone
blobTree.structure[56] = {1, 0, 0, 0, 0, 0}; // pyramid
blobTree.structure[57] = {0, OP_UNION, 0, 0, 1, 59 - 57}; // UNION of = opNode28
blobTree.structure[58] = {0, OP_UNION, 0, 0, 0, 0}; // UNION of = opNode29
int leafCnt = 0;
for (int i = 0; i < blobTree.structure.size(); ++i) {
if (blobTree.structure[i].isPrimitive) { blobTree.primitiveNodeIdx[leafCnt++] = i; }
}
assert(leafCnt == PRIMITIVE_CNT);
quadratureScene(primitiveDescriptions, sceneCenter - 0.5 * sceneSize - 0.2, sceneCenter + 0.5 * sceneSize + 0.2, blobTree);
}
void caseScene1()
{
const int PRIMITIVE_CNT = 2;
@ -413,7 +518,7 @@ void testTensorInverse()
void testRotation()
{
auto desc = std::make_shared<SphereDesc>(SphereDesc(0.1, uvector3(0.1, 0.2, 0.1)));
auto desc = std::make_shared<SphereDesc>(SphereDesc(0.1, uvector3(0, 0., 0.)));
tensor3 power(nullptr, 3);
algoim_spark_alloc(real, power);
VisiblePrimitiveRep visiblePrimitiveRep{{power}, AABB{}, BlobTree()};
@ -422,18 +527,18 @@ void testRotation()
real evalX = evalPower(power, testX);
std::cout << "before rotation, evalX = " << evalX << std::endl;
// tensor3 rotatedPower(nullptr, sum(power.ext()) - 3 + 1);
// algoim_spark_alloc(real, rotatedPower);
// uvector3 axis = uvector3(4, 2, 3);
// axis = axis / norm(axis);
// organizer::detail::powerRotation(axis, util::pi / 2, power, rotatedPower);
// evalX = evalPower(rotatedPower, testX);
// std::cout << "after rotation, evalX = " << evalX << std::endl;
// bool b = bernstein::autoReduction(rotatedPower, 1e4 * std::numeric_limits<real>::epsilon());
// std::cout << "auto reduction = " << b << std::endl;
// evalX = evalPower(rotatedPower, testX);
// std::cout << "after reduction, evalX = " << evalX << std::endl;
tensor3 rotatedPower(nullptr, sum(power.ext()));
algoim_spark_alloc(real, rotatedPower);
uvector3 axis = uvector3(4, 2, 3);
axis = axis / norm(axis);
organizer::detail::powerRotation(axis, util::pi / 2, power, rotatedPower);
evalX = evalPower(rotatedPower, testX);
std::cout << "after rotation, evalX = " << evalX << std::endl;
bool b = bernstein::autoReduction(rotatedPower, 1e5 * std::numeric_limits<real>::epsilon());
std::cout << "auto reduction = " << b << std::endl;
evalX = evalPower(rotatedPower, testX);
std::cout << "after reduction, evalX = " << evalX << std::endl;
}
void testPrimitive()
@ -443,8 +548,10 @@ void testPrimitive()
// casePolyhedronSphere();
// testSubDivideWithDeCasteljau();
// testBlob();
// testRotation();
// caseScene();
testRotation();
caseScene30Objs();
// caseScene1();
// caseScene2();
// caseCone();

Loading…
Cancel
Save