Move points to a '3D grid'

Move points to a '3D grid'

Postby rossthompson » Mon Mar 26, 2012 12:10 pm

Hi,

I am trying to write a script for cleaning up geometery created from another program (IES VE). Essentially what I want to achieve is to move each vertex so it sits on a '3D grid'. I believe this could be achieved by applying a rounding function to the X,Y and Z coordinates of each point.

The attached image hopefully illustrates what I am trying to achieve. Ideally the degree of rounding would be a user input variable.

Any help on this would be greatly appreciated.

Ross
0

rossthompson 
 

Re: Move points to a '3D grid'

Postby gilles » Mon Mar 26, 2012 12:51 pm

You can use the scale tool: begin to scale then type 400mm;400mm;400mm + enter.

Note that the separator may be "," for you .
0
" c'est curieux chez les marins ce besoin de faire des phrases "
User avatar
gilles 
Top SketchUcator
 

Re: Move points to a '3D grid'

Postby thomthom » Mon Mar 26, 2012 12:57 pm

gilles wrote:You can use the scale tool:

rossthompson wrote:I am trying to write a script
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: Move points to a '3D grid'

Postby thomthom » Mon Mar 26, 2012 1:01 pm

This is a nice idea - I might implement such a feature in Vertex Tools.

Of the top of my head, something like this:

pt = Geom::Point3d.new( 3.976879, 3.970209, 1.002568 )
grid_pt = pt.to_a.map { |n| n.round() }
v = pt.vector_to( grid_pt )


You can do something like that - iterate the vertices of a mesh, for each vertex find the nearest grid position to the vertex, collect the vertex and adjustment vector to each their array and use Entities.transform_by_vectors https://developers.google.com/sketchup/ ... by_vectors

Note that this simple example rounded to nearest whole number. Modifications is needed to account for grids fitted to decimal precision.
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: Move points to a '3D grid'

Postby thomthom » Mon Mar 26, 2012 1:01 pm

Actually, that example will round to nearest inch - which is SketchUp's internal unit...
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: Move points to a '3D grid'

Postby thomthom » Mon Mar 26, 2012 1:15 pm

Code: Select all
pt = Geom::Point3d.new( 3.976879.m, 3.760209.m, 1.002568.)
tolerance = 0.25.m
grid_pt 
= pt.to_a.map { |n|
  b = ( n / tolerance ).to_i * tolerance
  r 
= n % tolerance
  
(> tolerance / 2) ? b + tolerance : b
}
grid_pt = Geom::Point3d.new( *grid_pt )

puts "Original: #{pt}"
puts "Tolerance: #{tolerance}"
puts "Grid Point: #{grid_pt}" 


Output:
Original: (3976,879mm, 3760,209mm, 1002,568mm)
Tolerance: 250mm
Grid Point: (4000mm, 3750mm, 1000mm)
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: Move points to a '3D grid'

Postby thomthom » Mon Mar 26, 2012 1:35 pm

Test module - adjust the vertices in the active context to grid.

Code: Select all
module GridSnap

  def self
.round_pointpointtolerance )
    
grid_pt point.to_a.map { |n|
      
= ( tolerance ).to_i tolerance
      r 
tolerance
      
(tolerance 2) ? tolerance b
    
}
    
Geom::Point3d.new( *grid_pt )
  
end
  
  def self
.test_it
    pt 
Geom::Point3d.new( 3.976879.m3.760209.m1.002568.)
    
tolerance 0.25.m
    grid_pt 
self.round_pointpttolerance )
    
    
puts "Original: #{pt}"
    
puts "Tolerance: #{tolerance}"
    
puts "Grid Point: #{grid_pt}"
  
end
  
  def self
.adjust_verticestolerance 0.25.)
    
model Sketchup.active_model
    vertices 
= []
    
# Collect vertices.
    
for e in model.active_entities
      vertices 
<< e.vertices if e.is_a?( Sketchup::Edge )
    
end
    vertices
.flatten!
    
vertices.uniq!
    
# Calculate grid adjustments.
    
vectors = []
    
entities = []
    for 
vertex in vertices
      pt 
vertex.position
      grid_pt 
self.round_pointpttolerance )
      
vector pt.vector_togrid_pt )
      
next unless vector.valid?
      
entities << vertex
      vectors 
<< vector
    end
    
# Apply transformations
    
model.active_entities.transform_by_vectorsentitiesvectors )
    
puts "#{entities.size} adjusted to grid."
  
end

end
0
Thomas Thomassen — SketchUp Monkey & Coding addict
List of my plugins and link to the CookieWare fund
User avatar
thomthom 
PluginStore Author
PluginStore Author
 

Re: Move points to a '3D grid'

Postby Dan Rathbun » Mon Mar 26, 2012 1:54 pm

How about that ??

... from concept to module in under a hour. :thumb:
0
    I'm not here much anymore. But a PM will fire email notifications.
    User avatar
    Dan Rathbun 
    PluginStore Author
    PluginStore Author
     

    Re: Move points to a '3D grid'

    Postby TIG » Mon Mar 26, 2012 2:02 pm

    Could this then be a tiny step towards a poly-reducer?
    As the vertices are 'rationalized' onto a 'grid' some faces could become coplanar and therefore the superfluous shared edges could be removed.
    The fineness/coarseness of this 'grid' removes less/more 'detailing'... :?
    0
    TIG
    User avatar
    TIG 
    Global Moderator
     

    Re: Move points to a '3D grid'

    Postby thomthom » Mon Mar 26, 2012 2:09 pm

    Cubificator?

    I was thinking it might be usable to repair troublesome model imported from CAD drawings. Occasionally I run into models where splitting a face with an edge results in duplicate faces. I suspect its due to some precision errors. Maybe if the vertices where adjusted to fit to a finely grained 3D grid the troubles would go away... ?
    0
    Thomas Thomassen — SketchUp Monkey & Coding addict
    List of my plugins and link to the CookieWare fund
    User avatar
    thomthom 
    PluginStore Author
    PluginStore Author
     

    Re: Move points to a '3D grid'

    Postby rossthompson » Mon Mar 26, 2012 3:13 pm

    ThomThom thanks so much for your support! I have had a go at running your test module. My understanding is that it should shift the points in the active selection to a 0.25m grid as specified in the code.

    However I am having problems running the module. I have attempted to add it to the tools menu as below, but I am not 100% sure how to 'call' the routine. Appologies if I'm being an idiot - I am new to ruby scripting!

    Code: Select all
        module GridSnap

          def self.round_point( point, tolerance )
            grid_pt = point.to_a.map { |n|
              b = ( n / tolerance ).to_i * tolerance
              r = n % tolerance
              (r > tolerance / 2) ? b + tolerance : b
            }
            Geom::Point3d.new( *grid_pt )
          end
         
          def self.test_it
            pt = Geom::Point3d.new( 3.976879.m, 3.760209.m, 1.002568.m )
            tolerance = 0.25.m
            grid_pt = self.round_point( pt, tolerance )
           
            puts "Original: #{pt}"
            puts "Tolerance: #{tolerance}"
            puts "Grid Point: #{grid_pt}"
          end
         
          def self.adjust_vertices( tolerance = 0.25.m )
            model = Sketchup.active_model
            vertices = []
            # Collect vertices.
            for e in model.active_entities
              vertices << e.vertices if e.is_a?( Sketchup::Edge )
            end
            vertices.flatten!
            vertices.uniq!
            # Calculate grid adjustments.
            vectors = []
            entities = []
            for vertex in vertices
              pt = vertex.position
              grid_pt = self.round_point( pt, tolerance )
              vector = pt.vector_to( grid_pt )
              next unless vector.valid?
              entities << vertex
              vectors << vector
            end
            # Apply transformations
            model.active_entities.transform_by_vectors( entities, vectors )
            puts "#{entities.size} adjusted to grid."
          end

        end

    # Menu Entry:

    UI.menu("Tools").add_item("GridSnap") { GridSnap } if not file_loaded?("GridSnap.rb")
    file_loaded("GridSnap.rb")





    I think this could be a very useful tool for cleaning many types of imported geometry.

    Ross
    0

    rossthompson 
     

    Re: Move points to a '3D grid'

    Postby Dan Rathbun » Mon Mar 26, 2012 3:21 pm

    thomthom wrote:Cubificator?

    Polyhedronizer ?

    Orthogonizer ?

    Orthographizer ?

    OrthograFixer ?

    :lol:
    0
      I'm not here much anymore. But a PM will fire email notifications.
      User avatar
      Dan Rathbun 
      PluginStore Author
      PluginStore Author
       

      Re: Move points to a '3D grid'

      Postby TIG » Mon Mar 26, 2012 3:24 pm

      In case TT is away...
      Inside the code making the menu use
      {GridSnap.adjust_vertices(1.cm)}
      It affects the whole model.
      This example uses 1cm grid
      Use another 'tolerance' if desired...
      If you use () it defaults to 0.25m anyway...
      It's only some example code and could be better assembled into something working on a selection with warnings and an 'undo' ???
      0
      TIG
      User avatar
      TIG 
      Global Moderator
       

      Re: Move points to a '3D grid'

      Postby TIG » Mon Mar 26, 2012 3:43 pm

      Not sure this reduced poly rock is so good ?
      Cuboidalizer.PNG
      'Cuboidalizer' is another name idea too... that or 'Discombobulizer' :shock:
      0
      TIG
      User avatar
      TIG 
      Global Moderator
       

      Re: Move points to a '3D grid'

      Postby Dan Rathbun » Mon Mar 26, 2012 3:49 pm

      Here's a beta version with an inputbox and undo operation...

      It seemed to only change a cubes vertices in the Z axis ??
      Code: Select all
      module GridSnap

        @@last_tolerance = 0.25.m

        class << self # PROXY CLASS

          def round_point( point, tolerance )
            grid_pt = point.to_a.map { |n|
              b = ( n / tolerance ).to_i * tolerance
              r = n % tolerance
              (r > tolerance / 2) ? b + tolerance : b
            }
            Geom::Point3d.new( *grid_pt )
          end
         
          def test_it
            pt = Geom::Point3d.new( 3.976879.m, 3.760209.m, 1.002568.m )
            tolerance = @@last_tolerance
            grid_pt = round_point( pt, tolerance )
           
            puts "Original: #{pt}"
            puts "Tolerance: #{tolerance}"
            puts "Grid Point: #{grid_pt}"
          end
         
          def adjust_vertices( tolerance = @@last_tolerance )
            model = Sketchup.active_model
            vertices = []
            # Collect vertices.
            for e in model.active_entities
              vertices << e.vertices if e.is_a?( Sketchup::Edge )
            end
            vertices.flatten!
            vertices.uniq!
            # Calculate grid adjustments.
            vectors = []
            entities = []
            for vertex in vertices
              pt = vertex.position
              grid_pt = round_point( pt, tolerance )
              vector = pt.vector_to( grid_pt )
              next unless vector.valid?
              entities << vertex
              vectors << vector
            end
            # Apply transformations
            model.active_entities.transform_by_vectors( entities, vectors )
            puts "#{entities.size} adjusted to grid."
          end
         
          def menu_command()
            title   = 'Adjust Vertices'
            prompt  = 'Tolerance'
            default = @@last_tolerance
           
            result = UI.inputbox([prompt],[@@last_tolerance],title) rescue @@last_tolerance
            if result
              begin
                ###
                Sketchup.active_model.start_operation("#{title} (#{Sketchup.format_length(result[0])})")
                #
                adjust_vertices( result[0] )
                #
                ###
                Sketchup.active_model.commit_operation()
              rescue
                Sketchup.active_model.abort_operation()
              else
                @@last_tolerance = result[0]
              end
            end
          end

        end # PROXY CLASS
       
        #{# RUN ONCE
        #
        unless file_loaded?("GridSnap.rb")
         
          # Menu Entry:
          UI.menu("Tools").add_item("GridSnap") { menu_command() }
         
          file_loaded("GridSnap.rb")
       
        end #}

      end # module

      0
        I'm not here much anymore. But a PM will fire email notifications.
        User avatar
        Dan Rathbun 
        PluginStore Author
        PluginStore Author
         

        Re: Move points to a '3D grid'

        Postby thomthom » Mon Mar 26, 2012 7:53 pm

        Dan Rathbun wrote:It seemed to only change a cubes vertices in the Z axis ??

        Should apply to X,Y and Z... Seemed to work correctly in my quick test...
        0
        Thomas Thomassen — SketchUp Monkey & Coding addict
        List of my plugins and link to the CookieWare fund
        User avatar
        thomthom 
        PluginStore Author
        PluginStore Author
         

        Re: Move points to a '3D grid'

        Postby daiku » Tue Mar 27, 2012 2:47 pm

        Dan Rathbun wrote:
        thomthom wrote:Cubificator?

        Polyhedronizer ?

        Orthogonizer ?

        Orthographizer ?

        OrthograFixer ?

        :lol:


        It's like Autotune for cad! They can make you sound good, even if you can't sing.
        If you are editing digital music, and you need to make the drum beats perfect, you can move the beats to the nearest sixteenth note, or whatever. It's call "quantizing".
        0
        User avatar
        daiku 
        PluginStore Author
        PluginStore Author
         

        Re: Move points to a '3D grid'

        Postby Dan Rathbun » Tue Mar 27, 2012 4:00 pm

        daiku wrote:It's called "quantizing".

        TRUE !!

        Restriction to discrete values (or multiples thereof,) rather than any values in the set of possibles (real numbers, in this case.)

        So.. the long term:
        Vertex Positional Quantization

        The short form:
        Vertex to Grid
        0
          I'm not here much anymore. But a PM will fire email notifications.
          User avatar
          Dan Rathbun 
          PluginStore Author
          PluginStore Author
           

          Re: Move points to a '3D grid'

          Postby rossthompson » Wed Mar 28, 2012 2:30 pm

          Hi guys, I have had a play with Dan's Beta version and for me it works really well. The verticies are adjusted in X,Y and Z directions and the undo function works fine!

          The only slight problem: it adjusts all the geometry in the model, rather than just the active selection. The original module just adjusted the active selection.

          Any ideas?

          Again thanks for the support - this script should be a realy time saver!

          Ross
          0

          rossthompson 
           

          Re: Move points to a '3D grid'

          Postby Dan Rathbun » Wed Mar 28, 2012 3:27 pm

          Well .. I did not think I changed the context of what Thomas' code did... just tried to wrap the code properly and added the menu_command() method to handle an inputbox.

          I'll have a look at it.. again.

          (And it's not really MY edition just because I added the inputbox.. it's still Thomas' thing.)
          0
            I'm not here much anymore. But a PM will fire email notifications.
            User avatar
            Dan Rathbun 
            PluginStore Author
            PluginStore Author
             

            Re: Move points to a '3D grid'

            Postby Dan Rathbun » Wed Mar 28, 2012 3:56 pm

            OK... added support for a selection. (Pssst! ... there was no selection support from the beginning Ross.)

            This utility should probably be wrapped in Thomas' toplevel author module, and reside below his author directory in some manner.

            I'll leave those choices up to him, and when he releases version 1.0.0, we'll delete these beta versions in this thread and put in a link to the release thread.

            Code: Select all
            #  ==========================================================================
            #  GridSnap.rb
            #  --------------------------------------------------------------------------
            #  by Thomas Thomassen
            #
            #  --------------------------------------------------------------------------
            #  THIS SOFTWARE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR
            #  IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
            #  WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
            #  --------------------------------------------------------------------------
            #
            #  This utility quantizes the vertex locations, of the current selection,
            #    of the model, or just the current context, to a 3D grid, whose interval
            #    can be set via a popup inputbox.
            #
            #  --------------------------------------------------------------------------
            #  Revisions:
            #
            #   0.1.0 : 2012-03-26 : by Thomas Thomassen
            #   |
            #   initial beta release
            #
            #   0.2.0 : 2012-03-26 : by Dan Rathbun
            #   |
            #   + Added menu_command() method for inputbox and undo operation.
            #
            #   0.3.0 : 2012-03-28 : by Dan Rathbun
            #   |
            #   + Revised the menu_command() method to pass a selection set to the
            #       adjust_vertices() method as a 2nd argument.
            #
            #  ==========================================================================

            module GridSnap

              @@last_tolerance = 0.25.m

              class << self # PROXY CLASS

                def round_point( point, tolerance )
                  grid_pt = point.to_a.map { |n|
                    b = ( n / tolerance ).to_i * tolerance
                    r = n % tolerance
                    (r > tolerance / 2) ? b + tolerance : b
                  }
                  Geom::Point3d.new( *grid_pt )
                end
               
                def test_it
                  pt = Geom::Point3d.new( 3.976879.m, 3.760209.m, 1.002568.m )
                  tolerance = @@last_tolerance
                  grid_pt = round_point( pt, tolerance )
                 
                  puts "Original: #{pt}"
                  puts "Tolerance: #{tolerance}"
                  puts "Grid Point: #{grid_pt}"
                end
               
                def adjust_vertices( tolerance = @@last_tolerance, ents = nil )
                  model = Sketchup.active_model
                  vertices = []
                  # determine the context:
                  ents = model.active_entities() if ents.nil?
                  # Collect vertices.
                  for e in ents #model.active_entities
                    vertices << e.vertices if e.is_a?( Sketchup::Edge )
                  end
                  vertices.flatten!
                  vertices.uniq!
                  # Calculate grid adjustments.
                  vectors = []
                  entities = []
                  for vertex in vertices
                    pt = vertex.position
                    grid_pt = round_point( pt, tolerance )
                    vector = pt.vector_to( grid_pt )
                    next unless vector.valid?
                    entities << vertex
                    vectors << vector
                  end
                  # Apply transformations
                  model.active_entities.transform_by_vectors( entities, vectors )
                  puts "#{entities.size} adjusted to grid."
                end
               
                def menu_command()
                  title   = 'Adjust Vertices'
                  prompt  = 'Tolerance'
                  default = @@last_tolerance
                 
                  result = UI.inputbox([prompt],[@@last_tolerance],title) rescue @@last_tolerance
                  if result
                    model = Sketchup.active_model
                    begin
                      ###
                      model.start_operation("#{title} (#{Sketchup.format_length(result[0])})")
                        #
                        if model.selection.empty?
                          adjust_vertices( result[0] )
                        else
                          adjust_vertices( result[0], model.selection.to_a() )
                        end
                        #
                      model.commit_operation()
                      ###
                    rescue
                      model.abort_operation()
                    else
                      @@last_tolerance = result[0]
                    end
                  end
                end

              end # PROXY CLASS
             
              #{# RUN ONCE
              #
              unless file_loaded?("GridSnap.rb")
               
                # Menu Entry:
                UI.menu("Tools").add_item("GridSnap") { menu_command() }
               
                file_loaded("GridSnap.rb")
             
              end #}

            end # module
             
             
            0
              I'm not here much anymore. But a PM will fire email notifications.
              User avatar
              Dan Rathbun 
              PluginStore Author
              PluginStore Author
               

              Re: Move points to a '3D grid'

              Postby VertexMover » Fri Oct 10, 2014 12:45 am

              Is there an easy way to have it go through the Outliner list and open each model group and snap those corners to the grid?
              What would need changed in the script so that it would snap all visible geometry to the grid, Without having to manually select and open each group?
              0

              VertexMover 
               

              Re: Move points to a '3D grid'

              Postby Dan Rathbun » Fri Nov 07, 2014 5:10 pm

              Dan Rathbun wrote:This utility should probably be wrapped in Thomas' toplevel author module, and reside below his author directory in some manner.

              I'll leave those choices up to him, and when he releases version 1.0.0, we'll delete these beta versions in this thread and put in a link to the release thread.

              It would need to iterate the model's definition list, changing those that have instances.

              But I'm not sure if it is really safe to change entities collections outside the current context?

              PM'ing TT
              0
                I'm not here much anymore. But a PM will fire email notifications.
                User avatar
                Dan Rathbun 
                PluginStore Author
                PluginStore Author
                 

                Re: Move points to a '3D grid'

                Postby tt_su » Sat Nov 08, 2014 2:42 pm

                Dan Rathbun wrote:But I'm not sure if it is really safe to change entities collections outside the current context?

                That should be ok. One just need to keep in mind that the current open context apply a transformation that affect 3d points.
                0
                User avatar
                tt_su 
                SketchUp Team
                SketchUp Team
                 

                Re: Move points to a '3D grid'

                Postby Dan Rathbun » Sat Nov 08, 2014 4:56 pm

                Ok.. but are ya gonna repost under TT_GripSnap or whatever? (I had said we'd remove the code blocks above and replace with Store links when done.)
                0
                  I'm not here much anymore. But a PM will fire email notifications.
                  User avatar
                  Dan Rathbun 
                  PluginStore Author
                  PluginStore Author
                   

                  Re: Move points to a '3D grid'

                  Postby thomthom » Sun Nov 09, 2014 10:20 am

                  This wasn't something I ever planned to publish. It was just a code snipped posted for anyone to grab.
                  0
                  Thomas Thomassen — SketchUp Monkey & Coding addict
                  List of my plugins and link to the CookieWare fund
                  User avatar
                  thomthom 
                  PluginStore Author
                  PluginStore Author
                   

                  SketchUcation One-Liner Adverts

                  by Ad Machine » 5 minutes ago



                  Ad Machine 
                  Robot
                   



                   

                  Return to Developers' Forum

                  Who is online

                  Users browsing this forum: No registered users and 5 guests

                  Visit our sponsors: