BaseObject Size & Scale



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 25/07/2012 at 05:12, xxxxxxxx wrote:

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

    ---------
    Hey,

    Is there a way to retrieve the size of an object instead of the scale vector?

    Scale will always give you a vector of 1,1,1 which i can't use. But i can't find the size vector anywhere in the BaseObject class. Does someone know where i can find the size vector?

    Thnx,
    ~Dynad



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 25/07/2012 at 05:23, xxxxxxxx wrote:

    Coffee or C++?



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 25/07/2012 at 05:32, xxxxxxxx wrote:

    c++



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 25/07/2012 at 06:05, xxxxxxxx wrote:

    I think the best way would be to retrieve the object's ObjectData() and call ObjectData::GetDimension().

    ObjectData* data = (ObjectData* ) op->GetNodeData();  
    if (!data) return FALSE;  
    Vector mid, xyz;  
    data->GetDimension(op, &mid, &xyz);
    

    But be aware. I've found this statement in the SDK today under Stability & Testing > Virtual function calls:

    Originally posted by xxxxxxxx

    This Virtual Function Call will crash:

    PluginVideoPost \*node;   for (node = renderdata->GetFirstVideoPost(); node; node=node->GetNext())   {     VideoPostData \*pVPData = (VideoPostData\*=)node->GetNodeData();     LONG info = pVPData->GetRenderInfo();   }

    • Beware of calling NodeData members!
    • pVPData can be NULL, check necessary
    • A plugin is not allowed to use the virtual function table of another plugin! This will only work with the same plugin, not over plugin boundaries

    To avoid crashes the call above must be replaced by:
    `  
      PluginVideoPost *node;
      for (node = renderdata->GetFirstVideoPost(); node; node=node->GetNext())
      {
        VideoPostData *pVPData = (VideoPostData*=)node->GetNodeData();
        if (!pVPData) continue;
      
        LONG info = ((pVPData->*((VIDEOPOSTPLUGIN* )C4DOS.Bl->RetrieveTableX(pVPData,0))->GetRenderInfo)(node);
      }

    I'd appreciate if someone from the official support could enlighten us if we need to use this method for the code above, too. And maybe also why a plugin isn't allowed to use another plugin's ObjectData?

    I'm using this method (directly calling the virtual function) in a plugin that is under development, currently, and I haven't recognized any crashes yet.

    Cheers,
    -Niklas

    PS: I think in the first code-example from the quoted documentation, the call to VideoPostData::GetRenderInfo() is missing the "node" argument.
    `



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 25/07/2012 at 07:07, xxxxxxxx wrote:

    I think you'd better call BaseObject::GetRad(). No need to invoke ObjectData::GetDimension().

    Niklas, I'll ask the developers if this information is still valid.



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 25/07/2012 at 07:25, xxxxxxxx wrote:

    @Yannick: Oh, I've obviously missed that method. :)
    Thank you! Maybe you want to append the piece of code I'm actually using:

    /** This function converts a hierarchy of BaseObjects into PolygonObjects  
      only. A list of VirtualObjectConnection's is created with the passed  
      allocation-function. Returns FALSE on error, TRUE on success.  
      
      :param origin: The object to start the conversion from.  
      :param hh: A HierarchyHelp instance is necessary which may be passed  
              through from GetVirtualObjects().  
      :param desthead: A reference to a pointer that will be filled with the  
              address of the head of the sequence.  
      :param desttail: A reference to a pointer that will be filled with the  
              address of the tail of the sequence.  
      :param destroot: A pointer to a pointer that will be filled with the  
              address to hierarchies top-most object, just as *op* but  
              polygonized.  
      :param allocator: A pointer to a function that will allocate memory  
              for the sequence of VirtualObjectConnection objects. **/  
    bool PolygonizeHierarchy(BaseObject* origin, HierarchyHelp* hh,  
                           VirtualObjectConnection*& desthead,  
                           VirtualObjectConnection*& desttail,  
                           BaseObject** destroot, AllocatorProc allocator);  
      
    /** .. **/  
      
    bool PolygonizeHierarchy(BaseObject* origin, HierarchyHelp* hh,  
                           VirtualObjectConnection*& desthead,  
                           VirtualObjectConnection*& desttail,  
                           BaseObject** destroot, AllocatorProc allocator) {  
      ROCKGEN_DEBUG_INFO("invoked");  
      
      // Ensure we can actually convert the object to geometry. Therefore, we  
      // have to check if the object is a generator, not a spline and when it  
      // is using it's input (OBJECT_INPUT flag) it must also be handled  
      // seperately.  
      LONG info = origin->GetInfo();  
      bool isgenerator = info & OBJECT_GENERATOR;  
      bool isspline    = info & OBJECT_ISSPLINE;  
      bool ispolygonal = info & OBJECT_POLYGONOBJECT;  
      
      // This flag is only set in connection with OBJECT_GENERATOR  
      bool isinput     = info & OBJECT_INPUT;  
      
      if (!(isgenerator && !isspline) && !ispolygonal) {  
          return TRUE;  
      }  
      
      // The reference to the new polygonized object is stored in this variable.  
      BaseObject* new_object;  
      
      // When the object is already a PolygonObject, we will create a copy of it.  
      if (ispolygonal) {  
          COPYFLAGS cloneflag = COPYFLAGS_NO_HIERARCHY | COPYFLAGS_NO_ANIMATION;  
          new_object = (BaseObject* ) origin->GetClone(cloneflag, NULL);  
          if (!new_object) return TRUE;  
      
          // The object may have been "touched" before and may also have some  
          // bit's that we don't want it to have. (E.g. BIT_ACTIVE will make  
          // the object being highlighted as it was selected, although it  
          // actually exists in the virtual-hierarchy of a Generator object).  
          new_object->SetAllBits(0);  
      }  
      
      // Now, as we have already excluded the object being a spline or not  
      // generator, we can safely obtain the internal ObjectData from the object  
      // an create it's virtual objects which will be converted recursively.  
      else {  
          ObjectData* data = (ObjectData* ) origin->GetNodeData();  
          new_object = data->GetVirtualObjects(origin, hh);  
      
          if (!new_object) return TRUE;  
          if (!new_object->IsInstanceOf(Opolygon)) {  
              // We have to create a temporary object, as after conversion,  
              // we will have to free the object we've obtained by  
              // ObjectData::GetVirtualObjects().  
              // Note that we don't check if the object could be a spline or  
              // similar, because this is done by the call to  
              // PolygonizeHierarchy(). Yes, yes. It's well thought out. :)  
              BaseObject* temp = NULL;  
              PolygonizeHierarchy(new_object, hh, desthead, desttail, &temp,  
                                  allocator);  
              // TODO: implement break-up when previous function-call returns FALSE.  
              BaseObject::Free(new_object);  
              new_object = temp;  
          }  
      }  
      
      // The object obtained from the call to PolygonizeHierarchy() after  
      // obtaining an object from the ObjectData could be NULL. ;)  
      if (new_object) {  
          // We will fill the value pointed by *destroot* with the current object  
          // when the pointer is not NULL. Afterwards, we will set it to be NULL  
          // so it's not overwritten by following calls to this function.  
          if (destroot) {  
              *destroot = new_object;  
              destroot  = NULL;  
          }  
      
          // Well, the virtual object doesn't actually have the same position  
          // as the original, so we need to adjust that.  
          new_object->SetMl(origin->GetMl());  
      
          // And now comes the tricky thing about generator objects that accept  
          // objects as input. If the object is an input generator, we will NOT  
          // go down it's actual hierarchy recursively, because they've been  
          // touched by the original generator.  
          if (!isinput) {  
              BaseObject* temp;  
              BaseObject* new_child;  
              for (temp=origin->GetDown(); temp; temp=temp->GetNext()) {  
                  new_child = NULL;  
                  PolygonizeHierarchy(temp, hh, desthead, desttail, &new_child,  
                                      allocator);  
                  // TODO: implement break-up when previous function-call returns FALSE.  
                  if (new_child) new_child->InsertUnder(new_object);  
              }  
          }  
      
          // Ok, we're almost done. The last thing we will need to do, is to  
          // establish the connection of the original object with the new, virtual  
          // object.  
          VirtualObjectConnection* new_connection = (VirtualObjectConnection* )  
                  allocator(sizeof(VirtualObjectConnection));  
          if (!new_connection) return FALSE;  
          if (!desttail) {  
              desttail = new_connection;  
          }  
          else {  
              desttail->next = new_connection;  
              desttail = desttail->next;  
          }  
          if (!desthead) desthead = desttail;  
          new_connection->origin  = origin;  
          new_connection->cache   = new_object;  
          new_connection->normals = NULL;  
          new_connection->seqinfo = NULL;  
      }  
      
      ROCKGEN_DEBUG_INFO("End with success.");  
      return TRUE;  
    }
    


  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 30/07/2012 at 11:25, xxxxxxxx wrote:

    @Yannick: Did you get an answer from the devs? :)

    Thanks,
    Nik



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 31/07/2012 at 01:25, xxxxxxxx wrote:

    BaseObject::GetRad() is the correct way to obtain an object's dimension. For object hierarchies you need iterate through the object tree.

    https://plugincafe.maxon.net/topic/6493/6983_null-object-dimensions

    cheers,
    Matthias



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 05/08/2012 at 10:05, xxxxxxxx wrote:

    Hello Yannick,

    Could you please tell me what the devs answer is?

    Ty, Nik



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 05/08/2012 at 12:15, xxxxxxxx wrote:

    Matthias is official support, so you can be quite sure it's the most straight-forward answer NiklasR. And it indeed is GetRad().



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 05/08/2012 at 12:31, xxxxxxxx wrote:

    Hello Samir,

    it's not about the GetRad() topic. See the previous posts:

    Originally posted by xxxxxxxx

    I'd appreciate if someone from the official support could enlighten us if we need to use this method for the code above, too. And maybe also why a plugin isn't allowed to use another plugin's ObjectData?

    Originally posted by xxxxxxxx

    Niklas, I'll ask the developers if this information is still valid.

    -Nik



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 05/08/2012 at 15:57, xxxxxxxx wrote:

    Originally posted by xxxxxxxx

    Originally posted by xxxxxxxx

    To avoid crashes the call above must be replaced by:

    PluginVideoPost *node;
    for (node = renderdata->GetFirstVideoPost(); node; node=node->GetNext())
    {
    VideoPostData *pVPData = (VideoPostData*=)node->GetNodeData();
    if (!pVPData) continue;

    LONG info = ((pVPData->*((VIDEOPOSTPLUGIN* )C4DOS.Bl->RetrieveTableX(pVPData,0))->GetRenderInfo)(node);
    }

    I'd appreciate if someone from the official support could enlighten us if we need to use this method for the code above, too. And maybe also why a plugin isn't allowed to use another plugin's ObjectData?

    The mentioned information is still correct as far as I know.

    You should be aware that Cinema is a multi-threaded application. So a pointer might be valid in one thread but not in another. For example the user is rendering into the editor and the plugin is modifying the scene at the same time. This might lead to crashes.

    cheers,
    Matthias



  • THE POST BELOW IS MORE THAN 5 YEARS OLD. RELATED SUPPORT INFORMATION MIGHT BE OUTDATED OR DEPRECATED

    On 06/08/2012 at 01:38, xxxxxxxx wrote:

    Thank you Matthias! Ok, so that is why we have to call RetrieveTable, etc..
    Unfortunately, it's a complicated line of code to remember. ;)

    -Niklas


Log in to reply