• 0 Votes
    4 Posts
    511 Views
    ferdinandF
    Hi @blastframe, yes, that would be one, and probably the more modern way to do it. I personally like also an explicit call to the base implementation. I think it is more readable for someone else reading your code. But that is probably a rather subjective choice. So for clarity, I am speaking about something like this: foo = bar * baz return c4d.gui.GeUserArea.InputEvent(self, msg) There is of course the advantage of super taking care of calling the proper implementation(s) for you which is not taken care of by this approach, but you cannot have everything and in this case things are rather unambiguous for us here Cheers, Ferdinand
  • Undo Problem For TagData Plugin

    Cinema 4D SDK python r23
    4
    1
    0 Votes
    4 Posts
    616 Views
    ManuelM
    hi, @beatgram said in Undo Problem For TagData Plugin: So these bracket notation style is safer than using BaseContainer in any case? this should be exactly the same. Sorry i didn't got time to warp my head around it. Cheers, Manuel
  • Erratic Keyboard Messages in GeDialog

    Cinema 4D SDK python r23 windows
    7
    0 Votes
    7 Posts
    1k Views
    ?
    @mp5gosu Sorry, I missed it! That works! In case other devs have a solution, I'll mark yours as the right answer. Thank you!
  • 0 Votes
    3 Posts
    458 Views
    ?
    @ferdinand Thank you, Ferdinand for the thorough answer and ideas for workarounds. I don't quite have my head around how to use threading in Cinema 4D yet but you've inspired me to look into it. Thank you!
  • UVW coordinates in ShaderData.Output()

    Cinema 4D SDK r23 c++ python
    12
    3
    0 Votes
    12 Posts
    2k Views
    ManuelM
    hi, I don't see how we could do it with the Draw Method in a efficient way. Cheers, Manuel
  • CUSTOMGUI_FONTCHOOSER Text Disappears

    Cinema 4D SDK python windows r23
    5
    0 Votes
    5 Posts
    558 Views
    ferdinandF
    Hi @blastframe, so this is a bug that happens independently of Python. It also not connected to your example using a dangling dialog, but to the fact that it is using a dialog. When you implement some form of NodeData plugin and a FONT resource element in it, this bug won't happen. I have opened a bug report for this. For now you would have to either use my little workaround or move outside of a GeDialog environment an implement the whole plugin as some form of NodeData plugin. If a dialog is of high priority for you, you could also display an instance of that node in a DescriptionCustomGui inside your dialog. Which should work and somewhat be a mix of both options. Cheers, Ferdinand
  • Error: Wrong indentation of namespace member

    Cinema 4D SDK macos c++ r23
    9
    2
    0 Votes
    9 Posts
    2k Views
    fwilleke80F
    Wow, I never thought of that. Very good to know, thank you for asking! Cheers & have a nice weekend, Frank
  • Scaling a GeUserArea in a ScrollGroup

    Cinema 4D SDK python windows r23
    5
    0 Votes
    5 Posts
    931 Views
    ferdinandF
    Hello @blastframe, I forgot to put the final outcome for this here. So, after some back and forth we decided to not fix this for reasons I unfortunately cannot disclose. But we will update the documentation in an upcoming release to avoid this being as opaque as it currently is. This is probably not what you hoped for, but currently the best course of actions for us. Thank you for your understanding, Ferdinand
  • TEXTURE resource parameter

    Cinema 4D SDK c++ r23
    4
    0 Votes
    4 Posts
    688 Views
    rsodreR
    Thanks, seems to be working now, thanks.
  • 0 Votes
    4 Posts
    759 Views
    M
    Hi @mp5gosu , I will set the topic as closed. Note that the fix will not come in the next update but don't worry we have it logged and it's on our list of things to fix in the future. Cheers, Maxime.
  • Polygon Islands Convenience Method?

    Cinema 4D SDK r23 python
    7
    1
    0 Votes
    7 Posts
    2k 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!
  • 0 Votes
    18 Posts
    2k Views
    ManuelM
    Hi, Sorry about not having time to investigate the gradient part of your question. I was waiting for feedback about the color presets. With the new asset browser out there's no point into investigate this question furthermore. Cheers, Manuel
  • 0 Votes
    6 Posts
    1k Views
    P
    forget about it. i removed the c4d.OBJECT_INPUT flag during development and forgot to add it back.
  • Japanese Language Interface – Problems

    Cinema 4D SDK r23
    2
    0 Votes
    2 Posts
    606 Views
    ferdinandF
    Hi @lasselauch, thank you for reaching out to us and I am sorry to hear about your problems regarding targeting multiple localizations. I am struggling however a bit to understand what is exactly going wrong for you. You tell us that the plugin "isn't behaving correctly in R23" which is a bit too broad for us to come up with an reliable answer. I am also sorry for having to point out that your proposed way of getting hold of the implementation of the plugin via aescripts.com - with the proprietary downloader you provide there to distribute your products - is a bit much for us. I would suggest that you share the relevant code more directly here, or, in case you cannot do this, share it via sdk_support(at)maxon.net confidentially with us (please note the Forum Guidelines regarding Support Procedures: Confidential Data, specifically regarding NDAs, in case they would apply here). For your actual problem: It is really hard to give any advice without knowing what exactly is going wrong. I assume you have a Japanese localization in your resource folder and it does not work for the user? I would check: If the folder has the correct ISO 639-1 language code, for Japanese it should be ja-JP, so for the strings folder it should be strings_ja-JP for example. Not providing a matching language code for a running Cinema 4D instance should result in Cinema automatically falling back to en-US. Make sure that the Japanese translation files are all UTF-8. While the manuals do not state that restriction, it could be something that is tripping Cinema up, especially considering that languages with large character sets, like for example Japanese, are not fully represented in UTF-8 due to the limited namespace. I would however had to ask our translators how they handle Japanese if this is the culprit. But in the end these are mostly shots into the dark for me, due to not knowing what is exactly going wrong. So I would also had to ask you to describe more precisely what is going wrong. Cheers, Ferdinand
  • LineObject custom segment colors

    Cinema 4D SDK r23 sdk c++
    7
    0 Votes
    7 Posts
    1k Views
    ferdinandF
    Hi @mastergog, thank you for reaching out to us. I can reproduce your problem and this would have not been something which we would have expected. If you go significantly over one million segments (1.1 million still works for me for example) no matter if in one node or scattered over multiple nodes, the viewport will freeze. It is a bit hard to assess for us at the moment if this a bug or just a limitation of our viewport API. We will investigate the problem and I will report back here if there are going to be any short or mid-term fixes for that (or not if this is a limitation). For now there is unfortunately nothing you can do, since spreading out the segments over multiple nodes won't help you. Sorry for the inconvenience and cheers, Ferdinand
  • 0 Votes
    8 Posts
    1k Views
    beatgramB
    @Cairyn Thank you so much for helping me again!
  • ToolData::GetDDescription() redundant call, why?

    Cinema 4D SDK c++ r23
    4
    0 Votes
    4 Posts
    907 Views
    WTools3DW
    Thank you guys for quick reply. But I was probably not clear enough with the question. I do understated the concept of setting panel description via GetDDescription() callback. I already did the checks for whether it is request for full description of just single id. As it is listed in the example below (it is member function of C4dControls class from previous snippet void C4dControls::AddIntChoice(int id, int gid, const String& name, const BaseContainer& items) { const DescID cid = DescLevel(id, DTYPE_LONG, 0); //--------------------------------------------------------------------- if (ex_descr && (!ex_singleid || cid.IsPartOf(*ex_singleid, nullptr)) ) { BaseContainer bc = GetCustomDataTypeDefault(DTYPE_LONG); //--------------------------------------------- bc.SetInt32 (DESC_CUSTOMGUI, ID_QUICKTABSRADIO_GADGET); bc.SetString(DESC_NAME, name); bc.SetInt32 (DESC_SCALEH, 1); // animate OFF bc.SetInt32 (DESC_ANIMATE, DESC_ANIMATE_OFF); //--------------------------------------------- bc.SetContainer(DESC_CYCLE, items); //--------------------------------------------- ex_descr->SetParameter(cid, bc, DescLevel(gid)); } } But it is still calling to rewrite each control description several times after any event in GUI. What confuses me the most, is that each series of calls is with the different pointer to description (Description* description) For example there are five different pointers to description when ToolData::GetDDescription() is executed for the same event. (after mouse click into attribute manager) Is this the way how it really works? There are more versions of description for the same panel, and all of them have to be initialized repeatedly after each event? Thanks! Viktor
  • 0 Votes
    4 Posts
    974 Views
    M
    thank you for your help, I am trying to understand ... am I right in the assumption that this is not "clean code" in a pythonic sense ? kind regards
  • Gets the point weight of the Field object.

    Cinema 4D SDK
    2
    0 Votes
    2 Posts
    553 Views
    ferdinandF
    Hi @x_nerve, thank you for reaching out to us. The most straightforward way to sample a FieldObject is FieldObject.Sample; there are also other sample methods attached to the various fields related classes, most notably c4d.FieldList. We have two examples in the Python SDK examples which showcase field sampling, fieldlist_sampling_r20 and fieldobject_sampling_20. You also mention "Is there a way to get the weight of the cube field points?"; you are probably aware of this, but since your phrasing could imply otherwise, it seems noteworthy to point out that fields are not discrete. So in other words, there is no finite amount of points you can exhaustively sample for a field object, since the object is non-discrete. You have to pick a point or a set of points you want to sample for a field object, which can be any point in in the value range c4d.Vector can handle. If there are any questions left, please do not hesitate to ask. Cheers, Ferdinand
  • 0 Votes
    15 Posts
    2k Views
    beatgramB
    @m_adam Oh, that's a little update for many users but huge for tiny developers like me! Thank you so much for the heads up.