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
    • Recent
    • Tags
    • Users
    • Login

    ViewportSelect()

    Scheduled Pinned Locked Moved PYTHON Development
    3 Posts 0 Posters 317 Views
    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 Offline
      Helper
      last edited by

      On 07/04/2014 at 10:19, xxxxxxxx wrote:

      Hi,

      I`m using utils.ViewportSelect() within a Python plugin to select all polygons visible to the viewport camera..

      However - it seems to add around .25 sec overhead each time i loop over the pixels on screen.  I suspect this might be just because Python for loops are quite slow but looking for any ideas on this.  My code is as follows:

      vps = c4d.utils.ViewportSelect()
      			
      bd = doc.GetRenderBaseDraw()
      frame = bd.GetFrame()
      width = frame["cr"] - frame["cl"] + 1
      height = frame["cb"] - frame["ct"] +1
      			
      vps.Init(width, height, bd, [obj], c4d.Mpolygons, False, c4d.VIEWPORTSELECTFLAGS_0)
      			
      for i in xrange(width) :
      	for j in xrange(height) :
      		res = vps.GetPixelInfoPolygon(i, j)
      		if res:
      			baseSelection.Select(res["i"])
      

      Any ideas or suggestions on how this might run faster would be appreciated!

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

        On 11/04/2014 at 07:18, xxxxxxxx wrote:

        Hi Eclectrik,

        I'll make a C++ version to benchmark the two, but I don't think Python is the issue here. Python
        might not be fast, but is really not that slow either! I can iterate over 10 million empty passes in
        less than a second on my machine.

        Best,
        -Niklas

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

          On 17/04/2014 at 13:52, xxxxxxxx wrote:

          How do you come to the .25 sec per loop? I've compared the C++ and Python version and I
          have almost expected the Python version to be slower than it actually is.

          While the C++ version executed within about 45-60 milliseconds, tested on a landscape object with
          default parameters, the Python version executed in about 355 to 420 milliseconds, which is less
          than 9 times

          Note that I have set "onlyvisible" to True since you only want to select visible elements.

          Python Version

          >
          > import c4d
          > import time
          >
          > def main() :
          > start = time.time()
          > sel = op.GetPolygonS()
          > vps = c4d.utils.ViewportSelect()
          > bd = doc.GetRenderBaseDraw()
          > frame = bd.GetFrame()
          > width = frame["cr"] - frame["cl"] + 1
          > height = frame["cb"] - frame["ct"] +1
          >
          > vps.Init(width, height, bd, [op], c4d.Mpolygons, True, c4d.VIEWPORTSELECTFLAGS_0)
          >
          > for i in xrange(width) :
          > for j in xrange(height) :
          > res = vps.GetPixelInfoPolygon(i, j)
          > if res:
          > sel.Select(res["i"])
          >
          > c4d.EventAdd()
          > print (time.time() - start) * 1000, "ms"
          >
          > main()

          C++ Version

          >
          > if (!doc) return false; // better safe than sorry
          >
          > BaseObject* op = doc->GetActiveObject();
          > if (nullptr == op || !op->IsInstanceOf(Opolygon)) {
          > GePrint("Select a Polygon object.");
          > return true;
          > }
          > Float64 start = GeGetMilliSeconds();
          > doc->StartUndo();
          > doc->AddUndo(UNDOTYPE_CHANGE_SELECTION, op);
          > BaseSelect* sel = ToPoly(op)->GetPolygonS();
          > doc->EndUndo();
          >
          > AutoAlloc<ViewportSelect> vps;
          > BaseDraw* bd = doc->GetRenderBaseDraw();
          > Int32 cl, ct, cr, cb;
          > bd->GetFrame(&cl, &ct, &cr, &cb);
          >
          > Int32 width = cr - cl + 1;
          > Int32 height = cb - ct + 1;
          >
          > if (!vps->Init(width, height, bd, op, Mpolygons, true, VIEWPORTSELECTFLAGS_0)) {
          > GePrint("Could not initialize ViewportSelect");
          > return true;
          > }
          >
          > for (Int32 i=0; i < width; ++i) {
          > for (Int32 j=0; j < height; ++j) {
          > ViewportPixel* p = vps->GetPixelInfoPolygon(i, j);
          > while (p) {
          > sel->Select(p->i);
          > p = p->next;
          > }
          > }
          > }
          >
          > EventAdd();
          > GePrint(String::FloatToString(GeGetMilliSeconds() - start) + " ms");
          > return true;

          Best,
          -Niklas

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