ZBrushCentral

Append a subtool

How do you append a subtool?

When I tried to record a macro this is the command lines it comes up with:

[IPress,Tool:SubTool:Append]
[IPress,PopUp:Xdiff]

When I try that I get this error:

Interface Item could not be found
Error: PopUp:Xdiff
IN: [IPress,PopUp:Xdiff

However when I run this one it works:

[IPress,Tool:SubTool:Append]
[IPress,PopUp:Gear3D]

Gear3D is one of the default available tools. However when I run it this way it renames the Gear3D to Gear3D1 and then [IPress,PopUp:Gear3D] no longer works but [IPress,PopUp:Gear3D1] does, until it renames it to Gear3D2.

I tried this:

[IPress,Tool:SubTool:Append]
    [IPress,PopUp:Gear3D]
    [SubToolSelect, 1]
    [FileNameSetNext,"Xdiff.OBJ"] 
    [IPress,Tool:Import]

Which works but only once as the Gear3D is then renamed to Gear3D1. Shouldn’t there be a simple way of appending a subtool? This is getting ridiculous for something so simple.

When I try this:

[IPress,Tool:SubTool:Duplicate]
    [IPress,Tool:SubTool:MoveDown]
    [FileNameSetNext,"Xdiff.OBJ"] 
    [IPress,Tool:Import]

It should work but I run into problems with the scale between the models.

Another note is when I run these:

[Note,[IExists,PopUp:Xdiff],,0]

Returns 0

[Note,[IExists,PopUp:Gear3D],,0]

Returns 0

[IPress,Tool:SubTool:Append]
[Note,[IExists,PopUp:Xdiff],,0]

Returns 0

[IPress,Tool:SubTool:Append]
[Note,[IExists,PopUp:Gear3D],,0]

Returns 1

I just need a simple append or an import that doesn’t screw up my scale.

Appending subtools can be tricky. ZBrush seems to need a specific path which is not always clear when you simply record a zscript. I provide a couple of scripts inthis thread that may interest you but below is a snippet of the relevant code. It starts off by using [IGetTitle] to record the name of the tool you want to append, then switches to the tool that it will be added to.

    
        //store the new OBJ tool name				
  	[VarSet,toolName,[IGetTitle,Tool:Current Tool,0]]	
  	//select the main OBJ ztool					
  	[ISet,Tool:ItemInfo,#toolID]
  	//append the new OBJ
  	[If,[IExists,Tool:SubTool:Append],
  		[IPress,Tool:SubTool:Append]			
  		[IPress,[StrMerge,"PopUp:",[Var,toolName]]]	
  	]	

I have a followup question to this.

I have a primitive object that I use in a lot of my projects and I often insert it into my tool as a subtool. I have it saved as an OBJ in some folder. What I want to do is make a macro that appends a primitive, then switches to that primitive subtool, and imports my OBJ to replace it. But it seems that every time I insert a primitive, its name in zBrush changes. So the first time you can insert say a Sphere3D, but from that point on it’s called Sphere3D1 in zBrush. Next time you insert it, it’ll be called Sphere3D2, etc, and this gives an error past the first time.

I ended up making this macro:


[VarDef,toolID,0]
[VarSet,toolID,[IGet,Tool:Item Info]]

[IPress,Tool:PolyMesh3D]
[FileNameSetNext,"C:\Users\John\SimpleCube.obj"]
[IPress,Tool:Import]
[VarSet,toolName,[IGetTitle,Tool:Current Tool,0]]

[ISet,Tool:Item Info,toolID]

[IPress,Tool:SubTool:Insert]
[IPress,[StrMerge,"PopUp:",[Var,toolName]]]
[IPress,Tool:SubTool:SelectDown]
]

What it does is avoid the situation by switching to the PolyMesh3D tool and then doing the import. This works fine, but the problem is that I have tons of copies of the SimpleCube in my tool palette.

Ultimately though I’d love it if it just loaded my SimpleCube as a primitive so I wouldn’t even need a macro. I could just hit Insert and it’ll be there. But a macro works just the same.

There are a couple of things you could try. You could append the PolyMesh3D to your subtool tool and then import your cube into that new subtool. Or you could save out the cube as a ZTL and then load that once before appending it. Next time the check would just select the cube rather than loading again. Either method would keep down the contents of the Tool palette.

[If,[IExists,Tool:SimpleCube],
//no need to load
,//else load
[FileNameSetNext,“SimpleCube.ztl”]
[IPress,Tool:Load Tool]
]

Thanks for that. The first option doesn’t work because as soon as you append the PolyMesh3D, the regular zBrush one then becomes PolyMesh3D1.

The second option sounds interesting. Would you please expand on the “Else load” line. I understand what it does, but I’m not that familiar with zBrush’s syntax yet.

Helpful script>> http://www.zbrushcentral.com/showthread.php?176896-How-to-clean-the-excess-3D-Meshes-in-the-tool-palette-Answered
Save a copy of your project first. :wink: You could just start a project with the Cube3d in it, in edit mode. Open that and go to town with your modeling. More on scripting can be found here.

The ‘else load’ line is just a comment after the comma that divides to two branches of the If statement. In my example the condition is whether the SimpleCube already exists in the Tool palette. If it does, then there’s no need to do anything so the ‘true’ branch is empty apart from the comment ‘no need to load’. If the SimpleCube doesn’t exist in the Tool palette then the condition is false. This branch contains the code to load the SimpleCube from disk. (I have simply put the file name for which the file would need to be in the same folder as the zscript. A full path to the file would work just as well.)

After the If statement has executed we’ll have the SimpleCube in the Tool palette, whether it was there to start with or not, and we can run code to do what we want with it.

HTH,

Thanks guys. Really helped me out a bunch!

Actually, that didn’t work. I ran into the same problem as before. The If Statement line will necessarily fail for the same reason:
[If,[IExists,Tool:SimpleCube],

That as soon as you Insert/Append a subtool, zBrush changes the name of the original tool with a number. So what I end up with is a bunch of tools called SimpleCube1, SimpleCube2, etc, and so the If statement never finds a tool called SimpleCube. If zBrush didn’t do that, then I could just use my original way of appending any primitive and importing my OBJ on top of that primitive. But there too, it changes the name of the primitive by adding a number at the end.

OK, this shows how you can get the name of the PolyMesh3D tool and then append it whatever it’s called.


[If,[IExists,Transform:Edit],//if a 3D tool is selected
    [If,[IGet,Transform:Edit],//if Edit is on
      [VarSet,toolID,[IGet,Tool:Item Info]]//get ID for current tool
      [If,toolID != 48,//if the tool isn't the Polymesh3D
        [ISet,Tool:Item Info,48]//select PolyMesh3D
        [VarSet,polyMeshName,[IGetTitle,Tool:Current Tool]]//get its name
        [ISet,Tool:Item Info,#toolID]//reselect current tool
        [IPress,Tool:SubTool:Append]//append
        [IPress,[StrMerge,"Popup:",#polyMeshName]]//append polymesh
        [SubToolSelect,[SubToolGetCount]-1]//select last subtool
        [FileNameSetNext,"SimpleCube.obj"]
        [IPress,Tool:Import]//import cube obj
      ]//end if
    ]//end if
  ]//end if

Awesome. That one seems to work just right. For some reason my Polymesh3D tool had an ID of 41, so I had to change that, but other than that it works just right. Tested it under all sorts of usual conditions and the ID seems to stay at 41.

Thanks man.

That’s interesting, anyway I’m glad it’s useful. :slight_smile: