Rhino 3d plugin for opening a .3dm file - c#

I am new to writing plugin for rhino 3d.
I have gone through the documentation and sample code here:
http://wiki.mcneel.com/developer/dotnetplugins
but unable to figure out how to open a .3dm file from plugin.
Can someone help me?
Thanks!!

It depends a little on what you are trying to do and which version of Rhino you are running.
If you are running Rhino 4 and using the Rhino_DotNet SDK, then you need to have your command class derive from MRhinoScriptCommand and call RhinoApp().RunScript(#"-_Open C:\path_to_model.3dm")
If you are running Rhino 5 and using the RhinoCommon SDK (recommended), then you should call RunScript in a fashion that Brian suggested above. You also need to mark your command class with the the Rhino.Commands.Style attribute of ScriptRunner
ex.
using Rhino.Commands;
[CommandStyle(ScriptRunner)]
class MyCommand : Rhino.Commands.Command
{
public override string EnglishName { get { return "MyCommand"; } }
protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
RhinoApp.RunScript(#"-_Open C:\model.3dm");
}
}
This will open the 3dm file and make it the active document.
On the other hand if you just want to read the 3dm file into memory and inspect the contents of it, I would recommend using the Rhino.FileIO.File3dm class in RhinoCommon. There is a static Read function on that class that you can use.

You can script the Open command from inside a plug-in using:
Rhino.RhinoApp.RunScript() to script the open command. For example:
Rhino.RhinoApp.RunScript(#"-_Open C:\model.3dm");

Related

Is there a way to turn several csharp repl commands into a terminal alias?

Every day I make a GUID which I copy to my clipboard.
I do this by opening my terminal, writing csharp (see link below in case you are confused), writing GUID.NewGuid(), copying the output and writing quit.
Is there any way I can turn this whole procedure into a terminal alias?
Edit:
Just to clarify, I'm using this:
https://www.mono-project.com/docs/tools+libraries/tools/repl/
You can write and compile a console application, the question was geared towards whether you can inject statements directly into the command-line tool, not how to make a tiny executable.
There is an easy command from BSD to generate a UUID, it's available in macOS.
uuidgen
If you need to copy the UUID result to clipboard, use this:
uuidgen | pbcopy
So, what's the difference between UUID and GUID? Check out this thread.
Create a C# program
using System;
namespace guid
{
class MainClass
{
public static void Main(string[] args)
{
new MainClass().run();
}
private void run()
{
Console.WriteLine(Guid.NewGuid());
}
}
}
Compile to new-guid
Use in zsh like this
guid=$(./new-guid) #you may have to change the `.` to the appropriate path, depending on where the program is.
echo "${guid}"
Tested with zsh and mono-develop in Debian Gnu/Linux.
Note there are probably better ways to do this. One line purl script, or may be some Unix command.
Here's the answer I was looking for, in this case:
csharp -e 'Guid.NewGuid();' | pbcopy

How do I add an attachment to a MSTest running via SpecFlow

I have a suite of SpecFlow tests that are using the MSTest framework. I run them via Microsoft Test manager. What I want to know is if I can get it to attach a file to the run.
My code generates a HTML file that i'd like attached so that users can go into the results for test in MTM and simply open it up.
I saw a previous question had:
TestContext.AddResultFile(testPassedFile);
But when I tried to add TestContext to my "[AfterScenario]" method it doesnt have a method called AddResultFile.
Does anyone know how I might be able to achieve adding this HTML file to the results.
AFAIK there is no way of accessing the TestContext from within the StepBindings:
Access TestContext in SpecFlow Step Binding class
The only way I see is to write your own generator for the tests so that the generated test-code writes the TestContext for example to SpecFlow's ScenarioContext, so that you can access it from the step bindings.
If you want to take all that hassle, you might take a look at https://jessehouwing.net/specflow-custom-unit-test-generator/.
In SpecFlow 3, you can get the TestContext via content injection, and store a reference to it, which can then be accessed in the step definitions:
using Microsoft.VisualStudio.TestTools.UnitTesting;
using TechTalk.SpecFlow;
[Binding]
public class Context
{
private static TestContext test_context;
[BeforeScenario]
private static void SetContext(ScenarioContext context)
{
test_context = context.ScenarioContainer.Resolve<TestContext>();
}
public static void Attach(string file_name)
{
test_context.AddResultFile(file_name);
}
}

Is it possible to use Gephi compiled with IKVM in a website?

I'm currently trying to load and use the Gephi Toolkit from within a .Net 4 C# website.
I have a version of the toolkit jar file compiled against the IKVM virtual machine, which works as expected from a command line application using the following code:
var controller = (ProjectController)Lookup.getDefault().lookup(typeof(ProjectController));
controller.closeCurrentProject();
controller.newProject();
var project = controller.getCurrentProject();
var workspace = controller.getCurrentWorkspace();
The three instances are correctly instantiated in a form similar to org.gephi.project.impl.ProjectControllerImpl#8ddb93.
If however I run the exact same code, with the exact same using statements & references, the very first line loading the ProjectController instance returns null.
I have tried a couple of solutions
Firstly, I have tried ignoring the Lookup.getDefault().lookup(type) call, instead trying to create my own instances:
var controller = new ProjectControllerImpl();
controller.closeCurrentProject();
controller.newProject();
var project = controller.getCurrentProject();
var workspace = controller.getCurrentWorkspace();
This fails at the line controller.newProject();, I think because internally (using reflector) the same Lookup.getDefault().lookup(type) is used in a constructor, returns null and then throws an exception.
Secondly, from here: Lookup in Jython (and Gephi) I have tried to set the %CLASSPATH% to the location of both the toolkit JAR and DLL files.
Is there a reason why the Lookup.getDefault().lookup(type) would not work in a web environment? I'm not a Java developer, so I am a bit out of my depth with the Java side of this.
I would have thought it possible to create all of the instances myself, but haven't been able to find a way to do so.
I also cannot find a way of seeing why the ProjectController load returned null. No exception is thrown, and unless I'm being very dumb, there doesn't appear to be a method to see the result of the attempted load.
Update - Answer
Based on the answer from Jeroen Frijters, I resolved the issue like this:
public class Global : System.Web.HttpApplication
{
public Global()
{
var assembly = Assembly.LoadFrom(Path.Combine(root, "gephi-toolkit.dll"));
var acl = new AssemblyClassLoader(assembly);
java.lang.Thread.currentThread().setContextClassLoader(new MySystemClassLoader(acl));
}
}
internal class MySystemClassLoader : ClassLoader
{
public MySystemClassLoader(ClassLoader parent)
: base(new AppDomainAssemblyClassLoader(typeof(MySystemClassLoader).Assembly))
{ }
}
The code ikvm.runtime.Startup.addBootClassPathAssemby() didn't seem to work for me, but from the provided link, I was able to find a solution that seems to work in all instances.
This is a Java class loader issue. In a command line app your main executable functions as the system class loader and knows how to load assembly dependencies, but in a web process there is no main executable so that system class loader doesn't know how to load anything useful.
One of the solutions is to call ikvm.runtime.Startup.addBootClassPathAssemby() to add the relevant assemblies to the boot class loader.
For more on IKVM class loading issues see http://sourceforge.net/apps/mediawiki/ikvm/index.php?title=ClassLoader

Why do 'requires' statements fail when loading (iron)ruby script via a C# program?

IronRuby and VS2010 noob question:
I'm trying to do a spike to test the feasibility of interop between a C# project and an existing RubyGem rather than re-invent that particular wheel in .net. I've downloaded and installed IronRuby and the RubyGems package, as well as the gem I'd ultimately like to use.
Running .rb files or working in the iirb Ruby console is without problems. I can load the both the RubyGems package, and the gem itself and use it, so, at least for that use case, my environment is set up correctly.
However, when I try to do the same sort of thing from within a C# (4.0) console app, it complains about the very first line:
require 'RubyGems'
With the error:
no such file to load -- rubygems
My Console app looks like this:
using System;
using IronRuby;
namespace RubyInteropSpike
{
class Program
{
static void Main(string[] args)
{
var runtime = Ruby.CreateRuntime();
var scope = runtime.ExecuteFile("test.rb");
Console.ReadKey();
}
}
}
Removing the dependencies and just doing some basic self-contained Ruby stuff works fine, but including any kind of 'requires' statement seems to cause it to fail.
I'm hoping that I just need to pass some additional information (paths, etc) to the ruby runtime when I create it, and really hoping that this isn't some kind of limitation, because that would make me sad.
Short answer: Yes, this will work how you want it to.You need to use the engine's SetSearchPaths method to do what you wish.
A more complete example
(Assumes you loaded your IronRuby to C:\IronRubyRC2 as the root install dir)
var engine = IronRuby.Ruby.CreateEngine();
engine.SetSearchPaths(new[] {
#"C:\IronRubyRC2\Lib\ironruby",
#"C:\IronRubyRC2\Lib\ruby\1.8",
#"C:\IronRubyRC2\Lib\ruby\site_ruby\1.8"
});
engine.Execute("require 'rubygems'"); // without SetSearchPaths, you get a LoadError
/*
engine.Execute("require 'restclient'"); // install through igem, then check with igem list
engine.Execute("puts RestClient.get('http://localhost/').body");
*/
Console.ReadKey();

convert code snippet to C#

VS 2008
I have this code snippet I found on a VB website.
But for some reason I am having trouble converting it to C#.
My.Computer.Network.IsAvailable
Many thanks,
using System.Net.NetworkInformation;
internal class Program
{
private static void Main()
{
NetworkInterface.GetIsNetworkAvailable();
}
}
Yes, garethm is right, this class (Network) is from a VB.NET library - you need to reference the Microsoft.VisualBasic assembly if using in a C# project.
Microsoft.VisualBasic.Devices.Network n = new Microsoft.VisualBasic.Devices.Network();
if (n.IsAvailable)
{
// do stuff
}
Works for me - my network is available :).
As far as how Network relates to NetworkInterface class, it depends on what you want to do next. For instance, Network has such nice stuff as NetworkAvailabilityChanged event, and UploadFile method. On the other hand, NetworkInterface can give you a bunch of specific technical info such as speed or whether it supports multicast.
BTW, there is nothing undocumented about using a class from Microsoft.VisualBasic namespace - it's the core idea behind .NET that you can use classes from assemblies regardless of the language they were written in.
What I generally do is write a small app, then load then project in Reflector and disassemble it.
but you can use this class:
System.Net.NetworkInformation.NetworkChange.NetworkAddressChanged
Isn't the whole "My" thing from a VB library?
This appears to work. It's probably very undocumented usage though:
Microsoft.VisualBasic.Devices.Network net = new Microsoft.VisualBasic.Devices.Network();
if (net.IsAvailable)
{
Text = "Network is available";
}
else
{
Text = "Network unavailable";
}
Note that I needed to add a reference to Microsoft.VisualBasic to my project.

Categories