select edge points with python
-
hi there,
with mech check, there is the option to select all "edge points"
these are all points that are only connected to two eges. these points can be found on at the border or between two n-gones.i'd like to select and delete them with pyhon.
i was looking into the Neighbor() function. but it seems quite tricky, since neighbor seems to ignore n-gones and dissolves them internally.
alternatively, is there any chance to send a modeling command to mesh check or simulate a mouse click on the select button?
any ideas or hints are wellcome!
-
Hi,
Instead of reinventing the wheel, as you said, you can use the already existing function. This can be triggered by sending the right message the the SceneHook that is responsable to this mesh check tool. The only thing you need is to build a DescriptionCommand that just need to have its
_descId
defined.The scenehook ID is not available you have to define it. The message ID that correspond to the button clicked can be found in our documentation.
As DescriptionCommand is not available in python, it is not possible to do that using Python. I am afraid there is no solution neither checking yourself as ngon management in python is not possible.
#include "lib_description.h" #include "dmodeling.h" #define ID_MESHCHECK 431000027 static maxon::Result<void> PC14455(BaseDocument* doc) { iferr_scope; BaseSceneHook* meshHook = doc->FindSceneHook(ID_MESHCHECK); if (meshHook) { DescriptionCommand dcu; dcu._descId = MESH_CHECK_EDGEPOINT_SELECT; meshHook->Message(MSG_DESCRIPTION_COMMAND, &dcu); } return maxon::OK; }
Cheers,
Manuel -
hi manuel,
thanks for the response, the info and the code example!
sadly i have absolutely no idea how to handle c++ at allconcerning python and ngons:
it is possible to select all polygons or edges involved with ngons. it works here.
i'm struggling to find the specific edge-ids of the hiddn ngone-edges or the point-ids of these hidden edges.
if i had the point ids i would be able to make it work.
is there any way to distinguish visible and invisible edges of ngons?
or is this what you ment with "ngon management in python is not possible"? -
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 -
wohaa, thank you so much for your time an effort!
i will have a good look at it.
alos great insight into what the GetNgonEdgesCompact numbers mean. this was a bit mysterious in the sdk, or at least hard to decipher what the description meant.
-