diff --git a/algoim/organizer/blobtree.hpp b/algoim/organizer/blobtree.hpp index e030fb7..39eeb2f 100644 --- a/algoim/organizer/blobtree.hpp +++ b/algoim/organizer/blobtree.hpp @@ -73,7 +73,7 @@ void propagate(BlobTree& tree, unsigned int nodeIdx, bool in) int aaa = 1; int bb = 1; } - assert(node.inOut == NODE_IN_OUT_UNKNOWN); + // assert(node.inOut == NODE_IN_OUT_UNKNOWN); node.inOut = in ? NODE_IN : NODE_OUT; for (unsigned int nowIdx = nodeIdx; nowIdx != rootIdx;) { const auto& nowNode = tree.structure[nowIdx]; @@ -131,9 +131,14 @@ int traverse(BlobTree& tree, const std::vector& relatedPrimitives, const st return NODE_IN_OUT_UNKNOWN; } -int traverse(BlobTree& tree, const int relatedPrimitive, const bool primitiveInout) +int traverse(BlobTree& tree, const int relatedPrimitive, const bool in) { - propagate(tree, tree.primitiveNodeIdx[relatedPrimitive], primitiveInout); + int bbb = 1; + propagate(tree, tree.primitiveNodeIdx[relatedPrimitive], in); + if (tree.structure[tree.primitiveNodeIdx[relatedPrimitive]].inOut == NODE_IN_OUT_UNKNOWN) { + int aaa = 1; + int bbb = 1; + } return tree.structure.back().inOut; } }; // namespace algoim::organizer diff --git a/algoim/organizer/organizer.hpp b/algoim/organizer/organizer.hpp index 04c0ed1..81e576c 100644 --- a/algoim/organizer/organizer.hpp +++ b/algoim/organizer/organizer.hpp @@ -301,7 +301,7 @@ void buildOcTreeV0(const Scene& scene, const OcTreeNode& node, std::vector j(0, 2); ~j; ++j, ++subIdx) { + if (subIdx == 0) { + int aaa = 1; + int bbb = 1; + } if (!minimalRep.aabb.intersect(subNodes[subIdx].aabb)) { // out of the subcell organizer::traverse(subNodes[subIdx].blobTree, polyIntersectIndex, false); continue; } - if (subIdx == 1) { - int aaa = 1; - int bbb = 1; - } tensor3 subcellPoly(nullptr, minimalRep.tensor.ext()); algoim_spark_alloc(real, subcellPoly); bernstein::deCasteljau(minimalRep.tensor, subNodes[subIdx].aabb.min, subNodes[subIdx].aabb.max, subcellPoly); @@ -469,6 +470,10 @@ void basicTask(const std::vector>& primitives, in BasicTaskRes basicTask(const Scene& scene, const OcTreeNode& node, int q = 10) { if (node.polyIntersectIndices.size() == 0) { + if (node.blobTree.structure.back().inOut == NODE_IN_OUT_UNKNOWN) { + int aaa = 0; + int bbb = 0; + } assert(node.blobTree.structure.back().inOut != NODE_IN_OUT_UNKNOWN); if (node.blobTree.structure.back().inOut == NODE_IN) { return {node.aabb.volume(), 0}; @@ -577,11 +582,26 @@ void quadratureScene(const std::vector>& primitiv // 必须以自左向右的顺序访问所有叶节点 assert(blobTree.primitiveNodeIdx[i] < blobTree.primitiveNodeIdx[i + 1]); } - for (int i = 0; i < visiblePrimitiveReps.size(); ++i) { - int originLeafIdx = blobTree.primitiveNodeIdx[i]; - for (int j = 0; j < originLeafIdx; ++j) { - if (blobTree.structure[j].isLeft && blobTree.structure[j].ancestor + j > originLeafIdx) { - blobTree.structure[j].ancestor += std::max(int(visiblePrimitiveReps[i].subBlobTree.structure.size()) - 1, 0); + + /***注意这个写法的bug***/ + /***blobTree.structure[j].ancestor一边被修改一边作为条件判断依据***/ + /***需要对原始的ancestor存一份副本***/ + // std::vector oldAncestors(blobTree.structure.); + // for (int i = 0; i < visiblePrimitiveReps.size(); ++i) { + // int originLeafIdx = blobTree.primitiveNodeIdx[i]; + // for (int j = 0; j < originLeafIdx; ++j) { + // if (blobTree.structure[j].isLeft && blobTree.structure[j].ancestor + j > originLeafIdx) { + // blobTree.structure[j].ancestor += std::max(int(visiblePrimitiveReps[i].subBlobTree.structure.size()) - 1, 0); + // } + // } + // } + /***注意这个写法的bug***/ + + for (int i = 0; i < blobTree.structure.size(); ++i) { + int oldAncestor = blobTree.structure[i].ancestor; + for (int j = visiblePrimitiveReps.size() - 1; blobTree.primitiveNodeIdx[j] > i; --j) { + if (blobTree.structure[i].isLeft && oldAncestor + i > blobTree.primitiveNodeIdx[j]) { + blobTree.structure[i].ancestor += std::max(int(visiblePrimitiveReps[j].subBlobTree.structure.size()) - 1, 0); } } } diff --git a/algoim/organizer/primitive.hpp b/algoim/organizer/primitive.hpp index e03a87c..14088dd 100644 --- a/algoim/organizer/primitive.hpp +++ b/algoim/organizer/primitive.hpp @@ -568,13 +568,13 @@ class ConeDesc : virtual public PrimitiveDesc { public: const static PrimitiveType type = Cone; - uvector3 node1; + uvector3 bottom; // uvector3 node2; real radius; real height; int alignAxis; - ConeDesc(const uvector3& n1, real r, real h, int ax) : PrimitiveDesc(), node1(n1), radius(r), height(h), alignAxis(ax) + ConeDesc(const uvector3& n1, real r, real h, int ax) : PrimitiveDesc(), bottom(n1), radius(r), height(h), alignAxis(ax) { assert(alignAxis >= 0 && alignAxis <= 2); } @@ -886,25 +886,26 @@ void makeCylinder(const CylinderDesc& cylinderDesc, VisiblePrimitiveRep& visible void makeCone(const ConeDesc& coneDesc, VisiblePrimitiveRep& visiblePrimitive) { assert(visiblePrimitive.tensors.size() == 3); + int alignAxis = coneDesc.alignAxis; + assert(alignAxis >= 0 && alignAxis < 3); auto &coneSrf = visiblePrimitive.tensors[0], &plane1 = visiblePrimitive.tensors[1], &plane2 = visiblePrimitive.tensors[2]; xarrayInit(coneSrf); xarrayInit(plane1); xarrayInit(plane2); assert(all(coneSrf.ext() == 3)); - int alignAxis = coneDesc.alignAxis; - - int dimA = (alignAxis + 1) % 3, dimB = (alignAxis + 2) % 3; - real a = coneDesc.node1(dimA), b = coneDesc.node1(dimB), c = coneDesc.node1(alignAxis); - real scale = coneDesc.height / coneDesc.radius, scaleSquare = scale * scale; + // plane1 / plane2 分别为底面 / 顶点所在面 + int dimA = (alignAxis + 1) % 3, dimB = (alignAxis + 2) % 3; + real h = coneDesc.height, a = coneDesc.bottom(dimA), b = coneDesc.bottom(dimB), c = coneDesc.bottom(alignAxis) + h; + real scale = h / coneDesc.radius, scaleSquare = scale * scale; // f = (scale(x-a))^2 + (scale(y-b))^2 - (z-c)^2 uvector idx = 0; - plane1.m(idx) = c; - plane2.m(idx) = -c - coneDesc.height; + plane1.m(idx) = util::sign(h) * coneDesc.bottom(alignAxis); + plane2.m(idx) = -util::sign(h) * c; coneSrf.m(idx) = scaleSquare * (a * a + b * b) - c * c; idx(alignAxis) = 1; - plane1.m(idx) = -1; - plane2.m(idx) = 1; + plane1.m(idx) = -util::sign(h); + plane2.m(idx) = util::sign(h); coneSrf.m(idx) = 2 * c; idx(alignAxis) = 2; coneSrf.m(idx) = -1; @@ -922,10 +923,9 @@ void makeCone(const ConeDesc& coneDesc, VisiblePrimitiveRep& visiblePrimitive) // auto range = sceneBoundary.size(); // for (int i = 0; i < 3; ++i) { detail::powerTransformation(range, sceneBoundary.min, visiblePrimitive.tensors[i]); } - // AABB - visiblePrimitive.aabb.extend(coneDesc.node1); - auto node2 = coneDesc.node1; + visiblePrimitive.aabb.extend(coneDesc.bottom); + auto node2 = coneDesc.bottom; node2(alignAxis) += coneDesc.height; visiblePrimitive.aabb.extend(node2); visiblePrimitive.aabb.min(dimA) -= coneDesc.radius; diff --git a/gjj/primitiveDebug.hpp b/gjj/primitiveDebug.hpp index 9cea124..d13d522 100644 --- a/gjj/primitiveDebug.hpp +++ b/gjj/primitiveDebug.hpp @@ -135,6 +135,29 @@ void caseCubeSphere() basicTask({phi0, phi1}); } +void caseCone() +{ + const int PRIMITIVE_CNT = 4; + std::vector> primitiveDescriptions(PRIMITIVE_CNT); + primitiveDescriptions[0] = std::make_shared(CuboidDesc(0.0, 1.6)); + primitiveDescriptions[1] = std::make_shared(CuboidDesc(uvector3(0.6, 0.6, -0.6), 2.)); + primitiveDescriptions[2] = std::make_shared(SphereDesc(0.2, uvector3(0.2, -0.7, 0.), 1.)); + primitiveDescriptions[3] = std::make_shared(ConeDesc(uvector3(0., -0.2, 0.), 0.4, -0.7, 1)); + organizer::BlobTree blobTree; + blobTree.structure.resize(PRIMITIVE_CNT * 2 - 1); + blobTree.primitiveNodeIdx.resize(PRIMITIVE_CNT); + // blobTree.structure[0] = {0, 0, NODE_IN_OUT_UNKNOWN, 0, 1, 2}; // cube1 + blobTree.structure[0] = {1, 0, NODE_IN_OUT_UNKNOWN, 0, 1, 2 - 0}; // cube + blobTree.structure[1] = {1, 0, 0, 0, 0, 0}; // cube2 + blobTree.structure[2] = {0, OP_UNION, 0, 0, 1, 6 - 2}; // Union of cubes = opNode1 + blobTree.structure[3] = {1, 0, NODE_IN_OUT_UNKNOWN, 0, 1, 5 - 3}; // cone + blobTree.structure[4] = {1, 0, NODE_IN_OUT_UNKNOWN, 0, 0, 0}; // sphere + blobTree.structure[5] = {0, OP_UNION, NODE_IN_OUT_UNKNOWN, 0, 0, 0}; // cone u sphere = n1 + blobTree.structure[6] = {0, OP_DIFFERENCE, NODE_IN_OUT_UNKNOWN, 0, 0, 0}; // cube - n1 = n2 + blobTree.primitiveNodeIdx = {0, 1, 3, 4}; + quadratureScene(primitiveDescriptions, uvector3(-0.8, -1.3, -1.6), uvector3(1.6, 1.6, 1.5), blobTree, 10); +} + void caseScene() { const int PRIMITIVE_CNT = 6; @@ -152,23 +175,26 @@ void caseScene() }; // primitiveDescriptions[4] = std::make_shared(pyramidBottomVertices, uvector3{0, 0, 1}); primitiveDescriptions[4] = std::make_shared(SphereDesc(0.2, uvector3(0.2, -0.7, 0.), 1.)); + + // primitiveDescriptions[5] = std::make_shared(SphereDesc(0.2, uvector3(0., -0.5, 0.), 1)); primitiveDescriptions[5] = std::make_shared(ConeDesc(uvector3(0., -0.2, 0.), 0.4, -0.7, 1)); // primitiveDescriptions[6] = std::make_shared(CylinderDesc(uvector3(-0.3, 0.3, 2.3), 0.4, 3.6, 1)); organizer::BlobTree blobTree; blobTree.structure.resize(PRIMITIVE_CNT * 2 - 1); blobTree.primitiveNodeIdx.resize(PRIMITIVE_CNT); - blobTree.structure[0] = {1, 0, 0, 0, 1, 2}; // cube1 - blobTree.structure[1] = {1, 0, 0, 0, 0, 0}; // cube2 - blobTree.structure[2] = {0, 0, 0, 0, 1, 6 - 2}; // Union of cubes = opNode1 - blobTree.structure[3] = {1, 0, 0, 0, 1, 5 - 3}; // sphere1 - blobTree.structure[4] = {1, 0, 0, 0, 0, 0}; // sphere2 - blobTree.structure[5] = {0, 0, 0, 0, 0, 0}; // Union of spheres = opNode2 - blobTree.structure[6] = {0, 2, 0, 0, 1, 10 - 6}; // Difference of opNode1 and opNode2 = opNode3 - blobTree.structure[7] = {1, 0, 0, 0, 1, 9 - 7}; // Pyramid (sphere3) - blobTree.structure[8] = {1, 0, 0, 0, 0, 0}; // Cone - blobTree.structure[9] = {0, 0, 0, 0, 0, 0}; // UNION of Pyramid (sphere3) and Cone = opNode4 - blobTree.structure[10] = {0, 2, 0, 0, 1, 12 - 10}; // Difference of opNode3 and opNode4 = opNode5 - // blobTree.structure[11] = {1, 0, 0, 0, 0, 0}; // Cylinder + blobTree.structure[0] = {1, 0, 0, 0, 1, 2}; // cube1 + blobTree.structure[1] = {1, 0, 0, 0, 0, 0}; // cube2 + blobTree.structure[2] = {0, OP_UNION, 0, 0, 1, 6 - 2}; // Union of cubes = opNode1 + blobTree.structure[3] = {1, 0, 0, 0, 1, 5 - 3}; // sphere1 + blobTree.structure[4] = {1, 0, 0, 0, 0, 0}; // sphere2 + blobTree.structure[5] = {0, OP_UNION, 0, 0, 0, 0}; // Union of spheres = opNode2 + blobTree.structure[6] = {0, OP_DIFFERENCE, 0, 0, 1, 10 - 6}; // Difference of opNode1 and opNode2 = opNode3 + blobTree.structure[7] = {1, 0, 0, 0, 1, 9 - 7}; // Pyramid (sphere3) + blobTree.structure[8] = {1, 0, 0, 0, 0, 0}; // Cone + blobTree.structure[9] = {0, OP_UNION, 0, 0, 0, 0}; // UNION of Pyramid (sphere3) and Cone = opNode4 + blobTree.structure[10] = { + 0, OP_DIFFERENCE, 0, 0, 1, 12 - 10}; // Difference of opNode3 and opNode4 = opNode5 + // blobTree.structure[11] = {1, 0, 0, 0, 0, 0}; // Cylinder // blobTree.structure[12] = {0, 2, 0, 0, 1, 0}; // Difference of opNode5 and Cylinder // blobTree.primitiveNodeIdx = {0, 1, 3, 4, 7, 8, 11}; // quadratureScene(primitiveDescriptions, uvector3(-1., -1.3, -1.6), uvector3(1.6, 1.6, 2.3), blobTree); @@ -193,6 +219,35 @@ void caseScene1() quadratureScene(primitiveDescriptions, uvector3(-0.8, -1.3, -1.6), uvector3(1.6, 1.6, 1.5), blobTree); } +void caseScene2() +{ + const int PRIMITIVE_CNT = 4; + std::vector> primitiveDescriptions(PRIMITIVE_CNT); + primitiveDescriptions[0] = std::make_shared(CuboidDesc(0., 1.6)); + primitiveDescriptions[1] = std::make_shared(CuboidDesc(uvector3(0.6, 0.6, -0.6), 2.)); + primitiveDescriptions[2] = std::make_shared(SphereDesc(0.7, uvector3(0.8, 0.8, 0.8), 1.)); + primitiveDescriptions[3] = std::make_shared(SphereDesc(0.5, uvector3(-0.3, -0.8, 0.8), 1.)); + std::vector pyramidBottomVertices = { + uvector3{-1, -1, 0}, + uvector3{1, -1, 0}, + uvector3{1, 1, 0}, + uvector3{-1, 1, 0} + }; + organizer::BlobTree blobTree; + blobTree.structure.resize(PRIMITIVE_CNT * 2 - 1); + blobTree.primitiveNodeIdx.resize(PRIMITIVE_CNT); + // blobTree.structure[0] = {0, 0, NODE_IN_OUT_UNKNOWN, 0, 1, 2}; // cube1 + blobTree.structure[0] = {1, 0, NODE_IN_OUT_UNKNOWN, 0, 1, 2 - 0}; // cube1 + blobTree.structure[1] = {1, 0, NODE_IN_OUT_UNKNOWN, 0, 0, 0}; // cube2 + blobTree.structure[2] = {0, OP_UNION, NODE_IN_OUT_UNKNOWN, 0, 1, 6 - 2}; // INTERSECTION of cubes = opNode1 + blobTree.structure[3] = {1, 0, 0, 0, 1, 5 - 3}; // sphere1 + blobTree.structure[4] = {1, 0, 0, 0, 0, 0}; // sphere2 + blobTree.structure[5] = {0, OP_UNION, 0, 0, 0, 0}; // Union of spheres = opNode2 + blobTree.structure[6] = {0, OP_DIFFERENCE, 0, 0, 1, 10 - 6}; // Difference of opNode1 and opNode2 = opNode3 + blobTree.primitiveNodeIdx = {0, 1, 3, 4}; + quadratureScene(primitiveDescriptions, uvector3(-0.8, -1.3, -1.6), uvector3(1.6, 1.6, 1.5), blobTree); +} + void testDeCasteljau() { auto phiDesc = std::make_shared(SphereDesc(0.8, uvector3(0), 1.)); @@ -360,8 +415,10 @@ void testPrimitive() // casePolyhedronSphere(); // testSubDivideWithDeCasteljau(); // testBlob(); - // caseScene(); - caseScene1(); + caseScene(); + // caseScene1(); + // caseScene2(); + // caseCone(); // testPlaneWithinSubcell(); // caseCubeSphere(); // caseTwoCube();