PDA

View Full Version : >Layout< script/plugin to jump Pivot to center of geometry?



jeric_synergy
09-06-2015, 10:36 PM
Is there a Layout plugin that will jump the pivot point of an object to the center of the mesh, no matter where that center is?


(I'm defining 'center' as 'average of the mesh's points', which I realize is only approximately the center.)

(Actually, perhaps 'center of bounding box' is a more useful definition.)

erikals
09-06-2015, 10:56 PM
see >

https://www.youtube.com/watch?v=3IdQmqin1J4

jeric_synergy
09-07-2015, 09:11 AM
Is there a Layout plugin that will jump the pivot point of an object to the center of the mesh, no matter where that center is? :stumped:

daforum
09-07-2015, 10:27 AM
Like Modler has. A "Centre Pivot" for Layout script/ plugin.

That would be very useful :thumbsup:

jeric_synergy
09-07-2015, 10:31 AM
Better said, thanks, exactly. --Hmmm, a surprising # of LWM plugins work in Layout.....

erikals
09-07-2015, 10:34 AM
sorry, bit fast in the morning... http://erikalstad.com/backup/misc.php_files/smile.gif

but put short,
no, i don't believe there is...

this is another area where the Modeler / Layout workflow stagnates

jeric_synergy
09-07-2015, 10:40 AM
I'm sooooo exhausted making these little Feature Requests. And they're LITTLE! But they ALL ADD UP!!!!

ernpchan
09-07-2015, 10:50 AM
I'm sooooo exhausted making these little Feature Requests. And they're LITTLE! But they ALL ADD UP!!!!

You should get into scripting. :D

jeric_synergy
09-07-2015, 10:53 AM
I'm trying! :weeps: :cry:

erikals
09-07-2015, 11:36 AM
no, just jump directly to "C"

not sure if LightWave can use "C sharp" or just "C" ... hmm...

https://www.youtube.com/playlist?list=PL6gx4Cwl9DGAKIXv8Yr6nhGJ9Vlcjyymq

Kryslin
09-10-2015, 11:20 AM
Lightwave, AFAIK, is C. Lightwolf was working on a C++ wrapper, but I don't know what it's status is...

If it were C# (a .net language) I could program plugins in another .net language I am very familiar with... VB.net (which can use the C# assemblies).
(I think it could be done; You can use unmanaged types and calls in C#/VB .net, but it's not pretty...)

jeric_synergy
09-10-2015, 11:30 AM
I'm preeety sure this should be fairly simple in Python: bounding boxes are accessible in Layout via scripting I'm pretty sure, and moving the p.point too, soooo....

The part of scripting that's kicking my @$$ is the lwsdk interface-- that might as well be in Mandarin. BUT, I'm chipping away at it...

erikals
09-10-2015, 03:36 PM
Python?
why make it easy?

no... C all the way... (!) http://erikalstad.com/emoti/nerd-annoying.gif

jeric_synergy
09-10-2015, 03:39 PM
There's still the problem of interfacing with the lwsdk, and learning C, and obtaining a C compiler, and figuring out what a *.h file is, and all the other tripwires and time sumps.

erikals
09-10-2015, 04:09 PM
learning C, doesn't look too hard if you only code a few simple lines
learning C to create a new Rounding tool however, requires some good math knowledge too
getting a C compiler > seems quite easy
.h files > what is h file in c programming (https://www.google.no/search?q=ut+what+a+*.h+file+i&ie=utf-8&oe=utf-8&gws_rd=cr&ei=Sf_xVZC2FYqesAHYv5rYBA#q=what+is+h+file+in+c+pr ogramming)

i'll probably look a bit into C, but i'll keep it simple, i'm no "coder"

clintonman
09-10-2015, 04:15 PM
I'm preeety sure this should be fairly simple in Python: bounding boxes are accessible in Layout via scripting I'm pretty sure, and moving the p.point too, soooo....

The part of scripting that's kicking my @$$ is the lwsdk interface-- that might as well be in Mandarin. BUT, I'm chipping away at it...
Are you sure about the bounding box in layout? I ended up doing a brute force approach by looking at every single vertex in the mesh to calculate the bounds. It was a while ago, but if there's an easier way I would definitely like to know it.

ernpchan
09-10-2015, 04:27 PM
Are you sure about the bounding box in layout? I ended up doing a brute force approach by looking at every single vertex in the mesh to calculate the bounds. It was a while ago, but if there's an easier way I would definitely like to know it.

Only bounding box I found in the dox was for Modeler. Only thing for Layout is to change the Bounding Box threshold.

jeric_synergy
09-10-2015, 04:31 PM
FFS, really? If not, Bob should add it.

ernpchan
09-10-2015, 06:05 PM
FFS, really? If not, Bob should add it.

Feature request it.

jeric_synergy
09-10-2015, 08:07 PM
I'm just gobsmacked it may not exist.

vncnt
09-11-2015, 01:05 AM
Or use LScript for a simple task like this. It still works.

iain_r
09-11-2015, 08:49 AM
You need the console panel open to see the results. This should loop through the objects in the scene, had some strange results in v11 in that it didn't always find the object, no idea as to why, seems to work okay in v2015.2. Nulls and custom objects will probably return all zeros.

Haven't tried to set the pivot point but you should be able to execute the command.

Usual caveats apply, use at own risk

Regards

Iain


#! /usr/bin/env python
# -*- Mode: Python -*-
# -*- coding: ascii -*-

"""
This is a LightWave Generic plug-in.
"""

import sys
import lwsdk

__author__ = "Iain"
__date__ = ""
__copyright__ = ""
__version__ = "1.0"
__maintainer__ = "Iain"
__email__ = ""
__status__ = "Example"
__lwver__ = "11"

# Each class instance created must inherit from one (and only one) of the
# available SDK plug-in interfaces. This example plug-in implements the
# IGeneric class interface, from which Generic-type plug-in instances will
# be created by the Factory. An IGeneric plug-in performs its processing in
# the process() method, and receives a LWLayoutGeneric access interface.

class bbinfo(lwsdk.IGeneric):
def __init__(self, context):
super(bbinfo, self).__init__()
# context has no relevant value in a Generic plug-in

# LWGeneric -------------------------------------------
def process(self, generic_access):
# All this particular plug-in does is display some messages
# to various outputs...

info = lwsdk.LWSceneInfo()
item = lwsdk.LWItemInfo()
obj = lwsdk.LWObjectInfo()

id = item.first(lwsdk.LWI_OBJECT, lwsdk.LWITEM_NULL)

cntr = lwsdk.Vector()

while id:
name = item.name(id)

print(name)

val = obj.bounds(id)

bmin = lwsdk.Vector()
bmax = lwsdk.Vector()

bmin = val[0]
bmax = val[1]

cntr[0] = (bmin[0] + bmax[0]) /2
cntr[1] = (bmin[1] + bmax[1]) /2
cntr[2] = (bmin[2] + bmax[2]) /2

print(bmin)
print(bmax)
print(cntr)

id = item.next(id)



# ui = lwsdk.LWPanels()
# panel = ui.create('Bounding Box Information')
# c1 = panel.str_ctl('Minimum', 50)
# c2 = panel.str_ctl('Maximum', 50)
# c3 = panel.str_ctl('Center',50)
# panel.align_controls_vertical([c1, c2, c3])
# c1.set_str(min)
# c2.set_str(max)
# c3.set_str(cntr)


# if panel.open(lwsdk.PANF_BLOCKING | lwsdk.PANF_CANCEL) == 0:
# ui.destroy(panel)
# return lwsdk.AFUNC_OK

# ui.destroy(panel)

return lwsdk.AFUNC_OK


# ServerTagInfo is a list (or tuple) of one or more lists (or tuples) that
# define the plug-in's ServerTagInfo values. Please see the LightWave SDK
# documentation for more information about the values found in a
# ServerTagInfo entry.

ServerTagInfo = [
( "Python Bounding Box Information", lwsdk.SRVTAG_USERNAME | lwsdk.LANGID_USENGLISH ),
( "Bounding Box Information", lwsdk.SRVTAG_BUTTONNAME | lwsdk.LANGID_USENGLISH ),
( "Utilities/Python", lwsdk.SRVTAG_MENU | lwsdk.LANGID_USENGLISH )
]


ServerRecord = { lwsdk.GenericFactory("LW_BBInfo", bbinfo) : ServerTagInfo }

ernpchan
09-11-2015, 03:16 PM
Thanks Iain!

jeric_synergy
09-11-2015, 06:50 PM
Thanks, Iain! You come thru a lot! That will get me a lot closer, come what may.

ernpchan
09-12-2015, 03:11 AM
Doing a search for "bounding box" in the sdk dox doesn't return the .bounds listing as a hit. That's no good.

iain_r
09-12-2015, 03:28 AM
If you look at the objinfo.html file in the globals directory you will find bounds in the structure, appeared from version 10. Wasn't in the v9 sdk, just had a quick look.

From the definition of LWObjectInfo

bounds( object, min, max ) (rev.7+)
Obtains the bounding box of the object.

Regards

Iain

iain_r
09-12-2015, 07:37 AM
Quick example of pivot position.

I tried using the quick shot method which was okay with constants but didn't like variables. Tested this with a robot from the LW examples and it put the pivot positions in what appeared to be the correct posistion. i.e. pivots at hip, feet, etc. This should give you something to work with. Be careful with nulls, custom objects and objects with displacements. I've only tested this in 2015.2 and only with a couple of example scenes.

Regards

Iain


#! /usr/bin/env python
# -*- Mode: Python -*-
# -*- coding: ascii -*-

"""
This is a LightWave Generic plug-in.
"""

import sys
import lwsdk

__author__ = "Iain"
__date__ = ""
__copyright__ = ""
__version__ = "1.0"
__maintainer__ = "Iain"
__email__ = ""
__status__ = "Example"
__lwver__ = "11"

# Each class instance created must inherit from one (and only one) of the
# available SDK plug-in interfaces. This example plug-in implements the
# IGeneric class interface, from which Generic-type plug-in instances will
# be created by the Factory. An IGeneric plug-in performs its processing in
# the process() method, and receives a LWLayoutGeneric access interface.

class bbinfo(lwsdk.IGeneric):
def __init__(self, context):
super(bbinfo, self).__init__()
# context has no relevant value in a Generic plug-in

# LWGeneric -------------------------------------------
def process(self, generic_access):
# All this particular plug-in does is display some messages
# to various outputs...

info = lwsdk.LWSceneInfo()
item = lwsdk.LWItemInfo()
obj = lwsdk.LWObjectInfo()

id = item.first(lwsdk.LWI_OBJECT, lwsdk.LWITEM_NULL)

cntr = lwsdk.Vector()
interface_info = lwsdk.LWInterfaceInfo()
current_time = interface_info.curTime
autokey_is_on = ((interface_info.generalFlags & lwsdk.LWGENF_AUTOKEY) != 0)

while id:
name = item.name(id)

print(name)

val = obj.bounds(id)

bmin = lwsdk.Vector()
bmax = lwsdk.Vector()

bmin = val[0]
bmax = val[1]

cntr[0] = (bmin[0] + bmax[0]) /2
cntr[1] = (bmin[1] + bmax[1]) /2
cntr[2] = (bmin[2] + bmax[2]) /2

print(bmin)
print(bmax)
print(cntr)

x = cntr[0]
y = cntr[1]
z = cntr[2]

generic_access.evaluate(generic_access.data,"PivotPosition %f %f %f" % (x, y, z))

if not autokey_is_on:
generic_access.evaluate(generic_access.data, "CreateKey %f" % current_time)

id = item.next(id)



# ui = lwsdk.LWPanels()
# panel = ui.create('Bounding Box Information')
# c1 = panel.str_ctl('Minimum', 50)
# c2 = panel.str_ctl('Maximum', 50)
# c3 = panel.str_ctl('Center',50)
# panel.align_controls_vertical([c1, c2, c3])
# c1.set_str(min)
# c2.set_str(max)
# c3.set_str(cntr)


# if panel.open(lwsdk.PANF_BLOCKING | lwsdk.PANF_CANCEL) == 0:
# ui.destroy(panel)
# return lwsdk.AFUNC_OK

# ui.destroy(panel)

return lwsdk.AFUNC_OK


# ServerTagInfo is a list (or tuple) of one or more lists (or tuples) that
# define the plug-in's ServerTagInfo values. Please see the LightWave SDK
# documentation for more information about the values found in a
# ServerTagInfo entry.

ServerTagInfo = [
( "Python Bounding Box Information", lwsdk.SRVTAG_USERNAME | lwsdk.LANGID_USENGLISH ),
( "Bounding Box Information", lwsdk.SRVTAG_BUTTONNAME | lwsdk.LANGID_USENGLISH ),
( "Utilities/Python", lwsdk.SRVTAG_MENU | lwsdk.LANGID_USENGLISH )
]


ServerRecord = { lwsdk.GenericFactory("LW_BBInfo", bbinfo) : ServerTagInfo }

clintonman
09-12-2015, 09:14 AM
I see, looks like the bounds was fixed in LW 2015. LW 11.6.3 always returns 0,0,0 for the boundary values.

jeric_synergy
09-12-2015, 10:38 AM
Doing a search for "bounding box" in the sdk dox doesn't return the .bounds listing as a hit. That's no good.
Yes, if we can't trust the search tools, that's very bad indeed.

Report as bug.

ernpchan
09-12-2015, 06:47 PM
Yes, if we can't trust the search tools, that's very bad indeed.

Report as bug.

Done.