Navigation

    • Register
    • Login
    • Search
    • Categories
    1. Home
    2. mp5gosu
    3. Posts
    M
    • Profile
    • Following
    • Followers
    • Topics
    • Posts
    • Best
    • Groups

    Posts made by mp5gosu

    • RE: External dependencies question

      Here you go: https://github.com/NiklasRosenstein/py-localimport
      That helper is also available as a minified version.

      posted in Cinema 4D Development
      M
      mp5gosu
    • RE: Global Matrix - Trying to copy data from Mixamo Control Rig with Python

      You have to update the document each frame with ExecutePasses()
      In your for loop, simply add doc.ExecutePasses(None, True, True, False, c4d.BUILDFLAGS_NONE) as the first method call. (Adjust parameters to your needs.)

      posted in Cinema 4D Development
      M
      mp5gosu
    • RE: UVW coordinates in ShaderData.Output()

      As far as I remember, Viewport drawing is handled in Draw() method.

      posted in Cinema 4D Development
      M
      mp5gosu
    • RE: Erratic Keyboard Messages in GeDialog

      Did you try my proposed fix? ;)

      posted in Cinema 4D Development
      M
      mp5gosu
    • RE: Erratic Keyboard Messages in GeDialog

      This happens because tools that will be called twice in short succession gain focus in the C4D layout. Therefore your Dialog loses focus as the Move tool is bound toE.
      I don't kbnow exactly how to prevent that behavior, but there should be some message that can be processed. SDK team will be more of help here.

      edit: Easy fix: return c4d.NOTOK after your print statement. That consumes the message and does not call the base function, so Cinema simply does not get notified of the event.

      posted in Cinema 4D Development
      M
      mp5gosu
    • RE: Error: Wrong indentation of namespace member

      Are both header files or is the upper one a cpp file?
      Also, do the errors com from Intellisense or is it a style check/compilation error?

      If the LLVM convention is used, the error is correct. LLVM namespace formatting conventions don't use any intentaion. You might be a able to fix this by ignoring this error explicitly.
      It also might be caused by a bug in XCode.

      posted in Cinema 4D Development
      M
      mp5gosu
    • RE: Purely dynamic description for shader?

      Sure, your statement was correct. That's why I mentioned the possible misunderstanding here. That's on my side (as usual :)).
      You posts are invavuable for all of us, so I'd be damned if I'm going to accuse you of being wrong. :P

      posted in Cinema 4D Development
      M
      mp5gosu
    • RE: Purely dynamic description for shader?

      Sure. The reason why I know that is, I do it occassionally. :)
      Niklas answered me that question a while ago: https://plugincafe.maxon.net/topic/9400/12588_multiple-nodedata-descriptions-solved/2

      But it seems, there's a misunderstanding here. Multiple plugin IDs cannot be registered. But you can create a composite plugin with different descriptions.
      I usually do that with NodeData plugins.

      Best,
      Robert

      posted in Cinema 4D Development
      M
      mp5gosu
    • RE: Purely dynamic description for shader?

      @ferdinand said in Purely dynamic description for shader?:

      1. So you talk about multiple descriptions, but a singular plugin, which I do not understand. No matter what you do, you can only register a plugin once and provide a singular description for it. You cannot register the same plugin with multiple descriptions.

      I have to disagree here. The Cinema 4D Multipasses for example are implemented in exactly this way. ( by registering multiple descriptions though)

      posted in Cinema 4D Development
      M
      mp5gosu
    • Crash with GeListHead and TreeViewFunctions SetName()

      Hello,

      I noticed that when using a GeListHead for storing custom BaseList2D items leads to a crash when TreeViewFunctions' SetName is called.
      Is this a known bug/behavior?
      If not, what did I do wrong? ;)

      Here's a minimal example. Try to rename any ListItem with Double-Click -> Freeze.
      On R21 I did some more debugging and it turned out that obj in SetName() is of type long.

      import c4d
      from c4d import gui
      from c4d import plugins
      
      PLUGIN_ID = 1000001  # Test plugin id
      PLUGIN_ID_ND = 1000002  # Test plugin id
      
      
      class ListItem(plugins.NodeData):
          def Init(self, node):
              # do stuff here
              return True
      
      
      class Tvf(gui.TreeViewFunctions):
          def GetFirst(self, root, userdata):
              if not root:
                  return None
              return root.GetFirst()
      
      
          def GetNext(self, root, userdata, obj):
              return obj.GetNext()
      
      
          def GetName(self, root, userdata, obj):
              return obj.GetName()
      
      
          def SetName(self, root, userdata, obj, str):
              obj.SetName(str)
      
      
      class TestDialog(gui.GeDialog):
          def __init__(self):
              self.items = c4d.GeListHead()
              self.treegui = None
              self.tvf = Tvf()
      
      
          def add_item(self):
              item = c4d.BaseList2D(PLUGIN_ID_ND)
              item.SetName("ListItem")
              item.InsertUnder(self.items)
      
      
          def CreateLayout(self):
              settings = c4d.BaseContainer()
              settings.SetBool(c4d.TREEVIEW_HAS_HEADER, True)
      
              self.treegui = self.AddCustomGui(0, c4d.CUSTOMGUI_TREEVIEW, "",
                                               c4d.BFH_SCALEFIT | c4d.BFV_SCALEFIT,
                                               300,
                                               300,
                                               settings)
      
              return True
      
      
          def InitValues(self):
              for x in range(5):
                  self.add_item()
      
              layout_bc = c4d.BaseContainer()
              layout_bc.SetInt32(0, c4d.LV_TREE)
              self.treegui.SetLayout(1, layout_bc)
      
              self.treegui.SetHeaderText(0, "Name")
              self.treegui.Refresh()
      
              self.treegui.SetRoot(self.items, self.tvf, None)
              return True
      
      
      class TestCommand(plugins.CommandData):
          def __init__(self):
              self.dlg = None
      
      
          def Register(self):
              return plugins.RegisterCommandPlugin(PLUGIN_ID, "Test-Plugin", 0, None, None, self)
      
      
          def Execute(self, doc):
              if self.dlg is None:
                  self.dlg = TestDialog()
      
              return self.dlg.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=PLUGIN_ID, defaulth=400, defaultw=400)
      
      
          def RestoreLayout(self, sec_ref):
              if self.dlg is None:
                  self.dlg = TestDialog()
      
              return self.dlg.Restore(pluginid=PLUGIN_ID, secret=sec_ref)
      
      
      if __name__ == '__main__':
          TestCommand().Register()
          plugins.RegisterNodePlugin(PLUGIN_ID_ND, "ListItem", c4d.PLUGINFLAG_HIDE, ListItem, None)
      
      posted in Cinema 4D Development
      M
      mp5gosu
    • RE: "Frame Selected Elements" command not working when running script through c4dpy?

      @ferdinand said in "Frame Selected Elements" command not working when running script through c4dpy?:

      forgot to call c4d.documents.InsertDocument before calling c4d.documents.SetActiveDocument which causes all sorts of hiccups in Cinema, not only c4dpy

      This is a real classic! I stumbled over this several times! :)

      posted in Cinema 4D Development
      M
      mp5gosu
    • RE: "Frame Selected Elements" command not working when running script through c4dpy?

      Maybe this script helps you to frame your objects manually. The called helper methods should be self-explanatory.
      If you have any questions, feel free to ask.

      import c4d
      import sys
      import math
       
      from .. import Helpers
       
       
      class FramedCamera(object):
          """
          Modifies a given camera to frame a given object.
          The object to frame must be a clone since it is modified
          """
       
       
          def __init__(self, frame_obj, camera, azimuth=00, elevation=0):
              self.frame_object(frame_obj, camera, azimuth, elevation)
       
          # calculate the bounding sphere based on the camera FOV
       
          def calc_bsphere(self, op, camera):
              """Calculates a bounding sphere from a given object considering the FOV
       
              Args:
                  op (c4d.BaseObject): The object to calculate the bounding sphere from
                  camera (c4d.BaseObject): The camera to get the FOV from
       
              Returns:
                  list: The bounding sphere center and radius
              """
       
              points = Helpers.GetAllPoints(op)
              if not points:
                  raise ValueError("Object {} has no points".format(op.GetName()))
       
              p_min = c4d.Vector(sys.float_info.max)
              p_max = c4d.Vector(-sys.float_info.max)
       
              for p in points:
                  p_min = c4d.Vector(min(p.x, p_min.x), min(p.y, p_min.y), min(p.z, p_min.z))
                  p_max = c4d.Vector(max(p.x, p_max.x), max(p.y, p_max.y), max(p.z, p_max.z))
       
              center = (p_min + p_max) * 0.5
              radius = 0
              for p in points:
                  radius = max(radius, (center - p).GetLength())
       
              fov_h = camera[c4d.CAMERAOBJECT_FOV]
              fov_v = camera[c4d.CAMERAOBJECT_FOV_VERTICAL]
              radius = (radius * 1.1) / math.sin(max(fov_h, fov_v) * 0.5)
              return center, radius
       
          # LookAt function
          def look_at(self, origin, target):
              """
              Creates an orientation matrix from two vectors
       
              Args:
                  origin (c4d.Vector): The Vector to be used to orient
                  target (c4d.Vector): The target vector
       
              Returns:
                  c4d.Matrix: The orientation matrix
              """
              mat = c4d.Matrix()
              up_temp = c4d.Vector(0, 1.0, 0)
       
              v_fwd = (target - origin).GetNormalized()
              v_right = up_temp.Cross(v_fwd).GetNormalized()
              v_up = v_fwd.Cross(v_right).GetNormalized()
       
              mat.off = origin
              mat.v1 = v_right
              mat.v2 = v_up
              mat.v3 = v_fwd
       
              return mat
       
          # frame objects
          def frame_object(self, op, camera, elevation, azimuth):
              """
              Places and orients a camera to fit a given object An optional angle (H,P) can be given.
       
              Args:
                  op (c4d.BaseObject): The object to frame
                  camera (c4d.BaseObject): The camera that is used
                  elevation (float): Camera Heading, in radians
                  azimuth (float): Camera Pitch, in radians
       
              Returns:
                  bool: True for success, False otherwise.
              """
       
              Helpers.convertInstances(op)
       
              # Get bounding sphere depending on camera FOV
              b_sphere = self.calc_bsphere(op, camera)
              if not b_sphere:
                  raise ValueError("Bounding sphere cannot be calculated")
       
              # Set camera position and direction
              center, radius = b_sphere
              camera.SetMg(c4d.Matrix())
              cam_pos = c4d.Vector(center)
              cam_pos.x = cam_pos.x + math.cos(azimuth) * math.sin(elevation) * radius
              cam_pos.y = cam_pos.y + math.sin(azimuth) * radius
              cam_pos.z = cam_pos.z + math.cos(azimuth) * math.cos(elevation) * -radius
       
              camera.SetMg(self.look_at(cam_pos, center))
      

      Side note. This code comes from a prototype, therefore it is not optimized/comes with some syntactical flaws.

      posted in Cinema 4D Development
      M
      mp5gosu
    • RE: OOP class struggles: treeview envoce gui refresh outside class ListView()

      userdata parameter of the TreeViewFunctions overidden methods can be anything, your dialog for example. ;)

      posted in Cinema 4D Development
      M
      mp5gosu
    • RE: Attribute Manamger Update Delay When Description Added Dynamically

      By the way, it is also worth mentioning the Note on MSG_CHANGE

      posted in Cinema 4D Development
      M
      mp5gosu
    • RE: GroupBorderNoTitle change GUI or flags after user input

      Hello mogh.

      I usually come over such tasks by having a helper routine that does the layout (re-)building.
      In that routine, I can freely decide the gadget's appearance based on certain conditions. After rebuilding, the "old" gadgets have to be removed and replaced by the new ones and the only thing that's left is the refreshing of the dialog. Note that this only works for dynamic gadgets/groups.

      posted in Cinema 4D Development
      M
      mp5gosu
    • RE: How to change the EXR compression method via python

      @m_adam maybe the code example in the repo should be updated. ;)

      posted in Cineware SDK Development
      M
      mp5gosu
    • RE: How to change the EXR compression method via python

      Oh yes, you are right. The SDK example doesn't work at all.
      Problem is, maxon.Id is wrong. maxon.InternedId would be the correct way for setting the save options. Here's the correct code:

      """
      Copyright: MAXON Computer GmbH
      Author: Maxime Adam
      Description:
          - Configures OpenEXR output render format with SetImageSettingsDictionary() then reads these with GetImageSettingsDictionary().
      Class/method highlighted:
          - c4d.bitmaps.SetImageSettingsDictionary()
          - c4d.bitmaps.GetImageSettingsDictionary()
      Compatible:
          - Win / Mac
          - R20, R21, S22, R23
      """
      import c4d
      import maxon
      
      
      def main():
          # Retrieves render data and its container
          renderData = doc.GetActiveRenderData()
          bc = renderData.GetDataInstance()
      
          # Gets image filters options
          saveOptions = bc.GetContainerInstance(c4d.RDATA_SAVEOPTIONS)
      
          # Sets OpenEXR output format
          bc[c4d.RDATA_FORMAT] = c4d.FILTER_EXR
      
          # Defines OpenEXR settings
          compressionmethodID = maxon.InternedId('net.maxon.mediasession.openexr.export.compressionmethod')
          halffloatID = maxon.InternedId('net.maxon.mediasession.openexr.export.halffloat')
          layernumberingID = maxon.InternedId('net.maxon.mediasession.openexr.export.layernumbering')
      
          # Configures OpenEXR format options with a maxon.DataDictionary
          exportSettings = maxon.DataDictionary()
          exportSettings.Set(compressionmethodID, maxon.Id("rle"))
          exportSettings.Set(halffloatID, True)
          exportSettings.Set(layernumberingID, True)
      
          # Stores settings in render data container
          c4d.bitmaps.SetImageSettingsDictionary(exportSettings, saveOptions, c4d.FILTER_EXR)
      
          # Pushes an update event to Cinema 4D
          c4d.EventAdd()
      
          # Retrieves OpenEXR images settings
          settings = c4d.bitmaps.GetImageSettingsDictionary(saveOptions, c4d.FILTER_EXR)
      
          # Reads and prints OpenEXR format options
          print("openexr.export.compressionmethod: " + str(settings.Get(compressionmethodID)))
          print("openexr.export.halffloat: " + str(settings.Get(halffloatID)))
          print("openexr.export.layernumbering: " + str(settings.Get(layernumberingID)))
      
      
      if __name__ == '__main__':
          main()
      
      posted in Cineware SDK Development
      M
      mp5gosu
    • RE: How to change the EXR compression method via python

      Here you go: https://github.com/PluginCafe/cinema4d_py_sdk_extended/blob/762c9d505e0ed2f09dafdd8c6cef972a82d084e8/scripts/04_3d_concepts/rendering/render_settings_openexr_data_r20.py

      posted in Cineware SDK Development
      M
      mp5gosu
    • RE: Reflection Layer Settings

      Reflection Layers aren't simple parameters. They are of type c4d.ReflectionLayer and have their own ID. Since the number of reflection layers can change dynamically, the parameter access also happens dynamically.

      For example:

      import c4d
        
      def main() :
          mat = doc.GetActiveMaterial()
          cntLayer = mat.GetReflectionLayerCount() # get the number of all reflection layers
          
          for i in xrange(0, cntLayer) :  # loop through all layers
              layer = mat.GetReflectionLayerIndex(i) # process current layer
              
              # Sets the Strength for each layer to 50%
              mat[layer.GetDataID() + c4d.REFLECTION_LAYER_TRANS_BRIGHTNESS] = 0.5 # Here, the DataID is the unique, dynamic identifier for the layer. This can be chained with actual parameters.
        
          c4d.EventAdd() # update C4D
        
      if __name__=='__main__':
          main()
      

      There's plenty of questions and answers to reflection layers on this forum. Just need to search for it. :)

      posted in Cinema 4D Development
      M
      mp5gosu
    • RE: NodeData: How to get connected GeListNode

      Thought so.
      No, there's nothing missing in inherited methods. Thought, it'd be convenient. However, storing it to a member variable on init or forwarding does the trick.

      posted in Cinema 4D Development
      M
      mp5gosu