addChild with Tubes

Scripting
2016-12-30
2016-12-31
  • Nathan Ryan

    Nathan Ryan - 2016-12-30

    I'm trying to rewrite the Hairy script as a Tool so I can use a dialog. First, is there a string widget I can use to prompt for the name of the object you want the hair to grow on? Second, after the hairs (tubes) are created, I want to add them as children under the hairy object - as if you manually dragged them in the objects window and dropped them on the object. How do I get the object info for the Tubes?

    I tried this:
    info.addChild(hair,0); where info is the objectInfo for the hairy object and hair is a tube object. It's in a loop so all the tubes have the same name.

    and get this error:
    No signature of method: artofillusion.object.ObjectInfo.addChild() is applicable for argument types: (artofillusion.object.Tube, java.lang.Integer)

    info = scene.getObject(basemeshname);
    //....//
    hair = new Tube(v, (float []) [1.0f, 1.0f, 1.0f, 1.0f], ( double [])
    [thickness, thickness, thickness, 0.0], Tube.APPROXIMATING, Tube.OPEN_ENDS);
    window.addObject(hair, info.getCoords(), "hair", null);

      info.addChild(hair,0);
    
     
    Last edit: Nathan Ryan 2016-12-30
  • Nathan Ryan

    Nathan Ryan - 2016-12-30

    I found the BTextField for the first question. So no longer need that.

     
  • Luke S

    Luke S - 2016-12-30

    To understand the error, you need to look at the methods and constructor for ObjectInfo In particular, you need to create an ObjectInfo to add as a child, rather than just passing the tube. The signature breaks down like this:

    hairobject = new ObjectInfo(Object3d obj, //<-this is your tube
                   CoordinateSystem coords, //<-Position and rotation of tube
                   String name) //<-"hair"
    

    You can then call info.addChild(hairobject).

    For a dialog, you can check some of the existing tools for inspiration. The extrude dialog has examples of most of what you will require. To select an object, you want to use a BComboBox from the buoy library. EDIT: you do not want a BTextField for this, that would be for free-form text. For selecting an existing object, the ComboBox is better.

    The Extrude dialog actually uses two combo boxes: one for objects that can be extruded, and one for the paths that they can be extruded along. Your object sorting loop will be much simpler.

    • Lines 50-64 are how it creates the two separate lists.
    • Lines 74 and 93 are where the lists are used to create a combo box.

    A lot of the in-between stuff is related to laying out a dialog so that its easy to navigate. Again, yours is probably going to be much simpler, but you still need to set up the dialog:

    • If you are doing this in a script, you don't want to try to subclass BDialog, rather you will do something like:
    BDialog HairyDialog = new BDialog(layoutWindow, "Apply Hair", true);
    
    // create any object lists, since not all objects can have hair applied
    
    FormContainer content = new FormContainer(2, 4); //tweak for your layout
    
    /* continue building layout in `content` - as much as you need to.
    *If you want a live preview of the result, see the Extrude Dialog
    *for how that is embeded */
    
    HairyDialog.setContent(content);
    HairyDialog.pack();
    HairyDialog.UIUtilities.centerDialog(this, window);
    HairyDialog.updateComponents();
    HairyDialog.setVisible(true);
    
    • Make sure that you review the buttons, lines 128 - 131. They set up a call to another small method that actually adds the object to the scene when you are satisfied with it.
    • The buoy API docs have details on how the various dialog pieces fit together.

    If you have other questions, please let us know!

     
    Last edit: Luke S 2016-12-30
  • Nathan Ryan

    Nathan Ryan - 2016-12-30

    I think I've got the Dialog set up ok. Thanks Luke. But I'm still having trouble getting the coordinate system for the tube hair.

     
  • Nathan Ryan

    Nathan Ryan - 2016-12-30

    Also, where is the extrude dialog?

     
  • Luke S

    Luke S - 2016-12-30

    Perhaps I explained that a little backwards... Lets start with what you have. I'm assuming you have the following:

    • a Tube object in the correct shape (diameters, curve, etc)
    • a position and rotation where the tube should be placed in relation to the 'hairy' object.

    Then a CoordinateSystem is coords = new CoordinateSystem(Position, rot.x, rot.y, rot.z)

    And adding the hair to the scene is info.addChild(new ObjectInfo(Tube, coords, "hair");

    If any of the above assumptions are inccorect, let me know, and we'll work from there.

     
  • Nathan Ryan

    Nathan Ryan - 2016-12-30
      // Create the hair.
      hair = new Tube(v, (float []) [1.0f, 1.0f, 1.0f, 1.0f], (double [])
       [thickness, thickness,  thickness, 0.0], Tube.APPROXIMATING, Tube.OPEN_ENDS);
      window.addObject(hair, info.getCoords(), "hair", null);
    
            hairObject = new ObjectInfo(hair, info.getCoords(), "hair")
            info.addChild(hairObject,0);
    

    Here's the code. I create the vector v and then create the tube from that without explicitly creating a curve object. info is the hairy object.

    The next 2 lines don't do anything that I can tell. No errors though.

    I'm attaching the entire script

     
  • Luke S

    Luke S - 2016-12-31

    Okay, I see what is happening. Your window.addObject(hair, info.getCoords(), "hair", null); is implicitly creating an objectinfo for the scene, and then you are creating a second objectinfo for the same object the next line down. (This creates a live duplicate of each hair.)

    Instead, you want:

      hair = new Tube(v, (float []) [1.0f, 1.0f, 1.0f, 1.0f], (double [])
       [thickness, thickness,  thickness, 0.0], Tube.APPROXIMATING, Tube.OPEN_ENDS);
    
            hairObject = new ObjectInfo(hair, info.getCoords(), "hair")
            window.addObject(hairObject, null);        
            info.addChild(hairObject,0);
            }
    }     
            window.rebuildItemList(); // tells the window that we are done playing, and it should update all of its lists, etc.
    

    You probably also want to be able to undo the changes made by the script. You will want to call undo = new UndoRecord(window, false); before the begining of the loop, and window.setUndoRecord(undo); after the end of it.

     
  • Peter Eastman

    Peter Eastman - 2016-12-31

    You will want to call undo = new UndoRecord(window, false); before the begining of the loop, and window.setUndoRecord(undo); after the end of it.

    And pass that UndoRecord as the second argument to window.addObject().

     
  • Nathan Ryan

    Nathan Ryan - 2016-12-31

    Fantastic! That did it. Thanks so much. The undo was a nice touch as well.

     
    Last edit: Nathan Ryan 2016-12-31

Log in to post a comment.

Get latest updates about Open Source Projects, Conferences and News.

Sign up for the SourceForge newsletter:





No, thanks