[SOLVED/NotABug] Bug with c4d.CPolygon
-
Cinema 4D Version: R21
OS: Windows 10UPDATE: Not a bug, the CPolygon determines whether it's a triangle by checking if c == d.
Setting the 'c' component of a triangle CPolygon to anything other than 0 will cause the CPolygon to no longer be a triangle.
Foo = c4d.CPolygon(0, 1, 2) Foo.IsTriangle() # True Foo.c = 0 Foo.IsTriangle() # True Foo.c = 5 Foo.IsTriangle() # FalseEDIT: The problem also occurs with the C++ sdk, and also occurs if you set 'c' to 0.
CPolygon x( 0, 1, 2 ); x.IsTriangle(); // True x.c = 0; x.IsTriangle(); // False -
Of course not. If you change the c attribute, then c will no longer be equal to d, and it becomes a quadrangle.
To be more precise: A polygon object always has 4 corner points in form of point indices a,b,c,d. If the corners c and d are equal, then Cinema handles it as a triangle.
In your code, you create a triangle by setting the corners to the points 0, 1, 2. Corner d will automatically also be 2, since you didn't specify otherwise (print Foo.d to verify). So actually you get the CPolygon (0,1,2,2). This is a triangle.
Then you set c to 0, resulting in the CPolygon (0,1,0,2). This is a quadrangle (albeit a degenerated one). In your code, you comment
# Truebut actually that's wrong, you get False. (I just tried.)Then you set c to 5, resulting in the CPolygon (0,1,5,2). This is a proper quadrangle.
It would be easier to see if you had actual geometry attached to the points, instead of just having the indices.
-
I see, sorry for the confusion, thanks for the reply!
I was under the assumption that the CPolygon would stay as a triangle until you changed the 'd' attribute, in hindsight I realize why that wouldn't be the case (d is a property and isn't being set by a function). As for the improper True comment, I must have set 'd' to zero while testing and missed that while copying back the code, my bad.
-
@xNWP Yeah, a CPolygon is really just those four corner indices, a,b,c,d - there is no separate flag that would tell C4D whether this is a triangle or a quadrangle. The information what type of polygon the CPolygon is, is really only encoded in the equality c==d. The function IsTriangle could be written as
def IsTriangle(self): return self.c == self.dI assume you have read
https://developers.maxon.net/docs/py/2023_2/manuals/3d_concept/modeling/polygon_object.html#polygon-object
already, although that doesn't go in depth into the triangle property.(It gets even better when you come to edge indices: a triangle has edges ab, bc, da - not cd obviously, but also not ca!)
Learn more about Python for C4D scripting:
https://www.patreon.com/cairyn -
Hi @xNWP,
thank you for reaching out us. No need to be sorry, new APIs can sometimes be a bit confusing
And thank you @Cairyn for jumping in and answering the question correctly.I just wanted to point out that
a,b,canddof aCPolygonare not properties, but just fields, there is very little special going on with the whole entity, also indicated by it being astructin C++. The advantage of this design, i.e., also expressing tris as quads, is that you can often neglect checking if a polygon is a tri or quad and thereby optimize out branching.E.g.: You can always compute the arithmetic mean of the vertices of a.Cpolygonby computing(pnts[cpoly.a] + pnts[cpoly.b] + pnts[cpoly.c] + pnts[cpoly.d]) * .25, without having to worry if it is a tri or quadPlease note that we also have a ask-as-a-question feature in the forum which we would prefer you using instead of doing it manually.
Cheers,
Ferdinand -
E.g.: You can always compute the arithmetic mean of the vertices of a Cpolygon by computing (pnts[cpoly.a] + pnts[cpoly.b] + pnts[cpoly.c] + pnts[cpoly.d]) * .25, without having to worry if it is a tri or quad.
I tend to disagree here. In a triangle, the arithmetic center should only consider the first three vertices. Doubling the last vertex leads to a different (weighted) result. E.g. reduced to one axis:
1 + 2 + 9 = 12, divided by 3 results in 4
1 + 2 + 9 + 9 = 21, divided by 4 results in 5.25 -
Hi @Cairyn,
you are absolutely right, thanks for catching that, wasn't paying attention this morning. But I would still say that this design can has its advantages where one can optimize out some branching, .e.g. when computing a normal for
a x d(quad) ora x c(tri), where you then can just always computea x d.Cheers,
Ferdinand -
Thanks for all the extra info guys! I'll make sure to use the ask-as-a-question feature next time
