# Copyright 2004,2005 by Rick Wilson 

# 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 :          Weld 3.0
# Description :   weld edges into curve ("polyline")
# Author :        RickW
# Usage :         select edges, then run the script (Plugins>Weld)
#			Edges will be joined into a curve ("polyline")
#			Script will prompt to find faces
# Date :          4.Aug.2004
# Type :		tool
# History:
#			3.0 (4.Aug.2005) -  Special Anniversary Edition! :)
#						  now welds to existing curves, adds option
#						  to find faces
#			2.2 (1.Aug.2005) -  used group/explode to fix most problems
#						  still won't weld to non-arc curves
#			2.1 (27.Jul.2005) - fixed the fix that caused strange non-welding
#						  issues.
#			2.0 (25.Jul.2005) - fixed bug where unselected edges were welded,
#						  now retains existing faces.
#			1.2 (12.May.2005) - fixed edge bug that occasionally resulted
#						  in strange edge locations and deletions
#			1.1 (10.Sep.2004) - allows working in groups/components
#			1.0 (4.Aug.2004) - first version

require 'sketchup.rb'

def join_edges
	model=Sketchup.active_model
	ents=model.active_entities
	sel=model.selection
	sl=sel.length
	verts=[]
	edges=[]
	newVerts=[]
	startEdge=startVert=nil

#CHECK FOR A VALID SELECTION

#	if sel.first.curve
#		return UI.messagebox("Please select at least 2 non-joined edges") if sel.length == sel.first.curve.count_edges
#	end

#DELETE NON-EDGES, GET THE VERTICES

	sel.each {|item| edges.push(item) if item.typename=="Edge"}
	edges.each {|edge| verts.push(edge.vertices)}
	verts.flatten!
	return UI.messagebox("Please select at least 2 edges") if edges.length < 2

#FIND AN END VERTEX

	vertsShort=[]
	vertsLong=[]
	verts.each do |v|
		if vertsLong.include?(v)
			vertsShort.push(v)
		else
			vertsLong.push(v)
		end
	end
	if (startVert=(vertsLong-vertsShort).first)==nil
		startVert=vertsLong.first
		closed=true
		startEdge = startVert.edges.first
	else
		closed=false
		startEdge = (edges & startVert.edges).first
	end
	#sel.clear


#SORT VERTICES, LIMITING TO THOSE IN THE SELECTION SET

	if startVert==startEdge.start
		newVerts=[startVert]
		counter=0
		while newVerts.length < verts.length
			edges.each do |edge|
				if edge.end==newVerts.last
					newVerts.push(edge.start)
				elsif edge.start==newVerts.last
					newVerts.push(edge.end)
				end
			end
			counter+=1
			if counter > verts.length
				return nil if UI.messagebox("There seems to be a problem. Try again?", MB_YESNO)!=6
				newVerts.reverse!
				reversed=true
			end
		end
	else
		newVerts=[startVert]
		counter=0
		while newVerts.length < verts.length
			edges.each do |edge|
				if edge.end==newVerts.last
					newVerts.push(edge.start)
				elsif edge.start==newVerts.last
					newVerts.push(edge.end)
				end
			end
			counter+=1
			if counter > verts.length
				return nil if UI.messagebox("There seems to be a problem. Try again?", MB_YESNO)!=6
				newVerts.reverse!
				reversed=true
			end
		end
	end
	newVerts.uniq!
	newVerts.reverse! if reversed


#CONVERT VERTICES TO POINT3Ds

	newVerts.collect!{|x| x.position}
	if closed
		newVerts.push(newVerts[0])
	else
		newVerts.push(newVerts[0]) if UI.messagebox("Close curve?", MB_YESNO)==6
		closed=true
	end

#CREATE THE CURVE

	model.start_operation "weld"
	edges.each {|item| item.explode_curve if item.curve and newVerts.include?(item.start.position)}
	#sel.each {|e| e.erase!}
	gp1e=(gp1=ents.add_group).entities
	curveEdges=gp1e.add_curve(newVerts)
	$gpents=gp1.explode
	ents[-1].find_faces if closed and ents[-1].typename=="Edge" and UI.messagebox("Find faces for this curve?", MB_YESNO, "Weld Edges Utility")==6
#	if $gpents.first.typename=="Edge"
#		edges=$gpents.first.curve.edges
#	elsif $gpents.first.typename=="Curve"
#		edges=$gpents.first.edges
#	else
#		edges=$gpents.last.edges
#	end
#	model.active_entities.add_curve(newVerts)
#	edges.each_index do |i|
#		if i>0
#			edges[i].reverse! if edges[i].start!=edges[i-1].end
##			if edges[i].start!=edges[i-1].end
##				sel.clear
##				sel.add(edges)
##				join_edges
##				return
##			end
#		end
#	end
	model.commit_operation
	sel.clear
end

#ALL DONE!

#-----------------------------------------------------------------------------
if( not file_loaded?("weld.rb") )
    add_separator_to_menu("Plugins")
# BEGIN CHANGES BY organizerEdit.rb
if $submenu!=nil
    $submenu.add_item("Weld") { join_edges }
else
    UI.menu("Plugins").add_item("Weld") { join_edges }
end
# END CHANGES BY organizerEdit.rb
end
#-----------------------------------------------------------------------------
file_loaded("weld.rb")


#verts=sel.first.curve.vertices
#edges=[]
#pts=verts.collect{|v| v.position}
#0.upto(pts.length-3) {|i| edges.push(ents.add_line(pts[i],pts[i+2]))}
#edges.each {|e| e.erase!}
