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

    BaseSelect - IsSelected and GetRange.. [SOLVED]

    SDK Help
    0
    7
    633
    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 12/05/2015 at 02:05, xxxxxxxx wrote:

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

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

      In the C++ docs, it says that using GetRange() is faster than looping through all polygons with IsSelected() as follows:

      #### Bool GetRange(LONG seg, LONG maxElements, LONG* a, LONG* b) const_<_h4_>_
      #### Bool IsSelected(LONG num) co_<_h4_>_h4>
        
       **Note:**  If you efficiently want to go through selections you can use the following code:  
      `  
      LONG seg=0,a,b,i;  
        
      while (bs->GetRange(seg++,&a,&b))  
      {  
        for (i=a; i<=b; ++i)  
        {  
          // ... do something - i is the selected element  
        }  
      }`  
        
      This is faster than:  
        
      `    
      for (i=0; i<maxelements; i++)  
      {  
        if (bs->IsSelected(i))  
        {  
          // ... do something  
        }  
      }`
      `
      


      I am trying to understand how the above GetRange() code actually works, for example what the hell is a 'segment' as i deal with polygon selections, and how does this method actually work..  The above GetRange example also doesn't use MaxElements and throws an error without it.  And do a, b, and maxelements refer to index's within the entire BaseSelect or array index's of the selected elements array only..  Slightly confused 😕
      Specifically what i am currently doing ( just to complicate matters ), is a multithreaded approach.  Each thread loops through a portion of the objects polygons, and does some work with BaseSelect.  So the main question is:  is it possible to use GetRange() as above, but for each function to only operate on a portion of the range - for example, something like:

      `
      `LONG seg=0,a=startIndex,b=endIndex,i;  
        
      while (bs->GetRange(seg++,(endIndex-startIndex),&a,&b))  
      {  
        for (i=a; i<=b; ++i)  
        {  
          // ... do something - i is the selected element  
        }  
      }`
      `
      


      Thanks in advance for any help and advice, it's much appreciated.

      `

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

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

        Hi,

        first I'd like to apologize, the code example is wrong. It will be correct in the next released documentation.

        What the hell is a segment?

        As explained on GetSegments() segments are disjunct parts of a selection. For example if the indeces 0 to 3 and 6 to 9 are selected, then the BaseSelect has two segments.

        Parameter maxElements of GetRange() refers to indeces of the BaseSelect. It's basically the maximum, which will be returned in parameters a and b. If you don't need this functionality, simply pass LIMIT<Int32>::MAX.

        Threading:
        In general I think, it should be fine to work with multiple threads on the BaseSelect as long as you are only reading. But of course this may depend on several thing, like who's the owner of the BaseSelect and in which context are you trying to this.

        I hope, I was able to shed some light. If not, feel free to ask.

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

          On 12/05/2015 at 10:33, xxxxxxxx wrote:

          Threading is working fine with BaseSelect as long as you are careful, even using bs->Select() etc to alter the BaseSelect works multithreaded..  I've simply passed my 'core' BaseSelect into my control thread, and from there passed it on again into each individual thread, and that works..

          Thanks for the explanation on segments, have no idea why i didn't see the info on GetSegments().

          How would i then iterate between say the middle and the end of the GetRange()?  I'm still a bit unclear as to what a and b exactly are doing and what they refer to specifically..

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

            On 12/05/2015 at 10:50, xxxxxxxx wrote:

            a and b are the start index and end index of the currently retrieved segment (using GetRange()).

            As Andreas mentioned, imagine you have a cube with 8 vertices and the vertices 0-2 are selected (and no others), then after calling bs->GetRange(0,&a,&b) :

            a = 0
            b = 2

            bs->GetRange(1,&a,&b) would return FALSE, because no other vertices are selected, so there is only one segment (ranging from vertex index 0 to vertex index 2).

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

              On 12/05/2015 at 15:35, xxxxxxxx wrote:

              Ah ok i get it thanks Katachi..

              So i could use GetSegments() to find out the number of contiguous polygons, and instruct each thread to iterate through a portion of segments using GetRange()..

              However - say there was only for example two segments, and say 8 threads, it would not be so simple to distribute them over the threads..  Can the above GetRange() example code be manipulated to operate on a range of selected polygons or points regardless of segments?

              Apologies if i am asking seemingly obvious stuff here, i certainly don't mean to have anybody write my code for me 🙂  Just struggling a little to get to grips with how the GetRange() example code works exactly and how it can be used..

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

                On 13/05/2015 at 00:08, xxxxxxxx wrote:

                You could first use GetSegments() and if the number of segments is lower than your number of threads, simply subdivide segment as needed. There's no need to process from a to b in one go, if you don't want to.

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

                  On 13/05/2015 at 01:13, xxxxxxxx wrote:

                  Damnit i think i got it now.  I was really overthinking what GetRange() was doing..  😕

                  I've implemented it like this, where pIndexStart and pLength define the range of poly indexes to look at:

                  while (dupeSel->GetRange(seg++,MAXLONGl,&a,&b))
                  {
                      for (i=a; i<=b; ++i)
                      {
                          if (i>=pIndexStart && i<LONG(pLength+pIndexStart))
                          {
                              // Do some stuff with sel..
                          }
                      }
                  }
                  

                  Ideally i think the above could be faster ( with large numbers of selections ), because at the moment although it's only 'doing some stuff' to the desired range of polys, it's still spending time looping through the entire selection ( whereas it would probably be fractionally quicker if i could limit the start and end indexes that the 'while' and 'for' loops run over..

                  Just for reference, this is the older ( slightly slower? ) code:

                  for (int i=pIndexStart; i<(pLength+pIndexStart); i++)
                  {
                      if (sel->IsSelected(i))
                      {
                          // Do some stuff with sel..
                      }
                  ]
                  
                  1 Reply Last reply Reply Quote 0
                  • First post
                    Last post