|
|
@ -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
|