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. 作者: 肃画 时间: 2012-8-8 01:31
{:14:}~~~~~~~~~~~~~~~~~~~~~~~~~~~~·作者: zhouningyi1 时间: 2012-8-8 02:48
关于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.作者: zhouningyi1 时间: 2012-8-8 02:50
关于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作者: zhouningyi1 时间: 2012-8-8 02:53
目前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作者: zhouningyi1 时间: 2012-8-8 02:58
目前的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.作者: zhouningyi1 时间: 2012-8-8 03:02
目前犀牛尚不允许五边形以上的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.作者: zhouningyi1 时间: 2012-8-8 03:09
可以将一些外部的类库导入犀牛(比如文中的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.作者: zhouningyi1 时间: 2012-8-8 03:23
一个几何类型 例如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.作者: zhouningyi1 时间: 2012-8-8 03:30
初学者建议:
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 :))作者: wangjunxiong 时间: 2012-8-8 08:02
貌似您说的是VB,而不是c#,呵呵呵。作者: paul丶wu 时间: 2012-8-8 10:01
感谢分享。。。。。作者: panhao1 时间: 2012-8-8 11:11
rhino common没必要背吧 其它软件无法调用它作者: zhouningyi1 时间: 2012-8-8 15:18
犀牛是用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. 作者: zhouningyi1 时间: 2012-8-8 16:50
经常有个数据类型叫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.作者: zhouningyi1 时间: 2012-8-8 17:43
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.作者: angel120317 时间: 2012-8-8 18:10
感谢分享。。。。。作者: zhouningyi1 时间: 2012-8-8 18:12
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. 作者: zhouningyi1 时间: 2012-8-8 18:17
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.作者: zhouningyi1 时间: 2012-8-8 18: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.作者: zhouningyi1 时间: 2012-8-9 02:04 本帖最后由 zhouningyi1 于 2012-8-9 11:15 编辑
List是一个接口,而ListArray是一个类;
ListArray继承并实现了List;
所以List不能被构造,但可以向上面那样为List创建一个引用,而ListArray就可以被构造。
List list; //正确 list=null;
List list=new List(); // 是错误的用法
List list = new ArrayList();这句创建了一个ArrayList的对象后把上溯到了List。此时它是一个List对象了,有些ArrayList有但是List没有的属性和方法,它就不能再用了。
而ArrayList list=new ArrayList();创建一对象则保留了ArrayList的所有属性。
这是一个例子:
import java.util.*;
public class TestList{
public static void main(String[] args){
List list = new ArrayList();
ArrayList arrayList = new ArrayList();
问题的关键是:
为什么要用 List list = new ArrayList() ,而不用 ArrayList alist = new ArrayList()呢?
问题就在于List有多个实现类,现在你用的是ArrayList,也许哪一天你需要换成其它的实现类,如 LinkedList或者Vector等等,这时你只要改变这一行就行了:
List list = new LinkedList(); 其它使用了list地方的代码根本不需要改动。
假设你开始用 ArrayList alist = new ArrayList(), 这下你有的改了,特别是如果你使用了 ArrayList特有的方法和属性。
地区用 List arr = new ArrayList();定义;行业用 ArrayListarr = new ArrayList();定义;则说明,行业里用到了ArrayList的特殊的方法.