// OctreeADF.h: interface for the COctreeADF class. // ////////////////////////////////////////////////////////////////////// #if !defined(AFX_OCTREEADF_H__CAEEF34C_CAA4_4E00_B972_812FE827402E__INCLUDED_) #define AFX_OCTREEADF_H__CAEEF34C_CAA4_4E00_B972_812FE827402E__INCLUDED_ #include #include #include #include "gl/glu.h" #include "gl/gl.h" #include "mathlib/mathlib.h" #include "ISDF.h" using namespace SDF; #include "Utils.h" #include "ADFCreator_debug_flags.h" typedef struct { Point *v; // Vertex Data Point *Pc; // Closest Point on Surface double dist; // Signed Distance Vector *grad; // The distance gradient at v - calculated by nudging v by epsilon and averaging the change in distance } octreeVtx; class octreeNode { // Statics public: //--------------------------------- // (Steve) 2005-12-18 (20-04) // Tons of this code should be taken out of this class, // into an OctreeGenBase class, with octreeNode* generate_octree() // Then we can have, AdfOctreeGen, and BalancedAdfOctreeGen // These will take an ISDF and some parameters, and create octrees with // AdfOctreeNode's in them (with closest distance info). // // Actually, for now let's just focus on ADF's. So we have, // AdfGeneratorBase, then TopDownAdfGen <--inherits-- (BalancedTDAdfGen, UniformTDAdfGen) // AdfErrorToleranceCriteria: bool error_is_tolerable(expected sdf, actual sdf) // FixedDistanceCriteria // PercentageErrorCriteria // SdfInterpolator: SdfValue interpolate_sdf(SdfOctreeNode node, Point testPt) // CoonsSdfInterp // TrilinearSdfInterp //--------------------------------- enum Direction { L = 0, R, F, B, U, D, DIR_MAX };//left, right, front, back, up and down enum Octant {LFD = 0,RFD,LBD,RBD,LFU,RFU,LBU,RBU,ROOT}; // // TODO - move these adf generation parms into an AdfGen static double adf_distance_tolerance; static double adf_error_limit; // This should be renamed to..error %-age? static bool distance_meets_distance_tolerance(double interped_dist, double actual_dist); static bool distance_meets_error_tolerance(double interped_dist, double actual_dist ); static double interped_distance(octreeNode *node, const Point *pt); static bool corner_vert_meets_tolerance(const octreeVtx *vert, octreeNode *node_to_interp_with); static bool all_child_corner_verts_meet_tolerance(octreeVtx *corners[3][3][3], octreeNode *parent ); static octreeVtx* create_ADF_octree_vert(Point *p, const ISDF &reference_model); static void subdivide_octnode(octreeNode *node, octreeVtx *child_corner_verts[3][3][3], const ISDF &reference_model); // Instances public: bool check_corner_pts(void); int calc_max_depth(); octreeNode( const Point &origin, double edge_len ); bool subtree_is_balanced(); bool is_balanced_with_all_nbors(); octreeNode* find_edge_nbor_by_brute_force(int diag_index); bool is_balanced_with(octreeNode *other); unsigned int count_offspring(); octreeNode* create_child_node(int i, int j, int k); static Octant get_octant(int i, int j, int k); static Direction first_direction(); void get_face_nbors(octreeNode *face_nbors[DIR_MAX]); octreeNode* get_edge_nbor_if_larger(int diag_index, octreeNode *face_nbors[DIR_MAX]); octreeNode* get_edge_nbor_if_larger( Direction da, Direction db, octreeNode *a, octreeNode *b); static void get_directions_for_diagonal(int i, Direction &da, Direction &db); double longest_diagonal_dist(); bool contains_surface(); Direction next_direction(Direction d); void subdivide_for_balanced_ADF(octreeVtx *child_corner_verts[3][3][3], const ISDF &reference_model); void subdivide_for_ADF(octreeVtx *child_corner_verts[3][3][3], const ISDF &reference_model); bool isLeafNode(); // (Steve) I don't think this function is used. Commenting out. void buildBoundarySurfaces(); octreeNode(); ~octreeNode(); octreeVtx *vtxArray[2][2][2]; int inOnOut; octreeNode *subnodeArray[2][2][2]; // (Steve) moved this stuff into CoonsSdfInterp // float findCOONSInterpDist(float u, float v, float w); // float findCOONSInterpDist(const Point& pt); octreeNode* m_parent; Octant m_octant; unsigned int m_parentid; unsigned int m_id; unsigned int m_c000id,m_c100id,m_c010id,m_c110id,m_c001id,m_c101id,m_c011id,m_c111id; float m_d000,m_d100,m_d010,m_d110,m_d001,m_d101,m_d011,m_d111; Point m_v; unsigned int m_depth; //the depth in the octree void render(float r,float g,float b,bool solid); octreeNode* findNeighbor(Direction dir); static void calculate_child_corner_verts( octreeNode *node, const ISDF &reference_model, octreeVtx *child_corner_verts[3][3][3]); float m_edgeLength; private: unsigned reflect(Direction dir, Octant o); //for neighbor search bool octreeNode::adj(Direction d, Octant o); //for neighbor search }; #endif // !defined(AFX_OCTREEADF_H__CAEEF34C_CAA4_4E00_B972_812FE827402E__INCLUDED_)