Ruby c extension and Sketchup Objects
-
I created a ruby c extension and I know how to use primitive types (int arrays...) as parameter in the functions I created in c.
But is there any way to use a Sketchup object in a parameter? (like an entity) How can I decode the VALUE on the c side? Do I need a struct that fits the EXACT implementation of the object? Can I find that implementation?
Thank you
-
Ok I found a way to achieve that. Here is an exemple with the Sketchup class Geom::Point3d
static VALUE AddOne( VALUE self, VALUE p1 ) { VALUE point; VALUE rbGeom, rbPoint3d; float x,y,z; //Convert to c float x = NUM2DBL(rb_funcall( p1, rb_intern( "x" ), 0 )) + 1; y = NUM2DBL(rb_funcall( p1, rb_intern( "y" ), 0 )) + 1; z = NUM2DBL(rb_funcall( p1, rb_intern( "z" ), 0 )) + 1; //Convert back to ruby VALUE rbGeom = rb_define_module( "Geom" ); rbPoint3d = rb_define_class_under( rbGeom, "Point3d", rb_cObject ); point = rb_funcall( rbPoint3d, rb_intern( "new" ), 3, rb_float_new(x), rb_float_new(y), rb_float_new(z) ); return point; }
This code takes a Point3d as parameter, adds one to each value and return the resulting Sketchup ruby object.
-
You might want to make sure the user passed a Point3d object to your function.
Chris Lalancette got a nice series that digs into creating Ruby C Extensions:
http://clalance.blogspot.no/2011/01/writing-ruby-extensions-in-c-part-1.htmlWe recently released Ruby C++ Extension examples that include Visual Studio and Xcode projects as well as the exact binaries we use for SketchUp:
https://github.com/SketchUp/ruby-c-extension-examples -
I find this point conversion useful, along with SketchUp Ruby C Extension / src / Example - Basics / SXBasics.c by Thom, which demonstrates conversion from SU Point3d to C.
@tt_su said:
You might want to make sure the user passed a Point3d object to your function.
Is there a way to check if passed item is a Point3d object?
Edit: I think it really doesn't matter because user may also pass their custom point3d classes or just an array. The rb_funcall( v_point, rb_intern("x"), 0 ) should do the job and raise an error if v_point doesn't respond to
.x
method. -
Also, is SketchUp Length class handled well when it comes to converting it using NUM2DBL, or I should first convert it to float before passing to a c extension?
-
-
@anton_s said:
Also, is SketchUp Length class handled well when it comes to converting it using NUM2DBL, or I should first convert it to float before passing to a c extension?
Yes. Prior to SU2015 Length was hacked to be a subclass of Float. Now - that's not really possible in Ruby, but it was still done.
In 64bit Ruby that broke and we had to change it, it is now a Numeric which forwards to Float. Because of duck typing NUM2DBL should work. -
Thank you Thom.
Advertisement