## Move points to a '3D grid'

### Move points to a '3D grid'

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
Please, register (free) to access all the attachments on the forums.
rossthompson

Posts: 27
Joined: Tue Jan 27, 2009 12:26 pm
Location: Oxford
Name: Ross Thompson
Operating system: Windows
SketchUp version: 7
SketchUp use: architecture

### Re: Move points to a '3D grid'

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

Note that the separator may be "," for you .

gilles
Top SketchUcator

Posts: 796
Joined: Mon Apr 07, 2008 10:29 am
Location: france
Operating system: Mac
SketchUp version: 8
SketchUp use: other
Level of SketchUp: Intermediate

### Re: Move points to a '3D grid'

gilles wrote:You can use the scale tool:

rossthompson wrote:I am trying to write a script
Thomas Thomassen — SketchUp Monkey & Coding addict

thomthom
Global Moderator

Posts: 17907
Joined: Tue Nov 13, 2007 12:47 pm
Location: Trondheim, Norway
Name: Thomas Thomassen
Operating system: Windows
SketchUp version: 2013
SketchUp use: architecture

### Re: Move points to a '3D grid'

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.
Thomas Thomassen — SketchUp Monkey & Coding addict

thomthom
Global Moderator

Posts: 17907
Joined: Tue Nov 13, 2007 12:47 pm
Location: Trondheim, Norway
Name: Thomas Thomassen
Operating system: Windows
SketchUp version: 2013
SketchUp use: architecture

### Re: Move points to a '3D grid'

Actually, that example will round to nearest inch - which is SketchUp's internal unit...
Thomas Thomassen — SketchUp Monkey & Coding addict

thomthom
Global Moderator

Posts: 17907
Joined: Tue Nov 13, 2007 12:47 pm
Location: Trondheim, Norway
Name: Thomas Thomassen
Operating system: Windows
SketchUp version: 2013
SketchUp use: architecture

### Re: Move points to a '3D grid'

Code: Select all
`pt = Geom::Point3d.new( 3.976879.m, 3.760209.m, 1.002568.m )tolerance = 0.25.mgrid_pt = pt.to_a.map { |n|  b = ( n / tolerance ).to_i * tolerance  r = n % tolerance  (r > 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)
Thomas Thomassen — SketchUp Monkey & Coding addict

thomthom
Global Moderator

Posts: 17907
Joined: Tue Nov 13, 2007 12:47 pm
Location: Trondheim, Norway
Name: Thomas Thomassen
Operating system: Windows
SketchUp version: 2013
SketchUp use: architecture

### Re: Move points to a '3D grid'

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

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."  endend`
Thomas Thomassen — SketchUp Monkey & Coding addict

thomthom
Global Moderator

Posts: 17907
Joined: Tue Nov 13, 2007 12:47 pm
Location: Trondheim, Norway
Name: Thomas Thomassen
Operating system: Windows
SketchUp version: 2013
SketchUp use: architecture

### Re: Move points to a '3D grid'

... from concept to module in under a hour.

Dan Rathbun
Top SketchUcator

Posts: 4146
Joined: Tue Oct 06, 2009 3:06 am
Location: Florida, USA
Name: Dan Rathbun
Operating system: Windows
SketchUp version: 2013
SketchUp use: education

### Re: Move points to a '3D grid'

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'...
Please, register (free) to access all the attachments on the forums.
TIG

TIG
Global Moderator

Posts: 14308
Joined: Mon Nov 12, 2007 7:24 pm
Location: Northumbria UK
Name: TIG
Operating system: Windows
SketchUp version: 2013
SketchUp use: architecture

### Re: Move points to a '3D grid'

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... ?
Thomas Thomassen — SketchUp Monkey & Coding addict

thomthom
Global Moderator

Posts: 17907
Joined: Tue Nov 13, 2007 12:47 pm
Location: Trondheim, Norway
Name: Thomas Thomassen
Operating system: Windows
SketchUp version: 2013
SketchUp use: architecture

### Re: Move points to a '3D grid'

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
rossthompson

Posts: 27
Joined: Tue Jan 27, 2009 12:26 pm
Location: Oxford
Name: Ross Thompson
Operating system: Windows
SketchUp version: 7
SketchUp use: architecture

### Re: Move points to a '3D grid'

thomthom wrote:Cubificator?

Polyhedronizer ?

Orthogonizer ?

Orthographizer ?

OrthograFixer ?

Dan Rathbun
Top SketchUcator

Posts: 4146
Joined: Tue Oct 06, 2009 3:06 am
Location: Florida, USA
Name: Dan Rathbun
Operating system: Windows
SketchUp version: 2013
SketchUp use: education

### Re: Move points to a '3D grid'

In case TT is away...
Inside the code making the menu use
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' ???
TIG

TIG
Global Moderator

Posts: 14308
Joined: Mon Nov 12, 2007 7:24 pm
Location: Northumbria UK
Name: TIG
Operating system: Windows
SketchUp version: 2013
SketchUp use: architecture

### Re: Move points to a '3D grid'

Not sure this reduced poly rock is so good ?
Cuboidalizer.PNG
'Cuboidalizer' is another name idea too... that or 'Discombobulizer'
Please, register (free) to access all the attachments on the forums.
TIG

TIG
Global Moderator

Posts: 14308
Joined: Mon Nov 12, 2007 7:24 pm
Location: Northumbria UK
Name: TIG
Operating system: Windows
SketchUp version: 2013
SketchUp use: architecture

### Re: Move points to a '3D grid'

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`

Dan Rathbun
Top SketchUcator

Posts: 4146
Joined: Tue Oct 06, 2009 3:06 am
Location: Florida, USA
Name: Dan Rathbun
Operating system: Windows
SketchUp version: 2013
SketchUp use: education

### Re: Move points to a '3D grid'

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...
Thomas Thomassen — SketchUp Monkey & Coding addict

thomthom
Global Moderator

Posts: 17907
Joined: Tue Nov 13, 2007 12:47 pm
Location: Trondheim, Norway
Name: Thomas Thomassen
Operating system: Windows
SketchUp version: 2013
SketchUp use: architecture

### Re: Move points to a '3D grid'

Dan Rathbun wrote:
thomthom wrote:Cubificator?

Polyhedronizer ?

Orthogonizer ?

Orthographizer ?

OrthograFixer ?

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".
daiku

Posts: 213
Joined: Mon Nov 12, 2007 2:54 pm
Location: Minneapolis
Name: Clark Bremer

### Re: Move points to a '3D grid'

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

Dan Rathbun
Top SketchUcator

Posts: 4146
Joined: Tue Oct 06, 2009 3:06 am
Location: Florida, USA
Name: Dan Rathbun
Operating system: Windows
SketchUp version: 2013
SketchUp use: education

### Re: Move points to a '3D grid'

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
rossthompson

Posts: 27
Joined: Tue Jan 27, 2009 12:26 pm
Location: Oxford
Name: Ross Thompson
Operating system: Windows
SketchUp version: 7
SketchUp use: architecture

### Re: Move points to a '3D grid'

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.)

Dan Rathbun
Top SketchUcator

Posts: 4146
Joined: Tue Oct 06, 2009 3:06 am
Location: Florida, USA
Name: Dan Rathbun
Operating system: Windows
SketchUp version: 2013
SketchUp use: education

### Re: Move points to a '3D grid'

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  `

Dan Rathbun
Top SketchUcator

Posts: 4146
Joined: Tue Oct 06, 2009 3:06 am
Location: Florida, USA
Name: Dan Rathbun
Operating system: Windows
SketchUp version: 2013
SketchUp use: education

Not a Premium Member yet? Check out the great time-limited deal we are offering.