Esempio n. 1
0
  void UpdateGadgets(Bool relevants=false)
  {
    Int32 mode;
    Bool add_dynamics;
    GetBool(CHK_ADDDYNAMICS, add_dynamics);
    GetInt32(CMB_MODE, mode);

    BaseDocument* doc = GetActiveDocument();
    BaseObject* op = doc ? doc->GetActiveObject() : nullptr;

    Enable(EDT_MAXCONN, mode != CMB_MODE_CHAIN);
    Enable(EDT_RADIUS, mode != CMB_MODE_CHAIN);
    Enable(CHK_CLOSED, mode == CMB_MODE_CHAIN);
    Enable(CHK_COMPOUND, add_dynamics);

    // Need at least two child objects on the active object.
    Bool execEnabled = op != nullptr && op->GetDown() != nullptr
        && op->GetDown()->GetNext() != nullptr;
    Enable(BTN_EXECUTE, execEnabled);

    if (relevants)
    {
      FreeChildren(CMB_TYPE);

      Int32 pluginid;
      GetInt32(CMB_FORCE, pluginid);

      do {
        BaseObject* op = BaseObject::Alloc(pluginid);
        if (!op) break;
        AutoFree<BaseObject> free(op);

        AutoAlloc<Description> desc;
        if (!op->GetDescription(desc, DESCFLAGS_DESC_0)) break;

        BaseContainer temp;
        AutoAlloc<AtomArray> arr;
        const BaseContainer* param = desc->GetParameter(FORCE_TYPE, temp, arr);
        if (!param) break;

        const BaseContainer* cycle = param->GetContainerInstance(DESC_CYCLE);
        if (!cycle) break;

        const BaseContainer* icons = param->GetContainerInstance(DESC_CYCLEICONS);

        Int32 i = 0;
        Int32 last_id = -1;
        while (true) {
          Int32 id = cycle->GetIndexId(i++);
          if (id == NOTOK) break;

          Int32 icon = icons ? icons->GetInt32(id) : -1;

          String name = cycle->GetString(id);
          if (name.Content()) {
            if (icon > 0) name += "&i" + String::IntToString(icon);
            if (last_id < 0) last_id = id;
            AddChild(CMB_TYPE, id, name);
          }
        }

        SetInt32(CMB_TYPE, last_id);
      } while (0);

      LayoutChanged(CMB_TYPE);
    }
  }
Esempio n. 2
0
  Bool ExecuteAutoConnect()
  {
    ConnectOptions options;
    Bool addDynamicsTag = false, inheritDynamicsTag = true;
    GetInt32(CMB_FORCE, options.forcePluginId);
    GetInt32(CMB_TYPE, options.forceType);
    GetInt32(CMB_MODE, options.connectMode);
    GetInt32(EDT_MAXCONN, options.maxConnections);
    GetFloat(EDT_RADIUS, options.radius);
    GetBool(CHK_CLOSED, options.closedChain);
    GetBool(CHK_ADDDYNAMICS, addDynamicsTag);
    GetBool(CHK_COMPOUND, inheritDynamicsTag);

    // Create an InExcludeData for the selection object.
    GeData ge_selection(CUSTOMGUI_INEXCLUDE_LIST, DEFAULTVALUE);
    auto selectionList = static_cast<InExcludeData*>(
      ge_selection.GetCustomDataType(CUSTOMGUI_INEXCLUDE_LIST));
    if (!selectionList)
      return false;

    // Get the active document and object.
    BaseDocument* doc = GetActiveDocument();
    if (!doc)
      return false;
    BaseObject* op = doc->GetActiveObject();
    if (!op)
      return false;

    // Create the root object that will contain the connectors.
    AutoFree<BaseObject> root(BaseObject::Alloc(Onull));
    if (!root)
      return false;

    // Function to create a dynamics tag.
    auto fAddDynamicsTag = [doc] (BaseObject* op, Int32 mode)
    {
      // Create a dynamics tag for the root object if it
      // does not already exist.
      BaseTag* dyn = op->GetTag(ID_RIGIDBODY);
      if (!dyn)
      {
        dyn = op->MakeTag(ID_RIGIDBODY);
        if (dyn) doc->AddUndo(UNDOTYPE_NEW, dyn);
      }

      // Update the parameters.
      if (dyn)
      {
        dyn->SetParameter(RIGID_BODY_HIERARCHY, mode, DESCFLAGS_SET_0);
        doc->AddUndo(UNDOTYPE_CHANGE_SMALL, dyn);
      }
    };

    // This list will contain all objects that should be connected.
    // While collecting, create the dynamics tags.
    maxon::BaseArray<BaseObject*> objects;
    doc->StartUndo();
    for (BaseObject* child=op->GetDown(); child; child=child->GetNext())
    {
      objects.Append(child);
      if (addDynamicsTag && inheritDynamicsTag)
        fAddDynamicsTag(child, RIGID_BODY_HIERARCHY_COMPOUND);
    }
    if (addDynamicsTag && !inheritDynamicsTag)
      fAddDynamicsTag(op, RIGID_BODY_HIERARCHY_INHERIT);

    // If no objects where collected, quit already.
    if (objects.GetCount() <= 0)
    {
      doc->EndUndo();
      doc->DoUndo(false);
      return true;
    }

    // Create the connection objects.
    ConnectObjects(op->GetName() + ": ", objects, options);

    // Fill the selection list and insert the objects.
    for (auto it=options.output.Begin(); it != options.output.End(); ++it)
    {
      (*it)->InsertUnderLast(root);
      doc->AddUndo(UNDOTYPE_NEW, *it);
      selectionList->InsertObject(*it, 0);
    }

    root->SetName(op->GetName() + ": " + root->GetName() + " (" + options.forceName + ")");
    doc->InsertObject(root, nullptr, nullptr);
    doc->AddUndo(UNDOTYPE_NEW, root);

    // Create the selection object.
    if (selectionList->GetObjectCount() > 0)
    {
      BaseObject* selection = BaseObject::Alloc(Oselection);
      if (selection)
      {
        selection->SetParameter(SELECTIONOBJECT_LIST, ge_selection, DESCFLAGS_SET_0);
        selection->SetName(op->GetName() + ": " + options.forceName + " (" + selection->GetName() + ")");
        doc->InsertObject(selection, nullptr, nullptr);
        doc->AddUndo(UNDOTYPE_NEW, selection);
      }
      ActiveObjectManager_SetMode(ACTIVEOBJECTMODE_OBJECT, false);
      doc->SetActiveObject(selection);
    }
    else
      doc->SetActiveObject(root);

    root.Release();
    doc->EndUndo();
    EventAdd();
    return true;
  }