NCF参数化建筑论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

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

[网络资源] 关于rhino编程的一些基础知识

[复制链接]
跳转到指定楼层
1m
发表于 2012-8-8 01:14:34 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
本帖最后由 zhouningyi1 于 2012-8-8 03:16 编辑

在苏麒大哥的帖子下,最近也开始看下gh c#,不过基础知识欠缺,比如厚厚的Rhino.Common,貌似连构架的介绍也没有,导致经常用错,在grasshopper3d上翻到些帖子 还不错,在这里陆续添加些笔记,很零散,理解也可能不对 请大家纠正,也希望能抛砖引玉

http://www.grasshopper3d.com/forum/topics/baking-breps-w-color

This is correct. Rhino is the main Namespace in our SDK. There's other namespaces inside Rhino, for example Rhino.Geometry and Rhino.Collections. Every type in .NET is part of some namespace. Namespaces only have one raison d'être, which is to group types into logical chunks.

A Type is the definition of a class or a structure. Classes and structures are very similar entities (they can both contain any number of methods, properties and other types), but because they behave differently, you need to know which is which.

An Instance of a type is a single object that actually exists. For example, the class Human is the definition of what it means to be human. You are an instance of this class. I am a different instance of this class. Damien is yet another instance of this class. Every instance can assign unique values to all its properties and fields. If for example the type Human had a property for height, then in my case it would say 1.97m. In Damien's case it would be set to something much less, as Damien isn't anywhere near as handsome and tall as I am.

A Reference is a piece of information that tells you where a certain instance is. Think of a reference as an address. When you mail a letter (or e-mail), you must specify a valid and unambiguous address or the letter won't arrive. Similarly, every piece of data stored in the memory of your computer also has a unique address, but instead of "3670, Woodland Park Avenue, Seattle", it looks like this 0x12345678. Trying to access an instance through an invalid reference is like sending a letter without an address.

References are sometimes also called "variables", though sometimes the word variable is only used to indicate primitive types, such as Booleans, Integers and such. A reference is not the instance itself. Take the following code:

1. Dim crv As Rhino.Geometry.Curve
2. Dim dup As Rhino.Geometry.Curve
3. crv = GetACurveFromSomewhere()
4. dup = crv
5. If (dup IsNot Nothing) Then dup = dup.DuplicateCurve()

One lines (1) and (2) I declare two references, one is called "crv", the other "dup". Because Visual Basic is a strongly typed language, I can assign limitations to what sort of data crv and dup are allowed to reference. In this case they can only point to instances of the Rhino.Geometry.Curve class or any class which derives from Rhino.Geometry.Curve (such as Rhino.Geometry.NurbsCurve, or Rhino.Geometry.LineCurve).

On line (3) I assign an actual curve instance to the crv reference/variable. At least, assuming the GetACurveFromSomewhere() function actually returns a proper instance. If it doesn't, crv will remain a "null reference".

Line (4) is interesting, because both crv and dup will now point to the same curve instance. So even though there is only 1 curve in memory, both crv and dup provide access to it. This means that when we change the curve via crv, then dup will notice that change.

On line (5) two things happen. I want to duplicate my curve data so I can change the data via dup, without affecting the data available via crv. The best way to duplicate a curve (i.e. create a second curve in memory, that has the same shape as the first curve) is to use the DuplicateCurve() method on the Rhino.Geometry.Curve class. However I cannot call a method on an instance that doesn't exist, so before I do that, I need to check whether or not dup actually points to a real curve object, or whether it is a null reference.

Finally, it is also possible to have an instance of a class in memory, without any references to it. In this case nobody can reach that curve any more and it is essentially dead weight, taking up pointless memory. In C++ this is called a Memory Leak and it's considered a serious bug. In VB.NET and C# this memory will automatically be cleaned up by the .NET Garbage Collector. In my opinion the Garbage Collector is the single most important feature in .NET. It's what turns VB and C# from frustration central into a friendly and flexible coding platform.
分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
收藏收藏4 分享分享
2m
发表于 2012-8-8 01:31:10 | 只看该作者
{:14:}~~~~~~~~~~~~~~~~~~~~~~~~~~~~·
3m
 楼主| 发表于 2012-8-8 02:48:14 | 只看该作者
关于curve

Rhino.Geometry.Curve is to be treated as an abstract class. There are lots of different kinds of curves but they are all derived from the Curve base class. NurbsCurve is only one of these.
The special thing about NurbsCurve is that it can represent every other type of curve to within maximum accuracy. Circles and Arcs can be converted to degree=2 nurbs curves with weighted control points. Lines and Polylines can be converted into degree=1 nurbs curves. Polycurves can be converted into arbitrary nurbs curves with multiple interior knots for kinks. This is why all curve types support conversion to Nurbs curves.
The benefit from the developer point of view is that when your algorithms work on nurbs curves, they can work on all curves. If you rely on control-points or spans, then you can always get those via the ToNurbsCurve() method.
4m
 楼主| 发表于 2012-8-8 02:50:24 | 只看该作者
关于Line并非Curve
Rhino.Geometry.Line is not a type of curve. As in; it doesn't derive from Rhino.Geometry.Curve. There is another type called LineCurve which does derive from Curve and which provides a wrapper around the Line structure.
Curve have a method called GetLength() which has several overloads. It allows you to both get the length of the whole curve, or a sub-curve
5m
 楼主| 发表于 2012-8-8 02:53:43 | 只看该作者
目前gh的sdk中并没有材质图层等种种属性

currently there are no colors, layers, linestyles or other attributes in the Grasshopper SDK
Reply by Giulio Piacentino on July 5, 2012 at 2:13am
6m
 楼主| 发表于 2012-8-8 02:58:53 | 只看该作者
目前的gh sdk并不全面
Reply by David Rutten on July 9, 2012 at 1:43am
It is possible to set all properties of the slider via the SDK. There are a lot of classes in Grasshopper that have not been included in the SDK Documentation. The entire Grasshopper.Kernel.Special namespace is missing.
7m
 楼主| 发表于 2012-8-8 03:02:59 | 只看该作者
目前犀牛尚不允许五边形以上的mesh

faces with more than four sides are usually called n-gons. If you were able to create a 5-sided mesh face in Rhino, there would be a good chance that you could do that in Python, too. But Rhino does not allow that at present. It might be added in the future due to user requests. Requests are welcome on the Rhino newsgroup: news://news.rhino3d.com/rhino
Right now, you can create Patches (trimmed surfaces, if there are only a few). Another workaround, maybe more suitable for many faces, could be to import all faces as polylines?
I hope this helps, at least a little.
8m
 楼主| 发表于 2012-8-8 03:09:23 | 只看该作者
可以将一些外部的类库导入犀牛(比如文中的CGAL),但前提是数据结构必须简单
It is possible to invoke methods in a C++ dll using C#. However this requires that all method calls only use very simple data types (booleans, integers, doubles, pointers or arrays of the above, not an exhaustive list). This is how RhinoCommon talks to the Rhino C++ SDK.
I haven't looked at CGAL code but it is quite likely that some sort of wrapper dll needs to be written in C++ that exposes the functionality via such simplified functions. This is both difficult and a lot of work.
Porting code over to C# may or may not be feasible depending on how CGAL was written. If it uses a lot of pointers, instances and references then it will be a cr*pload of work to port it correctly.
The problem with porting libraries like these is that functions -such as straight skeletons- often rely on many other parts of the library, so porting a small part of it is in fact impossible.
I don't fancy your chances in the short term. I think there's a lot of interest in providing a .NET version of CGAL but it doesn't seem like there's anything out there yet.
9m
 楼主| 发表于 2012-8-8 03:23:07 | 只看该作者
一个几何类型 例如line,在gh的datatree里,并不是line,而是以GH_Structure的形式存在的

The data inside the tree cannot be Line, because the type Line in RhinoCommon does not implement the IGH_Goo interface, which is a prerequisite of GH_Structure.
This is why there is a GH_Line class, which exposes the Line type while implementing the IGH_Goo interface. This is true for practically all data types in Grasshopper. Rhino.Geometry.Brep is wrapped up in GH_Brep. System.Double is wrapped up in GH_Number.
If you want to get at the actual data inside the wrapper classes, there's usually a Value property that provides getter/setter access to the real data stored inside the wrapper.
Dim edgeData As Data.GH_Structure(Of GH_Line) = Nothing
If (Not DA.GetDataTree(0, edgeData)) Then Return
Dim edge As Line = edgeData.Branches(0)(0).Value
Note that when you retrieve IGH_Goo type data from input parameters you get the original data. This data may be shared amongst many parameters and therefore you should not change this data. Unfortunately there is no constness in .NET so I cannot enforce this limitation without copying data and I want to copy data as little as possible due to overhead.
Incidentally, if you want to make sure that there are no exceptions thrown in the code, you should probably add more tests:
Dim edgeData As GH_Structure(Of GH_Line) = Nothing
If (Not DA.GetDataTree(0, edgeData)) Then Return
If (edgeData Is Nothing) Then Return
If (edgeData.PathCount = 0) Then Return
Dim edgeList As List(Of GH_Line) = edgeData.Branch(0)
If (edgeList Is Nothing) Then Return
If (edgeList.Count = 0) Then Return
Dim edgeWrap As GH_Line = edgeList(0)
If (edgeWrap Is Nothing) Then Return
Dim edge As Line = edgeWrap.Value
As you can see, working with GH_Structures will involve a lot of bookkeeping and validation.
10m
 楼主| 发表于 2012-8-8 03:30:49 | 只看该作者
初学者建议:
Well it was difficult for me in the beginning too! Still is to be honest... So here is my advice.

First I'd like to point that it's much easier to learn if you have a specific project. It's true for learning GH as well as scripting. In my case my first shot was a grandstand script, which requires a simple iteration. So try to pick something where you know what the result should be, and keep it simple! Grandstand is good ;)
.
You really need to have clear ideas. So if you want to start from the very beginning script something you already did in GH, then write a pseudo-code ie write the script in plain english (in french in my case!) draw diagrams and sketches...
.
Second, forget open nurbs and go here to the RhinoCommon SDK reference site. Its much more simple. That is if you want to stick with VB. I don't know Python at all but I was told it's even simpler.
Btw "functions" are called Methods.  They apply to Objects and they need Arguments - that's what's within brackets. Got it?   Object.method(arg1,arg2)
.
Third, don't bother with data trees, its difficult and not very useful in most cases. Usually you can manage with the access type in the inputs menu (item, list, tree) and basic GH post processing if you really need to. But remember, keep it simple in the beginning!
.
And fourth, there are plenty of examples on this forum, and lots of people willing to help, so use the search feild and post questions (with precise titles plz!!)
Good luck! you'll spend a few nights over it for sure :))
11m
发表于 2012-8-8 08:02:39 | 只看该作者
貌似您说的是VB,而不是c#,呵呵呵。

点评

说的是rhino common  发表于 2012-8-8 11:23
12m
发表于 2012-8-8 10:01:47 | 只看该作者
感谢分享。。。。。
13m
发表于 2012-8-8 11:11:20 | 只看该作者
rhino common没必要背吧  其它软件无法调用它

点评

了解个命名的规则 毕竟很难像你一样从最底层干起。。  发表于 2012-8-8 11:25
14m
 楼主| 发表于 2012-8-8 15:18:34 | 只看该作者
犀牛是用c++写得 而gh是vb.net和c#写得 c#和c++不一样 不能互相自动转译

C is an old language. It was developed in the early 1970's and it is quite primitive. Bjarne Stroustrup (among others) extended C with the notion of OOP and it became 'C with classes' or 'C plus plus'. C++ arose in the early 80's and it is the language in which Rhino itself is written. C# is the next major version in this language family and it is the one used in .NET development. C# first appeared somewhere around 2001 and has gone through 4 major upgrades since then.
Grasshopper is written in C# and VB.NET (which is the .NET flavour of the Visual Basic language family) and the script components also allow only C# and VB.NET, none of the other c-style or vb-style languages out there.
There is no way to flawlessly convert code from C++ to C#. The two languages have non-overlapping features. Simple mathematical algorithms though tend to be highly portable.
15m
 楼主| 发表于 2012-8-8 16:50:29 | 只看该作者
经常有个数据类型叫IEnumerable(Of T),搞的不是很清楚,求高手解释下 不过 在c#里 可以用list替代

IEnumerable(Of T) is an interface which indicates that whoever implements it represents a collection of objects that can be iterated over. List(Of T) already implements this interface, as do almost all collection based types in the .NET framework. I.e. when a function wants an IEnumerable(Of Point3d), you can feed it List(Of Point3d) or a Point3d array and it will all work.
16m
 楼主| 发表于 2012-8-8 17:43:14 | 只看该作者
gh中 tree的结构:

A Tree is stored as two synchronized lists. The first one is a sorted list of all the paths, the second is a matching list of List(Of T), where T is the type of the Tree. So when you retrieve tree1.Branch(0), all you get is a single list filled with items that are of type T, with no path information whatsoever. The {0;3;0} now comes from the internal data matching logic.
But each of these branches has a path of {0;3;0}
That doesn't seem right to me either... Is there something I'm missing?
These branches do no have a path of {0;3;0}. They don't have a path at all, they are just List(Of T) instances. The {0;3;0} is only assigned at the very last moment, when RunScript returns and Grasshopper figures out that you've assigning a list to A. Since the input is marked as Tree Access, it simply picks the first path it comes across.
If you want to have control over the data structure of your outputs, you must output DataTree(Of T) instances, and not just the branches of a DataTree.
17m
发表于 2012-8-8 18:10:39 | 只看该作者
感谢分享。。。。。
18m
 楼主| 发表于 2012-8-8 18:12:34 | 只看该作者
gh几乎就没多少几何函数 都在rhino.common里

Don't look in Grasshopper for geometric functionality. That's all RhinoCommon as Aaron pointed out. Grasshopper is 75% graphic interface and 24% solution accounting.
19m
 楼主| 发表于 2012-8-8 18:17:39 | 只看该作者
class(类)和struct(结构)的一些区别
the Interval type in RhinoCommon is a struct (Value Type), not a class (Reference Type). What this means is that when you ask a Curve for it's domain, you get a copy of the actual interval. Changing this copy doesn't accomplish anything and therefore the compiler won't let you do it.
20m
 楼主| 发表于 2012-8-8 18:29:29 | 只看该作者
不能trim surface 但可以trim brep
Surfaces in Rhino do not support trims. You'll always need to use Breps, and in case of surfaces just use breps with a single face.

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

GMT+8, 2024-5-5 14:57 , Processed in 0.333033 second(s), 24 queries , Gzip On.

Powered by Discuz! X3.2

© 2001-2013 Comsenz Inc.

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