diff --git a/CMakeLists.txt b/CMakeLists.txt index bf73fd9..531f6c4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,6 +19,9 @@ endif() aux_source_directory(algoim algoim_SOURCES) add_executable(algoim examples/examples_quad_multipoly.cpp ${algoim_SOURCES}) - target_include_directories(algoim PRIVATE ${LAPACKE_INCLUDE_DIR}) 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}) diff --git a/algoim/organizer/loader.hpp b/algoim/organizer/loader.hpp index 842bb62..b13043e 100644 --- a/algoim/organizer/loader.hpp +++ b/algoim/organizer/loader.hpp @@ -1,8 +1,8 @@ #pragma once -#include "organizer.hpp" +#include #include +#include "organizer.hpp" #include "primitive.hpp" -#include 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& 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 scale = 1; + algoim::uvector 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& points, const Vector3D& extusion) + algoim::organizer::VisiblePrimitiveRep createPolygonalColumnWithoutTopBottom(const std::vector& points, + const Vector3D& extusion) { int pointNumber = points.size(); - + std::vector vertices; std::vector indices; std::vector 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*> 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*> 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*> 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*> 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*> 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& points, const std::vector& bulges, const Vector3D& extusion) + BodyTag addExtrudeWithTwoPoint(const std::vector& points, + const std::vector& 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& points, const std::vector& bulges, const Vector3D& extusion) + BodyTag addExtrude(const std::vector& points, const std::vector& 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*> 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 m_allVisible; std::vector*> m_allPointer; }; - -void test() -{ - Loader l; - - std::vector points; - std::vector 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); -} \ No newline at end of file diff --git a/algoim/organizer/minimalPrimitive.hpp b/algoim/organizer/minimalPrimitive.hpp index 10c4647..18512bc 100644 --- a/algoim/organizer/minimalPrimitive.hpp +++ b/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) { min(i) = std::min(min(i), aabb.min(i)); @@ -35,7 +35,7 @@ public: 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) { if (min(i) > aabb.max(i) || max(i) < aabb.min(i)) { return false; } @@ -43,11 +43,27 @@ public: 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) { min = (min - 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 { diff --git a/algoim/organizer/organizer.hpp b/algoim/organizer/organizer.hpp index 1000543..5056e1a 100644 --- a/algoim/organizer/organizer.hpp +++ b/algoim/organizer/organizer.hpp @@ -394,7 +394,7 @@ void buildOcTreeV0(const Scene& scene, int aaa = 1; int bbb = 1; } - if (!minimalRep.aabb.intersect(subNodes[subIdx].aabb)) { + if (!minimalRep.aabb.isIntersect(subNodes[subIdx].aabb)) { // out of the subcell organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, false); continue; @@ -418,7 +418,7 @@ void buildOcTreeV0(const Scene& scene, } } 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()) { int aaa = 1; int bbb = 1; diff --git a/examples/example_loader.cpp b/examples/example_loader.cpp new file mode 100644 index 0000000..5037127 --- /dev/null +++ b/examples/example_loader.cpp @@ -0,0 +1,223 @@ +#include "organizer/loader.hpp" + +void loaderTest1() +{ + Loader loader; + + std::vector points; + std::vector 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; +}