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

    How to resize an object?

    SDK Help
    0
    15
    1.3k
    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
      Helper
      last edited by

      On 08/01/2014 at 20:43, xxxxxxxx wrote:

      User Information:
      Cinema 4D Version:   13,14,15 
      Platform:   Windows  ;   
      Language(s) :     C++  ;

      ---------
      I want to resize an object, so that it's bounding box corresponds to another object's bounding box.

                 Vector vA = o_A->GetRad();
                 Vector vB = o_B->GetRad();
                  
                  Real scaleX = vA.x / vB.x;
                  Real scaleY = vA.y / vB.y;
                  Real scaleZ = vA.z / vB.z;
                  
                  o_B->SetRelScale(Vector(scaleX, scaleY, scaleZ));
        
      
      

      I assumed this would be one of the simplest tasks to carry out, but no.
      When I manually scale an object in Cinema 4D, the scale remains 1 regardless. So I think that scaling is not the proper way to do this. Or is it?
      So - this somehow works, but I would like to achieve the same programmatically, as when doing it directly in the C4D designer. And there scale is always 1 and remains 1. Is there a document setting?
      BTW, there is no SetRad() function. I am clueless..

      Edited:
      I see that when using "Object Mode" in C4D, scaling changes. When using "Modeling Mode", it does not. So doing the same with my C++ code, as when using the mouse in "Modeling mode", is probably what I am after.. I say "probably" because I am not sure what drawbacks the off value 1 scaling can lead to..

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

        On 09/01/2014 at 04:58, xxxxxxxx wrote:

        GetRad() returns the bounding box (half-width).  You cannot change that value as it is calculated internally based on scale and object dimensions.

        When in modeling mode, scale changes would affect the selected polygons, edges, points.

        Also, you might need to consider any scaling already on the object:

        o_B->SetRelScale(o_B->GetRelScale() * Vector(scaleX, scaleY, scaleZ));
        

        Don't forget to call these to have the object and document updated:

        o_B->Message(MSG_CHANGE);  
        EventAdd();
        
        1 Reply Last reply Reply Quote 0
        • H
          Helper
          last edited by

          On 09/01/2014 at 07:26, xxxxxxxx wrote:

          Howdy,

          Remember that in Modeling Mode the Scale tool only changes the size of the object's geometry, but in Object Mode the Scale tool changes the scale of the object's matrix (thereby changing the size of the geometry, too).

          So the question is do you want to change the size of the geometry only or change the scale of the matrix, too?

          Adios,
          Cactus Dan

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

            On 09/01/2014 at 12:23, xxxxxxxx wrote:

            Originally posted by xxxxxxxx

            Howdy,
            So the question is do you want to change the size of the geometry only

            Yes. And so far I don't see how to do it.

            @Robert
            Important point!! I took it for granted that the scale of the other object is 1.
            About the Message and CHANGE, will doc->AddUndo(..) do the same?

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

              On 09/01/2014 at 13:09, xxxxxxxx wrote:

              Howdy,

              Originally posted by xxxxxxxx

              Yes. And so far I don't see how to do it.

              You scale the geometry's vertices. 😉

              Adios,
              Cactus Dan

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

                On 09/01/2014 at 13:25, xxxxxxxx wrote:

                I have no idea how to scale the vertices.. if you could give me a hint Dan, I would appreciate it!
                Here is an update, and a piece of code that does what I want, with one exception, it does scale the object in question, which I don't want.

                    void ResizeToModel(GeListNode* node, BaseObject* model, BaseObject* victim)
                    {
                        BaseDocument* doc = node->GetDocument();
                        if(doc && model && victim)
                        {
                            Vector vModel = model->GetRad();
                            Vector vVictim = victim->GetRad();
                            
                            Real scaleX = (vModel.x / vVictim.x) * model->GetRelScale().x;
                            Real scaleY = (vModel.y / vVictim.y) * model->GetRelScale().y;
                            Real scaleZ = (vModel.z / vVictim.z) * model->GetRelScale().z;
                            
                            doc->StartUndo();
                  	    doc->AddUndo(UNDOTYPE_CHANGE_SMALL, victim);
                            victim->SetAbsScale(Vector(scaleX, scaleY, scaleZ));
                            doc->EndUndo();
                        }
                    }
                

                In hindsight.. maybe I should use victim->SetRelScale(..) ??

                Edited:
                Ok, this code is not perfect, I am currently experimenting and trying to improve it.

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

                  On 10/01/2014 at 01:15, xxxxxxxx wrote:

                  To scale the vertices move them in object space. E.g. to double the size, if a vertex has X=100, move it so that X=200. Repeat with Y & Z, and iterate through all vertices in the object. At the end, your object has twice the size but the same scale in its matrix.

                  Steve

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

                    On 10/01/2014 at 01:49, xxxxxxxx wrote:

                    Originally posted by xxxxxxxx

                    To scale the vertices move them in object space.

                    Thanks Steve! I will try to find out how to get hold of the vertices, and then how to move them in object space.
                    I started another thread here in this forum yesterday, where I wish for a library / collection of common functions for moving / resizing / measuring objects in 3D space.

                    As it is now, we plugin writers probably sit around in our own caves, building up such libraries. Each of us.. One library pr. developer..
                    In other words - wrapping up the C4D SDK API in common functions with readable understandable English names, functions we use all the time.

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

                      On 10/01/2014 at 07:11, xxxxxxxx wrote:

                      Originally posted by xxxxxxxx

                      I will try to find out how to get hold of the vertices, and then how to move them in object space.

                      Do it like this:

                      Vector *padr = ToPoint(object)->GetPointW(); // get the object's points array
                      LONG i, cnt = ToPoint(object)->GetPointCount(); // get the object's point count
                        
                      // loop through the points and scale them
                      for(i=0; i<cnt; i++)
                      {
                           padr[i].x = padr[i].x * scale.x;
                           padr[i].y = padr[i].y * scale.y;
                           padr[i].z = padr[i].z * scale.z;
                      }
                      

                      Adios,
                      Cactus Dan

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

                        On 10/01/2014 at 15:57, xxxxxxxx wrote:

                        Howdy Dan 😉
                        Super Duper!!!
                        By combining your post, with the one of Robert, I made it work. At first, nothing happened, then I saw Robert had added the message end event stuff, now it is magic, it works!!

                            	Vector* padr = ToPoint(cubeA)->GetPointW(); // get the object's points array
                            	LONG i, cnt = ToPoint(cubeA)->GetPointCount(); // get the object's point count
                            	
                            	Vector scale = Vector(0.5);
                                // loop through the points and scale them
                            	for(i = 0; i < cnt; i++)
                            	{
                            		padr[i].x = padr[i].x * scale.x;
                            		padr[i].y = padr[i].y * scale.y;
                            		padr[i].z = padr[i].z * scale.z;
                            	}
                                cubeA->Message(MSG_CHANGE);
                                EventAdd();
                        

                        I have to add though, why scaling a point works, is beyond my  comprehension.. I just have to accept that is works. If there was a function:

                        BaseArray<Vertice*> padr = ToPoint(cubeA)->GetVerticeW(); 
                        

                        I could have understood it. Ok, it is me, I just have to understand not only how, but why things work..
                        Greetings from cold Norway and a warm programmer's cave 😉

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

                          On 11/01/2014 at 10:27, xxxxxxxx wrote:

                          You're not scaling a point, it's a misnomer. What you're doing is changing the vertex position relative to the object axis. The effect is to make the object look bigger (or smaller) but the scale of the object remains the same.

                          That's why I said you have to move the points in object space. If you step through Dan's code for the eight points of a cube, you'll see what I mean.

                          Steve

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

                            On 11/01/2014 at 11:14, xxxxxxxx wrote:

                            Hi Steve, yes I thought about it since my last post, and understand it now. The words move, transfer, translate, shift etc. instead of scale would have made it more understandable for me I suppose.
                            It is my fault, mixing "scale" and "move", since you wrote "move".
                            In any case, it works very well!!

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

                              On 11/01/2014 at 11:26, xxxxxxxx wrote:

                              Howdy,

                              The thing to remember is that there is a distinct difference between size and scale. Think of it as when you were 6 years old, your size was small but your scale was 1. At your current age, your size is larger but your scale is still 1. 😉

                              Adios,
                              Cactus Dan

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

                                On 11/01/2014 at 12:30, xxxxxxxx wrote:

                                Originally posted by xxxxxxxx

                                Think of it as when you were 6 years old, your size was small but your scale was 1. At your current age, your size is larger but your scale is still 1. 😉

                                Howdy!
                                A good comparison, indeed.
                                Although, when it comes to the local politicians here, I am not sure about to what extent that rule of scaling applies 😂

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

                                  On 11/01/2014 at 12:34, xxxxxxxx wrote:

                                  Howdy,

                                  Yes indeed. Politicians everywhere always think their scale is bigger than 1. 😂

                                  Adios,
                                  Cactus Dan

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