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. kvb
    3. Topics
    K
    • Profile
    • Following 0
    • Followers 0
    • Topics 5
    • Posts 19
    • Best 0
    • Controversial 0
    • Groups 0

    Topics created by kvb

    • K

      GeDialog Timer Always Printing to Console?

      Cinema 4D SDK
      • s26 2023 python • • kvb
      2
      0
      Votes
      2
      Posts
      292
      Views

      K

      Well, that was a fast solution... couldn't it have emerged BEFORE I hit submit?!? Haha, the solution was easy... I was returning True on the Timer function. Took a look at the python memory viewer example and noticed they don't return a value on it. Removed the return from my Timer() function and all is working as expected.

      def Timer(self, msg): print("Timer")

      That's it:)

    • K

      Vertex Maps on Generators

      Cinema 4D SDK
      • r23 python • • kvb
      5
      0
      Votes
      5
      Posts
      1.0k
      Views

      K

      Apologies, I thought my mention of the Voronoi Fracture's ability to generate vertex map tags (itself being a generator that deals with variable geometry) would be clear enough, but I suppose a casual mention doesn't suffice for an app this complex, haha!

      Yeah, it's really all about overcoming that immutable nature of the vertex map tag. I'm generating them on parametric objects and I need them to be able to adapt to changing point counts. Just like they're able to do on editable polygon objects. Which means I have to create a new tag each time the host object's geometry changes and update anywhere else it's linked. That's where TransferGoal() comes in.

      Where my function was failing was a result of TransferGoal() not only updating the BaseLinks, but also the variables within my code. So in my function, once TransferGoal()is called, both vmap and replacement_tag variables end up referencing the same tag (the new one), leaving me without a variable filled with the old tag to delete.

      Passing True as the second argument left my variables alone and only updated the links, essentially making it work perfectly. So passing True or False to TransferGoal() didn't make any difference as far as the BaseLinks were concerned. Those always updated correctly. If I had to guess I would say it has to do with the memory addresses of the objects being transferred... which is just more reason to avoid ignoring that little instruction in the sdk;) I'll trust the devs on matters of memory handling lol.

      Turns out it's quite easy to work around. Since I insert the new tag directly after the old tag I can simply use GetPred() to find the old tag and successfully delete it.

      As far as your question as to whether I would consider this desirable or expected behavior, I would say no. I would much prefer that my in-code variables remain as they were before calling TransferGoal, because as it currently is I'm left with two distinct variables that hold the same object. In other words, I'm left with redundancy and it ends up preventing me from doing more to the old BaseList2D object. In my case, it happens to be relatively easy to re-find and re-reference that BaseList2D object, but that might not always be the case.

      But yeah, now I have a working skeleton function (that doesn't break the rules lol). Just gotta bulk it up with appropriate checks and I should be good to go!

      Thanks for your help @zipit!

      Cheers!
      Kevin

    • K

      MoData.GetData()?

      Cinema 4D SDK
      • python • • kvb
      11
      0
      Votes
      11
      Posts
      1.6k
      Views

      K

      Oh, man... I thought I hit reply on this days ago! Sorry!

      So, MoData tag container didn't work, that's not where the MoData is stored. Well, there seems to be MoData there, just always empty... but I think that's because the mograph stuff uses the messaging system so heavily that just grabbing a basecontainer doesn't cut it.

      @zipit said in MoData.GetData()?:

      Hi,

      I was a bit overworked when I wrote this test, which is why I did made a little booboo in the code above with rather dire consequences. I have fixed this now and the timings are now correct (aside from the general diceyness of the whole test). But the general consensus is the same. BaseContainer is not slow and a good choice when we need key, value pairs. One should also keep in mind, that I did employ simplifications for list both in the insert and delete case, if we want to truly delete and insert arbitrary elements from/to a list, this type is terrible, as it has to rebuild all data each time.

      Cheers,
      zipit

      Thanks for revising this. Even if the basecontainer times technically look worse by comparison, in context I can still see it's no slouch! I've moved forward with this approach and so far I'm getting great performance with breaking down and stashing away the array's data into basecontainers. Still wondering if it wouldn't be better to go with a Read/Write/CopyTo implementation, but I honestly don't see a need here. It's plenty fast enough and doesn't even need to be accessed often.

      @m_magalhaes said in MoData.GetData()?:

      hi,

      it's a bit hard to tell as i still don't understood what you were trying to achieve.
      Do you want to save the mograph data and use them in c4d as a kind of library, or do you want to export them to a 3rd Party software ?

      Cheers,
      Manuel

      I need mograph cache tag functionality without the mograph cache tag. So I need to store MoData and be able to have it persist through file saves/loads, copying to a new document/rendering, duplication, etc. Given the potential size of the data in question (especially once you add animation into the mix) I want to make sure I'm doing this in the most efficient manner possible.
      Given that all the datatypes that contain the MoData aren't directly supported by the normal storage methods in c4d (basecontainers and hyperfiles), I was concerned that breaking all the data into its individual components to store it away wouldn't be efficient. I'm seeing now that I had little to be concerned about. Performance is great so far!

      I think I've even cleared my final hurdle, which was creating an array of MoDatas. My problem there was trying to use a BaseArray when what I needed was a PointerArray. Since PointerArray's take ownership of the pointed object, freeing the allocated MoDatas is as clean and simple as calling Reset() on the Pointer Array:) Injecting my MoData into the effector pipeline is equally simple by doing a CopyTo() or MergeData()... currently I'm doing that in ModifyPoints, but maybe I should be doing it in InitPoints? I'll figure that part out, but right now I'm just happy to have it all working!

      Thank you again zipit and Manuel!

    • K

      Identify Critical Stop Please?

      Cinema 4D SDK
      • python r21 • • kvb
      6
      0
      Votes
      6
      Posts
      1.2k
      Views

      K

      @m_magalhaes said in Identify Critical Stop Please?:

      hello,

      For your next threads, please help us keeping things organised and clean. I know it's not your priority but it really simplify our work here.

      Q&A New Functionality.

      About the error it's related to FileName. But we need more information to help more.
      Be careful about the other thread, it may happen that we add stuff and the line will not refer to the correct DataType anymore.

      Cheers,
      Manuel

      Dammit! No wonder my code keeps breaking... I can't even follow simple forum instructions lol! But hey, at least I got it down to one link. Haha, progress!

      Yes, Filename, that actually makes perfect sense, so I'm pretty confident I've conquered this error. You're right that I shouldn't rely too strongly on those line numbers. Hell, the next bug fix could make that info obsolete, let alone a reference from years ago. But sometimes you can glean value from outdated info. Maybe in the future line 277 doesn't refer to Filename, but if that error pops up and all my Filename calls look to be in good order I might be able to make some guesses that increase my luck in identifying the issue faster. For instance, I might look at string or static text parameters first, thinking that like datatypes may have been grouped together in the source code. If 329 doesn't refer to baselink in the future I might start looking at in/exclude boxes or shader links first for the same reason. Maybe the list of datatypes in the description manual in the sdk is ordered how they are in ge_container.h and I can use that to choose my next lead. Shot in the dark type stuff, for sure, but maybe gets me generally in the right direction.

      You know what, this may have to do with me tracking down a weird behavior where Init() seemed to be the cause of every parameter invoking a MSG_DESCRIPTION_POSTSETPARAMETER message on any parameter change... but I have both debugging AND pandemic fog on my brain, so I don't even know exactly which thing I was doing wrong that may have been the culprit, so there's no point getting into all that... doesn't help that a VS Code update seems to like breaking my local git repo's randomly, so that makes reviewing previous code fun. In any case, the error hasn't popped up at all after ensuring all my base container calls were proper and there were no missing parameter initializations. Not that it was a readily reproduce-able error, just one that would pop up sometimes after a heavy testing session... so I had to do a lot of those to ensure it's really gone.

      But it does raise a question. Since the Filename object doesn't exist in python, what's the best way to initialize it? Docs say it's a string, but I saw something in a forum post that someone was initializing their filename parameter directly through the base container. I figured this had to do with how the python wrapper is internally converting the path to Filename object or something, so that's what I've been doing, but that WAS from 2013. So which is the proper way to initialize it?

      self.InitAttr(node, str, c4d.ID_FILENAME_PARAMETER)

      or

      data.SetFilename(c4d.ID_FILENAME_PARAMETER, "")

      And even if it's the former, do I set its default value through the basecontainer or in the normal way like so:

      node[c4d.ID_FILENAME_PARAMETER] = ""

      @r_gigante said in Identify Critical Stop Please?:

      Hi @kvb, with regard to the scope and purpose of the CriticalStop I warmly recommend you to have a look at:

      FAQ CriticalStop() Debug and Output Functions

      These pages properly explain how the CriticalStop is used in Cinema 4D, how it can be used in plugins and what to expect when it's hit.

      In you case, as already pointed out by @m_magalhaes , it's likely you're using a GeData::GetFilename() with a GeData whose type was not a Filename. Please recheck your code and if you don't spot the issue, provide us with an example or snippet to reproduce it.

      Cheers, R

      Thanks for the links. They'll come in handy on my next project, which will be in c++ (and I will be abusing the hell out of all the debugging options!).

      Could it have been caused by the filename returning None? Is that even a thing or just something I noticed while I was missing any initialization on my Filename parameter? I can't see it being anything else... unless an empty string could trigger that error?

      Thanks all!
      Kevin

    • K

      Generators, Materials, Undo's, Oh My!

      Cinema 4D SDK
      • python • • kvb
      12
      0
      Votes
      12
      Posts
      1.5k
      Views

      ManuelM

      the whole thread is the answer anyway 🙂