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

    Editor Translate/Scale/Rotate tools

    Scheduled Pinned Locked Moved SDK Help
    18 Posts 0 Posters 1.7k 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

      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

      On 02/09/2006 at 15:17, xxxxxxxx wrote:

      Ahh.. I'll try explaining better in an e-mail...

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

        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

        On 02/09/2006 at 20:46, xxxxxxxx wrote:

        This old message:

        _despite Begin2d and End2D
        the display never seems to get updated
        ive gone through just about every way I can think of to get the display to update.

        as I said , the circle is drawn to the Basedraw bitmap and can only be seen by minimising and then maximimising cinama.
        so im at a loss here.

        maybe the EditorWindow class is in some way blocking this update?

        maybe this plugintool class is just not allowed to refresh the screen?

        thanks for any help

        Paul "baffled" Everett
        _

        Followed by the superbly explanatory:

        _
        Subject: working now
        From: paul Everett
        Date: 9/14/2001 3:55 PM GMT

        thanks David :)_

        I'm having this problem as well - only orthographic views - and only some of them. It is so heartwarming to see that the solution was given for posterity (in invisible ink requiring lemon juice LISP code). Tell me the solution, please (this is not directed to you, Keith). Gad - it should be MANDATORY that solutions are posted for everyone either directly or on request. If this continues, I'm moving to Maya...

        Robert

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

          THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

          On 07/09/2006 at 23:53, xxxxxxxx wrote:

          Perhaps the old post about camera projections will help clear this up? <[URL-REMOVED]> Unfortunately I don't have the time right now to look into the math part of it.


          [URL-REMOVED] @maxon: This section contained a non-resolving link which has been removed.

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

            THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

            On 08/09/2006 at 00:09, xxxxxxxx wrote:

            As noted in my other thread, I cannot fathom why a 2D draw (based upon the screen pixels of the view) would be in any way affected by projection (ever!). Sometimes I get the 2D circle, most times not - especially not in axonometric views. OpenGL or Software modes don't make a difference.

            I can see how the 3D draws could be affected by the projection considering that they don't have the same 'z-distance' criteria as perspective projection. In that case, I'll have to experiment with the code in the link (and in the documentation).

            Nonetheless, one would assume that 2D drawing would be ubiquitous despite the active view unless there is some mitigating factor involved. I have been on the edge of providing the tool code in full to support to see if the error is obvious. May I do this after full investigation?

            Thanks,

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

              THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

              On 08/09/2006 at 00:14, xxxxxxxx wrote:

              (Code is always welcome! As usual, make it as short a snippet as possible but not shorter.)

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

                THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                On 08/09/2006 at 10:51, xxxxxxxx wrote:

                Here's the ToolData::Draw() code and one of the Control draw methods, some stuff removed for clarity, but still whopping (hey, my tool plugin is 2000 lines of code and growing).

                // ToolData.Draw  
                //*---------------------------------------------------------------------------*  
                LONG IPPTool::Draw(BaseDocument* doc, BaseContainer& data, BaseDraw* bd, BaseDrawHelp* bh, BaseThread* bt, LONG flags)  
                //*---------------------------------------------------------------------------*  
                {  
                     LONG     drawFlags;  
                     // Draw Operation Controls  
                     if (selectedBP)  
                     {  
                          if          (operation == IPTOP_ROTATE)          DrawRotateControl(bd, bh);  
                          else if (operation == IPTOP_TWIST)          DrawTwistControl(bd, bh);  
                          else if (operation == IPTOP_SCALE)          DrawScaleControl(bd, bh);  
                          else if (operation == IPTOP_TRANSLATE)     DrawTranslateControl(bd, bh);  
                          drawFlags =     DRAW_HANDLES;  
                     }  
                     else     drawFlags =     DRAW_AXIS|DRAW_HANDLES;  
                     // Only draw into active view  
                     if (bd != doc->GetActiveBaseDraw())     return drawFlags;  
                     // Go no further if in dragMode for operation  
                     if (dragMode)                              return drawFlags;  
                     // This allows click-deselection  
                     hilitedOP =                                   NULL;  
                     hilitedBP =                                   NULL;  
                     // From here on in, only draw highlighting (if R9.0+)  
                #ifdef C4D_R9  
                     if (!(flags & DRAWFLAGS_HIGHLIGHT))     return drawFlags;  
                #endif  
                     // Mouse outside of Editor view  
                     if (mouseX < 0.0)                         return drawFlags;  
                  
                     // Add IPP objects under cursor to selection list  
                     AutoAlloc<C4DObjectList>               objList;  
                     if (!objList)                              return drawFlags;  
                     if (!SelectionListCreate(doc, NULL, bd, mouseX, mouseY, NULL, objList))     return drawFlags;  
                     LONG               cnt =                    objList->GetCount();  
                     if (!cnt)                                   return drawFlags;  
                  
                     // The rest of the code involves Polygon/BoundingBox highlighting.  
                     // This is working in all views.  
                     // Though I do note that when the operation draws (above),  
                     // the BoundingBox highlighting is no longer in the highlight color.  
                  
                     ...  
                  
                     // So, I've included just a section where a bounding box is highlighted  
                     else  
                     {  
                          hilitedOP =               obj;  
                          hilitedBP =               ippTag->GetDataInstance()->GetObjectLink(IPPOBJECT_ROOTBONE, doc);  
                          if (!hilitedBP)          return drawFlags;  
                #ifdef C4D_R9  
                          bd->LineZOffset(32);  
                #endif  
                          bd->SetTransparency(100);  
                          Matrix          mg =     hilitedBP->GetMg();  
                          // Global position  
                          mg.off =               mg*hilitedBP->GetMp();  
                          // 'arbitrary cubic form to match bounding box  
                          Vector          rad =     hilitedBP->GetRad()*2;  
                          mg.v1 *=               rad.x;  
                          mg.v2 *=               rad.y;  
                          mg.v3 *=               rad.z;  
                          // color[0] is from the Vector color[4] array of colors used in polygon highlighting  
                          bd->Box3D(mg, 0.5, color[0]);  
                #ifdef C4D_R9  
                          bd->LineZOffset(0);  
                          return drawFlags|DRAW_HIGHLIGHTS;  
                #else  
                          return drawFlags;  
                #endif  
                     }  
                     return drawFlags;  
                }  
                  
                // IPPTool.DrawRotateControl  
                //*---------------------------------------------------------------------------*  
                void IPPTool::DrawRotateControl(BaseDraw* bd, BaseDrawHelp* bh)  
                //*---------------------------------------------------------------------------*  
                {  
                     Matrix m =          selectedBP->GetMg();  
                     Vector     ctr =     bd->WS(m.off);  
                     if (ctr.z <= 0.0)     return;  
                  
                     // BaseView dimensions  
                     LONG left, top, right, bottom, width, height;  
                     bd->GetFrame(&left;, &top;, &right;, &bottom;);  
                     width =               right - left + 1;  
                     height =          bottom - top + 1;  
                     Real     rad =     (Real)((width > height)?(height>>2) :(width>>2));  
                     // rad2 = 0.5 rad * ctr.z * scaling factor 0.0015  
                     Real     rad2 =     ctr.z * (rad * 0.00075);  
                  
                     // Scale for PolygonObject  
                     m.v1 =               !m.v1 * rad2;  
                     m.v2 =               !m.v2 * rad2;  
                     m.v3 =               !m.v3 * rad2;  
                  
                     // PolygonObject Color Properties  
                     ObjectColorProperties     ocp;  
                     ocp.usecolor =     ID_BASEOBJECT_USECOLOR_ALWAYS;  
                     ocp.xray =          FALSE;  
                  
                #ifdef C4D_R9  
                     bd->LineZOffset(32);  
                #endif  
                     bd->SetTransparency(255);  
                     // 'Sphere'  
                     bd->SetPen(GetWorldContainer().GetVector(WPREF_SELECT_AXIS_COL));  
                     bd->Circle2D(ctr.x, ctr.y, rad);  
                     // 'Rings'  
                ...  
                     // Z-Axis  
                     ocp.color =          GetWorldContainer().GetVector(WPREF_ZAXIS_COL);  
                     rotatObj->SetColorProperties(&ocp;);  
                     rotatObj->SetMg(m*MatrixRotX(Rad(-90.0)));  
                #ifdef C4D_R9  
                     bd->DrawPolygonObject(bh, rotatObj, 0L);  
                     bd->LineZOffset(0);  
                #else  
                     bd->PolygonObject(bh, rotatObj, 0L);  
                #endif  
                }
                

                Thanks,

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

                  THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                  On 08/09/2006 at 11:10, xxxxxxxx wrote:

                  Eh hem. Well, I found the first mistake - that helps the missing Circle2D partially. I though that I had double-checked this, but too many hours of working can play tricks on the mind. How about 'bd->SetTransparency(0)' instead of (255). Still not showing under every circumstance and most of the axonometric/orthographic views.

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

                    THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                    On 08/09/2006 at 12:19, xxxxxxxx wrote:

                    Next solution. Removing this for the controls draws them in any view:

                    if (ctr.z <= 0.0) return;

                    Seems that this is true for certain situations in axonometric/orthographic views. Now it's just a matter of keeping the control sizes the same relative to the screen space.

                    Also, I still haven't received any official information on how to factor in camera zoom/focal length with respect to control size.

                    Thanks,

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

                      THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                      On 09/09/2006 at 14:48, xxxxxxxx wrote:

                      Eureka!!!!!!!!!! ;D

                      For posterity and for the benefit of others to relieve their suffering in purgatory, I present code which ACTUALLY works in all projections, all views, all cameras for displaying Tool controls (similar to Cinema 4D's) using BaseDraw:

                      First off, implement these. ScreenToWorld is useful for drawing, but WorldToScreen may prove useful for picking.

                      // IPPTool.WorldToScreen (see BaseView.GetViewParameter)  
                      //*---------------------------------------------------------------------------*  
                      Vector IPPTool::WorldToScreen(const Vector& pp, BaseDraw* bd, LONG projection)  
                      //*---------------------------------------------------------------------------*  
                      {  
                           Vector     p =                    pp*bd->GetMi();  
                           Vector     off, scale, scalez;  
                           bd->GetViewParameter(&off;, &scale;, &scalez;);  
                        
                           if (projection == Pperspective)  
                           {  
                                Real     nz =     (p.z <= 0.0) ? 20.0 : 1.0/(p.z + 0.05);  
                                p.x =               p.x*scale.x*nz+off.x;  
                                p.y =               p.y*scale.y*nz+off.y;  
                                return p;  
                           }  
                        
                           p.x =     (p.x*scale.x)+off.x;  
                           p.y =     (p.y*scale.y)+off.y;  
                           switch (projection)  
                           {  
                                case Pmilitary: case Pfrog: case Pbird: case Pgentleman:  
                                p.x +=     p.z*scale.x*scalez.x;  
                                p.y -=     p.z*scale.y*scalez.y;  
                                break;  
                           }  
                           return p;  
                      }  
                      // IPPTool.ScreenToWorld (see BaseView.GetViewParameter)  
                      //*---------------------------------------------------------------------------*  
                      Vector IPPTool::ScreenToWorld(const Vector& pp, BaseDraw* bd, LONG projection)  
                      //*---------------------------------------------------------------------------*  
                      {  
                           Vector p =                    pp;  
                        
                           Vector     off, scale, scalez;  
                           bd->GetViewParameter(&off;, &scale;, &scalez;);  
                           switch (projection)  
                           {  
                                case Pmilitary: case Pfrog: case Pbird: case Pgentleman:  
                                p.x -= p.z*scale.x*scalez.x;  
                                p.y += p.z*scale.y*scalez.y;  
                                break;  
                           }  
                        
                           p.x = (p.x-off.x)/scale.x;  
                           p.y = (p.y-off.y)/scale.y;  
                        
                           if (projection==Pperspective)  
                           {  
                                Real nz = p.z + 0.05;  
                                p.x *= nz;  
                                p.y *= nz;  
                           }  
                           return p*bd->GetMg();  
                      }  
                      

                      Then do your controls like so:

                      // IPPTool.DrawRotateControl  
                      //*---------------------------------------------------------------------------*  
                      void IPPTool::DrawRotateControl(BaseDraw* bd, BaseDrawHelp* bh)  
                      //*---------------------------------------------------------------------------*  
                      {  
                           Matrix     m =          selectedBP->GetMg();  
                           Vector     ctr =     bd->WS(m.off);  
                        
                           LONG left, top, right, bottom, width, height;  
                           bd->GetFrame(&left;, &top;, &right;, &bottom;);  
                           width =               right - left + 1;  
                           height =          bottom - top + 1;  
                           Real     rad =     (Real)((width > height)?(height>>2) :(width>>2));  
                        
                            // Scale for PolygonObject  
                           LONG     proj =     bd->GetProjection();  
                           Vector     a =          ScreenToWorld(ctr, bd, proj);  
                           Vector     b =          ScreenToWorld(Vector(ctr.x+rad*0.5, ctr.y, ctr.z), bd, proj);  
                           Real     rad2 =     2.0 * Len(b-a);  
                           if (proj == Pfrog)  
                           {  
                                m.v1 =               !m.v1 * rad2;  
                                m.v2 =               !m.v2 * rad2 * 0.333;  
                                m.v3 =               !m.v3 * rad2;  
                           }  
                           else  
                           {  
                                m.v1 =               !m.v1 * rad2;  
                                m.v2 =               !m.v2 * rad2;  
                                m.v3 =               !m.v3 * rad2;  
                           }  
                        
                      #ifdef C4D_R9  
                           bd->LineZOffset(32);  
                      #endif  
                           bd->SetTransparency(0);  
                           // 'Sphere'  
                           bd->SetPen(GetWorldContainer().GetVector(WPREF_SELECT_AXIS_COL));  
                           bd->Circle2D(ctr.x, ctr.y, rad);  
                           // 'Rings'  
                           // X-Axis  
                           ocp.color =          GetWorldContainer().GetVector(WPREF_XAXIS_COL);  
                           rotatObj->SetColorProperties(&ocp;);  
                           rotatObj->SetMg(m*zrotMat);  
                      #ifdef C4D_R9  
                           bd->DrawPolygonObject(bh, rotatObj, 0L);  
                      #else  
                           bd->PolygonObject(bh, rotatObj, 0L);  
                      #endif  
                           // Y-Axis  
                           ocp.color =          GetWorldContainer().GetVector(WPREF_YAXIS_COL);  
                           rotatObj->SetColorProperties(&ocp;);  
                           rotatObj->SetMg(m);  
                      #ifdef C4D_R9  
                           bd->DrawPolygonObject(bh, rotatObj, 0L);  
                      #else  
                           bd->PolygonObject(bh, rotatObj, 0L);  
                      #endif  
                           // Z-Axis  
                           ocp.color =          GetWorldContainer().GetVector(WPREF_ZAXIS_COL);  
                           rotatObj->SetColorProperties(&ocp;);  
                           rotatObj->SetMg(m*xrotMat);  
                      #ifdef C4D_R9  
                           bd->DrawPolygonObject(bh, rotatObj, 0L);  
                           bd->LineZOffset(0);  
                      #else  
                           bd->PolygonObject(bh, rotatObj, 0L);  
                      #endif  
                      }  
                      

                      For non-radial controls (translate/scale), rad2 = Len(b-a). This considers projection, camera, view, focus, zoom - so simple and you wonder why NOONE (especially the developers) can provide this for .... sake!!

                      Thank you, thank me...

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

                        THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

                        On 09/09/2006 at 18:04, xxxxxxxx wrote:

                        Slight modification to ScreenToWorld() and WorldToScreen() to support pre-R9.0 versions:

                        replace:

                             bd->GetViewParameter(&off;, &scale;, &scalez;);
                        

                        with:

                        #ifdef C4D_R9  
                             bd->GetViewParameter(&off;, &scale;, &scalez;);  
                        #else  
                             bd->GetParameter(&off;, &scale;, &scalez;);  
                        #endif
                        

                        More information on the polygon objects used for the control interface. I built the controls in C4D and exported as Wavefront so that the extents were 1x1x1 (the radius is 0.5). The polygon objects are cone (translate), cube (scale) and ring (rotate/twist). These were setup as Vector arrays for the points and LONG arrays for the polygons in a header (could be done with either reading/parsing the Wavefront .obj files or reading some other proprietary format). The objects are created/stored in the constructor and verified in the ToolData::Init() so that they must exist whenever the tool is activated.

                        zrotMat is a MatrixRotZ(Rad(90)) matrix
                        xrotMat is a MatrixRotX(Rad(-90)) matrix

                        These two matrices 'orthogonalize' the polygon objects to the particular local axis.

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