How to resize an object?



  • 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..



  • 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();
    


  • 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



  • 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?



  • 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



  • 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.



  • 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



  • 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.



  • 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



  • 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 ;)



  • 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



  • 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!!



  • 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



  • 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 😂



  • 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


Log in to reply