Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    PY Double Circle example not working

    PYTHON Development
    0
    19
    1.6k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      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.

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        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

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          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.

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            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 ?

            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              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.

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                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

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  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
                  
                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    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

                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      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

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        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

                        1 Reply Last reply Reply Quote 0
                        • H
                          Helper
                          last edited by

                          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/class

                          OK - 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)

                          1 Reply Last reply Reply Quote 0
                          • H
                            Helper
                            last edited by

                            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

                            1 Reply Last reply Reply Quote 0
                            • H
                              Helper
                              last edited by

                              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

                              1 Reply Last reply Reply Quote 0
                              • H
                                Helper
                                last edited by

                                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)
                                		
                                  
                                	##########################	
                                
                                1 Reply Last reply Reply Quote 0
                                • H
                                  Helper
                                  last edited by

                                  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.

                                  1 Reply Last reply Reply Quote 0
                                  • H
                                    Helper
                                    last edited by

                                    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

                                    1 Reply Last reply Reply Quote 0
                                    • H
                                      Helper
                                      last edited by

                                      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 above

                                      in 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)
                                      
                                      1 Reply Last reply Reply Quote 0
                                      • H
                                        Helper
                                        last edited by

                                        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)} ...
                                        
                                        1 Reply Last reply Reply Quote 0
                                        • First post
                                          Last post