Your browser does not seem to support JavaScript. As a result, your viewing experience will be diminished, and you have been placed in read-only mode.
Please download a browser that supports JavaScript, or enable it if it's disabled (i.e. NoScript).
Hi,
There's a more convenient workaround than using GePrint(). sys.__stdout__ original standard output stream can be used to redirect stdout and print to the terminal/console. Here's some code:
GePrint()
sys.__stdout__
# Stores the stdout redirected by Cinema 4D Python c4d_stdout = sys.stdout # Redirects to original stdout sys.stdout = sys.__stdout__ # Prints something print("Some text to be printed to the terminal/console") # Restores Cinema 4D Python stdout redirection sys.stdout = c4d_stdout
The InExcludeData object count does not always reflect the accurate number of valid objects depending on the scenarios. Additionally to calling GetObjectCount() the returned value from ObjectFromIndex() should be checked if it's not None.
InExcludeData
GetObjectCount()
ObjectFromIndex()
Sorry for being late in the discussion here.
In R20 python_init.py is no longer executed at startup of Cinema. Sorry this change was not documented.
The __init__.py script in the preferences path python27/maxon_generated was not meant for this but it can be used as replacement. However, as Adam pointed out the difference in his last post here, the __init__.py script in R20 is executed after the plugins are registered. Pre-R20 python_init.py was executed before the plugins registration. This means a plugin cannot rely on operations done in python27/maxon_generated/__init__.py.
Note the other Python files in the directory python27/maxon_generated (_configuration.py and _enums.py) must not be modified.
Just a quick note on your code. A pythonic solution could be:
count = inExData.GetObjectCount() for i in xrange(count): obj = inExData.ObjectFromIndex(doc, i) if obj is None: continue
Why are you breaking out from the loop with the first invalid object in the InExcludeData?
That's right, the error you're getting is related to the type of the passed object to be processed by the PolygonReduction. The sample code shouldn't try to process an object that isn't a PolygonObject because there's this check at the beginning:
PolygonReduction
PolygonObject
if not polyObject.IsInstanceOf(c4d.Opolygon): return
To convert a BaseObject to a PolygonObject the Current State to Object modeling command can be used. The utility function below invokes the MCOMMAND_CURRENTSTATETOOBJECT:
BaseObject
MCOMMAND_CURRENTSTATETOOBJECT
def CSTO(obj, doc, inheritance, keepAnimation, noGenerate): bc = c4d.BaseContainer() bc.SetBool(c4d.MDATA_CURRENTSTATETOOBJECT_INHERITANCE, inheritance) bc.SetBool(c4d.MDATA_CURRENTSTATETOOBJECT_KEEPANIMATION, keepAnimation) bc.SetBool(c4d.MDATA_CURRENTSTATETOOBJECT_NOGENERATE, noGenerate) res = c4d.utils.SendModelingCommand(c4d.MCOMMAND_CURRENTSTATETOOBJECT, list=[obj.GetClone()], bc=bc, doc=doc) if isinstance(res, list): return res[0] else: return None
The CSTO() function can then be invoked like this:
if not polyObject.IsInstanceOf(c4d.Opolygon): polyObject = CSTO(polyObject, doc, True, True, False) if polyObject is None: return
I moved the topic to "CINEMA 4D DEVELOPMENT" category and I turned it into a question and answer (you can do this by yourself, see Q&A New Functionality).
A BaseObject is the base type of every object in a document. A PointObject is an object that holds points. Then an object can be a PolygonObject if it has polygons. For instance if a generator object is made editable then it's transformed into a PolygonObject which is also a PointObject. The (reduced) object classes inheritance tree is as follows:
Thanks for reporting the issue with GRIDSIZE. GRIDSIZE_H/GRIDSIZE_V were removed from the Definition list but not from Flags and Example in the SPLINE Description Resource page you linked. This will be fixed in the next update of the C++ API docs.
Several flags for the Spline have been removed in R20 but its overall GUI behavior hasn't changed. The Changes in R20 page provides the information about the discarded Spline GUI flags in R20.
Yes there's an issue with NO_FLOATING_WINDOW flag. The "Show in seperate Window.." button is still present in the GUI even if the flag is enabled. This will be reported.
About the other elements in the Spline GUI there aren't flags to get rid of them but the GUI can be minimized/maximized with the arrow on the top left.
PS: If you can't change the topic's title in edit mode then I can do it for you.
Are you using the Spline GUI inside a dialog? It looks like so if there's no arrow. If that's the case you can call SetLayoutMode(c4d.LAYOUTMODE_MINIMIZED) on the Spline custom GUI to change its layout to the minimized/spline element only.
SetLayoutMode(c4d.LAYOUTMODE_MINIMIZED)
Hi Victor,
There's a logic error in the code you posted from the first post. The condition for R20 if (str.IsEmpty()!=false) returns false if the string has content. It makes more sense to call IsPopulated() for the R20 code instead of IsEmpty().
if (str.IsEmpty()!=false)
IsPopulated()
IsEmpty()
Hi Rage,
Unfortunately several importers and exporters do not have a constant for their ID. This is the case for FBX. The ID for the FBX exporter is 1026370.
To find the ID of a specific exporter you can use the following code:
import c4d saverPlugs = c4d.plugins.FilterPluginList(c4d.PLUGINTYPE_SCENESAVER, True) for plug in saverPlugs: print('{} : {}'.format(plug.GetName(), plug.GetID()))
I turned the topic into a Q&A. Please remind to use this feature of the forum.
IMHO solution 2 is not the best because the user has to look below in the dialog to edit the text. I think solution 1 is the easiest and more convenient, you can simply call c4d.gui.InputDialog() to get the text. If you want the input dialog to be shown at the text's location in the user area then you can implement a GeDialog.
c4d.gui.InputDialog()
GeDialog
A string with format "PLUGIN_CMD_123456" is meant to be used with MENURESOURCE_COMMAND, not RegisterCommandPlugin(). It tells Cinema the command ID and name for the menu item to be added. Note the sub-IDs returned from GetSubContainer() are specific to a command and aren't global to Cinema.
MENURESOURCE_COMMAND
RegisterCommandPlugin()
GetSubContainer()
Maybe CommandData isn't what you really need. Scripts from the user folder are automatically loaded and can be added to any menu using Customize Menus dialog.
CommandData
Hi and welcome to the new Plugin Cafe!
It is not possible to pass a Python function for MENURESOURCE_COMMAND. Only a Cinema 4D command resource ID ("IDM_NEU") or a plugin command ID ("PLUGIN_CMD_123456") can be given.
A CommandData plugin can have sub-ID commands returned from GetSubContainer(). The sub-ID commands are then invoked with ExecuteSubID(). But there's a limitation with this currently. At least two CommandData have to be registered from the same plugin for the sub-commands to be taken into account.
ExecuteSubID()
Please read and use How to Post Questions and Q&A New Functionality. This time I added tags and turned the thread into a Q&A.
Hi Heinrich,
Welcome to the new forum
PYTHONPATH not added to sys.path is a known issue and has been already fixed for the R20 SP2 update. I don't see a better workaround then your with R20 SP1 currently.
I turned this topic into a Q&A. Please use this functionality in the future. For more information see Q&A New Functionality.
Only minor changes/fixes have been made to the PythonLibrary and its behavior hasn't changed in R20. So parsing a String with $ should still work fine.
How do you call the function and pass the string? What's the exact error message?
As I turned this discussion into a Q&A topic, if you're satisfied with my last post's solution then you can mark it as the correct answer or mark the topic as solved. For more information see Q&A New Functionality.