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
[URL-REMOVED] 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:
- This function as it's written in the SDK, should return a c4d.Vector, then make sure all your conditions return a vector.
- 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)
- 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.
- 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:
- 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
[URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.
-
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