text:
Cycles Materials Math node with more than two inputs
Are there any mods that allow Math nodes to accept more than just two inputs? I regularly find myself wanting to, say, get the Maximum value from multiple inputs and end up having to chain multiple Math nodes together. While this does work fine, it looks really messy and is quite inconvenient and cumbersome. It would be really nice to have a Math node that could work like the Group Input/Output nodes where a blank socket is used to add any additional inputs/outputs as required.
Obviously better than a mod would be native Blender functionality for this. Where would I post such a feature request if there isn't one already?
EDIT : The main question here is whether such a feature exists already - if it doesn't then I'll look into raising it as a feature request - but I'd like to determine that this feature doesn't already exist in some form first.

@cegaton See the edit. It is no longer a possible duplicate.

Quick Answer: Learn Python and the Blender's API, and look into bpy.types.NodeCustomGroup.

@Secrop I’d be very interested to see a working solution. I’ve dabbled with pynodes (see https://blender.stackexchange.com/a/75507/29586 for example) and I don’t think it would work - not efficiently, anyway - or do you mean something different?

@Rich Sedman, that link offers a wrong way to use python nodes with builtin systems (textures, compositor, cycles). Deriving from the Node class will not let Cycles to dig inside because the node is registered as Custom, and there's no code to interpret the node. The workaround, as I stated above, is to use the NodeCustomGroup class which is similar to NodeGroups. This way you can build and change the internal nodetree in runtime and Cycles will still interpret this as a NodeGroup. I can write a proper answer to this later, thought there's much to cover.

@Secrop Thanks for the explanation. Dynamically built nodegroups sounds very interesting. If you can provide a suitable working solution I’ll happily stump up a bounty.

Add the background your still using groups, and groups should be used to do this, so it seams bogus usage, this should not be a future request.

@user3800527 I know this can be done with node groups but it’s quite inconvenient to manipulate groups manually whenever the number of inputs changes. The NodeCustomGroup solution addresses this by automatically manipulating the groups for any number of sockets and operation while appearing and behaving like a standard node - and the bode group is still gpu/cuda friendly.

I won't cover the complete topic about Custom Nodes, because there's too much that can be done.
This is just a small compilation of things to know for writing custom nodes that work in Cycles. Knowledge of Python and Blender's API is required, as I won't dig deep into them.
In Blender's API we have a NodeCustomGroup class that is similar to the NodeGroup class. Before going into the NodeCustomGroup, let us explain a bit how the nodetrees work:
A Nodetree has mainly 4 collections. The nodes collection, the links collection, the inputs collection and the outputs collection. The NodeGroup node encapsulates a nodetree in order to turn it into a visible node in the editor. It scans the nodetree interface, and creates sockets for using the nodetree. This process is automatic and there's nothing we can do with it.
The good news is that we have the NodeCustomGroup. From this class, we can build the interface of a nodetree and even build/rebuild the same nodetree dynamically, have custom properties, respond to events, and have access to the Blender's context.
For the NodeCustomGroup, we'll need to create our nodetree (which must be a ShaderNodeTree, if we're going to make a Cycles' node). Then we need to populate this tree with one NodeGroupInput and one NodeGroupOutput, as they are used to create the nodetree interface. After we build our nodetree as we do for nodegroups: add nodes, input sockets, output sockets, and links to connect everything.
After that you need to define how the Custom Node is supposed to work...For example, in this case, would include functions that check if an input Virtual Socket is linked, and if so, make the changes to the nodetree, create a new Float Socket, remove that original link and add a new link to the created socket, etc. Actions for checking if some socket is disconnect might also be written.
When the node is completed one must register it, which is the same process as for any class in Blender.
For adding it to the Add Menu and the Add Panel, you should to use the nodeitems_utils module (and for a better integration, one should also use the ShaderNewNodeCategory from nodeitems_builtins). This should be used with caution as I know some well known addons that use these modules in ways that disable the interface of other addons (i.e. Blend4Web).
For the last, I leave here the code from a node from my Github page. It's small enough to paste it here, and it covers dynamic nodetree and interface management. Some examples of this node working here.
# Node Authors: Secrop
# Node Description: Node for creating loops over some nodegroup
# version: (0,0,3)

import bpy

# for blender2.80 we should derive the class from bpy.types.ShaderNodeCustomGroup
class ShaderNodeLoop(bpy.types.NodeCustomGroup):

    bl_name='ShaderNodeLoop'
    bl_label='Loop Node'

    def nodegroups(self, context):
        nt=context.space_data.edit_tree
        list=[('None','None','None')]
        for nd in nt.nodes:
            if nd.type=='GROUP':
                ng=nd.node_tree
                if ng.inputs.get('iterator'):
                    list.append((ng.name, ng.name, ng.name))
        return list

    def __nodeinterface_setup__(self):
        self.node_tree.outputs.clear()
        self.node_tree.inputs.clear()
        if self.step_nodegroup=='None':
            return
        for input in bpy.data.node_groups[self.step_nodegroup].inputs:
            if not input.name=='iterator':
                self.node_tree.nodes['Group Input'].outputs.new(input.bl_socket_idname, input.name)
                self.node_tree.inputs.new(input.bl_socket_idname, input.name)
        for output in bpy.data.node_groups[self.step_nodegroup].outputs:
            self.node_tree.nodes['Group Output'].inputs.new(output.bl_socket_idname, output.name)
            self.node_tree.outputs.new(output.bl_socket_idname, output.name)

    def __nodetree_setup__(self):
        self.node_tree.links.clear()
        for node in self.node_tree.nodes:
            if not node.name in ['Group Input','Group Output']:
                self.node_tree.nodes.remove(node)
        if self.step_nodegroup=='None':
            return
        previousnode=self.node_tree.nodes['Group Input']
        for iter in range(self.iterations):
            curnode=self.node_tree.nodes.new('ShaderNodeGroup')
            curnode.node_tree=bpy.data.node_groups[self.step_nodegroup]
            curnode.inputs['iterator'].default_value=iter
            for input in curnode.inputs:
                poutput=previousnode.outputs.get(input.name)
                if poutput:
                    self.node_tree.links.new(poutput, input)
            if iter==self.iterations-1:
                for input in self.node_tree.nodes['Group Output'].inputs:
                    poutput=curnode.outputs.get(input.name)
                    if poutput:
                        self.node_tree.links.new(poutput, input)
            else:
                previousnode=curnode

    def update_nt(self, context):
        self.__nodeinterface_setup__()
        self.__nodetree_setup__()

    def update_it(self, context):
        self.__nodetree_setup__()

    # for blender 2.80, the following properties should be annotations
    step_nodegroup=bpy.props.EnumProperty(name="step_nodegroup", items=nodegroups, update=update_nt)

    iterations=bpy.props.IntProperty(name="iterations", min=1, max=63, default=8, update=update_it)

    def init(self, context):
        self.node_tree=bpy.data.node_groups.new('.' + self.bl_name, 'ShaderNodeTree')
        self.node_tree.nodes.new('NodeGroupInput')
        self.node_tree.nodes.new('NodeGroupOutput')

    def draw_buttons(self, context, layout):
        row=layout.row()
        row.alert=(self.step_nodegroup=='None')
        row.prop(self, 'step_nodegroup', text='')
        row=layout.row()
        row.prop(self, 'iterations', text='iterations')

    def copy(self, node):
        self.node_tree=node.node_tree.copy()

    def free(self):
        bpy.data.node_groups.remove(self.node_tree, do_unlink=True)

from nodeitems_utils import NodeItem, register_node_categories, unregister_node_categories
# in blender2.80 use ShaderNodeCategory
from nodeitems_builtins import ShaderNewNodeCategory

newcatlist = [ShaderNewNodeCategory("SH_NEW_CUSTOM", "Custom Nodes", items=[NodeItem("ShaderNodeLoop"),]),]

def register():
    bpy.utils.register_class(ShaderNodeLoop)
    register_node_categories("CUSTOM_NODES", newcatlist)

def unregister():
    unregister_node_categories("CUSTOM_NODES")
    bpy.utils.unregister_class(ShaderNodeLoop)

if __name__ == "__main__":
    register()

And here's a small video of another node I wrote with a dynamic interface:
https://www.youtube.com/watch?v=11Xd-p3HE48

EDIT
The above techniques can be used to produce a dynamic maths node with a variable number of inputs.
For example, paste the following code into a Text Editor window, name the text block 'mathsDynamic.py', tick the Register checkbox (so it's executed automatically when the blend file is loaded) and click 'Run Script'.
# Node Authors: Secrop, Rich Sedman
# Node Description: Dynamic Maths node with variable number of inputs
# version: (0,0,1)

import bpy

# for blender2.80 we should derive the class from bpy.types.ShaderNodeCustomGroup
class MathsDynamic(bpy.types.NodeCustomGroup):

    bl_name='MathsDynamic'
    bl_label='Dynamic Maths'

    # Return the list of valid operators
    def operators(self, context):
        nt=context.space_data.edit_tree
        list=[('ADD','Add','Addition'),('SUBTRACT', 'Subtract', 'Subtraction'), ('MULTIPLY', 'Multiply', 'Multiplication'), ('DIVIDE', 'Divide', 'Division'), ('MAXIMUM','Max','Maximum'),('MINIMUM','Min','Minimum') ]
        return list

    # Manage the node's sockets, adding additional ones when needed and removing those no longer required
    def __nodeinterface_setup__(self):

        # No operators --> no inpout or output sockets
        if self.inputSockets < 1:
            self.node_tree.inputs.clear()
            self.node_tree.outputs.clear()

            return

        # Look for input sockets that are no longer required and remove them
        for i in range(len(self.node_tree.inputs),0,-1):
            if i > self.inputSockets:
                self.node_tree.inputs.remove(self.node_tree.inputs[-1])

        # Add any additional input sockets that are now required
        for i in range(0, self.inputSockets):
            if i > len(self.node_tree.inputs):
                self.node_tree.inputs.new("NodeSocketFloat", "Value")

        # Add the output socket
        if len(self.node_tree.outputs) < 1:
            self.node_tree.outputs.new("NodeSocketFloat", "Value")

    # Manage the internal nodes to perform the chained operation - clear all the nodes and build from scratch each time.
    def __nodetree_setup__(self):

        # Remove all links and all nodes that aren't Group Input or Group Output
        self.node_tree.links.clear()
        for node in self.node_tree.nodes:
            if not node.name in ['Group Input','Group Output']:
                self.node_tree.nodes.remove(node)

        # Start from Group Input and add nodes as required, chaining each new one to the previous level and the next input
        groupinput = self.node_tree.nodes['Group Input']
        previousnode = groupinput
        if self.inputSockets <= 1:
            # Special case <= 1 input --> link input directly to output
            self.node_tree.links.new(previousnode.outputs[0],self.node_tree.nodes['Group Output'].inputs[0])
        else:
            # Create one node for each input socket > 1
            for i in range(1, self.inputSockets):
                newnode = self.node_tree.nodes.new('ShaderNodeMath')
                newnode.operation = self.selectOperator
                self.node_tree.links.new(previousnode.outputs[0],newnode.inputs[0])
                self.node_tree.links.new(groupinput.outputs[i],newnode.inputs[1])
                previousnode = newnode

            # Connect the last one to the output
            self.node_tree.links.new(previousnode.outputs[0],self.node_tree.nodes['Group Output'].inputs[0])

    # Chosen operator has changed - update the nodes and links
    def update_operator(self, context):
        self.__nodeinterface_setup__()
        self.__nodetree_setup__()

    # Number of inputs has changed - update the nodes and links
    def update_inpSockets(self, context):
        self.__nodeinterface_setup__()
        self.__nodetree_setup__()

    # The node properties - Operator (Add, Subtract, etc.) and number of input sockets
    # for blender 2.80, the following properties should be annotations
    selectOperator=bpy.props.EnumProperty(name="selectOperator", items=operators, update=update_operator)
    inputSockets=bpy.props.IntProperty(name="Inputs", min=0, max=63, default=0, update=update_inpSockets)

    # Setup the node - setup the node tree and add the group Input and Output nodes
    def init(self, context):
        self.node_tree=bpy.data.node_groups.new('.' + self.bl_name, 'ShaderNodeTree')
        self.node_tree.nodes.new('NodeGroupInput')
        self.node_tree.nodes.new('NodeGroupOutput')

    # Draw the node components
    def draw_buttons(self, context, layout):
        row=layout.row()
        row.alert=(self.selectOperator=='None')
        row.prop(self, 'selectOperator', text='')
        row=layout.row()
        row.prop(self, 'inputSockets', text='Inputs')

    # Copy
    def copy(self, node):
        self.node_tree=node.node_tree.copy()

    # Free (when node is deleted)
    def free(self):
        bpy.data.node_groups.remove(self.node_tree, do_unlink=True)

from nodeitems_utils import NodeItem, register_node_categories, unregister_node_categories
# in blender2.80 use ShaderNodeCategory
from nodeitems_builtins import ShaderNewNodeCategory

def register():
    bpy.utils.register_class(MathsDynamic)
    newcatlist = [ShaderNewNodeCategory("SH_NEW_CUSTOM", "Custom Nodes", items=[NodeItem("MathsDynamic"),]),]
    register_node_categories("CUSTOM_NODES", newcatlist)

def unregister():
    unregister_node_categories("CUSTOM_NODES")
    bpy.utils.unregister_class(MathsDynamic)

# Attempt to unregister our class (in case it's already been registered before) and register it.
try :
    unregister()
except:
    pass
register()

In the Node Editor you should now have an additional Custom Nodes menu in the Add menu and within that a new node, 'Dynamic Maths'.

The new node provides a drop-down to select the maths operation (Add, Subtract, etc.) and a control to specify the required number of inputs. The node is essentially a Node Group that cannot be manually edited and looks like a normal node. The nodes inside the group are rebuilt automatically each time the node parameters (the operation and the number of inputs) are changed.
For example, setting the operation to 'Add' and setting the number of inputs to 3 will produce the following internal node structure :

Note that the nodes within the group are automatically generated. Changing the node properties changes in inner workings of the group to provide the desired function with the specified number of inputs :

The node can be used anywhere a standard 'Maths' node is used and the performance should be similar to using multiple cascaded Maths nodes to create the same function (since it's essentially just a NodeGroup). It currently supports Add, Subtract, Multiply, Divide, Max and Min functions, with up to 63 inputs.
EDIT II
I'd like to add that there was some changes in the API for Blender 2.80 that affect this answer. Instead of NodeCustomGroup, we now have two new classes we can use:
-ShaderNodeCustomGroup, which is now compatible with Eevee, Cycles and the Viewport material shading.
-CompositorNodeCustomGroup, which allows having custom nodes for Compositor Node_Trees.

This looks potentially promising but please could you explain how I can install the example you have provided? If I run or register the code I don't see any difference in the node editor. Do I need a particular version of Blender (I'm using 2.76b).

Added the code for creating a new category in the Node Editor.

I used your example code to produce a Dynamic Maths node that does exactly what I required. I've edited the answer to include the code and examples of it in operation. Thanks!

Essentially its still groups, i dont see the benefit here

@user3800527 Convenience - the internal group structure is hidden and automatically generated - updated on change of the node’s parameters. For the equivalent with node groups you’d need to create a group for every combination of operation and number of inputs. This same technique could also be extended to other uses.

@user3800527, apart from people being able to crete their workflows as they need, for any kind of project.... there're allways benefits!!

Edited script for compatibility with Blender 2.79b.

@RichSedman Hey, is there a way to do the same for Compositing?

@Hitokage I presume this would be possible by changing the code to work with CompositorNode objects rather than ShaderNodes but would require some reworking and testing. I'd suggest this being asked as a new question - linking to this one - so that someone can provide a separate answer. I'll try and answer it myself when I get the chance. I've been working on a more generic maths node add-on that allows the relationship to be simply types into a text field as an equation - I'll consider expanding that for compositor nodes at some point if it's feasible also.

@Hitokage, it might be pretty much the same thing... the only difference is that you need to use a CompositorNodeTree, and change the Poll function to be true when the node tree in the editor is Compositor.. I have to check if the rendering the compositor treat the CustomNodeGroup as a NodeGroup.

@Secrop Hey I have managed to create a compositor one but for some reason its output is not working. The node_tree is defined well cause when I use the same tree with a node group it works. It's just not working in the custom node. I have removed the copy function, could that be a problem? The copy function causes this error: ID user count error: NTLightningGen (from '[Main]')

@Hitokage, I'll try to have a look into this as soon as possible. I never really tried to write any comp node, but as far as I've seen from the source code, it should work the same way.  Note that ID user count might not work very well in the latest nightly builds, as it's supposed to change in the 2.8 (not so many news on this topic either).

@Secrop Thanks but I am a bit afraid that it might not be possible to combine the custom node with standard nodes which is what I want to do.

@Secrop, you are brilliant. Pity, you don't make more videos. :(

@RitaGeraghty, what kind of videos would you like to see? This is mainly coding, so the only videos I can imagine would be animated graphs :/

I'm interested in all aspects of Blender including scripting, mathematics via Animation Nodes, physics simulations, etc. I'm learning Python, C & C++, OpenGl, etc. just on and off, only whenever I get spare time.

@RitaGeraghty, I'm not so much of making videos, as they take me more time to do then to write some new program, but I'm available to help. I'll pm you in fb.

@Secrop, no worries and thanks.

@Secrop this is a fantastic answer and unfortunately seems to be the only resource on the entire internet about creating custom nodes in scripts. thank you for this!

This code is no longer working in 4.0.2. It breaks on the line from nodeitems_builtins import ShaderNewNodeCategory. Changing it to ShaderNodeCategory gets rid of the error, but doesn't do anything. Is there anything else that needs to be updated?

@evankh, yes, the code needs a bit more changes than that, to work in newer versions (due to API changes). I'll try to update it as soon as I can.

I'm adding this additional answer (but will leave @Secrop's answer as the accepted one) to share a solution that provides this functionality and more. I've developed an add-on that can be downloaded from https://github.com/baldingwizard/Blender-Addons/wiki/Dynamic-Maths-Expression which allows an arbitrary expression to be entered and the nodes automatically generated. Editing the expression automatically re-generates the nodes, changing the function of the group as desired.
Once installed, the add-on provides a 'Maths Expression' option in the Add menu - for example, for a 5-input 'add' node simply enter a+b+c+d+e and the node group is automatically generated for you. To add extra inputs or remove inputs just click the Edit button within the group and change it to the desired expression (eg, a+b+c+d+e+f+g+h+i+j for a 10 input 'add').

Various functions are provided so for a node group that takes the maximum of 6 inputs you could simply enter max(a,b,c,d,e,f).

That's nice.. It could also fit very well as a Python node, since you can have string inputs in the node's interface. I've thought about writing a node with this functionality, but never had the time nor the urge to do it.

@Secrop Thanks. I did start by using string input on a custom node but I found that Eevee (at least, the version that was available at the time) wasn't accepting the outputs from the custom node (but switching to Cycles worked find) - so transferred the custom node inside the group to hold the parameters and provide the interface for the 'Edit'. This has the added benefit of the generated group being fully functional (except for the 'edit') even without the add-on.

I'm not sure how to ask  this without intruding or going off-topic for this exchange... Could this, or the loop node, be used to simplify convolution,? In particular, avoid explicit repetition of the texture node? Perhaps I should post a separate question?

@RobinBetts I'm not sure what you mean... This could certainly be used as a quick way to build the maths node groups - but this doesn't provide a 'loop' node. I have managed to use this to create a hexagon shader that can provide an output for 'distance to edge' and am looking to extend it to add noise to produce a voronoi-like output - which should then remove the need for the edge detection in that particular example, so that in itself would simplify it greatly.

@RobinBetts in this kind of matrix logic, you could simplify the way to build the internal nodetree... but it won't make the nodetree less complex than the answer in the link you mentioned.

@Secrop   and  Rich This does have more to do with the loop node than the OP.  Sure, I was just thinking of building the tree more easily, perhaps by nesting the loop. It would be nice to have an easier route to passing a matrix over procedural textures. Thanks, both, for sharing this work. I'll back off until I've done some more of my own.

Amazing!!!!!!!!

The obvious solution you named it allready yourself, is to use groups filled with math nodes, i dont see a reason for doing future request, since even if there where such a node, it still had to be filled with (gues what...) math nodes based logic. (cuda needs to be able to understand it).
Cuda doesnt understand advanced languages such as python
As currently cycles nodes are based upon cuda math, its not possible to replace that with a python logic and have it run on GPU, the most close alternative exception to that is to use a OSL node. Though OSL scripting wont compile on GPU either.

Secrop’s solution with NodeCustomGroups addresses this by providing a convenient node interface for automatically generating it as an ‘internal’ (non-visible and non-editable) node group. This provides the convenience of being able to control the number of inputs and operation without having to manually manipulte the groups - while still being GPU/Cuda friendly since it’s all implemented as stardard nodes.


text:
Create A tree of string properties
I want to approach a script to make a tree of string list- like this ,(kind of advance version of Vertex group template list)
I can make a template list tho for start, but don't know how to make subnode to that and attach to it.
    bl_info = {
        "name": "object-uilist-dev",
        "description": "",
        "author": "p2or",
        "version": (0, 1),
        "blender": (2, 80, 0),
        "location": "Text Editor",
        "warning": "", # used for warning icon and text in addons panel
        "wiki_url": "",
        "tracker_url": "",
        "category": "Development"
    }

    import bpy

    from bpy.props import (IntProperty,
                           BoolProperty,
                           StringProperty,
                           CollectionProperty)

    from bpy.types import (Operator,
                           Panel,
                           PropertyGroup,
                           UIList)

    # -------------------------------------------------------------------
    #   Operators
    # -------------------------------------------------------------------

    class CUSTOM_OT_actions(Operator):
        """Move items up and down, add and remove"""
        bl_idname = "custom.list_action"
        bl_label = "List Actions"
        bl_description = "Move items up and down, add and remove"
        bl_options = {'REGISTER'}

        action: bpy.props.EnumProperty(
            items=(
                ('UP', "Up", ""),
                ('DOWN', "Down", ""),
                ('REMOVE', "Remove", ""),
                ('ADD', "Add", "")))

        def invoke(self, context, event):
            scn = context.scene
            idx = scn.custom_index

            try:
                item = scn.custom[idx]
            except IndexError:
                pass
            else:
                if self.action == 'DOWN' and idx < len(scn.custom) - 1:
                    item_next = scn.custom[idx+1].name
                    scn.custom.move(idx, idx+1)
                    scn.custom_index += 1
                    info = 'Item "%s" moved to position %d' % (item.name, scn.custom_index + 1)
                    self.report({'INFO'}, info)

                elif self.action == 'UP' and idx >= 1:
                    item_prev = scn.custom[idx-1].name
                    scn.custom.move(idx, idx-1)
                    scn.custom_index -= 1
                    info = 'Item "%s" moved to position %d' % (item.name, scn.custom_index + 1)
                    self.report({'INFO'}, info)

                elif self.action == 'REMOVE':
                    info = 'Item "%s" removed from list' % (scn.custom[idx].name)
                    scn.custom_index -= 1
                    scn.custom.remove(idx)
                    self.report({'INFO'}, info)

            if self.action == 'ADD':
                item = scn.custom.add()
                item.name = "Your Name"
                item.id = len(scn.custom)
                scn.custom_index = len(scn.custom)-1
                info = '"%s" added to list' % (item.name)
                self.report({'INFO'}, info)
            return {"FINISHED"}

    class CUSTOM_OT_printItems(Operator):
        """Print all items and their properties to the console"""
        bl_idname = "custom.print_items"
        bl_label = "Print Items to Console"
        bl_description = "Print all items and their properties to the console"
        bl_options = {'REGISTER', 'UNDO'}

        reverse_order: BoolProperty(
            default=False,
            name="Reverse Order")

        @classmethod
        def poll(cls, context):
            return bool(context.scene.custom)

        def execute(self, context):
            scn = context.scene
            if self.reverse_order:
                for i in range(scn.custom_index, -1, -1):
                    item = scn.custom[i]
                    print ("Name:", item.name,"-", "ID:", item.id )
            else:
                for item in scn.custom:
                    print ("Name:", item.name,"-", "ID", item.id)
            return{'FINISHED'}

    class CUSTOM_OT_clearList(Operator):
        """Clear all items of the list"""
        bl_idname = "custom.clear_list"
        bl_label = "Clear List"
        bl_description = "Clear all items of the list"
        bl_options = {'INTERNAL'}

        @classmethod
        def poll(cls, context):
            return bool(context.scene.custom)

        def invoke(self, context, event):
            return context.window_manager.invoke_confirm(self, event)

        def execute(self, context):
            if bool(context.scene.custom):
                context.scene.custom.clear()
                self.report({'INFO'}, "All items removed")
            else:
                self.report({'INFO'}, "Nothing to remove")
            return{'FINISHED'}

    # -------------------------------------------------------------------
    #   Drawing
    # -------------------------------------------------------------------

    class CUSTOM_UL_items(UIList):
        def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
            split = layout.split(factor=0.3)
            split.label(text="Index: %d" % (index))
            custom_icon = "COLOR"
            split.prop(item, "name", icon=custom_icon, emboss=False, text="")

        def invoke(self, context, event):
            pass

    class CUSTOM_PT_objectList(Panel):
        """Adds a custom panel to the TEXT_EDITOR"""
        bl_idname = 'TEXT_PT_my_panel'
        bl_space_type = "TEXT_EDITOR"
        bl_region_type = "UI"
        bl_label = "Custom Object List Demo"

        def draw(self, context):
            layout = self.layout
            scn = bpy.context.scene

            rows = 2
            row = layout.row()
            row.template_list("CUSTOM_UL_items", "", scn, "custom", scn, "custom_index", rows=rows)

            col = row.column(align=True)
            col.operator("custom.list_action", icon='ZOOM_IN', text="").action = 'ADD'
            col.operator("custom.list_action", icon='ZOOM_OUT', text="").action = 'REMOVE'
            col.separator()
            col.operator("custom.list_action", icon='TRIA_UP', text="").action = 'UP'
            col.operator("custom.list_action", icon='TRIA_DOWN', text="").action = 'DOWN'

            row = layout.row()
            col = row.column(align=True)
            row = col.row(align=True)
            row.operator("custom.print_items", icon="LINENUMBERS_ON") #LINENUMBERS_OFF, ANIM
            row = col.row(align=True)
            row.operator("custom.clear_list", icon="X")

    # -------------------------------------------------------------------
    #   Collection
    # -------------------------------------------------------------------

    class CUSTOM_colorCollection(PropertyGroup):
        #name: StringProperty() -> Instantiated by default
        id: IntProperty()

    # -------------------------------------------------------------------
    #   Register & Unregister
    # -------------------------------------------------------------------

    classes = (
        CUSTOM_OT_actions,
        CUSTOM_OT_printItems,
        CUSTOM_OT_clearList,
        CUSTOM_UL_items,
        CUSTOM_PT_objectList,
        CUSTOM_colorCollection,
    )

    def register():
        from bpy.utils import register_class
        for cls in classes:
            register_class(cls)

        # Custom scene properties
        bpy.types.Scene.custom = CollectionProperty(type=CUSTOM_colorCollection)
        bpy.types.Scene.custom_index = IntProperty()

    def unregister():
        from bpy.utils import unregister_class
        for cls in reversed(classes):
            unregister_class(cls)

        del bpy.types.Scene.custom
        del bpy.types.Scene.custom_index

    if __name__ == "__main__":
        register()

There is a post about approaching tree of property on Blender artist, but that code doesn't work :/
https://blenderartists.org/t/blender-treelist-expanding-subelements-ui/1191260

As mentioned in my previous answer, name is instantiated by default. Notice that the coding style/quality of the example given is not particularly beautiful, try to revise the code under consideration of Create an interface which is similar to the material list box.

import bpy

from bpy.types import PropertyGroup

from bpy.props import (
    CollectionProperty,
    IntProperty,
    BoolProperty,
    StringProperty,
    PointerProperty,
)

#
# This is what I am using to hold a single tree node in my raw example data.
# The entire example data is stored in **bpy.context.scene.myNodes**
#
class MyListTreeNode(bpy.types.PropertyGroup):
    selfIndex : bpy.props.IntProperty(default=-1)
    parentIndex : bpy.props.IntProperty(default=-1)
    childCount : bpy.props.IntProperty(default=0)

#
#   This represents an item that in the collection being rendered by
#   props.template_list. This collection is stored in ______
#   The collection represents a currently visible subset of MyListTreeNode
#   plus some extra info to render in a treelike fashion, eg indent.
#
class MyListTreeItem(bpy.types.PropertyGroup):
    indent: bpy.props.IntProperty(default=0)
    expanded: bpy.props.BoolProperty(default=False)
    nodeIndex : bpy.props.IntProperty(default=-1) #index into the real tree data.
    childCount: bpy.props.IntProperty(default=0) #should equal myNodes[nodeIndex].childCount

def SetupNodeData():
    bpy.types.Scene.myNodes = bpy.props.CollectionProperty(type=MyListTreeNode)
    myNodes = bpy.context.scene.myNodes
    myNodes.clear()

    for i in range(5):
        node = myNodes.add()
        node.name = "node {}".format(i)
        node.selfIndex = len(myNodes)-1

    for i in range(4):
        node = myNodes.add()
        node.name = "subnode {}".format(i)
        node.selfIndex = len(myNodes)-1
        node.parentIndex = 2

    parentIndex = len(myNodes)-2

    for i in range(2):
        node = myNodes.add()
        node.name = "subnode {}".format(i)
        node.selfIndex = len(myNodes)-1
        node.parentIndex = parentIndex

    parentIndex = len(myNodes)-3

    for i in range(2):
        node = myNodes.add()
        node.name = "subnode {}".format(i)
        node.selfIndex = len(myNodes)-1
        node.parentIndex = parentIndex

    parentIndex = len(myNodes)-1

    for i in range(2):
        node = myNodes.add()
        node.name = "subnode {}".format(i)
        node.selfIndex = len(myNodes)-1
        node.parentIndex = parentIndex

    # calculate childCount for all nodes
    for  node in myNodes :
        if node.parentIndex != -1:
            parent = myNodes[node.parentIndex]
            parent.childCount = parent.childCount + 1

    print("++++ SetupNodeData ++++")
    print("Node count: {}".format(len(myNodes)))
    for i in range(len(myNodes)):
        node = myNodes[i]
        print("{} node:{} child:{}".format(i, node.name, node.childCount))

def NewListItem( treeList, node):
    item = treeList.add()
    item.name = node.name
    item.nodeIndex = node.selfIndex
    item.childCount = node.childCount
    return item

def SetupListFromNodeData():
    bpy.types.Scene.myListTree = bpy.props.CollectionProperty(type=MyListTreeItem)
    bpy.types.Scene.myListTree_index = IntProperty()

    treeList = bpy.context.scene.myListTree
    treeList.clear()

    myNodes = bpy.context.scene.myNodes

    for node in myNodes:
        #print("node name:{} parent:{} kids:{}".format(node.name, node.parentIndex, node.children))
        if -1 == node.parentIndex :
            NewListItem(treeList, node)

#
#   Inserts a new item into myListTree at position item_index
#   by copying data from node
#
def InsertBeneath( treeList, parentIndex, parentIndent, node):
    after_index =parentIndex + 1
    item = NewListItem(treeList,node)
    item.indent = parentIndent+1
    item_index = len(treeList) -1 #because add() appends to end.
    treeList.move(item_index,after_index)

def IsChild( child_node_index, parent_node_index, node_list):
    if child_node_index == -1:
        print("bad node index")
        return False

    child = node_list[child_node_index]
    if child.parentIndex == parent_node_index:
        return True
    return False

#
#   Operation to Expand a list item.
#
class MyListTreeItem_Expand(bpy.types.Operator):
    bl_idname = "object.mylisttree_expand" #NOT SURE WHAT TO PUT HERE.
    bl_label = "Tool Name"

    button_id: IntProperty(default=0)

    def execute(self, context):
        item_index = self.button_id
        item_list = context.scene.myListTree
        item = item_list[item_index]
        item_indent = item.indent

        nodeIndex = item.nodeIndex

        myNodes = context.scene.myNodes

        print(item)
        if item.expanded:
            print("=== Collapse Item {} ===".format(item_index))
            item.expanded = False

            nextIndex = item_index+1
            while True:
                if nextIndex >= len(item_list):
                    break
                if item_list[nextIndex].indent <= item_indent:
                    break
                item_list.remove(nextIndex)
        else:
            print("=== Expand Item {} ===".format(item_index))
            item.expanded = True

            for n in myNodes:
                if nodeIndex == n.parentIndex:
                    InsertBeneath(item_list, item_index, item_indent, n)

        return {'FINISHED'}

#
#   Several debug operations
#   (bundled into a single operator with an "action" property)
#
class MyListTreeItem_Debug(bpy.types.Operator):
    bl_idname = "object.mylisttree_debug"
    bl_label = "Debug"

    action: StringProperty(default="default")

    def execute(self, context):
        action = self.action
        if "print" == action:
            print("=== Debug Print ====")
        elif "reset3" == action:
            print("=== Debug Reset ====")
            SetupListFromNodeData()
        elif "clear" == action:
            print("=== Debug Clear ====")
            bpy.context.scene.myListTree.clear()
        else:
            print("unknown debug action: "+action)

        return {'FINISHED'}

#
#   My List UI class to draw my MyListTreeItem
#   (The most important thing it does is show how to draw a list item)
#
#note this naming convention is important. For more info search for _UL_ in:
# https://wiki.blender.org/wiki/Reference/Release_Notes/2.80/Python_API/Addons
class MYLISTTREEITEM_UL_basic(bpy.types.UIList):

    def draw_item(self, context, layout, data, item, icon, active_data, active_propname, index):
        scene = data
        #print(data, item, active_data, active_propname)
        if self.layout_type in {'DEFAULT', 'COMPACT'}:

            for i in range(item.indent):
                split = layout.split(factor = 0.1)

            col = layout.column()

            #print("item:{} childCount:{}".format(item.name, item.childCount))
            if item.childCount == 0:
               op = col.operator("object.mylisttree_expand", text="", icon='DOT')
               op.button_id = index
               col.enabled = False
            #if False:
            #    pass
            elif item.expanded :
                op = col.operator("object.mylisttree_expand", text="", icon='TRIA_DOWN')
                op.button_id = index
            else:
                op = col.operator("object.mylisttree_expand", text="", icon='TRIA_RIGHT')
                op.button_id = index

            col = layout.column()
            col.label(text=item.name)

#
#   My Panel UI, assigned to view.
#
class SCENE_PT_mylisttree(bpy.types.Panel):

    bl_label = "My List Tree"
    bl_idname = "SCENE_PT_materials"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_category = "My Category"

    def draw(self, context):

        scn = context.scene
        layout = self.layout

        row = layout.row()
        row.template_list(
            "MYLISTTREEITEM_UL_basic",
            "",
            scn,
            "myListTree",
            scn,
            "myListTree_index",
            sort_lock = True
            )

        grid = layout.grid_flow( columns = 2 )

        grid.operator("object.mylisttree_debug", text="Reset").action = "reset3"
        grid.operator("object.mylisttree_debug", text="Clear").action = "clear"
        grid.operator("object.mylisttree_debug", text="Print").action = "print"

classes = (
        MyListTreeNode,
        MyListTreeItem,
        MyListTreeItem_Expand,
        MyListTreeItem_Debug,
        MYLISTTREEITEM_UL_basic,
        SCENE_PT_mylisttree)

def register():
    for cls in classes:
        bpy.utils.register_class(cls)

    SetupNodeData()
    SetupListFromNodeData()

def unregister():
    # fill this in.
    pass

if __name__ == "__main__":
    register()

source: Stack Exchange

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/

sort: votes


text:
Invoke event differentiate between UI and hotkey
I have a custom panel in which I have buttons that can use modifier keys, IE Clicking, Ctrl+Clicking, Alt+Clicking etc all do slightly different things and it works as expected.
I want to hotkey the UI button but dont know how to differentiate if its called via the UI (and take modifiers into account) or via a hotkey (and not take the modifiers into account).
class dummyButton(bpy.types.Operator):
bl_idname = "view3d.fd_dummybutton"
bl_label = "Dummy Button"
bl_options = {'REGISTER', 'UNDO'}

modeEnum : bpy.props.EnumProperty(
    items = {
        ("1", "Stuff", ""),
        ("2", "Other stuff", ""),
        ("3", "Even more stuff", ""),
        ("4", "Final stuff", "")
    },
    name = "Mode",
    default = "1"
)

def invoke(self, context, event):

    if event.ctrl:
        self.modeEnum = "2"
    elif event.shift:
        self.modeEnum = "3"
    elif event.alt:
        self.modeEnum = "4"

    return self.execute(context)

def execute(self, context):

    if self.modeEnum == "1":
        print("Do stuff")
    elif self.modeEnum == "2":
        print("Do other stuff")
    else:
        print("Stuff")

    return {'FINISHED'}

I'd prefer to use an enum since then I can choose the function in the hotkey menu
I want to be able to use Ctrl+9 as a hotkey without it forcing the modeEnum to be set to "2"
Am I going about this in the wrong way?

You can catch the left-click event when the button is pressed to differentiate between UI and hotkey call, using event.type == 'LEFTMOUSE': https://docs.blender.org/api/current/bpy.types.Event.html#bpy.types.Event.type
import bpy

# https://blender.stackexchange.com/a/24002/
class OBJECT_OT_CustomOp(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.simple_operator"
    bl_label = "Simple Object Operator"

    def invoke(self, context, event):
        #is_property_set
        ev = []
        if event.ctrl:
            ev.append("Ctrl")
        if event.shift:
            ev.append("Shift")
        if event.type == 'LEFTMOUSE':
            ev.append("Click")
        self.report({'INFO'}, "+".join(ev))
        return {'FINISHED'}

class OBJECT_PT_CustomPanel(bpy.types.Panel):
    bl_label = "Panel"
    bl_idname = "OBJECT_PT_custom_panel"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_category = "Tools"
    bl_context = "objectmode"

    def draw(self, context):
        layout = self.layout
        layout.operator(OBJECT_OT_CustomOp.bl_idname)
        layout.separator()

addon_keymaps = []

def register():
    bpy.utils.register_class(OBJECT_OT_CustomOp)
    bpy.utils.register_class(OBJECT_PT_CustomPanel)

    # https://blender.stackexchange.com/a/196518/
    wm = bpy.context.window_manager
    kc = wm.keyconfigs.addon
    if kc:
        km = wm.keyconfigs.addon.keymaps.new(name='3D View', space_type='VIEW_3D')
        kmi = km.keymap_items.new(OBJECT_OT_CustomOp.bl_idname, type='Q', value='PRESS', ctrl=True)
        addon_keymaps.append((km, kmi))

def unregister():
    bpy.utils.unregister_class(OBJECT_PT_CustomPanel)
    bpy.utils.unregister_class(OBJECT_OT_CustomOp)

    for km, kmi in addon_keymaps:
        km.keymap_items.remove(kmi)
    addon_keymaps.clear()

if __name__ == "__main__":
    register()

    # test call
    #bpy.ops.object.simple_operator()

Python: Ctrl+Click for buttons (capture invocation event)
Create keyboard shortcut for an operator using python?

This solution is both clean and simple, seems so obvious now in hindsight. Thanks for taking the time to help out!

You can also add a (hidden) property, IE Bool or Enum to the operator (as you already do) which will be set when the button is pressed. https://docs.blender.org/api/current/bpy.types.KeyMapItem.html#bpy.types.KeyMapItem.properties
import bpy

# https://blender.stackexchange.com/a/24002/
class OBJECT_OT_CustomOp(bpy.types.Operator):
    """Tooltip"""
    bl_idname = "object.simple_operator"
    bl_label = "Simple Object Operator"
    bl_options = {'REGISTER', 'UNDO'}

    # https://blender.stackexchange.com/a/21108/
    hotkey_call: bpy.props.BoolProperty(options={'HIDDEN', 'SKIP_SAVE'})

    def invoke(self, context, event):
        ev = []
        if event.ctrl:
            ev.append("Ctrl")
        if event.shift:
            ev.append("Shift")
        if self.hotkey_call:
            ev = ["Hotkey Call"]
        self.report({'INFO'}, "+".join(ev))
        return {'FINISHED'}

class OBJECT_PT_CustomPanel(bpy.types.Panel):
    bl_label = "Panel"
    bl_idname = "OBJECT_PT_custom_panel"
    bl_space_type = "VIEW_3D"
    bl_region_type = "UI"
    bl_category = "Tools"
    bl_context = "objectmode"

    def draw(self, context):
        layout = self.layout
        layout.operator(OBJECT_OT_CustomOp.bl_idname)
        layout.separator()

addon_keymaps = []

def register():
    bpy.utils.register_class(OBJECT_OT_CustomOp)
    bpy.utils.register_class(OBJECT_PT_CustomPanel)

    # https://blender.stackexchange.com/a/196518/
    wm = bpy.context.window_manager
    kc = wm.keyconfigs.addon
    if kc:
        km = wm.keyconfigs.addon.keymaps.new(name='3D View', space_type='VIEW_3D')
        kmi = km.keymap_items.new(OBJECT_OT_CustomOp.bl_idname, type='Q', value='PRESS', ctrl=True)
        kmi.properties.hotkey_call = True
        addon_keymaps.append((km, kmi))

def unregister():
    bpy.utils.unregister_class(OBJECT_PT_CustomPanel)
    bpy.utils.unregister_class(OBJECT_OT_CustomOp)
    for km, kmi in addon_keymaps:
        km.keymap_items.remove(kmi)
    addon_keymaps.clear()

if __name__ == "__main__":
    register()

    # test call
    #bpy.ops.object.simple_operator()

Option flags for custom properties (bpy.props)

Using a hidden property partly worked, its hidden from the tools popup but still shows up in the hotkey editor which is a bit annoying

Hey nice answer ! :) could you elaborate on what the property options {'HIDDEN', 'SKIP_SAVE'} do ?

@Gorgious this answer explains it well.

@CybranM perfect, thank you.

all_licenses: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/4.0/


text:
exporting half an unwrapped icosphere to create geodesic map projection
I'm trying to create a map projection of the northern hemisphere of the night sky on a geodesic dome. I naturally thought, "I can just project it as a material on an icosphere in Blender and then unwrap it!" but apparently it isn't that simple. (I'm new to Blender.)

This is the closest I've gotten to a "net" for the dome, but I don't know how to export it as an image I can cut out and turn into a physical dome that doesn't distort the constellations or cut any stars out.
Any help would be much appreciated!!

Reword your question as it seems to be about exporting, not unwrapping. And why don't you unwrap a UV sphere?

@Lukasz-40sth i'm going to build a geodesic dome out of the net

If you're happy with the projection, you might want to look at the shipped 'Paper Model'  add-on. It will unwrap in a way suitable for folding, and bake textures to the UV it constructs.

Do you know the projection your night sky image .. eg Mercator.  Related https://astronomy.stackexchange.com/questions/18219/map-projections-used-for-star-maps

@batFINGER equirectangular!

@RobinBetts thank you! that's exactly what I need.


text:
Export Paper Model addon installation problems in 2.8 Beta
I have tried to manually install the Export Paper Model addon to my copy of Blender 2.8 Beta, and it won't appear in the Add Ons section of my Preferences menu. Has anybody had a similar problem?
Here is a link to the addon.

Can you share a link to it? Don't know this addon, there are billions...

@brockmann Done! Thank you for your comment, sorry about the confusion.

The addon is versioned for "blender": (2, 73, 0),  Because of the major changes between 2.8 and 2.7x  addons with versions prior to 2.80 are disabled and will not show up in addons list. There will be a message in system console on start up.

It appears when selecting the python file. However it needs to be updated for 2.8, there are a few changes: https://wiki.blender.org/wiki/Reference/Release_Notes/2.80/Python_API


text:
How do take an object from 2.8 and work on it in 2.79b?
I'm trying to import the .dae file of a project I exported from my 2.8 installation, into my 2.79b installation. The object will import fine, but the textures get all messed up.
Here is the material I created in 2.8:

Here is how it renders when I import it into 2.79b:

Here is the image I am using for the material:

Which textures do you mean? 2.8 is not fully back-compatible with older versions due to multiple changes. Image files from disk used as textures should be imported fine. Materials created in 2.8 won't necessarily work

@MrZak i'm trying to import a texture that is an image from disk.

@MrZak my mistake! i was on mobile so couldn't add image examples. is this more clear?

Second screenshot shows object imported into Blender Render engine which isn't compatible with new Blender 2.8 per se. Try to make render engines the same first i.e. switch to Cycles


text:
How to auto-smooth in Geometry Nodes?
I can't seem to figure out how to Auto Smooth objects in Geometry Nodes. Here's a setup with a simple cylinder in three different states:

In the first image, setup seems to shade the top face flat as it should (since its edge angles are smaller than 40°), but sides stay faceted. I need to increase the Edge Angle to at least $50.626°$ to get the sides shaded smooth, but then it looks like it doesn't take top edges into account at all. In addition to that, I also need to enable Auto Smooth in Object Properties to get the desired result. That would be OK, but there's another problem. Enabling Auto Smooth only works if you're only manipulating a real mesh from the Group Input and if you don't have any geometry created inside the GN network itself:

As you can see, as soon as I add a mesh primitive to the network, Auto Smooth stops working. Which all makes me think I'm missing some knowledge about how shading works under the hood—or this is a bug/shortcoming?

Join Geometry order seems to matter (which is weird):

...strange, I can't reproduce this. Which Blender version are you using? I am using Blender v3.1 and it works without problems and also with geometry created inside GN.

@quellenform Really? I'm using 3.2 but when I try it with other versions (including a clean 3.1 with no addons installed or settings changed) I still get it. In fact, just now I noticed an even weirder thing, it works and stops working based on which geometry is linked first to the Join Geometry node!! https://i.imgur.com/hUIHXjY.mp4 Can you reproduce that? Also, do you not even get the edge angle stuff (50.626)? Does my first screenshot above give you a normal auto smooth result?

Yes, i can confirm that: If I change the order in "Join Geometry", the result changes. I couldn't see that in your screenshot. Strange. Looks like a bug indeed.

Yeah I couldn't see that as well, I guess because I normally use straight noodles. Could you answer my other question? Can you get a normal smooth surface with less than 50.626 degrees? It's a cylinder with 32 vertices so it should theoretically work with 11.25 degrees, I have no idea where 50.626 comes from. I'll make a bug report if you can confirm that too.

The documentation says that it uses "simple domain interpolation", whatever that means. But why 50,625? If you use a cylinder with 4 sides the angle is 90°, exactly what i would expect.

So you're getting the 50.626 thing too? Another interesting thing: if you delete the top and bottom faces of the cylinder, now it smooths the side faces when the angle is 5.626, exactly 10 times smaller. That's just gotta be a bug, right? I tend to second guess myself with these things so I'm trying to make sure I'm not missing something obvious.

This Answer is now to be understood as a Note after a revision, and was not deleted only because possibly still something useful could be found in it.

It should be noted that:

In any case the object must have Shade Smooth activated, otherwise all faces will always be displayed flat.

If Auto Smooth is not activated, all normals will always be interpolated over the entire object.
The angle used here for Auto Smooth therefore defines which faces should be smoothed.
If Auto Smooth decides on the basis of the angle that no smoothing should be applied to a face, the Set Shade Smooth node will have no effect because the normals will not be calculated accordingly.

If you join an existing geometry with a generated geometry in the Geometry Nodes using Join Geometry, the order is obviously decisive:

If one adds the geometry generated using Geometry Nodes after the existing geometry, the settings under Auto Smooth are also applied to the added geometry.
However, when adding an existing geometry to a geometry created using Geometry Nodes, no Auto Smooth is applied.

So the settings for Auto Smooth are always taken from the first object and applied to each added geometry.
This is probably more of a bug, and may not be quite what the user would expect.

As you can read in the Documentation, you always get an interpolated angle with the node Edge Angle except in the Edge domain: "For the Face, Face Corner, and Point domains, the node uses simple domain interpolation to move values from the mesh's edges."

To better understand the interpolation of angles by "Auto Smooth", the following illustration helps:

Thank you for the write-up. As far as I can understand, your answer boils down to "you can't, unless you use the original geometry in first order in a Join Geometry node" and this is because normals are not calculated for shading purposes in GN at all. Practically I was already aware of this as we've already talked about in the comments, and I'm not really sure about the explanation "because there's no Set Normals node" (not because I don't believe it, but because I don't have enough technical understanding of it).

By "because there's no Set Normals node" I meant that you do have a node with which you can read the normals of your domains, but you can't change them directly via a node (like "Set Position"). But I think you are right: the fact that the order is crucial points at least partly to a misbehavior/bug.

It's also still unclear why faces at 90d angles gets smoothed correctly by the node, but ones with shallower angles don't. PS about your setup: if I'm not mistaken, you don't need a Capture Attribute node? Directly linking Edge Angle to it like I do is enough (at least I can't see a diff when I unplug it). In fact, if you want auto-smooth behavior, you don't need Edge Angle at all, you just need the original geo at the top of Join, and Auto Smooth enabled. Edge Angle either makes things worse or doesn't do anything at all. It all looks like a bug/missing feature situation, in the end.

Hmm, I think you are partially right. There are still some interesting things here. My answer is also not completely correct, must revise it.
What I find strange: "Auto Smooth" does not change the angle in "Edge Angle", but the result in the shader. And "Edge Angle" always returns the interpolated value in all cases (which doesn't seem to make much sense), unless you use "Capture/Transfer Attribute" from the Edge domain like i did...

OK, thanks for your patience, but I just realized that my answer this time was complete nonsense and I was quite wrong. Is it possible to downvote my own answer? ;-) ...there are a few interesting things in there, but I have to look at it again more closely.

:) Why is it complete nonsense? I think your base argument is that GN can read shader normals but can't set them, no? I don't think it's the whole story (how can it set them for the inside-generated meshes when you join it to the original then?), but I feel like there is something to it. Regardless, can you show me where you see the difference between when you use Capture Att. and when you don't, because I don't see that. Viewer gives the same values whether it's there or not, and I don't see a change in the viewport either.

In any case, I think I'll prepare bug reports so the devs can tell us what's going on if it's not a bug, or they can fix it if it is. I'm thinking of two reports: one for Join Geometry order affecting Auto Smooth results, and another for Edge Angle not responding correctly, in case these are separate issues. Any thoughts on that?

Let us continue this discussion in chat.


text:
How can I freeze part of object while applying simple deform(twist)?
As the [Axis, Origin] is set to the Hemi lamp, the whole body twist along the lamp (upper image)
What I really want is to keep the feet freeze while applying the twist.(like lower image)
Is it possible?
thanks.

After using vertex group, the lower body is freeze.
But the weight paint not working well.

I believe using vertex groups/weight painting would be the best way to accomplish this. In the screenshot below the selected vertices are added to a vertex group and plugged into the deform modifier:

Keep in mind that with weight painting, you can also have areas that are only partly influenced: (more flexibility)

Lastly, there are tons of resources on the web about vertex groups, here is one link to the blender manual.

thank you for your help. Now I can freeze the lower body. But even with weight painting, the twist still not working as I want. Adding empty can help?


text:
How can I smoothly "blend" between 2 STLs?
I have 2 STL files, and I'd like to join them (not only as "join them into a single object", but "physically" join them). I'm using blender 2.8.
I'll give an illustration right away to clear what I'm talking about:

The STL in the center is purely flat, while the STL around it is more complex.
Is there any way that I can make these 2 STLs "meet" more or less smoothly so that the gap is filled and I obtain a single STL? Please consider that there might be lots of vertices on both STLs, so manually moving the vertices one by one wouldn't be a viable solution for me ;)
I'm a total blender noob, so maybe I'm simply not looking at the right software?
Thanks a lot!
Arnaud

Select both objects and press CTRL+J to join them as one object.
Then go into Edit Mode, Edge Select.
Select the outer edge loop then the inner edge loop (or vice-versa)
Menu>Edge>Bridge Edge Loops

Absolutely fantastic! Thanks a lot! :D

You should be able to merge them with Booleans, be that the BoolTools addon or modifier. Take a look!


text:
Is it possible for individual faces to have separate materials from the rest of a mesh?
I've only got maybe a week's worth of total experience with Blender and I figured it would be fun to attempt something that isn't overly complex, i.e. something cube-like, so I decided to recreate the Companion Cube from Portal 1.    In modeling and figuring out the center circle pieces I noticed something I missed earlier though. See how to the top of the center circle the pink actually continues into the base of the circle?

I thought I could use loop cuts aligned with the cut out parts of the cube core

which I would then separate from the rest of the mesh in order to have separate materials but I learned that with a subdivision surface modifier involved the results are not that great.

Is there a way for only the two faces resulting from loop cutting to have the pink material and also not go wacky or am I going about this in a way that won't work?
Thanks in advance for any and all help, assistance, and advice given and shared.

You can assign multiple materials to the same mesh, and then in edit mode select faces and in the material tab assign those faces to whichever material you want.


text:
Normal/Bump map show in Look Dev but not on Render
I am trying to bake a diffuse texture with all the shaders applied to it, including the bump map effect just applied to the texture instead of having a seperate normal map.
In Look Dev I can see the result I want to achieve, but when I switch the viewport to Render the bump map is missing.
I watched several tutorials already but I am apparently still missing something crucial and just can't figure out what.
This picture shows my shader setup and settings for the bake. Also you can see what I am trying to achieve in the Look Dev Viewport compared to the Render I get.

The shader to RGB node is not supported in Cycles.

Okay, I did some more testing around and finally came to a solution. Apparently a Mix Shader into a Shader to RGB make the bump map get renderer in Look Dev but not in Render. The solution (and in hindsight the more reasonable) approach is to use a Mix RGB node instead.
I'm not sure if this can be considerer as just plain stupidity or of it's an actual bug.
Here is my new setup that works:


text:
Is it possible to create a silhouette edge of a mesh in Blender?
I want to be able to create a silhouette edge from a chosen point on any given mesh. Essentially, the silhouette edge is a 3D curve made up of points on the mesh whose tangent planes intersect with a chosen perspective point. I'm not just looking for a silhouette to surround the mesh from all perspectives. I want to be able to create a silhouette edge from one perspective, and then look at the curve created from the previous viewpoint in different viewpoints.
This is a demonstration of what it would look like with a cube.
The silhouette edge take from perspective A:

This is the same silhouette edge viewed from a different perspective B:

https://blender.stackexchange.com/questions/101525/turning-a-complex-3d-object-into-a-2d-contour https://blender.stackexchange.com/questions/77279/projection-geometry-example

I'm not looking for a 2D projection. The silhouette edge is a 3D curve that runs along the mesh.

Could you upload a screenshot of your setup ?

I don't really have a setup in Blender, I started using it recently. This is an example of a silhouette edge. Again, it is a 3D curve, not a 2D projection. https://image.slidesharecdn.com/gtc2009openglkilgard-091008215235-phpapp01/95/opengl-32-and-more-42-728.jpg?cb=1255392697

Isn't it what Line Art does?

I think an important distinction is having a visual effect of a silhouette and calculating geometry of the silhouette...

The easierst way to do this is using a Grease Pencil object. Here is my proposal in Blender 3.3 how to do this in a few steps:
https://youtu.be/isZ31C1NYtQ

You can have a silhouette edge using freestyle
First you need to enable Freestyle in Properties Editor > Render tab > Freestyle panel:

In Properties Editor > Layer tab > Freestyle line set panel, you can choose how the line is formed. I.E. you can set it to display silhouette only:

More about it: A guide to Blender freestyle rendering with Eevee and Cycles


text:
how to display Modifier panel visible in N-panel?
I want to display the modifier panel in the Npanel,
I have achieved the panel like this,  but I cant't display the added modifiers:

This is my code:
import bpy
from bpy.types import Panel

from bl_ui.properties_data_modifier import DATA_PT_modifiers

class HelloWorldPanelA(bpy.types.Panel):
    """Creates a Panel in the Object properties window"""
    bl_label = "Hello World Panel"
    bl_idname = "OBJECT_PT_helloA"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'UI'

    bl_category= 'NewTab'

    def draw(self, context):
        mp = DATA_PT_modifiers(context)
        layout = self.layout
        ob = context.object
        row = layout.row()
        layout.operator_menu_enum("object.modifier_add", "type")
        layout.template_modifiers()

def register():
    bpy.utils.register_class(HelloWorldPanelA)

def unregister():
    bpy.utils.unregister_class(HelloWorldPanelA)

if __name__ == "__main__":
    register()

if I add a "Bevel modifier",
it will got an error "Panel type 'MOD_PT_Bevel' not found."
So how to display the added modifiers?
Thank you very much

I think It's not possible

here is the link to an addon that does exactly what you are looking for https://github.com/Symstract/modifier_list/releases
great for reverse engineering and learning more

I hope it helps you
class PanelName(Panel):
"""Creates a Panel in the Object properties window"""
bl_label = ""
bl_idname = "OBJECT_PT_name"
bl_space_type = 'VIEW_3D'
bl_region_type = 'UI'
bl_options = {'HIDE_HEADER'}

def draw(self, context):
    layout = self.layout

    obj = context.object
    row = layout.row()
    row.operator_menu_enum("object.modifier_add", "type")
    row = layout.row(align=True)
    if obj.modifiers:
        icon = [i for i in obj.modifiers.active.bl_rna.properties['type'].bl_rna.properties['icon'].enum_items.keys() if obj.modifiers.active.type in i][0]
        row.enabled =  obj.modifiers.active.is_active
        row.operator("object.modifier_set_active", text="", icon=icon)
        row.prop(obj.modifiers.active, "name", text="")
        row.prop(obj.modifiers.active, "show_in_editmode", text="")
        row.prop(obj.modifiers.active, "show_viewport", text="")
        row.prop(obj.modifiers.active, "show_render", text="")
        row.prop(obj.modifiers.active, "show_on_cage", text="")
        exclud_props = ['name', 'show_in_editmode', 'show_viewport', 'show_render', 'show_on_cage', 'rna_type', 'type', 'is_active', 'use_apply_on_spline', 'show_expanded', 'is_override_data']
        for p in obj.modifiers.active.bl_rna.properties.keys():
            if not p in exclud_props:
                if p == 'subdivision_type':
                    row = layout.row()
                    for v in obj.modifiers.active.bl_rna.properties[p].enum_items.keys():
                        row.prop_enum(obj.modifiers.active, p, value=v)
                else:
                    layout.prop(obj.modifiers.active, p)

Thank you so much!


text:
How to use one object's keyframe time as a driver?
I now have an object that has two keyframes, and I want to get the time of the second keyframe and use that as a driver for another parameter that controls the start time of the animation of the other object.
My current idea is to use the action in the driver, but searching the whole network did not find an example of using action to drive.
Can anyone give me a method, or use action to do an example of driving?

Hi liuran, i know you are pretty new here on the site, but a little hint: if an answer helped you, it would be helpful and nice, if you accept the answer by clicking on the checkmark left of the answer. By this other people also know that the answer helped you and is useful. Unfortunately commenting "thank you" isn't wanted here. So it would be nice if you could accept some of the answers of your old questions. thx.

Ok, thank you for reminding me!


text:
How to recreate dotted line material on sphere
I am trying to recreate the effect in the image attached where there are lines swirling around a sphere. I have problems recreating the dotted lines. In the image they appear to be evenly distributed but when recreating dotted lines with a wave or checker texture on a sphere I get distortions from the sphere mapping where the gaps are not evenly distributed everywhere on the sphere. I also tried to map a texture of dotted lines on a sphere but this texture also gets distorted in a way where the gaps of the line are not evenly distributed. Is there a way in Blender to achieve this effect on the sphere of the image? Much appreciation in advance!

Update:
I was able to recreate the dotted line effect thanks to @vklidu. However I have a problem with the gradient on the emission material shader. Although I used exactly the same node setup as provided in the marked answer, there is no gradient effect. It looks like evee only renders two colors without any smoothness at all. I also tried to use cycles, but no luck. I am not sure what I am missing?

Update 2:
Here is the final result. Because this was mainly an exercise on recreating the effect I am pleased with the result.

Related to curvy lines https://blender.stackexchange.com/questions/94991/trace-visualisation-in-3d-how-to-wrap-curves-onto-a-3d-mesh

I tried changing the dimension and making the spiral bigger but that didn't help, unfortunately. I uploaded the blend file to blend exchange.
https://blend-exchange.com/b/O293ROmz/

Main issue – you have to Apply Scale (Ctrl+A) to mesh object and set X Location 0.5  (for object 2m dimension) ... additionally add Solidify to see better dots, Change Array to Fit Curve so you don't have to care about a number of arrays ... https://imgur.com/7mFv2pQ ... for this screen I deleted also all other mesh objects and kept only one named "dotted" to see what is going on.

Also I noticed you rotated Spiral in edit mode (local) to keep arrays follow the spiral. That is not practical if you want rotate in some specific angle or reset rotation. To keep arrays follow spiral when rotated in object mode (global coord) you can add Constraint > Copy Rotation to mesh object or simply parent to spiral (in rot zero position and than rotate). just like that you would have to change Texture Coordinates for alpha from Generated to Object as well and adjust setup (it would be practical anyway than my Generated Coo).

Thank you @vklidu for your advice. I am very new to Blender and your insights are worth a tone! With your help I fixed the gradient error. Will post results when its done ;) Again, thank you very much for your time and effort you put into this.

Welcome on your journey :)

I added the result image of my exercise. Thanks again @vklidu for the help. Without you this image wouldn't exist ;)

version Curve

enable addon Extra Curve, add Spiral > Spheric (here 20 Turns 10 Steps, type NURBS)

create segment of dashed line (here I created all types in several rows as one mesh object, but for more variations would be better make them probably separately

modifiers - Array, Curve (Spiral), Cast > Sphere, Solidify
a bit of randomness between lines is done by Curve > random selected points and under side panel Item > >Transform > Mean Radious increase/decrease value
some simple material

To make it more wavy - select Spiral curve and in edit mode select some random points (2-3) and with Proportional editing (O) enabled and Transform Pivot Point > Cursor placed in object origin rotate them in some direction.

For an illusion of lines motion you can animate Z Location value of Noise texture in Mapping node ... or X Loc ... Click into the field and type #frame*0.2 ...

Beautiful, and practical. :)

@RobinBetts ... I'm sure you would be able to math shader that OP asked for :)

Hence.. 'practical'. Any shader written would only work on a sphere? I think? Not very useful.. unless @Sten really insists.... Although, I suppose, you could use the U of your swirly-curve, rather than constructing your dots-and-dashes in geometry.

You are truly amazing @vklidu! I really appreciate the time you put into your answer. You even created a freaking animation! I never would have expected such a thorough and practical answer. This is exactly what I was looking for. I was close at some point creating the curve with the particle system and vortex force field but wasn't able to get the mesh on the curve.

Does anyone know why the ColorRamp isn't working on my emission shader? I don't get a smooth gradient to white but a "constant" gradient to white. I did everything like in the screenshot @vklidu provided.

What do you mean constant gradient, please share your screen. Animation is just animated Z Location value of Noise texture in Mapping node ... or X Loc ... Click into the field and type #frame*0.2 ... Usually I share my blend, but versions 3.x are not recognized as blend file for some reason to be shared ... Hm (•‿•) ...ad to particles - yes they can follow a curve it is just not good idea to use force field, also there was an issue with ignoring Tilt value so you would have to use curve per single dashed line.

Appreciate your help! I edited my original post for clarity.


text:
Freestyle: control the Thickness of stroked curve using Radius?
(My english isn't very good, do not hesitate to edit my question)
I'm currently searching the best way to draw some 2D filled shape using Blender.
For example:

This image is a render from Freestyle, the variable stroke width is automatically generated which isn't what I want.
For the moment, I've found some interesting methods. One of them consists to play with a Bezier Curve in 3D mode that is extruded a little bit (with Tilt at 90°) then I can use ALT+S for change the radius of my extrusion. I really like that way of working and it give me that kind of result which is good:

The Problem is that I can't easily fill the shapes...
Lets see with this example:

If I want to fill that shape, I need to:

Duplicate my Bezier curve
Change the Z position of the duplicated curve to put it behind the original shape.
Change its mode to 2D so as fill it.
And finally, change its material to the color I want.

That's a bit annoying to do and when there is a lot of elements on my stage, it becomes a mess, even using Groups.
It would be easier to use Freestyle for that, but how could I control manually the thickness of the stroke like I do with those bezier curve when I'm changing the Radius ? Does a similar way exists (like weight for example) ?
I searched for a modifier of Freestyle Lineset but no luck. I've saw that it is possible to use Python, do you think it is possible to use that mode ? I tried a few, but the data input don't seems aware of a parameter like the Radius of the vertex...

You don't have to tilt your curve nor make it 3D, just use a flat bevel object as described

Possible duplicate of Planar curve with width

@DuarteFarrajotaRamos The example you show in your answer don't seems to provide a way to have a variable stroke width around the path :/  I'm wrong ? also it seems even less convenient to use, I rather prefer to use my curve solution. But by the way, the object of my question is to control manually the stroke width of the FreeStyle render, by, for example, changing the weight or the radius of a bezier, that would be neat !

Why not? What happens when you use curve radius?

Ok, it is possible to have a variable stroke width I get it but in that case I cant have a filled shape. You understand my problem ? I want filled shape with a color with a border having a different color and a variable stroke width

@DuarteFarrajotaRamos I edited my question, hope it clearer, I think it's not a duplicate at all

@DuarteFarrajotaRamos could you remove your "possible duplicate", please ?

Animation Nodes can be used here. Essentially, if you add a 2D curve and copy the 3D spline to it using this simple node tree, you will get what you need:

It also works for multiple splines:

But what if we have multiple spline objects? In this case we append all splines from all objects into a single list and use it instead, and the 3D spline objects can be sourced from a blender object group that the user will add:

What if we want the fill objects(2D Curves) to be separate objects so that we can add different materials for instance. In this case, the 2D curves can be dynamically generated using the Instancer Node:

Cracked it! :D.. I feel I should delete my answer, since it missed the point of the OP..

@RobinBetts I never knew freestyle could do that, so your answer taught me something new. Better leave the answer anyway.

wow , it really looks like the answer I'm seeking for, but don't know the animation nodes, never heard about it, it is blender vanilla or an addon ?

@snoobdogg It is an addon, see What is Animation Nodes?

ok I was able to recreate your firsts programs and it work like a charm, I've just an hardtime with your Loop with Invoke Subprogram. I can find 'Create Spline List' but not 'Spline List'. Also I didn't found the iterator you use for have Source / Target.

Update: Source and Target are Object List Iterator that you renamed right ? I think your answer is awesome but need more details

your last patch works like a charm, I also added an Object Transform Output  after Target to ensure that 2D curve is always behind the 3D one: ) thank you!

@snoobdogg The Spline List is not a node, but a generator, you can add it by pressing the plus button at the lower left corner of the Loop Input node and searching for spline, check the documentation on loops. You are right about the Source and Target.

There is a modifier in Freestyle which will let you do this:
in the Freestyle Line Style for your current line set, select 'Thickness' and assign an 'Along Stroke' modifier.
In the modifier, set the mapping to 'Curve', and , probably, the blend method of the modifier to 'Multiply' of some base thickness value of your stroke.

You can now click on the curve to create control points you can manipulate by dragging, to control the thickness of the stroke along its length.
It's easier to do this in the  Blender Internal renderer, where you can see the stroke reasonably interactively in the Rendered mode of the 3D View. There's nothing to stop you switching to Cycles when you have your strokes set.
There is (in my system, at least,) an annoyance: sometimes the drop-down menu from the spanner icon on the graph disappears before you can select one of its items. My get-around is to ShiftZ in and out of rendered mode .. there seems to be a contest for focus.

Thank you, that's what I already do in the first image of my question. For me that's not ideal at all because it's hard to control the points and because that modifier will be applied to each shape, right ? In fact, appart improve Freestyle with a modifier able to take Radius into account with 2D Bezier Curve, I fear there isn't good solutions to my question

Sorry, I didn't gather you were using this from the OP. The modifier is applied to the line set, so you  can have a line set for each shape, with different profiles... but yes, it's not the friendliest tool in the world..

for the moment I combine the Bezier curve technic with freestyle, that's the best solution I've found but it is not very ideal..


text:
Object showing only in render and not in viewport even though visibility settings are correct
The fluid sim obstacle is visible at the top of the monitor. Before this render I turned made sure that render visibility was set to off.

Viewport view, the obstacle is invisible whilst the visibility is on.

Something very strange I have noticed is that if I delete the object and then begin to render a frame the object is still present. I haven't a clue what could be causing this.
Perhaps this has something to do with the objects parent/child tree?
Edit:
I have managed to make the obstacle visible in the viewport, however I am still stuck with the issue of it always showing up in my render.
Blend file is included now.

It might be easier to find the solution if you upload your .blend file. https://blend-exchange.giantcowfilms.com/

You've got a second object, called Obstacle.001, which is hidden in viewport but not in render. It's a child of "Monitor" (maybe that's why you didn't seen it in the outliner, you need to expand "Monitor" to see it).


text:
Gpu rendering problem
I have been advised to download cuda and I downloaded nvidia cuda version 6.5,yet the cycle compute showed none. what should I do?  Help me please.
I'm using windows 7  im trying to enable graphics card nvidia geforce 320

@cegaton I'm using windows 7 64bit and blender 2.79, but I don't know what do you mean by ",what kind of GPU you are dealing with "

@cegaton I'm trying to enable graphics card

@cegaton  When I install Cuda it says "no supported version of visual studio was found. Some of the CuDa toolkit won't work properly" do I have to download the whole visual studio or is there a zip file around


text:
How to increase the speed of rendering
What is the effect of increasing your ram in blender?  Especially in the speed of rendering

RAM is mostly about storage amount. More ram will allow you to render more complex & more populated scenes (more objects, more polygons, more textures, etc....).
It will not have a significative impact on render times, unless you have less ram than is needed to handle the complexity of your scene (the more complex the scene the more ram is required) - in which case your system will store on your hard drives, which are way slower.
The important hardwares in render times are the CPU and the GPU.


text:
BUG or Mistake : Weird case of shape key
Iam trying a lip sync and my character doesnt lets me change the value of the shape key , i mean it does changed when i click and drag but it gets back to 0 again .
Here is the file :https://www.dropbox.com/s/j8vkahgn2lrco0v/error%20mouth.blend?dl=0
plz let me know the mistake iam doing in here
EDIT : So it turns out that when i double to open the file , shape key doesnt turn orange ( while changing the value ) . But when i open blender and import the file in it then it turns orange while changing the value .
Is it some kind of bug or what ??

you say that it doesn't let you change the value, but you have created shapekeys, so I'm not sure what you're talking about. You need to use "i" to create keyframes. The other point is that Blender can automatically create keyframes if the Automatic Keyframe Insertion is activated in the Timeline (button with a sphere next to play button & cie).

Yes i have added , but can you plz try adding more shape keys to the same girl character where it leads you when you double click the file .
.So here is the thing , when i double click the .blend file to open it directly i cannot add shape keys . But when i open blender then import the same .blend file then the shape key works

if you're talking about creating new shapekeys, you need to be in Object mode to create a new shapekey, and not in Edit mode. Then go in Edit mode to move the vertices. Then back in Object mode you can play with the Value of the shapekey and create keyframes with "i".

sir iam talking about creating more key frames ( i want my character to talk ) using the talk shape key that i have already made . But if you use and see my blender file when trying to register a key frame for the shape " talk " its not registering . Can you plz check and let me know sir ?

it does work. When, in Edit mode, you're glad with your shapekey, you can come back to the Object mode. Now, put your cursor on the frame you want in the Dopesheet or Timeline. Then play with the value under the Shapekeys list, and when you have the value you want put your cursor on the value and press "i" to insert a keyframe. The new keyframe will be created as a yellow dot on the Dopesheet. The thing is that the shapekeys you've created are hard to see because it doesn't change the mesh a lot.


text:
Stagger emission material animation
So. I'm teaching myself Blender so i can create interesting videos for my music.
I have been doing well so for but I hit a snag.
Using the array modifier it has been quite easy to do interesting stuff especially with and empty in object offset.
But now I want to add a strobing light effect to my array.
for now I added a new emission material and animated the strength with a sine function "built in".

this is all fine and dandy but I was wondering how to stagger this animation on the array so the strobe travels along the objects.
would I need to offset the emission strength with some math and an empty?
I'm not sure where to go from here and have not yet found a solution.
I have tried the solution in this post.
possible answer
But while the solution does resemble what i'm trying to do it has the problem of showing the gradient on each cube / light source.

I'm trying to make each light source solid in color.
A solution i can do for now is add 5 or 10 separate lights and animate them individually, then group them and use an array mod on the group. if possible.
But the scene i'm trying to build is huge. so doing this over and over will take up a lot of time.

Possible duplicate of how to animate a gradient moving over an object

Useful https://blender.stackexchange.com/questions/79851/make-an-objects-visibility-controlled-by-another-object-or-an-empty/

set the Color Ramp to Constant to avoid gradients

setting the Color Ramp to constant still creates a separation line in the emission material. I'm trying to create a softly blinking light and then stagger it on the next objects.
using the object coordinates may be the right direction though. I'm experimenting with it right now to see if i can use it to offset the Emission strength based on the object location. So far no luck though.


text:
The sprinkles aren't spread out on the icing - why? (Answered)
I've been following Blender Guru's new Blender 3.0 tutorial, and at the sprinkles chapter I noticed that my node setup is more or less the same as Andrew's, yet I only see one cylinder and it's not even on my donut icing.
Could someone please tell me where I'm wrong? Why aren't the sprinkles spread out on the doughnut icing?

It doesn't look like you've picked an object to instance in the Object Info node.

You need to enable as instance in the Object Info node; and you need to select an object to instance. I would guess "Cylinder" from your outliner:

Where I have "sprinkle.001" you need the name of your sprinkle.
Tip:  It's always a good idea to name objects.  Makes it easy to see what you're doing.


text:
Render Artifacts from Proximity
I'm working on a project where everything is looking fine in the viewport, yet under certain circumstances there are weird artifacts in the render. The render looks fine if there is more space between certain edges, but if the edges are closer together these artifacts show up. The proximity is being generated through geometry nodes. I need the edges as close as possible for my project, and that's where I get these artifacts. Here are examples:
Wireframe of the edges close together. To me, the topology looks good.

Here's how it looks in the viewport with cycles:

Here is how that renders in cycles:

Here is an eevee render:

When I increase the distance between the outer and inner edges the render looks fine. Here is a wireframe example:

And here is how that renders in cycles:

Now there are no artifacts. It renders equally well in eevee. If it would help I could upload the Blender file, but for now I am going with these pictures. I can't figure out what is causing these issues with the renders when the outer edges are close, and as I mentioned before, I need the edges to be as close together as possible!

Eureka! I solved it!! :-)
It turns out that having a subdivision surface modifier in the stack of your reference object messes up the render for the geometry node object. Once the subdivision surface modifier is removed, the artifacts are removed!
My project uses "reference" objects that I modeled and dragged into a geometry node project. Here is an example:

Note that the object itself has a subdivision surface modifier with zero levels and that is turned off in the viewer. Here is the render that resulted:

Once the subdivision surface model is totally removed from the stack,

The render turns out great!

Problem solved!


text:
The rigging did not work, one leg moved with the other
I did a rigging for a figure with the "parent-with Automatic weights", everything worked fine, the hands, the body, but when I came to do IK for the left leg, suddenly I notice that the right leg moves along with it. And I don't know how to fix it.
I'll note that I'm in the middle of a computer animation course, following step by step, so I don't have the tools and knowledge to fix this myself.

Hello please share your file

How can i add a file?

Please read the instructions here: https://blend-exchange.com/

I have attached the file, hope it is ok

You need to set the correct Chain Length for your IK bone (it needs to be 2 as it will influence 2 bones):

You also need to disable the Deform option of the control bone (it may be the problem here):

Once done you can symmetrize the armature (in the Operator Box you'll need to choose +X to -X):

Parent again With Automatic Weights, it will work fine:

thank you very very much!!
How beautiful that there are good people who invest for others and are ready to help!
I just have one more small question - now the legs really are separate, but it canceled all the IK - do I need to reset it or is there a way to preserve it?

I'm not sure what you mean, make sure that you symmetrize from +X to -X maybe?

That is - I can separate the character's legs, but the IK does not work, it seems to have been canceled, the leg is no longer yellow (as in IK in pose mode) and when I move it, it does not function as IK
If you easily find the problem, I'd be happy, and if not, then no big deal, I'll try to restart the IK.

Yes it looks like it's buggy in 3.6, you need to remove the right hand bones, then symmetrize, choose +X to -X, Ctrl Z in the Operator Box, it should work

Thank you! It works!


text:
How to get static particles centered on vertices?
I am trying to get particles to render at the center of vertices in blender 2.81.
So far, I am trying to use the hair particles with the source emitting from vertices. It seems to work but I noticed quite a big gap between the supposed vertice and some particles as shown in the image.

I was wondering if there is a setting that I missed or if there is another way to achieve this.

Under the Properties Window > Particle Settings tab make sure your Particle Physics are off by changing from Newtonian to None, if you don't need them.
If are planning on animating them, or require physics try turning down the Initial Velocity parameter.
Also make sure you Particle Modifier is right after the base mesh, not after any other constructive modifiers.

Thank you so much for your super quick answer I was desesperately searching for the last part!! I did not know about the order of modifier here to be that important. Marking as solved.

Hi @Duarte I am curious what tool you used to record the actions. For my own future answers it may be easier at times to demo than word smith it up.

I use Second Option, choose whichever suits you best.

"it may be easier at times to demo than word smith it up" While images are helpful and encouraged, thoroughly explain the issue too, don't just post an animation


text:
How do i go about Weight panting and animating this model?
I am new to rigging. I want to export a rocket launcher model with a shooting animation. The model and the flaps should be animated. I want to do it with bones.

Do i just Keep all the bones connected or are the 6 flap bones just childs to the main bone?
Should the flaps be separate from the rocket model or is keeping it all 1 model better?
If keeping them all 1 model makes it easier, how do i weight paint each flap to each bone separately?

Image 1

Im still having one issue, the armature, bone and vertex group are named the same and its weight painted with a value of 1 but i cant seem to tell the bone what vertex group its suppose to be assigned to. To clarify the bones are all separate and not parented or child to anything.

Hi, welcome to Blender.se. I edited your post for brevity. If I have removed any important details, please edit them back in.

(1) There is no need to connect the bones, disconnected child-parent relation have no drawbacks. (2) It is up to your personal preference. If you use a single model you use weight painting. If you use multiple model you can use parenting. (I would suggest weight painting.) (3) Manually create vertex groups, select the appropriate vertices and assign the to the group with a weight of one.

This way of assigning weights is best for your rigid model. Weightpainting is better suited for organic weights with smooth transitions. In your case you just want to have a group of vertices assigned to one vertex group 100%. With the vertex group panel you will have good control.


text:
Volumetric Emission Material Appears Black in Blender 4.2.3 LTS
I'm working in Blender 4.2.3 LTS and trying to use a volumetric emission material to create an animated fire effect. However, I’ve run into an issue: despite having ray tracing enabled, materials that should be illuminated by the emission appear completely black.

Ray tracing is active in my render settings. I followed some video tutorials suggesting the use of a lighting probe with baking, but it didn’t yield the desired results.
Here’s a snapshot of the volumetric emitter material I’m using (attached image or nodes setup if possible).

Has anyone else encountered this issue with volumetric emission, especially when animating effects like fire? Are there specific settings or techniques in Blender 4.2.3 LTS that could help improve the illumination on nearby surfaces?
is it a limitation of Blender 4.2 or a breaking change ? For example, "Volumetrics" seams to have been replaced by "Volume"
Edit 1
Using a Principled Volume node doesn't seem to make a difference.

You can't plug a surface shader into a volume shader socket. Try using Principled Volume instead of the Principled BSDF.

Principled Volume doesn't change anything, even with probe lightning but thanks, I will edit my question

I think this feature hasn't been implemented yet, indirect lighting from a volume emission. Raytracing in Eevee is still brand new.

so yes, it seams that for 4.3.2 you need to use cycle

Apart from EEVEE not being able to produce emissive volumetrics, here a tip if you want to it in Cycles: in the Principled Volume you don't need to set a general Color for the volume if you only want emission, this is actually scattering the light and therefore darkening your emission, especially if you increase the Density, the higher this value the darker the emission. So you should lower the Density to 0. And if you only want volumetric emission, no fog or smoke or anything, you can simply plug an Emission node into the Volume output. A Principle Volume is not necessary.

oh, interesting to know, I will try that tonight


text:
How to export Alembic in selection sequence or batch with Python script
Currently, I would like to automate some Alembic export tasks, by creating a script. How can I do this?
I know this script (but not sure how to make it happen):
bpy.ops.wm.alembic_export(filepath="Drive/Path/object.abc",
                          selected=True,
                          renderable_only=False,
                          visible_layers_only=False,
                          flatten=False,
                          uvs=True,
                          packuv=True,
                          normals=True,
                          vcolors=False,
                          face_sets=True,
                          subdiv_schema=False,
                          apply_subdiv=False,
                          global_scale=1,
                          triangulate=False,
                          quad_method='SHORTEST_DIAGONAL',
                          ngon_method='BEAUTY',
                          export_hair=False,
                          export_particles=False)

There are more options.
How do I make Blender export Alembic by script on one selection, then another selection after I've exported that?

what is it you dont know how to do? You posted a script that will export the selected object to an alembic file. Please [edit] your question and add exactly what it is that you can't do.

I am getting crashes with that script, and I am not sure how to either batch export or sequentially export different selection sets. Do objects need to have an active selected to export?

license: Creative Commons - Attribution Share-Alike - https://creativecommons.org/licenses/by-sa/3.0/


text:
How to fix the character's clothing to remain stable and intact all the time?
1.The garment was torn and destroyed during the walk, how can it be arranged that the garment remains intact and functions as a normal garment?

In the rander Mode The character is transparent when there is light on it - how do you fix this?

Hello, could you please be more precise? Your cloth doesn't seem to be transparent. You should merge by distance in order to avoid the gap, also maybe create a pin group, and parent to the armature

Thanks, I meant the figure was transparent, not the clothes. If you go to render mode you can see that in the light the figure is transparent.
What did you mean by 'merge by
distance'  you mean the vertices?

Unplug the image from the Alpha input of the Principled BSDF? As for the merge by distance, yes, I meant do it for the cloth

I will try, thank you!