Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Categories
      • Overview
      • News & Information
      • Cinema 4D SDK Support
      • Cineware SDK Support
      • ZBrush 4D SDK Support
      • Bugs
      • General Talk
    • Unread
    • Recent
    • Tags
    • Users
    • Login

    Getting the rendered color from a surface

    SDK Help
    0
    20
    1.6k
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • H
      Helper
      last edited by

      On 23/05/2015 at 14:03, xxxxxxxx wrote:

      Wow!!! Reading that thread I got a bit worried. It seems that using InitBakeTexture() and BakeTexture() is not easy 😞
      Do I really need to create a new thread in my code?!?
      I don't know how to do that. 😞

      1 Reply Last reply Reply Quote 0
      • H
        Helper
        last edited by

        On 24/05/2015 at 04:32, xxxxxxxx wrote:

        Definitely, I can't understand how to create my own thread and I believe that is required to check if the BakeTexture() has finished baking 😞
        Could anyone help me out?

        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 24/05/2015 at 05:26, xxxxxxxx wrote:

          Is this the correct way to create a array of pointers to pointers?

          TextureTag* text_tag[tags_count]; //tags_count is the number of texture tags, already calculated previously
          TextureTag** text_tags=text_tag;

          first_tag=b_source->GetFirstTag();
          LONG index=0;

          while (first_tag!=nullptr) {
               if (first_tag->IsInstanceOf(Ttexture))
               {
                    text_tag[index++]=(TextureTag* ) first_tag;
               }
               first_tag=first_tag->GetNext();
          }

          1 Reply Last reply Reply Quote 0
          • H
            Helper
            last edited by

            On 24/05/2015 at 06:55, xxxxxxxx wrote:

            Why not use something like this ?

              
                
                
                BaseDocument* BakeTextureTest(BaseDocument* doc, Int32 tagsCnt,const BaseContainer &settingsBc) 
                { //Remo: 24.05.2015  BakeTextureTest
                  maxon::BaseArray<TextureTag*> textags;
                  maxon::BaseArray<UVWTag*> texuvws;
                  maxon::BaseArray<UVWTag*> destuvws;
                 
                  textags.Resize(tagsCnt);
                  texuvws.Resize(tagsCnt);
                  destuvws.Resize(tagsCnt);
                 
                  // ... fill arrays ...
                  for(Int32 i=0; i<tagsCnt; ++i)
                  {
                    textags[i] = nullptr;
                    texuvws[i] = nullptr;
                    destuvws[i] = nullptr;
                  }
                 
                  BaseDocument* bakedDoc = InitBakeTexture(doc,textags.GetFirst(),texuvws.GetFirst(),destuvws.GetFirst(),tagsCnt,settingsBc);
                  return bakedDoc;
                }
            
            1 Reply Last reply Reply Quote 0
            • H
              Helper
              last edited by

              On 24/05/2015 at 10:07, xxxxxxxx wrote:

              That looks simple enough.
              But will that work for the InitBakeTexture() that deals with several texture tags? It seems to do so, but it only points to the first tag.
              Isn't it supposed to be filled with only the texture tags instead of being initialized with nullptr and simply pointing to the first one?

              1 Reply Last reply Reply Quote 0
              • H
                Helper
                last edited by

                On 24/05/2015 at 10:17, xxxxxxxx wrote:

                You do not need to make your own thread.  If you pass nullptr for it, the main C4D thread will be used (which is okay to do).

                On using BaseArray and GetFirst(), I am not sure that is going to work properly.  GetFirst() returns the first element (in this instance, a TextureTag* ).  InitBakeTexture() needs a TextureTag** to iterate through the array of TextureTag* elements.

                Remember that defining the array size locally like that (TextureTag* text_tag[tags_count]) will cause the array to be created on the stack instead of in memory (where you would use memory allocations).  Might work most of the time, but if you are dealing with a large number of elements, it make cause a stack overflow - basically, you run out of stack memory.

                I'd like to know if BaseArray or PointerArray could be used in this instance.

                1 Reply Last reply Reply Quote 0
                • H
                  Helper
                  last edited by

                  On 24/05/2015 at 10:34, xxxxxxxx wrote:

                  I would also like to know if BaseArray could be used.
                  If not, my code could be used?

                    
                  TextureTag* text_tag[tags_count]; //tags_count is the number of texture tags, already calculated previously   
                  TextureTag** text_tags=text_tag;   
                    
                  first_tag=b_source->GetFirstTag();   
                  LONG index=0;   
                    
                  while (first_tag!=nullptr) {   
                       if (first_tag->IsInstanceOf(Ttexture))   
                       {   
                            text_tag[index++]=(TextureTag* ) first_tag;   
                       }   
                       first_tag=first_tag->GetNext();   
                  }
                  

                  As for creating the array in the stack with this type of definition, I will only be baking one object and, at most, 10 to 20 Texture tags (usually much less than that). So, I guess there will be no stack memory problem.

                  As for not creating a Thread, will the control only return to my code (in the main thread) after the baking is complete?

                  1 Reply Last reply Reply Quote 0
                  • H
                    Helper
                    last edited by

                    On 25/05/2015 at 07:28, xxxxxxxx wrote:

                    On using BaseArray and GetFirst(), I am not sure that is going to work properly.
                    It should work, because GetFirst() return pointer to the firs element.
                    Another alternative would be to use  &array[0] instate.

                    Here is improved code that will compile and run.
                    Of course it is still not complete and will result in error 3007==BAKE_TEX_ERR_WRONG_BITMAP.

                      
                        
                        
                        bool BakeTextureTest2(BaseDocument* doc) 
                        { //Remo: 25.05.2015
                        	if(nullptr == doc) return false;
                        	BaseObject *obj = doc->GetActiveObject();
                        	if (nullptr == obj) return false;
                         
                        	maxon::BaseArray<TextureTag*> textags;
                        	maxon::BaseArray<UVWTag*> texuvws;
                        	maxon::BaseArray<UVWTag*> destuvws;
                         
                        	for (BaseTag *tag = obj->GetFirstTag(); tag; tag = tag->GetNext()) {
                        		if (tag->IsInstanceOf(Ttexture)) {
                        			TextureTag* texTag = static_cast<TextureTag*>(tag);
                        			print(texTag->GetName());
                        			textags.Append(texTag);
                        		}
                        	}
                        	texuvws.Resize(textags.GetCount());
                        	destuvws.Resize(textags.GetCount());
                        	// ! now fill texuvws and destuvws arrays !
                         
                        	BaseContainer settingsBc; 
                        	//fill settingsBc here ... BakeTexEnums
                         
                        	BAKE_TEX_ERR bakeError = BAKE_TEX_ERR_NONE;
                         
                        	AutoFree<BaseDocument> bakedDoc(
                        		InitBakeTexture(doc, //The document. 
                        			&textags[0], //The texture tags to bake. Must be assigned to objects. 
                        			texuvws.GetFirst(), //The UVW tags to bake. 
                        			nullptr/*destuvws.GetFirst()*/,  //The destination UVW tags for the bake. If not nullptr, the current projection is transformed into the uvw tags. 
                        			textags.GetCount(), //The number of tags in textags, texuvws and destuvws arrays. 
                        			settingsBc, //The bake settings: BakeTexEnums 
                        			&bakeError //Assigned the error result, if not nullptr: BAKE_TEX_ERR 
                        			)
                        		); 
                        	
                        	if (BAKE_TEX_ERR_NONE != bakeError) {
                        		print("bakeError ",bakeError);
                        		return false;
                        	}
                         
                        	//do something with bakedDoc ...
                         
                        	return true;
                        }
                      
                    
                    1 Reply Last reply Reply Quote 0
                    • H
                      Helper
                      last edited by

                      On 25/05/2015 at 11:31, xxxxxxxx wrote:

                      Thank you, I will give it a try (tomorrow).
                      I was having doubts with the previous code snippet because the tags array was filled with nullptr and that was what was being feed into the InitBakeTexture().

                      1 Reply Last reply Reply Quote 0
                      • H
                        Helper
                        last edited by

                        On 26/05/2015 at 09:36, xxxxxxxx wrote:

                        Hello,

                        the bake functions are relatively old functions, BaseArray is a relatively new class so these two things have nothing to do with each other. But it seems that indeed these two can be combined. Here is some code I came up with:

                          
                        // let's use the same UVW tag for all texture tags  
                        UVWTag* uvwTag = (UVWTag* )obj->GetTag(Tuvw);  
                          
                        if(uvwTag == nullptr)  
                         return true;  
                          
                        BaseTag* tag = obj->GetFirstTag();  
                          
                        // prepare arrays for texture tag ptr and uvw tag ptr  
                        maxon::BaseArray<TextureTag*> textureTagArray;  
                        maxon::BaseArray<UVWTag*> uvwTags;  
                          
                        // save ptr of all texture tags; fill uvw array  
                        while(tag)  
                        {  
                         if(tag->GetType() == Ttexture)  
                         {  
                             textureTagArray.Append((TextureTag* )tag);  
                             uvwTags.Append((UVWTag* )uvwTag);  
                         }  
                          
                         tag = tag->GetNext();  
                        }  
                          
                        // check if there is something to do  
                        if(textureTagArray.GetCount() == 0)  
                         return true;  
                          
                        // setup bake settings  
                        BaseContainer settings;  
                        settings.SetInt32(BAKE_TEX_WIDTH,400);  
                        settings.SetInt32(BAKE_TEX_HEIGHT, 400);  
                        settings.SetInt32(BAKE_TEX_PIXELBORDER, 2);  
                        settings.SetBool(BAKE_TEX_CONTINUE_UV, true);  
                        settings.SetBool(BAKE_TEX_USE_PHONG_TAG, true);  
                        settings.SetVector(BAKE_TEX_FILL_COLOR, Vector(0.0));  
                        settings.SetBool(BAKE_TEX_COLOR, true);  
                        settings.SetBool(BAKE_TEX_COLOR_ILLUM, false);  
                        settings.SetBool(BAKE_TEX_COLOR_SHADOWS, false);  
                        settings.SetBool(BAKE_TEX_COLOR_LUMINANCE, false);  
                        settings.SetBool(BAKE_TEX_COLOR_DIFFUSION, false);  
                          
                        // InitBakeTexure  
                        BAKE_TEX_ERR err;  
                          
                        BaseDocument* bakeDoc = InitBakeTexture(doc,textureTagArray.GetFirst(),uvwTags.GetFirst(),nullptr,textureTagArray.GetCount(),settings,&err,nullptr);  
                          
                        // if success, do bake  
                        if(err == BAKE_TEX_ERR_NONE)  
                        {  
                         // prepare multipass bitmap  
                         MultipassBitmap* bitmap = MultipassBitmap::Alloc(400,400,COLORMODE_RGB);  
                          
                         // bake  
                         BakeTexture(bakeDoc,settings,bitmap,nullptr,nullptr,nullptr);  
                          
                         // show result  
                         ShowBitmap(bitmap);  
                          
                         // clear result  
                         MultipassBitmap::Free(bitmap);  
                        }  
                          
                        // clear bake document  
                        BaseDocument::Free(bakeDoc);  
                        

                        best wishes,
                        Sebastian

                        1 Reply Last reply Reply Quote 0
                        • First post
                          Last post