Mat Preset to Change ONLY Colors on a Blender Node?



  • I've put together a freebie package of "messy painter" objects (paint brushes, ladder, sawhorse, towels, etc.), and each object has its own transparency mask that applies a paint color in various splatter shapes over the object's regular texture. The paint color comes from a Blender node with two close shades, blended by a Turbulence node.

    To change the color of the paint splatters on the objects, all the user needs to do is change the colors on the Blender node for each mat zone. Sounds easy enough, until you discover just how many mat zones there are, esp. for objects with different transparency masks for each part, like the ladder. So I want to find a way to make it as easy as possible for users to choose their own paint colors.

    Here's the best I've come up with so far:

    (1) With only the Blender & Turbulence nodes selected, save the new color as an MT5 w/ "Selected nodes only" checked.
    (2) Load the MT5 on a different object or mat zone using the Library's double check button ("Add to Scene"), rather than the default of "Replace."

    That loads the new color nodes into the shader setup, but the user would then need to delete the existing one and hook up the new one to the right input. And that would be pretty tedious to do over and over, given the number of mat zones.

    A better solution would be a material preset that changes ONLY the colors on the Blender node without changing anything else about the shader setup. If such a thing is possible, the user could then set up a new paint color and save it, and then apply it to each mat zone with a simple click.

    I suspect that Semidieu's Advanced Shader Builder can do this, but I still haven't quite wrapped my head around how it works, despite several attempts a year ago. And I'm not sure how many users would want to go to the trouble of installing it in order to use shaders created with it. (I installed it to use VYK's handy Sexy Skinz Clothes Shaders for V4.)

    If there's no way within Poser to save a material preset that will ONLY change colors on a Blender node when applied (w/o changing anything else about the shader), might there be a simpler Python script available that could do this? Or any other ideas?

    Below is a screenshot of the shader setup for one mat zone on one of the props, so you can how it works. What I want is a way for users to easily change the colors on the Blender node w/o touching any other part of the shader, so that they can apply the change to material zones that have different color maps, transparency masks and/or other elements.

    Thanks!

    0_1534998557553_{PR}Ladder-TreadMats-PaintBlender-Example.png



  • In this case - only script AFAIK.
    You make "false" mt5 file that only runs script - in the same dir to avoid any troubles with paths.



  • @perpetualrevision what I do for colour changes applied by pose, is to use @bagginsbill 's Parmatic scripts, to which I've added a modification allowing a "PMC:<name>" labelled SimpleColor node to be operated on by the scripts. This creates Red, Green and Blue parameters with appropriately prefixed names. An applied pose can change these values, and they can then be animated, if desired, or you can run the Delete Parameters script which removes all the User accessible PM: and PMC: parameters, thus locking in the colour change you last applied.

    Parmatic3.zip

    For your blender, you can set both colours to white and plug in two of the PMC: labelled SimpleColor nodes, which can both have their RGB values set simultaneously via pose.



  • @phdubrov I believe that is correct. Poser's material loader internals can create new nodes, but not modify existing ones.



  • I think I have something for you!

    It comprises a slightly different material node layout using a "Simple_Color" node, two HSV nodes to mind the difference in hue in your Blender node, and a python script to set that "Simple_Color" node to any desired colour with a standard colour picker.

    I'm currently still working on it to make it of more universal use, like:
    - work on all actors
    - or all props
    - or only the currently selected prop.

    The Gadget can be called from a simple .cr2 which you can place in any library folder of your choice.

    Give me one or two days and I'll post what I have.
    Probably the python experts can refine the script even more (my python skills are rather basic...)

    Of course the gadget will be Public Domain so you can distribute it with your set!

    Cheers!
    Karina

    0_1535042004500_4.1. Set Colour.png



  • @perpetualrevision:
    Your new MAT setting:

    0_1535046210400_pr-ladder-treadmats-paintblender-EDIT K.jpg

    Improvement is that you only have to set ONE colour (in the "User Input Colour (Python)" node instead of TWO slightly different in the blender node.
    The attached HSV nodes modify the colour "avtomaticheskiy" for you... :D

    --> Connecting the "User Input Colour (Python)" node to the "Custom_output_1" was simply for convenience and easy handling...

    Yet still struggling with the Python script...
    K



  • @karina said in Mat Preset to Change ONLY Colors on a Blender Node?:

    Improvement is that you only have to set ONE colour (in the "User Input Colour (Python)" node instead of TWO slightly different in the blender node.
    The attached HSV nodes modify the colour "avtomaticheskiy" for you... :D

    WOW -- this is amazing!! You are a true master at making things that are incredibly useful (like your Sasha-16 version of V4, which I love)!

    Would users just click the color chip on the User Input Color (Python) node to set the color, or would the script bring up its own color picker (presumably one in which you can enter RGB or HSB values)?

    I can't believe it might be able to apply the new color to multiple props -- that's exactly what I was wanting!

    I'd like to give you my "Messy Painter" set to test out this concept, but I'm still working on the hand poses for paint brushes and so on, so the set isn't quite ready. Should be ready for ShareCG by tonight or tomorrow! To give you an idea of what's in the set, here's the promo:

    0_1535071061824_{PR}Promo-MessyPainter-Color-1200x800.jpg



  • @perpetualrevision said in Mat Preset to Change ONLY Colors on a Blender Node?:

    Would users just click the color chip on the User Input Color (Python) node to set the color, or would the script bring up its own color picker (presumably one in which you can enter RGB or HSB values)?

    No need to be in the Maerial Room at all.

    The script first brings up the default colour picker where you can choose your new colour.
    Then you can select to apply it to any of these:

    • Apply to current actor/prop or current figure
    • Apply to ALL props in a scene
    • Apply to ALL figures in a scene.

    .
    The only prerequisite
    is that you have set up all your materials as I suggested in my previous post, i.e. the "User Input Colour (Python)" (or just any Poser standard "Simple_color" node) node MUST be connected to the "Custom_output_1".
    (I chose this way to spare us a dedicated search; so this is more of a "KISS" (f1) approach...)

    The Python script now works fairly well.
    I think I'll post the whole thing tomorrow, as a public Beta, kind of.
    Stay tuned.

    K

    Footnote:
    (f1) "KISS" == "KeepItSimpleStupid!" :D :D :D



  • @karina said in Mat Preset to Change ONLY Colors on a Blender Node?:

    The script first brings up the default colour picker where you can choose your new colour.

    By "default" color picker, do yo mean Poser's default or the OS default? I ask b/c Poser's default color picker doesn't seem to work on my Mac, and anyway I prefer the macOS Color Picker b/c I can save color swatches and I can enter values in RGB, HSB, or HEX format (HSB is my preferred). When I command+click on a color chip in Poser, the macOS Color Picker launches, so I never even bother with the default picker.

    I can't wait to try out your new script! I'm not going to upload my "Messy Painter" freebie until I've given the script a try, so that I can hopefully include it with the set.

    THANK YOU so much for making this useful "material kit"!



  • This post is deleted!


  • Here we are: this is what I have hitherto.

    0_1535214088900_Gadget Show.jpg
    Since !THIS! DUMB FORUM SOFTWARE is unable to display <code> I had to resort to alternatives.

    If you want to have a quick glance at the manual and the python code, please go here on SASHA's forum:

    http://sasha-16.forumprofi.de/showthread.php?tid=93

    That post also includes a ZIP file which contains a short manual, example pictures, and the actual files needed.

    Alternatively, you can download the same ZIP here:
    http://dl.free.fr/bi57IFYI9

    (file lifetime is 30 days after last download, PM me if link is dead)

    Cheers!

    Karina]



  • @karina said in Mat Preset to Change ONLY Colors on a Blender Node?:

    If you want to have a quick glance at the manual and the python code, please go here on SASHA's forum:
    http://sasha-16.forumprofi.de/showthread.php?tid=93
    That post also includes a ZIP file which contains a short manual, example pictures, and the actual files needed.

    THANK YOU again for putting that together and posting it! I just went to the SASHA forum and downloaded the zip. I'll test it out soon and let you know how it goes!

    FYI: The artist who wanted a way to change paint colors is a "she," not a "he"! :-)



  • @karina the technique I use for syntax coloured python code is to both prefix and suffix the code fragment with triple back quotes:

    "```" here double quoted to prevent their activation.

    # This is a comment.
    # Unfortunately, you can't just type the code in, as the forum editor swallows the tab key which you might need
    # for syntax indenting, unless you manually replace tabs with four (or some other code consistent number of) spaces.
    import poser
    

    And now we're back to normal text mode.



  • This post is deleted!


  • @perpetualrevision
    Oups! Sorry I didn't notice ;)
    I hope it will work on your MAC.

    @anomalaus
    Ah I see! thank you for the heads-up!
    I only hope I can remember that until the next time... :D :D

    import ego
    import brain
    true = forget.tooManyThings()
    root = oldAge
    
    if true:
        try:
            flogMeWithCookedNoodle()
        except:
            ignore()
                
    
    root_destroy()
    
    root.mainloop()
    

    Now let's see if I can do it :)

    Cheers!
    K



  • @karina said in Mat Preset to Change ONLY Colors on a Blender Node?:

    I hope it will work on your MAC.

    As I think you suspected, Python scripts that use Tkinter are not compatible with the Mac version of Poser, so when I tried to use your script, I got this error message:

    0_1535330998863_Karina-ColorScriptError-screenshot.png

    But once you've tested it to the point you're willing to share it somewhere like ShareCG, then I can add a note to my "Messy Painter" set directing Windows users to give the script a try!



  • Hold out Lady Paintalot! Rescue is near!

    Actually, a wxPython script I dangled together the last days.
    It's not the most elegant one, but it should work for now.
    However, there's still a caveat:

    wxPython experts to the rescue, please!

    When you run the script, the "Simple_Color" nodes will be set as expected. So the script does it's job.

    But Poser doesn't!

    • The preview window won't refresh, still showing the previous colour .
    • Same for the Material Room UI.
      It only refreshes when you use the pipette tool in the Material Room and click on the prop!
    • Or you switch to another material, and then back again. Or you click on the "eye" in the node...

    Strangely the tkInter version of the script works OK!

    I'll attach a raw version of the script so hopefully you can tell me what is missing.

    Thank you!
    Karina

    import poser, os
    import wx, wx.py, wx.aui
    revisor = poser.WxAuiManager()
    root = revisor.GetManagedWindow()
    
    #####  VARDEFS	###########################################################################################
    scene = poser.Scene()
    figura = scene.CurrentFigure() #figura == singular
    figuri = scene.Figures() #figuri == plural
    objekt = scene.CurrentActor() #objekt with "k"!
    feedbackString = "<PROP> " + objekt.Name()
    if objekt.IsBodyPart():
    	feedbackString = "<FIGURE> " + figura.Name()
    DiffuseList = [-1,-1,-1]
    rgb = (235,235,235)
    newColour = rgb
    hexcolour = "#ebebeb"
    variant = 1
    connectedToNode = 27 #27 is "Custom_output_1" socket in "PoserSurface"
    
    #####  MAIN CLASS  ########################################################################################
    
    
    class wxGUI(wx.ScrolledWindow):
    
    	def __init__(self, parent):
    		wx.ScrolledWindow.__init__(self,parent=parent,id=wx.NewId(),pos=wx.Point(-100,250))
    		self.parent = parent
    		self.panel = wx.ScrolledWindow(self)
    
    		self.labelDonor = wx.StaticText(self, id=-1, label="NOTICE: Works on ALL materials of selected Prop(s)/Figure(s).", pos=(10,2))
    				
    		self.radio1 = wx.RadioButton(self,11, label = feedbackString, pos = (10,30), style = wx.RB_GROUP) 
    		self.radio2 = wx.RadioButton(self,22, label = 'ALL PROPS',pos = (10,55)) 
    		self.radio3 = wx.RadioButton(self,33, label = 'ALL FIGURES',pos = (10,80)) 
    		self.Bind(wx.EVT_RADIOBUTTON, self.onBtn)
    		
    		self.buttonColourPick = wx.Button(self, id=-1, label="[ OPEN COLOUR PICKER ]", pos=(10,110), size=(130,50))
    		self.Bind(wx.EVT_BUTTON, self.colourPick, self.buttonColourPick)
    		
    		self.buttonQuit = wx.Button(self, id=-1, label="[  ABORT  ]", pos=(210,140), size=(80,20))
    		self.Bind(wx.EVT_BUTTON, self.closeAll, self.buttonQuit)
    		self.buttonRun = wx.Button(self, id=-1, label="[ MAKE IT SO ]", pos=(300,140), size=(80,20))
    		self.Bind(wx.EVT_BUTTON, self.makeItSo, self.buttonRun)
    		
    		self.colourBox = wx.StaticBox(self, wx.ID_ANY, "Your New Colour:", pos=(210,50), size=(170,80))
    
    
    		self.Centre() 
    		self.Show(True)    
    		
    		
    	def onChangeBackground(self, hexColour): # but this shall only set the colour of the "colourBox in line 62
    		self.SetBackgroundColour(hexColour)
    		self.Refresh()	
    		
    		
    	def onBtn(self, event): # not necessary atm. - IGNORE
    		global variant
    		if self.radio1.GetValue():
    			#feedback.config(text = "Apply this colour to:\n" + feedbackString)
    			variant = 1
    		if self.radio2.GetValue():
    			#feedback.config(text = "Apply this colour to:\n<ALL PROPS> in the scene.")
    			variant = 2
    		if 	self.radio3.GetValue():
    			#feedback.config(text = "Apply this colour to:\n<ALL FIGURES> in the scene.")
    			variant = 3
    		
    		
    	def colourPick(self, event):
    		global newColour
    		data = wx.ColourData()
    		data.SetChooseFull(1)
    		for i in range(17):
    			cCol = 255 - 17 * i
    			data.SetCustomColour(i, (cCol, cCol, cCol))
    		
    		data.SetColour((newColour)) # set the currently selected colour in the chooser
    		dialog = wx.ColourDialog(self, data)
    		if dialog.ShowModal() == wx.ID_OK:
    			data = dialog.GetColourData()
    			newColour = data.GetColour().Get()
    			hexColour = self.rgb_to_hex(newColour)
    			#self.onChangeBackground(hexColour)
    			
    	def rgb_to_hex(self, rgb):
    		return '#%02x%02x%02x' % (rgb)
    		
    		
    	def makeItSo(self, event): # Aaand Action!
    		self.iterate(variant)
    		scene.DrawAll()
    		self.closeAll(0)
    	
    	
    	def iterate(self, variant): #parses all props, figures and their mat zones as defined by the radiobuttons
    		for bce in scene.Actors(): #bce == "BCe"(all) in Russian :p
    			if variant == 3:
    				for fig in figuri:
    					self.setColour(fig)
    			if variant == 2:
    				if bce.IsProp():
    					self.setColour(bce)
    			if variant == 1:
    				obj = scene.CurrentActor()
    				if obj.IsProp:
    					self.setColour(obj)
    
    					
    	def setColour(self, currentObj): #parses the shader tree
    		for mat in currentObj.Materials():
    			tree = mat.ShaderTree()
    			self.setValues(tree, connectedToNode)
    
    			
    	def setValues(self, tree, nodeNr):
    		r = min(255, max(0, float(newColour[0]) / 255))
    		g = min(255, max(0, float(newColour[1]) / 255))
    		b = min(255, max(0, float(newColour[2]) / 255))
    		whichNode = tree.Node(0).Input(27)
    		pluggedIn = whichNode.InNode()
    		if pluggedIn is None:
    			1 == 1
    		else:	
    			colourChip = pluggedIn.InputByInternalName("Color")
    			colourChip.SetColor(r,g,b)
    		
    		
    	def doNothing(self):
    		_void = 0
    	
    	
    	def closeAll(self,event):
    		global scene
    		poser.WxAuiManager().DetachPane(self)
    		self.Close(True)
    		scene.DrawAll()
    
    
    
    #####  MAIN LOOP  #########################################################################################
    
    
    app = wxGUI(root)
    revisor.AddPane(app, wx.aui.AuiPaneInfo().
                Caption("Karina's Batch Colour Gadget V1.1").CaptionVisible().
                Float().Resizable().DestroyOnClose().Dockable(False).
                FloatingSize(wx.Size(400, 200)).CloseButton(True))
    info = revisor.GetPane(app)
    info.Show()
    revisor.Update()
    


  • @karina said in Mat Preset to Change ONLY Colors on a Blender Node?:

    ...
    info = revisor.GetPane(app)
    info.Show()
    revisor.Update()

    I don't see a material.ShaderTree().UpdatePreview() anywhere, so the material room can't update it's preview. Perhaps if that is done before the scene.DrawAll() calls, it will make a difference.

    I've also been frustrated with lack of updates in the material room, but the Update calls still have to be made.



  • @anomalaus:

    aaaaand: That did the trick!

    def setColour(self, currentObj): #parses the shader tree
    		for mat in currentObj.Materials():
    			tree = mat.ShaderTree()
    			self.setValues(tree, connectedToNode)
    			mat.ShaderTree().UpdatePreview()
    

    The materials AND the scene preview window now update as expected!
    All problems solved; thank you a ton! :)
    K



  • @karina Now that @Snarlygribbly has made the source for EZSkin (and others) public domain you can get a lot of examples of Wx and Other stuff especially to do with the mat room.