can't get bitmap shader work correctly

On 01/02/2018 at 11:11, xxxxxxxx wrote:

HI
It's my first post here.
I script a bit for a while, but it's my first try to write a plugin, so there could be  many dirty things.

I'm currently trying to write a ShaderData plugin to manipulate textures.
As I didn't find any example in python, for texturing/bitmap part, I try to "port" the sample from microbion site  (bmFlip), but which is in C++.
The workfow is a bit different. I try my own "version" and it has worked for a while,  but it's pretty buggy. Sometime I get it in viewport, sometime in render, and now just bug the other modes (World or Local, who just display World position color) and no more render succes. If I clear the bitmap channel, all return fine.
I'm obviously doing something wrong with my bitmap part "implentation".
In output the shader call is in the "Espace UV" part.

Somebody could put me in the right direction ?
I can join the complete folder if necessary.

And a second question I try to access different members of volumeData.
it work, but I all time get this message : "UnboundLocalError: local variable 'raypos' referenced before assignment".

And in case  I don't see anything to put an attachment, it must be extern ?

  
import os  
import math  
  
import c4d  
from c4d import plugins, bitmaps, utils  
  
  
PLUGIN_ID = 1040539  
  
FPLUGTWO_TEXTURE = 1000  
FPLUGTWO_FLIPX = 1010  
FPLUGTWO_FLIPY = 1020  
FPLUGTWO_MODE  = 1030  
FPLUGTWO_UV    = 0  
FPLUGTWO_WORLD = 1  
FPLUGTWO_LOCAL = 2  
FPLUGTWO_PREVIEW = 1040  
FPLUGTWO_TOTO = 1050  
  
class FPlugTwo(c4d.plugins.ShaderData) :  
  
  print "FPlugTwo ok"  
        
  def __init__(self) :  
      #debug color  
      self.ape = True  
      self.mode = 0  
      self.shader = None  
      self.flipx = False  
      self.flipy = False  
      self.mode = 1  
      self.preview = True  
      self.toto = 0.5  
        
      self.SetExceptionColor(c4d.Vector(1,0,0))  
    
  def Init(self, node) :  
      donnees = node.GetDataInstance()  
      donnees.SetBool(FPLUGTWO_FLIPX, self.flipx)  
      donnees.SetBool(FPLUGTWO_FLIPY, self.flipy)  
      donnees.SetLong(FPLUGTWO_MODE, self.mode)  
      donnees.SetBool(FPLUGTWO_PREVIEW, self.preview)  
      donnees.SetReal(FPLUGTWO_TOTO, self.toto)  
      return True  
        
  def InitRender(self, sh, irs) :  
      donnees = sh.GetDataInstance()  
      self.shader = donnees.GetLink(FPLUGTWO_TEXTURE, irs.doc)  
      print self.shader  
      self.flipx = donnees.GetBool(FPLUGTWO_FLIPX)  
      self.flipy = donnees.GetBool(FPLUGTWO_FLIPY)  
      self.mode = donnees.GetLong(FPLUGTWO_MODE)  
      self.preview = donnees.GetBool(FPLUGTWO_PREVIEW, self.preview)  
      self.toto = donnees.GetReal(FPLUGTWO_TOTO)  
      self.irs = irs  
      if self.shader :  
          result = self.shader.InitRender(irs);  
          if result == c4d.INITRENDERRESULT_OK :  
              print "INITRENDERRESULT_OK"  
          else :  
              print "something Wrong in InitRender"                  
          return result  
      return 0  
    
  #This method seem not used, or not relevant  
  def Message(self, node, type, msgdat) :  
      donnees = node.GetDataInstance()  
      if type == c4d.MSG_INITIALCHANNEL:  
          print "MSG_INITIALCHANNEL"              
      #data = ((PluginShader* )node)->GetDataInstance();  
      #HandleInitialChannel(node, BMFLIPSHADER_TEXTURE, type, msgdat);  
      #HandleShaderMessage(node, (PluginShader* )data->GetLink(BMFLIPSHADER_TEXTURE, node->GetDocument(), Xbase), type, msgdat);  
      return True  
    
  def Output(self, sh, cd) :  
      pos = c4d.Vector()  
      nor = c4d.Vector()  
    
      if self.mode == FPLUGTWO_WORLD : # Espace Monde  
          if cd.vd : # 3D  
              #just some tests  
              pos  = cd.vd.p  
              nor  = cd.vd.orign  
              uvPos= cd.vd.uvw  
              #print uvPos  
              aRay = cd.vd.ray  
              #print aRay  
              raypos = aRay.p  
              rayDir = aRay.v  
              rayIOR = aRay.ior/4.0  
              rayLength = cd.vd.dist #The distance between p and ray->p, i.e. the ray length.   
              rayAngle = (cd.vd.cosc  \+ 1) /2.0 #The angle between ray vector and unbumped normal.  
              mapVal = self.rangeMapper( rayAngle, 0.6, 1.0, 0.0, 1.0)  
              print mapVal  
              linVal = math.pow(mapVal, 2.2) #0.45454  
              colVal = c4d.Vector(linVal,linVal/2.0,linVal)            
          else : # Aperçu  
              if self.ape : pos = (cd.p - 0.5) * 100.0  
              else : return pos              
          color = colVal  
        
      elif self.mode == FPLUGTWO_UV : # Espace UV  
          #color = cd.p  
          color = self.shader.Sample(cd)  
        
      elif self.mode == FPLUGTWO_LOCAL : # Espace Objet  
          if cd.vd : # 3D  
              pos = cd.vd.p  
          else : # Aperçu  
              if self.ape : pos = (cd.p - 0.5) * 100.0  
              else : return pos  
          color = pos  
    
  def FreeRender(self, sh) :  
      #Free any resources used for the precalculated data from InitRender().  
      return  
    
    
  
def registerThePlug() :  
  #c4d.plugins.RegisterShaderPlugin(id, str, info, g, description[, disklevel][, res])  
    
  IDS_FPLUGTWO=10000  
  name = plugins.GeLoadString(IDS_FPLUGTWO);  
  return plugins.RegisterShaderPlugin(PLUGIN_ID, name, 0, FPlugTwo, "FPlugTwo", 0)  
    
if __name__ == "__main__":  
  registerThePlug()  

On 02/02/2018 at 04:02, xxxxxxxx wrote:

Hello and Welcome to Plugin Café f_lcc !

First of all I would like to remind you that we are not suppose to develop your plugin or even debug it.
Please help us to help you. Instead of telling it's not working, tell us what you want to achieve.
Moreover keep your example simple, one problem, one example (it will also help you to debug your code).

With that said, there are few issues in your code.

Output function:

  1. This function as it's written in the SDK, should return a c4d.Vector, then make sure all your conditions return a vector.
  2. Variable scope, if you create a variable within an indentation, this variable will only be available in this indentation scope or children one. (cf color variable)
  3. self.rangeMapper did not exist, so I replaced by c4d.utils.RangeMap(rayAngle, 0.6, 1.0, 0.0, 1.0, True). Use Clamp value to True since you are using pow.
  4. Always check for variable(cf self.shader)

While I know you are currently learning, in python you can do MyVariable = 10 if x < y else 20

	def Output(self, sh, cd) :
		pos = c4d.Vector()
		nor = c4d.Vector()
		color = c4d.Vector()
  
		if self.mode == FPLUGTWO_WORLD : # Espace Monde
			colVal = c4d.Vector()
  
			if cd.vd : # 3D
				#just some tests
				pos  = cd.vd.p
				nor  = cd.vd.orign
				uvPos= cd.vd.uvw
				#print uvPos
				aRay = cd.vd.ray
				#print aRay
				raypos = aRay.p
				rayDir = aRay.v
				rayIOR = aRay.ior/4.0
				rayLength = cd.vd.dist #The distance between p and ray->p, i.e. the ray length. 
				rayAngle = (cd.vd.cosc  \+ 1) /2.0 #The angle between ray vector and unbumped normal.
				mapVal = c4d.utils.RangeMap(rayAngle, 0.6, 1.0, 0.0, 1.0, True) 
				linVal = math.pow(mapVal, 2.2) #0.45454
				colVal = c4d.Vector(linVal, linVal/2.0, linVal)
  
			else : # Aperçu
				pos = (cd.p - 0.5) * 100.0 if self.ape else pos
				return pos
  
			color = colVal
		
		elif self.mode == FPLUGTWO_UV : # Espace UV
			#color = cd.p
			color = self.shader.Sample(cd) if self.shader else cd.p
  
		
		elif self.mode == FPLUGTWO_LOCAL : # Espace Objet
			if cd.vd : # 3D
				pos = cd.vd.p
			else : # Aperçu
				if self.ape : pos = (cd.p - 0.5) * 100.0
				else : return pos
			color = pos
  
		return color

FreeRender:

  1. In your InitRender you initialize a shader, Free this one when the render is finnish or you have some memory leaks.
    def FreeRender(self, sh) :
        #Free any resources used for the precalculated data from InitRender().
        if self.shader:
            self.shader.FreeRender()
        return

If you have any others questions feel free to ask 🙂

On 02/02/2018 at 07:58, xxxxxxxx wrote:

Thank for the quick response.

ok i will be more secifique next time.

Work perfectly now.

And true I hardly forgot the importance of scope 🙂