|
|
@ -1,8 +1,8 @@ |
|
|
|
#pragma once |
|
|
|
#include "organizer.hpp" |
|
|
|
#include <sparkstack.hpp> |
|
|
|
#include <uvector.hpp> |
|
|
|
#include "organizer.hpp" |
|
|
|
#include "primitive.hpp" |
|
|
|
#include <sparkstack.hpp> |
|
|
|
|
|
|
|
class Vector3D |
|
|
|
{ |
|
|
@ -22,37 +22,27 @@ public: |
|
|
|
|
|
|
|
Vector3D operator/(const double scalar) const |
|
|
|
{ |
|
|
|
if (scalar == 0) |
|
|
|
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 |
|
|
|
); |
|
|
|
|
|
|
|
return Vector3D(this->m_x / scalar, this->m_y / scalar, this->m_z / scalar); |
|
|
|
} |
|
|
|
|
|
|
|
Vector3D operator*(const double scalar) const |
|
|
|
{ |
|
|
|
return Vector3D( |
|
|
|
this->m_x * scalar, |
|
|
|
this->m_y * scalar, |
|
|
|
this->m_z * scalar |
|
|
|
); |
|
|
|
{ |
|
|
|
return Vector3D(this->m_x * scalar, this->m_y * scalar, this->m_z * scalar); |
|
|
|
} |
|
|
|
|
|
|
|
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, |
|
|
|
this->m_x * other.m_y - this->m_y * other.m_x |
|
|
|
); |
|
|
|
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 |
|
|
|
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; |
|
|
|
} |
|
|
@ -91,16 +81,14 @@ public: |
|
|
|
this->normalized(); |
|
|
|
} |
|
|
|
|
|
|
|
Direction3D cross(const Direction3D& other) const |
|
|
|
Vector3D cross(const Direction3D& other) const |
|
|
|
{ |
|
|
|
return Direction3D( |
|
|
|
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 |
|
|
|
); |
|
|
|
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 |
|
|
|
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; |
|
|
|
} |
|
|
@ -108,29 +96,24 @@ public: |
|
|
|
void normalized() |
|
|
|
{ |
|
|
|
double length = this->length(); |
|
|
|
if (std::abs(length) < 1e-8) |
|
|
|
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; |
|
|
|
this->m_y /= length, this->m_z /= length; |
|
|
|
} |
|
|
|
|
|
|
|
bool isParallel(const Direction3D& other) |
|
|
|
bool isParallel(const Direction3D& other) const |
|
|
|
{ |
|
|
|
auto cross = this->cross(other); |
|
|
|
return std::abs(cross.length()) < 1e-8; |
|
|
|
} |
|
|
|
|
|
|
|
Direction3D operator- () const |
|
|
|
Direction3D operator-() const |
|
|
|
{ |
|
|
|
return Direction3D( |
|
|
|
-this->m_x, |
|
|
|
-this->m_y, |
|
|
|
-this->m_z |
|
|
|
); |
|
|
|
return Direction3D(-this->m_x, -this->m_y, -this->m_z); |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
@ -144,55 +127,37 @@ public: |
|
|
|
this->m_y = y; |
|
|
|
this->m_z = z; |
|
|
|
} |
|
|
|
|
|
|
|
Vector3D operator- (const Point3D& other) const |
|
|
|
|
|
|
|
Vector3D operator-(const Point3D& other) const |
|
|
|
{ |
|
|
|
return Vector3D( |
|
|
|
this->m_x - other.m_x, |
|
|
|
this->m_y - other.m_y, |
|
|
|
this->m_z - other.m_z |
|
|
|
); |
|
|
|
return Vector3D(this->m_x - other.m_x, this->m_y - other.m_y, this->m_z - other.m_z); |
|
|
|
} |
|
|
|
|
|
|
|
Point3D operator- (const Direction3D& direction) const |
|
|
|
Point3D operator-(const Direction3D& direction) const |
|
|
|
{ |
|
|
|
return Point3D( |
|
|
|
this->m_x - direction.m_x, |
|
|
|
this->m_y - direction.m_y, |
|
|
|
this->m_z - direction.m_z |
|
|
|
); |
|
|
|
return Point3D(this->m_x - direction.m_x, this->m_y - direction.m_y, this->m_z - direction.m_z); |
|
|
|
} |
|
|
|
|
|
|
|
Point3D operator- (const Vector3D& offset) const |
|
|
|
Point3D operator-(const Vector3D& offset) const |
|
|
|
{ |
|
|
|
return Point3D( |
|
|
|
this->m_x - offset.m_x, |
|
|
|
this->m_y - offset.m_y, |
|
|
|
this->m_z - offset.m_z |
|
|
|
); |
|
|
|
return Point3D(this->m_x - offset.m_x, this->m_y - offset.m_y, this->m_z - offset.m_z); |
|
|
|
} |
|
|
|
|
|
|
|
Point3D operator+ (const Direction3D& direction) const |
|
|
|
Point3D operator+(const Direction3D& direction) const |
|
|
|
{ |
|
|
|
return Point3D( |
|
|
|
this->m_x + direction.m_x, |
|
|
|
this->m_y + direction.m_y, |
|
|
|
this->m_z + direction.m_z |
|
|
|
); |
|
|
|
return Point3D(this->m_x + direction.m_x, this->m_y + direction.m_y, this->m_z + direction.m_z); |
|
|
|
} |
|
|
|
|
|
|
|
Point3D operator+ (const Vector3D& offset) const |
|
|
|
Point3D operator+(const Vector3D& offset) const |
|
|
|
{ |
|
|
|
return Point3D( |
|
|
|
this->m_x + offset.m_x, |
|
|
|
this->m_y + offset.m_y, |
|
|
|
this->m_z + offset.m_z |
|
|
|
); |
|
|
|
return Point3D(this->m_x + offset.m_x, this->m_y + offset.m_y, this->m_z + offset.m_z); |
|
|
|
} |
|
|
|
|
|
|
|
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 |
|
|
@ -201,6 +166,8 @@ public: |
|
|
|
} |
|
|
|
}; |
|
|
|
|
|
|
|
typedef unsigned int BodyTag; |
|
|
|
|
|
|
|
class Loader |
|
|
|
{ |
|
|
|
public: |
|
|
@ -212,7 +179,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; |
|
|
@ -226,7 +193,7 @@ public: |
|
|
|
* @brief Create an empty blob tree |
|
|
|
* @return The created empty blob tree |
|
|
|
*/ |
|
|
|
static algoim::organizer::BlobTree createEmptyBlobTree() |
|
|
|
algoim::organizer::BlobTree createEmptyBlobTree() |
|
|
|
{ |
|
|
|
algoim::organizer::BlobTree tree; |
|
|
|
|
|
|
@ -269,7 +236,8 @@ public: |
|
|
|
* @param[in] rep2 The second visible primitive node |
|
|
|
* @return The unioned visible primitive |
|
|
|
*/ |
|
|
|
static algoim::organizer::VisiblePrimitiveRep unionNode(const algoim::organizer::VisiblePrimitiveRep& rep1, const algoim::organizer::VisiblePrimitiveRep rep2) |
|
|
|
algoim::organizer::VisiblePrimitiveRep unionNode(const algoim::organizer::VisiblePrimitiveRep& rep1, |
|
|
|
const algoim::organizer::VisiblePrimitiveRep& rep2) |
|
|
|
{ |
|
|
|
auto tree = createEmptyBlobTree(); |
|
|
|
tree.structure[2].nodeOp = 0; |
|
|
@ -280,10 +248,12 @@ public: |
|
|
|
|
|
|
|
algoim::organizer::VisiblePrimitiveRep result; |
|
|
|
result.subBlobTree = tree; |
|
|
|
for (auto& rep : minimalReps) |
|
|
|
result.aabb = rep1.aabb; |
|
|
|
result.aabb.extend(rep2.aabb); |
|
|
|
|
|
|
|
for (auto& iter : minimalReps) |
|
|
|
{ |
|
|
|
result.tensors.push_back(rep.tensor); |
|
|
|
result.aabb.extend(rep.aabb); |
|
|
|
result.tensors.push_back(iter.tensor); |
|
|
|
} |
|
|
|
|
|
|
|
return result; |
|
|
@ -295,7 +265,8 @@ public: |
|
|
|
* @param[in] rep2 The second visible primitive node |
|
|
|
* @return The intersected visible primitive |
|
|
|
*/ |
|
|
|
static algoim::organizer::VisiblePrimitiveRep intersectionNode(const algoim::organizer::VisiblePrimitiveRep& rep1, const algoim::organizer::VisiblePrimitiveRep rep2) |
|
|
|
algoim::organizer::VisiblePrimitiveRep intersectNode(const algoim::organizer::VisiblePrimitiveRep& rep1, |
|
|
|
const algoim::organizer::VisiblePrimitiveRep& rep2) |
|
|
|
{ |
|
|
|
auto tree = createEmptyBlobTree(); |
|
|
|
tree.structure[2].nodeOp = 1; |
|
|
@ -306,10 +277,12 @@ public: |
|
|
|
|
|
|
|
algoim::organizer::VisiblePrimitiveRep result; |
|
|
|
result.subBlobTree = tree; |
|
|
|
for (auto& rep : minimalReps) |
|
|
|
result.aabb = rep1.aabb; |
|
|
|
result.aabb.intersect(rep2.aabb); |
|
|
|
|
|
|
|
for (auto& iter : minimalReps) |
|
|
|
{ |
|
|
|
result.tensors.push_back(rep.tensor); |
|
|
|
result.aabb.extend(rep.aabb); |
|
|
|
result.tensors.push_back(iter.tensor); |
|
|
|
} |
|
|
|
|
|
|
|
return result; |
|
|
@ -321,7 +294,8 @@ public: |
|
|
|
* @param[in] rep2 The second visible primitive node |
|
|
|
* @return The differenced visible primitive |
|
|
|
*/ |
|
|
|
static algoim::organizer::VisiblePrimitiveRep differenceNode(const algoim::organizer::VisiblePrimitiveRep& rep1, const algoim::organizer::VisiblePrimitiveRep rep2) |
|
|
|
algoim::organizer::VisiblePrimitiveRep differentNode(const algoim::organizer::VisiblePrimitiveRep& rep1, |
|
|
|
const algoim::organizer::VisiblePrimitiveRep& rep2) |
|
|
|
{ |
|
|
|
auto tree = createEmptyBlobTree(); |
|
|
|
tree.structure[2].nodeOp = 2; |
|
|
@ -332,29 +306,84 @@ public: |
|
|
|
|
|
|
|
algoim::organizer::VisiblePrimitiveRep result; |
|
|
|
result.subBlobTree = tree; |
|
|
|
for (auto& rep : minimalReps) |
|
|
|
result.aabb = rep1.aabb; |
|
|
|
|
|
|
|
for (auto& iter : minimalReps) |
|
|
|
{ |
|
|
|
result.tensors.push_back(rep.tensor); |
|
|
|
result.aabb.extend(rep.aabb); |
|
|
|
result.tensors.push_back(iter.tensor); |
|
|
|
} |
|
|
|
|
|
|
|
return result; |
|
|
|
} |
|
|
|
|
|
|
|
void unionNode(const BodyTag body1, const BodyTag body2) |
|
|
|
{ |
|
|
|
auto& rep1 = this->m_allVisible[body1]; |
|
|
|
auto& rep2 = this->m_allVisible[body2]; |
|
|
|
|
|
|
|
auto result = this->unionNode(rep1, rep2); |
|
|
|
|
|
|
|
this->m_allVisible[body1] = result; |
|
|
|
} |
|
|
|
|
|
|
|
void intersectNode(const BodyTag body1, const BodyTag body2) |
|
|
|
{ |
|
|
|
auto& rep1 = this->m_allVisible[body1]; |
|
|
|
auto& rep2 = this->m_allVisible[body2]; |
|
|
|
|
|
|
|
auto result = this->intersectNode(rep1, rep2); |
|
|
|
|
|
|
|
this->m_allVisible[body1] = result; |
|
|
|
} |
|
|
|
|
|
|
|
void differentNode(const BodyTag body1, const BodyTag body2) |
|
|
|
{ |
|
|
|
auto& rep1 = this->m_allVisible[body1]; |
|
|
|
auto& rep2 = this->m_allVisible[body2]; |
|
|
|
|
|
|
|
auto result = this->differentNode(rep1, rep2); |
|
|
|
|
|
|
|
this->m_allVisible[body1] = result; |
|
|
|
} |
|
|
|
|
|
|
|
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(); |
|
|
|
|
|
|
|
auto& rep = this->m_allVisible[body]; |
|
|
|
|
|
|
|
for (auto& iter : rep.tensors) |
|
|
|
{ |
|
|
|
algoim::organizer::detail::powerTransformation(scale, bias, iter); |
|
|
|
} |
|
|
|
|
|
|
|
rep.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); |
|
|
|
this->m_allVisible[body] = result; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
|
* @brief Create a polygonal column without top face and bottom face |
|
|
|
* @param[in] points All the bottom point with counter clockwise |
|
|
|
* @param[in] extusion The stretch direction |
|
|
|
* @return The polygonal column |
|
|
|
* @return The polygonal column |
|
|
|
*/ |
|
|
|
algoim::organizer::VisiblePrimitiveRep createPolygonalColumnWithoutTopBottom(const std::vector<Point3D>& points, const Vector3D& extusion) |
|
|
|
algoim::organizer::VisiblePrimitiveRep createPolygonalColumnWithoutTopBottom(const std::vector<Point3D>& points, |
|
|
|
const Vector3D& extusion) |
|
|
|
{ |
|
|
|
int pointNumber = points.size(); |
|
|
|
|
|
|
|
|
|
|
|
std::vector<algoim::uvector3> vertices; |
|
|
|
std::vector<int> indices; |
|
|
|
std::vector<int> indexInclusiveScan; |
|
|
|
|
|
|
|
|
|
|
|
/* All bottom point */ |
|
|
|
for (int i = 0; i < pointNumber; i++) |
|
|
|
{ |
|
|
@ -374,14 +403,14 @@ public: |
|
|
|
indices.push_back((i + 1) % pointNumber); |
|
|
|
indices.push_back((i + 1) % pointNumber + pointNumber); |
|
|
|
indices.push_back(i + pointNumber); |
|
|
|
|
|
|
|
indexInclusiveScan.push_back(index); |
|
|
|
|
|
|
|
index += 4; |
|
|
|
indexInclusiveScan.push_back(index); |
|
|
|
} |
|
|
|
|
|
|
|
algoim::organizer::MeshDesc polygonalColumn(vertices, indices, indexInclusiveScan); |
|
|
|
algoim::organizer::VisiblePrimitiveRep result; |
|
|
|
result.tensors.resize(2 + pointNumber, algoim::tensor3(nullptr, 3)); |
|
|
|
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); |
|
|
@ -400,23 +429,29 @@ public: |
|
|
|
* @param[in] radius The radius of the cylinder |
|
|
|
* @param[in] length The length of the cylinder |
|
|
|
* @param[in] alignAxis The align axis of the cylinder |
|
|
|
* @return The cylinder column |
|
|
|
* @return The cylinder column |
|
|
|
*/ |
|
|
|
algoim::organizer::VisiblePrimitiveRep createCylinderWithoutTopBottom(const Point3D& origion, const double radius, const double length, const int alignAxis) |
|
|
|
algoim::organizer::VisiblePrimitiveRep createCylinderWithoutTopBottom(const Point3D& origion, |
|
|
|
const double radius, |
|
|
|
const double length, |
|
|
|
const int alignAxis) |
|
|
|
{ |
|
|
|
algoim::uvector3 ext = 3; |
|
|
|
ext(alignAxis) = 1; |
|
|
|
|
|
|
|
algoim::organizer::VisiblePrimitiveRep result; |
|
|
|
result.tensors.resize(1, algoim::tensor3(nullptr, ext)); |
|
|
|
std::vector<algoim::SparkStack<algoim::real>*> resultTemp; |
|
|
|
algoim::algoimSparkAllocHeapVector(resultTemp, result.tensors); |
|
|
|
this->m_allPointer.push_back(resultTemp[0]); |
|
|
|
|
|
|
|
algoim::organizer::CylinderDesc cylinderDesc(origion.getUVector3Data(), radius, length, alignAxis); |
|
|
|
algoim::organizer::VisiblePrimitiveRep cylinder; |
|
|
|
cylinder.tensors.resize(3, algoim::tensor3(nullptr, 3)); |
|
|
|
std::vector<algoim::SparkStack<algoim::real>*> temp; |
|
|
|
cylinder.tensors[0].ext_ = ext; |
|
|
|
algoim::algoim_spark_alloc(algoim::real, cylinder.tensors); |
|
|
|
algoim::organizer::makeCylinder(cylinderDesc, cylinder); |
|
|
|
|
|
|
|
algoim::organizer::VisiblePrimitiveRep result; |
|
|
|
result.tensors.resize(1, algoim::tensor3(nullptr, 3)); |
|
|
|
std::vector<algoim::SparkStack<algoim::real>*> resultTemp; |
|
|
|
algoim::algoimSparkAllocHeapVector(temp, result.tensors); |
|
|
|
this->m_allPointer.push_back(resultTemp[0]); |
|
|
|
|
|
|
|
result.tensors[0] = cylinder.tensors[0]; |
|
|
|
result.aabb = cylinder.aabb; |
|
|
|
result.subBlobTree.primitiveNodeIdx.push_back(0); |
|
|
@ -437,8 +472,8 @@ public: |
|
|
|
algoim::organizer::VisiblePrimitiveRep halfPlane; |
|
|
|
halfPlane.tensors.resize(1, algoim::tensor3(nullptr, 3)); |
|
|
|
std::vector<algoim::SparkStack<algoim::real>*> temp; |
|
|
|
algoim::algoim_spark_alloc(algoim::real, halfPlane.tensors); |
|
|
|
algoim::organizer::makeHalfPlane(halfPlaneDesc , halfPlane); |
|
|
|
algoim::algoimSparkAllocHeapVector(temp, halfPlane.tensors); |
|
|
|
algoim::organizer::makeHalfPlane(halfPlaneDesc, halfPlane); |
|
|
|
this->m_allPointer.push_back(temp[0]); |
|
|
|
|
|
|
|
return halfPlane; |
|
|
@ -450,9 +485,103 @@ public: |
|
|
|
* @param[in] bulges All the bulge on each edge of the base face |
|
|
|
* @param[in] extusion The Stretch direction and length |
|
|
|
*/ |
|
|
|
void addExtrudeWithTwoPoint(const std::vector<Point3D>& points, const std::vector<double>& bulges, const Vector3D& extusion) |
|
|
|
BodyTag addExtrudeWithTwoPoint(const std::vector<Point3D>& points, |
|
|
|
const std::vector<double>& bulges, |
|
|
|
const Vector3D& extusion) |
|
|
|
{ |
|
|
|
assert(bulges[0] >= 0.0 && bulges[1] >= 0.0); |
|
|
|
|
|
|
|
auto normal = Direction3D(extusion); |
|
|
|
auto& point1 = points[0]; |
|
|
|
auto& point2 = points[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 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))) |
|
|
|
{ |
|
|
|
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 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 origion = middlePoint + middleToOrigion * scalar; |
|
|
|
|
|
|
|
/* Create the cylinder face */ |
|
|
|
return this->createCylinderWithoutTopBottom(origion, radius, extusion.length(), alignAxis); |
|
|
|
}; |
|
|
|
|
|
|
|
if (std::abs(bulge1) <= 1e-8) |
|
|
|
{ |
|
|
|
assert(std::abs(bulge2) > 1e-8); |
|
|
|
rep1 = this->createHalfPlane(point1, -Direction3D{middleToOrigion2}); |
|
|
|
rep2 = getPrimitive(point2, point1, bulge2); |
|
|
|
result = this->intersectNode(rep1, rep2); |
|
|
|
} |
|
|
|
else if (std::abs(bulge2) <= 1e-8) |
|
|
|
{ |
|
|
|
assert(std::abs(bulge1) > 1e-8); |
|
|
|
rep1 = getPrimitive(point1, point2, bulge1); |
|
|
|
rep2 = this->createHalfPlane(point2, -Direction3D{middleToOrigion1}); |
|
|
|
result = this->intersectNode(rep1, rep2); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
rep1 = getPrimitive(point1, point2, bulge1); |
|
|
|
rep2 = getPrimitive(point2, point1, bulge2); |
|
|
|
|
|
|
|
/* if the bulge == 1 and bulge == 2, it is a cylinder */ |
|
|
|
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) |
|
|
|
{ |
|
|
|
result = this->intersectNode(rep1, rep2); |
|
|
|
} |
|
|
|
else if (bulge1 > 0.0) |
|
|
|
{ |
|
|
|
result = this->differentNode(rep1, rep2); |
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
result = this->differentNode(rep2, rep1); |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
auto halfPlane1 = createHalfPlane(points[0], -normal); |
|
|
|
auto halfPlane2 = createHalfPlane(points[0] + extusion, normal); |
|
|
|
result = this->unionNode(result, halfPlane1); |
|
|
|
result = this->unionNode(result, halfPlane2); |
|
|
|
|
|
|
|
this->m_allVisible.push_back(result); |
|
|
|
return this->m_allVisible.size() - 1; |
|
|
|
} |
|
|
|
|
|
|
|
/**
|
|
|
@ -461,14 +590,13 @@ public: |
|
|
|
* @param[in] bulges All the bulge on each edge of the base face |
|
|
|
* @param[in] extusion The Stretch direction and length |
|
|
|
*/ |
|
|
|
void addExtrude(const std::vector<Point3D>& points, const std::vector<double>& bulges, const Vector3D& extusion) |
|
|
|
BodyTag addExtrude(const std::vector<Point3D>& points, const std::vector<double>& bulges, const Vector3D& extusion) |
|
|
|
{ |
|
|
|
int pointNumber = points.size(); |
|
|
|
assert(pointNumber >= 2); |
|
|
|
if (pointNumber == 2) |
|
|
|
{ |
|
|
|
addExtrudeWithTwoPoint(points, bulges, extusion); |
|
|
|
return; |
|
|
|
return addExtrudeWithTwoPoint(points, bulges, extusion); |
|
|
|
} |
|
|
|
|
|
|
|
/* Get base polygonal column */ |
|
|
@ -532,7 +660,7 @@ public: |
|
|
|
flag = true; |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
/* Determine which axis is aligned */ |
|
|
|
int alignAxis; |
|
|
|
if (normal.isParallel(Direction3D(1, 0, 0))) |
|
|
@ -555,26 +683,23 @@ public: |
|
|
|
/* Create the cylinder face */ |
|
|
|
auto cylinder = createCylinderWithoutTopBottom(origion, radius, extusion.length(), alignAxis); |
|
|
|
|
|
|
|
|
|
|
|
/* Perform union and difference operations on the basic prismatic faces */ |
|
|
|
if (flag) |
|
|
|
{ |
|
|
|
/* Union */ |
|
|
|
/* cylinder - half plane */ |
|
|
|
auto halfPlane = createHalfPlane(middlePoint, middleToOrigion); |
|
|
|
auto subtraction = this->intersectionNode(cylinder, halfPlane); |
|
|
|
auto subtraction = this->intersectNode(cylinder, halfPlane); |
|
|
|
|
|
|
|
/* base + (cylinder - column) */ |
|
|
|
base = this->unionNode(base, subtraction); |
|
|
|
|
|
|
|
} |
|
|
|
else |
|
|
|
{ |
|
|
|
/* difference */ |
|
|
|
/* base - cylinder */ |
|
|
|
base = this->differenceNode(base, cylinder); |
|
|
|
base = this->differentNode(base, cylinder); |
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
auto halfPlane1 = createHalfPlane(points[0], -normal); |
|
|
@ -583,131 +708,57 @@ public: |
|
|
|
base = this->unionNode(base, halfPlane2); |
|
|
|
|
|
|
|
this->m_allVisible.push_back(base); |
|
|
|
|
|
|
|
return this->m_allVisible.size() - 1; |
|
|
|
} |
|
|
|
|
|
|
|
BodyTag addCone(const Point3D& topPoint, const Point3D& bottomPoint, const double radius1, const double radius2) |
|
|
|
{ |
|
|
|
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}; |
|
|
|
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); |
|
|
|
|
|
|
|
this->m_allVisible.push_back(cone); |
|
|
|
for (auto& pointer : temp) |
|
|
|
{ |
|
|
|
this->m_allPointer.push_back(pointer); |
|
|
|
} |
|
|
|
|
|
|
|
return this->m_allVisible.size() - 1; |
|
|
|
} |
|
|
|
|
|
|
|
void output(const BodyTag& tag) |
|
|
|
{ |
|
|
|
auto rep = this->m_allVisible[tag]; |
|
|
|
auto result = rep.tensors[0].m(algoim::uvector3(0)); |
|
|
|
} |
|
|
|
|
|
|
|
private: |
|
|
|
std::vector<algoim::organizer::VisiblePrimitiveRep> m_allVisible; |
|
|
|
std::vector<algoim::SparkStack<algoim::real>*> m_allPointer; |
|
|
|
}; |
|
|
|
|
|
|
|
void test() |
|
|
|
{ |
|
|
|
Loader l; |
|
|
|
|
|
|
|
std::vector<Point3D> points; |
|
|
|
std::vector<double> bulges; |
|
|
|
Vector3D extusion; |
|
|
|
|
|
|
|
points.clear(); |
|
|
|
bulges.clear(); |
|
|
|
points.push_back(Point3D{-32450.000001122418 ,-3.8391231093737305e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{32449.999998877582 ,-3.8392495305561452e-07 ,0.0000000000000000 }); |
|
|
|
bulges.push_back(0.99999999999999989); |
|
|
|
bulges.push_back(0.99999999999999989); |
|
|
|
extusion = Vector3D{0.0000000000000000,0.0000000000000000,3300.0000000000000}; |
|
|
|
l.addExtrude(points, bulges, extusion); |
|
|
|
|
|
|
|
points.clear(); |
|
|
|
bulges.clear(); |
|
|
|
points.push_back(Point3D{-32450.000001122418 ,-3.8391231093737305e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{32449.999998877582 ,-3.8392495305561452e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{33538.999998877582 ,-3.8392534654100421e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{-33539.000001122418 ,-3.8391228016184551e-07 ,0.0000000000000000 }); |
|
|
|
bulges.push_back(0.99999999999999989); |
|
|
|
bulges.push_back(0.0000000000000000); |
|
|
|
bulges.push_back(-0.99999999999999989); |
|
|
|
bulges.push_back(0.0000000000000000); |
|
|
|
extusion = Vector3D{0.0000000000000000,0.0000000000000000,3300.0000000000000}; |
|
|
|
l.addExtrude(points, bulges, extusion); |
|
|
|
|
|
|
|
points.clear(); |
|
|
|
bulges.clear(); |
|
|
|
points.push_back(Point3D{-32450.000001122418 ,-3.8391231093737305e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{32449.999998877582 ,-3.8392495305561452e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{33538.999998877582 ,-3.8392534654100421e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{-33539.000001122418 ,-3.8391228016184551e-07 ,0.0000000000000000 }); |
|
|
|
bulges.push_back(0.99999999999999989); |
|
|
|
bulges.push_back(0.0000000000000000); |
|
|
|
bulges.push_back(-0.99999999999999989); |
|
|
|
bulges.push_back(0.0000000000000000); |
|
|
|
extusion = Vector3D{0.0000000000000000,0.0000000000000000,3300.0000000000000}; |
|
|
|
l.addExtrude(points, bulges, extusion); |
|
|
|
|
|
|
|
points.clear(); |
|
|
|
bulges.clear(); |
|
|
|
points.push_back(Point3D{-32450.000001122418 ,-3.8391231093737305e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{32449.999998877582 ,-3.8392495305561452e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{33538.999998877582 ,-3.8392534654100421e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{-33539.000001122418 ,-3.8391228016184551e-07 ,0.0000000000000000 }); |
|
|
|
bulges.push_back(0.99999999999999989); |
|
|
|
bulges.push_back(0.0000000000000000); |
|
|
|
bulges.push_back(-0.99999999999999989); |
|
|
|
bulges.push_back(0.0000000000000000); |
|
|
|
extusion = Vector3D{0.0000000000000000,0.0000000000000000,3300.0000000000000}; |
|
|
|
l.addExtrude(points, bulges, extusion); |
|
|
|
|
|
|
|
points.clear(); |
|
|
|
bulges.clear(); |
|
|
|
points.push_back(Point3D{-32450.000001122418 ,-3.8391231093737305e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{32449.999998877582 ,-3.8392495305561452e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{33538.999998877582 ,-3.8392534654100421e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{-33539.000001122418 ,-3.8391228016184551e-07 ,0.0000000000000000 }); |
|
|
|
bulges.push_back(0.99999999999999989); |
|
|
|
bulges.push_back(0.0000000000000000); |
|
|
|
bulges.push_back(-0.99999999999999989); |
|
|
|
bulges.push_back(0.0000000000000000); |
|
|
|
extusion = Vector3D{0.0000000000000000,0.0000000000000000,3300.0000000000000}; |
|
|
|
l.addExtrude(points, bulges, extusion); |
|
|
|
|
|
|
|
points.clear(); |
|
|
|
bulges.clear(); |
|
|
|
points.push_back(Point3D{32449.999998877582 ,-3.8392495305561452e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{-32450.000001122418 ,-3.8391231093737305e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{-33539.000001122418 ,-3.8391191745198337e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{33538.999998877582 ,-3.8392498383114206e-07 ,0.0000000000000000 }); |
|
|
|
bulges.push_back(0.99999999999999989); |
|
|
|
bulges.push_back(0.0000000000000000); |
|
|
|
bulges.push_back(-0.99999999999999989); |
|
|
|
bulges.push_back(0.0000000000000000); |
|
|
|
extusion = Vector3D{0.0000000000000000,0.0000000000000000,3300.0000000000000}; |
|
|
|
l.addExtrude(points, bulges, extusion); |
|
|
|
|
|
|
|
points.clear(); |
|
|
|
bulges.clear(); |
|
|
|
points.push_back(Point3D{32449.999998877582 ,-3.8392495305561452e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{-32450.000001122418 ,-3.8391231093737305e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{-33539.000001122418 ,-3.8391191745198337e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{33538.999998877582 ,-3.8392498383114206e-07 ,0.0000000000000000 }); |
|
|
|
bulges.push_back(0.99999999999999989); |
|
|
|
bulges.push_back(0.0000000000000000); |
|
|
|
bulges.push_back(-0.99999999999999989); |
|
|
|
bulges.push_back(0.0000000000000000); |
|
|
|
extusion = Vector3D{0.0000000000000000,0.0000000000000000,3300.0000000000000}; |
|
|
|
l.addExtrude(points, bulges, extusion); |
|
|
|
|
|
|
|
points.clear(); |
|
|
|
bulges.clear(); |
|
|
|
points.push_back(Point3D{32449.999998877582 ,-3.8392495305561452e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{-32450.000001122418 ,-3.8391231093737305e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{-33539.000001122418 ,-3.8391191745198337e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{33538.999998877582 ,-3.8392498383114206e-07 ,0.0000000000000000 }); |
|
|
|
bulges.push_back(0.99999999999999989); |
|
|
|
bulges.push_back(0.0000000000000000); |
|
|
|
bulges.push_back(-0.99999999999999989); |
|
|
|
bulges.push_back(0.0000000000000000); |
|
|
|
extusion = Vector3D{0.0000000000000000,0.0000000000000000,3300.0000000000000}; |
|
|
|
l.addExtrude(points, bulges, extusion); |
|
|
|
|
|
|
|
points.clear(); |
|
|
|
bulges.clear(); |
|
|
|
points.push_back(Point3D{32449.999998877582 ,-3.8392495305561452e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{-32450.000001122418 ,-3.8391231093737305e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{-33539.000001122418 ,-3.8391191745198337e-07 ,0.0000000000000000 }); |
|
|
|
points.push_back(Point3D{33538.999998877582 ,-3.8392498383114206e-07 ,0.0000000000000000 }); |
|
|
|
bulges.push_back(0.99999999999999989); |
|
|
|
bulges.push_back(0.0000000000000000); |
|
|
|
bulges.push_back(-0.99999999999999989); |
|
|
|
bulges.push_back(0.0000000000000000); |
|
|
|
extusion = Vector3D{0.0000000000000000,0.0000000000000000,3300.0000000000000}; |
|
|
|
l.addExtrude(points, bulges, extusion); |
|
|
|
} |