private static Mesh GetMeshes(string model) { Mesh mesh = new Mesh(); if (Directory.Exists(LibraryPath)) { var files = Directory.GetFiles(LibraryPath, "*.3dm"); Rhino.DocObjects.Layer layer = null; foreach (var file in files) { Rhino.FileIO.File3dm geometry = Rhino.FileIO.File3dm.Read(file); layer = geometry.AllLayers.FirstOrDefault(x => x.Name == model); if (layer != null) { var meshes = geometry.Objects.Where(x => x.Attributes.LayerIndex == layer.Index).Select(x => x.Geometry as Mesh); foreach (var part in meshes) { mesh.Append(part); } break; } } if (layer == null) { throw new InvalidOperationException($" Tool \"{model}\" is not in the geometry file."); } } return(mesh); }
private static Mesh GetMeshes(string model) { var meshes = new List <Mesh>(); Mesh mesh = new Mesh(); // string folder = $@"{Util.AssemblyDirectory}\robots\tools"; string folder = Path.Combine(LibraryPath, "robots"); if (Directory.Exists(folder)) { var files = Directory.GetFiles(folder, "*.3dm"); Rhino.DocObjects.Layer layer = null; foreach (var file in files) { Rhino.FileIO.File3dm geometry = Rhino.FileIO.File3dm.Read($@"{file}"); layer = geometry.AllLayers.FirstOrDefault(x => x.Name == $"{model}"); if (layer != null) { meshes = geometry.Objects.Where(x => x.Attributes.LayerIndex == layer.Index).Select(x => x.Geometry as Mesh).ToList(); for (int i = 0; i < meshes.Count; ++i) { mesh.Append(meshes[i]); } } } if (layer == null) { throw new InvalidOperationException($" Tool \"{model}\" is not in the geometry file."); } } return(mesh); }
/// <summary> /// Sets the material association for a layer. /// </summary> /// <param name="LayerIndex"></param> /// <param name="Abs">0 to 100</param> /// <param name="Scat">0 to 100</param> /// <returns></returns> public static bool Material_SetLayer(int LayerIndex, int[] Abs, int[] Scat, int[] Trans) { Rhino.DocObjects.Layer layer = Rhino.RhinoDoc.ActiveDoc.Layers[LayerIndex]; layer.SetUserString("ABSType", ""); layer.SetUserString("Acoustics", RC_PachTools.EncodeAcoustics(Abs, Scat, Trans)); return(Rhino.RhinoDoc.ActiveDoc.Layers.Modify(layer, LayerIndex, false)); }
/// <summary> /// Sets the material association for a layer. /// </summary> /// <param name="LayerName"></param> /// <param name="Abs">0 to 100</param> /// <param name="Scat">0 to 100</param> /// <returns></returns> public static bool Material_SetLayer(string LayerName, int[] Abs, int[] Scat, int[] Trans = null) { int layer_index = Rhino.RhinoDoc.ActiveDoc.Layers.Find(LayerName, true); Rhino.DocObjects.Layer layer = Rhino.RhinoDoc.ActiveDoc.Layers[layer_index]; layer.SetUserString("Acoustics", RC_PachTools.EncodeAcoustics(Abs, Scat, Trans)); return(Rhino.RhinoDoc.ActiveDoc.Layers.Modify(layer, layer_index, false)); }
/// <summary> /// Adds a new reference layer with specified definition to the layer table /// Reference layers are not saved in files. /// </summary> /// <param name="layer"> /// definition of new layer. The information in layer is copied. If layer.Name is empty /// the a unique name of the form "Layer 01" will be automatically created. /// </param> /// <returns> /// >=0 index of new layer /// -1 layer not added because a layer with that name already exists. /// </returns> public int AddReferenceLayer(Rhino.DocObjects.Layer layer) { if (null == layer) { return(-1); } IntPtr pLayer = layer.ConstPointer(); return(UnsafeNativeMethods.CRhinoLayerTable_AddLayer(m_doc.m_docId, pLayer, true)); }
/// <summary>Modifies layer settings.</summary> /// <param name="newSettings">This information is copied.</param> /// <param name="layerIndex"> /// zero based index of layer to set. This must be in the range 0 <= layerIndex < LayerTable.Count. /// </param> /// <param name="quiet">if true, information message boxes pop up when illegal changes are attempted.</param> /// <returns> /// true if successful. false if layerIndex is out of range or the settings attempt /// to lock or hide the current layer. /// </returns> public bool Modify(Rhino.DocObjects.Layer newSettings, int layerIndex, bool quiet) { if (null == newSettings) { return(false); } IntPtr pLayer = newSettings.ConstPointer(); return(UnsafeNativeMethods.CRhinoLayerTable_ModifyLayer(m_doc.m_docId, pLayer, layerIndex, quiet)); }
//레이어 검정 => 하양 public static void LayerColorChange(RhinoDoc doc, Color layercolor) { Color defaultcolor = Color.Gold; Color tempcolor = Color.Black; if (layercolor == Color.Black) { tempcolor = Color.White; } var matching_layers = (from layer in doc.Layers where layer.Color == layercolor select layer).ToList <Rhino.DocObjects.Layer>(); Rhino.DocObjects.Layer layer_to_change = null; if (matching_layers.Count == 0) { RhinoApp.WriteLine("Layer" + layercolor.ToKnownColor() + "does not exist."); } else if (matching_layers.Count > 0) { for (int i = 0; i < matching_layers.Count; i++) { if (matching_layers[i].Name == "Default") { matching_layers[i].Color = Color.Gold; matching_layers[i].CommitChanges(); continue; } layer_to_change = matching_layers[i]; var obj = doc.Objects.FindByLayer(layer_to_change); foreach (Rhino.DocObjects.RhinoObject c in obj) { if (c.Attributes.ColorSource == Rhino.DocObjects.ObjectColorSource.ColorFromLayer) { continue; } c.Attributes.ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromLayer; c.CommitChanges(); } layer_to_change.Color = tempcolor; layer_to_change.CommitChanges(); } } }
public static void CreateLayers() { #region Root Layer Rhino.DocObjects.Layer RNN_Layer; int root_index = doc.Layers.Find("RhinoNatNet", false); if (root_index < 0) { //Rhino.RhinoApp.WriteLine("Couldn't find RhinoNatNet layer."); RNN_Layer = new Rhino.DocObjects.Layer(); RNN_Layer.Name = "RhinoNatNet"; RNN_Layer.Color = System.Drawing.Color.DarkRed; root_index = doc.Layers.Add(RNN_Layer); RNN_Layer.CommitChanges(); } //RNN_Layer = doc.Layers[root_index]; #endregion #region Marker Layer Rhino.DocObjects.Layer RNN_Markers_Layer; int index = doc.Layers.Find("RNN_Markers", true); if (index < 0) { RNN_Markers_Layer = new Rhino.DocObjects.Layer(); RNN_Markers_Layer.Name = "RNN_Markers"; RNN_Markers_Layer.ParentLayerId = doc.Layers[root_index].Id; RNN_Markers_Layer.Color = System.Drawing.Color.Lime; index = doc.Layers.Add(RNN_Markers_Layer); } doc.Layers[index].ParentLayerId = doc.Layers[root_index].Id; doc.Layers[index].CommitChanges(); //RNN_Markers_Layer = doc.Layers[index]; #endregion #region Geometry Layer Rhino.DocObjects.Layer RNN_Geo_Layer; index = doc.Layers.Find("RNN_Geometry", true); if (index < 0) { RNN_Geo_Layer = new Rhino.DocObjects.Layer(); RNN_Geo_Layer.Name = "RNN_Geometry"; RNN_Geo_Layer.ParentLayerId = doc.Layers[root_index].Id; RNN_Geo_Layer.Color = System.Drawing.Color.DarkRed; index = doc.Layers.Add(RNN_Geo_Layer); } //RNN_Geo_Layer = doc.Layers[index]; #endregion }
static List <Mesh> GetMeshes(string model) { var meshes = new List <Mesh>(); /* * using (var stream = new MemoryStream(Properties.Resources.Meshes)) * { * var formatter = new BinaryFormatter(); * JointMeshes jointMeshes = formatter.Deserialize(stream) as JointMeshes; * index = jointMeshes.Names.FindIndex(x => x == model); * if (index != -1) meshes = jointMeshes.Meshes[index]; * } */ // string folder = $@"{AssemblyDirectory}\robots"; string folder = LibraryPath; if (Directory.Exists(folder)) { var files = Directory.GetFiles(folder, "*.3dm"); Rhino.DocObjects.Layer layer = null; foreach (var file in files) { Rhino.FileIO.File3dm geometry = Rhino.FileIO.File3dm.Read($@"{file}"); layer = geometry.Layers.FirstOrDefault(x => x.Name == $"{model}"); if (layer != null) { int i = 0; while (true) { string name = $"{i++}"; var jointLayer = geometry.Layers.FirstOrDefault(x => (x.Name == name) && (x.ParentLayerId == layer.Id)); if (jointLayer == null) { break; } meshes.Add(geometry.Objects.First(x => x.Attributes.LayerIndex == jointLayer.LayerIndex).Geometry as Mesh); } break; } } if (layer == null) { throw new InvalidOperationException($" Robot \"{model}\" is not in the geometry file."); } } return(meshes); }
private List <Mesh> FindAnalysisGrid() { List <Mesh> anlysisGrid = new List <Mesh>(); try { string layerName = "Analysis Grid"; Rhino.RhinoDoc activeDoc = Rhino.RhinoDoc.ActiveDoc; activeDoc.Objects.UnselectAll(); List <Guid> objIds = new List <Guid>(); if (null != activeDoc) { int layerIndex = activeDoc.Layers.Find(layerName, true); if (layerIndex < 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, layerName + " cannot be found."); return(null); } Rhino.DocObjects.Layer layer = activeDoc.Layers[layerIndex]; Rhino.DocObjects.RhinoObject[] objs = activeDoc.Objects.FindByLayer(layer); if (objs != null) { foreach (Rhino.DocObjects.RhinoObject obj in objs) { if (obj.Geometry.ObjectType == Rhino.DocObjects.ObjectType.Mesh) { Mesh mesh = obj.Geometry as Mesh; if (null != mesh) { anlysisGrid.Add(mesh); Guid guid = obj.Id; objIds.Add(guid); } } } activeDoc.Objects.Select(objIds); } } } catch (Exception ex) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Analysis Grid cannot be exported.\n" + ex.Message); } return(anlysisGrid); }
private void Button_Click_Build(object sender, RoutedEventArgs e) { Rhino.RhinoDoc doc = Rhino.RhinoDoc.ActiveDoc; int ExpLayerIndex = doc.Layers.Find("Exploration", true); if (ExpLayerIndex < 0) { Rhino.DocObjects.Layer ExpLayer = new Rhino.DocObjects.Layer(); ExpLayer.Name = "Exploration"; doc.Layers.Add(ExpLayer); ExpLayerIndex = doc.Layers.Find("Exploration", true); } int subExpLayerIndex = 0; if (!(doc.Layers[ExpLayerIndex].GetChildren() == null)) { subExpLayerIndex = doc.Layers[ExpLayerIndex].GetChildren().Length; } Rhino.DocObjects.Layer subExpLayer = new Rhino.DocObjects.Layer(); subExpLayer.Name = "Exploration" + subExpLayerIndex.ToString(); subExpLayer.ParentLayerId = doc.Layers[ExpLayerIndex].Id; doc.Layers.Add(subExpLayer); subExpLayerIndex = doc.Layers.Find(subExpLayer.Name, true); Rhino.DocObjects.ObjectAttributes attr = new Rhino.DocObjects.ObjectAttributes(); attr.LayerIndex = subExpLayerIndex; foreach (Rhino.Geometry.Line l in Component.DesignLines) { doc.Objects.AddLine(l, attr); } foreach (Rhino.Geometry.Curve c in Component.DesignCurves) { doc.Objects.AddCurve(c, attr); } foreach (Rhino.Geometry.Brep b in Component.DesignBreps) { doc.Objects.AddBrep(b, attr); } foreach (Rhino.Geometry.Mesh m in Component.DesignMeshes) { doc.Objects.AddMesh(m, attr); } }
public static List <string> getAllChildren(Rhino.DocObjects.Layer layer) { string fullPath = layer.FullPath; List <string> predecessors = new List <string>(); if (fullPath.Contains("::")) { string[] preds = fullPath.Split(new[] { "::" }, StringSplitOptions.None); foreach (var p in preds) { predecessors.Add(p); } } else { predecessors.Add(fullPath); } return(predecessors); }
//Method returns the layer index after the sublayer is created public static int createSubLayer(String layerName, System.Drawing.Color color, Rhino.DocObjects.Layer parentLayer) { int layerIndex = 0; Rhino.DocObjects.Layer parent_layer_Approval = null; //create variable to hold approval layer Rhino.DocObjects.Layer childlayer = null; //Create a variable to hold child layers RhinoDoc doc = RhinoDoc.ActiveDoc; // Does a layer with the same name already exist? layerIndex = doc.Layers.Find(layerName, true); parent_layer_Approval = parentLayer; if (layerIndex < 0) //If the layer does not exist, create a new layer { childlayer = new Rhino.DocObjects.Layer(); childlayer.Color = color; childlayer.Name = layerName; if (layerName.Equals("FOLDS")) //Checks if the layer name getting created is called "FOLDS", if yes the folds line type should be dashed { const string linetype_name = "Dashed"; var linetype_index = doc.Linetypes.Find(linetype_name, true); //get the index of the line if (linetype_index < 0) { RhinoApp.WriteLine("\"{0}\" linetype not found.", linetype_name); // return Result.Nothing; } if (childlayer.LinetypeIndex != linetype_index) { childlayer.LinetypeIndex = linetype_index; //set the line type to the layer } } childlayer.ParentLayerId = parent_layer_Approval.Id; //set parent layer id of child layer(Parent layer - Apporval Layer) doc.Layers.Add(childlayer); //add child layer to the layer table return(layerIndex = doc.Layers.Find(layerName, true)); } else //if layer exists, set parent id of the layer to parent layer id { doc.Layers[layerIndex].ParentLayerId = parent_layer_Approval.Id; return(layerIndex = doc.Layers[layerIndex].LayerIndex); } }
public static Rhino.Commands.Result AddChildLayer(Rhino.RhinoDoc doc) { // Get an existing layer string default_name = doc.Layers.CurrentLayer.Name; // Prompt the user to enter a layer name Rhino.Input.Custom.GetString gs = new Rhino.Input.Custom.GetString(); gs.SetCommandPrompt("Name of existing layer"); gs.SetDefaultString(default_name); gs.AcceptNothing(true); gs.Get(); if (gs.CommandResult() != Rhino.Commands.Result.Success) { return(gs.CommandResult()); } // Was a layer named entered? string layer_name = gs.StringResult().Trim(); int index = doc.Layers.Find(layer_name, true); if (index < 0) { return(Rhino.Commands.Result.Cancel); } Rhino.DocObjects.Layer parent_layer = doc.Layers[index]; // Create a child layer string child_name = parent_layer.Name + "_child"; Rhino.DocObjects.Layer childlayer = new Rhino.DocObjects.Layer(); childlayer.ParentLayerId = parent_layer.Id; childlayer.Name = child_name; childlayer.Color = System.Drawing.Color.Red; index = doc.Layers.Add(childlayer); if (index < 0) { Rhino.RhinoApp.WriteLine("Unable to add {0} layer.", child_name); return(Rhino.Commands.Result.Failure); } return(Rhino.Commands.Result.Success); }
private int getLayerOrCreate(Rhino.RhinoDoc doc, string name) { int layer_index = 0; Rhino.DocObjects.Layer layer = doc.Layers.FindName(name); Guid current_layer_guid = doc.Layers.CurrentLayer.Id; if (layer == null) { Rhino.DocObjects.Layer newlayer = new Rhino.DocObjects.Layer(); newlayer.ParentLayerId = current_layer_guid; newlayer.Name = name; layer_index = doc.Layers.Add(newlayer); } else { layer_index = layer.Index; } return(layer_index); }
private void RhinoDoc_LayerTableEvent(object sender, Rhino.DocObjects.Tables.LayerTableEventArgs e) { // enabled ? if (!this.Settings.GetBool("enabled")) { return; } // Not add event if (e.EventType != Rhino.DocObjects.Tables.LayerTableEventType.Added) { return; } // In detail view if (Rhino.RhinoDoc.ActiveDoc.Views.ActiveView.ActiveViewport.ViewportType == Rhino.Display.ViewportType.DetailViewport) { return; } // Holding shift inverse SafeLayout new layer behavior. if (this.Settings.GetBool("new_layer_visible_in_layout") != ((Eto.Forms.Keyboard.Modifiers & Eto.Forms.Keys.Shift) != 0)) { return; } // Hide layer in every layouts and details Rhino.DocObjects.Layer layer = Rhino.RhinoDoc.ActiveDoc.Layers.FindIndex(e.LayerIndex); foreach (Rhino.Display.RhinoPageView pageView in Rhino.RhinoDoc.ActiveDoc.Views.GetPageViews()) { //layer.SetPerViewportVisible(pageView.MainViewport.Id, false); foreach (Rhino.DocObjects.DetailViewObject detail in pageView.GetDetailViews()) { layer.SetPerViewportVisible(detail.Id, false); } } Rhino.RhinoDoc.ActiveDoc.Views.Redraw(); //RhinoApp.WriteLine("SL : RhinoDoc_LayerTableEvent"); }
public static Rhino.Commands.Result AddChildLayer(Rhino.RhinoDoc doc) { // Get an existing layer string default_name = doc.Layers.CurrentLayer.Name; // Prompt the user to enter a layer name Rhino.Input.Custom.GetString gs = new Rhino.Input.Custom.GetString(); gs.SetCommandPrompt("Name of existing layer"); gs.SetDefaultString(default_name); gs.AcceptNothing(true); gs.Get(); if (gs.CommandResult() != Rhino.Commands.Result.Success) return gs.CommandResult(); // Was a layer named entered? string layer_name = gs.StringResult().Trim(); int index = doc.Layers.Find(layer_name, true); if (index<0) return Rhino.Commands.Result.Cancel; Rhino.DocObjects.Layer parent_layer = doc.Layers[index]; // Create a child layer string child_name = parent_layer.Name + "_child"; Rhino.DocObjects.Layer childlayer = new Rhino.DocObjects.Layer(); childlayer.ParentLayerId = parent_layer.Id; childlayer.Name = child_name; childlayer.Color = System.Drawing.Color.Red; index = doc.Layers.Add(childlayer); if (index < 0) { Rhino.RhinoApp.WriteLine("Unable to add {0} layer.", child_name); return Rhino.Commands.Result.Failure; } return Rhino.Commands.Result.Success; }
/* * public static int[] getLayerCounts() * { * Rhino.DocObjects.ObjectEnumeratorSettings objEnum = new Rhino.DocObjects.ObjectEnumeratorSettings * { * VisibleFilter = false, * IncludeLights = true, * IncludeGrips = true, * NormalObjects = true, * LockedObjects = true, * HiddenObjects = true * }; * var allObjectsInDoc = Rhino.RhinoDoc.ActiveDoc.Objects.GetObjectList(objEnum); * int[] layerCounts = Enumerable.Repeat(0, Rhino.RhinoDoc.ActiveDoc.Layers.Count).ToArray(); * foreach (var obj in allObjectsInDoc) * { * layerCounts[obj.Attributes.LayerIndex]++; * } * return layerCounts; * }*/ private void makeLayerVisible(Rhino.DocObjects.Layer lay) { Rhino.DocObjects.Layer layer1 = lay; List <Guid> guidList = new List <Guid>(); while (true) { guidList.Add(layer1.Id); if (!(layer1.ParentLayerId == Guid.Empty)) { layer1 = Rhino.RhinoDoc.ActiveDoc.Layers[(Rhino.RhinoDoc.ActiveDoc.Layers.Find(layer1.ParentLayerId, true))]; } else { break; } } for (int index = guidList.Count - 1; index >= 0; --index) { Rhino.DocObjects.Layer layer2 = Rhino.RhinoDoc.ActiveDoc.Layers[Rhino.RhinoDoc.ActiveDoc.Layers.Find(guidList[index], true)]; layer2.IsVisible = true; layer2.CommitChanges(); } }
private bool AddLayer(RhinoDoc doc) { bool result = false; try { Dictionary <string, Color> analysisDictionary = new Dictionary <string, Color>(); analysisDictionary.Add("Analysis Grid", Color.FromArgb(255, 255, 255)); analysisDictionary.Add("Node Values", Color.FromArgb(190, 190, 190)); analysisDictionary.Add("Nodes", Color.FromArgb(0, 0, 0)); analysisDictionary.Add("Radiance Legend", Color.FromArgb(0, 0, 0)); analysisDictionary.Add("Node Surfaces", Color.FromArgb(255, 175, 0)); Dictionary <string, Color> thermalDictionary = new Dictionary <string, Color>(); thermalDictionary.Add("ep_adiabatic", Color.FromArgb(0, 0, 0)); thermalDictionary.Add("ep_ceiling", Color.FromArgb(144, 144, 144)); thermalDictionary.Add("ep_floor", Color.FromArgb(254, 254, 254)); thermalDictionary.Add("ep_shading", Color.FromArgb(25, 25, 25)); thermalDictionary.Add("ep_wall", Color.FromArgb(200, 200, 200)); thermalDictionary.Add("ep_window", Color.FromArgb(63, 191, 191)); int analysisIndex = doc.Layers.Find("DIVA Analysis Surfaces", true); if (analysisIndex < 0) { analysisIndex = doc.Layers.Add("DIVA Analysis Surfaces", Color.FromArgb(0, 175, 200)); } Rhino.DocObjects.Layer analysisLayer = doc.Layers[analysisIndex]; Guid parentGuid = analysisLayer.Id; foreach (string layerName in analysisDictionary.Keys) { if (Rhino.DocObjects.Layer.IsValidName(layerName) && doc.Layers.Find(layerName, true) < 0) { Rhino.DocObjects.Layer childLayer = new Rhino.DocObjects.Layer(); childLayer.ParentLayerId = parentGuid; childLayer.Name = layerName; childLayer.Color = analysisDictionary[layerName]; int index = doc.Layers.Add(childLayer); } } int thermalIndex = doc.Layers.Find("DIVA Thermal", true); if (thermalIndex < 0) { thermalIndex = doc.Layers.Add("DIVA Thermal", Color.FromArgb(0, 0, 0)); } Rhino.DocObjects.Layer thermalLayer = doc.Layers[thermalIndex]; parentGuid = thermalLayer.Id; foreach (string layerName in thermalDictionary.Keys) { if (Rhino.DocObjects.Layer.IsValidName(layerName) && doc.Layers.Find(layerName, true) < 0) { Rhino.DocObjects.Layer childLayer = new Rhino.DocObjects.Layer(); childLayer.ParentLayerId = parentGuid; childLayer.Name = layerName; childLayer.Color = thermalDictionary[layerName]; int index = doc.Layers.Add(childLayer); } } result = true; } catch (Exception ex) { RhinoApp.WriteLine("Cannot add layers. " + ex.Message); result = false; } return(result); }
public static Result LockLayer(RhinoDoc doc) { string layer_name = ""; var rc = RhinoGet.GetString("Name of layer to lock", true, ref layer_name); if (rc != Result.Success) { return(rc); } if (String.IsNullOrWhiteSpace(layer_name)) { return(Result.Nothing); } // because of sublayers it's possible that mone than one layer has the same name // so simply calling doc.Layers.Find(layerName) isn't good enough. If "layerName" returns // more than one layer then present them to the user and let him decide. var matching_layers = (from layer in doc.Layers where layer.Name == layer_name select layer).ToList <Rhino.DocObjects.Layer>(); Rhino.DocObjects.Layer layer_to_lock = null; if (matching_layers.Count == 0) { RhinoApp.WriteLine("Layer \"{0}\" does not exist.", layer_name); return(Result.Nothing); } else if (matching_layers.Count == 1) { layer_to_lock = matching_layers[0]; } else if (matching_layers.Count > 1) { for (int i = 0; i < matching_layers.Count; i++) { RhinoApp.WriteLine("({0}) {1}", i + 1, matching_layers[i].FullPath.Replace("::", "->")); } int selected_layer = -1; rc = RhinoGet.GetInteger("which layer?", true, ref selected_layer); if (rc != Result.Success) { return(rc); } if (selected_layer > 0 && selected_layer <= matching_layers.Count) { layer_to_lock = matching_layers[selected_layer - 1]; } else { return(Result.Nothing); } } if (layer_to_lock == null) { return(Result.Nothing); } if (!layer_to_lock.IsLocked) { layer_to_lock.IsLocked = true; layer_to_lock.CommitChanges(); return(Result.Success); } else { RhinoApp.WriteLine("layer {0} is already locked.", layer_to_lock.FullPath); return(Result.Nothing); } }
public RhCommon_Scene(List <Rhino.DocObjects.RhinoObject> ObjRef, double Temp, double hr, double Pa, int Air_Choice, bool EdgeCorrection, bool IsAcoustic) : base(Temp, hr, Pa, Air_Choice, EdgeCorrection, IsAcoustic) { Vector3d NormalHolder = new Vector3d(); Plane PlaneHolder = new Plane(); Transform XHolder = new Transform(); Random RND = new Random(); ObjectList = new List <Rhino.DocObjects.ObjRef>(); for (int q = 0; q < ObjRef.Count; q++) { ObjectList.Add(new Rhino.DocObjects.ObjRef(ObjRef[q])); Rhino.Geometry.Brep BObj; if (ObjRef[q].ObjectType == Rhino.DocObjects.ObjectType.Brep) { BObj = ((Rhino.DocObjects.BrepObject)ObjRef[q]).BrepGeometry; } else { BObj = ((Rhino.DocObjects.ExtrusionObject)ObjRef[q]).ExtrusionGeometry.ToBrep(); } for (int j = 0; j < BObj.Faces.Count; j++) { Brep B_Temp = BObj.DuplicateSubBrep(new List <int>() { j }); BrepList.Add(B_Temp); string Mode = null; string AcousticsData = null; double[] Absorption = new double[8]; //double[,] Scattering = new double[8, 3]; //double[] Reflection = new double[8]; double[] phase = new double[8]; double[] Transparency = new double[8]; double[] Transmission = new double[8]; Mode = BObj.GetUserString("Acoustics_User"); double[] Scat = new double[8]; for (int oct = 0; oct < 8; oct++) { phase[oct] = 0; } if (Mode == "yes") { AcousticsData = BObj.GetUserString("Acoustics"); if (AcousticsData != "") { UI.PachydermAc_PlugIn.DecodeAcoustics(AcousticsData, ref Absorption, ref Scat, ref Transparency); } else { if (!Custom_Method) { Status = System.Windows.Forms.MessageBox.Show("A material is not specified correctly. Please assign absorption and scattering to all layers in the model.", "Materials Error", System.Windows.Forms.MessageBoxButtons.OK); Complete = false; return; } } } else { Rhino.DocObjects.Layer layer = Rhino.RhinoDoc.ActiveDoc.Layers[ObjRef[q].Attributes.LayerIndex]; string Method = layer.GetUserString("ABSType"); AcousticsData = layer.GetUserString("Acoustics"); if (Method == "Buildup") { List <AbsorptionModels.ABS_Layer> Layers = new List <AbsorptionModels.ABS_Layer>(); string[] Buildup = layer.GetUserString("Buildup").Split(new char[] { ';' }, StringSplitOptions.RemoveEmptyEntries); foreach (string l in Buildup) { Layers.Add(AbsorptionModels.ABS_Layer.LayerFromCode(l)); } AbsorptionData.Add(new Smart_Material(false, Layers, 44100, Env_Prop.Rho(0), Env_Prop.Sound_Speed(0), 2)); } if (!string.IsNullOrEmpty(AcousticsData)) { UI.PachydermAc_PlugIn.DecodeAcoustics(AcousticsData, ref Absorption, ref Scat, ref Transparency); AbsorptionData.Add(new Basic_Material(Absorption, phase)); } else { if (!Custom_Method) { Status = System.Windows.Forms.MessageBox.Show("A material is not specified correctly. Please assign absorption and scattering to all layers in the model.", "Materials Error", System.Windows.Forms.MessageBoxButtons.OK); Complete = false; return; } } } for (int oct = 0; oct < 8; oct++) { //Reflection[oct] = (1 - Absorption[oct]); Transmission[oct] = Transparency[oct]; //Scattering[oct, 1] = Scat[oct]; //phase[oct] = 0; } //ReflectionData.Add(Reflection); ScatteringData.Add(new Lambert_Scattering(Scat, SplitRatio)); TransmissionData.Add(Transmission); //PhaseData.Add(phase); bool Trans = false; for (int t_oct = 0; t_oct < 8; t_oct++) { if (Transmission[t_oct] > 0) { Trans = true; break; } } Transmissive.Add(Trans); PlaneBoolean.Add(BObj.Faces[j].IsPlanar()); if (PlaneBoolean[PlaneBoolean.Count - 1]) { Vector3d Normal = new Vector3d(); Point3d Origin = new Point3d(); //Transform MirrorSingle = new Transform(); //Plane PlaneSingle = new Plane(); Origin = BObj.Faces[j].PointAt(0, 0); Normal = BObj.Faces[j].NormalAt(RND.NextDouble(), RND.NextDouble()); Mirror.Add(Transform.Mirror(Origin, Normal)); Plane.Add(new Plane(Origin, Normal)); PlanarNormal.Add(Normal); } else { PlanarNormal.Add(NormalHolder); Plane.Add(PlaneHolder); Mirror.Add(XHolder); } } } Valid = true; }
/// <summary> /// This is the method that actually does the work. /// </summary> /// <param name="DA">The DA object is used to retrieve from inputs and store in outputs.</param> protected override void SolveInstance(IGH_DataAccess DA) { List <Curve> C = new List <Curve>(); List <string> Layer = new List <string>(); List <Color> LColor = new List <Color>(); if (!DA.GetDataList(0, C)) { return; } if (C == null || C.Count == 0) { return; } if (!DA.GetDataList(1, Layer)) { for (int i = 0; i < C.Count; i++) { Layer.Add("Default"); } } if (Layer == null || Layer.Count != C.Count) { return; } if (!DA.GetDataList(2, LColor)) { for (int i = 0; i < C.Count; i++) { LColor.Add(Color.Black); } } if (LColor == null || LColor.Count != C.Count) { return; } bool PreserveUnits = true, ViewBound = true, ColStyle = true, SolidHatch = true, OrderLayers = true; DA.GetData(3, ref PreserveUnits); DA.GetData(4, ref ViewBound); DA.GetData(5, ref ColStyle); DA.GetData(6, ref SolidHatch); DA.GetData(7, ref OrderLayers); string path = "", name = ""; if (!DA.GetData(8, ref path)) { return; } if (!DA.GetData(9, ref name)) { return; } bool export = false; DA.GetData(10, ref export); // NOTE // normally, a button would freeze GH canvas after a RunScript operation, while a Toggle would not; // this fix (use a pending variable) was suggested by Florian Frank here: // https://www.grasshopper3d.com/forum/topics/boolean-button-runscript if (!export && !pending) { return; } // as suggested by Rutten here: https://discourse.mcneel.com/t/rhino-command-export-in-c/63610/4 if (Rhino.RhinoDoc.ActiveDoc == null) { return; } if (!pending) { pending = true; return; } pending = false; // export options string presUn = PreserveUnits ? "Yes" : "No"; string vBound = ViewBound ? "Yes" : "No"; string cs = ColStyle ? "RGB" : "CMYK"; string solHatch = SolidHatch ? "Yes" : "No"; string ordLay = OrderLayers ? "Yes" : "No"; // Yes/No Yes/No RGB/CMYK Yes/No Yes/No string scriptOptions = " PreserveUnits=" + presUn + " ViewportBoundary=" + vBound + " Color=" + cs + " HatchesAsSolidFills=" + solHatch + " OrderLayers=" + ordLay; string scriptString = "-_Export " + '"' + path + name + ".ai" + '"' + scriptOptions + " _Enter"; Guid[] id = new Guid[C.Count]; string[] lay = Layer.ToArray(); Color[] col = LColor.ToArray(); // lists of effectively added layers List <int> addedLayers = new List <int>(); //Make new attribute to set name Rhino.DocObjects.ObjectAttributes att = new Rhino.DocObjects.ObjectAttributes(); if (!System.IO.Directory.Exists(path)) { System.IO.Directory.CreateDirectory(path); } Rhino.RhinoApp.RunScript("_SelNone", false); IEnumerator it = C.GetEnumerator(); int k = 0; int ind = 0; int cInd = 0; foreach (Curve curve in C) { //Set layer if (!string.IsNullOrEmpty(lay[ind]) && Rhino.DocObjects.Layer.IsValidName(lay[ind])) { //Get the current layer index Rhino.DocObjects.Tables.LayerTable layerTable = Rhino.RhinoDoc.ActiveDoc.Layers; //int layerIndex = layerTable.Find(lay[ind], true); int layerIndex = layerTable.FindByFullPath(lay[ind], -1); if (layerIndex < 0) //This layer does not exist, we add it { Rhino.DocObjects.Layer onlayer = new Rhino.DocObjects.Layer(); //Make a new layer onlayer.Name = lay[ind]; onlayer.Color = col[ind]; layerIndex = layerTable.Add(onlayer); //Add the layer to the layer table if (layerIndex > -1) //We managed to add layer! { att.LayerIndex = layerIndex; addedLayers.Add(layerIndex); // add index to the newly added layers list //Print("Added new layer to the document at position " + layerIndex + " named " + Layer + ". "); } //else //Print("Layer did not add. Try cleaning up your layers."); //This never happened to me. } else { att.LayerIndex = layerIndex; //We simply add to the existing layer } } // bake and select the object id[k] = Rhino.RhinoDoc.ActiveDoc.Objects.AddCurve(curve, att); Rhino.RhinoDoc.ActiveDoc.Objects.Select(id[k], true); // increment indexes k++; if (ind < lay.Length - 1) { ind++; } if (cInd < col.Length - 1) { cInd++; } } Rhino.RhinoApp.RunScript(scriptString, false); Rhino.RhinoApp.RunScript("_delete", false); // delete only the added layers Rhino.DocObjects.Tables.LayerTable layerTableNew = Rhino.RhinoDoc.ActiveDoc.Layers; foreach (int lInd in addedLayers) { layerTableNew.Delete(lInd, true); } }
protected override Result RunCommand(RhinoDoc doc, RunMode mode) { // Get a polyframe // Get a new point // Create the pipes and lines in the new location // the lines will be from an edge container of the PolyFrame // The pipes will be added extra. This will allow for the pipes to be used as a PolyFrame var primal = new PFoam(); var dual = new PFoam(); try { var guids = LoadData.LoadPrimalDual(out primal, out dual, out ContainerType container); if (primal.Cells.Count < 1) { Rhino.RhinoApp.WriteLine("Error loading PolyFrame from provided data!"); return(Result.Failure); } var form = primal.Edges.Where(e => e.Id > 0).Any(x => x.Faces.Count < 2); if (dual.Cells.Count < 1) { RhinoApp.WriteLine("Could not load dual from the selected PolyFrame."); return(Result.Failure); } double minLen; double maxLen; var pipePolyFrame = new PFoam(); if (form) { pipePolyFrame = primal; } else { pipePolyFrame = dual; } var edgeLengths = pipePolyFrame.Edges.Select(x => x.GetLength()); minLen = edgeLengths.Min(); maxLen = edgeLengths.Max(); //var medLen = edgeLengths.Average(); var gp = new Rhino.Input.Custom.GetPoint(); var minRadius = new Rhino.Input.Custom.OptionDouble(minLen / 10, true, double.Epsilon); var maxRadius = new Rhino.Input.Custom.OptionDouble(minLen / 2, true, double.Epsilon); gp.SetCommandPrompt("Place the Pipes. Hit <Enter> to replace Input"); gp.SetDefaultPoint(primal.Centroid); gp.AcceptPoint(true); gp.AddOptionDouble("MinRadius", ref minRadius); gp.AddOptionDouble("MaxRadius", ref maxRadius); while (true) { gp.Get(); if (gp.Result() == Rhino.Input.GetResult.Point) { break; } else if (gp.Result() == Rhino.Input.GetResult.Cancel) { return(Result.Failure); } } var moveVect = gp.Point() - pipePolyFrame.Centroid; pipePolyFrame.Offset(moveVect); if (gp.GotDefault()) { if (!form) { moveVect = primal.Centroid - dual.Centroid; } doc.Objects.Delete(guids, true); doc.Views.Redraw(); } var pipeLayer = new Rhino.DocObjects.Layer() { Name = "_Pipes" }; if (doc.Layers.All(x => x.Name != pipeLayer.Name)) { doc.Layers.Add(pipeLayer); } pipeLayer = doc.Layers.First(x => x.Name == "_Pipes"); var pipeCol = pipePolyFrame.PipeGeoDual(minRadius.CurrentValue, maxRadius.CurrentValue, pipePolyFrame.Edges.Select(x => x.Id).ToList()); var pipeGuids = new List <Guid>(); foreach (var pc in pipeCol) { var att = new Rhino.DocObjects.ObjectAttributes { LayerIndex = pipeLayer.Index, ObjectColor = pc.Item2, ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromObject }; pipeGuids.Add(doc.Objects.AddBrep(pc.Item1, att)); } doc.Groups.Add(pipePolyFrame.Id.ToString() + "_Pipes", pipeGuids); pipePolyFrame.SaveAsEdges(); doc.Views.Redraw(); } catch (PolyFrameworkException pfE) { RhinoApp.WriteLine(pfE.Message); primal.Hide(); dual.Hide(); return(Result.Failure); } return(Result.Success); }
public static void OptToRhino(OptFile opt, string rhinoPath, bool scale) { if (opt == null) { throw new ArgumentNullException("opt"); } string rhinoDirectory = Path.GetDirectoryName(rhinoPath); string rhinoName = Path.GetFileNameWithoutExtension(rhinoPath); var distances = opt.Meshes .SelectMany(t => t.Lods) .Select(t => t.Distance) .Distinct() .OrderByDescending(t => t) .ToArray(); for (int distance = 0; distance < distances.Length; distance++) { using (var file = new Rhino.FileIO.File3dm()) { file.Settings.ModelUnitSystem = Rhino.UnitSystem.Meters; int objectsIndex = 0; List<string> textureNames = new List<string>(); foreach (var mesh in opt.Meshes) { var lod = mesh.Lods.FirstOrDefault(t => t.Distance <= distances[distance]); if (lod == null) { continue; } foreach (var textureName in lod.FaceGroups .Where(t => t.Textures.Count > 0) .Select(t => t.Textures[0])) { if (!textureNames.Contains(textureName)) { textureNames.Add(textureName); } } string meshName = string.Format(CultureInfo.InvariantCulture, "{0}.{1:D3}", mesh.Descriptor.MeshType, objectsIndex); using (var layer = new Rhino.DocObjects.Layer()) { layer.Name = meshName; file.Layers.Add(layer); } foreach (var faceGroup in lod.FaceGroups) { using (var rhinoMesh = new Rhino.Geometry.Mesh()) using (var rhinoAttributes = new Rhino.DocObjects.ObjectAttributes()) { rhinoAttributes.Name = meshName; rhinoAttributes.LayerIndex = objectsIndex; if (faceGroup.Textures.Count > 0) { rhinoAttributes.MaterialIndex = textureNames.IndexOf(faceGroup.Textures[0]); } Action<Vector> addVertex; if (scale) { addVertex = vertex => rhinoMesh.Vertices.Add(vertex.X * OptFile.ScaleFactor, vertex.Y * OptFile.ScaleFactor, vertex.Z * OptFile.ScaleFactor); } else { addVertex = vertex => rhinoMesh.Vertices.Add(vertex.X, vertex.Y, vertex.Z); } Action<TextureCoordinates> addTexCoords = texCoords => rhinoMesh.TextureCoordinates.Add(texCoords.U, -texCoords.V); Action<Vector> addNormal = normal => rhinoMesh.Normals.Add(normal.X, normal.Y, normal.Z); int facesIndex = 0; foreach (var face in faceGroup.Faces) { var verticesIndex = face.VerticesIndex; var texCoordsIndex = face.TextureCoordinatesIndex; var normalsIndex = face.VertexNormalsIndex; addVertex(mesh.Vertices[verticesIndex.A]); addTexCoords(mesh.TextureCoordinates[texCoordsIndex.A]); addNormal(mesh.VertexNormals[normalsIndex.A]); facesIndex++; addVertex(mesh.Vertices[verticesIndex.B]); addTexCoords(mesh.TextureCoordinates[texCoordsIndex.B]); addNormal(mesh.VertexNormals[normalsIndex.B]); facesIndex++; addVertex(mesh.Vertices[verticesIndex.C]); addTexCoords(mesh.TextureCoordinates[texCoordsIndex.C]); addNormal(mesh.VertexNormals[normalsIndex.C]); facesIndex++; if (verticesIndex.D >= 0) { addVertex(mesh.Vertices[verticesIndex.D]); addTexCoords(mesh.TextureCoordinates[texCoordsIndex.D]); addNormal(mesh.VertexNormals[normalsIndex.D]); facesIndex++; } if (verticesIndex.D < 0) { rhinoMesh.Faces.AddFace(facesIndex - 1, facesIndex - 2, facesIndex - 3); } else { rhinoMesh.Faces.AddFace(facesIndex - 1, facesIndex - 2, facesIndex - 3, facesIndex - 4); } } rhinoMesh.Compact(); file.Objects.AddMesh(rhinoMesh, rhinoAttributes); } } objectsIndex++; } foreach (var textureName in textureNames) { Texture texture; opt.Textures.TryGetValue(textureName, out texture); using (var material = new Rhino.DocObjects.Material()) { material.Name = textureName; if (texture == null) { material.DiffuseColor = System.Drawing.Color.White; } else { texture.Save(Path.Combine(rhinoDirectory, textureName + ".png")); material.SetBitmapTexture(textureName + ".png"); if (texture.HasAlpha) { texture.SaveAlphaMap(Path.Combine(rhinoDirectory, textureName + "_alpha.png")); material.SetTransparencyTexture(textureName + "_alpha.png"); } } file.Materials.Add(material); } } file.Write(Path.Combine(rhinoDirectory, string.Format(CultureInfo.InvariantCulture, "{0}_{1}.3dm", rhinoName, distance)), 4); } } }
/// <summary> /// Saves the foam as a group of color-coded lines in the Rhino document /// For each line a user dictionary is saved with the following entries: /// EdgeId, StartVertexId, EndVertexId /// The first line contains a JSON serialization for the whole foam + /// If available the dual will also be saved /// </summary> public IList <Guid> SaveAsEdges() { // first determine if form or force // if foam has naked edges then it is form else it is force var doc = Rhino.RhinoDoc.ActiveDoc; doc.Views.RedrawEnabled = false; var form = Edges.Where(e => e.Id > 0).Any(x => x.Faces.Count < 2); var positiveEdges = Edges.Where(x => x.Id > 0); var edgeUserDict = new Dictionary <int, Dictionary <string, int> >(); bool foamSaved = false; var guids = new List <Guid>(); string primal = SerializeJson(); string dual = Dual?.SerializeJson() ?? ""; // pre-make the data for the user dictionary for each edge foreach (var edge in positiveEdges) { var edgeDict = new Dictionary <string, int>(); edgeDict.Add("Id", edge.Id); edgeDict.Add("V0", edge.Vertices[0].Id); edgeDict.Add("V1", edge.Vertices[1].Id); edgeUserDict.Add(edge.Id, edgeDict); } // handling different behaviors for form and force if (form) { var intEdges = new List <PFEdge>(); var halfExtEdges = new List <PFEdge>(); var fullExtEdges = new List <PFEdge>(); foreach (var edge in positiveEdges) { if (edge.Id > 0) { if (edge.Vertices[0].External && edge.Vertices[1].External) { fullExtEdges.Add(edge); } else if (edge.Vertices[0].External ^ edge.Vertices[1].External) { halfExtEdges.Add(edge); } else { intEdges.Add(edge); } } } var areas = intEdges.Select(x => x.Dual?.Area ?? 0.0); var maxArea = areas.Count() > 0 ? areas.Max() : 1.0; var minArea = areas.Count() > 0 ? areas.Min() : 0.0; // create all layers var intLineLayer = new Rhino.DocObjects.Layer() { Name = "_Form_InternalLines" }; if (doc.Layers.All(x => x.Name != intLineLayer.Name)) { doc.Layers.Add(intLineLayer); } intLineLayer = doc.Layers.First(x => x.Name == "_Form_InternalLines"); var extForceLayer = new Rhino.DocObjects.Layer() { Name = "_Form_ExternalForces" }; if (doc.Layers.All(x => x.Name != extForceLayer.Name)) { doc.Layers.Add(extForceLayer); } extForceLayer = doc.Layers.First(x => x.Name == "_Form_ExternalForces"); var externalPolyLayer = new Rhino.DocObjects.Layer() { Name = "_Form_ExternalPoly" }; if (doc.Layers.All(x => x.Name != externalPolyLayer.Name)) { doc.Layers.Add(externalPolyLayer); } externalPolyLayer = doc.Layers.First(x => x.Name == "_Form_ExternalPoly"); // handle the interior edges foreach (var edge in intEdges) { var attributes = new Rhino.DocObjects.ObjectAttributes { ObjectColor = Util.CreateBlue(Util.ValueUnitizer(edge.Dual?.Area ?? 1.0, new List <double> { minArea, maxArea }, new List <double> { 0.0, 1.0 })), PlotWeight = Math.Round(Util.ValueUnitizer(edge.Dual?.Area ?? 1.0, new List <double> { minArea, maxArea }, new List <double> { 0, 11 }) * 0.05 + 0.15), ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromObject, Name = edge.Id.ToString(), LayerIndex = intLineLayer.LayerIndex, }; var lineCrv = edge.CreateLine().ToNurbsCurve(); foreach (var keyVal in edgeUserDict[edge.Id]) { lineCrv.UserDictionary.Set(keyVal.Key, keyVal.Value); } // the foam will be serialized with the first interior edge // this will include the dual if present if (!foamSaved) { lineCrv.UserDictionary.Set("Primal", primal); lineCrv.UserDictionary.Set("Dual", dual); foamSaved = true; } guids.Add(doc.Objects.AddCurve(lineCrv, attributes)); } // handle applied forces - or half ext edges foreach (var edge in halfExtEdges) { var attributes = new Rhino.DocObjects.ObjectAttributes { ObjectColor = System.Drawing.Color.FromArgb(0, 100, 0), ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromObject, Name = edge.Id.ToString(), LayerIndex = extForceLayer.LayerIndex, }; if (edge.Vertices[1].External) { attributes.ObjectDecoration = Rhino.DocObjects.ObjectDecoration.StartArrowhead; } else { attributes.ObjectDecoration = Rhino.DocObjects.ObjectDecoration.EndArrowhead; } var lineCrv = edge.CreateLine().ToNurbsCurve(); foreach (var keyVal in edgeUserDict[edge.Id]) { lineCrv.UserDictionary.Set(keyVal.Key, keyVal.Value); } if (!foamSaved) { lineCrv.UserDictionary.Set("Primal", primal); lineCrv.UserDictionary.Set("Dual", dual); foamSaved = true; } guids.Add(doc.Objects.AddCurve(lineCrv, attributes)); } // handle external polyhedron or full external edges foreach (var edge in fullExtEdges) { var attributes = new Rhino.DocObjects.ObjectAttributes { ObjectColor = System.Drawing.Color.LightGray, ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromObject, Name = edge.Id.ToString(), LayerIndex = externalPolyLayer.LayerIndex, }; var lineCrv = edge.CreateLine().ToNurbsCurve(); foreach (var keyVal in edgeUserDict[edge.Id]) { lineCrv.UserDictionary.Set(keyVal.Key, keyVal.Value); } guids.Add(doc.Objects.AddCurve(lineCrv, attributes)); } } else { var forceLineLayer = new Rhino.DocObjects.Layer() { Name = "_Force_Lines" }; if (doc.Layers.All(x => x.Name != forceLineLayer.Name)) { doc.Layers.Add(forceLineLayer); } forceLineLayer = doc.Layers.First(x => x.Name == "_Force_Lines"); foreach (var edge in positiveEdges) { var attributes = new Rhino.DocObjects.ObjectAttributes { ObjectColor = System.Drawing.Color.DarkSlateGray, ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromObject, Name = edge.Id.ToString(), LayerIndex = forceLineLayer.LayerIndex, }; var lineCrv = edge.CreateLine().ToNurbsCurve(); foreach (var keyVal in edgeUserDict[edge.Id]) { lineCrv.UserDictionary.Set(keyVal.Key, keyVal.Value); } // the foam will be serialized with the first interior edge // this will include the dual if present if (!foamSaved) { lineCrv.UserDictionary.Set("Primal", primal); lineCrv.UserDictionary.Set("Dual", dual); foamSaved = true; } guids.Add(doc.Objects.AddCurve(lineCrv, attributes)); } } doc.Views.RedrawEnabled = true; doc.Groups.Add(Id.ToString(), guids); return(guids); }
/// <summary> /// Saves the foam object as a set of trimmed surfaces (one faced breps) /// For each brep it saves an entry in the user dictionary with the faceId /// For each vertex in the brep as Point an entry in the user dictionary is saved with the PFvertex Id /// </summary> /// <returns></returns> public IList <Guid> SaveAsFaces(bool asMesh = false) { // first determine if form or force // if foam has naked edges then it is form else it is force var doc = Rhino.RhinoDoc.ActiveDoc; doc.Views.RedrawEnabled = false; var form = Edges.Where(e => e.Id > 0).Any(x => x.Faces.Count < 2); var positiveFaces = Faces.Where(x => x.Id > 0); //var faceUserDict = new Dictionary<int, List<int>>(); bool foamSaved = false; var guids = new List <Guid>(); string primal = SerializeJson(); string dual = Dual?.SerializeJson() ?? ""; if (form) { // if the foam is a form then just save everything with the same color // except the exterior faces (applied forces and supports that will be printed with a different color var intFaces = new List <PFFace>(); var extFaces = new List <PFFace>(); foreach (var face in positiveFaces) { if (face.External) { extFaces.Add(face); } else { intFaces.Add(face); } } var intFaceLayer = new Rhino.DocObjects.Layer() { Name = "_Form_InternalFaces" }; if (doc.Layers.All(x => x.Name != intFaceLayer.Name)) { doc.Layers.Add(intFaceLayer); } intFaceLayer = doc.Layers.First(x => x.Name == "_Form_InternalFaces"); var extFaceLayer = new Rhino.DocObjects.Layer() { Name = "_Form_ExternalFaces" }; if (doc.Layers.All(x => x.Name != extFaceLayer.Name)) { doc.Layers.Add(extFaceLayer); } extFaceLayer = doc.Layers.First(x => x.Name == "_Form_ExternalFaces"); // go through internal faces foreach (var face in intFaces) { var attributes = new Rhino.DocObjects.ObjectAttributes { ObjectColor = System.Drawing.Color.SlateGray, ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromObject, Name = face.Id.ToString(), LayerIndex = intFaceLayer.LayerIndex, }; GeometryBase faceGeo; if (!asMesh) { faceGeo = face.CreateBrepMatched(); } else { faceGeo = face.FMesh; } // the foam will be serialized with the first interior face // this will include the dual if present if (!foamSaved) { faceGeo.UserDictionary.Set("Primal", primal); faceGeo.UserDictionary.Set("Dual", dual); foamSaved = true; } guids.Add(doc.Objects.Add(faceGeo, attributes)); } // go through the ext faces foreach (var face in extFaces) { var attributes = new Rhino.DocObjects.ObjectAttributes { ObjectColor = System.Drawing.Color.LightSlateGray, ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromObject, Name = face.Id.ToString(), LayerIndex = extFaceLayer.LayerIndex, }; GeometryBase faceGeo; if (!asMesh) { faceGeo = face.CreateBrepMatched(); } else { faceGeo = face.FMesh; } if (!foamSaved) { faceGeo.UserDictionary.Set("Primal", primal); faceGeo.UserDictionary.Set("Dual", dual); foamSaved = true; } guids.Add(doc.Objects.Add(faceGeo, attributes)); } } else // if force { var maxArea = Faces.Select(x => x.Area).Max(); var minArea = Faces.Select(x => x.Area).Min(); var forceFaceLayer = new Rhino.DocObjects.Layer() { Name = "_Force_Faces" }; if (doc.Layers.All(x => x.Name != forceFaceLayer.Name)) { doc.Layers.Add(forceFaceLayer); } forceFaceLayer = doc.Layers.First(x => x.Name == "_Force_Faces"); foreach (var face in positiveFaces) { var attributes = new Rhino.DocObjects.ObjectAttributes { ObjectColor = Util.CreateBlue(Util.ValueUnitizer(face.Area, new List <double> { minArea, maxArea }, new List <double> { 0.0, 1.0 })), ColorSource = Rhino.DocObjects.ObjectColorSource.ColorFromObject, Name = face.Id.ToString(), LayerIndex = forceFaceLayer.LayerIndex, }; GeometryBase faceGeo; if (!asMesh) { faceGeo = face.CreateBrepMatched(); } else { faceGeo = face.FMesh; } // the foam will be serialized with the first interior face // this will include the dual if present if (!foamSaved) { faceGeo.UserDictionary.Set("Primal", primal); faceGeo.UserDictionary.Set("Dual", dual); foamSaved = true; } guids.Add(doc.Objects.Add(faceGeo, attributes)); } } doc.Views.RedrawEnabled = true; doc.Groups.Add(Id.ToString(), guids); return(guids); }
private void BakeStoredObjects(Rhino.RhinoDoc rhdoc) { // do we need to add layers? int parent_index = rhdoc.Layers.Find(parent_layer_name, true); if (parent_index < 0) { parent_index = rhdoc.Layers.Add(parent_layer_name, Color.White); } Dictionary <string, int> layer_dict = new Dictionary <string, int>(); if (rhdoc.Layers[parent_index].GetChildren() != null) { foreach (Rhino.DocObjects.Layer l in rhdoc.Layers[parent_index].GetChildren()) { layer_dict.Add(l.Name, l.LayerIndex); } } foreach (string layername in required_layers) { if (!layer_dict.ContainsKey(layername)) { Rhino.DocObjects.Layer childlayer = new Rhino.DocObjects.Layer(); childlayer.ParentLayerId = rhdoc.Layers[parent_index].Id; childlayer.Name = layername; int index = rhdoc.Layers.Add(childlayer); if (index < 0) { AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Layer creation gone bad!"); } layer_dict.Add(layername, index); } } int group_index = -1; List <Guid> guids = new List <Guid>(); int current_branch_index = -1; for (int n = 0; n < m_obj.Count; n++) { if (m_branch_index[n] != current_branch_index) { group_index = rhdoc.Groups.Add(); current_branch_index = m_branch_index[n]; } object obj = m_obj[n]; Rhino.DocObjects.ObjectAttributes att = m_att[n].Value; att.LayerIndex = layer_dict[m_att[n].layer]; if (obj == null) { continue; } Guid id = new Guid(); Type objectType = obj.GetType(); if (objectType == typeof(Grasshopper.Kernel.Types.GH_Vector)) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Vectors are confusing things to bake - I'll just make a point at the vector position. If you want to visualize a 'positioned' vector, try giving me a Ray instead."); } if (obj is Grasshopper.Kernel.IGH_BakeAwareData) { Grasshopper.Kernel.IGH_BakeAwareData bakedata = (Grasshopper.Kernel.IGH_BakeAwareData)obj; bakedata.BakeGeometry(rhdoc, att, out id); rhdoc.Groups.AddToGroup(group_index, id); if (guids != null) { guids.Add(id); } // draw fill meshes for closed planar curves if (objectType == typeof(Grasshopper.Kernel.Types.GH_Curve)) { Rhino.Geometry.Curve rh_curve = ((Grasshopper.Kernel.Types.GH_Curve)obj).Value; if ((rh_curve.IsClosed) && (rh_curve.IsPlanar())) { Rhino.Geometry.Intersect.CurveIntersections iev = Rhino.Geometry.Intersect.Intersection.CurveSelf(rh_curve, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance); if (iev.Count == 0) { Rhino.Geometry.Mesh mesh = Rhino.Geometry.Mesh.CreateFromPlanarBoundary(rh_curve, Rhino.Geometry.MeshingParameters.Smooth); Grasshopper.Kernel.IGH_BakeAwareData meshbakedata = (Grasshopper.Kernel.IGH_BakeAwareData) new Grasshopper.Kernel.Types.GH_Mesh(mesh); att.PlotWeight = 0.0; meshbakedata.BakeGeometry(rhdoc, att, out id); rhdoc.Groups.AddToGroup(group_index, id); if (guids != null) { guids.Add(id); } } } } continue; } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The component does not know how to handle this type of gh_geometry: " + objectType.FullName); continue; } //if (groupIndex != -1) doc.Groups.AddToGroup(groupIndex, id); } rhdoc.Views.Redraw(); }
private void BakeStoredObjects(Rhino.RhinoDoc rhdoc) { // do we need to add layers? int parent_index = rhdoc.Layers.Find(parent_layer_name, true); if (parent_index < 0) parent_index = rhdoc.Layers.Add(parent_layer_name, Color.White); Dictionary<string, int> layer_dict = new Dictionary<string, int>(); if (rhdoc.Layers[parent_index].GetChildren() != null) foreach (Rhino.DocObjects.Layer l in rhdoc.Layers[parent_index].GetChildren()) layer_dict.Add(l.Name, l.LayerIndex); foreach (string layername in required_layers) if (!layer_dict.ContainsKey(layername)) { Rhino.DocObjects.Layer childlayer = new Rhino.DocObjects.Layer(); childlayer.ParentLayerId = rhdoc.Layers[parent_index].Id; childlayer.Name = layername; int index = rhdoc.Layers.Add(childlayer); if (index < 0) AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Layer creation gone bad!"); layer_dict.Add(layername, index); } int group_index = -1; List<Guid> guids = new List<Guid>(); int current_branch_index = -1; for (int n = 0; n < m_obj.Count; n++) { if (m_branch_index[n] != current_branch_index) { group_index = rhdoc.Groups.Add(); current_branch_index = m_branch_index[n]; } object obj = m_obj[n]; Rhino.DocObjects.ObjectAttributes att = m_att[n].Value; att.LayerIndex = layer_dict[m_att[n].layer]; if (obj == null) continue; Guid id = new Guid(); Type objectType = obj.GetType(); if (objectType == typeof(Grasshopper.Kernel.Types.GH_Vector)) { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "Vectors are confusing things to bake - I'll just make a point at the vector position. If you want to visualize a 'positioned' vector, try giving me a Ray instead."); } if (obj is Grasshopper.Kernel.IGH_BakeAwareData) { Grasshopper.Kernel.IGH_BakeAwareData bakedata = (Grasshopper.Kernel.IGH_BakeAwareData)obj; bakedata.BakeGeometry(rhdoc, att, out id); rhdoc.Groups.AddToGroup(group_index, id); if (guids != null) guids.Add(id); // draw fill meshes for closed planar curves if (objectType == typeof(Grasshopper.Kernel.Types.GH_Curve)) { Rhino.Geometry.Curve rh_curve = ((Grasshopper.Kernel.Types.GH_Curve)obj).Value; if ((rh_curve.IsClosed) && (rh_curve.IsPlanar())) { Rhino.Geometry.Intersect.CurveIntersections iev = Rhino.Geometry.Intersect.Intersection.CurveSelf(rh_curve, Rhino.RhinoDoc.ActiveDoc.ModelAbsoluteTolerance); if (iev.Count == 0){ Rhino.Geometry.Mesh mesh = Rhino.Geometry.Mesh.CreateFromPlanarBoundary(rh_curve, Rhino.Geometry.MeshingParameters.Smooth); Grasshopper.Kernel.IGH_BakeAwareData meshbakedata = (Grasshopper.Kernel.IGH_BakeAwareData) new Grasshopper.Kernel.Types.GH_Mesh(mesh); att.PlotWeight = 0.0; meshbakedata.BakeGeometry(rhdoc, att, out id); rhdoc.Groups.AddToGroup(group_index, id); if (guids != null) guids.Add(id); } } } continue; } else { AddRuntimeMessage(GH_RuntimeMessageLevel.Warning, "The component does not know how to handle this type of gh_geometry: " + objectType.FullName); continue; } //if (groupIndex != -1) doc.Groups.AddToGroup(groupIndex, id); } rhdoc.Views.Redraw(); }
public static void curves(int state, Rhino.DocObjects.RhinoObject geo) { //Verify geometery is being added, not transformed. string G00_Path = utils.file_structure.getPathFor("G00"); int verifyState = Convert.ToInt32(System.IO.File.ReadAllText(G00_Path)); if (verifyState == 3) { state = 3; } else { System.IO.File.WriteAllText(G00_Path, state.ToString()); } //Grab reference point from docBox. Rhino.Geometry.Point3d refPoint = utils.properties.getRefPoint(); double refPointX = refPoint.X; double refPointY = refPoint.Y; //Determine and sanitize cache file for new geometry. string G10_Path = utils.file_structure.getPathFor("G10"); if (System.IO.File.Exists(G10_Path) == false) { System.IO.File.WriteAllText(G10_Path, ""); //System.Threading.Thread.Sleep(500); } //Parse curve geometry from RhinoObject. Guid incomingGuid = geo.Id; Rhino.Geometry.Curve newCurve = null; int layerIndex = geo.Attributes.LayerIndex; Rhino.DocObjects.Layer incomingLayer = Rhino.RhinoDoc.ActiveDoc.Layers[layerIndex]; string incomingLayerName = incomingLayer.Name; Rhino.DocObjects.ObjRef oRef = new Rhino.DocObjects.ObjRef(incomingGuid); //Verify object is a curve, otherwise quit. if (oRef.Geometry().ObjectType.ToString().ToLower().Contains("curve")) { newCurve = oRef.Curve(); } else { //System.IO.File.AppendAllText(G10_Path, "X|" + Environment.NewLine); return; } //Run curve geometry through the coin sorter. //All data is cached in the same file, but keyed at the beginning by type. //0 - linear curve //1 - linear polyline //2 - arc //3 - circle //4 - ellipse //5 - arbitrary curve //6 - complex polycurve //New type key: //0 - linear curve //1 - linear polyline //2 - any non-linear curve if (newCurve.Degree == 1) { if (newCurve.SpanCount == 1) { //Treat as linear curve. //utils.debug.ping(0, "Linear curve added!"); Rhino.Geometry.Point3d startPoint = newCurve.PointAtStart; Rhino.Geometry.Point3d endPoint = newCurve.PointAtEnd; string x1 = (startPoint.X - refPointX).ToString(); string y1 = (startPoint.Y - refPointY).ToString(); string x2 = (endPoint.X - refPointX).ToString(); string y2 = (endPoint.Y - refPointY).ToString(); //utils.debug.alert(G10_Path); //utils.debug.alert(incomingGuid.ToString()); //utils.debug.alert(incomingLayerName); try { System.IO.File.AppendAllText(G10_Path, "0|" + incomingGuid.ToString() + "|" + incomingLayerName + "|1|" + x1 + "," + y1 + "," + x2 + "," + y2 + Environment.NewLine); } catch (Exception e) { utils.debug.alert(e.ToString()); } //utils.debug.alert("Pausing!!"); } else if (newCurve.SpanCount > 1) { //Treat as linear polyline. //utils.debug.ping(0, "Linear polyline added!"); List <string> coords = new List <string>(); int spanCount = newCurve.SpanCount; for (int i = 0; i < spanCount; i++) { double activeParameter = newCurve.SpanDomain(i).Min; Rhino.Geometry.Point3d activePoint = newCurve.PointAt(activeParameter); double activeX = activePoint.X - refPointX; coords.Add(activeX.ToString()); double activeY = activePoint.Y - refPointY; coords.Add(activeY.ToString()); if (i == spanCount - 1) { //On reaching final span, also record endpoint. double finalParameter = newCurve.SpanDomain(i).Max; Rhino.Geometry.Point3d finalPoint = newCurve.PointAt(finalParameter); double finalX = finalPoint.X - refPointX; coords.Add(finalX.ToString()); double finalY = finalPoint.Y - refPointY; coords.Add(finalY.ToString()); } } string coordInfo = string.Join(",", coords); System.IO.File.AppendAllText(G10_Path, "1|" + incomingGuid.ToString() + "|" + incomingLayerName + "|" + newCurve.SpanCount.ToString() + "|" + coordInfo + Environment.NewLine); } } else if (newCurve.Degree > 1) { //Generate degree 3 approximation of incoming curve. (Low tolerance makes it more than "good enough") Rhino.Geometry.BezierCurve[] bCurveSpans = Rhino.Geometry.BezierCurve.CreateCubicBeziers(newCurve, 0.01, 0.01); int bCurveCount = bCurveSpans.Length; List <string> bPointData = new List <string>(); List <double> bPointCache = new List <double>(); //Cache point info. for (int i = 0; i < bCurveCount; i++) { //Starting point caching process. if (i == 0) { //Parse anchor point data. Rhino.Geometry.Point3d activeAnchor = bCurveSpans[i].GetControlVertex3d(0); double activeAnchorX = activeAnchor.X - refPointX; double activeAnchorY = activeAnchor.Y - refPointY; bPointCache.Add(activeAnchorX); bPointCache.Add(activeAnchorY); //Parse left direction data. For starting point, this is the same as the anchor. bPointCache.Add(activeAnchorX); bPointCache.Add(activeAnchorY); //Parse right direction data. Rhino.Geometry.Point3d activeRightDirection = bCurveSpans[i].GetControlVertex3d(1); double activeRightDirectionX = activeRightDirection.X - refPointX; double activeRightDirectionY = activeRightDirection.Y - refPointY; bPointCache.Add(activeRightDirectionX); bPointCache.Add(activeRightDirectionY); //Push packaged point data to final list. string bPoint = string.Join(":", bPointCache); bPointData.Add(bPoint); bPointCache.Clear(); } //Intermediate point caching process. else { //Parse anchor point data. Rhino.Geometry.Point3d activeAnchor = bCurveSpans[i].GetControlVertex3d(0); double activeAnchorX = activeAnchor.X - refPointX; double activeAnchorY = activeAnchor.Y - refPointY; bPointCache.Add(activeAnchorX); bPointCache.Add(activeAnchorY); //Parse left direction data. Rhino.Geometry.Point3d activeLeftDirection = bCurveSpans[i - 1].GetControlVertex3d(2); double activeLeftDirectionX = activeLeftDirection.X - refPointX; double activeLeftDirectionY = activeLeftDirection.Y - refPointY; bPointCache.Add(activeLeftDirectionX); bPointCache.Add(activeLeftDirectionY); //Parse right direction data. Rhino.Geometry.Point3d activeRightDirection = bCurveSpans[i].GetControlVertex3d(1); double activeRightDirectionX = activeRightDirection.X - refPointX; double activeRightDirectionY = activeRightDirection.Y - refPointY; bPointCache.Add(activeRightDirectionX); bPointCache.Add(activeRightDirectionY); //Push packaged point data to final list. string bPoint = string.Join(":", bPointCache); bPointData.Add(bPoint); bPointCache.Clear(); } } //Cache endpoint info after loop finishes. //Parse anchor point data. Rhino.Geometry.Point3d lastActiveAnchor = bCurveSpans[bCurveCount - 1].GetControlVertex3d(3); double lastActiveAnchorX = lastActiveAnchor.X - refPointX; double lastActiveAnchorY = lastActiveAnchor.Y - refPointY; bPointCache.Add(lastActiveAnchorX); bPointCache.Add(lastActiveAnchorY); //Parse left direction data. Rhino.Geometry.Point3d lastActiveLeftDirection = bCurveSpans[bCurveCount - 1].GetControlVertex3d(2); double lastActiveLeftDirectionX = lastActiveLeftDirection.X - refPointX; double lastActiveLeftDirectionY = lastActiveLeftDirection.Y - refPointY; bPointCache.Add(lastActiveLeftDirectionX); bPointCache.Add(lastActiveLeftDirectionY); //Parse right direction data. For the ending point, this is the same as the anchor. bPointCache.Add(lastActiveAnchorX); bPointCache.Add(lastActiveAnchorY); //Push packaged point data to final list. string lastBPoint = string.Join(":", bPointCache); bPointData.Add(lastBPoint); bPointCache.Clear(); //Finalize and record data. string coordInfo = string.Join(";", bPointData); System.IO.File.AppendAllText(G10_Path, "2|" + incomingGuid.ToString() + "|" + incomingLayerName + "|" + newCurve.SpanCount.ToString() + "|" + coordInfo + Environment.NewLine); } }
public static void OptToRhino(OptFile opt, string rhinoPath, bool scale) { if (opt == null) { throw new ArgumentNullException("opt"); } string rhinoDirectory = Path.GetDirectoryName(rhinoPath); string rhinoName = Path.GetFileNameWithoutExtension(rhinoPath); var distances = opt.Meshes .SelectMany(t => t.Lods) .Select(t => t.Distance) .Distinct() .OrderByDescending(t => t) .ToArray(); for (int distance = 0; distance < distances.Length; distance++) { using (var file = new Rhino.FileIO.File3dm()) { file.Settings.ModelUnitSystem = Rhino.UnitSystem.Meters; int objectsIndex = 0; List <string> textureNames = new List <string>(); foreach (var mesh in opt.Meshes) { var lod = mesh.Lods.FirstOrDefault(t => t.Distance <= distances[distance]); if (lod == null) { continue; } foreach (var textureName in lod.FaceGroups .Where(t => t.Textures.Count > 0) .Select(t => t.Textures[0])) { if (!textureNames.Contains(textureName)) { textureNames.Add(textureName); } } string meshName = string.Format(CultureInfo.InvariantCulture, "{0}.{1:D3}", mesh.Descriptor.MeshType, objectsIndex); using (var layer = new Rhino.DocObjects.Layer()) { layer.Name = meshName; file.Layers.Add(layer); } foreach (var faceGroup in lod.FaceGroups) { using (var rhinoMesh = new Rhino.Geometry.Mesh()) using (var rhinoAttributes = new Rhino.DocObjects.ObjectAttributes()) { rhinoAttributes.Name = meshName; rhinoAttributes.LayerIndex = objectsIndex; if (faceGroup.Textures.Count > 0) { rhinoAttributes.MaterialIndex = textureNames.IndexOf(faceGroup.Textures[0]); } Action <Vector> addVertex; if (scale) { addVertex = vertex => rhinoMesh.Vertices.Add(vertex.X * OptFile.ScaleFactor, vertex.Y * OptFile.ScaleFactor, vertex.Z * OptFile.ScaleFactor); } else { addVertex = vertex => rhinoMesh.Vertices.Add(vertex.X, vertex.Y, vertex.Z); } Action <TextureCoordinates> addTexCoords = texCoords => rhinoMesh.TextureCoordinates.Add(texCoords.U, -texCoords.V); Action <Vector> addNormal = normal => rhinoMesh.Normals.Add(normal.X, normal.Y, normal.Z); int facesIndex = 0; foreach (var face in faceGroup.Faces) { var verticesIndex = face.VerticesIndex; var texCoordsIndex = face.TextureCoordinatesIndex; var normalsIndex = face.VertexNormalsIndex; addVertex(mesh.Vertices[verticesIndex.A]); addTexCoords(mesh.TextureCoordinates[texCoordsIndex.A]); addNormal(mesh.VertexNormals[normalsIndex.A]); facesIndex++; addVertex(mesh.Vertices[verticesIndex.B]); addTexCoords(mesh.TextureCoordinates[texCoordsIndex.B]); addNormal(mesh.VertexNormals[normalsIndex.B]); facesIndex++; addVertex(mesh.Vertices[verticesIndex.C]); addTexCoords(mesh.TextureCoordinates[texCoordsIndex.C]); addNormal(mesh.VertexNormals[normalsIndex.C]); facesIndex++; if (verticesIndex.D >= 0) { addVertex(mesh.Vertices[verticesIndex.D]); addTexCoords(mesh.TextureCoordinates[texCoordsIndex.D]); addNormal(mesh.VertexNormals[normalsIndex.D]); facesIndex++; } if (verticesIndex.D < 0) { rhinoMesh.Faces.AddFace(facesIndex - 1, facesIndex - 2, facesIndex - 3); } else { rhinoMesh.Faces.AddFace(facesIndex - 1, facesIndex - 2, facesIndex - 3, facesIndex - 4); } } rhinoMesh.Compact(); file.Objects.AddMesh(rhinoMesh, rhinoAttributes); } } objectsIndex++; } foreach (var textureName in textureNames) { Texture texture; opt.Textures.TryGetValue(textureName, out texture); using (var material = new Rhino.DocObjects.Material()) { material.Name = textureName; if (texture == null) { material.DiffuseColor = System.Drawing.Color.White; } else { texture.Save(Path.Combine(rhinoDirectory, textureName + ".png")); material.SetBitmapTexture(textureName + ".png"); if (texture.HasAlpha) { texture.SaveAlphaMap(Path.Combine(rhinoDirectory, textureName + "_alpha.png")); material.SetTransparencyTexture(textureName + "_alpha.png"); } } file.Materials.Add(material); } } file.Write(Path.Combine(rhinoDirectory, string.Format(CultureInfo.InvariantCulture, "{0}_{1}.3dm", rhinoName, distance)), 4); } } }