[Closed] simpleManipulator help
I have couple of questions about scripted manipulators
#1 Is it possible that when cloning this node each copy need to be unique object (not instance or reference) even if this options are selected in “CloneOptions” dialog.
The reason why I need this is because when user check “Set As RefCoordSys” checkbutton
only that node can be used as RefCoordSys, and all other will be set to checkbutton.checked = off
#2 Can simpleManipulator have “Point Helper” options like “Draw on top” and “Constant screen size”.
This is my first attempt to write this kind of plugin.
plugin simpleManipulator NewPivot name:"PivotHelper" invisible:false classID:#(0x38ba17e3, 0x451d9fac) category:"Manipulators" version:1
(
local ppNode, ppClass = NewPivot, gizClrR = [1,0,0], gizClrG = [0,1,0], gizClrB = [0,0,1]
local ppDotsA = #([0,0,0], [-0.5,0.5,1], [-0.15,0.15,8.0], [-0.5,0.5,8.5], [0,0,10.0], [0.5,-0.5,8.5], [0.15,-0.15,8.0], [0.5,-0.5,1], [0,0,0], [0.5,0.5,1], [0.15,0.15,8.0], [0.5,0.5,8.5], [0,0,10.0], [-0.5,-0.5,8.5], [-0.15,-0.1,8.0], [-0.5,-0.5,1], [0,0,0])
local ppDotsN = #([0,0,0], [-0.5,0.5,1], [0,0,10.0], [0.5,-0.5,1], [0,0,0], [0.5,0.5,1], [0,0,10.0], [-0.5,-0.5,1], [0,0,0])
fn rotatePoints rotAxis:[0,0,1] rotCenter:[0,0,0] rotAngle:90 posArr: =
(
q = quat rotAngle (normalize rotAxis)
for p in posArr collect (((p - rotCenter) * q) + rotCenter)
)
parameters main rollout:paramRoll
(
currentRCS type:#string ui:et_note default:(getRefCoordSys()) animatable:off
shownote type:#boolean ui:cb_shownote default:off animatable:off
note type:#string ui:et_note default:"PivotNote" animatable:off
notecolor type:#color ui:cp_notecolor default:yellow animatable:false
size type:#worldUnits ui:spn_size default:20 animatable:off
type type:#radiobtnIndex ui:rb_Type default:1 animatable:off
rcs type:#boolean ui:btn_rcs default:off animatable:off
on viewLabel set value do if isKindOf ppNode ppClass do (setUserPropBuffer ppNode value)
on rcs set value do if isKindOf ppNode ppClass do
(
if value == on then
(
currentRCS = getRefCoordSys()
toolMode.coordsys ppNode
enableRefCoordSys (not value)
)
else
(
enableRefCoordSys (not value)
setRefCoordSys (currentRCS as name)
)
)
)
rollout paramRoll "Parameters"
(
colorpicker cp_notecolor "" pos:[1,6] fieldwidth:12 height:12
checkbox cb_shownote "Show Note In Viewport" pos:[20,5]
edittext et_note "" pos:[0,22] fieldWidth:134 height:18
button btn_X "X" pos:[139,22] width:18 height:18
label lbl1 "Gizmo:" pos:[3,43] width:30
radiobuttons rb_type "" labels:#("Arrow","Needle") default:1 columns:2 pos:[50,43]
spinner spn_size "Gizmo Size: " pos:[3,60] fieldwidth:70 range:[0.01, 1e5, 20.0]
checkbutton btn_rcs "Set As RefCoordSys" pos:[3,80] width:154 height:20 highlightColor:((colorMan.getColor #background) * 150.0)
on cb_showViewLabel changed state do et_viewLabel.enabled = cb_showViewLabel.checked
on btn_X pressed do et_note.text = ""
on paramRoll open do
(
if ppNode == null do (ppNode = refs.dependentNodes this firstOnly:on)
if isKindOf ppNode ppClass do
(
if not (isKindOf ppNode[3][3].track Scale_Expression) do
(
ppNode[3][3].track = Scale_Expression()
ppNode[3][3].track.SetExpression "[1,1,1]"
)
)
)
)
on canManipulate target return false
tool create (on mousePoint click do (nodeTM.translation = gridPoint ; #stop))
on updateGizmos do
(
this.clearGizmos()
local coords = if type == 1 then ppDotsA else ppDotsN
local giz = manip.makeGizmoShape()
for n in coords do (giz.AddPoint (n * (size/10)))
this.addGizmoShape giz 0 gizClrB gizClrB
local giz = manip.makeGizmoShape()
for n in (rotatePoints rotAxis:[1,0,0] posArr:coords) do (giz.AddPoint (n * (size/10)))
this.addGizmoShape giz 0 gizClrG gizClrG
local giz = manip.makeGizmoShape()
for n in (rotatePoints rotAxis:[0,-1,0] posArr:coords) do (giz.AddPoint (n * (size/10)))
this.addGizmoShape giz 0 gizClrR gizClrR
if not shownote then (this.addGizmoText "" [0,0,0] 0 (notecolor/255.0) (notecolor/255.0))
else (this.addGizmoText note [0,0,0] 0 (notecolor/255.0) (notecolor/255.0))
)
) ; ok
#1… the best you can do activate with you manipulator plugin the NodeEventCallback and check if new your manipulator added. is so using InstanceMgr make it unique (MakeObjectsUnique)
#2… there is no built-in “constant screen size” functionality for manipulators. but you can use getScreenScaleFactor and transform all manipulator’s gizmos using this factor…
you can do “draw on top” only for gizmos which are flagged as gizmoUseScreenSpace or gizmoUseRelativeScreenSpace
Thanks for reply.
Anyway 2nd options will be only optional in this case. I was just curious if there is already built-in solution. It’s not important as first question.
Can you show me at least I you have some free time how to properly use NodeEventCallback in my case. I not have any expiriance using this callback mechanism.
edit:
can I use InstanceMgr inside plug like this
if InstanceMgr.CanMakeObjectsUnique (nodes = refs.dependentNodes this) do
(
InstanceMgr.MakeObjectsUnique &nodes #individual
)
here is it. it makes all Box class objects unique when an object was added to the scene:
try
(
MakeUnique_NodeEventCallback.enabled = off
MakeUnique_NodeEventCallback = undefined
)
catch()
fn MakeUnique_Callback event handles =
(
nodes = for n in handles where isvalidnode (node = getanimbyhandle n) and iskindof node Box collect
(
if InstanceMgr.CanMakeObjectsUnique node do
(
InstanceMgr.MakeObjectsUnique node #individual
--format ">>>> % %
" node (InstanceMgr.CanMakeObjectsUnique node)
)
node
)
)
MakeUnique_NodeEventCallback = NodeEventCallback added:MakeUnique_Callback modelStructured:MakeUnique_Callback
MakeUnique_NodeEventCallback.enabled = on
edited. we also have to monitor another event (structure changed) to prevent changing an node instancing after creation (by a script or some another tools).
Now I need to guess where to put all of theses.
First “try-catch” at the top ei belove plugin definition.
Then “MakeUnique_Callback” fn above parameter block
And before last bracket i will place ei enabled NodeEventCallback.
that’s an interesting thing… technically you can do it if your plugin is initializing in startup directory (or any other directory which loads after the system was loaded). but if you want to put your plugin in the right place (like sdtscripts) you have to force activating your callback after the system was competelly load. you can use sytem #postSystemStartup general callback for it
Good point. Maybe callbacks like #preNodesCloned and #preMirrorNodes.
This is also node related but not useful I this case (#nodeCreated, #nodeCloned, #sceneNodeAdded)
another solution might be to create and activate the node event callback when first plugin instance was created or loaded… it should work
I read about node event callback but I don’t understand how to setup to works.
All theses arguments just confuse me. :shrug:
here is it… i also wrote a manipulator which supports constant screen size.
try
(
MakeUnique_NodeEventCallback.enabled = off
MakeUnique_NodeEventCallback = undefined
)
catch()
global MakeUnique_NodeEventCallback
plugin simpleManipulator UniqueManip
name:"UniqueManip"
classID:#(-0x0001967, 0x0e598a4)
silentErrors:off
category:"Manipulators"
(
local c = colorMan.getColor #manipulatorsInactive
local node, giz
parameters main rollout:main
(
size type:#float default:1.0 ui:ui_size
constantscreensize type:#boolean default:on ui:ui_constantscreensize
)
rollout main "Parameters"
(
spinner ui_size "Size: " fieldwidth:56 range:[0, 1e9, 1.0] type:#float align:#right offset:[0,0]
checkbox ui_constantscreensize "Constant Screen Size"
)
tool create
(
on mousePoint click do
(
nodeTM.translation = gridPoint
#stop
)
)
on canmanipulate target do return false
on updateGizmos do
(
if not isvalidnode node do node = refs.dependentnodes this firstOnly:on
ntm = node.transform
this.clearGizmos()
giz = manip.makeCircle [0,0,0] size 24
if constantscreensize do
(
s = (getScreenScaleFactor ntm.pos)/25.0
giz.transform (scalematrix [s,s,s])
)
this.addGizmoShape giz (gizmoActiveViewportOnly) c c
)
fn makeCallback = if not iskindof MakeUnique_NodeEventCallback NodeEventCallback do
(
fn MakeUnique_Callback event handles =
(
nodes = for n in handles where isvalidnode (local node = getanimbyhandle n) and iskindof node UniqueManip collect
(
if InstanceMgr.CanMakeObjectsUnique node do InstanceMgr.MakeObjectsUnique node #individual
node
)
format "tm changed > event:% nodes:%
" event nodes
)
MakeUnique_NodeEventCallback = NodeEventCallback added:MakeUnique_Callback modelStructured:MakeUnique_Callback --all:MakeUnique_Callback
MakeUnique_NodeEventCallback.enabled = on
)
on create do makeCallback()
on load do makeCallback()
)
looks like a half your work is done
I will skip constant screen size. It behave very bad when I scroll mouse wheel or copy manipulator.
I’m going to study your method and see how could integrate this in my plug.
I realy appreciate your time and effort.Thank you Denis.
I integrated your method and works really well, as expected:). Also I added uncheck option for “Set as RefCoordSys” checkbutton.
try(MakeUnique_NodeEventCallback.enabled = off ; MakeUnique_NodeEventCallback = null)catch()
plugin simpleManipulator NewPivot name:"PivotHelper" invisible:false classID:#(0x38ba17e3, 0x451d9fac) category:"Manipulators" version:1
(
local ppNode, ppClass = NewPivot, gizClrR = [1,0,0], gizClrG = [0,1,0], gizClrB = [0,0,1]
local ppDotsA = #([0,0,0], [-0.5,0.5,1], [-0.15,0.15,8.0], [-0.5,0.5,8.5], [0,0,10.0], [0.5,-0.5,8.5], [0.15,-0.15,8.0], [0.5,-0.5,1], [0,0,0], [0.5,0.5,1], [0.15,0.15,8.0], [0.5,0.5,8.5], [0,0,10.0], [-0.5,-0.5,8.5], [-0.15,-0.1,8.0], [-0.5,-0.5,1], [0,0,0])
local ppDotsN = #([0,0,0], [-0.5,0.5,1], [0,0,10.0], [0.5,-0.5,1], [0,0,0], [0.5,0.5,1], [0,0,10.0], [-0.5,-0.5,1], [0,0,0])
fn rotatePoints rotAxis:[0,0,1] rotCenter:[0,0,0] rotAngle:90 posArr: =
(
q = quat rotAngle (normalize rotAxis)
for p in posArr collect (((p - rotCenter) * q) + rotCenter)
)
fn makeCallback = if not iskindof MakeUnique_NodeEventCallback NodeEventCallback do
(
fn MakeUnique_Callback event handles =
(
nodes = for n in handles where isvalidnode (local node = getanimbyhandle n) and iskindof node ppClass collect
(
if InstanceMgr.CanMakeObjectsUnique node do (node.rcs = off ; InstanceMgr.MakeObjectsUnique node #individual)
node
)
--format "tm changed > event:% nodes:%
" event nodes
)
MakeUnique_NodeEventCallback = NodeEventCallback added:MakeUnique_Callback modelStructured:MakeUnique_Callback
MakeUnique_NodeEventCallback.enabled = on
)
parameters main rollout:paramRoll
(
currentRCS type:#string ui:et_note default:(getRefCoordSys()) animatable:off
shownote type:#boolean ui:cb_shownote default:off animatable:off
note type:#string ui:et_note default:"PivotNote" animatable:off
notecolor type:#color ui:cp_notecolor default:yellow animatable:false
size type:#worldUnits ui:spn_size default:20 animatable:off
type type:#radiobtnIndex ui:rb_Type default:1 animatable:off
rcs type:#boolean ui:btn_rcs default:off animatable:off
on viewLabel set value do if isKindOf ppNode ppClass do (setUserPropBuffer ppNode value)
on rcs set value do if isKindOf ppNode ppClass do
(
if value == on then
(
currentRCS = getRefCoordSys()
toolMode.coordsys ppNode
enableRefCoordSys (not value)
)
else
(
enableRefCoordSys (not value)
setRefCoordSys (currentRCS as name)
)
)
)
rollout paramRoll "Parameters"
(
colorpicker cp_notecolor "" pos:[1,6] fieldwidth:12 height:12
checkbox cb_shownote "Show Note In Viewport" pos:[20,5]
edittext et_note "" pos:[0,22] fieldWidth:134 height:18
button btn_X "X" pos:[139,22] width:18 height:18
label lbl1 "Gizmo:" pos:[3,43] width:30
radiobuttons rb_type "" labels:#("Arrow","Needle") default:1 columns:2 pos:[50,43]
spinner spn_size "Gizmo Size: " pos:[3,60] fieldwidth:70 range:[0.01, 1e5, 20.0]
checkbutton btn_rcs "Set As RefCoordSys" pos:[3,80] width:154 height:20 highlightColor:((colorMan.getColor #background) * 150.0)
on cb_showViewLabel changed state do et_viewLabel.enabled = cb_showViewLabel.checked
on btn_X pressed do et_note.text = ""
on paramRoll open do
(
if ppNode == null do (ppNode = refs.dependentNodes this firstOnly:on)
if isKindOf ppNode ppClass do
(
if not (isKindOf ppNode[3][3].track Scale_Expression) do
(
ppNode[3][3].track = Scale_Expression()
ppNode[3][3].track.SetExpression "[1,1,1]"
)
)
)
)
on canManipulate target return false
tool create (on mousePoint click do (nodeTM.translation = gridPoint ; #stop))
on updateGizmos do
(
this.clearGizmos()
local coords = if type == 1 then ppDotsA else ppDotsN
local giz = manip.makeGizmoShape()
for n in coords do (giz.AddPoint (n * (size/10)))
this.addGizmoShape giz 0 gizClrB gizClrB
local giz = manip.makeGizmoShape()
for n in (rotatePoints rotAxis:[1,0,0] posArr:coords) do (giz.AddPoint (n * (size/10)))
this.addGizmoShape giz 0 gizClrG gizClrG
local giz = manip.makeGizmoShape()
for n in (rotatePoints rotAxis:[0,-1,0] posArr:coords) do (giz.AddPoint (n * (size/10)))
this.addGizmoShape giz 0 gizClrR gizClrR
if not shownote then (this.addGizmoText "" [0,0,0] 0 (notecolor/255.0) (notecolor/255.0))
else (this.addGizmoText note [0,0,0] 0 (notecolor/255.0) (notecolor/255.0))
)
on create do makeCallback()
on load do makeCallback()
) ; ok