Measure the surface of what is visible from a specific position?


#1

Hi together,
I created an object consisting of many cubes next and on top of eachother separated by a constant distance. I would like to know if it is possible to exactly measure the visible surfaces. When I walk around, kneel down or stand on a podest, obviously I have a different angle of view and thus can see different parts of the surfaces of my cubes, while other parts will be hiden by the previous cube. Is it possible to calculate exactly how many millimeters of “cube A” is visible from a specific position? I am very interested and hope you can help me.

Your help is very much appreciated.
Jean


#2

The API has no direct way to tell from an entity whether it can be seen. Another challenge are partially occluded entities.
You need to do a raycasting approach…


#3

…like this:

module AE

  module SketchUpHelpForum

    def self.get_visible_area(entity, step_size=1)
      model = entity.model
      view = model.active_view
      area = 0
      # Scan the viewport.
      (0..view.vpwidth).step(step_size){ |x|
        (0..view.vpheight).step(step_size){ |y|
          # Cast a ray to test whether it hits geometry...
          ray = view.pickray(x, y)
          hit = model.raytest(ray, false)
          unless hit.nil?
            point, path = *hit
            # ...and check whether it has hit a face of the desired entity.
            if path.include?(entity)
              face = path.last
              if face.is_a?(Sketchup::Face)
                # Create four rays through the corners of the pixel.
                plane = [point, face.normal]
                rays = [ view.pickray(x, y),
                         view.pickray(x, y+step_size),
                         view.pickray(x+step_size, y+step_size),
                         view.pickray(x+step_size, y) ]
                # Intersect them with the face's plane.
                points = rays.map{ |ray| Geom.intersect_line_plane(ray, plane) }.compact
                # Calculate the area of the resulting quadrilateral.
                if points.length == 4
                  area += 0.5 * ( points[0].vector_to(points[2]) * points[1].vector_to(points[3]) ).length
                end
              end
            end
          end
        }
      }
      return area # in square inch
    end

  end # module SketchUpHelpForum

end # module AE

Cool challenge!

To get a reference to your entity, select it (if all your boxes are for example in one group):
entity = Sketchup.active_model.selection[0]
And then paste into the ruby console:
AE::SketchUpHelpForum::get_visible_area(entity)

If you want it run faster (but some % less precise), you can do:
AE::SketchUpHelpForum::get_visible_area(entity, 10)
To have the result in square milimeters (instead of square inch), do:
AE::SketchUpHelpForum::get_visible_area(entity).to_mm.to_mm


#4

Hi Aerilius,
thanks for your answer. I’ll try and see if I can do it. By now I don’t understand much. If I need more help, I would be happy to ask you more.
Thanks,
Jean