Model#raytest in C API

Just doing some initial research before deciding whether to delve further into the live C API…
What is the C equivalent of the Ruby Model#raytest method?

1 Like

I find no equivalent function in the C API. Please file a request in the API Tacker.

The C API has a struct SURay3D and searching for it only brings up it’s related generic geometric functions. We would think that this struct was intended to support the later implementation of firing rays through model entity collections.

You still may be able to do this with the C API for SketchUp v2020.2 and higher.
You’d call the Ruby API’s #raytest method via Ruby Core’s C API rb_eval or rb_func_call

See tracker thread:

How to talk between ruby `Value` and C-API `**Ref` · Issue #5 · SketchUp/sketchup-live-c-api · GitHub

Thanks Dan.
Yes I saw the doc for SURay3D and as you say, it only seems to be a data structure to describe a ray (a point and a vector), not to fire it into the model geometry and return a result.

Seems a little counter-intuitive to call a Ruby method from C! I was assuming there would be an initial performance benefit to be gained from using a C raytest method called from Ruby iterations (many different rays are used), then gradually add layers of iterations and processing that are currently done in Ruby.
But I guess there could possibly be a benefit from doing the iteration in C and calling the Ruby raytest?

We would hope that there would be a performance benefit. Perhaps @tt_su could weigh in ?

Well there is no choice if a C API function is not implemented. And then again, Ruby is itself implemented in C and SketchUp’s Ruby API consists of C wrapper calls into it’s C++ core.

Also see this forum thread in this category:

1 Like

The raytest wouldn’t really be that faster, whether called from the Ruby or C API, they’d both call into the internal C++ implementation. The overhead of calling the Ruby method would probably not be that significant in this case.

Do you have an example to go with this? When speaking of performance, it’s best to have something concrete to measure, otherwise it’d be mostly guesswork.

1 Like

Hi ThomThom,
When I remove some specifics, what it essentially boils down to is this:

results = vectors.collect { |vect|
    strike_point, obj_path = Model.raytest(orig, vect)
    vect if strike_point

where various arrays of vectors are iterated over, sending out rays into the model and collecting the results for some post-processing. There was a bit of trig maths going on inside the loop to compute the vectors, but I just realised that could be pre-calculated.

The raytest itself is performed in C++, so we’re not gaining a lot from a CAPI version of that. But if you are doing a lot of trig maths in Ruby, that is a good candidate for being slow in Ruby. In general I’d recommend to make use of the SU APIs methods to do any vector manipulation as that happens with C++ code. In my own extensions I’ve had to offload mathematical computation to a Ruby C Extension to get a performance boost. Other than that, cache calculations also yield a significant performance improvement.

What would be interesting is if you could run a profiler to exactly pin-point where your bottleneck is. If you haven’t tried the SpeedUp profiler tool, could you do that please?

1 Like

Yes that has definitely been on my todo-list in general, but particularly for this part of the code. I took a look a while ago but got a bit lost on how to set up…

Depending on how long ago you tried that there might be updates to the notes. If you give it another go and run into issues, can you please start a new thread and we can take it from there?

1 Like