[SOLVED/NotABug] Bug with c4d.CPolygon
xNWP last edited by xNWP
Cinema 4D Version: R21
OS: Windows 10
UPDATE: 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() # False
EDIT: 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.
xNWP last edited by xNWP
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.d
I assume you have read
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:
ferdinand last edited by ferdinand
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
CPolygonare not properties, but just fields, there is very little special going on with the whole entity, also indicated by it being a
structin 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.
(pnts[cpoly.a] + pnts[cpoly.b] + pnts[cpoly.c] + pnts[cpoly.d]) * .25, without having to worry if it is a tri or quad
Please 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.
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
ferdinand last edited by
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) or
a x c(tri), where you then can just always compute
a x d.
xNWP last edited by
Thanks for all the extra info guys! I'll make sure to use the ask-as-a-question feature next time :)