@zipit Hahahahaha! Thank you! I see my lines now. Who hoo!
Posts made by blastframe
Drawing Multiple Lines from TagPlugin
I have a follow-up question regarding drawing from a Tag. why is this code only drawing one line? I am calling DrawLine2D four times in this example.
def Draw(self, tag, op, bd, bh): bd.SetPen(c4d.Vector(1, 0.7, 0)) bd.SetMatrix_Screen() p1 = c4d.Vector(0,0,0) p2 = c4d.Vector(100,100,100) p3 = c4d.Vector(500,500,500) p4 = c4d.Vector(300,300,300) bd.DrawLine2D(p1, p2) bd.DrawLine2D(p2, p3) bd.DrawLine2D(p3, p4) bd.DrawLine2D(p4, p1) return c4d.DRAWRESULT_OK
BaseDraw in TagDataPlugin
I'd like to draw a 2D line over the Viewport from a TagDataPlugin while the tag is Enabled. This is my Drawing function below. It worked as an ObjectData plugin when I called it with
DRAWPASS_OBJECT, but I'm not sure how to get this working as a Tag. Can anyone advise me on this? Thank you!
class BaseDrawTest(c4d.plugins.TagData): def __init__(self, *args): super(BaseDrawTest, self).__init__(*args) def Draw(self, tag, op, bd, bh): bd.SetPen(c4d.Vector(1, 0.7, 0)) v1 = c4d.Vector(0.0,0.0,0.0) v2 = c4d.Vector(1000.0,1000.0,1000.0) bd.SetMatrix_Screen() bd.DrawLine2D(v1, v2)
RE: CCurve.GetValue() with Track Before & After Functions
Remapdid the trick! Thanks for the help, Manuel
CCurve.GetValue() with Track Before & After Functions
CCurve.GetValue(), but it only seems to work when there is an actual curve, not when there is a Track Before or After Function. Is there a way to get the value of the attribute with
CCurve.GetValue()when using these functions?
How is NBIT_CKEY_ACTIVE used?
How does one use
NBIT_CKEY_ACTIVE? I see in the documentation that it's the "Active point of animation path in editor." I couldn't find any examples that use it successfully however. I found it used in this old post on CGSociety by Per-Anders from 2013, but I couldn't get it to work. Here's the code I'm using to test it:
import c4d def main(): tracks = op.GetCTracks() for track in tracks: print "*"*100 print track.GetName() curve = track.GetCurve() count = curve.GetKeyCount() for x in range(0,count): key = curve.GetKey(x) print "Key %s: NBIT_CKEY_ACTIVE: %s"%(x,key.GetNBit(c4d.NBIT_CKEY_ACTIVE)) if __name__=='__main__': main()
Get Active Timeline Request
I've been trying to develop tools for the Timeline and would like to determine if a key is selected in an F-Curve timeline. It appears that this is very difficult because there is no method for determining the active Timeline. Unless this exists and I'm unaware, I'd like to request this for the SDK please as I believe it would be very helpful for Animation Timeline plugins.
This is an issue originally brought up in this post.
How to Get the Selected Keyframes in Active Timeline/FCurve Manager
RE: Sizing Plugin Dialogs
Hi @r_gigante, thank you for the reply!
With regards to the
DLG_TYPE_ASYNC, the GeDialog size has not always worked consistently for me. Is Cinema 4D storing information for when the Async GeDialogs have been resized? If so, is there a way to clear this preference? Thanks!
RE: Sizing Plugin Dialogs
I'm thinking that the Main Dialog cannot be resized as it is
DLG_TYPE_ASYNC. The secondary Dialog is taking the width from the last dragged dimensions of the Main Dialog.
I'm not sure if this is correct, but I was able to get the dimensions I needed for the secondary GeDialog by giving it a unique PLUGIN_ID and removing the subid (code below).
self.anotherDialog.Open(c4d.DLG_TYPE_MODAL, pluginid=ANOTHER_DLG_ID, xpos=-2, ypos=-2, defaultw=600, defaulth=450)
Do I need to create a unique PLUGIN_ID for every GeDialog or is there another way?
Sizing Plugin Dialogs
In a previous post, How to open a GeDialog Modal to default width & height? the solution to the
defaulthbug for a script Modal was to pass the
pluginid. I am trying this solution with a Command Plugin and I'm not getting the specified sizes for either window. I thought maybe it has to do with the
subidbut my Main Dialog isn't behaving either.
Here is some test code I'm using:
import c4d from c4d import documents, gui, plugins PLUGIN_ID = 1055306 #test id ANOTHER_DLG_ID = 5000 class AnotherDlg(gui.GeDialog): MY_TEXT = 1000 def CreateLayout(self): self.SetTitle("Another Dialogue") self.AddStaticText(self.MY_TEXT, c4d.BFH_CENTER | c4d.BFH_SCALE, name="Another Dialog",inith=40) return True class MyDlg(gui.GeDialog): MY_BUTTON = 1000 def __init__(self): global anotherDialog self.anotherDialog = AnotherDlg() def CreateLayout(self): self.SetTitle("Test") self.AddButton(self.MY_BUTTON, c4d.BFH_CENTER | c4d.BFH_SCALE | c4d.BFV_CENTER | c4d.BFV_SCALE, initw=0, inith=0, name="Open Dialog") return True def Command(self, id, msg): if id == self.MY_BUTTON: self.anotherDialog.Open(c4d.DLG_TYPE_MODAL, pluginid=PLUGIN_ID, subid=ANOTHER_DLG_ID, xpos=-2, ypos=-2, defaultw=600, defaulth=150) return True def Restore(self, pluginid, secref): if secref['subid'] == ANOTHER_DLG_ID: return self.anotherDialog.Restore(pluginid, secref) else: return super(MyDlg, self).Restore(pluginid, secref) class MyData(c4d.plugins.CommandData): dialog = None def Execute(self, doc): if self.dialog is None: self.dialog = MyDlg() global myDlg myDlg = self.dialog return myDlg.Open(dlgtype=c4d.DLG_TYPE_ASYNC, xpos=-2, ypos=-2, pluginid=PLUGIN_ID, defaultw=700, defaulth=300) def RestoreLayout(self, sec_ref): if self.dialog is None: self.dialog = MyDlg() global myDlg myDlg = self.dialog return myDlg.Restore(pluginid=PLUGIN_ID, secref=sec_ref) if __name__ == "__main__": plugins.RegisterCommandPlugin(id=PLUGIN_ID, str="Test", info=0, help="Test", dat=MyData(), icon=None)
Here are the results:
The Main Dialog (
DLG_TYPE_ASYNC) is 324x51 and the secondary dialog (
DLG_TYPE_MODAL) is 324x100. This is making layout difficult.
Can anyone please help me to get these to open to the specified sizes? Thank you!
RE: Message when leaving an Edit Text
@C4DS This solution works for me! Unless someone from the SDK team advises against for some reason, I'll mark yours as the correct answer. Here's a Python version of your code:
import c4d from c4d import gui PLUGIN_ID = 9999996 #Test ID class My_Dlg(gui.GeDialog): mActiveEdit1 = False mActiveEdit2 = False ID_TEXTEDIT1 = 1001 ID_TEXTEDIT2 = 1002 def CreateLayout(self): self.SetTitle("Edit Text Focus Events") if self.GroupBegin(1000, c4d.BFH_SCALEFIT | c4d.BFV_SCALE |\ c4d.BFV_CENTER, initw=0, inith=0, cols=1, rows=1, title=""): self.GroupBorderSpace(20, 20, 20, 20) #left, top, right, bottom self.AddEditText(self.ID_TEXTEDIT1, c4d.BFH_SCALEFIT, 90, 0) self.AddEditText(self.ID_TEXTEDIT2, c4d.BFH_SCALEFIT, 90, 0) self.GroupEnd() return True def ActivateEditText(self,id,active): activeBool = getattr(self,active) if self.IsActive(id) and not activeBool: print("Activate TextEdit: %s"%id) setattr(self,active,True) elif not self.IsActive(id) and activeBool: print("TextEdit %s was active"%id) setattr(self,active,False) def Message(self, msg, result): self.ActivateEditText(self.ID_TEXTEDIT1,"mActiveEdit1") self.ActivateEditText(self.ID_TEXTEDIT2,"mActiveEdit2") return c4d.gui.GeDialog.Message(self, msg, result) def Command(self, id, msg): return True def main(): global myDlg myDlg = My_Dlg() myDlg.Open(dlgtype=c4d.DLG_TYPE_ASYNC, xpos=-2, ypos=-2,\ pluginid=PLUGIN_ID, defaultw=300, defaulth=200) if __name__=='__main__': main()
Message when leaving an Edit Text
onfocusouttriggered when the user has left an editable text input.
Similarly, I want to execute a function when the user leaves the EditText (by Tab or mouse) of my GeDialog. I thought maybe I could listen for the message with the ID of
c4d.BFM_LOSTFOCUS, but that seems to be when the entire GeDialog loses focus (similar to
c4d.BFM_ACTIVE_CHG). I also tried
c4d.BFM_INTERACTENDbut that happens after every input, including keystrokes. How can I listen for when a user leaves an EditText please? Thank you!
ids = [c4d.BFM_MARKFOCUS,c4d.BFM_ACTIVE_CHG,c4d.BFM_SETFOCUS,c4d.BFM_INTERACTEND,\ c4d.BFM_ACTION,c4d.BFM_LOSTFOCUS] def Message(self, msg, result): if msg.GetId() in self.ids: for cid,val in msg: print cid,val return c4d.gui.GeDialog.Message(self, msg, result)
RE: Creating Xpresso Python Node Inputs
For future people reading this post, I found answers in the C++ documentation for the GV_PYTHON_OPENEDITOR file reference.
''' In this DescID: c4d.DescID(c4d.DescLevel(3999,400006001,1022471)) 3999 is the ID for the parameter (GV_PYTHON_ON) 400006001 is the ID for the Data type (ID_GV_DATA_TYPE_BOOL) 1022471 is the Python Tag Id ''' onId = c4d.DescID(c4d.DescLevel(c4d.GV_PYTHON_ON,c4d.ID_GV_DATA_TYPE_BOOL,1022471)) longId = c4d.DescID(c4d.DescLevel(c4d.IN_LONG,c4d.ID_GV_DATA_TYPE_INTEGER,1022471)) linkId = c4d.DescID(c4d.DescLevel(c4d.IN_LINK,c4d.DTYPE_BASELISTLINK,1022471)) xnode_python.AddPort(c4d.GV_PORT_INPUT, onId) xnode_python.AddPort(c4d.GV_PORT_INPUT, longId) xnode_python.AddPort(c4d.GV_PORT_INPUT, linkId)
I do still have questions about how I'd find the DescIDs of this node's parameters through Python if anyone wants to chime in. Thank you.
RE: Creating Xpresso Python Node Inputs
onId = c4d.DescID(c4d.DescLevel(3999,400006001,1022471))
Hi @iluxa7k , thank you for the reply! May I please ask, how did you find this DescID? How can I find the other ports'?