# Copyright 2004, Todd Burch - Burchwood USA   http://www.burchwoodusa.com 

# 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 :          makefaces.rb 1.1
# Description :   Creates faces only on selected objects that could potentially receive a face.
# Author :        Todd Burch   http://www.burchwoodusa.com 
# Usage :         1. select all elements for which you want a face.
#                 2. Run "Make Faces" from the Tools menu.
# Date :          17.Jul.2004
# Type :          Tool
# History:        1.0 (17.Jul.2004) - first version
#                 1.1 (23.Aug.2004) - Add text-based percentage complete progress messages
#                                   - Move statistics to a pop-up messagebox from the Ruby Console.
#                                  
#-----------------------------------------------------------------------------

require 'sketchup.rb'

#-----------------------------------------------------------------------------
#
#  The following method will format the elapsed time when passed the total seconds
#  elapsed for a process.    
#
#  To use the routine, at the start of your script, issue: t1 = Time.now
#  That is the start time.
#
#  When your script is about finished, call this method while issueing 
#  the Time.now method again, and subtracting the initial time like this: 
#  elapsed_time = seconds_2_dhms(Time.now-t1).  
#
#  A formatted string is returned, in the format: 
# 
#  "W Days, X Hour(s), Y Minute(s), and Z Seconds."
#
#  If only seconds had elapsed (a quick running process), then only "Z Seconds." will be 
#  returned.  If the process lasted over a minute, "Y Minute(s), Z Seconds." will be returned, 
#  and so on. 
#
#
#-----------------------------------------------------------------------------

def seconds_2_dhms (secs)   # Input is seconds:  Time2 - Time1
    seconds = secs % 60     # Calcuate whole and fractional seconds.
    time = secs.round       # Round to nearest whole second.
    time /= 60              # Divide by 60 to remove seconds.
    minutes = time % 60     # Calculate portions of a hour.
    time /= 60              # Remove any portions of an hour 
    hours = time % 24       # Calculate portions of a day in hours
    days = time / 24        # The remainder is days

    if (days > 0) then days = days.to_s<<" Day(s), "  else days = " " end 
    if (hours > 0) then hours = hours.to_s<<" Hour(s), " else hours = " " end 
    if (minutes > 0) then minutes = minutes.to_s<< " Minute(s), " else minutes = " " end  
    seconds = seconds.to_s<< " Second(s)." 
    return (days<<hours<<minutes<<seconds).strip!
    end   # seconds_2_dhms 

#-----------------------------------------------------------------------------
#   This tellPctComplete method will display a text-based progress bar in the status bar. 
#    
#   It is passed two values.  The first is the iteration count of your loop.  The 
#   second value is the magnitude of your loop.  
#
#   Nothing is returned to the caller, but the status bar will have been updated.
#
#   Using the default characters, "-" and ">", the line will look similar to the following:
#
#   --------------->----------------  50% 
#
#-----------------------------------------------------------------------------

def tellPctComplete(iteration,total) 
    linechar = "-"                          # Set default line building character.
    progresschar = ">"                      # Set default moving indicator.
    pct = (iteration*100)/total             # Calculate percentage complete.
    pct = 1 if pct <= 0                     # round up to 1% if anything less than 1%.
    initial_block = linechar * 100          # Default progress bar line sequence.
    current_block = initial_block[0,pct-1] << progresschar << initial_block[pct,initial_block.length]
    Sketchup.set_status_text(current_block << "   " << (pct.to_s)<<"%.")
    return
    end    # tellPctComplete


#-----------------------------------------------------------------------------
#
# This routine creates faces from lines that make up closed sections.
#
#-----------------------------------------------------------------------------

def makeFaces11
    t1 = Time.now 
    Sketchup.active_model.start_operation "Make Faces"
    #Get the current selection 
    ss = Sketchup.active_model.selection  
    total_items = ss.count      # Total count of all selected entities.
    x = 0                       # faces-added accumulator 
    z = 0                       # loop count
    notAnEdge = 0               # Accumulator for non-Edges 
    ss.each {|e|
      if e.typename == "Edge" then  # find_faces only works on edges.
         x += e.find_faces          # This creates faces if they can created. Returns # faces created.
      else notAnEdge+=1             # Keep track of selections that were not an edge.
         end
      z+=1                          # bump loop counter      
      tellPctComplete z,total_items # Report Progress. 
      }   
    Sketchup.active_model.commit_operation    # "Make Faces"

    # Calculate the time that has elapsed in seconds. 
    elap = seconds_2_dhms(Time.now - t1) 
    UI.messagebox("makefaces.rb: Copyright 2004 Burchwood USA."        <<
                  "\nVersion 1.1   August 23,2004."                    << 
                  "\n\nThere were " << total_items.to_s << " selected items."   <<
                  "\n\nThere were " << notAnEdge.to_s << " non-Edge selected items."   <<
                  "\nThere were " << (total_items-notAnEdge).to_s << " Edges selected."   <<
                  "\n\nThere were " << x.to_s << " face(s) added."       <<  
                  "\nThe process lasted: "<< elap, MB_MULTILINE, "Make Faces Statistics")
    end  # makeFaces11
   

# This will add an item called "Make Faces 1.1" to the Tools menu.

# First check to see if we have already loaded this file so that we only 
# add the item to the menu once
if( not file_loaded?("makefaces11.rb") )
   # This will add a separator to the menu, but only once
   add_separator_to_menu("Tools")
   UI.menu("Tools").add_item("Make Faces 1.1") { makeFaces11 }
   end

#-----------------------------------------------------------------------------
file_loaded("makefaces11.rb")

