algorithmic modeling for Rhino
Hi to all,
I've written a class called MyMeshWrapper which has two data members:
1. string m_name
2. Mesh m_mesh
Also i've written a component called SerializeMesh that gets a Mesh as input and initialized a MyMeshWrapper instance with a hard-coded name and given Mesh,
Then it saves the MyMeshWrapper instance in a file (filepath hardcoded) by serialization
Also the component will load the MyMeshWrapper instance from the filepath is no Mesh was inserted as input (it is optional parameter)
After it loads it it will set the output parameter as the MyMeshWrapper.Mesh
Now till here everything is good - this works perfectly - the problem starts when i'm calling the UnloadGrasshopper command and Loading it again.
It seems that the de-serialization does not work so good with classes that are not Rhino built-ins. It works on the first time i run grasshopper and when i unload grasshopper and loads it again it doesn't work.
I have no idea yet how to solve this and i hope you guys will have something smarter to say :)
My guess is that my custom class needs to be linked somehow, maybe it's a problem with how i configured my visual studio project.
In the components folder all i have is the .gha maybe the .dll is missing? even tho manually copying it doesn't solve the problem
Just to be clear - There's only problem AFTER i UnloadGrasshopper and LoadGrasshopper again.
Maybe there's a bug in how Rhino reloads custom components ?
or maybe i just did something wrong in my end.
Please help :)
I've attached the component .cs which also contains the MyMeshWrapper.
Tags:
Why are you unloading Grasshopper?
--
David Rutten
david@mcneel.com
Well, first It's a Rhino command so i didn't think it'll cause any trouble
Second, i keep recompiling my component so it's a waste of time for me to relaunch Rhino all over again - and Unloading/Loading Grasshopper is also a waste of time but it's a smaller amount of wait-time. :) It would be alot easier if i could reload the component inside grasshopper
The unload/load worked perfect until i was trying to deserialze my class
Well, it could cause trouble. Assemblies are never truly unloaded from an AppDomain, but the UnloadGrasshopper command erases a bunch of caches. If you load dlls via memory, then recompile and load newer versions of the same ones, you may well run into problems because now both the old and the new assemblies are loaded at the same time. Are you sure there is no code anywhere that insists on using methods in the old assembly? Is the old assembly handling events or responding to triggers when it shouldn't?
I know it's annoying to launch Rhino all the time, but in my experience people mostly do this because they don't have the debugger hooked up correctly and they cannot actually step into their code, thus forcing them to code up all sorts of weird hacks to try and debug the code. Is that the case here as well?
Looking at your code now, comments in the next response.
--
David Rutten
david@mcneel.com
Well, I'm not trying to debug my code, and when i do i launch it in debug mode and it launched Rhino as well, and i can step into my code.
But that's not my intentions - I work quicker when i make small changes into my code and i want to immediately see it at work in Release mode so what i do is compile my component and alt-tab to the opened rhino window and i unload/load the GH component with a macro i made that does ONLY that, the GH has only my component in the Component Libraries folder so the load itself won't take alot of time. that's the quickest way i came up with.
if it doesn't work - it should not be available for public users
I think that besides my development habbits there's another issue - Unload/LoadGrasshopper commands should work properly. It should remove any object that are made by GH and unlink them from Rhino and the load command should load all the resources needed for GH to work. Don't you?
I never liked the SerializableAttribute approach, either I totally don't get it (which is entirely possible) or it's a very clunky solution. I rewrote the code using just a simple binary writer and reader object.
It works after UnloadGrasshopper, doesn't require a MeshWrapper class or any of that weird Serializable code.
You can also switch to using GH_IO as a platform for writing and reading data. It's a bit friendlier to work with than just pumping bytes directly, you get named values, hierarchical databases and compression thrown in for free.
--
David Rutten
david@mcneel.com
Thanks David, But the real problem is not with the wrapper.
I did not need the Wrapper really just to serailzie
The problem was that the wrapper was a custom class that i wrote that Rhino/GH did not recognize after the reload of GH.
If i change my code to serialize with Mesh it WILL work. only because that Mesh is Rhino built-in class and it does recognize it.
The reason my example code was with the MyMeshWrapper is because i tried to narrow down the reason that it doesnt work and that reason was that it does not recognize my custom class.
I'm planning to expand MyMeshWrapper so it'll contain a bunch of Meshes and other Geometry objects..
So from what you're saying - never to use unload/load and if public users will use my component i should state that if they're gonna use the Unload command - Nothing will really work?
BTW - Even though this reply might sound ungrateful i'm REALLY thankful for your quickest reply and the fact you took the time to re-code my example!
I'm not sure. I don't know how and if .NET keeps track of serializable classes. I don't know if the TypeID plays any role in this and if it does, I don't know how the typeID is determined for classes that occur in two similar loaded assemblies.
You can totally keep the MeshWrapper class if you want, but I'd use serialization using FileWriter or GH_IO. You can put this functionality in the MeshWrapper class so it's still properly blackboxed of course. This would make it easy to use (once you've written the code once) as you can expose the Read/Write as two methods on MeshWrapper. If you store your data using GH_IO then it'll also be easier to make changes to the class later and still be able to read files written with previous versions.
I do know that the Unload command will probably not feature in GH2, it's causing more trouble than it's worth. Hopefully by then Visual Studio will fully support Edit-And-Continue which will take away the biggest reason for having unload in the first place.
--
David Rutten
david@mcneel.com
Fair enough.
I'll give your suggestion a try :)
Cheers.
I agree that this "unload" feature is probably best to remove in GH2. Unless you are using separate AppDomains (and I'm pretty sure you're not), you are never really unloading code and there are a ton of difficult to track side effects that come along with this.
Our developer staff will be switching to VS2013 very soon for all of our development effort in V6 and Microsoft claims that edit-and-continue is supported in that version. I would recommend you try 2013 for your component code to see if that works better for you.
I would forgo supporting .NET serialization at first and use the methods that David suggests. You can always wire up standard .NET serialization at a later date. I agree the built in stuff in .NET can be confusing but it is the best approach to support in the long run since it will work with everything in the framework. The automatic serialization stuff which I'm assuming you are using is definitely not going to work with the multiple assemblies loaded in memory situation you are describing with unloading of components. When you do get around to supporting .NET style serialization, I would recommend directly implementing ISerializable instead of just depending on the automatic stuff.
Well i've re-read all the things you wrote here
And i have a question to you, david and steve as component developers that work on daily basis:
How do you work when you're working on a component development?
Do you code in visual studio, compile, launch rhino and within rhino launch grasshopper each time?
As For debugging, yes, i'm able to step into my code via Visual Studio. but most of my time i'm not debugging - i'm developing and making small changes and compiling more than 40 times a day.
I'd love to hear about any suggesstions of ways of work that you do that'll save me alot of time.
I wish there was a way to run Rhino with 'GH Developers' flag that'll run much faster.
Do you code in visual studio, compile, launch rhino and within rhino launch grasshopper each time?
Yes, I work on Visual Studio 2010 when developing code for Rhino5, Visual Studio 2012 when developing code for Rhino6 and Visual Studio 2013 while typing on Grasshopper 2.0
I launch Rhino and Grasshopper each time, takes about 15~17 seconds to load both programs, it takes about 25 seconds to compile the entire project. Because of this I don't write and test tiny amounts of code, I write and test large amounts, then use the debugger to fix bugs.
As For debugging, yes, i'm able to step into my code via Visual Studio. but most of my time i'm not debugging - i'm developing and making small changes and compiling more than 40 times a day.
40 sounds about the right order of magnitude. Somewhere between 5 and 500 I'd say, depending on whether I'm debugging something big or writing a lot of new code.
I'd love to hear about any suggesstions of ways of work that you do that'll save me alot of time.
I wish there was a way to run Rhino with 'GH Developers' flag that'll run much faster.
You can not load certain plugins when starting Rhino. That may speed up loading times, but probably not significantly.
--
David Rutten
david@mcneel.com
Welcome to
Grasshopper
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
Added by Parametric House 0 Comments 0 Likes
© 2024 Created by Scott Davidson. Powered by