Dialog Based Creation of Objects

The Interface::NonMouseCreate() method can be used to create a new object / node without going through the usual create mouse procedure sequence. This call must be made when the system is ready to create -- that is during execution of the system-provided default object creation process. To understand how this works consider the example of the Sphere object.

When the user selects sphere from the 3ds Max UI, an instance of the sphere is created in memory (but not in the scene) and its parameters can be edited in the roll-out panel. The sphere's user interface allows the user to type in a center position and radius value. When and then press a 'Create' button. When the button is pressed a new sphere in the scene will appear with these parameters. This is done through a call to Interface::NonMouseCreate() .

When the Interface::NonMouseCreate() method is called, 3ds Max checks if a sphere has been created but is not yet in the scene. If so it creates a copy of the object, places it in the scene by attaching it to a node, and immediately deletes the original object. If there is no sphere Interface::NonMouseCreate() will create an object and place into the scene immediately using the default parameters.

Note: When you call Interface::NonMouseCreate() from your plug-in object (assuming it is the one being created), it will be deleted immediately. You should return immediately and call no more methods, and access no fields on the object, since its "this" pointer is invalid.

The method Interface::NonMouseCreate() takes a single Matrix3 argument which is the transformation relative to the construction plane. In the code below, the translation part of this matrix is set to the values the user typed in for the X, Y, and Z location of the sphere.

The following code is from the file \samples\objects\sphere.cpp. This is the code that is executed if the user presses the 'Create' button in the 'Keyboard Entry' rollup page. This allows the user to type in the values for the sphere's position and radius using the keyboard and then create the object.

 
BOOL SphereTypeInDlgProc::DlgProc(
     TimeValue t,
     IParamMap *map,
     HWND hWnd,
     UINT msg,
     WPARAM wParam,
     LPARAM lParam)
{
   switch (msg)
   {
     case WM_COMMAND:
     switch (LOWORD(wParam))
     {
      case IDC_TI_CREATE:
       {
         // The user has pressed the create button...
         // If the radius is zero there is nothing to create
         // so just return.
         if (so->crtRadius==0.0) return TRUE;
 
         // We only want to set the value if the object is
         // not in the scene.
         if (so->TestAFlag(A_OBJ_CREATING)) {
           so->pblock->SetValue(PB_RADIUS,0,so->crtRadius);
         }
 
         // Create an identity matrix
         Matrix3 tm(1);
 
         // Update the translation portion of the matrix to the
         // creation position type-in parameter
         tm.SetTrans(so->crtPos);
 
         // Call the interface method to create the node...
         // This will use the values in the objects pblock.
         so->ip->NonMouseCreate(tm);
         so->suspendSnap = FALSE;
 
         // NOTE that calling NonMouseCreate() will create a copy
          // of this object and cause this object to be deleted.
          // DO NOT DO ANYTHING BUT RETURN.
         return TRUE;
       }
     }
     break;
   }
   return FALSE;
}