public static string[] SplitPatternList(SplitterOptions options, string originalString, string stringPattern, Regex regexPattern) { return(regexPattern == null ? Regex.Split(originalString, stringPattern) : options.LimitLength > 0 ? regexPattern.Split(originalString, options.LimitLength) : regexPattern.Split(originalString)); }
public static (string, string) SplitMap(SplitterOptions options, string middleString) { var t = middleString.Split(options.MapSeparator); var key = t[0]; var value = t.Length > 1 ? t[1] : string.Empty; return(key, value); }
public static (string, string) SplitMap(SplitterOptions options, string middleString) { #if NETFRAMEWORK || NETSTANDARD2_0 var t = middleString.Split(new[] { options.MapSeparator }, StringSplitOptions.None); #else var t = middleString.Split(options.MapSeparator); #endif var key = t[0]; var value = t.Length > 1 ? t[1] : string.Empty; return(key, value); }
public static string[] SplitList(SplitterOptions options, string originalString, string[] on) { return(originalString.Split(on, options.GetStringSplitOptions())); }
public static IEnumerable <string> OptionalRange(SplitterOptions options, string[] middleStrings) { return(options.TrimResultsFlag ? middleStrings.Select(options.TrimFunc) : middleStrings); }
/// <summary> /// Splits the supplied PolyMeshes on the specified plane and /// returns the desired results (specified by the options parameter) /// in a pair containing lists of PolyMeshes for the negative /// (element 0) and the positive side (element 1) of the plane. /// Note that the normal vector of the plane need not be normalized. /// </summary> public static (List <PolyMesh>, List <PolyMesh>) SplitOnPlane( this IEnumerable <PolyMesh> polyMeshes, Plane3d plane, double epsilon, SplitterOptions options) { return(polyMeshes.SplitOnPlane(plane, epsilon, options, s_polyMeshSplitOnPlane)); }
/// <summary> /// Splits the mesh on the specified plane in a pair containing the negative /// (element 0) and the positive side (element 1) of the plane. /// Note that the normal vector of the plane need not be normalized. /// </summary> public (PolyMesh, PolyMesh) SplitOnPlane( Plane3d plane, double epsilon, SplitterOptions options) { var heightArray = m_positionArray.Map( m_vertexCount, p => plane.Height(p)); var splitter = new PolygonSplitter( m_firstIndexArray, m_faceCount, m_vertexIndexArray, m_faceVertexCountRange.Max, heightArray, epsilon, options); var result = (default(PolyMesh), default(PolyMesh)); for (int side = 0; side < 2; side++) { var fia = splitter.FirstIndexArray(side); if (fia != null) { if (splitter.IsEqualToInput(side)) { //result[side] = this; switch (side) { case 0: result = (this, result.Item2); break; case 1: result = (result.Item1, this); break; default: throw new IndexOutOfRangeException(); } } else { var pm = new PolyMesh() { FirstIndexArray = fia, VertexIndexArray = splitter.VertexIndexArray(side), InstanceAttributes = InstanceAttributes, FaceAttributes = FaceIAttributes.Select( a => splitter.FaceAttribute(side, a)).ToSymbolDict(), VertexAttributes = VertexIAttributes.Select( a => splitter.VertexAttribute(side, a)).ToSymbolDict(), FaceVertexAttributes = FaceVertexIAttributes.Select( a => splitter.FaceVertexAttribute(side, a)).ToSymbolDict(), }; //result[side] = pm; switch (side) { case 0: result = (pm, result.Item2); break; case 1: result = (result.Item1, pm); break; default: throw new IndexOutOfRangeException(); } } } } return(result); }
/// <summary> /// A splitter can split a vertex-indexed face set, based on the /// supplied array of vertexHeights, which indicate for each vertex /// vi if it belongs to the negative split side (vertexHeights[vi] /// < 0.0) or positive split side (vertexHeights[vi] >= 0.0). /// </summary> public PolygonSplitter( int[] fia, int faceCount, int[] via, int maxFaceVertexCount, double[] vertexHeights, double eps, SplitterOptions options) { int vc = vertexHeights.Length; int vertexIndexCount = fia[faceCount]; bool doNeg = (options & SplitterOptions.Negative) != 0; bool doPos = (options & SplitterOptions.Positive) != 0; if (doPos && vertexHeights.All(h => h >= -eps)) { m_pfia = fia; m_pvia = via; m_ofia = null; return; } if (doNeg && vertexHeights.All(h => h <= eps)) { m_nfia = fia; m_nvia = via; m_ofia = null; return; } m_ofia = fia; var lineMap = new Dict <Line1i, (int, int, int)>(); m_spl = doNeg ? new List <SplitPoint>() : null; m_nvl = doPos ? new List <Vertex>() : null; m_pvl = doPos ? new List <Vertex>() : null; m_nfl = doNeg ? new List <Face>() : null; m_pfl = doPos ? new List <Face>() : null; int[] nffm = doNeg ? new int[faceCount].Set(-1) : null; int[] pffm = doPos ? new int[faceCount].Set(-1) : null; int[] nvfm = doNeg ? new int[vc].Set(-1) : null; int[] pvfm = doPos ? new int[vc].Set(-1) : null; var ha = new double[maxFaceVertexCount]; int nfc = 0, pfc = 0, nvic = 0, pvic = 0, nvc = 0, pvc = 0; for (int fvi = fia[0], fi = 0; fi < faceCount; fi++) { int nc = 0, pc = 0, zc = 0, fve = fia[fi + 1], fvc = fve - fvi; for (int fs = 0; fs < fvc; fs++) { double height = ha[fs] = vertexHeights[via[fvi + fs]]; if (height < -eps) { ++nc; continue; } if (height > +eps) { ++pc; continue; } ++zc; } if (nc == 0) { if (doPos) { pffm[fi] = pfc++; pvic += fvc; for (int fs = 0; fs < fvc; fs++) { pvfm.ForwardMapAdd(via[fvi + fs], ref pvc); } } } else if (pc == 0) { if (doNeg) { nffm[fi] = nfc++; nvic += fvc; for (int fs = 0; fs < fvc; fs++) { nvfm.ForwardMapAdd(via[fvi + fs], ref nvc); } } } else { if (zc > 2) { Report.Warn("non-convex polygon encountered"); } var nfvl = new List <FaceVertex>(nc + 2); var pfvl = new List <FaceVertex>(pc + 2); int sb = ha[0] > eps ? 1 : (ha[0] < -eps ? -1 : 0), vib = via[fvi]; int i0 = 0, s0 = sb, vi0 = vib; if (doNeg && sb <= 0) { nfvl.Add(new FaceVertex(nvfm.ForwardMapAdd(vib, ref nvc), 0)); } if (doPos && sb >= 0) { pfvl.Add(new FaceVertex(pvfm.ForwardMapAdd(vib, ref pvc), 0)); } for (int i1 = 1; i1 < fvc; i0 = i1++) { int s1 = ha[i1] > eps ? 1 : (ha[i1] < -eps ? -1 : 0), vi1 = via[fvi + i1]; if (s0 != 0 && s1 != 0 && s0 != s1) { double t = ha[i0] / (ha[i0] - ha[i1]); var key = Line1i.CreateSorted(vi0, vi1); (int, int, int)v; if (!lineMap.TryGetValue(key, out v)) { v = lineMap[key] = (nvc++, pvc++, m_spl.Count); m_spl.Add(new SplitPoint(t, vi0, vi1)); } if (doNeg) { m_nvl.Add(new Vertex(v.Item1, v.Item3, t, i0)); nfvl.Add(new FaceVertex(v.Item1, -m_nvl.Count)); } if (doPos) { m_pvl.Add(new Vertex(v.Item2, v.Item3, t, i0)); pfvl.Add(new FaceVertex(v.Item2, -m_pvl.Count)); } } if (doNeg && s1 <= 0) { nfvl.Add(new FaceVertex(nvfm.ForwardMapAdd(vi1, ref nvc), i1)); } if (doPos && s1 >= 0) { pfvl.Add(new FaceVertex(pvfm.ForwardMapAdd(vi1, ref pvc), i1)); } vi0 = vi1; s0 = s1; } if (s0 != 0 && sb != 0 && s0 != sb) { double t = ha[i0] / (ha[i0] - ha[0]); var key = Line1i.CreateSorted(vi0, vib); (int, int, int)v; if (!lineMap.TryGetValue(key, out v)) { v = lineMap[key] = (nvc++, pvc++, m_spl.Count); m_spl.Add(new SplitPoint(t, vi0, vib)); } if (doNeg) { m_nvl.Add(new Vertex(v.Item1, v.Item3, t, i0)); nfvl.Add(new FaceVertex(v.Item1, -m_nvl.Count)); } if (doPos) { m_pvl.Add(new Vertex(v.Item2, v.Item3, t, i0)); pfvl.Add(new FaceVertex(v.Item2, -m_pvl.Count)); } } if (doNeg && nfvl.Count > 2) { m_nfl.Add(new Face(fi, nfvl)); nvic += nfvl.Count; } if (doPos && pfvl.Count > 2) { m_pfl.Add(new Face(fi, pfvl)); pvic += pfvl.Count; } } fvi = fve; } if (doNeg && (nfc > 0 || m_nfl.Count > 0)) { CalculateIndices(fia, faceCount, via, nfc, nvic, nvc, nffm, m_nfl, nvfm, out m_nfia, out m_nvia, out m_nfbm, out m_nvbm); } if (doPos && (pfc > 0 || m_pfl.Count > 0)) { CalculateIndices(fia, faceCount, via, pfc, pvic, pvc, pffm, m_pfl, pvfm, out m_pfia, out m_pvia, out m_pfbm, out m_pvbm); } }
/// <summary> /// A splitter can split a vertex-indexed triangle set, based on the /// supplied array of vertexHeights, which indicate for each vertex /// vi if it belongs to the negative split side (vertexHeights[vi] /// < 0.0) or positive split side (vertexHeights[vi] >= 0.0). /// </summary> public TriangleSplitter(int[] indices, double[] vertexHeights, double eps, SplitterOptions options) { m_negativeIndices = null; m_positiveIndices = null; bool doNeg = (options & SplitterOptions.Negative) != 0; bool doPos = (options & SplitterOptions.Positive) != 0; if (doPos && vertexHeights.All(h => h >= -eps)) { m_positiveIndices = indices; m_positiveVertexBackwardMap = null; // flag: move input to positive return; } if (doNeg && vertexHeights.All(h => h <= eps)) { m_negativeIndices = indices; m_negativeVertexBackwardMap = null; // flag: move input to negative return; } var lineMap = new Dictionary <Line1i, Line1i>(); var negTriangleList = doNeg ? new List <(int, Triangle1i)>() : null; var posTriangleList = doPos ? new List <(int, Triangle1i)>() : null; m_negVertexMap = doNeg ? new Dictionary <int, Line1iPoint>() : null; m_posVertexMap = doPos ? new Dictionary <int, Line1iPoint>() : null; int tc = indices.Length / 3; int ntc = 0; int ptc = 0; int nvc = 0; int pvc = 0; int[] negTriangleForwardMap = doNeg ? new int[tc].Set(-1) : null; int[] posTriangleForwardMap = doPos ? new int[tc].Set(-1) : null; int[] negVertexForwardMap = doNeg ? new int[vertexHeights.Length].Set(-1) : null; int[] posVertexForwardMap = doPos ? new int[vertexHeights.Length].Set(-1) : null; var ia = new int[3]; var ha = new double[3]; var negIndices = new List <int>(4); var posIndices = new List <int>(4); for (int ti = 0; ti < tc; ti++) { int nc = 0, pc = 0; int tvi = 3 * ti; for (int ts = 0; ts < 3; ts++) { int vi = indices[tvi + ts]; ia[ts] = vi; double height = ha[ts] = vertexHeights[vi]; if (height < -eps) { ++nc; continue; } if (height > +eps) { ++pc; continue; } } if (nc == 0) { if (doPos) { posTriangleForwardMap[ti] = ptc++; foreach (var vi in ia) { posVertexForwardMap.ForwardMapAdd(vi, ref pvc); } } } else if (pc == 0) { if (doNeg) { negTriangleForwardMap[ti] = ntc++; foreach (var vi in ia) { negVertexForwardMap.ForwardMapAdd(vi, ref nvc); } } } else { int sb = ha[0] > eps ? 1 : (ha[0] < -eps ? -1 : 0); int vi = ia[0]; if (doNeg && sb <= 0) { negIndices.Add(negVertexForwardMap.ForwardMapAdd(vi, ref nvc)); } if (doPos && sb >= 0) { posIndices.Add(posVertexForwardMap.ForwardMapAdd(vi, ref pvc)); } int i0 = 0, i1 = 1; int s0 = sb; while (i1 < 3) { int s1 = ha[i1] > eps ? 1 : (ha[i1] < -eps ? -1 : 0); if (s0 != 0 && s1 != 0 && s0 != s1) { double t = ha[i0] / (ha[i0] - ha[i1]); int vi0 = ia[i0], vi1 = ia[i1]; var key = Line1i.CreateSorted(vi0, vi1); if (!lineMap.TryGetValue(key, out Line1i line)) { var sp = new Line1iPoint(vi0, vi1, t); if (doNeg) { m_negVertexMap[line.I0 = nvc++] = sp; } if (doPos) { m_posVertexMap[line.I1 = pvc++] = sp; } lineMap[key] = line; } if (doNeg) { negIndices.Add(line.I0); } if (doPos) { posIndices.Add(line.I1); } } vi = ia[i1]; if (doNeg && s1 <= 0) { negIndices.Add(negVertexForwardMap.ForwardMapAdd(vi, ref nvc)); } if (doPos && s1 >= 0) { posIndices.Add(posVertexForwardMap.ForwardMapAdd(vi, ref pvc)); } i0 = i1++; s0 = s1; } if (s0 != 0 && sb != 0 && s0 != sb) { double t = ha[i0] / (ha[i0] - ha[0]); int vi0 = ia[i0], vi1 = ia[0]; var key = Line1i.CreateSorted(vi0, vi1); if (!lineMap.TryGetValue(key, out Line1i line)) { var sp = new Line1iPoint(vi0, vi1, t); if (doNeg) { m_negVertexMap[line.I0 = nvc++] = sp; } if (doPos) { m_posVertexMap[line.I1 = pvc++] = sp; } lineMap[key] = line; } if (doNeg) { negIndices.Add(line.I0); } if (doPos) { posIndices.Add(line.I1); } } // at this point we have lists of indices for the positive and // negative triangles if (doNeg && negIndices.Count > 2) { for (int i = 1; i < negIndices.Count - 1; i++) { negTriangleList.Add( (ntc++, new Triangle1i(negIndices[0], negIndices[i], negIndices[i + 1]))); } } if (doPos && posIndices.Count > 2) { for (int i = 1; i < posIndices.Count - 1; i++) { posTriangleList.Add( (ptc++, new Triangle1i(posIndices[0], posIndices[i], posIndices[i + 1]))); } } negIndices.Clear(); posIndices.Clear(); } } if (doNeg && ntc > 0) { m_negativeIndices = CalculateIndices(indices, ntc, negTriangleForwardMap, negTriangleList, negVertexForwardMap); m_negativeVertexBackwardMap = negVertexForwardMap.CreateBackMap(nvc); } if (doPos && ptc > 0) { m_positiveIndices = CalculateIndices(indices, ptc, posTriangleForwardMap, posTriangleList, posVertexForwardMap); m_positiveVertexBackwardMap = posVertexForwardMap.CreateBackMap(pvc); } }
/// <summary> /// Main processing method /// </summary> /// <returns>0 if no error, error code if an error</returns> public static int Main() { var commandLineParser = new clsParseCommandLine(); // Initialize the options mInputFilePath = string.Empty; mOutputDirectoryName = string.Empty; mParameterFilePath = string.Empty; mRecurseDirectories = false; mMaxLevelsToRecurse = 0; mLogMessagesToFile = false; var options = new SplitterOptions(); try { var proceed = commandLineParser.ParseCommandLine() && SetOptionsUsingCommandLineParameters(commandLineParser, options); if (!proceed || commandLineParser.NeedToShowHelp || commandLineParser.ParameterCount + commandLineParser.NonSwitchParameterCount == 0 || mInputFilePath.Length == 0) { ShowProgramHelp(); return(-1); } // Note: mSplitCount and mSplitCount will be overridden if mParameterFilePath points to a valid parameter file that has these settings defined var fastaFileSplitter = new clsFastaFileSplitter(options) { LogMessagesToFile = mLogMessagesToFile }; RegisterEvents(fastaFileSplitter); fastaFileSplitter.ProgressReset += ProgressReset; int returnCode; if (mRecurseDirectories) { if (fastaFileSplitter.ProcessFilesAndRecurseDirectories(mInputFilePath, mOutputDirectoryName, mOutputDirectoryAlternatePath, mRecreateDirectoryHierarchyInAlternatePath, mParameterFilePath, mMaxLevelsToRecurse)) { returnCode = 0; } else { if (fastaFileSplitter.ErrorCode == ProcessFilesBase.ProcessFilesErrorCodes.NoError) { returnCode = -1; } else { returnCode = (int)fastaFileSplitter.ErrorCode; } } } else if (fastaFileSplitter.ProcessFilesWildcard(mInputFilePath, mOutputDirectoryName, mParameterFilePath)) { returnCode = 0; } else { if (fastaFileSplitter.ErrorCode != ProcessFilesBase.ProcessFilesErrorCodes.NoError) { Console.WriteLine("Error while processing: " + fastaFileSplitter.GetErrorMessage()); } returnCode = (int)fastaFileSplitter.ErrorCode; } DisplayProgressPercent(mLastProgressReportValue, true); return(returnCode); } catch (Exception ex) { ConsoleMsgUtils.ShowError("Error occurred in modMain->Main", ex); return(-1); } }
private static bool SetOptionsUsingCommandLineParameters(clsParseCommandLine commandLineParser, SplitterOptions options) { // Returns True if no problems; otherwise, returns false var validParameters = new List <string> { "I", "N", "MB", "O", "P", "S", "A", "R", "L" }; try { // Make sure no invalid parameters are present if (commandLineParser.InvalidParametersPresent(validParameters)) { ConsoleMsgUtils.ShowErrors("Invalid command line parameters", (from item in commandLineParser.InvalidParameters(validParameters) select("/" + item)).ToList()); return(false); } // Query commandLineParser to see if various parameters are present if (commandLineParser.RetrieveValueForParameter("I", out var inputFilePath)) { mInputFilePath = inputFilePath; } else if (commandLineParser.NonSwitchParameterCount > 0) { mInputFilePath = commandLineParser.RetrieveNonSwitchParameter(0); } if (commandLineParser.RetrieveValueForParameter("N", out var splitCount)) { if (int.TryParse(splitCount, out var value)) { options.SplitCount = value; } else { ConsoleMsgUtils.ShowError( "Error parsing number from the /N parameter; " + "for example, use /N:{0} to specify the file be split into {0} parts", SplitterOptions.DEFAULT_SPLIT_COUNT); options.SplitCount = SplitterOptions.DEFAULT_SPLIT_COUNT; } } if (commandLineParser.RetrieveValueForParameter("MB", out var targetSizeMB)) { options.UseTargetFileSize = true; if (int.TryParse(targetSizeMB, out var value)) { options.TargetFastaFileSizeMB = value; } else { ConsoleMsgUtils.ShowError( "Error parsing number from the /MB parameter; " + "for example, use /MB:{0} to specify the file be split into files that are each {0} MB in size", SplitterOptions.DEFAULT_TARGET_FILE_SIZE_MB); options.TargetFastaFileSizeMB = SplitterOptions.DEFAULT_TARGET_FILE_SIZE_MB; } } if (commandLineParser.RetrieveValueForParameter("O", out var outputDirectory)) { mOutputDirectoryName = outputDirectory; } if (commandLineParser.RetrieveValueForParameter("P", out var parameterFile)) { mParameterFilePath = parameterFile; } if (commandLineParser.RetrieveValueForParameter("S", out var recurseSubdirectories)) { mRecurseDirectories = true; if (!int.TryParse(recurseSubdirectories, out mMaxLevelsToRecurse)) { mMaxLevelsToRecurse = 0; } } if (commandLineParser.RetrieveValueForParameter("A", out var alternateOutputDirectory)) { mOutputDirectoryAlternatePath = alternateOutputDirectory; } if (commandLineParser.IsParameterPresent("R")) { mRecreateDirectoryHierarchyInAlternatePath = true; } if (commandLineParser.IsParameterPresent("L")) { mLogMessagesToFile = true; } return(true); } catch (Exception ex) { ConsoleMsgUtils.ShowError("Error parsing the command line parameters", ex); return(false); } }
public static KeyValuePair <string, TValue> OptionalMap <TValue>(SplitterOptions options, string key, string value, Func <string, TValue> to) { return(options.MapTrimResultsFlag ? new KeyValuePair <string, TValue>(options.KeyTrimFunc(key), to(options.ValueTrimFunc(value))) : new KeyValuePair <string, TValue>(key, to(value))); }