private void startInteractions() { List <int> moleculeIDs = molecules.GetIDs(); if (moleculeIDs.Count != 2) { if (moleculeIDs.Count > 2) { console.ShowError("Can't monitor molecule interactions. Only two molecules can to be loaded"); } else { console.ShowError("Can't monitor molecule interactions. At least two molecules need to be loaded"); } return; } MoleculeRenderSettings molecule1Settings = molecules.Get(moleculeIDs[0]).RenderSettings; MoleculeRenderSettings molecule2Settings = molecules.Get(moleculeIDs[1]).RenderSettings; if (molecules.Get(moleculeIDs[0]).HasTrajectory || molecules.Get(moleculeIDs[1]).HasTrajectory) { MoleculeEvents.RaiseInteractionsMessage("Can't monitor interactions. Monitored molecules cannot have trajectories loaded.", true); return; } MonitoringEnabled = true; StartStopButtonText.text = "Stop Monitoring Interactions"; UserInterfaceEvents.RaiseStartMonitoringMoleculeInteractions(moleculeIDs[0], moleculeIDs[1], interactionSettings, molecule1Settings, molecule2Settings); ResetPositionsButton.interactable = true; }
private float getAtomRadius(Atom atom, MoleculeRenderSettings settings, MolecularRepresentation?customRepresentation) { MolecularRepresentation atomRepresentation; if (customRepresentation != null && customRepresentation != MolecularRepresentation.None) { atomRepresentation = (MolecularRepresentation)customRepresentation; } else { atomRepresentation = settings.Representation; } float atomRadius; if (atomRepresentation == MolecularRepresentation.VDW) { atomRadius = atom.VDWRadius; } else // default to CPK { atomRadius = atom.AtomicRadius / 2f; } return(atomRadius * settings.AtomScale); }
private IEnumerator createSecondaryStructure(MoleculeRenderSettings settings, PrimaryStructureFrame frame, SecondaryStructure secondaryStructure) { for (int i = 0; i < primaryStructure.Chains().Count; i++) { Chain chain = primaryStructure.Chains()[i]; if (chain.ResidueType != StandardResidue.AminoAcid) { // UnityEngine.Debug.Log("Skipping secondary strucure. Non protein structures not currently supported."); continue; } if (chain.MainChainResidues.Count < 2) { // UnityEngine.Debug.Log("Skipping secondary strucure. Protein structure doesn't have enough residues for mesh."); continue; } Mesh structureMesh = BuildStructureMesh(settings, chain, frame, secondaryStructure); GameObject structure = (GameObject)Instantiate(SecondaryStructurePrefab); structure.GetComponent <MeshFilter>().sharedMesh = structureMesh; structure.SetActive(false); structure.transform.SetParent(StructureParent.transform, false); yield return(null); } }
public void Initialise(string residueName, MoleculeRenderSettings settings, PrimaryStructure primaryStructure, SaveCustomResidueSettingsDelegate saveCustomResidueSettings, ResidueRenderSettingsUpdated settingsUpdatedCallback, ClosedResidueSettingsPanel onClose) { this.residueName = residueName; this.moleculeRenderSettings = settings; this.primaryStructure = primaryStructure; this.saveCustomResidueSettings = saveCustomResidueSettings; this.settingsUpdatedCallback = settingsUpdatedCallback; this.onClose = onClose; ResidueNameInformationText.text = "Showing residue IDs for " + residueName; residueIDs = primaryStructure.GetResidueIDs(new List <String>() { residueName }).ToList(); residueIDs.Sort(); renderResidueIDButtons(); allResiduesEnabled = true; foreach (int residueID in residueIDs) { if (!moleculeRenderSettings.EnabledResidueIDs.Contains(residueID)) { allResiduesEnabled = false; break; } } updateToggleResidueButtonText(); residueIDsPanel.SetActive(true); }
public void Initialise(MoleculeRenderSettings moleculeRenderSettings, ResidueRenderSettingsUpdated settingsUpdatedCallback, UpdatedResidueIDsDelegate residueIDsUpdated, OpenUpdateAllResiduesPanel openUpdateAllPanel, ClosedResidueSettingsPanel onClose) { this.moleculeRenderSettings = moleculeRenderSettings; this.settingsUpdatedCallback = settingsUpdatedCallback; this.residueIDsUpdated = residueIDsUpdated; this.openUpdateAllPanel = openUpdateAllPanel; this.onClose = onClose; updateToggleResidueButtonText(); residueUpdateRangePanel.SetActive(true); }
private void loadRenderSettings(int moleculeID, MoleculeRenderSettings settings) { MoleculeSettings molecule = molecules.Get(moleculeID); if (molecule == null) { return; } molecule.RenderSettings = (MoleculeRenderSettings)settings; UserInterfaceEvents.RaiseMoleculeRenderSettingsUpdated(molecule.ID, molecule.RenderSettings, molecule.CurrentTrajectoryFrameNumber); }
private void showResidueNamesPanel(MoleculeRenderSettings renderSettings, PrimaryStructure primaryStructure) { residueNamesPanel.Initialise(renderSettings, primaryStructure, updateMoleculeRender); if (primaryStructure.ResidueNames == null || primaryStructure.ResidueNames.Count == 0 || primaryStructure.ResidueIDs == null || primaryStructure.ResidueIDs.Count == 0) { residueNamesPanelGO.gameObject.SetActive(false); } else { residueNamesPanelGO.gameObject.SetActive(true); } }
public void SetMolecule2RenderSettings(MoleculeRenderSettings molecule2Settings) { UnityEngine.Debug.Log("Molecule2Interaction Settings " + molecule2Settings); if (!molecule2Settings.ShowPrimaryStructure) { this.molecule2RenderedAtoms = new List <Atom>(); UnityEngine.Debug.Log("Interactions calc. Molecule2 Atom empty list"); } else { this.molecule2RenderedAtoms = Molecule2.PrimaryStructure.GetAtoms(molecule2Settings.ShowStandardResidues, molecule2Settings.ShowNonStandardResidues, molecule2Settings.EnabledElements, molecule2Settings.EnabledResidueNames, molecule2Settings.EnabledResidueIDs).Values.ToList(); UnityEngine.Debug.Log(Time.time + " Interactions calc. Molecule2 Atom count: " + this.molecule2RenderedAtoms.Count); } }
public MoleculeSettings(int moleculeID, string filePath) { ID = moleculeID; FilePath = filePath; Loaded = false; Hidden = false; PendingRerender = false; Name = ""; Description = ""; AtomCount = 0; ResidueCount = 0; HasTrajectory = false; TrajectoryFilePath = ""; TrajectoryFrameCount = 0; CurrentTrajectoryFrameNumber = null; RenderSettings = MoleculeRenderSettings.Default(); }
public MoleculeRenderSettings Clone() { MoleculeRenderSettings renderSettings = new MoleculeRenderSettings(); renderSettings.ShowPrimaryStructure = this.ShowPrimaryStructure; renderSettings.ShowBonds = this.ShowBonds; renderSettings.ShowAtoms = this.ShowAtoms; renderSettings.ShowStandardResidues = this.ShowStandardResidues; renderSettings.ShowNonStandardResidues = this.ShowNonStandardResidues; renderSettings.ShowMainChains = this.ShowMainChains; renderSettings.Representation = this.Representation; renderSettings.AtomScale = this.AtomScale; renderSettings.BondScale = this.BondScale; renderSettings.ShowSecondaryStructure = this.ShowSecondaryStructure; renderSettings.ShowHelices = this.ShowHelices; renderSettings.ShowSheets = this.ShowSheets; renderSettings.ShowTurns = this.ShowTurns; renderSettings.SmoothNodes = this.SmoothNodes; renderSettings.ShowSimulationBox = this.ShowSimulationBox; renderSettings.CalculateBoxEveryFrame = this.CalculateBoxEveryFrame; renderSettings.EnabledElements = this.EnabledElements == null ? null : new HashSet <string>(this.EnabledElements); renderSettings.EnabledResidueNames = this.EnabledResidueNames == null ? null : new HashSet <string>(this.EnabledResidueNames); renderSettings.CustomResidueNames = this.CustomResidueNames == null ? null : new HashSet <string>(this.CustomResidueNames); renderSettings.EnabledResidueIDs = this.EnabledResidueIDs == null ? null : new HashSet <int>(this.EnabledResidueIDs); if (this.CustomResidueRenderSettings == null) { renderSettings.CustomResidueRenderSettings = null; } else { renderSettings.CustomResidueRenderSettings = new Dictionary <int, ResidueRenderSettings>(); foreach (KeyValuePair <int, ResidueRenderSettings> item in this.CustomResidueRenderSettings) { renderSettings.CustomResidueRenderSettings.Add(item.Key, item.Value.Clone()); } } return(renderSettings); }
public void Initialise(MoleculeRenderSettings moleculeRenderSettings, PrimaryStructure primaryStructure, ResidueRenderSettingsUpdated settingsUpdatedCallback) { this.moleculeRenderSettings = moleculeRenderSettings; this.primaryStructure = primaryStructure; this.settingsUpdatedCallback = settingsUpdatedCallback; residueNames = primaryStructure.ResidueNames.ToList(); residueNames.Sort(); renderResidueNameButtons(); allResiduesEnabled = false; if (this.moleculeRenderSettings.EnabledResidueNames != null && residueNameButtons.Count == this.moleculeRenderSettings.EnabledResidueNames.Count) { allResiduesEnabled = true; } updateToggleResidueButtonText(); residueNamesPanel.SetActive(true); }
public void UpdateMoleculeRenderSettings(int moleculeID, MoleculeRenderSettings settings, int?frameNumber = null) { if (molecules.ContainsKey(moleculeID)) { molecules[moleculeID].SetRenderSettings(settings); molecules[moleculeID].SetFrameNumber(frameNumber); StartCoroutine(molecules[moleculeID].Render(generalSettings.MeshQuality)); } if (moleculeInterations.Active) { if (moleculeInterations.Molecule1.ID == moleculeID) { moleculeInterations.SetMolecule1RenderSettings(settings); } else if (moleculeInterations.Molecule2.ID == moleculeID) { moleculeInterations.SetMolecule2RenderSettings(settings); } } }
// RenderStructure and ShowStructure are separate to allow the primary and secondary structures to be prerendered and then // both turned on at the same time. Without this, the show of the structures is staggered and shows some level of flickering public IEnumerator RenderStructure(MoleculeRenderSettings settings, PrimaryStructureFrame frame, int meshQuality) { Stopwatch watch = new Stopwatch(); watch.Start(); storeExistingStructure(); // create the new model objects if (settings.ShowPrimaryStructure) { if (settings.ShowAtoms) { yield return(StartCoroutine(createModelAtomsByElement(settings, frame, meshQuality))); } if (settings.Representation != MolecularRepresentation.VDW && settings.ShowBonds) { if (bonds == null) { yield return(StartCoroutine(calculateBonds())); } if (bonds != null && bonds.Count > 0) { yield return(StartCoroutine(createModelBonds(settings, frame, meshQuality))); } } if (settings.ShowMainChains) { yield return(StartCoroutine(createMainChains(frame))); } } watch.Stop(); //if (Settings.DebugMessages) // console.BannerBuildTime = watch.ElapsedMilliseconds.ToString(); }
// RenderStructure and ShowStructure are separate to allow the primary and secondary structures to be prerendered and then // both turned on at the same time. Without this, the show of the structures is staggered and shows some level of flickering public IEnumerator RenderStructure(MoleculeRenderSettings settings, PrimaryStructureFrame frame, SecondaryStructure secondaryStructure) { if (!initialised) { yield break; } System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); yield return(null); storeExistingStructure(); // create mesh if (secondaryStructure != null && settings.ShowSecondaryStructure) { yield return(StartCoroutine(createSecondaryStructure(settings, frame, secondaryStructure))); } watch.Stop(); }
public void Initialise(int id, PrimaryStructure primaryStructure, MoleculeRenderSettings renderSettings) { if (primaryStructure == null) { return; } this.ID = id; this.PrimaryStructure = primaryStructure; this.renderSettings = renderSettings; this.frameNumber = null; try { secondaryStructure = SecondaryStructure.CreateFromPrimaryStructure(primaryStructure, Settings.StrideExecutablePath, Settings.TmpFilePath); } catch (Exception ex) { Debug.Log("Error Parsing Secondary Structure from Structure File: " + ex.Message); buildSecondaryStructureTrajectory = false; } moleculeBox.gameObject.SetActive(renderSettings.ShowSimulationBox); boundingBox = new BoundingBox(primaryStructure, true); moleculeRender.transform.position = new Vector3(-1 * boundingBox.Centre.x, -1 * boundingBox.Centre.y, -1 * boundingBox.Centre.z); this.transform.position = new Vector3(boundingBox.Centre.x, boundingBox.Centre.y, boundingBox.Centre.z); if (renderSettings.ShowSimulationBox) { moleculeBox.Build(boundingBox); } primaryStructureRenderer.Initialise(primaryStructure); secondaryStructureRenderer.Initialise(primaryStructure); moleculeInput.enabled = false; autoRotateEnabled = false; AutoRotateSpeed = 0f; }
public void LoadMolecule(int moleculeID, string filePath, MoleculeRenderSettings settings) { StartCoroutine(LoadMoleculeStructure(moleculeID, filePath, settings)); }
private IEnumerator createModelBonds(MoleculeRenderSettings renderSettings, PrimaryStructureFrame frame, int meshQuality) { // set colour for bonds Color32 bondColour; if (!MolecularConstants.CPKColors.TryGetValue("Bond", out bondColour)) { MolecularConstants.CPKColors.TryGetValue("Other", out bondColour); } List <Matrix4x4> standardTransforms = new List <Matrix4x4>(); Dictionary <Color, List <Matrix4x4> > highlightedTransforms = new Dictionary <Color, List <Matrix4x4> >(); float standardCylinderWidth = 0.015f * renderSettings.BondScale; float enlargedCylinderWidth = 0.040f * renderSettings.BondScale; // get atoms for bonds Dictionary <int, Atom> atoms; Dictionary <int, Atom> highLightedAtoms = new Dictionary <int, Atom>(); atoms = primaryStructure.GetAtoms(renderSettings.ShowStandardResidues, renderSettings.ShowNonStandardResidues, renderSettings.EnabledElements, renderSettings.EnabledResidueNames, renderSettings.EnabledResidueIDs); if (renderSettings.CustomResidueRenderSettings != null) { HashSet <int> customResidueIDs = new HashSet <int>(renderSettings.CustomResidueRenderSettings.Keys.ToList()); highLightedAtoms = primaryStructure.GetAtoms(renderSettings.ShowStandardResidues, renderSettings.ShowNonStandardResidues, renderSettings.EnabledElements, renderSettings.EnabledResidueNames, customResidueIDs); } foreach (KeyValuePair <int, Bond> bond in bonds) { Vector3 atom1pos, atom2pos; Atom atom1 = null; Atom atom2 = null; if (!atoms.TryGetValue(bond.Value.Atom1Index, out atom1) || !atoms.TryGetValue(bond.Value.Atom2Index, out atom2)) { continue; } if (frame == null) { atom1pos = new Vector3(atom1.Position.x, atom1.Position.y, atom1.Position.z); atom2pos = new Vector3(atom2.Position.x, atom2.Position.y, atom2.Position.z); } else { if (bond.Value.Atom1Index >= frame.AtomCount || bond.Value.Atom2Index >= frame.AtomCount) { // no need to send error message as this will have already been done in the atom render yield break; } atom1pos = new Vector3(frame.Coords[bond.Value.Atom1Index * 3], frame.Coords[(bond.Value.Atom1Index * 3) + 1], frame.Coords[(bond.Value.Atom1Index * 3) + 2]); atom2pos = new Vector3(frame.Coords[bond.Value.Atom2Index * 3], frame.Coords[(bond.Value.Atom2Index * 3) + 1], frame.Coords[(bond.Value.Atom2Index * 3) + 2]); } // flip coord system for Unity atom1pos.z *= -1; atom2pos.z *= -1; // bonds aren't recalculated on each frame. In some frames atoms jump from one side of the simulation box to another. When this happens need to disable bond view float bondLength = (atom2pos - atom1pos).magnitude / 2; if (bondLength > BondLengths.MaximumLengthAllElements) { continue; } Vector3 position = ((atom1pos - atom2pos) / 2.0f) + atom2pos; float length = (atom2pos - atom1pos).magnitude; Quaternion rotation = Quaternion.FromToRotation(Vector3.up, atom1pos - atom2pos); if (highLightedAtoms != null && highLightedAtoms.Count > 0 && highLightedAtoms.ContainsKey(atom1.Index) && highLightedAtoms.ContainsKey(atom2.Index)) { int atom1residue = atom1.ResidueID; int atom2residue = atom2.ResidueID; // only colour or highlight bonds between atoms of the same residue if (atom1residue == atom2residue && renderSettings.CustomResidueRenderSettings.ContainsKey(atom1residue) && renderSettings.CustomResidueRenderSettings[atom1residue].ColourBonds) { ResidueRenderSettings options = renderSettings.CustomResidueRenderSettings[atom1residue]; float cylinderWidth = standardCylinderWidth; if (options.LargeBonds) { cylinderWidth = enlargedCylinderWidth; } Vector3 localScale = new Vector3(cylinderWidth, length, cylinderWidth); Matrix4x4 bondTransform = Matrix4x4.TRS(position, rotation, localScale); if (!highlightedTransforms.ContainsKey(options.ResidueColour)) { highlightedTransforms.Add(options.ResidueColour, new List <Matrix4x4>()); } highlightedTransforms[options.ResidueColour].Add(bondTransform); } else { float cylinderWidth = standardCylinderWidth; if (atom1residue == atom2residue && renderSettings.CustomResidueRenderSettings.ContainsKey(atom1residue) && renderSettings.CustomResidueRenderSettings[atom1residue].LargeBonds) { cylinderWidth = enlargedCylinderWidth; } Vector3 localScale = new Vector3(cylinderWidth, length, cylinderWidth); standardTransforms.Add(Matrix4x4.TRS(position, rotation, localScale)); } } else { Vector3 localScale = new Vector3(standardCylinderWidth, length, standardCylinderWidth); standardTransforms.Add(Matrix4x4.TRS(position, rotation, localScale)); } } GameObject prefab = BondPrefabs[meshQuality]; GameObject parent = new GameObject("StandardCombinedMeshParent"); parent.SetActive(false); yield return(StartCoroutine(meshBuilder.CombinedMesh(prefab, standardTransforms.ToArray(), bondColour, parent))); parent.transform.SetParent(BondParent.transform, false); parent = new GameObject("HighligtedCombinedMeshParent"); parent.SetActive(false); foreach (KeyValuePair <Color, List <Matrix4x4> > item in highlightedTransforms) { yield return(StartCoroutine(meshBuilder.CombinedMesh(prefab, item.Value.ToArray(), item.Key, parent))); } parent.transform.SetParent(BondParent.transform, false); }
private IEnumerator createModelAtomsByElement(MoleculeRenderSettings renderSettings, PrimaryStructureFrame frame, int meshQuality) { Quaternion atomOrientation = Quaternion.Euler(45, 45, 45); // generate combined meshes (i.e single GameObject) for atoms with same element/colour Dictionary <Color, List <Matrix4x4> > mergeTransforms = new Dictionary <Color, List <Matrix4x4> >(); Dictionary <int, Atom> atoms = primaryStructure.GetAtoms(renderSettings.ShowStandardResidues, renderSettings.ShowNonStandardResidues, renderSettings.EnabledElements, renderSettings.EnabledResidueNames, renderSettings.EnabledResidueIDs); foreach (KeyValuePair <int, Atom> item in atoms) { Atom atom = item.Value; Vector3 position; // if no frame use the base structure coordinates. if (frame == null) { position = new Vector3(atom.Position.x, atom.Position.y, atom.Position.z); } else { if (atom.Index >= frame.AtomCount) { MoleculeEvents.RaiseShowMessage("Atoms not found in frame record. Aborting frame render.", true); yield break; } position = new Vector3(frame.Coords[atom.Index * 3], frame.Coords[(atom.Index * 3) + 1], frame.Coords[(atom.Index * 3) + 2]); } // flip coord system for Unity position.z *= -1; Color32?customColour = null; MolecularRepresentation?customRepresentation = null; if (renderSettings.CustomResidueRenderSettings != null && renderSettings.CustomResidueRenderSettings.ContainsKey(atom.ResidueID)) { ResidueRenderSettings residueSettings = renderSettings.CustomResidueRenderSettings[atom.ResidueID]; if (residueSettings != null) { // use the atom specific settings if available. if (residueSettings.AtomSettings.ContainsKey(atom.Name)) { AtomRenderSettings atomSettings = residueSettings.AtomSettings[atom.Name]; if (atomSettings.CustomColour) { customColour = atomSettings.AtomColour; } if (atomSettings.Representation != MolecularRepresentation.None) { customRepresentation = atomSettings.Representation; } } // if we didn't get from atom specific settings then get from residue settings if (customColour == null && residueSettings.ColourAtoms) { customColour = residueSettings.ResidueColour; } if (customRepresentation == null) { if (residueSettings.AtomRepresentation != MolecularRepresentation.None) { customRepresentation = residueSettings.AtomRepresentation; } } } } Color32 atomColour = Color.white; if (customColour != null) { atomColour = (Color)customColour; } else { if (!MolecularConstants.CPKColors.TryGetValue(atom.Element.ToString(), out atomColour)) { MolecularConstants.CPKColors.TryGetValue("Other", out atomColour); } } float atomDiameter = getAtomRadius(atom, renderSettings, customRepresentation) * 2; Vector3 scale = new Vector3(atomDiameter, atomDiameter, atomDiameter); Matrix4x4 atomTransform = Matrix4x4.TRS(position, atomOrientation, scale); if (!mergeTransforms.ContainsKey(atomColour)) { mergeTransforms.Add(atomColour, new List <Matrix4x4>()); } mergeTransforms[atomColour].Add(atomTransform); } // create the meshes by colour GameObject prefab = AtomPrefabs[meshQuality]; GameObject parent = new GameObject("CombinedMeshParent"); parent.SetActive(false); foreach (KeyValuePair <Color, List <Matrix4x4> > item in mergeTransforms) { yield return(StartCoroutine(meshBuilder.CombinedMesh(prefab, item.Value.ToArray(), item.Key, parent))); } parent.transform.SetParent(AtomParent.transform, false); yield break; }
public IEnumerator LoadMolecule(int moleculeID, string structureFilePath, string trajectoryFilePath, MoleculeRenderSettings settings) { yield return(StartCoroutine(LoadMoleculeStructure(moleculeID, structureFilePath, settings))); if (molecules.ContainsKey(moleculeID)) { yield return(StartCoroutine(LoadMoleculeTrajectory(moleculeID, trajectoryFilePath))); } }
// Loads and renders a molecule using a structure file path and render settings public IEnumerator LoadMoleculeStructure(int moleculeID, string filePath, MoleculeRenderSettings settings) { if (molecules.ContainsKey(moleculeID)) { MoleculeEvents.RaiseShowMessage("Error Loading Molecule: already loaded", true); MoleculeEvents.RaiseOnMoleculeLoadFailed(moleculeID); yield break; } if (loadingStructure) { MoleculeEvents.RaiseShowMessage("Can't Load Molecule: another molecule currently loading", true); MoleculeEvents.RaiseOnMoleculeLoadFailed(moleculeID); yield break; } var watch = System.Diagnostics.Stopwatch.StartNew(); MoleculeEvents.RaiseShowMessage("Loading Structure File: " + filePath, false); loadingStructure = true; int oldAtomMeshQuality = generalSettings.MeshQuality; Debug.Log("Loading structure"); PrimaryStructure primaryStructure = null; string loadException = null; Thread thread = new Thread(() => { try { if (filePath.EndsWith(".gro")) { primaryStructure = GROStructureParser.GetStructure(filePath); } else if (filePath.EndsWith(".xyz")) { primaryStructure = XYZStructureParser.GetStructure(filePath); } else if (filePath.EndsWith(".pdb")) { primaryStructure = PDBStructureParser.GetPrimaryStructure(filePath); } } catch (FileParseException ex) { loadException = ex.Message; } }); thread.Start(); while (thread.IsAlive) { yield return(null); } Debug.Log("Finished Loading structure"); if (loadException != null) { Debug.Log("Error Loading Structure File: " + loadException); MoleculeEvents.RaiseShowMessage("Error Loading Structure File: " + loadException, true); MoleculeEvents.RaiseOnMoleculeLoadFailed(moleculeID); loadingStructure = false; yield break; } watch.Stop(); MoleculeEvents.RaiseShowMessage("Structure File Load Complete [" + watch.ElapsedMilliseconds + "ms]", false); yield return(null); if (primaryStructure != null) { GameObject moleculeGO = GameObject.Instantiate(MoleculePrefab); moleculeGO.transform.parent = this.transform; moleculeGO.SetActive(true); Molecule molecule = moleculeGO.GetComponent <Molecule>(); molecule.Initialise(moleculeID, primaryStructure, settings); molecule.AutoRotateSpeed = generalSettings.AutoRotateSpeed; molecule.SetInputSensitivity(generalSettings.MoleculeInputSensitivity); molecule.SetSpaceNavigatorControlEnabled(generalSettings.SpaceNavigatorMoleculeControlEnabled); molecules.Add(moleculeID, molecule); // check to see if the meshQuality needs to change given the new primary structure updateMeshQuality(); molecule.SetRenderSettings(settings); yield return(StartCoroutine(molecule.Render(generalSettings.MeshQuality))); MoleculeEvents.RaiseMoleculeLoaded(moleculeID, Path.GetFileName(filePath), primaryStructure); } if (oldAtomMeshQuality != generalSettings.MeshQuality) { reRenderMolecules(); } SaveCurrentMoleculeTransformAsDefault(moleculeID); loadingStructure = false; }
public void StartMonitoring(Molecule molecule1, Molecule molecule2, MolecularInteractionSettings interactionSettings, MoleculeRenderSettings molecule1Settings, MoleculeRenderSettings molecule2Settings) { UnityEngine.Debug.Log("Start monitoring " + Time.time); if (molecule1 == null) { MoleculeEvents.RaiseInteractionsMessage("Can't monitor interactions. First molecule is null.", true); return; } if (molecule2 == null) { MoleculeEvents.RaiseInteractionsMessage("Can't monitor interactions. Second molecule is null.", true); return; } if (molecule1.PrimaryStructureTrajectory != null || molecule2.PrimaryStructureTrajectory != null) { MoleculeEvents.RaiseInteractionsMessage("Can't monitor interactions. Monitored molecules cannot have trajectories loaded.", true); return; } this.Molecule1 = molecule1; this.Molecule2 = molecule2; this.interactionSettings = interactionSettings; SetMolecule1RenderSettings(molecule1Settings); SetMolecule2RenderSettings(molecule2Settings); interactionsRenderer.Molecule1 = molecule1; interactionsRenderer.Molecule2 = molecule2; reportSigmaEpsilonValueDefaults(molecule1, molecule2); Active = true; }
public IEnumerator Render(int meshQuality) { // if currently rendering, then store render request if (rendering) { awaitingMeshQuality = meshQuality; awaitingRender = true; yield break; } rendering = true; System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch(); watch.Start(); // primary structure render PrimaryStructureFrame frame = null; if (PrimaryStructureTrajectory != null && frameNumber != null) { frame = PrimaryStructureTrajectory.GetFrame((int)frameNumber); } // We use a clone of the render settings so any settings updates dont interfere with the builds MoleculeRenderSettings renderSettingsClone = renderSettings.Clone(); yield return(StartCoroutine(primaryStructureRenderer.RenderStructure(renderSettingsClone, frame, meshQuality))); // secondary structure render SecondaryStructure secondaryStructureToBuild = null; if (secondaryStructureTrajectory != null && frameNumber != null && buildSecondaryStructureTrajectory) { string loadException = null; Thread thread = new Thread(() => { try { secondaryStructureToBuild = secondaryStructureTrajectory.GetStructure((int)frameNumber); } catch (FileParseException ex) { loadException = ex.Message; } }); thread.Start(); while (thread.IsAlive) { yield return(null); } if (loadException != null) { MoleculeEvents.RaiseShowMessage(loadException + " - Aborting trajectory secondary structure builds.", true); buildSecondaryStructureTrajectory = false; } } else { secondaryStructureToBuild = secondaryStructure; } yield return(StartCoroutine(secondaryStructureRenderer.RenderStructure(renderSettingsClone, frame, secondaryStructureToBuild))); primaryStructureRenderer.ShowStructure(); secondaryStructureRenderer.ShowStructure(); // simulation box render if (renderSettingsClone.ShowSimulationBox) { moleculeBox.gameObject.SetActive(true); BoundingBox box = boundingBox; if (renderSettingsClone.CalculateBoxEveryFrame && frame != null) { box = new BoundingBox(frame, true); } moleculeBox.Build(box); } else { moleculeBox.gameObject.SetActive(false); } //Cleanup.ForeceGC(); rendering = false; watch.Stop(); if (Settings.DebugMessages) { //console.BannerBuildTime = watch.ElapsedMilliseconds.ToString(); } //UnityEngine.Debug.Log("Ending model build. Elapsed time [" + watch.ElapsedMilliseconds.ToString() + "]"); yield break; }
public void SetRenderSettings(MoleculeRenderSettings settings) { renderSettings = settings; atomHighlightsRenderer.SetRenderSettings(settings); }
private void Awake() { atomHighlightMeshes = new Dictionary <float, GameObject>(); renderSettings = MoleculeRenderSettings.Default(); }
public void SetRenderSettings(MoleculeRenderSettings settings) { renderSettings = settings; }
public void StartMonitoringInteractions(int molecule1ID, int molecule2ID, MolecularInteractionSettings interactionSettings, MoleculeRenderSettings molecule1Settings, MoleculeRenderSettings molecule2Settings) { if (!molecules.ContainsKey(molecule1ID)) { MoleculeEvents.RaiseInteractionsMessage("Can't monitor interactions. Molecule " + molecule1ID + " not found", true); return; } if (!molecules.ContainsKey(molecule2ID)) { MoleculeEvents.RaiseInteractionsMessage("Can't monitor interactions. Molecule " + molecule2ID + " not found", true); return; } moleculeInterations.StartMonitoring(molecules[molecule1ID], molecules[molecule2ID], interactionSettings, molecule1Settings, molecule2Settings); }
private Mesh BuildStructureMesh(MoleculeRenderSettings renderSettings, Chain chain, PrimaryStructureFrame frame, SecondaryStructure secondaryStructure) { Mesh structureMesh = null; int interpolation = 20; int resolution = 6; // should be in config float radius = 0.015f; List <DynamicMeshNode> nodes = new List <DynamicMeshNode>(); Vector3 lastPosition = Vector3.zero; Vector3 lastNormal = Vector3.zero; Vector3 averagedNormal = Vector3.zero; SecondaryStructureType lastType = SecondaryStructureType.Coil; for (int i = 0; i < chain.MainChainResidues.Count; i++) { DynamicMeshNode node = new DynamicMeshNode(); Residue residue = chain.MainChainResidues[i]; // check if residue mainchain information is complete. Ignore if not if (residue.AlphaCarbon == null || residue.CarbonylCarbon == null || residue.CarbonylOxygen == null) { continue; } // set position Atom atom = residue.AlphaCarbon; // if no frame number use the base structure coordinates. Vector3 position; if (frame == null) { position = new Vector3(atom.Position.x, atom.Position.y, atom.Position.z); } else { position = new Vector3(frame.Coords[atom.Index * 3], frame.Coords[(atom.Index * 3) + 1], frame.Coords[(atom.Index * 3) + 2]); } // flip coord system for Unity position.z *= -1; node.Position = position; SecondaryStructureInfomation structureInformation = secondaryStructure.GetStructureInformation(residue.Index); Residue nextResidue = null; if (i + 1 < chain.MainChainResidues.Count) { nextResidue = chain.MainChainResidues[i + 1]; } SecondaryStructureInfomation nextResidueStructureInfo = null; if (nextResidue != null) { nextResidueStructureInfo = secondaryStructure.GetStructureInformation(nextResidue.Index); } // store the node type if (structureInformation != null) { if (renderSettings.ShowHelices && (structureInformation.type == SecondaryStructureType.ThreeHelix || structureInformation.type == SecondaryStructureType.AlphaHelix || structureInformation.type == SecondaryStructureType.FiveHelix)) { node.Type = DynamicMeshNodeType.SpiralRibbon; } else if (renderSettings.ShowSheets && structureInformation.type == SecondaryStructureType.BetaSheet) { if (nextResidue == null || (nextResidueStructureInfo != null && nextResidueStructureInfo.type != SecondaryStructureType.BetaSheet)) { node.Type = DynamicMeshNodeType.RibbonHead; } else { node.Type = DynamicMeshNodeType.Ribbon; } } else if (renderSettings.ShowTurns && structureInformation.type == SecondaryStructureType.Turn) { node.Type = DynamicMeshNodeType.LargeTube; } else { node.Type = DynamicMeshNodeType.Tube; } // calculate and store the node color bool foundColour = false; if (renderSettings.CustomResidueRenderSettings != null && renderSettings.CustomResidueRenderSettings.ContainsKey(residue.ID)) { ResidueRenderSettings residueRenderSettings = renderSettings.CustomResidueRenderSettings[residue.ID]; if (residueRenderSettings != null && residueRenderSettings.ColourSecondaryStructure) { node.VertexColor = residueRenderSettings.ResidueColour; foundColour = true; } } if (foundColour == false) { switch (structureInformation.type) { case SecondaryStructureType.ThreeHelix: node.VertexColor = Settings.ThreeHelixColour; break; case SecondaryStructureType.AlphaHelix: node.VertexColor = Settings.AlphaHelixColour; break; case SecondaryStructureType.FiveHelix: node.VertexColor = Settings.FiveHelixColour; break; case SecondaryStructureType.Turn: node.VertexColor = Settings.TurnColour; break; case SecondaryStructureType.BetaSheet: node.VertexColor = Settings.BetaSheetColour; break; case SecondaryStructureType.BetaBridge: node.VertexColor = Settings.BetaBridgeColour; break; case SecondaryStructureType.Bend: node.VertexColor = Settings.BendColour; break; case SecondaryStructureType.Coil: node.VertexColor = Settings.CoilColour; break; default: node.VertexColor = ErrorColor; break; } } } else { Debug.Log("*** Structure info null: assigning defaults"); node.Type = DynamicMeshNodeType.Tube; node.VertexColor = ErrorColor; } // determine the node rotation // calculate the normal from the peptide plane and store as the node rotation Vector3 vertexA = residue.AlphaCarbon.Position; Vector3 vertexB = residue.CarbonylCarbon.Position; Vector3 vertexC = residue.CarbonylOxygen.Position; // flip coord system for Unity vertexA.z *= -1; vertexB.z *= -1; vertexC.z *= -1; //// create a triangle to show the peptide plane on the model for debugging purposes //GameObject residuePlane = createTriangle(vertexA, vertexB, vertexC); //residuePlane.name = "ResiduePlane"; //AddMeshToModel(residuePlane, StructureParent); Vector3 direction = Vector3.Cross(vertexB - vertexA, vertexC - vertexA); Vector3 normal = Vector3.Normalize(direction); if (structureInformation != null && structureInformation.type == SecondaryStructureType.BetaSheet || lastType == SecondaryStructureType.BetaSheet) { if (Vector3.Dot(normal, lastNormal) < 0) { normal *= -1; } if (lastType != SecondaryStructureType.BetaSheet) { averagedNormal = normal; } else { averagedNormal += normal; averagedNormal.Normalize(); normal = averagedNormal; } } node.Rotation = normal; lastNormal = normal; if (structureInformation != null) { lastType = structureInformation.type; } else { lastType = SecondaryStructureType.Coil; } nodes.Add(node); } if (renderSettings.SmoothNodes) { nodes = smoothMeshNodes(nodes); } //// draw debug line from node points along rotation vector //for (int q = 0; q < nodePositions.Count; q++) { // Vector3 fromPosition = nodePositions[q]; // Vector3 toPosition = fromPosition + nodeRotations[q] * 0.3f; // GameObject line = createLine(fromPosition, toPosition, Color.white, Color.red); // AddMeshToModel(line, StructureParent); //} List <Vector3> nodePositions = new List <Vector3>(); foreach (DynamicMeshNode node in nodes) { nodePositions.Add(node.Position); } List <DynamicMeshNode> splineNodes = new List <DynamicMeshNode>(); IEnumerable splinePoints = Interpolate.NewCatmullRom(nodePositions.ToArray(), interpolation, false); int j = 0; foreach (Vector3 position in splinePoints) { int nodeIndex = j / (interpolation + 1); int splinePointsSinceLastNode = j % (interpolation + 1); DynamicMeshNode node = new DynamicMeshNode(); node.Position = position; //int colorIndex = nodeIndex % DebugColors.Count; //node.VertexColor = DebugColors[colorIndex]; node.VertexColor = nodes[nodeIndex].VertexColor; node.Type = nodes[nodeIndex].Type; // set the mesh rotations for the node // dont do rotations on tube structures switch (node.Type) { case DynamicMeshNodeType.Ribbon: case DynamicMeshNodeType.RibbonHead: case DynamicMeshNodeType.SpiralRibbon: if (nodeIndex < nodes.Count - 1) { float percentThroughNode = (float)splinePointsSinceLastNode / ((float)interpolation + 1f); node.Rotation = Vector3.Lerp((Vector3)nodes[nodeIndex].Rotation, (Vector3)nodes[nodeIndex + 1].Rotation, percentThroughNode); } else // last node { node.Rotation = (Vector3)nodes[nodeIndex].Rotation; } break; } splineNodes.Add(node); j++; } DynamicMesh dynamicMesh = new DynamicMesh(splineNodes, radius, resolution, interpolation + 1); structureMesh = dynamicMesh.Build(Settings.DebugFlag); return(structureMesh); }