|
|
@ -8,6 +8,7 @@ class Vector3D |
|
|
|
{ |
|
|
|
public: |
|
|
|
Vector3D() = default; |
|
|
|
|
|
|
|
Vector3D(const double x, const double y, const double z) |
|
|
|
{ |
|
|
|
this->m_x = x; |
|
|
@ -15,17 +16,11 @@ public: |
|
|
|
this->m_z = z; |
|
|
|
} |
|
|
|
|
|
|
|
double length() const |
|
|
|
{ |
|
|
|
return std::sqrt(this->m_x * this->m_x + this->m_y * this->m_y + this->m_z * this->m_z); |
|
|
|
} |
|
|
|
double length() const { return std::sqrt(this->m_x * this->m_x + this->m_y * this->m_y + this->m_z * this->m_z); } |
|
|
|
|
|
|
|
Vector3D operator/(const double scalar) const |
|
|
|
{ |
|
|
|
if (scalar == 0) |
|
|
|
{ |
|
|
|
throw std::runtime_error("Division by zero error."); |
|
|
|
} |
|
|
|
if (scalar == 0) { throw std::runtime_error("Division by zero error."); } |
|
|
|
|
|
|
|
return Vector3D(this->m_x / scalar, this->m_y / scalar, this->m_z / scalar); |
|
|
|
} |
|
|
@ -37,15 +32,11 @@ public: |
|
|
|
|
|
|
|
Vector3D cross(const Vector3D& other) const |
|
|
|
{ |
|
|
|
return Vector3D(this->m_y * other.m_z - this->m_z * other.m_y, |
|
|
|
this->m_z * other.m_x - this->m_x * other.m_z, |
|
|
|
return Vector3D(this->m_y * other.m_z - this->m_z * other.m_y, this->m_z * other.m_x - this->m_x * other.m_z, |
|
|
|
this->m_x * other.m_y - this->m_y * other.m_x); |
|
|
|
} |
|
|
|
|
|
|
|
double dot(const Vector3D& other) const |
|
|
|
{ |
|
|
|
return this->m_x * other.m_x + this->m_y * other.m_y + this->m_z * other.m_z; |
|
|
|
} |
|
|
|
double dot(const Vector3D& other) const { return this->m_x * other.m_x + this->m_y * other.m_y + this->m_z * other.m_z; } |
|
|
|
|
|
|
|
algoim::uvector3 getUVector3Data() const |
|
|
|
{ |
|
|
@ -63,6 +54,7 @@ class Direction3D : public Vector3D |
|
|
|
{ |
|
|
|
public: |
|
|
|
Direction3D() = default; |
|
|
|
|
|
|
|
Direction3D(const double x, const double y, const double z) |
|
|
|
{ |
|
|
|
this->m_x = x; |
|
|
@ -83,23 +75,16 @@ public: |
|
|
|
|
|
|
|
Vector3D cross(const Direction3D& other) const |
|
|
|
{ |
|
|
|
return Vector3D(this->m_y * other.m_z - this->m_z * other.m_y, |
|
|
|
this->m_z * other.m_x - this->m_x * other.m_z, |
|
|
|
return Vector3D(this->m_y * other.m_z - this->m_z * other.m_y, this->m_z * other.m_x - this->m_x * other.m_z, |
|
|
|
this->m_x * other.m_y - this->m_y * other.m_x); |
|
|
|
} |
|
|
|
|
|
|
|
double dot(const Direction3D& other) const |
|
|
|
{ |
|
|
|
return this->m_x * other.m_x + this->m_y * other.m_y + this->m_z * other.m_z; |
|
|
|
} |
|
|
|
double dot(const Direction3D& other) const { return this->m_x * other.m_x + this->m_y * other.m_y + this->m_z * other.m_z; } |
|
|
|
|
|
|
|
void normalized() |
|
|
|
{ |
|
|
|
double length = this->length(); |
|
|
|
if (std::abs(length) < 1e-8) |
|
|
|
{ |
|
|
|
throw std::runtime_error("Cannot normalize a zero-length vector."); |
|
|
|
} |
|
|
|
if (std::abs(length) < 1e-8) { throw std::runtime_error("Cannot normalize a zero-length vector."); } |
|
|
|
|
|
|
|
this->m_x /= length; |
|
|
|
this->m_y /= length, this->m_z /= length; |
|
|
@ -111,16 +96,14 @@ public: |
|
|
|
return std::abs(cross.length()) < 1e-8; |
|
|
|
} |
|
|
|
|
|
|
|
Direction3D operator-() const |
|
|
|
{ |
|
|
|
return Direction3D(-this->m_x, -this->m_y, -this->m_z); |
|
|
|
} |
|
|
|
Direction3D operator-() const { return Direction3D(-this->m_x, -this->m_y, -this->m_z); } |
|
|
|
}; |
|
|
|
|
|
|
|
class Point3D : public Vector3D |
|
|
|
{ |
|
|
|
public: |
|
|
|
Point3D() = default; |
|
|
|
|
|
|
|
Point3D(const double x, const double y, const double z) |
|
|
|
{ |
|
|
|
this->m_x = x; |
|
|
@ -155,9 +138,8 @@ public: |
|
|
|
|
|
|
|
double getDistance(const Point3D& other) const |
|
|
|
{ |
|
|
|
return std::sqrt((other.m_x - this->m_x) * (other.m_x - this->m_x) + |
|
|
|
(other.m_y - this->m_y) * (other.m_y - this->m_y) + |
|
|
|
(other.m_z - this->m_z) * (other.m_z - this->m_z)); |
|
|
|
return std::sqrt((other.m_x - this->m_x) * (other.m_x - this->m_x) + (other.m_y - this->m_y) * (other.m_y - this->m_y) |
|
|
|
+ (other.m_z - this->m_z) * (other.m_z - this->m_z)); |
|
|
|
} |
|
|
|
|
|
|
|
Point3D getMiddlePoint(const Point3D& other) const |
|
|
@ -179,8 +161,7 @@ public: |
|
|
|
Point3D computePolygonCentroid(const std::vector<Point3D>& points) const |
|
|
|
{ |
|
|
|
double centroidX = 0, centroidY = 0, centroidZ = 0; |
|
|
|
for (const auto& point : points) |
|
|
|
{ |
|
|
|
for (const auto& point : points) { |
|
|
|
centroidX += point.m_x; |
|
|
|
centroidY += point.m_y; |
|
|
|
centroidZ += point.m_z; |
|
|
@ -198,30 +179,30 @@ public: |
|
|
|
algoim::organizer::BlobTree tree; |
|
|
|
|
|
|
|
algoim::organizer::Blob blob0; |
|
|
|
blob0.isPrimitive = 1; |
|
|
|
blob0.nodeOp = 0; |
|
|
|
blob0.inOut = 0; |
|
|
|
blob0.isPrimitive = 1; |
|
|
|
blob0.nodeOp = 0; |
|
|
|
blob0.inOut = 0; |
|
|
|
blob0.oneChildInOut = 0; |
|
|
|
blob0.isLeft = 1; |
|
|
|
blob0.ancestor = 2; |
|
|
|
blob0.isLeft = 1; |
|
|
|
blob0.ancestor = 2; |
|
|
|
tree.structure.push_back(blob0); |
|
|
|
|
|
|
|
algoim::organizer::Blob blob1; |
|
|
|
blob1.isPrimitive = 1; |
|
|
|
blob1.nodeOp = 0; |
|
|
|
blob1.inOut = 0; |
|
|
|
blob1.isPrimitive = 1; |
|
|
|
blob1.nodeOp = 0; |
|
|
|
blob1.inOut = 0; |
|
|
|
blob1.oneChildInOut = 0; |
|
|
|
blob1.isLeft = 0; |
|
|
|
blob1.ancestor = 0; |
|
|
|
blob1.isLeft = 0; |
|
|
|
blob1.ancestor = 0; |
|
|
|
tree.structure.push_back(blob1); |
|
|
|
|
|
|
|
algoim::organizer::Blob blob2; |
|
|
|
blob2.isPrimitive = 0; |
|
|
|
blob2.nodeOp = 3; // no set
|
|
|
|
blob2.inOut = 0; |
|
|
|
blob2.isPrimitive = 0; |
|
|
|
blob2.nodeOp = 3; // no set
|
|
|
|
blob2.inOut = 0; |
|
|
|
blob2.oneChildInOut = 0; |
|
|
|
blob2.isLeft = 0; |
|
|
|
blob2.ancestor = 0; |
|
|
|
blob2.isLeft = 0; |
|
|
|
blob2.ancestor = 0; |
|
|
|
tree.structure.push_back(blob2); |
|
|
|
|
|
|
|
tree.primitiveNodeIdx.push_back(0); |
|
|
@ -239,38 +220,28 @@ public: |
|
|
|
*/ |
|
|
|
algoim::organizer::VisiblePrimitiveRep unionNode(const algoim::organizer::VisiblePrimitiveRep& rep1, |
|
|
|
const algoim::organizer::VisiblePrimitiveRep& rep2, |
|
|
|
const bool modify = true) |
|
|
|
const bool modify = true) |
|
|
|
{ |
|
|
|
auto tree = createEmptyBlobTree(); |
|
|
|
auto tree = createEmptyBlobTree(); |
|
|
|
tree.structure[2].nodeOp = 0; |
|
|
|
|
|
|
|
const std::vector<algoim::organizer::VisiblePrimitiveRep> reps = {rep1, rep2}; |
|
|
|
std::vector<algoim::organizer::MinimalPrimitiveRep> minimalReps; |
|
|
|
std::vector<algoim::organizer::MinimalPrimitiveRep> minimalReps; |
|
|
|
algoim::organizer::mergeSubtree2Leaf(tree, minimalReps, reps); |
|
|
|
|
|
|
|
algoim::organizer::VisiblePrimitiveRep result; |
|
|
|
result.subBlobTree = tree; |
|
|
|
result.aabb = rep1.aabb; |
|
|
|
result.aabb = rep1.aabb; |
|
|
|
result.aabb.extend(rep2.aabb); |
|
|
|
|
|
|
|
if (modify) |
|
|
|
{ |
|
|
|
for (auto& iter : minimalReps) |
|
|
|
{ |
|
|
|
if (modify) { |
|
|
|
for (auto& iter : minimalReps) { |
|
|
|
result.tensors.push_back(iter.tensor); |
|
|
|
result.aabbs.push_back(iter.aabb); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
for (auto& iter : rep1.tensors) |
|
|
|
{ |
|
|
|
result.tensors.push_back(iter); |
|
|
|
} |
|
|
|
for (auto& iter : rep2.tensors) |
|
|
|
{ |
|
|
|
result.tensors.push_back(iter); |
|
|
|
} |
|
|
|
} else { |
|
|
|
for (auto& iter : rep1.tensors) { result.tensors.push_back(iter); } |
|
|
|
for (auto& iter : rep2.tensors) { result.tensors.push_back(iter); } |
|
|
|
result.aabbs = rep1.aabbs; |
|
|
|
result.aabbs.insert(result.aabbs.end(), rep2.aabbs.begin(), rep2.aabbs.end()); |
|
|
|
} |
|
|
@ -287,38 +258,28 @@ public: |
|
|
|
*/ |
|
|
|
algoim::organizer::VisiblePrimitiveRep intersectNode(const algoim::organizer::VisiblePrimitiveRep& rep1, |
|
|
|
const algoim::organizer::VisiblePrimitiveRep& rep2, |
|
|
|
const bool modify = true) |
|
|
|
const bool modify = true) |
|
|
|
{ |
|
|
|
auto tree = createEmptyBlobTree(); |
|
|
|
auto tree = createEmptyBlobTree(); |
|
|
|
tree.structure[2].nodeOp = 1; |
|
|
|
|
|
|
|
const std::vector<algoim::organizer::VisiblePrimitiveRep> reps = {rep1, rep2}; |
|
|
|
std::vector<algoim::organizer::MinimalPrimitiveRep> minimalReps; |
|
|
|
std::vector<algoim::organizer::MinimalPrimitiveRep> minimalReps; |
|
|
|
algoim::organizer::mergeSubtree2Leaf(tree, minimalReps, reps); |
|
|
|
|
|
|
|
algoim::organizer::VisiblePrimitiveRep result; |
|
|
|
result.subBlobTree = tree; |
|
|
|
result.aabb = rep1.aabb; |
|
|
|
result.aabb = rep1.aabb; |
|
|
|
result.aabb.intersect(rep2.aabb); |
|
|
|
|
|
|
|
if (modify) |
|
|
|
{ |
|
|
|
for (auto& iter : minimalReps) |
|
|
|
{ |
|
|
|
if (modify) { |
|
|
|
for (auto& iter : minimalReps) { |
|
|
|
result.tensors.push_back(iter.tensor); |
|
|
|
result.aabbs.push_back(iter.aabb); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
for (auto& iter : rep1.tensors) |
|
|
|
{ |
|
|
|
result.tensors.push_back(iter); |
|
|
|
} |
|
|
|
for (auto& iter : rep2.tensors) |
|
|
|
{ |
|
|
|
result.tensors.push_back(iter); |
|
|
|
} |
|
|
|
} else { |
|
|
|
for (auto& iter : rep1.tensors) { result.tensors.push_back(iter); } |
|
|
|
for (auto& iter : rep2.tensors) { result.tensors.push_back(iter); } |
|
|
|
result.aabbs = rep1.aabbs; |
|
|
|
result.aabbs.insert(result.aabbs.end(), rep2.aabbs.begin(), rep2.aabbs.end()); |
|
|
|
} |
|
|
@ -335,37 +296,27 @@ public: |
|
|
|
*/ |
|
|
|
algoim::organizer::VisiblePrimitiveRep differentNode(const algoim::organizer::VisiblePrimitiveRep& rep1, |
|
|
|
const algoim::organizer::VisiblePrimitiveRep& rep2, |
|
|
|
const bool modify = true) |
|
|
|
const bool modify = true) |
|
|
|
{ |
|
|
|
auto tree = createEmptyBlobTree(); |
|
|
|
auto tree = createEmptyBlobTree(); |
|
|
|
tree.structure[2].nodeOp = 2; |
|
|
|
|
|
|
|
const std::vector<algoim::organizer::VisiblePrimitiveRep> reps = {rep1, rep2}; |
|
|
|
std::vector<algoim::organizer::MinimalPrimitiveRep> minimalReps; |
|
|
|
std::vector<algoim::organizer::MinimalPrimitiveRep> minimalReps; |
|
|
|
algoim::organizer::mergeSubtree2Leaf(tree, minimalReps, reps); |
|
|
|
|
|
|
|
algoim::organizer::VisiblePrimitiveRep result; |
|
|
|
result.subBlobTree = tree; |
|
|
|
result.aabb = rep1.aabb; |
|
|
|
result.aabb = rep1.aabb; |
|
|
|
|
|
|
|
if (modify) |
|
|
|
{ |
|
|
|
for (auto& iter : minimalReps) |
|
|
|
{ |
|
|
|
if (modify) { |
|
|
|
for (auto& iter : minimalReps) { |
|
|
|
result.tensors.push_back(iter.tensor); |
|
|
|
result.aabbs.push_back(iter.aabb); |
|
|
|
} |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
for (auto& iter : rep1.tensors) |
|
|
|
{ |
|
|
|
result.tensors.push_back(iter); |
|
|
|
} |
|
|
|
for (auto& iter : rep2.tensors) |
|
|
|
{ |
|
|
|
result.tensors.push_back(iter); |
|
|
|
} |
|
|
|
} else { |
|
|
|
for (auto& iter : rep1.tensors) { result.tensors.push_back(iter); } |
|
|
|
for (auto& iter : rep2.tensors) { result.tensors.push_back(iter); } |
|
|
|
result.aabbs = rep1.aabbs; |
|
|
|
result.aabbs.insert(result.aabbs.end(), rep2.aabbs.begin(), rep2.aabbs.end()); |
|
|
|
} |
|
|
@ -375,21 +326,16 @@ public: |
|
|
|
|
|
|
|
void unionNode(const BodyTag body1, const BodyTag body2) |
|
|
|
{ |
|
|
|
auto& rep1 = this->m_allVisible[body1]; |
|
|
|
auto& rep2 = this->m_allVisible[body2]; |
|
|
|
auto& rep1 = this->m_allVisible[body1]; |
|
|
|
auto& rep2 = this->m_allVisible[body2]; |
|
|
|
algoim::organizer::VisiblePrimitiveRep result; |
|
|
|
|
|
|
|
if (rep1.isEmpty()) |
|
|
|
{ |
|
|
|
if (rep1.isEmpty()) { |
|
|
|
result = rep2; |
|
|
|
} |
|
|
|
else if (rep2.isEmpty()) |
|
|
|
{ |
|
|
|
} else if (rep2.isEmpty()) { |
|
|
|
result = rep1; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
result = this->differentNode(rep1, rep2, false); |
|
|
|
} else { |
|
|
|
result = this->unionNode(rep1, rep2, false); |
|
|
|
} |
|
|
|
|
|
|
|
this->m_allVisible[body1] = result; |
|
|
@ -397,17 +343,14 @@ public: |
|
|
|
|
|
|
|
void intersectNode(const BodyTag body1, const BodyTag body2) |
|
|
|
{ |
|
|
|
auto& rep1 = this->m_allVisible[body1]; |
|
|
|
auto& rep2 = this->m_allVisible[body2]; |
|
|
|
auto& rep1 = this->m_allVisible[body1]; |
|
|
|
auto& rep2 = this->m_allVisible[body2]; |
|
|
|
algoim::organizer::VisiblePrimitiveRep result; |
|
|
|
|
|
|
|
if (rep1.isEmpty() || rep2.isEmpty()) |
|
|
|
{ |
|
|
|
if (rep1.isEmpty() || rep2.isEmpty()) { |
|
|
|
result = algoim::organizer::VisiblePrimitiveRep{}; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
result = this->differentNode(rep1, rep2, false); |
|
|
|
} else { |
|
|
|
result = this->intersectNode(rep1, rep2, false); |
|
|
|
} |
|
|
|
|
|
|
|
this->m_allVisible[body1] = result; |
|
|
@ -415,16 +358,13 @@ public: |
|
|
|
|
|
|
|
void differentNode(const BodyTag body1, const BodyTag body2) |
|
|
|
{ |
|
|
|
auto& rep1 = this->m_allVisible[body1]; |
|
|
|
auto& rep2 = this->m_allVisible[body2]; |
|
|
|
auto& rep1 = this->m_allVisible[body1]; |
|
|
|
auto& rep2 = this->m_allVisible[body2]; |
|
|
|
algoim::organizer::VisiblePrimitiveRep result; |
|
|
|
|
|
|
|
if (rep1.isEmpty() || rep2.isEmpty()) |
|
|
|
{ |
|
|
|
if (rep1.isEmpty() || rep2.isEmpty()) { |
|
|
|
result = rep1; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
} else { |
|
|
|
result = this->differentNode(rep1, rep2, false); |
|
|
|
} |
|
|
|
|
|
|
@ -434,23 +374,21 @@ public: |
|
|
|
void offset(const BodyTag body, const Direction3D& directrion, const double length) |
|
|
|
{ |
|
|
|
algoim::uvector<algoim::real, 3> scale = 1; |
|
|
|
algoim::uvector<algoim::real, 3> bias = -directrion.getUVector3Data(); |
|
|
|
algoim::uvector<algoim::real, 3> bias = -directrion.getUVector3Data(); |
|
|
|
|
|
|
|
auto& rep = this->m_allVisible[body]; |
|
|
|
|
|
|
|
for (auto& iter : rep.tensors) |
|
|
|
{ |
|
|
|
algoim::organizer::detail::powerTransformation(scale, bias, iter); |
|
|
|
} |
|
|
|
for (auto& iter : rep.tensors) { algoim::organizer::detail::powerTransformation(scale, bias, iter); } |
|
|
|
|
|
|
|
rep.aabb += directrion.getUVector3Data(); |
|
|
|
for (auto& aabb : rep.aabbs) { aabb += directrion.getUVector3Data(); } |
|
|
|
} |
|
|
|
|
|
|
|
void split(const BodyTag body, const Point3D& basePoint, const Direction3D& normal) |
|
|
|
{ |
|
|
|
auto& rep = this->m_allVisible[body]; |
|
|
|
auto halfPlane = this->createHalfPlane(basePoint, -normal); |
|
|
|
auto result = this->intersectNode(rep, halfPlane, false); |
|
|
|
auto& rep = this->m_allVisible[body]; |
|
|
|
auto halfPlane = this->createHalfPlane(basePoint, -normal); |
|
|
|
auto result = this->intersectNode(rep, halfPlane, false); |
|
|
|
this->m_allVisible[body] = result; |
|
|
|
} |
|
|
|
|
|
|
@ -461,29 +399,22 @@ public: |
|
|
|
* @return The polygonal column |
|
|
|
*/ |
|
|
|
algoim::organizer::VisiblePrimitiveRep createPolygonalColumnWithoutTopBottom(const std::vector<Point3D>& points, |
|
|
|
const Vector3D& extusion) |
|
|
|
const Vector3D& extusion) |
|
|
|
{ |
|
|
|
int pointNumber = points.size(); |
|
|
|
|
|
|
|
std::vector<algoim::uvector3> vertices; |
|
|
|
std::vector<int> indices; |
|
|
|
std::vector<int> indexInclusiveScan; |
|
|
|
std::vector<int> indices; |
|
|
|
std::vector<int> indexInclusiveScan; |
|
|
|
|
|
|
|
/* All bottom point */ |
|
|
|
for (int i = 0; i < pointNumber; i++) |
|
|
|
{ |
|
|
|
vertices.push_back(points[i].getUVector3Data()); |
|
|
|
} |
|
|
|
for (int i = 0; i < pointNumber; i++) { vertices.push_back(points[i].getUVector3Data()); } |
|
|
|
/* All top point */ |
|
|
|
for (int i = 0; i < pointNumber; i++) |
|
|
|
{ |
|
|
|
vertices.push_back((points[i] + extusion).getUVector3Data()); |
|
|
|
} |
|
|
|
for (int i = 0; i < pointNumber; i++) { vertices.push_back((points[i] + extusion).getUVector3Data()); } |
|
|
|
|
|
|
|
/* Side face */ |
|
|
|
int index = 0; |
|
|
|
for (int i = 0; i < pointNumber; i++) |
|
|
|
{ |
|
|
|
for (int i = 0; i < pointNumber; i++) { |
|
|
|
indices.push_back(i); |
|
|
|
indices.push_back((i + 1) % pointNumber); |
|
|
|
indices.push_back((i + 1) % pointNumber + pointNumber); |
|
|
@ -493,17 +424,14 @@ public: |
|
|
|
indexInclusiveScan.push_back(index); |
|
|
|
} |
|
|
|
|
|
|
|
algoim::organizer::MeshDesc polygonalColumn(vertices, indices, indexInclusiveScan); |
|
|
|
algoim::organizer::MeshDesc polygonalColumn(vertices, indices, indexInclusiveScan); |
|
|
|
algoim::organizer::VisiblePrimitiveRep result; |
|
|
|
result.tensors.resize(pointNumber, algoim::tensor3(nullptr, 3)); |
|
|
|
std::vector<algoim::SparkStack<algoim::real>*> temp; |
|
|
|
algoim::algoimSparkAllocHeapVector(temp, result.tensors); |
|
|
|
algoim::organizer::makeMesh(polygonalColumn, result); |
|
|
|
|
|
|
|
for (auto& pointer : temp) |
|
|
|
{ |
|
|
|
this->m_allPointer.push_back(pointer); |
|
|
|
} |
|
|
|
for (auto& pointer : temp) { this->m_allPointer.push_back(pointer); } |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
@ -517,12 +445,12 @@ public: |
|
|
|
* @return The cylinder column |
|
|
|
*/ |
|
|
|
algoim::organizer::VisiblePrimitiveRep createCylinderWithoutTopBottom(const Point3D& origion, |
|
|
|
const double radius, |
|
|
|
const double length, |
|
|
|
const int alignAxis) |
|
|
|
const double radius, |
|
|
|
const double length, |
|
|
|
const int alignAxis) |
|
|
|
{ |
|
|
|
algoim::uvector3 ext = 3; |
|
|
|
ext(alignAxis) = 1; |
|
|
|
ext(alignAxis) = 1; |
|
|
|
|
|
|
|
algoim::organizer::VisiblePrimitiveRep result; |
|
|
|
result.tensors.resize(1, algoim::tensor3(nullptr, ext)); |
|
|
@ -530,7 +458,7 @@ public: |
|
|
|
algoim::algoimSparkAllocHeapVector(resultTemp, result.tensors); |
|
|
|
this->m_allPointer.push_back(resultTemp[0]); |
|
|
|
|
|
|
|
algoim::organizer::CylinderDesc cylinderDesc(origion.getUVector3Data(), radius, length, alignAxis); |
|
|
|
algoim::organizer::CylinderDesc cylinderDesc(origion.getUVector3Data(), radius, length, alignAxis); |
|
|
|
algoim::organizer::VisiblePrimitiveRep cylinder; |
|
|
|
cylinder.tensors.resize(3, algoim::tensor3(nullptr, 3)); |
|
|
|
cylinder.tensors[0].ext_ = ext; |
|
|
@ -538,7 +466,7 @@ public: |
|
|
|
algoim::organizer::makeCylinder(cylinderDesc, cylinder); |
|
|
|
|
|
|
|
result.tensors[0] = cylinder.tensors[0]; |
|
|
|
result.aabb = cylinder.aabb; |
|
|
|
result.aabb = cylinder.aabb; |
|
|
|
result.subBlobTree.primitiveNodeIdx.push_back(0); |
|
|
|
result.subBlobTree.structure.push_back(algoim::organizer::Blob{1, 0, 0, 0, 0, 0}); |
|
|
|
|
|
|
@ -571,102 +499,92 @@ public: |
|
|
|
* @param[in] extusion The Stretch direction and length |
|
|
|
*/ |
|
|
|
BodyTag addExtrudeWithTwoPoint(const std::vector<Point3D>& points, |
|
|
|
const std::vector<double>& bulges, |
|
|
|
const Vector3D& extusion) |
|
|
|
const std::vector<double>& bulges, |
|
|
|
const Vector3D& extusion) |
|
|
|
{ |
|
|
|
auto normal = Direction3D(extusion); |
|
|
|
auto normal = Direction3D(extusion); |
|
|
|
auto& point1 = points[0]; |
|
|
|
auto& point2 = points[1]; |
|
|
|
auto bulge1 = bulges[0]; |
|
|
|
auto bulge2 = bulges[1]; |
|
|
|
auto bulge1 = bulges[0]; |
|
|
|
auto bulge2 = bulges[1]; |
|
|
|
|
|
|
|
algoim::organizer::VisiblePrimitiveRep rep1, rep2, result; |
|
|
|
|
|
|
|
auto halfDistance = point1.getDistance(point2) / 2.0; |
|
|
|
auto middlePoint = point1.getMiddlePoint(point2); |
|
|
|
auto middlePoint = point1.getMiddlePoint(point2); |
|
|
|
|
|
|
|
auto middleToOrigion1 = normal.cross(Direction3D(point2 - point1)); |
|
|
|
auto middleToOrigion2 = normal.cross(Direction3D(point1 - point2)); |
|
|
|
|
|
|
|
/* Determine which axis is aligned */ |
|
|
|
int alignAxis; |
|
|
|
if (normal.isParallel(Direction3D(1, 0, 0))) |
|
|
|
{ |
|
|
|
if (normal.isParallel(Direction3D(1, 0, 0))) { |
|
|
|
alignAxis = 0; |
|
|
|
} |
|
|
|
else if (normal.isParallel(Direction3D(0, 1, 0))) |
|
|
|
{ |
|
|
|
} else if (normal.isParallel(Direction3D(0, 1, 0))) { |
|
|
|
alignAxis = 1; |
|
|
|
} |
|
|
|
else if (normal.isParallel(Direction3D(0, 0, 1))) |
|
|
|
{ |
|
|
|
} else if (normal.isParallel(Direction3D(0, 0, 1))) { |
|
|
|
alignAxis = 2; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
} else { |
|
|
|
throw std::runtime_error("Non align axis cylinder."); |
|
|
|
} |
|
|
|
|
|
|
|
auto getPrimitive = [this, normal, halfDistance, middlePoint, extusion, alignAxis]( |
|
|
|
const Point3D& point1, const Point3D& point2, const double bulge) { |
|
|
|
auto middleToOrigion = normal.cross(Direction3D(point2 - point1)); |
|
|
|
double sinHalfTheta = 2 * bulge / (1 + bulge * bulge); |
|
|
|
double radius = halfDistance / sinHalfTheta; |
|
|
|
double scalar = std::sqrt(radius * radius - halfDistance * halfDistance); |
|
|
|
auto middleToOrigion = normal.cross(Direction3D(point2 - point1)); |
|
|
|
double sinHalfTheta = 2 * bulge / (1 + bulge * bulge); |
|
|
|
double radius = halfDistance / sinHalfTheta; |
|
|
|
double scalar = std::sqrt(radius * radius - halfDistance * halfDistance); |
|
|
|
// GJJ
|
|
|
|
if (std::abs(bulge) > 1.0) { scalar *= -1; } |
|
|
|
|
|
|
|
auto origion = middlePoint + middleToOrigion * scalar; |
|
|
|
|
|
|
|
/* Create the cylinder face */ |
|
|
|
return this->createCylinderWithoutTopBottom(origion, radius, extusion.length(), alignAxis); |
|
|
|
}; |
|
|
|
|
|
|
|
if (std::abs(bulge1) <= 1e-8) |
|
|
|
{ |
|
|
|
if (std::abs(bulge1) <= 1e-8) { |
|
|
|
assert(std::abs(bulge2) > 1e-8); |
|
|
|
rep1 = this->createHalfPlane(point1, -Direction3D{middleToOrigion2}); |
|
|
|
rep2 = getPrimitive(point2, point1, bulge2); |
|
|
|
// GJJ
|
|
|
|
rep1 = this->createHalfPlane(point1, Direction3D{middleToOrigion2}); |
|
|
|
// rep1 = this->createHalfPlane(point1, -Direction3D{middleToOrigion2});
|
|
|
|
rep2 = getPrimitive(point2, point1, bulge2); |
|
|
|
result = this->intersectNode(rep1, rep2); |
|
|
|
} |
|
|
|
else if (std::abs(bulge2) <= 1e-8) |
|
|
|
{ |
|
|
|
} else if (std::abs(bulge2) <= 1e-8) { |
|
|
|
assert(std::abs(bulge1) > 1e-8); |
|
|
|
rep1 = getPrimitive(point1, point2, bulge1); |
|
|
|
rep2 = this->createHalfPlane(point2, -Direction3D{middleToOrigion1}); |
|
|
|
// GJJ
|
|
|
|
rep1 = getPrimitive(point1, point2, bulge1); |
|
|
|
rep2 = this->createHalfPlane(point2, Direction3D{middleToOrigion1}); |
|
|
|
// rep2 = this->createHalfPlane(point2, -Direction3D{middleToOrigion1});
|
|
|
|
result = this->intersectNode(rep1, rep2); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
} else { |
|
|
|
rep1 = getPrimitive(point1, point2, bulge1); |
|
|
|
rep2 = getPrimitive(point2, point1, bulge2); |
|
|
|
|
|
|
|
/* if the bulge == 1 and bulge == 1, it is a cylinder */ |
|
|
|
if (std::abs(bulge1 - 1.0) < 1e-8 && std::abs(bulge2 - 1.0) < 1e-8) |
|
|
|
{ |
|
|
|
if (std::abs(bulge1 - 1.0) < 1e-8 && std::abs(bulge2 - 1.0) < 1e-8) { |
|
|
|
result = getPrimitive(point1, point2, bulge1); |
|
|
|
} |
|
|
|
/* if the bulge == -1 and bulge == -1, it is a cylinder */ |
|
|
|
else if (std::abs(bulge1 + 1.0) < 1e-8 && std::abs(bulge2 + 1.0) < 1e-8) |
|
|
|
{ |
|
|
|
else if (std::abs(bulge1 + 1.0) < 1e-8 && std::abs(bulge2 + 1.0) < 1e-8) { |
|
|
|
result = getPrimitive(point1, point2, bulge1); |
|
|
|
} |
|
|
|
/* if the bulge1 and bulge2 has the same symbol, it is merge */ |
|
|
|
else if (bulge1 * bulge2 > 0.0) |
|
|
|
{ |
|
|
|
else if (bulge1 * bulge2 > 0.0) { |
|
|
|
result = this->intersectNode(rep1, rep2); |
|
|
|
} |
|
|
|
else if (bulge1 > 0.0) |
|
|
|
{ |
|
|
|
// GJJ
|
|
|
|
// } else if (bulge1 > 0.0) {
|
|
|
|
} else if (std::abs(bulge1) > std::abs(bulge2)) { |
|
|
|
result = this->differentNode(rep1, rep2); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
} else { |
|
|
|
result = this->differentNode(rep2, rep1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
auto halfPlane1 = createHalfPlane(points[0], -normal); |
|
|
|
auto halfPlane2 = createHalfPlane(points[0] + extusion, normal); |
|
|
|
result = this->intersectNode(result, halfPlane1); |
|
|
|
result = this->intersectNode(result, halfPlane2); |
|
|
|
result = this->intersectNode(result, halfPlane1); |
|
|
|
result = this->intersectNode(result, halfPlane2); |
|
|
|
|
|
|
|
this->m_allVisible.push_back(result); |
|
|
|
return this->m_allVisible.size() - 1; |
|
|
@ -682,69 +600,51 @@ public: |
|
|
|
{ |
|
|
|
int pointNumber = points.size(); |
|
|
|
assert(pointNumber >= 2); |
|
|
|
if (pointNumber == 2) |
|
|
|
{ |
|
|
|
return addExtrudeWithTwoPoint(points, bulges, extusion); |
|
|
|
} |
|
|
|
if (pointNumber == 2) { return addExtrudeWithTwoPoint(points, bulges, extusion); } |
|
|
|
|
|
|
|
/* Get base polygonal column */ |
|
|
|
auto base = createPolygonalColumnWithoutTopBottom(points, extusion); |
|
|
|
|
|
|
|
auto normal = Direction3D(extusion); |
|
|
|
for (int i = 0; i < points.size(); i++) |
|
|
|
{ |
|
|
|
for (int i = 0; i < points.size(); i++) { |
|
|
|
/* Get point and bulge data */ |
|
|
|
auto bulge = bulges[i]; |
|
|
|
if (std::abs(bulge) < 1e-8) |
|
|
|
{ |
|
|
|
continue; |
|
|
|
} |
|
|
|
if (std::abs(bulge) < 1e-8) { continue; } |
|
|
|
|
|
|
|
auto& point1 = points[i]; |
|
|
|
auto& point1 = points[i]; |
|
|
|
Point3D point2; |
|
|
|
if (i + 1 == points.size()) |
|
|
|
{ |
|
|
|
if (i + 1 == points.size()) { |
|
|
|
point2 = points[0]; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
} else { |
|
|
|
point2 = points[i + 1]; |
|
|
|
} |
|
|
|
|
|
|
|
/* Compute the origion and radius */ |
|
|
|
auto halfDistance = point1.getDistance(point2) / 2.0; |
|
|
|
auto middlePoint = point1.getMiddlePoint(point2); |
|
|
|
auto halfDistance = point1.getDistance(point2) / 2.0; |
|
|
|
auto middlePoint = point1.getMiddlePoint(point2); |
|
|
|
auto middleToOrigion = normal.cross(Direction3D(point2 - point1)); |
|
|
|
|
|
|
|
double sinHalfTheta = 2 * bulge / (1 + bulge * bulge); |
|
|
|
double radius = halfDistance / sinHalfTheta; |
|
|
|
double scalar = std::sqrt(radius * radius - halfDistance * halfDistance); |
|
|
|
double radius = halfDistance / sinHalfTheta; |
|
|
|
double scalar = std::sqrt(radius * radius - halfDistance * halfDistance); |
|
|
|
|
|
|
|
/* Determine whether to merge or subtract */ |
|
|
|
/* The operation is merge if flag is true, otherwise it is subtract */ |
|
|
|
bool flag; |
|
|
|
/* */ |
|
|
|
auto centroidPoint = computePolygonCentroid(points); |
|
|
|
auto centroidPoint = computePolygonCentroid(points); |
|
|
|
auto middleToCentroid = Direction3D(centroidPoint - middlePoint); |
|
|
|
/* out */ |
|
|
|
if (middleToCentroid.dot(middleToOrigion) > 0.0) |
|
|
|
{ |
|
|
|
if (middleToCentroid.dot(middleToOrigion) > 0.0) { |
|
|
|
/* |bulge| > 1 */ |
|
|
|
if (std::abs(bulge) > 1.0 + 1e-8) |
|
|
|
{ |
|
|
|
scalar *= -1; |
|
|
|
} |
|
|
|
if (std::abs(bulge) > 1.0 + 1e-8) { scalar *= -1; } |
|
|
|
|
|
|
|
flag = true; |
|
|
|
} |
|
|
|
/* in */ |
|
|
|
else |
|
|
|
{ |
|
|
|
else { |
|
|
|
/* |bulge| > 1 */ |
|
|
|
if (std::abs(bulge) > 1.0 + 1e-8) |
|
|
|
{ |
|
|
|
scalar *= -1; |
|
|
|
} |
|
|
|
if (std::abs(bulge) > 1.0 + 1e-8) { scalar *= -1; } |
|
|
|
|
|
|
|
flag = false; |
|
|
|
} |
|
|
@ -753,20 +653,13 @@ public: |
|
|
|
|
|
|
|
/* Determine which axis is aligned */ |
|
|
|
int alignAxis; |
|
|
|
if (normal.isParallel(Direction3D(1, 0, 0))) |
|
|
|
{ |
|
|
|
if (normal.isParallel(Direction3D(1, 0, 0))) { |
|
|
|
alignAxis = 0; |
|
|
|
} |
|
|
|
else if (normal.isParallel(Direction3D(0, 1, 0))) |
|
|
|
{ |
|
|
|
} else if (normal.isParallel(Direction3D(0, 1, 0))) { |
|
|
|
alignAxis = 1; |
|
|
|
} |
|
|
|
else if (normal.isParallel(Direction3D(0, 0, 1))) |
|
|
|
{ |
|
|
|
} else if (normal.isParallel(Direction3D(0, 0, 1))) { |
|
|
|
alignAxis = 2; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
} else { |
|
|
|
throw std::runtime_error("Non align axis cylinder."); |
|
|
|
} |
|
|
|
|
|
|
@ -774,18 +667,15 @@ public: |
|
|
|
auto cylinder = createCylinderWithoutTopBottom(origion, radius, extusion.length(), alignAxis); |
|
|
|
|
|
|
|
/* Perform union and difference operations on the basic prismatic faces */ |
|
|
|
if (flag) |
|
|
|
{ |
|
|
|
if (flag) { |
|
|
|
/* Union */ |
|
|
|
/* cylinder - half plane */ |
|
|
|
auto halfPlane = createHalfPlane(middlePoint, middleToOrigion); |
|
|
|
auto halfPlane = createHalfPlane(middlePoint, middleToOrigion); |
|
|
|
auto subtraction = this->intersectNode(cylinder, halfPlane); |
|
|
|
|
|
|
|
/* base + (cylinder - column) */ |
|
|
|
base = this->unionNode(base, subtraction); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
} else { |
|
|
|
/* difference */ |
|
|
|
/* base - cylinder */ |
|
|
|
base = this->differentNode(base, cylinder); |
|
|
@ -794,13 +684,10 @@ public: |
|
|
|
|
|
|
|
auto halfPlane1 = createHalfPlane(points[0], -normal); |
|
|
|
auto halfPlane2 = createHalfPlane(points[0] + extusion, normal); |
|
|
|
base = this->intersectNode(base, halfPlane1); |
|
|
|
base = this->intersectNode(base, halfPlane2); |
|
|
|
|
|
|
|
for (size_t i = 0; i < base.aabbs.size(); i++) |
|
|
|
{ |
|
|
|
base.aabbs[i] = base.aabb; |
|
|
|
} |
|
|
|
base = this->intersectNode(base, halfPlane1); |
|
|
|
base = this->intersectNode(base, halfPlane2); |
|
|
|
// gjj
|
|
|
|
for (size_t i = 0; i < base.aabbs.size(); i++) { base.aabbs[i] = base.aabb; } |
|
|
|
|
|
|
|
this->m_allVisible.push_back(base); |
|
|
|
|
|
|
@ -809,44 +696,34 @@ public: |
|
|
|
|
|
|
|
BodyTag addCone(const Point3D& topPoint, const Point3D& bottomPoint, const double radius1, const double radius2) |
|
|
|
{ |
|
|
|
auto bottomToTop = topPoint - bottomPoint; |
|
|
|
auto normal = Direction3D{bottomToTop}; |
|
|
|
// gjj
|
|
|
|
// auto bottomToTop = topPoint - bottomPoint;
|
|
|
|
// auto normal = Direction3D{bottomToTop};
|
|
|
|
|
|
|
|
/* Determine which axis is aligned */ |
|
|
|
int alignAxis; |
|
|
|
if (normal.isParallel(Direction3D(1, 0, 0))) |
|
|
|
{ |
|
|
|
alignAxis = 0; |
|
|
|
} |
|
|
|
else if (normal.isParallel(Direction3D(0, 1, 0))) |
|
|
|
{ |
|
|
|
alignAxis = 1; |
|
|
|
} |
|
|
|
else if (normal.isParallel(Direction3D(0, 0, 1))) |
|
|
|
{ |
|
|
|
alignAxis = 2; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
throw std::runtime_error("Non align axis cone."); |
|
|
|
} |
|
|
|
|
|
|
|
auto coneDesc = algoim::organizer::ConeDesc{bottomPoint.getUVector3Data(), radius1, radius2, alignAxis}; |
|
|
|
// int alignAxis;
|
|
|
|
// if (normal.isParallel(Direction3D(1, 0, 0))) {
|
|
|
|
// alignAxis = 0;
|
|
|
|
// } else if (normal.isParallel(Direction3D(0, 1, 0))) {
|
|
|
|
// alignAxis = 1;
|
|
|
|
// } else if (normal.isParallel(Direction3D(0, 0, 1))) {
|
|
|
|
// alignAxis = 2;
|
|
|
|
// } else {
|
|
|
|
// throw std::runtime_error("Non align axis cone.");
|
|
|
|
// }
|
|
|
|
|
|
|
|
// auto coneDesc = algoim::organizer::ConeDesc{bottomPoint.getUVector3Data(), radius1, radius2, alignAxis};
|
|
|
|
auto coneDesc = |
|
|
|
algoim::organizer::ConeDesc{bottomPoint.getUVector3Data(), topPoint.getUVector3Data(), radius2, radius1}; |
|
|
|
algoim::organizer::VisiblePrimitiveRep cone; |
|
|
|
cone.tensors.resize(3, algoim::tensor3(nullptr, 3)); |
|
|
|
std::vector<algoim::SparkStack<algoim::real>*> temp; |
|
|
|
algoim::algoimSparkAllocHeapVector(temp, cone.tensors); |
|
|
|
algoim::organizer::makeCone(coneDesc, cone); |
|
|
|
|
|
|
|
for (auto& pointer : temp) |
|
|
|
{ |
|
|
|
this->m_allPointer.push_back(pointer); |
|
|
|
} |
|
|
|
for (auto& pointer : temp) { this->m_allPointer.push_back(pointer); } |
|
|
|
|
|
|
|
for (int i = 0; i < 3; i++) |
|
|
|
{ |
|
|
|
cone.aabbs.push_back(cone.aabb); |
|
|
|
} |
|
|
|
for (int i = 0; i < 3; i++) { cone.aabbs.push_back(cone.aabb); } |
|
|
|
|
|
|
|
this->m_allVisible.push_back(cone); |
|
|
|
return this->m_allVisible.size() - 1; |
|
|
@ -863,15 +740,9 @@ public: |
|
|
|
algoim::algoimSparkAllocHeapVector(temp, box.tensors); |
|
|
|
algoim::organizer::makeMesh(boxDesc, box); |
|
|
|
|
|
|
|
for (auto& pointer : temp) |
|
|
|
{ |
|
|
|
this->m_allPointer.push_back(pointer); |
|
|
|
} |
|
|
|
for (auto& pointer : temp) { this->m_allPointer.push_back(pointer); } |
|
|
|
|
|
|
|
for (int i = 0; i < 6; i++) |
|
|
|
{ |
|
|
|
box.aabbs.push_back(box.aabb); |
|
|
|
} |
|
|
|
for (int i = 0; i < 6; i++) { box.aabbs.push_back(box.aabb); } |
|
|
|
|
|
|
|
this->m_allVisible.push_back(box); |
|
|
|
return this->m_allVisible.size() - 1; |
|
|
@ -881,44 +752,30 @@ public: |
|
|
|
{ |
|
|
|
auto normal = Direction3D{offset}; |
|
|
|
/* Determine which axis is aligned */ |
|
|
|
int alignAxis; |
|
|
|
if (normal.isParallel(Direction3D(1, 0, 0))) |
|
|
|
{ |
|
|
|
int alignAxis; |
|
|
|
if (normal.isParallel(Direction3D(1, 0, 0))) { |
|
|
|
alignAxis = 0; |
|
|
|
} |
|
|
|
else if (normal.isParallel(Direction3D(0, 1, 0))) |
|
|
|
{ |
|
|
|
} else if (normal.isParallel(Direction3D(0, 1, 0))) { |
|
|
|
alignAxis = 1; |
|
|
|
} |
|
|
|
else if (normal.isParallel(Direction3D(0, 0, 1))) |
|
|
|
{ |
|
|
|
} else if (normal.isParallel(Direction3D(0, 0, 1))) { |
|
|
|
alignAxis = 2; |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
} else { |
|
|
|
throw std::runtime_error("Non align axis cylinder."); |
|
|
|
} |
|
|
|
|
|
|
|
algoim::uvector3 ext = 3; |
|
|
|
ext(alignAxis) = 1; |
|
|
|
ext(alignAxis) = 1; |
|
|
|
|
|
|
|
algoim::organizer::VisiblePrimitiveRep cylinder; |
|
|
|
cylinder.tensors.resize(3, algoim::tensor3(nullptr, 3)); |
|
|
|
cylinder.tensors[0].ext_ = ext; |
|
|
|
std::vector<algoim::SparkStack<algoim::real>*> temp; |
|
|
|
algoim::algoimSparkAllocHeapVector(temp, cylinder.tensors); |
|
|
|
algoim::organizer::CylinderDesc cylinderDesc( |
|
|
|
bottomOrigion.getUVector3Data(), radius, offset.length(), alignAxis); |
|
|
|
algoim::organizer::CylinderDesc cylinderDesc(bottomOrigion.getUVector3Data(), radius, offset.length(), alignAxis); |
|
|
|
|
|
|
|
for (auto& pointer : temp) |
|
|
|
{ |
|
|
|
this->m_allPointer.push_back(pointer); |
|
|
|
} |
|
|
|
for (auto& pointer : temp) { this->m_allPointer.push_back(pointer); } |
|
|
|
|
|
|
|
for (int i = 0; i < 3; i++) |
|
|
|
{ |
|
|
|
cylinder.aabbs.push_back(cylinder.aabb); |
|
|
|
} |
|
|
|
for (int i = 0; i < 3; i++) { cylinder.aabbs.push_back(cylinder.aabb); } |
|
|
|
|
|
|
|
this->m_allVisible.push_back(cylinder); |
|
|
|
return this->m_allVisible.size() - 1; |
|
|
@ -937,9 +794,8 @@ public: |
|
|
|
assert(rep.tensors.size() == rep.aabbs.size()); |
|
|
|
|
|
|
|
std::vector<algoim::organizer::MinimalPrimitiveRep> minimalReps; |
|
|
|
algoim::uvector3 range = rep.aabb.max - rep.aabb.min; |
|
|
|
for (size_t i = 0; i < rep.tensors.size(); i++) |
|
|
|
{ |
|
|
|
algoim::uvector3 range = rep.aabb.max - rep.aabb.min; |
|
|
|
for (size_t i = 0; i < rep.tensors.size(); i++) { |
|
|
|
auto& tenser = rep.tensors[i]; |
|
|
|
|
|
|
|
algoim::organizer::detail::powerTransformation(range, rep.aabb.min, tenser); |
|
|
@ -949,31 +805,24 @@ public: |
|
|
|
minimalReps.push_back(minimalRep); |
|
|
|
} |
|
|
|
|
|
|
|
auto size = rep.aabb.size(); |
|
|
|
algoim::organizer::Scene scene{minimalReps, |
|
|
|
auto size = rep.aabb.size(); |
|
|
|
algoim::organizer::Scene scene{minimalReps, |
|
|
|
algoim::organizer::AABB(rep.aabb.min - size * 1e-5, rep.aabb.max + size * 1e-5)}; |
|
|
|
algoim::organizer::OcTreeNode rootNode(0, 1, rep.subBlobTree); |
|
|
|
for (int i = 0; i < minimalReps.size(); ++i) |
|
|
|
{ |
|
|
|
rootNode.polyIntersectIndices.emplace_back(i); |
|
|
|
} |
|
|
|
int cnt = 1; |
|
|
|
for (int i = 0; i < minimalReps.size(); ++i) { rootNode.polyIntersectIndices.emplace_back(i); } |
|
|
|
int cnt = 1; |
|
|
|
std::vector<algoim::organizer::OcTreeNode> leaves; |
|
|
|
algoim::organizer::buildOcTreeV0(scene, rootNode, leaves, 1, cnt, 0, -1); |
|
|
|
std::cout << "octree built over" << std::endl; |
|
|
|
// basicTask(scene, leaves[14], q);
|
|
|
|
|
|
|
|
int i = 0; |
|
|
|
int q = 10; |
|
|
|
int i = 0; |
|
|
|
int q = 10; |
|
|
|
double volume = 0; |
|
|
|
double area = 0; |
|
|
|
for (const auto& leaf : leaves) |
|
|
|
{ |
|
|
|
double area = 0; |
|
|
|
for (const auto& leaf : leaves) { |
|
|
|
auto basicRes = algoim::organizer::basicTask(scene, leaf, q); |
|
|
|
if (std::isinf(basicRes.volume)) |
|
|
|
{ |
|
|
|
std::cout << "inf volume when solving leaf: " << i << std::endl; |
|
|
|
} |
|
|
|
if (std::isinf(basicRes.volume)) { std::cout << "inf volume when solving leaf: " << i << std::endl; } |
|
|
|
volume += basicRes.volume; |
|
|
|
std::cout << "Solved leaves: " << ++i << "/" << leaves.size() |
|
|
|
<< ", primitive cnt: " << leaf.polyIntersectIndices.size() << ", volume: " << volume << std::endl; |
|
|
@ -985,11 +834,9 @@ public: |
|
|
|
return std::make_pair(area, volume); |
|
|
|
} |
|
|
|
|
|
|
|
void output(const BodyTag& tag) |
|
|
|
{ |
|
|
|
} |
|
|
|
void output(const BodyTag& tag) {} |
|
|
|
|
|
|
|
private: |
|
|
|
std::vector<algoim::organizer::VisiblePrimitiveRep> m_allVisible; |
|
|
|
std::vector<algoim::SparkStack<algoim::real>*> m_allPointer; |
|
|
|
std::vector<algoim::SparkStack<algoim::real>*> m_allPointer; |
|
|
|
}; |
|
|
|