On 07/02/2013 at 09:39, xxxxxxxx wrote:
Hi larsen,
the following code has exactly the same effect as the soft-selection moving the points when using
it with radius = 100, falloff = linear and offsetting the points about (0, 0, 100).
Note that I used the c4dtools module for computing the midpoint. You can find the source-code
for this function here: https://github.com/NiklasRo...
import c4d
import c4dtools
import itertools
import collections
def soft_move(op, sel, offset, falloff, radius) :
r"""
Move the points in the selection *sel* of *op* about the *offset*
with the falloff described by the callable object *falloff*.
@param op c4d.PointObject instance
@param sel c4d.BaseSelect instance
@param offset c4d.Vector instance
@param falloff Callable object accepting a floating-point value as
sole argument (between 0 and 1, including) and returning a
floating-point argument as multiplier.
@param radius The radius for the soft selection.
"""
if not isinstance(op, c4d.PointObject) :
raise TypeError('expected c4d.PointObject for parameter `op`')
if not isinstance(sel, c4d.BaseSelect) :
raise TypeError('expected c4d.BaseSelect for parameter `sel`')
if not isinstance(offset, c4d.Vector) :
raise TypeError('expected c4d.Vector for parameter `offset`')
if not isinstance(falloff, collections.Callable) :
raise TypeError('expected callable object for parameter `falloff`')
points = op.GetAllPoints()
point_count = op.GetPointCount()
sel_count = sel.GetCount()
if point_count <= 0 or sel_count <= 0:
return
# Compute the mid-point of the selected points.
midp = []
for i, p in itertools.izip(xrange(point_count), points) :
if sel.IsSelected(i) :
midp.append(p)
midp = c4dtools.utils.vbbmid(midp)
# Offset all points.
for i, p in itertools.izip(xrange(point_count), points) :
distance = (midp - p).GetLength()
if distance > radius:
continue
x = falloff(distance / radius)
p = p + offset * x
op.SetPoint(i, p)
def main() :
if not op or not op.CheckType(c4d.Opoint) :
return
offset = c4d.Vector(0, 0, 100)
falloff = lambda x: (1-x)
radius = 100
doc.AddUndo(c4d.UNDOTYPE_CHANGE, op)
soft_move(op, op.GetPointS(), offset, falloff, radius)
op.Message(c4d.MSG_UPDATE)
c4d.EventAdd()
if __name__ == "__main__":
main()
Best,
Niklas