• How to create a layer Reflection (Legacy) ?

    python
    2
    0 Votes
    2 Posts
    604 Views
    KantroninK
    I found the solution to my problem, on the internet, with code samples: https://www.c4dcafe.com/ipb/forums/topic/101805-materials-and-shaders-with-python/
  • Using Console Variable in the Script Manager?

    r21 python
    4
    0 Votes
    4 Posts
    409 Views
    B
    @m_magalhaes Thanks for the confirmation. Although what zipit provided also works for my use case (i.e. defining the variable from Document B but using that same variable in Document A) @zipit Thanks for the code. It works as expected
  • Python Render Token - no frame number?

    r21
    3
    0 Votes
    3 Posts
    475 Views
    CairynC
    @m_adam Thanks for the confirmation! (I swear I'm not doing this on purpose...)
  • Generating Splines from JSON Data

    6
    0 Votes
    6 Posts
    2k Views
    M
    Hi @wuzelwazel, I think @zipit already did a great job and answers your questions, Another point that may be important for you is to turn off the interpolation of the SplineObject via splineObject[c4d.SPLINEOBJECT_INTERPOLATION] = c4d.SPLINEOBJECT_INTERPOLATION_NONE. But except that I don't more to optimize on the C4D side. Cheers, Maxime.
  • Creating Xpresso Python Node Inputs

    s22 sdk python
    6
    1
    0 Votes
    6 Posts
    2k Views
    ?
    @m_adam That's a great solution, thank you!
  • Some confusing things about Python standard dialogs

    r21 s22 python
    3
    1 Votes
    3 Posts
    370 Views
    CairynC
    @m_magalhaes thanks, that'll do!
  • MoData.GetData()?

    python
    11
    0 Votes
    11 Posts
    2k 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!
  • Post Deformer Spline

    c++ r20 sdk
    7
    2
    0 Votes
    7 Posts
    1k Views
    D
    @m_magalhaes said in Post Deformer Spline: Thanks, Manuel! This is what I was looking for!
  • This topic is deleted!

    1
    1
    0 Votes
    1 Posts
    3 Views
    No one has replied
  • 0 Votes
    4 Posts
    780 Views
    M
    @m_adam Hi Maxime, thanks for your detailed reply. I had a feeling that EventAdd() performed an asynchronous operation (i.e., placed an event on the event queue) and therefore it didn't matter, since control of the main thread would not be relinquished until both EndUndo() were called (regardless of sequence). However, as C4DS and you yourself pointed out, it makes more sense to call EndUndo() prior to EventAdd(). This is not only true from a safety perspective, but the calls to StartUndo() and EndUndo() can be wrapped in a Python Context Manager, along exception handling and cleanup to be done automatically and correctly when a scope is exited. If one is going to undo whatever operation in case of an error, anyways (e.g., as part of said exception handling), it makes sense to call c4d.EventAdd() after we know that the entire action was successfully performed. I am going on the assumption that if my code performs some action inside of a StartUndo() / EndUndo() sequence, possibly consisting of multiple sub-actions and changes resulting in multiple AddUndo() calls, then sees mid-action that there is an and it cannot continue, and assuming the Start/End undo sequence is wrapped in a Python context manager class. Python will call EndUndo() on my behalf, as part of exiting the block governed by the context manager and then in the exception handler, I can perform an undo of the last action, undoing whatever sub-action did perform successfully (and added their AddUndo() pieces). Since this will hopefully leave everything in the same state that it was before the action was started, I am going to assume that there is no point in calling c4d.EventAdd() after the undo of the action is performed in my exception handler. To summarize, here is an example scenario: try: with MyUndoContextManager(doc) as undo_manager: # Calls StartUndo() as part of its Context Manager __enter__() method # undo_manager will make the calls to AddUndo() based on our actions DoSomethingAndCallAddUndoOnTheDoc(undo_manager); DoSomethingElseAndCallAddUndoOnTheDoc(undo_manager); DoOneLastThingAndCallAddUndoOnTheDoc(undo_manager); # Oh, oh, fails and throws exception # Note: EndUndo() will get called as part of the implicit call to MyUndoContextManager's __exit__() method # which will automatically get called when we exit this block due to the exception being thrown c4d.EventAdd(); # This code will not get reached due to exception being thrown above except: # An error occurred, get back to the initial state prior to the action # Undo whichever action sub-steps were performed successfully and AddUndo()s got called for, if any # Since the undo_manager object no longer exists, call DoUndo() on the doc object, directly doc.DoUndo() # Since, we reverted to the initial state before the action, there is no need to call c4d.EventAdd(), right?
  • Threading bitmaps

    c++
    2
    0 Votes
    2 Posts
    388 Views
    P
    Not sure if it helps, but there is an example of using ParallelImage() to write into a Bitmap in the documentation.
  • 0 Votes
    3 Posts
    439 Views
    CairynC
    I just answered this on CGSociety, as the thread was started there: https://forums.cgsociety.org/t/help-with-the-simple-but-advanced-rig-at-the-same-time-with-xpresso-or-python-i-am-talking-about-tank-belts/2058564/12
  • Parent Behavior on a "Script" Form

    r21 python
    8
    0 Votes
    8 Posts
    779 Views
    B
    @Cairyn Thanks for the confirmation. I'll just continue with the revised script until I find a bug (lol). RE: Ah. Don't the built-in mirror functions suffice? Not really. Correct me if I'm wrong, The built-in mirror tool 1) mirrors only the objects itself and not the mirror plane 2) when it mirrors, it creates additional copy. might be good when you are modelling and rigging, but not on animating. Again, thank you for the detailed responses. Appreciate it alot. Have a great day ahead!
  • Modifier dependencies

    c++ r19 r20 r21 s22
    6
    0 Votes
    6 Posts
    949 Views
    rsodreR
    Hi @m_magalhaes This was research for a feature I'll start implementing soon, and possible refactor. I'll mark as solved and if there's anything else I need I'll open it again. Thanks.
  • iterating on multiple Tmgselection tags

    2
    0 Votes
    2 Posts
    528 Views
    N
    Replying to my own question. We need to define it using mo.GeGetMoDataSelection(Tag) Code that works. import c4d from c4d.modules import mograph as mo def main(): Cloner = op.GetObject() md = mo.GeGetMoData(Cloner) AllTags = Cloner.GetTags() for Tag in AllTags: if Tag.GetType() == c4d.Tmgselection: print Tag SelTag = mo.GeGetMoDataSelection(Tag) #This is the new line print SelTag.GetCount()
  • Add Custom Command in the Content Browser?

    r21 python
    3
    0 Votes
    3 Posts
    363 Views
    B
    @m_adam Thanks for the confirmation. Will close this for now.
  • Written Description in the Documentation?

    c++ r21
    2
    0 Votes
    2 Posts
    260 Views
    r_giganteR
    Hi @bentraje , thanks for pointing it out. We'll get it filled by a future documentation release. Best, Riccardo
  • Copying All Compatible Properties from One Object to Another?

    python s22
    6
    0 Votes
    6 Posts
    1k Views
    dskeithD
    Realizing I never responded to this Thank you @m_magalhaes, @mikegold10, and @PluginStudent. I ended up manually making a list of the parameters I wanted to copy and iterating through all of them. Not ideal, but at least glad to know there wasn't an automated method I was missing.
  • How to properly update and reset deform cache.

    11
    0 Votes
    11 Posts
    2k Views
    M
    First of all, I'm sorry I simply forget your topic, so thanks for bumping it again. Regarding your question, I'm really not sure about what you want to achieve. So maybe try to explain what you want to achieve with simple step by step. Anyway, I will try to answers your question about how to retrieve the delta from a non-deformed geometry to a deformed geometry. Keep in mind that all points position retrieved by GetAllPoints() are local to the current object matrix, so doing a SetRelPos, on the object will most likely not affect the point position returned since it moves the whole object matrix. So here a quick example that properly retrieves the delta from a deformed object and its normal version. import c4d def main(): # Get the current world position allPtCurrentFrame = op.GetDeformCache().GetAllPoints() mgCurrentFrame = op.GetDeformCache().GetMg() # Move the mod +10 in Z in world position mod = doc.SearchObject('mod_1') modMat = mod.GetMg() modMat.off += c4d.Vector(0, 0, 10) mod.SetMg(modMat) # change the frame doc.SetTime(c4d.BaseTime(1, doc.GetFps())) buildflag = c4d.BUILDFLAGS_NONE if c4d.GetC4DVersion() > 20000 else c4d.BUILDFLAGS_0 doc.ExecutePasses(None, True, True, True, buildflag) # Get the next world position allPtNextFrame = op.GetDeformCache().GetAllPoints() mgNextFrame = op.GetDeformCache().GetMg() # Calculate the difference in both local space and global space diffLocalSpace = [allPtNextFrame[ptID] - x for ptID, x in enumerate(allPtCurrentFrame)] diffGlobalSpace = [(allPtNextFrame[ptID] * mgNextFrame) - (x * mgCurrentFrame) for ptID, x in enumerate(allPtCurrentFrame)] # For each axes create a Vertex map componentNames = ["x", "y", "z"] for componentId, componentName in enumerate(componentNames): # First find the maximum delta for the current component maxLocalSpace = 1 maxGlobalSpace = 1 for ptLocal in diffLocalSpace: maxLocalSpace = max(maxLocalSpace, ptLocal[componentId]) for ptGlobal in diffGlobalSpace: maxGlobalSpace = max(maxGlobalSpace, ptGlobal[componentId]) # Normalize all of them from 0 to 1 normalizedLocal = [pt[componentId] / float(maxLocalSpace) for pt in diffLocalSpace] normalizedGlobal = [pt[componentId] / float(maxGlobalSpace) for pt in diffGlobalSpace] # Create Tag for local vMapLocal = op.MakeVariableTag(c4d.Tvertexmap, op.GetPointCount()) op.InsertTag(vMapLocal) vMapLocal.SetName("{0}_local".format(componentName)) vMapLocal.SetAllHighlevelData(normalizedLocal) # Create Tag for Global vMapGlobal = op.MakeVariableTag(c4d.Tvertexmap, op.GetPointCount()) op.InsertTag(vMapGlobal) vMapGlobal.SetName("{0}_global".format(componentName)) vMapGlobal.SetAllHighlevelData(normalizedGlobal) c4d.EventAdd() # Execute main() if __name__=='__main__': main() Cheers, Maxime.
  • How to Communicate between SubDialog and main GeDialog

    s22 python sdk
    5
    0 Votes
    5 Posts
    702 Views
    ?
    @m_adam Hi Maxime, I did try your example and I saw it working as a gadget but, you're right, I want to communicate between two GeDialogs. I followed your advice on using CoreMessage and found success with SpecialEventAdd. Thank you!