Get edges segments in a polygon object

Hi!
I'm trying to find the selected edges segments in a polygon object, like the one below:
I want to get each segment separated, so I can create some functions like the example below:
for segment in segmentlist: MoveInUvSpace()
I've tried a lot of things with
BaseSelect
,Neighbor
andPolygonObject
classes, but no success...here's my testing code, I was able to get the total edge count, get the ammount of edges selected edges and get the the selected edge with its index.
import c4d def main(): op = doc.GetActiveObject() nb = c4d.utils.Neighbor() nb.Init(op) seledges = op.GetSelectedEdges(nb,c4d.EDGESELECTIONTYPE_SELECTION) #base select print seledges.GetSegments() print seledges.GetCount() print seledges.GetRange(1,nb.GetEdgeCount()) print "total edges", nb.GetEdgeCount() notselected = [] selectededge = [] bs = op.GetEdgeS() sel = bs.GetAll(nb.GetEdgeCount()) for index, selected in enumerate(sel): if not selected: continue print "Index", index, "is selected" selectededge.append(selected) print notselected print selected if __name__=='__main__': main()
if anyone have any hint in how I could achieve this, I would be very happy!
Flavio Diniz

hello,
i gave it a try and came with that "solution", i just ran some test on a plane but that should give you some idea.
this would need some polish like ordering the points in the result and it can probably be optimized.I've set this thread to "ask a question" please set it as solved if you think your question as been replied (even if there's no solution :p)
Of course this will consider a "cross" as one single segment
import c4d from c4d import gui # Welcome to the world of Python class MySegments (object): def __init__(self, op): if op is None: raise ValueError("can't initialize class with a None object") if op.IsInstanceOf(c4d.Opolygon) != True: raise ValueError("class only work with polygon object") self.op = op self.nb = c4d.utils.Neighbor() self.nb.Init(op) self.polys = op.GetAllPolygons() self.edgeSelected = op.GetEdgeS() self.ces = self.edgeSelected.GetClone() self.segments = [] def CreateSegment(self, polyAid, edgeAid): """ Recursive function that will check if any neighbor edge is selected If so, it will recurse with the new edge. """ # first deselect edge so we are sure we are not adding this edge twice self.DeselectEdge(polyAid, edgeAid) # retrieves the points of this edge points = self.polys[polyAid].EdgePoints(edgeAid) # add this edge to the last segment self.segments[1].append(points) # for each point, check if any attached edge is selected for point in points: neibPolysIds = self.nb.GetPointPolys(point) for polyBid in neibPolysIds: for edgeBid in xrange(4): if self.ces.IsSelected(4 * polyBid + edgeBid): # checks if any point are in common if self.PointInCommon(polyAid, edgeAid, polyBid, edgeBid): # this edge must be added to the last segment and check for the next edges. self.CreateSegment(polyBid, edgeBid) def PointInCommon(self, polyAid, edgeAid, polyBid, edgeBid): """ this function check if two edge have some point in common""" polyA = self.op.GetPolygon(polyAid) polyB = self.op.GetPolygon(polyBid) edgeAPoints = polyA.EdgePoints(edgeAid) edgeBPoints = polyB.EdgePoints(edgeBid) if edgeAPoints[0] == edgeBPoints[0] or edgeAPoints[0] == edgeBPoints[1]: return True if edgeAPoints[1] == edgeBPoints[0] or edgeAPoints[1] == edgeBPoints[1]: return True return False def ComparePoints(self, pointsA, pointsB): """ This function compare if two array of points are equals """ if pointsA[0] == pointsB[0] and pointsA[1] == pointsB[1]: return True if pointsA[1] == pointsB[0] and pointsA[0] == pointsB[1]: return True return False def DeselectEdge(self, polyAid, edgeAid): """ The BaseSelect we got from GetEdgeS will have two entry for one selected edge (on per polygon) we must retrieve the other polygon and find the edge in common to deselect it. """ # Deselect the first edge. self.ces.Deselect(4 * polyAid + edgeAid) # Gets the poinfs from edge A id pointsA = self.polys[polyAid].EdgePoints(edgeAid) # Retrieves the polygin ID of the polygon on the other side of the edge polyBid = self.nb.GetNeighbor(pointsA[0], pointsA[1], polyAid) #checks if there's no polygon on the other side if polyBid == 1: return # Get the polygon Structure polyB = self.op.GetPolygon(polyBid) # Check each edge if it's the same than the firt edge and deselect it. for edgeBid in xrange(4): pointsB = polyB.EdgePoints(edgeBid) if self.ComparePoints(pointsA, pointsB): self.ces.Deselect(4 * polyBid + edgeBid) def Execute(self): segments = [] polycnt = self.op.GetPolygonCount() for polyid in xrange(polycnt): for edgeid in xrange(4): element = 4 * polyid + edgeid # checks if the edge is selected if self.ces.IsSelected(element): # create a new segment for this edge self.segments.append([]) # the function CreateSegment will add this edge and search for any other edge attached to that edge. self.CreateSegment(polyid, edgeid) print self.segments def main(): if op is None: raise ValueError("select at least one object") mySegments = MySegments(op) mySegments.Execute() # Execute main() if __name__=='__main__': main()
cheers,
Manuel

I don't think there is such a thing as a "edge segment". There are only individually selected edges. How such single edges are combined to a "segment" is up to you.
I also think one would probably need the GetOriginalEdgePoints() function of the Modeling class, which is not available in Python.

As far as I know your only option would be to collect your "segments" yourself. At least, that is how I have been doing it.

@PluginStudent @C4DS
ah, so I think this is more complex than I thoughtI guess I have to make a function to compare the edges by using their points...
if two edges shares the same point, it means these two edges are a single segment. So create a BaseSelect of these edges and use it in afor
loop.
It may cause some bugs depending how the geometry is... but at least is a starting point and a tough one for me xDThank you guys!
Flavio Diniz

hello,
i gave it a try and came with that "solution", i just ran some test on a plane but that should give you some idea.
this would need some polish like ordering the points in the result and it can probably be optimized.I've set this thread to "ask a question" please set it as solved if you think your question as been replied (even if there's no solution :p)
Of course this will consider a "cross" as one single segment
import c4d from c4d import gui # Welcome to the world of Python class MySegments (object): def __init__(self, op): if op is None: raise ValueError("can't initialize class with a None object") if op.IsInstanceOf(c4d.Opolygon) != True: raise ValueError("class only work with polygon object") self.op = op self.nb = c4d.utils.Neighbor() self.nb.Init(op) self.polys = op.GetAllPolygons() self.edgeSelected = op.GetEdgeS() self.ces = self.edgeSelected.GetClone() self.segments = [] def CreateSegment(self, polyAid, edgeAid): """ Recursive function that will check if any neighbor edge is selected If so, it will recurse with the new edge. """ # first deselect edge so we are sure we are not adding this edge twice self.DeselectEdge(polyAid, edgeAid) # retrieves the points of this edge points = self.polys[polyAid].EdgePoints(edgeAid) # add this edge to the last segment self.segments[1].append(points) # for each point, check if any attached edge is selected for point in points: neibPolysIds = self.nb.GetPointPolys(point) for polyBid in neibPolysIds: for edgeBid in xrange(4): if self.ces.IsSelected(4 * polyBid + edgeBid): # checks if any point are in common if self.PointInCommon(polyAid, edgeAid, polyBid, edgeBid): # this edge must be added to the last segment and check for the next edges. self.CreateSegment(polyBid, edgeBid) def PointInCommon(self, polyAid, edgeAid, polyBid, edgeBid): """ this function check if two edge have some point in common""" polyA = self.op.GetPolygon(polyAid) polyB = self.op.GetPolygon(polyBid) edgeAPoints = polyA.EdgePoints(edgeAid) edgeBPoints = polyB.EdgePoints(edgeBid) if edgeAPoints[0] == edgeBPoints[0] or edgeAPoints[0] == edgeBPoints[1]: return True if edgeAPoints[1] == edgeBPoints[0] or edgeAPoints[1] == edgeBPoints[1]: return True return False def ComparePoints(self, pointsA, pointsB): """ This function compare if two array of points are equals """ if pointsA[0] == pointsB[0] and pointsA[1] == pointsB[1]: return True if pointsA[1] == pointsB[0] and pointsA[0] == pointsB[1]: return True return False def DeselectEdge(self, polyAid, edgeAid): """ The BaseSelect we got from GetEdgeS will have two entry for one selected edge (on per polygon) we must retrieve the other polygon and find the edge in common to deselect it. """ # Deselect the first edge. self.ces.Deselect(4 * polyAid + edgeAid) # Gets the poinfs from edge A id pointsA = self.polys[polyAid].EdgePoints(edgeAid) # Retrieves the polygin ID of the polygon on the other side of the edge polyBid = self.nb.GetNeighbor(pointsA[0], pointsA[1], polyAid) #checks if there's no polygon on the other side if polyBid == 1: return # Get the polygon Structure polyB = self.op.GetPolygon(polyBid) # Check each edge if it's the same than the firt edge and deselect it. for edgeBid in xrange(4): pointsB = polyB.EdgePoints(edgeBid) if self.ComparePoints(pointsA, pointsB): self.ces.Deselect(4 * polyBid + edgeBid) def Execute(self): segments = [] polycnt = self.op.GetPolygonCount() for polyid in xrange(polycnt): for edgeid in xrange(4): element = 4 * polyid + edgeid # checks if the edge is selected if self.ces.IsSelected(element): # create a new segment for this edge self.segments.append([]) # the function CreateSegment will add this edge and search for any other edge attached to that edge. self.CreateSegment(polyid, edgeid) print self.segments def main(): if op is None: raise ValueError("select at least one object") mySegments = MySegments(op) mySegments.Execute() # Execute main() if __name__=='__main__': main()
cheers,
Manuel

Fantastic @m_magalhaes !
works very well! and for the use I'm planning, I will always be using parallel selection segments, so cross selections isn't a issue !there's an small error, I guess it's happening because there's no polygons to the left to be checked.
I haven't had time to fully read your code yet, but it's already very helpful!
I'll try to solve this error by modifying your code or building another use using you as base.Thank you!
(I'll let it unsolved for today, in case someone wants to post something else, then I'll change to solved)
Flavio Diniz

hi,
right, if you are at a border there's not polygon on the other side:
i've update my code on the other post with this
if polyBid == 1: return
Cheers,
Manuel

Awesome @m_magalhaes, works perfect now!
Thank very much!Flavio