''  This file downloaded from www.EdHarriss.com
''  
''  www.EdHarriss.com File Information:
''  
''    Script Name: Nurbs2Subdiv v1.5
''    Author: Reinhard Claus
''    Update/Change this file at by sending e-mail to EdHarriss@EdHarriss.com
''


 '++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'
'nurbs2subdiv.vbs by reinhard claus (ray@giga4u.de)
'
'++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
'
' builds a subdivision surface from a NURBS surface
' (lets user choose mesh subdivision level and whether to delete the source object)
' Next version will also consider multiple knot curves (lower continuity)

nurbs2subdiv

sub nurbs2subdiv
	dim Log
	
	if not valid(Selection,Log) then
		Application.LogMessage Log, siError
		exit sub
	end if
	
	FreezeObj
	ResetTransform , siCtr, siSRT, siXYZ

	set oSource = Selection.Item(0)
	set oGeo = oSource.ActivePrimitive.Geometry
	set oCtrlPts = oGeo.Surfaces(0).ControlPoints
	set oRoot = Application.ActiveProject.ActiveScene.Root
	set oTemp = GetPrim ("Null") 'property holder
	
	if not promptprops(oTemp ,Log) then 
		Application.LogMessage Log, siError
		DeleteObj oTemp
		exit sub
	end if 
		
	udim = oCtrlPts.Dimension(siUDirection)
	vdim = oCtrlPts.Dimension(siVDirection)
	udimdata = udim-1
	vdimdata = vdim-1
	bCloseU = oGeo.Surfaces(0).UKnots.Closed
	bCloseV = oGeo.Surfaces(0).VKnots.Closed
	if bCloseU then udimdata = udimdata + 1 end if
	if bCloseV then vdimdata = vdimdata + 1 end if
	rray = oCtrlPts.Array
	redim vertices(udim*vdim*3)
	redim data(udimdata*vdimdata*5)		
	vidx = 0
	didx = 0
	pidx = 0
	
	for i = 0 to vdim-1
		for j = 0 to udim-1
			vertices(vidx) = rray(0,i,j)
			vertices(vidx+1) = rray(1,i,j)
			vertices(vidx+2) = rray(2,i,j)
			if j<>udim-1 and i<>vdim-1 then			
			addquad data,didx,pidx,pidx+1,pidx+udim+1,pidx+udim
			end if 
				if j=udim-1 and i<>vdim-1 and bCloseU then
				addquad data,didx,pidx,pidx-(udim-1),pidx+1,pidx+udim
			end if
			if i=vdim-1 and j<>udim-1 and bCloseV then
				addquad data,didx,pidx,pidx+1,pidx-(udim*(vdim-1))+1,pidx-(udim*(vdim-1))
			end if
			if i=vdim-1 and j=udim-1 and bCloseU and bCloseV then
				addquad data,didx,pidx,pidx-(udim-1),0,udim-1
			end if
			pidx = pidx + 1
			vidx = vidx + 3
		next
	next
	
	if GetValue (oTemp&".Conversion_settings.dso") Then 
		DeleteObj oSource 
	End If

	set oObj = oRoot.AddPolygonMesh(vertices, data, "Subdiv_from_nurbs")
	
	AddProp "GeomApprox"
	SetValue oObj.FullName & ".geomapprox.gapproxmosl", GetValue (oTemp & ".Conversion_settings.subdl")
	
	DeleteObj oTemp	
end sub

sub addquad(ar,i,idx1,idx2,idx3,idx4)
	ar(i) = 4
	ar(i+1) = idx1
	ar(i+2) = idx2
	ar(i+3) = idx3
	ar(i+4) = idx4
	i = i + 5
end sub

function valid(s,Log)
	if s.Count=0 then
		Log = "Nothing selected"
	elseif s.Count<>1 then
		Log = "Multiple objects selected" 
	elseif s.Item(0).type <> "surfmsh" then
		Log = "Wrong object type" 
	else
		valid = TRUE
	end if
end function

function promptprops(oNode,Log)
	set oProps = AddProp("Custom_parameter_list",oNode, , "Conversion_settings").Value("Value")
	SIAddCustomParameter oProps, "subdl", siUByte , 0, 0, 4, siClassifVisualization, 0, 0.000, 0.000, "SubdivL", "Mesh Subdivision Level"
	SIAddCustomParameter oProps, "dso", siBool , 1, 0, 1, siClassifVisualization, 0, 0.000, 0.000, "DeleteS", "Delete Source Object"
	
	On Error Resume Next
	InspectObj oProps,,"Inspecting",siModal
	if Err.Number <> 0 then
		Log = "Dialog canceled"
		exit function 
	else 
		Err.Clear
		promptprops = TRUE
	end if
end function