LoadDocument()



  • On 14/02/2015 at 18:57, xxxxxxxx wrote:

    User Information:
    Cinema 4D Version:   R14 
    Platform:   Windows  ;   
    Language(s) :     C++  ;

    ---------
    Hi folks,

    just dropping by briefly while in temporary cryo-status.

    I've been close to this one before in another thread, but I'm wanting to use LoadDocument instead of LoadFile so that the scene is open in memory only, and not accessible to the user.

    I have a function to deal with the loading and rendering. Nothing fancy. Simplified function example here:

      
    void My_Plugin::RenderMe(Filename FN,C4DThread* Thread)   
    {   
        BaseDocument *doc = NULL;   
      
        if(Thread == NULL)   
        {   
            doc = LoadDocument(FN,SCENEFILTER_0,Thread->Get());   
        }   
        else   
        {   
            doc = LoadDocument(FN,SCENEFILTER_0,Thread->Get());   
        }   
            
         MultipassBitmap *Mp;   
         Mp->Alloc(...);   
         Mp->AddChannel(TRUE,TRUE);   
            
         BaseContainer rd;   
         ....set render flags etc here....   
            
         if(Thread == NULL)   
         {   
              RenderDocument(doc,rd,NULL,NULL,Mp,RENDERFLAGS_EXTERNAL,NULL);   
         }   
         else   
         {   
              RenderDocument(doc,rd,NULL,NULL,Mp,RENDERFLAGS_EXTERNAL,Thread->Get());   
         }   
                 
         ShowBitmap(Mp);   
    }   
    

    The issue is that the rendered image always returns blank, regardless of thread context. The main thread gives the same blank result. Oddly enough, the camera position is located where the editor camera would be if the file was open and in editor camera mode. I can see the grid and world axis (I'm rendering in software preview mode). But no objects etc are rendered. Is there something I'm suppose to do in order to "initialise" the scene before I render it?

    The second issue I'm having, is that I'm not getting an alpha channel rendered. I've had this issue before which I raised in another topic, but it's never been resolved. I now need this to work too. Does someone have a working example of rendering to memory with the alpha channel valid - one that doesn't require the image to be saved?

    Thanks folks,

    WP.



  • On 14/02/2015 at 20:19, xxxxxxxx wrote:

    1. Make sure that it is the active document: SetActiveDocument(doc).

    2. Maybe you need to include an EventAdd() after LoadDocument() to get C4D to do its thing.  From time immemorial, C4D will not update its internals without being kicked in the arse.

    3. As always, always check that your pointers are valid.   If the document fails to load, doc will be NULL and nothing will work.  Doubt that this is your problem, just safe programming practice.



  • On 15/02/2015 at 06:03, xxxxxxxx wrote:

    this is wrong:

      
        
        
            if(Thread == NULL)
          
          {
          
              doc = LoadDocument(FN,SCENEFILTER_0,Thread->Get() /*should be NULL*/);
          
          }
        
    


  • On 15/02/2015 at 08:41, xxxxxxxx wrote:

    And you could instead just write

    BaseThread* bt = nullptr;
    if (Thread) bt = Thread->Get();
    

    and use bt everywhere.



  • On 15/02/2015 at 15:59, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    this is wrong:

    <pre ="BBcode" style="line-height: 16.7999992370605px; width: 1141.25px; : rgb248, 248, 252;">    if(Thread == NULL)   
        {   
            doc = LoadDocument(FN,SCENEFILTER_0,Thread->Get() /*should be NULL*/);   
        }   
    

    <!-- bmi_SafeAddOnload(bmi_load,"bmi_orig_img",0);//-->

    Ah yes, sorry that's a typo. It's null in the real function - I'll edit the original post.

    Originally posted by xxxxxxxx

    And you could instead just write

     
    BaseThread* bt = nullptr;   
    if (Thread) bt = Thread->Get();   
    

    and use bt everywhere.

    I hadn't thought of that, thanks Niklas. Saves the 'getting' and null check statements!

    WP.



  • On 16/02/2015 at 10:10, xxxxxxxx wrote:

    Hello,

    to correctly load a document you have to set the correct flags. So if you want to load objects, you should set the SCENEFILTER_OBJECTS flag, if you want to load materials, you should also set the SCENEFILTER_MATERIALS flag. You find some example in the command line renderer example.

    Rendering the alpha channel should work using a MultipassBitmap. The alpha channel is of course only available in production rendering, not using the software preview mode.

    Best wishes,
    Sebastian



  • On 17/02/2015 at 01:57, xxxxxxxx wrote:

    Hi Sebastian,

    thanks for the notification of the flags. That seems to of sorted out the lack of objects being rendered. I thought I had tried some of these flags, but perhaps not!

    Re the alpha channel - the thing with this one is that I can get an alpha channel by doing it via the render to pv command. But doing it in code doesn't. What/why is there a difference here?

    How can I get a software-based preview image with an alpha channel?

    WP.



  • On 17/02/2015 at 02:17, xxxxxxxx wrote:

    Hello,

    what do you mean with "doing it via the render to pv command"? The Software Renderer does not render an alpha channel.

    Best wishes,
    Sebastian



  • On 17/02/2015 at 02:45, xxxxxxxx wrote:

    Hi Seb,

    I can get an alpha channel when hitting the render to picture viewer command - the actual button.

    WP.



  • On 17/02/2015 at 06:36, xxxxxxxx wrote:

    Hello,

    when you render a scene using Software Renderer to the Picture Viewer and the Alpha channel option in the Render Settings is turned on, you will find an alpha layer in the result. But this alpha layer is empty, so I don't see the purpose of that.

    Best wishes,
    Sebastian



  • On 17/02/2015 at 19:32, xxxxxxxx wrote:

    Hi Seb,

    but it's not empty. I can see it in black and white

    It's an alpha of the software render ala editor-viewport-style, which is what I'm after. But I can't seem to get the same result through code, which is what I need.

    Take a look at the two following links (sorry, you'll need to copy and paste - the url link fields wouldn't work).

    Software Render:
    http://s3.postimg.org/9o3h8fc8j/Animated_Teapot.jpg

    Software Render's alpha:
    http://s8.postimg.org/syix87wxh/A_Animated_Teapot.jpg

    I need to get something like the above images, but via code.

    Cheers,

    WP

    Edit: just a thought, could a video post plugin accomplish this?



  • On 18/02/2015 at 07:01, xxxxxxxx wrote:

    Hello,

    sorry, I cannot reproduce your results. Can you please share details about your Cinema 4D version and provide a scene file illustrating your results?

    Best wishes,
    Sebastian



  • On 18/02/2015 at 19:20, xxxxxxxx wrote:

    Hi Sebastian,

    yeah sure. Doing all testing on R14.042 32bit. Build RC76788. PM sent with scene file as I don't think I can upload files here.

    One thing I've noticed is that I only seem to get the alpha when the save path etc details are included. So if you untick the save in the render settings, or leave the path blank, it won't work. Don't know if that helps any more?

    Cheers,

    WP.



  • On 20/02/2015 at 06:37, xxxxxxxx wrote:

    Hello,

    the alpha channel you discovered is actually no feature of Cinema 4D. It is only usefull in special, internal cases and should not be used.

    Best wishes,
    Sebastian



  • On 20/02/2015 at 16:56, xxxxxxxx wrote:

    Hi Seb,

    thanks for the update!

    This still leaves the question though - how can I get an editor-style render with an alpha? A virtual viewport? VideoPost plugin? Something else?

    A big part of the plugin is riding on this bit working

    WP.



  • On 20/02/2015 at 18:56, xxxxxxxx wrote:

    hey,

    here is how you can get the alpha , it is a video post plugin for sure, modify vpvisualizenormals example to be like this:

      
    RENDERRESULT VisualizePostData::Execute(BaseVideoPost* node, VideoPostStruct* vps)
    {
    	if (vps->vp == VIDEOPOSTCALL_RENDER && !vps->open && *vps->error == RENDERRESULT_OK && !vps->thread->TestBreak())
    	{
    		VPBuffer*			rgba = vps->render->GetBuffer(VPBUFFER_RGBA, NOTOK);
    		RayParameter* ray	 = vps->vd->GetRayParameter();	// only in VP_INNER & VIDEOPOSTCALL_RENDER
    		if (!ray)
    			return RENDERRESULT_OUTOFMEMORY;
    		if (!rgba)
    			return RENDERRESULT_OUTOFMEMORY;
      
    		Int32 x1, y1, x2, y2, x, y, cnt;
      
    		// example functions
    		Int32 cpp = rgba->GetInfo(VPGETINFO_CPP);
      
    		x1	= ray->left;
    		y1	= ray->top;
    		x2	= ray->right;
    		y2	= ray->bottom;
    		cnt = x2 - x1 + 1;
      
    		Int			 bufferSize = cpp * cnt;
    		Float32* b, *buffer = nullptr;
      
    		if (bufferSize > 0)
    			buffer = NewMemClear(Float32, bufferSize);
    		if (!buffer)
    			return RENDERRESULT_OUTOFMEMORY;
      
    		for (y = y1; y <= y2; y++)
    		{
    			rgba->GetLine(x1, y, cnt, buffer, 32, true);
      
    			VPFragment** frag = vps->vd->GetFragments(x1, y, cnt, VPGETFRAGMENTS_Z_P | VPGETFRAGMENTS_N), ** ind = frag;
    			if (!frag)
    				continue;
      
    			for (b = buffer, x = x1; x <= x2; x++, b += cpp, ind++)
    			{
    				//Vector32		col = Vector32(0.0);
    				//VPFragment* f;
    				//for (f = (*ind); f; f = f->next)
    				//	col += (Vector32(Abs(f->n.x), Abs(f->n.y), Abs(f->n.z)) * f->weight) * f->color;
      
    				//col /= (Float32) 256.0;
    				//b[0] = col.x;
    				//b[1] = col.y;
    				//b[2] = col.z;
      
    				Ray anyray;
    				vps->vd->GetRay(x, y, &anyray);
    				SurfaceIntersection si(DC);
    				if(vps->vd->TraceGeometry(&anyray, 1e30, RayHitID(), &si) == TRUE)//intersects, fill alpha, here i fill color
    				{
    					b[0] = 1.f;
    					b[1] = 1.f;
    					b[2] = 1.f;
    				}
    				else
    				{
    					b[0] = 0.f;
    					b[1] = 0.f;
    					b[2] = 0.f;
    				}
    			}
      
    			DeleteMem(frag);
      
    			rgba->SetLine(x1, y, cnt, buffer, 32, true);
    		}
    		DeleteMem(buffer);
    	}
      
    	return RENDERRESULT_OK;
    }
    
    Bool VisualizePostData::RenderEngineCheck(BaseVideoPost* node, Int32 id)
    {
    	return true;
    }
    

    happy ray tracing 



  • On 20/02/2015 at 19:58, xxxxxxxx wrote:

    BTW it doesn't work for software renderer with picture viewer "only in viewport" , may the SDK support team help in this case



  • On 20/02/2015 at 20:40, xxxxxxxx wrote:

    Hi Mohamed!

    unfortunately, on some (and possibly many) occasions I'll need this to happen without a viewport! I.e. with a doc in memory. I'm not making things easy I know, but it's just the way it has to be

    The last option I could think of would be to render it with a chosen background colour and key it out ala green-screen-style. Maybe pick a colour brighter than white - I don't know if the software renderer would clip this or not though. But this then brings other things into play such as how to deal with transparency etc.

    I'll have a play around with the above to see what I can get out of it. Thanks for your efforts! If support or anyone else can think of something I'm all ears!

    Cheers,

    WP.



  • On 23/02/2015 at 00:05, xxxxxxxx wrote:

    Hello,

    as said before, Software and Hardware renderers do not render Alpha channels and the Alpha channel you discovered is not supposed to be used.

    So I think the best solution to get an Alpha channel is to render the given scene with the Standard renderer (and enabled Alpha channel). Since you just want the Alpha channel you can decrease the render time by disabling many render features. Then you can combine this Alpha channel with the Software RGB image.

    Best wishes,
    Sebastian



  • On 23/02/2015 at 03:07, xxxxxxxx wrote:

    Hi there Sebastian,

    hadn't thought of using the software render with a standard render alpha! Maybe. But I think this will quickly become unusable once scenes start to get a bit of oomph in them. A cube on it's own is fine. But an animated character under hypernurbs won't be. I don't really want to be doing anything with the scene itself, it's only meant to be a preview. Maybe worth a try though.

    Oddly enough, I've been using this software alpha channel for a long time! I didn't realise we weren't suppose to use it. It's been quite useful in projects of the past! Am I allowed to ask why we're not suppose to use it? (you don't have to answer that)

    At this stage I've tried a VideoPost plugin but I couldn't seem to get it working with the software renderer. I've also attempted keying the background out, which works, but I don't know if this will cater for all scenarios. Is it possible to test for depth in the preview? Maybe then key out using depth info? Get depth via a virtual viewport of some sorts?

    I'm a little hesitant to mention this one - this one might be the elephant, but would an ogl access point give me my alpha channel? Can I draw/render into a frame buffer using the sdk and get things there somehow? Trying to think outside the box. I'd be prepared to throw someone a few dollars to get me going with the ogl route though. I need a simple ogl for another purpose anyway, a bit like the material preview, but of course, different enough to make the material one not usable. I always pick the hard ones. Anyway, would anyone know if something like this could be an option?

    WP.


Log in to reply