Select all materials in model
Select all materials in model
I want a script that selects all materials in a model, learning the SDK don't know how to set this up.
- xsisupport
- Posts: 713
- Joined: 09 Jun 2009, 11:02
- Location: Montreal Canada
- Contact:
Re: Select all materials in model
A model supports the Model interface, so you should go to the Model reference page and look through the properties and methods. You'll find your answer there.
Re: Select all materials in model
ActiveProject.SceneItem.Material
SceneItem.Material.
Atleast I hope I'm on the right path ?
The language syntax I'm grasping, putting it together, arghh.
SceneItem.Material.
Atleast I hope I'm on the right path ?
The language syntax I'm grasping, putting it together, arghh.
- xsisupport
- Posts: 713
- Joined: 09 Jun 2009, 11:02
- Location: Montreal Canada
- Contact:
Re: Select all materials in model
You want to find all materials on a model. Those would return a single material.
On the Model reference page, there are two possibilities that jump out: Materials and FindObjects.
On the Model reference page, there are two possibilities that jump out: Materials and FindObjects.
- Hirazi Blue
- Administrator
- Posts: 5107
- Joined: 04 Jun 2009, 12:15
Re: Select all materials in model
I fully understand this would be a weird way to approach the problem ("don't try this at home"), but couldn't you just iterate all materials and use the "UsedBy" property to figure out if a material is used by your specific model?
Stay safe, sane & healthy!
Re: Select all materials in model
To learn scripting, i wouldn´t try to make so "simple" things.
I haven´t much experience in scripting but i can say how i would make it in C++.
First of all, i would write a recursive function which can call itself like this:
Then i get the children under the model with GetChildren() as an CRef array:
The next step is to go through the array and generate a X3DObject:
Then i would check, if the new obj is also a model and if yes, the function call itself:
When the obj is a mesh or a surface, i would save the materials in another CRefArray.
The next step is to store new materials to a CRefArray which should be a parameter in the function to transport it from call to call.
Now i think the function is complete.
The last step is to call the function with:
After the call, the matArray will hold the CRefs of each material.
Haven´t test it and it´s possible that there are some errors. It´s only to show how it can work.
Hope this helps a little bit...
face
I haven´t much experience in scripting but i can say how i would make it in C++.
First of all, i would write a recursive function which can call itself like this:
Code: Select all
bool findChildren( Model inModel ) {
return true;
}
Code: Select all
bool findChildren( Model inModel ) {
CRefArray cRefs( inModel.GetChildren() );
return true;
}
Code: Select all
bool findChildren( Model inModel ) {
CRefArray cRefs( inModel.GetChildren() );
for( LONG t = 0; t < cRefs.GetCount(); ++t ) {
X3DObject obj( cRef.GetItem( t ) );
}
return true;
}
Code: Select all
bool findChildren( Model inModel ) {
CRefArray cRefs( inModel.GetChildren() );
for( LONG t = 0; t < cRefs.GetCount(); ++t ) {
X3DObject obj( cRef.GetItem( t ) );
if( obj.GetType() == L"#model" )
findChildren( Model( obj ) );
}
return true;
}
Code: Select all
bool findChildren( Model inModel ) {
CRefArray cRefs( inModel.GetChildren() );
for( LONG t = 0; t < cRefs.GetCount(); ++t ) {
X3DObject obj( cRef.GetItem( t ) );
if( obj.GetType() == L"#model" )
findChildren( Model( obj ) );
else if( obj.GetType() == L"polymsh" || obj.GetType() == L"surfmsh" ) {
CRefArray mats( obj.GetMaterials() )
}
}
return true;
}
Code: Select all
bool findChildren( Model inModel, CRefArray& inArray ) {
CRefArray cRefs( inModel.GetChildren() );
for( LONG t = 0; t < cRefs.GetCount(); ++t ) {
X3DObject obj( cRef.GetItem( t ) );
if( obj.GetType() == L"#model" )
findChildren( Model( obj ), inArray );
else if( obj.GetType() == L"polymsh" || obj.GetType() == L"surfmsh" ) {
CRefArray mats( obj.GetMaterials() )
for( LONG u = 0; u < mats.GetCount(); ++u ) {
Material mat( mats.GetItem( u ) );
bool found = false;
for( LONG o = 0; o < inArray.GetCount(); ++o )
if( inArray.GetItem( o ) == mat.GetRef() )
found = true;
if( !found )
inArray.Add( mat.GetRef() );
}
mats.Clear();
}
}
cRefs.Clear();
return true;
}
The last step is to call the function with:
Code: Select all
CRefArray matArray;
Selection selection( app.GetSelection() );
Model mod( selection.GetItem( 0 ) );
if( mod.GetType() == L"#model" )
findChildren( mod, matArray );
Haven´t test it and it´s possible that there are some errors. It´s only to show how it can work.
Hope this helps a little bit...
face
Re: Select all materials in model
Face - That was helpful except, as much as I understand how you did what you did in C++ it's converting it to Js for me to understand that is one of the issues, the other thing, the order of the code that needs to be done, to be able to select all the materials in a model.
Edit: I messed my own self over
Edit: I messed my own self over
Last edited by Falam on 29 Jun 2013, 20:44, edited 1 time in total.
Re: Select all materials in model
Then i would prefer to take a look at the MaterialLibrary and check each material with UsedBy(), how Hirazi wrote...
face
face
- xsisupport
- Posts: 713
- Joined: 09 Jun 2009, 11:02
- Location: Montreal Canada
- Contact:
-
- Posts: 102
- Joined: 14 Jun 2012, 02:30
Re: Select all materials in model
This is probably an embarrassingly silly way of doing what you want since I'm not very good at scripting, just searched around the xsi wiki and tried to understand some things for fun , . Sorry for it being vbs(is all I know), shouldn't be too hard to convert to js if needed ?
just select a model and run..again it's probably a silly way to do it and might miss some materials.. kinda seems to work tho
http://softimage.wiki.softimage.com/sdk ... ldren2.htm
http://softimage.wiki.softimage.com/sdkdocs/Cluster.htm
http://softimage.wiki.softimage.com/sdk ... UsedBy.htm
Edit : Did a little bit work on it to get it working with multiple selections or start a picksession if no object selected. Also made it select the objects material / cluster material incase I select a polymesh or whatever instead of a model.. not really needed, am just a little ocd .. http://pastebin.com/mu5WdR9X
Code: Select all
'Create a collection to add the materials to
Set ChildMaterials = CreateObject( "XSI.Collection" )
set oSelecto = Application.Selection(0)
'use findchildren to find the children ;)
Set oChildren = oSelecto.FindChildren2
'Itterate a simple material selection for each child and add to the collective
for i = 0 to (oChildren.Count - 1)
DeselectAll
'Select the child's material
SelectMaterialsUsedBy oChildren(i)
'add it to the ChildMaterials collection
ChildMaterials.add application.Selection(0)
'if it is a polygon / nurb surface then look for clusters and add their materials too
if oChildren(i).type = "polymsh" or oChildren(i).type = "surfmsh" then
for each oItem in oChildren
on error resume next
set oClusters = oItem.ActivePrimitive.Geometry.Clusters
if ( err = 0 ) then
for each oCls in oClusters
DeselectAll
'select the cluster's material
SelectMaterialsUsedBy oCls
'add it to the ChildMaterials collection
ChildMaterials.add application.Selection(0)
next
end if
next
end if
next
'Select the collection
selectobj ChildMaterials
http://softimage.wiki.softimage.com/sdk ... ldren2.htm
http://softimage.wiki.softimage.com/sdkdocs/Cluster.htm
http://softimage.wiki.softimage.com/sdk ... UsedBy.htm
Edit : Did a little bit work on it to get it working with multiple selections or start a picksession if no object selected. Also made it select the objects material / cluster material incase I select a polymesh or whatever instead of a model.. not really needed, am just a little ocd .. http://pastebin.com/mu5WdR9X
Re: Select all materials in model
of topic... for thoses who just want to find without scripting... use the softimage search "Search selection" on materials...
Re: Select all materials in model
Verifying, this script selects all materials in a model ?SpookyMunky wrote:This is probably an embarrassingly silly way of doing what you want since I'm not very good at scripting, just searched around the xsi wiki and tried to understand some things for fun , . Sorry for it being vbs(is all I know), shouldn't be too hard to convert to js if needed ?
just select a model and run..again it's probably a silly way to do it and might miss some materials.. kinda seems to work thoCode: Select all
'Create a collection to add the materials to Set ChildMaterials = CreateObject( "XSI.Collection" ) set oSelecto = Application.Selection(0) 'use findchildren to find the children ;) Set oChildren = oSelecto.FindChildren2 'Itterate a simple material selection for each child and add to the collective for i = 0 to (oChildren.Count - 1) DeselectAll 'Select the child's material SelectMaterialsUsedBy oChildren(i) 'add it to the ChildMaterials collection ChildMaterials.add application.Selection(0) 'if it is a polygon / nurb surface then look for clusters and add their materials too if oChildren(i).type = "polymsh" or oChildren(i).type = "surfmsh" then for each oItem in oChildren on error resume next set oClusters = oItem.ActivePrimitive.Geometry.Clusters if ( err = 0 ) then for each oCls in oClusters DeselectAll 'select the cluster's material SelectMaterialsUsedBy oCls 'add it to the ChildMaterials collection ChildMaterials.add application.Selection(0) next end if next end if next 'Select the collection selectobj ChildMaterials
http://softimage.wiki.softimage.com/sdk ... ldren2.htm
http://softimage.wiki.softimage.com/sdkdocs/Cluster.htm
http://softimage.wiki.softimage.com/sdk ... UsedBy.htm
Edit : Did a little bit work on it to get it working with multiple selections or start a picksession if no object selected. Also made it select the objects material / cluster material incase I select a polymesh or whatever instead of a model.. not really needed, am just a little ocd .. http://pastebin.com/mu5WdR9X
- csaez
- Posts: 253
- Joined: 09 Jul 2012, 15:31
- Skype: csaezmargotta
- Location: Sydney, Australia
- Contact:
Re: Select all materials in model
It is not the most elegant piece of code but works...Falam wrote:I want a script that selects all materials in a model, learning the SDK don't know how to set this up.
Code: Select all
model = Application.Selection(0)
materials = [material for child in model.FindChildren("*") for material in child.Materials]
Application.SelectObj(materials)
Re: Select all materials in model
Oh you python guys, maybe I should learn it
One more request, what about selecting all materials in a model without a specific progID (shader) ?
One more request, what about selecting all materials in a model without a specific progID (shader) ?
-
- Moderator
- Posts: 754
- Joined: 25 Nov 2009, 01:41
- Contact:
Re: Select all materials in model
Going to chime in here on this thread. Firstly, it's broken one of the rules I have setup in the "Programming Read First" thread. This board shouldn't be for requesting someone to write a script for you.
@Falam, you posted a meager 2 simplistic lines of code and not even in your first post. In the future you HAVE TO post code that isn't working. This is a forum for programming and like I mention above you shouldn't be coming to this board hoping that others are going to just give you the code.
These threads end up with little value in terms of learning programming since they simply have code that works. They aren't necessarily going through the steps of how to achieve the end goal, explaining each step along the way. We are going to end up with a ton of posts with code with no explanations and others aren't going to be able learn from them.
Here is some code that may help others understand the method of going through the model and its objects to find materials, then select them:
@Falam, you posted a meager 2 simplistic lines of code and not even in your first post. In the future you HAVE TO post code that isn't working. This is a forum for programming and like I mention above you shouldn't be coming to this board hoping that others are going to just give you the code.
These threads end up with little value in terms of learning programming since they simply have code that works. They aren't necessarily going through the steps of how to achieve the end goal, explaining each step along the way. We are going to end up with a ton of posts with code with no explanations and others aren't going to be able learn from them.
Here is some code that may help others understand the method of going through the model and its objects to find materials, then select them:
Code: Select all
from win32com.client import constants as c
from win32com.client.dynamic import Dispatch as d
xsi = Application
log = xsi.LogMessage
sel = xsi.Selection
def selectMdlMats(model):
# If input object is not a model, return false.
if model.Type != "#model":
log("Input object is not a model!", 4)
return False
mats = d("XSI.Collection") # Create an empty collection
mats.Unique = True # Make sure objects only appear once in collection
# Loop through the children of the model and find materials
for eachChild in model.Children:
childMats = eachChild.Materials
mats.AddItems(childMats) # Add all materials on a child object to our mats collection
return mats
if sel.Count: # Check that something is selected
modelMats = selectMdlMats(sel(0)) # Pass first select object as function input
# modelMats is now a pointer to the 'mats' returned from the selectMdlMats function
if modelMats: # If the function returned something valid continue to select it
sel.SetAsText(modelMats.GetAsText()) # Set selection from our mats collection
Re: Select all materials in model
Even if the code is Gobbledygook, alright, you said it.
Edit: Both csaez and Eric code do the same task, csaez is a little smaller, this ain't a competition. Either script is helpful, and beneficial I suppose I'm obliged to say 'thank you' to both.
Posting my code, on how to only select materials that don't contain a specific node, won't be understandable. Why I haven't, simply because I'm still coming to grips with the SDK and it would be a mess. Everyone is posting in Python, which is fine, but it would be a little helpful if someone would post in Javascript, so I can read it.
Edit: Both csaez and Eric code do the same task, csaez is a little smaller, this ain't a competition. Either script is helpful, and beneficial I suppose I'm obliged to say 'thank you' to both.
Posting my code, on how to only select materials that don't contain a specific node, won't be understandable. Why I haven't, simply because I'm still coming to grips with the SDK and it would be a mess. Everyone is posting in Python, which is fine, but it would be a little helpful if someone would post in Javascript, so I can read it.
Who is online
Users browsing this forum: No registered users and 26 guests