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