Notifications
Clear all

[Closed] Why ArrowHelper extending Helper and not mesh?

in your example it’s also not necessary to rebuild whole mesh on size changed. you can just move (transform, scale) the mesh instance verts …
ideally we should rebuild mesh only in topology changed case

memory leaking is a big issue for this type of scripted helpers

plugin Helper arrow_helper
name:"arrow_helper"
classID:#(0x45c33d08, 0x16e70cb1)
category:"Standard"
extends:dummy
replaceUI:true;
    (
    	local lastSize, msh = trimesh(), initialized = false;
    	
    	parameters main rollout:params
    	(
    		size type:#float ui:ui_size default:10.0;
    	)
    	
    	rollout params "Params"
    	(
    		spinner ui_size "Icon Size:" range:[0, 100000000.0, size] fieldwidth:64 type:#float align:#center;
    	)

    	tool create
    	(
     		on mousePoint click do case click of
     		(
     			1: 
     			(
     				nodeTM.translation = gridPoint;
     				size = 0.01;
     			)
     			2: #stop
     		)
     		on mouseMove click do case click of
     		(
     			2:  size = amax (abs gridDist.x) (abs gridDist.y);
     		)
    	)
    		
    	fn setedgevisflags m face flags =
    	(	
    		setEdgeVis m face 1 flags[1];
    		setEdgeVis m face 2 flags[2];
    		setEdgeVis m face 3 flags[3];
    	)

    	fn BuildMesh =
    	(
    		if not initialized then
    		(	
    			setNumVerts msh 13
    			setNumFaces msh 22
    			setface msh 1 [1,2,6]
    			setface msh 2 [6,5,1]
    			setface msh 3 [2,3,7]
    			setface msh 4 [7,6,2]
    			setface msh 5 [3,4,8]
    			setface msh 6 [8,7,3]
    			setface msh 7 [4,1,5]
    			setface msh 8 [5,8,4]
    			setface msh 9 [3,2,1]
    			setface msh 10 [1,4,3]
    			setface msh 11 [7,8,12]
    			setface msh 12 [7,12,11]
    			setface msh 13 [6,7,11]
    			setface msh 14 [6,11,10]
    			setface msh 15 [5,6,10]
    			setface msh 16 [5,10,9]
    			setface msh 17 [8,5,9]
    			setface msh 18 [8,9,12]
    			setface msh 19 [9,10,13]
    			setface msh 20 [10,11,13]
    			setface msh 21 [11,12,13]
    			setface msh 22 [12,9,13]
    			setedgevisflags msh  1 #{1..2}
    			setedgevisflags msh  2 #{1..2}
    			setedgevisflags msh  3 #{1..2}
    			setedgevisflags msh  4 #{1..2}
    			setedgevisflags msh  5 #{1..2}
    			setedgevisflags msh  6 #{1..2}
    			setedgevisflags msh  7 #{1..2}
    			setedgevisflags msh  8 #{1..2}
    			setedgevisflags msh  9 #{1..2}
    			setedgevisflags msh  10 #{1..2}
    			setedgevisflags msh  11 #{1}
    			setedgevisflags msh  12 #{2}
    			setedgevisflags msh  13 #{1}
    			setedgevisflags msh  14 #{2}
    			setedgevisflags msh  15 #{1}
    			setedgevisflags msh  16 #{2}
    			setedgevisflags msh  17 #{1}
    			setedgevisflags msh  18 #{2}
    			setedgevisflags msh  19 #{1..3}
    			setedgevisflags msh  20 #{1..3}
    			setedgevisflags msh  21 #{1..3}
    			setedgevisflags msh  22 #{1..3}
                        initialized = true	
    		)
    		
    		setvert msh 1 ([0.5,0,0] * size)
    		setvert msh 2 ([0,0.5,0] * size)
    		setvert msh 3 ([-0.5,0,0] * size)
    		setvert msh 4 ([0,-0.5,0] * size)
    		setvert msh 5 ([0.5,0,7] * size)
    		setvert msh 6 ([0,0.5,7] * size)
    		setvert msh 7 ([-0.5,0,7] * size)
    		setvert msh 8 ([0,-0.5,7] * size)
    		setvert msh 9 ([1.5,0,7] * size)
    		setvert msh 10 ([0,1.5,7] * size)
    		setvert msh 11 ([-1.5,0,7] * size)
    		setvert msh 12 ([0,-1.5,7] * size)
    		setvert msh 13 ([0,0,10] * size)
    		update msh
    	)
    	
    	on getDisplayMesh do 
    	(
    		if size != lastSize  do 
    		(
    			buildmesh();
    			lastSize = size;
    		)
    		msh;
    	)
    )

@denisT Sory what I meand is just something like this:

plugin Helper arrow_helper
name:"arrow_helper"
classID:#(0x45c33d08, 0x16e70cb1)
category:"Standard"
extends:dummy
replaceUI:true;
    (
    	msh = trimesh()
            ...
    )

I mean without local modifier.

also another difference between hanging the mesh off a dummy , forcing it to be a helper, and not a simpleObject is that it can only ever be displayed in the viewports as backface culled wireframe when a helper.

So a red_arrow_helper, which should display a red arrow, is not posible?
Also tried that HelperTest_DisplayMesh example from max help, but when triing to change the size of that box it always crashes and the problem seems to be in this line:

lastSize = size

At least the error mesage saies something about a problem wit “=” operator between lastSize and size.

Delete both ‘\’ characters in the lines above the two lastSize = size occurrencies.

always red arrow

plugin Helper arrow_helper
	name:"arrow_helper"
	classID:#(0x45c33d08, 0x16e70cb1)
	category:"Standard"
	extends:dummy
	replaceUI:true;
(
	local lastsize, msh = trimesh(), initialized = false, this_node = undefined;
	
	parameters main rollout:params
	(
		size type:#worldunits ui:ui_size default:10.0;
	)
	
	rollout params "Params"
	(
		spinner ui_size "Size:" range:[0, 100000000.0, size] fieldwidth:64 type:#worldunits align:#right;
	)

	tool create
	(
 		on mousePoint click do case click of
 		(
 			1: 
 			(
 				nodeTM.translation = gridPoint;
 				size = 0.01;
 			)
 			2: #stop
 		)
 		on mouseMove click do case click of
 		(
 			2:  size = amax (abs gridDist.x) (abs gridDist.y);
 		)
	)
		
	fn setedgevisflags m face flags =
	(	
		setEdgeVis m face 1 flags[1];
		setEdgeVis m face 2 flags[2];
		setEdgeVis m face 3 flags[3];
	)

	fn BuildMesh =
	(
		if not initialized then
		(	
			setNumVerts msh 13;
			setNumFaces msh 12;
			setface msh 1 [1,2,6];
			setface msh 2 [6,5,1];
			setface msh 3 [2,3,7];
			setface msh 4 [7,6,2];
			setface msh 5 [3,4,8];
			setface msh 6 [8,7,3];
			setface msh 7 [4,1,5];
			setface msh 8 [5,8,4];
			setface msh 9 [9,10,13];
			setface msh 10 [10,11,13];
			setface msh 11 [11,12,13];
			setface msh 12 [12,9,13];
			setedgevisflags msh  1 #{1..2};
			setedgevisflags msh  2 #{1..2};
			setedgevisflags msh  3 #{1..2};
			setedgevisflags msh  4 #{1..2};
			setedgevisflags msh  5 #{1..2};
			setedgevisflags msh  6 #{1..2};
			setedgevisflags msh  7 #{1..2};
			setedgevisflags msh  8 #{1..2};
			setedgevisflags msh  9 #{1..3};
			setedgevisflags msh  10 #{1..3};
			setedgevisflags msh  11 #{1..3};
			setedgevisflags msh  12 #{1..3};
			initialized = true;
		)
		
		setvert msh 1 ([0.05,0,0] * size);
		setvert msh 2 ([0,0.05,0] * size);
		setvert msh 3 ([-0.05,0,0] * size);
		setvert msh 4 ([0,-0.05,0] * size);
		setvert msh 5 ([0.05,0,0.7] * size);
		setvert msh 6 ([0,0.05,0.7] * size);
		setvert msh 7 ([-0.05,0,0.7] * size);
		setvert msh 8 ([0,-0.05,0.7] * size);
		setvert msh 9 ([0.15,0,0.7] * size);
		setvert msh 10 ([0,0.15,0.7] * size);
		setvert msh 11 ([-0.15,0,0.7] * size);
		setvert msh 12 ([0,-0.15,0.7] * size);
		setvert msh 13 ([0,0,1] * size);
				
		update msh;
	)
	
	on getDisplayMesh do 
	(
		if size != lastsize then
		(
			buildmesh();
			lastsize = size;
		)
		msh;
	)
	
	on attachedToNode n do this_node = n;
	on detachedFromNode n do this_node = undefinedl	
	on useWireColor do 
	(	
		if this_node != undefined then this_node.wirecolor = red;
		true;
	)	
)

Sorry my error again, was tallking about a solid red arrow, not a wire one. But thanks for the code, it looks interesting.

you can’t draw a solid mesh in a helper plugin. it’s a limitation.

check the code below:

plugin Helper AdvHelperBox
	name:"AdvHelperBox"
	classID:#(0x47db14fe, 0x4e9b5f99)
	category:"Standard"
	extends:dummy
(
	struct mesh_data_struct (obj, mesh, size)
	
	local mesh_data, test_var
	
	parameters pblock rollout:params
	(
		size type:#float ui:ui_amount default:40.0
	)
	rollout params "HelperTest Parameters"
	(
		spinner ui_amount "Size:" range:[0, 1e9, 40]
	)
	on getDisplayMesh do
	(
		format "display mesh - %\n" (timeStamp())
		
		if not isstruct mesh_data do 
		(
			mesh_data = mesh_data_struct()
		)
		if not iskindof mesh_data.obj Box do
		(
			mesh_data.obj = createInstance box mapCoords:false
			mesh_data.size = undefined
		)
		if (mesh_data.size != size) do
		(
			format "build mesh - %\n" (timeStamp())
			
			mesh_data.obj.length = mesh_data.obj.width = mesh_data.obj.height = size
			mesh_data.mesh = mesh_data.obj.mesh
		)
		mesh_data.size = size
		mesh_data.mesh
	)
	tool create
	(
		on mousePoint click do
		(
			nodeTM.translation = gridPoint
			#stop
		)
	)
	on update do
	(
		mesh_data = mesh_data_struct()
	)
)

i’ve just modified the code from the MXS help.
why?

the problem is – every helper node has more than simple geometry events which handle Mesh Build
for example a view redraw.
so we have to care about only reasonable mesh rebuild.

as you can see the output trace in the listener my plugin going very often in display event, but does rebuild only if size changed.
it’s very simple situation where we have to check only one parameter or condition. in real life the “rebuild reason” might be much more complicated.

another problem is every time we change any variable in plugins local scope it causes the update as well.
as you can see i put obj, mesh, and size into a struct variable. so all changes we do are in this struct scope, and it doesn’t cause the plugin update

try to change a “test” variable ‘test_var’

$.test_var = 0

it causes the plugin update, instead of after changing any mesh_data property:

$.mesh_data.size = 10
1 Reply
(@denist)
Joined: 11 months ago

Posts: 0

I already anticipate your possible question: – But how to render mesh solid?

look at simpleManipulator and its addGizmoMesh method

You mean this here?
If yes, unfortunatelly I don´t understand how it can help me to create a solide red arrow helper plugin, which has nothing to say since I have really bad knowledge in maxscript.

Page 2 / 3