def lineset_post(scene, layer, lineset): if not (scene.render.use_freestyle and scene.svg_export.use_svg_export and scene.svg_export.object_fill): return if RenderState.is_fill_written: return # reset the stroke selection (but don't delete the already generated strokes) Operators.reset(delete_strokes=False) # shape detection upred = AndUP1D(QuantitativeInvisibilityUP1D(0), ContourUP1D()) Operators.select(upred) # chain when the same shape and visible bpred = SameShapeIdBP1D() Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(QuantitativeInvisibilityUP1D(0))) # sort according to the distance from camera Operators.sort(pyZBP1D()) # render and write fills shader = SVGFillShader(create_path(scene), render_height(scene), lineset.name) Operators.create(TrueUP1D(), [ shader, ]) shader.write() RenderState.is_fill_written = True
def lineset_post(cls, scene, layer, lineset): if not cls.poll(scene, lineset.linestyle): return # reset the stroke selection (but don't delete the already generated strokes) Operators.reset(delete_strokes=False) # Unary Predicates: visible and correct edge nature upred = AndUP1D( QuantitativeInvisibilityUP1D(0), OrUP1D(ExternalContourUP1D(), pyNatureUP1D(Nature.BORDER)), ) # select the new edges Operators.select(upred) # Binary Predicates bpred = AndBP1D( MaterialBP1D(), NotBP1D(pyZDiscontinuityBP1D()), ) bpred = OrBP1D(bpred, AndBP1D(NotBP1D(bpred), AndBP1D(SameShapeIdBP1D(), MaterialBP1D()))) # chain the edges Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred)) # export SVG collector = StrokeCollector() Operators.create(TrueUP1D(), [collector]) builder = SVGFillBuilder(create_path(scene), render_height(scene), layer.name + '_' + lineset.name) builder.write(collector.strokes) # make strokes used for filling invisible for stroke in collector.strokes: for svert in stroke: svert.attribute.visible = False
def lineset_post(scene, layer, lineset): if not (scene.render.use_freestyle and scene.svg_export.use_svg_export and scene.svg_export.object_fill): return # reset the stroke selection (but don't delete the already generated strokes) Operators.reset(delete_strokes=False) # shape detection upred = AndUP1D(QuantitativeInvisibilityUP1D(0), ContourUP1D()) Operators.select(upred) # chain when the same shape and visible bpred = SameShapeIdBP1D() Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(QuantitativeInvisibilityUP1D(0))) # sort according to the distance from camera Operators.sort(pyZBP1D()) # render and write fills shader = SVGFillShader(create_path(scene), render_height(scene), lineset.name) Operators.create(TrueUP1D(), [shader, ]) shader.write()
def postprocess(frame_start=None, frame_end=None, interval=0): """ frame_start: the start frame (default Scene.frame_start) frame_end: the end frame (default: Scene.frame_end) interval: the number of frames inserted as interval between two strokes """ totlen = 0.0 nstrokes = Operators.get_strokes_size() #print('#strokes', nstrokes) for i in range(nstrokes): stroke = Operators.get_stroke_from_index(i) totlen += stroke.length_2d #print('totlen', totlen) scene = getCurrentScene() sta = scene.frame_start if frame_start is None else frame_start end = scene.frame_end if frame_end is None else frame_end cur = scene.frame_current fac = (cur - sta) / (end - sta) #print('fac', fac) totDrawingFrames = (end - sta + 1) - interval * (nstrokes - 1) if totDrawingFrames < 0: raise RuntimeError('The number of frames is too small') lengthPerFrame = totlen / totDrawingFrames #print('lengthPerFrame', lengthPerFrame) thresh = (cur - sta + 1) * lengthPerFrame + 1e-6 #print('thresh', thresh) curlen = 0.0 for i in range(nstrokes): stroke = Operators.get_stroke_from_index(i) for svert in stroke: svert.attribute.visible = curlen + svert.curvilinear_abscissa < thresh curlen += stroke.length_2d + lengthPerFrame * interval #print('done')
def render_visible_strokes(): """Renders the scene, selects visible strokes and returns them as a tuple""" upred = QuantitativeInvisibilityUP1D(0) # visible lines only #upred = TrueUP1D() # all lines Operators.select(upred) Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred)) Operators.create(TrueUP1D(), []) return get_strokes()
def postprocess(frame_start=None, frame_end=None, interval=0): """ frame_start: the start frame (default Scene.frame_start) frame_end: the end frame (default: Scene.frame_end) interval: the number of frames inserted as interval between two strokes """ totlen = 0.0 nstrokes = Operators.get_strokes_size() #print('#strokes', nstrokes) for i in range(nstrokes): stroke = Operators.get_stroke_from_index(i) totlen += stroke.length_2d #print('totlen', totlen) scene = getCurrentScene() sta = scene.frame_start if frame_start is None else frame_start end = scene.frame_end if frame_end is None else frame_end cur = scene.frame_current fac = (cur - sta) / (end - sta) #print('fac', fac) totDrawingFrames = (end - sta + 1) - interval * (nstrokes - 1) if totDrawingFrames < 0: raise RuntimeError('The number of frames is too small') lengthPerFrame = totlen / totDrawingFrames #print('lengthPerFrame', lengthPerFrame) thresh = (cur - sta + 1) * lengthPerFrame + 1e-6 #print('thresh', thresh) curlen = 0.0 for i in range(nstrokes): stroke = Operators.get_stroke_from_index(i) for svert in stroke: svert.attribute.visible = curlen + svert.curvilinear_abscissa < thresh curlen += stroke.length_2d + lengthPerFrame * interval
def render_external_contour(): """Renders the scene, selects visible strokes of the Contour nature and returns them as a tuple""" upred = AndUP1D(QuantitativeInvisibilityUP1D(0), ContourUP1D()) Operators.select(upred) # chain when the same shape and visible bpred = SameShapeIdBP1D() Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(upred)) Operators.create(TrueUP1D(), []) return get_strokes()
def render_visible_strokes(): """Renders the scene, selects visible strokes and returns them as a tuple""" if (bpy.context.scene.freestyle_gpencil_export.visible_only == True): upred = QuantitativeInvisibilityUP1D(0) # visible lines only else: upred = TrueUP1D() # all lines Operators.select(upred) Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred)) Operators.create(TrueUP1D(), []) return get_strokes()
# the stopping extremities for strokes from freestyle.chainingiterators import ChainSilhouetteIterator from freestyle.predicates import ( NotUP1D, QuantitativeInvisibilityUP1D, TrueUP1D, pyBackTVertexUP0D, pyVertexNatureUP0D, ) from freestyle.shaders import ( ConstantColorShader, IncreasingThicknessShader, SpatialNoiseShader, ) from freestyle.types import Nature, Operators upred = QuantitativeInvisibilityUP1D(0) Operators.select(upred) Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred)) # starting and stopping predicates: start = pyVertexNatureUP0D(Nature.NON_T_VERTEX) stop = pyBackTVertexUP0D() Operators.sequential_split(start, stop, 10) shaders_list = [ SpatialNoiseShader(7, 120, 2, True, True), IncreasingThicknessShader(5, 8), ConstantColorShader(0.2, 0.2, 0.2, 1), ] Operators.create(TrueUP1D(), shaders_list)
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # # ##### END GPL LICENSE BLOCK ##### # Filename : ignore_small_oclusions.py # Author : Stephane Grabli # Date : 04/08/2005 # Purpose : The strokes are drawn through small occlusions from freestyle.chainingiterators import pyFillOcclusionsAbsoluteChainingIterator from freestyle.predicates import ( QuantitativeInvisibilityUP1D, TrueUP1D, ) from freestyle.shaders import ( ConstantColorShader, ConstantThicknessShader, SamplingShader, ) from freestyle.types import Operators Operators.select(QuantitativeInvisibilityUP1D(0)) # Operators.bidirectional_chain(pyFillOcclusionsChainingIterator(0.1)) Operators.bidirectional_chain(pyFillOcclusionsAbsoluteChainingIterator(12)) shaders_list = [ SamplingShader(5.0), ConstantThicknessShader(3), ConstantColorShader(0.0, 0.0, 0.0), ] Operators.create(TrueUP1D(), shaders_list)
# Filename : external_contour.py # Author : Stephane Grabli # Date : 04/08/2005 # Purpose : Draws the external contour of the scene from freestyle.chainingiterators import ChainPredicateIterator from freestyle.predicates import ( AndUP1D, ExternalContourUP1D, NotUP1D, QuantitativeInvisibilityUP1D, TrueBP1D, TrueUP1D, ) from freestyle.shaders import ( ConstantColorShader, ConstantThicknessShader, ) from freestyle.types import Operators upred = AndUP1D(QuantitativeInvisibilityUP1D(0), ExternalContourUP1D()) Operators.select(upred) bpred = TrueBP1D() Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(upred)) shaders_list = [ ConstantThicknessShader(3), ConstantColorShader(0.0, 0.0, 0.0, 1), ] Operators.create(TrueUP1D(), shaders_list)
# Authors : Fredo Durand, Stephane Grabli, Francois Sillion, Emmanuel Turquin # Date : 08/04/2005 from freestyle.chainingiterators import ChainSilhouetteIterator from freestyle.predicates import ( QuantitativeInvisibilityUP1D, pyDensityUP1D, pyZBP1D, ) from freestyle.shaders import ( ConstantColorShader, ConstantThicknessShader, SamplingShader, StrokeTextureShader, ) from freestyle.types import IntegrationType, Operators, Stroke Operators.select(QuantitativeInvisibilityUP1D(0)) Operators.bidirectional_chain(ChainSilhouetteIterator()) #Operators.sequential_split(pyVertexNatureUP0D(Nature.VIEW_VERTEX), 2) Operators.sort(pyZBP1D()) shaders_list = [ StrokeTextureShader("smoothAlpha.bmp", Stroke.OPAQUE_MEDIUM, False), ConstantThicknessShader(3), SamplingShader(5.0), ConstantColorShader(0, 0, 0, 1), ] Operators.create(pyDensityUP1D(2, 0.05, IntegrationType.MEAN, 4), shaders_list) #Operators.create(pyDensityFunctorUP1D(8, 0.03, pyGetInverseProjectedZF1D(), 0, 1, IntegrationType.MEAN), shaders_list)
# Filename : thickness_fof_depth_discontinuity.py # Author : Stephane Grabli # Date : 04/08/2005 # Purpose : Assigns to strokes a thickness that depends on the depth discontinuity from freestyle.chainingiterators import ChainSilhouetteIterator from freestyle.predicates import ( NotUP1D, QuantitativeInvisibilityUP1D, TrueUP1D, ) from freestyle.shaders import ( ConstantColorShader, ConstantThicknessShader, SamplingShader, pyDepthDiscontinuityThicknessShader, ) from freestyle.types import Operators Operators.select(QuantitativeInvisibilityUP1D(0)) Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(QuantitativeInvisibilityUP1D(0))) shaders_list = [ SamplingShader(1), ConstantThicknessShader(3), ConstantColorShader(0.0, 0.0, 0.0), pyDepthDiscontinuityThicknessShader(0.8, 6), ] Operators.create(TrueUP1D(), shaders_list)
# Date : 04/08/2005 # Purpose : Draws the external contour of the scene using a sketchy # chaining iterator (in particular each ViewEdge can be drawn # several times from freestyle.chainingiterators import pySketchyChainingIterator from freestyle.predicates import AndUP1D, ExternalContourUP1D, NotUP1D, QuantitativeInvisibilityUP1D, TrueUP1D from freestyle.shaders import ( IncreasingColorShader, IncreasingThicknessShader, SamplingShader, SmoothingShader, SpatialNoiseShader, TextureAssignerShader, ) from freestyle.types import Operators upred = AndUP1D(QuantitativeInvisibilityUP1D(0), ExternalContourUP1D()) Operators.select(upred) Operators.bidirectional_chain(pySketchyChainingIterator(), NotUP1D(upred)) shaders_list = [ SamplingShader(4), SpatialNoiseShader(10, 150, 2, True, True), IncreasingThicknessShader(4, 10), SmoothingShader(400, 0.1, 0, 0.2, 0, 0, 0, 1), IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1), TextureAssignerShader(4), ] Operators.create(TrueUP1D(), shaders_list)
# Date : 04/08/2005 # Purpose : The topology of the strokes is built # so as to chain several times the same ViewEdge. # The topology of the objects is preserved from freestyle.chainingiterators import pySketchyChainSilhouetteIterator from freestyle.predicates import ( QuantitativeInvisibilityUP1D, TrueUP1D, ) from freestyle.shaders import ( ConstantColorShader, IncreasingThicknessShader, SamplingShader, SmoothingShader, SpatialNoiseShader, ) from freestyle.types import Operators upred = QuantitativeInvisibilityUP1D(0) Operators.select(upred) Operators.bidirectional_chain(pySketchyChainSilhouetteIterator(3, True)) shaders_list = [ SamplingShader(4), SpatialNoiseShader(20, 220, 2, True, True), IncreasingThicknessShader(4, 8), SmoothingShader(300, 0.05, 0, 0.2, 0, 0, 0, 0.5), ConstantColorShader(0.6, 0.2, 0.0), ] Operators.create(TrueUP1D(), shaders_list)
# Date : 04/08/2005 # Purpose : Draws lines having a high a prior density from freestyle.chainingiterators import ChainPredicateIterator from freestyle.predicates import ( AndUP1D, NotUP1D, QuantitativeInvisibilityUP1D, TrueBP1D, TrueUP1D, pyHighViewMapDensityUP1D, ) from freestyle.shaders import ( ConstantColorShader, ConstantThicknessShader, ) from freestyle.types import Operators Operators.select( AndUP1D(QuantitativeInvisibilityUP1D(0), pyHighViewMapDensityUP1D(0.1, 5))) bpred = TrueBP1D() upred = AndUP1D(QuantitativeInvisibilityUP1D(0), pyHighViewMapDensityUP1D(0.0007, 5)) Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(QuantitativeInvisibilityUP1D(0))) shaders_list = [ ConstantThicknessShader(2), ConstantColorShader(0.0, 0.0, 0.0, 1.0) ] Operators.create(TrueUP1D(), shaders_list)
# Filename : nature.py # Author : Stephane Grabli # Date : 04/08/2005 # Purpose : Uses the NatureUP1D predicate to select the lines # of a given type (among Nature.SILHOUETTE, Nature.CREASE, Nature.SUGGESTIVE_CONTOURS, # Nature.BORDERS). # The suggestive contours must have been enabled in the # options dialog to appear in the View Map. from freestyle.chainingiterators import ChainSilhouetteIterator from freestyle.predicates import ( NotUP1D, TrueUP1D, pyNatureUP1D, ) from freestyle.shaders import ( IncreasingColorShader, IncreasingThicknessShader, ) from freestyle.types import Operators, Nature Operators.select(pyNatureUP1D(Nature.SILHOUETTE)) Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(pyNatureUP1D(Nature.SILHOUETTE))) shaders_list = [ IncreasingThicknessShader(3, 10), IncreasingColorShader(0.0, 0.0, 0.0, 1, 0.8, 0, 0, 1), ] Operators.create(TrueUP1D(), shaders_list)
from freestyle.chainingiterators import pySketchyChainingIterator from freestyle.predicates import ( QuantitativeInvisibilityUP1D, TrueUP1D, ) from freestyle.shaders import ( IncreasingColorShader, IncreasingThicknessShader, SamplingShader, SmoothingShader, SpatialNoiseShader, pyBackboneStretcherNoCuspShader, ) from freestyle.types import Operators Operators.select(QuantitativeInvisibilityUP1D(0)) ## Chain 3 times each ViewEdge independently from the ## initial objects topology Operators.bidirectional_chain(pySketchyChainingIterator(3)) shaders_list = [ SamplingShader(4), SpatialNoiseShader(6, 120, 2, True, True), IncreasingThicknessShader(4, 10), SmoothingShader(100, 0.1, 0, 0.2, 0, 0, 0, 1), pyBackboneStretcherNoCuspShader(20), IncreasingColorShader(0.2, 0.2, 0.2, 1, 0.5, 0.5, 0.5, 1), ] Operators.create(TrueUP1D(), shaders_list)
UnaryPredicate1D.__init__(self) self._wsize = wsize self._threshold = threshold self._integration = integration self._func = DensityF1D(self._wsize, self._integration, sampling) self._func2 = DensityF1D(self._wsize, IntegrationType.MAX, sampling) def __call__(self, inter): c = self._func(inter) m = self._func2(inter) if c < self._threshold: return 1 if m > 4*c: if c < 1.5*self._threshold: return 1 return 0 Operators.select(QuantitativeInvisibilityUP1D(0)) Operators.bidirectional_chain(ChainSilhouetteIterator(),NotUP1D(QuantitativeInvisibilityUP1D(0))) Operators.select(pyHigherLengthUP1D(40)) ## selects lines having a high anisotropic a priori density Operators.select(pyHighDensityAnisotropyUP1D(0.3,4)) Operators.sort(pyLengthBP1D()) shaders_list = [ SamplingShader(2.0), ConstantThicknessShader(2), ConstantColorShader(0.2,0.2,0.25,1), ] ## uniform culling Operators.create(pyDensityUP1D(3.0,2.0e-2, IntegrationType.MEAN, 0.1), shaders_list)
# Filename : contour.py # Author : Stephane Grabli # Date : 04/08/2005 # Purpose : Draws each object's visible contour from freestyle.chainingiterators import ChainPredicateIterator from freestyle.predicates import ( AndUP1D, ContourUP1D, NotUP1D, QuantitativeInvisibilityUP1D, SameShapeIdBP1D, TrueUP1D, ) from freestyle.shaders import ( ConstantThicknessShader, IncreasingColorShader, ) from freestyle.types import Operators Operators.select(AndUP1D(QuantitativeInvisibilityUP1D(0), ContourUP1D())) bpred = SameShapeIdBP1D() upred = AndUP1D(QuantitativeInvisibilityUP1D(0), ContourUP1D()) Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(QuantitativeInvisibilityUP1D(0))) shaders_list = [ ConstantThicknessShader(5.0), IncreasingColorShader(0.8,0,0,1,0.1,0,0,1), ] Operators.create(TrueUP1D(), shaders_list)
# Filename : contour.py # Author : Stephane Grabli # Date : 04/08/2005 # Purpose : Draws each object's visible contour from freestyle.chainingiterators import ChainPredicateIterator from freestyle.predicates import ( AndUP1D, ContourUP1D, NotUP1D, QuantitativeInvisibilityUP1D, SameShapeIdBP1D, TrueUP1D, ) from freestyle.shaders import ( ConstantThicknessShader, IncreasingColorShader, ) from freestyle.types import Operators Operators.select(AndUP1D(QuantitativeInvisibilityUP1D(0), ContourUP1D())) bpred = SameShapeIdBP1D() upred = AndUP1D(QuantitativeInvisibilityUP1D(0), ContourUP1D()) Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(QuantitativeInvisibilityUP1D(0))) shaders_list = [ ConstantThicknessShader(5.0), IncreasingColorShader(0.8, 0, 0, 1, 0.1, 0, 0, 1), ] Operators.create(TrueUP1D(), shaders_list)
from freestyle.chainingiterators import pySketchyChainingIterator from freestyle.predicates import ( AndUP1D, ExternalContourUP1D, NotUP1D, QuantitativeInvisibilityUP1D, TrueUP1D, ) from freestyle.shaders import ( IncreasingColorShader, IncreasingThicknessShader, SamplingShader, SmoothingShader, SpatialNoiseShader, TextureAssignerShader, ) from freestyle.types import Operators upred = AndUP1D(QuantitativeInvisibilityUP1D(0), ExternalContourUP1D()) Operators.select(upred) Operators.bidirectional_chain(pySketchyChainingIterator(), NotUP1D(upred)) shaders_list = [ SamplingShader(4), SpatialNoiseShader(10, 150, 2, True, True), IncreasingThicknessShader(4, 10), SmoothingShader(400, 0.1, 0, 0.2, 0, 0, 0, 1), IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1), TextureAssignerShader(4), ] Operators.create(TrueUP1D(), shaders_list)
pyParameterUP0D, ) from freestyle.shaders import ( BezierCurveShader, ConstantColorShader, ConstantThicknessShader, SamplingShader, TextureAssignerShader, TipRemoverShader, pyNonLinearVaryingThicknessShader, pySamplingShader, ) from freestyle.types import IntegrationType, Operators Operators.select(QuantitativeInvisibilityUP1D(0)) Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(QuantitativeInvisibilityUP1D(0))) ## Splits strokes at points of highest 2D curavture ## when there are too many abrupt turns in it func = pyInverseCurvature2DAngleF0D() Operators.recursive_split(func, pyParameterUP0D(0.2, 0.8), NotUP1D(pyHigherNumberOfTurnsUP1D(3, 0.5)), 2) ## Keeps only long enough strokes Operators.select(pyHigherLengthUP1D(100)) ## Sorts so as to draw the longest strokes first ## (this will be done using the causal density) Operators.sort(pyLengthBP1D()) shaders_list = [ pySamplingShader(10), BezierCurveShader(30), SamplingShader(50), ConstantThicknessShader(10),
def process(layer_name, lineset_name): scene = getCurrentScene() layer = scene.render.layers[layer_name] lineset = layer.freestyle_settings.linesets[lineset_name] linestyle = lineset.linestyle selection_criteria = [] # prepare selection criteria by visibility if lineset.select_by_visibility: if lineset.visibility == 'VISIBLE': selection_criteria.append( QuantitativeInvisibilityUP1D(0)) elif lineset.visibility == 'HIDDEN': selection_criteria.append( NotUP1D(QuantitativeInvisibilityUP1D(0))) elif lineset.visibility == 'RANGE': selection_criteria.append( QuantitativeInvisibilityRangeUP1D(lineset.qi_start, lineset.qi_end)) # prepare selection criteria by edge types if lineset.select_by_edge_types: edge_type_criteria = [] if lineset.select_silhouette: upred = pyNatureUP1D(Nature.SILHOUETTE) edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_silhouette else upred) if lineset.select_border: upred = pyNatureUP1D(Nature.BORDER) edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_border else upred) if lineset.select_crease: upred = pyNatureUP1D(Nature.CREASE) edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_crease else upred) if lineset.select_ridge_valley: upred = pyNatureUP1D(Nature.RIDGE) edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_ridge_valley else upred) if lineset.select_suggestive_contour: upred = pyNatureUP1D(Nature.SUGGESTIVE_CONTOUR) edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_suggestive_contour else upred) if lineset.select_material_boundary: upred = pyNatureUP1D(Nature.MATERIAL_BOUNDARY) edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_material_boundary else upred) if lineset.select_edge_mark: upred = pyNatureUP1D(Nature.EDGE_MARK) edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_edge_mark else upred) if lineset.select_contour: upred = ContourUP1D() edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_contour else upred) if lineset.select_external_contour: upred = ExternalContourUP1D() edge_type_criteria.append(NotUP1D(upred) if lineset.exclude_external_contour else upred) if lineset.edge_type_combination == 'OR': upred = OrUP1D(*edge_type_criteria) else: upred = AndUP1D(*edge_type_criteria) if upred is not None: if lineset.edge_type_negation == 'EXCLUSIVE': upred = NotUP1D(upred) selection_criteria.append(upred) # prepare selection criteria by face marks if lineset.select_by_face_marks: if lineset.face_mark_condition == 'BOTH': upred = FaceMarkBothUP1D() else: upred = FaceMarkOneUP1D() if lineset.face_mark_negation == 'EXCLUSIVE': upred = NotUP1D(upred) selection_criteria.append(upred) # prepare selection criteria by group of objects if lineset.select_by_group: if lineset.group is not None: names = {ob.name: True for ob in lineset.group.objects} upred = ObjectNamesUP1D(names, lineset.group_negation == 'EXCLUSIVE') selection_criteria.append(upred) # prepare selection criteria by image border if lineset.select_by_image_border: upred = WithinImageBoundaryUP1D(*ContextFunctions.get_border()) selection_criteria.append(upred) # select feature edges upred = AndUP1D(*selection_criteria) if upred is None: upred = TrueUP1D() Operators.select(upred) # join feature edges to form chains if linestyle.use_chaining: if linestyle.chaining == 'PLAIN': if linestyle.use_same_object: Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred)) else: Operators.bidirectional_chain(ChainPredicateIterator(upred, TrueBP1D()), NotUP1D(upred)) elif linestyle.chaining == 'SKETCHY': if linestyle.use_same_object: Operators.bidirectional_chain(pySketchyChainSilhouetteIterator(linestyle.rounds)) else: Operators.bidirectional_chain(pySketchyChainingIterator(linestyle.rounds)) else: Operators.chain(ChainPredicateIterator(FalseUP1D(), FalseBP1D()), NotUP1D(upred)) # split chains if linestyle.material_boundary: Operators.sequential_split(MaterialBoundaryUP0D()) if linestyle.use_angle_min or linestyle.use_angle_max: angle_min = linestyle.angle_min if linestyle.use_angle_min else None angle_max = linestyle.angle_max if linestyle.use_angle_max else None Operators.sequential_split(Curvature2DAngleThresholdUP0D(angle_min, angle_max)) if linestyle.use_split_length: Operators.sequential_split(Length2DThresholdUP0D(linestyle.split_length), 1.0) if linestyle.use_split_pattern: pattern = [] if linestyle.split_dash1 > 0 and linestyle.split_gap1 > 0: pattern.append(linestyle.split_dash1) pattern.append(linestyle.split_gap1) if linestyle.split_dash2 > 0 and linestyle.split_gap2 > 0: pattern.append(linestyle.split_dash2) pattern.append(linestyle.split_gap2) if linestyle.split_dash3 > 0 and linestyle.split_gap3 > 0: pattern.append(linestyle.split_dash3) pattern.append(linestyle.split_gap3) if len(pattern) > 0: sampling = 1.0 controller = SplitPatternController(pattern, sampling) Operators.sequential_split(SplitPatternStartingUP0D(controller), SplitPatternStoppingUP0D(controller), sampling) # sort selected chains if linestyle.use_sorting: integration = integration_types.get(linestyle.integration_type, IntegrationType.MEAN) if linestyle.sort_key == 'DISTANCE_FROM_CAMERA': bpred = pyZBP1D(integration) elif linestyle.sort_key == '2D_LENGTH': bpred = Length2DBP1D() elif linestyle.sort_key == 'PROJECTED_X': bpred = pyProjectedXBP1D(integration) elif linestyle.sort_key == 'PROJECTED_Y': bpred = pyProjectedYBP1D(integration) if linestyle.sort_order == 'REVERSE': bpred = NotBP1D(bpred) Operators.sort(bpred) # select chains if linestyle.use_length_min or linestyle.use_length_max: length_min = linestyle.length_min if linestyle.use_length_min else None length_max = linestyle.length_max if linestyle.use_length_max else None Operators.select(LengthThresholdUP1D(length_min, length_max)) if linestyle.use_chain_count: Operators.select(pyNFirstUP1D(linestyle.chain_count)) # prepare a list of stroke shaders shaders_list = [] for m in linestyle.geometry_modifiers: if not m.use: continue if m.type == 'SAMPLING': shaders_list.append(SamplingShader( m.sampling)) elif m.type == 'BEZIER_CURVE': shaders_list.append(BezierCurveShader( m.error)) elif m.type == 'SINUS_DISPLACEMENT': shaders_list.append(SinusDisplacementShader( m.wavelength, m.amplitude, m.phase)) elif m.type == 'SPATIAL_NOISE': shaders_list.append(SpatialNoiseShader( m.amplitude, m.scale, m.octaves, m.smooth, m.use_pure_random)) elif m.type == 'PERLIN_NOISE_1D': shaders_list.append(PerlinNoise1DShader( m.frequency, m.amplitude, m.octaves, m.angle, _seed.get(m.seed))) elif m.type == 'PERLIN_NOISE_2D': shaders_list.append(PerlinNoise2DShader( m.frequency, m.amplitude, m.octaves, m.angle, _seed.get(m.seed))) elif m.type == 'BACKBONE_STRETCHER': shaders_list.append(BackboneStretcherShader( m.backbone_length)) elif m.type == 'TIP_REMOVER': shaders_list.append(TipRemoverShader( m.tip_length)) elif m.type == 'POLYGONIZATION': shaders_list.append(PolygonalizationShader( m.error)) elif m.type == 'GUIDING_LINES': shaders_list.append(GuidingLinesShader( m.offset)) elif m.type == 'BLUEPRINT': if m.shape == 'CIRCLES': shaders_list.append(pyBluePrintCirclesShader( m.rounds, m.random_radius, m.random_center)) elif m.shape == 'ELLIPSES': shaders_list.append(pyBluePrintEllipsesShader( m.rounds, m.random_radius, m.random_center)) elif m.shape == 'SQUARES': shaders_list.append(pyBluePrintSquaresShader( m.rounds, m.backbone_length, m.random_backbone)) elif m.type == '2D_OFFSET': shaders_list.append(Offset2DShader( m.start, m.end, m.x, m.y)) elif m.type == '2D_TRANSFORM': shaders_list.append(Transform2DShader( m.pivot, m.scale_x, m.scale_y, m.angle, m.pivot_u, m.pivot_x, m.pivot_y)) # -- Base color, alpha and thickness -- # if (not linestyle.use_chaining) or (linestyle.chaining == 'PLAIN' and linestyle.use_same_object): thickness_position = linestyle.thickness_position else: thickness_position = 'CENTER' import bpy if bpy.app.debug_freestyle: print("Warning: Thickness position options are applied when chaining is disabled\n" " or the Plain chaining is used with the Same Object option enabled.") shaders_list.append(ConstantColorShader(*(linestyle.color), alpha=linestyle.alpha)) shaders_list.append(BaseThicknessShader(linestyle.thickness, thickness_position, linestyle.thickness_ratio)) # -- Modifiers -- # for m in linestyle.color_modifiers: if not m.use: continue if m.type == 'ALONG_STROKE': shaders_list.append(ColorAlongStrokeShader( m.blend, m.influence, m.color_ramp)) elif m.type == 'DISTANCE_FROM_CAMERA': shaders_list.append(ColorDistanceFromCameraShader( m.blend, m.influence, m.color_ramp, m.range_min, m.range_max)) elif m.type == 'DISTANCE_FROM_OBJECT' and m.target is not None: shaders_list.append(ColorDistanceFromObjectShader( m.blend, m.influence, m.color_ramp, m.target, m.range_min, m.range_max)) elif m.type == 'MATERIAL': shaders_list.append(ColorMaterialShader( m.blend, m.influence, m.color_ramp, m.material_attribute, m.use_ramp)) for m in linestyle.alpha_modifiers: if not m.use: continue if m.type == 'ALONG_STROKE': shaders_list.append(AlphaAlongStrokeShader( m.blend, m.influence, m.mapping, m.invert, m.curve)) elif m.type == 'DISTANCE_FROM_CAMERA': shaders_list.append(AlphaDistanceFromCameraShader( m.blend, m.influence, m.mapping, m.invert, m.curve, m.range_min, m.range_max)) elif m.type == 'DISTANCE_FROM_OBJECT' and m.target is not None: shaders_list.append(AlphaDistanceFromObjectShader( m.blend, m.influence, m.mapping, m.invert, m.curve, m.target, m.range_min, m.range_max)) elif m.type == 'MATERIAL': shaders_list.append(AlphaMaterialShader( m.blend, m.influence, m.mapping, m.invert, m.curve, m.material_attribute)) for m in linestyle.thickness_modifiers: if not m.use: continue if m.type == 'ALONG_STROKE': shaders_list.append(ThicknessAlongStrokeShader( thickness_position, linestyle.thickness_ratio, m.blend, m.influence, m.mapping, m.invert, m.curve, m.value_min, m.value_max)) elif m.type == 'DISTANCE_FROM_CAMERA': shaders_list.append(ThicknessDistanceFromCameraShader( thickness_position, linestyle.thickness_ratio, m.blend, m.influence, m.mapping, m.invert, m.curve, m.range_min, m.range_max, m.value_min, m.value_max)) elif m.type == 'DISTANCE_FROM_OBJECT' and m.target is not None: shaders_list.append(ThicknessDistanceFromObjectShader( thickness_position, linestyle.thickness_ratio, m.blend, m.influence, m.mapping, m.invert, m.curve, m.target, m.range_min, m.range_max, m.value_min, m.value_max)) elif m.type == 'MATERIAL': shaders_list.append(ThicknessMaterialShader( thickness_position, linestyle.thickness_ratio, m.blend, m.influence, m.mapping, m.invert, m.curve, m.material_attribute, m.value_min, m.value_max)) elif m.type == 'CALLIGRAPHY': shaders_list.append(CalligraphicThicknessShader( thickness_position, linestyle.thickness_ratio, m.blend, m.influence, m.orientation, m.thickness_min, m.thickness_max)) # -- Textures -- # has_tex = False if scene.render.use_shading_nodes: if linestyle.use_nodes and linestyle.node_tree: shaders_list.append(BlenderTextureShader(linestyle.node_tree)) has_tex = True else: if linestyle.use_texture: textures = tuple(BlenderTextureShader(slot) for slot in linestyle.texture_slots if slot is not None) if textures: shaders_list.extend(textures) has_tex = True if has_tex: shaders_list.append(StrokeTextureStepShader(linestyle.texture_spacing)) # -- Stroke caps -- # if linestyle.caps == 'ROUND': shaders_list.append(RoundCapShader()) elif linestyle.caps == 'SQUARE': shaders_list.append(SquareCapShader()) # -- Dashed line -- # if linestyle.use_dashed_line: pattern = [] if linestyle.dash1 > 0 and linestyle.gap1 > 0: pattern.append(linestyle.dash1) pattern.append(linestyle.gap1) if linestyle.dash2 > 0 and linestyle.gap2 > 0: pattern.append(linestyle.dash2) pattern.append(linestyle.gap2) if linestyle.dash3 > 0 and linestyle.gap3 > 0: pattern.append(linestyle.dash3) pattern.append(linestyle.gap3) if len(pattern) > 0: shaders_list.append(DashedLineShader(pattern)) # create strokes using the shaders list Operators.create(TrueUP1D(), shaders_list)
def process(layer_name, lineset_name): scene = getCurrentScene() layer = scene.render.layers[layer_name] lineset = layer.freestyle_settings.linesets[lineset_name] linestyle = lineset.linestyle selection_criteria = [] # prepare selection criteria by visibility if lineset.select_by_visibility: if lineset.visibility == 'VISIBLE': selection_criteria.append(QuantitativeInvisibilityUP1D(0)) elif lineset.visibility == 'HIDDEN': selection_criteria.append(NotUP1D(QuantitativeInvisibilityUP1D(0))) elif lineset.visibility == 'RANGE': selection_criteria.append( QuantitativeInvisibilityRangeUP1D(lineset.qi_start, lineset.qi_end)) # prepare selection criteria by edge types if lineset.select_by_edge_types: edge_type_criteria = [] if lineset.select_silhouette: upred = pyNatureUP1D(Nature.SILHOUETTE) edge_type_criteria.append( NotUP1D(upred) if lineset.exclude_silhouette else upred) if lineset.select_border: upred = pyNatureUP1D(Nature.BORDER) edge_type_criteria.append( NotUP1D(upred) if lineset.exclude_border else upred) if lineset.select_crease: upred = pyNatureUP1D(Nature.CREASE) edge_type_criteria.append( NotUP1D(upred) if lineset.exclude_crease else upred) if lineset.select_ridge_valley: upred = pyNatureUP1D(Nature.RIDGE) edge_type_criteria.append( NotUP1D(upred) if lineset.exclude_ridge_valley else upred) if lineset.select_suggestive_contour: upred = pyNatureUP1D(Nature.SUGGESTIVE_CONTOUR) edge_type_criteria.append( NotUP1D(upred) if lineset.exclude_suggestive_contour else upred ) if lineset.select_material_boundary: upred = pyNatureUP1D(Nature.MATERIAL_BOUNDARY) edge_type_criteria.append( NotUP1D(upred) if lineset.exclude_material_boundary else upred) if lineset.select_edge_mark: upred = pyNatureUP1D(Nature.EDGE_MARK) edge_type_criteria.append( NotUP1D(upred) if lineset.exclude_edge_mark else upred) if lineset.select_contour: upred = ContourUP1D() edge_type_criteria.append( NotUP1D(upred) if lineset.exclude_contour else upred) if lineset.select_external_contour: upred = ExternalContourUP1D() edge_type_criteria.append( NotUP1D(upred) if lineset.exclude_external_contour else upred) if lineset.edge_type_combination == 'OR': upred = OrUP1D(*edge_type_criteria) else: upred = AndUP1D(*edge_type_criteria) if upred is not None: if lineset.edge_type_negation == 'EXCLUSIVE': upred = NotUP1D(upred) selection_criteria.append(upred) # prepare selection criteria by face marks if lineset.select_by_face_marks: if lineset.face_mark_condition == 'BOTH': upred = FaceMarkBothUP1D() else: upred = FaceMarkOneUP1D() if lineset.face_mark_negation == 'EXCLUSIVE': upred = NotUP1D(upred) selection_criteria.append(upred) # prepare selection criteria by group of objects if lineset.select_by_group: if lineset.group is not None: names = {ob.name: True for ob in lineset.group.objects} upred = ObjectNamesUP1D(names, lineset.group_negation == 'EXCLUSIVE') selection_criteria.append(upred) # prepare selection criteria by image border if lineset.select_by_image_border: upred = WithinImageBoundaryUP1D(*ContextFunctions.get_border()) selection_criteria.append(upred) # select feature edges upred = AndUP1D(*selection_criteria) if upred is None: upred = TrueUP1D() Operators.select(upred) # join feature edges to form chains if linestyle.use_chaining: if linestyle.chaining == 'PLAIN': if linestyle.use_same_object: Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred)) else: Operators.bidirectional_chain( ChainPredicateIterator(upred, TrueBP1D()), NotUP1D(upred)) elif linestyle.chaining == 'SKETCHY': if linestyle.use_same_object: Operators.bidirectional_chain( pySketchyChainSilhouetteIterator(linestyle.rounds)) else: Operators.bidirectional_chain( pySketchyChainingIterator(linestyle.rounds)) else: Operators.chain(ChainPredicateIterator(FalseUP1D(), FalseBP1D()), NotUP1D(upred)) # split chains if linestyle.material_boundary: Operators.sequential_split(MaterialBoundaryUP0D()) if linestyle.use_angle_min or linestyle.use_angle_max: angle_min = linestyle.angle_min if linestyle.use_angle_min else None angle_max = linestyle.angle_max if linestyle.use_angle_max else None Operators.sequential_split( Curvature2DAngleThresholdUP0D(angle_min, angle_max)) if linestyle.use_split_length: Operators.sequential_split( Length2DThresholdUP0D(linestyle.split_length), 1.0) if linestyle.use_split_pattern: pattern = [] if linestyle.split_dash1 > 0 and linestyle.split_gap1 > 0: pattern.append(linestyle.split_dash1) pattern.append(linestyle.split_gap1) if linestyle.split_dash2 > 0 and linestyle.split_gap2 > 0: pattern.append(linestyle.split_dash2) pattern.append(linestyle.split_gap2) if linestyle.split_dash3 > 0 and linestyle.split_gap3 > 0: pattern.append(linestyle.split_dash3) pattern.append(linestyle.split_gap3) if len(pattern) > 0: sampling = 1.0 controller = SplitPatternController(pattern, sampling) Operators.sequential_split(SplitPatternStartingUP0D(controller), SplitPatternStoppingUP0D(controller), sampling) # sort selected chains if linestyle.use_sorting: integration = integration_types.get(linestyle.integration_type, IntegrationType.MEAN) if linestyle.sort_key == 'DISTANCE_FROM_CAMERA': bpred = pyZBP1D(integration) elif linestyle.sort_key == '2D_LENGTH': bpred = Length2DBP1D() elif linestyle.sort_key == 'PROJECTED_X': bpred = pyProjectedXBP1D(integration) elif linestyle.sort_key == 'PROJECTED_Y': bpred = pyProjectedYBP1D(integration) if linestyle.sort_order == 'REVERSE': bpred = NotBP1D(bpred) Operators.sort(bpred) # select chains if linestyle.use_length_min or linestyle.use_length_max: length_min = linestyle.length_min if linestyle.use_length_min else None length_max = linestyle.length_max if linestyle.use_length_max else None Operators.select(LengthThresholdUP1D(length_min, length_max)) if linestyle.use_chain_count: Operators.select(pyNFirstUP1D(linestyle.chain_count)) # prepare a list of stroke shaders shaders_list = [] for m in linestyle.geometry_modifiers: if not m.use: continue if m.type == 'SAMPLING': shaders_list.append(SamplingShader(m.sampling)) elif m.type == 'BEZIER_CURVE': shaders_list.append(BezierCurveShader(m.error)) elif m.type == 'SINUS_DISPLACEMENT': shaders_list.append( SinusDisplacementShader(m.wavelength, m.amplitude, m.phase)) elif m.type == 'SPATIAL_NOISE': shaders_list.append( SpatialNoiseShader(m.amplitude, m.scale, m.octaves, m.smooth, m.use_pure_random)) elif m.type == 'PERLIN_NOISE_1D': shaders_list.append( PerlinNoise1DShader(m.frequency, m.amplitude, m.octaves, m.angle, _seed.get(m.seed))) elif m.type == 'PERLIN_NOISE_2D': shaders_list.append( PerlinNoise2DShader(m.frequency, m.amplitude, m.octaves, m.angle, _seed.get(m.seed))) elif m.type == 'BACKBONE_STRETCHER': shaders_list.append(BackboneStretcherShader(m.backbone_length)) elif m.type == 'TIP_REMOVER': shaders_list.append(TipRemoverShader(m.tip_length)) elif m.type == 'POLYGONIZATION': shaders_list.append(PolygonalizationShader(m.error)) elif m.type == 'GUIDING_LINES': shaders_list.append(GuidingLinesShader(m.offset)) elif m.type == 'BLUEPRINT': if m.shape == 'CIRCLES': shaders_list.append( pyBluePrintCirclesShader(m.rounds, m.random_radius, m.random_center)) elif m.shape == 'ELLIPSES': shaders_list.append( pyBluePrintEllipsesShader(m.rounds, m.random_radius, m.random_center)) elif m.shape == 'SQUARES': shaders_list.append( pyBluePrintSquaresShader(m.rounds, m.backbone_length, m.random_backbone)) elif m.type == '2D_OFFSET': shaders_list.append(Offset2DShader(m.start, m.end, m.x, m.y)) elif m.type == '2D_TRANSFORM': shaders_list.append( Transform2DShader(m.pivot, m.scale_x, m.scale_y, m.angle, m.pivot_u, m.pivot_x, m.pivot_y)) # -- Base color, alpha and thickness -- # if (not linestyle.use_chaining) or (linestyle.chaining == 'PLAIN' and linestyle.use_same_object): thickness_position = linestyle.thickness_position else: thickness_position = 'CENTER' import bpy if bpy.app.debug_freestyle: print( "Warning: Thickness position options are applied when chaining is disabled\n" " or the Plain chaining is used with the Same Object option enabled." ) shaders_list.append( ConstantColorShader(*(linestyle.color), alpha=linestyle.alpha)) shaders_list.append( BaseThicknessShader(linestyle.thickness, thickness_position, linestyle.thickness_ratio)) # -- Modifiers -- # for m in linestyle.color_modifiers: if not m.use: continue if m.type == 'ALONG_STROKE': shaders_list.append( ColorAlongStrokeShader(m.blend, m.influence, m.color_ramp)) elif m.type == 'DISTANCE_FROM_CAMERA': shaders_list.append( ColorDistanceFromCameraShader(m.blend, m.influence, m.color_ramp, m.range_min, m.range_max)) elif m.type == 'DISTANCE_FROM_OBJECT' and m.target is not None: shaders_list.append( ColorDistanceFromObjectShader(m.blend, m.influence, m.color_ramp, m.target, m.range_min, m.range_max)) elif m.type == 'MATERIAL': shaders_list.append( ColorMaterialShader(m.blend, m.influence, m.color_ramp, m.material_attribute, m.use_ramp)) for m in linestyle.alpha_modifiers: if not m.use: continue if m.type == 'ALONG_STROKE': shaders_list.append( AlphaAlongStrokeShader(m.blend, m.influence, m.mapping, m.invert, m.curve)) elif m.type == 'DISTANCE_FROM_CAMERA': shaders_list.append( AlphaDistanceFromCameraShader(m.blend, m.influence, m.mapping, m.invert, m.curve, m.range_min, m.range_max)) elif m.type == 'DISTANCE_FROM_OBJECT' and m.target is not None: shaders_list.append( AlphaDistanceFromObjectShader(m.blend, m.influence, m.mapping, m.invert, m.curve, m.target, m.range_min, m.range_max)) elif m.type == 'MATERIAL': shaders_list.append( AlphaMaterialShader(m.blend, m.influence, m.mapping, m.invert, m.curve, m.material_attribute)) for m in linestyle.thickness_modifiers: if not m.use: continue if m.type == 'ALONG_STROKE': shaders_list.append( ThicknessAlongStrokeShader(thickness_position, linestyle.thickness_ratio, m.blend, m.influence, m.mapping, m.invert, m.curve, m.value_min, m.value_max)) elif m.type == 'DISTANCE_FROM_CAMERA': shaders_list.append( ThicknessDistanceFromCameraShader(thickness_position, linestyle.thickness_ratio, m.blend, m.influence, m.mapping, m.invert, m.curve, m.range_min, m.range_max, m.value_min, m.value_max)) elif m.type == 'DISTANCE_FROM_OBJECT' and m.target is not None: shaders_list.append( ThicknessDistanceFromObjectShader( thickness_position, linestyle.thickness_ratio, m.blend, m.influence, m.mapping, m.invert, m.curve, m.target, m.range_min, m.range_max, m.value_min, m.value_max)) elif m.type == 'MATERIAL': shaders_list.append( ThicknessMaterialShader(thickness_position, linestyle.thickness_ratio, m.blend, m.influence, m.mapping, m.invert, m.curve, m.material_attribute, m.value_min, m.value_max)) elif m.type == 'CALLIGRAPHY': shaders_list.append( CalligraphicThicknessShader(thickness_position, linestyle.thickness_ratio, m.blend, m.influence, m.orientation, m.thickness_min, m.thickness_max)) # -- Textures -- # has_tex = False if scene.render.use_shading_nodes: if linestyle.use_nodes and linestyle.node_tree: shaders_list.append(BlenderTextureShader(linestyle.node_tree)) has_tex = True else: if linestyle.use_texture: textures = tuple( BlenderTextureShader(slot) for slot in linestyle.texture_slots if slot is not None) if textures: shaders_list.extend(textures) has_tex = True if has_tex: shaders_list.append(StrokeTextureStepShader(linestyle.texture_spacing)) # -- Stroke caps -- # if linestyle.caps == 'ROUND': shaders_list.append(RoundCapShader()) elif linestyle.caps == 'SQUARE': shaders_list.append(SquareCapShader()) # -- Dashed line -- # if linestyle.use_dashed_line: pattern = [] if linestyle.dash1 > 0 and linestyle.gap1 > 0: pattern.append(linestyle.dash1) pattern.append(linestyle.gap1) if linestyle.dash2 > 0 and linestyle.gap2 > 0: pattern.append(linestyle.dash2) pattern.append(linestyle.gap2) if linestyle.dash3 > 0 and linestyle.gap3 > 0: pattern.append(linestyle.dash3) pattern.append(linestyle.gap3) if len(pattern) > 0: shaders_list.append(DashedLineShader(pattern)) # create strokes using the shaders list Operators.create(TrueUP1D(), shaders_list)
# Filename : qi1.py # Author : Stephane Grabli # Date : 04/08/2005 # Purpose : Draws lines hidden by one surface. # *** Quantitative Invisibility must have been # enabled in the options dialog to use this style module **** from freestyle.chainingiterators import ChainSilhouetteIterator from freestyle.predicates import ( NotUP1D, QuantitativeInvisibilityUP1D, TrueUP1D, ) from freestyle.shaders import ( ConstantColorShader, ConstantThicknessShader, SamplingShader, ) from freestyle.types import Operators Operators.select(QuantitativeInvisibilityUP1D(1)) Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(QuantitativeInvisibilityUP1D(1))) shaders_list = [ SamplingShader(5.0), ConstantThicknessShader(3), ConstantColorShader(0.5, 0.5, 0.5, 1) ] Operators.create(TrueUP1D(), shaders_list)
# and, second, so as to chain several times the same ViewEdge. from freestyle.chainingiterators import pySketchyChainingIterator from freestyle.predicates import ( QuantitativeInvisibilityUP1D, TrueUP1D, ) from freestyle.shaders import ( IncreasingColorShader, IncreasingThicknessShader, SamplingShader, SmoothingShader, SpatialNoiseShader, pyBackboneStretcherNoCuspShader, ) from freestyle.types import Operators Operators.select(QuantitativeInvisibilityUP1D(0)) ## Chain 3 times each ViewEdge independently from the ## initial objects topology Operators.bidirectional_chain(pySketchyChainingIterator(3)) shaders_list = [ SamplingShader(4), SpatialNoiseShader(6, 120, 2, True, True), IncreasingThicknessShader(4, 10), SmoothingShader(100, 0.1, 0, 0.2, 0, 0, 0, 1), pyBackboneStretcherNoCuspShader(20), IncreasingColorShader(0.2, 0.2, 0.2, 1, 0.5, 0.5, 0.5, 1), ] Operators.create(TrueUP1D(), shaders_list)
from freestyle.chainingiterators import ChainSilhouetteIterator from freestyle.predicates import ( NotUP1D, QuantitativeInvisibilityUP1D, TrueUP1D, pyBackTVertexUP0D, pyVertexNatureUP0D, ) from freestyle.shaders import ( ConstantColorShader, IncreasingThicknessShader, SpatialNoiseShader, ) from freestyle.types import Nature, Operators upred = QuantitativeInvisibilityUP1D(0) Operators.select(upred) Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred)) ## starting and stopping predicates: start = pyVertexNatureUP0D(Nature.NON_T_VERTEX) stop = pyBackTVertexUP0D() Operators.sequential_split(start, stop, 10) shaders_list = [ SpatialNoiseShader(7, 120, 2, True, True), IncreasingThicknessShader(5, 8), ConstantColorShader(0.2, 0.2, 0.2, 1), ] Operators.create(TrueUP1D(), shaders_list)
def get_strokes(): return tuple( map(Operators().get_stroke_from_index, range(Operators().get_strokes_size())))
# Purpose : Draws only the lines that are occluded by a given object from freestyle.chainingiterators import ChainSilhouetteIterator from freestyle.predicates import ( AndUP1D, NotUP1D, QuantitativeInvisibilityUP1D, TrueUP1D, pyIsInOccludersListUP1D, ) from freestyle.shaders import ( ConstantColorShader, ConstantThicknessShader, SamplingShader, ) from freestyle.types import Id, Operators # the id of the occluder (use SHIFT+click on the ViewMap to # retrieve ids) id = Id(3, 0) upred = AndUP1D(NotUP1D(QuantitativeInvisibilityUP1D(0)), pyIsInOccludersListUP1D(id)) Operators.select(upred) Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred)) shaders_list = [ SamplingShader(5), ConstantThicknessShader(3), ConstantColorShader(0.3, 0.3, 0.3, 1), ] Operators.create(TrueUP1D(), shaders_list)
# Purpose : Draws only the lines that are occluded by a given object from freestyle.chainingiterators import ChainSilhouetteIterator from freestyle.predicates import ( AndUP1D, NotUP1D, QuantitativeInvisibilityUP1D, TrueUP1D, pyIsInOccludersListUP1D, ) from freestyle.shaders import ( ConstantColorShader, ConstantThicknessShader, SamplingShader, ) from freestyle.types import Id, Operators ## the id of the occluder (use SHIFT+click on the ViewMap to ## retrieve ids) id = Id(3,0) upred = AndUP1D(NotUP1D(QuantitativeInvisibilityUP1D(0)), pyIsInOccludersListUP1D(id)) Operators.select(upred) Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(upred)) shaders_list = [ SamplingShader(5), ConstantThicknessShader(3), ConstantColorShader(0.3, 0.3, 0.3, 1), ] Operators.create(TrueUP1D(), shaders_list)
def get_strokes(): # a tuple containing all strokes from the current render. should get replaced by freestyle.context at some point return tuple( map(Operators().get_stroke_from_index, range(Operators().get_strokes_size())))
# Author : Stephane Grabli # Date : 04/08/2005 # Purpose : Draws the visible lines (chaining follows same nature lines) # (most basic style module) from freestyle.chainingiterators import ChainSilhouetteIterator from freestyle.functions import pyInverseCurvature2DAngleF0D from freestyle.predicates import ( NotUP1D, QuantitativeInvisibilityUP1D, TrueUP1D, pyHigherLengthUP1D, pyParameterUP0D, ) from freestyle.shaders import ( ConstantThicknessShader, IncreasingColorShader, ) from freestyle.types import Operators Operators.select(QuantitativeInvisibilityUP1D(0)) Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(QuantitativeInvisibilityUP1D(0))) func = pyInverseCurvature2DAngleF0D() Operators.recursive_split(func, pyParameterUP0D(0.4, 0.6), NotUP1D(pyHigherLengthUP1D(100)), 2) shaders_list = [ ConstantThicknessShader(10), IncreasingColorShader(1, 0, 0, 1, 0, 1, 0, 1), ] Operators.create(TrueUP1D(), shaders_list)
# Filename : sketchy_topology_preserved.py # Author : Stephane Grabli # Date : 04/08/2005 # Purpose : The topology of the strokes is built # so as to chain several times the same ViewEdge. # The topology of the objects is preserved from freestyle.chainingiterators import pySketchyChainSilhouetteIterator from freestyle.predicates import QuantitativeInvisibilityUP1D, TrueUP1D from freestyle.shaders import ( ConstantColorShader, IncreasingThicknessShader, SamplingShader, SmoothingShader, SpatialNoiseShader, ) from freestyle.types import Operators upred = QuantitativeInvisibilityUP1D(0) Operators.select(upred) Operators.bidirectional_chain(pySketchyChainSilhouetteIterator(3, True)) shaders_list = [ SamplingShader(4), SpatialNoiseShader(20, 220, 2, True, True), IncreasingThicknessShader(4, 8), SmoothingShader(300, 0.05, 0, 0.2, 0, 0, 0, 0.5), ConstantColorShader(0.6, 0.2, 0.0), ] Operators.create(TrueUP1D(), shaders_list)
self._integration = integration self._func = DensityF1D(self._wsize, self._integration, sampling) self._func2 = DensityF1D(self._wsize, IntegrationType.MAX, sampling) def __call__(self, inter): c = self._func(inter) m = self._func2(inter) if c < self._threshold: return 1 if m > 4 * c: if c < 1.5 * self._threshold: return 1 return 0 Operators.select(QuantitativeInvisibilityUP1D(0)) Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(QuantitativeInvisibilityUP1D(0))) Operators.select(pyHigherLengthUP1D(40)) ## selects lines having a high anisotropic a priori density Operators.select(pyHighDensityAnisotropyUP1D(0.3, 4)) Operators.sort(pyLengthBP1D()) shaders_list = [ SamplingShader(2.0), ConstantThicknessShader(2), ConstantColorShader(0.2, 0.2, 0.25, 1), ] ## uniform culling Operators.create(pyDensityUP1D(3.0, 2.0e-2, IntegrationType.MEAN, 0.1), shaders_list)
# # ##### END GPL LICENSE BLOCK ##### # Filename : uniformpruning_zsort.py # Authors : Fredo Durand, Stephane Grabli, Francois Sillion, Emmanuel Turquin # Date : 08/04/2005 from freestyle.chainingiterators import ChainSilhouetteIterator from freestyle.predicates import ( QuantitativeInvisibilityUP1D, pyDensityUP1D, pyZBP1D, ) from freestyle.shaders import ( ConstantColorShader, ConstantThicknessShader, SamplingShader, ) from freestyle.types import IntegrationType, Operators, Stroke Operators.select(QuantitativeInvisibilityUP1D(0)) Operators.bidirectional_chain(ChainSilhouetteIterator()) #Operators.sequential_split(pyVertexNatureUP0D(Nature.VIEW_VERTEX), 2) Operators.sort(pyZBP1D()) shaders_list = [ ConstantThicknessShader(3), SamplingShader(5.0), ConstantColorShader(0, 0, 0, 1), ] Operators.create(pyDensityUP1D(2, 0.05, IntegrationType.MEAN, 4), shaders_list)
# Author : Stephane Grabli # Date : 04/08/2005 # Purpose : Selects the lines with high a priori density and # subjects them to the causal density so as to avoid # cluttering from freestyle.chainingiterators import ChainPredicateIterator from freestyle.predicates import ( AndUP1D, NotUP1D, QuantitativeInvisibilityUP1D, TrueBP1D, pyDensityUP1D, pyHighViewMapDensityUP1D, ) from freestyle.shaders import ( ConstantColorShader, ConstantThicknessShader, ) from freestyle.types import IntegrationType, Operators upred = AndUP1D(QuantitativeInvisibilityUP1D(0), pyHighViewMapDensityUP1D(0.3, IntegrationType.LAST)) Operators.select(upred) bpred = TrueBP1D() Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(QuantitativeInvisibilityUP1D(0))) shaders_list = [ ConstantThicknessShader(2), ConstantColorShader(0, 0, 0, 1), ] Operators.create(pyDensityUP1D(1, 0.1, IntegrationType.MEAN), shaders_list)
pyLengthBP1D, pyParameterUP0D, ) from freestyle.shaders import ( BezierCurveShader, ConstantColorShader, ConstantThicknessShader, SamplingShader, TextureAssignerShader, TipRemoverShader, pyNonLinearVaryingThicknessShader, pySamplingShader, ) from freestyle.types import IntegrationType, Operators Operators.select(QuantitativeInvisibilityUP1D(0)) Operators.bidirectional_chain(ChainSilhouetteIterator(), NotUP1D(QuantitativeInvisibilityUP1D(0))) ## Splits strokes at points of highest 2D curavture ## when there are too many abrupt turns in it func = pyInverseCurvature2DAngleF0D() Operators.recursive_split(func, pyParameterUP0D(0.2, 0.8), NotUP1D(pyHigherNumberOfTurnsUP1D(3, 0.5)), 2) ## Keeps only long enough strokes Operators.select(pyHigherLengthUP1D(100)) ## Sorts so as to draw the longest strokes first ## (this will be done using the causal density) Operators.sort(pyLengthBP1D()) shaders_list = [ pySamplingShader(10), BezierCurveShader(30),
# Filename : apriori_density.py # Author : Stephane Grabli # Date : 04/08/2005 # Purpose : Draws lines having a high a priori density from freestyle.chainingiterators import ChainPredicateIterator from freestyle.predicates import ( AndUP1D, NotUP1D, QuantitativeInvisibilityUP1D, TrueBP1D, TrueUP1D, pyHighViewMapDensityUP1D, ) from freestyle.shaders import ( ConstantColorShader, ConstantThicknessShader, ) from freestyle.types import Operators Operators.select(AndUP1D(QuantitativeInvisibilityUP1D(0), pyHighViewMapDensityUP1D(0.1,5))) bpred = TrueBP1D() upred = AndUP1D(QuantitativeInvisibilityUP1D(0), pyHighViewMapDensityUP1D(0.0007,5)) Operators.bidirectional_chain(ChainPredicateIterator(upred, bpred), NotUP1D(QuantitativeInvisibilityUP1D(0))) shaders_list = [ ConstantThicknessShader(2), ConstantColorShader(0.0, 0.0, 0.0, 1.0) ] Operators.create(TrueUP1D(), shaders_list)
# # ##### END GPL LICENSE BLOCK ##### # Filename : ignore_small_oclusions.py # Author : Stephane Grabli # Date : 04/08/2005 # Purpose : The strokes are drawn through small occlusions from freestyle.chainingiterators import pyFillOcclusionsAbsoluteChainingIterator from freestyle.predicates import ( QuantitativeInvisibilityUP1D, TrueUP1D, ) from freestyle.shaders import ( ConstantColorShader, ConstantThicknessShader, SamplingShader, ) from freestyle.types import Operators Operators.select(QuantitativeInvisibilityUP1D(0)) #Operators.bidirectional_chain(pyFillOcclusionsChainingIterator(0.1)) Operators.bidirectional_chain(pyFillOcclusionsAbsoluteChainingIterator(12)) shaders_list = [ SamplingShader(5.0), ConstantThicknessShader(3), ConstantColorShader(0.0, 0.0, 0.0), ] Operators.create(TrueUP1D(), shaders_list)