<?xml version="1.0" encoding="UTF-8"?><rss xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:atom="http://www.w3.org/2005/Atom" version="2.0"><channel><title><![CDATA[I want to extract the polygon index of the inverted normal]]></title><description><![CDATA[<p dir="auto">Hi, I'd like to know a code that automatically finds the inverted normal (polygon changed to blue) of the object and extracts the polygon index of the object. Can you help me write the relevant code?</p>
<p dir="auto"><img src="/forum/assets/uploads/files/1719379740051-24e80c08-ca70-4e90-9277-2d69e5304206-image.png" alt="24e80c08-ca70-4e90-9277-2d69e5304206-image.png" class=" img-fluid img-markdown" /></p>
]]></description><link>http://developers.maxon.net/forum/topic/15577/i-want-to-extract-the-polygon-index-of-the-inverted-normal</link><generator>RSS for Node</generator><lastBuildDate>Sun, 17 May 2026 21:01:10 GMT</lastBuildDate><atom:link href="http://developers.maxon.net/forum/topic/15577.rss" rel="self" type="application/rss+xml"/><pubDate>Wed, 26 Jun 2024 05:32:19 GMT</pubDate><ttl>60</ttl><item><title><![CDATA[Reply to I want to extract the polygon index of the inverted normal on Mon, 30 Jun 2025 21:10:30 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/forum/user/ferdinand">@<bdi>ferdinand</bdi></a><br />
I'm showing an example with a curved surface composed of 8 zones.<br />
Each zone is the union of several polygons with normals oriented in the same direction (represented by an arrow).<br />
I think C4D should be able to identify this type of tiling and colorize these areas to highlight them.<br />
Depending on the case, this tiling could be important, but most often, creators assemble the faces logically.<br />
A window could then offer the option to select each tiling, in order to invert the normals with a single click.<br />
A plugin could also do this kind of work, which would save creators time.<br />
<img src="/forum/assets/uploads/files/1751317789481-surface.jpg" alt="surface.jpg" class=" img-fluid img-markdown" /></p>
]]></description><link>http://developers.maxon.net/forum/post/76653</link><guid isPermaLink="true">http://developers.maxon.net/forum/post/76653</guid><dc:creator><![CDATA[Kantronin]]></dc:creator><pubDate>Mon, 30 Jun 2025 21:10:30 GMT</pubDate></item><item><title><![CDATA[Reply to I want to extract the polygon index of the inverted normal on Mon, 30 Jun 2025 17:07:51 GMT]]></title><description><![CDATA[<p dir="auto">Hey,</p>
<p dir="auto">It is not just Cinema 4D which stores things like that, it is baked into math itself. At the core this is about the <em>winding order</em> as explained above. The cross product <code>u * v</code> will point into the opposite direction of <code>v * u</code>. When you have two edges <code>e</code> and <code>f</code> in a polygon, it matters in which order they appear as it will determine normal of the polygon and how the <em>'rendering math'</em> can interact with it.</p>
<p dir="auto">You can for example find the same principle documented in the <a href="https://www.khronos.org/opengl/wiki/Face_Culling" target="_blank" rel="noopener noreferrer nofollow ugc">Open GL</a> or <a href="https://docs.unity3d.com/2021.2/Documentation/Manual/AnatomyofaMesh.html" target="_blank" rel="noopener noreferrer nofollow ugc">Unity</a> docs.</p>
<p dir="auto">It is totally possible to realize a tool that aligns polygons from some user input. E.g., you could use <code>c4d.utils.ViewportSelect</code> to let a user select a polygon, and then using raycasting to figure out if that polygon is front or back facing for the current camera and with that then figure out if that polygon is correctly aligned or not, and then start to adjust all other polygons according to that polygon  (because with raycasting you can do that, check <a href="https://developers.maxon.net/docs/py/2025_3_1/modules/c4d.utils/GeRayCollider/index.html#GeRayCollider.GetIntersection" target="_blank" rel="noopener noreferrer nofollow ugc">GeRayCollider.GetIntersection</a>). But it requires the user choice of that <em>"that is the camera position and polygon that counts"</em>.</p>
<p dir="auto">But what is impossible, is to determine how polygons should face for an object with no further inputs. You do not need a Moebius strip as an example for that; just take a simple plane with two polygons, facing in different directions. It is impossible to solve the aligmment of that objects polygons. One polygon could be misaligned (we cannot figure out which), two could be misaligned, or both could be correct. But we cannot find out without any user input. For closed meshes with some quickly-not-so-trivial-anymore math, we can figure out what likely should be the outside of something and what not. But even there one could then run into the case, that someone intentionally created a sphere with inverted normals to do some rendering tricks.</p>
<p dir="auto">Cheers,<br />
Ferdinand</p>
]]></description><link>http://developers.maxon.net/forum/post/76651</link><guid isPermaLink="true">http://developers.maxon.net/forum/post/76651</guid><dc:creator><![CDATA[ferdinand]]></dc:creator><pubDate>Mon, 30 Jun 2025 17:07:51 GMT</pubDate></item><item><title><![CDATA[Reply to I want to extract the polygon index of the inverted normal on Mon, 30 Jun 2025 16:34:49 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/forum/user/seora">@<bdi>seora</bdi></a><br />
If you take a simple, seamless 3D surface bounded by edges, you can almost always create two distinct sets of faces with the same orientation. Thus, under certain conditions, you can find the misoriented faces with a Python program.<br />
But generally, since C4D coding cannot find how a polygon should be interpreted, finding misoriented faces is geometrically impossible. Only an AI program could list possible scenarios to answer this question (knowing that several scenarios exist).<br />
On the other hand, if your Python program knows the target shape you're working on (cube, sphere, ellipse, torus, etc.), you can find the misoriented faces very easily.<br />
<img src="/forum/assets/uploads/files/1751301271168-pic_surface.jpg" alt="pic_surface.jpg" class=" img-fluid img-markdown" /></p>
]]></description><link>http://developers.maxon.net/forum/post/76650</link><guid isPermaLink="true">http://developers.maxon.net/forum/post/76650</guid><dc:creator><![CDATA[Kantronin]]></dc:creator><pubDate>Mon, 30 Jun 2025 16:34:49 GMT</pubDate></item><item><title><![CDATA[Reply to I want to extract the polygon index of the inverted normal on Mon, 30 Jun 2025 15:36:16 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/forum/user/seora">@<bdi>seora</bdi></a></p>
<p dir="auto">From a purely mathematical point of view, there must exist a set of polygons for which this extraction is theoretically possible, given how C4D encodes faces.<br />
But I think there must exist many polygons for which this possibility makes no sense. For example, a Möbius strip where there is no back and no front for a face.</p>
<p dir="auto"><img src="/forum/assets/uploads/files/1751297737763-twist.gif" alt="Twist.gif" class=" img-fluid img-markdown" /></p>
]]></description><link>http://developers.maxon.net/forum/post/76649</link><guid isPermaLink="true">http://developers.maxon.net/forum/post/76649</guid><dc:creator><![CDATA[Kantronin]]></dc:creator><pubDate>Mon, 30 Jun 2025 15:36:16 GMT</pubDate></item><item><title><![CDATA[Reply to I want to extract the polygon index of the inverted normal on Mon, 26 Aug 2024 07:54:48 GMT]]></title><description><![CDATA[<p dir="auto">Hi <a class="plugin-mentions-user plugin-mentions-a" href="/forum/user/ceen">@<bdi>ceen</bdi></a>, the only option available natively in Cinema 4D is the Align Normal but this change the normal, sadly there is no way to only select the inverted normal polygons.</p>
<p dir="auto">With that's said please for any feature request, contact the <a href="https://support.maxon.net/hc/en-us/requests/new" target="_blank" rel="noopener noreferrer nofollow ugc">Cinema 4D Support Center</a>.<br />
Cheers,<br />
Maxime.</p>
]]></description><link>http://developers.maxon.net/forum/post/74822</link><guid isPermaLink="true">http://developers.maxon.net/forum/post/74822</guid><dc:creator><![CDATA[m_adam]]></dc:creator><pubDate>Mon, 26 Aug 2024 07:54:48 GMT</pubDate></item><item><title><![CDATA[Reply to I want to extract the polygon index of the inverted normal on Sun, 25 Aug 2024 19:07:58 GMT]]></title><description><![CDATA[<p dir="auto">Hi,<br />
can you please implement a function into C4D to select blue/inverted normal polygons? We all need it regularly to fix CAD import etc. It is really important. Align function fails too often</p>
]]></description><link>http://developers.maxon.net/forum/post/74818</link><guid isPermaLink="true">http://developers.maxon.net/forum/post/74818</guid><dc:creator><![CDATA[ceen]]></dc:creator><pubDate>Sun, 25 Aug 2024 19:07:58 GMT</pubDate></item><item><title><![CDATA[Reply to I want to extract the polygon index of the inverted normal on Tue, 02 Jul 2024 10:16:30 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/forum/user/ferdinand">@<bdi>ferdinand</bdi></a> This is the feature I wanted. Thank you for your help!</p>
]]></description><link>http://developers.maxon.net/forum/post/74529</link><guid isPermaLink="true">http://developers.maxon.net/forum/post/74529</guid><dc:creator><![CDATA[seora]]></dc:creator><pubDate>Tue, 02 Jul 2024 10:16:30 GMT</pubDate></item><item><title><![CDATA[Reply to I want to extract the polygon index of the inverted normal on Tue, 02 Jul 2024 07:27:05 GMT]]></title><description><![CDATA[<p dir="auto">Hello <a class="plugin-mentions-user plugin-mentions-a" href="/forum/user/chuanzhen">@<bdi>chuanzhen</bdi></a>,</p>
<p dir="auto">Good catch! Yes, Cinema uses a <a href="https://en.wikipedia.org/wiki/Right-hand_rule" target="_blank" rel="noopener noreferrer nofollow ugc">left-handed coordinate system</a>, I simply misspoke/typed. I have fixed that (and also that I used the vertex index <code>d</code> twice in the diagram).</p>
<p dir="auto">Cheers,<br />
Ferdinand</p>
]]></description><link>http://developers.maxon.net/forum/post/74527</link><guid isPermaLink="true">http://developers.maxon.net/forum/post/74527</guid><dc:creator><![CDATA[ferdinand]]></dc:creator><pubDate>Tue, 02 Jul 2024 07:27:05 GMT</pubDate></item><item><title><![CDATA[Reply to I want to extract the polygon index of the inverted normal on Tue, 02 Jul 2024 02:24:46 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/forum/user/ferdinand">@<bdi>ferdinand</bdi></a> In the code description in the previous text, it was described as using a <strong>right-hand coordinate system</strong>, but the Python SDK doc described using a <strong>left-hand coordinate system</strong>, which I have some doubts about it.</p>
<blockquote>
<p dir="auto">...Cinema 4D uses a right-handed coordinate system....</p>
</blockquote>
<p dir="auto"><img src="/forum/assets/uploads/files/1719886541514-e1251f68-39cb-4fa1-afad-c228186a5cda-image.png" alt="e1251f68-39cb-4fa1-afad-c228186a5cda-image.png" class=" img-fluid img-markdown" /><br />
<img src="/forum/assets/uploads/files/1719886799462-9be9aeaf-d6c0-4304-86f5-7ad4ced44430-image.png" alt="9be9aeaf-d6c0-4304-86f5-7ad4ced44430-image.png" class=" img-fluid img-markdown" /></p>
]]></description><link>http://developers.maxon.net/forum/post/74526</link><guid isPermaLink="true">http://developers.maxon.net/forum/post/74526</guid><dc:creator><![CDATA[chuanzhen]]></dc:creator><pubDate>Tue, 02 Jul 2024 02:24:46 GMT</pubDate></item><item><title><![CDATA[Reply to I want to extract the polygon index of the inverted normal on Tue, 02 Jul 2024 08:43:02 GMT]]></title><description><![CDATA[<p dir="auto">Hey <a class="plugin-mentions-user plugin-mentions-a" href="/forum/user/seora">@<bdi>seora</bdi></a>,</p>
<p dir="auto">The somewhat trick to solve your problem is to step away from the notion of figuring out "which polygons are inverted" and instead ask which polygons are not aligned, or in other words compute two groups of polygons for a mesh, one group which is facing into "one direction", and one which is facing into the "other direction". You can then simply align the smaller group with larger one by flipping the winding direction of each polygon.</p>
<p dir="auto">When you use Cinema's built-in align tool, you will see that it will do exactly do that, it always aligns the smaller group with the bigger one. With ray casting one can also figure out which group is the "right-one", but that would be different subject. The underlying topological identity is one of the fundamental things in Computer Graphics, but since this is not the first time this has been asked, I wrote a small example. You will have to go the rest of the way yourself, as this is out of scope of support.</p>
<p dir="auto">Cheers,<br />
Ferdinand</p>
<h4>Input</h4>
<p dir="auto"><img src="/forum/assets/uploads/files/1719847899593-a3fe5529-71fd-40a9-aa6b-6b32875a297a-image.png" alt="a3fe5529-71fd-40a9-aa6b-6b32875a297a-image.png" class=" img-fluid img-markdown" /></p>
<h4>Result</h4>
<pre><code class="language-txt">(0, True)
(1, True)
(2, True)
(3, True)
(4, True)
(5, True)
(6, False)
(7, True)
(8, False)
</code></pre>
<h4>Code</h4>
<pre><code class="language-py">"""Demonstrates how to "group" the facing direction of polygons in a polygon object.

To run the script, select a poly object with some flipped normals and execute the script. It will print 
out the facing direction of all polygons in the object as either True or False. The script will be 
very slow for objects with many polygons, and does not handle disconnected parts.

The notion of the facing, i.e., normal, of a polygon is determined by the cross product of two edges
of the polygon (assuming a triangle). The cross product in its quality of either pointing upwards or 
downwards from the plane spanned by its two input vectors is dependent on the handedness of the
coordinate system. Cinema 4D uses a left-handed coordinate system, which in effect means that 
polygons must organize their vertices in a clockwise fashion (winding-order) to be considered 
front-facing for a top-down observer as shown in Fig.I (we look in 3D "down" on these polygons).

                                    a- → -b b- → -e
                                    |     | |     |
                                    ↑  P  ↓ ↑  Q  ↓
                                    |     | |     |
                                    d- ← -c c- ← -f 

                                         Fig. I

As shown, the polygon P is ordering its vertices in a clockwise fashion (a, b, c, d). This does not 
mean that a is the vertex with the index 0, it could for example be the 99th vertex, it just means
that P orders its vertices in this manner. The polygon must also not index its vertices in this 
exact order to be front facing, (b, c, d, a) is for example also a valid ordering. Important is only 
the name giving (clockwise) winding-order/direction. This is all related to the cross product, which
is used to determine the normal of a polygon. See the reference below for more information.

When we want to maintain this winding order for a polygon Q which shares the edge (b, c) with P, 
the point order of that edge must be reversed, i.e., become (c, b), to maintain the clockwise winding.
This also becomes visible in Fig.I, because for P (b, c) is the "right" edge and for Q (c, b) is the
"left" edge. 

So, while the notion of clockwise and counter-clockwise is somewhat fuzzy as we have to determine
for that what is a top-down observer, we can easily determine if two polygons are aligned by checking 
their shared edge. When the points of an edge E shared between the polygons P and Q are appearing in 
the same order in both polygons, the normals are misaligned. When the points appear in the opposite 
order, the normals of the polygons are aligned.

Reference:
    https://github.com/PluginCafe/cinema4d_py_sdk_extended/blob/master/scripts/04_3d_concepts/
    modeling/geometry/geometry_polygonobject_s26.py

WARNING:
    This is everything but production code. I deliberately wrote this with a for loop nested in a
    while loop to keep the code simple and to show the basic concept. This results in a rather
    nasty exponential time complexity in the worst case. In production code, you should use c4d.utils.
    Neighbor.GetEdgePolys and a more complex lookup table to consume all polygons.
"""

import c4d
from mxutils import CheckType

doc: c4d.documents.BaseDocument  # The currently active document.
op: c4d.BaseObject | None  # The primary selected object in `doc`. Can be `None`.

def GetEdgePairs(poly: c4d.CPolygon) -&gt; list[tuple[int&rsqb;&rsqb;:
    """Returns a list of edge pairs for the given polygon.
    """
    return ([(poly.a, poly.b), (poly.b, poly.c), (poly.c, poly.d), (poly.d, poly.a)] 
            if poly.c != poly.d else 
            [(poly.a, poly.b), (poly.b, poly.c), (poly.c, poly.a)])

def main() -&gt; None:
    """Called by Cinema 4D when the script is being executed.
    """
    CheckType(op, c4d.PolygonObject)

    # Get all polygons from the object.
    polygons: list[c4d.CPolygon] = op.GetAllPolygons()
    if not polygons:
        raise ValueError("No polygons found.")

    # Create a lookup table for polygons and edges to store their facing direction. We simply declare
    # the first polygon as True. With ray-casting one can figure out the "true" facing direction of
    # a polygon. But all we are after here, is to group all polygons into two groups of "one" and
    # "other" facing polygons. Which of these is front or back facing is not important for us here.
    polyLookup: dict[int, bool] = { 0: True }
    edgeLookup: dict[tuple[int], bool] = { (a, b): True for a, b in GetEdgePairs(polygons[0]) }

    # Now iterate over all polygons and determine their facing direction. We could use here c4d.utils.
    # Neighbor.GetEdgePolys to more cleverly consume all polygons, I went here for a brute force 
    # approach to keep the code simple. This has a rather nasty time complexity, use GetEdgePolys 
    # in production code.

    # While we have not found a facing direction for all polygons ...
    found: bool = True
    while len(polygons) &gt; len(polyLookup):
        # This is an exit condition for meshes with multiple islands. I just exit once we
        # have consumed the first island, in production code we would have to "jump" to the
        # next island and continue the search.
        if not found:
            break

        # ... we iterate over all polygons, skipping those we have already processed, ...
        found = False
        for i, poly in enumerate(polygons):
            if i in polyLookup:
                continue
            # ... to find polygons which have edges we have encountered before.
            for a, b in GetEdgePairs(poly):
                facing: bool | None = None
                # The edge appears in the same order in both polygons, they are misaligned, we
                # must invert the stored facing direction for this polygon.
                if (a, b) in edgeLookup:
                    facing = not edgeLookup[(a, b)]
                # The edge appears in the inverted order in the polygons, they are aligned, we
                # can keep the facing direction of the other polygon for this polygon.
                elif (b, a) in edgeLookup:
                    facing = edgeLookup[(b, a)]

                if facing is None:
                    continue
                
                # When we have found a facing direction for the polygon, we update our edge lookup with 
                # the facing direction. One could write this a bit nicer, as we store at least one
                # edge twice (because we found one edge in another polygon), but I kept this simple.
                for a, b in GetEdgePairs(poly):
                    edgeLookup[(a, b)] = facing

                # And we store our final output, the facing direction of the polygon.
                polyLookup[i] = facing
                found = True
                break
    
    # Print the results.
    for item in polyLookup.items():
        print (item)


if __name__ == '__main__':
    main()
</code></pre>
]]></description><link>http://developers.maxon.net/forum/post/74525</link><guid isPermaLink="true">http://developers.maxon.net/forum/post/74525</guid><dc:creator><![CDATA[ferdinand]]></dc:creator><pubDate>Tue, 02 Jul 2024 08:43:02 GMT</pubDate></item><item><title><![CDATA[Reply to I want to extract the polygon index of the inverted normal on Mon, 01 Jul 2024 10:59:51 GMT]]></title><description><![CDATA[<p dir="auto"><a class="plugin-mentions-user plugin-mentions-a" href="/forum/user/i_mazlov">@<bdi>i_mazlov</bdi></a> Thank you for providing a lot of data! I'll try</p>
]]></description><link>http://developers.maxon.net/forum/post/74524</link><guid isPermaLink="true">http://developers.maxon.net/forum/post/74524</guid><dc:creator><![CDATA[seora]]></dc:creator><pubDate>Mon, 01 Jul 2024 10:59:51 GMT</pubDate></item><item><title><![CDATA[Reply to I want to extract the polygon index of the inverted normal on Fri, 28 Jun 2024 15:21:52 GMT]]></title><description><![CDATA[<p dir="auto">Hi <a class="plugin-mentions-user plugin-mentions-a" href="/forum/user/seora">@<bdi>seora</bdi></a>,</p>
<p dir="auto">Please keep in mind that according to our <a href="https://developers.maxon.net/forum/topic/15244/support-procedures/3?_=1719586480069" target="_blank" rel="noopener noreferrer nofollow ugc">Support Procedures</a>:</p>
<blockquote>
<p dir="auto">"We cannot provide support for the math and computer science that stands behind them."</p>
</blockquote>
<p dir="auto">As for your question, to find out the normal direction of the polygon you need to look at the so-called winding order, namely the order of the polygon vertices. Searching the forum gives you this posting with a little more detailed explanation: <a href="https://developers.maxon.net/forum/topic/14324/how-to-detectflip-normals-of-object-inwardoutward/3" target="_blank" rel="noopener noreferrer nofollow ugc">https://developers.maxon.net/forum/topic/14324/how-to-detectflip-normals-of-object-inwardoutward/3</a></p>
<p dir="auto">If you just need to flip these polygons you are welcome to execute <a href="https://developers.maxon.net/docs/py/2024_4_0a/modules/c4d.utils/index.html?highlight=sendmodelingcommand#c4d.utils.SendModelingCommand" target="_blank" rel="noopener noreferrer nofollow ugc">SendModelingCommand</a> with the <a href="https://developers.maxon.net/docs/py/2024_4_0a/consts/MCOMMAND.html?highlight=mcommand_alignnormals" target="_blank" rel="noopener noreferrer nofollow ugc">c4d.MCOMMAND_ALIGNNORMALS</a> command id.</p>
<p dir="auto">Cheers,<br />
Ilia</p>
]]></description><link>http://developers.maxon.net/forum/post/74519</link><guid isPermaLink="true">http://developers.maxon.net/forum/post/74519</guid><dc:creator><![CDATA[i_mazlov]]></dc:creator><pubDate>Fri, 28 Jun 2024 15:21:52 GMT</pubDate></item></channel></rss>