Page 1 of 14 123 11 ... LastLast
Results 1 to 20 of 269
  1. #1
    Member
    Join Date
    Jun 2010
    Location
    Australia
    Posts
    241

    Sapling: A Tree Generator Add-On for Blender (OSX Fix 10 Aug 2011)

    Introduction
    I have been working on implementing the tree model described by Jason Weber and Joseph Penn into Blender. This model has proven popular and is used in the tree generator Arbaro and the Blender 2.49 plugin Gen3.

    Download Location
    http://projects.blender.org/tracker/..._OSX_Fixed.zip

    Installation Instructions

    1. Download the above file and unzip it into your Blender Add-Ons folder (.../blender/2.58/scripts/addons or some such)
    2. Start Blender and go to FILE -> USER PREFERENCES, in the window that opens click on the Add-Ons tab.
    3. Click Add Curve in the list on the left.
    4. Check the box next to the 'Sapling' add-on.
    5. Now in the 3D view, go to Add -> Curve -> Add Tree
    6. A tree is added and the options are in the tool shelf (T-KEY)
    7. Have fun playing around with the options!

    Wiki
    http://wiki.blender.org/index.php/Ex...e/Sapling_Tree

    Tracker
    http://projects.blender.org/tracker/...d=153&atid=469

    Version 0.2.4

    1. Added rectangular leaves with UV mapping
    2. Fixed tracker URL


    Version 0.2.3

    1. Added wiki and tracker URLs
    2. Fixed usage of Matrix.Rotation

    Version 0.2.2

    1. Fixed preset path to work with user defined script location (code thanks to Sanne).
    2. Fixed limit import to work correctly and not export limit import value.
    3. Fixed radius calculation issue to correctly implement the weeping willow preset.
    4. Fixed presets to have all parameters correct in the preset file.
    5. Minor code improvements.

    Version 0.2.1

    1. Updated to 2.58 API
    2. Added the ability to start the tree at an angle to the ground via startCurv
    3. Fixed an issue where, even if the seed value was the same, the tree generated would be different
    4. Fixed calculation of upward attraction for correct implementation
    5. Added presets for CA Black Oak and Weeping Willow.

    Version 0.2
    Version 0.2 of Sapling has now been uploaded and can be found here. The following changes have been made to this version:

    1. Automatic armatures have been added so it is possible to generate an armature and bones for the whole tree easily. This includes the leaves which also have vertex groups to make sure they stay attached to their branches.
    2. Automatic armature animations have also been included to add wind to a tree automatically.
    3. GUI updated to make it smaller, a drop down box within the panel now allows access to each section of tree parameters. They are in the recommended order of editting.
    4. PruneRatio has been added which allows for adjusting the amount of pruning applied.
    5. A better visualisation of the pruning envelope has been added to make it easier to see the shape that you are forcing the tree to take on.
    6. Leaf generation has had some corrections which should also speed it up.
    7. Comments on the code have been added for those interested.

    Cheers,
    Truman

    Version 0.1
    Hi All,

    I have been working on implementing the tree model described by Jason Weber and Joseph Penn into Blender. This model has proven popular and is used in the tree generator Arbaro and the Blender 2.49 plugin Gen3.

    I am happy to announce that 'Sapling' is ready for a first release (v0.1) and can be found here. This was written using Blender 2.56.6 r36007 (RC2).

    In order to use the script follow these steps:

    1. Download the above file and place it in your Blender Add-Ons folder (.../blender/2.56/scripts/addons or some such)
    2. Start Blender and go to FILE -> USER PREFERENCES, in the window that opens click on the Add-Ons tab.
    3. Click Add Curve in the list on the left.
    4. Check the box next to the 'Sapling' add-on.
    5. Now in the 3D view, go to Add -> Curve -> Add Tree
    6. A tree is added and the options are in the tool shelf (T-KEY)
    7. Have fun playing around with the options!

    There are a few things to note:

    • You can adjust the quality of the tree at any time using the 'Preview U' and 'Bevel Resolution' option in the Object Data section of the properties panel.
    • The following options are disabled by default to speed up editing:
      • You must tick the 'Bevel' box to see the actual tree.
      • You must tick the 'Leaves' box to generate the leaves.

    • You can change 'Levels' to see only the level you are editing (and the ones below it).
    • You must tick the box 'Prune' if you want to enforce a shape on the tree.
    • The tree which is created by default is the 'Quaking Aspen'.

    Also, there are some elements of the model which are not implemented:

    • Flaring of the trunk is not yet supported, I am currently looking into this.
    • Periodic tapering of the branches is not supported and is unlikely to be due to limitations of using curves for the branches.
    • Wind sway is not yet implemented but is the next item on the to-do list.

    The default output of the script, with bevelling and leaves enabled (plus some quick materials) is shown below:
    tree.jpg
    This tree has about 180k verts but as described above, this can be adjusted.

    If there is enough interest I might create a tutorial explaining all the options and how to use them.

    Please feel free to leave any comments and suggestions as well as bugs to I can try to get them out of the way quickly.

    Cheers and enjoy,
    Truman
    Last edited by TrumanBlending; 10-Aug-11 at 05:25. Reason: Updated for New Version



  2. #2
    Member PKHG's Avatar
    Join Date
    Sep 2009
    Location
    NL
    Posts
    1,852
    Wow , nice to use ;-)!!!!
    Question: what should one do to make the leaves be fixed to the twigs and move in the wind?
    Attached Images Attached Images
    Last edited by PKHG; 12-Apr-11 at 11:24.



  3. #3
    Member Atom's Avatar
    Join Date
    Jan 2006
    Location
    Ohio
    Posts
    11,408
    Looks great!

    Some very nice additions to the previous script. I like the split feature a lot. Pruning is nice as well.

    It did not crash at all. The only unexpected operation that happened was when I typed in a number in one of the fields then pressed CTRL-Z (to undo) the entire panel disappeared as well as the tree I had spent much time on. That is probably more of a Blender panel issue, however. But if you have anyway to deny the panel exit if a CTRL-Z is pressed it might be nice to add.
    Attached Images Attached Images
    Last edited by Atom; 12-Apr-11 at 11:27.
    OSX Mac Mini i7 @ 2.6ghz 16Gb Ram (no GPU)
    Windows 7 8Gb, GeForce GTX 660 2Gb Ram AMD Hexcore @ 2.7Ghz.
    Atom's Links Page



  4. #4
    Member batFINGER's Avatar
    Join Date
    Jun 2007
    Location
    Lochiel NSW Australia
    Posts
    1,741
    Very cool script... ground my win32 shitbox to a halt with too many branches and leaves.

    I have a suggestion for setting up your properties. In an addon I'm grinding away on i started using xml data to store the default settings that the user changes in an operator and preserve these settings for the lifetime of the blend file or to disk.

    I think this method or something similar has application here giving an easy way to save your settings as presets like "Oak Tree" or "Rasperry Bush" etc. Saving them to a file makes them available to your next file. The xml data could be served from/to a webserver with a collaborative database. Or easilly added via the text editor.

    The snippets come from a multiple script addon in a directory "MocapMadness" . __init__.py takes care of the importing and calling the register method of each script.

    In the config.py script the settings are loaded from settings.xml.


    a snippet from config.py
    Code:
    def LoadSettings():
        import os
        Dir = os.path.dirname(__file__)
        path = os.path.join(Dir, 'settings.xml')
        # load settings from the addon. (can be user saved)
        settings = ET.parse(path)
        #print(ET.tostring(settings))
        return settings
    
    settings = LoadSettings()
    # Set operator settings from settings node
    #
    
    
    def SetOperatorProperties(name):
    
        global settings
        dprint("SET OPERATOR PROPERTIES: %s"%name)
        if not settings :
            return(False)
    
        cmds = []
        Settings = settings.findall('Settings[@name="%s"]/Setting'%name)
        
        for Setting in Settings:
    
            attrs = ["name","description"]
        
            default = False # Take out default value code.. settings 
            '''
            It's set by settings anyhow.. enables values like
            bpy.context.scene.fps
            to be used as default
            '''
            proptype = Setting.get("type")
            prop_name = Setting.get("prop_name")
            args = []
            
            if proptype in ["int","float"]:
                if default:
                   def_value = eval("%s"%Setting.text)
                attrs.extend(["min","max","soft_min","soft_max","unit"])
            elif proptype in ["str"]:
                if default:
                    def_value = '"%s"'%Setting.text
                attrs.extend(["maxlen"])
                proptype = "string"
               
            for attr in attrs :
                
                if Setting.get(attr):
                    if attr == "default":
                        args.append('%s=%s'%(attr,def_value))
                    elif attr in ["description","name"]:
                        args.append('%s="%s"'%(attr,Setting.get(attr)))
                    else:
                        args.append('%s=%s'%(attr,Setting.get(attr)))
    
            expr = '%s =  %sProperty('%(prop_name,str.title(proptype))
            for arg in args:
                expr += '%s,'%arg
            expr += ")"
            cmds.append(expr)
        return cmds
    
    def SetOperatorSettings(operator):
        name = operator.mocapmadness_name
        global settings
        print("GetSettings: %s"%name)
        if not settings :
            return(False)
    
    
        Settings = settings.findall('Settings[@name="%s"]/Setting'%name)
        for Setting in Settings:
            print("SETTING: %s"%Setting.text)
            if Setting.get("type") == "str":
                value = Setting.text
            else:    
                value = eval("%s"%Setting.text)
            expr = 'operator.%s =  value'%(Setting.get("prop_name"))
            exec(expr)
                
    def PreserveSettings(operator):
        name = operator.mocapmadness_name
        global settings
        print("Preserve Settings:: %s"%name)
        if not settings :
            print("NO SETTINGS")
            return(False)
    
    
        Settings = settings.findall('Settings[@name="%s"]/Setting'%name)
        for Setting in Settings:
    
            value = eval('operator.%s'%Setting.get("prop_name"))
            if Setting.get("type") == "float":
                value = str(round(value,2))
            Setting.text = value
    Now in the operator.py script the operator class. The methods above are called to generate the operator's properties and are set, and saved (to file if desired) in the invoke and execute methods.
    I haven't been using vector properties, the code for them needs to be set up.

    Code:
    import MocapMadness.config as mocapmadness
    class LoadBvhButton(bpy.types.Operator, ImportHelper):
        bl_idname = "mocapmadness.import_bvh"
        bl_label = "Load BVH file (.bvh)"
        mocapmadness_name = bl_idname
        for cmd in mocapmadness.SetOperatorProperties("mocapmadness.import_bvh"):
            exec(cmd)
        filename_ext = ".bvh"
        filter_glob = StringProperty(default="*.bvh", options={'HIDDEN'})
        rot_mode = EnumProperty(items=(
            ('QUATERNION', "Quaternion", "Convert rotations to quaternions"),
            ('NATIVE', "Euler (Native)", "Use the rotation order defined in the BVH file"),
            ('XYZ', "Euler (XYZ)", "Convert rotations to euler XYZ"),
            ('XZY', "Euler (XZY)", "Convert rotations to euler XZY"),
            ('YXZ', "Euler (YXZ)", "Convert rotations to euler YXZ"),
            ('YZX', "Euler (YZX)", "Convert rotations to euler YZX"),
            ('ZXY', "Euler (ZXY)", "Convert rotations to euler ZXY"),
            ('ZYX', "Euler (ZYX)", "Convert rotations to euler ZYX"),
            ),
                name="Rotation",
                description="Rotation conversion.",
                default='NATIVE')
    
        def invoke(self, context, event):
            mocapmadness.SetOperatorSettings(self)   
            context.window_manager.fileselect_add(self)
            return {'RUNNING_MODAL'} 
    
        def execute(self, context):
            ... do stuff
            mocapmadness.Save()
            mocapmadness.PreserveSettings(self)
    The data is set up like this and holds the default value of your properties. You use expressions from the math lib and blender props like bpy.context.scene.render.fps.

    settings.xml

    Code:
    <Settings>
        <Settings name="mocapmadness.import_bvh">
            <Setting prop_name="Scale" type="float" description="Scale the bvh">0.12</Setting>
            <Setting prop_name="Rot90" type="bool" name="Rotate 90 (Z up)">True</Setting>
            <Setting prop_name="Sync" type="bool" name="Use timing from bvh">True</Setting>
            <Setting prop_name="Origin" type="bool" name="Travel Origin" description="Make the starting position (0,0) and original hip height" >True</Setting>
            <Setting prop_name="TPose" type="bool" name="TPose Rest Pose" description="Attempt to change rest pose to TPose in frame 0"   >True</Setting>
            <Setting prop_name="Discard" type="bool" name="Action Only" description="Keep the action but discard rig and armature">False</Setting>
            <Setting prop_name="UseOnlyRootBoneLoc" type="bool" name="Only rootbone locations" description="Only calculate locations for root bones.">False</Setting> 
            <Setting prop_name="Dismiss" type="bool" name="Dismiss Dialog" description="Return to Import View to Import another.">True</Setting> 
            <Setting prop_name="TargetRig" type="str" name="TargetRig" description="Name of Target Rig">ST_Rig</Setting>
        </Settings>
            <Setting prop_name="fps" type="int" name="Frames_Per_Second" description="Frame Rate">bpy.context.scene.render.fps</Setting>
    </Settings>
    Last edited by batFINGER; 13-Apr-11 at 11:21.



  5. #5
    Member
    Join Date
    Jun 2010
    Location
    Australia
    Posts
    241
    batFINGER: This is exactly what I would like to do, but up until now didn't know how to. It'll take some work to get this set up so it might not be introduced for a while but it is now on my to-do list. Thanks for the great examples.

    On a general note, does anyone know how (or even if it is possible) to do the following things:

    1. Make sections of script's UI collapsable so they don't take up so much room in the tool shelf.
    2. Add edit bones to an armature without using bpy.ops.

    Cheers,
    Truman

    PS I have created the animation armature for the tree (using bpy.ops) and corrected the code for the leaves which should also speed up the script. Once the animation is added and a few other things tidied up, I'll release v0.2



  6. #6
    Member Evil Moon MOose's Avatar
    Join Date
    Feb 2011
    Location
    Copperas Cove Texas
    Posts
    1,953
    thanks Im subscribing to this thread for later updates
    View my portfolio here... My Portfolio
    Sackboy Animation! Check it out!
    By the way, I have a god complex....and blender only helps it....



  7. #7
    Make sections of script's UI collapsable so they don't take up so much room in the tool shelf.
    There's a 'default collapse' or something like that so it doesn't show the full panel, just search the ui directory for one that is collapsed by default.
    Add edit bones to an armature without using bpy.ops.
    arm.edit_bones.new('bone')

    But the armature needs to be in editmode and if you don't set the head/tail blender will delete your zero-length bone (IIRC).



  8. #8
    Member batFINGER's Avatar
    Join Date
    Jun 2007
    Location
    Lochiel NSW Australia
    Posts
    1,741
    Originally Posted by TrumanBlending View Post
    1. Make sections of script's UI collapsable so they don't take up so much room in the tool shelf.

    Cheers,
    Truman
    On the collapsible UI. If it was a panel class you could do something like this http://www.blender.org/documentation...mix-in-classes

    But since your panel relies on the draw of the operator it might pay to set up a buttons for tabs kinda thing using some dummy display properties and display for that selection in the draw method. In the snippet below your "Branch Growth" box will only show once bevel is True.

    Code:
            if self.bevel:
                box = layout.box()
                box.label('Branch Growth')
                row = box.row()
                row.prop(self,'levels')
                row = box.row()
                row.prop(self,'attractUp')
                row = box.row()
                col = row.column()
                col.prop(self,'length')
                col = row.column()
                col.prop(self,'lengthV')
                row = box.row()
                col = row.column()
                col.prop(self,'curve')
                col = row.column()
                col.prop(self,'curveV')
                row = box.row()
                col = row.column()
                col.prop(self,'curveBack')
                col = row.column()
                col.prop(self,'taper')
                row = box.row()
                col = row.column()
                col.prop(self,'curveRes')
    Last edited by batFINGER; 14-Apr-11 at 03:44.



  9. #9
    Member
    Join Date
    Jun 2010
    Location
    Australia
    Posts
    241
    Originally Posted by Uncle Entity View Post
    There's a 'default collapse' or something like that so it doesn't show the full panel, just search the ui directory for one that is collapsed by default.

    arm.edit_bones.new('bone')

    But the armature needs to be in editmode and if you don't set the head/tail blender will delete your zero-length bone (IIRC).
    Thanks Uncle, I'll look into the panels. With respect to the edit bones, my question was phrased poorly. I have used the method you describe, but unfortunately it requires bpy.ops to enter/exit edit mode, that was the main problem, not actually adding the bones. I have a suspicion there is no way to add bones without this enter/exit op.

    Originally Posted by batFINGER View Post
    On the collapsible UI. If it was a panel class you could do something like this http://www.blender.org/documentation...mix-in-classes

    But since your panel relies on the draw of the operator it might pay to set up a buttons for tabs kinda thing using some dummy display properties and display for that selection in the draw method. In the snippet below your "Branch Growth" box will only show once bevel is True.
    Good idea this one, I've used an EnumProperty to drive the visibility instead of a boolean to it works like it want it to. Thanks for the idea.



  10. #10



  11. #11
    Originally Posted by TrumanBlending View Post
    Thanks Uncle, I'll look into the panels. With respect to the edit bones, my question was phrased poorly. I have used the method you describe, but unfortunately it requires bpy.ops to enter/exit edit mode, that was the main problem, not actually adding the bones. I have a suspicion there is no way to add bones without this enter/exit op.
    Yep, I think that's the only way it works due to the way blender stores armatures internally (it creates edit bones when going into edit mode and destroys them when leaving).



  12. #12
    Member
    Join Date
    Jun 2010
    Location
    Australia
    Posts
    241
    Hi All,

    Here is a quick update on what I have been working on.



    This animation is completely handled by the script using only fcurve modifiers. No keyframing required! The parenting, vertex groups and armature modifiers are also all automatic.

    I'm currently trying to clean up the code and add more useful comments. A new version including all these features should be available soon.

    Cheers,
    Truman



  13. #13
    Member Meta-Androcto's Avatar
    Join Date
    Aug 2006
    Location
    australia
    Posts
    3,455
    very cool script!
    I was testing it out the other day.
    thanks, I look forward to the next version.



  14. #14
    awesome, but need a second motion for the leafs.



  15. #15
    Member MikeJ's Avatar
    Join Date
    Aug 2009
    Location
    Santa Cruz, CA
    Posts
    386
    Great work!



  16. #16
    Member Meta-Androcto's Avatar
    Join Date
    Aug 2006
    Location
    australia
    Posts
    3,455
    hi,
    It would be good to add this to Blender contrib scripts & svn.
    If you read this: http://wiki.blender.org/index.php/Dev:Py/Sharing
    You can start the proccess easily with a Projects & Wiki page & we can provide you with a good developement enviroment.
    I can provide any help you need setting this up.
    Thanks, what a cool script.



  17. #17
    Member
    Join Date
    Jun 2010
    Location
    Australia
    Posts
    241
    Version 0.2 has been uploaded, see the first post for the link and a list of the updates. Thanks for the support too!

    Originally Posted by Meta-Androcto View Post
    hi,
    It would be good to add this to Blender contrib scripts & svn.
    If you read this: http://wiki.blender.org/index.php/Dev:Py/Sharing
    You can start the proccess easily with a Projects & Wiki page & we can provide you with a good developement enviroment.
    I can provide any help you need setting this up.
    Thanks, what a cool script.
    Hi Meta,

    This would be great! I'll have a read through and get back to you with any questions.

    Cheers,
    Truman



  18. #18
    Member
    Join Date
    Jun 2010
    Location
    Australia
    Posts
    241

    Addition of Presets

    Hi All,

    Here is a tentative update for the tree generator. I have been working on allowing saving and loading of presets and thus needed to move to a multi-script add-on. The zipped files can be found here. To install, unzip into the addons directory of your Blender distribution. Then go into User Preferences and enable 'Sapling'.

    I won't update the main post yet as I would like to get any feedback that anyone has before making a new release. I will also look into putting up a wiki page for this.

    Cheers,
    Truman

    PS The preset options are available at the top of the panel. Two presets are included, the Quaking Aspen and the Black Tupelo. Enjoy!



  19. #19
    Member PKHG's Avatar
    Join Date
    Sep 2009
    Location
    NL
    Posts
    1,852
    Great improvement (see picture, generated by your script)

    Small problem?
    File "C:\Users\Peter\25Blender\blenderLatest\2.57\scrip ts\addons\add_curve_sapling\utils.py", line 238, in growSpline
    angleX = stem.splitAngle(splitAng,splitAngV) + stem.curv + uniform(-stem.curvV,stem.curvV) - curveUpAng
    UnboundLocalError: local variable 'curveUpAng' referenced before assignment

    Last edited by PKHG; 26-Apr-11 at 01:33. Reason: typing errors removed



  20. #20
    Member Atom's Avatar
    Join Date
    Jan 2006
    Location
    Ohio
    Posts
    11,408
    As it is spring, here in Ohio, I see lots of trees moving in the wind and I do have to agree with bat3a. A secondary movement on the leaves would be a nice addition.
    OSX Mac Mini i7 @ 2.6ghz 16Gb Ram (no GPU)
    Windows 7 8Gb, GeForce GTX 660 2Gb Ram AMD Hexcore @ 2.7Ghz.
    Atom's Links Page



Page 1 of 14 123 11 ... LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •