• GUI shows M (meters) instead of CM (centimeters) in CUSTOMGUI_VECTOR

    c++
    4
    0 Votes
    4 Posts
    820 Views
    ferdinandF
    Hey, it seems I was a bit too tightlipped here. So in more verbose: You cannot customize the chosen unit of a parameter. This is impossible as this is a globally set value (which is also just smoke and mirrors as explained in the link above). There is a UnitScale custom GUI but it does not what you want, it is the field used in the document settings and is not really meant to store a value and unit but just a unit. [image: 1742223539308-cd7250f7-2ea2-4efe-be63-70e67e574078-image.png] When you really-really-really want this, you can implement you own custom GUI, either targeting your own custom data types or existing data types. There you could then do whatever you want. But that might not mesh so well with the rest of Cinema 4D, given that Cinema 4D does not operate like that. Cheers, Ferdinand
  • autocreate RS node material based texture sets in tex folder

    2025 python windows
    9
    0 Votes
    9 Posts
    1k Views
    A
    thanks @ferdinand this makes perfect sense now. I appreciate the time you took to explaint he best practice.
  • Start CUSTOMGUI_LINKBOX expanded

    c++
    2
    0 Votes
    2 Posts
    513 Views
    ferdinandF
    Hey @ECHekman, thank you for reaching out to us. This GUI does not support any of these flags (DESC_DEFAULT, i.e., DEFAULT is also not for gadgets but groups). This means that you cannot toggle the collapsed state of a link box (be it a normal one or a texture one) by setting a description flag either in a resource file or programmatically. Which makes sense, because other than for example a color field or a group, a link box is not guaranteed to have content which could be unfolded. Cheers, Ferdinand
  • 0 Votes
    2 Posts
    667 Views
    i_mazlovI
    Hi @BigRoy, Please check our Support Procedures in regards of the question structure, namely: Singular Question: The initial posting of a support topic must contain a singular question. Do not ask ten things at once, that makes it extremely hard to answer topics. Break up your questions into multiple topics. Asking follow-up questions is allowed but they must be bound to the initial subject. Singular Subject: From all this follows that a topic must have a singular and sparse subject tied to a specific problem. 'My Nodes API Questions' is not a valid topic as it splits up into too many subtopics. A valid subject could be 'accessing node attributes' or 'traversing a node graph'. One could for example first ask 'how to get the name attribute of a node?' and then ask a follow up question about 'how to get the icon attribute too?'. This specifically applies to plugins, just because you have two problems with one plugin does not mean that they should be asked in the same topic. Regarding you question, there's no high level API that allows you to get a list of all files you've mentioned at once. This effectively means that not only do you need to access this yourself, but you also need to do so for the render engines you'd like to support, as these are likely going to differ among them. Specifically for the Redshift AOVs and output files question, please check related threads: get the names of redshift multi passes AOV names from the render settings Add Expression Value in Render Settings Save Path As for the takes, the only application where they make any sense is the Render Queue. If you're not using it, it's only the active take that's being rendered. Of course you can deal with it by using SetCurrentTake function. I suggest you keeping this thread for the "render output files" part of your initial question and encourage you to make separate postings for your other questions that diverse from this topic here. Cheers, Ilia
  • 0 Votes
    5 Posts
    1k Views
    V
    @ferdinand You are correct, there was no further question, I was just closing the loop in case someone else ran into something similar. Thanks for the additional suggestions. -v
  • Efficient way of saving array to BaseContainer

    r21 2025 linux macos windows
    3
    0 Votes
    3 Posts
    784 Views
    B
    Thank you @ferdinand for the help! Write raw memory does help a lot, appreciate!
  • Changing OCIO View Transform doesn't work using Python

    python 2025
    4
    0 Votes
    4 Posts
    701 Views
    ferdinandF
    Hey @Smolak, I understood what you wanted to do, but it is still not possible. First of all, the OCIO color space enum values are dynamically assigned, i.e., the value 3 might not always mean the same space. In the OCIO API there are special conversion functions for that, but you could also do that manually by parsing the description of the document. But you will never be able to apply such value then, because to do that, you have to call BaseDocument::UpdateOcioColorSpaces which does not exist in Python (yet). See the C++ Docs for an example. Cheers, Ferdinand
  • Show or Hide Object in Viewport

    2024 python
    4
    1
    0 Votes
    4 Posts
    838 Views
    ferdinandF
    Sorry, I am rotating on the spot right now, did not yet get to answering here. @gheyret is right, there is still a bug, will give @m_adam a note on Monday.
  • update error?

    r20 python
    10
    0 Votes
    10 Posts
    3k Views
    JH23J
    I want to finish with this in case someone reads it. Years ago, I asked about the outdated methods when using these techniques. I tried to adjust the depth of the IK spline controls with the actual length of the spline itself. Today, I understand my mistake, as I was trying something that didn’t make logical sense. At the time, I thought it was the best option for what I was looking for. In short, this was never a problem, and the low response time is normal because the length depends on the depth of the controls. I thought there would be a solution, but choosing this path was not useful. In conclusion, what eventually satisfied my requirements was directly referencing the angles of the controls, meaning identifying how oriented each control is to another. I took this angle and used it as a factor to multiply by the depth. This model is much more logical and doesn’t have any flaws. At the time, I couldn’t think of a direct solution, but I didn’t want to leave this post like that. Thanks anyway, Ferdinand, for trying to help me. Cheers JH
  • Polygon Islands Convenience Method?

    r23 python
    7
    1
    0 Votes
    7 Posts
    3k Views
    E
    Here is something I recently used to count UV Islands as well as get some other info import c4d from collections import defaultdict def get_uv_islands(obj, tol=1e-5): """ Compute UV islands for the given polygon object using its UVW tag. This version retrieves the UV dictionary for each polygon using uvTag.GetSlow(polyIndex), then groups connected polygons (sharing at least one UV coordinate) into islands using an iterative flood-fill algorithm. """ uvw_tag = obj.GetTag(c4d.Tuvw) if uvw_tag is None: c4d.gui.MessageDialog("The object does not have a UVW tag.") return None poly_count = obj.GetPolygonCount() # Build maps: # - face_to_uvs: mapping from polygon index to its set of rounded UV keys. # - uv_to_faces: reverse mapping from each UV key to the set of polygon indices using that UV. face_to_uvs = defaultdict(set) uv_to_faces = defaultdict(set) def uv_key(vec): # Round UV vector components to mitigate floating-point precision issues. return (round(vec.x, 5), round(vec.y, 5)) # Build connectivity maps based on each polygon's UV data. for poly_index in range(poly_count): poly = obj.GetPolygon(poly_index) uv_data = obj.GetTag(c4d.Tuvw).GetSlow(poly_index) # If the polygon is a triangle, remove the extraneous 'd' key. if poly.IsTriangle() and 'd' in uv_data: del uv_data['d'] for key in uv_data: uv_vec = uv_data[key] key_tuple = uv_key(uv_vec) face_to_uvs[poly_index].add(key_tuple) uv_to_faces[key_tuple].add(poly_index) # Use an iterative flood-fill to group connected faces. islands = [] faces_left = set(range(poly_count)) while faces_left: island = [] start_face = next(iter(faces_left)) # Pick an arbitrary face from unvisited ones. stack = [start_face] while stack: face_idx = stack.pop() if face_idx not in faces_left: continue faces_left.remove(face_idx) island.append(face_idx) # For every UV key in this face, add all neighboring faces. for uv_val in face_to_uvs[face_idx]: for neighbor in uv_to_faces[uv_val]: if neighbor in faces_left: stack.append(neighbor) islands.append(island) return islands def get_island_uv_center(obj, uvw_tag, island): """ Given a polygon object, its UVW tag, and an island (list of polygon indices), compute the UV bounding box and center. """ # Initialize min/max with infinities. min_u = float('inf') max_u = -float('inf') min_v = float('inf') max_v = -float('inf') # Gather unique UV coordinates from all faces in the island. unique_uvs = {} for face_idx in island: poly = obj.GetPolygon(face_idx) uv_data = uvw_tag.GetSlow(face_idx) if poly.IsTriangle() and 'd' in uv_data: del uv_data['d'] for key in uv_data: uv = uv_data[key] key_tuple = (round(uv.x, 6), round(uv.y, 6)) unique_uvs[key_tuple] = uv # Compute the bounding box. for uv in unique_uvs.values(): if uv.x < min_u: min_u = uv.x if uv.x > max_u: max_u = uv.x if uv.y < min_v: min_v = uv.y if uv.y > max_v: max_v = uv.y center_u = (min_u + max_u) / 2.0 # Invert V axis so the center is correct in UV space. center_v = 1.0 - ((min_v + max_v) / 2.0) return center_u, center_v, min_u, max_u, min_v, max_v def main(): doc = c4d.documents.GetActiveDocument() obj = doc.GetActiveObject() if obj is None: c4d.gui.MessageDialog("Please select a polygon object.") return uvw_tag = obj.GetTag(c4d.Tuvw) if uvw_tag is None: c4d.gui.MessageDialog("The object does not have a UVW tag!") return islands = get_uv_islands(obj) if islands is None: return num_islands = len(islands) print("Number of UV islands:", num_islands) for idx, island in enumerate(islands): center_u, center_v, min_u, max_u, min_v, max_v = get_island_uv_center(obj, uvw_tag, island) print("Island", idx, "has faces:", island) print("Island Num",idx," Bounding Box: U [{:.6f}, {:.6f}], V [{:.6f}, {:.6f}]".format(min_u, max_u, min_v, max_v)) print(" Center: U = {:.6f}, V = {:.6f}".format(center_u, center_v)) if __name__=='__main__': main() Output looks something like Number of UV islands: 2 Island 0 has faces: [0, 5, 3, 4] Island Num 0 Bounding Box: U [0.004902, 0.495098], V [0.004902, 0.740196] Center: U = 0.250000, V = 0.627451 Island 1 has faces: [1, 2] Island Num 1 Bounding Box: U [0.004902, 0.495098], V [0.750000, 0.995098] Center: U = 0.250000, V = 0.127451 Hope it is useful!
  • How to create UV of obj.

    windows python 2025
    4
    0 Votes
    4 Posts
    834 Views
    M
    I use this to Thank You Ferdinand. This is how I imagine an SDK example should look like .... a simplest version , an altered simple version and a complex touching the boundaries of the subject. I am thankful and praise your work .... ! cheers mogh
  • create link parameter accept Alembic tag

    r21 2025 c++
    3
    0 Votes
    3 Posts
    724 Views
    B
    @m_adam, Thank you! Yes, Message(GeListNode* node, Int32 type, void* data) works for me. I'm wondering shall my plugin just return true after processing MSG_DESCRIPTION_CHECKDRAGANDDROP in the Message() function (set the value of DescriptionCheckDragAndDrop::_result) or still call SUPER::Message(node, type, data); at the end? It looks to me that calling SUPER::Message(node, type, data); at the end still works. But the example in MSG_DESCRIPTION_CHECKDRAGANDDROP Message doesn't call SUPER::Message(node, type, data);. Thanks!
  • Read Alembic tag's data

    r21 2025 c++
    3
    0 Votes
    3 Posts
    726 Views
    B
    @m_adam, Thank you very much, this works for me!
  • Plugin does not appear in Expression on client's Cinema 4D

    s26 2024 c++ windows
    24
    1
    0 Votes
    24 Posts
    5k Views
    Y
    Oh, you've edited your previous message! Thanks! I will try it.
  • Order Of Hierarchy Updates For Fieldobjects

    2025 c++
    3
    0 Votes
    3 Posts
    623 Views
    J
    @ferdinand Thanks for the response. That's what I was afraid the situation would be, I believe I have a work around that will be able to fulfill what I need it to do. John Thomas
  • Volume Builder Type Fog Should it be solid?

    c++ 2024
    3
    1
    0 Votes
    3 Posts
    675 Views
    D
    Hi @m_adam , Thank you so much! That was exactly what I needed. Dan
  • How to store "cached" data in the document from the scenehook?

    c++
    17
    0 Votes
    17 Posts
    2k Views
    H
    Hi Ferdinand, Yes, I remember reading about that, so the IDs for this container data is 5060 and 5061 (I work in IP telephony as my day job so this is surely no coincidence), but I even tried to move them to 50060 and 50061 and the freeze still happens. I will pack up the project shortly and email it in.
  • How to drag rows in Treeview

    2024 python
    4
    1
    0 Votes
    4 Posts
    678 Views
    chuanzhenC
    @ferdinand Thanks for your help!
  • 0 Votes
    10 Posts
    2k Views
    B
    Thank you very much for all your detailed explanation, @ferdinand!
  • 0 Votes
    4 Posts
    685 Views
    ferdinandF
    Hey @vhardy, yes, @m_adam as supporting expressions on his Todo list for the VS Code bridge. But it is not very high in our priority list, you are the first user requesting it. I gave the subject a gentle nudge in our task tracking. FYI: Generally we do not make any guarantees if or when we will implement something. Cheers, Ferdinand