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