// compute FWN cache for all points underneath this box protected void make_box_fast_winding_cache(int iBox, IEnumerable <int> pointIndices) { Util.gDevAssert(FastWindingCache.ContainsKey(iBox) == false); // construct cache var cacheInfo = new FWNInfo(); FastPointWinding.ComputeCoeffs(points, pointIndices, FastWindingAreaCache, ref cacheInfo.Center, ref cacheInfo.R, ref cacheInfo.Order1Vec, ref cacheInfo.Order2Mat); FastWindingCache[iBox] = cacheInfo; }
// evaluate the FWN cache for iBox protected double evaluate_box_fast_winding_cache(int iBox, ref Vector3d q) { FWNInfo cacheInfo = FastWindingCache[iBox]; if (FWNApproxOrder == 2) { return(FastPointWinding.EvaluateOrder2Approx(ref cacheInfo.Center, ref cacheInfo.Order1Vec, ref cacheInfo.Order2Mat, ref q)); } else { return(FastPointWinding.EvaluateOrder1Approx(ref cacheInfo.Center, ref cacheInfo.Order1Vec, ref q)); } }
// evaluate winding number contribution for all points below iBox protected double branch_fast_winding_num(int iBox, Vector3d p) { double branch_sum = 0; int idx = box_to_index[iBox]; if (idx < points_end) { // point-list case, array is [N t1 t2 ... tN] int num_pts = index_list[idx]; for (int i = 1; i <= num_pts; ++i) { int pi = index_list[idx + i]; Vector3d v = Points.GetVertex(pi); Vector3d n = Points.GetVertexNormal(pi); double a = FastWindingAreaCache[pi]; branch_sum += FastPointWinding.ExactEval(ref v, ref n, a, ref p); } } else { // internal node, either 1 or 2 child boxes int iChild1 = index_list[idx]; if (iChild1 < 0) { // 1 child, descend if nearer than cur min-dist iChild1 = (-iChild1) - 1; // if we have winding cache, we can more efficiently compute contribution of all points // below this box. Otherwise, recursively descend tree. bool contained = box_contains(iChild1, p); if (contained == false && can_use_fast_winding_cache(iChild1, ref p)) { branch_sum += evaluate_box_fast_winding_cache(iChild1, ref p); } else { branch_sum += branch_fast_winding_num(iChild1, p); } } else { // 2 children, descend closest first iChild1 = iChild1 - 1; int iChild2 = index_list[idx + 1] - 1; bool contained1 = box_contains(iChild1, p); if (contained1 == false && can_use_fast_winding_cache(iChild1, ref p)) { branch_sum += evaluate_box_fast_winding_cache(iChild1, ref p); } else { branch_sum += branch_fast_winding_num(iChild1, p); } bool contained2 = box_contains(iChild2, p); if (contained2 == false && can_use_fast_winding_cache(iChild2, ref p)) { branch_sum += evaluate_box_fast_winding_cache(iChild2, ref p); } else { branch_sum += branch_fast_winding_num(iChild2, p); } } } return(branch_sum); }