Plugin Cafe Homepage
Forum Home Forum Home > Plugin Cafe > PYTHON Development
  New Posts New Posts
  FAQ FAQ  Forum Search

Material won't render until...

Author
Message
  Topic Search Topic Search
terrachild View Drop Down
Member
Member


Joined: 2014 Apr 30
Location: United States
Online Status: Offline
Posts: 111
Direct Link To This Post Topic: Material won't render until...
    Posted: 2018 Apr 16 at 5:59pm

I'm stumped by an issue with a created hair material not rendering at first.
I create a spline, a hair material, a hair tag, and then add the tag to the spline.
Just to be safe I do this:
mat.Update(True, True)   
mat.Message(c4d.MSG_UPDATE)

If I drop the material into the console I see:
<c4d.BaseMaterial object called 'Fade: 1/Hair Material' with ID 1017730 at 0x00000181D66C5350>

If I drop the tag into the console I see:
<c4d.BaseTag object called 'Tag: Fade: 1/Hair Material' with ID 1017729 at 0x00000181D66C5410>

The ID's look correct.


The problem is it won't render by either pressing "Render View" or pressing "Render to Picture Viewer."

I then tried clicking on Material box>Menu>Function>Render All Materials.
This doesn't cause them to render.

What does work, is clicking:
Material box>Menu>Create>Shader>Hair Material.
And then rendering.

I don't apply the newly created shader; in fact, I can delete it before I render, and the previously non-rendering materials render perfectly.

Just the act of creating a hair shader suddenly makes C4D render correctly.
What the heck?


Further testing:
1) If I save the non-rendering scene to a file, and then close C4D, re-open C4D and load the file, it still doesn't render. 

2) If I create the hair shader with the menu, delete it, and then save the scene to a file.  Upon reloading the scene, everything renders correctly.  Once the scene has had a menu created shader, it will render fine, even if saved and reloaded.

What is C4D doing?

I've uploaded the file so you can see for yourself:https://drive.google.com/open?id=1gEo3_UYwQMoWNgMc51FmkAaEYgeF9TjB


I'm using R17 by the way.

Thanks,

Chris



Back to Top
Andreas Block View Drop Down
Forum Moderator
Forum Moderator
Avatar

Joined: 2014 Oct 01
Location: Hannover
Online Status: Offline
Posts: 1878
Direct Link To This Post Posted: 2018 Apr 17 at 5:33am
Hi Chris,

when creating the Hair material manually, you also need to create a "Hair Render" VideoPost and add it to the render settings (RenderData.InsertVideoPost()). When creating a Hair Material from the user interface, this is done implicitly and thus "fixes" your scene.
Roughly like so:
vpHair = c4d.documents.BaseVideoPost(c4d.VPhair)
rd = doc.GetActiveRenderData()
rd.InsertVideoPostLast(vpHair)

Cheers,
Andreas
SDK Support Engineer
Back to Top
terrachild View Drop Down
Member
Member


Joined: 2014 Apr 30
Location: United States
Online Status: Offline
Posts: 111
Direct Link To This Post Posted: 2018 Apr 17 at 10:18am
Andreas,

This doesn't work in R17.
It looks like the docs say 'BaseVideoPost' is new in R19:

The console printed out:
AttributeError: 'module' object has no attribute 'BaseVideoPost'

How do I do this prior to R19?


Thanks,

Chris
Back to Top
terrachild View Drop Down
Member
Member


Joined: 2014 Apr 30
Location: United States
Online Status: Offline
Posts: 111
Direct Link To This Post Posted: 2018 Apr 17 at 10:42am
I went back to the R14 docs and it says:

RenderData.InsertVideoPostLast(pvp)

Inserts pvp as the last video post in this render setting.

Parameters:pvp (BaseList2D) – The video post to insert.

So I tried this:
vpHair = c4d.BaseList2D(c4d.VPhair)
rd = doc.GetActiveRenderData()
rd.InsertVideoPostLast(vpHair)

This caused it to render perfectly with a new doc.

Will this method work on R14+, including R19?

EDIT - This is explored in my next post.
Also, since a user can do this over and over, does it matter if 'InsertVideoPostLast' occurs over and over.  Should I be checking if the render data already has a 'C4D.VPhair' inserted?

Thanks,

Chris


Edited by terrachild - 2018 Apr 17 at 2:35pm
Back to Top
terrachild View Drop Down
Member
Member


Joined: 2014 Apr 30
Location: United States
Online Status: Offline
Posts: 111
Direct Link To This Post Posted: 2018 Apr 17 at 2:34pm
Well, I checked the 'Render Settings' box, and sure enough every time the code executes it adds another "Hair Render" to the list.  So I did this:

rd = doc.GetActiveRenderData()
fp = rd.GetFirstVideoPost()
            
# If fp isn't 'None'
#print fp    # Prints:  '<c4d.BaseList2D object called 'Hair Render/Hair Render' with ID 1017325 at 0x000001C9E857EB50>''
#print fp.GetTypeName()     # Prints: 'Hair Render'
# How do you get the ID above to test for VPhair?
#c4d.VPhair = 1017325
            
            
if fp == None or fp.GetTypeName() != 'Hair Render':   # GetName() also works.
    #vpHair = c4d.documents.BaseVideoPost(c4d.VPhair)   # R19+
    vpHair = c4d.BaseList2D(c4d.VPhair)
    rd.InsertVideoPostLast(vpHair)


This works.  Now, they don't stack up in the 'Render Settings' box.

However, because I'm only checking the first post with:
fp = rd.GetFirstVideoPost()
It doesn't work if something else is inserted first like this:
vpLens = c4d.BaseList2D(1001049)
rd.InsertVideoPostLast(vpLens)

So, what needs to be done is to iterate over everything in the 'Render Settings' box to look only for 'Hair Render'.

How do I do that?

Also, I'd rather test for
ID == c4d.VPhair
instead of using
GetTypeName() != 'Hair Render'

But I can't find a way to extract the ID from this:
<c4d.BaseList2D object called 'Hair Render/Hair Render' with ID 1017325 at 0x000001C9E857EB50>
How do you do that?

Thanks


Edited by terrachild - 2018 Apr 17 at 3:27pm
Back to Top
Andreas Block View Drop Down
Forum Moderator
Forum Moderator
Avatar

Joined: 2014 Oct 01
Location: Hannover
Online Status: Offline
Posts: 1878
Direct Link To This Post Posted: 2018 Apr 18 at 9:49am
Hi Chris,

sorry, I missed the R17 hint...
Your solution is fine. and you are right, you should check, if the VideoPost is already there.
Just get the first VideoPost (GetFirstVideoPost()) and then iterate through with GetNext() and check for the ID with CheckType(). While I link to our current R19 docs, this works the same in R17.
Like so:
rd = doc.GetActiveRenderData()
vp = rd.GetFirstVideoPost()
found = False
while vp is not None:
    if vp.CheckType(c4d.VPhair): # alternatively compare the return value of GetType()
        found = True
        break
    vp = vp.GetNext()

Cheers,
Andreas
SDK Support Engineer
Back to Top
terrachild View Drop Down
Member
Member


Joined: 2014 Apr 30
Location: United States
Online Status: Offline
Posts: 111
Direct Link To This Post Posted: 2018 Apr 18 at 1:08pm
Andreas,

Thanks for you help.
Everything is working properly now.
Back to Top

Forum Jump Forum Permissions View Drop Down

Bulletin Board Software by Web Wiz Forums® version 9.61 [Free Express Edition]
Copyright ©2001-2009 Web Wiz

This page was generated in 0.109 seconds.