本文主旨是介绍“进程间通讯”在Grasshopper中的应用。

常用场景:手头已经有一个程序,这个程序想控制Grasshopper画布中某些组件进行一些数据操作,这个程序是独立Rhino和Grasshopper之外运行的。

另一个程序来控制 Grasshopper 中的组件。


进程之间通讯

Windows平台下,进程间通讯称为“Interprocess Communications”,具体详见msdn文档,有多重实现模式,在此就不赘述了:

https://docs.microsoft.com/en-us/windows/win32/ipc/interprocess-communications
(中文版暂未提供)

鉴于Rhino/Grasshopper是.NET Framework平台,本文选择一个最简单的实现方法来实现这一点 —— Remoting。

关于Remoting的介绍:

https://docs.microsoft.com/en-us/dotnet/api/system.runtime.remoting?view=netframework-4.8

实现方法

Grasshopper电池中新开一个 自定义线程 用来接收外部程序的调用,外部程序与Grasshopper中新建的 自定义线程 通过Remoting协议实现通讯,这个线程负责依照外部程序指令对Grasshopper进行相应操作。

本文的例子是通过外部程序使得Grasshopper中重新计算(Recompute)。


  1. 新建一个 .Net Framework Library项目,里面用来定义进程通讯的对象的接口。

namespace IPCLibrary
{public interface IPCInterface{// 定义一个能够被外部调用的接口,具体实现在Grasshopper中完成void Recompute(); }
}

将该项目编译,构建一个 IPCInterface.dll 文件,该文件在接下来会被引用。


  1. 新建一个Grasshopper电池项目,并引用步骤1中生成的 IPCInterface.dll 文件。这个项目主要是实现两个部分的内容:
    (1)依据步骤1中定义的接口,实现一个对象用来对Grasshopper实现所需的操作;
    (2)在SolveInstance内部开启新线程,用于实例化 步骤(1) 中的对象的静态属性以及注册通讯协议至操作系统。

using Grasshopper.Kernel;
using IPCLibrary;
using System;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;
using System.Threading;namespace SolutionExpirer
{internal class SolutionExpirer : MarshalByRefObject, IPCInterface{internal static GH_Component component; // 静态属性,在线程启动时指定为线程发起者public void Recompute() => component.OnPingDocument().NewSolution(true); // 实现Grasshopper重算逻辑}public class SolutionExpirerComponent : GH_Component{public SolutionExpirerComponent(): base("SolutionExpirer", "SEer","","IPC", "IPC"){ }protected override void RegisterInputParams(GH_Component.GH_InputParamManager pManager) { }protected override void RegisterOutputParams(GH_Component.GH_OutputParamManager pManager) { }Thread thd;         // 定义线程int slvCount = 0;   // 用于存储该电池总共的运行次数(证明真的ExpireSolution了)protected override void SolveInstance(IGH_DataAccess DA){slvCount++;Message = slvCount.ToString();   // 用来显示SolveInstance自该电池在画布上起,总共运行了几次if (thd != null) return;thd = new Thread(() =>{var channel = new IpcServerChannel("GHMFIPCD");ChannelServices.RegisterChannel(channel, false);RemotingConfiguration.RegisterWellKnownServiceType(typeof(SolutionExpirer), "SE", WellKnownObjectMode.SingleCall);SolutionExpirer.component = this; // 指定静态属性while (true) { } // 线程保活});thd.Start(); // 开启线程}protected override System.Drawing.Bitmap Icon => null;public override Guid ComponentGuid => new Guid("*** *** Apply a new Guid here *** ***"); }
}

  1. 外部程序调用:这里采用一个Console程序来实现 —— 新建一个Visual Studio命令行项目,将步骤1中的 IPCInterface.dll 加入引用。

using IPCLibrary;
using System;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Ipc;namespace ClientSide
{class Program{static void Main(string[] args){var channel = new IpcClientChannel();ChannelServices.RegisterChannel(channel, false);var url = @"ipc://GHMFIPCD/SE";  // 分别对应Grasshopper电池定义中的Channel名字及ServiceType名字var remoteObj = (IPCInterface)Activator.GetObject(typeof(IPCInterface), url);remoteObj.Recompute();}}
}

本质上来说,是使用Activator.GetObject()来实例化了一个在Grasshopper内的对象(远程对象),而在命令行程序中可以作为本地对象来使用。

将上述命令行程序运行的结果就是Recompute()方法被执行,Grasshopper中画布上的所有电池将会被Expire并重启运算。运行结果:

图中,靠上部的电池是一个随机数生成器,每次会随即生成一个0~1之间的浮点数。可以看到,每次Recompute的时候,都会生成一批新的浮点数。

左侧命令行运行的是步骤3中的生成的外部程序。可以看到,每次程序运行时都成功地将使Grasshopper重新计算了。电池本身的计数器也在不断增长。

生成器,每次会随即生成一个0~1之间的浮点数。可以看到,每次Recompute的时候,都会生成一批新的浮点数。

左侧命令行运行的是步骤3中的生成的外部程序。可以看到,每次程序运行时都成功地将使Grasshopper重新计算了。电池本身的计数器也在不断增长。

此时如果我们对命令行程序(步骤3中的代码)进行重构、任何更改,都不会影响到Rhino或者Grasshopper的运行。甚至可以在Rhino运行的时候进行代码调试。在某些特定情况下,还是十分有效的。

【Grasshopper进阶】Grasshopper外部调用相关推荐

  1. 【Grasshopper进阶】在Grasshopper画布上实现动画效果

    最近笔者为了能够做到对用户友好,深入地学习了一些前端的知识,等回过神来,发现已经好久没有在CSDN上更过东西了- 结合最近看到的某些前端框架的底层,突然想到为什么不在Grasshopper上玩动画呢? ...

  2. 【Grasshopper进阶】反射?什么反射?用反射屏蔽掉C#Script电池的运行时长

    写这次这一篇的原因是来自一个CSDN网友找到我提出了一个拷问: 知名网友:"我想把下面的代码放到 C# Script电池里,怎么加?" public override TimeSp ...

  3. 【Grasshopper进阶】强制Grasshopper电池输入/输出参数数据结构扁平化 (i.e. Flatten/拍平/展开…)

    我们都知道,Grasshopper中一个很重要的概念就是数据结构,把数据输入到电池某个端口时,根据数据的结构的不同(列表/数据树),电池对数据会做出不同的响应.这也是为什么在我们在Grasshoppe ...

  4. 【Grasshopper基础14】创建可在画布上自由传递的自定义类型数据(下)—— 电池与自定义IGH_Goo的交互

    2022年3月至今,这段日子真是一段令人印象深刻的时光. 总之,居家这么久了,忙了一阵终于可以来写点东西了.首先要对上一期[基础13]内的两个小错误进行一个勘误: 在 class Pudge 中对 I ...

  5. 使用V-Ray为Grasshopper渲染参数化设计

    使用V-Ray for Grasshopper,包含在最新版本的V-Ray for Rhino中,用户可以在Grasshopper中创建逼真的图像.我们让Imago Design的创始人Jan Kok ...

  6. 维基解密最新文件揭露CIA如何攻击Windows PC

    在过去的一个月里,维基解密已经曝光一系列据说显示美国中情局(CIA)如何监视电子设备的文件,其中包括CIA专门针对苹果电脑Mac和iPhone 手机进行监控的项目.最新放出的Vault 7系列文件则主 ...

  7. Rhino6安装Weaverbird

    版本6.5可用--Weaverbird下载链接 进入网页后在点击Download Weaverbird for Rhino 6 下载下来是一个.gh的文件,双击运行,会打开rhino和grasshop ...

  8. grasshopper python可以做什么_Grasshopper 有哪些奇技淫巧?

    // >>>>>>>>>> 更新至 7.5(热键第二章) <<<<<<<<<<& ...

  9. staruml顺序图生成协作图_小组课 | Grasshopper分析图的快速生成

    SEMINAR 小组课课程 线上小班化教学:场地分析课程.设计概念课程.基础图纸课程.进阶理论课程.方案表现课程.交互基础课程 上课方式: 相应的小组课QQ群内视频 上课周期: 每个申请年循环2-3次 ...

最新文章

  1. 计算机安全设,默认的安全性还不够!这几个保护计算机的步骤要设置好
  2. python场景异常_python-异常
  3. 如何搭建一个完整的Vue3.0 + ts 的项目
  4. 2017.8.10 树上染色 失败总结
  5. 关于HashMap初始化容量问题
  6. 一步一步教你玩转.NET Framework的配置文件app.config (转载)
  7. matlab求两向量夹角_MATLAB基础练习(一)
  8. IOS 使用自签名证书开发HTTPS文件传输
  9. 嵌入式设备的机器码、cpu的id号以及网卡mac地址
  10. Java常见面试题_理论+实践
  11. github 修改密码密码_雇主要求提供GitHub密码。 如何处理呢?
  12. 视频怎样转换html代码,超简单的视频格式转换方法,你会吗?
  13. python批量下载巨潮PDF年报
  14. 8086逻辑移位指令SHL和SHR
  15. 【亚马逊运营】几点选品的建议卖家们都注意了吗?
  16. 漫谈程序员(二)程序员保值的4个秘密
  17. android 提醒app,安卓手机上提醒工作的软件有哪些?
  18. python3彻底卸载与安装教程
  19. CNN实战:猫狗大战
  20. python函数和类的区别_python-函数、类与对象

热门文章

  1. 攻防世界-MISC-新手区(掀桌子)
  2. 机器学习建模基本过程
  3. 探讨使用UML设计机器学习特征工程与深度学习建模等大数据分析软件
  4. IT行业常用的软件汇总及使用说明
  5. 【二、FreeBSD的系统按装步骤】(基于FreeBSD虚拟机安装好的基础之上)
  6. FreeBSD 安装ports
  7. 金和OA在自定义表单中,加入Fusionchart图表功能
  8. python pygame库入门
  9. 用python海龟画笔绘制标准五星红旗
  10. 车载软件背景(留坑)