PY Double Circle example not working
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 17/04/2012 at 13:20, xxxxxxxx wrote:
SDK Plugin Example file - PY Double Circle
(apart from the handles not working)OrientObject(op, plane, reverse) :
doesn't appear to be working
I've been trying to learn from the examples but can't figure whats wrong with it
anyone?
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 17/04/2012 at 13:27, xxxxxxxx wrote:
not sure what is going wrong with the python examples, but the logic is to remap the three axis
of the input vector on the output vector. from the c++ sdk rounded tube example :static Vector SwapPoint(const Vector &p, LONG axis) { switch (axis) { case 0: return Vector(p.y,-p.x,p.z); break; case 1: return Vector(-p.y,p.x,p.z); break; case 3: return Vector(-p.x,-p.y,p.z); break; case 4: return Vector(p.x,-p.z,p.y); break; case 5: return Vector(p.x,p.z,-p.y); break; } return p; }
i haven't used splines very much yet, so i can't say anything spcefic on the splineplanes, but i
guess the general idea is the same. you might have to rotate some tangents to. -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 17/04/2012 at 13:55, xxxxxxxx wrote:
Thanks Ferdinand
I think the tangent code is broken as well - as the Circle is twisted when transformed
Can the support team supply a working version (without the handles) please
While we are here......
I noticed that the c4d spline primitive hide and show UI elements (length angle etc) based on the interpolation type
how is that done?
obviously some logiC 'ifs' etc
but how do you access the HIDE SHOW ?tia
Paul
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 17/04/2012 at 14:09, xxxxxxxx wrote:
to disable / enable description elements you have to overwrite GetDEnabling for your plugin,
https://developers.maxon.net/forum/topic/6287/6675_getdenabling--getddescription-in-python--c
actually hiding stuff is only possible in c++. note that the python sdk description of GetDEnabling
is at least very confusing, not to say wrong. the thread explains it more or less in details. -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 17/04/2012 at 14:21, xxxxxxxx wrote:
**
GetDEnabling
**
**
returns True** if the parameter should be enabled, otherwise False.should be enabled ?
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 17/04/2012 at 14:42, xxxxxxxx wrote:
cinema callls GetDEnabling for each description element . by returning true or false you
enable/disable this element.something like that :
def GetDEnabling(self, node, id, t_data, flags, itemdesc) : if (id[0].id == c4d.ElementToDisable) : if (node[c4d.ElementThatDrivesDisableState] == True) return True # unhide the element else : return False # hides the element # when your criteria don't match, close with a call to the parent class of your plugin return super(yourPluginClass, self).GetDEnabling(self, node, id, t_data, flags, itemdesc)
not sure if that last line actually works this way in pyhton , i switched to c++ before getting
deeper into this. in c++ it is working for GetDDescription with :return __super::GetDDescription(node, description, flags);
however this call to the parent isn't mandatory. things will work without it, but maxon wants us
to do it you could just return true instead of it. -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 17/04/2012 at 21:32, xxxxxxxx wrote:
Can the support team supply a working version of the SDK Example (without the handles) please
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 18/04/2012 at 02:09, xxxxxxxx wrote:
Tangents are not swapped so here is the code for the fixed OrientObject() method:
@staticmethod def OrientObject(op, plane, reverse) : pcnt = op.GetPointCount() points = op.GetAllPoints() if plane>=c4d.PRIM_PLANE_ZY: if plane==c4d.PRIM_PLANE_ZY: for i, point in enumerate(points) : x = -point.z y = point.y z = point.x op.SetPoint(i, c4d.Vector(x, y, z)) h = op.GetTangent(i) vl = h["vl"] vr = h["vr"] vl = c4d.Vector(-vl.z, vl.y, vl.x) vr = c4d.Vector(-vr.z, vr.y, vr.x) op.SetTangent(i, vl, vr) elif plane==c4d.PRIM_PLANE_XZ: for i, point in enumerate(points) : x = point.x y = -point.z z = point.y op.SetPoint(i, c4d.Vector(x, y, z)) h = op.GetTangent(i) vl = h["vl"] vr = h["vr"] vl = c4d.Vector(vl.x, -vl.z, vl.y) vr = c4d.Vector(vr.x, -vr.z, vr.y) op.SetTangent(i, vl, vr) if reverse: to = pcnt/float(2) if pcnt%2: to+=1 for i, point in enumerate(points[:int(to)]) : op.SetPoint(i, points[pcnt-1-i]) op.SetPoint(pcnt-1-i, point) h = op.GetTangent(i) tangents = op.GetTangent(pcnt-1-i) # Move from right to left vr, vl = tangents["vl"], tangents["vr"] op.SetTangent(i, vl, vr) op.SetTangent(pcnt-1-i, h["vr"], h["vl"]) op.Message(c4d.MSG_UPDATE)
And MoveHandle() :
def MoveHandle(self, op, undo, mouse_pos, hit_id, qualifier, bd) : if hit_id==c4d.NOTOK: return False src = undo.GetDataInstance() dst = op.GetDataInstance() handle_dir = c4d.Vector(1.0, 0.0, 0.0) handle_dir = DoubleCircleData.SwapPoint(handle_dir, src.GetLong(c4d.PRIM_PLANE)) val = 0 #tm.off.Dot(handle_dir) # FIX cut = utils.FCut(src.GetReal(c4d.PYCIRCLEOBJECT_RAD)+val, 0.0, sys.maxint) dst.SetReal(c4d.PYCIRCLEOBJECT_RAD, cut) return True
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 18/04/2012 at 02:19, xxxxxxxx wrote:
Much appreciate the great support Yannick
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 19/04/2012 at 01:06, xxxxxxxx wrote:
Originally posted by xxxxxxxx
cinema callls GetDEnabling for each description element . by returning true or false you
enable/disable this element.something like that :
def GetDEnabling(self, node, id, t_data, flags, itemdesc) : if (id[0].id == c4d.ElementToDisable) : if (node[c4d.ElementThatDrivesDisableState] == True) return True # unhide the element else : return False # hides the element # when your criteria don't match, close with a call to the parent class of your plugin return super(yourPluginClass, self).GetDEnabling(self, node, id, t_data, flags, itemdesc)
not sure if that last line actually works this way in pyhton , i switched to c++ before getting
deeper into this. in c++ it is working for GetDDescription with :return __super::GetDDescription(node, description, flags);
however this call to the parent isn't mandatory. things will work without it, but maxon wants us
to do it you could just return true instead of it.I can't see how you set the itemdesc container (its a basecontainer - but how to set) no python examples (C++SDK tells me its a pointer to a basecontainer - so I;m no futher)
OK look at it from newbie world
GetDEnabling(self, node, id, t_data, flags, itemdesc) :
if you were calling this method and writing in words what the params were
JSplineObject, self.GetDEnabling(self, op(current object), 37000(ID in the res file of item ), 100 (Value in init or current vale?), flags(not used), itemdesc (a base container (set how))
and in the method
if (id[0].id == c4d.ElementToDisable) :
if (node[c4d.ElementThatDrivesDisableState] == True)what does ElementToDisable and ElementThatDrivesDisableState refer to?
tia
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 19/04/2012 at 02:57, xxxxxxxx wrote:
read the thread i have posted on GetDEnabling. don't mess with itemdesc, it is meant to be
read only. it also doesn't seem to be the description container of your current instance of
your class, but the the class itself.you do not call GetDEnabling, you overwrite it. not sure if you are aware of the basics of object
orientation / polymorphism, so a quick explanation. you have a class GenericAnimal which
implements the method MakeSound which does nothing. now you create two other classes which
inherit from GenericAnimal - CowClass and DogClass they both overwrite the method MakeSound
which they inherited from their parent class GenericAnimal. if you call MakeSound on CowClass you
could let it print "moo", if you call it on DogClass you could let it print "bark".this is what you are doing for Init(), GetContour(), GetDEanabling(), Message() and so on.
the BaseObject class your plugin inherts from is the GenericAnimal class which provides virtual
implementations for these methods. JSpline is your CowClass which has to overwrite GetDEnabling
(MakeSound) to fill it with some logic.the example was actually quite close to copy & paste ready. an example with real world ids:
def GetDEnabling(self, node, id, t_data, flags, itemdesc) : if (id[0].id == c4d.SPLINEOBJECT_ANGLE ) : if (node[c4d.SPLINEOBJECT_INTERPOLATION] == c4d.SPLINEOBJECT_INTERPOLATION_ADAPTIVE or node[c4d.SPLINEOBJECT_INTERPOLATION] == c4d.SPLINEOBJECT_INTERPOLATION_SUBDIV ) return True # the angle interpolation input box is shown when the interpolation mode is set to adapative or subdiv else : return False # hides the element # when your criteria don't match, close with a call to the parent class of your plugin return super(JSplineObject, self).GetDEnabling(self, node, id, t_data, flags, itemdesc)
edit : to clearify things a bit - as i wrote earlier GetDEnabling is called for each description
element of your plugin. id is the the DescID of the element GetDEnabling is called for.edit2 : forgot some c4d. on the ids in my example
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 19/04/2012 at 06:15, xxxxxxxx wrote:
LD - thanks , those few lines explain a lot. I'm a designer who in daily life is full of logos, brochures, type, colours etc and the occasional need to deal with PHP, MYSQL, JS and a little programming in C4D. Many moons ago I wrote Z80 assembler (running code with system hooks) and enough C to understand pointers and basic classes (also with PHP)
The inheritance thing is now much clearer, thank you for talking the time to explain.
From what I now understand we define what GetDEnabling will do for this particular class.
From there, its almost like we've hooked into something that is always run by C4D and if nothing needs to be changed - use the return to carry on with the rest of the plugin/classOK - sorry for all the questions
is overloading the same thing as you refer to as overwriting?
what is an atom? (OK looks like the root base container - but I don't see the point or it being used much)
the 'node' thing is still confusing. (an object that contains data and links to other nodes)
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 19/04/2012 at 07:00, xxxxxxxx wrote:
first of all, i am also not very good at coding, just messing arround, i am an architect, so i have
a basic understanding of math, but my explanations might not be 100% accurate.overloading is also polymorphism , but not the same as overwriting. overloading means that
you have different implementations of the same method.class Dog (GenericAnimal) def MakeNoise() // this is overwriting (assuming MakeNoise is also defined in GenericAnimal) print "Bark !" def MakeNoise(mood) // this is overloading, we create a 2nd def of MakeNoise, which accepts a parameter and behaves differently if (mood == "agressive") : print "Bark !" elif (mood == "scared") : print "Whimper !" else: print "Hackle !"
a c4datom is the parent class of most of the classes in c4d which have some kind of object
manager representation. a basecontainer has nothing to do with c4datom. never had to use
atoms yet, so i guess you have only to deal with them, when you are doing really fundamental
stuff.you could read node as op if it is easier to understand for you, it is the current instance of your
class, aka the GeListNode which originally implemented GetDEnabling and now is calling it.GeListNode > BaseList2D > BaseObject > YourPlugin is the chain of inheritance. note that there
is an inheritance diagramm for the c4d sdk. http://www.thirdpartyplugins.com/python/misc/diagram.html -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 19/04/2012 at 08:14, xxxxxxxx wrote:
Even more fog clearing - thanks LD
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 20/04/2012 at 01:32, xxxxxxxx wrote:
All works OK
loads OK
but when run i.e. an interface element is selected
i get TypeError: element 5
from the last return line
########################## def GetDEnabling(self, node, id, t_data, flags, itemdesc) : #### disable the chamfer amount if both chamfer switches are off if (id[0].id == c4d.CHAMFER) : if (node[c4d.CHAMFER_BASE] == False) and (node[c4d.CHAMFER_TAIL] == False) : return False # disable the chamfer amount if both chamfer switches are off else: return True # show the element #### enable/disable appropriate gui for selected spline type if (id[0].id == c4d.SPLINEOBJECT_SUB) : if ((node[c4d.SPLINEOBJECT_INTERPOLATION] == c4d.SPLINEOBJECT_INTERPOLATION_NATURAL) or (node[c4d.SPLINEOBJECT_INTERPOLATION] == c4d.SPLINEOBJECT_INTERPOLATION_UNIFORM )) : return True # the angle interpolation input box is shown when the interpolation mode is set to adapative or subdiv else: return False # hides the element if (id[0].id == c4d.SPLINEOBJECT_ANGLE) : if ((node[c4d.SPLINEOBJECT_INTERPOLATION] == c4d.SPLINEOBJECT_INTERPOLATION_ADAPTIVE) or (node[c4d.SPLINEOBJECT_INTERPOLATION] == c4d.SPLINEOBJECT_INTERPOLATION_SUBDIV)) : return True # the angle interpolation input box is shown when the interpolation mode is set to adapative or subdiv else: return False # hides the element if (id[0].id == c4d.SPLINEOBJECT_MAXIMUMLENGTH) : if (node[c4d.SPLINEOBJECT_INTERPOLATION] == c4d.SPLINEOBJECT_INTERPOLATION_SUBDIV) : return True # the angle interpolation input box is shown when the interpolation mode is set to adapative or subdiv else: return False # hides the element # when your criteria doesn't match, close with a call to the parent class of your plugin return super(JSplineObject, self).GetDEnabling( node, id, t_data, flags, itemdesc) ##########################
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 20/04/2012 at 02:55, xxxxxxxx wrote:
try :
return super(JSplineObject, self).GetDEnabling( self, node, id, t_data, flags, itemdesc)
or as i said use return true instead of it, as i am not 100% sure about the super call snytax in python.
ps : as a sidenote, stop using hash keys to seperate you methods, in this case it doesn't matter,
but for larger code chunks it makes it more difficult to read the code. whitespaces are interpreted
differently by different text display softwares.use an editor with code folding like notepad++ or sublimetext2 (great editor), or use a fully blown
ide like eclipse with a python module. -
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 20/04/2012 at 03:32, xxxxxxxx wrote:
Sorry - missed that
Text Wranger on Mac is a nice simple text editor and it has fold
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 22/04/2012 at 23:51, xxxxxxxx wrote:
I still couldn't get the reverse to work
so I tried reversing the list - which worked
but I still can't figure why the tangents are set twice -
they appear to be read once from either end
written back in reverse point/index order from the Get abovein the write - one SetTangent uses indexes and vectors
the other uses reverse indexes and dictionary descriptions of the reversed vectors - why different methods ?I just cant get my head around it - it appears to swap tangents from one end of hte spline, working to the middle, then do it again as the counters cross over?
can someone explain pls
if reverse==True: allpoints = op.GetAllPoints() allpoints.reverse() op.SetAllPoints(allpoints) to = pcnt/float(2) if pcnt%2: to+=1 for i in range(int(to)) : h = op.GetTangent(i) tangents = op.GetTangent(pcnt-1-i) # Move from right to left vl = tangents["vr"] vr = tangents["vl"] op.SetTangent(i, vl, vr) op.SetTangent(pcnt-1-i, h["vr"], h["vl"]) op.Message(c4d.MSG_UPDATE) return
this swaps the tangents - but doesn't work?
(surely the points have already been reversed by the first statements)for i in reversed(xrange(0, pcnt)) : tangent = op.GetTangent(i) tl = tangent["vr"] tr = tangent["vl"] op.SetTangent(i, tl,tr)
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 23/04/2012 at 02:14, xxxxxxxx wrote:
1. your code sets the tangent twice, because you are looping with to through your points.
to = op.GetAllPoints() / float(2). so you are looping only through half of your objects
points. it seems to be meant to shorten the methods rutime, but this will only work for
symmetrical objects if i am not missing something.2. your second code chunk (SetTangent i.p.) is working, did a quick test on the flower primitive.
however you have to consider that spline tangents are in most cases symmetrical and swapping
them won't lead to dramatic visual changes.import c4d from c4d import documents def main() : obj = doc.GetActiveObject() for i in xrange(0, obj.GetPointCount()) : t1 = obj.GetTangent(i) obj.SetTangent(i, t1["vr"],t1["vl"]) t2 = obj.GetTangent(i) print 'Point {0}'.format(i) print 'old {0}'.format(t1) print 'new {0}'.format(t2) c4d.EventAdd() if __name__=='__main__': main()
for the flower primitive it returns :
Point 0 old {'vr': Vector(0, 25, 0), 'vl': Vector(0, -25, 0)} new {'vr': Vector(0, -25, 0), 'vl': Vector(0, 25, 0)} Point 1 old {'vr': Vector(-9.588, -16.559, 0), 'vl': Vector(9.588, 16.559, 0)} new {'vr': Vector(9.588, 16.559, 0), 'vl': Vector(-9.588, -16.559, 0)} Point 2 old {'vr': Vector(18.488, -4.929, 0), 'vl': Vector(-18.488, 4.929, 0)} new {'vr': Vector(-18.488, 4.929, 0), 'vl': Vector(18.488, -4.929, 0)} Point 3 old {'vr': Vector(17.678, -17.678, 0), 'vl': Vector(-17.678, 17.678, 0)} new {'vr': Vector(-17.678, 17.678, 0), 'vl': Vector(17.678, -17.678, 0)} ...