sketchucation logo sketchucation
    • Login
    ℹ️ Licensed Extensions | FredoBatch, ElevationProfile, FredoSketch, LayOps, MatSim and Pic2Shape will require license from Sept 1st More Info

    Determine Whether a Point is 'in' a Volume

    Scheduled Pinned Locked Moved Developers' Forum
    8 Posts 6 Posters 1.2k Views 6 Watching
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • R Offline
      remus
      last edited by

      Is there any easy way of saying whether or not a given point is enclosed by some volume?

      I've got a cunning plan for a volume calculating plugin but it kind of relies on there being some easy way to do the above.

      http://remusrendering.wordpress.com/

      1 Reply Last reply Reply Quote 0
      • thomthomT Offline
        thomthom
        last edited by

        This is something I've been meaning to ask myself. Paying close attention to this topic.

        Thomas Thomassen β€” SketchUp Monkey & Coding addict
        List of my plugins and link to the CookieWare fund

        1 Reply Last reply Reply Quote 0
        • TIGT Offline
          TIG Moderator
          last edited by

          @remus said:

          Is there any easy way of saying whether or not a given point is enclosed by some volume?
          I've got a cunning plan for a volume calculating plugin but it kind of relies on there being some easy way to do the above.

          I've already done a couple of volume calculating scripts using quite different approaches...
          To check if a point is inside a volume do a 'raytest'...
          raytest=model.raytest(point,[1,0,0])
          This vector [1,0,0] shouldn't matter if its a 'manifold' shape - alternatively you could use [0,0,-1] to look straight down - unless your shape might be bottomless etc !!!
          raytest returns a 2 item array or nil if the ray misses everything and hits nothing.
          raytest[0] is the point where the ray hit something.
          raytest[1] is an array giving the hit object and perhaps its container, and its container's container etc etc e.g. [group, component_instance, group, face]
          So raytest[1][-1] is the thing that was 'hit' by the ray e.g. a face
          and its container is raytest[1][-2] etc
          whereas raytest[1][0] is the main container - if it's a lone face in the model it has no container and the array has only one item ...
          You'll need to test that what's hit is in the selection or group entities etc being analyzed etc...

          TIG

          1 Reply Last reply Reply Quote 0
          • R Offline
            remus
            last edited by

            Hmmm, all sounding pretty computationally intensive at the moment.

            The original idea was to check lots of points in the bounding box of the object and see what proportion of them are in the volume, then take that proportion of the volume. I think some testing is in order.

            Thanks for the tips TIG πŸ‘

            Oh and i dont mean for the script to compete with yours, its more of an exercise than anything πŸ‘

            http://remusrendering.wordpress.com/

            1 Reply Last reply Reply Quote 0
            • W Offline
              Whaat
              last edited by

              @tig said:

              I've already done a couple of volume calculating scripts using quite different approaches...
              To check if a point is inside a volume do a 'raytest'...
              raytest=model.raytest(point,[1,0,0])
              This vector [1,0,0] shouldn't matter if its a 'manifold' shape - alternatively you could use [0,0,-1] to look straight down - unless your shape might be bottomless etc !!!
              raytest returns a 2 item array or nil if the ray misses everything and hits nothing.
              raytest[0] is the point where the ray hit something.
              raytest[1] is an array giving the hit object and perhaps its container, and its container's container etc etc e.g. [group, component_instance, group, face]
              So raytest[1][-1] is the thing that was 'hit' by the ray e.g. a face
              and its container is raytest[1][-2] etc
              whereas raytest[1][0] is the main container - if it's a lone face in the model it has no container and the array has only one item ...
              You'll need to test that what's hit is in the selection or group entities etc being analyzed etc...

              This is essentially the foundation for my BoolTools script. One pitfall though is self-intersections caused by floating point precision errors. You can get around this by 'nudging' the ray origin a very small distance after it intersects a face.

              Performing one raytest is not enough. Once you find an intersection, you have to do another raytest using the intersection point as the origin (remember to nudge the origin).

              A point will be inside a manifold mesh if a ray intersects the faces of the mesh an odd number of times.

              SketchUp Plugins for Professionals

              1 Reply Last reply Reply Quote 0
              • Dan RathbunD Offline
                Dan Rathbun
                last edited by

                @remus said:

                The original idea was to check lots of points in the bounding box of the object and see what proportion of them are in the volume, then take that proportion of the volume.

                IF the object is box-like, it would be very easy.

                pt=[1,2,3] bb=obj.bounds in_volume=bb.contains?(pt)

                Unfortunately, not all volumes can be box-like and aligned with the x,y,z axes.

                I'm not here much anymore.

                1 Reply Last reply Reply Quote 0
                • TIGT Offline
                  TIG Moderator
                  last edited by

                  I also use similar techniques to check if a shape is 'inside-out'.
                  Make a group of the surfaces.
                  Find the topmost face of that envelope [comparing face.bb.max.z and then face.bb.min.z].
                  Find a point on it's surface [sometimes easier said than done - I use the mid-point between vertices[0] and vertices[2] as the bb.center is unreliable].
                  Find that face's normal.
                  Do a raytest from that point using this normal as the vector.
                  If it intersects with nil then the surface faces outwards
                  It it intersects with something that belongs to the group it faces inwards.
                  If it intersects with 'something else' repeat the raytest from the new intersection point using the same vector until it returns the group - then it faces inwards or nil and then it faces outwards...
                  If it faces inwards reverse all of its faces...

                  TIG

                  1 Reply Last reply Reply Quote 0
                  • icehuliI Offline
                    icehuli
                    last edited by

                    is there a better solution for this now?

                    1 Reply Last reply Reply Quote 0
                    • 1 / 1
                    • First post
                      Last post
                    Buy SketchPlus
                    Buy SUbD
                    Buy WrapR
                    Buy eBook
                    Buy Modelur
                    Buy Vertex Tools
                    Buy SketchCuisine
                    Buy FormFonts

                    Advertisement