• 0 Votes
    2 Posts
    393 Views
    ferdinandF
    Dear user, the problem with your example code is that you do use a VoxelizationInterface which is not well suited for this task. The type DistanceQueryInterface(Documentation) is much better suited for the task. You should also be more cautious with statements like the following, taken from your code, voxelRef = maxon::PolyVoxelization().Create() iferr_ignore("Could not create VoxelizationRef"); as stepping over a failure of initialization will lead to crashes. At the end of this posting you will find an example for how to use DistanceQueryInterface as well as some light comments on error handling. I hope this helps and cheers, Ferdinand /* This function expects a point object (A) to be the first object in the scene, followed by a polygon object (B) as the second object. It will then return the index for closest polygon in B for each vertex in A. */ static maxon::Result<void> Pc13296(BaseDocument* doc) { iferr_scope; // Get the first and second node in the scene. The first one is expected // to be a point node, serving as a point source, and the second one is // expected to be a polygon node, serving as a polygon source. BaseObject* node = doc->GetFirstObject(); if (node == nullptr || !node->IsInstanceOf(Opoint)) { ApplicationOutput("Please provide a point object as the first node in the scene."_s); return maxon::OK; } PointObject* pointNode = static_cast<PointObject*>(node); node = node->GetNext(); if (node == nullptr || !node->IsInstanceOf(Opolygon)) { ApplicationOutput("Please provide a polygon object as the second node in the scene."_s); return maxon::OK; } PolygonObject* polygonNode = static_cast<PolygonObject*> (node); // Get access to the point and polygon data and the global transforms of both nodes. const Vector* points = pointNode->GetPointR(); const CPolygon* polygons = polygonNode->GetPolygonR(); const int pointCount = pointNode->GetPointCount(); const int polygonCount = polygonNode->GetPolygonCount(); Matrix mgPointNode = pointNode->GetMg(); // We invert it right away, as we only will need it in this form. Matrix iMgPolygonNode = ~polygonNode->GetMg(); // When an error is being raised by Cinema we should be cautious with using iferr_ingore, as // then the code will keep running in the current scope. In some cases like manipulating an // array like structure this can be useful. But when an initialization of an entity fails, we // almost never want to keep going, as trying to use that not initialized object then will be // a sure fire way to crash Cinema 4D. Instead we can either use iferr_return to simply leave // the current scope, use iferr_throw to throw a specific error or handle it manually with // iferr(). Below you will find a two examples. // Create a reference to the distance query interface. maxon::DistanceQueryRef distanceQuery = maxon::DistanceCalculator().Create() iferr_return; // Pass true for the second argument to voxelize the input to speed up larger queries. Just as // with any optimization, for smaller data sets this voxelization setup might eat up all the // performance benefits gained latter on. iferr(distanceQuery.Init(polygonNode, false)) { ApplicationOutput("Failed to initialize DistanceQueryInterfacae for @", polygonNode->GetName()); return maxon::OK; } // Go over all vertices and query them for the closest polygon (id) in the other mesh. float distance = 0; Vector p; for (int poindId = 0; poindId < pointCount; poindId++) { // The point in the point mesh converted first to global coordinates and then to local // coordinates in the polygon node. We have to do that because the points in the point // source live in their own coordinate system as well the ones in the polygon source. p = mgPointNode * iMgPolygonNode * points[poindId]; maxon::PrimitiveInformation info; distance = distanceQuery.GetClosestMeshPrimitive(p, info); ApplicationOutput("Closest polygon id for point id @: @", poindId, info.GetRealPolyIndex()); } return maxon::OK; } The output/setup: [image: 1617968576078-642545d3-3ffa-467e-9123-cf0a328b18f1-image.png]
  • 0 Votes
    4 Posts
    556 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
  • Erratic Keyboard Messages in GeDialog

    Cinema 4D SDK python r23 windows
    7
    0 Votes
    7 Posts
    2k 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
    505 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!
  • CUSTOMGUI_FONTCHOOSER Text Disappears

    Cinema 4D SDK python windows r23
    5
    0 Votes
    5 Posts
    602 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
  • Scaling a GeUserArea in a ScrollGroup

    Cinema 4D SDK python windows r23
    5
    0 Votes
    5 Posts
    1k 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
  • Handles in R18

    Cinema 4D SDK python r19 windows
    3
    1
    0 Votes
    3 Posts
    833 Views
    ?
    Thank you for letting me know, @ferdinand !
  • Drawing to Multiple Views at Once

    Cinema 4D SDK r23 python windows
    5
    0 Votes
    5 Posts
    729 Views
    ?
    @ferdinand That's very helpful, thank you!
  • Spline dynamics

    Cinema 4D SDK python r21 windows
    7
    0 Votes
    7 Posts
    2k Views
    bacaB
    @ferdinand you were clear and example is pretty good, I got the idea. No need to write code for me But it's not trivial overall, I just need to spend some time on this. Thanks again.
  • 0 Votes
    5 Posts
    1k Views
    ManuelM
    hi, thanks @mp5gosu for the answer. About inserting material before making some changes, there's no real right way of doing it. It just that if something go wrong about the change you are doing, you have to remove the material from the document, while if you don't insert it, you don't have to. As @mp5gosu said it's better to insert the object in the document before linking them. Even if should work if you insert the material after. Cheers, Manuel
  • Errors when recompiling R20 plugin to R21

    Cinema 4D SDK
    6
    0 Votes
    6 Posts
    1k Views
    r_giganteR
    hi @Boony2000 , these are Visual Studio Intellisense errors which you can safely ignore. If they bother you switch the filter from "Build + Intellisense" to "Build". Cheers, R
  • 0 Votes
    4 Posts
    524 Views
    ManuelM
    @blastframe said in Updating F-Curves in Timeline on EditSlider Drag: What's c4d.EVMSG_FCURVECHANGE for then? After a quick check (sorry, I should have checked yesterday for a more complete answer) literally nothing. It's used nowhere. Cheers, Manuel
  • 0 Votes
    3 Posts
    492 Views
    ?
    @ferdinand Thank you for this; it makes things much clearer. I am very grateful we have the forum to clarify these issues.
  • 0 Votes
    3 Posts
    466 Views
    ?
    @ferdinand That was exactly what I was seeking, thank you, Ferdinand!
  • 0 Votes
    6 Posts
    826 Views
    ManuelM
    hi, this shouldn't make any difference, what do you mean by "my own FIELDLIST gui element" . Can i see how do you add it and initialise it ? Cheers, Manuel
  • 0 Votes
    3 Posts
    374 Views
    ?
    @zipit Thank you very much, Ferdinand. This helped me a lot!
  • Rotating a GeClipMap

    Cinema 4D SDK windows python sdk r23
    11
    1
    0 Votes
    11 Posts
    2k Views
    ?
    @zipit Thank you for the information.
  • Difficulty with cloners and and lifetime of objects

    Cinema 4D SDK
    13
    0 Votes
    13 Posts
    3k Views
    M
    All right, thank you for all the help. I'll close this now.
  • 0 Votes
    17 Posts
    3k Views
    M
    Glad you found a way and yes I think it's safe now I guess there is no more open pint? If so I let you define your topic as solved (see Forum Structure and Features - Ask as Question If you don't know how to do it). Just in case a BaseContainer can also store a BaseContainer. so you could store your own BaseContainer at the ID_PLUGIN And in this BaseContainer at ID 0 stores, the obj counts, and then you can safely iterate over it. Cheers, Maxime.
  • 0 Votes
    4 Posts
    2k Views
    M
    @m_adam Thanks for the clarification. Regards, Georgi.