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

    SceneHook and DisplayControl

    SDK Help
    0
    6
    1.1k
    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 26/02/2018 at 23:06, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   r19 
      Platform:      Mac OSX  ; 
      Language(s) :     C++  ;

      ---------
      Hi,

      i've got a project, the main idea is to draw the object wireframe in a selected color. (based on the object color or the layer color or an arbitrary color)

      I've decided to rebuild something like the layermanager. So i got a sceneHook to store a list of dummy nodes with colors. When i drag object on those "mylayer" i'm adding in the object's BaseContainer a baselink to the layer. (not sure if it's something i'll go with)

      In the scenehook, i'm using inside the function  DisplayControl the function

      bd->DrawPolygonObject(bh, op, DRAWOBJECT_FORCELINES|DRAWOBJECT_USE_CUSTOM_COLOR,nullptr,mycolor);
      

      And it's working fast.
      The problem is when i'm trying to access the object base container and retrieve the color of my "mylayer"
      the function "DisplayControl" is executed twice, the first "pass" i'm only getting an empty basecontainer with this code

      const BaseContainer* bcNode = op->GetDataInstance();
      

      that's the same if i'm asking for the name's object or anything else but the mesh informations (pointscount, polycount) (asking for the first tag doesn't work neither)

      The second time "DisplayControl" is executed, i can get my color but the "DrawPolygonObject" return DRAWRESULT_SKIP.

      i've tried to use the "Draw" functions with some draw lines but my code is so slow ^^'

      i don't know where to look. I'm pretty sure you'll have some tips.
      i hope my description is clear enough 🙂

      cheers
      Manu.

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

        On 27/02/2018 at 01:46, xxxxxxxx wrote:

        Hello,

        DisplayControl() is not used to draw arbitrary shapes in the viewport. DisplayControl() should be implemented to fill the given ControlDisplayStruct structure. See the documentation of SceneHookData::DisplayControl().

        DisplayControl() is not called for different "passes". DisplayControl() is called for each selected object in the scene. The filled ControlDisplayStruct defines how this object should be displayed in the viewport.

        To draw arbitrary shapes one must do that in the Draw() function.

        If you are still interested in using DisplayControl() here is an example on how it is used:

          
        class VertexColorSceneHook : public SceneHookData  
        {  
          INSTANCEOF(VertexColorSceneHook, SceneHookData);  
          
        public:  
          
          // This SceneHook example defines polygon vertex colors for each selected polygon object.  
          // These colors are used to display the objects in the viewport.  
          
          Bool InitDisplayControl(BaseSceneHook* node, BaseDocument* doc, BaseDraw* bd, const AtomArray* active)  
          {  
          if (active && active->GetCount() > 0)  
            return true;  
          
          return false;  
          }  
          
          Bool DisplayControl(BaseDocument* doc, BaseObject*  op, BaseObject*  chainstart, BaseDraw*  bd, BaseDrawHelp*  bh, ControlDisplayStruct& cds)  
          {  
          // handle only polygon objects  
          if (!op || !op->IsInstanceOf(Opolygon))  
            return true;  
          
          // check if the object is selected or if the cache parent is selected  
          Bool active = op->GetBit(BIT_ACTIVE);  
          if (!active)  
          {  
            if (op->GetCacheParent() && op->GetCacheParent()->GetBit(BIT_ACTIVE))  
              active = true;  
          }  
          
          // if the object is not selected, don't handle it  
          if (!active)  
            return true;  
          
          // create colors for each polygon  
          PolygonObject* poly = static_cast<PolygonObject*>(op);  
          const Int32    polyCount = poly->GetPolygonCount();  
          
          if (polyCount > 0)  
          {  
            const Float stepSize = 1 / Float(polyCount);  
            Float       hue = 0.0;  
          
            Vector32* _colors = NewMem(Vector32, 4 * polyCount);  
            if (_colors == nullptr)  
              return false;  
          
            // fill with colors  
            Int32 colorIndex = 0;  
          
            for (Int32 i = 0; i < polyCount; ++i)  
            {  
              // make color  
              const Vector   hsv = Vector(hue, 1.0, 1.0);  
              const Vector32 rgb = (Vector32)HSVToRGB(hsv);  
          
              hue += stepSize;  
          
              for (Int32 p = 0; p < 4; ++p)  
              {  
                _colors[colorIndex] = (Vector32)bd->ConvertColor((Vector)rgb);  
                colorIndex++;  
              }  
            }  
          
            // set ControlDisplayStruct  
            cds.vertex_color = _colors;  
            cds.perPolygonVertexColor = true;  
          
            return true;  
          }  
          
          return true;  
          }  
          
          void FreeDisplayControl()  
          {  
          }  
          
          //------------------------------------------  
          
          static NodeData* Alloc()  
          {  
          return NewObj(VertexColorSceneHook);  
          };  
        };  
        
        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 27/02/2018 at 02:38, xxxxxxxx wrote:

          Thanks for the exemple.

          So i don't understand why i see DisplayControl called twice the number of object. (even if they are not selected)

          My problem is more about drawing wireframe of objects (selected or not) without slowing down the viewport.

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

            On 27/02/2018 at 06:06, xxxxxxxx wrote:

            ok i was not editing the object, only working with primitive 😊😊😊😊
            now it's almost working as expected but it's really slow.
            Cinema4D's wireframe mode over shading is not slow like that.

            talking about DisplayControl, i didn't understood the purpose of the chainstart parameter.

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

              On 27/02/2018 at 09:20, xxxxxxxx wrote:

              Hello,

              I was mistaken, DisplayControl() is called for all objects in the scene (the limitation to active object only applies to above example). If is called for "real" object as well as objects in caches. So for a "Cube" generator it is called for the generator as well as the polygon object in its cache. The chainstart argument references the parent object of such a cached object.

              A way to draw a wireframe of an object is to use the corresponding display options of BaseDrawHelp. You find an example in the BaseDraw Manual.

              best wishes,
              Sebastian

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

                On 27/02/2018 at 23:45, xxxxxxxx wrote:

                The information about chainstart was like switching on the light.
                I just have to check the chainstart to get my information from either op or chainstart. 
                in every case i can call

                bd->DrawPolygonObject(bh, op, DRAWOBJECT_FORCELINES| DRAWOBJECT_USE_CUSTOM_COLOR, nullptr, color);
                

                That's why this functions return DRAWRESULT_SKIP when it's called for the "cache". This make sense now.

                I know i should use the draw function but this way i don't have to walk through the hierarchy.
                thanks a lot for the help ;D

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