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

    DrawPolygonObject at specific z-offset

    Cinema 4D SDK
    r23 c++
    2
    5
    880
    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.
    • C4DSC
      C4DS
      last edited by

      I am doing some experimentation with a SceneHookData-derived plugin, and would like in the SceneHookData::Draw to perform during SCENEHOOKDRAW::DRAW_PASS the following steps:

      • fill the viewport with a color
      • draw a wireframe of a sphere on top

      To achieve this I create a GeClipMap the size of the viewport, fill it with a color, get its bitmap and perform a BaseDraw::DrawTexture.
      I am using BaseDraw::SetMatrix_Screen(lineZoffset). By default the lineZoffset is set to 0.

      Then I use BaseDraw::DrawPolygonObject to draw a mesh object.

      Unfortunately, I do not see the wireframe of the object, and wonder if this is due some z-offset?
      I have tried to perform a ```BaseDraw::LineZOffset(lineZoffset + 1) right before the DrawPolygonObject in order to make sure the z-order of the wireframe is always higher than that of the DrawTexture, although documentation doesn't mention the DrawPolygonObject to be affected by the LineZOffset.

      I am wondering how to get the wireframe shown on top of the DrawTexture.

      1 Reply Last reply Reply Quote 0
      • ferdinandF
        ferdinand
        last edited by ferdinand

        Hi @C4DS,

        thank you for reaching out to us. This is probably not possible in the way you are trying to implement it, assuming that I do understand your approach correctly. Note the special note in the description of BaseDarw::SetMatrix_Screen

        This method only affects the new 3D drawing methods below it, i.e. DrawLine(), LineStrip(), DrawHandle(), DrawPoly(), DrawTexture(), DrawCircle(), DrawBox(), DrawPolygon() and DrawSphere().

        What is also a bit unclear to me is on which plane you do draw your texture, I assume on the camera plane, i.e., at z=0.0? I am not sure if you are aware of it, but screen space does not mean 2D, you can still offset things along the depth/z-axis.

        Long story short, I did recreate your setup in Python and do not really see a way out. I also looked at the code of DrawPolygonObject and it looks like that is should respect the z-depth of a drawing operation when you pass DRAWOBJECT::Z_OFFSET as flag, but it does not work for me. I will reach out to the devs to ask them if this combination of screen space (the texture) and world space (the polygon object) drawing operation while supporting a drawing order is supported. I will report back when I have an answer. But I would not hold my breath that this is possible.

        Cheers,
        Ferdinand

        My test script as a Python scripting tag, in case I somehow misunderstood you.

        import c4d
        
        LINEZOFFSET = 0
        
        
        def GetViewBitmapData(viewFrame, color=c4d.Vector(.25, .5, 1), alpha=.5,
                              zdepth=0.):
            """Returns the data for a texture drawing operation of filling the 
            viewport with an uniformly colored bitmap.
            """
            # Create the canvas for a 1x1 bitmap.
            color *= 255
            alpha *= 255
            canvas = c4d.bitmaps.GeClipMap()
            canvas.Init(w=1, h=1)
            canvas.BeginDraw()
            canvas.SetColor(int(color.x), 
                            int(color.y), 
                            int(color.z), 
                            int(alpha))
            canvas.SetPixel(0, 0)
            canvas.EndDraw()
        
            # The polygon data.
            padr4 = [c4d.Vector(viewFrame["cl"], viewFrame["ct"], zdepth),
                     c4d.Vector(viewFrame["cl"], viewFrame["cb"], zdepth),
                     c4d.Vector(viewFrame["cr"], viewFrame["cb"], zdepth),
                     c4d.Vector(viewFrame["cr"], viewFrame["ct"], zdepth)]
            cadr = [c4d.Vector(1)] * 4
            vnadr = [c4d.Vector(0, 0, 1)] * 4
            uvadr = [c4d.Vector(0, 0, 0),
                     c4d.Vector(0, 1, 0),
                     c4d.Vector(1, 1, 0),
                     c4d.Vector(1, 0, 0)]
        
            # Return the DrawTexture signature.
            return {"bmp": canvas.GetBitmap().GetClone(),
                    "padr4": padr4,
                    "cadr": cadr,
                    "vnadr": vnadr,
                    "uvadr": uvadr,
                    "pntcnt": 4,
                    "alphamode": c4d.DRAW_ALPHA_FROM_IMAGE,
                    "flags": c4d.DRAW_TEXTUREFLAGS_USE_PROFILE_COLOR}
        
        
        def draw(bd):
            """
            """
            # The hosting object and the frame of the viewport.
            node = op.GetObject()
            viewFrame = bd.GetSafeFrame()
        
            # Draw the bitmap.
            bd.SetMatrix_Screen(LINEZOFFSET)
            #bd.DrawTexture(**GetViewBitmapData(viewFrame))
        
            # Draw the polygon object.
            bh = c4d.plugins.BaseDrawHelp(bd, doc)
            # bd.SetMatrix_Screen(LINEZOFFSET + 1)
            bd.LineZOffset(5)
            bd.DrawPolygonObject(bh, node, c4d.DRAWOBJECT_Z_OFFSET)
        
        
        def main():
            pass 
        

        MAXON SDK Specialist
        developers.maxon.net

        1 Reply Last reply Reply Quote 0
        • ferdinandF
          ferdinand
          last edited by

          Hi @C4DS,

          so I heard back from the developers and tried out a couple of things. The devs told me what you and I already did suspect, i.e., that the z-depth of a drawing operation is not being shared between drawing spaces. They suggested that you should try camera space, but after trying that myself, I cannot see a scenario where this would help you other than making the texture placement slightly more convenient.

          In the camera space scenario you would have to place the texture physically behind the object, since DrawPolygonObject will always be drawn in matrix space. In matrix space you could reverse the order, but you have to remember that zdepth is actually that, a depth value, and not an integer drawing order, so setting that value can be tricky. In both cases you would have to do manually the math to place the texture precisely within the view- or safeframe.

          I hope this somewhat helps, although it is again no solution for you.

          Cheers,
          Ferdinand

          MAXON SDK Specialist
          developers.maxon.net

          C4DSC 1 Reply Last reply Reply Quote 0
          • C4DSC
            C4DS @ferdinand
            last edited by

            @ferdinand
            Thanks for the details.

            Unfortunately, the z-order of the texture is not in my hands.
            I am actually using a DrawTexture in order to emulate a 3rd party GPU render preview.
            As such, I have no control how that preview is drawn. What I am trying to achieve is draw some mesh objects in front of said preview, and for this I was experimenting with the DrawPolygonObject on top of a DrawTexture.

            From the replies so far I understand there is no adequate solution.

            I have also experimented with DrawLine and Line Strip drawing.
            While these provide some useful results, they're more labor intensive then a simple DrawPolygonObject. And are rather slow, especially DrawLine.

            If no further comments are to be given, I will consider the case closed, since no appropriate solution is at hand.

            1 Reply Last reply Reply Quote 0
            • ferdinandF
              ferdinand
              last edited by ferdinand

              Hi @C4DS,

              I am not sure that I can follow on what you are exactly doing. But my assumption is that you have x objects in a scene, want to block out all these objects with some kind of background texture and then draw one of these objects on top of that background texture, right? This is unfortunately not possible in my understanding.

              What you could do, is fill the viewport with a background texture by putting it behind an object by manually doing the trigonometry/transforms necessary for a given cemara. Not fun to do, because you have all these ifs and whens of camera parameters, but doable. This however would only give you a custom background and block out everything behind it, but not what is between the camera, the object and the background. Which is probably not what you are after if I understand you correctly.

              Cheers,
              Ferdinand

              MAXON SDK Specialist
              developers.maxon.net

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