From 38063bf16a80fbe78fdc4c6651d61b4c38d0f6ca Mon Sep 17 00:00:00 2001 From: wangxiaolong Date: Sun, 13 Oct 2024 16:39:50 +0800 Subject: [PATCH] Add loader --- algoim/organizer/loader.hpp | 1254 +++++++++++++++++++++-------------- examples/example_loader.cpp | 983 +++++++++++++++++++++++++-- wxl/parser.py | 190 +++++- 3 files changed, 1853 insertions(+), 574 deletions(-) diff --git a/algoim/organizer/loader.hpp b/algoim/organizer/loader.hpp index 1934613..7e24715 100644 --- a/algoim/organizer/loader.hpp +++ b/algoim/organizer/loader.hpp @@ -16,11 +16,17 @@ public: this->m_z = z; } - double length() const { return std::sqrt(this->m_x * this->m_x + this->m_y * this->m_y + this->m_z * this->m_z); } + double length() const + { + return std::sqrt(this->m_x * this->m_x + this->m_y * this->m_y + this->m_z * this->m_z); + } Vector3D operator/(const double scalar) const { - if (scalar == 0) { throw std::runtime_error("Division by zero error."); } + if (scalar == 0) + { + throw std::runtime_error("Division by zero error."); + } return Vector3D(this->m_x / scalar, this->m_y / scalar, this->m_z / scalar); } @@ -32,11 +38,15 @@ public: Vector3D cross(const Vector3D& other) const { - return Vector3D(this->m_y * other.m_z - this->m_z * other.m_y, this->m_z * other.m_x - this->m_x * other.m_z, + return Vector3D(this->m_y * other.m_z - this->m_z * other.m_y, + this->m_z * other.m_x - this->m_x * other.m_z, this->m_x * other.m_y - this->m_y * other.m_x); } - double dot(const Vector3D& other) const { return this->m_x * other.m_x + this->m_y * other.m_y + this->m_z * other.m_z; } + double dot(const Vector3D& other) const + { + return this->m_x * other.m_x + this->m_y * other.m_y + this->m_z * other.m_z; + } algoim::uvector3 getUVector3Data() const { @@ -75,16 +85,23 @@ public: Vector3D cross(const Direction3D& other) const { - return Vector3D(this->m_y * other.m_z - this->m_z * other.m_y, this->m_z * other.m_x - this->m_x * other.m_z, + return Vector3D(this->m_y * other.m_z - this->m_z * other.m_y, + this->m_z * other.m_x - this->m_x * other.m_z, this->m_x * other.m_y - this->m_y * other.m_x); } - double dot(const Direction3D& other) const { return this->m_x * other.m_x + this->m_y * other.m_y + this->m_z * other.m_z; } + double dot(const Direction3D& other) const + { + return this->m_x * other.m_x + this->m_y * other.m_y + this->m_z * other.m_z; + } void normalized() { double length = this->length(); - if (std::abs(length) < 1e-8) { throw std::runtime_error("Cannot normalize a zero-length vector."); } + if (std::abs(length) < 1e-8) + { + throw std::runtime_error("Cannot normalize a zero-length vector."); + } this->m_x /= length; this->m_y /= length, this->m_z /= length; @@ -96,7 +113,10 @@ public: return std::abs(cross.length()) < 1e-8; } - Direction3D operator-() const { return Direction3D(-this->m_x, -this->m_y, -this->m_z); } + Direction3D operator-() const + { + return Direction3D(-this->m_x, -this->m_y, -this->m_z); + } }; class Point3D : public Vector3D @@ -138,8 +158,9 @@ public: double getDistance(const Point3D& other) const { - return std::sqrt((other.m_x - this->m_x) * (other.m_x - this->m_x) + (other.m_y - this->m_y) * (other.m_y - this->m_y) - + (other.m_z - this->m_z) * (other.m_z - this->m_z)); + return std::sqrt((other.m_x - this->m_x) * (other.m_x - this->m_x) + + (other.m_y - this->m_y) * (other.m_y - this->m_y) + + (other.m_z - this->m_z) * (other.m_z - this->m_z)); } Point3D getMiddlePoint(const Point3D& other) const @@ -154,528 +175,232 @@ class Loader { public: /** - * @brief Compute the barycentric coordinates of polygon - * @param[in] points All points which define the polygon - * @return The barycentric coordinates - */ - Point3D computePolygonCentroid(const std::vector& points) const - { - double centroidX = 0, centroidY = 0, centroidZ = 0; - for (const auto& point : points) { - centroidX += point.m_x; - centroidY += point.m_y; - centroidZ += point.m_z; - } - int n = points.size(); - return Point3D(centroidX / n, centroidY / n, centroidZ / n); - } - - /** - * @brief Create an empty blob tree - * @return The created empty blob tree - */ - algoim::organizer::BlobTree createEmptyBlobTree() - { - algoim::organizer::BlobTree tree; - - algoim::organizer::Blob blob0; - blob0.isPrimitive = 1; - blob0.nodeOp = 0; - blob0.inOut = 0; - blob0.oneChildInOut = 0; - blob0.isLeft = 1; - blob0.ancestor = 2; - tree.structure.push_back(blob0); - - algoim::organizer::Blob blob1; - blob1.isPrimitive = 1; - blob1.nodeOp = 0; - blob1.inOut = 0; - blob1.oneChildInOut = 0; - blob1.isLeft = 0; - blob1.ancestor = 0; - tree.structure.push_back(blob1); - - algoim::organizer::Blob blob2; - blob2.isPrimitive = 0; - blob2.nodeOp = 3; // no set - blob2.inOut = 0; - blob2.oneChildInOut = 0; - blob2.isLeft = 0; - blob2.ancestor = 0; - tree.structure.push_back(blob2); - - tree.primitiveNodeIdx.push_back(0); - tree.primitiveNodeIdx.push_back(1); - - return tree; - } - - /** - * @brief Union two visible primitive node - * @param[in] rep1 The first visible primitive node - * @param[in] rep2 The second visible primitive node - * @param[in] modify Whether the aabb of primitive node is need to modify - * @return The unioned visible primitive - */ - algoim::organizer::VisiblePrimitiveRep unionNode(const algoim::organizer::VisiblePrimitiveRep& rep1, - const algoim::organizer::VisiblePrimitiveRep& rep2, - const bool modify = true) - { - auto tree = createEmptyBlobTree(); - tree.structure[2].nodeOp = 0; - - const std::vector reps = {rep1, rep2}; - std::vector minimalReps; - algoim::organizer::mergeSubtree2Leaf(tree, minimalReps, reps); - - algoim::organizer::VisiblePrimitiveRep result; - result.subBlobTree = tree; - result.aabb = rep1.aabb; - result.aabb.extend(rep2.aabb); - - if (modify) { - for (auto& iter : minimalReps) { - result.tensors.push_back(iter.tensor); - result.aabbs.push_back(iter.aabb); - } - } else { - for (auto& iter : rep1.tensors) { result.tensors.push_back(iter); } - for (auto& iter : rep2.tensors) { result.tensors.push_back(iter); } - result.aabbs = rep1.aabbs; - result.aabbs.insert(result.aabbs.end(), rep2.aabbs.begin(), rep2.aabbs.end()); - } - - return result; - } - - /** - * @brief Intersect two visible primitive node - * @param[in] rep1 The first visible primitive node - * @param[in] rep2 The second visible primitive node - * @param[in] modify Whether the aabb of primitive node is need to modify - * @return The intersected visible primitive - */ - algoim::organizer::VisiblePrimitiveRep intersectNode(const algoim::organizer::VisiblePrimitiveRep& rep1, - const algoim::organizer::VisiblePrimitiveRep& rep2, - const bool modify = true) - { - auto tree = createEmptyBlobTree(); - tree.structure[2].nodeOp = 1; - - const std::vector reps = {rep1, rep2}; - std::vector minimalReps; - algoim::organizer::mergeSubtree2Leaf(tree, minimalReps, reps); - - algoim::organizer::VisiblePrimitiveRep result; - result.subBlobTree = tree; - result.aabb = rep1.aabb; - result.aabb.intersect(rep2.aabb); - - if (modify) { - for (auto& iter : minimalReps) { - result.tensors.push_back(iter.tensor); - result.aabbs.push_back(iter.aabb); - } - } else { - for (auto& iter : rep1.tensors) { result.tensors.push_back(iter); } - for (auto& iter : rep2.tensors) { result.tensors.push_back(iter); } - result.aabbs = rep1.aabbs; - result.aabbs.insert(result.aabbs.end(), rep2.aabbs.begin(), rep2.aabbs.end()); - } - - return result; - } - - /** - * @brief Difference two visible primitive node - * @param[in] rep1 The first visible primitive node - * @param[in] rep2 The second visible primitive node - * @param[in] modify Whether the aabb of primitive node is need to modify - * @return The differenced visible primitive + * @brief Union two visible primitive node, result will be writen to first noed + * @param[in] body1 The first index of primitive node + * @param[in] body2 The second index of primitive node */ - algoim::organizer::VisiblePrimitiveRep differentNode(const algoim::organizer::VisiblePrimitiveRep& rep1, - const algoim::organizer::VisiblePrimitiveRep& rep2, - const bool modify = true) - { - auto tree = createEmptyBlobTree(); - tree.structure[2].nodeOp = 2; - - const std::vector reps = {rep1, rep2}; - std::vector minimalReps; - algoim::organizer::mergeSubtree2Leaf(tree, minimalReps, reps); - - algoim::organizer::VisiblePrimitiveRep result; - result.subBlobTree = tree; - result.aabb = rep1.aabb; - - if (modify) { - for (auto& iter : minimalReps) { - result.tensors.push_back(iter.tensor); - result.aabbs.push_back(iter.aabb); - } - } else { - for (auto& iter : rep1.tensors) { result.tensors.push_back(iter); } - for (auto& iter : rep2.tensors) { result.tensors.push_back(iter); } - result.aabbs = rep1.aabbs; - result.aabbs.insert(result.aabbs.end(), rep2.aabbs.begin(), rep2.aabbs.end()); - } - - return result; - } - void unionNode(const BodyTag body1, const BodyTag body2) { - auto& rep1 = this->m_allVisible[body1]; - auto& rep2 = this->m_allVisible[body2]; + auto& rep1 = this->m_allVisible[body1]; + auto& rep2 = this->m_allVisible[body2]; algoim::organizer::VisiblePrimitiveRep result; - if (rep1.isEmpty()) { + if (rep1.isEmpty()) + { result = rep2; - } else if (rep2.isEmpty()) { + } + else if (rep2.isEmpty()) + { result = rep1; - } else { + } + else + { result = this->unionNode(rep1, rep2, false); } this->m_allVisible[body1] = result; } + /** + * @brief Intersect two visible primitive node, result will be writen to first noed + * @param[in] body1 The first index of primitive node + * @param[in] body2 The second index of primitive node + */ void intersectNode(const BodyTag body1, const BodyTag body2) { - auto& rep1 = this->m_allVisible[body1]; - auto& rep2 = this->m_allVisible[body2]; + auto& rep1 = this->m_allVisible[body1]; + auto& rep2 = this->m_allVisible[body2]; algoim::organizer::VisiblePrimitiveRep result; - if (rep1.isEmpty() || rep2.isEmpty()) { + if (rep1.isEmpty() || rep2.isEmpty()) + { result = algoim::organizer::VisiblePrimitiveRep{}; - } else { + } + else + { result = this->intersectNode(rep1, rep2, false); } this->m_allVisible[body1] = result; } + /** + * @brief Difference two visible primitive node, result will be writen to first noed + * @param[in] body1 The first index of primitive node + * @param[in] body2 The second index of primitive node + */ void differentNode(const BodyTag body1, const BodyTag body2) { - auto& rep1 = this->m_allVisible[body1]; - auto& rep2 = this->m_allVisible[body2]; + auto& rep1 = this->m_allVisible[body1]; + auto& rep2 = this->m_allVisible[body2]; algoim::organizer::VisiblePrimitiveRep result; - if (rep1.isEmpty() || rep2.isEmpty()) { + if (rep1.isEmpty() || rep2.isEmpty()) + { result = rep1; - } else { + } + else + { result = this->differentNode(rep1, rep2, false); } this->m_allVisible[body1] = result; } + /** + * @brief Offset a body + * @param[in] body The index of primitive node + * @param[in] directrion The offset direction + * @param[in] length The length of offset + */ void offset(const BodyTag body, const Direction3D& directrion, const double length) { algoim::uvector scale = 1; - algoim::uvector bias = -directrion.getUVector3Data(); + algoim::uvector bias = -directrion.getUVector3Data(); auto& rep = this->m_allVisible[body]; - for (auto& iter : rep.tensors) { algoim::organizer::detail::powerTransformation(scale, bias, iter); } + for (auto& iter : rep.tensors) + { + algoim::organizer::detail::powerTransformation(scale, bias, iter); + } rep.aabb += directrion.getUVector3Data(); - for (auto& aabb : rep.aabbs) { aabb += directrion.getUVector3Data(); } + for (auto& aabb : rep.aabbs) + { + aabb += directrion.getUVector3Data(); + } } + /** + * @brief Split a body + * @param[in] body The index of primitive node + * @param[in] basePoint The base point of the split face + * @param[in] normal The normal of the split face + */ void split(const BodyTag body, const Point3D& basePoint, const Direction3D& normal) { - auto& rep = this->m_allVisible[body]; - auto halfPlane = this->createHalfPlane(basePoint, -normal); - auto result = this->intersectNode(rep, halfPlane, false); + auto& rep = this->m_allVisible[body]; + auto halfPlane = this->createHalfPlane(basePoint, -normal); + auto result = this->intersectNode(rep, halfPlane, false); this->m_allVisible[body] = result; } /** - * @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 + * @brief Add a extrude body to csg tree + * @param[in] points All the bottom point which define the base face + * @param[in] bulges All the bulge on each edge of the base face + * @param[in] extusion The Stretch direction and length + * @return The index of the added extrude body */ - algoim::organizer::VisiblePrimitiveRep createPolygonalColumnWithoutTopBottom(const std::vector& points, - 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) + { + return addExtrudeWithTwoPoint(points, bulges, extusion); + } - std::vector vertices; - std::vector indices; - std::vector indexInclusiveScan; + /* Get base polygonal column */ + auto base = createPolygonalColumnWithoutTopBottom(points, extusion); - /* All bottom point */ - for (int i = 0; i < pointNumber; i++) { vertices.push_back(points[i].getUVector3Data()); } - /* All top point */ - for (int i = 0; i < pointNumber; i++) { vertices.push_back((points[i] + extusion).getUVector3Data()); } + auto normal = Direction3D(extusion); + for (int i = 0; i < points.size(); i++) + { + /* Get point and bulge data */ + auto bulge = bulges[i]; + if (std::abs(bulge) < 1e-8) + { + continue; + } - /* Side face */ - int index = 0; - for (int i = 0; i < pointNumber; i++) { - indices.push_back(i); - indices.push_back((i + 1) % pointNumber); - indices.push_back((i + 1) % pointNumber + pointNumber); - indices.push_back(i + pointNumber); + auto& point1 = points[i]; + Point3D point2; + if (i + 1 == points.size()) + { + point2 = points[0]; + } + else + { + point2 = points[i + 1]; + } - index += 4; - indexInclusiveScan.push_back(index); - } + /* Compute the origion and radius */ + auto halfDistance = point1.getDistance(point2) / 2.0; + auto middlePoint = point1.getMiddlePoint(point2); + auto middleToOrigion = normal.cross(Direction3D(point2 - point1)); - algoim::organizer::MeshDesc polygonalColumn(vertices, indices, indexInclusiveScan); - algoim::organizer::VisiblePrimitiveRep result; - result.tensors.resize(pointNumber, algoim::tensor3(nullptr, 3)); - std::vector*> temp; - algoim::algoimSparkAllocHeapVector(temp, result.tensors); - algoim::organizer::makeMesh(polygonalColumn, result); + double sinHalfTheta = 2 * bulge / (1 + bulge * bulge); + double radius = halfDistance / sinHalfTheta; + double scalar = std::sqrt(radius * radius - halfDistance * halfDistance); - for (auto& pointer : temp) { this->m_allPointer.push_back(pointer); } + /* Determine whether to merge or subtract */ + /* The operation is merge if flag is true, otherwise it is subtract */ + bool flag; + /* */ + auto centroidPoint = computePolygonCentroid(points); + auto middleToCentroid = Direction3D(centroidPoint - middlePoint); + /* out */ + if (middleToCentroid.dot(middleToOrigion) > 0.0) + { + /* |bulge| > 1 */ + if (std::abs(bulge) > 1.0 + 1e-8) + { + scalar *= -1; + } - return result; - } + flag = true; + } + /* in */ + else + { + /* |bulge| > 1 */ + if (std::abs(bulge) > 1.0 + 1e-8) + { + scalar *= -1; + } - /** - * @brief Create a cylinder column without top face and bottom face - * @param[in] origion The origion point of bottom circle of the cylinder - * @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 - */ - algoim::organizer::VisiblePrimitiveRep createCylinderWithoutTopBottom(const Point3D& origion, - const double radius, - const double length, - const int alignAxis) - { - algoim::uvector3 ext = 3; - ext(alignAxis) = 1; + flag = false; + } - 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]); + Point3D origion = middlePoint + middleToOrigion * scalar; - algoim::organizer::CylinderDesc cylinderDesc(origion.getUVector3Data(), radius, length, alignAxis); - algoim::organizer::VisiblePrimitiveRep cylinder; - cylinder.tensors.resize(3, algoim::tensor3(nullptr, 3)); - cylinder.tensors[0].ext_ = ext; - algoim::algoim_spark_alloc(algoim::real, cylinder.tensors); - algoim::organizer::makeCylinder(cylinderDesc, cylinder); + /* 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."); + } - result.tensors[0] = cylinder.tensors[0]; - result.aabb = cylinder.aabb; - result.subBlobTree.primitiveNodeIdx.push_back(0); - result.subBlobTree.structure.push_back(algoim::organizer::Blob{1, 0, 0, 0, 0, 0}); + /* Create the cylinder face */ + auto cylinder = createCylinderWithoutTopBottom(origion, radius, extusion.length(), alignAxis); - return result; - } - - /** - * @brief Create a half plane - * @param[in] basePoint The base point of the plane - * @param[in] normal The normal of the plane - * @return The half plane - */ - algoim::organizer::VisiblePrimitiveRep createHalfPlane(const Point3D& basePoint, const Direction3D& normal) - { - auto halfPlaneDesc = algoim::organizer::HalfPlaneDesc(basePoint.getUVector3Data(), normal.getUVector3Data()); - algoim::organizer::VisiblePrimitiveRep halfPlane; - halfPlane.tensors.resize(1, algoim::tensor3(nullptr, 3)); - std::vector*> temp; - algoim::algoimSparkAllocHeapVector(temp, halfPlane.tensors); - algoim::organizer::makeHalfPlane(halfPlaneDesc, halfPlane); - this->m_allPointer.push_back(temp[0]); - halfPlane.aabbs.push_back(halfPlane.aabb); - return halfPlane; - } - - /** - * @brief Add a extrude body to csg tree with only two points - * @param[in] points All the bottom point which define the base face - * @param[in] bulges All the bulge on each edge of the base face - * @param[in] extusion The Stretch direction and length - */ - BodyTag addExtrudeWithTwoPoint(const std::vector& points, - const std::vector& bulges, - const Vector3D& extusion) - { - 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); - // GJJ - if (std::abs(bulge) > 1.0) { scalar *= -1; } - - auto origion = middlePoint + middleToOrigion * scalar; - - /* Create the cylinder face */ - return this->createCylinderWithoutTopBottom(origion, radius, extusion.length(), alignAxis); - }; - - if (std::abs(bulge1) <= 1e-8) { - assert(std::abs(bulge2) > 1e-8); - // GJJ - rep1 = this->createHalfPlane(point1, Direction3D{middleToOrigion2}); - // rep1 = this->createHalfPlane(point1, -Direction3D{middleToOrigion2}); - rep2 = getPrimitive(point2, point1, bulge2); - result = this->intersectNode(rep1, rep2); - } else if (std::abs(bulge2) <= 1e-8) { - assert(std::abs(bulge1) > 1e-8); - // GJJ - rep1 = getPrimitive(point1, point2, bulge1); - rep2 = this->createHalfPlane(point2, Direction3D{middleToOrigion1}); - // 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 == 1, 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 bulge == -1 and bulge == -1, it is a cylinder */ - else if (std::abs(bulge1 + 1.0) < 1e-8 && std::abs(bulge2 + 1.0) < 1e-8) { - 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); - // GJJ - // } else if (bulge1 > 0.0) { - } else if (std::abs(bulge1) > std::abs(bulge2)) { - 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->intersectNode(result, halfPlane1); - result = this->intersectNode(result, halfPlane2); - - this->m_allVisible.push_back(result); - return this->m_allVisible.size() - 1; - } - - /** - * @brief Add a extrude body to csg tree - * @param[in] points All the bottom point which define the base face - * @param[in] bulges All the bulge on each edge of the base face - * @param[in] extusion The Stretch direction and length - */ - BodyTag addExtrude(const std::vector& points, const std::vector& bulges, const Vector3D& extusion) - { - int pointNumber = points.size(); - assert(pointNumber >= 2); - if (pointNumber == 2) { return addExtrudeWithTwoPoint(points, bulges, extusion); } - - /* Get base polygonal column */ - auto base = createPolygonalColumnWithoutTopBottom(points, extusion); - - auto normal = Direction3D(extusion); - for (int i = 0; i < points.size(); i++) { - /* Get point and bulge data */ - auto bulge = bulges[i]; - if (std::abs(bulge) < 1e-8) { continue; } - - auto& point1 = points[i]; - Point3D point2; - if (i + 1 == points.size()) { - point2 = points[0]; - } else { - point2 = points[i + 1]; - } - - /* Compute the origion and radius */ - auto halfDistance = point1.getDistance(point2) / 2.0; - auto middlePoint = point1.getMiddlePoint(point2); - auto middleToOrigion = normal.cross(Direction3D(point2 - point1)); - - double sinHalfTheta = 2 * bulge / (1 + bulge * bulge); - double radius = halfDistance / sinHalfTheta; - double scalar = std::sqrt(radius * radius - halfDistance * halfDistance); - - /* Determine whether to merge or subtract */ - /* The operation is merge if flag is true, otherwise it is subtract */ - bool flag; - /* */ - auto centroidPoint = computePolygonCentroid(points); - auto middleToCentroid = Direction3D(centroidPoint - middlePoint); - /* out */ - if (middleToCentroid.dot(middleToOrigion) > 0.0) { - /* |bulge| > 1 */ - if (std::abs(bulge) > 1.0 + 1e-8) { scalar *= -1; } - - flag = true; - } - /* in */ - else { - /* |bulge| > 1 */ - if (std::abs(bulge) > 1.0 + 1e-8) { scalar *= -1; } - - flag = false; - } - - Point3D origion = middlePoint + middleToOrigion * scalar; - - /* 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."); - } - - /* 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->intersectNode(cylinder, halfPlane); + /* Perform union and difference operations on the basic prismatic faces */ + if (flag) + { + /* Union */ + /* cylinder - half plane */ + auto halfPlane = createHalfPlane(middlePoint, middleToOrigion); + auto subtraction = this->intersectNode(cylinder, halfPlane); /* base + (cylinder - column) */ base = this->unionNode(base, subtraction); - } else { + } + else + { /* difference */ /* base - cylinder */ base = this->differentNode(base, cylinder); @@ -684,16 +409,27 @@ public: auto halfPlane1 = createHalfPlane(points[0], -normal); auto halfPlane2 = createHalfPlane(points[0] + extusion, normal); - base = this->intersectNode(base, halfPlane1); - base = this->intersectNode(base, halfPlane2); + base = this->intersectNode(base, halfPlane1); + base = this->intersectNode(base, halfPlane2); // gjj - for (size_t i = 0; i < base.aabbs.size(); i++) { base.aabbs[i] = base.aabb; } + for (size_t i = 0; i < base.aabbs.size(); i++) + { + base.aabbs[i] = base.aabb; + } this->m_allVisible.push_back(base); return this->m_allVisible.size() - 1; } + /** + * @brief Add a cone body to csg tree + * @param[in] topPoint The top point of the cone + * @param[in] bottomPoint The bottom point of the cone + * @param[in] radius1 The radius of the top point + * @param[in] radius2 The radius of the bottom point + * @return The index of the added cone body + */ BodyTag addCone(const Point3D& topPoint, const Point3D& bottomPoint, const double radius1, const double radius2) { // gjj @@ -721,14 +457,28 @@ public: algoim::algoimSparkAllocHeapVector(temp, cone.tensors); algoim::organizer::makeCone(coneDesc, cone); - for (auto& pointer : temp) { this->m_allPointer.push_back(pointer); } + for (auto& pointer : temp) + { + this->m_allPointer.push_back(pointer); + } - for (int i = 0; i < 3; i++) { cone.aabbs.push_back(cone.aabb); } + for (int i = 0; i < 3; i++) + { + cone.aabbs.push_back(cone.aabb); + } this->m_allVisible.push_back(cone); return this->m_allVisible.size() - 1; } + /** + * @brief Add a box body to csg tree + * @param[in] leftBottomPoint The left bottom point of the box + * @param[in] length The length of the box + * @param[in] width The width of the box + * @param[in] height The height of the box + * @return The index of the added box body + */ BodyTag addBox(const Point3D& leftBottomPoint, const double length, const double width, const double height) { auto size = Vector3D{length, width, height}; @@ -740,47 +490,122 @@ public: algoim::algoimSparkAllocHeapVector(temp, box.tensors); algoim::organizer::makeMesh(boxDesc, box); - for (auto& pointer : temp) { this->m_allPointer.push_back(pointer); } + for (auto& pointer : temp) + { + this->m_allPointer.push_back(pointer); + } - for (int i = 0; i < 6; i++) { box.aabbs.push_back(box.aabb); } + for (int i = 0; i < 6; i++) + { + box.aabbs.push_back(box.aabb); + } this->m_allVisible.push_back(box); return this->m_allVisible.size() - 1; } + /** + * @brief Add a cylinder body to csg tree + * @param[in] bottomOrigion The bottom origion point of the cylinder + * @param[in] radius The radius of the cylinder + * @param[in] offset The direction and length of the cylinder + * @return The index of the added cylinder body + */ BodyTag addCylinder(const Point3D& bottomOrigion, const double radius, const Vector3D& offset) { auto normal = Direction3D{offset}; /* Determine which axis is aligned */ - int alignAxis; - if (normal.isParallel(Direction3D(1, 0, 0))) { + int alignAxis; + if (normal.isParallel(Direction3D(1, 0, 0))) + { alignAxis = 0; - } else if (normal.isParallel(Direction3D(0, 1, 0))) { + } + else if (normal.isParallel(Direction3D(0, 1, 0))) + { alignAxis = 1; - } else if (normal.isParallel(Direction3D(0, 0, 1))) { + } + else if (normal.isParallel(Direction3D(0, 0, 1))) + { alignAxis = 2; - } else { + } + else + { throw std::runtime_error("Non align axis cylinder."); } algoim::uvector3 ext = 3; - ext(alignAxis) = 1; + ext(alignAxis) = 1; algoim::organizer::VisiblePrimitiveRep cylinder; cylinder.tensors.resize(3, algoim::tensor3(nullptr, 3)); cylinder.tensors[0].ext_ = ext; std::vector*> temp; algoim::algoimSparkAllocHeapVector(temp, cylinder.tensors); - algoim::organizer::CylinderDesc cylinderDesc(bottomOrigion.getUVector3Data(), radius, offset.length(), alignAxis); + algoim::organizer::CylinderDesc cylinderDesc( + bottomOrigion.getUVector3Data(), radius, offset.length(), alignAxis); - for (auto& pointer : temp) { this->m_allPointer.push_back(pointer); } + for (auto& pointer : temp) + { + this->m_allPointer.push_back(pointer); + } - for (int i = 0; i < 3; i++) { cylinder.aabbs.push_back(cylinder.aabb); } + for (int i = 0; i < 3; i++) + { + cylinder.aabbs.push_back(cylinder.aabb); + } this->m_allVisible.push_back(cylinder); return this->m_allVisible.size() - 1; } + /** + * @brief Add a cylinder mesh to csg tree + * @param[in] points The points of the mesh + * @param[in] index The indexs of the mesh + * @param[in] faces The faces of the mesh + * @return The index of the added mesh body + */ + BodyTag addMesh(const std::vector points, + const std::vector index, + const std::vector> faces) + { + std::vector vertices; + for (auto& point : points) + { + vertices.push_back(point.getUVector3Data()); + } + + std::vector tempFaces; + for (auto& face : faces) + { + tempFaces.push_back(algoim::uvector2i(face.first, face.second)); + } + + auto meshDesc = algoim::organizer::MeshDesc{vertices, index, tempFaces}; + algoim::organizer::VisiblePrimitiveRep mesh; + mesh.tensors.resize(faces.size(), algoim::tensor3(nullptr, 3)); + std::vector*> temp; + algoim::algoimSparkAllocHeapVector(temp, mesh.tensors); + algoim::organizer::makeMesh(meshDesc, mesh); + + for (auto& pointer : temp) + { + this->m_allPointer.push_back(pointer); + } + + for (size_t i = 0; i < faces.size(); i++) + { + mesh.aabbs.push_back(mesh.aabb); + } + + this->m_allVisible.push_back(mesh); + return this->m_allVisible.size() - 1; + } + + /** + * @brief Add an empty body to csg tree + * @return The index of the added empty body + */ BodyTag addEmpty() { algoim::organizer::VisiblePrimitiveRep empty; @@ -788,14 +613,20 @@ public: return this->m_allVisible.size() - 1; } + /** + * @brief Get the area and volume of the body + * @param[in] body The index of primitive node + * @return [area, volume] The area and volume of the given body + */ std::pair getAreaAndVolume(const BodyTag& tag) { auto& rep = this->m_allVisible[tag]; assert(rep.tensors.size() == rep.aabbs.size()); std::vector minimalReps; - algoim::uvector3 range = rep.aabb.max - rep.aabb.min; - for (size_t i = 0; i < rep.tensors.size(); i++) { + algoim::uvector3 range = rep.aabb.max - rep.aabb.min; + for (size_t i = 0; i < rep.tensors.size(); i++) + { auto& tenser = rep.tensors[i]; algoim::organizer::detail::powerTransformation(range, rep.aabb.min, tenser); @@ -805,24 +636,31 @@ public: minimalReps.push_back(minimalRep); } - auto size = rep.aabb.size(); - algoim::organizer::Scene scene{minimalReps, + auto size = rep.aabb.size(); + algoim::organizer::Scene scene{minimalReps, algoim::organizer::AABB(rep.aabb.min - size * 1e-5, rep.aabb.max + size * 1e-5)}; algoim::organizer::OcTreeNode rootNode(0, 1, rep.subBlobTree); - for (int i = 0; i < minimalReps.size(); ++i) { rootNode.polyIntersectIndices.emplace_back(i); } - int cnt = 1; + for (int i = 0; i < minimalReps.size(); ++i) + { + rootNode.polyIntersectIndices.emplace_back(i); + } + int cnt = 1; std::vector leaves; algoim::organizer::buildOcTreeV0(scene, rootNode, leaves, 1, cnt, 0, -1); std::cout << "octree built over" << std::endl; // basicTask(scene, leaves[14], q); - int i = 0; - int q = 10; + int i = 0; + int q = 10; double volume = 0; - double area = 0; - for (const auto& leaf : leaves) { + double area = 0; + for (const auto& leaf : leaves) + { auto basicRes = algoim::organizer::basicTask(scene, leaf, q); - if (std::isinf(basicRes.volume)) { std::cout << "inf volume when solving leaf: " << i << std::endl; } + if (std::isinf(basicRes.volume)) + { + std::cout << "inf volume when solving leaf: " << i << std::endl; + } volume += basicRes.volume; std::cout << "Solved leaves: " << ++i << "/" << leaves.size() << ", primitive cnt: " << leaf.polyIntersectIndices.size() << ", volume: " << volume << std::endl; @@ -834,9 +672,441 @@ public: return std::make_pair(area, volume); } - void output(const BodyTag& tag) {} +protected: + /** + * @brief Compute the barycentric coordinates of polygon + * @param[in] points All points which define the polygon + * @return The barycentric coordinates + */ + Point3D computePolygonCentroid(const std::vector& points) const + { + double centroidX = 0, centroidY = 0, centroidZ = 0; + for (const auto& point : points) + { + centroidX += point.m_x; + centroidY += point.m_y; + centroidZ += point.m_z; + } + int n = points.size(); + return Point3D(centroidX / n, centroidY / n, centroidZ / n); + } + + /** + * @brief Create an empty blob tree + * @return The created empty blob tree + */ + algoim::organizer::BlobTree createEmptyBlobTree() + { + algoim::organizer::BlobTree tree; + + algoim::organizer::Blob blob0; + blob0.isPrimitive = 1; + blob0.nodeOp = 0; + blob0.inOut = 0; + blob0.oneChildInOut = 0; + blob0.isLeft = 1; + blob0.ancestor = 2; + tree.structure.push_back(blob0); + + algoim::organizer::Blob blob1; + blob1.isPrimitive = 1; + blob1.nodeOp = 0; + blob1.inOut = 0; + blob1.oneChildInOut = 0; + blob1.isLeft = 0; + blob1.ancestor = 0; + tree.structure.push_back(blob1); + + algoim::organizer::Blob blob2; + blob2.isPrimitive = 0; + blob2.nodeOp = 3; // no set + blob2.inOut = 0; + blob2.oneChildInOut = 0; + blob2.isLeft = 0; + blob2.ancestor = 0; + tree.structure.push_back(blob2); + + tree.primitiveNodeIdx.push_back(0); + tree.primitiveNodeIdx.push_back(1); + + return tree; + } + + /** + * @brief Union two visible primitive node + * @param[in] rep1 The first visible primitive node + * @param[in] rep2 The second visible primitive node + * @param[in] modify Whether the aabb of primitive node is need to modify + * @return The unioned visible primitive + */ + algoim::organizer::VisiblePrimitiveRep unionNode(const algoim::organizer::VisiblePrimitiveRep& rep1, + const algoim::organizer::VisiblePrimitiveRep& rep2, + const bool modify = true) + { + auto tree = createEmptyBlobTree(); + tree.structure[2].nodeOp = 0; + + const std::vector reps = {rep1, rep2}; + std::vector minimalReps; + algoim::organizer::mergeSubtree2Leaf(tree, minimalReps, reps); + + algoim::organizer::VisiblePrimitiveRep result; + result.subBlobTree = tree; + result.aabb = rep1.aabb; + result.aabb.extend(rep2.aabb); + + if (modify) + { + for (auto& iter : minimalReps) + { + result.tensors.push_back(iter.tensor); + result.aabbs.push_back(iter.aabb); + } + } + else + { + for (auto& iter : rep1.tensors) + { + result.tensors.push_back(iter); + } + for (auto& iter : rep2.tensors) + { + result.tensors.push_back(iter); + } + result.aabbs = rep1.aabbs; + result.aabbs.insert(result.aabbs.end(), rep2.aabbs.begin(), rep2.aabbs.end()); + } + + return result; + } + + /** + * @brief Intersect two visible primitive node + * @param[in] rep1 The first visible primitive node + * @param[in] rep2 The second visible primitive node + * @param[in] modify Whether the aabb of primitive node is need to modify + * @return The intersected visible primitive + */ + algoim::organizer::VisiblePrimitiveRep intersectNode(const algoim::organizer::VisiblePrimitiveRep& rep1, + const algoim::organizer::VisiblePrimitiveRep& rep2, + const bool modify = true) + { + auto tree = createEmptyBlobTree(); + tree.structure[2].nodeOp = 1; + + const std::vector reps = {rep1, rep2}; + std::vector minimalReps; + algoim::organizer::mergeSubtree2Leaf(tree, minimalReps, reps); + + algoim::organizer::VisiblePrimitiveRep result; + result.subBlobTree = tree; + result.aabb = rep1.aabb; + result.aabb.intersect(rep2.aabb); + + if (modify) + { + for (auto& iter : minimalReps) + { + result.tensors.push_back(iter.tensor); + result.aabbs.push_back(iter.aabb); + } + } + else + { + for (auto& iter : rep1.tensors) + { + result.tensors.push_back(iter); + } + for (auto& iter : rep2.tensors) + { + result.tensors.push_back(iter); + } + result.aabbs = rep1.aabbs; + result.aabbs.insert(result.aabbs.end(), rep2.aabbs.begin(), rep2.aabbs.end()); + } + + return result; + } + + /** + * @brief Difference two visible primitive node + * @param[in] rep1 The first visible primitive node + * @param[in] rep2 The second visible primitive node + * @param[in] modify Whether the aabb of primitive node is need to modify + * @return The differenced visible primitive + */ + algoim::organizer::VisiblePrimitiveRep differentNode(const algoim::organizer::VisiblePrimitiveRep& rep1, + const algoim::organizer::VisiblePrimitiveRep& rep2, + const bool modify = true) + { + auto tree = createEmptyBlobTree(); + tree.structure[2].nodeOp = 2; + + const std::vector reps = {rep1, rep2}; + std::vector minimalReps; + algoim::organizer::mergeSubtree2Leaf(tree, minimalReps, reps); + + algoim::organizer::VisiblePrimitiveRep result; + result.subBlobTree = tree; + result.aabb = rep1.aabb; + + if (modify) + { + for (auto& iter : minimalReps) + { + result.tensors.push_back(iter.tensor); + result.aabbs.push_back(iter.aabb); + } + } + else + { + for (auto& iter : rep1.tensors) + { + result.tensors.push_back(iter); + } + for (auto& iter : rep2.tensors) + { + result.tensors.push_back(iter); + } + result.aabbs = rep1.aabbs; + result.aabbs.insert(result.aabbs.end(), rep2.aabbs.begin(), rep2.aabbs.end()); + } + + return 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 + */ + 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++) + { + vertices.push_back(points[i].getUVector3Data()); + } + /* All top point */ + for (int i = 0; i < pointNumber; i++) + { + vertices.push_back((points[i] + extusion).getUVector3Data()); + } + + /* Side face */ + int index = 0; + for (int i = 0; i < pointNumber; i++) + { + indices.push_back(i); + indices.push_back((i + 1) % pointNumber); + indices.push_back((i + 1) % pointNumber + pointNumber); + indices.push_back(i + pointNumber); + + index += 4; + indexInclusiveScan.push_back(index); + } + + algoim::organizer::MeshDesc polygonalColumn(vertices, indices, indexInclusiveScan); + algoim::organizer::VisiblePrimitiveRep result; + result.tensors.resize(pointNumber, algoim::tensor3(nullptr, 3)); + std::vector*> temp; + algoim::algoimSparkAllocHeapVector(temp, result.tensors); + algoim::organizer::makeMesh(polygonalColumn, result); + + for (auto& pointer : temp) + { + this->m_allPointer.push_back(pointer); + } + + return result; + } + + /** + * @brief Create a cylinder column without top face and bottom face + * @param[in] origion The origion point of bottom circle of the cylinder + * @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 + */ + 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)); + cylinder.tensors[0].ext_ = ext; + algoim::algoim_spark_alloc(algoim::real, cylinder.tensors); + algoim::organizer::makeCylinder(cylinderDesc, cylinder); + + result.tensors[0] = cylinder.tensors[0]; + result.aabb = cylinder.aabb; + result.subBlobTree.primitiveNodeIdx.push_back(0); + result.subBlobTree.structure.push_back(algoim::organizer::Blob{1, 0, 0, 0, 0, 0}); + + return result; + } + + /** + * @brief Create a half plane + * @param[in] basePoint The base point of the plane + * @param[in] normal The normal of the plane + * @return The half plane + */ + algoim::organizer::VisiblePrimitiveRep createHalfPlane(const Point3D& basePoint, const Direction3D& normal) + { + auto halfPlaneDesc = algoim::organizer::HalfPlaneDesc(basePoint.getUVector3Data(), normal.getUVector3Data()); + algoim::organizer::VisiblePrimitiveRep halfPlane; + halfPlane.tensors.resize(1, algoim::tensor3(nullptr, 3)); + std::vector*> temp; + algoim::algoimSparkAllocHeapVector(temp, halfPlane.tensors); + algoim::organizer::makeHalfPlane(halfPlaneDesc, halfPlane); + this->m_allPointer.push_back(temp[0]); + halfPlane.aabbs.push_back(halfPlane.aabb); + return halfPlane; + } + + /** + * @brief Add a extrude body to csg tree with only two points + * @param[in] points All the bottom point which define the base face + * @param[in] bulges All the bulge on each edge of the base face + * @param[in] extusion The Stretch direction and length + * @return The index of the added extrude body + */ + BodyTag addExtrudeWithTwoPoint(const std::vector& points, + const std::vector& bulges, + const Vector3D& extusion) + { + 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); + // GJJ + if (std::abs(bulge) > 1.0) + { + scalar *= -1; + } + + auto origion = middlePoint + middleToOrigion * scalar; + + /* Create the cylinder face */ + return this->createCylinderWithoutTopBottom(origion, radius, extusion.length(), alignAxis); + }; + + if (std::abs(bulge1) <= 1e-8) + { + assert(std::abs(bulge2) > 1e-8); + // GJJ + rep1 = this->createHalfPlane(point1, Direction3D{middleToOrigion2}); + // rep1 = this->createHalfPlane(point1, -Direction3D{middleToOrigion2}); + rep2 = getPrimitive(point2, point1, bulge2); + result = this->intersectNode(rep1, rep2); + } + else if (std::abs(bulge2) <= 1e-8) + { + assert(std::abs(bulge1) > 1e-8); + // GJJ + rep1 = getPrimitive(point1, point2, bulge1); + rep2 = this->createHalfPlane(point2, Direction3D{middleToOrigion1}); + // 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 == 1, 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 bulge == -1 and bulge == -1, it is a cylinder */ + else if (std::abs(bulge1 + 1.0) < 1e-8 && std::abs(bulge2 + 1.0) < 1e-8) + { + 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); + // GJJ + // } else if (bulge1 > 0.0) { + } + else if (std::abs(bulge1) > std::abs(bulge2)) + { + 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->intersectNode(result, halfPlane1); + result = this->intersectNode(result, halfPlane2); + + this->m_allVisible.push_back(result); + return this->m_allVisible.size() - 1; + } private: std::vector m_allVisible; - std::vector*> m_allPointer; + std::vector*> m_allPointer; }; diff --git a/examples/example_loader.cpp b/examples/example_loader.cpp index 4f3e9dd..4e2e851 100644 --- a/examples/example_loader.cpp +++ b/examples/example_loader.cpp @@ -5,12 +5,12 @@ void loaderTest1() Loader loader; std::vector points; - std::vector bulges; - Vector3D extusion; - Point3D topPoint, bottomPoint, basePoint, leftBottomPoint; - Direction3D direction; + std::vector bulges; + Vector3D extusion; + Point3D topPoint, bottomPoint, basePoint, leftBottomPoint; + Direction3D direction; - double offset, radius1, radius2, length, width, height, areaDifference, volumeDifference; + double offset, radius, radius1, radius2, length, width, height, areaDifference, volumeDifference; std::pair before, after; @@ -21,7 +21,7 @@ void loaderTest1() 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}; + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 3300.0000000000000}; auto tag1 = loader.addExtrude(points, bulges, extusion); loader.getAreaAndVolume(tag1); @@ -37,7 +37,7 @@ void loaderTest1() bulges.push_back(0.0000000000000000); bulges.push_back(-0.99999999999999989); bulges.push_back(0.0000000000000000); - extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 3300.0000000000000}; + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 3300.0000000000000}; auto tag2 = loader.addExtrude(points, bulges, extusion); loader.getAreaAndVolume(tag2); @@ -53,17 +53,17 @@ void loaderTest1() bulges.push_back(0.0000000000000000); bulges.push_back(-0.99999999999999989); bulges.push_back(0.0000000000000000); - extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 3300.0000000000000}; + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 3300.0000000000000}; auto tag3 = loader.addExtrude(points, bulges, extusion); loader.getAreaAndVolume(tag3); /* 体4 */ - topPoint = Point3D{-1.1224183253943920e-06, -3.8391322798592142e-07, 0.0000000000000000}; + 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); + radius1 = 32450.000000000000; + radius2 = 33539.000000000000; + auto tag4 = loader.addCone(topPoint, bottomPoint, radius1, radius2); loader.getAreaAndVolume(tag4); @@ -90,7 +90,7 @@ void loaderTest1() bulges.push_back(0.0000000000000000); bulges.push_back(-0.99999999999999989); bulges.push_back(0.0000000000000000); - extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 3300.0000000000000}; + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 3300.0000000000000}; auto tag5 = loader.addExtrude(points, bulges, extusion); /* 体5被切割 */ @@ -112,7 +112,7 @@ void loaderTest1() bulges.push_back(0.0000000000000000); bulges.push_back(-0.99999999999999989); bulges.push_back(0.0000000000000000); - extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 3300.0000000000000}; + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 3300.0000000000000}; auto tag6 = loader.addExtrude(points, bulges, extusion); /* 体6被切割 */ @@ -137,7 +137,7 @@ void loaderTest1() bulges.push_back(0.0000000000000000); bulges.push_back(-0.99999999999999989); bulges.push_back(0.0000000000000000); - extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 3300.0000000000000}; + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 3300.0000000000000}; auto tag7 = loader.addExtrude(points, bulges, extusion); /* 体8 */ @@ -151,15 +151,15 @@ void loaderTest1() bulges.push_back(0.0000000000000000); bulges.push_back(-0.99999999999999989); bulges.push_back(0.0000000000000000); - extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 3300.0000000000000}; + 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}; + 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); + 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}; @@ -180,7 +180,7 @@ void loaderTest1() bulges.push_back(0.0000000000000000); bulges.push_back(-0.99999999999999989); bulges.push_back(0.0000000000000000); - extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 3300.0000000000000}; + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 3300.0000000000000}; auto tag10 = loader.addExtrude(points, bulges, extusion); /* 体10被切割 */ @@ -202,7 +202,7 @@ void loaderTest1() bulges.push_back(0.0000000000000000); bulges.push_back(-0.99999999999999989); bulges.push_back(0.0000000000000000); - extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 3300.0000000000000}; + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 3300.0000000000000}; auto tag11 = loader.addExtrude(points, bulges, extusion); /* 体11被切割 */ @@ -224,7 +224,7 @@ void loaderTest1() /* 体1 Z轴偏移 -3600 */ direction = Direction3D{0, 0, 1}; - offset = -3600; + offset = -3600; loader.offset(tag1, direction, offset); /* 新的体11 */ @@ -234,7 +234,7 @@ void loaderTest1() points.push_back(Point3D{32049.999998877582, -3.8387224776670337e-07, 0.0000000000000000}); bulges.push_back(0.99999999999999989); bulges.push_back(0.99999999999999989); - extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; auto newTag11 = loader.addExtrude(points, bulges, extusion); /* 体0 */ @@ -244,7 +244,7 @@ void loaderTest1() points.push_back(Point3D{11801.337366082498, 5999.2409883221590, 0.0000000000000000}); bulges.push_back(0.99999999999999989); bulges.push_back(0.99999999999999989); - extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; auto tag0 = loader.addExtrude(points, bulges, extusion); /* 新的体11和体0布尔差 */ @@ -252,7 +252,7 @@ void loaderTest1() /* 新的体11 Z轴偏移 -3500 */ direction = Direction3D{0, 0, 1}; - offset = -3500; + offset = -3500; loader.offset(newTag11, direction, offset); /* 体1和新的体11判交 */ @@ -265,12 +265,12 @@ void loaderTest1() points.push_back(Point3D{-673.66711640879771, 5999.2409883221790, 0.0000000000000000}); bulges.push_back(0.99999999999999989); bulges.push_back(0.99999999999999989); - extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; auto tag12 = loader.addExtrude(points, bulges, extusion); /* 体12 Z轴偏移 -3500 */ direction = Direction3D{0, 0, 1}; - offset = -3500; + offset = -3500; loader.offset(tag12, direction, offset); /* 体1和体12判交 */ @@ -286,7 +286,7 @@ void loaderTest1() points.push_back(Point3D{2401.3334598319489, 5999.2409883221790, 0.0000000000000000}); bulges.push_back(0.99999999999999989); bulges.push_back(0.99999999999999989); - extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; auto tag13 = loader.addExtrude(points, bulges, extusion); /* 体14 */ @@ -296,7 +296,7 @@ void loaderTest1() points.push_back(Point3D{676.33403607269543, 5999.2409883221790, 0.0000000000000000}); bulges.push_back(-0.99999999999999989); bulges.push_back(-0.99999999999999989); - extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; auto tag14 = loader.addExtrude(points, bulges, extusion); /* 体13和体14布尔差 */ @@ -304,7 +304,7 @@ void loaderTest1() /* 体13 Z轴偏移-3500 */ direction = Direction3D{0, 0, 1}; - offset = -3500; + offset = -3500; loader.offset(tag13, direction, offset); /* 体1和体13判交 */ @@ -321,17 +321,18 @@ void loaderTest1() after = loader.getAreaAndVolume(tag1); /* 获取 体1 布尔前后的 体积差 和 面积差 */ - areaDifference = after.first - before.first; + areaDifference = after.first - before.first; volumeDifference = after.second - before.second; + std::cout << areaDifference << ", " << volumeDifference << std::endl; /* 定义空体 扣减体1 */ auto subTag1 = loader.addEmpty(); - auto cycle = [&loader, subTag1](const Point3D& point) { + auto cycle = [&loader, subTag1](const Point3D& point) { std::vector points; - std::vector bulges; - Vector3D extusion; - Direction3D direction; - double offset; + std::vector bulges; + Vector3D extusion; + Direction3D direction; + double offset; /* 循环体1 */ points.clear(); @@ -344,18 +345,18 @@ void loaderTest1() bulges.push_back(0.0000000000000000); bulges.push_back(0.0000000000000000); bulges.push_back(0.0000000000000000); - extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; auto cycleTag1 = loader.addExtrude(points, bulges, extusion); /* 循环体1 偏移+ 传入的X,Y,Z坐标值 */ loader.offset(cycleTag1, Direction3D{point}, point.length()); /* 循环体2 */ - auto leftBottomPoint = Point3D{point.m_x - 1000, point.m_y - 1000, point.m_z + 0.0000000000005}; - double length = 2000.0000000000036; - double width = 2000.0000000000036; - double height = 600; - auto cycleTag2 = loader.addBox(leftBottomPoint, length, width, height); + auto leftBottomPoint = Point3D{point.m_x - 1000, point.m_y - 1000, point.m_z + 0.0000000000005}; + double length = 2000.0000000000036; + double width = 2000.0000000000036; + double height = 600; + auto cycleTag2 = loader.addBox(leftBottomPoint, length, width, height); /* 循环体3 */ points.clear(); @@ -364,12 +365,12 @@ void loaderTest1() points.push_back(Point3D{32049.999998877582, -3.8387224776670337e-07, 0.0000000000000000}); bulges.push_back(0.99999999999999989); bulges.push_back(0.99999999999999989); - extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; auto cycleTag3 = loader.addExtrude(points, bulges, extusion); /* 循环体3 Z轴偏移 -2900 */ direction = Direction3D{0, 0, 1}; - offset = -2900; + offset = -2900; loader.offset(cycleTag3, direction, offset); /* 循环体3和体2布尔交 */ @@ -432,22 +433,34 @@ void loaderTest1() points.push_back(Point3D{23121.637452736089, 11781.092611367474, -2900.0000000000000}); points.push_back(Point3D{11781.053468361089, -23121.619302695028, -2900.0000000000000}); points.push_back(Point3D{-23121.583250388911, 11781.089681679974, -2900.0000000000000}); - for (auto& point : points) { cycle(point); } + for (auto& point : points) + { + cycle(point); + } before = loader.getAreaAndVolume(tag1); - /* 体1和扣减体1布尔差 */ loader.differentNode(tag1, subTag1); - after = loader.getAreaAndVolume(tag1); /* 获取 体1 布尔前后的 体积差 和 面积差 */ - areaDifference = after.first - before.first; + areaDifference = after.first - before.first; volumeDifference = after.second - before.second; + std::cout << areaDifference << ", " << volumeDifference << std::endl; /* 体15:Ent1.bool */ + bottomPoint = Point3D{0.0000, 0.0000, -3600.0000}; + radius = 32150.0; + direction = Direction3D{0, 0, 100}; + auto tag15 = loader.addCylinder(bottomPoint, radius, direction); + bottomPoint = Point3D{1.3330, 5999.2412, -3600.0000}; + radius = 11700.43125; + direction = Direction3D{0, 0, 100}; + auto tag15_1 = loader.addCylinder(bottomPoint, radius, direction); + loader.differentNode(tag15, tag15_1); /* 体1和体15布尔差 */ + loader.differentNode(tag1, tag15); /* 体16 */ points.clear(); @@ -456,23 +469,887 @@ void loaderTest1() points.push_back(Point3D{2501.2960250298465, 5999.2409883221790, -3500.0000000000000}); bulges.push_back(0.99999999999999989); bulges.push_back(0.99999999999999989); - extusion = Vector3D{-0.0000000000000000, -0.0000000000000000, -100.00000000000000}; + extusion = Vector3D{-0.0000000000000000, -0.0000000000000000, -100.00000000000000}; auto tag16 = loader.addExtrude(points, bulges, extusion); before = loader.getAreaAndVolume(tag1); - /* 体1和体16布尔差 */ loader.differentNode(tag1, tag16); + after = loader.getAreaAndVolume(tag1); + + /* 获取 体1 布尔前后的 体积差 和 面积差 */ + areaDifference = after.first - before.first; + volumeDifference = after.second - before.second; + std::cout << areaDifference << ", " << volumeDifference << std::endl; +} + +void loaderTest2() +{ + Loader loader; + + std::vector points; + std::vector bulges; + Vector3D extusion; + Point3D topPoint, bottomPoint, basePoint, leftBottomPoint; + Direction3D direction; + + double offset, radius, radius1, radius2, length, width, height, areaDifference, volumeDifference; + + std::pair before, after; + + /* 体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); + + /* 体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被切割 */ + direction = Direction3D{0, 0, 1}; + basePoint = Point3D{-1.1224183253943920e-06, -3.8391322798592142e-07, 0.0000000000000000}; + 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被切割 */ + direction = Direction3D{0, 0, 1}; + basePoint = Point3D{-1.1224183253943920e-06, -3.8391322798592142e-07, 3300.0000000000000000}; + loader.split(tag5, 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被切割 */ + direction = Direction3D{0, 0, 1}; + basePoint = Point3D{-1.1224183253943920e-06, -3.8391322798592142e-07, 3300.0000000000000000}; + 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被切割 */ + direction = Direction3D{0, 0, 1}; + basePoint = Point3D{-1.1224183253943920e-06, -3.8392403600706615e-07, 3300.0000000000000000}; + 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被切割 */ + direction = Direction3D{0, 0, 1}; + basePoint = Point3D{-1.1224183253943920e-06, -3.8392403600706615e-07, 3300.0000000000000000}; + 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被切割 */ + direction = Direction3D{0, 0, 1}; + basePoint = Point3D{-1.1224183253943920e-06, -3.8392403600706615e-07, 3300.0000000000000000}; + 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); + + /* 体111 */ + points.clear(); + bulges.clear(); + points.push_back(Point3D{-32050.000001122418, -3.8396319723688066e-07, 0.0000000000000000}); + points.push_back(Point3D{32049.999998877582, -3.8387224776670337e-07, 0.0000000000000000}); + bulges.push_back(0.99999999999999989); + bulges.push_back(0.99999999999999989); + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; + auto tag111 = loader.addExtrude(points, bulges, extusion); + + /* 体0 */ + points.clear(); + bulges.clear(); + points.push_back(Point3D{-11798.670446418590, 5999.2409883221799, 0.0000000000000000}); + points.push_back(Point3D{11801.337366082498, 5999.2409883221590, 0.0000000000000000}); + bulges.push_back(0.99999999999999989); + bulges.push_back(0.99999999999999989); + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; + auto tag0 = loader.addExtrude(points, bulges, extusion); + + /* 体111和体0布尔差 */ + loader.differentNode(tag111, tag0); + + /* 体111 Z轴偏移 -3500 */ + direction = Direction3D{0, 0, 1}; + offset = -3500; + loader.offset(tag111, direction, offset); + + /* 体1和体111判交 */ + /* TODO */ + + /* 体12 */ + points.clear(); + bulges.clear(); + points.push_back(Point3D{676.33403607269543, 5999.2409883221790, 0.0000000000000000}); + points.push_back(Point3D{-673.66711640879771, 5999.2409883221790, 0.0000000000000000}); + bulges.push_back(0.99999999999999989); + bulges.push_back(0.99999999999999989); + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; + auto tag12 = loader.addExtrude(points, bulges, extusion); + + /* 体12 Z轴偏移 -3500 */ + direction = Direction3D{0, 0, 1}; + offset = -3500; + loader.offset(tag12, direction, offset); + + /* 体1和体12判交 */ + /* TODO */ + + /* 体111和体12布尔并 */ + loader.unionNode(tag111, tag12); + /* 体13 */ + points.clear(); + bulges.clear(); + points.push_back(Point3D{-2398.6665401680511, 5999.2409883221771, 0.0000000000000000}); + points.push_back(Point3D{2401.3334598319489, 5999.2409883221790, 0.0000000000000000}); + bulges.push_back(0.99999999999999989); + bulges.push_back(0.99999999999999989); + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; + auto tag13 = loader.addExtrude(points, bulges, extusion); + + /* 体14 */ + points.clear(); + bulges.clear(); + points.push_back(Point3D{-673.66711640879771, 5999.2409883221790, 0.0000000000000000}); + points.push_back(Point3D{676.33403607269543, 5999.2409883221790, 0.0000000000000000}); + bulges.push_back(-0.99999999999999989); + bulges.push_back(-0.99999999999999989); + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; + auto tag14 = loader.addExtrude(points, bulges, extusion); + + /* 体13和体14布尔差 */ + loader.differentNode(tag13, tag14); + + /* 体13 Z轴偏移 -3500 */ + direction = Direction3D{0, 0, 1}; + offset = -3500; + loader.offset(tag13, direction, offset); + + /* 体1和体13判交 */ + /* TODO */ + + /* 体111和体13布尔并 */ + loader.unionNode(tag111, tag13); + + before = loader.getAreaAndVolume(tag1); + /* 体1和体111布尔差 */ + loader.differentNode(tag1, tag111); + after = loader.getAreaAndVolume(tag1); + + /* 获取体1 布尔前后的体积差和面积差 */ + areaDifference = after.first - before.first; + volumeDifference = after.second - before.second; + std::cout << areaDifference << ", " << volumeDifference << std::endl; + + /* 定义空体 扣减体1 */ + auto subTag1 = loader.addEmpty(); + auto cycle = [&loader, subTag1](const Point3D& point) { + std::vector points; + std::vector bulges; + Vector3D extusion; + Direction3D direction; + double offset; + + /* 循环体1 */ + points.clear(); + bulges.clear(); + points.push_back(Point3D{-1000.0000000000000, 1000.0000000000001, 0.0000000000000000}); + points.push_back(Point3D{-1000.0000000000000, -1000.0000000000000, 0.0000000000000000}); + points.push_back(Point3D{1000.0000000000000, -1000.0000000000000, 0.0000000000000000}); + points.push_back(Point3D{1000.0000000000000, 1000.0000000000000, 0.0000000000000000}); + bulges.push_back(0.0000000000000000); + bulges.push_back(0.0000000000000000); + bulges.push_back(0.0000000000000000); + bulges.push_back(0.0000000000000000); + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; + auto cycleTag1 = loader.addExtrude(points, bulges, extusion); + + /* 循环体1 偏移+ 传入的X,Y,Z坐标值 */ + loader.offset(cycleTag1, Direction3D{point}, point.length()); + + /* 循环体2 */ + auto leftBottomPoint = Point3D{point.m_x - 1000, point.m_y - 1000, point.m_z + 0.0000000000005}; + double length = 2000.0000000000036; + double width = 2000.0000000000036; + double height = 600; + auto cycleTag2 = loader.addBox(leftBottomPoint, length, width, height); + + /* 循环体3 */ + points.clear(); + bulges.clear(); + points.push_back(Point3D{-32050.000001122418, -3.8396319723688066e-07, 0.0000000000000000}); + points.push_back(Point3D{32049.999998877582, -3.8387224776670337e-07, 0.0000000000000000}); + bulges.push_back(0.99999999999999989); + bulges.push_back(0.99999999999999989); + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 600.0000000000000}; + auto cycleTag3 = loader.addExtrude(points, bulges, extusion); + + /* 循环体3 Z轴偏移 -2900 */ + direction = Direction3D{0, 0, 1}; + offset = -2900; + loader.offset(cycleTag3, direction, offset); + + /* 循环体3和体2布尔交 */ + loader.intersectNode(cycleTag3, cycleTag2); + + /* 循环体1和体3布尔交 */ + loader.intersectNode(cycleTag1, cycleTag3); + + /* 循环体1和体1判交 */ + /* TODO */ + + /* 扣减体1和循环体1布尔并 */ + loader.unionNode(subTag1, cycleTag1); + }; + + points.clear(); + points.push_back(Point3D{-21595.036456438422, -21609.173181957169, -2900.0000000000000}); + points.push_back(Point3D{-13505.711180076411, -13505.717935507526, -2900.0000000000000}); + points.push_back(Point3D{-2987.8729842756293, -18864.829751913778, -2900.0000000000000}); + points.push_back(Point3D{2987.9196792985895, -18864.830728476278, -2900.0000000000000}); + points.push_back(Point3D{13505.770265236089, -13505.722818320026, -2900.0000000000000}); + points.push_back(Point3D{17018.254640236089, -8671.2047519137759, -2900.0000000000000}); + points.push_back(Point3D{27220.281983986089, -13869.397623007526, -2900.0000000000000}); + points.push_back(Point3D{21602.139405861089, -21602.103677695028, -2900.0000000000000}); + points.push_back(Point3D{30173.926515236089, -4778.9669589450259, -2900.0000000000000}); + points.push_back(Point3D{18864.887452736089, -2987.8275546481514, -2900.0000000000000}); + points.push_back(Point3D{-18864.815672263911, -2987.8811435153389, -2900.0000000000000}); + points.push_back(Point3D{-30173.856687888911, -4779.0570468356509, -2900.0000000000000}); + points.push_back(Point3D{-13869.422117576411, -27220.218912070028, -2900.0000000000000}); + points.push_back(Point3D{-11781.052000388911, -23121.591958945028, -2900.0000000000000}); + points.push_back(Point3D{-8671.2131332014105, -17018.193521445028, -2900.0000000000000}); + points.push_back(Point3D{-27220.229734763911, -13869.391763632526, -2900.0000000000000}); + points.push_back(Point3D{-17018.194578513911, -8671.1974276950259, -2900.0000000000000}); + points.push_back(Point3D{-30173.856687888911, 4779.0965176174741, -2900.0000000000000}); + points.push_back(Point3D{-25630.485594138911, 4059.4959316799741, -2900.0000000000000}); + points.push_back(Point3D{-18864.815672263911, 2987.9134121487236, -2900.0000000000000}); + points.push_back(Point3D{-15863.798094138911, 8083.0535488674741, -2900.0000000000000}); + points.push_back(Point3D{-27220.216062888911, 13869.449056679974, -2900.0000000000000}); + points.push_back(Point3D{-21602.091062888911, 21602.130697304972, -2900.0000000000000}); + points.push_back(Point3D{-18349.393797263911, 18349.437337929972, -2900.0000000000000}); + points.push_back(Point3D{-13908.684812888911, 13908.728353554974, -2900.0000000000000}); + points.push_back(Point3D{-9584.8552230451605, 18811.339681679972, -2900.0000000000000}); + points.push_back(Point3D{-13869.425047263911, 27220.249837929972, -2900.0000000000000}); + points.push_back(Point3D{-4779.0493148420355, 30173.900228554972, -2900.0000000000000}); + points.push_back(Point3D{4779.0900894548395, 30173.904134804972, -2900.0000000000000}); + points.push_back(Point3D{13869.430421486089, 27220.275228554972, -2900.0000000000000}); + points.push_back(Point3D{9584.8806167985895, 18811.363119179972, -2900.0000000000000}); + points.push_back(Point3D{13908.739015236089, 13908.728353554974, -2900.0000000000000}); + points.push_back(Point3D{18349.453858986089, 18349.433431679972, -2900.0000000000000}); + points.push_back(Point3D{21602.147218361089, 21602.130697304972, -2900.0000000000000}); + points.push_back(Point3D{27220.268312111089, 13869.454916054974, -2900.0000000000000}); + points.push_back(Point3D{15863.852296486089, 8083.0574551174741, -2900.0000000000000}); + points.push_back(Point3D{18864.879640236089, 2987.9153652737236, -2900.0000000000000}); + points.push_back(Point3D{25630.543702736089, 4059.4900723049741, -2900.0000000000000}); + points.push_back(Point3D{30173.912843361089, 4779.0896816799741, -2900.0000000000000}); + points.push_back(Point3D{13869.432374611089, -27220.242349570028, -2900.0000000000000}); + points.push_back(Point3D{-4776.1108367703273, -30098.869302695028, -2900.0000000000000}); + points.push_back(Point3D{4779.0915542985895, -30098.869302695028, -2900.0000000000000}); + points.push_back(Point3D{-23121.594969138911, -11781.033365195026, -2900.0000000000000}); + points.push_back(Point3D{23121.637452736089, 11781.092611367474, -2900.0000000000000}); + points.push_back(Point3D{11781.053468361089, -23121.619302695028, -2900.0000000000000}); + points.push_back(Point3D{-23121.583250388911, 11781.089681679974, -2900.0000000000000}); + for (auto& point : points) + { + cycle(point); + } + + before = loader.getAreaAndVolume(tag1); + /* 体1和扣减体1布尔差 */ + loader.differentNode(tag1, subTag1); after = loader.getAreaAndVolume(tag1); /* 获取 体1 布尔前后的 体积差 和 面积差 */ - areaDifference = after.first - before.first; + areaDifference = after.first - before.first; + volumeDifference = after.second - before.second; + std::cout << areaDifference << ", " << volumeDifference << std::endl; + + /* 体15:Ent1.bool */ + bottomPoint = Point3D{0.0000, 0.0000, -3600.0000}; + radius = 32150.0; + direction = Direction3D{0, 0, 100}; + auto tag15 = loader.addCylinder(bottomPoint, radius, direction); + bottomPoint = Point3D{1.3330, 5999.2412, -3600.0000}; + radius = 11700.43125; + direction = Direction3D{0, 0, 100}; + auto tag15_1 = loader.addCylinder(bottomPoint, radius, direction); + loader.differentNode(tag15, tag15_1); + + /* 体1和体15布尔差 */ + loader.differentNode(tag1, tag15); + + /* 体16 */ + points.clear(); + bulges.clear(); + points.push_back(Point3D{-2503.6291053659488, 5999.2409883221790, -3500.0000000000000}); + points.push_back(Point3D{2501.2960250298465, 5999.2409883221790, -3500.0000000000000}); + bulges.push_back(0.99999999999999989); + bulges.push_back(0.99999999999999989); + extusion = Vector3D{-0.0000000000000000, -0.0000000000000000, -100.00000000000000}; + auto tag16 = loader.addExtrude(points, bulges, extusion); + + /* 体1和体16布尔差 */ + loader.differentNode(tag1, tag16); + + /* 体17 */ + points.clear(); + bulges.clear(); + points.push_back(Point3D{2079.8334638622341, 5999.2409883221844, 0.0000000000000000}); + points.push_back(Point3D{-2070.1665441983364, 5999.2409883221844, 0.0000000000000000}); + points.push_back(Point3D{-1320.1665441983364, 5999.2409883221844, 0.0000000000000000}); + points.push_back(Point3D{1329.8334638622341, 5999.2409883221844, 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, 2750.0000000000000}; + auto tag17 = loader.addExtrude(points, bulges, extusion); + + /* 体17 Z轴偏移 -2900 */ + direction = Direction3D{0, 0, 1}; + offset = -2900; + loader.offset(tag17, direction, offset); + + /* 体1和体17布尔差 */ + loader.differentNode(tag1, tag17); + + /* 体18 */ + points.clear(); + bulges.clear(); + points.push_back(Point3D{-2070.1665441983364, 5999.2409883221844, 0.0000000000000000}); + points.push_back(Point3D{2079.8334638622341, 5999.2409883221844, 0.0000000000000000}); + points.push_back(Point3D{1329.8334638622341, 5999.2409883221844, 0.0000000000000000}); + points.push_back(Point3D{-1320.1665441983364, 5999.2409883221844, 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, 2750.0000000000000}; + auto tag18 = loader.addExtrude(points, bulges, extusion); + + /* 体18 Z轴偏移 -2900 */ + direction = Direction3D{0, 0, 1}; + offset = -2900; + loader.offset(tag18, direction, offset); + + /* 体1和体18布尔差 */ + loader.differentNode(tag1, tag18); + + /* 体19 */ + points.clear(); + bulges.clear(); + points.push_back(Point3D{8760.4644464528919, -16861.795338417785, 0.0000000000000000}); + points.push_back(Point3D{5893.9646280986062, -18064.309214597473, 0.0000000000000000}); + points.push_back(Point3D{6248.1524494726591, -18208.769763083357, 0.0000000000000000}); + points.push_back(Point3D{8651.1159137951836, -17197.859075721935, 0.0000000000000000}); + bulges.push_back(-0.039803147455118697); + bulges.push_back(0.0000000000000000); + bulges.push_back(0.032943018176267741); + bulges.push_back(0.0000000000000000); + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 2850.0000000000000}; + auto tag19 = loader.addExtrude(points, bulges, extusion); + + /* 体19 Z轴偏移 -2900 */ + direction = Direction3D{0, 0, 1}; + offset = -2900; + loader.offset(tag19, direction, offset); + + /* 体1和体19布尔差 */ + loader.differentNode(tag1, tag19); + + /* 体20 */ + points.clear(); + bulges.clear(); + points.push_back(Point3D{8472.1973651856952, -23124.378331468590, 0.0000000000000000}); + points.push_back(Point3D{11234.316117012168, -21717.002618593218, 0.0000000000000000}); + points.push_back(Point3D{10898.067054009927, -21607.748991111552, 0.0000000000000000}); + points.push_back(Point3D{8581.4512221945606, -22788.128674499021, 0.0000000000000000}); + bulges.push_back(0.0000000000000000); + bulges.push_back(0.0000000000000000); + bulges.push_back(0.0000000000000000); + bulges.push_back(0.0000000000000000); + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 2850.0000000000000}; + auto tag20 = loader.addExtrude(points, bulges, extusion); + + /* 体20 Z轴偏移 -2900 */ + direction = Direction3D{0, 0, 1}; + offset = -2900; + loader.offset(tag20, direction, offset); + + /* 体1和体20布尔差 */ + loader.differentNode(tag1, tag20); + + /* 体21 */ + points.clear(); + bulges.clear(); + points.push_back(Point3D{11234.316117012169, -21717.002618593222, 0.0000000000000000}); + points.push_back(Point3D{8760.4644464528919, -16861.795338417785, 0.0000000000000000}); + points.push_back(Point3D{8651.1159137951836, -17197.859075721935, 0.0000000000000000}); + points.push_back(Point3D{10898.067054009929, -21607.748991111555, 0.0000000000000000}); + bulges.push_back(0.0000000000000000); + bulges.push_back(0.0000000000000000); + bulges.push_back(0.0000000000000000); + bulges.push_back(0.0000000000000000); + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 2850.0000000000000}; + auto tag21 = loader.addExtrude(points, bulges, extusion); + + /* 体21 Z轴偏移 -2900 */ + direction = Direction3D{0, 0, 1}; + offset = -2900; + loader.offset(tag21, direction, offset); + + /* 体1和体21布尔差 */ + loader.differentNode(tag1, tag21); + + /* 体22 */ + points.clear(); + bulges.clear(); + points.push_back(Point3D{5893.9646280986062, -18064.309214597473, 0.0000000000000000}); + points.push_back(Point3D{8472.1973651856970, -23124.378331468593, 0.0000000000000000}); + points.push_back(Point3D{8581.4512221945624, -22788.128674499025, 0.0000000000000000}); + points.push_back(Point3D{6248.1524494726591, -18208.769763083357, 0.0000000000000000}); + bulges.push_back(0.0000000000000000); + bulges.push_back(0.0000000000000000); + bulges.push_back(0.0000000000000000); + bulges.push_back(0.0000000000000000); + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 2850.0000000000000}; + auto tag22 = loader.addExtrude(points, bulges, extusion); + + /* 体22 Z轴偏移 -2900 */ + direction = Direction3D{0, 0, 1}; + offset = -2900; + loader.offset(tag22, direction, offset); + + before = loader.getAreaAndVolume(tag1); + /* 体1和体22布尔差 */ + loader.differentNode(tag1, tag22); + after = loader.getAreaAndVolume(tag1); + + /* 获取体1 布尔前后的体积差和面积差 */ + areaDifference = after.first - before.first; + volumeDifference = after.second - before.second; + std::cout << areaDifference << ", " << volumeDifference << std::endl; + + /* 体23 */ + points.clear(); + bulges.clear(); + points.push_back(Point3D{7380.7150904719992, -20706.098050612181, 0.0000000000000000}); + points.push_back(Point3D{9920.1451018985645, -19412.300707257506, 0.0000000000000000}); + points.push_back(Point3D{9829.3529561354007, -19234.096368736471, 0.0000000000000000}); + points.push_back(Point3D{7289.9229447088355, -20527.893712091147, 0.0000000000000000}); + bulges.push_back(0.0000000000000000); + bulges.push_back(0.0000000000000000); + bulges.push_back(0.0000000000000000); + bulges.push_back(0.0000000000000000); + extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 2850.0000000000000}; + auto tag23 = loader.addExtrude(points, bulges, extusion); + + /* 体23 Z轴偏移 -2900 */ + direction = Direction3D{0, 0, 1}; + offset = -2900; + loader.offset(tag23, direction, offset); + + before = loader.getAreaAndVolume(tag1); + /* 体1和体23布尔差 */ + loader.differentNode(tag1, tag23); + after = loader.getAreaAndVolume(tag1); + + /* 获取体1 布尔前后的体积差和面积差 */ + areaDifference = after.first - before.first; + volumeDifference = after.second - before.second; + std::cout << areaDifference << ", " << volumeDifference << std::endl; + + /* 以下为一个循环,凸度组固定,但点组不一样,其他操作一致 */ + auto cycle1 = [&loader, tag1](const Point3D& point1, const Point3D point2) { + /* 循环体 */ + const std::vector points = {point1, point2}; + std::vector bulges = {0.99999999999999989, 0.99999999999999989}; + Vector3D extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 2850.0000000000000}; + auto cycleTag = loader.addExtrude(points, bulges, extusion); + + /* 循环体 Z轴偏移 -2900 */ + Direction3D direction = Direction3D{0, 0, 1}; + double offset = -2900; + loader.offset(cycleTag, direction, offset); + + /* 体1和循环体布尔差 */ + loader.differentNode(tag1, cycleTag); + }; + + points.clear(); + bulges.clear(); + points.push_back(Point3D{25330.544191030145, 4059.4890957491152, 0.0000000000000000}); + points.push_back(Point3D{25930.544191030145, 4059.4890957491152, 0.0000000000000000}); + points.push_back(Point3D{2637.9248093705974, -18864.831701145784, 0.0000000000000000}); + points.push_back(Point3D{3337.9248093705974, -18864.831701145784, 0.0000000000000000}); + points.push_back(Point3D{-19214.815183982137, -2987.8808536118449, 0.0000000000000000}); + points.push_back(Point3D{-18514.815183982137, -2987.8808536118449, 0.0000000000000000}); + points.push_back(Point3D{13155.774659765651, -13505.730142548899, 0.0000000000000000}); + points.push_back(Point3D{13855.774659765651, -13505.730142548899, 0.0000000000000000}); + points.push_back(Point3D{-23421.584711222677, 11781.088222738428, 0.0000000000000000}); + points.push_back(Point3D{-22821.584711222677, 11781.088222738428, 0.0000000000000000}); + points.push_back(Point3D{-21952.083741631068, -21602.101728577210, 0.0000000000000000}); + points.push_back(Point3D{-21252.083741631068, -21602.101728577210, 0.0000000000000000}); + points.push_back(Point3D{-3337.8756971632247, -18864.831700995899, 0.0000000000000000}); + points.push_back(Point3D{-2637.8756971632247, -18864.831700995899, 0.0000000000000000}); + points.push_back(Point3D{22821.635010756669, 11781.088216097109, 0.0000000000000000}); + points.push_back(Point3D{23421.635010756669, 11781.088216097109, 0.0000000000000000}); + points.push_back(Point3D{8321.2448748154566, -17018.220376670986, 0.0000000000000000}); + points.push_back(Point3D{9021.2448748154566, -17018.220376670986, 0.0000000000000000}); + points.push_back(Point3D{-1871.5656374104437, -9922.6107521542435, 0.0000000000000000}); + points.push_back(Point3D{-1271.5656374104440, -9922.6107521542435, 0.0000000000000000}); + points.push_back(Point3D{26920.265871888550, 13869.448081589901, 0.0000000000000000}); + points.push_back(Point3D{27520.265871888550, 13869.448081589901, 0.0000000000000000}); + points.push_back(Point3D{29873.915284768678, 4779.0894375231728, 0.0000000000000000}); + points.push_back(Point3D{30473.915284768678, 4779.0894375231728, 0.0000000000000000}); + points.push_back(Point3D{1271.6142550302902, -9922.6210172974243, 0.0000000000000000}); + points.push_back(Point3D{1871.6142550302900, -9922.6210172974243, 0.0000000000000000}); + points.push_back(Point3D{7608.7448703002883, -7908.7010952570563, 0.0000000000000000}); + points.push_back(Point3D{8208.7448703002883, -7908.7010952570563, 0.0000000000000000}); + points.push_back(Point3D{11431.053468361089, -23121.619302695020, 0.0000000000000000}); + points.push_back(Point3D{12131.053468361089, -23121.619302695020, 0.0000000000000000}); + points.push_back(Point3D{21252.143796979217, -21602.113447324591, 0.0000000000000000}); + points.push_back(Point3D{21952.143796979217, -21602.113447324591, 0.0000000000000000}); + points.push_back(Point3D{26870.284425387275, -13869.400552711551, 0.0000000000000000}); + points.push_back(Point3D{27570.284425387275, -13869.400552711551, 0.0000000000000000}); + points.push_back(Point3D{16668.254151753965, -8671.2113439714158, 0.0000000000000000}); + points.push_back(Point3D{17368.254151753965, -8671.2113439714158, 0.0000000000000000}); + points.push_back(Point3D{21302.142824993702, 21602.129722254482, 0.0000000000000000}); + points.push_back(Point3D{21902.142824993702, 21602.129722254482, 0.0000000000000000}); + points.push_back(Point3D{18514.882078273164, -2987.8308623732737, 0.0000000000000000}); + points.push_back(Point3D{19214.882078273164, -2987.8308623732737, 0.0000000000000000}); + points.push_back(Point3D{-27570.225340223697, -13869.390298805301, 0.0000000000000000}); + points.push_back(Point3D{-26870.225340223697, -13869.390298805301, 0.0000000000000000}); + points.push_back(Point3D{15563.854737884307, 8083.0486660407769, 0.0000000000000000}); + points.push_back(Point3D{16163.854737884307, 8083.0486660407769, 0.0000000000000000}); + points.push_back(Point3D{29823.926027013978, -4778.9706820347201, 0.0000000000000000}); + points.push_back(Point3D{30523.926027013978, -4778.9706820347201, 0.0000000000000000}); + points.push_back(Point3D{-25930.485105855274, 4059.4890957491152, 0.0000000000000000}); + points.push_back(Point3D{-25330.485105855274, 4059.4890957491152, 0.0000000000000000}); + points.push_back(Point3D{-15906.105228972388, 2471.7791264631815, 0.0000000000000000}); + points.push_back(Point3D{-15306.105228972388, 2471.7791264631815, 0.0000000000000000}); + points.push_back(Point3D{-14208.685301157355, 13908.728353561615, 0.0000000000000000}); + points.push_back(Point3D{-13608.685301157355, 13908.728353561615, 0.0000000000000000}); + points.push_back(Point3D{15306.173097269726, 2471.7791347907769, 0.0000000000000000}); + points.push_back(Point3D{15906.173097269726, 2471.7791347907769, 0.0000000000000000}); + points.push_back(Point3D{-30523.856199605914, -4779.0607699771499, 0.0000000000000000}); + points.push_back(Point3D{-29823.856199605914, -4779.0607699771499, 0.0000000000000000}); + points.push_back(Point3D{13608.744379809476, 13908.728344973482, 0.0000000000000000}); + points.push_back(Point3D{14208.744379809476, 13908.728344973482, 0.0000000000000000}); + points.push_back(Point3D{-19164.815183980274, 2987.9090176032769, 0.0000000000000000}); + points.push_back(Point3D{-18564.815183980274, 2987.9090176032769, 0.0000000000000000}); + points.push_back(Point3D{18049.454334036331, 18349.429508093293, 0.0000000000000000}); + points.push_back(Point3D{18649.454334036331, 18349.429508093293, 0.0000000000000000}); + points.push_back(Point3D{18564.882081644726, 2987.9090176032769, 0.0000000000000000}); + points.push_back(Point3D{19164.882081644726, 2987.9090176032769, 0.0000000000000000}); + points.push_back(Point3D{-18649.394773816515, 18349.429525433647, 0.0000000000000000}); + points.push_back(Point3D{-18049.394773816515, 18349.429525433647, 0.0000000000000000}); + points.push_back(Point3D{-16163.795652730274, 8083.0486660407769, 0.0000000000000000}); + points.push_back(Point3D{-15563.795652730274, 8083.0486660407769, 0.0000000000000000}); + points.push_back(Point3D{-13089.545652741857, 6516.6287441791064, 0.0000000000000000}); + points.push_back(Point3D{-12489.545652741857, 6516.6287441791064, 0.0000000000000000}); + points.push_back(Point3D{-12432.865969395847, 1921.6695098721102, 0.0000000000000000}); + points.push_back(Point3D{-11832.865969395847, 1921.6695098721102, 0.0000000000000000}); + points.push_back(Point3D{11832.924069322587, 1921.6787872227869, 0.0000000000000000}); + points.push_back(Point3D{12432.924069322587, 1921.6787872227869, 0.0000000000000000}); + points.push_back(Point3D{-14219.424558988423, -27220.219888640844, 0.0000000000000000}); + points.push_back(Point3D{-13519.424558988423, -27220.219888640844, 0.0000000000000000}); + points.push_back(Point3D{-8208.6860335274250, -7908.7010897282598, 0.0000000000000000}); + points.push_back(Point3D{-7608.6860335274250, -7908.7010897282598, 0.0000000000000000}); + points.push_back(Point3D{11531.074457970564, 23121.638501036170, 0.0000000000000000}); + points.push_back(Point3D{12031.074457970564, 23121.638501036170, 0.0000000000000000}); + points.push_back(Point3D{-21902.083733627456, 21602.129728298649, 0.0000000000000000}); + points.push_back(Point3D{-21302.083733627456, 21602.129728298649, 0.0000000000000000}); + points.push_back(Point3D{-5079.0456527201459, 30173.900228539613, 0.0000000000000000}); + points.push_back(Point3D{-4479.0456527201459, 30173.900228539613, 0.0000000000000000}); + points.push_back(Point3D{-3223.9956954814261, 18461.557455070157, 0.0000000000000000}); + points.push_back(Point3D{-2623.9956954814261, 18461.557455070157, 0.0000000000000000}); + points.push_back(Point3D{2624.0444348900346, 18461.557454720794, 0.0000000000000000}); + points.push_back(Point3D{3224.0444348900346, 18461.557454720794, 0.0000000000000000}); + points.push_back(Point3D{-8405.0161077585071, 15906.991054460479, 0.0000000000000000}); + points.push_back(Point3D{-7805.0161077585071, 15906.991054460479, 0.0000000000000000}); + points.push_back(Point3D{4479.0942398422048, 30173.900228537284, 0.0000000000000000}); + points.push_back(Point3D{5079.0942398422048, 30173.900228537284, 0.0000000000000000}); + points.push_back(Point3D{-30473.855223292368, 4779.0894371719478, 0.0000000000000000}); + points.push_back(Point3D{-29873.855223292368, 4779.0894371719478, 0.0000000000000000}); + points.push_back(Point3D{-9834.8557113136048, 18811.339681665777, 0.0000000000000000}); + points.push_back(Point3D{-9334.8557113136048, 18811.339681665777, 0.0000000000000000}); + points.push_back(Point3D{13569.434806959180, 27220.270333465378, 0.0000000000000000}); + points.push_back(Point3D{14169.434806959180, 27220.270333465378, 0.0000000000000000}); + points.push_back(Point3D{13452.094479468651, -2178.0609130331286, 0.0000000000000000}); + points.push_back(Point3D{14052.094479468651, -2178.0609130331286, 0.0000000000000000}); + points.push_back(Point3D{7635.4943863257067, -4043.3108920587547, 0.0000000000000000}); + points.push_back(Point3D{8235.4943863257067, -4043.3108920587547, 0.0000000000000000}); + points.push_back(Point3D{-5030.7456039006938, -9284.6107577729126, 0.0000000000000000}); + points.push_back(Point3D{-4430.7456039006938, -9284.6107577729126, 0.0000000000000000}); + points.push_back(Point3D{9334.8840347801452, 18811.357259790777, 0.0000000000000000}); + points.push_back(Point3D{9834.8840347801452, 18811.357259790777, 0.0000000000000000}); + points.push_back(Point3D{-3675.6656478448422, 21628.976400436615, 0.0000000000000000}); + points.push_back(Point3D{-3175.6656478448422, 21628.976400436615, 0.0000000000000000}); + points.push_back(Point3D{3809.4943863322260, 25630.529134790777, 0.0000000000000000}); + points.push_back(Point3D{4309.4943863322260, 25630.529134790777, 0.0000000000000000}); + points.push_back(Point3D{4430.7846695982153, -9284.6210116034345, 0.0000000000000000}); + points.push_back(Point3D{5030.7846695982153, -9284.6210116034345, 0.0000000000000000}); + points.push_back(Point3D{-13855.715086132754, -13505.720376673606, 0.0000000000000000}); + points.push_back(Point3D{-13155.715086132754, -13505.720376673606, 0.0000000000000000}); + points.push_back(Point3D{-12131.054926622368, -23121.600743537347, 0.0000000000000000}); + points.push_back(Point3D{-11431.054926622368, -23121.600743537347, 0.0000000000000000}); + points.push_back(Point3D{-10578.765375099087, -1627.9909095301846, 0.0000000000000000}); + points.push_back(Point3D{-9978.7653750990867, -1627.9909095301846, 0.0000000000000000}); + points.push_back(Point3D{3175.7141128947260, 21628.976400436615, 0.0000000000000000}); + points.push_back(Point3D{3675.7141128947260, 21628.976400436615, 0.0000000000000000}); + points.push_back(Point3D{11239.354737904854, 11539.338705116606, 0.0000000000000000}); + points.push_back(Point3D{11839.354737904854, 11539.338705116606, 0.0000000000000000}); + points.push_back(Point3D{-17318.196043352364, -8671.2008456719195, 0.0000000000000000}); + points.push_back(Point3D{-16718.196043352364, -8671.2008456719195, 0.0000000000000000}); + points.push_back(Point3D{-14169.424558975501, 27220.248861367945, 0.0000000000000000}); + points.push_back(Point3D{-13569.424558975501, 27220.248861367945, 0.0000000000000000}); + points.push_back(Point3D{9978.8439957064693, -1627.9708957259863, 0.0000000000000000}); + points.push_back(Point3D{10578.843995706469, -1627.9708957259863, 0.0000000000000000}); + points.push_back(Point3D{13519.435304297367, -27220.250162088065, 0.0000000000000000}); + points.push_back(Point3D{14219.435304297367, -27220.250162088065, 0.0000000000000000}); + points.push_back(Point3D{-3550.8955367645249, -6380.2710360850760, 0.0000000000000000}); + points.push_back(Point3D{-2950.8955367645249, -6380.2710360850760, 0.0000000000000000}); + points.push_back(Point3D{10709.754156451614, -5609.7207374573773, 0.0000000000000000}); + points.push_back(Point3D{11309.754156451614, -5609.7207374573773, 0.0000000000000000}); + points.push_back(Point3D{12489.604245378461, 6516.6389926101110, 0.0000000000000000}); + points.push_back(Point3D{13089.604245378461, 6516.6389926101110, 0.0000000000000000}); + points.push_back(Point3D{-8235.4355452836026, -4043.3108920448431, 0.0000000000000000}); + points.push_back(Point3D{-7635.4355452836026, -4043.3108920448431, 0.0000000000000000}); + points.push_back(Point3D{2950.9448257543263, -6380.2808017734642, 0.0000000000000000}); + points.push_back(Point3D{3550.9448257543263, -6380.2808017734642, 0.0000000000000000}); + points.push_back(Point3D{-11309.696043347765, -5609.7207431293646, 0.0000000000000000}); + points.push_back(Point3D{-10709.696043347765, -5609.7207431293646, 0.0000000000000000}); + points.push_back(Point3D{-11839.285398820706, 11539.328939490792, 0.0000000000000000}); + points.push_back(Point3D{-11239.285398820706, 11539.328939490792, 0.0000000000000000}); + points.push_back(Point3D{-14052.005613667367, -2178.0908755634300, 0.0000000000000000}); + points.push_back(Point3D{-13452.005613667367, -2178.0908755634300, 0.0000000000000000}); + points.push_back(Point3D{-9021.2153273623553, -17018.201329904943, 0.0000000000000000}); + points.push_back(Point3D{-8321.2153273623553, -17018.201329904943, 0.0000000000000000}); + points.push_back(Point3D{-4309.4457381869433, 25630.529134784956, 0.0000000000000000}); + points.push_back(Point3D{-3809.4457381869433, 25630.529134784956, 0.0000000000000000}); + points.push_back(Point3D{-27520.215574607428, 13869.448080100890, 0.0000000000000000}); + points.push_back(Point3D{-26920.215574607428, 13869.448080100890, 0.0000000000000000}); + points.push_back(Point3D{-12031.065183990693, 23121.618978540777, 0.0000000000000000}); + points.push_back(Point3D{-11531.065183990693, 23121.618978540777, 0.0000000000000000}); + points.push_back(Point3D{7805.0446787483525, 15907.018391851525, 0.0000000000000000}); + points.push_back(Point3D{8405.0446787483525, 15907.018391851525, 0.0000000000000000}); + points.push_back(Point3D{4354.0942397164181, -30098.870279427545, 0.0000000000000000}); + points.push_back(Point3D{5204.0942397164044, -30098.870279427545, 0.0000000000000000}); + points.push_back(Point3D{-5204.0456527279457, -30098.870279264738, 0.0000000000000000}); + points.push_back(Point3D{-4354.0456527279594, -30098.870279264738, 0.0000000000000000}); + points.push_back(Point3D{-23421.612136159150, -11781.067532595984, 0.0000000000000000}); + points.push_back(Point3D{-22821.612136159150, -11781.067532595984, 0.0000000000000000}); + for (size_t i = 0; i < points.size(); i += 2) + { + cycle1(points[i], points[i + 1]); + } + + /* 以下为一个循环,凸度组固定,但点组不一样,其他操作一致 */ + auto cycle2 = [&loader, + tag1](const Point3D& point1, const Point3D point2, const Point3D point3, const Point3D point4) { + /* 循环体 */ + const std::vector points = {point1, point2, point3, point4}; + std::vector bulges = {0.0000000000000000, 0.0000000000000000, 0.0000000000000000, 0.0000000000000000}; + Vector3D extusion = Vector3D{0.0000000000000000, 0.0000000000000000, 2850.0000000000000}; + auto cycleTag = loader.addExtrude(points, bulges, extusion); + + /* 循环体 Z轴偏移 -2900 */ + Direction3D direction = Direction3D{0, 0, 1}; + double offset = -2900; + loader.offset(cycleTag, direction, offset); + + /* 体1和循环体布尔差 */ + loader.differentNode(tag1, cycleTag); + }; + + points.clear(); + bulges.clear(); + points.push_back(Point3D{-24963.009860716236, 7446.7650615308812, 0.0000000000000000}); + points.push_back(Point3D{-24459.052558350675, 7366.9792723925602, 0.0000000000000000}); + points.push_back(Point3D{-24388.685618648018, 7811.4435496937649, 0.0000000000000000}); + points.push_back(Point3D{-24833.149895949224, 7881.8104893964210, 0.0000000000000000}); + points.push_back(Point3D{24963.106150213611, 7446.7650615305229, 0.0000000000000000}); + points.push_back(Point3D{24459.148847848050, 7366.9792723922019, 0.0000000000000000}); + points.push_back(Point3D{24388.781908145393, 7811.4435496934066, 0.0000000000000000}); + points.push_back(Point3D{24833.246185446598, 7881.8104893960626, 0.0000000000000000}); + points.push_back(Point3D{6085.2898662776533, -18440.931060827090, 0.0000000000000000}); + points.push_back(Point3D{6530.7930936759531, -18213.935742862825, 0.0000000000000000}); + points.push_back(Point3D{6326.4973075081125, -17812.982838204356, 0.0000000000000000}); + points.push_back(Point3D{5880.9940801098128, -18039.978156168621, 0.0000000000000000}); + points.push_back(Point3D{9198.0021988374647, -24549.990396445304, 0.0000000000000000}); + points.push_back(Point3D{9643.5067429911614, -24322.997662776565, 0.0000000000000000}); + points.push_back(Point3D{9439.2132826892957, -23922.043573038238, 0.0000000000000000}); + points.push_back(Point3D{8993.7087385355990, -24149.036306706977, 0.0000000000000000}); + + before = loader.getAreaAndVolume(tag1); + for (size_t i = 0; i < points.size(); i += 4) + { + cycle2(points[i], points[i + 1], points[i + 2], points[i + 3]); + } + after = loader.getAreaAndVolume(tag1); + + /* 获取体1 布尔前后的体积差和面积差 */ + areaDifference = after.first - before.first; volumeDifference = after.second - before.second; + std::cout << areaDifference << ", " << volumeDifference << std::endl; } int main(int argc, char** argv) { - loaderTest1(); + loaderTest2(); return 0; } diff --git a/wxl/parser.py b/wxl/parser.py index 64b94e1..af5941f 100644 --- a/wxl/parser.py +++ b/wxl/parser.py @@ -4,70 +4,202 @@ class Parser: def __init__(self): self.all = [] + self.op = [] def parser(self): - pattern1 = re.compile(r"m_pData\[\d+\]\t\{x=(.*?) y=(.*?) z=(.*?) \}\tOdGePoint3d\n", re.VERBOSE) - pattern2 = re.compile(r"m_pData\[\d+\]\t(.*?)\tdouble\n", re.VERBOSE) + pattern1 = re.compile(r"m_pData\[\d+\]\t\{x=(.*?) y=(.*?) z=(.*?) \}\tOdGePoint3d", re.VERBOSE) + pattern2 = re.compile(r"m_pData\[\d+\]\t(.*?)\tdouble", re.VERBOSE) pattern3 = re.compile(r"\{x=(.*?) y=(.*?) z=(.*?) \}") + pattern4 = re.compile(r"m_pt\[\d+\]\t\{x=(.*?) y=(.*?) z=(.*?) \}\tOdGePoint3d", re.VERBOSE) + pattern5 = re.compile(r"m_dBugle\[\d+\]\t(.*?)\tdouble", re.VERBOSE) - end_pattern = re.compile(r"浣(\d+)") + begin_pattern = re.compile(r"浣(\d+)锛(createCone)?") - with open("/home/xiaolong/HeteQuadrature/wxl/data.txt") as f: + op_pattern = re.compile(r"(?:寰幆浣搢鎵e噺浣搢浣)(\d+)鍜(?:寰幆浣搢鎵e噺浣搢浣)(\d+)甯冨皵([骞朵氦宸甝)") + offset_pattern = re.compile(r"浣(\d+) ([XYZ])杞村亸绉(-?\d+)") + split_pattern = re.compile(r"浣(\d+)琚垏鍓") + + + with open("/home/xiaolong/HeteQuadrature/wxl/data_1.txt") as f: points = [] bulges = [] extusion = [] + index = 1 + + end = False for line in f: - if line.find("浣") != -1: - self.all.append([points, bulges, extusion]) - points = [] - bulges = [] - extusion = [] + mathc0 = begin_pattern.findall(line) + + if mathc0 != []: + index = mathc0[0][0] + + if mathc0[0][1] != "": + next_line = next(f) + temp_pattern = re.compile(r"topPt\t\{x=(.*?) y=(.*?) z=(.*?) \}\tOdGePoint3d") + temp_match1 = temp_pattern.findall(next_line) + + next_line = next(f) + temp_pattern = re.compile(r"downPt\t\{x=(.*?) y=(.*?) z=(.*?) \}\tOdGePoint3d") + temp_match2 = temp_pattern.findall(next_line) + + next_line = next(f) + temp_pattern = re.compile(r"dRadius1\t(.*?)\tdouble") + temp_match3 = temp_pattern.findall(next_line) + + next_line = next(f) + temp_pattern = re.compile(r"dRadius2\t(.*?)\tdouble") + temp_match4 = temp_pattern.findall(next_line) + + self.all.append([4, [index, temp_match1[0], temp_match2[0], temp_match3[0], temp_match4[0]]]) + continue match1 = pattern1.findall(line) if match1 != []: points.append(match1) - #print(match1) + continue + + match4 = pattern4.findall(line) + if match4 != []: + points.append(match4) continue match2 = pattern2.findall(line) if match2 != []: bulges.append(match2) - #print(match2) + continue + + match5 = pattern5.findall(line) + if match5 != []: + bulges.append(match5) continue match3 = pattern3.findall(line) if match3 != []: extusion = match3 - #print(match3) + self.all.append([0, index, points, bulges, extusion]) + points = [] + bulges = [] + extusion = [] + continue + + op_match = op_pattern.findall(line) + if op_match != []: + self.all.append([1, op_match[0]]) + continue + + offset_match = offset_pattern.findall(line) + if offset_match != []: + self.all.append([2, offset_match[0]]) + continue + + split_match = split_pattern.findall(line) + if split_match != []: + + next_line = next(f) + temp_pattern1 = re.compile(r"topPt\t\{x=(.*?) y=(.*?) z=(.*?) \}\tOdGePoint3d") + temp_match1 = temp_pattern1.findall(next_line) + + next_line = next(f) + temp_pattern2 = re.compile(r"k([XYZ])Axis") + temp_match2 = temp_pattern2.findall(next_line) + + self.all.append([3, [split_match[0], temp_match1[0], temp_match2[0]]]) continue + + + + + def generate(self): - result = " Loader l;\n\n" + result = " Loader loader;\n\n" result += " std::vector points;\n" result += " std::vector bulges;\n" result += " Vector3D extusion;\n\n" for value in self.all: - points, bulges, extusion = value - if points == []: - continue - - result += " points.clear();\n" - result += " bulges.clear();\n" - - for point in points: - result += " points.push_back(Point3D{" + point[0][0] + "," + point[0][1] + "," + point[0][2] +"});\n" - - - for bulge in bulges: - result += " bulges.push_back(" + bulge[0] + ");\n" - - result += " extusion = Vector3D{" + extusion[0][0] + "," + extusion[0][1] + "," + extusion[0][2] + "};\n" - result += " l.addExtrude(points, bulges, extusion);\n\n" + if (value[0] == 0): + _, index, points, bulges, extusion = value + + result += " /* 浣搟} */\n".format(index) + + if points == []: + continue + + result += " points.clear();\n" + result += " bulges.clear();\n" + + for point in points: + result += " points.push_back(Point3D{" + point[0][0] + "," + point[0][1] + "," + point[0][2] +"});\n" + + + for bulge in bulges: + result += " bulges.push_back(" + bulge[0] + ");\n" + + if extusion != []: + result += " extusion = Vector3D{" + extusion[0][0] + "," + extusion[0][1] + "," + extusion[0][2] + "};\n" + result += " auto tag" + index + " = loader.addExtrude(points, bulges, extusion);\n" + + result += "\n" + + + if (value[0] == 1): + op = value[1] + + result += " /* 浣搟}鍜屼綋{}甯冨皵{} */\n".format(op[0], op[1], op[2]) + + if (op[2] == "骞"): + result += " loader.unionNode(tag" + op[0] + ", tag" + op[1] + ");\n\n" + elif (op[2] == "浜"): + result += " loader.intersectNode(tag" + op[0] + ", tag" + op[1] + ");\n\n" + elif (op[2] == "宸"): + result += " loader.differentNode(tag" + op[0] + ", tag" + op[1] + ");\n\n" + + if (value[0] == 2): + offset =value[1] + + result += " /* 浣搟} {}杞村亸绉 {} */\n".format(offset[0], offset[1], offset[2]) + + if (offset[1] == "X"): + result += " direction = Direction3D{1, 0, 0};\n" + elif (offset[1] == "Y"): + result += " direction = Direction3D{0, 1, 0};\n" + elif (offset[1] == "Z"): + result += " direction = Direction3D{0, 0, 1};\n" + + result += " offset = " + offset[2] + ";\n" + result += " loader.offset(tag" + offset[0] + ", direction, offset);\n\n" + + if (value[0] == 3): + split = value[1] + + result += " /* 浣搟}琚垏鍓 */\n".format(split[0]) + + if (split[2] == "X"): + result += " direction = Direction3D{1, 0, 0};\n" + elif (split[2] == "Y"): + result += " direction = Direction3D{0, 1, 0};\n" + elif (split[2] == "Z"): + result += " direction = Direction3D{0, 0, 1};\n" + + result += " basePoint = Point3D{" + split[1][0] + "," + split[1][1] + "," + split[1][2] +"};\n" + result += " loader.split(tag" + split[0] + ", basePoint, direction);\n\n" + + if (value[0] == 4): + cone = value[1] + index, top, bottom, radius1, radius2 = cone + + result += " /* 浣搟} */\n".format(index) + result += " topPoint = Point3D{" + top[0] + "," + top[1] + "," + top[2] +"};\n" + result += " bottomPoint = Point3D{" + bottom[0] + "," + bottom[1] + "," + bottom[2] +"};\n" + result += " radius1 = " + radius1 + ";\n" + result += " radius2 = " + radius2 + ";\n" + result += " auto tag" + index + " = loader.addCone(topPoint, bottomPoint, radius1, radius2);\n\n" + print(result)