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;
)
)
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
I already anticipate your possible question: – But how to render mesh solid?
look at simpleManipulator and its addGizmoMesh method