Advertisement
Guest User

Untitled

a guest
Sep 26th, 2016
208
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 6.83 KB | None | 0 0
  1. /////////////////////////////////////////////////////////////
  2. // CINEMA 4D SDK                                           //
  3. /////////////////////////////////////////////////////////////
  4. // (c) 1989-2013 MAXON Computer GmbH, all rights reserved  //
  5. /////////////////////////////////////////////////////////////
  6.  
  7. #include "main.h"
  8. #include "c4d.h"
  9. #include "c4d_snapdata.h"
  10.  
  11. ////////////////////////////////////////////////////////////////////////////////////
  12. // Simple point to point Move tool
  13. // topic covered in this example:
  14. // enable tool specific snap
  15. // use snap in GetCursorInfo() and MouseInput()
  16. // use snapflags
  17. // use snap result
  18. // use dynamic/inferred guide
  19. ////////////////////////////////////////////////////////////////////////////////////
  20.  
  21. #define ID_SNAPTOOL 1030693
  22.  
  23. class SnapTool : public DescriptionToolData
  24. {
  25. public:
  26.     SnapTool();
  27.     virtual ~SnapTool();
  28.  
  29.     virtual Int32                   GetToolPluginId() { return ID_SNAPTOOL; }
  30.     virtual const String    GetResourceSymbol() { return String("toolsnap"); }
  31.  
  32.     void                                    InitDefaultSettings(BaseDocument* doc, BaseContainer& data);
  33.     virtual Int32                   GetState(BaseDocument* doc);
  34.     virtual Bool                    MouseInput(BaseDocument* doc, BaseContainer& data, BaseDraw* bd, EditorWindow* win, const BaseContainer& msg);
  35.     virtual Bool                    GetCursorInfo(BaseDocument* doc, BaseContainer& data, BaseDraw* bd, Float x, Float y, BaseContainer& bc);
  36.     virtual void                    FreeTool(BaseDocument* doc, BaseContainer& data);
  37.  
  38. private:
  39.  
  40.     SnapCore* _snap;            // the snap object for this tool
  41. };
  42.  
  43. SnapTool::SnapTool()
  44. {
  45.     _snap = nullptr;
  46. }
  47.  
  48. SnapTool::~SnapTool()
  49. {
  50.     if (_snap)
  51.         SnapCore::Free(_snap);
  52.     _snap = nullptr;
  53. }
  54.  
  55. void SnapTool::InitDefaultSettings(BaseDocument* doc, BaseContainer& data)
  56. {
  57.     DescriptionToolData::InitDefaultSettings(doc, data);
  58.  
  59.     //Enable local snap settings for the tool
  60.     BaseContainer psnap;
  61.     psnap.SetBool(SNAP_SETTINGS_ENABLED, true);
  62.  
  63.     BaseContainer psnapFalse;
  64.     psnapFalse.SetBool(SNAP_SETTINGS_ENABLED, false);
  65.  
  66.     BaseContainer snap_settings;
  67.     snap_settings.SetBool(SNAP_SETTINGS_ENABLED, true);
  68.     snap_settings.SetFloat(SNAP_SETTINGS_RADIUS, 10.0);
  69.     snap_settings.SetContainer(SNAPMODE_POINT, psnap);
  70.     snap_settings.SetContainer(SNAPMODE_EDGE, psnapFalse);
  71.  
  72.     data.SetContainer(SNAP_SETTINGS, snap_settings);
  73. }
  74.  
  75. Int32   SnapTool::GetState(BaseDocument *doc)
  76. {
  77.     return CMD_ENABLED;
  78. }
  79.  
  80. Bool    SnapTool::GetCursorInfo(BaseDocument* doc, BaseContainer& data, BaseDraw* bd, Float x, Float y, BaseContainer& bc)
  81. {
  82.     if (bc.GetId() == BFM_CURSORINFO_REMOVE)
  83.         return true;
  84.  
  85.     // allocate snap if necessary
  86.     if (!_snap)
  87.     {
  88.         _snap = SnapCore::Alloc();
  89.         if (!_snap)
  90.             return false;
  91.     }
  92.  
  93.     // initialize snap always
  94.     if (!_snap->Init(doc, bd))
  95.         return false;
  96.  
  97.     // just use snap in get GetCursorInfo if you need realtime snap drawing or if you need to snap at single click like in guide tool or knife tool
  98.     Vector          startPos = bd->SW(Vector(x, y, 500));
  99.     SnapResult  snapResul = SnapResult();
  100.  
  101.     _snap->Snap(startPos, snapResul, SNAPFLAGS_0);
  102.     // in case of single click tool you can use the filled SnapResult to update realtime preview
  103.     return true;
  104. }
  105.  
  106. Bool SnapTool::MouseInput(BaseDocument* doc, BaseContainer& data, BaseDraw* bd, EditorWindow* win, const BaseContainer& msg)
  107. {
  108.     BaseObject*     op = nullptr;
  109.     BaseContainer bc;
  110.     BaseContainer device;
  111.     Int32                   button;
  112.     Float                   dx, dy;
  113.     Float                   mouseX = msg.GetFloat(BFM_INPUT_X);
  114.     Float                   mouseY = msg.GetFloat(BFM_INPUT_Y);
  115.  
  116.     SnapResult      snapResul = SnapResult();
  117.     Vector              startPos = bd->SW(Vector(mouseX, mouseY, 500));
  118.     Vector              destPos;
  119.     Vector              deltaPos;
  120.  
  121.     Matrix              guideMatrix = Matrix();
  122.  
  123.     AutoAlloc<AtomArray>vecList;
  124.     if (!vecList)
  125.         return false;
  126.  
  127.     switch (msg.GetInt32(BFM_INPUT_CHANNEL))
  128.     {
  129.         case BFM_INPUT_MOUSELEFT : button = KEY_MLEFT; break;
  130.         case BFM_INPUT_MOUSERIGHT: button = KEY_MRIGHT; break;
  131.         default: return true;
  132.     }
  133.  
  134.     AutoAlloc<AtomArray>opList;
  135.     if (!opList)
  136.         return false;
  137.  
  138.     doc->GetActiveObjects(*opList, GETACTIVEOBJECTFLAGS_CHILDREN);
  139.     if (opList->GetCount() <= 0)
  140.         return true;
  141.  
  142.     maxon::BaseArray<Vector> oldPos;
  143.     maxon::BaseArray<Vector> oldPosPoints;
  144.  
  145.     for (Int32 i = 0; i < opList->GetCount(); ++i)
  146.     {
  147.         op = (BaseObject*)opList->GetIndex(i);
  148.         if (op)
  149.             oldPos.Append(op->GetAbsPos());
  150.         doc->AddUndo(UNDOTYPE_CHANGE, op);
  151.     }
  152.  
  153.     // allocate snap if necessary
  154.     if (!_snap)
  155.     {
  156.         _snap = SnapCore::Alloc();
  157.         if (!_snap)
  158.             goto Error;
  159.     }
  160.  
  161.     // initialize snap always
  162.     if (!_snap->Init(doc, bd))
  163.             goto Error;
  164.  
  165.     // if snap modify initial position do not pass SNAPFLAGS_IGNORE_SELECTED otherwise selected object will be not evaluated
  166.     if (_snap->Snap(startPos, snapResul, SNAPFLAGS_0) && snapResul.snapmode != NOTOK)
  167.         startPos = snapResul.mat.off;
  168.  
  169.     // use snap matrix for inferred guide to use the correct orientation
  170.     if (snapResul.snapmode != NOTOK)
  171.         guideMatrix = snapResul.mat;
  172.     else
  173.         guideMatrix.off = startPos;
  174.  
  175.     // add an inferred guide to start point this show its effect only if dynamic guide snap is on
  176.     _snap->AddInferred(doc, guideMatrix, INFERRED_GUIDE_POINT);
  177.  
  178.     win->MouseDragStart(button, mouseX, mouseY, MOUSEDRAGFLAGS_DONTHIDEMOUSE | MOUSEDRAGFLAGS_NOMOVE);
  179.     while (win->MouseDrag(&dx, &dy, &device) == MOUSEDRAGRESULT_CONTINUE)
  180.     {
  181.         if (dx == 0.0 && dy == 0.0)
  182.             continue;
  183.  
  184.         mouseX += dx;
  185.         mouseY += dy;
  186.         snapResul = SnapResult();
  187.         destPos = bd->SW(Vector(mouseX, mouseY, bd->WS(startPos).z));
  188.  
  189.         // if snap modify initial position here pass SNAPFLAGS_IGNORE_SELECTED to avoid self snapping
  190.         // IMPORTANT : call SnapCore:Update() before snap if geometry is changed during MouseDrag
  191.         if (_snap->Snap(destPos, snapResul, SNAPFLAGS_IGNORE_SELECTED) && snapResul.snapmode != NOTOK)
  192.         {
  193.             PointObject*    pobj = ToPoint(op);
  194.             BaseSelect* bs = pobj->GetPointS();
  195.  
  196.  
  197.             const Vector* pts = pobj->GetPointR();
  198.             Vector* points = pobj->GetPointW();
  199.             Int32 seg = 0, a, b, i;
  200.             while (bs->GetRange(seg++, LIMIT<Int32>::MAX, &a, &b))
  201.             {
  202.                 for (i = a; i <= b; ++i)
  203.                 {
  204.                     GePrint(String::VectorToString(snapResul.mat.off));
  205.                     destPos.x = snapResul.mat.off.x;
  206.                     destPos.y = pts[i].y;
  207.                     destPos.z = pts[i].z;
  208.  
  209.                     points[i] = destPos;
  210.                     op->Message(MSG_UPDATE);
  211.                 }
  212.             }
  213.  
  214.             DrawViews(DRAWFLAGS_ONLY_ACTIVE_VIEW | DRAWFLAGS_NO_THREAD | DRAWFLAGS_NO_ANIMATION);
  215.         }
  216.        
  217.     }
  218.  
  219.     if (win->MouseDragEnd() == MOUSEDRAGRESULT_ESCAPE)
  220.         doc->DoUndo();
  221.  
  222.     // flush dynamc guides to clean the screen
  223.     _snap->FlushInferred();
  224.  
  225.     opList->Flush();
  226.     EventAdd();
  227.     return true;
  228. Error:
  229.    
  230.     opList->Flush();
  231.     return false;
  232. }
  233.  
  234. void SnapTool::FreeTool(BaseDocument* doc, BaseContainer& data)
  235. {
  236.     if (_snap)
  237.         SnapCore::Free(_snap);
  238.     _snap = nullptr;
  239. }
  240.  
  241. Bool RegisterSnapTool()
  242. {
  243.     return RegisterToolPlugin(ID_SNAPTOOL, "Axis Constraint Tool", 0, nullptr, "Axis Constraint Tool", NewObjClear(SnapTool));
  244. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement