|
@ -1,16 +1,19 @@ |
|
|
#pragma once |
|
|
#pragma once |
|
|
#include <vector> |
|
|
#include <vector> |
|
|
|
|
|
#include <cassert> |
|
|
|
|
|
#include <iostream> |
|
|
|
|
|
|
|
|
namespace algoim::organizer |
|
|
namespace algoim::organizer |
|
|
{ |
|
|
{ |
|
|
// bitfield
|
|
|
// bitfield
|
|
|
struct Blob { |
|
|
struct Blob { |
|
|
unsigned int isPrimitive : 1; // 1 for leaf
|
|
|
unsigned int isPrimitive : 1; // 1 for leaf
|
|
|
unsigned int nodeOp : 5; // 0 for intersection, 1 for union, 2 for difference
|
|
|
unsigned int nodeOp : 2; // 0 for union, 1 for intersection, 2 for difference
|
|
|
// unsigned int ignoreMod : 2; // 目前用不到
|
|
|
// unsigned int ignoreMod : 2; // 目前用不到
|
|
|
unsigned int inOut : 2; // 0 for unknown, 1 for in, 2 for out
|
|
|
unsigned int inOut : 2; // 0 for unknown, 1 for in, 2 for out
|
|
|
unsigned int isLeft : 1; |
|
|
unsigned int oneChildInOut : 2; // 0 for unknown, 1 for in, 2 for out
|
|
|
unsigned int ancestor : 23; |
|
|
unsigned int isLeft : 1; |
|
|
|
|
|
unsigned int ancestor : 24; |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
bool isPrimitive(Blob b) { return b.isPrimitive == 1; } |
|
|
bool isPrimitive(Blob b) { return b.isPrimitive == 1; } |
|
@ -19,36 +22,78 @@ unsigned int type(Blob b) { return 0; } |
|
|
|
|
|
|
|
|
bool isLeft(Blob b) { return b.isLeft == 1; } |
|
|
bool isLeft(Blob b) { return b.isLeft == 1; } |
|
|
|
|
|
|
|
|
struct BlobTree { |
|
|
class BlobTree |
|
|
std::vector<Blob> structure; |
|
|
{ |
|
|
|
|
|
public: |
|
|
|
|
|
std::vector<Blob> structure; |
|
|
|
|
|
std::vector<unsigned int> primtiveNodeIdx; |
|
|
|
|
|
|
|
|
|
|
|
BlobTree() {} |
|
|
}; |
|
|
}; |
|
|
|
|
|
|
|
|
void propagate(BlobTree &tree, unsigned int nodeIdx, bool in) |
|
|
void propagate(BlobTree& tree, unsigned int nodeIdx, bool in) |
|
|
{ |
|
|
{ |
|
|
const std::size_t rootIdx = tree.structure.size() - 1; |
|
|
const std::size_t rootIdx = tree.structure.size() - 1; |
|
|
|
|
|
auto& node = tree.structure[nodeIdx]; |
|
|
|
|
|
assert(node.inOut == 0); |
|
|
|
|
|
node.inOut = in ? 1 : 2; |
|
|
for (unsigned int nowIdx = nodeIdx; nowIdx != rootIdx; ++nodeIdx) { |
|
|
for (unsigned int nowIdx = nodeIdx; nowIdx != rootIdx; ++nodeIdx) { |
|
|
unsigned int nextIdx = isLeft(tree.structure[nowIdx]) ? tree.structure[nowIdx].ancestor : nodeIdx + 1; |
|
|
const auto& nowNode = tree.structure[nowIdx]; |
|
|
if (tree.structure[nowIdx].inOut == 2) { |
|
|
unsigned int nextIdx = isLeft(nowNode) ? nowNode.ancestor : nodeIdx + 1; |
|
|
|
|
|
auto& nextNode = tree.structure[nextIdx]; |
|
|
|
|
|
if (nextNode.inOut != 0) { return; } |
|
|
|
|
|
if (nowNode.inOut == 2) { |
|
|
// out
|
|
|
// out
|
|
|
if (tree.structure[nextIdx].nodeOp == 0) { |
|
|
if (nextNode.nodeOp == 1) { |
|
|
// intersection
|
|
|
// intersection
|
|
|
tree.structure[nextIdx].inOut = 2; |
|
|
} else if (nextNode.nodeOp == 2 && isLeft(nowNode)) { |
|
|
nextIdx = nowIdx; |
|
|
// difference and left
|
|
|
continue; |
|
|
nextNode.inOut = 2; |
|
|
} else if (tree.structure[nextIdx].nodeOp == 2 && isLeft(tree.structure[nowIdx])) { |
|
|
} else if (nextNode.oneChildInOut == 1) { |
|
|
// difference
|
|
|
// 两种情况,Union: in, Difference: NowNode一定是right,in-out,还是in
|
|
|
tree.structure[nextIdx].inOut = 2; |
|
|
nextNode.inOut = 1; |
|
|
nextIdx = nowIdx; |
|
|
} else if (nextNode.oneChildInOut == 2) { |
|
|
// continue;
|
|
|
// 两种情况,Union: out, Difference: out-out, 还是out
|
|
|
|
|
|
nextNode.inOut = 2; |
|
|
} else { |
|
|
} else { |
|
|
|
|
|
nextNode.oneChildInOut = 2; |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
} else if (tree.structure[nowIdx].inOut == 1) { |
|
|
} else if (nowNode.inOut == 1) { |
|
|
// in
|
|
|
// in
|
|
|
// TODO:
|
|
|
if (nextNode.nodeOp == 0) { |
|
|
|
|
|
// union
|
|
|
|
|
|
nextNode.inOut = 1; |
|
|
|
|
|
} else if (nextNode.nodeOp == 2 && !isLeft(nowNode)) { |
|
|
|
|
|
// difference and right
|
|
|
|
|
|
nextNode.inOut = 2; |
|
|
|
|
|
} else if (nextNode.oneChildInOut == 1) { |
|
|
|
|
|
// 两种情况,Intersection: in, Difference: in-in,out
|
|
|
|
|
|
nextNode.inOut = nextNode.nodeOp == 1 ? 1 : 2; |
|
|
|
|
|
} else if (nextNode.oneChildInOut == 2) { |
|
|
|
|
|
// 两种情况,Intersection: out, Difference: NowNode一定是left,in-out,in
|
|
|
|
|
|
nextNode.inOut = nextNode.nodeOp == 1 ? 2 : 1; |
|
|
|
|
|
} else { |
|
|
|
|
|
nextNode.oneChildInOut = 1; |
|
|
|
|
|
return; |
|
|
|
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
nextIdx = nowIdx; |
|
|
} |
|
|
} |
|
|
return; |
|
|
return; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
// 这里传入的是拷贝,因为要修改,但不同traversal的修改不相互影响
|
|
|
|
|
|
// TODO: 最好优化掉拷贝
|
|
|
|
|
|
// TODO: std::vector<bool> 可以改成bitset之类
|
|
|
|
|
|
bool traverse(BlobTree tree, std::vector<int> possiblePrimtivies, const std::vector<bool>& primitiveInout) |
|
|
|
|
|
{ |
|
|
|
|
|
assert(possiblePrimtivies.size() == tree.primtiveNodeIdx.size()); |
|
|
|
|
|
for (int nodeIdx : tree.primtiveNodeIdx) { |
|
|
|
|
|
propagate(tree, nodeIdx, primitiveInout[]); |
|
|
|
|
|
if (tree.structure.back().inOut != 0) { return tree.structure.back().inOut == 1; } |
|
|
|
|
|
} |
|
|
|
|
|
std::cerr << "should not be here" << std::endl; |
|
|
|
|
|
return false; |
|
|
|
|
|
} |
|
|
}; // namespace algoim::organizer
|
|
|
}; // namespace algoim::organizer
|
|
|