Browse Source

Add Loader

master
wangxiaolong 5 months ago
parent
commit
3f6e94826a
  1. 5
      CMakeLists.txt
  2. 519
      algoim/organizer/loader.hpp
  3. 20
      algoim/organizer/minimalPrimitive.hpp
  4. 4
      algoim/organizer/organizer.hpp
  5. 223
      examples/example_loader.cpp

5
CMakeLists.txt

@ -19,6 +19,9 @@ endif()
aux_source_directory(algoim algoim_SOURCES) aux_source_directory(algoim algoim_SOURCES)
add_executable(algoim examples/examples_quad_multipoly.cpp ${algoim_SOURCES}) add_executable(algoim examples/examples_quad_multipoly.cpp ${algoim_SOURCES})
target_include_directories(algoim PRIVATE ${LAPACKE_INCLUDE_DIR}) target_include_directories(algoim PRIVATE ${LAPACKE_INCLUDE_DIR})
target_link_libraries(algoim PRIVATE ${LAPACKE_LIB} ${LAPACK_LIBRARIES} ${BLAS_LIBRARIES}) target_link_libraries(algoim PRIVATE ${LAPACKE_LIB} ${LAPACK_LIBRARIES} ${BLAS_LIBRARIES})
add_executable(loader examples/example_loader.cpp ${algoim_SOURCES})
target_include_directories(loader PRIVATE ${LAPACKE_INCLUDE_DIR})
target_link_libraries(loader PRIVATE ${LAPACKE_LIB} ${LAPACK_LIBRARIES} ${BLAS_LIBRARIES})

519
algoim/organizer/loader.hpp

@ -1,8 +1,8 @@
#pragma once #pragma once
#include "organizer.hpp" #include <sparkstack.hpp>
#include <uvector.hpp> #include <uvector.hpp>
#include "organizer.hpp"
#include "primitive.hpp" #include "primitive.hpp"
#include <sparkstack.hpp>
class Vector3D class Vector3D
{ {
@ -22,37 +22,27 @@ public:
Vector3D operator/(const double scalar) const Vector3D operator/(const double scalar) const
{ {
if (scalar == 0) if (scalar == 0)
{ {
throw std::runtime_error("Division by zero error."); throw std::runtime_error("Division by zero error.");
} }
return Vector3D( return Vector3D(this->m_x / scalar, this->m_y / scalar, this->m_z / scalar);
this->m_x / scalar,
this->m_y / scalar,
this->m_z / scalar
);
} }
Vector3D operator*(const double scalar) const Vector3D operator*(const double scalar) const
{ {
return Vector3D( return Vector3D(this->m_x * scalar, this->m_y * scalar, this->m_z * scalar);
this->m_x * scalar,
this->m_y * scalar,
this->m_z * scalar
);
} }
Vector3D cross(const Vector3D& other) const Vector3D cross(const Vector3D& other) const
{ {
return Vector3D( return Vector3D(this->m_y * other.m_z - this->m_z * other.m_y,
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_z * other.m_x - this->m_x * other.m_z, this->m_x * other.m_y - this->m_y * other.m_x);
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; 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(); this->normalized();
} }
Direction3D cross(const Direction3D& other) const Vector3D cross(const Direction3D& other) const
{ {
return Direction3D( return Vector3D(this->m_y * other.m_z - this->m_z * other.m_y,
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_z * other.m_x - this->m_x * other.m_z, this->m_x * other.m_y - this->m_y * other.m_x);
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; 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() void normalized()
{ {
double length = this->length(); 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."); throw std::runtime_error("Cannot normalize a zero-length vector.");
} }
this->m_x /= length; this->m_x /= length;
this->m_y /= length, this->m_y /= length, this->m_z /= length;
this->m_z /= length;
} }
bool isParallel(const Direction3D& other) bool isParallel(const Direction3D& other) const
{ {
auto cross = this->cross(other); auto cross = this->cross(other);
return std::abs(cross.length()) < 1e-8; return std::abs(cross.length()) < 1e-8;
} }
Direction3D operator- () const Direction3D operator-() const
{ {
return Direction3D( return Direction3D(-this->m_x, -this->m_y, -this->m_z);
-this->m_x,
-this->m_y,
-this->m_z
);
} }
}; };
@ -144,55 +127,37 @@ public:
this->m_y = y; this->m_y = y;
this->m_z = z; this->m_z = z;
} }
Vector3D operator- (const Point3D& other) const Vector3D operator-(const Point3D& other) const
{ {
return Vector3D( return Vector3D(this->m_x - other.m_x, this->m_y - other.m_y, this->m_z - other.m_z);
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( return Point3D(this->m_x - direction.m_x, this->m_y - direction.m_y, this->m_z - direction.m_z);
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( return Point3D(this->m_x - offset.m_x, this->m_y - offset.m_y, this->m_z - offset.m_z);
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( return Point3D(this->m_x + direction.m_x, this->m_y + direction.m_y, this->m_z + direction.m_z);
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( return Point3D(this->m_x + offset.m_x, this->m_y + offset.m_y, this->m_z + offset.m_z);
this->m_x + offset.m_x,
this->m_y + offset.m_y,
this->m_z + offset.m_z
);
} }
double getDistance(const Point3D& other) const 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 Point3D getMiddlePoint(const Point3D& other) const
@ -201,6 +166,8 @@ public:
} }
}; };
typedef unsigned int BodyTag;
class Loader class Loader
{ {
public: public:
@ -212,7 +179,7 @@ public:
Point3D computePolygonCentroid(const std::vector<Point3D>& points) const Point3D computePolygonCentroid(const std::vector<Point3D>& points) const
{ {
double centroidX = 0, centroidY = 0, centroidZ = 0; double centroidX = 0, centroidY = 0, centroidZ = 0;
for (const auto& point : points) for (const auto& point : points)
{ {
centroidX += point.m_x; centroidX += point.m_x;
centroidY += point.m_y; centroidY += point.m_y;
@ -226,7 +193,7 @@ public:
* @brief Create an empty blob tree * @brief Create an empty blob tree
* @return The created empty blob tree * @return The created empty blob tree
*/ */
static algoim::organizer::BlobTree createEmptyBlobTree() algoim::organizer::BlobTree createEmptyBlobTree()
{ {
algoim::organizer::BlobTree tree; algoim::organizer::BlobTree tree;
@ -269,7 +236,8 @@ public:
* @param[in] rep2 The second visible primitive node * @param[in] rep2 The second visible primitive node
* @return The unioned visible primitive * @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(); auto tree = createEmptyBlobTree();
tree.structure[2].nodeOp = 0; tree.structure[2].nodeOp = 0;
@ -280,10 +248,12 @@ public:
algoim::organizer::VisiblePrimitiveRep result; algoim::organizer::VisiblePrimitiveRep result;
result.subBlobTree = tree; 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.tensors.push_back(iter.tensor);
result.aabb.extend(rep.aabb);
} }
return result; return result;
@ -295,7 +265,8 @@ public:
* @param[in] rep2 The second visible primitive node * @param[in] rep2 The second visible primitive node
* @return The intersected visible primitive * @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(); auto tree = createEmptyBlobTree();
tree.structure[2].nodeOp = 1; tree.structure[2].nodeOp = 1;
@ -306,10 +277,12 @@ public:
algoim::organizer::VisiblePrimitiveRep result; algoim::organizer::VisiblePrimitiveRep result;
result.subBlobTree = tree; 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.tensors.push_back(iter.tensor);
result.aabb.extend(rep.aabb);
} }
return result; return result;
@ -321,7 +294,8 @@ public:
* @param[in] rep2 The second visible primitive node * @param[in] rep2 The second visible primitive node
* @return The differenced visible primitive * @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(); auto tree = createEmptyBlobTree();
tree.structure[2].nodeOp = 2; tree.structure[2].nodeOp = 2;
@ -332,29 +306,84 @@ public:
algoim::organizer::VisiblePrimitiveRep result; algoim::organizer::VisiblePrimitiveRep result;
result.subBlobTree = tree; result.subBlobTree = tree;
for (auto& rep : minimalReps) result.aabb = rep1.aabb;
for (auto& iter : minimalReps)
{ {
result.tensors.push_back(rep.tensor); result.tensors.push_back(iter.tensor);
result.aabb.extend(rep.aabb);
} }
return result; 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 * @brief Create a polygonal column without top face and bottom face
* @param[in] points All the bottom point with counter clockwise * @param[in] points All the bottom point with counter clockwise
* @param[in] extusion The stretch direction * @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(); int pointNumber = points.size();
std::vector<algoim::uvector3> vertices; std::vector<algoim::uvector3> vertices;
std::vector<int> indices; std::vector<int> indices;
std::vector<int> indexInclusiveScan; std::vector<int> indexInclusiveScan;
/* All bottom point */ /* All bottom point */
for (int i = 0; i < pointNumber; i++) for (int i = 0; i < pointNumber; i++)
{ {
@ -374,14 +403,14 @@ public:
indices.push_back((i + 1) % pointNumber); indices.push_back((i + 1) % pointNumber);
indices.push_back((i + 1) % pointNumber + pointNumber); indices.push_back((i + 1) % pointNumber + pointNumber);
indices.push_back(i + pointNumber); indices.push_back(i + pointNumber);
indexInclusiveScan.push_back(index);
index += 4; index += 4;
indexInclusiveScan.push_back(index);
} }
algoim::organizer::MeshDesc polygonalColumn(vertices, indices, indexInclusiveScan); algoim::organizer::MeshDesc polygonalColumn(vertices, indices, indexInclusiveScan);
algoim::organizer::VisiblePrimitiveRep result; 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; std::vector<algoim::SparkStack<algoim::real>*> temp;
algoim::algoimSparkAllocHeapVector(temp, result.tensors); algoim::algoimSparkAllocHeapVector(temp, result.tensors);
algoim::organizer::makeMesh(polygonalColumn, result); algoim::organizer::makeMesh(polygonalColumn, result);
@ -400,23 +429,29 @@ public:
* @param[in] radius The radius of the cylinder * @param[in] radius The radius of the cylinder
* @param[in] length The length of the cylinder * @param[in] length The length of the cylinder
* @param[in] alignAxis The align axis 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::CylinderDesc cylinderDesc(origion.getUVector3Data(), radius, length, alignAxis);
algoim::organizer::VisiblePrimitiveRep cylinder; algoim::organizer::VisiblePrimitiveRep cylinder;
cylinder.tensors.resize(3, algoim::tensor3(nullptr, 3)); 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::algoim_spark_alloc(algoim::real, cylinder.tensors);
algoim::organizer::makeCylinder(cylinderDesc, cylinder); 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.tensors[0] = cylinder.tensors[0];
result.aabb = cylinder.aabb; result.aabb = cylinder.aabb;
result.subBlobTree.primitiveNodeIdx.push_back(0); result.subBlobTree.primitiveNodeIdx.push_back(0);
@ -437,8 +472,8 @@ public:
algoim::organizer::VisiblePrimitiveRep halfPlane; algoim::organizer::VisiblePrimitiveRep halfPlane;
halfPlane.tensors.resize(1, algoim::tensor3(nullptr, 3)); halfPlane.tensors.resize(1, algoim::tensor3(nullptr, 3));
std::vector<algoim::SparkStack<algoim::real>*> temp; std::vector<algoim::SparkStack<algoim::real>*> temp;
algoim::algoim_spark_alloc(algoim::real, halfPlane.tensors); algoim::algoimSparkAllocHeapVector(temp, halfPlane.tensors);
algoim::organizer::makeHalfPlane(halfPlaneDesc , halfPlane); algoim::organizer::makeHalfPlane(halfPlaneDesc, halfPlane);
this->m_allPointer.push_back(temp[0]); this->m_allPointer.push_back(temp[0]);
return halfPlane; return halfPlane;
@ -450,9 +485,103 @@ public:
* @param[in] bulges All the bulge on each edge of the base face * @param[in] bulges All the bulge on each edge of the base face
* @param[in] extusion The Stretch direction and length * @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] bulges All the bulge on each edge of the base face
* @param[in] extusion The Stretch direction and length * @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(); int pointNumber = points.size();
assert(pointNumber >= 2); assert(pointNumber >= 2);
if (pointNumber == 2) if (pointNumber == 2)
{ {
addExtrudeWithTwoPoint(points, bulges, extusion); return addExtrudeWithTwoPoint(points, bulges, extusion);
return;
} }
/* Get base polygonal column */ /* Get base polygonal column */
@ -532,7 +660,7 @@ public:
flag = true; flag = true;
} }
} }
/* Determine which axis is aligned */ /* Determine which axis is aligned */
int alignAxis; int alignAxis;
if (normal.isParallel(Direction3D(1, 0, 0))) if (normal.isParallel(Direction3D(1, 0, 0)))
@ -555,26 +683,23 @@ public:
/* Create the cylinder face */ /* Create the cylinder face */
auto cylinder = createCylinderWithoutTopBottom(origion, radius, extusion.length(), alignAxis); auto cylinder = createCylinderWithoutTopBottom(origion, radius, extusion.length(), alignAxis);
/* Perform union and difference operations on the basic prismatic faces */ /* Perform union and difference operations on the basic prismatic faces */
if (flag) if (flag)
{ {
/* Union */ /* Union */
/* cylinder - half plane */ /* cylinder - half plane */
auto halfPlane = createHalfPlane(middlePoint, middleToOrigion); auto halfPlane = createHalfPlane(middlePoint, middleToOrigion);
auto subtraction = this->intersectionNode(cylinder, halfPlane); auto subtraction = this->intersectNode(cylinder, halfPlane);
/* base + (cylinder - column) */ /* base + (cylinder - column) */
base = this->unionNode(base, subtraction); base = this->unionNode(base, subtraction);
} }
else else
{ {
/* difference */ /* difference */
/* base - cylinder */ /* base - cylinder */
base = this->differenceNode(base, cylinder); base = this->differentNode(base, cylinder);
} }
} }
auto halfPlane1 = createHalfPlane(points[0], -normal); auto halfPlane1 = createHalfPlane(points[0], -normal);
@ -583,131 +708,57 @@ public:
base = this->unionNode(base, halfPlane2); base = this->unionNode(base, halfPlane2);
this->m_allVisible.push_back(base); 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: private:
std::vector<algoim::organizer::VisiblePrimitiveRep> m_allVisible; std::vector<algoim::organizer::VisiblePrimitiveRep> m_allVisible;
std::vector<algoim::SparkStack<algoim::real>*> m_allPointer; 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);
}

20
algoim/organizer/minimalPrimitive.hpp

@ -21,7 +21,7 @@ public:
} }
} }
void extend(const AABB& aabb) void extend(const AABB& aabb)
{ {
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
min(i) = std::min(min(i), aabb.min(i)); min(i) = std::min(min(i), aabb.min(i));
@ -35,7 +35,7 @@ public:
real volume() const { return prod(size()); } real volume() const { return prod(size()); }
bool intersect(const AABB& aabb) const bool isIntersect(const AABB& aabb) const
{ {
for (int i = 0; i < 3; ++i) { for (int i = 0; i < 3; ++i) {
if (min(i) > aabb.max(i) || max(i) < aabb.min(i)) { return false; } if (min(i) > aabb.max(i) || max(i) < aabb.min(i)) { return false; }
@ -43,11 +43,27 @@ public:
return true; return true;
} }
void intersect(const AABB& other)
{
for (int i = 0; i < 3; i++){
min(i) = std::max(min(i), other.min(i));
max(i) = std::min(max(i), other.max(i));
}
}
void normalize(const uvector3& scale, const uvector3& boundaryMin) void normalize(const uvector3& scale, const uvector3& boundaryMin)
{ {
min = (min - boundaryMin) / scale; min = (min - boundaryMin) / scale;
max = (max - boundaryMin) / scale; max = (max - boundaryMin) / scale;
} }
void operator+=(const uvector3& offset)
{
for (int i = 0; i < 3; i++){
min(i) += offset(i);
max(i) += offset(i);
}
}
}; };
struct MinimalPrimitiveRep { struct MinimalPrimitiveRep {

4
algoim/organizer/organizer.hpp

@ -394,7 +394,7 @@ void buildOcTreeV0(const Scene& scene,
int aaa = 1; int aaa = 1;
int bbb = 1; int bbb = 1;
} }
if (!minimalRep.aabb.intersect(subNodes[subIdx].aabb)) { if (!minimalRep.aabb.isIntersect(subNodes[subIdx].aabb)) {
// out of the subcell // out of the subcell
organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, false); organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, false);
continue; continue;
@ -418,7 +418,7 @@ void buildOcTreeV0(const Scene& scene,
} }
} }
if (subNodes[1].blobTree.structure[4].inOut != NODE_IN_OUT_UNKNOWN if (subNodes[1].blobTree.structure[4].inOut != NODE_IN_OUT_UNKNOWN
& std::find(subNodes[1].polyIntersectIndices.begin(), subNodes[1].polyIntersectIndices.end(), 3) && std::find(subNodes[1].polyIntersectIndices.begin(), subNodes[1].polyIntersectIndices.end(), 3)
!= subNodes[1].polyIntersectIndices.end()) { != subNodes[1].polyIntersectIndices.end()) {
int aaa = 1; int aaa = 1;
int bbb = 1; int bbb = 1;

223
examples/example_loader.cpp

@ -0,0 +1,223 @@
#include "organizer/loader.hpp"
void loaderTest1()
{
Loader loader;
std::vector<Point3D> points;
std::vector<double> bulges;
Vector3D extusion;
Point3D topPoint, bottomPoint, basePoint;
Direction3D direction;
double offset, radius1, radius2;
/* 体1 */
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};
auto tag1 = loader.addExtrude(points, bulges, extusion);
loader.output(tag1);
/* 体2 */
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};
auto tag2 = loader.addExtrude(points, bulges, extusion);
/* 体3 */
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};
auto tag3 = loader.addExtrude(points, bulges, extusion);
/* 体4 */
topPoint = Point3D{-1.1224183253943920e-06, -3.8391322798592142e-07, 0.0000000000000000};
bottomPoint = Point3D{-1.1224183253943920e-06, -3.8391322798592142e-07, 3300.0000000000000000};
radius1 = 32450.000000000000;
radius2 = 33539.000000000000;
auto tag4 = loader.addCone(topPoint, bottomPoint, radius1, radius2);
/* 体3被切割 */
basePoint = Point3D{-1.1224183253943920e-06, -3.8391322798592142e-07, 0.0000000000000000};
direction = Direction3D{0, 0, 1};
loader.split(tag3, basePoint, direction);
/* 体3和体4布尔差 */
loader.differentNode(tag3, tag4);
/* 体5 */
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};
auto tag5 = loader.addExtrude(points, bulges, extusion);
/* 体5被切割 */
basePoint = Point3D{-1.1224183253943920e-06, -3.8391322798592142e-07, 3300.0000000000000000};
direction = Direction3D{0, 0, 1};
loader.split(tag3, basePoint, direction);
/* 体3和体5布尔并 */
loader.unionNode(tag3, tag5);
/* 体6 */
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};
auto tag6 = loader.addExtrude(points, bulges, extusion);
/* 体6被切割 */
basePoint = Point3D{-1.1224183253943920e-06, -3.8391322798592142e-07, 3300.0000000000000000};
direction = Direction3D{0, 0, 1};
loader.split(tag6, basePoint, direction);
/* 体3和体6布尔并 */
loader.unionNode(tag3, tag6);
/* 体2和体3布尔差 */
loader.differentNode(tag2, tag3);
/* 体7 */
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};
auto tag7 = loader.addExtrude(points, bulges, extusion);
/* 体8 */
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};
auto tag8 = loader.addExtrude(points, bulges, extusion);
/* 体9 */
topPoint = Point3D{-1.1224183253943920e-06, -3.8392403600706615e-07, 0.0000000000000000};
bottomPoint = Point3D{-1.1224183253943920e-06, -3.8392403600706615e-07, 3300.0000000000000000};
radius1 = 32450.000000000000;
radius2 = 33539.000000000000;
auto tag9 = loader.addCone(topPoint, bottomPoint, radius1, radius2);
/* 体8被切割 */
basePoint = Point3D{-1.1224183253943920e-06, -3.8392403600706615e-07, 3300.0000000000000000};
direction = Direction3D{0, 0, 1};
loader.split(tag8, basePoint, direction);
/* 体8和体9布尔差 */
loader.differentNode(tag8, tag9);
/* 体10 */
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};
auto tag10 = loader.addExtrude(points, bulges, extusion);
/* 体10被切割 */
basePoint = Point3D{-1.1224183253943920e-06, -3.8392403600706615e-07, 3300.0000000000000000};
direction = Direction3D{0, 0, 1};
loader.split(tag10, basePoint, direction);
/* 体8和体10布尔并 */
loader.unionNode(tag8, tag10);
/* 体11 */
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};
auto tag11 = loader.addExtrude(points, bulges, extusion);
/* 体11被切割 */
basePoint = Point3D{-1.1224183253943920e-06, -3.8392403600706615e-07, 3300.0000000000000000};
direction = Direction3D{0, 0, 1};
loader.split(tag11, basePoint, direction);
/* 体8和体11布尔并 */
loader.unionNode(tag8, tag11);
/* 体7和体8布尔差 */
loader.differentNode(tag7, tag8);
/* 体2和体7布尔并 */
loader.unionNode(tag2, tag7);
/* 体1和体2布尔并 */
loader.unionNode(tag1, tag2);
/* 体1 Z轴偏移 -3600 */
direction = Direction3D{0, 0, 1};
offset = -3600;
loader.offset(tag1, direction, offset);
}
int main(int argc, char** argv)
{
loaderTest1();
return 0;
}
Loading…
Cancel
Save