Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - NevTD

Pages: 1 2 [3] 4 5 ... 9
...but getting values from the graph being referenced by the node (node.getReferencedResource()) is returning the default values instead of the actual values

So in your example you used node.getReferencedResource() which will most likely return a SDSBSCompGraph object.
This is returning an instance of the graph from the source (sbsar). This source does not have the overrides since the overrides belong to the node.

When the node is created it is simply a representation of the last saved state of the graph. Any overrides you apply to the node, belong to the node, not the graph it was created from.

Maybe it's bad wording on my part, so let me try it this way:
- You're working on pkg_a.graph_a and set your parameters (x=1, y=2). These parameters are recognized as default values.
- You reference pkg_a.graph_a into pkg_b.graph_b, it is now known as node_a. (at this point you haven't applied overrides)
- You query these parameters from node_a and you get x=1, y=2. These are your actual values ONLY in pkg_b, inherited from pkg_a.
- You override these parameters in pkg_b.graph_b.node_a to x=10, y=5. These are your actual values ONLY in pkg_b.
- You query these parameters from node_a again, this time you get x=10, y=5. Still actual values in  pkg_b.

- access the sbsar SDNode by parsing the current graph, get the property value for the integer we modified, we get 5.
When you query them using node_a.getPropertyValue(), you're getting the correct values because you're querying them from the pkg_b.graph_b.node_a, which is the source of these overrides.

- access the sbsar SDGraph from the node (being SDNode.getReferencedResrouce()), get the property value for the integer we modified, we get 1.
When you query these parameters using node.getReferencedResoruce(), you get x=1, y=2. This is because you're actually querying them from pkg_a.graph_a, instead of pkg_b.graph_b.node_a.

The overrides you applied in pkg_b.graph_b.node_a belong to node_a.
GetReferencedResource() returns the source of your reference (pkg_a.graph_a), which is in a totally different context than the graph you're currently manipulating (pkg_b.graph_b).

If I'm not mistaken, the Pro license does not come with SAT by default, it's an additional purchase.

You'll have better luck contacting them directly, as this forum doesn't get much attention.

Indeed getting values from the node is working, but getting values from the graph being referenced by the node (node.getReferencedResource()) is returning the default values instead of the actual values
In this case both "default" values and "actual" values are the same. Once you save a graph, those values become the "default/actual" values.

Setting property values into the graph object changes its default values, whereas setting property values into the node changes its current values. So things are consistent, I just didn't know it worked like this
Something along those lines.
For clarification; when you reference that graph into another one, the overrides for any parameters on the referenced graph, always belong to the node in the parent graph.


     - param_x: 1
     - param_y: 2

    instances (nodes):

      node_a (sbsar instance of pkg_a.graph_a)

           - param_x: 1 --> 10    #Default 1 still belongs to pkg_a.graph_a, but the override of 10 now belongs to pkg_b.graph_b.node_a.
           - param_y: 2 --> 5    #Default 2 still belongs to pkg_a.graph_a, but the override of 5 now belongs to pkg_b.graph_b.node_a.

Not seeing this issue on my end; although I'm having difficulty following your logic.

Hi, I am trying to retrieve current values of input parameters of an sbsar present into my current graph.
Your code on the other hand is attempting to get the property value from a graph.

1) How is this set up? Is this sbsar parameter you're querying exposed to the main graph? Or is it simply showing you the values of another parameter that happens to have the same id as the sbsar parameter?

2) To get the actual value from the sbsar, you'd need to query it from the node.
Code: [Select]

Lambda is the pythonic way of calling anonymous functions.
Refer back to my original post for sbs::compositing::normal. It includes a link to the docs which defines the sdDefinitionID for comp nodes.

You need to do something along the lines of this:
Code: [Select]
def NewBuild(graph):
    NodeSpawn = graph.newNode(sdDefinitionId = 'sbs::compositing::normal')

if find == None:
    pkg = app.getPackageMgr().getUserPackages()[0]
    graph = pkg.getChildrenResources(False)[0]

    menu = uiMgr.newMenu(menuTitle = "Normal Tool", objectName = "Tool_Normal_Build")
    act = QtWidgets.QAction("New",menu)
    act.triggered.connect(lambda: NewBuild(graph))

How are SDGraph and NormalMaker defined? Can you post the relevant code preceding this?

SDGraph is treated as an instance class; the only reason it could be warning you of a positional argument is if the constuctor wasn't called and the class never initialized.

Hard to tell without looking at the rest of the code; however, it won't work if you're attempting the following:
Code: [Select]
from sd.api.sdgraph import SDGraph
node = SDGraph.newNode(sdDefinitionId='normal')

Here's a quick snippet of the proper way of doing this:
Code: [Select]
pkg_mgr = aContext.getSDApplication().getPackageMgr()
pkg = pkg_mgr.getUserPackages()[0]
graph = pkg.getChildrenResources(False)[0]

node = graph.newNode(sdDefinitionId='sbs::compositing::normal’)  # Docs: ../resources/documentation/pythonapi/html/pythonapi/modules/sbs_compositing.html

You can also check out the .../resources/python/samples directory under your Designer installation.

Neither did I.
It's a huge assumption on my part so it's possible there's an easier way, but I haven't come across one so far.

So it seems to me we cannot currently create sbsar instances in a graph, is this right?

Nope, it's absolutely possible and you almost had it.
The fault lies with the documentation, as it's lacking and really unclear for this process.

Code: [Select]
pkg_mgr = aContext.getSDApplication().getPackageMgr()
pkg = pkg_mgr.getUserPackages()[0]
graph = pkg.getChildrenResources(False)[0]
# Load graph instance.
my_sbsar_pkg = pkg_mgr.loadUserPackage('path_to_sbsar')  # Load the pacakge.
my_sbsar_node = graph.newInstanceNode(my_sbsar_pkg.findResourceFromUrl('name_of_graph'))  # Create graph instance.

# Cleanup.
pkg_mgr.unloadUserPackage(my_sbsar_pkg)  # Unload the package.

Note: I don't remember how I figured this out as it was months ago.
There may even be other/better ways of doing this now, but it works well enough.

Maybe I grep'd through the examples directory? Can't remember.

Since both nodes belong to your graph, you can do this at a graph level.

  • Double click on graph and create a new Input Parameter:
    - Identifier: "tile_x"
    - Type: "Integer 1" (this has to match the "X Amount" parameter type on the tile generator)
  • Select your first tile generator, go to the "X Amount" parameter and set the function to "tile_x". (see attachment)
  • Repeate for "Y Amount".

I think your issue here is the complete opposite; it's not a down scaling issue, but rather an up scaling issue.

Note: The numbers underlined below are strictly hypothetical numbers used for the example...

Your source image appears to be 1024x1024, which you are then "down scaling" via transform 2d, to... let's say a 512x512 image in a 1024x1024 workspace.

This is then being plugged into your blend node, which is set to 2048x2048, this is essentially "up scaling" your 512x512 image, to a 1024x1024 image within a 2048x2048 workspace.

The pixelization you see is a result of this up scaling.

To fix this, you need to either:
  • Start with a higher resolution version of the logo.
  • Or more ideally, you can change the output size for the transform 2d node to "Relative to parent", which will downscale the logo to 512x512 within a 2048x2048 (inherited from graph) workspace; this will prevent any additional transformations at the blend level and should preserve your original detail.

Hopefully that makes sense.

Regarding "open a graph or function in the UI", there is apparently no such functionality currently. I meant to open a container in the UI in the same way you would do when double-clicking on a function in the Explorer view or a graph or using CTRL+E to enter a node.
You're right, there doesn't appear to be a way to open an instance in the view.

This seems more of a 2 step GUI related operation: open reference first (sdpackagemgr.loadUserPackage()), then load reference in graph view (possible GUI op?).
I don't have access to the latest API currently, but have you looked into the new QT GUI related API features introduced in > 2019.1.0?

Regarding comments, they can actually be associated to nodes, you can see this by creating a node, right-clicking on it to assign it a comment, then when you move the node in the view, the comment also moves with it. So there is a logical link between the two, however this link doesn't seem to be accessible in the API currently.
Ah, I wasn't aware of this but I did look into it and it is possible, just not from the node object.
Although the comment created in this manner still belongs to the active graph, it adds an additional attribute creating a dependency to the node.
The dependency appears to be strictly one way* (comment --> node), so my guess is that it would be impossible to get "comment" via sdnode.

However, you can still use the example I provided above and perform a check to see if a certain node is a parent to the comment, with a small addition:
Code: [Select]
from sd.api.sdgraphobjectcomment import SDGraphObjectComment

pkg = aContext.getSDApplication().getPackageMgr().getUserPackages()[0]
graph = pkg.getChildrenResources(False)[0]
objs = graph.getGraphObjects()
for obj in objs:
    if isinstance(obj, SDGraphObjectComment):
        if obj.getParent():
            parent_node = obj.getParent()

Now if you're looking to create a comment and parent it to a node, use SdGraphObjectComment.sNewAsChild().

* If you're wondering how I know this: The sbs file is pretty much an xml file; you can open it up in an editor and try to cross reference the compNode and GUIObjects.

A parented comment creates a GUIDependency attribute with a pointer to the node's UUID.
However, if you try to cross-reference the GUIObject UUID for the comment, with the compNode it's parented to, the node stores no such data.
Therefore, it's a one way relationship stored on the GUIObject itself.

I'm not entirely sure what you're looking for here in terms of functionality, but here's some answers based on my interpretation of your questions:

Is there a way to open a graph or function in the UI using the plugin Python API? I cannot find this functionality in the API currently.
If you're referring to opening a package similar to File > Open, you can use the following...
Code: [Select]

...I am not sure we are able to get access to the comment from an SDNode
A comment is a GUI element belonging to the graph, not the node itself.
If you're trying to get the comments belonging to a graph instance, then you can try the following...
Code: [Select]
from sd.api.sdgraphobjectcomment import SDGraphObjectComment

pkg = aContext.getSDApplication().getPackageMgr().getUserPackages()[0]
graph = pkg.getChildrenResources(False)[0]
objs = graph.getGraphObjects()
for obj in objs:
    if isinstance(obj, SDGraphObjectComment):

It doesn't seem the Python API is currently handling the loading/saving of presets (not for MDL but regular graphs and sbsar), can this be added?
This does appear to be missing and would be nice to have.

This still leaves my other question unanswered...

How do you save an .SBS file so that all materiel and scene options in the 3D view are also saved?

Simply put; you can't.

Unlike a Painter project, the SBS is strictly a material description that doesn't include scene information.
Your scene and its settings are completely de-coupled from the material itself.

That being said, there are a couple of ways to achieve what you want:

In your 3D View, click on Scene > Export current state... \ Scene > Load current state , or Scene > Save current state as default, to preserve your scene.

You can also use Scene > Create 3D resource from current scene...; however, much like adding a custom mesh as a resource, it will add the scene mesh to your sbs package without preserving the scene overrides.

Unfortunately, the Designer API doesn't have a module for scene config management (or maybe it does now? I'm using 2018.3.1), so there doesn't appear to be a way to automate this step using the onAfterFileSaved / onAfterFileLoaded callbacks.

As you've discovered, there's no direct way to render every single preset.

You could pre-process the sbs files by running them through pysbs and retrieving all available presets for the graph/graphs, then creating a sbsrender job for each preset. This way it's fully dynamic and you don't have to query or define the presets manually.

- Create a list of all sbs files available in folder
- For sbs_file in sbs_file_list:
    - Run pysbs and extract list of presets from graph/graphs
    - For preset_name in preset_list:
        - sbsrender --input sbs_file --use-preset preset_name ...

Pages: 1 2 [3] 4 5 ... 9