[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [12671] trunk/blender/release/scripts/ wizard_curve2tree.py: new twig type that gives more even results - " Fill Twigs" option
Campbell Barton
ideasman42 at gmail.com
Sun Nov 25 21:49:40 CET 2007
Revision: 12671
http://projects.blender.org/plugins/scmsvn/viewcvs.php?view=rev&root=bf-blender&revision=12671
Author: campbellbarton
Date: 2007-11-25 21:49:38 +0100 (Sun, 25 Nov 2007)
Log Message:
-----------
new twig type that gives more even results - "Fill Twigs" option
Modified Paths:
--------------
trunk/blender/release/scripts/wizard_curve2tree.py
Modified: trunk/blender/release/scripts/wizard_curve2tree.py
===================================================================
--- trunk/blender/release/scripts/wizard_curve2tree.py 2007-11-25 20:12:54 UTC (rev 12670)
+++ trunk/blender/release/scripts/wizard_curve2tree.py 2007-11-25 20:49:38 UTC (rev 12671)
@@ -38,6 +38,7 @@
import bpy
import Blender
+import BPyMesh
from Blender.Mathutils import Vector, Matrix, CrossVecs, AngleBetweenVecs, LineIntersect, TranslationMatrix, ScaleMatrix, RotationMatrix, Rand
from Blender.Geometry import ClosestPointOnLine
@@ -73,7 +74,16 @@
q1+= q2
q2+= q3;
+def points_from_bezier_seg(steps, pointlist, radlist, bez1_vec, bez2_vec, radius1, radius2):
+
+ # x,y,z,axis
+ for ii in (0,1,2):
+ forward_diff_bezier(bez1_vec[1][ii], bez1_vec[2][ii], bez2_vec[0][ii], bez2_vec[1][ii], pointlist, steps, ii)
+
+ # radius - no axis, Copied from blenders BBone roll interpolation.
+ forward_diff_bezier(radius1, radius1 + 0.390464*(radius2-radius1), radius2 - 0.390464*(radius2-radius1), radius2, radlist, steps, None)
+
def debug_pt(co):
Blender.Window.SetCursorPos(tuple(co))
Blender.Window.RedrawAll()
@@ -158,6 +168,7 @@
self.limbScale = 1.0
self.debug_objects = []
+ self.steps = 6 # defalt, curve overwrites
def __repr__(self):
s = ''
@@ -175,7 +186,7 @@
self.objectCurveMat = objectCurve.matrixWorld
self.objectCurveIMat = self.objectCurveMat.copy().invert()
curve = objectCurve.data
- steps = curve.resolu # curve resolution
+ self.steps = curve.resolu # curve resolution
# Set the curve object scale
if curve.bevob:
@@ -188,8 +199,8 @@
# forward_diff_bezier will fill in the blanks
# nice we can reuse these for every curve segment :)
- pointlist = [[None, None, None] for i in xrange(steps+1)]
- radlist = [ None for i in xrange(steps+1) ]
+ pointlist = [[None, None, None] for i in xrange(self.steps+1)]
+ radlist = [ None for i in xrange(self.steps+1) ]
for spline in curve:
@@ -209,19 +220,7 @@
for i in xrange(1, len(bez_list)):
bez1 = bez_list[i-1]
bez2 = bez_list[i]
- bez1_vec = bez1.vec
- bez2_vec = bez2.vec
-
- radius1 = bez1.radius
- radius2 = bez2.radius
-
- # x,y,z,axis
- for ii in (0,1,2):
- forward_diff_bezier(bez1_vec[1][ii], bez1_vec[2][ii], bez2_vec[0][ii], bez2_vec[1][ii], pointlist, steps, ii)
-
- # radius - no axis, Copied from blenders BBone roll interpolation.
- forward_diff_bezier(radius1, radius1 + 0.390464*(radius2-radius1), radius2 - 0.390464*(radius2-radius1), radius2, radlist, steps, None)
-
+ points_from_bezier_seg(self.steps, pointlist, radlist, bez1.vec, bez2.vec, bez1.radius, bez2.radius)
bpoints = [ bpoint(brch, Vector(pointlist[ii]), Vector(), radlist[ii] * self.limbScale) for ii in xrange(len(pointlist)) ]
# remove endpoint for all but the last
@@ -264,11 +263,11 @@
self.objectLeafBoundsMesh = objectMesh.getData(mesh=1)
self.objectLeafBoundsIMat = objectMesh.matrixWorld.copy().invert()
- def isPointInTwigBounds(self, co):
- return self.objectTwigBoundsMesh.pointInside(co * self.objectCurveMat * self.objectTwigBoundsIMat)
+ def isPointInTwigBounds(self, co, selected_only=False):
+ return self.objectTwigBoundsMesh.pointInside(co * self.objectCurveMat * self.objectTwigBoundsIMat, selected_only)
- def isPointInLeafBounds(self, co):
- return self.objectLeafBoundsMesh.pointInside(co * self.objectCurveMat * self.objectLeafBoundsIMat)
+ def isPointInLeafBounds(self, co, selected_only=False):
+ return self.objectLeafBoundsMesh.pointInside(co * self.objectCurveMat * self.objectLeafBoundsIMat, selected_only)
def resetTags(self, value):
for brch in self.branches_all:
@@ -300,11 +299,21 @@
variation_seed = 1,\
variation_orientation = 0.0,\
variation_scale = 0.0,\
+ do_twigs_fill = 0,\
+ twig_fill_levels=4,\
+ twig_fill_rand_scale=0.0,\
+ twig_fill_fork_angle_max=60.0,\
+ twig_fill_radius_min=0.1,\
+ twig_fill_radius_factor=0.75,\
+ twig_fill_shape_type=0,\
+ twig_fill_shape_rand=0.0,\
+ twig_fill_shape_power=0.3,\
):
'''
build tree data - fromCurve must run first
'''
+
# Sort the branchs by the first radius, so big branchs get joins first
### self.branches_all.sort( key = lambda brch: brch.bpoints[0].radius )
@@ -377,6 +386,9 @@
# mat_orientation = RotationMatrix(0, 3, 'r', brch.parent_pt.no)
brch.transformRecursive(self, mat_scale * mat_orientation, brch.parent_pt.co)
+ if (do_twigs or do_twigs_fill) and twig_ob_bounds: # Only spawn twigs inside this mesh
+ self.setTwigBounds(twig_ob_bounds)
+
# Important we so this with existing parent/child but before connecting and calculating verts.
if do_twigs:
@@ -386,9 +398,6 @@
irational_num = 22.0/7.0 # use to make the random number more odd
- if twig_ob_bounds: # Only spawn twigs inside this mesh
- self.setTwigBounds(twig_ob_bounds)
-
if not twig_recursive:
twig_recursive_limit = 0
@@ -542,6 +551,19 @@
self.branches_all.extend(branches_twig_attached)
branches_twig_attached = []
+
+ if do_twigs_fill and twig_ob_bounds:
+ self.twigFill(\
+ twig_fill_levels,\
+ twig_fill_rand_scale,\
+ twig_fill_fork_angle_max,\
+ twig_fill_radius_min,\
+ twig_fill_radius_factor,\
+ twig_fill_shape_type,\
+ twig_fill_shape_rand,\
+ twig_fill_shape_power,\
+ )
+
### self.branches_all.sort( key = lambda brch: brch.parent_pt != None )
# Calc points with dependancies
@@ -610,6 +632,482 @@
for brch in self.branches_all:
brch.branchReJoin()
'''
+
+ def twigFill(self_tree,\
+ twig_fill_levels,\
+ twig_fill_rand_scale,\
+ twig_fill_fork_angle_max,\
+ twig_fill_radius_min,\
+ twig_fill_radius_factor,\
+ twig_fill_shape_type,\
+ twig_fill_shape_rand,\
+ twig_fill_shape_power,\
+ ):
+ '''
+ Fill with twigs, this function uses its own class 'segment'
+
+ twig_fill_shape_type;
+ 0 - no child smoothing
+ 1 - smooth one child
+ 2 - smooth both children
+
+ '''
+
+ segments_all = []
+ segments_level = []
+
+ # Only for testing
+ def preview_curve():
+ TWIG_WIDTH_MAX = 1.0
+ TWIG_WIDTH_MIN = 0.1
+ cu = bpy.data.curves["cu"]
+ # remove all curves
+ while len(cu):
+ del cu[0]
+ # return
+
+ cu.setFlag(1)
+ cu.ext2 = 0.01
+
+ WIDTH_STEP = (TWIG_WIDTH_MAX-TWIG_WIDTH_MIN) / twig_fill_levels
+
+ for i, seg in enumerate(segments_all):
+
+ # 1 is the base and 2 is the tail
+
+ p1_h2 = seg.getHeadHandle() # isnt used
+ p1_co = seg.headCo
+ p1_h1 = seg.getHeadHandle()
+
+ p2_h1 = seg.getTailHandle()
+
+ p2_co = seg.tailCo
+ p2_h2 = seg.tailCo # isnt used
+
+ bez1 = Blender.BezTriple.New([ p1_h1[0], p1_h1[1], p1_h1[2], p1_co[0], p1_co[1], p1_co[2], p1_h2[0], p1_h2[1], p1_h2[2] ])
+ bez2 = Blender.BezTriple.New([ p2_h1[0], p2_h1[1], p2_h1[2], p2_co[0], p2_co[1], p2_co[2], p2_h2[0], p2_h2[1], p2_h2[2] ])
+ bez1.handleTypes = bez2.handleTypes = [Blender.BezTriple.HandleTypes.FREE, Blender.BezTriple.HandleTypes.FREE]
+
+ bez1.radius = TWIG_WIDTH_MIN + (WIDTH_STEP * (seg.levelFromLeaf+1))
+ bez2.radius = TWIG_WIDTH_MIN + (WIDTH_STEP * seg.levelFromLeaf)
+
+ cunurb = cu.appendNurb(bez1)
+ cunurb.append(bez2)
+
+ # This sucks
+ for bez in cunurb:
+ bez.handleTypes = [Blender.BezTriple.HandleTypes.FREE, Blender.BezTriple.HandleTypes.FREE]
+
+ ### cc = sce.objects.new( cu )
+ cu.update()
+
+
+ def mergeCo(parentCo, ch1Co, ch2Co, twig_fill_shape_rand):
+ if twig_fill_shape_rand==0.0:
+ return (parentCo + ch1Co + ch2Co) / 3.0
+ else:
+ w1 = Rand(0.0, twig_fill_shape_rand) + (1-twig_fill_shape_rand)
+ w2 = Rand(0.0, twig_fill_shape_rand) + (1-twig_fill_shape_rand)
+ w3 = Rand(0.0, twig_fill_shape_rand) + (1-twig_fill_shape_rand)
+ wtot = w1+w2+w3
+ w1=w1/wtot
+ w2=w2/wtot
+ w3=w3/wtot
+
+ # return (parentCo*w1 + ch1Co*w2 + ch2Co*w2)
+ co1 = (parentCo * w1) + (ch1Co * (1.0-w1))
+ co2 = (ch1Co * w2) + (ch2Co * (1.0-w2))
+ co3 = (ch2Co * w3) + (parentCo * (1.0-w3))
+
+ return (co1 + co2 + co3) / 3.0
+
+
+
+ class segment:
+ def __init__(self, level):
+ self.headCo = Vector()
+ self.tailCo = Vector()
+ self.parent = None
+ self.mergeCount = 0
+ self.levelFromLeaf = level # how far we are from the leaf in levels
+ self.levelFromRoot = -1 # set later, assume root bone
+ self.children = []
+ segments_all.append(self)
+
+ if level >= len(segments_level): segments_level.append([self])
+ else: segments_level[level].append(self)
+
+ self.brothers = []
+ self.no = Vector() # only endpoints have these
+ self.id = len(segments_all)
+ self.bpt = None # branch point for root segs only
+
+ def getHeadHandle(self):
+ """
+ For Bezier only
+ """
+
+ if not self.parent:
+ return self.headCo
+
+ if twig_fill_shape_type == 0: # no smoothing
+ return self.headCo
+ elif twig_fill_shape_type == 1:
+ if self.parent.children[1] == self:
+ return self.headCo
+ # 2 - always do both
+
+
+ # Y shape with curve? optional
+
+ # we have a parent but it has no handle direction, easier
+ if not self.parent.parent: no = self.parent.headCo - self.parent.tailCo
+ else: no = self.parent.parent.headCo-self.parent.tailCo
+
+ no.length = self.getLength() * twig_fill_shape_power
+ # Ok we have to account for the parents handle
+ return self.headCo - no
+ # return self.headCo - Vector(1, 0,0)
+
+ def getTailHandle(self):
+ """
+ For Bezier only
+ """
+ if self.parent:
+ no = self.parent.headCo-self.tailCo
+ no.length = self.getLength() * twig_fill_shape_power
+ return self.tailCo + no
+ else:
+ return self.tailCo # isnt used
+
+ def getRootSeg(self):
+ seg = self
+ while seg.parent:
+ seg = seg.parent
+
+ return seg
+
+ def calcBrothers(self):
+ # Run on children first
+ self.brothers.extend( \
+ [seg_child_sibling.parent \
+ for seg_child in self.children \
+ for seg_child_sibling in seg_child.brothers \
+ if seg_child_sibling.parent not in (self, None)]\
+ )
+ #print self.brothers
+
+ def calcLevelFromRoot(self):
+ if self.parent:
@@ Diff output truncated at 10240 characters. @@
More information about the Bf-blender-cvs
mailing list