Can I fire multiple rays at the same time using the raytest command?

Can I fire multiple rays at the same time using the raytest command?When there are more detection points, the program will run very slowly, and I want to be able to issue multiple ray inspections at the same time, or multi-threaded calls to the raytest command.I tried to call raytest multi-threaded, but it doesn’t seem to work, so let’s take a look at it.I call raytest to detect 24 dots of a circle, divided into two groups and run with two threads, the program did not report an error but the result did not come out
示例.skp (100.5 KB)

# Default code, use or delete...
mod = Sketchup.active_model # Open model
ent = mod.entities # All entities in model
sel = mod.selection # Current selection
detect_point = [[2.68, 4.22, 0.0], [3.68, 3.38, 0.0], [4.43, 2.32, 0.0], [4.88, 1.09, 0.0], [5.0, -0.21, 0.0], [4.77, -1.5, 0.0], [4.22, -2.68, 0.0], [3.38, -3.68, 0.0], [2.32, -4.43, 0.0], [1.09, -4.88, 0.0], [-0.21, -5.0, 0.0], [-1.5, -4.77, 0.0], [-2.68, -4.22, 0.0], [-3.68, -3.38, 0.0], [-4.43, -2.32, 0.0], [-4.88, -1.09, 0.0], [-5.0, 0.21, 0.0], [-4.77, 1.5, 0.0], [-4.22, 2.68, 0.0], [-3.38, 3.68, 0.0], [-2.32, 4.43, 0.0], [-1.09, 4.88, 0.0], [0.21, 5.0, 0.0], [1.5, 4.77, 0.0]]

detect_point1 = detect_point[0..11]
detect_point2 = detect_point[12..23]
occlusion_points_number1 = 0
occlusion_points_number2 = 0

result1=Thread.new do
  detect_time = Time.utc(2021,1,17,10,50,0)
  info=mod.shadow_info
  info["Displayshadows"]=true
  info["DisplayOnGroundPlane"]=true
  info["ShadowTime"]=detect_time
  info["Latitude"]=36.02
  info["Longitude"]=100.54
  direction_towards_sun = info["SunDirection"]
  detect_point1.length.times do |i|
    ray=[Geom::Point3d.new(detect_point1[i]),direction_towards_sun]
    ignore_hidden_geometry = false
    result01 = mod.raytest( ray, ignore_hidden_geometry )
    if result01==nil
    else
       occlusion_points_number1 +=1
    end 
  end
end


result2=Thread.new do
  detect_time = Time.utc(2021,1,17,10,50,0)
  info=mod.shadow_info
  info["Displayshadows"]=true
  info["DisplayOnGroundPlane"]=true
  info["ShadowTime"]=detect_time
  info["Latitude"]=36.02
  info["Longitude"]=100.54
  direction_towards_sun = info["SunDirection"]
  detect_point2.length.times do |i|
    ray=[Geom::Point3d.new(detect_point2[i]),direction_towards_sun]
    ignore_hidden_geometry = false
    result02 = mod.raytest( ray, ignore_hidden_geometry )
    if result02==nil
    else
       occlusion_points_number2 +=1
    end 
  end
end


result1.join
result2.join

I do not have so much experience with that but reading others, I concluded Threads in some way does not really work well within SU.


Some remark

I would do like this

    if result02
       occlusion_points_number2 +=1
    end 

If you really want to check if the result is nil you can use the .nil? method.

    if result02.nil?
      #do something
    else
       #do something else
    end 

BTW: Your attached skp file does not reach us… because you wrapped into preformatted code text.

Thank you for your reply, according to your link I browsed the relevant questions, I am pessimistic about using multi-threading to increase the detection speed, is there any way to call the raytest command to detect with multiple rays at the same time? If multiple rays could be emitted at the same time, should the inspection speed be accelerated?

The SketchUp Ruby API is not thread safe. I think we even have checks that might fail calls from even attempting to call SU API methods from threads other than main thread.

Also, Ruby threads aren’t working properly within SketchUp.

Have you profiled the code? And found raytest being the bottleneck?

1 Like

Thank you for your answer, I am more determined that I can not use multi-threading to optimize my code, but the number of points I detect is more intensive, I do ray detection of 45,000 points, cycle 150 inspections, how is the performance of this order of magnitude of computational ray inspection? Is there any way to optimize?

Do you have a non-threaded code example and a model you can share? When talking performance it’s best to have concrete examples as generic optimizations can be tricky.