What's the state of Ngons in Python?



  • Hello again, as Ngons seem to pop up once again in the questions, I'm doing some investigations on them, and... well, they are still not very Python friendly.

    Question 1: Is anybody currently working on expanding the Ngon handling in the Python API? (Status August 2020, comparing the newest Python and C++ documentation) Python is missing the classes Ngon and NgonBase and the struct NgonNeighbor. The PolygonObject does not have the functions GetNgonBase and GetAndBuildNgon. The modeling interface is missing AddNgon, SetNgon, FindNgon, GetNgon, NewNgon, and more. In total, that means Ngons cannot be created in Python (sure, we can use SendModelingCommand to send a Melt command, but that is not practical and only feasible at all in certain threading situations.)

    This seems to be the case since a long time, and I wonder if the Python API will ever be amended to enable Ngon generation, or whether that's not even planned (as Ngon handling is fairly complicated and may not be suitable for the targeted Python audience)

    (Edit: I am aware that there are functions in the PolygonObject that allow inferring the Ngons - returning the relationship lists between Ngons and polygons. But these are read-only: GetPolygonTranslationMap() and GetNGonTranslationMap().)

    Question 2: Browsing the PluginCafé history, I found the mention that GetPolygonTranslationMap() is broken (2017). Is that still the case? It was also mentioned that the error is known and it's being worked on, but in lack of a complete error history I can't find a confirmation that it has been fixed. The thread ends shortly after without mentioning the issue again.

    Question 3: Is there any documentation on permitted Ngon constructs? An Ngon is ultimately just a collection of polygons, but not every arbitrary collection of polygons can be an Ngon. This is normally ensured by C4D functions that generate the Ngons. But if we could create Ngons ourselves (let's pretend we have the needed C++ functionality), what are the rules? From the behavior of the Melt command, I can only infer:

    • Disjunct polygons cannot make an Ngon
    • Polygons that meet only in a point cannot make an Ngon
    • Corollary: Any two polygons in an Ngon must transitively share an edge
    • All points of an Ngon are border points. An Ngon cannot contain "inner" points (points that are only part of "inner" Ngon edges).
    • An Ngon may not have edges that "cut into" the Ngon and end on an isolated point (an edge that is technically a border edge but neighbors only Ngon polygons)
    • Ngons can contain holes, even multiple ones
    • Ngons can be non-planar and have concave borders
    • A polygon of an Ngon may have only inner Ngon edges (but its points still must be border points)

    Also:

    Melt may completely change the polygon selection and create triangles and poles with inner Ngon edges even if the original polygon selection in my opinion would have made a perfectly valid Ngon. -- I am fairly sure that this is just a weakness of the algorithm but I cannot be totally sure that there are more rules behind it that I simply don't know.

    By cutting a line between two holes in an Ngon, I was able to create an Ngon that is invalid - it's not an open manifold, and it contains an edge that cuts into the Ngon. Apparently a bug, since the algorithm also closed one of the holes. Just for fun:
    20200823__02__NgonInvalid.c4d



  • Hi @Cairyn,

    one of your rabbit holes again, eh ;) I cannot say much, but

    Corollary: Any two polygons in an Ngon must transitively share an edge

    seems very unlikely to me, as it would limit Ngons to being composed of at most of three polygons, since an edge can only be shared by two polygons in a non-degenerated topology. You might want to rephrase whatever you were trying to express there ;)

    Cheers,
    zipit



  • @zipit Yes, it's heavy lifting. Ngons are fairly nasty as far as side conditions are concerned. I must admit, I never did anything with them on the C++ side. But nevertheless I am surprised that they are practically missing from the Python API, with the exception of a few read-only functions.

    The corollary is correct - it says "transitively share", so if you have polygons 1 and 2 sharing an edge, and 2 and 3 sharing an edge, then 1 and 3 are sharing an edge via 2. Okay, "share" may not be proper terminology, I could invent a new relationship operator, but people are already complaining about my overlong posts, so I try to suppress my inner mathematician 😸



  • hi,

    Q1:
    No. The modeling kernel have been rewrite as you may know. There's new datatype that must be translate/port to python witch make a bit useless the effort of adding the old functions to python. Of course we don't know when it will be available.

    Q2:
    what's wrong with GetPolygonTranslationMap on my test it's returning the expected result.

    Q3:
    No but I've asked.

    i don't understand what your file is showing and the problem with the melt command. One screen shot or two may help my brain to understand.

    Cheers,
    Manuel



  • Answer from the dev. I'll try to find a place in the documentation. From S22 on, this rules should be applied eveytime.

    • The new kernel supports real ngons, meaning 1 outline with n points with an arbitrary amount of holes with each m points. None of the points are allowed to be used twice. With that definition a lot of the answers can be derived.

    • Disjunct polygons cannot make an Ngon
      Correct

    • Polygons that meet only in a point cannot make an Ngon
      Correct

    • Corollary: Any two polygons in an Ngon must transitively share an edge
      Not correct. The polygons are an arbitrary valid tessellation of the polygon, and 2 polygons of that tessellation must not necessarily share an edge. There are however always two polygon that will share an internal edge.

    • All points of an Ngon are border points. An Ngon cannot contain "inner" points (points that are only part of "inner" Ngon edges).
      Correct

    • An Ngon may not have edges that "cut into" the Ngon and end on an isolated point (an edge that is technically a border edge but neighbors only Ngon polygons)
      Correct in the new kernel. The old one allowed this in some setups, which caused problems. Tracing the “outline” of such an polygon shows that it breaks the rule of points not being used more than once.

    • Ngons can contain holes, even multiple ones
      Correct

    • Ngons can be non-planar and have concave borders
      Correct

    • A polygon of an Ngon may have only inner Ngon edges (but its points still must be border points)
      Not correct. Some polygons of the tessellation of an Ngon must make up the border edges and the hole edges of the Ngon and those are not inner ngon edges. All points must be part of the outline or a hole (no inner points) is Correct
      Not correct. Some polygons of the tessellation of an Ngon must make up the border edges and the hole edges of the Ngon and those are not inner ngon edges. All points must be part of the outline or a hole (no inner points) is Correct

    Cheers,
    Manuel



  • @m_magalhaes Thank you for the answers!

    Q1: ok, so the C++ functions are close to deprecation too... I thought these were already using the new kernel, but when looking at the timeframe, I notice that the Ngons have been around for a while...

    Q2: I don't know, this is information found on a thread here, stating that the function is broken and will be fixed. I was unable to find a similar statement that it actually has been fixed. The corresponding thread peters out without saying so.
    This is a general issue; I often browse old posts where something or the other doesn't work but I can't find information on the fix (if there even was a fix). Naturally, I understand that it's impossible to follow up on all old threads with fix information, but I wished there was a searchable list with all the fixes (that are announced with a release anyway, but often lacking the precise information) where I could look up what function was fixed when. Or a list of known errors, so any problems will not come as a surprise.
    I assume this special error has already been fixed as I can't provoke a problem either today, but it's guesswork.

    The file: ok, here's what I do:

    I start with an octagon
    96946198-0f49-47c7-a603-e97f95ada821-image.png

    There I delete some polys to create holes, and then I melt the whole object into one Ngon.
    f826dd8a-b37e-4e75-b25c-2f8eb03d816c-image.png
    Note that the tesselation is pretty confusing even in parts of the octagon where the original polys would have made a perfectly legal tesselation of the Ngon, but that's another thing.

    Now I cut an edge between two holes:
    0010a54e-8783-4eac-803c-0ce82325c43f-image.png

    You can already see that this is going wrong... Looking at the result (highlighting the Ngon) I see that the hole is gone and actually the tesselation has created coincident polygons on top of each other:

    10138a75-d3d0-4251-8f99-0ccd514ddb71-image.png

    The marked point in the following screenshot is the end of... well, it's partly an inner edge and partly an outer edge that ends in a... somewhat inner point.
    00dda87e-b460-4055-baee-ebe48d40450a-image.png

    It's hard to describe because the result is not even a proper manifold any more; when I lift the two edge points it becomes visible:

    b8d347e3-c17e-47b8-adf3-87ce56dd77c4-image.png

    The foot edge of that polygon (opposite the two selected points, inner edge) is actually used by three polygons.
    This is still all just one single Ngon (and it doesn't lead to crashes even inside of an SDS).
    The behavior is easily repeatable.

    Anyway, I don't think this issue is of huge interest as you said there's a replacement in the new kernel already, which will probably come with a diferent tesselation algorithm, so I present it here as a curiosity.



  • @m_magalhaes Thanks again. I really should look into the C++ New Maxon API documentation, but I find it hard to get access to it. I am under the impression that the Maxon API does not really cover all aspects of the Classic API yet, and we still have to use BaseDocument, BaseObject etc for access. Which means that I cannot see the Ngons of the new kernel exposed (?)

    Just two remarks:

    Corollary: Any two polygons in an Ngon must transitively share an edge
    Not correct. The polygons are an arbitrary valid tessellation of the polygon, and 2 polygons of that tessellation must not necessarily share an edge. There are however always two polygon that will share an internal edge.

    I need to work on my wording, the "transitively sharing" was apparently not a wise choice (see above) 😿. What I meant was: a polygon must be connected to the rest of the Ngon by a shared edge; all polygons share at least one edge with another polygon within the Ngon. It's only a corollary though from the previous two statements.

    A polygon of an Ngon may have only inner Ngon edges (but its points still must be border points)
    Not correct. Some polygons of the tessellation of an Ngon must make up the border edges and the hole edges of the Ngon and those are not inner ngon edges. All points must be part of the outline or a hole (no inner points) is Correct

    I fell for a Germanism here in the usage of "may"; what I was trying to say was "can possibly". The situation I thought of was the following:

    d0e24986-5449-476c-927d-5bfb6df72be2-image.png

    The innermost polygon (central triangle) contains only inner edges of the Ngon; it has no outer edges. I was actually surprised that this is possible since the tesselation algorithm seems to avoid such situations. This is not a C++ coded construct though; I only used onboard tools. It took me quite a few knife cuts and Melt calls before the tesselation finally came up with this.



  • hi,

    About the bugs on the forum, we have introduce few month ago new tags "Bug report" and "Bug Fixed". We are also adding some tag in our bug database to retrieve faster the post on the forum. I know it's not perfect and sometimes we may forgot to add this tag on the first post of the thread. But it's better than nothing.

    @Cairyn said in What's the state of Ngons in Python?:

    Anyway, I don't think this issue is of huge interest as you said there's a replacement in the new kernel already, which will probably come with a diferent tesselation algorithm, so I present it here as a curiosity.

    Don't get me wrong, all modeling command have been migrated to the new modeling kernel. If you are using SendModelingCommand, it will use the new kernel.
    So what you see now in S22 and R23 (ok you will see in R23) IS the new kernel. There will be no better tesselation.
    I consider this as a bug.

    I really should look into the C++ New Maxon API documentation, but I find it hard to get access to it. I am under the impression that the Maxon API does not really cover all aspects of the Classic API yet, and we still have to use BaseDocument, BaseObject etc for access. Which means that I cannot see the Ngons of the new kernel exposed (?)

    The new modeling kernel isn't exposed yet. But it is used. I understand, it's a bit confusing. We are moving Cinema4D to the new core. But as long as some part of Cinema4D are using the old system (object manager for exemple), the new core need to "translate" that to the classic API.
    That mean for now, if you send a modeling command to a polygon (and create a ngon) this polygon will be translate to the new api polygon model, apply the modeling operation, translate the result to the old classic api model. Even with that "translation", the kernel is faster.
    You access the Ngon the same way but the result is coming for the new kernel.

    I hope it's clear.

    I fell for a Germanism here in the usage of "may"; what I was trying to say was "can possibly". The situation I thought of was the following:
    this look like a valid ngon but i will ask :)

    (i hope i didn't missed anything ^^)

    Cheers,
    Manuel



  • @m_magalhaes said in What's the state of Ngons in Python?:

    About the bugs on the forum, we have introduce few month ago new tags "Bug report" and "Bug Fixed". We are also adding some tag in our bug database to retrieve faster the post on the forum. I know it's not perfect and sometimes we may forgot to add this tag on the first post of the thread. But it's better than nothing.

    Yeah, I'll try to use that in the future although it probably won't affect existing threads (a lot of valuable knowledge still resides in the "old forum" parts).

    @Cairyn said in What's the state of Ngons in Python?:

    Anyway, I don't think this issue is of huge interest as you said there's a replacement in the new kernel already, which will probably come with a diferent tesselation algorithm, so I present it here as a curiosity.

    Don't get me wrong, all modeling command have been migrated to the new modeling kernel. If you are using SendModelingCommand, it will use the new kernel.
    So what you see now in S22 and R23 (ok you will see in R23) IS the new kernel. There will be no better tesselation.
    I consider this as a bug.

    As a Perpetual user, I'm still on R21 (as tagged) so is this also the new kernel? AFAIK the new kernel has been working behind the API for a while now, being gradually introduced into the functionality, so it's possible that this bug still persists.

    I can't test it on a demo of S22 for you, as the current licensing does not allow me to install one.

    The new modeling kernel isn't exposed yet. But it is used. I understand, it's a bit confusing. We are moving Cinema4D to the new core. But as long as some part of Cinema4D are using the old system (object manager for exemple), the new core need to "translate" that to the classic API. (...)
    I hope it's clear.

    Sure, I have a few decades of programming under the belt. It's just a bit difficult as non-Maxon developer to see the details. Seeing only the API (and therefore the user-side of the translation layer), I can't always tell what the underlying data model really is; what's stored as attribute, what's calculated on the fly, what's internally cached for fast access, what's abstracted and what's plainly stored... I may make wrong assumptions on the internal workings.

    this look like a valid ngon but i will ask :)

    It probably is valid - I don't see a reason why it should be forbidden. I just notice that the tesselation algorithm tends to avoid such "inner polygons". That may not be intentional (based on a rule) though, but just a consequence of how the algorithm works.

    Thanks again,
    -- Cairyn --