'MultiCvMg 
'
'javier@internarte.com
'info:	merges multiple curves with automatic recognition of 
'	closest points. if necessary inverts the curves.
'use:	run vbs and follow instructions: pick curves in merging order 
'work in progress, more to come.
'------------------------------------------------------
'MAIN
DeselectAll

Msgbox "Select Curves to merge in merging order"

set collection = CreateObject("XSI.Collection")

DO		'accumulates curves on propmt
	PickElement "curve", "Toggle/Select CURVE", "Toggle/Select CURVE", crve,button,modifhhier
	if button = 0 then
		exit do
	else
		ToggleSelection crve, , True
	end if
LOOP

collection.additems selection
delcv = Msgbox("to DELETE after merging hit    'OK'"&VbCr&VbCr&"to KEEP after merging hit    'Cancel'",1, "ORIGINAL CURVES")
logmessage delcv

FOR index = 0 to collection.Count - 2 	
	 
		CALL mergetwocurves (cont, seam, modifytan,startrage, startscl, endrange, endscl)

NEXT  

'-----------------------
SUB mergetwocurves (cont, seam, modifytan,startrage, startscl, endrange, endscl)
	
	set oCvA = selection (0)
	set oCvB = collection (index+1)
	
	set oGeoA = oCvA.activeprimitive.geometry
	set oGeoB = oCvB.activeprimitive.geometry
	set oPtA = oGeoA.Points
	set oPtB = oGeoB.Points
	cta = oPtA.count -1
	ctb = oPtB.count -1
' define vector points and distances btw points for curve boundaries
	set CrvA_0 = createobject("Sumatra\Scripting\Math\SIVector3")
	set CrvA_LAST = createobject("Sumatra\Scripting\Math\SIVector3")
	set CrvB_0 = createobject("Sumatra\Scripting\Math\SIVector3")
	set CrvB_LAST = createobject("Sumatra\Scripting\Math\SIVector3")
	set dist = createobject("Sumatra\Scripting\Math\SIVector3")
	set dist1 = createobject("Sumatra\Scripting\Math\SIVector3")
	set dist2 = createobject("Sumatra\Scripting\Math\SIVector3")
	set dist3 = createobject("Sumatra\Scripting\Math\SIVector3")
' freeze scaling in all curves to avoid surprises
	Scale oCvA&", "&oCvB, 1, 1, 1, siAbsolute, siLocal, siCtr, siX
	Scale oCvA&", "&oCvB, 1, 1, 1, siAbsolute, siLocal, siCtr, siY
	Scale oCvA&", "&oCvB, 1, 1, 1, siAbsolute, siLocal, siCtr, siZ
' set vectors points for curve boundaries
	CrvA_0.set oPtA(0).Position.x, oPtA(0).Position.y, oPtA(0).Position.z
	CrvA_LAST.set oPtA(cta).Position.x, oPtA(cta).Position.y, oPtA(cta).Position.z
	CrvB_0.set oPtB(0).Position.x, oPtB(0).Position.y, oPtB(0).Position.z
	CrvB_LAST.set oPtB(ctb).Position.x, oPtB(ctb).Position.y, oPtB(ctb).Position.z
'compute distance vectors between boundaries of 2 selected curves
	dist.Sub CrvA_0, CrvB_LAST	
	dist1.Sub CrvA_LAST, CrvB_0	
	dist2.Sub CrvA_0, CrvB_0	
	dist3.Sub CrvA_LAST, CrvB_LAST
'use quicksort to find out minimum distance 	
	set utils = CreateObject("xsi.utils")  
	dim values 
	values = array(dist.length,dist1.length,dist2.length,dist3.length)  
	utils.quicksort values 
	for each value in values
		logmessage value
	next 
'select points at minimum distance (i am sure there is a shortcut for this using quicksort)
	if values (0) = dist.length then
		invertcv = 0
		pta = 0
		ptb =	"LAST"
	elseif values (0) = dist1.length then
		invertcv = 0
		pta = "LAST"
		ptb =	0
	elseif values (0) = dist2.length then	
		invertcv = 1
		pta = 0
		ptb = "LAST"
	else
		invertcv = 1
		pta = "LAST"
		ptb = 0
	end if
	
	if invertcv = 1 then
		ApplyTopoOp "CrvInverse", oCvB, 3, siPersistentOperation

	end if	
	DeselectAll
'this merges the curves
	ApplyOp "CrvMerge", oCvA&".crvbndry["&pta&"];"&oCvB&".crvbndry["&ptb&"]", 3, siPersistentOperation
		set crv = selection(0)
		if index = 0 then
			SetValue crv&".crvlist.mergecrv.endrange", 0.15
			SetValue crv&".crvlist.mergecrv.startrange", 0.15
			
			On Error Resume Next
			InspectObj crv&".crvlist.mergecrv.cont",,"SELECT Default MERGE SHAPE To Propagate (Start and End Scale are unsupported) ",4
			if Err.Number <> 0 then
				Deleteobj crv
				exit sub
			end if
			call GetCurveDef (cont, seam, modifytan,startrage, startscl, endrange, endscl)

			Err.Clear
			On Error Goto 0
		else
			call SetCurveDef (cont, seam, modifytan,startrage, startscl, endrange, endscl)
		end if
		FreezeObj crv&".crvlist.mergecrv"
		SetValue crv&".display.wirecol", 126
	if delcv = 1 then
		Deleteobj oCvA&","&oCvB
	else 
		if index <> 0 then
			Deleteobj oCvA
		end if
	end if
END SUB
'-------
SUB GetCurveDef (cont, seam, modifytan,startrage, startscl, endrange, endscl)
		cont = Getvalue (crv&".crvlist.mergecrv.cont")
		seam= Getvalue (crv&".crvlist.mergecrv.seam")
		startrange = Getvalue (crv&".crvlist.mergecrv.startrange")
		endrange = Getvalue (crv&".crvlist.mergecrv.endrange")
		if cont <> 0 then
			modifytan = Getvalue (crv&".crvlist.mergecrv.modifytan")
			startscl = Getvalue (crv&".crvlist.mergecrv.startscl")		
			endscl = Getvalue (crv&".crvlist.mergecrv.endscl")
		end if
END SUB
'-------
SUB SetCurveDef (cont, seam, modifytan,startrage, startscl, endrange, endscl)
	set crv = selection(0)
	SetValue crv&".crvlist.mergecrv.cont,"&cont
	Setvalue crv&".crvlist.mergecrv.seam,"&seam
	Setvalue crv&".crvlist.mergecrv.startrange,"&startrange
	Setvalue crv&".crvlist.mergecrv.endrange,"&endrange
	if cont <> 0 then
		Setvalue crv&".crvlist.mergecrv.modifytan,"&modifytan
		'Setvalue crv&".crvlist.mergecrv.startscl,"&startscl
		'Setvalue crv&".crvlist.mergecrv.endscl,"&endscl
	end if
END SUB

