Maxon Developers Maxon Developers
    • Documentation
      • Cinema 4D Python API
      • Cinema 4D C++ API
      • Cineware API
      • ZBrush GoZ API
      • Code Examples on Github
    • Forum
    • Downloads
    • Support
      • Support Procedures
      • Registered Developer Program
      • Plugin IDs
      • Contact Us
    • Unread
    • Recent
    • Tags
    • Users
    • Login
    1. Maxon Developers Forum
    2. r_gigante
    3. Best
    • Profile
    • Following 0
    • Followers 3
    • Topics 15
    • Posts 636
    • Best 259
    • Controversial 0
    • Groups 0

    Best posts made by r_gigante

    • RE: Frame all

      Hi WickedP, thanks for reaching us.

      Can you please better explain the final intent of your request? Is the document displayed in viewport (which means it's the active document)? Or is it just a cloned document being hold in "memory"?

      That said, supposing that you've your document displayed in the editor, beside the option to invoke CallCommand, there's no built-in function or method to invoke, but rather, as already depicted by @fwilleke80 you can think of doing something like:

      for each object in all objects:
        get object bounding box center and radius
        evalute the bbox max and min and update the overall bbox
      
      reposition the editor camera target in the center of the overall bbox 
      
      for each overall bbox vertex:
        convert from world to screen space
        verify that's inside the frame of the editing camera 
        if not in frame:
         zoom out a little and recheck if vertex is now in frame
      
      posted in Cinema 4D SDK
      r_giganteR
      r_gigante
    • RE: MAXON Data Type and explicit constructors

      Hi mp5gosu, thanks for following up.

      I see your point, but actually you can still initialize the member variables to a "reasonable" default value helping to identify cases when the class was instantiated without any explicit value.

      A final, additional, side note about initialization: considering that constructors can't return any "evidence" of failure when allocating members we advise against initializing members directly in the constructor.
      We rather suggest implementing an additional Init() method where the members' initialization takes place as shown in the code snippet in the Entity Creation section.

      Best, Riccardo

      posted in Cinema 4D SDK
      r_giganteR
      r_gigante
    • RE: Beginner:How to assign A-material to B-cube by python?

      Hi Ilad, thanks for reaching out us.

      With regard to your request, I warmly recommend to have a look at Materials and Shaders Overview where the basic of Cinema 4D materials and shading handling are discussed. Consider that even if the documentation refers to C++ the described concepts can be applied to Python as well.

      Briefly the solution to your request is:

      def main():
          # get first object
          cubeA = doc.GetActiveObject()
          if cubeA is None: 
             return
         
          # get second object
          cubeB = op.GetNext()
          if cubeB is None:
              cubeB = op.GetPred()
          
          #get first material
          matA = doc.GetActiveMaterial()
          if matA is None: 
              return
          
          # get second material
          matB = matA.GetNext()
          if matB is None:
              matB = matA.GetPred()
          
          # create the texture tags for A and B
          ttagA = c4d.TextureTag()
          ttagB = c4d.TextureTag()
          
          # assign the swapped materials to the texture tags
          ttagA.SetMaterial(matB)
          ttagB.SetMaterial(matA)
          
          # insert the tags to the corresponding objects
          cubeA.InsertTag(ttagA)
          cubeB.InsertTag(ttagB)
          
          # queue an event
          c4d.EventAdd()
      

      Last but not least, it's recommended for future threads to use the appropriate category and mark it as "Ask as a question" upon creation.

      Best, Riccardo

      posted in Cinema 4D SDK
      r_giganteR
      r_gigante
    • RE: How to set project scale

      Hi Rage thanks for reaching us.

      With regard to your question, please consider that it was already discussed in the past in this thread.

      Long story short you can set the scene scale simply using

      def main():
          # check the current values for the currently active scene
          # for default scene it returns (1.0, 3) where scale is "1.0" and unit is "cm"
          print "current scale:", doc[c4d.DOCUMENT_DOCUNIT].GetUnitScale()
      
          # instantiate an UnitScaleData()
          sclData = c4d.UnitScaleData()
          # set the data accordingly to your needs
          # e.g. scale by 10x and set to mm units 
          sclData.SetUnitScale(10, c4d.DOCUMENT_UNIT_MM)
          # set the proper parameter in the active doc
          doc[c4d.DOCUMENT_DOCUNIT] = sclData
          # fire an EventAdd() 
          c4d.EventAdd()
      
          # check the new value
          print "new scale:", doc[c4d.DOCUMENT_DOCUNIT].GetUnitScale()
      

      Finally, to speed up your issues' resolution, I warmly encourage making use of the search function.

      Best, Riccardo

      posted in General Talk
      r_giganteR
      r_gigante
    • RE: VPBUFFER_OBJECTBUFFER is not rendered correctly

      Hi Petros, sorry for getting late here.

      I've tried to replicate the behavior you're reporting, but unfortunately I've succeeded in.
      The way i usually handle buffer fill-up in VPData is :

      ...
      VPBuffer* rgba = render->GetBuffer(VPBUFFER_RGBA, 0);
      Int32 rgbaBufferCPP = NOTOK, rgbaBufferDepth = NOTOK, rgbaBufferWidth = NOTOK, rgbaBufferHeight = NOTOK;
      if (rgba)
      {
          rgbaBufferCPP = rgba->GetInfo(VPGETINFO::CPP);
          rgbaBufferDepth = rgba->GetInfo(VPGETINFO::BITDEPTH);
          rgbaBufferWidth = rgba->GetInfo(VPGETINFO::XRESOLUTION);
          rgbaBufferHeight = rgba->GetInfo(VPGETINFO::YRESOLUTION);
          DiagnosticOutput("rgbaBuffer: @ / @ / @ / @", rgbaBufferCPP, rgbaBufferDepth, rgbaBufferWidth, rgbaBufferHeight);
          
          if (rgbaBufferDepth == 32)
          {
              iferr (rgbaBuffer = NewMemClear(Float32, rgbaBufferWidth * rgbaBufferCPP))
              {
                  CriticalOutput("Failed to allocate rgba 32-bit buffer");
                  return RENDERRESULT::OUTOFMEMORY;
              };
          }
          else
          {
              iferr (rgbaBuffer = NewMemClear(UChar, rgbaBufferWidth * rgbaBufferCPP))
              {
                  CriticalOutput("Failed to allocate rgba 8-bit buffer");
                  return RENDERRESULT::OUTOFMEMORY;
              };
          }
      }
      
      Float percent = 0.0;
      while (percent < 1.0)
      {
          for (Int32 i = 0; i < rgbaBufferHeight; i++)
          {
              if (rgbaBuffer)
              {
                  if (rgbaBufferDepth == 32)
                      r_gigante::FillBufferWithRandomValues((Float32*)rgbaBuffer, rgbaBufferWidth, rgbaBufferCPP);
                  else
                      r_gigante::FillBufferWithRandomValues((UChar*)rgbaBuffer, rgbaBufferWidth, rgbaBufferCPP);
              
                  rgba->SetLine(0, i, rgbaBufferWidth, rgbaBuffer, rgbaBufferDepth, true);
              }
              
              if (thread->TestBreak())
              {
                  if (rgbaBuffer)
                      DeleteMem(rgbaBuffer);
                  return RENDERRESULT::USERBREAK;
              }
          }
      } 
      ...
      

      where FillBufferWithRandomValues is

      void FillBufferWithRandomValues(Float32* buffer, UInt32 bufferSize, UInt32 channels/* = 4*/)
      {
      	Random rng;
      	rng.Init(UInt32(rand()));
      	if (channels == 4)
      	{
      		for (UInt32 i = 0; i < bufferSize; i++)
      		{
      			buffer[i * channels + 0] = Float32(rng.Get01());
      			buffer[i * channels + 1] = Float32(rng.Get01());
      			buffer[i * channels + 2] = Float32(rng.Get01());
      			buffer[i * channels + 3] = Float32(0);
      		}
      		return;
      	}
      	
      	if (channels == 3)
      	{
      		for (UInt32 i = 0; i < bufferSize; i++)
      		{
      			buffer[i * channels + 0] = Float32(rng.Get01());
      			buffer[i * channels + 1] = Float32(rng.Get01());
      			buffer[i * channels + 2] = Float32(rng.Get01());
      		}
      		return;
      	}
      	
      	if (channels == 1)
      	{
      		for (UInt32 i = 0; i < bufferSize; i++)
      		{
      			buffer[i * channels + 0] = Float32(rng.Get01());
      		}
      		return;
      	}
      }
      

      (NOTE - in my code the FillBufferWithRandomValues has definition for both 8-bit and 32-bit buffers)

      If you can provide with a complete example showing your issue, I'd be glad to look into, but being blind to your code I really can't be more helpful.
      With regard to the second question, I think the above code properly answers here.

      In case you got your issue fixed, please mark this thread as solved.

      Best, Riccardo

      posted in Cinema 4D SDK
      r_giganteR
      r_gigante
    • RE: Compute the Area of an Irregular Polygon?

      Hi Bentraje,

      with regard to computing the area of a non self-intersecting planar polygon you can use:

      # area of a polygon using 
      # shoelace formula 
        
      # (X[i], Y[i]) are coordinates of i'th point. 
      
      def polygonArea(X, Y, n): 
          # Initialze area 
          area = 0.0
      
          # Calculate value of shoelace formula 
          j = n - 1
          for i in range(0,n): 
              area += (X[j] + X[i]) * (Y[j] - Y[i]) 
              j = i   # j is previous vertex to i
          # Return absolute ;
          return int(abs(area / 2.0)) 
      

      Best, Riccardo

      posted in General Talk
      r_giganteR
      r_gigante
    • RE: MAXON_MODULE_ID undeclared identifier [R20 C++ plugin]

      Hi Andi, first of all no need to apologize at all. My work IS to be interrupted and to be as much as possible helpful to our developers! 😉

      In order to port/migrate/adapt code pre-R20 to R20, I kindly recommend to read the Plugin Migration section in our documentation where it's properly explained how make this transition happen.

      Do I have to create this file manually in all plugins folders?

      Yes, projectdefinition.txt should be created for both the project and solutions. The SDK shipped with Cinema has a few projectdefinition.txt files which clearly show where and what to write in.

      Do I have to run the project tool over these folders once the projectdefinition.txt file is there?

      Yes, the projecttool should be run on the whole folder that contains the sdk where both frameworks and plugins are located.
      The projecttool is indeed responsible to create both VisualStudio and Xcode project/solution files, so running once you get your IDE-required files properly created.

      But in our R 19 plugin folders these files are already existing. Would it be enough to put an additional projectdefinition.txt into these folders?

      My suggestion is to use a completely different folder for your R20 plugins and to structure it as follow:

      <plugins folder>
          |-<project a>
          |-<project b>
          |-<project x>
          |   |-project
          |   |   |- projectdefinition.txt
          |   |-source
          |       |-source_1.cpp
          |       |-source_2.cpp
          |       |-...
          |       |-source_n.cpp
      
      

      Then run the projecttool and you should be provided with all the needed files for VisualStudio.

      Let me know if something is still unclear or missing.

      Best, Riccardo

      posted in Cinema 4D SDK
      r_giganteR
      r_gigante
    • RE: Recent spam boom

      Hi guys, thanks for your comments on the topic. We do appreciate your effort in trying to keep this place tidy and clean.

      We've considered a few options and a better spam-prevention mechanism are now in place.

      Cheers, R

      posted in General Talk
      r_giganteR
      r_gigante
    • RE: Some suggestions about Python SDK

      Hi mike, first of all thanks for providing feedback on the Python API.

      1. GetPoint() isn't return accurate postion, just initial postion.please note or append another method(maybe already have?)

      PointObject::GetPoint() is indeed accurate and it's supposed to return the position of a point regardless of the affine transformation operated by the global transformation matrix belonging to the BaseObject the PointObject inherits from. This grant a proper design where linear motion-blur doens't require the points to effectively move in space.

      1. Matrix.mul(other) (matrix * matrix)
        ususlly computational order is 'left to right' , such as handwriting or Matlab, but here is 'right to left' ,could you make some changes?it is trouble to adapt.

      Matrix::Mul() actually is used to left multiply a vector by a matrix

          transformed_vector = transformation_matrix.mul(original_vector)
      

      To multiply matrices instead simply use the "*"operator

          matA = c4d.Matrix() 
          matA.v1 = c4d.Vector(3.0, 9.0, 27.0)
          matB = c4d.Matrix()
          matB.v3 = c4d.Vector(8.0, 4.0, 2.0)
          print matA * matB
          print matB * matA
      

      3.maybe c4d.utils.QSlerp(q1,q2,alfa) is 'spherical interpolation' and c4d.utils.QBlend(q1, q2, r) is 'Linear interpolates '?

      Yes, your guess it's right. c4d.utils.QSlerp is spherical interpolation for quaternions whilst c4d.utils.QBlend is the linear interpolation.

      Last but not least, please mark your initial post as "Ask as a question" from the Topic Tools menù, and if the answer provide is correct don't forget to set the answering post as "Mark this post as correct answer" from the three-vertical dots menu.

      Best, Riccardo

      posted in Cinema 4D SDK
      r_giganteR
      r_gigante
    • RE: debugging question

      Hi ello, first of all thanks for getting back with the code fragment.

      Analyzing the fragment provided I've ended up in a list of comments:

      • why the "Dependency List" approach is used twice in your code to check children dirty status?

      • why the "Dependency List" approach is used in combination with BaseObject::GetAndCheckHierarchyClone()? In the BaseObject Manual they are properly described and making them working in-cascade can actually lead to unexpected behaviors.

      • most of your code completely lacks pointer validity check; I warmly suggest to extend such a type of check to the whole code snippet to be user that unallocated pointer's methods are not called resulting in a message like "CINEMA 4D.exe hat einen Haltepunkt ausgelöst."

      • what does it mean when the debugger holds at a line like that,
        Vector rndoffset = bc->GetVector(RNDOFFSET);
        with a message "CINEMA 4D.exe hat einen Haltepunkt ausgelöst."

        it simply means that the bc pointer is likely to be invalid.

      Last but not least, considering that in the very net days I'll be pretty busy for the DevKitchen 2018 preparation[URL-REMOVED] I can't engage longer discussion or provide thoughtful answers, but back from the event I'll be eager to assist further. One last question: what is the intended delivered functionality of your ObjectData?

      Best, Riccardo


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

      posted in Cinema 4D SDK
      r_giganteR
      r_gigante
    • RE: Rendering deformed Spline with Hair material

      Hi Roger,

      sorry come coming with a little bit of delay here, but actually the question was not that easy to address.

      The "Deformers" flag enabled in the Advanced tab of Cinema Hair actually execute something like:

      • create a dummy spline for each hair based on the hair definition
      • deform the dummy spline by applying the modifier stack found under the hair object
      • use the deformed spline data to overwrite the hair primitive

      What is important to note is that in the end what is actually rendered is still an hair primitive and not the deformed spline.
      As additional note the hairs are not represented in the scene as real geometry that's why you can't find any evidence in the Active Object Dialog since the hair renderer is not handling with 3D data but delivers a representation of hair in 2.5D space where geometry is not needed.
      Finally the primitives which can be currently rendered are those satisfying the following expression (obj is the object being evaluated by the hair renderer)

      obj->GetType() == HAIR_STYLE_OBJECT_ID || 
      obj->IsInstanceOf(Opolygon) || 
      obj->IsInstanceOf(Ospline) || 
      obj->IsInstanceOf(Oline)) || 
      obj->IsInstanceOf(Oparticle) || 
      obj->GetType() == ID_TP_PARTICLEGEOMETRY
      

      That said since I see no reason to deny deformed splines to be rendered by the hair renderer, I'm going to file a bug report on this regard.

      Best, Riccardo

      posted in Cinema 4D SDK
      r_giganteR
      r_gigante
    • RE: Object Target Expression in Python

      Hi Tudor, thanks for following up.

      The issue you notice takes place when the temporary up-vector is aligned with the forward-vector: under this scenario the rVec is ambiguous and the whole system results unstable. The solution to the issue is represented by Quaternions or, alternatively you can try to mitigate the effect by putting in place some "work-around" like:

          ...
          uVec = fVec.Cross(rVec).GetNormalized()
      
          # try to mitigate Gimbal-lock
          if (fVec + tmpVec).z < 0:
              uVec.x = -uVec.x
      
          if abs(rVec.x - 1.0) < 0.001:
              rVec.x = -rVec.x
      
          # fill-up the transformation matrix
          ...
      

      Best, Riccardo

      edit: @ferdinand

      The approach shown here can be problematic. You instead should choose an up-vector which is not parallel or anti-parallel to the input vector. See Gimbal Lock Safe Target Expression for an example.

      posted in Cinema 4D SDK
      r_giganteR
      r_gigante
    • RE: Object Target Expression in Python

      Hi Tudor, with regard to using quaternions, I suggest to search around the web for it: there are hundreds of sites talking extensively about.
      I warmly suggest to have a look here where Gimbal lock is presented and some notes are spent on how to avoid it.

      Best, Riccardo

      posted in Cinema 4D SDK
      r_giganteR
      r_gigante
    • RE: Re-build plugin for R20 - missing file "delegate.h"

      Hi steve_r,

      porting pre-R20 plugins to R20 definitively requires to review the code and deliver the changes needed to make it nicely work with the new API structure and syntax.
      I warmly suggest to run through all of them and fix accordingly to what stated on the Plugin Migration section of the Cinema API C++ documentation.

      Last but not least, consider that a few of the issue might be due to code-style strictness level: in such case you can consider to lower the code-style strictness (see style-check) for an initial transition and concentrate on design issues.

      Best, Riccardo

      posted in Cinema 4D SDK
      r_giganteR
      r_gigante
    • RE: Objectdata and Bevel objects

      Hi Pim,

      with regard to your last question, it's worth to mention that although you can't interactively define selections, you can indeed deliver SelectionTags within your ObjectData.

      Best, Riccardo

      posted in Cinema 4D SDK
      r_giganteR
      r_gigante
    • RE: Current document in Team Render

      Hi Victor, thanks for reaching us.

      With regard to the issue mentioned, please provide me with some more detail about the context in which you're attempting to retrieve the document being rendered.
      Waiting for your additional details, please beware as pointed out in the Access section of the BaseDocument Manual that GetActiveDocument() just returns the document being displayed in the editor. In the context of TeamRender you definitively don't have to make use of it but depending on the context you're, you have to select a different option.

      Looking forward further info, give best.

      Riccardo

      posted in Cinema 4D SDK
      r_giganteR
      r_gigante
    • RE: Polygon selection order

      Hi Pim, thanks for reaching us.

      With regard to your question, I confirm that there's no option to get the order of the selected polygons nor the interaction tag can help in this direction.

      Best, Riccardo

      posted in Cinema 4D SDK
      r_giganteR
      r_gigante
    • RE: Sampling effect channel shaders

      Hi Roger, thanks for following up.

      With regard to "previewing" a Vertex Map in viewport you're not actually seeing the output generated by the VertexMap shader but the actual data belonging to VertexMap Tag where the VolumeData information is no needed at all.

      Finally, despite the naming similarity, VolumeBuilder, PointsToVolume and MeshToVolume have nothing to do with VolumeData.
      While the first three are indeed related to the new Volume-based modeling workflow introduced in R20, the latter, present in Cinema since time, has relevance in the context of rendering and is responsible for storing all the scene data information ready to be dispatched to a rendering engine.

      Best, Riccardo

      posted in Cinema 4D SDK
      r_giganteR
      r_gigante
    • RE: Spline notRealOffset to RealOffset

      Hi Rownn, thanks for reaching us.

      With regard to your question, as pointed out in our documentation you can move back and forth from percentage to unit offset by using:

      • SplineHelp::GetOffsetFromReal: given a certain curve percentage you'r provided with the offset;
      • SplineHelp::GetOffsetFromUnit: given a certain distance you're provided with the offset.

      A few observations now:

      • the curve parameter or "offset" as called in Cinema 4D, always ranges (on a specific segment) from 0 to 1.
      • depending on the curve parametrization, actually how "intermediate points" are generated the offset can be equal to the curve percentage: this happens only if the Uniform mode as been set.

      Let's see two simple cases:

      • given a certain curve with Intermediate Points generation set to Natural and an "arbitrary" distance of 400 units we obtain:
          splineLength: 849.075096635
          customLength: 400
          lengthRatio (customLength / splineLength): 0.471100850308
          GetOffsetFromReal(lengthRatio,0): 0.452809444459
          GetOffsetFromUnit(customLength,0): 0.452809444459
      
      • given the same curve with Intermediate Points generation set to Uniform and an "arbitrary" distance of 400 units we obtain:
          splineLength: 845.774079501
          customLength: 400
          lengthRatio (customLength / splineLength): 0.472939535148
          GetOffsetFromReal(lengthRatio,0): 0.472783546885
          GetOffsetFromUnit(customLength,0): 0.47278354688
      

      In the second case the ratio expressed by the arbitrary length and the overall curve length matches the offset which is completely correct considering the Uniform option

      Let me know if it helps to address your question or if there are further points to better discuss.

      Riccardo

      EDIT: I've fixed the naming convention the text snippets to make it more readable

      posted in Cinema 4D SDK
      r_giganteR
      r_gigante
    • RE: Sampling effect channel shaders

      Hi Roger,

      although I see your concern, in the current API there are no means to know beforehand if a certain shader requires a valid VolumeData instance to be passed within the ChannelData instance to deliver a "proper" sampling.
      Being the VolumeData pointer equal to nullptr in the ChannelData constructor, there's actually nothing back when the BaseShader::Sample() methods are invoked without a valid VolumeData being passed.

      Last but not least, also BaseShader::GetRenderInfo() isn't of any help in this case.

      Best, Riccardo

      posted in Cinema 4D SDK
      r_giganteR
      r_gigante