• Baking MoGraph color animation to keyframes.

    Cinema 4D SDK python r20
    6
    0 Votes
    6 Posts
    2k Views
    ManuelM
    hi, I will mark that thread as resolved tomorrow if you don't have anything to add Cheers, Manuel
  • ParallelFor: TestBreak()

    Cinema 4D SDK c++ r20 r21
    7
    0 Votes
    7 Posts
    681 Views
    ManuelM
    hi, as @PluginStudent said i was using GeGetEscTestThread and by the way, it's not really working But that's the same question with your code. You test the thread that have been provided to you or your own thread. For that you pass that thread as a reference to the lambda function. Cheers, Manuel
  • ParallelFor vs. ParallelImage

    Cinema 4D SDK c++ r20 sdk macos
    6
    0 Votes
    6 Posts
    648 Views
    fwilleke80F
    Thanks a lot! That helps Cheers, Frank
  • Setting the width of a treeview column

    Cinema 4D SDK r20 python
    3
    1
    0 Votes
    3 Posts
    502 Views
    ManuelM
    hello, that's because you set the width of your columns to more that what it show. But you can simply passed that argument when you add your customGUI settings.SetBool(c4d.TREEVIEW_RESIZE_HEADER, False) In the c++ doc you have that page and in python this one Cheers, Manuel
  • I cannot get multiple polygons from GetNearestPolygon

    Cinema 4D SDK r20 c++
    6
    0 Votes
    6 Posts
    635 Views
    ManuelM
    hello, I've lookied into the live selection tool and internally it's using GetPixelInfoPolygon, or the equivalent for point and edges. You also have Get<xxx>PixelBuffer where <xxx> is Point, Edge or Polygon. That return the internal buffer constructed inside the Init function of the ViewportSelect Class. pixelBuffer[ width*y + x] will give you the right pixel on that buffer. Sorry to have missed those functions. Cheers, Manuel
  • 0 Votes
    4 Posts
    508 Views
    fwilleke80F
    Oh man, it really was the missing message. Never thought it would have such weird consequences to forget that. Thanks guys!
  • GetSplinePointSegment Offset

    Cinema 4D SDK r20 c++ sdk
    8
    0 Votes
    8 Posts
    1k Views
    r_giganteR
    Hi @JohnThomas thanks for the follow-up. I see the point, but when you're dealing with uniform splines you've also to consider the number of intermediate points you're using to approximate the natural spline. With a natural parametrization even with a low number of points the vertexes position returned from SplineHelp::GetPosition() are accurate, whilst with a uniform parametrization you get higher accuracy as long as you increase the number of points. See the data below, where first coordinate is the position returned by the SplineHelp::GetPosition and the second coordinate is returned by quering the points vector PointsObject::GetPointR() Natural_4 [4, 2123.461, BEZIER, 1] 0 [0/0], 0.000[0.000] --> (200.000,0.000,0.000) -- (200.000,0.000,0.000) 1 [17/0], 0.250[530.865] --> (0.000,700.000,0.000) -- (0.000,700.000,0.000) 2 [34/0], 0.500[1061.731] --> (-200.000,0.000,0.000) -- (-200.000,0.000,0.000) 3 [51/0], 0.750[1592.596] --> (0.000,-200.000,0.000) -- (0.000,-200.000,0.000) Uniform_4 [4, 2107.332, BEZIER, 2] 0 [0/0], 0.000[0.000] --> (200.000,0.000,0.000) -- (200.000,0.000,0.000) 1 [7/0], 0.350[737.566] --> (4.370,699.695,0.000) --> (0.000,700.000,0.000) 2 [14/0], 0.700[1475.132] --> (-199.849,8.692,0.000) -- (-200.000,0.000,0.000) 3 [17/0], 0.850[1791.232] --> (-4.394,-199.953,0.000) -- (0.000,-200.000,0.000) Uniform_16 [4, 2107.332, BEZIER, 2] 0 [0/0], 0.000[0.000] --> (200.000,0.000,0.000) -- (200.000,0.000,0.000) 1 [7/0], 0.350[737.566] --> (4.370,699.695,0.000) -- (0.000,700.000,0.000) 2 [14/0], 0.700[1475.132] --> (-199.849,8.692,0.000) -- (-200.000,0.000,0.000) 3 [17/0], 0.850[1791.232] --> (-4.394,-199.953,0.000) -- (0.000,-200.000,0.000) Uniform_128 [4, 2124.555, BEZIER, 2] 0 [0/0], 0.000[0.000] --> (200.000,0.000,0.000) -- (200.000,0.000,0.000) 1 [182/0], 0.353[749.359] --> (-1.373,699.970,0.000) -- (0.000,700.000,0.000) 2 [363/0], 0.703[1494.600] --> (-199.996,1.279,0.000) -- (-200.000,0.000,0.000) 3 [440/0], 0.853[1811.636] --> (1.380,-199.995,0.000) -- (0.000,-200.000,0.000) If no further help is needed please don't forget to set the thread as Solved. Cheers, R
  • Custom Errors

    Cinema 4D SDK r20 c++
    13
    0 Votes
    13 Posts
    2k Views
    r_giganteR
    Hi @tdapper thanks for reaching out us. With regard to your comment, although I confirm that you don't have to put them in a separate framework but it's actually recommended to grant good design and straightforward reusability. For the sake of clarity, find below the files used to create a project which includes both the declaration and the implementation of the custom error together with the code using it. The example is derived from the code presented on GitHub. project/projectdefinition.txt // Supported platforms - can be [Win64;OSX] Platform=Win64;OSX // Type of project - can be [Lib;DLL;App] Type=DLL // API dependencies APIS=cinema.framework;mesh_misc.framework;math.framework;crypt.framework;python.framework;core.framework; // C4D component C4D=true stylecheck.level=3 // must be set after c4d=true stylecheck.enum-registration=false stylecheck.enum-class=false ModuleId=net.maxonexample.support.single_plugins.PC12316 source/PC12316_CustomErrorImpl.cpp #include "PC12316_CustomErrorInterface.h" // This example shows the implementation of a custom error type. class PC12316_CustomErrorImpl : public maxon::Component<PC12316_CustomErrorImpl, PC12316_CustomErrorInterface> { // use ErrorObjectClass to implement basic error functionality MAXON_COMPONENT(NORMAL, maxon::ErrorObjectClass); public: maxon::Result<void> CopyFrom(const PC12316_CustomErrorImpl& src) { _errorCode = src._errorCode; return maxon::OK; } public: MAXON_METHOD maxon::String GetMessage() const { return FormatString("Custom error code is @", _errorCode); } // custom methods MAXON_METHOD void SetCustomErrorCode(maxon::Int errorCode) { _errorCode = errorCode; } MAXON_METHOD maxon::Int GetCustomErrorCode() const { return _errorCode; } private: maxon::Int _errorCode; ///< error code value }; // register all the non-static methods in the implementation MAXON_COMPONENT_OBJECT_REGISTER(PC12316_CustomErrorImpl, PC12316_CustomErrorObject); source/PC12316_CustomErrorInterface.h #ifndef PC12316_CUSTOMERRORINTERFACE_H__ #define PC12316_CUSTOMERRORINTERFACE_H__ #include "maxon/object.h" // This example shows the declaration of a custom error type. // The custom error is able to store a custom error code. // --------------------------------------------------------------------- // Custom error class that stores an error code. // --------------------------------------------------------------------- class PC12316_CustomErrorInterface : MAXON_INTERFACE_BASES(maxon::ErrorInterface) { MAXON_INTERFACE(PC12316_CustomErrorInterface, MAXON_REFERENCE_COPY_ON_WRITE, "net.maxonexample.example.errors.PC12316_customerror"); public: MAXON_ADD_TO_COPY_ON_WRITE_REFERENCE_CLASS( void Create(MAXON_SOURCE_LOCATION_DECLARATION, maxon::Int errorCode) { #if API_VERSION >= 20000 && API_VERSION < 21000 * static_cast<typename S::DirectlyReferencedType::ReferenceClassHelper::type*>(this) = S::DirectlyReferencedType::ReferenceClassHelper::object::GetInstance() (); #elif API_VERSION >= 21000 *static_cast<typename S::DirectlyReferencedType::Hxx1::ReferenceClass*>(this) = S::DirectlyReferencedType::Hxx1::ErrObj::GetInstance()(); #endif typename S::DirectlyReferencedType::Ptr e = this->MakeWritable(false).GetPointer(); e.SetLocation(MAXON_SOURCE_LOCATION_FORWARD); e.SetCustomErrorCode(errorCode); } ); // custom methods // --------------------------------------------------------------------- // Stores an custom error code. // --------------------------------------------------------------------- MAXON_METHOD void SetCustomErrorCode(maxon::Int errorCode); // --------------------------------------------------------------------- // Returns the stored custom error code. // --------------------------------------------------------------------- MAXON_METHOD maxon::Int GetCustomErrorCode() const; }; #include "PC12316_CustomErrorInterface1.hxx" #include "PC12316_CustomErrorInterface2.hxx" #endif /* PC12316_CUSTOMERRORINTERFACE_H__ */ source/PC12316.cpp #include "c4d.h" static const Int32 PluginID = 99912316; #include "PC12316_CustomErrorInterface.h" // Dummy test function maxon::Result<void> TestFunction(maxon::Int * val); maxon::Result<void> TestFunction(maxon::Int * val) { iferr_scope; if (!val) return PC12316_CustomError(MAXON_SOURCE_LOCATION, 4242); ApplicationOutput("Value is @", *val); return maxon::OK; } // Command to test the custom error class CustomErrorExample : public CommandData { public: #if API_VERSION >= 20000 && API_VERSION < 21000 Bool Execute(BaseDocument* doc) #elif API_VERSION >= 21000 Bool Execute(BaseDocument* doc, GeDialog* parentManager) #endif { iferr_scope_handler { return false; }; if (!doc) return false; iferr (TestFunction(nullptr)) ApplicationOutput("Error: @", err); maxon::Int a = 100; iferr (TestFunction(&a)) ApplicationOutput("Error: @", err); return true; } static CommandData* Alloc() { return NewObj(CustomErrorExample) iferr_ignore("Unexpected failure on allocating CustomErrorExample plugin."_s); } }; Bool RegisterCustomErrorExample(); Bool RegisterCustomErrorExample() { return RegisterCommandPlugin(PluginID, "PC12316_CustomErrorExample"_s, PLUGINFLAG_COMMAND_OPTION_DIALOG, nullptr, ""_s, CustomErrorExample::Alloc()); } Bool PluginStart() { if (!RegisterCustomErrorExample()) return false; return true; } void PluginEnd() { } Bool PluginMessage(Int32 id, void* data) { return true; } A final minor note on register=true: since R21 it's not needed anymore because in former releases it was needed to specify when a module was supposed to run in pure legacy-mode but nowadays modules can be either hybrid (classic + maxon API) or maxon API-only. Hoping this makes using our Error Handling system more clear and easy to integrate in your products, give best and don't hesitate to ask for more. Best, R
  • Best plugin type for background (thread) processing?

    Cinema 4D SDK r20 python
    16
    0 Votes
    16 Posts
    3k Views
    M
    Since this topic is older than a week I marked is as closed, but feel free to reopen it if you have further questions. Cheers, Maxime
  • Exporting Polygonized scene

    Cinema 4D SDK python r20
    8
    0 Votes
    8 Posts
    892 Views
    R
    You're welcome, Manuel. Actually, I usually prepare all the textures and mapping to be in UVW mapping, when texturing is required. But, mainly, what I need is exporting geometry that is animated.
  • Loading BaseBitmap from memory

    Cinema 4D SDK r20 python
    5
    0 Votes
    5 Posts
    564 Views
    P
    Thanks, I understand. I am now going to do it outside DrawMsg in parallel (thread) plugin. See my other post. https://developers.maxon.net/forum/topic/12310/best-plugin-type-for-background-thread-processing -Pim
  • Connect + Delete groups iteratively

    Cinema 4D SDK python r20
    5
    0 Votes
    5 Posts
    1k Views
    ManuelM
    hello, I'will consider this thread as solved tomorrow if you have nothing to add Cheers, Manuel
  • FieldList.GetCount Bug

    Moved Cinema 4D SDK r21 r20 r19 python
    2
    0 Votes
    2 Posts
    574 Views
    M
    Hi @pyr, I've just reached the development team about it. So for them, this is not a bug since FieldList store only baseLink. In Python, we don't have BaseLink, but if you are not aware of what it is, please read BaseLink Manual. But since there is no BaseLink in Python, if a link points to a destructed object (like in your case, Python simply returns None) So I guess your workaround is ok. Cheers, Maxime
  • BaseShader global vs local filename

    Cinema 4D SDK c++ r19 r20 r21
    6
    0 Votes
    6 Posts
    658 Views
    kbarK
    @C4DS That was the most normal happy smiling glad you solved your issue emoji I could find. Any of the others could definitely have been interpreted in many ways. Hope that one came across alright
  • 0 Votes
    6 Posts
    654 Views
    r_giganteR
    Hi @C4DS , maybe I wasn't enough clear. you end up with a single merged object, which has 2 selection tags, and both still have the specific name ... but none have the added unique ID. Surely you start to think something is really wrong. Actually you end up in a new mesh with new selection tags which beside having the data copied from the two source selection tags, they are NEW and hence the UniqueID is not supposed to be kept. The names are kept for convenience but I don't see any reason to have also the UniqueID being kept considering that - in the end - they are indeed new instances and have nothing to do with the source selection tags. Cheers, R
  • Changing font size.

    Cinema 4D SDK python r20
    4
    0 Votes
    4 Posts
    566 Views
    P
    Great example, thank you. -Pim
  • Trigger on BaseShader change

    Cinema 4D SDK r19 r20 r21 c++
    4
    0 Votes
    4 Posts
    558 Views
    C4DSC
    @m_magalhaes Thanks for reminding me of the GeDialog::CoreMessage. I totally overlooked that.
  • Python Volume access

    Moved Cinema 4D SDK r20
    6
    0 Votes
    6 Posts
    1k Views
    rsodreR
    @m_adam got it! it's working now. The final code for my float sdf exporter is here.
  • 0 Votes
    11 Posts
    2k Views
    r_giganteR
    Well @pyxelrigger thanks for clarifying the final scope. Since, as already stated, folding or unfolding a scene entry doesn't generate any valuable message to be intercepted, the sole - brute force - hack you might try to implement in Python would be to implement a MessageData plugin which constantly checks for the folded/unfolded state of the entries in the scene and eventually delete the unfolded one. This approach carries strong performances penalties to the whole Cinema 4D UI because you need to constantly traverse the scene and depending on the scene size this could strongly affect Cinema performances. If there are no further question please mark the thread as solved. Best, R
  • BaseLink from cloned document

    Cinema 4D SDK r19 r20 r21 c++
    11
    0 Votes
    11 Posts
    2k Views
    P
    There is no relationship between BaseContainer IDs and plugin IDs. All you need is a unique ID, that you can use as a BaseContainer ID. This forum (the plugin ID page) provides such IDs.