Blender V5.0
dualcon/intern/octree.h
Go to the documentation of this file.
1/* SPDX-FileCopyrightText: 2011-2023 Blender Authors
2 *
3 * SPDX-License-Identifier: GPL-2.0-or-later */
4
5#ifndef __OCTREE_H__
6#define __OCTREE_H__
7
8#include "GeoCommon.h"
9#include "MemoryAllocator.h"
10#include "ModelReader.h"
11#include "Projections.h"
12#include "cubes.h"
13#include "dualcon.h"
14#include "manifold_table.h"
15#include <cassert>
16#include <cstdio>
17#include <cstring>
18
25
26/* Global defines */
27/* Uncomment to see debug information */
28// #define IN_DEBUG_MODE
29
30/* Uncomment to see more output messages during repair */
31// #define IN_VERBOSE_MODE
32
33/* Set scan convert params */
34
35#define EDGE_FLOATS 4
36
37union Node;
38struct LeafNode;
39
41 /* Initialized in Octree::BuildTable */
42 static int numChildrenTable[256];
43 static int childrenCountTable[256][8];
44 static int childrenIndexTable[256][8];
45
46 /* Bit N indicates whether child N exists or not */
47 unsigned char has_child_bitfield;
48 /* Bit N indicates whether child N is a leaf or not */
50
51 /* Can have up to eight children */
53
55 int is_child_leaf(int index) const
56 {
57 return (child_is_leaf_bitfield >> index) & 1;
58 }
59
61 int has_child(int index) const
62 {
63 return (has_child_bitfield >> index) & 1;
64 }
65
68 {
69 return children[count];
70 }
71
72 const Node *get_child(int count) const
73 {
74 return children[count];
75 }
76
78 int get_num_children() const
79 {
81 }
82
84 int get_child_count(int index) const
85 {
87 }
92 const int *get_child_counts() const
93 {
95 }
96
98 void fill_children(Node *children[8], int leaf[8])
99 {
100 int count = 0;
101 for (int i = 0; i < 8; i++) {
102 leaf[i] = is_child_leaf(i);
103 if (has_child(i)) {
105 count++;
106 }
107 else {
108 children[i] = nullptr;
109 leaf[i] = 0;
110 }
111 }
112 }
113
115 void set_child(int count, Node *chd)
116 {
117 children[count] = chd;
118 }
119 void set_internal_child(int index, int count, InternalNode *chd)
120 {
121 set_child(count, (Node *)chd);
122 has_child_bitfield |= (1 << index);
123 }
124 void set_leaf_child(int index, int count, LeafNode *chd)
125 {
126 set_child(count, (Node *)chd);
127 has_child_bitfield |= (1 << index);
128 child_is_leaf_bitfield |= (1 << index);
129 }
130};
131
143struct LeafNode /* TODO: remove this attribute once everything is fixed */ {
144 unsigned short edge_parity : 12;
145 unsigned short primary_edge_intersections : 3;
146
147 /* XXX: maybe actually unused? */
148 unsigned short in_process : 1;
149
150 /* bitfield */
151 char signs;
152
154
155 unsigned short flood_fill;
156
158};
159
160/* Doesn't get directly allocated anywhere, just used for passing
161 pointers to nodes that could be internal or leaf. */
162union Node {
165};
166
167/* Global variables */
168extern const int edgemask[3];
169extern const int faceMap[6][4];
170extern const int cellProcFaceMask[12][3];
171extern const int cellProcEdgeMask[6][5];
172extern const int faceProcFaceMask[3][4][3];
173extern const int edgeProcEdgeMask[3][2][5];
174extern const int faceProcEdgeMask[3][4][6];
175extern const int processEdgeMask[3][4];
176extern const int dirCell[3][4][3];
177extern const int dirEdge[3][4];
178
182
184 /* Origin */
185 int pos[3];
186
187 /* link */
189};
190
191struct PathList {
192 /* Head */
195
196 /* Length of the list */
198
199 /* Next list */
201};
202
206class Octree {
207 public:
208 /* Public members */
209
213
216
219
222
224 int dimen;
226
229
231 float origin[3];
232 float range;
233
238
240
242
244 int outType; /* 0 for OFF, 1 for PLY, 2 for VOL */
245
246 /* For flood filling */
248 float thresh;
249
251
253
255
260 DualConAllocOutput alloc_output_func,
261 DualConAddVert add_vert_func,
262 DualConAddQuad add_quad_func,
263 DualConFlags flags,
264 DualConMode dualcon_mode,
265 int depth,
266 float threshold,
267 float sharpness);
268
273
277 void scanConvert();
278
280 {
281 return output_mesh;
282 }
283
284 private:
285 /* Helper functions */
286
290 void initMemory();
291
295 void freeMemory();
296
300 void printMemUsage();
301
305 void resetMinimalEdges();
306
307 void cellProcParity(Node *node, int leaf, int depth);
308 void faceProcParity(Node *node[2], const int leaf[2], const int depth[2], int maxdep, int dir);
309 void edgeProcParity(Node *node[4], const int leaf[4], const int depth[4], int maxdep, int dir);
310
311 void processEdgeParity(LeafNode *node[4], const int depths[4], int maxdep, int dir);
312
316 void addAllTriangles();
317 void addTriangle(Triangle *trian, int triind);
318 InternalNode *addTriangle(InternalNode *node, CubeTriangleIsect *p, int height);
319
323 LeafNode *updateCell(LeafNode *node, CubeTriangleIsect *p);
324
325 /* Routines to detect and patch holes */
326 int numRings;
327 int totRingLengths;
328 int maxRingLength;
329
333 void trace();
337 Node *trace(Node *node, int *st, int len, int depth, PathList *&paths);
341 void findPaths(Node *node[2],
342 const int leaf[2],
343 const int depth[2],
344 int *st[2],
345 int maxdep,
346 int dir,
347 PathList *&paths);
352 void combinePaths(PathList *&list1, PathList *list2, PathList *paths, PathList *&rings);
356 PathList *combineSinglePath(PathList *&head1,
357 PathList *pre1,
358 PathList *&list1,
359 PathList *&head2,
360 PathList *pre2,
361 PathList *&list2);
362
366 Node *patch(Node *node, int st[3], int len, PathList *rings);
367 Node *patchSplit(Node *node,
368 int st[3],
369 int len,
370 PathList *rings,
371 int dir,
372 PathList *&nrings1,
373 PathList *&nrings2);
374 Node *patchSplitSingle(Node *node,
375 int st[3],
376 int len,
377 PathElement *head,
378 int dir,
379 PathList *&nrings1,
380 PathList *&nrings2);
381 Node *connectFace(Node *node, int st[3], int len, int dir, PathElement *f1, PathElement *f2);
382 Node *locateCell(InternalNode *node,
383 const int st[3],
384 int len,
385 int ori[3],
386 int dir,
387 int side,
388 Node *&rleaf,
389 int rst[3],
390 int &rlen);
391 void compressRing(PathElement *&ring);
392 void getFacePoint(PathElement *leaf, int dir, int &x, int &y, float &p, float &q);
393 LeafNode *patchAdjacent(InternalNode *node,
394 int len,
395 int st1[3],
396 LeafNode *leaf1,
397 int st2[3],
398 LeafNode *leaf2,
399 int walkdir,
400 int inc,
401 int dir,
402 int side,
403 float alpha);
404 int findPair(PathElement *head, int pos, int dir, PathElement *&pre1, PathElement *&pre2);
405 int getSide(PathElement *e, int pos, int dir);
406 int isEqual(PathElement *e1, PathElement *e2);
407 void preparePrimalEdgesMask(InternalNode *node);
408 void testFacePoint(PathElement *e1, PathElement *e2);
409
413 void deletePath(PathList *&head, PathList *pre, PathList *&curr);
414 void printPath(PathList *path);
415 void printPath(PathElement *path);
416 void printElement(PathElement *ele);
417 void printPaths(PathList *path);
418 void checkElement(PathElement *ele);
419 void checkPath(PathElement *path);
420
425 void buildSigns();
426 void buildSigns(unsigned char table[], Node *node, int isLeaf, int sg, int rvalue[8]);
427
428 /************************************************************************/
429 /* To remove disconnected components */
430 /************************************************************************/
431 void floodFill();
432 void clearProcessBits(Node *node, int height);
433 int floodFill(LeafNode *leaf, const int st[3], int len, int height, int threshold);
434 int floodFill(Node *node, int st[3], int len, int height, int threshold);
435
439 void writeOut();
440
441 void countIntersection(Node *node, int height, int &nedge, int &ncell, int &nface);
442 void generateMinimizer(Node *node, int st[3], int len, int height, int &offset);
443 void computeMinimizer(const LeafNode *leaf, int st[3], int len, float rvalue[3]) const;
448 void cellProcContour(Node *node, int leaf, int depth);
449 void faceProcContour(Node *node[2], const int leaf[2], const int depth[2], int maxdep, int dir);
450 void edgeProcContour(Node *node[4], const int leaf[4], int depth[4], int maxdep, int dir);
451 void processEdgeWrite(Node *node[4], int depths[4], int maxdep, int dir);
452
453 /* output callbacks/data */
454 DualConAllocOutput alloc_output;
455 DualConAddVert add_vert;
456 DualConAddQuad add_quad;
457 void *output_mesh;
458
459 /************ Operators for all nodes ************/
460
462 int numEdgeTable[8];
463 int edgeCountTable[8][3];
464
466 void buildTable()
467 {
468 for (int i = 0; i < 256; i++) {
470 int count = 0;
471 for (int j = 0; j < 8; j++) {
472 InternalNode::numChildrenTable[i] += ((i >> j) & 1);
475 count += ((i >> j) & 1);
476 }
477 }
478
479 for (int i = 0; i < 8; i++) {
480 numEdgeTable[i] = 0;
481 int count = 0;
482 for (int j = 0; j < 3; j++) {
483 numEdgeTable[i] += ((i >> j) & 1);
484 edgeCountTable[i][j] = count;
485 count += ((i >> j) & 1);
486 }
487 }
488 }
489
490 int getSign(Node *node, int height, int index)
491 {
492 if (height == 0) {
493 return getSign(&node->leaf, index);
494 }
495 if (node->internal.has_child(index)) {
496 return getSign(
497 node->internal.get_child(node->internal.get_child_count(index)), height - 1, index);
498 }
499 return getSign(node->internal.get_child(0), height - 1, 7 - node->internal.get_child_index(0));
500 }
501
502 /************ Operators for leaf nodes ************/
503
504 void printInfo(int st[3])
505 {
506 printf("INFO AT: %d %d %d\n", st[0] >> minshift, st[1] >> minshift, st[2] >> minshift);
507 LeafNode *leaf = locateLeafCheck(st);
508 if (leaf) {
509 printInfo(leaf);
510 }
511 else {
512 printf("Leaf not exists!\n");
513 }
514 }
515
516 void printInfo(const LeafNode *leaf)
517 {
518 /*
519 printf("Edge mask: ");
520 for(int i = 0; i < 12; i ++)
521 {
522 printf("%d ", getEdgeParity(leaf, i));
523 }
524 printf("\n");
525 printf("Stored edge mask: ");
526 for(i = 0; i < 3; i ++)
527 {
528 printf("%d ", getStoredEdgesParity(leaf, i));
529 }
530 printf("\n");
531 */
532 printf("Sign mask: ");
533 for (int i = 0; i < 8; i++) {
534 printf("%d ", getSign(leaf, i));
535 }
536 printf("\n");
537 }
538
540 int getSign(const LeafNode *leaf, int index)
541 {
542 return ((leaf->signs >> index) & 1);
543 }
544
546 void setSign(LeafNode *leaf, int index)
547 {
548 leaf->signs |= (1 << index);
549 }
550
551 void setSign(LeafNode *leaf, int index, int sign)
552 {
553 leaf->signs &= (~(1 << index));
554 leaf->signs |= ((sign & 1) << index);
555 }
556
557 int getSignMask(const LeafNode *leaf) const
558 {
559 return leaf->signs;
560 }
561
562 void setInProcessAll(const int st[3], int dir)
563 {
564 int nst[3], eind;
565 for (int i = 0; i < 4; i++) {
566 nst[0] = st[0] + dirCell[dir][i][0] * mindimen;
567 nst[1] = st[1] + dirCell[dir][i][1] * mindimen;
568 nst[2] = st[2] + dirCell[dir][i][2] * mindimen;
569 eind = dirEdge[dir][i];
570
571 LeafNode *cell = locateLeafCheck(nst);
572 assert(cell);
573
574 setInProcess(cell, eind);
575 }
576 }
577
578 void flipParityAll(const int st[3], int dir)
579 {
580 int nst[3], eind;
581 for (int i = 0; i < 4; i++) {
582 nst[0] = st[0] + dirCell[dir][i][0] * mindimen;
583 nst[1] = st[1] + dirCell[dir][i][1] * mindimen;
584 nst[2] = st[2] + dirCell[dir][i][2] * mindimen;
585 eind = dirEdge[dir][i];
586
587 LeafNode *cell = locateLeaf(nst);
588 flipEdge(cell, eind);
589 }
590 }
591
592 void setInProcess(LeafNode *leaf, int eind)
593 {
594 assert(eind >= 0 && eind <= 11);
595
596 leaf->flood_fill |= (1 << eind);
597 }
598
599 void setOutProcess(LeafNode *leaf, int eind)
600 {
601 assert(eind >= 0 && eind <= 11);
602
603 leaf->flood_fill &= ~(1 << eind);
604 }
605
606 int isInProcess(LeafNode *leaf, int eind)
607 {
608 assert(eind >= 0 && eind <= 11);
609
610 return (leaf->flood_fill >> eind) & 1;
611 }
612
614 void generateSigns(LeafNode *leaf, const unsigned char table[], int start)
615 {
616 leaf->signs = table[leaf->edge_parity];
617
618 if ((start ^ leaf->signs) & 1) {
619 leaf->signs = ~(leaf->signs);
620 }
621 }
622
624 int getEdgeParity(const LeafNode *leaf, int index) const
625 {
626 assert(index >= 0 && index <= 11);
627
628 return (leaf->edge_parity >> index) & 1;
629 }
630
632 int getFaceParity(LeafNode *leaf, int index)
633 {
634 int a = getEdgeParity(leaf, faceMap[index][0]) + getEdgeParity(leaf, faceMap[index][1]) +
635 getEdgeParity(leaf, faceMap[index][2]) + getEdgeParity(leaf, faceMap[index][3]);
636 return (a & 1);
637 }
638 int getFaceEdgeNum(LeafNode *leaf, int index)
639 {
640 int a = getEdgeParity(leaf, faceMap[index][0]) + getEdgeParity(leaf, faceMap[index][1]) +
641 getEdgeParity(leaf, faceMap[index][2]) + getEdgeParity(leaf, faceMap[index][3]);
642 return a;
643 }
644
646 void flipEdge(LeafNode *leaf, int index)
647 {
648 assert(index >= 0 && index <= 11);
649
650 leaf->edge_parity ^= (1 << index);
651 }
652
654 void setEdge(LeafNode *leaf, int index)
655 {
656 assert(index >= 0 && index <= 11);
657
658 leaf->edge_parity |= (1 << index);
659 }
660
662 void resetEdge(LeafNode *leaf, int index)
663 {
664 assert(index >= 0 && index <= 11);
665
666 leaf->edge_parity &= ~(1 << index);
667 }
668
670 void createPrimalEdgesMask(LeafNode *leaf)
671 {
672 leaf->primary_edge_intersections = getPrimalEdgesMask2(leaf);
673 }
674
675 void setStoredEdgesParity(LeafNode *leaf, int pindex)
676 {
677 assert(pindex <= 2 && pindex >= 0);
678
679 leaf->primary_edge_intersections |= (1 << pindex);
680 }
681
682 int getStoredEdgesParity(const LeafNode *leaf, int pindex) const
683 {
684 assert(pindex <= 2 && pindex >= 0);
685
686 return (leaf->primary_edge_intersections >> pindex) & 1;
687 }
688
689 LeafNode *flipEdge(LeafNode *leaf, int index, float alpha)
690 {
691 flipEdge(leaf, index);
692
693 if ((index & 3) == 0) {
694 int ind = index / 4;
695 if (getEdgeParity(leaf, index) && !getStoredEdgesParity(leaf, ind)) {
696 /* Create a new node */
697 int num = getNumEdges(leaf) + 1;
698 setStoredEdgesParity(leaf, ind);
699 int count = getEdgeCount(leaf, ind);
700 LeafNode *nleaf = createLeaf(num);
701 *nleaf = *leaf;
702
703 setEdgeOffset(nleaf, alpha, count);
704
705 if (num > 1) {
706 float *pts = leaf->edge_intersections;
707 float *npts = nleaf->edge_intersections;
708 for (int i = 0; i < count; i++) {
709 for (int j = 0; j < EDGE_FLOATS; j++) {
710 npts[i * EDGE_FLOATS + j] = pts[i * EDGE_FLOATS + j];
711 }
712 }
713 for (int i = count + 1; i < num; i++) {
714 for (int j = 0; j < EDGE_FLOATS; j++) {
715 npts[i * EDGE_FLOATS + j] = pts[(i - 1) * EDGE_FLOATS + j];
716 }
717 }
718 }
719
720 removeLeaf(num - 1, leaf);
721 leaf = nleaf;
722 }
723 }
724
725 return leaf;
726 }
727
729 void updateParent(InternalNode *node, int len, int st[3], LeafNode *leaf)
730 {
731 /* First, locate the parent */
732 int count;
733 InternalNode *parent = locateParent(node, len, st, count);
734
735 /* Update */
736 parent->set_child(count, (Node *)leaf);
737 }
738
739 void updateParent(InternalNode *node, int len, int st[3])
740 {
741 if (len == dimen) {
742 root = (Node *)node;
743 return;
744 }
745
746 /* First, locate the parent */
747 int count;
748 InternalNode *parent = locateParent(len, st, count);
749
750 /* Update */
751 parent->set_child(count, (Node *)node);
752 }
753
755 int getEdgeIntersectionByIndex(int st[3], int index, float pt[3], int check) const
756 {
757 /* First, locat the leaf */
758 const LeafNode *leaf;
759 if (check) {
760 leaf = locateLeafCheck(st);
761 }
762 else {
763 leaf = locateLeaf(st);
764 }
765
766 if (leaf && getStoredEdgesParity(leaf, index)) {
767 float off = getEdgeOffset(leaf, getEdgeCount(leaf, index));
768 pt[0] = (float)st[0];
769 pt[1] = (float)st[1];
770 pt[2] = (float)st[2];
771 pt[index] += off * mindimen;
772
773 return 1;
774 }
775 return 0;
776 }
777
779 int getPrimalEdgesMask(const LeafNode *leaf) const
780 {
781 return leaf->primary_edge_intersections;
782 }
783
784 int getPrimalEdgesMask2(LeafNode *leaf)
785 {
786 return (((leaf->edge_parity & 0x1) >> 0) | ((leaf->edge_parity & 0x10) >> 3) |
787 ((leaf->edge_parity & 0x100) >> 6));
788 }
789
791 int getEdgeCount(const LeafNode *leaf, int index) const
792 {
793 return edgeCountTable[getPrimalEdgesMask(leaf)][index];
794 }
795 int getNumEdges(LeafNode *leaf)
796 {
797 return numEdgeTable[getPrimalEdgesMask(leaf)];
798 }
799
800 int getNumEdges2(LeafNode *leaf)
801 {
802 return numEdgeTable[getPrimalEdgesMask2(leaf)];
803 }
804
806 void setEdgeOffset(LeafNode *leaf, float pt, int count)
807 {
808 float *pts = leaf->edge_intersections;
809 pts[EDGE_FLOATS * count] = pt;
810 pts[EDGE_FLOATS * count + 1] = 0;
811 pts[EDGE_FLOATS * count + 2] = 0;
812 pts[EDGE_FLOATS * count + 3] = 0;
813 }
814
816 void setEdgeOffsets(LeafNode *leaf, const float pt[3], int len)
817 {
818 float *pts = leaf->edge_intersections;
819 for (int i = 0; i < len; i++) {
820 pts[i] = pt[i];
821 }
822 }
823
825 float getEdgeOffset(const LeafNode *leaf, int count) const
826 {
827 return leaf->edge_intersections[4 * count];
828 }
829
831 LeafNode *updateEdgeOffsets(LeafNode *leaf, int oldlen, int newlen, float offs[3])
832 {
833 /* First, create a new leaf node */
834 LeafNode *nleaf = createLeaf(newlen);
835 *nleaf = *leaf;
836
837 /* Next, fill in the offsets */
838 setEdgeOffsets(nleaf, offs, newlen);
839
840 /* Finally, delete the old leaf */
841 removeLeaf(oldlen, leaf);
842
843 return nleaf;
844 }
845
847 void setMinimizerIndex(LeafNode *leaf, int index)
848 {
849 leaf->minimizer_index = index;
850 }
851
853 int getMinimizerIndex(LeafNode *leaf)
854 {
855 return leaf->minimizer_index;
856 }
857
858 int getMinimizerIndex(LeafNode *leaf, int eind)
859 {
860 int add = manifold_table[getSignMask(leaf)].pairs[eind][0] - 1;
861 assert(add >= 0);
862 return leaf->minimizer_index + add;
863 }
864
865 void getMinimizerIndices(LeafNode *leaf, int eind, int inds[2])
866 {
867 const int *add = manifold_table[getSignMask(leaf)].pairs[eind];
868 inds[0] = leaf->minimizer_index + add[0] - 1;
869 if (add[0] == add[1]) {
870 inds[1] = -1;
871 }
872 else {
873 inds[1] = leaf->minimizer_index + add[1] - 1;
874 }
875 }
876
878 void setEdgeOffsetNormal(LeafNode *leaf, float pt, float a, float b, float c, int count)
879 {
880 float *pts = leaf->edge_intersections;
881 pts[4 * count] = pt;
882 pts[4 * count + 1] = a;
883 pts[4 * count + 2] = b;
884 pts[4 * count + 3] = c;
885 }
886
887 float getEdgeOffsetNormal(LeafNode *leaf, int count, float &a, float &b, float &c)
888 {
889 float *pts = leaf->edge_intersections;
890 a = pts[4 * count + 1];
891 b = pts[4 * count + 2];
892 c = pts[4 * count + 3];
893 return pts[4 * count];
894 }
895
897 void setEdgeOffsetsNormals(
898 LeafNode *leaf, const float pt[], const float a[], const float b[], const float c[], int len)
899 {
900 float *pts = leaf->edge_intersections;
901 for (int i = 0; i < len; i++) {
902 if (pt[i] > 1 || pt[i] < 0) {
903 printf("\noffset: %f\n", pt[i]);
904 }
905 pts[i * 4] = pt[i];
906 pts[i * 4 + 1] = a[i];
907 pts[i * 4 + 2] = b[i];
908 pts[i * 4 + 3] = c[i];
909 }
910 }
911
913 void getEdgeIntersectionByIndex(
914 const LeafNode *leaf, int index, const int st[3], int len, float pt[3], float nm[3]) const
915 {
916 int count = getEdgeCount(leaf, index);
917 const float *pts = leaf->edge_intersections;
918
919 float off = pts[4 * count];
920
921 pt[0] = (float)st[0];
922 pt[1] = (float)st[1];
923 pt[2] = (float)st[2];
924 pt[index] += (off * len);
925
926 nm[0] = pts[4 * count + 1];
927 nm[1] = pts[4 * count + 2];
928 nm[2] = pts[4 * count + 3];
929 }
930
931 float getEdgeOffsetNormalByIndex(LeafNode *leaf, int index, float nm[3])
932 {
933 int count = getEdgeCount(leaf, index);
934 float *pts = leaf->edge_intersections;
935
936 float off = pts[4 * count];
937
938 nm[0] = pts[4 * count + 1];
939 nm[1] = pts[4 * count + 2];
940 nm[2] = pts[4 * count + 3];
941
942 return off;
943 }
944
945 void fillEdgeIntersections(
946 const LeafNode *leaf, int st[3], int len, float pts[12][3], float norms[12][3]) const
947 {
948 int i;
949 // int stt[3] = {0, 0, 0};
950
951 // The three primal edges are easy
952 int pmask[3] = {0, 4, 8};
953 for (i = 0; i < 3; i++) {
954 if (getEdgeParity(leaf, pmask[i])) {
955 // getEdgeIntersectionByIndex(leaf, i, stt, 1, pts[pmask[i]], norms[pmask[i]]);
956 getEdgeIntersectionByIndex(leaf, i, st, len, pts[pmask[i]], norms[pmask[i]]);
957 }
958 }
959
960 // 3 face adjacent cubes
961 int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
962 int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
963 for (i = 0; i < 3; i++) {
964 int e1 = getEdgeParity(leaf, fmask[i][0]);
965 int e2 = getEdgeParity(leaf, fmask[i][1]);
966 if (e1 || e2) {
967 int nst[3] = {st[0], st[1], st[2]};
968 nst[i] += len;
969 // int nstt[3] = {0, 0, 0};
970 // nstt[i] += 1;
971 const LeafNode *node = locateLeaf(nst);
972
973 if (e1) {
974 // getEdgeIntersectionByIndex(node, femask[i][0], nstt, 1, pts[fmask[i][0]],
975 // norms[fmask[i][0]]);
976 getEdgeIntersectionByIndex(
977 node, femask[i][0], nst, len, pts[fmask[i][0]], norms[fmask[i][0]]);
978 }
979 if (e2) {
980 // getEdgeIntersectionByIndex(node, femask[i][1], nstt, 1, pts[fmask[i][1]],
981 // norms[fmask[i][1]]);
982 getEdgeIntersectionByIndex(
983 node, femask[i][1], nst, len, pts[fmask[i][1]], norms[fmask[i][1]]);
984 }
985 }
986 }
987
988 // 3 edge adjacent cubes
989 int emask[3] = {3, 7, 11};
990 int eemask[3] = {0, 1, 2};
991 for (i = 0; i < 3; i++) {
992 if (getEdgeParity(leaf, emask[i])) {
993 int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
994 nst[i] -= len;
995 // int nstt[3] = {1, 1, 1};
996 // nstt[i] -= 1;
997 const LeafNode *node = locateLeaf(nst);
998
999 // getEdgeIntersectionByIndex(node, eemask[i], nstt, 1, pts[emask[i]], norms[emask[i]]);
1000 getEdgeIntersectionByIndex(node, eemask[i], nst, len, pts[emask[i]], norms[emask[i]]);
1001 }
1002 }
1003 }
1004
1005 void fillEdgeIntersections(const LeafNode *leaf,
1006 int st[3],
1007 int len,
1008 float pts[12][3],
1009 float norms[12][3],
1010 int parity[12]) const
1011 {
1012 int i;
1013 for (i = 0; i < 12; i++) {
1014 parity[i] = 0;
1015 }
1016 // int stt[3] = {0, 0, 0};
1017
1018 // The three primal edges are easy
1019 int pmask[3] = {0, 4, 8};
1020 for (i = 0; i < 3; i++) {
1021 if (getStoredEdgesParity(leaf, i)) {
1022 // getEdgeIntersectionByIndex(leaf, i, stt, 1, pts[pmask[i]], norms[pmask[i]]);
1023 getEdgeIntersectionByIndex(leaf, i, st, len, pts[pmask[i]], norms[pmask[i]]);
1024 parity[pmask[i]] = 1;
1025 }
1026 }
1027
1028 // 3 face adjacent cubes
1029 int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
1030 int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
1031 for (i = 0; i < 3; i++) {
1032 {
1033 int nst[3] = {st[0], st[1], st[2]};
1034 nst[i] += len;
1035 // int nstt[3] = {0, 0, 0};
1036 // nstt[i] += 1;
1037 const LeafNode *node = locateLeafCheck(nst);
1038 if (node == nullptr) {
1039 continue;
1040 }
1041
1042 int e1 = getStoredEdgesParity(node, femask[i][0]);
1043 int e2 = getStoredEdgesParity(node, femask[i][1]);
1044
1045 if (e1) {
1046 // getEdgeIntersectionByIndex(node, femask[i][0], nstt, 1, pts[fmask[i][0]],
1047 // norms[fmask[i][0]]);
1048 getEdgeIntersectionByIndex(
1049 node, femask[i][0], nst, len, pts[fmask[i][0]], norms[fmask[i][0]]);
1050 parity[fmask[i][0]] = 1;
1051 }
1052 if (e2) {
1053 // getEdgeIntersectionByIndex(node, femask[i][1], nstt, 1, pts[fmask[i][1]],
1054 // norms[fmask[i][1]]);
1055 getEdgeIntersectionByIndex(
1056 node, femask[i][1], nst, len, pts[fmask[i][1]], norms[fmask[i][1]]);
1057 parity[fmask[i][1]] = 1;
1058 }
1059 }
1060 }
1061
1062 // 3 edge adjacent cubes
1063 int emask[3] = {3, 7, 11};
1064 int eemask[3] = {0, 1, 2};
1065 for (i = 0; i < 3; i++) {
1066 // if(getEdgeParity(leaf, emask[i]))
1067 {
1068 int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
1069 nst[i] -= len;
1070 // int nstt[3] = {1, 1, 1};
1071 // nstt[i] -= 1;
1072 const LeafNode *node = locateLeafCheck(nst);
1073 if (node == nullptr) {
1074 continue;
1075 }
1076
1077 if (getStoredEdgesParity(node, eemask[i])) {
1078 // getEdgeIntersectionByIndex(node, eemask[i], nstt, 1, pts[emask[i]], norms[emask[i]]);
1079 getEdgeIntersectionByIndex(node, eemask[i], nst, len, pts[emask[i]], norms[emask[i]]);
1080 parity[emask[i]] = 1;
1081 }
1082 }
1083 }
1084 }
1085
1086 void fillEdgeOffsetsNormals(
1087 LeafNode *leaf, int st[3], int len, float pts[12], float norms[12][3], int parity[12])
1088 {
1089 int i;
1090 for (i = 0; i < 12; i++) {
1091 parity[i] = 0;
1092 }
1093 // int stt[3] = {0, 0, 0};
1094
1095 // The three primal edges are easy
1096 int pmask[3] = {0, 4, 8};
1097 for (i = 0; i < 3; i++) {
1098 if (getStoredEdgesParity(leaf, i)) {
1099 pts[pmask[i]] = getEdgeOffsetNormalByIndex(leaf, i, norms[pmask[i]]);
1100 parity[pmask[i]] = 1;
1101 }
1102 }
1103
1104 // 3 face adjacent cubes
1105 int fmask[3][2] = {{6, 10}, {2, 9}, {1, 5}};
1106 int femask[3][2] = {{1, 2}, {0, 2}, {0, 1}};
1107 for (i = 0; i < 3; i++) {
1108 {
1109 int nst[3] = {st[0], st[1], st[2]};
1110 nst[i] += len;
1111 // int nstt[3] = {0, 0, 0};
1112 // nstt[i] += 1;
1113 LeafNode *node = locateLeafCheck(nst);
1114 if (node == nullptr) {
1115 continue;
1116 }
1117
1118 int e1 = getStoredEdgesParity(node, femask[i][0]);
1119 int e2 = getStoredEdgesParity(node, femask[i][1]);
1120
1121 if (e1) {
1122 pts[fmask[i][0]] = getEdgeOffsetNormalByIndex(node, femask[i][0], norms[fmask[i][0]]);
1123 parity[fmask[i][0]] = 1;
1124 }
1125 if (e2) {
1126 pts[fmask[i][1]] = getEdgeOffsetNormalByIndex(node, femask[i][1], norms[fmask[i][1]]);
1127 parity[fmask[i][1]] = 1;
1128 }
1129 }
1130 }
1131
1132 // 3 edge adjacent cubes
1133 int emask[3] = {3, 7, 11};
1134 int eemask[3] = {0, 1, 2};
1135 for (i = 0; i < 3; i++) {
1136 // if(getEdgeParity(leaf, emask[i]))
1137 {
1138 int nst[3] = {st[0] + len, st[1] + len, st[2] + len};
1139 nst[i] -= len;
1140 // int nstt[3] = {1, 1, 1};
1141 // nstt[i] -= 1;
1142 LeafNode *node = locateLeafCheck(nst);
1143 if (node == nullptr) {
1144 continue;
1145 }
1146
1147 if (getStoredEdgesParity(node, eemask[i])) {
1148 pts[emask[i]] = getEdgeOffsetNormalByIndex(node, eemask[i], norms[emask[i]]);
1149 parity[emask[i]] = 1;
1150 }
1151 }
1152 }
1153 }
1154
1156 LeafNode *updateEdgeOffsetsNormals(
1157 LeafNode *leaf, int oldlen, int newlen, float offs[3], float a[3], float b[3], float c[3])
1158 {
1159 /* First, create a new leaf node */
1160 LeafNode *nleaf = createLeaf(newlen);
1161 *nleaf = *leaf;
1162
1163 /* Next, fill in the offsets */
1164 setEdgeOffsetsNormals(nleaf, offs, a, b, c, newlen);
1165
1166 /* Finally, delete the old leaf */
1167 removeLeaf(oldlen, leaf);
1168
1169 return nleaf;
1170 }
1171
1176 LeafNode *locateLeaf(const int st[3])
1177 {
1178 Node *node = root;
1179 for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
1180 int index = (((st[0] >> i) & 1) << 2) | (((st[1] >> i) & 1) << 1) | (((st[2] >> i) & 1));
1181 node = node->internal.get_child(node->internal.get_child_count(index));
1182 }
1183
1184 return &node->leaf;
1185 }
1186
1187 const LeafNode *locateLeaf(const int st[3]) const
1188 {
1189 const Node *node = root;
1190 for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
1191 int index = (((st[0] >> i) & 1) << 2) | (((st[1] >> i) & 1) << 1) | (((st[2] >> i) & 1));
1192 node = node->internal.get_child(node->internal.get_child_count(index));
1193 }
1194
1195 return &node->leaf;
1196 }
1197
1198 LeafNode *locateLeaf(InternalNode *parent, int len, const int st[3])
1199 {
1200 Node *node = (Node *)parent;
1201 int index;
1202 for (int i = len / 2; i >= mindimen; i >>= 1) {
1203 index = (((st[0] & i) ? 4 : 0) | ((st[1] & i) ? 2 : 0) | ((st[2] & i) ? 1 : 0));
1204 node = node->internal.get_child(node->internal.get_child_count(index));
1205 }
1206
1207 return &node->leaf;
1208 }
1209
1210 LeafNode *locateLeafCheck(const int st[3])
1211 {
1212 Node *node = root;
1213 for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
1214 int index = (((st[0] >> i) & 1) << 2) | (((st[1] >> i) & 1) << 1) | (((st[2] >> i) & 1));
1215 if (!node->internal.has_child(index)) {
1216 return nullptr;
1217 }
1218 node = node->internal.get_child(node->internal.get_child_count(index));
1219 }
1220
1221 return &node->leaf;
1222 }
1223
1224 const LeafNode *locateLeafCheck(const int st[3]) const
1225 {
1226 const Node *node = root;
1227 for (int i = GRID_DIMENSION - 1; i > GRID_DIMENSION - maxDepth - 1; i--) {
1228 int index = (((st[0] >> i) & 1) << 2) | (((st[1] >> i) & 1) << 1) | (((st[2] >> i) & 1));
1229 if (!node->internal.has_child(index)) {
1230 return nullptr;
1231 }
1232 node = node->internal.get_child(node->internal.get_child_count(index));
1233 }
1234
1235 return &node->leaf;
1236 }
1237
1238 InternalNode *locateParent(int len, const int st[3], int &count)
1239 {
1240 InternalNode *node = (InternalNode *)root;
1241 InternalNode *pre = nullptr;
1242 int index = 0;
1243 for (int i = dimen / 2; i >= len; i >>= 1) {
1244 index = (((st[0] & i) ? 4 : 0) | ((st[1] & i) ? 2 : 0) | ((st[2] & i) ? 1 : 0));
1245 pre = node;
1246 node = &node->get_child(node->get_child_count(index))->internal;
1247 }
1248
1249 count = pre->get_child_count(index);
1250 return pre;
1251 }
1252
1253 InternalNode *locateParent(InternalNode *parent, int len, const int st[3], int &count)
1254 {
1255 InternalNode *node = parent;
1256 InternalNode *pre = nullptr;
1257 int index = 0;
1258 for (int i = len / 2; i >= mindimen; i >>= 1) {
1259 index = (((st[0] & i) ? 4 : 0) | ((st[1] & i) ? 2 : 0) | ((st[2] & i) ? 1 : 0));
1260 pre = node;
1261 node = &node->get_child(node->get_child_count(index))->internal;
1262 }
1263
1264 count = pre->get_child_count(index);
1265 return pre;
1266 }
1267
1268 /************ Operators for internal nodes ************/
1269
1271 InternalNode *addChild(InternalNode *node, int index, Node *child, int aLeaf)
1272 {
1273 // Create new internal node
1274 int num = node->get_num_children();
1275 InternalNode *rnode = createInternal(num + 1);
1276
1277 // Establish children
1278 int i;
1279 int count1 = 0, count2 = 0;
1280 for (i = 0; i < 8; i++) {
1281 if (i == index) {
1282 if (aLeaf) {
1283 rnode->set_leaf_child(i, count2, &child->leaf);
1284 }
1285 else {
1286 rnode->set_internal_child(i, count2, &child->internal);
1287 }
1288 count2++;
1289 }
1290 else if (node->has_child(i)) {
1291 if (node->is_child_leaf(i)) {
1292 rnode->set_leaf_child(i, count2, &node->get_child(count1)->leaf);
1293 }
1294 else {
1295 rnode->set_internal_child(i, count2, &node->get_child(count1)->internal);
1296 }
1297 count1++;
1298 count2++;
1299 }
1300 }
1301
1302 removeInternal(num, node);
1303 return rnode;
1304 }
1305
1307 InternalNode *createInternal(int length)
1308 {
1309 InternalNode *inode = (InternalNode *)alloc[length]->allocate();
1310 inode->has_child_bitfield = 0;
1311 inode->child_is_leaf_bitfield = 0;
1312 return inode;
1313 }
1314
1315 LeafNode *createLeaf(int length)
1316 {
1317 assert(length <= 3);
1318
1319 LeafNode *lnode = (LeafNode *)leafalloc[length]->allocate();
1320 lnode->edge_parity = 0;
1321 lnode->primary_edge_intersections = 0;
1322 lnode->signs = 0;
1323
1324 return lnode;
1325 }
1326
1327 void removeInternal(int num, InternalNode *node)
1328 {
1329 alloc[num]->deallocate(node);
1330 }
1331
1332 void removeLeaf(int num, LeafNode *leaf)
1333 {
1334 assert(num >= 0 && num <= 3);
1335 leafalloc[num]->deallocate(leaf);
1336 }
1337
1339 InternalNode *addLeafChild(InternalNode *par, int index, int count, LeafNode *leaf)
1340 {
1341 int num = par->get_num_children() + 1;
1342 InternalNode *npar = createInternal(num);
1343 *npar = *par;
1344
1345 if (num == 1) {
1346 npar->set_leaf_child(index, 0, leaf);
1347 }
1348 else {
1349 int i;
1350 for (i = 0; i < count; i++) {
1351 npar->set_child(i, par->get_child(i));
1352 }
1353 npar->set_leaf_child(index, count, leaf);
1354 for (i = count + 1; i < num; i++) {
1355 npar->set_child(i, par->get_child(i - 1));
1356 }
1357 }
1358
1359 removeInternal(num - 1, par);
1360 return npar;
1361 }
1362
1363 InternalNode *addInternalChild(InternalNode *par, int index, int count, InternalNode *node)
1364 {
1365 int num = par->get_num_children() + 1;
1366 InternalNode *npar = createInternal(num);
1367 *npar = *par;
1368
1369 if (num == 1) {
1370 npar->set_internal_child(index, 0, node);
1371 }
1372 else {
1373 int i;
1374 for (i = 0; i < count; i++) {
1375 npar->set_child(i, par->get_child(i));
1376 }
1377 npar->set_internal_child(index, count, node);
1378 for (i = count + 1; i < num; i++) {
1379 npar->set_child(i, par->get_child(i - 1));
1380 }
1381 }
1382
1383 removeInternal(num - 1, par);
1384 return npar;
1385 }
1386
1387 MEM_CXX_CLASS_ALLOC_FUNCS("DUALCON:Octree")
1388};
1389
1390#endif /* __OCTREE_H__ */
ATTR_WARN_UNUSED_RESULT const size_t num
#define GRID_DIMENSION
Definition Projections.h:13
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
virtual int getNumEdges() const
btBroadphasePair * findPair(btBroadphaseProxy *proxy0, btBroadphaseProxy *proxy1)
SIMD_FORCE_INLINE btScalar length() const
Return the length of the vector.
Definition btVector3.h:257
Definition cubes.h:13
unsigned short flood_fill
unsigned short primary_edge_intersections
float edge_intersections[0]
unsigned short in_process
unsigned short edge_parity
ModelReader * reader
VirtualMemoryAllocator * alloc[9]
VirtualMemoryAllocator * leafalloc[4]
void * getOutputMesh()
DualConMode mode
Octree(const BoundBox &bbox)
PathList * ringList
nullptr float
const int processEdgeMask[3][4]
const int edgeProcEdgeMask[3][2][5]
const int faceProcFaceMask[3][4][3]
const int cellProcFaceMask[12][3]
const int faceMap[6][4]
const int faceProcEdgeMask[3][4][6]
const int cellProcEdgeMask[6][5]
const int dirEdge[3][4]
const int dirCell[3][4][3]
const int edgemask[3]
const int faceMap[6][4]
#define EDGE_FLOATS
const int dirEdge[3][4]
const int dirCell[3][4][3]
DualConMode
Definition dualcon.h:45
void(* DualConAddQuad)(void *output, const int vert_indices[4])
Definition dualcon.h:39
void(* DualConAddVert)(void *output, const float co[3])
Definition dualcon.h:37
void *(* DualConAllocOutput)(int totvert, int totquad)
Definition dualcon.h:35
DualConFlags
Definition dualcon.h:41
uint pos
#define assert(assertion)
#define printf(...)
constexpr T sign(T) RET
int count
const ManifoldIndices manifold_table[256]
static void add(blender::Map< std::string, std::string > &messages, Message &msg)
Definition msgfmt.cc:222
unsigned char child_is_leaf_bitfield
Node * get_child(int count)
unsigned char has_child_bitfield
const Node * get_child(int count) const
static int childrenCountTable[256][8]
void set_leaf_child(int index, int count, LeafNode *chd)
int get_child_index(int count)
static int numChildrenTable[256]
int has_child(int index) const
static int childrenIndexTable[256][8]
int get_num_children() const
const int * get_child_counts() const
void fill_children(Node *children[8], int leaf[8])
int is_child_leaf(int index) const
void set_internal_child(int index, int count, InternalNode *chd)
void set_child(int count, Node *chd)
int get_child_count(int index) const
InternalNode internal
PathElement * tail
PathElement * head
i
Definition text_draw.cc:230
uint len