Create new object like tv screen.

Create new object like tv screen.

mightykuchka
Observer Observer
841 Views
2 Replies
Message 1 of 3

Create new object like tv screen.

mightykuchka
Observer
Observer

Hello.
I need a script that would create a new object, the screen based on the size of the diagonal and the thickness of the frame and depth of the object, the ratio of 16x9 or 16:10. or 4:3.
For example, I enter a diagonal of 55" and a frame of 1cm and a depth of 4cm.
And the script creates a rectangle 1218mm x 685mm, adds 1cm thickness to it and adds 4cm volume.
How can this be done?

0 Likes
842 Views
2 Replies
Replies (2)
Message 2 of 3

klvnk
Collaborator
Collaborator

this should get you started.....

plugin simpleObject picframe
	name:"picframe"
	classID:#(0x68021924, 0x627ffe63)
	category:"Scripted"
(
	--local params;
	
	parameters main rollout:params
	(
		curvedata 		type:#point3Tab tabSize:4  tabSizeVariable:true;
		width			type:#float  	default:10.0 	ui:ui_width;
		height  		type:#float  	default:10.0	ui:ui_height;
		wsegs			type:#integer 	default:1   	ui:ui_wsegs;
		hsegs			type:#integer  	default:1 		ui:ui_hsegs;
		size			type:#float 	default:2.0 	ui:ui_size;
		zscale  		type:#float  	default:1.0 	ui:ui_zscale;
		mapCoords 		type:#boolean 	default:on 		ui:ui_mapCoords;
		flipUV			type:#boolean 	default:off 	ui:ui_flipUV;	
		contUV			type:#boolean 	default:off 	ui:ui_contUV;
		picplane		type:#boolean 	default:on 		ui:ui_picQuad;	
		smoothframe		type:#boolean 	default:on 		ui:ui_smoothframe;
		cornersegs 		type:#boolean 	default:off 	ui:ui_cornersegs;
		manualUpdate 	type:#boolean 	default:off animatable:off ui:ui_manualUpdate;
		
		on curvedata set  arg1 arg2 do
		(
			--params.getProfile();
		)	
	)
	
-- our starting profile	
	
	fn defCurveData =
	(	
		curvedata.count = 4;
		curvedata[1] = [0.0,0.0,0.0];			
		curvedata[2] = [0.0,1.0,0.0];
		curvedata[3] = [1.0,1.0,0.0];
		curvedata[4] = [1.0,0.0,0.0];
	)	
	
-- rollout	
	
	rollout params "Params"
	(
		local updating = on
		spinner ui_width   "Width:" range:[0, 1e9, 0] fieldwidth:64 type:#float align:#right;
		spinner ui_height  "Height:" range:[0, 1e9, 0] fieldwidth:64 type:#float align:#right;
		spinner ui_wsegs   "Width Segs:" range:[1, 32, 1] fieldwidth:64 type:#integer align:#right offset:[0,4];
		spinner ui_hsegs   "Height Segs:" range:[1, 32, 1] fieldwidth:64 type:#integer align:#right;
		spinner ui_size    "Size:" range:[0, 1e9, 0] fieldwidth:64 type:#float align:#right offset:[0,4];
		spinner ui_zscale  "Z Scale:" range:[-1e9, 1e9, 0] fieldwidth:64 type:#float align:#right;
		checkbox ui_mapCoords "Generate Map Coords." align:#left offset:[-2,4];
		checkbox ui_flipUV  "Flip UV Coords." align:#left offset:[-2,0];
		checkbox ui_contUV "Continuous UV Coords." align:#left offset:[-2,0];
		checkbox ui_picQuad "Create Picture Plane." align:#left offset:[-2,0];
		checkbox ui_smoothframe "Smooth Frame." align:#left offset:[-2,0];
		checkbox ui_cornersegs "Corner Segments." align:#left offset:[-2,0];
		
		group "Profile: "
		(
			CurveControl ui_profile numCurves:1 width:144 height:100 align:#left offset:[-4,2] enabled:on \
				x_range:[0,1] y_range:[-0.5,1] x_value:0 \
				scrollValues:[0,-10] zoomValues:[128,60] \
				uiFlags:#(#constrainY, #noFilterButtons) \
				rcmFlags:#(#move_xy, #move_x, #move_y, #corner, #delete) 
			
			checkbox ui_manualUpdate "Manual Update" align:#left offset:[-2,0]
			button ui_updateProfile "Update" width:71 align:#left offset:[-4,0] tooltip:"Update Profile" across:2
			button ui_resetProfile "Reset" width:71 align:#right offset:[4,0] tooltip:"Reset Profile"
		)
		
-- CurveControl -> curvedata	
		
		fn setProfile updateMesh: = 
		(
			if updateMesh == unsupplied do updateMesh = not manualUpdate
			
			curve = ui_profile.curves[1]
			curvedata.count = curve.points.count;
			for i = 1 to curve.points.count do 
			(
				pnt = curve.points[i]
				curvedata[i] = [pnt.value.x, pnt.value.y, 0.0]
			)
			if updateMesh do 
			(
				this.doBuildMesh()
				redrawviews()
			)
		)
		
--  curvedata	-> CurveControl	
		
		fn getProfile = 
		(
			curve = ui_profile.curves[1];
			curve.numPoints = curvedata.count;
			for i =1 to curvedata.count  do 
			(
				pnt = curve.points[i]
				cd = curvedata[i]
				pnt.value = [cd.x, cd.y]
				pnt.bezier = off
				pnt.corner = on
				if i == 1 or i == curvedata.count then pnt.lock_x = true;
			)
		)

		on ui_profile deleted c val do if not loading and not updating do setProfile()
		on ui_profile ptChanged c val do if not loading and not updating do setProfile()
		on ui_profile tangentChanged c val type do if not loading and not updating do setProfile()
		
		fn resetProfile = 
		(
			defCurveData();
			getProfile();
		)
		
		on ui_updateProfile pressed do undo "Update Frame Profile" on  setProfile()
		on ui_resetProfile pressed do undo "Reset Frame Profile" on  resetProfile()

		on params open do
		(
			updating = on
			deleteAllChangeHandlers id:#frame_callback
			getProfile();
			ccTarget = (refs.dependents ui_profile.curves[1])[1]
			when topology ccTarget change id:#frame_callback do 
			(
				if ui_profile.curves[1].numpoints != curvedata.count do setProfile()
			)
			updating = off
		)
		on params close do  deleteAllChangeHandlers id:#frame_callback
	)	

	on create do  defCurveData();
	
-- viewport create	
	
	tool create
	(
 		on mousePoint click do case click of
 		(
 			1: 
 			(
 				nodeTM.translation = gridPoint
 				width = 0.0;
				height = 0.0;
				size = 0.01;
 			)
 			3: #stop
 		)
 		on mouseMove click do case click of
 		(
 			2: 
			(
				width = 2.0 * abs gridDist.x;
				height = 2.0 * abs gridDist.y;
			)	
			3: 
			(
				size = abs gridDist.x
				zscale = abs gridDist.y
			)	
 		)
	)
		
-- simple lerp
	
	fn lerp  a b s = (a + s * (b - a))	

-- sets edge vis
		
	fn mxssetedgevisflags m face flags =
	(	
		setEdgeVis m  face 1 flags[1];
		setEdgeVis m  face 2 flags[2];
		setEdgeVis m  face 3 flags[3];
	)
	
-- generate ucoords base on distances	
	
	fn GetUCoords =
	(
		ucoords = #();
		ucoords.count = curvedata.count;
		ucoords[1] = 0.0;
		if curvedata.count == 2 then
			ucoords[2] = 1.0;
		else
		(
			tlen = 0.0;
			p1 = curvedata[1]
			for i = 2 to curvedata.count  do
			(
				p2 = curvedata[i]; 
				tlen += distance p1 p2;
				ucoords[i] = tlen;
				p1 = p2;
			)
			for i = 1 to ucoords.count do ucoords[i] /= tlen; -- normalize to the total length
		)		
		ucoords	
	)	

-- generate V coords base on the x or y dimension	
	
	fn GetVCoords npsegs xdim =
	(	
		vcoords = #();
		vcoords.count = npsegs + 1;
		scalar = 0.5/size;
		
		for i = 1 to npsegs + 1  do
		(
			p = getvert mesh i;
			if xdim then
				vcoords[i] = scalar * abs p.x;
			else
				vcoords[i] = scalar * abs p.y;
		)
		vcoords;
	)	

-- create the mesh	
	
	fn doBuildMesh =
	(
		nlsegs = (wsegs + hsegs) * 2;
		if cornersegs then nlsegs += 8;
			
		npsegs = curvedata.count - 1;
		npsegs_p1 = npsegs + 1;
		
		nverts = npsegs_p1 * nlsegs;
		nfaces = npsegs * nlsegs * 2;
		
-- offsets and sizes		
		
		w = width * 0.5;
		h = height * 0.5;
		s = size;
		
-- "cardinal" points that form the interior and exterior corners of the picture frame  		
		
		cp = #([-w-s,-h-s,0],[-w,-h,0], [w+s,-h-s,0],[w,-h,0], [w+s,h+s,0],[w,h,0], [-w-s,h+s,0],[-w,h,0]);
		
		setNumVerts mesh nverts;
		setNumFaces mesh nfaces;
		
-- cache the side variations in a arrays so we can loop through them		
		
		segcounts = #(wsegs,hsegs,wsegs,hsegs);
		seglenghts = #(width,height,width,height);
		segstarts = #(-w,-h,w,h);
		segdir = #(1,1,-1,-1);
		posindex = #(1,2,1,2);
		
-- geo verts		
		
		pa = #();
		pa.count = npsegs_p1;
		vi = 1;	-- vert incrementer
		
		for i = 1 to 4 do
		(
			pind = i*2;
			p1 = cp[pind - 1];
			p2 = cp[pind];	
			
-- cache the profile			
			
			for j = 1 to npsegs_p1  do
			(
				pa[j] = lerp p1 p2 (curvedata[j].x); 
				pa[j].z = curvedata[j].y * zscale;
			)	
			
-- the initial starting line of diagonal verts			
			
			for j = 1 to npsegs_p1  do
			(
				setvert mesh vi pa[j];
				vi += 1;
			)
			if cornersegs then
			(
				pos = [0,0,0];
				pos[posindex[i]] = segstarts[i];
				for j = 1 to npsegs_p1  do
				(
					pos[3 - posindex[i]] = pa[j][3 - posindex[i]]; 	-- profile coord reverse of the lenght wise
					pos.z = pa[j].z;
					setvert mesh vi pos;
					vi += 1;
				)
			)	
					
-- the length wize subdivisions			
			
			for k = 1 to segcounts[i] - 1 do
			(
				pos = [0,0,0];
				pos[posindex[i]] = segstarts[i] +  segdir[i] * seglenghts[i] * k/segcounts[i];
				for j = 1 to npsegs_p1  do
				(
					pos[3 - posindex[i]] = pa[j][3 - posindex[i]]; 	-- profile coord reverse of the lenght wise
					pos.z = pa[j].z;
					setvert mesh vi pos;
					vi += 1;
				)
			)
			if cornersegs then
			(
				pos = [0,0,0];
				pos[posindex[i]] = -segstarts[i];
				for j = 1 to npsegs_p1  do
				(
					pos[3 - posindex[i]] = pa[j][3 - posindex[i]]; 	-- profile coord reverse of the lenght wise
					pos.z = pa[j].z;
					setvert mesh vi pos;
					vi += 1;
				)
			)	
		)	

-- geo faces			
		fi = 1;	-- face incrementer
		si_offset = 0;
		ei_offset = npsegs_p1;
		starts = #(0, wsegs, wsegs + hsegs,2 * wsegs + hsegs, nlsegs);
		if cornersegs then 
			starts = #(0, 2 + wsegs,4 + wsegs + hsegs,6 + 2 * wsegs + hsegs, nlsegs + 2);
		side = 0;
		for i = 1 to nlsegs do
		(	
			if smoothframe then -- bit of a pain to compute the correct smoothing group
			(		
				smg = 2;
				if i > starts[side+1] then 	side+=1;
				if mod side 2 == 0 then smg = 4;	
			)		
			else
				smg = 0;
			
			for j = 1 to npsegs  do
			(
				s1 = si_offset + j;
				e1 = ei_offset + j;
				s2 = s1 + 1;
				e2 = e1 + 1;
				
				setface mesh fi [e1,e2,s1];
				mxssetedgevisflags mesh fi #{1,3};
				setFaceSmoothGroup mesh fi smg;
				setFaceMatID mesh fi 2;
				fi += 1;
				
				setface mesh fi [s2,s1,e2];
				mxssetedgevisflags mesh fi #{1,3};
				setFaceSmoothGroup mesh fi smg;
				setFaceMatID mesh fi 2;
				fi += 1;
			)
			si_offset += npsegs_p1;
			ei_offset += npsegs_p1;
			if i == nlsegs - 1 then ei_offset = 0; -- wrap around the mesh make the first vert row our end verts
		)	
	
		if mapCoords then
		(	
			if contUV then
			(	
-- allocate mapping			
			
				ntverts = nverts + npsegs_p1;
				meshop.setMapSupport mesh 1 true;
				meshop.setNumMapVerts mesh 1 ntverts;
				meshop.setNumMapFaces mesh 1 nfaces; 	

-- mapping verts			
				tlen = 2 * (width + height);
				vcoords = #(0.0, width/tlen, (width + height)/tlen, (2.0 * width + height)/tlen, 1.0);
				ucoords = GetUCoords();
				vi = 1;
				for i = 1 to 4 do 
				(
					v = vcoords[i];
					for j = 1 to npsegs_p1 do	-- initial row of tverts
					(
						vv = v; -- restore v every loop
						u = ucoords[j];
						if flipUV then swap vv u;
						meshop.setmapvert mesh 1 vi [u,vv,0.0];
						vi += 1;
					)
					if cornersegs then			-- start row of corner tverts
					(
						v = vcoords[i] + size/tlen;	
						for j = 1 to npsegs_p1 do
						(
							vv = v;
							u = ucoords[j];
							if flipUV then swap vv u;
							meshop.setmapvert mesh 1 vi [u,vv,0.0];
							vi += 1;
						)
					)	
					for k = 1 to segcounts[i] - 1 do -- side subdivisions tvert rows
					(	
						v = lerp vcoords[i] vcoords[i+1] (k as float/segcounts[i] as float);
						for j = 1 to npsegs_p1 do
						(
							vv = v; -- restore v every loop
							u = ucoords[j];
							if flipUV then swap vv u;
							meshop.setmapvert mesh 1 vi [u,vv,0.0];
							vi += 1;
						)
					)	
					if cornersegs then		-- end row of corner tverts
					(
						v = vcoords[i+1] - size/tlen;
						for j = 1 to npsegs_p1 do
						(
							vv = v;
							u = ucoords[j];
							if flipUV then swap vv u;
							meshop.setmapvert mesh 1 vi [u,vv,0.0];
							vi += 1;
						)
					)
				)
				for j = 1 to npsegs_p1 do -- the last set of verts	
				(
					u = ucoords[j];
					v = 1.0;
					if flipUV then swap v u;
					meshop.setmapvert mesh 1 vi [u,v,0.0];
					vi += 1;
				)
-- mapping faces	
				fi = 1;	
				si_offset = 0;
				ei_offset = npsegs_p1;
				for i = 1 to nlsegs do
				(	
					for j = 1 to npsegs  do
					(
						s1 = si_offset + j;
						e1 = ei_offset + j;
						s2 = s1 + 1;
						e2 = e1 + 1;
						meshop.setMapFace mesh 1 fi [e1,e2,s1]
						fi += 1;
						meshop.setMapFace mesh 1 fi [s2,s1,e2]
						fi += 1;
					)
					si_offset += npsegs_p1;
					ei_offset += npsegs_p1;
				)	
			)				
			else -- create mapping base on xy positions
			(
				ntverts = 4 * (nlsegs + 1) * npsegs_p1;
				meshop.setMapSupport mesh 1 true;
				meshop.setNumMapVerts mesh 1 ntverts;
				meshop.setNumMapFaces mesh 1 nfaces;
				
				ucoords = GetUCoords();
				w_vcoords = GetVCoords npsegs true;
				h_vcoords = GetVCoords npsegs false;
				
				vi = 1;
				for i = 1 to 4 do
				(	
					for j = 1 to npsegs_p1 do -- initial row
					(	
						u = ucoords[j];
						if i == 1 or i == 3 then
							v =  0.5 + w_vcoords[j];
						else
							v =  0.5 + h_vcoords[j];
						if flipUV then swap v u;
						
						meshop.setmapvert mesh 1 vi [u,v,0.0];
						vi += 1;
					)
					if cornersegs then
					(
						if i == 1 or i == 3 then
							v =  0.5 + w_vcoords[npsegs_p1];
						else
							v =  0.5 + h_vcoords[npsegs_p1];
					
						for j = 1 to npsegs_p1 do
						(	
							vv = v; -- restore vcoord for each loop
							u = ucoords[j];
							if flipUV then swap vv u;
							meshop.setmapvert mesh 1 vi [u,vv,0.0];
							vi += 1;
						)
					)	
					for k = 1 to segcounts[i] - 1 do -- handle the length wize subdivision	
					(
						if i == 1 or i == 3 then
							v =  0.5 - lerp -w_vcoords[npsegs_p1] w_vcoords[npsegs_p1] (k as float/segcounts[i] as float);
						else
							v =  0.5 - lerp -h_vcoords[npsegs_p1] h_vcoords[npsegs_p1] (k as float/segcounts[i] as float);
					
						for j = 1 to npsegs_p1 do
						(	
							vv = v; -- restore vcoord for each loop
							u = ucoords[j];
							if flipUV then swap vv u;
							meshop.setmapvert mesh 1 vi [u,vv,0.0];
							vi += 1;
						)
					)	
					if cornersegs then
					(
						if i == 1 or i == 3 then
							v =  0.5 - w_vcoords[npsegs_p1];
						else
							v =  0.5 - h_vcoords[npsegs_p1];
					
						for j = 1 to npsegs_p1 do
						(	
							vv = v; -- restore vcoord for each loop
							u = ucoords[j];
							if flipUV then swap vv u;
							meshop.setmapvert mesh 1 vi [u,vv,0.0];
							vi += 1;
						)
					)			
					for j = 1 to npsegs_p1 do -- end row	
					(	
						u = ucoords[j];
						if i == 1 or i == 3 then
							v = 0.5 - w_vcoords[j];
						else
							v = 0.5 - h_vcoords[j];
						if flipUV then swap v u;
						meshop.setmapvert mesh 1 vi [u,v,0.0];
						vi += 1;
					)
				)	
-- create the faces, every face generating routine is slightly different !!! :? 				
				fi = 1;	
				si_offset = 0;
				ei_offset = npsegs_p1;
				for i = 1 to 4 do
				(	
					segs = segcounts[i];
					if cornersegs then segs += 2;
					for k = 1 to segs do
					(	
						for j = 1 to npsegs  do
						(
							s1 = si_offset + j;
							e1 = ei_offset + j;
							s2 = s1 + 1;
							e2 = e1 + 1;
							meshop.setMapFace mesh 1 fi [e1,e2,s1];
							fi += 1;
							meshop.setMapFace mesh 1 fi [s2,s1,e2];
							fi += 1;
						)
						si_offset += npsegs_p1;
						ei_offset += npsegs_p1;
					)	
					si_offset += npsegs_p1;
					ei_offset += npsegs_p1;
				)
			)		
		)	
		if picplane then   -- add our picture quad with sub divisions
		(
			msh = TriMesh();
			setMesh msh length:height  width:width  lengthsegs:hsegs  widthsegs:wsegs;
			for v = 1 to msh.numverts do  -- offset so its center on the origin
				setvert msh v ((getvert msh v) - [w,h,-curvedata[curvedata.count].y * zscale]); 
			if mapCoords then
				meshop.defaultMapFaces msh 1; -- add a normalized planar map
			mesh += msh;	-- boolean is nice as it even welds the verts
			delete msh;
		)	
		update mesh;
	)
	on update do doBuildMesh();
	on buildmesh do doBuildMesh();
)
0 Likes
Message 3 of 3

mightykuchka
Observer
Observer

Very interesting.

Good start point.

I will try it.

Thanks.

0 Likes