/// <summary> /// Test a triangle's subtriangle whether they are partial. // if level is nonzero, recurse, unless some conditions are met /// </summary> /// <param name="min_addlevel"></param> /// <param name="level"></param> /// <param name="hid"></param> /// <param name="v0"></param> /// <param name="v1"></param> /// <param name="v2"></param> /// <param name="PPrev"></param> private void testPartial(int min_addlevel, int level, Int64 hid, Cartesian v0, Cartesian v1, Cartesian v2, int PPrev){ Int64[] ids = new Int64[4]; Int64 id0; Convex.Savecode why; Convex.Markup[] m = new Convex.Markup[4]; bool keepgoing; // force later termination of recorsion int P, F;// count number of partials and fulls // Console.WriteLine("testpartial level {0}", level); Cartesian w0 = new Cartesian(v1); w0.addMe(v2); w0.normalizeMe(); Cartesian w1 = new Cartesian(v0); w1.addMe(v2); w1.normalizeMe(); Cartesian w2 = new Cartesian(v1); w2.addMe(v0); w2.normalizeMe(); ids[0] = id0 = hid << 2; ids[1] = id0 + 1; ids[2] = id0 + 2; ids[3] = id0 + 3; m[0] = testNode(v0, w2, w1, ids[0]); m[1] = testNode(v1, w0, w2, ids[1]); m[2] = testNode(v2, w1, w0, ids[2]); m[3] = testNode(w0, w1, w2, ids[3]); // [DEBUG] After 36 entries F = 0; if (m[0] == Markup.Full) F++; if (m[1] == Markup.Full) F++; if (m[2] == Markup.Full) F++; if (m[3] == Markup.Full) F++; P = 0; if (m[0] == Markup.Partial) P++; if (m[1] == Markup.Partial) P++; if (m[2] == Markup.Partial) P++; if (m[3] == Markup.Partial) P++; // // Several interesting cases for saving this (the parent) trixel. // Case P==4, all four children are partials, so pretend parent is full, we save and return // Case P==3, and F==1, most of the parent is in, so pretend that parent is full again // Case P==2 or 3, but the previous testPartial had three partials, so parent was in an arc // as opposed to previous partials being fewer, so parent was in a tiny corner... why = Savecode.Nosave; // // The Big Idea: several heuristics cut off further subdivisions // but this may cause huge overshoots! // So, I added an option to tweak the heuristics // with a flagarray to ignore certain heuristic on demand // // code abbrev summary // ---------------------------------------------------- // p4 peq4 all four children are partial // f2 fge2 more than two children are full // p3 peq3feq1 3 are partial one is full // p1 pgt1ppreveq3 more than 1 partial, parent had three partials // a good halfspace to test this on is // (1, 0.8, 0.5, 0.9998) normalized, of course. // /* <EXP> */ //if (HtmState.Instance.maxlevel - level >= this._smallestLevel) { // why = Savecode.Reachedlevel; //} /* </EXP> */ // if you remove EXP code, make sure that else is also removed below // We sometimes force the smallest level // maxlevel is usually 20 - level is levels yet to go. // _smalletstLevel keepgoing = (HtmState.Instance.maxlevel - level >= this._smallestLevel); if (level <= 0) why = Savecode.Reachedlevel; else if (P == 4) why = Savecode.Peq4; else if (F >= 2) why = Savecode.Fge2; else if ((P == 3) && (F == 1)) why = Savecode.Peq3Feq1; // // Feb 07, 2005, ruls // if the feature size (side) is in the same ballpark // as the radius of the smallest circle among the halfspaces // Use this condition to stop if current level is greater than // smallest desired level else if (keepgoing && (P > 1 && PPrev == 3)) // WAS1 : else if ((P > 1 && PPrev == 3)) // WAS2 : else if ((level <= this._smallestLevel) && (P > 1 && PPrev == 3)) // level is levels yet to go, so currect level is HtmState.Instance.maxlevel - level { why = Savecode.Pgt1Ppreveq3; } // // from the C++ source: // if ((level-- <= 0) || ((P == 4) || (F >= 2) || (P == 3 && F == 1) || (P > 1 && PPrev == 3))){ // in above legacy line, level-- was wrong, it should be decremented after // all the tests are made // GYF: added to ensure a minimum depth // if (min_addlevel > 0 && level > 0) why = Savecode.Nosave; // Force recursion, unless if (why != Savecode.Nosave){ /// /// <LOG>"Saving <hid> code <why> "</LOG> /// if(_mode == Mode.File){ this._tracefile.dump("Saving {0} why {1} (level to go {2})", hid, why, level); } saveTrixel(hid, "1", level); return; } else { // look at each child, see if some need saving; for(int i=0; i<4; i++){ if (m[i] == Markup.Full){ /// /// <LOG>"saving <hid> code Child is full"</LOG> if (_mode == Mode.File){ this._tracefile.dump("Saving {0} why {1} (level to go {2})", ids[i], Savecode.Childisfull, level); } saveTrixel(ids[i], "2", level); } } // look at the four kids again, for partials level--; // <--- moved here from above, see legacy comment min_addlevel--; if (m[0] == Markup.Partial) testPartial(min_addlevel, level, ids[0], v0, w2, w1, P); if (m[1] == Markup.Partial) testPartial(min_addlevel, level, ids[1], v1, w0, w2, P); if (m[2] == Markup.Partial) testPartial(min_addlevel, level, ids[2], v2, w1, w0, P); if (m[3] == Markup.Partial) testPartial(min_addlevel, level, ids[3], w0, w1, w2, P); } }