Thanks for the confirmation. I guess I'll use an empty group then and fill in the scrolling group in the code.
Posts made by Cairyn
RE: How to layout a dialog that is smaller than its components?
RE: Transform coordinates of a polygon's points
Get the object's (polygon, in this case) world matrix through GetMg(). Multiply the point's coordinates with that matrix to transform their local coordinates into world coordinates. Use the inverted matrix to convert the world coordinates back.
(It is really hard to answer that without general theory.)
RE: Objects created in real time
self.dlg.Open(c4d.DLG_TYPE_ASYNC, -1, -1, 400, 200)
However, the plugin window opens to the left of my screen and to move it to the center of the screen, I must first enlarge it.
The GeDialog manual says:
If xpos=-1 and ypos=-1 the dialog will be opened at the current mouse position.
If xpos=-2 and ypos=-2 the dialog will be opened at the center of the screen.
So, if the dialog opens to the left of your screen, I guess that's where your mouse was? Try -2, -2.
RE: Displaying the texture baking progress preview.
You cannot compile R20/R21 stuff directly for R19 and with the R19 libraries. The whole "Maxon" namespace has been added in the recent releases. The whole thread/job stuff has changed, thus I'm afraid that the example is only of limited use to you.
(Also, the error handling and everything else that starts with maxon::)
I only skimmed over the code but it looks as if you would have to replace all job stuff with classic threading stuff for R19.
RE: Any reason SceneHook is still not supported by Python?
@m_adam Thanks, yes, you're right, a timer may be my best choice here to avoid too much load on the system. Checking the project list every 3 seconds or so should suffice for the usecases. And since I'm in a GeDialog, the timer function is easy to implement.
(I just have to take care that within the 3 seconds, the state of the dialog may be inconsistent with the actual system state.)
Any reason SceneHook is still not supported by Python?
after wasting a good deal of time with the attempt to receive MSG_DOCUMENTINFO messages (not sent to CommandData plugins, not sent to dialogs(!!), not even sent to MessageData plugins(!!!!)), I finally found that the only scene-independent way to get those messages is a SceneHook. All other objects that get MSG_DOCUMENTINFO are inside a scene: objects, tags...
Sadly, the current Python SDK still doesn't seem to support SceneHooks. I wonder whether there is a reason for that (like, Python is too slow to respond in a timely manner), or if not, when we will get that addition. At the moment Python is my only choice to support MacOS, and evaluating MSG_CHANGE is not doing execution times a favor ;-)
RE: How to layout a dialog that is smaller than its components?
Yup, something like making SCROLLGROUP_NOSCROLLER and other flags available in the .res file. I haven't tried yet to define a GeUserArea through the .res file.
(It's a question out of interest only... a dialog where stuff is foreseeably too large for the dialog is most likely based on automatic generation of dialog components anyway, so I can go a step higher and create the non-scrolling scrolling area through code as well...)
How to layout a dialog that is smaller than its components?
Hello; here's a weird one:
Normally, a dialog is at least as big as the sum of its content according to the layout. It does not matter which layout flags you use (FIT, SCALE, SIZE) - it will not get any smaller, even when embedding the dialog into a screen Layout or moving the dialog's borders.
You can use a SCROLLGROUP to include a subarea that is larger than the dialog itself, yes. But what if I just don't want "overhanging" items to show? No scrollbar, no enforced size, just clipping. I know it is possible because the toolbars behave like this; icons outside of the current toolbar just disappear when the toolbar is resized too much.
Apparently that doesn't work with an external layout file?
RE: plugins folder, now you see me, now you don't.
Now R21.026 does also create a plugins folder in the user's location (again: Nice!), and when this path is added to the preferences it doesn't complain about colliding pluginIDs. When removing the path from preferences the plugins still get loaded. Just as with R20.057 it seems to internally know about this "default" path, and ignores the duplicate when it's added by the user.
Well, I am probably not of much use here, but I can at least confirm that R21 does know about some plugin paths internally. Actually, when you start C4D in debug mode, you will see the current plugin paths in one of the debug outputs: first come the two plugin folders from the installation directory and the user directory (whether they exist or not - I do not have a plugin folder in the installation directory), then the ones that are set manually in the preferences. I don't have issues with duplicate loads either, so obviously the paths are collated before C4D tries to load anything.
RE: Message behavior of tabbed dialogs changed R19->R21?
That's ok, I have meanwhile refactored everything* into a MessageData plugin anyway so the plugin will work** even if the dialog is closed.
*Everything except for timer stuff, which for some reason works differently for a dialog than for a message plugin.
**There are some strange effects like hanging or crashing application on Close, when the dialog is in certain states. I will need to investigate whether this is an effect of the missing CoreMessage calls or something that happens now due to refactoring.
RE: random.seed() vs R21
Nope. Same commands work fine here (R21.022)
Message behavior of tabbed dialogs changed R19->R21?
I was transforming some plugins from R19 to R21, and I noticed a weird thing about the message behavior of a dialog in a tabbed GUI.
When the GUI-docked dialog is in a tab that is currently not visible, its CoreMessage() is no longer executed at all!
This is rather unfortunate since I rely on the dialog to handle certain messages from another thread that I send by SpecialEventAdd(). That is necessary to perform the desired actions in the main thread where they belong. But as the new behavior just kills off all messages, it's no longer possible to dock the dialog in a tab in the background.
I can find no documentation in the Core Message Manual (the link to "Core Messages" is wrong in the documentation for all four found instances of "CoreMessage", by the way) that such a change was made, although it might already have been in R20 and perhaps the doc dropped out for R21.
Thus: Is this a bug?
Or is it intentional? (Which is possible as CoreMessages are mainly for GUI updates, and dialogs in a currently-hidden tabs may not need GUI updates. Although that would mean that you cannot use SpecialEventAdd to send anything to a dialog because it would never receive it if tabbed invisibly, even if the event in question has nothing to do with the GUI.)
And do I have to use a completely new concept with a MessageData Plugin now? (As these have no GUI, I assume CoreMessage() would always be called.)
RE: How to enable object X-Ray option - C++
@mfersaoui Do you get an error message? If yes, which one?
Perhaps you need to construct a DescID since that is the parameter SetParameter wants to have? So
Did you call EventAdd() to make the XRay visible?
Sorry, can't fire up C++ right now but I tried it in Python for ***** and giggles, and it works:
import c4d def main(): op.SetParameter(c4d.DescID(c4d.DescLevel(c4d.ID_BASEOBJECT_XRAY)), True, c4d.DESCFLAGS_SET_NONE) c4d.EventAdd() if __name__=='__main__': main()
RE: Writing data to the .c4d file
@blastframe For me, it works fine this way. Did you really "close and reopen" the document? Not "save", "close", "load"? Because if you just close the document, the data from the container is gone, which leads to your error message.
The Q regarding MyUniqueId vs. PLUGIN_ID is not relevant (probably typed in a hurry), you can use either. But the ID value should come from Maxon in the end, so you avoid collisions with existing IDs.
RE: Writing data to the .c4d file
I suppose you mean saving data to the BaseContainer of the BaseDocument? You'll need a plugin id for that so it will not collide with the existing IDs, then you can put a sub-BaseContainer with your data into that container. Or you can define your own datatype.
RE: Modified Pop Up Menu
Thanks for the response. I tried adding it. It didn't error out but it also didn't close
Unreached code. You return
truewhen MY_BUTTON is clicked, and never get to the
(You can remove two of the three returns from that method.)
RE: Tag Based Subdivision Surface?
Reprogramming a full SDS (however this is done) seems like overkill to me.
Personally, I did a few simple scripts (tied to keystrokes) that allow me to "walk" the object tree for cases like this, like:
- from the currently selected object, go down to the next polygon object below (for the SDS case)
- from the currently selected (polygon) object, go upwards and (de)activate all SDS and symmetry objects containing this poly object
and so on. This method is easier to implement and can be adapted for all kinds of special cases.
RE: Lock / unlock plugin from Plugins menu
@mfersaoui You misunderstand the return value.
This is not a single true/false flag, but a set of flags. As I mentioned,
CMD_ENABLEDstands for the enabling of the command (greyed out if not set), and
CMD_VALUEstands for the checked state (in case of icons, the background changes, as you saw in your test). These two flags are not mutually exclusive but can be used together! (use
The actual value to use if you want neither flag set is simply
Falseworks in this case because the numeric equivalent of false is 0.
import c4d from c4d import gui def state(): op = doc.GetActiveObject() if op is not None: if op.GetType() == c4d.Ocube : return c4d.CMD_ENABLED | c4d.CMD_VALUE elif op.GetType() == c4d.Ocylinder : return c4d.CMD_VALUE else : return c4d.CMD_ENABLED return 0 # Main function def main(): print "Triggered!" # Execute main() if __name__=='__main__': main()
If you watch the above script as icon in a toolbar, you will see all four state combinations depending on what primitive you select. If nothing is selected, the icon is grayed out. If you select a cylinder, the icon is still grayed out and unselectable but the background changes to make clear it's checked. A cube will show both the checked and active states, and some other object will show only the active state.
To be fair, the standard default script in R20 mentions False explicitly though.
RE: Plane by Python Generator
Just food for thought:
I once had the same desire to create landscapes in optimum resolution, but I came to realize that it is necessary to create a dynamic subdivision that reserves the higher resolutions for spots close to the camera. The numbers just accumulate too fast:
Subdivision of 15 means
2^15 = 32768 segments in either direction, which amounts to
32768^2 = 1,073,741,824 polygons (one gigapoly ).
Almost the same number of points is needed to define these polygons
(strictly one row and one line more, so 32769^2 = 1,073,807,361).
Each point is a vector from three floats, which is eight bytes each, resulting in a payload of roundabout 8GB for storing the points alone. Each polygon refers to four points which requires an index of four bytes at least (too lazy to look up the type now), which is another 16GB.
Thus, your plane has a memory footprint of 24GB for (2^15)^2 segments (for 2^17 it's 16 times more, or 384GB). A well equipped machine may still be able to work with that, but it's not practical, and causes inavoidable lags and most likely swapping. Not having a special datatype underlying, C4D may need to copy that data for rendering, too...