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 - david376

Pages: [1] 2 3
1
I can't find any method to delete or remove a graph in package class.

Is there any way to delete graph via python api?

2
You have to tell the shader whether the basecolor is linear or not. Go to Materials / Default / Edit and set the "sRGB Base Color" parameter to false.

wow, it works . Thank you.

3
not a texture,actually a uniform color node with value set to 0.214

When the display colorspace are all set to sRGB, the same uniform color node looks different in 2d view and 3d view.

While looks the same ,when the 2d view's colorspace is set to Raw.


But as I'm using the value 0.214(18%grey) ,it should looks like mid grey.

So I felt that the 2d view's colorspace must set to sRGB. But the result in 3d view looks wrong whatever I set.

Is there any way I can change the colorspace of the node I'm using in 3d view?

4
you can check here , really good to use
https://www.artstation.com/artwork/3oP8Bg

This plugin can create new nodes by custom shortcuts. And reconnect nodes automatically.


Some people want a plugin in SD to work just closer to UE4 or Nuke ,like me. ;)

When the python api updated ,I found I can make a lot.

Then this plugin comes out.

Hope it will help.

Feel free to share ,if you like it.

and email me if you find bug ,or have some requests.

w.dai@outlook.com

5
Hi ,NevTD Trank you again here. By your help, I made a new SD plugin to create new nodes by shortcuts.

It works really good!

https://www.artstation.com/artwork/3oP8Bg


So it appears neither the SD API or the PyQt wrapper allows you to do this.
You were on the right track...

Here's a slightly hackey but effective solution to create nodes at the cursor position relative to the graph:
Code: [Select]
from PySide2 import QtGui
from sd.api.sduimgr import SDUIMgr
import sd

class CompNodeCreator(object):
    def __init__(self):
        # Get app and UI manager.
        ctx = sd.getContext()
        app = ctx.getSDApplication()
        self.ui_manager = app.getQtForPythonUIMgr()
       
        # Get Qt window.
        self.qt_app_window = self.ui_manager.getMainWindow()
       
        # Qt graph widgets.
        self.qt_graph_widget = None
        self.qt_graph_viewer = None
   
    def add_node(self, name):
        """ Add node to the graph.

        Args:
            name(str): Node definiton name as defined in docs.
                ../resources/documentation/pythonapi/html/pythonapi/modules/sbs_compositing.html
        """
        valid = self._check_qt_graph_validity()
   
        if valid:
            return self._create_comp_node_at_cursor(name)
        else:
            print('Focus is invalid. Cursor must be over graph')

               
    def _check_qt_graph_validity(self):
        """ Checks if the widget under cursor is actually the graph.
       
        Returns:
            (bool): True if cursor is above graph. False if cursor is anywhere else.
        """
        # Get related Qt graph widgets.
        self.qt_graph_widget = self.qt_app_window.childAt(QtGui.QCursor().pos())  # Returns QWidget.
       
        # The base class name of this graph QtGraphicsView object is 'Pfx::Editor::Components::Graph::GraphView'.
        # Continue operation only if the QGrapgicsView object class matches the class name.
        # This is to prevent other QGraphicsView objects (2D View) from accidentally being considered.
        if self.qt_graph_widget:
            self.qt_graph_viewer = self.qt_graph_widget.parent()  # Should return QGraphicsView.
           
            if self.qt_graph_viewer.metaObject().className() == 'Pfx::Editor::Components::Graph::GraphView':
                return True
            else:
                return False
        else:
            return False
   
    def _create_comp_node_at_cursor(self, name):
        """ Create comp node object at cursor position relative to QGraphicsScene.

        Args:
            name(str): Node definiton name as defined in docs.
                ../resources/documentation/pythonapi/html/pythonapi/modules/sbs_compositing.html
       
        Returns:
            sd_node(sd.api.sdnode): Node object
        """
        scene = self.qt_graph_viewer.scene()  # Returns QGraphicsScene.
       
        # Map global cursor position to viewer and then translate to scene position.
        # This will give us the cursor position relative to the QGraphicsScene object.
        view_pos = self.qt_graph_viewer.mapFromGlobal(QtGui.QCursor().pos())
        scene_pos = self.qt_graph_viewer.mapToScene(view_pos)
       
        # Get the comp graph.
        sd_graph = self.ui_manager.getCurrentGraph()
       
        # Create a node.
        node_def_id = 'sbs::compositing::{definition}'.format(definition=name)
        sd_node = sd_graph.newNode(node_def_id)
        sd_node.setPosition(sd.api.sdbasetypes.float2(scene_pos.x(), scene_pos.y()))
       
        return sd_node

# Run.
if __name__ == '__main__':
    node_creator = CompNodeCreator()
    node = node_creator.add_node(name='hsl')
    print(node)

####################
# Testing...
"""
# Get app and UI manager.
ctx = sd.getContext()
app = ctx.getSDApplication()
ui_manager = app.getQtForPythonUIMgr()

# Get QT window.
qt_app_window = ui_manager.getMainWindow()

# Used to recursively track down all widgets of window and get their class names.
# Can be used to find 'Pfx::Editor::Components::Graph::GraphView'.
def recursive_search(parent, lvl):
    for child in parent.children():
        print('{0} - {1}'.format(lvl, child.metaObject().className()))
       
        if child.children():
            lvl += 1
            recursive_search(child, lvl)
recursive_search(qt_app_window, 0)
"""

7
https://forum.substance3d.com/index.php/topic,30012.0.html

In this page we discussed some scripting tech.

As the getCurrentGraphSelection() method returns only nodes. We need some new method to get the connections between nodes.

Thank you

8
Got it.Thank you for your patience for answering my questions.

Waiting for SD updating ;)

BTW, is there any way to get current selected connections(properties) ?

I found the getCurrentGraphSelection() returns only nodes.

There doesn't appear to be any way to do this via the API currently, the options for connections are very limited.

Even if you could find the QT object representing the connection pipe, there's not much you could do with it since there doesn't appear to be a way to point that to an SD API object (sdconnection). Forcing a connection change at the QT level, won't necessarily get recognized by Designer, if done improperly.

This is something they should expand in the API.

9
clever idea!  appreciate that!

BTW, is there any way to get current selected connections(properties) ?

I found the getCurrentGraphSelection() returns only nodes.


How do you know the class name is  Pfx::Editor::Components::Graph::GraphView

Glad it worked for you.  :)

There's a small commented out section I left in at the bottom so you could see my thought process.
Initially I was trying to find the graph by recursively finding all the widgets in the window and filtering by the objectName, but almost all of the object names were empty.
I decided to get the class name instead (see "recursive_search" function) and searched the results for everything with "graph".

Alternatively, you can use 'self.qt_graph_widget = self.qt_app_window.childAt(QtGui.QCursor().pos())' while the cursor is over the graph and then get the parent of that widget (QGraphicsView) and check its class name, which will return  'Pfx::Editor::Components::Graph::GraphView' as well.

I haven't tested it with other graph types 'mdl', 'fx' etc., but I assume it would still work since 'Pfx::Editor::Components::Graph::GraphView' is the base class.

10
Wow, it works out very well. Thank you so much NevTD, I learned so much from you .

Are you the allegorithmic staff ? How do you know the class name is  Pfx::Editor::Components::Graph::GraphView

perfect solute ;)


So it appears neither the SD API or the PyQt wrapper allows you to do this.
You were on the right track...

Here's a slightly hackey but effective solution to create nodes at the cursor position relative to the graph:
Code: [Select]
from PySide2 import QtGui
from sd.api.sduimgr import SDUIMgr
import sd

class CompNodeCreator(object):
    def __init__(self):
        # Get app and UI manager.
        ctx = sd.getContext()
        app = ctx.getSDApplication()
        self.ui_manager = app.getQtForPythonUIMgr()
       
        # Get Qt window.
        self.qt_app_window = self.ui_manager.getMainWindow()
       
        # Qt graph widgets.
        self.qt_graph_widget = None
        self.qt_graph_viewer = None
   
    def add_node(self, name):
        """ Add node to the graph.

        Args:
            name(str): Node definiton name as defined in docs.
                ../resources/documentation/pythonapi/html/pythonapi/modules/sbs_compositing.html
        """
        valid = self._check_qt_graph_validity()
   
        if valid:
            return self._create_comp_node_at_cursor(name)
        else:
            print('Focus is invalid. Cursor must be over graph')

               
    def _check_qt_graph_validity(self):
        """ Checks if the widget under cursor is actually the graph.
       
        Returns:
            (bool): True if cursor is above graph. False if cursor is anywhere else.
        """
        # Get related Qt graph widgets.
        self.qt_graph_widget = self.qt_app_window.childAt(QtGui.QCursor().pos())  # Returns QWidget.
       
        # The base class name of this graph QtGraphicsView object is 'Pfx::Editor::Components::Graph::GraphView'.
        # Continue operation only if the QGrapgicsView object class matches the class name.
        # This is to prevent other QGraphicsView objects (2D View) from accidentally being considered.
        if self.qt_graph_widget:
            self.qt_graph_viewer = self.qt_graph_widget.parent()  # Should return QGraphicsView.
           
            if self.qt_graph_viewer.metaObject().className() == 'Pfx::Editor::Components::Graph::GraphView':
                return True
            else:
                return False
        else:
            return False
   
    def _create_comp_node_at_cursor(self, name):
        """ Create comp node object at cursor position relative to QGraphicsScene.

        Args:
            name(str): Node definiton name as defined in docs.
                ../resources/documentation/pythonapi/html/pythonapi/modules/sbs_compositing.html
       
        Returns:
            sd_node(sd.api.sdnode): Node object
        """
        scene = self.qt_graph_viewer.scene()  # Returns QGraphicsScene.
       
        # Map global cursor position to viewer and then translate to scene position.
        # This will give us the cursor position relative to the QGraphicsScene object.
        view_pos = self.qt_graph_viewer.mapFromGlobal(QtGui.QCursor().pos())
        scene_pos = self.qt_graph_viewer.mapToScene(view_pos)
       
        # Get the comp graph.
        sd_graph = self.ui_manager.getCurrentGraph()
       
        # Create a node.
        node_def_id = 'sbs::compositing::{definition}'.format(definition=name)
        sd_node = sd_graph.newNode(node_def_id)
        sd_node.setPosition(sd.api.sdbasetypes.float2(scene_pos.x(), scene_pos.y()))
       
        return sd_node

# Run.
if __name__ == '__main__':
    node_creator = CompNodeCreator()
    node = node_creator.add_node(name='hsl')
    print(node)

####################
# Testing...
"""
# Get app and UI manager.
ctx = sd.getContext()
app = ctx.getSDApplication()
ui_manager = app.getQtForPythonUIMgr()

# Get QT window.
qt_app_window = ui_manager.getMainWindow()

# Used to recursively track down all widgets of window and get their class names.
# Can be used to find 'Pfx::Editor::Components::Graph::GraphView'.
def recursive_search(parent, lvl):
    for child in parent.children():
        print('{0} - {1}'.format(lvl, child.metaObject().className()))
       
        if child.children():
            lvl += 1
            recursive_search(child, lvl)
recursive_search(qt_app_window, 0)
"""

11
forgot  to say , my purpose is to create a new node at the mouse position .

There's probably a better way to do whatever it is that you need with the cursor position and widgets.
What exactly is your objective? Can you provide more details?

To answer your question, you can get the cursor pos using Qt, rather than get external Python libraries for cross-platform support:
Code: [Select]
from PySide2 import QtGui

print QtGui.QCursor().pos()

12
thank you NevTD.

I know how to get mouse position in screen coordinate.But it's not my purpose.

Acturally I want to know the relative position of mouse to the CURRENT GRAPH.

It’s relative, even though I pan my view ,my mouse comes from right to left on the screen, the relative position is still not change.


I don't know exactly how the Node Graph window was build. I tried to get every child of the mainWindow ,but still can't find what controls the Node Graph window.

There's probably a better way to do whatever it is that you need with the cursor position and widgets.
What exactly is your objective? Can you provide more details?

To answer your question, you can get the cursor pos using Qt, rather than get external Python libraries for cross-platform support:
Code: [Select]
from PySide2 import QtGui

print QtGui.QCursor().pos()

13
Is there any way to get current mouse position via python api ?

My purpose is to create New Node at mouse position,so I need to get the relative position of the mouse to the current node graph.

Could I get the information via pyside ?

I tried to find out the widget class of graph.But I can't figure out which is which.


[MSG][2079]<PySide2.QtWidgets.QLabel object at 0x000002A25D6DE548>
[MSG][2080]child
[MSG][2081]graphatomic://item_comment
[MSG][2082]objectName
[MSG][2083]_
[MSG][2084]<PySide2.QtWidgets.QLabel object at 0x000002A25D6DE588>
[MSG][2085]child
[MSG][2086]graphatomic://item_frame
[MSG][2087]objectName
[MSG][2088]_
[MSG][2089]<PySide2.QtWidgets.QLabel object at 0x000002A25D6DE5C8>
[MSG][2090]child
[MSG][2091]graphatomic://item_pin
[MSG][2092]objectName
[MSG][2093]_
[MSG][2094]<PySide2.QtWidgets.QToolBar object at 0x000002A25D6DE608>
[MSG][2095]child
[MSG][2096]enginetoolbar
[MSG][2097]objectName
[MSG][2098]_

14
I got it. There are some classes called  sdtypefloat  sdtypebool  and so on. Those are correct

15
this seems the new method added this version .

in documentation ,it mentioned that this method needs three vars.

newProperty(sdPropertyId, sdPropertyType, sdPropertyCategory)


but I can't find out what to feed in sdPropertyType. Anybody help?

Pages: [1] 2 3