1 /*! \file HiReconstruction.hpp
2  * This class implements a high order surface/curve reconstruction method which takes a surface/curve mesh as input
3  * and compute local polynomial fittings (in monomial basis) around user specified vertices. Little noise is allowed and least square
4  * will be used in such case.
5  * This method assumes the underlying geometry of input mesh is smooth.
6  * The local fitting results could be used for estimate the exact geometry of the surface. For instance, if mesh
7  *  refinement is perform on the input mesh, then the position of new vertices introduced by refinement could be
8  * estimated by the local fitting, rather than using linear interpolation.
9  * Implementations are based on the WALF method in paper:
10  * Jiao, Xiangmin, and Duo Wang. "Reconstructing high-order surfaces for meshing." Engineering with Computers 28.4 (2012): 361-373.
11  */
12 
13 
14 #ifndef HI_RECONSTRUCTION_HPP
15 #define HI_RECONSTRUCTION_HPP
16 
17 #include "moab/Range.hpp"
18 #include "moab/HalfFacetRep.hpp"
19 
20 #ifdef MOAB_HAVE_MPI
21 #include "moab/ParallelComm.hpp"
22 #endif
23 
24 #include <vector>
25 
26 namespace moab
27 {
28 	enum GEOMTYPE{ HISURFACE, HI3DCURVE, HI2DCURVE};
29 
30 	class Core;
31 	class HalfFaceRep;
32 	class ParallelComm;
33 
34 	class HiReconstruction
35 	{
36 		public:
37 
38 			HiReconstruction(Core *impl, ParallelComm *comm=0, EntityHandle meshIn=0, int minpnts=5, bool recwhole=true);
39 
40 			~HiReconstruction();
41 
42 			ErrorCode initialize(bool recwhole);
43 
44 			//! \brief Reconstruct a high order surface on given surface mesh
45 			/** Given a mesh, compute vertex based polynomial fittings for all vertices hosted by current processor.
46 				* The result will be stored interally for later usage of evalution. The inputs are: a) degree, which
47 				* is the order of polynomial used for vertex based fitting. b) interp, if it's true, then interpolation
48 				* will be applied for local fitting, otherwise it's least square fitting. c) safeguard, specifies whether
49 				* to use safeguarded numeric method. d) reset, if fittings have been computed and stored in current
50 				* object, then reset=true will recompute the fittings based on user input and replace the existing one.
51 				* \param degree Integer, order of polynomials used for local fittings.
52 				* \param interp Boolean, true=Interpolation, false=least square fitting.
53 				* \param safeguard Boolean, true=using safe guarded method in numerical computing.
54 				* \param reset Boolean, reset=true will recompute the fittings based on user input and replace the existing one.
55 			*/
56 			ErrorCode reconstruct3D_surf_geom(int degree, bool interp, bool safeguard, bool reset=false);
57 
58 			//! \brief Reconstruct a high order surface on given surface mesh
59 			/** Given a mesh, compute vertex based polynomial fittings for all vertices hosted by current processor.
60 				* User could specify various degrees for different vertices. It assumes that the input degrees for
61 				* vertices stored in the same order as that this class stores vertices: 1) reconstruction will be
62 				* only performed at vertices hosted by current processor, thus input npts should match the number of
63 				* hosted vertices. 2) all hosted vertices will be stored in a MOAB::Range object, degrees for all these
64 				* vertices should be stored in degrees as the same order in the MOAB::Range object
65 				* The result will be stored interally for later usage of evalution.
66 				* \param npts Integer size of array pointed by degrees, used for check
67 				* \param degrees Integer arrray, order of polynomials for local fitting at all hosted vertices
68 				* \param interp Boolean, true=Interpolation, false=least square fitting.
69 				* \param safeguard Boolean, true=using safe guarded method in numerical computing.
70 				* \param reset Boolean, reset=true will recompute the fittings based on user input and replace the existing one.
71 			*/
72 			ErrorCode reconstruct3D_surf_geom(size_t npts, int* degrees, bool* interps, bool safeguard, bool reset=false);
73 
74 			//! \brief Reconstruct a high order curve on given curve mesh
75 			/** Given a curve mesh, compute vertex based polynomail fittings for all vertices hosted by current processor.
76 				* The vertex based fitting is done by perfoming three one-parameter fittings along each axis, i.e. x,y,z.
77 				* The result will be stored interally for later usage of evalution.
78 				* \param degree Integer, order of polynomials used for local fittings.
79 				* \param interp Boolean, true=Interpolation, false=least square fitting.
80 				* \param safeguard Boolean, true=using safe guarded method in numerical computing.
81 				* \param reset Boolean, reset=true will recompute the fittings based on user input and replace the existing one.
82 			*/
83 			ErrorCode reconstruct3D_curve_geom(int degree, bool interp, bool safeguard, bool reset=false);
84 
85 			//! \brief Reconstruct a high order curve on given curve mesh
86 			/** Given a curve mesh, compute vertex based polynomail fittings for all vertices hosted by current processor.
87 				* The vertex based fitting is done by perfoming three one-parameter fittings along each axis, i.e. x,y,z.
88 				* User could specify various degrees for different vertices. It assumes that the input degrees for
89 				* vertices stored in the same order as that this class stores vertices: 1) reconstruction will be
90 				* only performed at vertices hosted by current processor, thus input npts should match the number of
91 				* hosted vertices. 2) all hosted vertices will be stored in a MOAB::Range object, degrees for all these
92 				* vertices should be stored in degrees as the same order in the MOAB::Range object
93 				* The result will be stored interally for later usage of evalution.
94 				* \param npts Integer size of array pointed by degrees, used for check
95 				* \param degrees Integer arrray, order of polynomials for local fitting at all hosted vertices.
96 				* \param interp Boolean, true=Interpolation, false=least square fitting.
97 				* \param safeguard Boolean, true=using safe guarded method in numerical computing.
98 				* \param reset Boolean, reset=true will recompute the fittings based on user input and replace the existing one.
99 			*/
100 			ErrorCode reconstruct3D_curve_geom(size_t npts, int* degrees, bool* interps, bool safeguard, bool reset=false);
101 
102 			//! \brief Construct vertex based polynomial fitting on a surface mesh
103 			/** Given a vertex on a surface mesh, construct a local fitting around this vertex. Stencils around this vertex will
104 				* be selected according to input degree and if data is noise. Local uv-plane will be the estimated tangent plane
105 				* at this vertex. minpnts will be used to specify the minimum number allowed in the local stencil.
106 				* The result will be returned to user by preallocated memory coords, degree_out, coeffs.
107 				* \param vid EntityHandle, the fitting will be performed around this vertex for the local height function over the uv-plane.
108 				* \param interp Boolean, true=Interpolation, false=least square fitting.
109 				* \param degree Integer, order of polynomials used for local fittings.
110 				* \param minpnts Integer, the allowed minimum number of vertices in local stencil. If too small, the resulted fitting might be low order accurate. If too large, it may introduce overfitting.
111 				* \param safeguard Boolean, true=using safe guarded method in numerical computing.
112 				* \param coords Pointer to double, preallocated memory by user, should have at least 9 doubles; stores the global coordinates of local coordinates system uvw directions.
113 				* \param degree_out Pointer to integer, used to store the degree of resulted fitting
114 				* \param coeffs, Pointer to double, preallocated memory for coefficients of local fittings, should have at least (degree+2)(degree+1)/2 doubles.
115 			*/
116 			ErrorCode polyfit3d_walf_surf_vertex(const EntityHandle vid, const bool interp, int degree, int minpnts, const bool safeguard, const int ncoords, double* coords, int* degree_out, const int ncoeffs, double* coeffs);
117 
118 			//! \brief Construct vertex based polynomial fitting on a curve mesh
119 			/** Given a vertex on a curve mesh, construct three one-parameter local fittings for each coordinates axis around
120 				* this vertex. Stencils around this vertex will be selected according to input degree and if data is noise.
121 				* Local u-line, or the single parameter will be the estimated tangent line at this vertex. On each axis of xyz,
122 				* a polynomial fitting will be performed according to user input.
123 				* minpnts will be used to specify the minimum number allowed in the local stencil.
124 				* The result will be returned to user by preallocated memory coords, degree_out, coeffs.
125 				* \param vid EntityHandle, the fittings will be performed around this vertex.
126 				* \param interp Boolean, true=Interpolation, false=least square fitting.
127 				* \param degree Integer, order of polynomials used for local fittings.
128 				* \param minpnts Integer, the allowed minimum number of vertices in local stencil. If too small, the resulted fitting might be low order accurate. If too large, it may introduce overfitting.
129 				* \param safeguard Boolean, true=using safe guarded method in numerical computing.
130 				* \param coords Pointer to double, preallocated memory by user, should have at least 3 doubles; stores the global coordinates of local coordinate system u direction.
131 				* \param degree_out Pointer to integer, used to store the degree of resulted fitting
132 				* \param coeffs, Pointer to double, preallocated memory for coefficients of local fittings, should have at least 3*(degree+1) doubles.
133 			*/
134 			ErrorCode polyfit3d_walf_curve_vertex(const EntityHandle vid, const bool interp, int degree, int minpnts, const bool safeguard, const int ncoords, double* coords, int* degree_out, const int ncoeffs, double* coeffs);
135 
136 			//! \brief Perform high order projection of points in an element, using estimated geometry by reconstruction class
137 			/** Given an element on the input mesh, and new points in this element, represented as natural coordinates in element,
138 				* estimate their position in surface. This is done by weighted averaging of local fittings: for each vertex of this
139 				* elment, a fitting has been computed and the new points could be projected by this fitting. The final result of projection
140 				* is the weighted average of these projections, weights are chosen as the barycentric coordinates of the point in this element.
141 				* The result will be returned to the user preallocated memory
142 				* \param elem EntityHandle, the element on which to perform high order projection.
143 				* \param nvpe Integer, number of nodes of this element, triangle is 3, quad is four.
144 				* \param npts2fit Integer, number of points lying in elem to be projected.
145 				* \param naturalcoords2fit Pointer to array of doubles, size=nvpe*npts2fit, natural coordinates in elem of points to be projected.
146 				* \param newcoords Pointer to array of doubles, preallocated by user, size=3*npts2fit, estimated positions of input points.
147 			*/
148 			ErrorCode hiproj_walf_in_element(EntityHandle elem, const int nvpe, const int npts2fit, const double* naturalcoords2fit, double* newcoords);
149 
150 			//! \brief Perform high order projection of points around a vertex, using estimated geometry by reconstruction class
151 			/** Given an vertex on the input mesh, and new points around this vertex, estimate their position in surface.
152 				* This is done by first projecting input points onto the local uv-plane around this vertex and use the precomputed local
153 				* fitting to estimate the ideal position of input points.
154 				* The result will be returned to the user preallocated memory
155 				* \param vid EntityHandle, the vertex around which to perform high order projection.
156 				* \param npts2fit Integer, number of points lying around vid to be fitted.
157 				* \param coords2fit Pointer to array of doubles, size=3*npts2fit, current coordinates of points to be projected.
158 				* \param newcoords Pointer to array of doubles, preallocated by user, size=3*npts2fit, estimated positions of input points.
159 			*/
160 			ErrorCode hiproj_walf_around_vertex(EntityHandle vid, const int npts2fit, const double* coords2fit, double* hiproj_new);
161 
162 			//! \brief Perform high order projection of points around a center vertex, assume geometry is surface
163 			/** Given a vertex position and the local fitting parameter around this vertex, estimate the ideal position of input position
164 				* according to the local fitting. This is done by first projecting input points onto the local uv-plane around this vertex
165 				* and use the given fitting to estimate the ideal position of input points.
166 				* The result will be returned to user preallocated memory
167 				* \param local_origin Pointer to 3 doubles, coordinates of the center vertex
168 				* \param local_coords Pointer to 9 doubles, global coordinates of directions of local uvw coordinates axis at center vertex
169 				* \param local_deg Integer, order of local polynomial fitting
170 				* \param local_coeffs Pointer to array of doubles, size=(local_deg+2)(local_deg+1)/2, coefficients of local polynomial fittings, in monomial basis
171 				* \param interp Boolean, true=local fitting is interpolation, false=local fitting is least square fitting
172 				* \param npts2fit Integer, number of points to be estimated, around the center vertices
173 				* \param coords2fit Pointer to array of doubles, size=3*npts2fit, current coordinates of points to be estimated
174 				* \param hiproj_new Pointer to array of doubles, size=3*npts2fit, memory preallocated by user to store the fitting/estimated positions of input points.
175 			*/
176 			void walf3d_surf_vertex_eval(const double* local_origin, const double* local_coords, const int local_deg, const double* local_coeffs, const bool interp, const int npts2fit, const double* coords2fit, double* hiproj_new);
177 
178 			//! \brief Perform high order projection of points around a center vertex, assume geometry is curve
179 			/** Given a vertex position and the local one-parameter fittings parameter around this vertex, estimate the ideal position of input position
180 				* according to the local fittings. This is done by first projecting input points onto the local u-direction at this vertex
181 				* and then use the value u as parameter for the three fittings, one for each coordinates axis of xyz.
182 				* The result will be returned to user preallocated memory
183 				* \param local_origin Pointer to 3 doubles, coordinates of the center vertex
184 				* \param local_coords Pointer to 3 doubles, global coordinates of direction of local u coordinate axis at center vertex
185 				* \param local_deg Integer, order of local polynomial fitting
186 				* \param local_coeffs Pointer to array of doubles, size=3*(local_deg+1), coefficients of three local polynomial fittings, in monomial basis. For each fitting, local_deg+1 parameters.
187 				* \param interp Boolean, true=local fitting is interpolation, false=local fitting is least square fitting
188 				* \param npts2fit Integer, number of points to be estimated, around the center vertices
189 				* \param coords2fit Pointer to array of doubles, size=3*npts2fit, current coordinates of points to be estimated
190 				* \param hiproj_new Pointer to array of doubles, size=3*npts2fit, memory preallocated by user to store the fitting/estimated positions of input points.
191 			*/
192 			void walf3d_curve_vertex_eval(const double* local_origin, const double* local_coords, const int local_deg, const double* local_coeffs, const bool interp, const int npts2fit, const double* coords2fit, double* hiproj_new);
193 
194 
195 			//! \brief Get interally stored fitting results
196 			/** Get fittings results of a vertex, stored internally, results will be writtend to user provided memory
197 				* \param vid EntityHandle, a vertex in _verts2rec
198 				* \param geomtype GEOMTYPE, one of HISURFACE,HI3DCURVE,HI2DCURVE
199 				* \param coords vector, global coordinates of local uvw coordinate system axis directions will be appended to the end of coords
200 				* \param degree_out Reference to Integer, order of polynomial fittings for vid
201 				* \param coeffs vector, coefficients of local polynomial fittings in monomial basis will be appended to the end of coeffs
202 				* \param interp Reference to Boolean, true =  interpolation
203 			*/
204 			bool get_fittings_data(EntityHandle vid, GEOMTYPE& geomtype, std::vector<double>& coords, int& degree_out, std::vector<double>& coeffs, bool& interp);
205 
206 			//Helper function: estimate require number of ghost layers in parallel setting
estimate_num_ghost_layers(int degree,bool interp=false)207 			static int estimate_num_ghost_layers(int degree,bool interp=false){
208 				return 1+(interp?((degree+1)>>1)+((degree+1)&1):((degree+2)>>1)+((degree+2)&1));
209 			};
210 
211 		protected:
212 			Core *mbImpl;
213 			ParallelComm *pcomm;
214 			HalfFacetRep *ahf;
215 			//prevent copying
216 			HiReconstruction(const HiReconstruction& source);
217 			HiReconstruction& operator= (const HiReconstruction& right);
218 
219 			//mesh on which to perform reconstruction
220 			EntityHandle _mesh2rec;
221 			//_verts2rec all locally hosted vertices, in parallel might be different from _invert which is all the vertices in _mesh2rec, including ghost vertices
222 			Range _verts2rec,_inverts,_inedges,_infaces,_incells;
223 			size_t _nv2rec;//size of _verts2rec
224 
225 			int _MAXPNTS,_MINPNTS;
226 			double _MINEPS;
227 
228 			//in curve mesh, _hasderiv=true means vertex tangent vectors have been computed over _verts2rec
229 			//in surface mesh, _hasderiv=true means vertex normals have been computed over _verts2rec
230 			bool _hasderiv;
231 
232 			GEOMTYPE _geom;
233 			int _dim;
234 			bool _hasfittings;
235 			bool _initfittings;
236 			std::vector<double> _local_coords;
237 			std::vector<double> _local_fit_coeffs;
238 			std::vector<size_t> _vertID2coeffID;
239 			std::vector<int> _degrees_out;
240 			std::vector<bool> _interps;
241 
242 			//Estimate stencil size
243 			int estimate_num_rings(int degree,bool interp);
244 
245 			//! \brief Given a vertex, return the incident elements with dimension elemdim
246 			/** Wrapper of MOAB Core->get_adjacencies and HalfRep->get_up_adjacencies, depends on if USE_AHF is defined
247 				* \param vid EntityHandle of vertex
248 				* \param elemdim Integer, dimension of elements incidented in vid
249 				* \param adjents vector<EntityHandle>, container which push incident elements in
250 			*/
251 			ErrorCode vertex_get_incident_elements(const EntityHandle& vid, const int elemdim, std::vector<EntityHandle>& adjents);
252 
253 			//! \brief Get n-ring neighbor vertices, assuming curve/surface mesh, not volume mesh
254 			/** Given a vertex, find its n-ring neighbor vertices including itself in _mesrh2rec.
255 				* 1-ring neighbor vertices of a vertex are the vertices connected with this vertex with an edge
256 				* n-ring vertices are obtained first get the 1-ring vertices and then get the 1-ring of these vertices, and so on
257 				* \param vid EntityHandle, vertex around which to get n-ring vertices
258 				* \param ring Integer, number of rings
259 				* \param minpnts Integer, number of minimum vertices to obtain, if the input ring could not provide enough vertices, i.e. more than minpnts, then expand the number of rings
260 				* \param ngbvs Range, the n-ring vertices of vid, including vid. If too many points found, i.e. more than _MAXPNTS, then terminate early.
261 			*/
262 			ErrorCode obtain_nring_ngbvs(const EntityHandle vid, int ring, const int minpnts, Range& ngbvs);
263 
264 			/** Initialize the storage for fitting results over _mesh2rec, curve/surface mesh
265 				* Two options are provided: a) use uniform degree for all vertices b) use customized degrees for different vertices
266 				* After calling of initializing functions, _initfitting is set to be true, the fitting result could be stored internally
267 			*/
268 			void initialize_surf_geom(const int degree);
269 			void initialize_surf_geom(const size_t npts, const int* degrees);
270 			void initialize_3Dcurve_geom(const int degree);
271 			void initialize_3Dcurve_geom(const size_t npts, const int* degrees);
272 
273 			/** Save fitting results of a vertex into internal storage
274 				* \param vid EntityHandle, a vertex in _mesh2rec, in _verts2rec
275 				* \param coords Pointer to double array, global coordinates of local uvw coordinate system axis directions
276 				* \param degree_out Integer, order of polynomial fittings for vid
277 				* \param coeffs Pointer to double array, coefficients of local polynomial fittings in monomial basis
278 				* \param interp Boolean, true =  interpolation
279 			*/
280 			//ErrorCode set_geom_data_surf(const EntityHandle vid, const double* coords, const double degree_out, const double* coeffs, bool interp);
281 			//ErrorCode set_geom_data_3Dcurve(const EntityHandle vid, const double* coords, const double degree_out, const double* coeffs, bool interp);
282 
283 			/** Compute area weighted average vertex normals for given vertex, assuming surface mesh
284 				* For arbitrary polygon mesh, use incident two edges of each incident polygon of this vertex to form a triangle, then use
285 				* these incident "triangles" to compute area weighted average vertex normals
286 				* \param vid EntityHandle, vertex in _mesh2rec, might be ghost vertex
287 				* \param nrm Pointer to 3-doubles array, preallocated by user
288 			*/
289 			ErrorCode average_vertex_normal(const EntityHandle vid, double* nrm);
290 
291 			/** Compute weighted average vertex normals for all vertices in _verts2rec, not including ghost vertices, results
292 				* are stored interally in _local_coords
293 			*/
294 			ErrorCode compute_average_vertex_normals_surf();
295 
296 			/** Return the normals of given vertices in a Range, writing to preallocated memory
297 				* If normals have been computed and stored, just access them
298 				* If not, compute on the fly
299 				* \param vertsh Range, EntityHandles of vertices
300 				* \param nrms Pointer of array of doubles, size = 3*vertsh.size()
301 			*/
302 			ErrorCode get_normals_surf(const Range& vertsh, double* nrms);
303 
304 			/** Compute area weighted average vertex tangent vector for given vertex, assuming curve mesh
305 				* Use incident two edges of vertex as estimatation of tangent vectors, weighted by length
306 				* \param vid EntityHandle, vertex in _mesh2rec, might be ghost vertex
307 				* \param tang Pointer to 3-doubles array, preallocated by user
308 			*/
309 			ErrorCode average_vertex_tangent(const EntityHandle vid, double* tang);
310 
311 			/** Compute weighted average vertex tangent vectors for all vertices in _verts2rec, not including ghost vertices, results
312 				* are stored interally in _local_coords
313 			*/
314 			ErrorCode compute_average_vertex_tangents_curve();
315 
316 			/** Return the tangent vectors of given vertices in a Range, writing to preallocated memory
317 				* If tangent vectors have been computed and stored, just access them
318 				* If not, compute on the fly
319 				* \param vertsh Range, EntityHandles of vertices
320 				* \param tangs Pointer of array of doubles, size = 3*vertsh.size()
321 			*/
322 			ErrorCode get_tangents_curve(const Range& vertsh, double* tangs);
323 
324 			//! \brief Compute local coordinates system of a vertex, and perform vertex based polynomial fittings of local height function
325 			/** This function take the first vertex of input as center, and build local uv-plane by estimating vertex normals and tangent planes
326 				* Then other vertices forms vectors starting from center and then are projectd onto this uv-plane to form a local height function. Local fitting of this local height function
327 				* is performed in WLS sense, according if interpolation required or not.
328 				* \param nverts Integer, number of vertices of input
329 				* \param ngbcors Pointer to array of doubles, size = 3*nverts, coordinates of input vertices, first will be center
330 				* \param ngbnrms Pointer to array of doubles, size = 3*nverts, vertex normals of input vertices
331 				* \param degree Integer, user specified fitting degree
332 				* \param interp Boolean, user input, interpolation or not
333 				* \param safeguard Boolean, true = use safeguarded numerical method in computing
334 				* \param ncoords Integer, size of *coords, should be 9, used for check
335 				* \param coords Pointer to array of doubles, preallocated memory for storing the glocal coordinates of local uvw axis directions
336 				* \param ncoeffs Integer, size of *coeffs, should be (degree+2)(degree+1)/2, used for check
337 				* \param coeffs Pointer to array of doubles, preallocated memory for storing coefficients of local fittings in monomial basis
338 				* \param degree_out Pointer to integer, order of resulted polynomial of fitting, could be downgraded due to numerical issues
339 				* \param degree_pnt Pointer to integer, polynomial fitting order determined by stencil size/number of points
340 				* \param degree_qr Pointer to integer, polynomial fitting order determined by Vandermonde system condition number
341 			*/
342 			void polyfit3d_surf_get_coeff(const int nverts, const double* ngbcors, const double* ngbnrms, int degree, const bool interp, const bool safeguard, const int ncoords, double* coords, const int ncoeffs, double* coeffs, int* degree_out, int* degree_pnt, int* degree_qr);
343 			//! \brief Form and solve Vandermonde system of bi-variables
344 			void eval_vander_bivar_cmf(const int npts2fit, const double* us, const int ndim, double* bs, int degree, const double* ws, const bool interp, const bool safeguard, int* degree_out, int* degree_pnt, int* degree_qr);
345 
346 			//! \brief Compute local single variable coordinate system of a vertex, and perform vertex based polynomial fittings of three global coordinates axis
347 			/** This function take the first vertex of input as center, and build local u-line by estimating tangent vector
348 				* Then other vertices form vectors originating from center and vectors then are projectd onto this u-plane to form three local height functions,
349 				* one for each coordinates axis. Local fitting of these local height functions are performed in WLS sense, according if interpolation required or not.
350 				* \param nverts Integer, number of vertices of input
351 				* \param ngbcors Pointer to array of doubles, size = 3*nverts, coordinates of input vertices, first will be center
352 				* \param ngbtangs Pointer to array of doubles, size = 3*nverts, vertex tangent vectors of input vertices
353 				* \param degree Integer, user specified fitting degree
354 				* \param interp Boolean, user input, interpolation or not
355 				* \param safeguard Boolean, true = use safeguarded numerical method in computing
356 				* \param ncoords Integer, size of *coords, should be 3, used for check
357 				* \param coords Pointer to array of doubles, preallocated memory for storing the glocal coordinates of local u axis direction
358 				* \param ncoeffs Integer, size of *coeffs, should be 3*(degree+1), used for check
359 				* \param coeffs Pointer to array of doubles, preallocated memory for storing coefficients of local fittings in monomial basis
360 				* \param degree_out Pointer to integer, order of resulted polynomial of fitting, could be downgraded due to numerical issues
361 			*/
362 			void polyfit3d_curve_get_coeff(const int nverts, const double* ngbcors, const double* ngbtangs, int degree, const bool interp, const bool safeguard, const int ncoords, double* coords, const int ncoeffs, double* coeffs, int* degree_out);
363 			//! \brief Form and solve Vandermonde system of single-variables
364 			void eval_vander_univar_cmf(const int npts2fit, const double* us, const int ndim, double* bs, int degree, const double* ws, const bool interp, const bool safeguard, int* degree_out);
365 			//! \brief Compute weights for points selected in weighted least square fittigns
366 			int compute_weights(const int nrows, const int ncols, const double* us, const int nngbs, const double* ngbnrms, const int degree, const double toler, double* ws);
367 			//! \brief Check the correctness of barycentric coordination, wi>=0 and sum(wi)=1
368 			bool check_barycentric_coords(const int nws, const double* naturalcoords);
369 	};//class HiReconstruction
370 }//namespace moab
371 #endif
372