NCF参数化建筑论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

搜索
查看: 41506|回复: 22
打印 上一主题 下一主题

[个人作品] Rhino.python实时动态显示与鼠标捕捉 ---像玩Processing一样玩Rhino.Python?

  [复制链接]
跳转到指定楼层
1m
发表于 2013-8-23 20:29:20 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 wdc63 于 2013-8-23 20:36 编辑


                               
登录/注册后可看大图

Rhino.Python平台是以静态建模为主的算法三维建模工具,很少有人会用它来作一些动态效果,因为在一般情况下使用Rhino.Python进行动态效果显示需要首先生成模型然后再删除之,这个过程会极大的影响速度,而且一般只能依靠写好的算法自动运行,与即时的鼠标或键盘事件互动也很困难。
不过还是有方法可循,虽然与Processing、cinder。openframwork等工具完全不可比拟。
最初从自带案例中的CustomGetPoint.py得到相关线索。Rhinocommon SDK可查询到Rhino.Display类下的DisplayPipeline类型可以在Rhino中进行比较简单的即时显示,虽说简单,就模型类型而言还是比较全面,点、线、面和基本曲面几何体都可不生成模型的情况下即时显示。Rhino本身的显示依靠OpenGL,因此速度尚可。缺陷便是这里面无法进行阴影、纹理着色和光源等高级显示效果。


                               
登录/注册后可看大图

DisplayPipeline类型可借助.net编程中的事件与委托(event,delegate)来调用DynamicDraw(动态显示)方法。DynamicDraw方法的第二个参数只能是Rhino.Input.Custom. GetPointDrawEventArgs。
在Rhinocommon SDK中可以查到Rhino.Input.Custom.GetPointDrawEventArgs类有Display方法,Rhino.Input.Custom.GetPointDrawEventArgs属于Rhino.Display.DisplayPipeline的成员。



                               
登录/注册后可看大图


因此就可以使用以下语法在Rhino视窗内进行即时显示:
point = Rhino.Input.Custom.GetPoint()
def func(sender,args):
  args.Display.DrawPoint(args.CurrentPoint,System.Drawing.Color.Blue)
point.DynamicDraw += func
point.Get()
以上point.DynamicDraw += func一句便是将gp.DynamicDraw方法与func函数进行事件委托,如果要取消委托可以用point.DynamicDraw -= func。
由于DynamicDraw方法只能向函数内传递一个参数,即GetPointDrawEventArgs,可以定义一个类来达到传递多个参数的方法,如以下例子
gp = Rhino.Input.Custom.GetPoint()
mypt = Rhino.Geometry.Point3d(1,2,3)
if( gp.Get() == Rhino.Input.GetResult.Point ):
  mypt = gp.Point()
  mypts = [mypt]
class MyGetPoint:
def __init__(self, pt, pts):
   self.point = pt
   self.points = pts
def DynDraw( self, sender, args ):
   if( self.point!=None ):
     for i in self.points:
         args.Display.DrawPoint(i,System.Drawing.Color.Blue)
myclass = MyGetPoint(mypt,mypts)
gp.DynamicDraw += myclass.DynDraw  
while( gp.Get() == Rhino.Input.GetResult.Point ):
   myclass.point = gp.Point()
   mypts.append(gp.Point())
   myclass.points = mypts
另外一个问题是取得鼠标事件,这个比较简单,其一本身GetPointDrawEventArgs就是一种鼠标事件,另外Rhino.Input.Custom.GetPointMouseEventArgs类型中有监听鼠标事件的方法,但是由于Rhino本身定义的鼠标右键为退出,因此只能采用左键和中键进行监听,至于键盘监听现在还没找到好办的方法,那些想在Rhino中玩游戏的最多只能用鼠标点点了。
以下为一个模拟点磁场线运动的例子,GIF显示卡大概是没有完全下载的原因,一共4000余根动态曲线,运行还是比较流畅,另外有两个研究过程中的例子和以上两个算法的完整代码。本研究仅是技术讨论范畴,并不代表建议用Rhino.Python来做Processcing的事情。使用这些代码请遵循非商业,署名,相同方式共享。



                               
登录/注册后可看大图




其他代码.rar

2.28 KB, 阅读权限: 10, 下载次数: 164, 下载积分: 照度 -1 lux

售价: 1 lux照度  [记录]

其他代码.rar

磁场线.py

3.66 KB, 阅读权限: 10, 下载次数: 42, 下载积分: 照度 -1 lux

售价: 1 lux照度  [记录]

磁场线.py

评分

参与人数 2强度 +2 照度 +8 收起 理由
外夏的晴雨花 + 3 很有启发!抱歉今天没强度了
claudemit + 2 + 5 感谢分享!

查看全部评分

分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏5 分享分享
2m
 楼主| 发表于 2013-8-23 20:38:03 | 只看该作者
NCF支持html编辑帖子就好了,从word上粘贴上来的东西全部变样,有些表格样式也不可能在里面编辑,还有代码部分如果没有html样式后面的教程还真不好办。
3m
发表于 2013-8-23 21:09:06 | 只看该作者
木有想到站到2楼了,这个有点不好意思哈
4m
发表于 2013-8-23 22:45:47 | 只看该作者
支持      
5m
发表于 2013-8-24 01:10:29 | 只看该作者
对事件这块一直很迷糊。楼主的案例很受启发
6m
发表于 2013-8-24 02:14:43 | 只看该作者
从来没用过.net编程中的事件与委托,学习了
期待大川兄的python系统教程^o^
7m
发表于 2013-8-24 10:39:16 | 只看该作者
好高深啊好高深,看不懂啊看不懂,只看得到他在动,哈哈~~
8m
发表于 2013-8-24 12:07:36 | 只看该作者
大川的帖子支持,只是看不懂啊,继续学习
9m
发表于 2013-8-24 23:25:13 | 只看该作者
lz。我有个问题。
gp.DynamicDraw += myclass.DynDraw  这个语句。gp.DynamicDraw 事件的参数列表是(sender,args),而myclass.DynDraw函数的参数列表是(self,sender,args)。为什么参数列表不同也可以进行事件委托。我印象好像必须一致才可以。
10m
发表于 2013-8-25 08:45:46 | 只看该作者
这个属于教程吗?一大堆英文看不懂啊,渺茫了
11m
 楼主| 发表于 2013-8-25 11:14:25 来自手机 | 只看该作者
tianrock2002 发表于 2013-8-24 23:25
lz。我有个问题。
gp.DynamicDraw += myclass.DynDraw  这个语句。gp.DynamicDraw 事件的参数列表是(send ...

python类方法中的第一个参数self是自身引用,实际上是一种显式指针。
12m
 楼主| 发表于 2013-8-25 11:15:04 来自手机 | 只看该作者
奥巴马 发表于 2013-8-25 08:45
这个属于教程吗?一大堆英文看不懂啊,渺茫了

不属于教程。
13m
发表于 2013-8-25 13:09:43 | 只看该作者
那sender是否为也为隐式指针。为什么在gp.DynamicDraw 事件里只能看到GetPointDrawEventArgs,看不到sender呢?
14m
发表于 2013-8-25 18:49:35 | 只看该作者

大川哥,能不能编一个程序,把gh生成的物件(不烘焙)直接从rhino工作平面保存成图片jpg呀?rhino中可以打印成jpg格式,但尝试了很久都没能解决批量处理。求大神指点,谢谢。
15m
 楼主| 发表于 2013-8-25 21:50:49 | 只看该作者
tianrock2002 发表于 2013-8-25 13:09
那sender是否为也为隐式指针。为什么在gp.DynamicDraw 事件里只能看到GetPointDrawEventArgs,看不到sender ...

sender是事件参量,比如说用户点击鼠标这个事件,eventargs是传递事件细节的参量
建议你查询下.net的event delegate,网上有很多资料。
16m
 楼主| 发表于 2013-8-25 21:55:03 | 只看该作者
wangjunxiong 发表于 2013-8-25 18:49
大川哥,能不能编一个程序,把gh生成的物件(不烘焙)直接从rhino工作平面保存成图片jpg呀?rhino中可以打 ...

slider里面的animate不就可以么。
17m
发表于 2013-8-25 23:02:20 | 只看该作者
wdc63 发表于 2013-8-25 21:55
slider里面的animate不就可以么。

我晕了!忘了这个!谢谢大川哥提醒!
18m
发表于 2013-8-26 00:09:44 | 只看该作者
嗯,网上看了一些。但是我还是很奇怪为什么rhinocommon里gp.DynamicDraw 事件里只能看到GetPointDrawEventArgs,而且是在尖括号里。看不到sender怎么回事?那个尖括号又是什么意思呢?
19m
 楼主| 发表于 2013-8-26 01:00:06 | 只看该作者
tianrock2002 发表于 2013-8-26 00:09
嗯,网上看了一些。但是我还是很奇怪为什么rhinocommon里gp.DynamicDraw 事件里只能看到GetPointDrawEventA ...

GetPointDrawEventArgs是一个EventHandler,.net中的EventHandler包含两个参数,定义如下:

public delegate void EventHandler<TEventArgs>(
        Object sender,
        TEventArgs e
)
20m
发表于 2013-8-26 13:22:46 | 只看该作者
感觉怪怪的。GetPointDrawEventArgs看名称应该是一个参数名啊,不像是EventHandler。

小黑屋|手机版|NCF参数化建筑论坛 ( 浙ICP备2020044100号-2 )    辽公网安备21021102000973号

GMT+8, 2024-4-25 18:55 , Processed in 0.123512 second(s), 25 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表