• MAXON Data Type and explicit constructors

    Cinema 4D SDK c++ r20 windows
    7
    0 Votes
    7 Posts
    2k Views
    M
    Thanks Riccardo! Now I understand - thanks to your side note. And of course I understand, that this goes hand in hand with your guidelines. Cheers, Robert
  • Deformer update and Fields

    Cinema 4D SDK c++ r20 windows macos
    2
    0 Votes
    2 Posts
    867 Views
    ValkaariV
    using the CheckDirty function seem to be the solution. void Spherify::CheckDirty(BaseObject* op, BaseDocument* doc) { if (falloff) { BaseContainer *data = op->GetDataInstance(); Int32 dirty = falloff->GetDirty(doc, data); if (dirty == lastFalloffDirtyCheck) return; op->SetDirty(DIRTYFLAGS::DATA); lastFalloffDirtyCheck = dirty; } } the full code for the spherify deformer : // deformer object example #include "c4d.h" #include "c4d_symbols.h" #include "main.h" #include "ospherifydeformer.h" #include "c4d_falloffdata.h" #define HANDLE_CNT 2 class Spherify : public ObjectData { public: virtual Bool Init(GeListNode* node); virtual Bool Message (GeListNode* node, Int32 type, void* data); virtual void GetDimension (BaseObject* op, Vector* mp, Vector* rad); virtual DRAWRESULT Draw (BaseObject* op, DRAWPASS type, BaseDraw* bd, BaseDrawHelp* bh); virtual void GetHandle (BaseObject* op, Int32 i, HandleInfo& info); virtual Int32 DetectHandle (BaseObject* op, BaseDraw* bd, Int32 x, Int32 y, QUALIFIER qualifier); virtual Bool MoveHandle (BaseObject* op, BaseObject* undo, const Vector& mouse_pos, Int32 hit_id, QUALIFIER qualifier, BaseDraw* bd); virtual Bool ModifyObject (BaseObject* op, BaseDocument* doc, BaseObject* mod, const Matrix& op_mg, const Matrix& mod_mg, Float lod, Int32 flags, BaseThread* thread); AutoAlloc<C4D_Falloff> falloff; Int32 lastFalloffDirtyCheck; virtual Int32 GetHandleCount(BaseObject *op); virtual void SetHandle(BaseObject *op, Int32 i, Vector p, const HandleInfo &info); virtual Bool CopyTo(NodeData *dest, GeListNode *snode, GeListNode *dnode, COPYFLAGS flags, AliasTrans *trn); virtual Bool GetDDescription(GeListNode *node, Description *description, DESCFLAGS_DESC &flags); virtual Bool AddToExecution(BaseObject *op, PriorityList *list); virtual EXECUTIONRESULT Execute(BaseObject *op, BaseDocument *doc, BaseThread *bt, Int32 priority, EXECUTIONFLAGS flags); virtual void CheckDirty(BaseObject* op, BaseDocument* doc); static NodeData* Alloc() { return NewObjClear(Spherify); } }; Int32 Spherify::GetHandleCount(BaseObject *op) { BaseContainer *bc = op->GetDataInstance(); if (!bc) return 0; if (falloff) return falloff->GetHandleCount(bc) + HANDLE_CNT; return 0; } void Spherify::SetHandle(BaseObject *op, Int32 i, Vector p, const HandleInfo &info) { BaseContainer *bc = op->GetDataInstance(); if (!bc) return; if (falloff) falloff->SetHandle(i, p, bc, info); } Bool Spherify::CopyTo(NodeData *dest, GeListNode *snode, GeListNode *dnode, COPYFLAGS flags, AliasTrans *trn) { Spherify *df = (Spherify*)dest; if (!df) return false; if (falloff && df->falloff) if (!falloff->CopyTo(df->falloff)) return false; return ObjectData::CopyTo(dest, snode, dnode, flags, trn); } Bool Spherify::GetDDescription(GeListNode *node, Description *description, DESCFLAGS_DESC &flags) { BaseObject *op = (BaseObject*)node; if (!op) return false; BaseContainer *data = op->GetDataInstance(); if (!data) return false; if (!description->LoadDescription(op->GetType())) return false; //--------------------------------- // Add the falloff interface if (falloff) { if (!falloff->SetMode(FIELDS, data)) // The falloff parameters have to have been setup before it can be added to the description, this like makes sure of that return false; if (!falloff->AddFalloffToDescription(description, data, DESCFLAGS_DESC::NONE)) return false; } flags |= DESCFLAGS_DESC::LOADED; return true; } void Spherify::CheckDirty(BaseObject* op, BaseDocument* doc) { if (falloff) { BaseContainer *data = op->GetDataInstance(); Int32 dirty = falloff->GetDirty(doc, data); if (dirty == lastFalloffDirtyCheck) return; op->SetDirty(DIRTYFLAGS::DATA); lastFalloffDirtyCheck = dirty; } } Bool Spherify::AddToExecution(BaseObject *op, PriorityList *list) { list->Add(op, EXECUTIONPRIORITY_INITIAL, EXECUTIONFLAGS::NONE); return TRUE; } EXECUTIONRESULT Spherify::Execute(BaseObject *op, BaseDocument *doc, BaseThread *bt, Int32 priority, EXECUTIONFLAGS flags) { BaseContainer *data = op->GetDataInstance(); if (!data) return EXECUTIONRESULT::USERBREAK; if (falloff) if (!falloff->InitFalloff(data, doc, op)) return EXECUTIONRESULT::OUTOFMEMORY; return EXECUTIONRESULT::OK; } Bool Spherify::Message(GeListNode* node, Int32 type, void* data) { if (type == MSG_MENUPREPARE) { ((BaseObject*)node)->SetDeformMode(true); } return true; } Bool Spherify::ModifyObject(BaseObject* mod, BaseDocument* doc, BaseObject* op, const Matrix& op_mg, const Matrix& mod_mg, Float lod, Int32 flags, BaseThread* thread) { BaseContainer* data = mod->GetDataInstance(); Vector p, *padr = nullptr; Matrix m, im; Int32 i, pcnt; Float rad = data->GetFloat(SPHERIFYDEFORMER_RADIUS), strength = data->GetFloat(SPHERIFYDEFORMER_STRENGTH); Float s; Float32* weight = nullptr; if (!op->IsInstanceOf(Opoint)) return true; padr = ToPoint(op)->GetPointW(); pcnt = ToPoint(op)->GetPointCount(); if (!pcnt) return true; FieldInput inputs(padr, pcnt, op_mg); Bool outputsOK = falloff->PreSample(doc, mod, inputs, FIELDSAMPLE_FLAG::VALUE); Float fallOffSampleValue(1.0); weight = ToPoint(op)->CalcVertexMap(mod); m = (~mod_mg) * op_mg; // op -> world -> modifier im = ~m; for (i = 0; i < pcnt; i++) { if (thread && !(i & 63) && thread->TestBreak()) break; p = m * padr[i]; s = strength; if (weight) s *= weight[i]; if (outputsOK) falloff->Sample(p, &fallOffSampleValue, true, 0.0, nullptr, i); s *= fallOffSampleValue; p = s * (!p * rad) + (1.0 - s) * p; padr[i] = im * p; } DeleteMem(weight); op->Message(MSG_UPDATE); return true; } void Spherify::GetDimension(BaseObject* op, Vector* mp, Vector* rad) { BaseContainer* data = op->GetDataInstance(); *mp = Vector(0.0); *rad = Vector(data->GetFloat(SPHERIFYDEFORMER_RADIUS)); } DRAWRESULT Spherify::Draw(BaseObject* op, DRAWPASS drawpass, BaseDraw* bd, BaseDrawHelp* bh) { if (!op->GetDeformMode()) return DRAWRESULT::SKIP; BaseContainer *bc = op->GetDataInstance(); if (!bc) return DRAWRESULT::FAILURE; if (falloff) falloff->Draw(bd, bh, drawpass, bc); if (drawpass == DRAWPASS::OBJECT) { BaseContainer* data = op->GetDataInstance(); Float rad = data->GetFloat(SPHERIFYDEFORMER_RADIUS); Matrix m = bh->GetMg(); m.sqmat *= rad; bd->SetMatrix_Matrix(nullptr, Matrix()); bd->SetPen(bd->GetObjectColor(bh, op)); bd->DrawCircle(m); maxon::Swap(m.sqmat.v2, m.sqmat.v3); bd->DrawCircle(m); maxon::Swap(m.sqmat.v1, m.sqmat.v3); bd->DrawCircle(m); } else if (drawpass == DRAWPASS::HANDLES) { Int32 i; Int32 hitid = op->GetHighlightHandle(bd); HandleInfo info; bd->SetPen(GetViewColor(VIEWCOLOR_ACTIVEPOINT)); bd->SetMatrix_Matrix(op, bh->GetMg()); for (i = 0; i < HANDLE_CNT; i++) { GetHandle(op, i, info); if (hitid == i) bd->SetPen(GetViewColor(VIEWCOLOR_SELECTION_PREVIEW)); else bd->SetPen(GetViewColor(VIEWCOLOR_ACTIVEPOINT)); bd->DrawHandle(info.position, DRAWHANDLE::BIG, 0); } GetHandle(op, 1, info); bd->SetPen(GetViewColor(VIEWCOLOR_ACTIVEPOINT)); bd->DrawLine(info.position, Vector(0.0), 0); } return DRAWRESULT::OK; } void Spherify::GetHandle(BaseObject* op, Int32 i, HandleInfo& info) { BaseContainer* data = op->GetDataInstance(); if (!data) return; if (falloff) falloff->GetHandle(i, data, info); switch (i) { case 0: info.position.x = data->GetFloat(SPHERIFYDEFORMER_RADIUS); info.direction.x = 1.0; info.type = HANDLECONSTRAINTTYPE::LINEAR; break; case 1: info.position.x = data->GetFloat(SPHERIFYDEFORMER_STRENGTH) * 1000.0; info.direction.x = 1.0; info.type = HANDLECONSTRAINTTYPE::LINEAR; break; default: break; } } Int32 Spherify::DetectHandle(BaseObject* op, BaseDraw* bd, Int32 x, Int32 y, QUALIFIER qualifier) { if (qualifier & QUALIFIER::CTRL) return NOTOK; HandleInfo info; Matrix mg = op->GetMg(); Int32 i, ret = NOTOK; Vector p; for (i = 0; i < HANDLE_CNT; i++) { GetHandle(op, i, info); if (bd->PointInRange(mg * info.position, x, y)) { ret = i; if (!(qualifier & QUALIFIER::SHIFT)) break; } } return ret; } Bool Spherify::MoveHandle(BaseObject* op, BaseObject* undo, const Vector& mouse_pos, Int32 hit_id, QUALIFIER qualifier, BaseDraw* bd) { BaseContainer* dst = op->GetDataInstance(); HandleInfo info; Float val = mouse_pos.x; GetHandle(op, hit_id, info); if (bd) { Matrix mg = op->GetUpMg() * undo->GetMl(); Vector pos = bd->ProjectPointOnLine(mg * info.position, mg.sqmat * info.direction, mouse_pos.x, mouse_pos.y); val = Dot(~mg * pos, info.direction); } switch (hit_id) { case 0: dst->SetFloat(SPHERIFYDEFORMER_RADIUS, ClampValue(val, 0.0_f, (Float) MAXRANGE)); break; case 1: dst->SetFloat(SPHERIFYDEFORMER_STRENGTH, Clamp01(val * 0.001)); break; default: break; } return true; } Bool Spherify::Init(GeListNode* node) { BaseObject* op = (BaseObject*)node; BaseContainer* data = op->GetDataInstance(); data->SetFloat(SPHERIFYDEFORMER_RADIUS, 200.0); data->SetFloat(SPHERIFYDEFORMER_STRENGTH, 0.5); if (falloff) { if (!falloff->InitFalloff(nullptr, nullptr, op)) return false; lastFalloffDirtyCheck = -1; } return true; } // be sure to use a unique ID obtained from www.plugincafe.com #define ID_SPHERIFYOBJECT 1001158 Bool RegisterSpherify() { return RegisterObjectPlugin(ID_SPHERIFYOBJECT, GeLoadString(IDS_SPHERIZE), OBJECT_MODIFIER | OBJECT_CALL_ADDEXECUTION, Spherify::Alloc, "Ospherifydeformer"_s, AutoBitmap("spherify.tif"_s), 0); }
  • SaveDocument() file name character limit?

    Cinema 4D SDK python windows r19
    3
    0 Votes
    3 Posts
    866 Views
    .
    Problem was with the total path length versus the file name length. 256 characters for the entire path and filename.
  • Seperators in GetSubContainer

    Cinema 4D SDK python windows r20
    2
    1
    0 Votes
    2 Posts
    543 Views
    M
    Hi @Boony2000 In a GetSubContainer, to insert a separator use InsData(0, "") The ID used should always be 0. As described in ShowPopupDialog Example. Which give us def GetSubContainer(self, doc, submenu) : menuItems = [["name1"], ["name2", "hasIcon"], ["name3"]] for i, data in enumerate(menuItems) : if len(data) > 1: submenu.SetString(i+1000, data[0] + "&i" + str(c4d.IDM_KEY_NEXT) + "&") submenu.InsData(0, "") else: submenu.SetString(i+1000, data[0]) return True Cheers, Maxime.
  • 0 Votes
    8 Posts
    2k Views
    CairynC
    Hi again; just to close off the topic here's what I ultimately found: A lot of the delay that causes the choppyness of the motion is apparently an issue with EventAdd(). I require this call to update the Attribute Manager for the current camera, and to start the recalculation of the interactive render region. But as it seems to refresh about everything, the call causes a noticeable delay before the next viewport refresh comes through. (It is surprising that this call takes longer than a redraw of the viewport, and it is very hard to time as EventAdd() just posts a message to the queue, so I cannot actually measure the execution duration.) The scene camera is slower than the viewport camera. CollieMouse treats both the same, in fact, all handling is done through a CameraObject that I get in a similar way as the one you posted above. Yet, the redraw is slightly slower by itself, and there are apparently things indirectly happening for a scene camera that take even more time (even when expressions are switched off). There is not much I can do about that except allow the user to suppress certain refreshs for the sake of a smoother Space Navigator experience. I'm still not sure what some of the DrawViews() flags exactly mean, by the way. I guess I can ignore the HIGHLIGHT ones for now, but what are INDRAG, INMOVE and FORCEFULLREDRAW really doing, and when do I need to use them? I see that you use INMOVE in your code (but not NO_EXPRESSIONS which surprises me).
  • 3D Mouse Slider Focus

    Cinema 4D SDK python windows r19 maxon api
    13
    1
    0 Votes
    13 Posts
    4k Views
    CairynC
    @charly CollieMouse rotates around the current selection or the explicit rotation center (the one you set with the INS shortcut). It will not rotate around the mouse pointer (I think... I implemented so many modes over time that I tend to forget the options...). The mouse pointer only exists in 2D space anyway so the actual rotation would happen around a projection of the mouse position into the scene, and if you move the mouse, the rotational center would change... not sure whether that is even a usable mode. The mode I'd recommend would be around the explicit center: Position the mouse, press INS (or whatever shortcut you use), and then use the 3D mouse to rotate around that. C4D shows the explicit center as green cross so you always know where it is. At the moment there is no R2023 version of CollieMouse anyway, so the point is moot. But you can reach me under cairyn (at) tigress (dot) com if you require specialty development.
  • Frame all

    Cinema 4D SDK c++ windows sdk
    5
    0 Votes
    5 Posts
    2k Views
    r_giganteR
    Hi WickedP, sorry for no bringing good news, but the architecture of the CommandData doesn't allow to "piggyback" off the "Frame All" command nor I've evidences of messages being sent around to have the "Frame All" to take place. The only, but maybe non-trivial, way to go is to write your own function based on the currently active rendering-camera in your "in-memory" document. Cheers, Riccardo
  • Adding icon to submenu

    Cinema 4D SDK python windows r20
    7
    1
    0 Votes
    7 Posts
    2k Views
    B
    Thanks, Maxime! I will use that in the meantime. Edit: Why can't I flag your posts as the correct answer? I can only flag my own.
  • Check if Cinema window is active

    Cinema 4D SDK python windows r20
    3
    0 Votes
    3 Posts
    768 Views
    B
    Ok, that's a shame. Would have been useful. Thanks anyway.
  • Blocking interaction like a modal dialog

    Cinema 4D SDK python r20 windows
    4
    0 Votes
    4 Posts
    1k Views
    B
    Just to follow up, what Maxime suggested worked perfectly. No more cheating, basically just c4d.StopAllThreads() dialogThread.Start() dialogThread.Wait(True)
  • 0 Votes
    3 Posts
    1k Views
    M
    @m_adam wow! I did what you say,it works!! you are so cool!! thank you very much!!! yeah!!
  • 0 Votes
    3 Posts
    976 Views
    A
    Amazing! Thank you again Andreas!
  • Clear LinkBox field

    Cinema 4D SDK python r19 windows
    3
    0 Votes
    3 Posts
    1k Views
    A
    Hi Andreas, Thank you very much! It works like a treat and I appreciate your thorough explanation! Happy Friday! Andre
  • Plugin crashes on Windows 10

    Cinema 4D SDK r19 c++ windows
    2
    0 Votes
    2 Posts
    811 Views
    a_blockA
    Hi Florian, sorry, to hear about this issue. To be honest, I can hardly believe that it's those parameters or sliders causing a crash on plugin registration. I'm more thinking of some memory maybe being trashed beforehand. But in the end, it doesn't matter so much, what I do believe or not or what I might suspect, we want to assist you in solving this riddle. As we have no evidence for issues in the described area, nor are we able to reproduce it via a simply example, I'd like to ask you for some more information. Could you maybe provide us with a stack trace, when the crash happened? Either from within Visual Studio or via the crash reporter (in the latter case, please notify me here, I need to look out for the report). I have turned this thread into a question. Cheers, Andreas
  • Project tool and non-cpp file extensions

    Cinema 4D SDK
    4
    0 Votes
    4 Posts
    1k Views
    S
    That's great, Andreas. Thanks! I'll kludge on until then.
  • Rotate selected polygons

    Cinema 4D SDK r20 python windows
    3
    0 Votes
    3 Posts
    886 Views
    P
    Hi Andreas, Ok, so I have to rotate the points to rotate a polygon. I thought so. That is why I assumed that when I can rotate points, I can rotate polygons. Thanks. Regards, Pim
  • Get rotation of animated object with python

    Cinema 4D SDK python windows
    2
    0 Votes
    2 Posts
    761 Views
    a_blockA
    Hi, don't be surprised, I have turned your thread into a question. The problem is, that the document will actually not be animated (or lets rather say, it will not be evaluated or executed) when calling SetTime(). Additionally you need to call ExecutePasses(). The BaseDocument manual in our C++ SDK documentation contains some extra information on this topic in the sections Time and Animate. Cheers, Andreas
  • 1 Votes
    5 Posts
    2k Views
    bnsB
    @m_adam thanks for R23.110 C4DPYTHONPATH37 !
  • Tell the HTML Viewer to ignore javascript

    Cinema 4D SDK c++ r20 windows
    5
    0 Votes
    5 Posts
    2k Views
    kbarK
    One last note. I just tried this on OSX and it works fine. So it is just an issue for Windows machines and whatever version of IE the widget is using.
  • 0 Votes
    3 Posts
    999 Views
    X
    @a_block No inconvenience at all, just happy to hear it's not only me!