Average color of a polygon from texture
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 20/08/2012 at 04:17, xxxxxxxx wrote:
To complete this topic, I ended up using a random sampling method within the polygon to get the average value. The user can select the number of samples and it works very well. If anyone needs to know how to get random points within a triangle/quadrangle, the code is very simple and I would be very happy to provide it.
-
THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED
On 20/08/2012 at 08:16, xxxxxxxx wrote:
I would kill to see a working a example on texture sampling Robert using a ray.
I'm still trying to figure out how to sample the texture colors on objects.
Every time the subject comes up here. The complete solution is never posted.I tried to use the code posted here a while back. But I couldn't manage to convert it to R12+.
Some kind of working example would be wonderful. If it's something you are willing to provide.-ScottA
-
On 05/04/2013 at 08:44, xxxxxxxx wrote:
Hi Remo,
I've downloaded the code from GitHub. And found that I could not compile it for R13.
I had to change some things in the Init() function to make it compile:LONG Sampler::Init(BaseMaterial *mat,LONG chnr, Real time,BaseDocument *doc, BaseObject *op) { if (!doc || !mat || chnr < 0 || chnr > 12) return 1; if (!cd.vd || !tex || !irs || !rop) return 2; TexInit = FALSE; LONG err = 0; BaseContainer chandata; LONG fps = doc->GetFps(); Filename dpath = doc->GetDocumentPath(); BaseChannel *texChan1 = mat->GetChannel(chnr); if (!texChan1) return 3;//no Channel texShader = texChan1->GetShader(); if(!texShader) return 4; if (op){ //Object rop->link = op; rop->mg = op->GetMg(); rop->mp = op->GetMp()*op->GetMg(); rop->rad = op->GetRad(); if (op->IsInstanceOf(Opolygon)) { rop->pcnt = ToPoly(op)->GetPointCount(); rop->padr = ToPoly(op)->GetPointW(); rop->vcnt = ToPoly(op)->GetPolygonCount(); rop->vadr = (RayPolygon* )ToPoly(op)->GetPolygonW(); rop->type = O_POLYGON; } } //----------------- TexData ------------------- tex->mp = mat;// Set Material //------------ InitRenderStruct ---------------- irs->fps = fps; irs->time = BaseTime(time); irs->doc = doc; irs->docpath = dpath; irs->vd = cd.vd; //---------------- Sampling --------------------- chandata = texChan1->GetData(); cd.off = chandata.GetReal(BASECHANNEL_BLUR_OFFSET,0.0); cd.scale = 0.0; cd.d = 0.0; cd.n = Vector(0.0,1.0,0.0); cd.texflag = TEX_TILE; if (texShader->InitRender(*irs)==INITRENDERRESULT_OK) { TexInit = TRUE; return 0;} else err = 5; //Error: //The Complier doesn't like this for some reason // texShader->FreeRender(); // return err; }
There's a problem with the way you wrote your "Error" code that my V.S. 2010 compiler does not like. So I just commented it out for now.
I also have some basic questions on how to use the code:
-
I assume I'm supposed to use this as an .h file in my project? (that's how I've been using it)
-
Suppose for example, I wanted to sample the shader in the color channel of the first material in the material manager.
I would normally create the code to get the material..Get the channel..Get the shader. But the way you have your constructor set up with the channel numbers and such. I'm a bit confused how to use it.
If you don't mind too much. It would be nice to see a very, very small example of using the class so I can see how to use the constructor. Because it's a little bit foreign to me from the normal way I code for materials.
Thanks,
-ScottA -
-
On 05/04/2013 at 12:54, xxxxxxxx wrote:
Just remove Error: but do not remove texShader->FreeRender(); and return.
1) yes of course.
- it is already in Init() of course you can create another Init() with the Shader as parameter.
I need to search in my code old to find some example for this.
-
On 05/04/2013 at 18:46, xxxxxxxx wrote:
Let me try to help you... help me. If I may.
I've been able to figure out how to use it. But I'm not sure what it is you've given me.I have your code in my project as an .h file.
And this is how I'm using it to get a result from the Sample3D() function:BaseDocument *doc = GetActiveDocument(); BaseObject *obj = doc->GetActiveObject(); if (!obj) return FALSE; BaseMaterial *mat = doc->GetFirstMaterial(); //The material to target if (!mat) return FALSE; BaseContainer *mdata = mat->GetDataInstance(); //The material's container data Sampler smpl; smpl.Init(mat,CHANNEL_COLOR, 0.0, doc, obj); //Initialize an instance of the Sample class with these items smpl.Sample3D(0, 0, 0.0); //<--- What is this that I have now?
What I don't understand is. How do I use this result to get the texture colors from the shader?
I'm completely lost about how this whole "getting the textures on a specific area of an object" thing works.
All this stuff about ChannelData, VolumeData, Text Data, cd.p, cd.uv, etc...
I'm trying to get a basic understanding of it all. And how to use it all. But there's precious few posts about this subject.
-ScottA -
On 05/04/2013 at 20:32, xxxxxxxx wrote:
Sample3D() returns a Vector which represents the color (0-1 for RGB) at that sample coordinate.
-
On 05/04/2013 at 21:18, xxxxxxxx wrote:
Oh. I see.
Thanks Robert.That gives me a way to get the color values. But what about the UV values for it?
There's only one param. But I need two(U&V) to be able to sample a specific position on the object.
One param. for both severely limits where I can sample the UV's:Sampler smpl; smpl.Init(mat,CHANNEL_COLOR, 0.0, doc, obj); Vector color = smpl.Sample3D(0, .5, 0.0); //<--- Gets the center of the UV's...But why do I only have one UV value param instead of two? //Having only one limits where I can target the U&V coords. Real r = color.x; Real g = color.y; Real b = color.z; GePrint( RealToString(r) + " " +RealToString(g) + " " +RealToString(b) );
Also:
What about all the VolumeData and RayObject stuff in that class?
Can I use that code in some manner? Or is all of that code just there to make the SampleUV() & Sample3D() functions work?Sorry for all the questions guys.
But like I said. I have lots questions about this subject and I'm trying to learn how everything works.-ScottA
-
On 05/04/2013 at 21:36, xxxxxxxx wrote:
The first two arguments for Sample3D() are vectors. He is just using a shortcut to create a vector with all three values being equal (0.0 = Vector(0.0, 0.0, 0.0) for instance). If you want to sample other locations, you will need to pass both the 3D point and the UVW vector associated with it. Unfortunately, Remotion4D has not provided an example of how he uses his Sampler class to get or calculate this information. Like me, you will need to determine how to sample, how many samples for each polygon. I went for a random sampling since I only needed the average color of the polygon but for something more detailed like a scanline sampling or marching cubes or subpixel sampling you will need to research the methods required.
-
On 06/04/2013 at 04:33, xxxxxxxx wrote:
Please lock here:
https://github.com/PluginCafe/Cinema-4D-Code-Collection/blob/master/C++/SamplerRemo.hHope this help.
-
On 06/04/2013 at 09:05, xxxxxxxx wrote:
Thanks Remo,
Your new notes make it more clear how to sample a specific UV coord now:
BaseDocument *doc = GetActiveDocument(); BaseObject *obj = doc->GetActiveObject(); if (!obj) return FALSE; BaseMaterial *mat = doc->GetFirstMaterial(); if (!mat) return FALSE; //The material to be sampled Sampler smpl; const LONG init_res = smpl.Init(mat,CHANNEL_COLOR, 0.0, doc); if(init_res != 0) return FALSE; Vector pos3d; //3d coordinates for 3D shader. Vector uv; //UVW coordinates for all other shaders. //Control the focus point where to sample the color from uv.x = .5; uv.y = .1; //set here pos3d and uv !!! const Vector color = smpl.Sample3D(pos3d, uv); GePrint( RealToString(color.x) + " " +RealToString(color.y) + " " +RealToString(color.z) ); //prints the RGB color values
I will take a look at the other two functions in your class later today and try to understand what they also do.
I just wish there was more information about the whole subject. Things like: how and why to use Volume and Ray objects. Stuff like that.Thanks for posting the code,
-ScottA