 # Copyright 2004-2011, D. Bur, C. Fale

# Permission to use, copy, modify, and distribute this software for 
# any purpose and without fee is hereby granted, provided that the above
# copyright notice appear in all copies.

# 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.
#-----------------------------------------------------------------------------
# Name        :   points_cloud_triangulation
# Description :   A tool to create triangles starting from a construction points selection
# Menu Item   :   Plugins -> Triangulate Points
# Context Menu:   NONE
# Usage       :   Select construction points. Select menu Plugins/Triangulate points
#             :   read the status bar to check information about triangulation
# Date        :   9/17/2004
# Type        :   Tool

#### TIG tweaked 2011.........
#### put code into protective class, with a new delauney3 method
#### all triangles now face 'up'
#### colinear vertical cpoint errors trapped
#### triangulated mesh is now grouped
#### layer dialog asks for layer if you cancel = Layer0
#### type in Layer to use that id not existing its made
#### 
#-----------------------------------------------------------------------------

class TIGPointsCloudTriangulation

def initialize() ### TIG
  @model = Sketchup.active_model
  self.triangulate_points()
end


def points_to_array()
  ###
  @model = Sketchup.active_model
  ss = @model.selection
  if ss.empty? 
    UI.messagebox("No Selection !")
    return nil
  end
  ### only process cpoints [TIG]
  ss.to_a.each{|e|ss.remove(e) unless e.kind_of?(Sketchup::ConstructionPoint)}
  if ss.empty? 
    UI.messagebox("No Guide-Points in the Selection !")
    return nil
  end
  if not ss[2]
    UI.messagebox("Insufficient Guide-Points in the Selection [needs >= 3] !")
    return nil
  end
  ###
  points_array = []   
  ss.to_a.each{|cpt| ### TIG'd
    x = cpt.position[0].to_f
    y = cpt.position[1].to_f
    z = cpt.position[2].to_f
    points_array << [x, y ,z]
  }
  points_array.uniq!
  return points_array
  ###
end #of def


def triangulate_points()
###
entities = @model.active_entities
layer=nil
prompts = ["Layer Name: "]
values = ["Triangulated_Points"]
results = UI.inputbox(prompts, values, "Layer Name")
layer=@model.layers.add(results[0])if results
points_table = []
points_table = self.points_to_array()
###
triangles = []
if points_table[0]
  triangles = Delauney3::triangulate(points_table)
else
  puts "No triangles can be made."
  return nil
end
@model.start_operation("Triangulate Points")
### group for tri's output
group=entities.add_group()
gents=group.entities
group.name="Triangulated_Points"
i='0'
len=triangles.length.to_s
triangles.each{|tri|
  Sketchup.set_status_text("Adding Triangle: #{i} of #{len}")
  begin
    face=gents.add_face( points_table[tri[2]], points_table[tri[1]], points_table[tri[0]] )
    face.reverse! if face.normal.z < 0 ### so all face 'up'
  rescue
    puts "Points don't triangulate."
  end
  i.next!
}
group.layer=layer
@model.commit_operation
###
end#def

end#class