/// <summary> /// Sorts index array (optionally single threaded) /// Both variants return a CountdownEvent. For /// sequential execution (parallel = false), the /// returned event initially is signalled. /// </summary> public CountdownEvent SortVertexIndexArray( Order order, V3d eye, int[] vertexIndexArray, bool parallel = true) { var target = new TargetArray() { Via = vertexIndexArray, Finished = new CountdownEvent(1) }; Action <Action> runParallel = a => Task.Factory.StartNew(a); Action <Action> runSequential = a => a(); Action <Action> runChild = parallel ? runParallel : runSequential; if (order == Order.BackToFront) { runChild(() => { m_tree.SortBackToFront(this, target, 0, eye, true, runChild); target.Finished.Signal(); }); } else { runChild(() => { m_tree.SortFrontToBack(this, target, 0, eye, true, runChild); target.Finished.Signal(); }); } if (!parallel) { target.Finished.Wait(); } return(target.Finished); }
/// <summary> /// Note, that the parallel implementation of this method could be /// optimized, by providing separate node types for parallel and non /// parallel execution. /// </summary> internal void SortBackToFront( BspTree t, TargetArray via, int ti3, V3d eye, bool mainTask, Action <Action> runChild) { int nti3 = ti3; double height = V3d.Dot(m_normal, eye - m_point); if (height >= 0.0) { ti3 += m_negativeCount; foreach (int tiMul3 in m_zeroList) { t.GetTriangleVertexIndices(tiMul3, out via.Via[ti3], out via.Via[ti3 + 1], out via.Via[ti3 + 2]); ti3 += 3; } } else { nti3 += m_positiveCount; foreach (int tiMul3 in m_zeroList) { t.GetTriangleVertexIndices(tiMul3, out via.Via[nti3], out via.Via[nti3 + 1], out via.Via[nti3 + 2]); nti3 += 3; } } if (m_negativeTree != null) { if (mainTask && m_negativeCount < c_taskChunkSize) { // via.Count += 1; via.Finished.AddCount(1); runChild(() => { m_negativeTree.SortBackToFront( t, via, nti3, eye, false, runChild); via.Finished.Signal(); }); } else { m_negativeTree.SortBackToFront( t, via, nti3, eye, mainTask, runChild); } } if (m_positiveTree != null) { if (mainTask && m_positiveCount < c_taskChunkSize) { // via.Count += 1; via.Finished.AddCount(1); runChild(() => { m_positiveTree.SortBackToFront( t, via, ti3, eye, false, runChild); via.Finished.Signal(); }); } else { m_positiveTree.SortBackToFront( t, via, ti3, eye, mainTask, runChild); } } }