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
    1. Maxon Developers Forum
    2. .del
    3. Posts
    .
    • Profile
    • Following 0
    • Followers 0
    • Topics 13
    • Posts 45
    • Best 2
    • Controversial 0
    • Groups 0

    Posts made by .del

    • RE: Python Documentation - Icon Color

      Thank you @i_mazlov . I had worked around it by setting it up as a custom color but my preference is to use the display color as I'm already setting that. I'll throw your solution into my project and give it a try.

      Do you think this might be changed in the future? If so I want to leave myself a note in the script to revisit the sdk.

      Have a great weekend,
      .del

      posted in Cinema 4D SDK
      .
      .del
    • Python Documentation - Icon Color

      Hi - How can I set the icon color in the object manager to use the Display Color? The UX has options for None, Display Color, and Custom.

      The sdk and VS Code only show values for None and Custom.

      I'm not sure if the value was accidentally overlooked or if I'm approaching it incorrectly. I tried taking a stab at c4d.ID_BASELIST_ICON_COLORIZE_MODE_DISPLAYCOLOR but that did not work.

      thanks,
      .del

      Cinema 4D SDK 2024.2.0 documentation ยป Classic Resource Overview ยป Basic Properties

      Parameter: Icon Color

      Parameter ID: c4d.ID_BASELIST_ICON_COLORIZE_MODE
      
      Parameter Type: int
      
      Cycle Values:
      
              None (c4d.ID_BASELIST_ICON_COLORIZE_MODE_NONE)
      
              Custom (c4d.ID_BASELIST_ICON_COLORIZE_MODE_CUSTOM)
      
      posted in Cinema 4D SDK 2024 python
      .
      .del
    • RE: Python: GetTags() returning non-existent tags

      thanks @i_mazlov

      posted in Cinema 4D SDK
      .
      .del
    • RE: Python: GetTags() returning non-existent tags

      HI @i_mazlov - I have a script that cycles through polygon selection tags on an object and I'm inserting materials tags next to the associated polygon selection tag that it's matched to.

      As far as KIllTag() goes, sometimes I have multiple tags of the same type. I don't necessarily want to remove all of them so starting at a specific index to just remove the tag I wanted made sense. I don't mind using Remove(). It's just that KillTag() is right there in the sdk with all of the other tag related things so that's where I started. I also think that the definition of it made me think that it removed a single tag versus all of the tags of that type "Removes a tag from the object and free its resources."

      posted in Cinema 4D SDK
      .
      .del
    • RE: Python: GetTags() returning non-existent tags

      Do these tags always occupy the same position?

      I'm trying things like MakeTag and KillTag that require an indexed position and having two invisible tags is kind of throwing things off. Right now I'm subtracting 2 from the position that I'm targeting but this feels ripe for a script error down the road.

      posted in Cinema 4D SDK
      .
      .del
    • RE: Python: GetTags() returning non-existent tags

      Thank you. I'll have to remember TAG_VISIBLE for future scripts.

      posted in Cinema 4D SDK
      .
      .del
    • Python: GetTags() returning non-existent tags

      Why does op.GetTags() return a polygon tag and point tag even if there are not any on the object?

      [<c4d.BaseTag object called Phong/Phong with ID 5612 at 1906901951872>, <c4d.PolygonTag object called with ID 5604 at 1906901936256>, <c4d.PointTag object called with ID 5600 at 1906901964288>]

      posted in Cinema 4D SDK python
      .
      .del
    • RE: Material Tag: Fit to object

      Hi @m_adam - In this particular instance I'm calling it on objects that have children and I'm getting the prompt to include sub objects. If it were a modeling command or something like that it may include the ability to include or exclude the children programmatically.

      I'm creating 30 objects and each object has six flat projections that I want to set to the size of the object. That's 180 confirmation clicks.

      posted in Cinema 4D SDK
      .
      .del
    • Material Tag: Fit to object

      Hi - It looks like the only way to to fit a flat projected material tag to an object via python is with a callCommand(). I couldn't find anything in the SDK but that doesn't mean it's not there. Can anybody please confirm that Fit To Object is not available or kindly point me in the right direction in the SDK?

      thanks,
      .del

      posted in Cinema 4D SDK python 2024
      .
      .del
    • RE: OBJ Import setting not changing

      Hi @ferdinand -

      What do you think about changing the git file to math.radians(22.5)?

      Thanks,
      .del

      posted in Cinema 4D SDK
      .
      .del
    • RE: OBJ Import setting not changing

      I figured it out.

      objImport[c4d.OBJIMPORTOPTIONS_PHONG_ANGLE_DEFAULT] = 22.5
      

      This needs to be in radians versus degrees.

      posted in Cinema 4D SDK
      .
      .del
    • OBJ Import setting not changing

      Hi -

      I'm looking at the git hub example for obj import and ran that code as it is and it leaves me wondering if changing the import settings is working. Based on the git hub script the phong tag should come in at 22.5 degrees.

      Another strange thing. I set my preferences to a phong of 60 degrees and closed the preference panel. Then I ran the script which should have imported the obj at 22.5 but instead it actually came in at 180 degrees.

      Is it possible that the documentation or perhaps the python implementation is incorrect?

      thanks,
      .del

      Straight from the git -

      ๏ปฟ"""
      Copyright: MAXON Computer GmbH
      Author: Joey Gaspe
      
      Description:
          - Imports Obj with custom settings.
      
      Class/method highlighted:
          - c4d.plugins.FindPlugin()
          - MSG_RETRIEVEPRIVATEDATA
          - c4d.documents.MergeDocument()
      
      """
      import c4d
      
      
      def main():
          # Retrieves a path to load the imported file
          selectedFile = c4d.storage.LoadDialog(title="Load File for OBJ Import", type=c4d.FILESELECTTYPE_ANYTHING, force_suffix="obj")
          if not selectedFile:
              return
      
          # Retrieves Obj import plugin, defined in R17 as FORMAT_OBJ2IMPORT and below R17 as FORMAT_OBJIMPORT
          objExportId = c4d.FORMAT_OBJIMPORT if c4d.GetC4DVersion() < 17000 else c4d.FORMAT_OBJ2IMPORT
          plug = c4d.plugins.FindPlugin(objExportId, c4d.PLUGINTYPE_SCENELOADER)
          if plug is None:
              raise RuntimeError("Failed to retrieve the obj importer.")
      
          data = dict()
          # Sends MSG_RETRIEVEPRIVATEDATA to OBJ import plugin
          if not plug.Message(c4d.MSG_RETRIEVEPRIVATEDATA, data):
              raise RuntimeError("Failed to retrieve private data.")
      
          # BaseList2D object stored in "imexporter" key hold the settings
          objImport = data.get("imexporter", None)
          if objImport is None:
              raise RuntimeError("Failed to retrieve BaseContainer private data.")
      
          # Defines the settings
          objImport[c4d.OBJIMPORTOPTIONS_PHONG_ANGLE_DEFAULT] = 22.5
          if c4d.GetC4DVersion() > 22600:
              objImport[c4d.OBJIMPORTOPTIONS_IMPORT_UVS] = c4d.OBJIMPORTOPTIONS_UV_ORIGINAL
          else:
              objImport[c4d.OBJEXPORTOPTIONS_TEXTURECOORDINATES] = True
      
          objImport[c4d.OBJIMPORTOPTIONS_SPLITBY] = c4d.OBJIMPORTOPTIONS_SPLITBY_OBJECT
          objImport[c4d.OBJIMPORTOPTIONS_MATERIAL] = c4d.OBJIMPORTOPTIONS_MATERIAL_MTLFILE
          objImport[c4d.OBJIMPORTOPTIONS_POINTTRANSFORM_FLIPZ] = True
      
          # Finally imports without dialogs
          if not c4d.documents.MergeDocument(doc, selectedFile, c4d.SCENEFILTER_OBJECTS | c4d.SCENEFILTER_MATERIALS, None):
              raise RuntimeError("Failed to load the document.")
      
          # Pushes an update event to Cinema 4D
          c4d.EventAdd()
      
      
      if __name__ == '__main__':
          main()
      
      posted in Cinema 4D SDK python 2024 windows
      .
      .del
    • RE: Howto add headers & dividers for a ShowPopupDialog?

      Hi - How are you generating the popup dialog right now? Are you using gui.GeDialog to create your own dialog box or are you using c4d.gui.MessageDialog to generate a simple prompt?

      I found that I can create the kind of stuff your talking about with gui.GeDialog but it also makes me feel like I'm in over my head ๐Ÿ™‚ - (self taught hack that is distracted easily)

      posted in Cinema 4D SDK
      .
      .del
    • RE: Get all textures for a material

      Thanks Ferdinand. I'll take a stab at it again. I have to start by learning more about your Python syntax.

      Did I mention I'm a 3D/mograph guy that pretends to understand python and the c4d sdk? ๐Ÿ™‚

      Thanks for taking the time to help people like me out. I try to do what I can with the documentation, forums and search but sometimes it's the syntax in the documentation that I don't quite understand. That's the downside for me. I learn a little more each time though and that helps.

      Thanks again for the example. I'll see if I can get GetAllTextures() to work for me.

      posted in Cinema 4D SDK
      .
      .del
    • RE: Get all textures for a material

      That makes total sense @ferdinand.

      Kind of have to start at the beginning to understand where I'm coming from. I found myself exporting individual .fbx files on a more regular basis but only a couple at a time so it was not a problem to do it in the interface. I added the Export Selected Objects As to my toolbar for ease of use as it fills in the fbx file name with the selected objects name by default. I have my fbx export preferences preset to Selection Only. This work flow has gotten me into a habit of clicking a button to open the export panel and then clicking ok. Easy.

      That brings us to this week where I have to export 160 objects. Writing a script to do exactly what I was doing was easy enough. But then I got greedy and wanted to collect the textures as well. We don't use embedded textures in our fbx so collecting them for transfer has been a manual process. That's when I was faced with two options.

      1. Get a cake ๐Ÿ™‚ (I love that analogy by the way) I do this for many of my other exports like .c4d, .obj and .gltf
      2. Leverage the built in Selection Only aspect of the fbx exporter and then simply use Python to copy some texture files from my tex folder to my delivery folder. It felt like it would be a simpler, lower overhead solution versus creating a 'donor' doc. Or at least it feels like it should be simple. There's even a function called GetAllTextures and an option to have it restricted to a single model rather than from the entire doc.

      I'm ok with how I had to make it in the end but now I'm really curious how the GetAllTextures() works in case I can leverage it for this or something else down the road.

      The FBX exporter is unique in Cinema since Maxon added the Selection Only option to it. If it weren't for that thing I'd be at the bakery....all.....day.....long ๐Ÿ™‚

      import c4d
      import os
      from c4d import gui
      from c4d import documents
      from c4d import plugins
      
      
      def listModels():
          selected = []
          rawSelection = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_NONE)
          for item in rawSelection:
              if item.CheckType(5100) or item.CheckType(5140): # PolygonalObject or Null
                  selected.append(item)
          rawSelection = []
          return selected
      
      
      models = listModels()
      if models == []:
          message = "You must select at least one object"
          c4d.gui.MessageDialog(message, c4d.GEMB_OK)
      else:
          gui.SetMousePointer(c4d.MOUSE_BUSY)
          c4d.StatusSetSpin()
      
          # Get fbx export plugin,
          plug = plugins.FindPlugin(c4d.FORMAT_FBX_EXPORT, c4d.PLUGINTYPE_SCENESAVER)
          if plug is None:
              print("noPlug")
      
          op = {}
          # Send MSG_RETRIEVEPRIVATEDATA to fbx export plugin
          if plug.Message(c4d.MSG_RETRIEVEPRIVATEDATA, op):
      
              # BaseList2D object stored in "imexporter" key holds the settings
              fbxExport = op["imexporter"]
      
              # Define the settings
              fbxExport[c4d.FBXEXPORT_FBX_VERSION] = c4d.FBX_EXPORTVERSION_NATIVE
              fbxExport[c4d.FBXEXPORT_SELECTION_ONLY] = True
              fbxExport[c4d.FBXEXPORT_TRIANGULATE] = True
              fbxExport[c4d.FBXEXPORT_SAVE_NORMALS] = True
              fbxExport[c4d.FBXEXPORT_UP_AXIS] = c4d.FBXEXPORT_UP_AXIS_Y
              fbxExport[c4d.FBXEXPORT_FLIP_Z_AXIS] = False
              fbxExport[c4d.FBXEXPORT_MATERIALS] = True
              fbxExport[c4d.FBXEXPORT_EMBED_TEXTURES] = False
              fbxExport[c4d.FBXEXPORT_BAKE_MATERIALS] = False
      
      
      
          #check for target directory
          targetPath = os.path.join(doc.GetDocumentPath(), "FBX_Exports")
          if os.path.exists(targetPath) == False: #makes a new directory to store the converted files in
              os.mkdir(targetPath)
      
          for obj in (models):
              fbxName = c4d.BaseList2D.GetName(obj) + ".fbx" #get the name of the model
              fbxPath = os.path.join(targetPath,fbxName)
      
              # Get the texture files and a save a c4d file for rendering
              theTextures = doc.GetAllTextures(False, [obj])
              print(theTextures)
              # if I can get the textures I will write some shutil.copyFile type of stuff here
      
      
      
              #export the fbx
              if c4d.documents.SaveDocument(newDoc, fbxPath, c4d.SAVEDOCUMENTFLAGS_DONTADDTORECENTLIST, c4d.FORMAT_FBX_EXPORT) == False:
                  if gui.MessageDialog("Export failed!" + " - " + fbxName, c4d.GEMB_OKCANCEL) == c4d.GEMB_R_CANCEL:
                      break
      
      
      
      
          c4d.gui.SetMousePointer(c4d.MOUSE_NORMAL)
          gui.MessageDialog("Export Complete", c4d.GEMB_OK)
          c4d.StatusClear()
      
      posted in Cinema 4D SDK
      .
      .del
    • RE: Get all textures for a material

      Thanks @ferdinand for the reply and the example.

      You are correct that my current solution uses IsolateObjects and creates a new doc. Since that doc only has the single mesh and materials in it I can use SaveProject to collect the textures.

      In reference to GetAllAssets vs GetAllAssetsNew - I had originally written an exporter in R19 and pulled some of my script forward to begin this new version. I saw the new version for this but I kept getting an error and the old command still worked. I didn't understand what the last parameter was supposed to be. The documentation shows this - assetList (List[Dict]). After awhile I gave up because the old command still worked. I know that isn't the right thing to do but when the clock is ticking I have to go with what I can get working. Your example sheds more light on how I have to format that last parameter. I'm going to give it a try.

      Ultimately I was trying to create a different solution that didn't require creating an isolation doc. I feel like I should be able to iterate through a list of selected objects and export them as fbx files without creating temporary documents. I have that working. The next step is to collect the textures for those objects. I can get the material for each object and crawl through the shader tree looking for bitmaps but I was hoping for something that was going to be quicker to set up. GetAllTextures() looked promising but I struggled to get it to work and I haven't been able to find any threads or examples that.

      thanks,
      .del

      posted in Cinema 4D SDK
      .
      .del
    • RE: Get all textures for a material

      I found a way around what I want to do by using this -
      c4d.documents.SaveProject(newDoc, c4d.SAVEPROJECT_NONE|c4d.SAVEPROJECT_ASSETS|c4d.SAVEPROJECT_DIALOGSALLOWED, targetPath, theAssets)

      I didn't realize that I could skip saving the actual project file but instead use the call just to gather textures. It's probably not very clean creating a new document and isolating my selected models to it just for the purpose of texture collection but it gets me through this jam while I learn more about how to do it the right way.

      posted in Cinema 4D SDK
      .
      .del
    • Get all textures for a material

      Hi- I'm a bit stumped and looking for some direction. I have a file with multiple objects in it. I'd like to select 10 of those objects and export each one as an individual fbx file that has only a single object in it. 10 selected objects equates to 10 fbx files. That part I have working.

      I'd also like to collect the textures associated with the single material that has been applied to the single object in the fbx.

      I tried using doc.GetAllAssets() and set the flag to textures only but I could not find a way to link the single models to the correct texture files in the list. Maybe there is an identifier in that list that I'm not seeing that will allow me to find only the texture files I want versus the list of all textures used?

      Since I couldn't figure that out I moved on to doc.GetAllTextures() . I feel like the optional [List[c4d.C4DAtom]] is the thing I need to use in order to get the texture file list for the single, selected model instead of the all of the textures for the entire document.

      models = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_NONE)
      for obj in (models):
              #theAssets = c4d.documents.GetAllAssets(doc, False, lastPath, c4d.ASSETDATA_FLAG_TEXTURESONLY)
              theTextures = doc.GetAllTextures(False, [obj])
              print(theTextures)
      

      The script returns a c4d.BaseContainer. I'm scratching my head on what to do with that. Am I on the right path or am I missing something?

      Any tips on where to look next or reference material on how to get my texture file names out of that BaseContainer will be greatly appreciated.

      thanks,
      .del

      posted in Cinema 4D SDK
      .
      .del
    • RE: Possible typo in documentation

      Thanks for the info and adding the tag. I totally forgot that the Cafe' merged. I'm so used to approaching from my view. I actually answered somebodies question yesterday and at the very end saw the C++ tag and hit delete ๐Ÿ™‚

      Thanks for tips on the GUI. I was able to implement what I needed.

      posted in Cinema 4D SDK
      .
      .del
    • Possible typo in documentation

      Hi - I'm currently making an attempt to better understand the gui.GeDialog stuff and ran across this in the sdk.

      GeDialog.GroupBorder(self, borderstyle)
      Sets the border type of the current group, and displays the title in the border if possible.

      GeDialog.GroupBorderNoTitle(self, borderstyle)
      Sets the border type of the current group, and displays the title in the border if possible.

      Am I reading these wrong and haven't learned anything yet or should GroupBorderNoTitle have a different explanation and not have border title parameters listed below it?

      Thanks for looking,
      .del

      posted in Cinema 4D SDK python
      .
      .del