├── LICENSE
├── lib
├── InstantMeshes.exe
└── InstantMeshes LICENSE.txt
├── Resources
└── InstantMeshes.ico
├── Properties
└── AssemblyInfo.cs
├── InstantMeshesInfo.cs
├── InstantMeshes.sln
├── README.md
├── InstantMeshes.csproj
├── FileObj.cs
└── InstantMeshesComponent.cs
/LICENSE:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dalefugier/InstantMeshes/HEAD/LICENSE
--------------------------------------------------------------------------------
/lib/InstantMeshes.exe:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dalefugier/InstantMeshes/HEAD/lib/InstantMeshes.exe
--------------------------------------------------------------------------------
/Resources/InstantMeshes.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/dalefugier/InstantMeshes/HEAD/Resources/InstantMeshes.ico
--------------------------------------------------------------------------------
/Properties/AssemblyInfo.cs:
--------------------------------------------------------------------------------
1 | using System.Reflection;
2 | using System.Runtime.InteropServices;
3 |
4 | [assembly: AssemblyTrademark("")]
5 | [assembly: AssemblyCulture("")]
6 | [assembly: ComVisible(false)]
7 | [assembly: Guid("416e37e9-85bf-439c-992f-6bac1ab72ebe")]
8 |
--------------------------------------------------------------------------------
/InstantMeshesInfo.cs:
--------------------------------------------------------------------------------
1 | using Grasshopper.Kernel;
2 | using System;
3 | using System.Drawing;
4 | using System.Reflection;
5 |
6 | namespace InstantMeshes
7 | {
8 | public class InstantMeshesInfo : GH_AssemblyInfo
9 | {
10 | public override string Name => "InstantMeshes";
11 | public override Bitmap Icon
12 | {
13 | get
14 | {
15 | const string resource = "InstantMeshes.Resources.InstantMeshes.ico";
16 | Size size = new Size(24, 24);
17 | Assembly assembly = Assembly.GetExecutingAssembly();
18 | Icon icon = Rhino.UI.DrawingUtilities.IconFromResource(resource, size, assembly);
19 | return icon.ToBitmap();
20 | }
21 | }
22 | public override string Description => "Field-aligned mesh generator for Grasshopper®";
23 | public override Guid Id => new Guid("06cbea6f-9c7a-46e1-b0e2-fc0f114ecfd0");
24 | public override string AuthorName => "Robert McNeel & Associates";
25 | public override string AuthorContact => "https://github.com/dalefugier/InstantMeshes";
26 | public override string Version => "8.19.25132.1001";
27 | }
28 | }
29 |
--------------------------------------------------------------------------------
/InstantMeshes.sln:
--------------------------------------------------------------------------------
1 |
2 | Microsoft Visual Studio Solution File, Format Version 12.00
3 | # Visual Studio 15
4 | VisualStudioVersion = 15.0.28307.779
5 | MinimumVisualStudioVersion = 10.0.40219.1
6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "InstantMeshes", "InstantMeshes.csproj", "{416E37E9-85BF-439C-992F-6BAC1AB72EBE}"
7 | EndProject
8 | Global
9 | GlobalSection(SolutionConfigurationPlatforms) = preSolution
10 | Debug|Any CPU = Debug|Any CPU
11 | Release|Any CPU = Release|Any CPU
12 | EndGlobalSection
13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution
14 | {416E37E9-85BF-439C-992F-6BAC1AB72EBE}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15 | {416E37E9-85BF-439C-992F-6BAC1AB72EBE}.Debug|Any CPU.Build.0 = Debug|Any CPU
16 | {416E37E9-85BF-439C-992F-6BAC1AB72EBE}.Release|Any CPU.ActiveCfg = Release|Any CPU
17 | {416E37E9-85BF-439C-992F-6BAC1AB72EBE}.Release|Any CPU.Build.0 = Release|Any CPU
18 | EndGlobalSection
19 | GlobalSection(SolutionProperties) = preSolution
20 | HideSolutionNode = FALSE
21 | EndGlobalSection
22 | GlobalSection(ExtensibilityGlobals) = postSolution
23 | SolutionGuid = {094541CE-66EB-4D21-A58A-B2CE5C9DC3F3}
24 | EndGlobalSection
25 | EndGlobal
26 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # InstantMeshes
2 |
3 | [
](https://github.com/wjakob/instant-meshes)
4 |
5 | Grasshopper for Windows plug-in that uses the [Instant Meshes](https://github.com/wjakob/instant-meshes) open source meshing utility.
6 |
7 | InstantMeshes is available in Rhino via the [PackageManager](https://www.rhino3d.com/features/package-manager/).
8 |
9 | ## Prerequisites
10 |
11 | The following tools are required to build InstantMeshes:
12 |
13 | - [Microsoft Visual Studio](https://visualstudio.microsoft.com/)
14 | - [Rhino 8 for Windows](https://www.rhino3d.com/)
15 |
16 | ## Compiling
17 |
18 | 1. Clone the repository. At a command prompt, enter the following command:
19 | ```
20 | git clone https://github.com/dalefugier/InstantMeshes
21 | ```
22 | 2. Open the `InstantMeshes.sln` solution file in Visual Studio.
23 | 4. Press F7, or click *Build > Build Solution* to build the solution.
24 |
25 | ## License
26 | This source code is licensed under the [MIT License](https://github.com/dalefugier/InstantMeshes/blob/master/LICENSE).
27 |
28 | [Instant Meshes](https://github.com/wjakob/instant-meshes/blob/master/LICENSE.txt) has its own separate license agreement.
29 |
30 |
--------------------------------------------------------------------------------
/lib/InstantMeshes LICENSE.txt:
--------------------------------------------------------------------------------
1 | Copyright (c) 2015 Wenzel Jakob, Daniele Panozzo, Marco Tarini,
2 | and Olga Sorkine-Hornung. All rights reserved.
3 |
4 | Redistribution and use in source and binary forms, with or without
5 | modification, are permitted provided that the following conditions are met:
6 |
7 | 1. Redistributions of source code must retain the above copyright notice, this
8 | list of conditions and the following disclaimer.
9 |
10 | 2. Redistributions in binary form must reproduce the above copyright notice,
11 | this list of conditions and the following disclaimer in the documentation
12 | and/or other materials provided with the distribution.
13 |
14 | 3. Neither the name of the copyright holder nor the names of its contributors
15 | may be used to endorse or promote products derived from this software
16 | without specific prior written permission.
17 |
18 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
19 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
20 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
21 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
22 | FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23 | DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
24 | SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
25 | CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
26 | OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
27 | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 |
29 | You are under no obligation whatsoever to provide any bug fixes, patches, or
30 | upgrades to the features, functionality or performance of the source code
31 | ("Enhancements") to anyone; however, if you choose to make your Enhancements
32 | available either publicly, or directly to the authors of this software, without
33 | imposing a separate written license agreement for such Enhancements, then you
34 | hereby grant the following license: a non-exclusive, royalty-free perpetual
35 | license to install, use, modify, prepare derivative works, incorporate into
36 | other computer software, distribute, and sublicense such enhancements or
37 | derivative works thereof, in binary and source code form.
38 |
--------------------------------------------------------------------------------
/InstantMeshes.csproj:
--------------------------------------------------------------------------------
1 |
2 |
3 | net7.0;net48
4 | true
5 | NU1701
6 | .gha
7 | .\bin\
8 | Library
9 |
10 |
11 |
12 | Robert McNeel & Associates
13 | Copyright © 2013-2025, Robert McNeel & Associates
14 | InstantMeshes
15 | Field-aligned mesh generator for Grasshopper®
16 | 8.19.25132.1001
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 | PreserveNewest
28 | InstantMeshes.exe
29 |
30 |
31 |
32 |
33 |
34 |
35 | PreserveNewest
36 | InstantMeshes LICENSE.txt
37 |
38 |
39 |
40 |
41 |
42 |
43 | C:\Program Files\Rhino 8\System\Yak.exe
44 | True
45 |
46 |
47 |
48 |
49 |
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 |
59 |
60 |
--------------------------------------------------------------------------------
/FileObj.cs:
--------------------------------------------------------------------------------
1 | using Rhino;
2 | using Rhino.Geometry;
3 | using System;
4 | using System.Collections.Generic;
5 | using System.Globalization;
6 | using System.IO;
7 | using System.Text.RegularExpressions;
8 |
9 | namespace InstantMeshes
10 | {
11 | internal static class FileObj
12 | {
13 | public static void Write(IEnumerable meshes, string filename)
14 | {
15 | try
16 | {
17 | StreamWriter sw = new StreamWriter(filename);
18 | // Write header
19 | sw.WriteLine("#OBJ");
20 | // Write mesh geometry
21 | long vert_counter = 1;
22 | foreach (Mesh m in meshes)
23 | {
24 | // Write all Verticies: v 1 2 3
25 | int vc = m.Vertices.Count;
26 | for (int i = 0; i < vc; i++)
27 | sw.WriteLine($"v {m.Vertices[i].X.ToString(CultureInfo.InvariantCulture)} {m.Vertices[i].Y.ToString(CultureInfo.InvariantCulture)} {m.Vertices[i].Z.ToString(CultureInfo.InvariantCulture)}");
28 | // Write All vertex normals: vn 1 2 3
29 | int nc = m.Normals.Count;
30 | m.Normals.UnitizeNormals();
31 | for (int i = 0; i < nc; i++)
32 | sw.WriteLine($"vn {m.Normals[i].X.ToString(CultureInfo.InvariantCulture)} {m.Normals[i].Y.ToString(CultureInfo.InvariantCulture)} {m.Normals[i].Z.ToString(CultureInfo.InvariantCulture)}");
33 | // Write All Faces: f 1 2 3 / 4
34 | int fc = m.Faces.Count;
35 | for (int i = 0; i < fc; i++)
36 | {
37 | if (m.Faces[i].IsTriangle)
38 | sw.WriteLine(
39 | $"f {m.Faces[i].A + vert_counter} {m.Faces[i].B + vert_counter} {m.Faces[i].C + vert_counter}");
40 | if (m.Faces[i].IsQuad)
41 | sw.WriteLine(
42 | $"f {m.Faces[i].A + vert_counter} {m.Faces[i].B + vert_counter} {m.Faces[i].C + vert_counter} {m.Faces[i].D + vert_counter}");
43 | }
44 | vert_counter += m.Vertices.Count;
45 | }
46 | sw.Close();
47 | }
48 | catch (Exception e)
49 | {
50 | RhinoApp.WriteLine(e.Message);
51 | }
52 | }
53 |
54 | public static Mesh Read(string filename)
55 | {
56 | try
57 | {
58 | using (StreamReader sr = new StreamReader(filename))
59 | {
60 | string obj_file = sr.ReadToEnd();
61 | Mesh obj = new Mesh();
62 |
63 | #region ADD NORMALS
64 | //n vector normals
65 | const string normal_reg = @"vn( +[\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)";
66 | foreach (Match m in Regex.Matches(obj_file, normal_reg))
67 | {
68 | Vector3d n = new Vector3d(double.Parse(m.Groups[1].Value, CultureInfo.InvariantCulture), double.Parse(m.Groups[2].Value, CultureInfo.InvariantCulture),
69 | double.Parse(m.Groups[3].Value, CultureInfo.InvariantCulture));
70 | if (n.IsValid)
71 | obj.Normals.Add(n);
72 | }
73 | #endregion
74 |
75 | #region ADD VERTS
76 | //v add verts
77 | const string vertex_reg = @"v( +[\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)( [\d|\.|\+|\-|e]+)";
78 | MatchCollection verts = Regex.Matches(obj_file, vertex_reg);
79 | if (verts.Count > 0)
80 | {
81 | foreach (Match m in verts)
82 | {
83 | int vc = obj.Vertices.Count;
84 | Point3d p = new Point3d(double.Parse(m.Groups[1].Value, CultureInfo.InvariantCulture),
85 | double.Parse(m.Groups[2].Value, CultureInfo.InvariantCulture),
86 | double.Parse(m.Groups[3].Value, CultureInfo.InvariantCulture));
87 | if (p.IsValid)
88 | obj.Vertices.SetVertex(vc, p.X, p.Y, p.Z);
89 |
90 | }
91 | //obj.Vertices.CombineIdentical(true, true);
92 |
93 | }
94 | #endregion
95 |
96 | #region ADD FACES
97 | // HUNT FOR FACES
98 |
99 | // f vertex vertex vertex eg f 1 2 3
100 | const string fvvv_reg = @"f( +[\d]+)( [\d]+)( [\d]+)( [\d]+)?";
101 | MatchCollection fvvv = Regex.Matches(obj_file, fvvv_reg);
102 |
103 | if (fvvv.Count > 0)
104 | {
105 | foreach (Match m in fvvv)
106 | {
107 | MeshFace mf = new MeshFace
108 | {
109 | A = int.Parse(m.Groups[1].Value, CultureInfo.InvariantCulture) - 1,
110 | B = int.Parse(m.Groups[2].Value, CultureInfo.InvariantCulture) - 1,
111 | C = int.Parse(m.Groups[3].Value, CultureInfo.InvariantCulture) - 1
112 | };
113 | if (m.Groups.Count == 5)
114 | mf.D = int.Parse(m.Groups[4].Value, CultureInfo.InvariantCulture) - 1;
115 | obj.Faces.AddFace(mf);
116 | }
117 | }
118 | else
119 | {
120 | //f quad based face structure v//n v//n v//n v//n
121 | const string fvnq_reg = @"(^f )[\d].+";
122 | const RegexOptions options = RegexOptions.Multiline;
123 | MatchCollection fvnq = Regex.Matches(obj_file, fvnq_reg, options);
124 | if (fvnq.Count > 0)
125 | {
126 | foreach (Match m in fvnq)
127 | {
128 | const string faces_req = @" [\d]+";
129 | MatchCollection faces = Regex.Matches(m.Value, faces_req);
130 |
131 | if (faces.Count <= 0)
132 | continue;
133 |
134 | MeshFace mf = new MeshFace
135 | {
136 | A = int.Parse(faces[0].Value, CultureInfo.InvariantCulture) - 1,
137 | B = int.Parse(faces[1].Value, CultureInfo.InvariantCulture) - 1,
138 | C = int.Parse(faces[2].Value, CultureInfo.InvariantCulture) - 1
139 | };
140 |
141 | if (faces.Count == 4)
142 | {
143 | mf.D = int.Parse(faces[3].Value, CultureInfo.InvariantCulture) - 1;
144 | }
145 | else
146 | {
147 | mf.D = mf.C;
148 | }
149 |
150 | obj.Faces.AddFace(mf);
151 |
152 | }
153 |
154 | }
155 | }
156 | #endregion
157 |
158 |
159 | sr.Close();
160 |
161 | obj.Faces.CullDegenerateFaces();
162 | obj.Compact();
163 |
164 |
165 | if (obj.Normals.Count == 0)
166 | obj.Normals.ComputeNormals();
167 |
168 | if (obj.IsValid)
169 | obj.Weld(22.5);
170 |
171 | return obj;
172 | }
173 | }
174 | catch
175 | {
176 | return null;
177 | }
178 | }
179 | }
180 | }
181 |
182 |
183 |
--------------------------------------------------------------------------------
/InstantMeshesComponent.cs:
--------------------------------------------------------------------------------
1 | using Grasshopper;
2 | using Grasshopper.Kernel;
3 | using Rhino.Geometry;
4 | using System;
5 | using System.Diagnostics;
6 | using System.Drawing;
7 | using System.IO;
8 | using System.Reflection;
9 | using System.Threading;
10 |
11 | namespace InstantMeshes
12 | {
13 | public class InstantMeshesComponent : GH_Component
14 | {
15 | public InstantMeshesComponent()
16 | : base("InstantMeshes", "IM", "Construct a field-aligned mesh.", "Mesh", "Triangulation")
17 | {
18 | }
19 |
20 | protected override void RegisterInputParams(GH_Component.GH_InputParamManager args)
21 | {
22 | args.AddMeshParameter("Mesh", "M", "Mesh", GH_ParamAccess.item);
23 | args.AddIntegerParameter("Faces", "F", "Target face count", GH_ParamAccess.item, 1000);
24 | args.AddIntegerParameter("Smooth", "S", "Smoothing steps", GH_ParamAccess.item, 2);
25 | args.AddIntegerParameter("Format", "F", "Mesh format: 0 = Triangles (6-RoSy, 6-PoSy), 1 = Quads (2-RoSy, 4-PoSy), 2 = Quads (4-RoSy,4-PoSy)", GH_ParamAccess.item, 2);
26 | args.AddBooleanParameter("Extrinsic", "E", "Extrinsic or intrinsic", GH_ParamAccess.item, true);
27 | args.AddBooleanParameter("Align", "A", "Align to boundaries", GH_ParamAccess.item, true);
28 | args.AddBooleanParameter("Creases", "C", "Sharp creases", GH_ParamAccess.item, true);
29 | args.AddNumberParameter("Angle", "A", "Crease angle in degrees", GH_ParamAccess.item, 90.0);
30 |
31 | //args[7].Optional = true;
32 | }
33 |
34 | protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager args)
35 | {
36 | args.AddMeshParameter("Mesh", "M", "Instant mesh", GH_ParamAccess.item);
37 | }
38 |
39 | protected override void SolveInstance(IGH_DataAccess access)
40 | {
41 | #region Process input
42 |
43 | Mesh mesh = new Mesh();
44 | int target_face_count = 1000;
45 | int smooth_iterations = 2;
46 | int mesh_format = 2;
47 | bool extrinsic = true;
48 | bool align_boundaries = true;
49 | bool sharp_creases = true;
50 | double crease_angle = 90.0;
51 |
52 | if (!access.GetData(0, ref mesh)) return;
53 | if (!access.GetData(1, ref target_face_count)) return;
54 | if (!access.GetData(2, ref smooth_iterations)) return;
55 | if (!access.GetData(3, ref mesh_format)) return;
56 | if (!access.GetData(4, ref extrinsic)) return;
57 | if (!access.GetData(5, ref align_boundaries)) return;
58 | if (!access.GetData(6, ref sharp_creases)) return;
59 | if (!access.GetData(7, ref crease_angle)) return;
60 |
61 | if (!mesh.IsValid)
62 | {
63 | AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Input mesh is invalid");
64 | return;
65 | }
66 | if (mesh_format < 0 || mesh_format > 2)
67 | {
68 | AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Mesh format must be: 0 <= Format <= 2");
69 | return;
70 | }
71 | if (crease_angle < 0.0 || crease_angle > 180.0)
72 | {
73 | AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Crease angle must be: 0 < Angle < 180.0");
74 | return;
75 | }
76 |
77 | #endregion
78 |
79 |
80 | #region Setup paths
81 |
82 |
83 | string gha_path = AssemblyDirectory;
84 | string im_path = Path.Combine(gha_path, "InstantMeshes.exe");
85 | if (!File.Exists(im_path))
86 | {
87 | AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "InstantMeshes.exe not found");
88 | return;
89 | }
90 |
91 | string tmp_path = Path.GetTempPath();
92 | Guid guid = Guid.NewGuid();
93 |
94 | string temp_obj = Path.Combine(tmp_path, $"input{guid}.obj");
95 | if (File.Exists(temp_obj))
96 | File.Delete(temp_obj);
97 |
98 | string temp_output_obj = Path.Combine(tmp_path, $"output{guid}.obj");
99 | if (File.Exists(temp_output_obj))
100 | File.Delete(temp_output_obj);
101 |
102 | FileObj.Write(new[] { mesh }, temp_obj);
103 |
104 | #endregion
105 |
106 |
107 | #region Configure and run InstantMeshes
108 |
109 | int mx = 2;
110 | if (mesh_format == 0)
111 | mx = 6;
112 | else if (mesh_format == 1)
113 | mx = 2;
114 | else if (mesh_format == 2)
115 | mx = 4;
116 |
117 | int my = 4;
118 | if (mesh_format == 0)
119 | my = 6;
120 | else if (mesh_format == 1 || mesh_format == 2)
121 | my = 4;
122 |
123 | string b = align_boundaries == true ? "-b" : string.Empty;
124 | string i = extrinsic == true ? string.Empty : "-i";
125 | string c = sharp_creases == true ? $"-c {crease_angle}" : string.Empty;
126 |
127 | string args = $"\"{temp_obj}\" -f {target_face_count} -p {my} -r {mx} {i} {c} {b} -S {smooth_iterations} -o \"{temp_output_obj}\"";
128 |
129 | ProcessStartInfo start_info = new ProcessStartInfo()
130 | {
131 | FileName = im_path,
132 | Arguments = args,
133 | UseShellExecute = false,
134 | RedirectStandardOutput = true,
135 | RedirectStandardError = true,
136 | WindowStyle = ProcessWindowStyle.Hidden,
137 | CreateNoWindow = true
138 | };
139 |
140 | Process process = new Process
141 | {
142 | StartInfo = start_info,
143 | EnableRaisingEvents = true
144 | };
145 | try
146 | {
147 | process.Start();
148 | }
149 | catch
150 | {
151 | AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Failed to start InstantMeshes process");
152 | return;
153 |
154 | }
155 |
156 | StreamReader s_out = process.StandardOutput;
157 | StreamReader s_err = process.StandardError;
158 | try
159 | {
160 | string str;
161 | while ((str = s_out.ReadLine()) != null && !s_out.EndOfStream)
162 | {
163 | s_out.BaseStream.Flush();
164 | }
165 | while ((str = s_err.ReadLine()) != null && !s_err.EndOfStream)
166 | {
167 | s_err.BaseStream.Flush();
168 | }
169 |
170 | }
171 | finally
172 | {
173 | s_out.Close();
174 | s_err.Close();
175 | }
176 |
177 | #endregion
178 |
179 |
180 | #region Return meshes from InstantMeshes
181 |
182 | if (!File.Exists(temp_output_obj))
183 | {
184 | AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "Mesh creation failed");
185 | return;
186 | }
187 |
188 | int retries = 0;
189 | while (IsFileLocked(new FileInfo(temp_output_obj)) || retries >= 4)
190 | {
191 | Thread.Sleep(500);
192 | retries++;
193 | }
194 |
195 | Mesh imported_mesh = FileObj.Read(temp_output_obj);
196 | if (imported_mesh == null)
197 | {
198 | AddRuntimeMessage(GH_RuntimeMessageLevel.Error, "An invalid mesh was returned from InstantMeshes");
199 | return;
200 | }
201 |
202 | if (imported_mesh.SolidOrientation() == -1)
203 | imported_mesh.Flip(true, true, true);
204 |
205 | #endregion
206 |
207 |
208 | if (File.Exists(temp_output_obj))
209 | File.Delete(temp_output_obj);
210 |
211 | if (File.Exists(temp_obj))
212 | File.Delete(temp_obj);
213 |
214 | access.SetData(0, imported_mesh);
215 | }
216 |
217 | ///
218 | /// Returns the path to this assembly
219 | ///
220 | private string AssemblyDirectory
221 | {
222 | get
223 | {
224 | GH_AssemblyInfo info = Instances.ComponentServer.FindAssemblyByObject(ComponentGuid);
225 | return (null != info) ? Path.GetDirectoryName(info.Location) : null;
226 | }
227 | }
228 |
229 | ///
230 | /// Returns true if the specified file is locked by another process
231 | ///
232 | private bool IsFileLocked(FileInfo file)
233 | {
234 | FileStream stream = null;
235 | try
236 | {
237 | stream = file.Open(FileMode.Open, FileAccess.ReadWrite, FileShare.None);
238 | }
239 | catch (IOException)
240 | {
241 | return true;
242 | }
243 | finally
244 | {
245 | stream?.Close();
246 | }
247 | return false;
248 | }
249 |
250 |
251 | public override GH_Exposure Exposure => GH_Exposure.quarternary;
252 |
253 | protected override Bitmap Icon
254 | {
255 | get
256 | {
257 | const string resource = "InstantMeshes.Resources.InstantMeshes.ico";
258 | Size size = new Size(24, 24);
259 | Assembly assembly = Assembly.GetExecutingAssembly();
260 | Icon icon = Rhino.UI.DrawingUtilities.IconFromResource(resource, size, assembly);
261 | return icon.ToBitmap();
262 | }
263 | }
264 |
265 | public override Guid ComponentGuid => new Guid("30392475-f7c9-4317-b8e8-4480cd13cdfd");
266 | }
267 | }
268 |
--------------------------------------------------------------------------------