Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush Python 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

    GetActiveUVSet

    SDK Help
    0
    8
    746
    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 21/12/2016 at 06:51, xxxxxxxx wrote:

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

      ---------
      Hi again,

      Working on my Seamilar plugin I use the CallUVCommand to perform a relax and realignment of UVs. To do so I get a TempUVHandle by calling the GetActiveUVSet. I read in forum replies that for this to work I need to set the document mode into UVpolygon (or UVpoint).
      However, I noticed that even doing so, the returned TempUVHandle is always null IF no BodyPaint 3D Texture View has been opened since Cinema 4D was started.
      Open a new Bodypaint 3D Texture View window, and from then on (even after closing the window) the returned TempUVHandle is always successful (in UV mode).
      Now, I will be looking for any possible workaround to this, but was wondering if someone already knows a workaround, or maybe I am just doing something wrong?

      This is my current code:

        
        
        // Cinema must be in UV Poly edit mode  
        BaseDocument* doc = GetActiveDocument();  
        Int32 currentDocMode = doc->GetMode();  
        if (Muvpolygons != doc->GetMode())  
            doc->SetMode(Muvpolygons);  
        
        TempUVHandle* handle = GetActiveUVSet(doc, GETACTIVEUVSET_ALL);  
        if (handle)  
        
      <...>  
        
        // set the mode back  
        if (Muvpolygons != currentDocMode)  
            doc->SetMode(currentDocMode);  
        
      

      So, when I start Cinema 4D with a default layout (or any other one which has no BodyPaint 3D Texture View) the above code will return a null handle. Open a new Texture View, close it, and above code will return a correct handle. Same for R17

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

        On 22/12/2016 at 08:46, xxxxxxxx wrote:

        Hi C4DS, thanks for writing us.

        I confirm that the GetActiveUVSet() returning Null is by design and it's required in order to have the objects used to fill the TempUVHandle properly allocated. This occurs, as pointed in your post, when the doc mode is set to Muvpoints or Muvpolygon and the Texture View has not been opened at least once.

        Beside this, please note that if doc mode is set to Mpoints or Medges or Mpolygons , even if the Texture View has never been opened, the GetActiveUVSet() should return a valid TempUVHandle pointer whose data should match those coming from using invoking the method in the first scenario (Muvpoints or Muvpolygon and the Texture View opened at least once).

        ...
        if (currentDocMode != Mpoints || currentDocMode != Medges)  
          doc->SetMode(Mpoints); // or Medges is equivalent
          
        TempUVHandle *handle = nullptr;  
        UVWStruct *uvw = nullptr;  
        handle = GetActiveUVSet(doc, GETACTIVEUVSET_ALL);  
        if (handle)  
        {  
          GePrint("PolyCount from TempUVHandle: " + String::IntToString(handle->GetPolyCount()));  
          GePrint("PointCount from TempUVHandle: " + String::IntToString(handle->GetPointCount()));  
          uvw = handle->GetUVW();  
          if (uvw)  
          {  
              // use uvw data   
          }  
        }  
        doc->SetMode(currentDocMode);
        ...
        

        Best, Riccardo

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

          On 22/12/2016 at 11:32, xxxxxxxx wrote:

          Hi Riccardo,
          Thanks for the details.
          It seems I misinterpreted the need to change to UV polygon mode.

          I got the UV handle working as you described, which is exactly what I needed.
          However, I can not get CallUVCommand working (to perform relax or realign) ... unless the Texture View has been opened once.
          I understand this to be by design, as you mention in your first sentence.
          Is there a way for a plugin to trigger the objects being properly allocated, as when manually switching to Muvpolygon mode and opening a Texture View?

          thanks,
          Daniel

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

            On 23/12/2016 at 07:37, xxxxxxxx wrote:

            Hi Daniel, thanks for providing these additional comments.

            I've looked more in detail and running the code below the method that requires the Texture View to be opened at least once isn't CallUVCommand to fail - it indeed produces the correct results in terms of uv data, but it's SetUVW() method belonging to TempUVHandle returning false and thus not properly updating the uv data.

            Diving into it is seems that the SetUVW requires the Texture View to be opened and showing the current UVWTag.

            if (uvw)  
            {  
              // use uvw data   
                
              BaseObject *op = handle->GetBaseObject();  
              if (!op)  
                  return false;  
              const Vector *pvPoints = handle->GetPoint();  
              if (!pvPoints)  
                  return false;  
              const CPolygon* pPolys = handle->GetPoly();  
              if (!pPolys)  
                  return false;  
              Int32 lPointCount = handle->GetPointCount(), lPolyCount = handle->GetPolyCount();  
              BaseSelect* pPolySel = handle->GetPolySel();  
              BaseSelect* pPointSel = handle->GetUVPointSel();  
              Int32 mode = handle->GetMode();  
              BaseContainer set;  
              set.SetBool(RELAXUV_KEEP_BORDER, true);  
              set.SetBool(RELAXUV_KEEP_NEIGHBORS, false);  
              set.SetBool(RELAXUV_KEEP_POINTSEL, false);  
              set.SetBool(RELAXUV_CUT_EDGESEL, false);  
              set.SetInt32(RELAXUV_MAX_ITERATIONS, 10);  
              set.SetInt32(RELAXUV_MODE, RELAXUV_MODE_LSCM);  
              Bool res = CallUVCommand(pvPoints, lPointCount, pPolys, lPolyCount, uvw, pPolySel, pPointSel, op, Mpolygons, UVCOMMAND_RELAX, set);  
              if (!res)  
              {  
                  GePrint("CallUVCommand failed");  
                  return res;  
              }
                res = handle->SetUVW(uvw);  
              if (!res)  
              {  
                  GePrint("SetUVW failed");  
                  return res;  
              }  
            }
            

            Best, Riccardo

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

              On 23/12/2016 at 08:20, xxxxxxxx wrote:

              Honestly, I didn't think to check the SetUVW call, I assumed it was the CallUVCommand which didn't perform, although returning success.
              Actually, I am using the newer SetUVWFromTextureView call instead of SetUVW as I need the additional parameter to avoid storing the undo state. But here as well, this SetUVW... returns false, as you mentioned.

              So I guess there's no workaround and the Texture View needs to be opened (at least once), which probably isn't possible via plugin?

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

                On 27/12/2016 at 01:54, xxxxxxxx wrote:

                Hi Daniel,

                I confirm there actually no workaround to your workflow which indeed requires the Texture View to get opened by user interaction.

                Best, Riccardo

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

                  On 27/12/2016 at 04:44, xxxxxxxx wrote:

                  OK.
                  Thanks for letting me know.

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

                    On 13/01/2017 at 01:16, xxxxxxxx wrote:

                    I have been informed by a fellow user to do a CallCommand(170103) which opens a new Texture View. Works perfectly.
                    Is there maybe a way to close the view
                    I have searched the forum and found the same question asked back in 2013, without conclusive answer. Hoping it might get answered now.

                    This topic has been set to [SOLVED] ?

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