How to make the whole model to bottom center with C++ API?

Hi, all:
Just described as the title, I wanna covert the coordinate’s original of the model to the model’s bottom center with no changing the direction of the axis. Are there any C++ APIs could to do this? Or a code segment is better.

Thanks in advance.

So you want to move the content of the model to be centered around the origin of the current working axes?

I don’t have a complete script at hand, but the gist of it would be:

  1. Get the root entities: SUModelGetEntities
  2. Get the bounding box of this entities collection: SUEntitiesGetBoundingBox
  3. Get the bottom center found of the bounding box. (Take the average of x and y from the min and max values, and the lowest of min and max).
  4. Create a transformation from that point to (0, 0, 0)
  5. Apply the transformation to all the entities in the SUEntitiesRef: SUEntitiesTransform

Hey, tt. Thanks for your instant reply, I have completed the first four steps. However, the last step with function SUEntitiesRef : SUEntitiesTransform, the in parameters as following:

[in] entities The entities object.
[in] len The number of entities in the array.
[in] elements The elements to be transformed.
[in] trans The transform to be applied.

I have got the root entities from the model, is there any way to get all entity from entities for the second and third parameters of SUEntitiesTransform?

Thank you again.

You can use SUEntitiesEntityListFill with the type SURefType_Entity to get an SUEntityListRef that you can use to iterate the entire collection. While iterating you use SUEntityListIteratorGetEntity to get and SUEntityRef object which you can add to the array you pass to SUEntitiesTransform.

… and then after filling, SUEntityListSize will give the len for the 2nd argument.

Thank you tt and Dan. I have finished the whole process and it works fine. The last question is about code optimization, I use the iterator of SUEntityListRef, but didn’t find how to judge the end of the iterator with the single line of code in loop for. And my workround way is as following:

for (SUEntityListBegin(list, &iterator); SUEntityListIteratorIsInRange(iterator, &in_range)==SU_ERROR_NONE; SUEntityListIteratorNext(iterator)) {
    		if (in_range != true) { break; }
    		entity = SU_INVALID;
    		SU_CALL(SUEntityListIteratorGetEntity(iterator, &entity));
    		SU_CALL(SUEntitiesTransform(entities, 1, &entity, &transform));

Is there a better method to find if the iterator is the end of the collection?

SUEntityListIteratorNext returns SU_ERROR_OUT_OF_RANGE when it reached the end of the collection.

This should work:

for (SUEntityListBegin(list, &iterator); SUEntityListIteratorNext(iterator) == SU_ERROR_NONE) {
  entity = SU_INVALID;
  SU_CALL(SUEntityListIteratorGetEntity(iterator, &entity));
  SU_CALL(SUEntitiesTransform(entities, 1, &entity, &transform));

That doesn’t capture SU_ERROR_INVALID_INPUT - but that shouldn’t happen if SUEntityListBegin succeeded.

1 Like

Appreciate for all, tt. All is well.