Hi,
I created a function in Object_Plugin which creates a leaf.
The leaf is created with a plane. In the SplineData in the Attribute-Manager you can shape the leaf shape, like in the hair-Material and depending on how much points the user adds, the plane subdivides. Also I move the points of the plane so that the axis is exact on the tip/bottom of the plane.
Then I added a bend deformer and wanted to fit it to the parent but I had to do it twice, so at the end i also had to move the deformer , so it behaves a little weird. It doesn`t really fit.
At the the end the deformer is in the right place but it just refresh if the user moves a point in the splinedata.
So the code is just a test and far from finished.
At the end I convert all into a polygon object.
- why does I have to call fit to parent twice
- why does it not refresh
So what is the problem here, can you help me.
So I added the code and for the res-file, I think the header and str file is in this case not necessary.
I also attached the plugin file and a small video do demonstate, what I mean.
Cheers
Thomas
import c4d
from c4d import plugins, bitmaps
import os
import math
PLUGIN_ID = 999999999
doc = c4d.documents.GetActiveDocument()
def create_leaf(op):
spline_data = op[c4d.PY_SPLINE]
point_cnt = spline_data.GetKnotCount()
leaf = c4d.BaseObject(c4d.Oplane)
leaf[c4d.PRIM_PLANE_WIDTH] = 12
leaf[c4d.PRIM_PLANE_HEIGHT] = 12
leaf[c4d.PRIM_AXIS] = 2 #5
leaf[c4d.PRIM_PLANE_SUBH] = 1
leaf[c4d.PRIM_PLANE_SUBW] = 2
if op[c4d.PY_CHECK_EXCLUDE]:
if point_cnt >= 2:
leaf[c4d.PRIM_PLANE_SUBH] = point_cnt - 1
leaf = c4d.utils.SendModelingCommand(command=c4d.MCOMMAND_CURRENTSTATETOOBJECT, list=[leaf], doc=op.GetDocument())[0]
for tag in leaf.GetTags():
if tag.IsInstanceOf(c4d.TAG_POLYSELECTION) or tag.IsInstanceOf(c4d.Tedgeselection):
tag.Remove()
for index, pos in enumerate(leaf.GetAllPoints()):
leaf.SetPoint(index, pos + c4d.Vector(0, 0, 6))
knots = spline_data.GetKnots()
counter = 0
for index in range(0, (leaf.GetPointCount() - 1) - 1, 3):
knot_pos = knots[counter]["vPos"]
x = -knot_pos.y / 8
y = knot_pos.z
z = knot_pos.x / 2
counter += 1
leaf.SetPoint(index, c4d.Vector(x, y, z))
if index + 1 == 1:
z_var = 0
elif index + 1 == leaf.GetPointCount() - 2:
z_var = 0
else:
z_var = 0 #x / 3
leaf.SetPoint(index + 1, c4d.Vector(0, z_var, z))
leaf.SetPoint(index + 2, c4d.Vector(-x, y, z))
bend = c4d.BaseObject(c4d.Obend)
bend.InsertUnder(leaf)
bend[c4d.DEFORMOBJECT_ALIGNMENT] = 5
if c4d.threading.GeIsMainThread():
c4d.CallButton(bend, c4d.DEFORMOBJECT_FITTOPARENT)
bend[c4d.DEFORMOBJECT_STRENGTH] = c4d.utils.DegToRad(30)
bend[c4d.DEFORMOBJECT_ANGLE] = c4d.utils.DegToRad(90)
bend[c4d.DEFORMOBJECT_ALIGNMENT] = 0
if c4d.threading.GeIsMainThread():
c4d.CallButton(bend, c4d.DEFORMOBJECT_FITTOPARENT)
bend[c4d.DEFORMOBJECT_SIZE] = c4d.Vector(17, 50, 0)
bend.SetRelPos(c4d.Vector(0, 0, 25))
leaf = \
c4d.utils.SendModelingCommand(command=c4d.MCOMMAND_CURRENTSTATETOOBJECT, list=[leaf], doc=op.GetDocument())[
0]
for tag in leaf.GetTags():
if tag.IsInstanceOf(c4d.TAG_POLYSELECTION) or tag.IsInstanceOf(c4d.Tedgeselection):
tag.Remove()
else:
leaf = \
c4d.utils.SendModelingCommand(command=c4d.MCOMMAND_CURRENTSTATETOOBJECT, list=[leaf], doc=op.GetDocument())[0]
for tag in leaf.GetTags():
if tag.IsInstanceOf(c4d.TAG_POLYSELECTION) or tag.IsInstanceOf(c4d.Tedgeselection):
tag.Remove()
for index, pos in enumerate(leaf.GetAllPoints()):
leaf.SetPoint(index, pos + c4d.Vector(0, 6, 0))
return leaf
class Ivy_Maker(plugins.ObjectData):
def __init__(self):
self.SetOptimizeCache(True)
def Init(self, op):
self.InitAttr(op, bool, c4d.PY_CHECK_EXCLUDE)
op[c4d.PY_CHECK_EXCLUDE] = True
return True
def GetVirtualObjects(self, op, hh):
# dirty = op.CheckCache(hh) or op.IsDirty(c4d.DIRTYFLAGS_DATA)
# if not dirty:
# return op.GetCache(hh)
leaf = create_leaf(op)
return leaf
def GetDDescription(self, op, description, flags):
if not description.LoadDescription(op.GetType()):
return False
spline_data = c4d.DescID(c4d.PY_SPLINE)
in_exclude = c4d.DescID(c4d.PY_INEXCLUDE)
db = description.GetParameterI(spline_data)
db2 = description.GetParameterI(in_exclude)
if op[c4d.PY_CHECK_EXCLUDE] == 0:
db.SetBool(c4d.DESC_HIDE, True)
else:
if db2:
db2.SetBool(c4d.DESC_HIDE, True)
return (True, flags | c4d.DESCFLAGS_DESC_LOADED)
def GetDEnabling(self, op, did, t_data, flags, itemdesc):
# if did[0].id == c4d.PY_SPLINE and op[c4d.PY_CHECK_EXCLUDE] == 1:
# return False
return True
def Message(self, op, type, data):
if type == c4d.MSG_MENUPREPARE:
spline_data = c4d.SplineData()
spline_data.MakeLinearSplineLinear(lPoints=6)
spline_data.SetKnot(0, c4d.Vector(0, 10, 0), c4d.FLAG_KNOT_T_BREAK, interpol=c4d.CustomSplineKnotInterpolationLinear)
spline_data.SetKnot(1, c4d.Vector(10, 40, 0), c4d.FLAG_KNOT_T_BREAK, interpol=c4d.CustomSplineKnotInterpolationLinear)
spline_data.SetKnot(2, c4d.Vector(30, 75, 0), c4d.FLAG_KNOT_T_BREAK, interpol=c4d.CustomSplineKnotInterpolationLinear)
spline_data.SetKnot(3, c4d.Vector(52, 73, 0), c4d.FLAG_KNOT_T_BREAK, interpol=c4d.CustomSplineKnotInterpolationLinear)
spline_data.SetKnot(4, c4d.Vector(75, 50, 0), c4d.FLAG_KNOT_T_BREAK, interpol=c4d.CustomSplineKnotInterpolationLinear)
spline_data.SetKnot(5, c4d.Vector(105, 0, 0), c4d.FLAG_KNOT_T_BREAK, interpol=c4d.CustomSplineKnotInterpolationLinear)
op[c4d.PY_SPLINE] = spline_data
return True
if __name__ == "__main__":
path, file = os.path.split(__file__)
file = "icon.tif"
new_path = os.path.join(path, "res", file)
bitmap = bitmaps.BaseBitmap()
bitmap.InitWith(new_path)
plugins.RegisterObjectPlugin(id=PLUGIN_ID, str="ivy_maker", g=Ivy_Maker, description="ivy_maker", icon=bitmap,
info=c4d.OBJECT_GENERATOR)
res file:
CONTAINER Ivy_Maker //Grossbuchstaben
{
NAME IVY_MAKER; //dieser Name wird im Attribute Manager angezeigt
INCLUDE Obase;
GROUP ID_OBJECTPROPERTIES
{
BOOL PY_CHECK_EXCLUDE {}
SPLINE PY_SPLINE
{
SHOWGRID_H;
SHOWGRID_V;
MINSIZE_H 120;
MINSIZE_V 120;
EDIT_H;
EDIT_V;
X_MIN 0;
X_MAX 120;
Y_MIN 0;
Y_MAX 120;
X_STEPS 1;
Y_STEPS 1;
}
IN_EXCLUDE PY_INEXCLUDE
{
ACCEPT { Obase; };
}
}
}