Mass Addition component in C#

need to do the same as Mass Addition component but in C#, any help? thanks in advance.

I don’t see transform here in description, you say same as mass addition component. Mass addition component does not work on transformations.

Could you possibly mean that you want to do what the compound transformation component does?

what I need is this python operation but in C#, sorry for the confusion. (11.8 KB)

For visual studio or script editor?

You only need to change @Michael_Pryor script a little bit to get what you want:

Transform result = Transform.Identity;
List<Transform> partialResult = new List<Transform>();
foreach(Transform t in T)
  result = t * result ;
R = result;
Pr = partialResult;

Thomas (16.1 KB)

and I ask visual studio or script editor because in VS I would use GH_Transform which needs to multiply in the opposite way of Rhinocommon. GH components use GH_Transform so actually if you want to get these partial results to transform in the same order as GH you need to change the order of transforms first unless you use GH_Transform.

Mathematically, RhinoCommon matrices multiply in the correct way. Intuitively, Grasshopper transforms multiply in the correct way. If you want to first move, then scale, the order for a compound transform is (1) move (2) scale. To achieve the same with RhinoCommon transforms you need scale * move .

1 Like

Thanks, @Michael_Pryor. I didn’t know that.

1 Like

I think you might have to actually reverse the initial list of transforms as well to comply with correct order of operations? Have not tested it, it’s confusing to think about. :smiley: Seems easier to just use GH_Transform for this.

@Michael_Pryor Thank for correcting me continuously :grin:
I couldn’t figure it out how to add two objects of GH_Transform type, it seems that there is no Multiply method in this class like the one that we have in Rhinocommon Transform..

You use Compound.

Think of it like this:

thanks to @Michael_Pryor and @Mahdiyar, why the results are different from those of Python, (R and Pr). I mean that for my purpose Python works fine, but the C# and the cluster with standard compound produce different results. (21.7 KB)

The C# is correct actually The reasons are discussed above.

with Python version the result is wrong because rhinocommon transforms need to multiple backwards to be like grasshopper transforms. You won’t notice the wrong result with move (unless each move has different directions) but throw some other stuff in there like scale and rotate and the wrong results are clear.

C# version is correct in result because the C# changes
“result *= t” to “result = t * result” which is the correct order to multiple to get the result GH expects.

See attached: (16.1 KB)

C# versions partial results are correct as well: When used as a list in transform component you get the correct positions step by step with the order of our transforms from GH, with python version you do not. (23.5 KB)


Given the opportunity and having RhinoCommon in mind this is the general case with regard the Trans (non morph) 4*4 Matrix. Notice the difference VS the orthodox way (as exposed in the “majority” of literature) thus transpose is required.


Is that really how the C# operator works??

I would be really hesitant to call that “correct” behaviour, even if it is more intuitive coming from GH components. In every case of operator overloading I’ve encountered, x @= y is equivalent to x = x @ y (where @ is any binary operator). Messing with those semantics seems like a bad idea.

Especially when there are plenty of legitimate reasons to do right-multiplication as well as left-multiplication when it comes to transformation matrices - depending on whether you’re using them to represent object transforms or reference frame transforms. Neither should be considered the “canonical” way to do it.

Well im not saying the logic makes sense to be designed that way, what I’m saying is the end result is correct that way (if it is to conform with the order of operations of gh components). It’s not really C# vs Python either. It’s Rhinocommon vs GH_.

As David explained “. If you want to first move, then scale, the order for a compound transform is (1) move (2) scale. To achieve the same with RhinoCommon transforms you need scale * move .”

1 Like

Hmm, I might have misunderstood - was the Python code not using RhinoCommon? I thought there was a Python vs C# difference being demonstrated above ( can’t open the files right now - haven’t been using Rhino/GH for the past few months at my new job :confused: )

The Python is using Rhinocommon but in the wrong order that Rhinocommon needs. It is only Python because I guess he downloaded from the old thread you put it in. The language doesn’t matter here. The issue was that in the python component it is “result *= t” which seems how it should be logically (and how GH_Transform would use it) but Rhinocommon transforms need the opposite “result = t * result” for transform multiplying which is the code in the C# component. I only know this because that small nuance tripped me up in something I was coding and David explained it in the thread I linked above.

And you can see in the images I posted above with the way it is in the Python component the result (blue box) does not land where it should. The result from the C# component (white box) with the inverted multiplication does land in the correct place and has the proper partial result steps along the way.

So the difference is just “result * = t” vs “result = t * result”

1 Like

Actually I think the issue is that the compound assignment *= is syntax sugar that really should be avoided in cases like this where the underlying operator is noncommutative (x*y != y*x).
It’s easy to be conditioned by the familiar * scalar operator and gloss over the ambiguous (?) meaning of xform1 *= xform2.

In that other thread I’m pretty sure I was doing coordinate basis transformations, where multiplying additional transformations onto the right was the correct way of doing things. (as opposed to geometry transformations in fixed reference space as is being done here)

I’d definitely just spend the extra couple of keystrokes and type result = t * result or result = result * t to make the intention clear.


Where is Matrix Revolutions? :smiley:

Alas: The End occured first => adios amigos

Brobably for the best we never got there :rofl:

A disappointing conclusion to the Matrix trilogy
1 Like