29 #ifndef MULTI_GRID_OCTREE_DATA_INCLUDED
30 #define MULTI_GRID_OCTREE_DATA_INCLUDED
32 #define GRADIENT_DOMAIN_SOLUTION 1 // Given the constraint vector-field V(p), there are two ways to solve for the coefficients, x, of the indicator function
65 #define FORCE_NEUMANN_FIELD 1 // This flag forces the normal component across the boundary of the integration domain to be zero.
68 #define ROBERTO_TOLDO_FIX 1
70 #if !FORCE_NEUMANN_FIELD
71 #pragma message( "[WARNING] Not zeroing out normal component on boundary" )
72 #endif // !FORCE_NEUMANN_FIELD
75 #include "BSplineData.h"
77 char* outputFile=NULL;
79 void DumpOutput(
const char* format , ... )
83 FILE* fp = fopen( outputFile ,
"a" );
85 va_start( args , format );
86 vfprintf( fp , format , args );
93 va_start( args , format );
94 vprintf( format , args );
98 void DumpOutput2(
char* str ,
const char* format , ... )
102 FILE* fp = fopen( outputFile ,
"a" );
104 va_start( args , format );
105 vfprintf( fp , format , args );
112 va_start( args , format );
113 vprintf( format , args );
117 va_start( args , format );
118 vsprintf( str , format , args );
120 if( str[strlen(str)-1]==
'\n' ) str[strlen(str)-1] = 0;
126 typedef float MatrixReal;
133 const TreeOctNode* node;
141 static long long EdgeIndex(
const TreeOctNode* node ,
int eIndex ,
int maxDepth ,
int index[DIMENSION] );
142 static long long EdgeIndex(
const TreeOctNode* node ,
int eIndex ,
int maxDepth );
143 static long long FaceIndex(
const TreeOctNode* node ,
int fIndex ,
int maxDepth,
int index[DIMENSION] );
144 static long long FaceIndex(
const TreeOctNode* node ,
int fIndex ,
int maxDepth );
145 static long long CornerIndex(
int depth ,
const int offSet[DIMENSION] ,
int cIndex ,
int maxDepth ,
int index[DIMENSION] );
146 static long long CornerIndex(
const TreeOctNode* node ,
int cIndex ,
int maxDepth ,
int index[DIMENSION] );
147 static long long CornerIndex(
const TreeOctNode* node ,
int cIndex ,
int maxDepth );
148 static long long CenterIndex(
int depth ,
const int offSet[DIMENSION] ,
int maxDepth ,
int index[DIMENSION] );
149 static long long CenterIndex(
const TreeOctNode* node ,
int maxDepth ,
int index[DIMENSION] );
150 static long long CenterIndex(
const TreeOctNode* node ,
int maxDepth );
151 static long long CornerIndexKey(
const int index[DIMENSION] );
156 Pointer( TreeOctNode* ) treeNodes;
161 void set( TreeOctNode& root );
164 int idx[Cube::CORNERS];
165 CornerIndices(
void ) { memset( idx , -1 ,
sizeof(
int ) * Cube::CORNERS ); }
166 int& operator[] (
int i ) {
return idx[i]; }
167 const int& operator[] (
int i )
const {
return idx[i]; }
173 void clear(
void ) { cTable.clear() ; cCount = 0; }
175 const CornerIndices& operator[] (
const TreeOctNode* node )
const;
177 const CornerIndices& cornerIndices(
const TreeOctNode* node )
const;
179 std::vector< CornerIndices > cTable;
180 std::vector< int > offsets;
182 void setCornerTable(
CornerTableData& cData ,
const TreeOctNode* rootNode ,
int depth ,
int threads )
const;
183 void setCornerTable(
CornerTableData& cData ,
const TreeOctNode* rootNode ,
int threads )
const { setCornerTable( cData , rootNode , maxDepth-1 , threads ); }
184 void setCornerTable( CornerTableData& cData ,
int threads )
const { setCornerTable( cData , NULL , maxDepth-1 , threads ); }
185 int getMaxCornerCount(
int depth ,
int maxDepth ,
int threads )
const ;
188 int idx[Cube::EDGES];
189 EdgeIndices(
void ) { memset( idx , -1 ,
sizeof(
int ) * Cube::EDGES ); }
190 int& operator[] (
int i ) {
return idx[i]; }
191 const int& operator[] (
int i )
const {
return idx[i]; }
197 void clear(
void ) { eTable.clear() , eCount=0; }
198 EdgeIndices& operator[] (
const TreeOctNode* node );
199 const EdgeIndices& operator[] (
const TreeOctNode* node )
const;
200 EdgeIndices& edgeIndices(
const TreeOctNode* node );
201 const EdgeIndices& edgeIndices(
const TreeOctNode* node )
const;
203 std::vector< EdgeIndices > eTable;
204 std::vector< int > offsets;
206 void setEdgeTable(
EdgeTableData& eData ,
const TreeOctNode* rootNode ,
int depth ,
int threads );
207 void setEdgeTable(
EdgeTableData& eData ,
const TreeOctNode* rootNode ,
int threads ) { setEdgeTable( eData , rootNode , maxDepth-1 , threads ); }
208 void setEdgeTable( EdgeTableData& eData ,
int threads ) { setEdgeTable( eData , NULL , maxDepth-1 , threads ); }
209 int getMaxEdgeCount(
const TreeOctNode* rootNode ,
int depth ,
int threads )
const ;
221 Real centerWeightContribution;
225 Real constraint , solution;
233 template<
int Degree >
238 bool _constrainValues;
242 std::vector< int > _pointCount;
250 std::vector< PointData > _points;
256 Real GetLaplacian(
const int index[DIMENSION] )
const;
258 Real GetLaplacian(
const TreeOctNode* node1 ,
const TreeOctNode* node2 )
const;
259 Real GetDivergence(
const TreeOctNode* node1 ,
const TreeOctNode* node2 ,
const Point3D<Real>& normal1 )
const;
260 Real GetDivergenceMinusLaplacian(
const TreeOctNode* node1 ,
const TreeOctNode* node2 , Real value1 ,
const Point3D<Real>& normal1 )
const;
266 void Function(
const TreeOctNode* node1,
const TreeOctNode* node2);
270 int *adjacencies,adjacencyCount;
271 void Function(
const TreeOctNode* node1,
const TreeOctNode* node2);
277 void Function(TreeOctNode* node1,
const TreeOctNode* node2);
282 int fIndex , maxDepth;
283 std::vector< std::pair< RootInfo , RootInfo > >* edges;
284 hash_map< long long , std::pair< RootInfo , int > >* vertexCount;
285 void Function(
const TreeOctNode* node1 ,
const TreeOctNode* node2 );
288 int _SolveFixedDepthMatrix(
int depth ,
const SortedTreeNodes& sNodes , Real* subConstraints ,
bool showResidual ,
int minIters ,
double accuracy ,
bool noSolve =
false ,
int fixedIters=-1 );
289 int _SolveFixedDepthMatrix(
int depth ,
const SortedTreeNodes& sNodes , Real* subConstraints ,
int startingDepth ,
bool showResidual ,
int minIters ,
double accuracy ,
bool noSolve =
false ,
int fixedIters=-1 );
291 void SetMatrixRowBounds(
const TreeOctNode* node ,
int rDepth ,
const int rOff[3] ,
int& xStart ,
int& xEnd ,
int& yStart ,
int& yEnd ,
int& zStart ,
int& zEnd )
const;
292 int GetMatrixRowSize(
const TreeOctNode::Neighbors5& neighbors5 )
const;
293 int GetMatrixRowSize(
const TreeOctNode::Neighbors5& neighbors5 ,
int xStart ,
int xEnd ,
int yStart ,
int yEnd ,
int zStart ,
int zEnd )
const;
294 int SetMatrixRow(
const TreeOctNode::Neighbors5& neighbors5 , Pointer(
MatrixEntry< MatrixReal > ) row ,
int offset ,
const double stencil[5][5][5] )
const;
295 int SetMatrixRow(
const TreeOctNode::Neighbors5& neighbors5 , Pointer(
MatrixEntry< MatrixReal > ) row ,
int offset ,
const double stencil[5][5][5] ,
int xStart ,
int xEnd ,
int yStart ,
int yEnd ,
int zStart ,
int zEnd )
const;
296 void SetDivergenceStencil(
int depth ,
Point3D< double > stencil[5][5][5] ,
bool scatter )
const;
297 void SetLaplacianStencil(
int depth ,
double stencil[5][5][5] )
const;
298 template<
class C ,
int N >
struct Stencil{ C values[N][N][N]; };
303 static void UpdateCoarserSupportBounds(
const TreeOctNode* node ,
int& startX ,
int& endX ,
int& startY ,
int& endY ,
int& startZ ,
int& endZ );
304 void UpdateConstraintsFromCoarser(
const TreeOctNode::NeighborKey5& neighborKey5 , TreeOctNode* node , Real* metSolution ,
const Stencil< double , 5 >& stencil )
const;
305 void SetCoarserPointValues(
int depth ,
const SortedTreeNodes& sNodes , Real* metSolution );
306 Real WeightedCoarserFunctionValue(
const TreeOctNode::NeighborKey3& neighborKey3 ,
const TreeOctNode* node , Real* metSolution )
const;
308 void DownSampleFinerConstraints(
int depth ,
SortedTreeNodes& sNodes )
const;
309 template<
class C >
void DownSample(
int depth ,
const SortedTreeNodes& sNodes , C* constraints )
const;
310 template<
class C >
void UpSample(
int depth ,
const SortedTreeNodes& sNodes , C* coefficients )
const;
312 int GetRestrictedFixedDepthLaplacian(
SparseSymmetricMatrix< Real >& matrix ,
int depth ,
const int* entries ,
int entryCount ,
const TreeOctNode* rNode, Real radius ,
const SortedTreeNodes& sNodes , Real* subConstraints );
314 void SetIsoCorners( Real isoValue , TreeOctNode* leaf ,
SortedTreeNodes::CornerTableData& cData , Pointer(
char ) valuesSet , Pointer( Real ) values , TreeOctNode::ConstNeighborKey3& nKey ,
const Real* metSolution ,
const Stencil< Real , 3 > stencil1[8] ,
const Stencil< Real , 3 > stencil2[8][8] );
315 static int IsBoundaryFace(
const TreeOctNode* node ,
int faceIndex ,
int subdivideDepth );
316 static int IsBoundaryEdge(
const TreeOctNode* node ,
int edgeIndex ,
int subdivideDepth );
317 static int IsBoundaryEdge(
const TreeOctNode* node ,
int dir ,
int x ,
int y ,
int subidivideDepth );
325 hash_map< long long , int > boundaryRoots;
327 hash_map< long long , std::pair< Real , Point3D< Real > > > *boundaryValues;
328 Pointer(
int ) interiorRoots;
329 Pointer( Real ) cornerValues;
331 Pointer(
char ) cornerValuesSet;
332 Pointer(
char ) cornerNormalsSet;
333 Pointer(
char ) edgesSet;
336 int SetBoundaryMCRootPositions(
int sDepth , Real isoValue ,
RootData& rootData ,
CoredMeshData* mesh ,
int nonLinearFit );
337 int SetMCRootPositions( TreeOctNode* node ,
int sDepth , Real isoValue , TreeOctNode::ConstNeighborKey5& neighborKey5 ,
RootData& rootData ,
341 static int AddTriangles(
CoredMeshData* mesh , std::vector<CoredPointIndex>& edges , std::vector<
Point3D< Real > >* interiorPositions ,
int offSet ,
bool polygonMesh , std::vector<
Point3D< Real > >* barycenters );
344 void GetMCIsoEdges( TreeOctNode* node ,
int sDepth , std::vector< std::pair< RootInfo , RootInfo > >& edges );
345 static int GetEdgeLoops( std::vector< std::pair< RootInfo , RootInfo > >& edges , std::vector< std::vector< std::pair< RootInfo , RootInfo > > >& loops);
346 static int InteriorFaceRootCount(
const TreeOctNode* node ,
const int &faceIndex ,
int maxDepth );
347 static int EdgeRootCount(
const TreeOctNode* node ,
int edgeIndex ,
int maxDepth );
349 int GetRoot(
const RootInfo& ri , Real isoValue , TreeOctNode::ConstNeighborKey5& neighborKey5 ,
Point3D<Real> & position ,
RootData& rootData ,
int sDepth ,
const Real* metSolution ,
int nonLinearFit );
350 static int GetRootIndex(
const TreeOctNode* node ,
int edgeIndex ,
int maxDepth ,
RootInfo& ri );
351 static int GetRootIndex(
const TreeOctNode* node ,
int edgeIndex ,
int maxDepth ,
int sDepth ,
RootInfo& ri );
353 static int GetRootPair(
const RootInfo& root ,
int maxDepth ,
RootInfo& pair );
355 int UpdateWeightContribution( TreeOctNode* node ,
const Point3D<Real>& position , TreeOctNode::NeighborKey3& neighborKey , Real weight=Real(1.0) );
356 Real GetSampleWeight( TreeOctNode* node ,
const Point3D<Real>& position , TreeOctNode::NeighborKey3& neighborKey );
357 void GetSampleDepthAndWeight( TreeOctNode* node ,
const Point3D<Real>& position , TreeOctNode::NeighborKey3& neighborKey , Real samplesPerNode , Real& depth , Real& weight );
358 int SplatOrientedPoint( TreeOctNode* node ,
const Point3D<Real>& point ,
const Point3D<Real>& normal , TreeOctNode::NeighborKey3& neighborKey );
359 int SplatOrientedPoint( TreeOctNode* node ,
const Point3D<Real>& point ,
const Point3D<Real>& normal , TreeOctNode::NeighborKey5& neighborKey );
360 Real SplatOrientedPoint(
const Point3D<Real>& point ,
const Point3D<Real>& normal , TreeOctNode::NeighborKey3& neighborKey ,
int kernelDepth , Real samplesPerNode ,
int minDepth ,
int maxDepth );
361 Real SplatOrientedPoint(
const Point3D<Real>& point ,
const Point3D<Real>& normal , TreeOctNode::NeighborKey3& neighborKey3 , TreeOctNode::NeighborKey5& neighborKey5 ,
int kernelDepth , Real samplesPerNode ,
int minDepth ,
int maxDepth );
363 int HasNormals(TreeOctNode* node,Real epsilon);
364 Real getCornerValue(
const TreeOctNode::ConstNeighborKey3& neighborKey3 ,
const TreeOctNode* node ,
int corner ,
const Real* metSolution );
365 Point3D< Real > getCornerNormal(
const TreeOctNode::ConstNeighborKey5& neighborKey5 ,
const TreeOctNode* node ,
int corner ,
const Real* metSolution );
366 Real getCornerValue(
const TreeOctNode::ConstNeighborKey3& neighborKey3 ,
const TreeOctNode* node ,
int corner ,
const Real* metSolution ,
const Real stencil1[3][3][3] ,
const Real stencil2[3][3][3] );
367 Real getCenterValue(
const TreeOctNode::ConstNeighborKey3& neighborKey3 ,
const TreeOctNode* node );
368 static bool _IsInset(
const TreeOctNode* node );
369 static bool _IsInsetSupported(
const TreeOctNode* node );
372 static double maxMemoryUsage;
373 static double MemoryUsage(
void );
374 std::vector< Point3D<Real> >* normals;
375 Real postDerivativeSmooth;
381 void finalize(
int subdivisionDepth );
382 int refineBoundary(
int subdivisionDepth );
383 Pointer( Real ) GetSolutionGrid(
int& res , Real isoValue=0.f ,
int depth=-1 );
384 int setTree(
char* fileName ,
int maxDepth ,
int minDepth ,
int kernelDepth , Real samplesPerNode ,
385 Real scaleFactor ,
int useConfidence , Real constraintWeight ,
int adaptiveExponent ,
XForm4x4< Real > xForm=
XForm4x4< Real >::Identity() );
386 int setTreeMemory(
std::vector< Real >& _pts_stream,
int maxDepth ,
int minDepth ,
387 int splatDepth , Real samplesPerNode , Real scaleFactor ,
388 int useConfidence , Real constraintWeight ,
int adaptiveExponent ,
XForm4x4< Real > xForm=
XForm4x4< Real >::Identity() );
389 void SetLaplacianConstraints(
void);
391 int LaplacianMatrixIteration(
int subdivideDepth ,
bool showResidual ,
int minIters ,
double accuracy ,
int maxSolveDepth ,
int fixedIters );
393 Real GetIsoValue(
void );
394 void GetMCIsoTriangles( Real isoValue ,
int subdivideDepth ,
CoredMeshData* mesh ,
int fullDepthIso=0 ,
int nonLinearFit=1 ,
bool addBarycenter=false ,
bool polygonMesh=false );
397 #ifndef DOXY_IGNORE_THIS
398 #include "MultiGridOctreeData.inl"
400 #endif // MULTI_GRID_OCTREE_DATA_INCLUDED