PDA

View Full Version : Log Spiral model script



clintonman
03-04-2012, 04:21 PM
This is a recreation of code from an article in 3D Artist magazine. It makes a kind of spiral shell shape. I wanted to try out the ui panels and add comments for what sdk documents I used for reference since I tend to sometimes get lost going around in circles in the docs. In this version the points wrap around to the same location and are merged at the end. In an earlier version I tried using discontinuous uv, but it gave errors. I think it might be a bug. This is the general format I tried to use:


uvd = [1.0, 0.0]
mesh_edit_op.pntVPMap(mesh_edit_op.state, ptID[baseIndex-wrapOffset-self._crossSection],polygon,lwsdk.LWVMAP_TXUV,"LogUVMap",2,uvd)


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

"""
This is a LightWave Command Sequence plug-in (Modeler) that creates
a log spiral. The original code is from an article
in 3D Artist magazine Issue #49 by Petr Sorfa
"""

import sys
import math
import lwsdk

__author__ = "Clinton Reese"
__date__ = "Mar 3 2012"
__copyright__ = "Copyright (C) 2011 Clinton's 3D Creations"
__version__ = "1.0"
__maintainer__ = "Clinton Reese"
__email__ = "[email protected]"
__status__ = "Example modified 2"
__lwver__ = "11"

class make_logspiral(lwsdk.ICommandSequence):
def __init__(self, context):
super(make_logspiral, self).__init__()

self._crossSection = 10
self._length = 50
self._scale = 0.09
self._crossSectionScale = 0.65
self._loopSeparation = 1.9

def get_commands(self, mod_command):
command_list = {} #LWCommandCode
# /LightWave11.0/sdk/lwsdk11.0/html/commands/modeler.html
for command in ["TOGGLEPATCHES",
"SEL_INVERT",
"MERGEPOINTS"]:
command_list[command] = mod_command.lookup(mod_command.data, command)
return command_list

# LWCommandSequence -----------------------------------
def process(self, mod_command):
# panels
# /LightWave11.0/sdk/lwsdk11.0/html/globals/panel.html
# /LightWave11.0/sdk/lwsdk11.0/include/lwpanel.h
ui = lwsdk.LWPanels()
panel = ui.create('Log Spiral')

c1 = panel.int_ctl('Length')
c2 = panel.int_ctl('Cross Section Segments')
c3 = panel.float_ctl('Overall Scale')
c4 = panel.float_ctl('Cross Section Scale')
c5 = panel.float_ctl('Loop Separation')

panel.align_controls_vertical([c1, c2, c3, c4, c5])
panel.size_to_layout(5, 5)

c1.set_int(self._length)
c2.set_int(self._crossSection)
c3.set_float(self._scale)
c4.set_float(self._crossSectionScale)
c5.set_float(self._loopSeparation)

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

self._length = c1.get_int()
self._crossSection = c2.get_int()
self._scale = c3.get_float()
self._crossSectionScale = c4.get_float()
self._loopSeparation = c5.get_float()

ui.destroy(panel)

# /LightWave11.0/sdk/lwsdk11.0/html/classes/me.html
# /LightWave11.0/sdk/lwsdk11.0/include/lwmeshedt.h
edit_op_result = lwsdk.EDERR_NONE
mesh_edit_op = mod_command.editBegin(0, 0, lwsdk.OPSEL_USER)
if not mesh_edit_op:
print >>sys.stderr, 'Failed to engage mesh edit operations!'
return lwsdk.AFUNC_OK

ptID = [] #LWPntID
for i in range(self._length): # 0 to length-1
#print >>sys.stderr, 'hello'
theta = i/1.0
r = math.exp(theta*self._scale)
d=self._crossSectionScale*r
for j in range(self._crossSection): # 0 to crossSection-1
phi = 2.0*math.pi*j/(self._crossSection-1)
x = d*math.cos(phi)*math.cos(theta)
z = d*math.sin(phi)
y = d*math.cos(phi)*math.sin(theta)
x += r*math.cos(theta)
y += r*math.sin(theta)
z += r*self._loopSeparation
pt = [x,y,z]
ptID.append(mesh_edit_op.addPoint(mesh_edit_op.sta te, pt))
baseIndex = i*self._crossSection+j

uv = [0.0, 0.0]
uv[0] = float(j)/float(self._crossSection-1)
uv[1] = float(i)/float(self._length)
mesh_edit_op.pntVMap(mesh_edit_op.state, ptID[baseIndex], lwsdk.LWVMAP_TXUV, "LogUVMap", uv)

if i > 0 and j > 0:
polyPointID = []
polyPointID.append(ptID[baseIndex-1-self._crossSection+1])
polyPointID.append(ptID[baseIndex-1-self._crossSection])
polyPointID.append(ptID[baseIndex-1])
polyPointID.append(ptID[baseIndex])
polygon = mesh_edit_op.addPoly(mesh_edit_op.state, lwsdk.LWPOLTYPE_FACE, None, "SLogSurface", polyPointID)

mesh_edit_op.done(mesh_edit_op.state, edit_op_result, 0)

cs_dict = self.get_commands(mod_command)
cs_options = None
# /LightWave11.0/sdk/lwsdk11.0/html/classes/cs.html
# /LightWave11.0/sdk/lwsdk11.0/include/lwcmdseq.h
result = mod_command.execute(mod_command.data, cs_dict["MERGEPOINTS"], cs_options, lwsdk.OPSEL_USER)
result = mod_command.execute(mod_command.data, cs_dict["TOGGLEPATCHES"], cs_options, lwsdk.OPSEL_USER)

return lwsdk.AFUNC_OK

# /LightWave11.0/sdk/lwsdk11.0/html/server.html
ServerTagInfo = [
( "Python LogSpiral", lwsdk.SRVTAG_USERNAME | lwsdk.LANGID_USENGLISH ),
( "Make LogSpiral", lwsdk.SRVTAG_BUTTONNAME | lwsdk.LANGID_USENGLISH ),
( "Utilities/Python", lwsdk.SRVTAG_MENU | lwsdk.LANGID_USENGLISH )
]

ServerRecord = { lwsdk.CommandSequenceFactory("LW_PyMakeLogSpiral", make_logspiral) : ServerTagInfo }

UnCommonGrafx
03-04-2012, 04:40 PM
Nice conversion.
Nice image.

daforum
03-05-2012, 12:50 PM
Will this script work in earlier versions of LW too?
Will it be available on your website?

I like the image aswell...

BigHache
03-05-2012, 01:27 PM
Awesome work, that looks great!


Will this script work in earlier versions of LW too?

It would need to be converted to LScript since Python is new to 11.

clintonman
03-05-2012, 07:17 PM
Will this script work in earlier versions of LW too?
Will it be available on your website?

I like the image aswell...
No, it won't work in earlier versions of Lightwave because it uses the new LW11 python scripting. I'll probably be adding to the website later, but first I'll add some sanity checks to this script. Small changes in some of the ui values can make big crazy changes in the result.

daforum
03-06-2012, 04:30 AM
An Lscript would be great... :thumbsup: