• Weird Bug on Creating FFD (1) Manually and (2) Script

    r21 python
    3
    0 Votes
    3 Posts
    404 Views
    B
    @m_adam Thanks for the response. #1 option works as expected.
  • Copy, Paste, Flip X a Pose Morph Target?

    r21 python
    12
    0 Votes
    12 Posts
    3k Views
    B
    @m_magalhaes @zipit I managed to flip the mesh (not necessarily a pose morph target since I'd have to know the API). Anyhow, here is a demo of it working: https://www.dropbox.com/s/bh4p26s4m9qwljw/c4d272_flip_miror_mesh.mp4?dl=0 Here is wip script. It only works if the x-axis is dead set on 0. Also, it is slow since it has to loop within a loop. import c4d from c4d import gui # Main function def main(): neutral_geo = doc.SearchObject('neutral_geo') posed_geo = doc.SearchObject('posed_geo') neutral_world_matrix = neutral_geo.GetMg() posed_world_matrix = posed_geo.GetMg() neut_lcl_pnts = neutral_geo.GetAllPoints() neut_gbl_pnts = [point * neutral_world_matrix for point in neut_lcl_pnts] posed_lcl_pnts = posed_geo.GetAllPoints() posed_gbl_pnts = [point * posed_world_matrix for point in posed_lcl_pnts] match_pnts = [] left_pnts = [] right_pnts = [] for idx, point in enumerate(neut_gbl_pnts): if point[0] == 0.0: # ignore points at the world x axis continue if point[0] > 0.0: left_pnts.append((idx,point)) if point[0] < 0.0: right_pnts.append((idx,point)) for left in left_pnts: for right in right_pnts: if left[1][1] == right[1][1]: # check if Y pos match if left[1][2] == right[1][2]: # check if Z pos match if left[1][0] == -1 * (right[1][0]):# check if X pos are inverse match_pnts.append((left[0],right[0])) for pnt in match_pnts: reversed_left = posed_lcl_pnts[pnt[1]] reversed_left[0] = reversed_left[0] * -1 reversed_right = posed_lcl_pnts[pnt[0]] reversed_right[0] = reversed_right[0] * -1 posed_geo.SetPoint(pnt[0], reversed_left) posed_geo.SetPoint(pnt[1], reversed_right) posed_geo.Message(c4d.MSG_UPDATE) c4d.EventAdd() # Execute main() if __name__=='__main__': main()
  • GetRad() and GetMp() for Selected Points?

    r21 python
    3
    0 Votes
    3 Posts
    380 Views
    B
    @zipit Thanks for the response. I was able to compute the bounding box as you mentioned. I went with the #2 route. Though I have problem with creating the FFD deformer, but that would be for another thread.
  • This topic is deleted!

    1
    2
    0 Votes
    1 Posts
    3 Views
    No one has replied
  • Shader plugin & object

    7
    0 Votes
    7 Posts
    1k Views
    Y
    I have time and you have my attention sir Manuel! I'm looking forward for this I think adding this feature to C4D will be a good improvement... at least, for those who are interested in. Thank you again
  • Unable to update Alembic path in xref

    6
    0 Votes
    6 Posts
    1k Views
    M
    I know, it's not what you expected but there is for the moment no way to automate this using Cinema 4D API. Cheers, Maxime.
  • Splinefield radius reset to 0 when using takes

    r20 r21
    3
    0 Votes
    3 Posts
    538 Views
    M
    Hi @pyr I don't think there is anything related to the SDK and its a Cinema 4D bug so I invite you to post it on https://support.maxon.net/open.php On the contrary, if you experience this bug only via a script please post your script here so we can help you. Cheers, Maxime.
  • Check if the object parameters has been changed

    python
    6
    0 Votes
    6 Posts
    1k Views
    mfersaouiM
    Hi, Thank you @r_gigante, @zipit for your replies. The problem comes from the GetDDescription funtion because I use some of dynamic parameters on my objects. It is for this reason that op.IsDirty(c4d.DIRTY_DATA) returning True when I Move, Scale, Zoom or Rotate the perspective view.
  • Unique name for object

    c++ python r20
    5
    0 Votes
    5 Posts
    908 Views
    C4DSC
    OK ... so I reinvented the wheel. # make unique tag name def makeUniqueTagName(theTag): if theTag != None: obj = theTag.GetObject() # get all names of the tags of same type usedNames = [] if obj != None: tag = obj.GetFirstTag() while tag != None: # skip the tag and # ignore tags of other types if tag != theTag and tag.IsInstanceOf(theTag.GetType()) == True: usedNames.append(tag.GetName()) tag = tag.GetNext() # If the name is already taken we will append a dot and number # and increment the number until a unique name is found. # Note that since we have created the tag we can assume that # the original name does not have a dot and number already. suffix = 0 uniqueName = theTag.GetName() while uniqueName in usedNames: suffix = suffix + 1 uniqueName = theTag.GetName() + '.' + str(suffix) theTag.SetName(uniqueName) return Maybe not the best nor cleanest code, but then again I am not used to code in Python. I am sure others might have a better solution, but this seems to work for what I need, so I am happy with how it turned out.
  • PointInRange details please

    r20 c++
    3
    0 Votes
    3 Posts
    399 Views
    C4DSC
    @m_magalhaes said in PointInRange details please: But as you can see, this is pretty easy to create your own function, there's nothing fancy True, and I did. I just wanted to bring this up, as the documentation was rather ambiguous.
  • Buggy GeDialog Local2Global and Local2Screen

    c++ r20 r21
    8
    1
    0 Votes
    8 Posts
    992 Views
    C4DSC
    @r_gigante Sorry Riccardo, I do not understand your reply. I had tried with empty as well as non-empty dialogs. Both as DLG_TYPE::ASYNC and DLG_TYPE::ASYNC_POPUPEDIT. Still with these 4 combinations I do not get appropriate values for the global position. Bool MyDialog::CreateLayout() { Bool res = GeDialog::CreateLayout(); GroupBegin(0, BFH_SCALEFIT | BFV_SCALEFIT, 2, 0, ""_s, 0); AddButton(ACTION_1, BFH_CENTER | BFV_CENTER, 200, 10, "button A"_s); AddButton(ACTION_2, BFH_CENTER | BFV_CENTER, 300, 10, "button B"_s); AddEditText(ACTION_3, BFH_CENTER | BFV_CENTER, 500, 10); GroupEnd(); return res; } Bool MyCommand::Execute(BaseDocument* doc) { if (mDlg.IsOpen()) { mDlg.Close(); return true; } BaseContainer bc; if (GetInputState(BFM_INPUT_MOUSE, BFM_INPUT_MOUSELEFT, bc)) { const Int32 mx = bc.GetInt32(BFM_INPUT_X); const Int32 my = bc.GetInt32(BFM_INPUT_Y); const Int32 w = 50; const Int32 h = 50; mDlg.Open(DLG_TYPE::ASYNC /*ASYNC_POPUPEDIT*/, TEST_COMMAND_PLUGIN_ID, mx, my, w, h, 0); ApplicationOutput("Mouse cursor at @, @", mx, my); Int32 dlgX = 0; Int32 dlgY = 0; mDlg.Local2Screen(&dlgX, &dlgY); ApplicationOutput("Dialog created at @, @ (screen)", dlgX, dlgY); dlgX = 0; dlgY = 0; mDlg.Local2Global(&dlgX, &dlgY); ApplicationOutput("Dialog created at @, @ (global)", dlgX, dlgY); } return true; } Additionally, when activating the plugin when Cinema4D is fullscreen, the dialog gets positioned at the expected coordinates. But the position of the dialog is nowhere near the expected position if the plugin is activated when the Cinema4D window is not full screen. It seems as if the mouse coordinates relative to the application window are applied relative to the screen origin. Which means that if: 1 Cinema4D is not full screen 2 and offset from the top left corner of the screen by an amount X 3 assuming the mouse position is at coordinate mx from the Cinema4D's main window's top left corner The dialog ends up at mx from the screen's top left corner, instead of the expected X + mx. (All the above was tested with R20 only, since I have refrained from further R21 development) Unfortunately, I have moved on and am currently not focused on this particular plugin anymore. As such, I may have missed some details. I will need to find the time to pick up where I had left.
  • Rendering deformed Spline with Hair material

    c++
    19
    1 Votes
    19 Posts
    5k Views
    r_giganteR
    Hi @rsodre I'm sorry but I don't have any update on the bug resolution being it, as already stated, low-prio nor I can share bug-tracking information on a public forum. Best, R
  • Connecting Camera Focus Distance to Null Object with Python

    Moved python r21
    6
    1
    0 Votes
    6 Posts
    1k Views
    C
    @Cairyn Thanks for this fantastic resource, I will definitely use this summer to level up with Python.
  • Change parameter's unit type

    Moved python
    5
    0 Votes
    5 Posts
    864 Views
    bacaB
    @zipit thanks a lot, but based on c++ docs made this (seems there are just more checking): def GetDDescription(self, node, description, flags) : data = node.GetDataInstance() if data is None or not description.LoadDescription(node.GetType()): return False singleID = description.GetSingleDescID() paramID = c4d.DescID(c4d.DescLevel(c4d.TESTPLUGIN_OFFSET)) if ( singleID is None or paramID.IsPartOf(singleID)[0] ): bc = description.GetParameterI(paramID) if (bc): if data.GetLong(c4d.TESTPLUGIN_MODE) == TESTPLUGIN_MODE_DISTANCE: bc.SetLong(c4d.DESC_UNIT, c4d.DESC_UNIT_METER) else: bc.SetLong(c4d.DESC_UNIT, c4d.DESC_UNIT_PERCENT) return (True, flags | c4d.DESCFLAGS_DESC_LOADED)
  • Drawing Multiple Lines from TagPlugin

    s22 python sdk
    3
    1
    0 Votes
    3 Posts
    344 Views
    ?
    @zipit Hahahahaha! Thank you! I see my lines now. Who hoo!
  • BaseDraw in TagDataPlugin

    s22 python sdk
    3
    0 Votes
    3 Posts
    387 Views
    ?
    @m_adam My apologies for not being clearer. I thought there was something wrong with how I was doing the Draw function. The issue was the TAG_IMPLEMENTS_DRAW_FUNCTION flag was missing. Thank you very much!
  • Getting a list of objects at a given hierarchy

    2
    0 Votes
    2 Posts
    494 Views
    M
    Hi @nicholas_yue there is nothing builtin but the most optimized way I think will be import c4d def GetNodeListsAtCurrentLevel(bl2D): parent = bl2D.GetUp() if parent is None: parent = bl2D.GetListHead() return parent.GetChildren() def main(): print GetNodeListsAtCurrentLevel(doc.GetActiveTag()) # Execute main() if __name__=='__main__': main() Cheers, Maxime.
  • Render filtered Hardware Preview

    s22 classic api python
    10
    0 Votes
    10 Posts
    2k Views
    a_blockA
    Thanks for validating my assumptions. Much appreciated. Yes, I already have multiple code branches and for S22 my workaround looks as described. Because it doesn't hurt to insert the RenderData in this case, it doesn't even need multiple branches. Thanks for looking into it, Maxime. Is this going to be fixed in a future version?
  • CCurve.GetValue() with Track Before & After Functions

    python s22 sdk
    3
    1
    0 Votes
    3 Posts
    458 Views
    ?
    @m_magalhaes Remap did the trick! Thanks for the help, Manuel
  • How is NBIT_CKEY_ACTIVE used?

    python s22 sdk
    3
    0 Votes
    3 Posts
    270 Views
    ?
    @r_gigante Ahhhhhhhh, okay, I get it now. Thank you