How to create dynamic trajectories for mesh vertices?

How to create dynamic trajectories for mesh vertices?

Anonymous
Not applicable
1,295 Views
6 Replies
Message 1 of 7

How to create dynamic trajectories for mesh vertices?

Anonymous
Not applicable

Hi all,

 

I have two editable meshes representing the same object at two different times. They are exactly the same (same number of points etc.), just in different configurations. I am studying the transition from time 1 to time 2. I applied the Morpher modifier to represent the motion between the two states. What I am interested in is to display the vectors that represent the displacement of each single vertex of the mesh between the initial and the final state. Basically I am looking for a way to connect corresponding vertices with a segment. 

For now I have a script that creates static lines connecting corresponding vertices of the two meshes. I am wondering if it is possible to adapt this script in order to make it more dynamic. I mean like automatically adapting the lines when I move one of the two meshes to always keep them connected? I am thinking about displaying somehow the changes in the lines' lengths during an animation (while using the morpher modifier would be perfect, but probably not doable?). Also, is it possible to create arrows instead of lines? I'd be interested in displaying the vectors representing the motion of vertices (pointing to state2 from state1). Thank you a lot!!

 

Here is the script I am using:

 

-- Creates lines between corresponding vertices of two selected editable meshes.
-- No error checking is done.
-- v1 12/30/2020 LRM
--

fn Line2Points pointA pointB =
(
ss = SplineShape pos:pointA
addNewSpline ss
addKnot ss 1 #corner #line PointA
addKnot ss 1 #corner #line PointB
updateShape ss
ss
)

fn morph_vectors vstart vend =
(
-- Creates a line between corresponding vertices of two selected objects
-- that have the same number of vertices.
--
for i = vstart to vend do
(
pA = meshop.getVert objA i
pB = meshop.getVert objB i
newLine = Line2Points pA pB
)
)

objA = selection[1]
objB = selection[2]
nV = meshop.getNumVerts objA
nvt = nv as string
rollout vectorRollout3 "Morph Vectors" width:200 height:160
(
button 'btnGo' "Go" pos:[32,104] width:96 height:36 align:#left
edittext 'edt1' "" pos:[64,32] width:78 height:24 align:#left
label 'lbl1' "Start vertex" pos:[0,32] width:65 height:15 align:#left
edittext 'edt2' "" pos:[64,64] width:78 height:24 align:#left
label 'lbl2' "End Vertex" pos:[0,64] width:56 height:16 align:#left
label 'lbl3' "Total number of vertices:" pos:[0,8] width:120 height:17 align:#left
label 'labelnverts' nvt pos:[128,8] width:48 height:19 align:#left
on btnGo pressed do
(
vstart = edt1.text as integer
vend = edt2.text as integer
morph_vectors vstart vend
messagebox "Done"
)
)
createdialog vectorRollout3

 

0 Likes
Accepted solutions (2)
1,296 Views
6 Replies
Replies (6)
Message 2 of 7

denisT.MaxDoctor
Advisor
Advisor

you can look at Scripted Manipulators.

this is the most efficient solution for this kind of tasks

0 Likes
Message 3 of 7

denisT.MaxDoctor
Advisor
Advisor

here is an example how to work with Scripted Manipulator... 

 

plugin simpleManipulator MorphTracksManipulator
name:"Morph Tracks"
classID:#(0x2feb0000, 0x00ddc02)
silentErrors:off
category:"Manipulators"
(
	local node, giz

	local source_mesh
	local target_mesh

	fn getThisNode = (refs.dependentnodes this)[1]  
	
    parameters params rollout:params
    ( 
		source_node type:#node subanim:on ui:ui_source
		target_node type:#node subanim:on ui:ui_target
	)
	
	fn isGeometryNode node = isvalidnode node and iskindof node GeometryClass
	
	rollout params "Parameters"
	(
		group "Geometry: "
		(
			pickbutton ui_source "< Source >" width:144 autoDisplay:on filter:isgeometrynode align:#left offset:[-4,0] \
				tooltip:"Pick Source Node"
			pickbutton ui_target "< Tareget >" width:144 autoDisplay:on filter:isgeometrynode align:#left offset:[-4,0] \
				tooltip:"Pick Target Node"
		)
	)

	tool create 
	(
		on mousePoint click do 
		(
			nodeTM.translation = [0,0,0] --gridPoint
			#stop 
		)
	)
	
	on canmanipulate target do return true
		
	fn makeMorphTracks = 
	(
		node = getThisNode()
		node_tm = inverse node.transform
		line_color = node.wirecolor as point4
		
		if isGeometryNode target_node and isGeometryNode source_node do
		(
			this.clearGizmos()
			
			source_mesh = source_node.mesh
			target_mesh = target_node.mesh
			
			source_tm = source_node.transform
			target_tm = target_node.transform
			
			num = amin source_mesh.numverts target_mesh.numverts
			for i=1 to num do
			(
				giz = manip.makeGizmoShape() 
				giz.startNewLine()
				
				p0 = getvert target_mesh i * target_tm 
				giz.addPoint p0
				p1 = getvert source_mesh i * source_tm
				giz.addPoint p1
				
				giz.transform node_tm
				this.addGizmoShape giz (gizmoActiveViewportOnly) line_color line_color
			)	
		)
	)
	on updateGizmos do 
	(
		makeMorphTracks()
	)
)
/*
-------------- Test scene setup: ----------

gc()

delete objects
src=geosphere name:#source wirecolor:orange pos:[-50,0,0]
trg = torus name:#target wirecolor:green pos:[50,0,0]
rotate trg (angleaxis 90 y_axis)

manuip_node = MorphTracksManipulator name:"MorphTracker" isselected:on wirecolor:yellow
manuip_node.source_node = src
manuip_node.target_node = trg

*/

 

 

but there are many more things you need to learn. The main issue with all script manipulators is how to minimize memory leaks (optimize memory usage).

 

 

0 Likes
Message 4 of 7

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

this is better version:

plugin simpleManipulator MorphTracksManipulator
name:"Morph Tracks"
classID:#(0x2feb0000, 0x00ddc02)
silentErrors:off
category:"Manipulators"
(
	local node, giz

	local source_mesh
	local target_mesh

	fn getThisNode = (refs.dependentnodes this)[1]  
	
    parameters params rollout:params
    ( 
		source_node type:#node subanim:on ui:ui_source
		target_node type:#node subanim:on ui:ui_target
			
		selected type:#boolean animatable:off ui:ui_selected
	)
	
	fn isGeometryNode node = isvalidnode node and iskindof node GeometryClass
	
	rollout params "Parameters"
	(
		group "Geometry: "
		(
			pickbutton ui_source "< Source >" width:144 autoDisplay:on filter:isgeometrynode align:#left offset:[-4,0] \
				tooltip:"Pick Source Node"
			pickbutton ui_target "< Tareget >" width:144 autoDisplay:on filter:isgeometrynode align:#left offset:[-4,0] \
				tooltip:"Pick Target Node"
			
			checkbox ui_selected "Use Selected Vertices" offset:[0,8]
		)
	)

	tool create 
	(
		on mousePoint click do 
		(
			nodeTM.translation = [0,0,0] --gridPoint
			#stop 
		)
	)
	
	on canmanipulate target do return true
		
	fn makeMorphTracks = 
	(
		node = getThisNode()
		node_tm = inverse node.transform
		line_color = node.wirecolor as point4
		
		if isGeometryNode target_node and isGeometryNode source_node do
		(
			this.clearGizmos()
			
			source_mesh = source_node.mesh
			target_mesh = target_node.mesh
			
			source_tm = source_node.transform
			target_tm = target_node.transform
			
			tvv = if selected then target_mesh.selectedverts as bitarray else #{1..target_mesh.numverts}
			svv = source_mesh.numverts
			
			giz = manip.makeGizmoShape() 
			
			for v in tvv where v <= svv do
			(
				giz.startNewLine()
				
				p0 = getvert target_mesh v * target_tm 
				giz.addPoint p0
				p1 = getvert source_mesh v * source_tm
				giz.addPoint p1
			)
				
			giz.transform node_tm
			this.addGizmoShape giz (gizmoActiveViewportOnly) line_color line_color
		)
	)
	on updateGizmos do 
	(
		makeMorphTracks()
	)
)
/*
-------------- Test scene setup: ----------

gc()

delete objects
src=geosphere name:#source wirecolor:orange pos:[-50,0,0]
trg = torus name:#target wirecolor:green pos:[50,0,0]
rotate trg (angleaxis 90 y_axis)

manuip_node = MorphTracksManipulator name:"MorphTracker" isselected:on wirecolor:yellow
manuip_node.source_node = src
manuip_node.target_node = trg

*/
Message 5 of 7

Anonymous
Not applicable

@denisT.MaxDoctor  Thank you very much!! Your script works perfectly! Just one last question: is it possible to draw arrows instead of simple lines? I'd be interested in knowing the direction of motion. Thank you again!

0 Likes
Message 6 of 7

denisT.MaxDoctor
Advisor
Advisor
Accepted solution

@Anonymous wrote:

@denisT.MaxDoctor  Thank you very much!! Your script works perfectly! Just one last question: is it possible to draw arrows instead of simple lines? I'd be interested in knowing the direction of motion. Thank you again!

 


plugin simpleManipulator MorphTracksManipulator
name:"Morph Tracks"
classID:#(0x2feb0000, 0x00ddc02)
silentErrors:off
category:"Manipulators"
(
	local node, giz

	local source_mesh
	local target_mesh

	fn getThisNode = (refs.dependentnodes this)[1]  
	
    parameters params rollout:params
    ( 
		source_node type:#node subanim:on ui:ui_source
		target_node type:#node subanim:on ui:ui_target
			
		selected type:#boolean animatable:off ui:ui_selected
		markers type:#boolean animatable:off ui:ui_markers
		
		source_marker type:#integer default:6 animatable:off ui:ui_source_marker
		target_marker type:#integer default:9 animatable:off ui:ui_target_marker
	)
	
	fn isGeometryNode node = isvalidnode node and iskindof node GeometryClass
	
	
	rollout params "Parameters"
	(
		local marker_types = 
		#(
			"None", 
			"Point", "Plus Sign", "Asterisk", "xMarker",
			"Dot", "Small Dot", 
			"Small HollowBox", "HollowBox", "Big Box", 
			"Small Circle", "Circle", 
			"Small Triangle", "Triangle", 
			"Small Diamond", "Diamond"     
		)
		group "Source: "
		(
			pickbutton ui_source "< Source >" width:144 autoDisplay:on filter:isgeometrynode align:#left offset:[-4,0] \
				tooltip:"Pick Source Node"
			label lb_source "Marker:" align:#left offset:[0,2] across:2
			dropdownlist ui_source_marker items:marker_types width:102 height:(marker_types.count+1) align:#right offset:[5,-2]
			
		)
		group "Target: "
		(
			pickbutton ui_target "< Tareget >" width:144 autoDisplay:on filter:isgeometrynode align:#left offset:[-4,0] \
				tooltip:"Pick Target Node"
			label lb_target "Marker:" align:#left offset:[0,2] across:2
			dropdownlist ui_target_marker items:marker_types width:102 height:(marker_types.count+1) align:#right offset:[5,-2]
			
		)
		group "Display: "
		(
			checkbox ui_selected "Use Selected Vertices" offset:[0,0]
			checkbox ui_markers "Show Markers" offset:[0,0]
		)
		
		fn getMarkerType index = 
		(
			if index > 1 and index <= marker_types.count do (substitutestring marker_types[index] " " "") as name 
		)
	)

	tool create 
	(
		on mousePoint click do 
		(
			nodeTM.translation = [0,0,0] --gridPoint
			#stop 
		)
	)
	
	on canmanipulate target do return true
		
	fn makeMorphTracks = 
	(
		node = getThisNode()
		node_tm = inverse node.transform
		line_color = yellow as point4
		mark_color = orange as point4  
		
		if isGeometryNode target_node and isGeometryNode source_node do
		(
			this.clearGizmos()
			
			source_mesh = source_node.mesh
			target_mesh = target_node.mesh
			
			source_tm = source_node.transform
			target_tm = target_node.transform
			
			tvv = if selected then target_mesh.selectedverts as bitarray else #{1..target_mesh.numverts}
			svv = source_mesh.numverts
			
			giz = manip.makeGizmoShape() 
			
			startline = giz.startNewLine
			addpoint = giz.addPoint
			
			addmarker = this.addGizmoMarker
			
			trg_mark = this.params.getMarkerType target_marker 
			src_mark = this.params.getMarkerType source_marker 
			
			for v in tvv where v <= svv do
			(
				startline()
				
				p0 = getvert target_mesh v * target_tm 
				addpoint p0
				p1 = getvert source_mesh v * source_tm
				addpoint p1
				
				if markers do
				(
					if trg_mark != undefined do
						addmarker trg_mark (p0 * node_tm) (gizmoActiveViewportOnly) mark_color mark_color
					if src_mark != undefined do
						addmarker src_mark (p1 * node_tm) (gizmoActiveViewportOnly) mark_color mark_color
				)
			)
				
			giz.transform node_tm
			this.addGizmoShape giz (gizmoActiveViewportOnly) line_color line_color
		)
	)
	on updateGizmos do 
	(
		makeMorphTracks()
	)
)
/*
-------------- Test scene setup: ----------

gc()

delete objects
src=geosphere name:#source wirecolor:orange pos:[-50,0,0]
trg = torus name:#target wirecolor:green pos:[50,0,0]
rotate trg (angleaxis 90 y_axis)

manuip_node = MorphTracksManipulator name:"MorphTracker" isselected:on wirecolor:yellow
manuip_node.source_node = src
manuip_node.target_node = trg

*/

 

From a performance point of view it is not good to draw arrows (extra shapes, extra calculations), it is easier and faster to use Markers ... This example shows how to do it

0 Likes
Message 7 of 7

Anonymous
Not applicable

Thank you so much!!! This is perfect 🙂

0 Likes