| 
						
						
						
					 | 
				
				 | 
				
					@ -1,5 +1,6 @@ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#pragma once | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <cassert> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <cmath> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <cstddef> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include <vector> | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					#include "iostream" | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -17,36 +18,6 @@ namespace algoim::Organizer | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					namespace detail | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					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())); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        xarrayInit(res); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    if (powerIdx == powers.size()) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        res.m(powerSum) += factor; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    auto& power = powers[powerIdx]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (auto i = power.loop(); ~i; ++i) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (power.l(i) == 0) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            factor = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            continue; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        compositePower(powers, powerIdx + 1, powerSum + i(), factor * power.l(i), res); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // int a = 1;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// void compositePower(const std::vector<xarray<real, 3>>& powers) {}
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					template <int N> | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -113,7 +84,7 @@ class Primitive | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					public: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    virtual void print() = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    virtual real eval(uvector3) { return 0; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    virtual real eval(const uvector3&) { return 0; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					template <int N> | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -135,216 +106,243 @@ real evalBernstein(const xarray<real, N>& phi, const uvector<real, N>& x) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return bernstein::evalBernsteinPoly(phi, x); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class PowerTensor : public Primitive | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// class PowerTensor : public Primitive
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// public:
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     xarray<real, 3> tensor;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     // SparkStack<real>* sparkStackPtr;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     void print() override { std::cout << "Power" << std::endl; }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     real eval(const uvector3& p) override { return evalPower(tensor, p); }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     // PowerTensor() {}
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     PowerTensor(const xarray<real, 3>& t_) : tensor(t_) {}
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     // const xarray<real, 3>& getTensor() { return tensor; }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     ~PowerTensor() = default;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// };
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// class PowerTensorComplex : public Primitive
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// public:
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     xarray<real, 3>              compositeTensor; // 复合后的张量
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     SparkStack<real>*            sparkStackPtr;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     std::vector<xarray<real, 3>> tensors;         // 原始张量
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     // std::vector<PowerTensor> powerTensors; // 原始张量
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     void print() override { std::cout << "PowerTensorComplex" << std::endl; }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     static void compositePower(const std::vector<PowerTensor>& powers,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                                int                             powerIdx,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                                uvector<int, 3>                 powerSum,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                                real                            factor,
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                                xarray<real, 3>&                res)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         // const xarray<real, 3>& tensor
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         if (powerIdx == 0) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                 uvector3 ext(1, 1, 1);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                 for (auto& t : powers) { ext += t.tensor.ext() - 1; }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                 assert(all(ext == res.ext()));
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             xarrayInit(res);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         if (powerIdx == powers.size()) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             res.m(powerSum) += factor;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             return;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         auto& tensor = powers[powerIdx].tensor;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         for (auto i = tensor.loop(); ~i; ++i) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             if (tensor.l(i) == 0) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                 factor = 0;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                 continue;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             compositePower(powers, powerIdx + 1, powerSum + i(), factor * tensor.l(i), res);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     static 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()));
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             xarrayInit(res);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         if (powerIdx == powers.size()) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             res.m(powerSum) += factor;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             return;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         auto& power = powers[powerIdx];
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         for (auto i = power.loop(); ~i; ++i) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             if (power.l(i) == 0) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                 factor = 0;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                 continue;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             compositePower(powers, powerIdx + 1, powerSum + i(), factor * power.l(i), res);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     // PowerTensorComplex() {}
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     PowerTensorComplex(const std::vector<xarray<real, 3>>& ts_, xarray<real, 3>& ct_) : tensors(ts_), compositeTensor(ct_)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         uvector3 ext(1);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         for (auto& t : ts_) { ext += t.ext() - 1; }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         assert(all(ext == compositeTensor.ext()));
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         compositePower(tensors, 0, uvector3(0), 1, compositeTensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     PowerTensorComplex(const std::vector<PowerTensor>& pts_, xarray<real, 3>& ct_) : compositeTensor(ct_)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         uvector3 ext(1);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         tensors.resize(pts_.size());
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         for (int i = 0; i < pts_.size(); ++i) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             tensors[i]  = pts_[i].tensor;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             ext        += pts_[i].tensor.ext() - 1;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         assert(all(ext == compositeTensor.ext()));
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         compositePower(tensors, 0, uvector3(0), 1, compositeTensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     PowerTensorComplex(const std::vector<PowerTensorComplex>& ptcs_, xarray<real, 3>& ct_) : compositeTensor(ct_)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         std::vector<xarray<real, 3>> originCompositeTensors;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         uvector3                     ext(1);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         for (auto& ptc : ptcs_) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             for (auto& t : ptc.tensors) { tensors.emplace_back(t); }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             originCompositeTensors.push_back(ptc.compositeTensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             ext += ptc.compositeTensor.ext() - 1;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         compositePower(originCompositeTensors, 0, uvector3(0, 0, 0), 1, compositeTensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     real eval(const uvector3& p) override { return evalPower(compositeTensor, p); }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     bool isInside(const uvector3& p)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         for (auto& t : tensors) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             if (evalPower(t, p) >= 0) { return false; }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         return true;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// };
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// class BernsteinPrimitive : public Primitive
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// };
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// class BernsteinTensor : public BernsteinPrimitive
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// public:
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     xarray<real, 3> tensor;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     void print() override { std::cout << "Bernstein" << std::endl; }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     real eval(const uvector3& p) override { return evalBernstein(tensor, p); }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     BernsteinTensor(const PowerTensor& pt_)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         auto v0 = xarray2StdVector(pt_.tensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         tensor.ext_ = pt_.tensor.ext();
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         algoim_spark_alloc(real, tensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         auto v1 = xarray2StdVector(pt_.tensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         auto v2 = xarray2StdVector(tensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         detail::power2BernsteinTensor(pt_.tensor, tensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         uvector3 x(0.2, 0.5, 0.6);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         real     BernsteinValue = bernstein::evalBernsteinPoly(tensor, x);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         real     PowerValue     = evalPower(pt_.tensor, x);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         int      a              = 1;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     bool isInside(uvector3 p) { return eval(p) < 0; }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// };
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// class BernsteinTensorComplex : public BernsteinPrimitive
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// public:
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     bool                         fromPower;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     xarray<real, 3>              compositeTensor; // 复合后的张量
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     std::vector<xarray<real, 3>> tensors;         // 原始张量
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     void print() override { std::cout << "Bernstein Complex" << std::endl; }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     real eval(const uvector3& p) override { return evalBernstein(compositeTensor, p); }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     // BernsteinTensorComplex(const PowerTensorComplex& pc_) : fromPower(true), tensors(pc_.tensors)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     // {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     //     compositeTensor.ext_ = pc_.compositeTensor.ext();
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     //     algoim_spark_alloc(real, compositeTensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     //     detail::power2BernsteinTensor(pc_.compositeTensor, compositeTensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     // };
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     bool isInside(uvector3 p)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         if (fromPower) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             for (auto& t : tensors) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                 if (evalPower(t, p) >= 0) { return false; }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             return true;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         } else {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             for (auto& t : tensors) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//                 if (eval(p) >= 0) { return false; }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//             return true;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//         return true;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					//     };
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					// };
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					bool isInsidePowers(const std::vector<tensor3>& tensors, const uvector3& p) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					public: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    xarray<real, 3> tensor; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // SparkStack<real>* sparkStackPtr;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    void print() override { std::cout << "Power" << std::endl; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    real eval(uvector3 p) override { return evalPower(tensor, p); } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // PowerTensor() {}
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    PowerTensor(const xarray<real, 3>& t_) : tensor(t_) {} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // const xarray<real, 3>& getTensor() { return tensor; }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    ~PowerTensor() = default; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class PowerTensorComplex : public Primitive | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					public: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    xarray<real, 3>          compositeTensor; // 复合后的张量
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    SparkStack<real>*        sparkStackPtr; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // std::vector<xarray<real, 3>> tensors;         // 原始张量
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::vector<PowerTensor> tensors; // 原始张量
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    void print() override { std::cout << "PowerTensorComplex" << std::endl; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // PowerTensorComplex() {}
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // PowerTensorComplex(const std::vector<xarray<real, 3>>& ts_) : tensors(ts_)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    //     uvector3 ext(1, 1, 1);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    //     for (auto& t : ts_) { ext += t.ext() - 1; }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    //     compositeTensor.ext_ = ext;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    //     sparkStackPtr        = algoim_spark_alloc_heap(real, compositeTensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    //     // detail::compositePower(tensors, 0, uvector3(0, 0, 0), 1, compositeTensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    PowerTensorComplex(const std::vector<PowerTensor>& pts_, xarray<real, 3>& ptc_) : tensors(pts_), compositeTensor(ptc_) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        uvector3 ext(1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for (auto& pt : pts_) { ext += pt.tensor.ext() - 1; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        assert(all(ext == compositeTensor.ext())); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        detail::compositePower(tensors, 0, uvector3(0, 0, 0), 1, compositeTensor); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    PowerTensorComplex(const std::vector<PowerTensorComplex>& pcs_) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for (auto& pc : pcs_) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for (auto& t : pc.tensors) { tensors.push_back(t); } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        std::vector<xarray<real, 3>> originCompositeTensors; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        uvector3                     ext(1, 1, 1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for (auto& pc : pcs_) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            originCompositeTensors.push_back(pc.compositeTensor); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            ext += pc.compositeTensor.ext() - 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        compositeTensor.ext_ = ext; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        sparkStackPtr        = algoim_spark_alloc_heap(real, compositeTensor); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        detail::compositePower(originCompositeTensors, 0, uvector3(0, 0, 0), 1, compositeTensor); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    PowerTensorComplex add(const PowerTensorComplex& pc) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        std::vector<PowerTensorComplex> pcs; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        pcs.emplace_back(*this); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        pcs.emplace_back(pc); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return PowerTensorComplex(pcs); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    PowerTensorComplex add(const PowerTensor& pt) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        std::vector<PowerTensorComplex> pcs; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        pcs.emplace_back(*this); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        // pcs.emplace_back(PowerTensorComplex({pt.tensor}));
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return PowerTensorComplex(pcs); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    real eval(uvector3 p) override { return evalPower(compositeTensor, p); } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    bool isInside(uvector3 p) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for (auto& t : tensors) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            // if (evalPower(t, p) >= 0) { return false; }
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (auto& t : tensors) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (evalPower(t, p) >= 0) { return false; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					PowerTensorComplex makeMesh(const std::vector<uvector3>& vertices, const std::vector<uvector<int, 3>>& indices) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    uvector3                 ext(1 + indices.size()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // PowerTensorComplex pc(ext);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::vector<PowerTensor> pts; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (const auto& index : indices) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        // xarray<real, 3> tensor(nullptr, ); // 最高1次
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        // algoim_spark_alloc(real, tensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        PowerTensor pt(uvector3(2)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        uvector3 V01                    = vertices[index(1)] - vertices[index(0)]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        uvector3 V02                    = vertices[index(2)] - vertices[index(0)]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        uvector3 N                      = cross(V01, V02); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        N                              /= norm(N); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        real d                          = -dot(N, vertices[index(0)]); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        // 法线所指方向为>0区域
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        pt.tensor.m(uvector3(0, 0, 0))  = d; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        pt.tensor.m(uvector3(1, 0, 0))  = N(0); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        pt.tensor.m(uvector3(0, 1, 0))  = N(1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        pt.tensor.m(uvector3(0, 0, 1))  = N(2); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        pts.push_back(pt); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    PowerTensorComplex pc(pts); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    pc.compositeTensor.ext_ = ext; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    algoim_spark_alloc(real, pc.compositeTensor); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // detail::compositePower(pc.tensors, 0, 0, 1, pc.compositeTensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return pc; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					bool isInsideBernstein(const tensor3& t, const uvector3& p) { return evalBernstein(t, p) < 0; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					PowerTensor makeSphere(const real r, const uvector3& c = 0, const uvector3& a = 1) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    uvector<int, 3> ext = 3; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    PowerTensor     pt(ext); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (int dim = 0; dim < 3; ++dim) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        uvector<int, 3> idx  = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        pt.tensor.m(idx)    += c(dim) * c(dim); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        idx(dim)             = 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        pt.tensor.m(idx)     = 2 * a(dim) * (-c(dim)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        idx(dim)             = 2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        pt.tensor.m(idx)     = a(dim) * a(dim); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    pt.tensor.m(0) -= r * r; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return pt; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					bool isInsidePower(const tensor3& t, const uvector3& p) { return evalPower(t, p) < 0; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					PowerTensor makeCylinder(uvector3 startPt, uvector3 endPt, real r) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // PowerTensor pt;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // TODO:
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    return PowerTensor({}); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class BernsteinPrimitive : public Primitive | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class FRep : public Primitive | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					private: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::function<real(uvector3)> f; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class BernsteinTensor : public BernsteinPrimitive | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					public: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    xarray<real, 3> tensor; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    void print() override { std::cout << "Bernstein" << std::endl; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    real eval(uvector3 p) override { return evalBernstein(tensor, p); } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    void print() override { std::cout << "FRep" << std::endl; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    BernsteinTensor(const PowerTensor& pt_) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto v0 = xarray2StdVector(pt_.tensor); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        tensor.ext_ = pt_.tensor.ext(); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        algoim_spark_alloc(real, tensor); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto v1 = xarray2StdVector(pt_.tensor); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto v2 = xarray2StdVector(tensor); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        detail::power2BernsteinTensor(pt_.tensor, tensor); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        uvector3 x(0.2, 0.5, 0.6); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        real     BernsteinValue = bernstein::evalBernsteinPoly(tensor, x); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        real     PowerValue     = evalPower(pt_.tensor, x); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        int      a              = 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    real eval(const uvector3& p) override { return f(p); } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    bool isInside(uvector3 p) { return eval(p) < 0; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    FRep(std::function<real(uvector3)> f_) : f(f_) {} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class BernsteinTensorComplex : public BernsteinPrimitive | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					enum PrimitiveType { Sphere, Cylinder, Cone, Mesh, BRep }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class PrimitiveDesc | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					public: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    bool                         fromPower; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    xarray<real, 3>              compositeTensor; // 复合后的张量
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::vector<xarray<real, 3>> tensors;         // 原始张量
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    void print() override { std::cout << "Bernstein Complex" << std::endl; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    real eval(uvector3 p) override { return evalBernstein(compositeTensor, p); } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // const static PrimitiveType type;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    PrimitiveDesc() = default; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // BernsteinTensorComplex(const PowerTensorComplex& pc_) : fromPower(true), tensors(pc_.tensors)
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    //     compositeTensor.ext_ = pc_.compositeTensor.ext();
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    //     algoim_spark_alloc(real, compositeTensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    //     detail::power2BernsteinTensor(pc_.compositeTensor, compositeTensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // };
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    bool isInside(uvector3 p) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        if (fromPower) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for (auto& t : tensors) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (evalPower(t, p) >= 0) { return false; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            return true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } else { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            for (auto& t : tensors) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					                if (eval(p) >= 0) { return false; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            return true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return true; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    }; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    virtual void print() {} // 空定义也可以,但是一定要有定义
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class ParametricSurface | 
				
			
			
		
	
	
		
			
				
					| 
						
							
								
							
						
						
							
								
							
						
						
					 | 
				
				 | 
				
					@ -388,27 +386,30 @@ private: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    int                   degree; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class BRep : public Primitive | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class BRepDesc : virtual public PrimitiveDesc | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const static PrimitiveType     type = BRep; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::vector<uvector3>          vertices; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::vector<ParametricCurve>   curves; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::vector<ParametricSurface> surfaces; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					public: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    void print() override { std::cout << "FRep" << std::endl; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    void print() override { std::cout << "BRep Description" << std::endl; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    real eval(uvector3 p) override | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    real eval(const uvector3& p) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        // DOTO: the implicit conversion of Parametric BRep
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        return 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    BRep(const std::vector<uvector3>& vs_, const std::vector<ParametricCurve>& cs_, const std::vector<ParametricSurface>& ss_) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    BRepDesc(const std::vector<uvector3>&          vs_, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             const std::vector<ParametricCurve>&   cs_, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             const std::vector<ParametricSurface>& ss_) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        : vertices(vs_), curves(cs_), surfaces(ss_) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    BRep(const BRep& brep) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    BRepDesc(const BRepDesc& brep) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        vertices = brep.vertices; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        curves   = brep.curves; | 
				
			
			
		
	
	
		
			
				
					| 
						
						
						
							
								
							
						
					 | 
				
				 | 
				
					@ -416,16 +417,116 @@ public: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class FRep : public Primitive | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class SphereDesc : virtual public PrimitiveDesc | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					private: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::function<real(uvector3)> f; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					public: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const static PrimitiveType type = Sphere; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    real                       radius; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    uvector3                   center; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    uvector3                   amplitude; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    SphereDesc(real r_, const uvector3& c_, const uvector3& a_) : PrimitiveDesc(), radius(r_), center(c_), amplitude(a_) {} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    void print() override { std::cout << "Sphere Description" << std::endl; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class CylinderDesc : virtual public PrimitiveDesc | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const static PrimitiveType type = Cylinder; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    uvector3                   node1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    uvector3                   node2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    real                       radius; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    CylinderDesc(const uvector3& n1_, const uvector3& n2_, real r_) : PrimitiveDesc(), node1(n1_), node2(n2_), radius(r_) {} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    void print() override { std::cout << "Cylinder Description" << std::endl; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class ConeDesc : virtual public PrimitiveDesc | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const static PrimitiveType type = Cone; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    uvector3                   node1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    uvector3                   node2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    real                       radius; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    ConeDesc(const uvector3& n1_, const uvector3& n2_, real r_) : PrimitiveDesc(), node1(n1_), node2(n2_), radius(r_) {} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    void print() override { std::cout << "Cone Description" << std::endl; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					class MeshDesc : virtual public PrimitiveDesc | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					public: | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    void print() override { std::cout << "FRep" << std::endl; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    const static PrimitiveType type = Mesh; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::vector<uvector3>      vertices; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::vector<int>           indices; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    std::vector<int>           indexInclusiveScan; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    MeshDesc(const std::vector<uvector3>& vertices_, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             const std::vector<int>&      indices_, | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					             const std::vector<int>&      indexInclusiveScan_) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        : PrimitiveDesc(), vertices(vertices_), indices(indices_), indexInclusiveScan(indexInclusiveScan_) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    real eval(uvector3 p) override { return f(p); } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    void print() override { std::cout << "Mesh Description" << std::endl; } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    FRep(std::function<real(uvector3)> f_) : f(f_) {} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void makeMesh(const MeshDesc& mesh, xarray<real, 3>& tensor, std::vector<xarray<real, 3>>& planeTensors) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    uvector3 ext(1 + mesh.indexInclusiveScan.size()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    assert(all(ext == tensor.ext())); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    assert(planeTensors.size() == mesh.indexInclusiveScan.size()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // for (const auto& index : indices) {
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (int i = 0; i < mesh.indexInclusiveScan.size(); ++i) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const int indexBeg  = i == 0 ? 0 : mesh.indexInclusiveScan[i - 1]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        const int indexSize = mesh.indexInclusiveScan[i] - indexBeg; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        assert(indexSize >= 3); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto& planeTensor = planeTensors[i]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        xarrayInit(planeTensor); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto&    vertices                 = mesh.vertices; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        auto&    indices                  = mesh.indices; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        uvector3 V01                      = vertices[indices[indexBeg + 1]] - mesh.vertices[indices[indexBeg]]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        uvector3 V02                      = vertices[indices[indexBeg + 2]] - mesh.vertices[indices[indexBeg]]; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        uvector3 N                        = cross(V01, V02); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        N                                /= norm(N); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        real d                            = -dot(N, vertices[indices[indexBeg]]); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        // 法线所指方向为>0区域
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        planeTensor.m(uvector3(0, 0, 0))  = d; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        planeTensor.m(uvector3(1, 0, 0))  = N(0); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        planeTensor.m(uvector3(0, 1, 0))  = N(1); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        planeTensor.m(uvector3(0, 0, 1))  = N(2); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        // test other vertices
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        for (int j = indexBeg + 3; j < mesh.indexInclusiveScan[i]; ++j) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					            assert(dot(N, vertices[indices[j]]) + d < std::numeric_limits<real>::epsilon()); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // compositePower(planeTensors, 0, 0, 1, tensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // return PowerTensorComplex(planeTensors, tensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void makeSphere(const SphereDesc& sphereDesc, xarray<real, 3>& tensor) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    uvector<int, 3> ext = 3; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    assert(all(ext == tensor.ext())); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    for (int dim = 0; dim < 3; ++dim) { | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        uvector<int, 3> idx  = 0; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        tensor.m(idx)       += sphereDesc.center(dim) * sphereDesc.center(dim); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        idx(dim)             = 1; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        tensor.m(idx)        = 2 * sphereDesc.amplitude(dim) * (-sphereDesc.center(dim)); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        idx(dim)             = 2; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					        tensor.m(idx)        = sphereDesc.amplitude(dim) * sphereDesc.amplitude(dim); | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    } | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    tensor.m(0) -= sphereDesc.radius * sphereDesc.radius; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // return PowerTensor(tensor);
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					}; | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					void makeCylinder(xarray<real, 3>& tensor, uvector3 startPt, uvector3 endPt, real r) | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					{ | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // PowerTensor pt;
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					    // TODO:
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					
 | 
				
			
			
		
	
		
			
				
					 | 
					 | 
				
				 | 
				
					} // namespace algoim::Organizer
 |