• Creating Xpresso Python Node Inputs

    Cinema 4D SDK s22 sdk python
    6
    1
    0 Votes
    6 Posts
    1k Views
    ?
    @m_adam That's a great solution, thank you!
  • 1 Votes
    3 Posts
    365 Views
    CairynC
    @m_magalhaes thanks, that'll do!
  • Parent Behavior on a "Script" Form

    Cinema 4D SDK 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!
  • 0 Votes
    4 Posts
    1k Views
    dskeithbuckD
    Thank you @zipit and @m_magalhaes for your replies! @zipit your response put me on the right track. The issue was that I was trying to do all of the conversions using C4D's left-handed coordinate matrices, and it was auto-fixing my "malformed" matrices. I ended up porting the Three.js Matrix4 and Euler classes from JS to python and using them in my script. So, the final code (leaving out the ported methods) looked something like: mg = self.op.GetMg() parent_mg = self.op.GetUpMg() c4d_to_three = c4d.Matrix( off=c4d.Vector(0), v1=c4d.Vector(1, 0, 0), v2=c4d.Vector(0, 1, 0), v3=c4d.Vector(0, 0, -1) ) # Convert to new coordinate space # http://www.techart3d.com/2016/02/convert-left-handed-to-right-handed-coordinates/ mg_three_coords = c4d_to_three * mg * c4d_to_three parent_mg_three_coords = c4d_to_three * parent_mg * c4d_to_three mg_mat4 = Matrix4(mg_three_coords) parent_mg_mat4 = Matrix4(parent_mg_three_coords) inv_parent_mg_mat4 = parent_mg_mat4.Clone() inv_parent_mg_mat4 = inv_parent_mg_mat4.Inverse() node_local = inv_parent_mg_mat4.Clone() node_local = node_local.MultiplyMatrices(inv_parent_mg_mat4, mg_mat4) position, scale, rotation = node_local.Decompose() if position != c4d.Vector(0): self.props["position"] = position if scale != c4d.Vector(1): self.props["scale"] = scale if rotation != c4d.Vector(0): self.props["rotation"] = rotation
  • Stuck with loop through tags

    General Talk python
    4
    0 Votes
    4 Posts
    852 Views
    ManuelM
    hi @SuperHomiak welcome to the forum. Thanks @zipit for the answer 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. How to Post Questions especially the tagging part. I've set the thread to a question and marked zipit answer as the right answer Cheers, Manuel
  • Add Custom Command in the Content Browser?

    Cinema 4D SDK r21 python
    3
    0 Votes
    3 Posts
    363 Views
    B
    @m_adam Thanks for the confirmation. Will close this for now.
  • 0 Votes
    5 Posts
    698 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!
  • Setting the FontData for a Text Object

    Cinema 4D SDK s22 python sdk
    2
    0 Votes
    2 Posts
    391 Views
    ?
    For whatever reason, the default Text Object has no FontData in Text[c4d.PRIM_TEXT_FONT]. By creating a FontData instance, I was able to set the Font. import c4d def main(doc): textObject = c4d.BaseObject(c4d.Osplinetext) doc.InsertObject(textObject) fontData = c4d.FontData() bc = c4d.BaseContainer() bc.SetString(500, 'Arial') bc.SetString(501, '11') bc.SetInt32(502, 400) bc.SetInt32(503, 0) bc.SetString(509, 'Arial') bc.SetString(508, 'ArialMT') fontData.SetFont(bc) textObject[c4d.PRIM_TEXT_FONT] = fontData textObject[c4d.ID_BASELIST_NAME] = bc[500] textObject[c4d.PRIM_TEXT_TEXT] = bc[500] c4d.EventAdd() if __name__=='__main__': main(doc)
  • MoData.GetData()?

    Cinema 4D SDK 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!
  • 2 Votes
    9 Posts
    987 Views
    M
    This is fixed in R23. Cheers, Maxime.
  • Make clean-up after script

    Cinema 4D SDK python
    3
    0 Votes
    3 Posts
    643 Views
    r_giganteR
    Hi @iluxa7k thanks for reaching out us. With regard to your question, as already pointed out by @zipit , the Python del statement just is only responsible for decrementing the reference counter for the instance being "deleted" and not to actually free the memory used by the instance itself. This is clearly noted in the official Python documentation on the Note coming along with object.__del__(self) in Python 3 or object.__del__(self) in Python 2 . Given that, also consider that the del app statement you've described in your first post might not actually deliver the "clean-up" action you're thinking about. Best, Riccardo
  • Rotating Spline Points

    Cinema 4D SDK s22 python sdk
    8
    0 Votes
    8 Posts
    2k Views
    ?
    @nophoto Very nice! Thank you
  • 0 Votes
    4 Posts
    892 Views
    ManuelM
    hi, i'll set that thread to solved tomorrow without further feedback Cheers, Manuel
  • 0 Votes
    9 Posts
    1k Views
    B
    @m_magalhaes Thanks for the response. The confusion is entirely mine. I was confused because I initially thought the GetName and SetName is only for typical C4D objects. but there is actually a separate GetName and SetName functions for the TreeView objects. I was able to retrieve the new string by just this code: def SetName(self,root, userdata, obj, name): print name # new name when you hit enter I can now use the name variable to use in my separate renaming function (i.e. rename a folder for which the TreeView was based on). Thanks!
  • 0 Votes
    3 Posts
    368 Views
    B
    @m_magalhaes Thanks! It works as expected
  • TreeViewFunctions, two LV_USER fields

    Cinema 4D SDK r20 python
    8
    1
    0 Votes
    8 Posts
    960 Views
    P
    Thanks, it is working.
  • update User Data with Preset info

    Moved Cinema 4D SDK python
    5
    0 Votes
    5 Posts
    933 Views
    ferdinandF
    Hi, you cannot, because the data container of a BaseList2D is not dynamically typed (like Python itself), but bound to data types specified in its description. If you want to change the data type of an user data element, you will have to modify the description of that element via GetUserDataContainer and SetUserDataContainer. There is also no 2D-Vector type in Cinema, only the crosshair thing custom GUI which you can apply to a Vector description element. Cheers, zipit
  • Setting up ObjectData plugin priority in Python

    Cinema 4D SDK python sdk
    3
    0 Votes
    3 Posts
    610 Views
    M
    Hi @Eduardo-Oliveira first of all welcome on the PluginCafe community. I think @zipit already provided you some correct answers or at least point you that this workflow is kind of strange for a Cinema 4D user since normally the object by itself doesn't really set its own position, but it's up to a tag (constraint Tag) to define the object position to another one. But in case you really want to do it, doing it in the Execute method of your ObjectData is fine. def AddToExecution(self, op, list): list.Add(op, c4d.EXECUTIONPRIORITY_GENERATOR, c4d.EXECUTIONFLAGS_CACHEBUILDING) return True def Execute(self, op, doc, bt, priority, flags): op.SetMg(doc.GetFirstObject().GetMg()) return c4d.EXECUTIONRESULT_OK You also need to ensure you registered your object with the flag c4d.OBJECT_CALL_ADDEXECUTION so AddToExecution and Execute are called. Cheers, Maxime.
  • Implement A Rudimentary Licensing Solution?

    Cinema 4D SDK r21 python
    13
    0 Votes
    13 Posts
    1k Views
    B
    Thanks will close the thread for now.