How to import/export block from/to external file into open document?

rhino5

#1

In my C# plugin I’d like to load objects defined in external files and place them to a specific location in my open document.
Also, I’d like to do it the other way round: export specific blocks into separate files.

Attempt 1: File3dm class

So far, I tried to use the File3dm class but it has no method to write an InstanceDefinition or InstanceObject into a file, nor does it give access to the block definitions in order to transform instances of them to specific points.

Attempt 2: InstanceDefinition/InstanceObject class

I also did not find a method to export/save and InstanceDefinition or InstanceObject.

Attempt 3: _-Import script

Always returns false:

RhinoApp.RunScript("_-Import myfile.3dm", true)

same with the commands _Load or _Open.

Could someone direct me to the right resource? I know my problem should be solvable.


(Dale Fugier) #2

The easiest way to import geometry from another file is to just script the Import command using RhinoApp.RunScript. However, in order to run a Rhino command from a plug-in command, your plug-in command must have a special attribute. See the following dev note for details.

http://developer.rhino3d.com/guides/rhinocommon/run_rhino_command_from_plugin/


#3

Fantastic, @dale!
One suggestion: maybe the RunScript could raise a well-named exception indicating the problem instead of just returning false. Maybe you could also link to the resource about ScriptRunner command style attribute inside of the method’s documentation.


#4

…and for exporting a block without the user selecting it, what can I use? The following does not work:

RhinoApp.RunScript("_-BlockManager _Export <block_name> <file_path> _Enter _Enter")

I took it from this example .rvb script : https://github.com/mcneel/rhinoscript/blob/master/ExportBlocks.rvb

What works however, but with the user having to select the block which I don’t want:

RhinoApp.RunScript("_-Export")

Can you spot my error?


#5

…also, the following hack

_ExplodeBlock <blockname>   //fails
_SelLast
_Export <file_name> _Enter _Enter

only works in the Rhino editor, when the user selects the block rather than specifying <blockname> programmatically. It does not run via RhinoApp.RunScript()


(Dale Fugier) #6

When scripting commands using RhinoApp.RunScript, make sure to surround literal strings that contain spaces with double-quote characters.

For example:

var filename = @"C:\Users\Dale\Desktop\Test.3dm";
var script = string.Format("_-Open \"{0}\"", filename);
RhinoApp.RunScript(script, false);

#7

Thank you for the reminder. Yet, my filenames do not contain whitespace. Neither
_BlockManager _Export <blockname> /my/absolute/path.3dm nor _ExplodeBlock <blockname> work already, also in Rhino’s command input box. The error message is “Unknown command: < blockname>”.

It seems that the macros do not accept a block name as argument.


(Dale Fugier) #8

Can you post your 3dm file and some sample command code that I can run here?


#9

Osszeallitas-cleansed.3dm (12.1 MB)

Great! Please try e.g.

_BlockManager _Export Haz /tmp/haz-export.3dm

(Dale Fugier) #10

Have you tried doing this in just Rhino? It appears that the BlockManager command is not scriptable in MacRhino yet…


#11

I tried both: Rhino for Mac as well as in a C# plugin.
When do you think this could be available?


(Dale Fugier) #12

Being that the issue was just discovered, I have no idea when this will be fixed. But here is a link to the issue so you can track it’s progress.

https://mcneel.myjetbrains.com/youtrack/issue/MR-2889

– Dale


#13

thank you. Do you see another possibility to export one (or multiple) blocks on Rhino Mac? As described above, also Macros like

 ExplodeBlock Haz

fail saying “Unknown command: Haz”, which is a block name.


(Dale Fugier) #14

You might consider inserting "Haz"at the world origin, selecting it, then scripting the Export command.


#15

Similar problem. In Rhino _Insert Haz also invokes the block manager dialog.
Via RhinoApp.RunScript(_-Insert Haz) however, it works to insert it but I am prompted in the UI for all the different options (insert as block, insertion point, rotation, scale factor).
How can I specify the options via RunScript?

RhinoApp.RunScript("_-Insert Haz _Block 0,0,0 _Enter _Enter", true)
RhinoApp.RunScript("_-Insert Haz _Block 0,0,0 0.0 1.0", true);

are not the right way.


How to import selected blocks from a File3dm? (Or were blocks saved incorrectly in this file?)
#16

##update
RhinoApp.RunScript("_-Insert Haz _Block 0,0,0 _Scale 1.0 _Rotation 0.0", true)

or simply

RhinoApp.RunScript("_-Insert Haz _Block 0,0,0 1.0 0.0", true)

do work indeed.

Thank you very much for your help, @dale. I am quite new to macros and scripting in Rhino.


(Dale Fugier) #17

If you don’t want to script the Insert command, you can always insert it yourself…

protected override Result RunCommand(RhinoDoc doc, RunMode mode)
{
  const string idef_name = "Haz";
  var idef = doc.InstanceDefinitions.Find(idef_name, true);
  if (null == idef)
  {
    RhinoApp.WriteLine("Block definition \"{0}\" does not exist.", idef_name);
    return Result.Nothing;
  }

  var iref_uuid = doc.Objects.AddInstanceObject(idef.Index, Transform.Identity);
  doc.Views.Redraw();

  return Result.Success;
}

#18

great, thank you.


#19

@dale I did a follow-up post because I was not able to import selected blocks from an external file. With a specific file I was unsuccessful with both File3dm.Objects and File.InstanceDefinitions: How to import selected blocks from a File3dm? (Or were blocks saved incorrectly in this file?).
Could you help me there?


(Dale Fugier) #20

See my reply to your other block topic…