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

    Coding a Python Plugin for fields

    Cinema 4D SDK
    python r20 windows
    3
    4
    1.0k
    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.
    • D
      darrellp
      last edited by darrellp

      Hope I'm not doing something wrong. Second post and I got a kind of warning on the first one without really saying what I'd done wrong. If I am, sorry - please gently correct me and I'll abide by the rules.

      Starting in on plugin writing and kind of working my way up. I thought I'd do a field since there is a built in "python field" so I started there and finally got that working. Then I'd try a python plugin and finally I'd turn it into a C++ plugin - a language I'm much more familiar with. I decided to do a field that would be alternate off and on in angular segments around an axis. Okay - next I'd try a python plugin. I have my code from the "python field" I created - how hard can it be? I eventually figured out the menu system and got a plugin with a non-functional but proper menu to appear under plugins. At this point, I'm ready to create a field, give it a somewhat tweaked version of the Sampling method I'd written for the "python field" and return that - somewhere. I'm not sure where (GetVirtualObjects? But that seems to create objects that don't end up on the object list so doesn't seem right) but figured I'd definitely have to create a subclassed field so I made a new class and subclassed it off of c4d.modules.mograph.FieldObject. That should do it - but no:

       type 'c4d.FieldObject' is not an acceptable base type
      

      I had used "c4d.modules.mograph.FieldObject" but the message refers to "c4d.FieldObject" but whatever. I assume this is because I'm not a python guru and I'm missing some sort of aliasing weirdness on classes maybe. Spent the last 30 years writing in C++ and C# but not much Python programming. I looked at the documentation which is very low on semantic content and pretty much just gives barebones functions so I'm not really sure what I should be instantiating here - just guessed that it might be something called FieldObject but I guessed wrong. Saw FieldList and finally kinda guessed that this represents the list of fields in Falloffs, etc.. Saw that you put "FieldLayers" in these so maybe that's what I should be instantiating? Tried it and got the same "not acceptable base type". I've seen a few lists of "objects you can create in R20" and I don't see "Field" on them. I know that I can create an Ofield object but that will be a generic field object that doesn't have my sampling behavior, correct? Do I create one of those and somehow alter it? Is there a pointer to a sampling function that I replace somehow so I don't do subclassing at all? I've included a zipped file of what I've got currently (at least I tried - the forum told me that I didn't allow zip files but then uploaded it anyway so I'm keeping my fingers crossed). At this point it doesn't work since I've got the class in there that subclasses off of FieldObject. Remove that class and you get my nice little non-functional plugin with it's non-functional parameters menu.

      Thanks for any help here.

      Darrell Plank

      P.S. Finger crossing failed. I guess I'll just post the python function code by itself. Won't work without all the supporting stuff, but at least you'll see what I've got.

      P.P.S. Didn't want to load the pyp file either. I'm not sure how to upload a file. I press the "upload file" button and it seems to upload something but then just leaves some stuff in brackets which doesn't link anywhere. Sorry if I'm being dumb and obtuse, but I'm not figuring this out. I'll try again. Oh wait - it only allows image files and c4d files? That seems crazy in a forum dedicated to plugins, but okay. I tried to put a OneDrive link to the zip file up but my OneDrive is busy uploading other stuff at the moment. Argh. I guess I'll just past in my pyp code. Not very satisfactory, but...

      import c4d
      from c4d import gui, plugins
      import os
      
      PLUGIN_ID = 1050334
      
      ANGULAR_AXIS		= 1000
      ANGULAR_AXISX		= 1001
      ANGULAR_AXISY		= 1002
      ANGULAR_AXISZ		= 1003
      ANGULAR_STRCOUNT	= 1004
      ANGULAR_RATIO		= 1005
      ANGULAR_OFFSET		= 1006
      
      Ofield				= 440000200
      
      class AngularField(c4d.plugins.ObjectData):
      
          def GetVirtualObjects(self, op, hierarchyhelp):
              dirty = op.CheckCache(hierarchyhelp) or op.IsDirty(c4d.DIRTY_DATA)
              if dirty is False:
                  return op.GetCache(hierarchyhelp)
      
          def __init__(self):
              self.SetOptimizeCache(True)
          
          def Init(self, op):
          	print c4d.Ofield
          	self.InitAttr(op, int, ANGULAR_AXIS)
          	self.InitAttr(op, float, ANGULAR_RATIO)
          	
          	op[ANGULAR_AXIS] = ANGULAR_AXISX
          	op[ANGULAR_RATIO] = 0.5
              return True
      
          def Execute(self, op, doc, bt, priority, flags):
              return True
      
      """
      class AngularFieldObject(c4d.modules.mograph.FieldObject):
      
      	def Sample( op, inputs, outputs, info):
      	    # Determine field strength based on angle around Y axis
      	    localMl = ~op.GetMg()
      	    for i in range(0, inputs._blockCount):
      	        localpos = localMl.Mul(inputs._position[i])
      	        if op[AXIS] == ANGULAR_AXISX:
      	        	xval = localpos.y
      	        	yval = localpos.z
      	        elif op[AXIS] == ANGULAR_AXISY:
      	        	xval = localpos.x
      	        	yval = localpos.z
      	        else:
      	        	xval = localpos.x
      	        	yval = localpos.y
      	        
      	        angle = math.atan2(yval, xval) + math.pi
      	        angleBin = math.floor(op[ANGULAR_STRCOUNT] * angle / math.pi)
      	        val = 1.0 if angleBin % 2 == 0 else 0.0
      	        outputs.SetValue(i, val)
      	    return True	
      """
      
      # Register
      if __name__=='__main__':
          bmp = c4d.bitmaps.BaseBitmap()
          dir, file = os.path.split(__file__)
          fn = os.path.join(dir, "res", "Angular.tif")
          bmp.InitWith(fn)
          result = plugins.RegisterObjectPlugin(
              id=PLUGIN_ID,
              str="AngularField",
              g=AngularField,
              description="AngularField",
              info=c4d.OBJECT_GENERATOR,
              icon=bmp
              )
      
      1 Reply Last reply Reply Quote 0
      • M
        mp5gosu
        last edited by mp5gosu

        This post is deleted!
        1 Reply Last reply Reply Quote 0
        • S
          s_bach
          last edited by

          Hello,

          in the Cinema 4D APIs, plugins are not created by creating a subclass of the object class. To create a plugin you have to implement a subclass of a special plugin class. To create custom Field objects, you must not create a subclass of FieldObject but of the dedicated class FieldData.

          Currently FieldData is not available in the Python API. The only way to create a Field using Python is to use the Python Field.

          The C++ API contains the FieldData class. You find information about that in the C++ documentation:

          • FieldData Manual
          • Example on GitHub

          best wishes,
          Sebastian

          MAXON SDK Specialist

          Development Blog, MAXON Registered Developer

          D 1 Reply Last reply Reply Quote 0
          • D
            darrellp @s_bach
            last edited by

            @s_bach I was beginning to wonder if I was beating my head against a brick wall. Apparently so. Thanks so much for alleviating the pain! Well, I learned quite a bit about Python in the process so not really a loss. Guess I'll try moving on directly to the C++ version.

            1 Reply Last reply Reply Quote 0
            • First post
              Last post