Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'release/scripts/freestyle/style_modules/ChainingIterators.py')
-rw-r--r--release/scripts/freestyle/style_modules/ChainingIterators.py726
1 files changed, 726 insertions, 0 deletions
diff --git a/release/scripts/freestyle/style_modules/ChainingIterators.py b/release/scripts/freestyle/style_modules/ChainingIterators.py
new file mode 100644
index 00000000000..5ef4b9c61dc
--- /dev/null
+++ b/release/scripts/freestyle/style_modules/ChainingIterators.py
@@ -0,0 +1,726 @@
+#
+# Filename : ChainingIterators.py
+# Author : Stephane Grabli
+# Date : 04/08/2005
+# Purpose : Chaining Iterators to be used with chaining operators
+#
+#############################################################################
+#
+# Copyright (C) : Please refer to the COPYRIGHT file distributed
+# with this source distribution.
+#
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+#
+#############################################################################
+
+from freestyle_init import *
+
+## the natural chaining iterator
+## It follows the edges of same nature following the topology of
+## objects with preseance on silhouettes, then borders,
+## then suggestive contours, then everything else. It doesn't chain the same ViewEdge twice
+## You can specify whether to stay in the selection or not.
+class pyChainSilhouetteIterator(ChainingIterator):
+ def __init__(self, stayInSelection=1):
+ ChainingIterator.__init__(self, stayInSelection, 1,None,1)
+ def getExactTypeName(self):
+ return "pyChainSilhouetteIterator"
+ def init(self):
+ pass
+ def traverse(self, iter):
+ winner = None
+ it = AdjacencyIterator(iter)
+ tvertex = self.next_vertex
+ if type(tvertex) is TVertex:
+ mateVE = tvertex.get_mate(self.current_edge)
+ while not it.is_end:
+ ve = it.object
+ if ve.id == mateVE.id:
+ winner = ve
+ break
+ it.increment()
+ else:
+ ## case of NonTVertex
+ natures = [Nature.SILHOUETTE,Nature.BORDER,Nature.CREASE,Nature.SUGGESTIVE_CONTOUR,Nature.VALLEY,Nature.RIDGE]
+ for i in range(len(natures)):
+ currentNature = self.current_edge.nature
+ if (natures[i] & currentNature) != 0:
+ count=0
+ while not it.is_end:
+ visitNext = 0
+ oNature = it.object.nature
+ if (oNature & natures[i]) != 0:
+ if natures[i] != oNature:
+ for j in range(i):
+ if (natures[j] & oNature) != 0:
+ visitNext = 1
+ break
+ if visitNext != 0:
+ break
+ count = count+1
+ winner = it.object
+ it.increment()
+ if count != 1:
+ winner = None
+ break
+ return winner
+
+## the natural chaining iterator
+## It follows the edges of same nature on the same
+## objects with preseance on silhouettes, then borders,
+## then suggestive contours, then everything else. It doesn't chain the same ViewEdge twice
+## You can specify whether to stay in the selection or not.
+## You can specify whether to chain iterate over edges that were
+## already visited or not.
+class pyChainSilhouetteGenericIterator(ChainingIterator):
+ def __init__(self, stayInSelection=1, stayInUnvisited=1):
+ ChainingIterator.__init__(self, stayInSelection, stayInUnvisited,None,1)
+ def getExactTypeName(self):
+ return "pyChainSilhouetteGenericIterator"
+ def init(self):
+ pass
+ def traverse(self, iter):
+ winner = None
+ it = AdjacencyIterator(iter)
+ tvertex = self.next_vertex
+ if type(tvertex) is TVertex:
+ mateVE = tvertex.get_mate(self.current_edge)
+ while not it.is_end:
+ ve = it.object
+ if ve.id == mateVE.id:
+ winner = ve
+ break
+ it.increment()
+ else:
+ ## case of NonTVertex
+ natures = [Nature.SILHOUETTE,Nature.BORDER,Nature.CREASE,Nature.SUGGESTIVE_CONTOUR,Nature.VALLEY,Nature.RIDGE]
+ for i in range(len(natures)):
+ currentNature = self.current_edge.nature
+ if (natures[i] & currentNature) != 0:
+ count=0
+ while not it.is_end:
+ visitNext = 0
+ oNature = it.object.nature
+ ve = it.object
+ if ve.id == self.current_edge.id:
+ it.increment()
+ continue
+ if (oNature & natures[i]) != 0:
+ if natures[i] != oNature:
+ for j in range(i):
+ if (natures[j] & oNature) != 0:
+ visitNext = 1
+ break
+ if visitNext != 0:
+ break
+ count = count+1
+ winner = ve
+ it.increment()
+ if count != 1:
+ winner = None
+ break
+ return winner
+
+class pyExternalContourChainingIterator(ChainingIterator):
+ def __init__(self):
+ ChainingIterator.__init__(self, 0, 1,None,1)
+ self._isExternalContour = ExternalContourUP1D()
+ def getExactTypeName(self):
+ return "pyExternalContourIterator"
+ def init(self):
+ self._nEdges = 0
+ self._isInSelection = 1
+ def checkViewEdge(self, ve, orientation):
+ if orientation != 0:
+ vertex = ve.second_svertex()
+ else:
+ vertex = ve.first_svertex()
+ it = AdjacencyIterator(vertex,1,1)
+ while not it.is_end:
+ ave = it.object
+ if self._isExternalContour(ave):
+ return 1
+ it.increment()
+ print("pyExternlContourChainingIterator : didn't find next edge")
+ return 0
+ def traverse(self, iter):
+ winner = None
+ it = AdjacencyIterator(iter)
+ while not it.is_end:
+ ve = it.object
+ if self._isExternalContour(ve):
+ if ve.time_stamp == GetTimeStampCF():
+ winner = ve
+ it.increment()
+
+ self._nEdges = self._nEdges+1
+ if winner is None:
+ orient = 1
+ it = AdjacencyIterator(iter)
+ while not it.is_end:
+ ve = it.object
+ if it.is_incoming:
+ orient = 0
+ good = self.checkViewEdge(ve,orient)
+ if good != 0:
+ winner = ve
+ it.increment()
+ return winner
+
+## the natural chaining iterator
+## with a sketchy multiple touch
+class pySketchyChainSilhouetteIterator(ChainingIterator):
+ def __init__(self, nRounds=3,stayInSelection=1):
+ ChainingIterator.__init__(self, stayInSelection, 0,None,1)
+ self._timeStamp = GetTimeStampCF()+nRounds
+ self._nRounds = nRounds
+ def getExactTypeName(self):
+ return "pySketchyChainSilhouetteIterator"
+ def init(self):
+ self._timeStamp = GetTimeStampCF()+self._nRounds
+ def traverse(self, iter):
+ winner = None
+ it = AdjacencyIterator(iter)
+ tvertex = self.next_vertex
+ if type(tvertex) is TVertex:
+ mateVE = tvertex.get_mate(self.current_edge)
+ while not it.is_end:
+ ve = it.object
+ if ve.id == mateVE.id:
+ winner = ve
+ break
+ it.increment()
+ else:
+ ## case of NonTVertex
+ natures = [Nature.SILHOUETTE,Nature.BORDER,Nature.CREASE,Nature.SUGGESTIVE_CONTOUR,Nature.VALLEY,Nature.RIDGE]
+ for i in range(len(natures)):
+ currentNature = self.current_edge.nature
+ if (natures[i] & currentNature) != 0:
+ count=0
+ while not it.is_end:
+ visitNext = 0
+ oNature = it.object.nature
+ ve = it.object
+ if ve.id == self.current_edge.id:
+ it.increment()
+ continue
+ if (oNature & natures[i]) != 0:
+ if (natures[i] != oNature) != 0:
+ for j in range(i):
+ if (natures[j] & oNature) != 0:
+ visitNext = 1
+ break
+ if visitNext != 0:
+ break
+ count = count+1
+ winner = ve
+ it.increment()
+ if count != 1:
+ winner = None
+ break
+ if winner is None:
+ winner = self.current_edge
+ if winner.chaining_time_stamp == self._timeStamp:
+ winner = None
+ return winner
+
+
+# Chaining iterator designed for sketchy style.
+# can chain several times the same ViewEdge
+# in order to produce multiple strokes per ViewEdge.
+class pySketchyChainingIterator(ChainingIterator):
+ def __init__(self, nRounds=3, stayInSelection=1):
+ ChainingIterator.__init__(self, stayInSelection, 0,None,1)
+ self._timeStamp = GetTimeStampCF()+nRounds
+ self._nRounds = nRounds
+ def getExactTypeName(self):
+ return "pySketchyChainingIterator"
+ def init(self):
+ self._timeStamp = GetTimeStampCF()+self._nRounds
+ def traverse(self, iter):
+ winner = None
+ it = AdjacencyIterator(iter)
+ while not it.is_end:
+ ve = it.object
+ if ve.id == self.current_edge.id:
+ it.increment()
+ continue
+ winner = ve
+ it.increment()
+ if winner is None:
+ winner = self.current_edge
+ if winner.chaining_time_stamp == self._timeStamp:
+ return None
+ return winner
+
+
+## Chaining iterator that fills small occlusions
+## percent
+## The max length of the occluded part
+## expressed in % of the total chain length
+class pyFillOcclusionsRelativeChainingIterator(ChainingIterator):
+ def __init__(self, percent):
+ ChainingIterator.__init__(self, 0, 1,None,1)
+ self._length = 0
+ self._percent = float(percent)
+ def getExactTypeName(self):
+ return "pyFillOcclusionsChainingIterator"
+ def init(self):
+ # each time we're evaluating a chain length
+ # we try to do it once. Thus we reinit
+ # the chain length here:
+ self._length = 0
+ def traverse(self, iter):
+ winner = None
+ winnerOrientation = 0
+ print(self.current_edge.id.first, self.current_edge.id.second)
+ it = AdjacencyIterator(iter)
+ tvertex = self.next_vertex
+ if type(tvertex) is TVertex:
+ mateVE = tvertex.get_mate(self.current_edge)
+ while not it.is_end:
+ ve = it.object
+ if ve.id == mateVE.id:
+ winner = ve
+ if not it.is_incoming:
+ winnerOrientation = 1
+ else:
+ winnerOrientation = 0
+ break
+ it.increment()
+ else:
+ ## case of NonTVertex
+ natures = [Nature.SILHOUETTE,Nature.BORDER,Nature.CREASE,Nature.SUGGESTIVE_CONTOUR,Nature.VALLEY,Nature.RIDGE]
+ for nat in natures:
+ if (self.current_edge.nature & nat) != 0:
+ count=0
+ while not it.is_end:
+ ve = it.object
+ if (ve.nature & nat) != 0:
+ count = count+1
+ winner = ve
+ if not it.is_incoming:
+ winnerOrientation = 1
+ else:
+ winnerOrientation = 0
+ it.increment()
+ if count != 1:
+ winner = None
+ break
+ if winner is not None:
+ # check whether this edge was part of the selection
+ if winner.time_stamp != GetTimeStampCF():
+ #print("---", winner.id.first, winner.id.second)
+ # if not, let's check whether it's short enough with
+ # respect to the chain made without staying in the selection
+ #------------------------------------------------------------
+ # Did we compute the prospective chain length already ?
+ if self._length == 0:
+ #if not, let's do it
+ _it = pyChainSilhouetteGenericIterator(0,0)
+ _it.begin = winner
+ _it.current_edge = winner
+ _it.orientation = winnerOrientation
+ _it.init()
+ while not _it.is_end:
+ ve = _it.object
+ #print("--------", ve.id.first, ve.id.second)
+ self._length = self._length + ve.length_2d
+ _it.increment()
+ if _it.is_begin:
+ break;
+ _it.begin = winner
+ _it.current_edge = winner
+ _it.orientation = winnerOrientation
+ if not _it.is_begin:
+ _it.decrement()
+ while (not _it.is_end) and (not _it.is_begin):
+ ve = _it.object
+ #print("--------", ve.id.first, ve.id.second)
+ self._length = self._length + ve.length_2d
+ _it.decrement()
+
+ # let's do the comparison:
+ # nw let's compute the length of this connex non selected part:
+ connexl = 0
+ _cit = pyChainSilhouetteGenericIterator(0,0)
+ _cit.begin = winner
+ _cit.current_edge = winner
+ _cit.orientation = winnerOrientation
+ _cit.init()
+ while _cit.is_end == 0 and _cit.object.time_stamp != GetTimeStampCF():
+ ve = _cit.object
+ #print("-------- --------", ve.id.first, ve.id.second)
+ connexl = connexl + ve.length_2d
+ _cit.increment()
+ if connexl > self._percent * self._length:
+ winner = None
+ return winner
+
+## Chaining iterator that fills small occlusions
+## size
+## The max length of the occluded part
+## expressed in pixels
+class pyFillOcclusionsAbsoluteChainingIterator(ChainingIterator):
+ def __init__(self, length):
+ ChainingIterator.__init__(self, 0, 1,None,1)
+ self._length = float(length)
+ def getExactTypeName(self):
+ return "pySmallFillOcclusionsChainingIterator"
+ def init(self):
+ pass
+ def traverse(self, iter):
+ winner = None
+ winnerOrientation = 0
+ #print(self.current_edge.id.first, self.current_edge.id.second)
+ it = AdjacencyIterator(iter)
+ tvertex = self.next_vertex
+ if type(tvertex) is TVertex:
+ mateVE = tvertex.get_mate(self.current_edge)
+ while not it.is_end:
+ ve = it.object
+ if ve.id == mateVE.id:
+ winner = ve
+ if not it.is_incoming:
+ winnerOrientation = 1
+ else:
+ winnerOrientation = 0
+ break
+ it.increment()
+ else:
+ ## case of NonTVertex
+ natures = [Nature.SILHOUETTE,Nature.BORDER,Nature.CREASE,Nature.SUGGESTIVE_CONTOUR,Nature.VALLEY,Nature.RIDGE]
+ for nat in natures:
+ if (self.current_edge.nature & nat) != 0:
+ count=0
+ while not it.is_end:
+ ve = it.object
+ if (ve.nature & nat) != 0:
+ count = count+1
+ winner = ve
+ if not it.is_incoming:
+ winnerOrientation = 1
+ else:
+ winnerOrientation = 0
+ it.increment()
+ if count != 1:
+ winner = None
+ break
+ if winner is not None:
+ # check whether this edge was part of the selection
+ if winner.time_stamp != GetTimeStampCF():
+ #print("---", winner.id.first, winner.id.second)
+ # nw let's compute the length of this connex non selected part:
+ connexl = 0
+ _cit = pyChainSilhouetteGenericIterator(0,0)
+ _cit.begin = winner
+ _cit.current_edge = winner
+ _cit.orientation = winnerOrientation
+ _cit.init()
+ while _cit.is_end == 0 and _cit.object.time_stamp != GetTimeStampCF():
+ ve = _cit.object
+ #print("-------- --------", ve.id.first, ve.id.second)
+ connexl = connexl + ve.length_2d
+ _cit.increment()
+ if connexl > self._length:
+ winner = None
+ return winner
+
+
+## Chaining iterator that fills small occlusions
+## percent
+## The max length of the occluded part
+## expressed in % of the total chain length
+class pyFillOcclusionsAbsoluteAndRelativeChainingIterator(ChainingIterator):
+ def __init__(self, percent, l):
+ ChainingIterator.__init__(self, 0, 1,None,1)
+ self._length = 0
+ self._absLength = l
+ self._percent = float(percent)
+ def getExactTypeName(self):
+ return "pyFillOcclusionsChainingIterator"
+ def init(self):
+ # each time we're evaluating a chain length
+ # we try to do it once. Thus we reinit
+ # the chain length here:
+ self._length = 0
+ def traverse(self, iter):
+ winner = None
+ winnerOrientation = 0
+ print(self.current_edge.id.first, self.current_edge.id.second)
+ it = AdjacencyIterator(iter)
+ tvertex = self.next_vertex
+ if type(tvertex) is TVertex:
+ mateVE = tvertex.get_mate(self.current_edge)
+ while not it.is_end:
+ ve = it.object
+ if ve.id == mateVE.id:
+ winner = ve
+ if not it.is_incoming:
+ winnerOrientation = 1
+ else:
+ winnerOrientation = 0
+ break
+ it.increment()
+ else:
+ ## case of NonTVertex
+ natures = [Nature.SILHOUETTE,Nature.BORDER,Nature.CREASE,Nature.SUGGESTIVE_CONTOUR,Nature.VALLEY,Nature.RIDGE]
+ for nat in natures:
+ if (self.current_edge.nature & nat) != 0:
+ count=0
+ while not it.is_end:
+ ve = it.object
+ if (ve.nature & nat) != 0:
+ count = count+1
+ winner = ve
+ if not it.is_incoming:
+ winnerOrientation = 1
+ else:
+ winnerOrientation = 0
+ it.increment()
+ if count != 1:
+ winner = None
+ break
+ if winner is not None:
+ # check whether this edge was part of the selection
+ if winner.time_stamp != GetTimeStampCF():
+ #print("---", winner.id.first, winner.id.second)
+ # if not, let's check whether it's short enough with
+ # respect to the chain made without staying in the selection
+ #------------------------------------------------------------
+ # Did we compute the prospective chain length already ?
+ if self._length == 0:
+ #if not, let's do it
+ _it = pyChainSilhouetteGenericIterator(0,0)
+ _it.begin = winner
+ _it.current_edge = winner
+ _it.orientation = winnerOrientation
+ _it.init()
+ while not _it.is_end:
+ ve = _it.object
+ #print("--------", ve.id.first, ve.id.second)
+ self._length = self._length + ve.length_2d
+ _it.increment()
+ if _it.is_begin:
+ break;
+ _it.begin = winner
+ _it.current_edge = winner
+ _it.orientation = winnerOrientation
+ if not _it.is_begin:
+ _it.decrement()
+ while (not _it.is_end) and (not _it.is_begin):
+ ve = _it.object
+ #print("--------", ve.id.first, ve.id.second)
+ self._length = self._length + ve.length_2d
+ _it.decrement()
+
+ # let's do the comparison:
+ # nw let's compute the length of this connex non selected part:
+ connexl = 0
+ _cit = pyChainSilhouetteGenericIterator(0,0)
+ _cit.begin = winner
+ _cit.current_edge = winner
+ _cit.orientation = winnerOrientation
+ _cit.init()
+ while _cit.is_end == 0 and _cit.object.time_stamp != GetTimeStampCF():
+ ve = _cit.object
+ #print("-------- --------", ve.id.first, ve.id.second)
+ connexl = connexl + ve.length_2d
+ _cit.increment()
+ if (connexl > self._percent * self._length) or (connexl > self._absLength):
+ winner = None
+ return winner
+
+## Chaining iterator that fills small occlusions without caring about the
+## actual selection
+## percent
+## The max length of the occluded part
+## expressed in % of the total chain length
+class pyFillQi0AbsoluteAndRelativeChainingIterator(ChainingIterator):
+ def __init__(self, percent, l):
+ ChainingIterator.__init__(self, 0, 1,None,1)
+ self._length = 0
+ self._absLength = l
+ self._percent = float(percent)
+ def getExactTypeName(self):
+ return "pyFillOcclusionsChainingIterator"
+ def init(self):
+ # each time we're evaluating a chain length
+ # we try to do it once. Thus we reinit
+ # the chain length here:
+ self._length = 0
+ def traverse(self, iter):
+ winner = None
+ winnerOrientation = 0
+ print(self.current_edge.id.first, self.current_edge.id.second)
+ it = AdjacencyIterator(iter)
+ tvertex = self.next_vertex
+ if type(tvertex) is TVertex:
+ mateVE = tvertex.get_mate(self.current_edge)
+ while not it.is_end:
+ ve = it.object
+ if ve.id == mateVE.id:
+ winner = ve
+ if not it.is_incoming:
+ winnerOrientation = 1
+ else:
+ winnerOrientation = 0
+ break
+ it.increment()
+ else:
+ ## case of NonTVertex
+ natures = [Nature.SILHOUETTE,Nature.BORDER,Nature.CREASE,Nature.SUGGESTIVE_CONTOUR,Nature.VALLEY,Nature.RIDGE]
+ for nat in natures:
+ if (self.current_edge.nature & nat) != 0:
+ count=0
+ while not it.is_end:
+ ve = it.object
+ if (ve.nature & nat) != 0:
+ count = count+1
+ winner = ve
+ if not it.is_incoming:
+ winnerOrientation = 1
+ else:
+ winnerOrientation = 0
+ it.increment()
+ if count != 1:
+ winner = None
+ break
+ if winner is not None:
+ # check whether this edge was part of the selection
+ if winner.qi != 0:
+ #print("---", winner.id.first, winner.id.second)
+ # if not, let's check whether it's short enough with
+ # respect to the chain made without staying in the selection
+ #------------------------------------------------------------
+ # Did we compute the prospective chain length already ?
+ if self._length == 0:
+ #if not, let's do it
+ _it = pyChainSilhouetteGenericIterator(0,0)
+ _it.begin = winner
+ _it.current_edge = winner
+ _it.orientation = winnerOrientation
+ _it.init()
+ while not _it.is_end:
+ ve = _it.object
+ #print("--------", ve.id.first, ve.id.second)
+ self._length = self._length + ve.length_2d
+ _it.increment()
+ if _it.is_begin:
+ break;
+ _it.begin = winner
+ _it.current_edge = winner
+ _it.orientation = winnerOrientation
+ if not _it.is_begin:
+ _it.decrement()
+ while (not _it.is_end) and (not _it.is_begin):
+ ve = _it.object
+ #print("--------", ve.id.first, ve.id.second)
+ self._length = self._length + ve.length_2d
+ _it.decrement()
+
+ # let's do the comparison:
+ # nw let's compute the length of this connex non selected part:
+ connexl = 0
+ _cit = pyChainSilhouetteGenericIterator(0,0)
+ _cit.begin = winner
+ _cit.current_edge = winner
+ _cit.orientation = winnerOrientation
+ _cit.init()
+ while not _cit.is_end and _cit.object.qi != 0:
+ ve = _cit.object
+ #print("-------- --------", ve.id.first, ve.id.second)
+ connexl = connexl + ve.length_2d
+ _cit.increment()
+ if (connexl > self._percent * self._length) or (connexl > self._absLength):
+ winner = None
+ return winner
+
+
+## the natural chaining iterator
+## It follows the edges of same nature on the same
+## objects with preseance on silhouettes, then borders,
+## then suggestive contours, then everything else. It doesn't chain the same ViewEdge twice
+## You can specify whether to stay in the selection or not.
+class pyNoIdChainSilhouetteIterator(ChainingIterator):
+ def __init__(self, stayInSelection=1):
+ ChainingIterator.__init__(self, stayInSelection, 1,None,1)
+ def getExactTypeName(self):
+ return "pyChainSilhouetteIterator"
+ def init(self):
+ pass
+ def traverse(self, iter):
+ winner = None
+ it = AdjacencyIterator(iter)
+ tvertex = self.next_vertex
+ if type(tvertex) is TVertex:
+ mateVE = tvertex.get_mate(self.current_edge)
+ while not it.is_end:
+ ve = it.object
+ feB = self.current_edge.last_fedge
+ feA = ve.first_fedge
+ vB = feB.second_svertex
+ vA = feA.first_svertex
+ if vA.id.first == vB.id.first:
+ winner = ve
+ break
+ feA = self.current_edge.first_fedge
+ feB = ve.last_fedge
+ vB = feB.second_svertex
+ vA = feA.first_svertex
+ if vA.id.first == vB.id.first:
+ winner = ve
+ break
+ feA = self.current_edge.last_fedge
+ feB = ve.last_fedge
+ vB = feB.second_svertex
+ vA = feA.second_svertex
+ if vA.id.first == vB.id.first:
+ winner = ve
+ break
+ feA = self.current_edge.first_fedge
+ feB = ve.first_fedge
+ vB = feB.first_svertex
+ vA = feA.first_svertex
+ if vA.id.first == vB.id.first:
+ winner = ve
+ break
+ it.increment()
+ else:
+ ## case of NonTVertex
+ natures = [Nature.SILHOUETTE,Nature.BORDER,Nature.CREASE,Nature.SUGGESTIVE_CONTOUR,Nature.VALLEY,Nature.RIDGE]
+ for i in range(len(natures)):
+ currentNature = self.current_edge.nature
+ if (natures[i] & currentNature) != 0:
+ count=0
+ while not it.is_end:
+ visitNext = 0
+ oNature = it.object.nature
+ if (oNature & natures[i]) != 0:
+ if natures[i] != oNature:
+ for j in range(i):
+ if (natures[j] & oNature) != 0:
+ visitNext = 1
+ break
+ if visitNext != 0:
+ break
+ count = count+1
+ winner = it.object
+ it.increment()
+ if count != 1:
+ winner = None
+ break
+ return winner
+