[Info] Ambient Occlusion -> Simple Rays
-
Hello there.
Since I need to calculate sun exposure time in my current project I've added this functionality to the plugin. Here you can see an example. Yellow corresponds to 10h exposure, blue is no exposure.
It is based on peculiar polish building code (which requires an apartment to have at least 3 hours of direct sunlight on vernal equinox between 7am and 5pm) making this version useful in Poland. It can be easily adjusted though to fit any location and sun position.ps. My previous question is still actual - Would doing the raytest in Javascript via Webdialog be faster than Ruby?
-
@qpik said:
How about doing the raytest in Javascript via Webdialog?
Would that be faster than Ruby?To get this to happen at all in Ruby is heroic. I'm impressed.
Neither Ruby nor JavaScript is a compiled language. C++ may be an order of magnitude better.
-
Does anyone know if there is a way of creating a faster replacement for
model.raytest
method?
I've found a Ruby PNG library. That's a step towards layering textures in Sketchup (using PNG alpha).
Kuba
ps. Would anybody like to cooperate on this plugin?
-
This is really amazing. I mean, if you could do the raytesting separately with a faster language, it'd be really useful.
-
The
.raytest
method is running in SU's C. Not calculated using Ruby. Ruby just calls the C method. -
Does that mean that
model.raytest
algorithm is inherently slow?
So I would need to write my own in C. -
What I meant was that the
.raytest
is probably written in C already. -
Yeah, to make it faster wouldn't you need to export the geometry so an external routine could both loop and perform the raytest?
-
But I would have to export geometry for that one external routine.
Is there other way?@thomthom said:
What I meant was that the
.raytest
is probably written in C already.I've got that, I just wonder what makes it slow then and how to write a faster one.
I guess I have to prepare myself for switching to C. Even for my simple use, which is lately sunlight exposure analysis, it's simply too slow, when run on part of the city centre model.
Kuba
ps. Many thanks for all the help so far.
-
@thomthom said:
The
.raytest
method is running in SU's C. Not calculated using Ruby. Ruby just calls the C method.Ok.
I guess I don't know what I'm talking about, but doesn't SU's raytest method extract more information than you need for your plugin? Maybe that's why it's so (comparatively) slow.
-
Possibly. I guess it depends on what you need it for.
-
@wacov said:
I guess I don't know what I'm talking about, but doesn't SU's raytest method extract more information than you need for your plugin? Maybe that's why it's so (comparatively) slow.
I thought exactly the same, as it returns "the first thing that the ray hits". I suppose it means "the closest thing". For my purpose it's enough to get first-on-the-list hit end exit.
That might do the trick. -
I quickly wrote this, but it worked MUCH slower than original method.
def raytest2 ray hit = false entities = self.entities entities.each { |face| if face.kind_of?(Sketchup;;Face) and face.classify_point(ray[0]) > 4 plane = [face.vertices[0].position, face.normal] intersection = Geom.intersect_line_plane(ray, plane) if intersection and face.classify_point(intersection) < 8 hit = true break end end } return hit end
This could be optimized by passing pre-sorted face array (based on results from previous tests) instead of browsing entities array, but I doubt it would speed it up much.
What do you think? -
@qpik said:
plane = [face.vertices[0].position, face.normal]
You can use
face.plane
instead@qpik said:
This could be optimized by passing pre-sorted face array (based on results from previous tests) instead of browsing entities array, but I doubt it would speed it up much.
What do you think?hmm... If you only iterate the entities collection once then it won't help to pre-process to filter out only faces. Infact, that would mean more iterations. But if you need to iterate the face multiple times, then you will save time on pre-filtering.
@qpik said:
I thought exactly the same, as it returns "the first thing that the ray hits". I suppose it means "the closest thing". For my purpose it's enough to get first-on-the-list hit end exit.
Isn't that the same thing?
@qpik said:
I quickly wrote this, but it worked MUCH slower than original method.
You're writing a ruby method to be faster than a C method - that C method must be doing a lot of extra processing in order to be able to out-perform it in Ruby.
-
@thomthom said:
You can use
face.plane
insteadSomehow I didn't notice that one in the API
@thomthom said:
hmm... If you only iterate the entities collection once then it won't help to pre-process to filter out only faces. Infact, that would mean more iterations. But if you need to iterate the face multiple times, then you will save time on pre-filtering.
I meant to sort the collection before proceeding to the next testing point. The faces that got hit before might as well be the first to get hit by rays cast from adjacent point.
@thomthom said:
@qpik said:
I thought exactly the same, as it returns "the first thing that the ray hits". I suppose it means "the closest thing". For my purpose it's enough to get first-on-the-list hit end exit.
Isn't that the same thing?
I suppose
model.raytest
doesn't break after first positive ray hit, but returns the closest one from an array of all.@thomthom said:
@qpik said:
I quickly wrote this, but it worked MUCH slower than original method.
You're writing a ruby method to be faster than a C method - that C method must be doing a lot of extra processing in order to be able to out-perform it in Ruby.
That is certainly true. That is why I managed to connect with a DLL using
Win32api.call
(BTW thanks to TBD for his SUDLL example).
Now I'm on my way to moving everything to C. I hope this will finally give a speed boost.I'm looking into Ruby-OpenGL as well for another approach.
Here is an example - http://forums.sketchucation.com/viewtopic.php?f=180&t=20893&p=209966#p209966 -
@qpik said:
I suppose model.raytest doesn't break after first positive ray hit, but returns the closest one from an array of all.
that would be very odd. if it did produce a full array before returning I think it should return the full array.
-
But then how would it find out the closest intersection?
ps. I write all this out of my head, I'm not familiar with 3d algorithms.
-
@qpik said:
I suppose
model.raytest
doesn't break after first positive ray hit, but returns the closest one from an array of all.I think it does break after first positive hit. Make sure you check if the object is not hidden or on a hidden layer, otherwise your rays will stop too early when hidden layer present in a model.
-
Yeah, but how would the method know if the first hit is the closest?
It could be for example some distant face that got hit first, because it was first in the collection. -
Did you ever find any improvements that could be made?
Advertisement