public override void DeleteGeometryForIdentifier(string identifier, bool requestUpdate = true) { lock (Model3DDictionaryMutex) { var geometryModels = FindAllGeometryModel3DsForNode(identifier); if (!geometryModels.Any()) { return; } foreach (var kvp in geometryModels) { var model3D = Model3DDictionary[kvp.Key] as GeometryModel3D; if (model3D != null) { model3D.Detach(); } Model3DDictionary.Remove(kvp.Key); } } if (!requestUpdate) { return; } RaisePropertyChanged("SceneItems"); OnRequestViewRefresh(); }
private void AttachAllGeometryModel3DToRenderHost() { foreach (var model3D in Model3DDictionary.Select(kvp => kvp.Value)) { OnRequestAttachToScene(model3D); } }
/// <summary> /// A utility method for finding all the geometry model objects in the geometry /// dictionary which correspond to a node. /// </summary> /// <param name="node">The node.</param> /// <returns></returns> private KeyValuePair <string, Model3D>[] FindGeometryModel3DsForNode(NodeModel node) { var geometryModels = Model3DDictionary .Where(x => x.Key.Contains(node.AstIdentifierBase)) .Where(x => x.Value is GeometryModel3D) .Select(x => x).ToArray(); return(geometryModels); }
/// <summary> /// Initialize the Helix with these values. These values should be attached before the /// visualization starts. Deleting them and attaching them does not make any effect on helix. /// So they are initialized before the process starts. /// </summary> private void InitializeHelix() { if (Model3DDictionary == null) { throw new Exception("Helix could not be initialized."); } directionalLight = new DirectionalLight3D { Color = directionalLightColor, Direction = directionalLightDirection, Name = DefaultLightName }; if (!Model3DDictionary.ContainsKey(DefaultLightName)) { Model3DDictionary.Add(DefaultLightName, directionalLight); } var gridModel3D = new DynamoLineGeometryModel3D { Geometry = Grid, Transform = Model1Transform, Color = Color.White, Thickness = 0.3, IsHitTestVisible = false, Name = DefaultGridName }; if (!Model3DDictionary.ContainsKey(DefaultGridName)) { Model3DDictionary.Add(DefaultGridName, gridModel3D); } var axesModel3D = new DynamoLineGeometryModel3D { Geometry = Axes, Transform = Model1Transform, Color = Color.White, Thickness = 0.3, IsHitTestVisible = false, Name = DefaultAxesName }; if (!Model3DDictionary.ContainsKey(DefaultAxesName)) { Model3DDictionary.Add(DefaultAxesName, axesModel3D); } AttachAllGeometryModel3DToRenderHost(); }
private KeyValuePair <string, Model3D>[] FindAllGeometryModel3DsForNode(string identifier) { KeyValuePair <string, Model3D>[] geometryModels; lock (Model3DDictionaryMutex) { geometryModels = Model3DDictionary .Where(x => x.Key.Contains(identifier)) .Where(x => x.Value is GeometryModel3D) .Select(x => x).ToArray(); } return(geometryModels); }
protected override void OnClear() { lock (Model3DDictionaryMutex) { var keysList = new List <string> { DefaultLightName, DefaultGridName, DefaultAxesName }; foreach (var key in Model3DDictionary.Keys.Except(keysList).ToList()) { var model = Model3DDictionary[key] as GeometryModel3D; model.Detach(); Model3DDictionary.Remove(key); } } RaisePropertyChanged("SceneItems"); OnRequestViewRefresh(); }
/// <summary> /// Initialize the Geometry everytime a workspace is opened or closed. /// Always, keep these DirectionalLight,Grid,Axes. These values are rendered /// only once by helix, attaching them again will make no effect on helix /// </summary> private void VisualizationManager_WorkspaceOpenedClosedHandled() { List <string> keysList = new List <string> { "DirectionalLight", "Grid", "Axes", "BillBoardText" }; if (Text != null && Text.TextInfo.Any()) { Text.TextInfo.Clear(); } foreach (var key in Model3DDictionary.Keys.Except(keysList).ToList()) { var model = Model3DDictionary[key] as GeometryModel3D; model.Detach(); Model3DDictionary.Remove(key); } NotifyPropertyChanged(""); View.InvalidateRender(); }
/// <summary> /// when a node is deleted, then update the Geometry /// and notify helix /// </summary> /// <param name="node">The node.</param> private void VisualizationManager_DeletionHandled(NodeModel node) { var geometryModels = FindGeometryModel3DsForNode(node); if (!geometryModels.Any()) { return; } foreach (var kvp in geometryModels) { var model = Model3DDictionary[kvp.Key] as GeometryModel3D; if (model != null) { model.Detach(); model.MouseDown3D -= meshGeometry3D_MouseDown3D; } Model3DDictionary.Remove(kvp.Key); } NotifyPropertyChanged(""); }
private void CreateOrUpdateText(string baseId, Vector3 pt, IRenderPackage rp) { var textId = baseId + TextKey; BillboardTextModel3D bbText; if (Model3DDictionary.ContainsKey(textId)) { bbText = Model3DDictionary[textId] as BillboardTextModel3D; } else { bbText = new BillboardTextModel3D() { Geometry = HelixRenderPackage.InitText3D(), }; Model3DDictionary.Add(textId, bbText); } var geom = bbText.Geometry as BillboardText3D; geom.TextInfo.Add(new TextInfo(HelixRenderPackage.CleanTag(rp.Description), new Vector3(pt.X + 0.025f, pt.Y + 0.025f, pt.Z + 0.025f))); }
private void AggregateRenderPackages(IEnumerable <HelixRenderPackage> packages) { lock (Model3DDictionaryMutex) { foreach (var rp in packages) { // Each node can produce multiple render packages. We want all the geometry of the // same kind stored inside a RenderPackage to be pushed into one GeometryModel3D object. // We strip the unique identifier for the package (i.e. the bit after the `:` in var12345:0), and replace it // with `points`, `lines`, or `mesh`. For each RenderPackage, we check whether the geometry dictionary // has entries for the points, lines, or mesh already. If so, we add the RenderPackage's geometry // to those geometry objects. var baseId = rp.Description; if (baseId.IndexOf(":", StringComparison.Ordinal) > 0) { baseId = baseId.Split(':')[0]; } var id = baseId; var p = rp.Points; if (p.Positions.Any()) { id = baseId + PointsKey; PointGeometryModel3D pointGeometry3D; if (Model3DDictionary.ContainsKey(id)) { pointGeometry3D = Model3DDictionary[id] as PointGeometryModel3D; } else { pointGeometry3D = CreatePointGeometryModel3D(rp); Model3DDictionary.Add(id, pointGeometry3D); } var points = pointGeometry3D.Geometry as PointGeometry3D; var startIdx = points.Positions.Count; points.Positions.AddRange(p.Positions); points.Colors.AddRange(p.Colors.Any() ? p.Colors : Enumerable.Repeat(defaultPointColor, points.Positions.Count)); points.Indices.AddRange(p.Indices.Select(i => i + startIdx)); if (rp.DisplayLabels) { CreateOrUpdateText(baseId, p.Positions[0], rp); } pointGeometry3D.Geometry = points; pointGeometry3D.Name = baseId; } var l = rp.Lines; if (l.Positions.Any()) { id = baseId + LinesKey; LineGeometryModel3D lineGeometry3D; if (Model3DDictionary.ContainsKey(id)) { lineGeometry3D = Model3DDictionary[id] as LineGeometryModel3D; } else { // If the package contains mesh vertices, then the lines represent the // edges of meshes. Draw them with a different thickness. lineGeometry3D = CreateLineGeometryModel3D(rp, rp.MeshVertices.Any()?0.5:1.0); Model3DDictionary.Add(id, lineGeometry3D); } var lineSet = lineGeometry3D.Geometry as LineGeometry3D; var startIdx = lineSet.Positions.Count; lineSet.Positions.AddRange(l.Positions); lineSet.Colors.AddRange(l.Colors.Any() ? l.Colors : Enumerable.Repeat(defaultLineColor, l.Positions.Count)); lineSet.Indices.AddRange(l.Indices.Any() ? l.Indices.Select(i => i + startIdx) : Enumerable.Range(startIdx, startIdx + l.Positions.Count)); if (rp.DisplayLabels) { var pt = lineSet.Positions[startIdx]; CreateOrUpdateText(baseId, pt, rp); } lineGeometry3D.Geometry = lineSet; lineGeometry3D.Name = baseId; } var m = rp.Mesh; if (!m.Positions.Any()) { continue; } id = ((rp.RequiresPerVertexColoration || rp.Colors != null) ? rp.Description : baseId) + MeshKey; DynamoGeometryModel3D meshGeometry3D; if (Model3DDictionary.ContainsKey(id)) { meshGeometry3D = Model3DDictionary[id] as DynamoGeometryModel3D; } else { meshGeometry3D = CreateDynamoGeometryModel3D(rp); Model3DDictionary.Add(id, meshGeometry3D); } var mesh = meshGeometry3D.Geometry == null ? HelixRenderPackage.InitMeshGeometry() : meshGeometry3D.Geometry as MeshGeometry3D; var idxCount = mesh.Positions.Count; mesh.Positions.AddRange(m.Positions); mesh.Colors.AddRange(m.Colors); mesh.Normals.AddRange(m.Normals); mesh.TextureCoordinates.AddRange(m.TextureCoordinates); mesh.Indices.AddRange(m.Indices.Select(i => i + idxCount)); if (mesh.Colors.Any(c => c.Alpha < 1.0)) { meshGeometry3D.SetValue(AttachedProperties.HasTransparencyProperty, true); } if (rp.DisplayLabels) { var pt = mesh.Positions[idxCount]; CreateOrUpdateText(baseId, pt, rp); } meshGeometry3D.Geometry = mesh; meshGeometry3D.Name = baseId; } AttachAllGeometryModel3DToRenderHost(); } }