[Bf-blender-cvs] [ce72967] master: D319: Freestyle Python scripts update.

Tamito Kajiyama noreply at git.blender.org
Tue Jun 24 06:53:30 CEST 2014


Commit: ce729677db3e9934e2e2c56a9397a868c7546ee9
Author: Tamito Kajiyama
Date:   Tue Jun 24 13:52:12 2014 +0900
https://developer.blender.org/rBce729677db3e9934e2e2c56a9397a868c7546ee9

D319: Freestyle Python scripts update.

This revision is meant to update Freestyle's Python scripts to make full usage
of the new features of Python and Freestyle's Python API.

Freestyle's Python scripts are pretty old already, and were never given much
attention. With the 2.7x generation of Blender coming up, this is an excellent
time to update Freestyle's Python scripts, hopefully adding some new features
and achieving some speed improvements on the way.

Main goals:
* use for loops where possible
* general cleanup, making use of more recent python features (generators,
  ternary operator, ect.)
* update the documentation on the way (it's lacking atm)


Differential revision: https://developer.blender.org/D319

Author: flokkievids (Folkert de Vries)

Reviewed by: kjym3 (Tamito Kajiyama)

===================================================================

M	release/scripts/freestyle/modules/freestyle/chainingiterators.py
M	release/scripts/freestyle/modules/freestyle/functions.py
M	release/scripts/freestyle/modules/freestyle/predicates.py
M	release/scripts/freestyle/modules/freestyle/shaders.py
M	release/scripts/freestyle/modules/freestyle/utils.py

===================================================================

diff --git a/release/scripts/freestyle/modules/freestyle/chainingiterators.py b/release/scripts/freestyle/modules/freestyle/chainingiterators.py
index ae0a8a0..080919f 100644
--- a/release/scripts/freestyle/modules/freestyle/chainingiterators.py
+++ b/release/scripts/freestyle/modules/freestyle/chainingiterators.py
@@ -23,6 +23,20 @@ rules.  Also intended to be a collection of examples for defining
 chaining iterators in Python
 """
 
+__all__ = (
+    "pyChainSilhouetteIterator",
+    "pyChainSilhouetteGenericIterator",
+    "pyExternalContourChainingIterator",
+    "pySketchyChainSilhouetteIterator",
+    "pySketchyChainingIterator",
+    "pyFillOcclusionsRelativeChainingIterator",
+    "pyFillOcclusionsAbsoluteChainingIterator",
+    "pyFillOcclusionsAbsoluteAndRelativeChainingIterator",
+    "pyFillQi0AbsoluteAndRelativeChainingIterator",
+    "pyNoIdChainSilhouetteIterator",
+    )
+
+
 # module members
 from _freestyle import (
     ChainPredicateIterator,
@@ -41,11 +55,30 @@ from freestyle.predicates import (
     )
 from freestyle.utils import (
     ContextFunctions as CF,
-    stroke_normal,
+    get_chain_length,
+    find_matching_vertex,
     )
+
 import bpy
 
 
+NATURES = (
+    Nature.SILHOUETTE,
+    Nature.BORDER,
+    Nature.CREASE,
+    Nature.MATERIAL_BOUNDARY,
+    Nature.EDGE_MARK,
+    Nature.SUGGESTIVE_CONTOUR,
+    Nature.VALLEY,
+    Nature.RIDGE
+    )
+
+
+def nature_in_preceding(nature, index):
+    """ Returns True if given nature appears before index, else False """
+    return any(nature & nat for nat in NATURES[:index])
+
+
 class pyChainSilhouetteIterator(ChainingIterator):
     """Natural chaining iterator
 
@@ -61,43 +94,28 @@ class pyChainSilhouetteIterator(ChainingIterator):
         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.MATERIAL_BOUNDARY,Nature.EDGE_MARK,
-                       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
+        ## case of TVertex
+        vertex = self.next_vertex
+        if type(vertex) is TVertex:
+            mate = vertex.get_mate(self.current_edge)
+            return find_matching_vertex(mate.id, it)
+        ## case of NonTVertex
+        winner = None
+        for i, nat in enumerate(NATURES):
+            if (nat & self.current_edge.nature):
+                for ve in it:
+                    ve_nat = ve.nature
+                    if (ve_nat & nat):
+                        # search for matches in previous natures. if match -> break
+                        if nat != ve_nat and nature_in_preceding(ve_nat, index=i):
+                            break
+                        # a second match must be an error
+                        if winner is not None:
+                            return None
+                        # assign winner
+                        winner = ve
+                return winner
 
 
 class pyChainSilhouetteGenericIterator(ChainingIterator):
@@ -120,47 +138,30 @@ class pyChainSilhouetteGenericIterator(ChainingIterator):
         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.MATERIAL_BOUNDARY,Nature.EDGE_MARK,
-                       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
+        ## case of TVertex
+        vertex = self.next_vertex
+        if type(vertex) is TVertex:
+            mate = vertex.get_mate(self.current_edge)
+            return find_matching_vertex(mate.id, it)
+        ## case of NonTVertex
+        winner = None
+        for i, nat in enumerate(NATURES):
+            if (nat & self.current_edge.nature):
+                for ve in it:
+                    ve_nat = ve.nature
+                    if ve.id == self.current_edge.id:
+                        continue
+                    if (ve_nat & nat):
+                        if nat != ve_nat and nature_in_preceding(ve_nat, index=i):
+                            break
+
+                        if winner is not None:
+                            return None
+
+                        winner = ve
+                return winner
+        return None
 
 
 class pyExternalContourChainingIterator(ChainingIterator):
@@ -168,49 +169,40 @@ class pyExternalContourChainingIterator(ChainingIterator):
 
     def __init__(self):
         ChainingIterator.__init__(self, False, True, None, True)
-        self._isExternalContour = ExternalContourUP1D()
+        self.ExternalContour = ExternalContourUP1D()
 
     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 True
-            it.increment()
-        if bpy.app.debug_freestyle:
+        vertex = (ve.first_viewvertex if orientation else
+                  ve.last_viewvertex)
+
+        it = AdjacencyIterator(vertex, True, True)
+        result = any(self.ExternalContour(ave) for ave in it)
+        # report if there is no result (that's bad)
+        if not result and bpy.app.debug_freestyle:
             print("pyExternalContourChainingIterator : didn't find next edge")
-        return False
+
+        return result
 
     def traverse(self, iter):
         winner = None
+        self._nEdges += 1
+
         it = AdjacencyIterator(iter)
-        while not it.is_end:
-            ve = it.object
-            if self._isExternalContour(ve):
-                if ve.time_stamp == CF.get_time_stamp():
-                    winner = ve
-            it.increment()
+        time_stamp = CF.get_time_stamp()
+
+        for ve in it:
+            if self.ExternalContour(ve) and ve.time_stamp == time_stamp:
+                winner = ve
 
-        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:
+            for ve in it:
+                if self.checkViewEdge(ve, not it.is_incoming):
                     winner = ve
-                it.increment()
+
         return winner
 
 
@@ -227,58 +219,49 @@ class pySketchyChainSilhouetteIterator(ChainingIterator):
 
     def __init__(self, nRounds=3,stayInSelection=True):
         ChainingIterator.__init__(self, stayInSelection, False, None, True)
-        self._timeStamp = CF.get_time_stamp()+nRounds
+        self._timeStamp = CF.get_time_stamp() + nRounds
         self._nRounds = nRounds
 
     def init(self):
-        self._timeStamp = CF.get_time_stamp()+self._nRounds
+        self._timeStamp = CF.get_time_stamp() + self._nRounds
+
+    # keeping this local saves passing a reference to 'self' around
+    def make_sketchy(self, ve):
+        """
+        Creates the skeychy effect by causing th

@@ Diff output truncated at 10240 characters. @@




More information about the Bf-blender-cvs mailing list