public Rect CalcSize(XdObjectJson xdObject, Rect rect) { var svg = SvgUtil.CreateSvg(xdObject, null); var bounds = SvgUtil.CalcBounds(svg); return(bounds); }
public (IComponent[], IAsset[]) Render(XdObjectJson xdObject, XdAssetHolder assetHolder, IObbGetter obbGetter) { var components = new List <IComponent>(); var assets = new List <IAsset>(); var color = xdObject.GetFillUnityColor(); var svg = SvgUtil.CreateSvg(xdObject); xdObject.Group.Children = new XdObjectJson[] { }; var size = obbGetter.Get(xdObject).Size; var spriteUid = $"{xdObject.GetSimpleName()}_{xdObject.Id.Substring(0, 8)}.png"; var svgHash = FastHash.CalculateHash(svg); var cachedSvg = assetHolder.GetCachedSvg(svgHash); if (cachedSvg != null) { spriteUid = cachedSvg.SpriteUid; } else { assets.Add(new SpriteAsset(spriteUid, svgHash, size, null, null)); var xdImportSettings = XdImporter.Settings; assetHolder.Save(spriteUid, () => SvgToPng.Convert(svg, size, xdImportSettings)); assetHolder.SaveCacheSvg(spriteUid, svgHash); } components.Add(new ImageComponent( spriteUid, new Color(1f, 1f, 1f, color.a), Vector2Int.one )); return(components.ToArray(), assets.ToArray()); }
static void Main(string[] args) { NestPath bin = new NestPath(); double binWidth = 75; double binHeight = 41; bin.add(0, 0); bin.add(binWidth, 0); bin.add(binWidth, binHeight); bin.add(0, binHeight); Console.WriteLine("Bin Size : Width = " + binWidth + " Height=" + binHeight); //将多边形转换为坐标形式 var nestPaths = SvgUtil.transferSvgIntoPolygons("test3.xml"); Console.WriteLine("Reading File = test1.xml"); Console.WriteLine("No of parts = " + nestPaths.Count); Config config = new Config(); Console.WriteLine("Configuring Nest"); Nest nest = new Nest(bin, nestPaths, config, 2); Console.WriteLine("Performing Nest"); List <List <Placement> > appliedPlacement = nest.startNest(); Console.WriteLine("Nesting Completed"); var svgPolygons = SvgUtil.svgGenerator(nestPaths, appliedPlacement, binWidth, binHeight); Console.WriteLine("Converted to SVG format"); SvgUtil.saveSvgFile(svgPolygons, "output.svg"); Console.WriteLine("Saved svg file..Opening File"); Process.Start("output.svg"); Console.ReadLine(); }
/// <summary> /// Get structure image with hilighting from a result link /// </summary> /// <param name="mc"></param> /// <param name="resultLink"></param> /// <param name="width"></param> /// <returns></returns> public override Bitmap GetImage( MetaColumn mc, string resultLink, int width) { string hls, rs; int hitListId, rowId; Lex.Split(resultLink, ",", out hls, out rs); int.TryParse(hls, out hitListId); int.TryParse(rs, out rowId); DateTime t0 = DateTime.Now; if (SwDao != null && SwDao.Swp != null) { bool color = SwDao.Swp.Highlight; bool align = SwDao.Swp.Align; string svgXml = SwDao.GetDepiction(hitListId, rowId, color, align); Bitmap bm = SvgUtil.GetBitmapFromSvgXml(svgXml, width); if (bm != null && BitmapCache != null) { BitmapCache[resultLink] = bm; // cache the bitmap } return(bm); } else { throw new Exception("Failed to get image for " + mc.MetaTable.Name + "." + mc.Name); } }
public (IComponent[], IAsset[]) Render(XdObjectJson xdObject, XdAssetHolder assetHolder, IObbGetter obbGetter) { var obb = obbGetter.Get(xdObject); var clipPath = xdObject.Meta.Ux.ClipPathResources.Children[0]; if (SvgUtil.IsAlphaOnly(clipPath)) { return(new IComponent[] { }, new IAsset[] { }); } var(imageComponent, assets) = ShapeObjectParser.RenderImage(clipPath, obb, assetHolder); return(new IComponent[] { new MaskComponent(imageComponent.Sprite) }, assets); }
public static Rect CalcSize(XdObjectJson xdObject) { var position = Vector2.zero; var size = Vector2.zero; var scaleBehavior = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.ScaleBehavior ?? "fill"; var xdObjectShape = xdObject.Shape; var shapeType = xdObjectShape.Type; if (SvgUtil.Types.Contains(shapeType)) { var svg = SvgUtil.CreateSvg(xdObject, null, true); var bounds = SvgUtil.CalcBounds(svg); if (bounds.width > 0.0001f && bounds.height > 0.0001f) { size = new Vector2(bounds.width, bounds.height); position = new Vector2(bounds.x, bounds.y); } } if (scaleBehavior == "cover" && size.x > 0.0001f && size.y > 0.0001f) { var imageWidth = xdObject.Style?.Fill?.Pattern?.Width ?? 1f; var imageHeight = xdObject.Style?.Fill?.Pattern?.Height ?? 1f; var imageSize = new Vector2(imageWidth, imageHeight); var imageAspect = imageSize.x / imageSize.y; var offsetX = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.OffsetX ?? 0f; var offsetY = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.OffsetY ?? 0f; var scale = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.Scale ?? 1.0f; // Widthに対するスケール var originalSize = size; var originalPosition = position; size = new Vector2( originalSize.x * scale, originalSize.x * scale / imageAspect ); position = new Vector2( originalPosition.x + (originalSize.x / 2f - size.x / 2f) + originalSize.x * offsetX, originalPosition.y + (originalSize.y / 2f - size.y / 2f) + originalSize.x / imageAspect * offsetY ); } return(new Rect(position, size)); }
public static Bitmap HelmToBitmap( MoleculeMx mol, int pixWidth) { Bitmap bm = null; string svg = mol?.SvgString; string msg = String.Format("mol.Id: {0}, mol.Helm: {1}", mol?.Id, mol?.HelmString); try { if (mol.PrimaryFormat == MoleculeFormat.Helm && Lex.IsDefined(svg)) { // if SVG available use it bm = SvgUtil.GetBitmapFromSvgXml(svg, pixWidth); if (Debug) { DebugLog.Message(msg + " used existing SVG"); } return(bm); } else { string helm = mol.HelmString; bm = HelmControl.GetBitmap(helm, pixWidth); if (Debug) { DebugLog.Message(msg + " generated SVG"); } return(bm); } } catch (Exception ex) { msg += "\r\n" + DebugLog.FormatExceptionMessage(ex); DebugLog.Message(msg); // log it return(null); } }
/// <summary> /// Load the browser with html to display the supplied SVG string /// </summary> /// <param name="svgString"></param> public void LoadSvgString(string svgString) { string html = SvgUtil.CreateHtlmWithSvgCenteredOnPage(svgString); LoadHtmlString(html); }
public static (ImageComponent, IAsset[]) RenderImage(XdObjectJson xdObject, Obb obb, XdAssetHolder assetHolder) { ImageComponent imageComponent = null; SpriteAsset asset = null; var color = xdObject.GetFillUnityColor(); var ux = xdObject.Style?.Fill?.Pattern?.Meta?.Ux; var flipX = ux?.FlipX ?? false; var flipY = ux?.FlipY ?? false; var direction = new Vector2Int(flipX ? -1 : 1, flipY ? -1 : 1); var shapeType = xdObject.Shape?.Type; if (!string.IsNullOrWhiteSpace(ux?.Uid)) { var spriteUid = $"{xdObject.GetSimpleName()}_{ux?.Uid.Substring(0, 8)}.png"; asset = new SpriteAsset(spriteUid, xdObject.Style.Fill.Pattern.Meta.Ux.HrefLastModifiedDate, obb.Size, null, null); imageComponent = new ImageComponent( spriteUid, color, direction ); assetHolder.Save(spriteUid, xdObject.Style.Fill.Pattern.Meta); } else if (SvgUtil.Types.Contains(shapeType)) { var spriteUid = $"{xdObject.GetSimpleName()}_{xdObject.Id.Substring(0, 8)}.png"; var svg = SvgUtil.CreateSvg(xdObject); var svgHash = FastHash.CalculateHash(svg); var cachedSvg = assetHolder.GetCachedSvg(svgHash); if (cachedSvg != null) { spriteUid = cachedSvg.SpriteUid; } else { asset = new SpriteAsset(spriteUid, svgHash, obb.Size, null, null); var xdImportSettings = XdImporter.Settings; assetHolder.Save(spriteUid, () => SvgToPng.Convert(svg, obb.Size, xdImportSettings)); assetHolder.SaveCacheSvg(spriteUid, svgHash); } imageComponent = new ImageComponent( spriteUid, new Color(1f, 1f, 1f, color.a), direction ); } else { Debug.LogError($"Unknown shape type {shapeType} in {xdObject.Name}({xdObject.Id}, {xdObject.Guid})"); } var assets = new List <IAsset>(); if (!xdObject.HasParameter("placeholder") && asset != null) { assets.Add(asset); } return(imageComponent, assets.ToArray()); }
public Rect CalcSize(XdObjectJson xdObject) { var position = Vector2.zero; var size = new Vector2(xdObject.Shape.Width, xdObject.Shape.Height); var scaleBehavior = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.ScaleBehavior ?? "fill"; var spriteUid = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.Uid; var shapeType = xdObject.Shape?.Type; if (!string.IsNullOrWhiteSpace(spriteUid)) { // nothing } else if (SvgUtil.Types.Contains(shapeType)) { var svg = SvgUtil.CreateSvg(xdObject); using (var reader = new StringReader(svg)) { var sceneInfo = SVGParser.ImportSVG(reader, ViewportOptions.DontPreserve); var tessOptions = SvgToPng.TessellationOptions; var geometry = VectorUtils.TessellateScene(sceneInfo.Scene, tessOptions, sceneInfo.NodeOpacity); var vertices = geometry.SelectMany(geom => geom.Vertices.Select(x => (geom.WorldTransform * x))).ToArray(); var bounds = VectorUtils.Bounds(vertices); if (bounds.width > 0.0001f && bounds.height > 0.0001f) { size = new Vector2(bounds.width, bounds.height); position = new Vector2(bounds.x, bounds.y); } } } if (scaleBehavior == "cover" && size.x > 0.0001f && size.y > 0.0001f) { var imageWidth = xdObject.Style?.Fill?.Pattern?.Width ?? 0f; var imageHeight = xdObject.Style?.Fill?.Pattern?.Height ?? 0f; var imageSize = new Vector2(imageWidth, imageHeight); var imageAspect = imageSize.x / imageSize.y; var instanceAspect = size.x / size.y; var offsetX = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.OffsetX ?? 0f; var offsetY = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.OffsetY ?? 0f; var scale = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.Scale ?? 1.0f; if (imageAspect > instanceAspect) { var prev = size.x; size.x = size.y * (imageSize.x / imageSize.y); position.x -= (size.x - prev) / 2f; position.x += offsetX * xdObject.Shape.Width * imageAspect / instanceAspect; position.y += offsetY * xdObject.Shape.Height; } else { var prev = size.y; size.y = size.x * (imageSize.y / imageSize.x); position.y -= (size.y - prev) / 2f; position.x += offsetX * xdObject.Shape.Width; position.y += offsetY * xdObject.Shape.Height * imageAspect / instanceAspect; } { var prev = size; size *= scale; position -= (size - prev) / 2f; } } return(new Rect(position, size)); }
public static Rect CalcSize(XdObjectJson xdObject) { var position = Vector2.zero; var size = Vector2.zero; var scaleBehavior = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.ScaleBehavior ?? "fill"; var shapeType = xdObject.Shape?.Type; if (shapeType == "rect") { size = new Vector2(xdObject.Shape.Width, xdObject.Shape.Height); } else if (SvgUtil.Types.Contains(shapeType)) { var svg = SvgUtil.CreateSvg(xdObject, null); var bounds = SvgUtil.CalcBounds(svg); if (bounds.width > 0.0001f && bounds.height > 0.0001f) { size = new Vector2(bounds.width, bounds.height); position = new Vector2(bounds.x, bounds.y); } } if (scaleBehavior == "cover" && size.x > 0.0001f && size.y > 0.0001f) { var imageWidth = xdObject.Style?.Fill?.Pattern?.Width ?? 0f; var imageHeight = xdObject.Style?.Fill?.Pattern?.Height ?? 0f; var imageSize = new Vector2(imageWidth, imageHeight); var imageAspect = imageSize.x / imageSize.y; var instanceAspect = size.x / size.y; var offsetX = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.OffsetX ?? 0f; var offsetY = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.OffsetY ?? 0f; var scale = xdObject.Style?.Fill?.Pattern?.Meta?.Ux?.Scale ?? 1.0f; if (imageAspect > instanceAspect) { var prev = size.x; size.x = size.y * (imageSize.x / imageSize.y); position.x -= (size.x - prev) / 2f; position.x += offsetX * xdObject.Shape.Width * imageAspect / instanceAspect; position.y += offsetY * xdObject.Shape.Height; } else { var prev = size.y; size.y = size.x * (imageSize.y / imageSize.x); position.y -= (size.y - prev) / 2f; position.x += offsetX * xdObject.Shape.Width; position.y += offsetY * xdObject.Shape.Height * imageAspect / instanceAspect; } { var prev = size; size *= scale; position -= (size - prev) / 2f; } } return(new Rect(position, size)); }
/// <summary> /// Scale and translate structure and format into buffer /// </summary> /// <param name="mol">The structure</param> /// <param name="cellStyle">Style/conditional formatting to apply to cell</param> /// <param name="commandChar">Command character to use in buffer</param> /// <param name="x">Coordinate of left side of structure</param> /// <param name="width">Width of molecule box in milliinches</param> /// <param name="r">Row in buffer to put on. If less than 0 then return formatted data</param> /// <param name="heightInLines">number of lines used</param> public FormattedFieldInfo FormatStructure( MoleculeMx mol, CellStyleMx cellStyle, char commandChar, int x, int width, int r, ResultsField rfld = null, DataRowMx dataRow = null) { Rectangle destRect, boundingRect; int height; // formatted height in milliinches bool markBoundaries; int fixedHeight; Bitmap bm; Font font; string txt, molfile, molString = "", svg, cid = null; int translateType, desiredBondLength = 100; int pixWidth = 0, pixHeight = 0; bool debug = DataTableManager.DebugDetails; if (debug) { DebugLog.Message("=============================== FormattingStructure ==============================="); } PerformanceTimer pt = PT.Start("FormatStructure"); Stopwatch swTotal = Stopwatch.StartNew(); Stopwatch sw = Stopwatch.StartNew(); try { MoleculeFormat initialCsType = mol.PrimaryFormat; string initialCsValue = mol.PrimaryValue; QueryColumn qc = (rfld != null) ? rfld.QueryColumn : null; FormattedFieldInfo ffi = new FormattedFieldInfo(); if (dataRow != null) // get any cid in row { int ki = DataTableManager.DefaultKeyValueVoPos; if (ki < dataRow.Length) { cid = dataRow[ki] as string; } } //DebugLog.Message("FormatStructure " + cid); //if (!Rf.Grid) x = x; // debug /////////////////////////////////// // Highlight structure /////////////////////////////////// if (StructureHighlightPssc != null) { ParsedStructureCriteria pssc = StructureHighlightPssc; // Hilight substructure search match if (pssc.SearchType == StructureSearchType.Substructure || // regular SSS pssc.SearchTypeUnion == StructureSearchType.Substructure) // handles related search for just SSS to get hilighting { if (HighlightStructureMatches) { try { mol = StrMatcher.HighlightMatchingSubstructure(mol); if (DebugMx.False) // debug { //string highlightChildren = mol.MolLib.HighlightChildren; //Color highlightColor = mol.MolLib.HighlightColor; if (debug) { DebugLog.StopwatchMessage("tHilight", sw); } } } catch (Exception ex) { ex = ex; } } if (AlignStructureToQuery) { try { mol = StrMatcher.AlignToMatchingSubstructure(mol); if (debug) { DebugLog.StopwatchMessage("tOrient", sw); } } catch (Exception ex) { ex = ex; } } } // Hilight SmallWorld structure match else if (pssc.SearchType == StructureSearchType.SmallWorld) // Hilight SmallWorld structure search results { if (SmallWorldDepictions == null) { SmallWorldDepictions = new SmallWorldDepictions(); } SmallWorldPredefinedParameters swp = pssc.SmallWorldParameters; //DebugLog.Message("Depict " + cid + ", Hilight " + swp.Highlight + ", Align " + swp.Align); // + "\r\n" + new StackTrace(true)); if ((swp.Highlight || swp.Align) & Lex.IsDefined(cid)) // call depiction for these { svg = SmallWorldDepictions.GetDepiction(cid, swp.Highlight, swp.Align); if (Lex.IsDefined(svg)) // have depiction? { { pixWidth = MoleculeMx.MilliinchesToPixels(width); bm = SvgUtil.GetBitmapFromSvgXml(svg, pixWidth); ffi.FormattedBitmap = mol.FormattedBitmap = bm; // store in formatting info and chem structure return(ffi); } } else if (svg == null) // start retrieval of this decpiction type & fall through to get default structure initially { SmallWorldDepictions.StartDepictionRetrieval(Qm, StructureHighlightQc, swp.Highlight, swp.Align); } else { } // tried to get it but failed, fall through to get basic structure } } else if (mol.AltFormDefined("Svg")) // svg form exist (e.g. SmallWorld or "related" structure search)? { svg = mol.SvgString; if (Lex.IsDefined(svg)) { pixWidth = MoleculeMx.MilliinchesToPixels(width); bm = SvgUtil.GetBitmapFromSvgXml(svg, pixWidth); ffi.FormattedBitmap = mol.FormattedBitmap = bm; // store in formatting info and chem structure return(ffi); } } } /////////////////////////////////// // Handle each output device /////////////////////////////////// ffi.HeightInLines = 1; // min of 1 line if (Rf.SdFile) { FormatSdfileStructure(mol); return(null); } int pageHeight = 11000; if (Rf.PageMargins != null) { pageHeight = Rf.PageMargins.Top + Rf.PageHeight + Rf.PageMargins.Bottom; } if (Rf.Excel || Rf.Word) { translateType = 2; } else { translateType = 0; } if (!Rf.FixedHeightStructures) { fixedHeight = 0; // not fixed height } else if (Rf.Excel || Rf.Word) { fixedHeight = 1; // always fixed height } else { fixedHeight = 2; // fixed height unless need to expand } if (Rf.Word && Rf.FixedHeightStructures) { markBoundaries = true; } else { markBoundaries = false; } destRect = new Rectangle(0, 0, width, width * 4 / 5); // default dest rect /////////////////////////////////////////////////////////////////////////// // Tempory fake generation of HELM & associatedimage for biopolymer testing /////////////////////////////////////////////////////////////////////////// //if (MoleculeMx.HelmEnabled == DebugMx.False) // artificially generate helm molecules // MoleculeMx.SetMoleculeToTestHelmString(mol.GetCorpId().ToString(), mol); /////////////////////////////////////////////////////////////////////////// // End of tempory fake generation of HELM & associatedimage for biopolymer testing /////////////////////////////////////////////////////////////////////////// bool fitStructure = true; if (mol.IsChemStructureFormat) { if (Rf.Grid) // special scale for grid { double scale = (float)width / MoleculeMx.StandardBoxWidth; desiredBondLength = mol.CdkMol.AdjustBondLengthToValidRange((int)(MoleculeMx.StandardBondLength * scale)); //desiredBondLength = (int)(ChemicalStructure.StandardBondLength * (Rf.PageScale / 100.0)); desiredBondLength = (int)(desiredBondLength * 90.0 / 100.0); // scale down a bit for grid if (debug) { DebugLog.StopwatchMessage("tAdjustBondLength1", sw); } } else // set desired bond length based on page scaling { float scale = (float)width / MoleculeMx.StandardBoxWidth; desiredBondLength = mol.CdkMol.AdjustBondLengthToValidRange((int)(MoleculeMx.StandardBondLength * scale)); //desiredBondLength = (int)(ChemicalStructure.StandardBondLength * (Rf.PageScale / 100.0)); if (debug) { DebugLog.StopwatchMessage("tAdjustBondLength2", sw); } } if (desiredBondLength < 1) { desiredBondLength = 1; } if (debug) { DebugLog.StopwatchMessage("tBeforeFit", sw); } if (fitStructure) { mol.CdkMol.FitStructureIntoRectangle // scale and translate structure into supplied rectangle. (ref destRect, desiredBondLength, translateType, fixedHeight, markBoundaries, pageHeight, out boundingRect); } if (debug) { DebugLog.StopwatchMessage("tFitStructure", sw); } ffi.HeightInLines = (int)(destRect.Height / Rf.LineHeight + 1); // lines needed } else if (mol.IsBiopolymerFormat) { if (mol.PrimaryFormat == MoleculeFormat.Helm && Rf.Excel) { svg = HelmControl.GetSvg(mol.HelmString); float inchWidth = width / 1000.0f; // convert width milliinches to inches Svg.SvgDocument svgDoc = SvgUtil.AdjustSvgDocumentToFitContent(svg, inchWidth, Svg.SvgUnitType.Inch); RectangleF svgbb = svgDoc.Bounds; float ar = svgbb.Width / svgbb.Height; // aspect ratio of svg bounding box height = (int)(width / ar); // height in milliinches ffi.HeightInLines = (int)(height / Rf.LineHeight) + 1; // lines needed destRect = new Rectangle(0, 0, width, height); } } ////////////////////////// /// Output to Grid ////////////////////////// if (Rf.Grid) { pixWidth = MoleculeMx.MilliinchesToPixels(destRect.Width); pixHeight = MoleculeMx.MilliinchesToPixels(destRect.Height); if (cellStyle == null) { if (Qm == null || Qm.MoleculeGrid == null) { font = new Font("Tahoma", 8.25f); } else { font = new Font(Qm.MoleculeGrid.Font, FontStyle.Underline); } cellStyle = new CellStyleMx(font, Color.Blue, Color.Empty); } if (mol.IsChemStructureFormat) // molfile type molecule { if (debug) { DebugLog.StopwatchMessage("tBeforeGetDisplayPreferences", sw); } DisplayPreferences dp = mol.GetDisplayPreferences(); if (debug) { DebugLog.StopwatchMessage("tGetDisplayPreferences", sw); } //desiredBondLength = mol.CdkMol.AdjustBondLengthToValidRange(desiredBondLength); // be sure bond len within allowed range //if (debug) DebugLog.StopwatchMessage("tAdjustBondLengthToValidRange", sw); //dp.StandardBondLength = MoleculeMx.MilliinchesToDecipoints(desiredBondLength); bm = mol.CdkMol.GetFixedHeightMoleculeBitmap(pixWidth, pixHeight, dp, cellStyle, mol.Caption); if (debug) { DebugLog.StopwatchMessage("tGetBitmap", sw); } } else if (mol.IsBiopolymerFormat) // Output HELM image for biopolymer { pixWidth = MoleculeMx.MilliinchesToPixels(width); bm = HelmConverter.HelmToBitmap(mol, pixWidth); } else { bm = new Bitmap(1, 1); } ffi.FormattedBitmap = mol.FormattedBitmap = bm; // store in formatting & structure ffi.FormattedText = "Formatted"; // indicate formatted (could save structure string but not needed and avoids possible conversion overhead) return(ffi); } ////////////////////////// /// Output to Html ////////////////////////// else if (Rf.Html) { if (r >= 0) { AssureTbFree(0, r + ffi.HeightInLines - 1); } if (mol.IsChemStructureFormat) { FormatChemStructureHtml(mol, destRect, width, r); } else if (mol.IsBiopolymerFormat) { FormatBiopolymerStructureHtml(mol, destRect, width, r); } if (debug) { DebugLog.StopwatchMessage("tFormatHtmlStructure", sw); } ffi.FormattedBitmap = mol.FormattedBitmap; ffi.FormattedText = mol.FormattedText; return(ffi); } ///////////////////////////////////////////////////////////////// /// Other format, store Smiles or Helm & any cellStyle in buffer ///////////////////////////////////////////////////////////////// else { if (mol.IsChemStructureFormat) { if (Rf.ExportStructureFormat == ExportStructureFormat.Smiles) { molString = mol.GetSmilesString(); } else { molString = mol.GetChimeString(); // use Chime if not smiles } } else if (mol.IsBiopolymerFormat) { molString = mol.PrimaryValue; // usually Helm but could be sequence } txt = String.Format("{0} {1} {2} {3} {4} {5} {6}", x, width, destRect.Left, destRect.Top, destRect.Right, destRect.Bottom, molString); if (cellStyle != null) // apply style to cell? { txt += " <CellStyle " + cellStyle.Serialize() + ">"; } txt = commandChar + " " + txt + "\t"; if (r >= 0) { AssureTbFree(0, r + ffi.HeightInLines - 1); Tb.Lines[r] += txt; // put in buffer } else { return(new FormattedFieldInfo(txt)); // just return formatting } } return(null); } catch (Exception ex) { DebugLog.Message(DebugLog.FormatExceptionMessage(ex)); return(null); } finally { pt.Update(); int formatCount = pt.Count; //ClientLog.Message(pt.ToString() + ", " + cs.GetMolHeader()[2]); // + ", " + new StackTrace(true)); if (debug) { DebugLog.StopwatchMessage("tTotalTime", swTotal); } } }
/// <summary> /// Retrieve any existing SVG for the list of supplied molecules /// The Id column should contain the CorpId /// </summary> /// <param name="molList"></param> public static int SelectMoleculeListSvg( List <MoleculeMx> molList) { MoleculeMx mol; int corpId, molSvgsFetchedCount = 0; string corpIdString, molString, svg; const string sql = @" SELECT corp_nbr, molstructure svgString FROM mbs_owner.corp_moltable_mx WHERE corp_nbr in (<list>) and molstructure is not null " ; if (!Security.UserInfo.Privileges.CanRetrieveStructures) // structures allowed? { return(0); } //if (DebugMx.True) return 0; // debug, don't use existing values List <string> lsnList = new List <string>(); Dictionary <string, MoleculeMx> molDict = new Dictionary <string, MoleculeMx>(); foreach (MoleculeMx mol0 in molList) // set up a dict keyed by cid with mol values { if (mol0.PrimaryFormat != MoleculeFormat.Helm || Lex.IsUndefined(mol0.PrimaryValue)) { continue; } if (int.TryParse(mol0.Id, out corpId)) { molDict[mol0.Id] = mol0; } } if (molDict.Count == 0) { return(0); } DbCommandMx cmd = new DbCommandMx(); cmd.PrepareListReader(sql, DbType.String); cmd.ExecuteListReader(new List <string>(molDict.Keys)); while (cmd.Read()) { corpId = cmd.GetInt(0); if (!cmd.IsNull(1)) // molstructure { molString = cmd.GetClob(1); if (!SvgUtil.IsSvgString(molString)) { continue; // skip if not SVG } svg = molString; // should be compressed format SVG corpIdString = CompoundId.Normalize(corpId.ToString()); if (Lex.IsDefined(svg) && molDict.ContainsKey(corpIdString)) { mol = molDict[corpIdString]; mol.SvgString = svg; molSvgsFetchedCount++; } } } cmd.CloseReader(); return(molSvgsFetchedCount); }
/// <summary> /// Sync the Mobius CorpMoltable replicate used to retrieve Smiles /// Syntax: UpdateCorpDbMoltableMx [ ByDateRange | ByCorpIdRange | LoadMissing | <singleCorpId>] /// </summary> /// <returns></returns> public static string UpdateCorpDbMoltableMx( string args) { DateTime moleculeDateTime = DateTime.MinValue; double mw; string msg = "", sql = "", maxCorpIdSql, mf = "", chime = "", smiles = "", checkPointDate = "", helm = "", sequence = "", svg = ""; object[][] pva = null; int pvaCount = 0, CorpId, lowCorpId = 0, highCorpId = 0, srcMaxCorpId = 0; int SelectChunkSize = 20; // small chunks int InsertBufferSize = 10; //int SelectChunkSize = 100000; // big chunks //int InsertBufferSize = 1000; // Select data from corp_moltable by CorpId range const string SelectByCorpIdRange = @" SELECT m.corp_nbr, chime(m.ctab), m.molformula, m.molweight, null molsmiles, s.helm_txt, s.sequence_txt, m.molecule_date FROM corp_owner.corp_moltable m, corp_owner.corp_substance s where m.corp_nbr > 0 and s.corp_nbr = m.corp_nbr and (s.status_code is null or s.status_code = 'A') ORDER BY corp_nbr"; // Select data from corp_moltable by date range comparing to corp_moltable_mx const string SelectByDateRange = @" select m.corp_nbr, chime(m.ctab), m.molformula, m.molweight, null molsmiles, s.helm_txt, s.sequence_txt, m.molecule_date, m2.molecule_date from corp_owner.corp_moltable m, corp_owner.corp_substance s, corp_moltable_mx m2 where m.molecule_date > to_date('1-jan-1900 000000','DD-MON-YYYY HH24MISS') and s.corp_nbr = M.CORP_NBR and (s.status_code is null or s.status_code = 'A') and m2.corp_nbr (+) = m.corp_nbr and m2.molecule_date (+) != m.molecule_date order by m.molecule_date" ; // Select for missing smiles strings, ex: Update CorpDbMoltableMx LoadMissing mx.molecule_date > '1-jan-2014' const string SelectMissingSmilesFix = @" select /* check for CorpIds in corp_moltable not in corp_moltable_mx */ corp_nbr, chime(ctab), molformula, molweight, null molsmiles, helm_txt, sequence_txt, molecule_date from ( select m.*, s.helm_txt, s.sequence_txt, mx.molsmiles molsmiles_mx from corp_owner.corp_moltable m, corp_owner.corp_substance s, corp_moltable_mx mx where s.corp_nbr = M.CORP_NBR and (s.status_code is null or s.status_code = 'A') and mx.corp_nbr (+) = m.corp_nbr and 1=1 /* condition to substitute */ ) m where molsmiles_mx is null /* extra condition */ order by corp_nbr" ; // Insert missing helm info const string SelectMissingHelmFix = @" select /* check for CorpIds in corp_moltable not in corp_moltable_mx */ corp_nbr, chime(ctab), molformula, molweight, null molsmiles, helm_txt, sequence_txt, molecule_date from ( select m.*, s.helm_txt, s.sequence_txt, mx.molsmiles molsmiles_mx from corp_owner.corp_moltable m, corp_owner.corp_substance s, corp_moltable_mx mx where s.corp_nbr = M.CORP_NBR and (s.status_code is null or s.status_code = 'A') and mx.corp_nbr (+) = m.corp_nbr and 1=1 /* condition to substitute */ ) m where length(helm_txt) > 0 /* extra condition */ order by corp_nbr" ; // Secondary "large" structure table (~5k mols) const string SelectLargeMols = @" select corp_nbr, to_clob(molstructure), to_clob(molformula), molweight, molsmiles, null helm_txt, null sequence_txt, molecule_date from (select corp_srl_nbr corp_nbr, 'CompoundId=' || corp_srl_nbr molstructure, null ctab, mlclr_frml_txt molformula, mlclr_wgt molweight, null molsmiles, null molecule_date from rdm_owner.rdm_sbstnc where rdw_src_cd = 'LRG'" ; // Insert statement const string InsertSql = @" insert into mbs_owner.corp_moltable_mx ( corp_nbr, molstructure, molformula, molweight, molsmiles, molecule_date) values (:0, :1, :2, :3, :4, :5)" ; // Build select sql bool byDateRange = false, byCorpIdRange = false, missingFix = true, deleteExisting = true; string missingFixCriteria = ""; if (Lex.IsUndefined(args) || Lex.Eq(args, "ByDateRange")) { byDateRange = true; } else if (Lex.Eq(args, "ByCorpIdRange")) { byCorpIdRange = true; Progress.Show("Getting range of CorpIds to insert..."); maxCorpIdSql = "select max(corp_nbr) from corp_owner.corp_moltable"; // get highest CorpId in source db srcMaxCorpId = SelectSingleValueDao.SelectInt(maxCorpIdSql); if (srcMaxCorpId < 0) { srcMaxCorpId = 0; } maxCorpIdSql = "select max(corp_nbr) from mbs_owner.corp_moltable_mx"; // get highest CorpId in dest db highCorpId = SelectSingleValueDao.SelectInt(maxCorpIdSql); if (highCorpId < 0) { highCorpId = 0; } } else if (Lex.StartsWith(args, "LoadMissing")) { missingFix = true; if (args.Contains(" ")) { missingFixCriteria = args.Substring(10).Trim(); } } else if (int.TryParse(args, out srcMaxCorpId)) // single CorpId { byCorpIdRange = true; highCorpId = srcMaxCorpId - 1; // say 1 less is the max we have } else { return("Syntax: UpdateCorpDbMoltableMx [ ByDateRange | ByCorpIdRange | LoadMissing | <singleCorpId>]"); } Log("UpdateCorpDbMoltableMx started: " + args); int readCount = 0, insCount = 0, insertCount = 0, updateCount = 0, undefinedStructures = 0, smilesSuccess = 0, smilesFails = 0, helmStructures = 0; List <string> CorpIdList = new List <string>(); for (int chunk = 1; ; chunk++) // loop over chunks { if (byDateRange) // single chunk { if (chunk > 1) { break; // break 2nd time through } checkPointDate = UserObjectDao.GetUserParameter("MOBIUS", "UpdateCorpDbMoltableMxCheckpointDate", "01-sep-2013 000000"); //UserObjectDao.SetUserParameter("MOBIUS", "UpdateCorpDbMoltableMxCheckpointDate", checkPointDate); sql = Lex.Replace(SelectByDateRange, "1-jan-1900 000000", checkPointDate); msg = "Reading where date >= " + checkPointDate; } else if (byCorpIdRange) // by CorpId range { if (highCorpId >= srcMaxCorpId) { break; // done } lowCorpId = highCorpId + 1; // start of next chunk highCorpId = lowCorpId + SelectChunkSize; if (highCorpId >= srcMaxCorpId) { highCorpId = srcMaxCorpId; } sql = Lex.Replace(SelectByCorpIdRange, "corp_nbr > 0", "corp_nbr between " + lowCorpId + " and " + highCorpId); msg = "Reading: " + lowCorpId + " to " + highCorpId + ", Reads: " + readCount + ", Inserts: " + insertCount; } else if (missingFix) { if (chunk > 1) { break; // break 2nd time through } sql = SelectMissingHelmFix; if (Lex.IsDefined(missingFixCriteria)) // substitute any criteria { sql = Lex.Replace(sql, "1=1", missingFixCriteria); } msg = "Fixing missing data"; } Progress.Show(msg); DbCommandMx readCmd = new DbCommandMx(); readCmd.MxConn = DbConnectionMx.GetConnection("prd123"); readCmd.PrepareUsingDefinedConnection(sql, null); DbDataReader rdr = readCmd.ExecuteReader(); DbCommandMx insertCmd = new DbCommandMx(); OracleDbType[] pta = new OracleDbType[6]; pta[0] = OracleDbType.Int32; // corp_nbr pta[1] = OracleDbType.Clob; // molstructure pta[2] = OracleDbType.Clob; // molformula pta[3] = OracleDbType.Double; // molweight pta[4] = OracleDbType.Clob; // smiles pta[5] = OracleDbType.Date; // molecule_date insertCmd.Prepare(InsertSql, pta); insertCmd.BeginTransaction(); // be sure we have a transaction going pva = DbCommandMx.NewObjectArrayArray(6, InsertBufferSize); // alloc insert row array object[] vo = new object[6]; while (true) { bool readOk = rdr.Read(); if (readOk) { rdr.GetValues(vo); CorpId = readCmd.GetInt(0); // corp_nbr vo[0] = CorpId; CorpIdList.Add(CorpId.ToString()); if (!readCmd.IsNull(1)) // molstructure { chime = readCmd.GetClob(1); chime = OracleMx.ClearStringIfExceedsMaxStringSize(chime); vo[1] = chime; } else { chime = ""; } if (!readCmd.IsNull(2)) // molformula { mf = readCmd.GetClob(2); mf = OracleMx.ClearStringIfExceedsMaxStringSize(mf); vo[2] = mf; } if (!readCmd.IsNull(3)) // molweight { mw = readCmd.GetDouble(3); vo[3] = mw; } if (Lex.IsDefined(chime)) // molsmiles - calculate from chime string { MoleculeMx cs = new MoleculeMx(MoleculeFormat.Chime, chime); if (cs.AtomCount > 1) // need more than one atom { MoleculeMx cs2 = cs.ConvertTo(MoleculeFormat.Smiles); smiles = cs2.GetSmilesString(); if (Lex.IsDefined(smiles)) { smilesSuccess++; } else { Log("Smiles conversion failure for CorpId: " + CorpId); smilesFails++; } smiles = OracleMx.ClearStringIfExceedsMaxStringSize(smiles); vo[4] = smiles; } else { undefinedStructures++; } } else { undefinedStructures++; } if (!readCmd.IsNull(5)) { helm = readCmd.GetClob(5); if (Lex.IsDefined(helm)) { svg = HelmControl.GetSvg(helm); vo[1] = SvgUtil.CompressSvgString(svg); // store compressed svg in molstructure column for now helmStructures++; } } if (!readCmd.IsNull(6)) { sequence = readCmd.GetClob(6); if (Lex.IsDefined(sequence)) { // nothing yet } } moleculeDateTime = DateTime.MinValue; if (!readCmd.IsNull(7)) // molecule_date { moleculeDateTime = readCmd.GetDateTime(7); vo[5] = moleculeDateTime; } for (int pi = 0; pi < 6; pi++) // invert for insert { pva[pi][pvaCount] = vo[pi]; } if (Debug) { msg = String.Format("CorpId: {0}, mf: {1}, chime: {2}, smiles: {3}", CorpId.ToString(), mf.Length, chime.Length, smiles.Length); Log(msg); } pvaCount++; } if (pvaCount >= InsertBufferSize || (!readOk && pvaCount > 0)) // write if buffer full or at end { try { if (deleteExisting) { int delCount = DoDeletes(CorpIdList); updateCount += delCount; // count deletes as updates insertCount -= delCount; // subtract from inserts } CorpIdList.Clear(); insCount = insertCmd.ExecuteArrayNonReader(pva, ref pvaCount); insertCmd.Commit(); insertCmd.BeginTransaction(); insertCount += insCount; } catch (Exception ex) { throw new Exception(ex.Message, ex); } if (byDateRange) { string checkPointDate2 = String.Format("{0:dd-MMM-yyyy HHmmss}", moleculeDateTime); // format date time that will work with oracle UserObjectDao.SetUserParameter("MOBIUS", "UpdateCorpDbMoltableMxCheckpointDate", checkPointDate2); msg = "Processing where date >= " + checkPointDate + ", Reads: " + readCount + ", Inserts: " + insertCount + ", Updates: " + updateCount; } else if (byCorpIdRange) // CorpId range { msg = "Processing: " + lowCorpId + " to " + highCorpId + ", Reads: " + readCount + ", Inserts: " + insertCount; } else if (missingFix) { msg = "Fixing missing smiles, Updates: " + updateCount; } msg += String.Format(", Undefined structures: {0} , Smiles failures: {1}, Helms: {2}", undefinedStructures, smilesFails, helmStructures); Progress.Show(msg); } if (!readOk) { break; } readCount++; } readCmd.Dispose(); insertCmd.Dispose(); } // end for select chunk msg = "UpdateCorpDbMoltableMx - Inserts: " + insertCount + ", Updates: " + updateCount; msg += String.Format(", Undefined structures: {0} , Smiles failures: {1}, Helms: {2}", undefinedStructures, smilesFails, helmStructures); Log(msg); return(msg); }
/// <summary> /// RenderMolecule /// </summary> public void RenderMolecule() { Rectangle destRect = this.Bounds, boundingRect; string svg; Svg.SvgDocument svgDoc; Bitmap bm; int height; // formatted height in milliinches bool markBoundaries = false; int fixedHeight = 0, translateType = 0, desiredBondLength = 100, pageHeight = 11000; int miWidth; if (MolFormat == MoleculeFormat.Unknown || Lex.IsUndefined(MolString)) { ImageCtl.SvgImage = null; ImageCtl.Image = null; return; } svg = CdkMol.GetMoleculeSvg(this.Width, this.Height); // get svg if (DebugMx.False) // Create bitmap from CdkMol { bm = CdkMol.GetMoleculeBitmap(this.Width, this.Height); ImageCtl.Image = bm; return; } if (DebugMx.False) // Create svg, then get bitmap { bm = SvgUtil.GetBitmapFromSvgXml(svg, this.Width); ImageCtl.Image = bm; return; } if (DebugMx.False) // Fit structure, then get bitmap { int stdBoxWidthPx = Mobius.Data.MoleculeMx.MilliinchesToPixels(Mobius.Data.MoleculeMx.StandardBoxWidth); double scale = (float)this.Width / stdBoxWidthPx; desiredBondLength = CdkMol.AdjustBondLengthToValidRange((int)(Mobius.Data.MoleculeMx.StandardBondLength * scale)); // (not implemented) if (desiredBondLength < 1) { desiredBondLength = 1; } CdkMol.FitStructureIntoRectangle // scale and translate structure into supplied rectangle. (ref destRect, desiredBondLength, translateType, fixedHeight, markBoundaries, pageHeight, out boundingRect); bm = CdkMol.GetMoleculeBitmap(this.Width, this.Height); ImageCtl.Image = bm; return; } if (DebugMx.True) // Create control SvgImage directly from SVG { MemoryStream ms = StreamConverter.StringToMemoryStream(svg); // convert SVG to image for control SvgImage svgImg = new SvgImage(ms); ImageCtl.SvgImage = svgImg; return; } if (DebugMx.True) { //miWidth = MoleculeMx.PixelsToMilliinches(this.Width); //float inchWidth = miWidth / 1000.0f; // convert width milliinches to inches //svgDoc = SvgUtil.AdjustSvgDocumentToFitContent(svg, inchWidth, Svg.SvgUnitType.Inch); string newSvg = SvgUtil.AdjustSvgToFitContent(svg, this.Width, Svg.SvgUnitType.Pixel, out svgDoc); ImageCtl.Image = svgDoc.Draw(ImageCtl.Width, ImageCtl.Height); //bm = SvgUtil.GetBitmapFromSvgXml(newSvg, this.Width); //ImageCtl.Image = bm; return; } }