#include #include #include #include #include #include #include #include #include #include "bernstein.hpp" #include "multiloop.hpp" #include "quadrature_multipoly.hpp" #include "binomial.hpp" #include "real.hpp" #include "sparkstack.hpp" #include "uvector.hpp" #include "vector" #include "xarray.hpp" #include #include #include #include "organizer/primitive.hpp" namespace algoim::Organizer { bool keepQuadraturePoint(std::vector& originTensors, const uvector3& originPt) { // TODO: using blobtree to filter tensors for (auto& t : originTensors) { if (evalPower(t, originPt) >= 0) { return false; } } return true; } // std::vector> primitives; // BasicTask(std::vector> ps) {}; void basicTask(const std::shared_ptr& p, int q = 20, real xmin = -1, real xmax = 1) { real volume = 0; auto integrand = [](const uvector& x) { return 1.0; }; uvector3 range = xmax - xmin; if (auto pt = std::dynamic_pointer_cast(p)) { tensor3 tensor(nullptr, 3); algoim_spark_alloc(real, tensor); makeSphere(*pt, tensor); detail::powerTransformation(range, xmin, tensor); tensor3 phi(nullptr, 3); algoim_spark_alloc(real, phi); detail::power2BernsteinTensor(tensor, phi); uvector testX(0., 0., 0.25); real testEvalBernstein = bernstein::evalBernsteinPoly(phi, testX); // auto vec1 = xarray2StdVector(phi); std::cout << "eval bernstein without interpolation:" << testEvalBernstein << std::endl; ImplicitPolyQuadrature<3> ipquad(phi); ipquad.integrate(AutoMixed, q, [&](const uvector& x, real w) { if (isInsideBernstein(phi, x)) volume += w * integrand(xmin + x * (xmax - xmin)); }); } else if (auto pt = std::dynamic_pointer_cast(p)) { const int faceCount = pt->indexInclusiveScan.size(); assert(faceCount > 1); std::vector planeTensors(faceCount, tensor3(nullptr, 2)); algoim_spark_alloc(real, planeTensors); tensor3 compositeTensor(nullptr, 1 + faceCount); algoim_spark_alloc(real, compositeTensor); makeMesh(*pt, compositeTensor, planeTensors); detail::powerTransformation(range, xmin, compositeTensor); auto planeStdVector1 = xarray2StdVector(planeTensors[0]); auto planeStdVector2 = xarray2StdVector(planeTensors[1]); auto compositeTensorStdVector = xarray2StdVector(compositeTensor); uvector testX(0., 0.75, 0.2); real textEvalPower = evalPower(compositeTensor, testX); tensor3 phi(nullptr, 1 + faceCount); algoim_spark_alloc(real, phi); detail::power2BernsteinTensor(compositeTensor, phi); int quadraturePointCount = 0; ImplicitPolyQuadrature<3> ipquad(phi); real testEvalBernstein = bernstein::evalBernsteinPoly(phi, testX); ipquad.integrate(AutoMixed, q, [&](const uvector& x, real w) { quadraturePointCount++; auto realX = x * range + xmin; if (isInsidePowers(planeTensors, realX)) volume += w * integrand(realX); }); std::cout << "textEvalPower: " << textEvalPower << std::endl; std::cout << "quadraturePointCount: " << quadraturePointCount << std::endl; } volume *= pow(xmax - xmin, 3); std::cout << "Volume xxx: " << volume << std::endl; }; void basicTask(const std::vector>& primitives, int q = 20, real xmin = -1, real xmax = 1) { std::vector*> phiStacks; std::vector phis; std::vector*> originTensorStacks; std::vector originTensors; real volume; auto integrand = [](const uvector& x) { return 1.0; }; uvector3 range = xmax - xmin; uvector testX(0., 0.75, 0.2); for (int i = 0; i < primitives.size(); i++) { if (auto pt = std::dynamic_pointer_cast(primitives[i])) { tensor3 originTensor(nullptr, 3), transformedTensor(nullptr, 3); originTensorStacks.emplace_back(algoim_spark_alloc_heap(real, originTensor)); // 记录,用以最后bool tensor3 phi(nullptr, 3); phiStacks.emplace_back( algoim_spark_alloc_heap(real, phi)); // 必须先于algoim_spark_alloc,使transformedTensor的内存以栈形式释放 algoim_spark_alloc(real, transformedTensor); makeSphere(*pt, originTensor); originTensors.emplace_back(originTensor); detail::powerTransformation(range, xmin, originTensor, transformedTensor); detail::power2BernsteinTensor(transformedTensor, phi); phis.emplace_back(phi); } else if (auto pt = std::dynamic_pointer_cast(primitives[i])) { const int faceCount = pt->indexInclusiveScan.size(); assert(faceCount > 1); std::vector planeTensors(faceCount, tensor3(nullptr, 2)); algoimSparkAllocHeapVector(originTensorStacks, planeTensors); tensor3 phi(nullptr, 1 + faceCount); phiStacks.emplace_back( algoim_spark_alloc_heap(real, phi)); // 必须先于algoim_spark_alloc,使compositeTensor的内存以栈形式释放 tensor3 compositeTensor(nullptr, 1 + faceCount); algoim_spark_alloc(real, compositeTensor); makeMesh(*pt, compositeTensor, planeTensors); detail::powerTransformation(range, xmin, compositeTensor); real testEvalPower = evalPower(compositeTensor, testX); originTensors.insert(originTensors.end(), planeTensors.begin(), planeTensors.end()); detail::power2BernsteinTensor(compositeTensor, phi); real testEvalBernstein = bernstein::evalBernsteinPoly(phi, testX); phis.emplace_back(phi); } } real testEvalBernstein = bernstein::evalBernsteinPoly(phis[0], testX); ImplicitPolyQuadrature<3> ipquad(phis); ipquad.integrate(AutoMixed, q, [&](const uvector& x, real w) { auto realX = x * range + xmin; if (keepQuadraturePoint(originTensors, realX)) volume += w * integrand(realX); }); volume *= pow(xmax - xmin, 3); std::cout << "Volume xxx: " << volume << std::endl; // free memory, thus deallocate memory of xarray for (auto& p : phiStacks) delete p; for (auto& p : originTensorStacks) delete p; }; void quadratureTask(const Scene& scene) {} void buildOctree(const Scene& scene, std::vector& nodes, const uvector3& min, const uvector3& max) {} }; // namespace algoim::Organizer