hi,
In c4d there is no edge, edges are just defined by being connected between two points.
After trying a lot of things i finally found something that looks to work.
It is a combinaison of many ideas. The idea is to count the number of times a point is present on a polygon and the number of times this point is present on a ngon's edge. Make the difference and just keep the point that have a difference of 2 so this point is connected to only two edges.
from typing import Optional
import c4d
doc: c4d.documents.BaseDocument # The active document
op: Optional[c4d.BaseObject] # The active object, None if unselected
# Tries to get the points that are only connected to two edge and part of NGons
def main() -> None:
polys = op.GetAllPolygons()
# GetNgonEdgesCompact will give a list of value for each polygon.
# Those correspond to a binary value where 1 mean the edge is part of an ngon
# and 0 mean no. Be careful that for Triangle edge 2 must not be taken into account.
# edge 3 2 1 0
# - - - - = 0
# - - - x = 1
# - - x - = 2
# - - x x = 3
# - x - - = 4
# - x - x = 5
# - x x - = 6
# - x x x = 7
# x - - - = 8
# x - - x = 9
# x - x - = 10
# x - x x = 11
# x x - - = 12
# x x - x = 13
# x x x - = 14
# x x x x = 15
ngonEC = op.GetNgonEdgesCompact()
pointCount = op.GetPointCount()
# Array allowing to count, for each point, the number of time this point is present in an polygon
# and the number of time this point is present in an ngon edge.
pointNgonDict = {}
pointPolyDict = {}
answer = []
for index in range(0, pointCount):
pointNgonDict[index] = 0
pointPolyDict[index] = 0
# Prepare a neighbor object so we can check if the edge is marked or not avoiding
# to count mutiple time an edge
nb = c4d.utils.Neighbor()
nb.Init(op)
# For each polygon
for polyIndex, cPoly in enumerate(polys):
pli = nb.GetPolyInfo(polyIndex)
# mark those points as part of the polygon
pointPolyDict[cPoly.a] += 1
pointPolyDict[cPoly.b] += 1
pointPolyDict[cPoly.c] += 1
if cPoly.IsTriangle():
# here the edge are really 0, 1, 3 we do not use 2.
for edgeIndex in [0, 1, 3]:
# To avoid counting twice an edge only check those that are marked as false.
if pli["mark"][edgeIndex] == False:
# If the bit of this edge is set to 1, that mean this edge is on a ngon
if ngonEC[polyIndex] & (1 << edgeIndex):
p1, p2 = cPoly.EdgePoints(edgeIndex)
pointNgonDict[p1] += 1
pointNgonDict[p2] += 1
else:
# we include the fourth point.
pointPolyDict[cPoly.d] +=1
# same as the triangle but with all index 0, 1, 2, 3
for edgeIndex in [0, 1, 2, 3]:
if pli["mark"][edgeIndex] == False:
if ngonEC[polyIndex] & (1 << edgeIndex):
p1, p2 = cPoly.EdgePoints(edgeIndex)
pointNgonDict[p1] += 1
pointNgonDict[p2] += 1
# We calculate the difference between those two array and put in the result
# array only points index that are
# in 2 more polygons than the number of edge present on a ngon this point is part of.
for i, (j, k) in enumerate(zip(pointPolyDict.values(), pointNgonDict.values())):
# Check i the point is at least in one ngon with k > 0
if k > 0 andj - k == 2:
answer.append(i)
print (pointNgonDict)
print (pointPolyDict)
print(answer)
if __name__ == '__main__':
main()
Cheers,
Manuel