1 /* 2 field.h: Routines for averaging orientations and directions subject 3 to various symmetry conditions. Also contains the Optimizer class which 4 uses these routines to smooth fields hierarchically. 5 6 This file is part of the implementation of 7 8 Instant Field-Aligned Meshes 9 Wenzel Jakob, Daniele Panozzo, Marco Tarini, and Olga Sorkine-Hornung 10 In ACM Transactions on Graphics (Proc. SIGGRAPH Asia 2015) 11 12 All rights reserved. Use of this source code is governed by a 13 BSD-style license that can be found in the LICENSE.txt file. 14 */ 15 16 #pragma once 17 18 19 #include "hierarchy.h" 20 #include <map> 21 22 /* Rotation helper functions */ 23 extern Vector3f rotate60(const Vector3f &d, const Vector3f &n); 24 extern Vector3f rotate90(const Vector3f &d, const Vector3f &n); 25 extern Vector3f rotate180(const Vector3f &d, const Vector3f &n); 26 extern Vector3f rotate60_by(const Vector3f &d, const Vector3f &n, int amount); 27 extern Vector3f rotate90_by(const Vector3f &d, const Vector3f &n, int amount); 28 extern Vector3f rotate180_by(const Vector3f &d, const Vector3f &n, int amount); 29 extern Vector2i rshift60(Vector2i shift, int amount); 30 extern Vector2i rshift90(Vector2i shift, int amount); 31 extern Vector2i rshift180(Vector2i shift, int amount); 32 extern Vector3f rotate_vector_into_plane(Vector3f q, const Vector3f &source_normal, const Vector3f &target_normal); 33 34 /* Extrinsic & intrinsic orientation symmetry functors */ 35 extern std::pair<Vector3f, Vector3f> 36 compat_orientation_intrinsic_2(const Vector3f &q0, const Vector3f &n0, 37 const Vector3f &q1, const Vector3f &n1); 38 39 extern std::pair<Vector3f, Vector3f> 40 compat_orientation_intrinsic_4(const Vector3f &q0, const Vector3f &n0, 41 const Vector3f &q1, const Vector3f &n1); 42 43 extern std::pair<Vector3f, Vector3f> 44 compat_orientation_intrinsic_4_knoeppel(const Vector3f &q0, const Vector3f &n0, 45 const Vector3f &q1, const Vector3f &n1); 46 47 extern std::pair<Vector3f, Vector3f> 48 compat_orientation_intrinsic_6(const Vector3f &q0, const Vector3f &n0, 49 const Vector3f &q1, const Vector3f &n1); 50 51 extern std::pair<Vector3f, Vector3f> 52 compat_orientation_extrinsic_2(const Vector3f &q0, const Vector3f &n0, 53 const Vector3f &q1, const Vector3f &n1); 54 55 extern std::pair<Vector3f, Vector3f> 56 compat_orientation_extrinsic_4(const Vector3f &q0, const Vector3f &n0, 57 const Vector3f &q1, const Vector3f &n1); 58 59 extern std::pair<Vector3f, Vector3f> 60 compat_orientation_extrinsic_6(const Vector3f &q0, const Vector3f &n0, 61 const Vector3f &q1, const Vector3f &n1); 62 63 extern std::pair<int, int> 64 compat_orientation_extrinsic_index_2(const Vector3f &q0, const Vector3f &n0, 65 const Vector3f &q1, const Vector3f &n1); 66 67 extern std::pair<int, int> 68 compat_orientation_extrinsic_index_4(const Vector3f &q0, const Vector3f &n0, 69 const Vector3f &q1, const Vector3f &n1); 70 71 extern std::pair<int, int> 72 compat_orientation_extrinsic_index_6(const Vector3f &q0, const Vector3f &n0, 73 const Vector3f &q1, const Vector3f &n1); 74 75 extern std::pair<int, int> 76 compat_orientation_intrinsic_index_2(const Vector3f &q0, const Vector3f &n0, 77 const Vector3f &q1, const Vector3f &n1); 78 79 extern std::pair<int, int> 80 compat_orientation_intrinsic_index_4(const Vector3f &q0, const Vector3f &n0, 81 const Vector3f &q1, const Vector3f &n1); 82 83 extern std::pair<int, int> 84 compat_orientation_intrinsic_index_6(const Vector3f &q0, const Vector3f &n0, 85 const Vector3f &q1, const Vector3f &n1); 86 87 /* Extrinsic & intrinsic position symmetry functors */ 88 extern std::pair<Vector3f, Vector3f> compat_position_extrinsic_3( 89 const Vector3f &p0, const Vector3f &n0, const Vector3f &q0, 90 const Vector3f &o0, const Vector3f &p1, const Vector3f &n1, 91 const Vector3f &q1, const Vector3f &o1, Float scale, Float inv_scale); 92 93 extern std::pair<Vector3f, Vector3f> compat_position_extrinsic_4( 94 const Vector3f &p0, const Vector3f &n0, const Vector3f &q0, 95 const Vector3f &o0, const Vector3f &p1, const Vector3f &n1, 96 const Vector3f &q1, const Vector3f &o1, Float scale, Float inv_scale); 97 98 extern std::pair<Vector2i, Vector2i> compat_position_extrinsic_index_3( 99 const Vector3f &p0, const Vector3f &n0, const Vector3f &q0, 100 const Vector3f &o0, const Vector3f &p1, const Vector3f &n1, 101 const Vector3f &q1, const Vector3f &o1, Float scale, Float inv_scale, 102 Float *error = nullptr); 103 104 extern std::pair<Vector2i, Vector2i> compat_position_extrinsic_index_4( 105 const Vector3f &p0, const Vector3f &n0, const Vector3f &q0, 106 const Vector3f &o0, const Vector3f &p1, const Vector3f &n1, 107 const Vector3f &q1, const Vector3f &o1, Float scale, Float inv_scale, 108 Float *error = nullptr); 109 110 extern std::pair<Vector3f, Vector3f> compat_position_intrinsic_3( 111 const Vector3f &p0, const Vector3f &n0, const Vector3f &q0, 112 const Vector3f &o0, const Vector3f &p1, const Vector3f &n1, 113 const Vector3f &q1, const Vector3f &o1, Float scale, Float inv_scale); 114 115 extern std::pair<Vector3f, Vector3f> compat_position_intrinsic_4( 116 const Vector3f &p0, const Vector3f &n0, const Vector3f &q0, 117 const Vector3f &o0, const Vector3f &p1, const Vector3f &n1, 118 const Vector3f &q1, const Vector3f &o1, Float scale, Float inv_scale); 119 120 extern std::pair<Vector2i, Vector2i> compat_position_intrinsic_index_3( 121 const Vector3f &p0, const Vector3f &n0, const Vector3f &q0, 122 const Vector3f &o0, const Vector3f &p1, const Vector3f &n1, 123 const Vector3f &q1, const Vector3f &o1, Float scale, Float inv_scale, 124 Float *error = nullptr); 125 126 extern std::pair<Vector2i, Vector2i> compat_position_intrinsic_index_4( 127 const Vector3f &p0, const Vector3f &n0, const Vector3f &q0, 128 const Vector3f &o0, const Vector3f &p1, const Vector3f &n1, 129 const Vector3f &q1, const Vector3f &o1, Float scale, Float inv_scale, 130 Float *error = nullptr); 131 132 /* Optimization kernels */ 133 134 extern Float optimize_orientations( 135 MultiResolutionHierarchy &mRes, int level, bool extrinsic, int rosy, 136 const std::function<void(uint32_t)> &progress); 137 138 extern Float optimize_positions( 139 MultiResolutionHierarchy &mRes, int level, bool extrinsic, int posy, 140 const std::function<void(uint32_t)> &progress); 141 142 /* Singularity computation */ 143 144 extern void compute_orientation_singularities( 145 const MultiResolutionHierarchy &mRes, std::map<uint32_t, uint32_t> &sing, 146 bool extrinsic, int rosy); 147 148 extern void 149 compute_position_singularities(const MultiResolutionHierarchy &mRes, 150 const std::map<uint32_t, uint32_t> &orient_sing, 151 std::map<uint32_t, Vector2i> &pos_sing, 152 bool extrinsic, int rosy, int posy); 153 154 /* Field optimizer (invokes optimization kernels in a separate thread) */ 155 156 class Serializer; 157 class Optimizer { 158 public: 159 Optimizer(MultiResolutionHierarchy &mRes, bool interactive); 160 void save(Serializer &state); 161 void load(const Serializer &state); 162 stop()163 void stop() { 164 if (mOptimizeOrientations) 165 mRes.propagateSolution(mRoSy); 166 mOptimizePositions = mOptimizeOrientations = false; 167 notify(); 168 } 169 shutdown()170 void shutdown() { mRunning = false; notify(); mThread.join(); } 171 active()172 bool active() { return mOptimizePositions | mOptimizeOrientations; } notify()173 inline void notify() { mCond.notify_all(); } 174 175 void optimizeOrientations(int level); 176 177 void optimizePositions(int level); 178 179 void wait(); 180 setExtrinsic(bool extrinsic)181 void setExtrinsic(bool extrinsic) { mExtrinsic = extrinsic; } extrinsic()182 bool extrinsic() const { return mExtrinsic; } 183 setRoSy(int rosy)184 void setRoSy(int rosy) { mRoSy = rosy; } rosy()185 int rosy() const { return mRoSy; } setPoSy(int posy)186 void setPoSy(int posy) { mPoSy = posy; } posy()187 int posy() const { return mPoSy; } setLevel(int level)188 void setLevel(int level) { mLevel = level; } level()189 int level() const { return mLevel; } progress()190 Float progress() const { return mProgress; } 191 192 #ifdef VISUALIZE_ERROR error()193 const VectorXf &error() { return mError; } 194 #endif 195 moveSingularity(const std::vector<uint32_t> & path,bool orientations)196 void moveSingularity(const std::vector<uint32_t> &path, bool orientations) { 197 std::lock_guard<ordered_lock> lock(mRes.mutex()); 198 mAttractorStrokes.push_back(std::make_pair(orientations, path)); 199 setLevel(0); 200 } 201 202 void run(); 203 protected: 204 MultiResolutionHierarchy &mRes; 205 std::vector<std::pair<bool, std::vector<uint32_t>>> mAttractorStrokes; 206 bool mRunning; 207 bool mOptimizeOrientations; 208 bool mOptimizePositions; 209 std::thread mThread; 210 std::condition_variable_any mCond; 211 int mLevel, mLevelIterations; 212 bool mHierarchical; 213 int mRoSy, mPoSy; 214 bool mExtrinsic; 215 bool mInteractive; 216 double mLastUpdate; 217 Float mProgress; 218 #ifdef VISUALIZE_ERROR 219 VectorXf mError; 220 #endif 221 Timer<> mTimer; 222 }; 223