Ejemplo n.º 1
0
	def testStandardAttributeConversion( self ) :
		
		torus = self.createTorus()
		color = torus.createOutputNode( "color" )
		color.parm( "colortype" ).set( 2 )
		rest = color.createOutputNode( "rest" )
		scale = rest.createOutputNode( "attribcreate" )
		scale.parm( "name1" ).set( "pscale" )
		scale.parm( "value1v1" ).setExpression( "$PT" )
		uvunwrap = scale.createOutputNode( "uvunwrap" )
		
		converter = IECoreHoudini.FromHoudiniPolygonsConverter( uvunwrap )
		result = converter.convert()
		if hou.applicationVersion()[0] >= 15 :
			self.assertEqual( result.keys(), [ "Cs", "P", "Pref", "s", "t", "width" ] )
		else :
			self.assertEqual( result.keys(), [ "Cs", "P", "Pref", "s", "t", "varmap", "width" ] )
		
		self.assertTrue( result.arePrimitiveVariablesValid() )
		self.assertEqual( result["P"].data.getInterpretation(), IECore.GeometricData.Interpretation.Point )
		self.assertEqual( result["Pref"].data.getInterpretation(), IECore.GeometricData.Interpretation.Point )
		
		sData = result["s"].data
		tData = result["t"].data
		geo = uvunwrap.geometry()
		uvs = geo.findVertexAttrib( "uv" )
		
		i = 0
		for prim in geo.prims() :
			verts = list(prim.vertices())
			verts.reverse()
			for vert in verts :
				uvValues = vert.attribValue( uvs )
				self.assertAlmostEqual( sData[i], uvValues[0] )
				self.assertAlmostEqual( tData[i], 1 - uvValues[1] )
				i += 1
		
		converter["convertStandardAttributes"].setTypedValue( False )
		result = converter.convert()
		if hou.applicationVersion()[0] >= 15 :
			self.assertEqual( result.keys(), [ "Cd", "P", "pscale", "rest", "uv" ] )
		else :
			self.assertEqual( result.keys(), [ "Cd", "P", "pscale", "rest", "uv", "varmap" ] )
		self.assertTrue( result.arePrimitiveVariablesValid() )
		self.assertEqual( result["P"].data.getInterpretation(), IECore.GeometricData.Interpretation.Point )
		self.assertEqual( result["rest"].data.getInterpretation(), IECore.GeometricData.Interpretation.Point )
		
		uvData = result["uv"].data
		geo = uvunwrap.geometry()
		uvs = geo.findVertexAttrib( "uv" )
		
		i = 0
		for prim in geo.prims() :
			verts = list(prim.vertices())
			verts.reverse()
			for vert in verts :
				uvValues = vert.attribValue( uvs )
				self.assertAlmostEqual( uvData[i][0], uvValues[0] )
				self.assertAlmostEqual( uvData[i][1], uvValues[1] )
				i += 1
Ejemplo n.º 2
0
	def testStandardAttributeConversion( self ) :
		
		points = self.createPoints()
		color = points.createOutputNode( "color" )
		color.parm( "colortype" ).set( 2 )
		rest = color.createOutputNode( "rest" )
		scale = rest.createOutputNode( "attribcreate" )
		scale.parm( "name1" ).set( "pscale" )
		scale.parm( "value1v1" ).setExpression( "$PT" )
		
		converter = IECoreHoudini.FromHoudiniPointsConverter( scale )
		result = converter.convert()
		if hou.applicationVersion()[0] >= 15 :
			self.assertEqual( result.keys(), [ "Cs", "N", "P", "Pref", "width" ] )
		else :
			self.assertEqual( result.keys(), [ "Cs", "N", "P", "Pref", "varmap", "width" ] )
		self.assertTrue( result.arePrimitiveVariablesValid() )
		self.assertEqual( result["P"].data.getInterpretation(), IECore.GeometricData.Interpretation.Point )
		self.assertEqual( result["Pref"].data.getInterpretation(), IECore.GeometricData.Interpretation.Point )
		self.assertEqual( result["N"].data.getInterpretation(), IECore.GeometricData.Interpretation.Normal )
		
		converter["convertStandardAttributes"].setTypedValue( False )
		result = converter.convert()
		if hou.applicationVersion()[0] >= 15 :
			self.assertEqual( result.keys(), [ "Cd", "N", "P", "pscale", "rest" ] )
		else :
			self.assertEqual( result.keys(), [ "Cd", "N", "P", "pscale", "rest", "varmap" ] )
		self.assertTrue( result.arePrimitiveVariablesValid() )
		self.assertEqual( result["P"].data.getInterpretation(), IECore.GeometricData.Interpretation.Point )
		self.assertEqual( result["rest"].data.getInterpretation(), IECore.GeometricData.Interpretation.Point )
		self.assertEqual( result["N"].data.getInterpretation(), IECore.GeometricData.Interpretation.Normal )
	def testWeldUVs( self ) :

		torus = self.createTorus()
		uvunwrap = torus.createOutputNode( "uvunwrap" )

		converter = IECoreHoudini.FromHoudiniPolygonsConverter( uvunwrap )
		result = converter.convert()
		if hou.applicationVersion()[0] >= 15 :
			self.assertEqual( result.keys(), [ "P", "uv" ] )
		else :
			self.assertEqual( result.keys(), [ "P", "uv", "varmap" ] )
		self.assertTrue( result.arePrimitiveVariablesValid() )
		self.assertEqual( result["uv"].data.getInterpretation(), IECore.GeometricData.Interpretation.UV )
		self.assertEqual( result["uv"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.FaceVarying )

		uvData = result["uv"].data
		uvIndices = result["uv"].indices

		geo = uvunwrap.geometry()
		uvs = geo.findVertexAttrib( "uv" )

		i = 0
		for prim in geo.prims() :
			verts = list(prim.vertices())
			verts.reverse()
			for vert in verts :
				uvValues = vert.attribValue( uvs )
				self.assertAlmostEqual( uvData[ uvIndices[i] ][0], uvValues[0] )
				self.assertAlmostEqual( uvData[ uvIndices[i] ][1], uvValues[1] )
				i += 1

		converter["weldUVs"].setTypedValue( False )
		result = converter.convert()
		if hou.applicationVersion()[0] >= 15 :
			self.assertEqual( result.keys(), [ "P", "uv" ] )
		else :
			self.assertEqual( result.keys(), [ "P", "uv", "varmap" ] )
		self.assertTrue( result.arePrimitiveVariablesValid() )
		self.assertEqual( result["uv"].data.getInterpretation(), IECore.GeometricData.Interpretation.UV )
		self.assertEqual( result["uv"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.FaceVarying )

		uvData = result["uv"].data
		self.assertEqual( result["uv"].indices, None )

		geo = uvunwrap.geometry()
		uvs = geo.findVertexAttrib( "uv" )

		i = 0
		for prim in geo.prims() :
			verts = list(prim.vertices())
			verts.reverse()
			for vert in verts :
				uvValues = vert.attribValue( uvs )
				self.assertAlmostEqual( uvData[i][0], uvValues[0] )
				self.assertAlmostEqual( uvData[i][1], uvValues[1] )
				i += 1
Ejemplo n.º 4
0
	def testWeldUVs( self ) :

		torus = self.createTorus()
		uvunwrap = torus.createOutputNode( "uvunwrap" )

		converter = IECoreHoudini.FromHoudiniPolygonsConverter( uvunwrap )
		result = converter.convert()
		if hou.applicationVersion()[0] >= 15 :
			self.assertEqual( result.keys(), [ "P", "uv" ] )
		else :
			self.assertEqual( result.keys(), [ "P", "uv", "varmap" ] )
		self.assertTrue( result.arePrimitiveVariablesValid() )
		self.assertEqual( result["uv"].data.getInterpretation(), IECore.GeometricData.Interpretation.UV )
		self.assertEqual( result["uv"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.FaceVarying )

		uvData = result["uv"].data
		uvIndices = result["uv"].indices

		geo = uvunwrap.geometry()
		uvs = geo.findVertexAttrib( "uv" )

		i = 0
		for prim in geo.prims() :
			verts = list(prim.vertices())
			verts.reverse()
			for vert in verts :
				uvValues = vert.attribValue( uvs )
				self.assertAlmostEqual( uvData[ uvIndices[i] ][0], uvValues[0] )
				self.assertAlmostEqual( uvData[ uvIndices[i] ][1], uvValues[1] )
				i += 1

		converter["weldUVs"].setTypedValue( False )
		result = converter.convert()
		if hou.applicationVersion()[0] >= 15 :
			self.assertEqual( result.keys(), [ "P", "uv" ] )
		else :
			self.assertEqual( result.keys(), [ "P", "uv", "varmap" ] )
		self.assertTrue( result.arePrimitiveVariablesValid() )
		self.assertEqual( result["uv"].data.getInterpretation(), IECore.GeometricData.Interpretation.UV )
		self.assertEqual( result["uv"].interpolation, IECoreScene.PrimitiveVariable.Interpolation.FaceVarying )

		uvData = result["uv"].data
		self.assertEqual( result["uv"].indices, None )

		geo = uvunwrap.geometry()
		uvs = geo.findVertexAttrib( "uv" )

		i = 0
		for prim in geo.prims() :
			verts = list(prim.vertices())
			verts.reverse()
			for vert in verts :
				uvValues = vert.attribValue( uvs )
				self.assertAlmostEqual( uvData[i][0], uvValues[0] )
				self.assertAlmostEqual( uvData[i][1], uvValues[1] )
				i += 1
Ejemplo n.º 5
0
    def __init__(self, name="", version=None):
        super(Houdini, self).__init__(name, version)

        from stalker import Repository
        # re initialize repo vars
        for repo in Repository.query.all():
            env_var_name = repo.env_var
            value = repo.path
            self.set_environment_variable(env_var_name, value)

        self.name = '%s%s.%s' % (self.name, hou.applicationVersion()[0],
                                 hou.applicationVersion()[1])
Ejemplo n.º 6
0
    def init_engine(self):
        """
        Main initialization entry point.
        """

        self.log_debug("%s: Initializing..." % self)

        if hou.applicationVersion()[0] < 12:
            raise tank.TankError(
                "Your version of Houdini is not supported. Currently, Toolkit only supports version 12+"
            )

        # Support OS X on 14+ only
        if sys.platform == "darwin" and hou.applicationVersion()[0] < 14:
            raise tank.TankError(
                "Your version of Houdini is not supported on OS X. Currently, "
                "Toolkit only supports version 14+ on OS X.")

        try:
            hou_ver_str = ".".join([str(v) for v in hou.applicationVersion()])
            self.log_user_attribute_metric("Houdini version", hou_ver_str)
        except:
            # ignore all errors. ex: using a core that doesn't support metrics
            pass

        # keep track of if a UI exists
        self._ui_enabled = hasattr(hou, 'ui')

        # pyside is integrated as of houdini 14.
        if hou.applicationVersion()[0] >= 14:
            self._integrated_pyside = True
            self._ui_type = "PySide"
            self.log_debug("Using integrated PySide.")
        else:
            self._integrated_pyside = False
            self._ui_type = None

        # add our built-in pyside to the python path when on windows
        if not self._integrated_pyside and sys.platform == "win32":
            py_ver = sys.version_info[0:2]
            if py_ver == (2, 6):
                pyside_path = os.path.join(self.disk_location, "resources",
                                           "pyside112_py26_win64")
                sys.path.append(pyside_path)
                self.log_debug("Using bundled PySide: %s" % (pyside_path, ))
            elif py_ver == (2, 7):
                pyside_path = os.path.join(self.disk_location, "resources",
                                           "pyside121_py27_win64")
                sys.path.append(pyside_path)
                self.log_debug("Using bundled PySide: %s" % (pyside_path, ))
            else:
                self.log_warning("PySide not bundled for python %d.%d" %
                                 (py_ver[0], py_ver[1]))
Ejemplo n.º 7
0
    def __init__(self, name="", version=None):
        super(Houdini, self).__init__(name, version)

        from stalker import Repository
        # re initialize repo vars
        for repo in Repository.query.all():
            env_var_name = repo.env_var
            value = repo.path
            self.set_environment_variable(env_var_name, value)
            # TODO: remove the following line
            # export old env var
            self.set_environment_variable("REPO%s" % repo.id, value)

        self.name = '%s%s.%s' % (self.name, hou.applicationVersion()[0],
                                 hou.applicationVersion()[1])
Ejemplo n.º 8
0
        def apply_stylesheet(self):
            import hou

            self._changing_stylesheet = True
            try:
                # This is only safe in pre-H16. If we do this in 16 it destroys
                # some styling in Houdini itself.
                if self.parent() and hou.applicationVersion() < (16, 0, 0):
                    self.parent().setStyleSheet("")

                engine._apply_external_styleshet(bundle, self)

                # Styling in H16+ is very different than in earlier versions of
                # Houdini. The result is that we have to be more careful about
                # behavior concerning stylesheets, because we might bleed into
                # Houdini itself if we change qss on parent objects or make use
                # of QStyles on the QApplication.
                #
                # Below, we're combining the engine-level qss with whatever is
                # already assigned to the widget. This means that the engine
                # styling is helping patch holes in any app- or framework-level
                # qss that might have already been applied.
                if hou.applicationVersion() >= (16, 0, 0):
                    qss_file = engine._get_engine_qss_file()
                    with open(qss_file, "rt") as f:
                        qss_data = f.read()
                        qss_data = engine._resolve_sg_stylesheet_tokens(
                            qss_data)
                        qss_data = qss_data.replace(
                            "{{ENGINE_ROOT_PATH}}",
                            engine._get_engine_root_path())
                        self.setStyleSheet(self.styleSheet() + qss_data)
                        self.update()

                    # We have some funky qss behavior in H16 that requires us to
                    # kick the parent's stylesheet by reassigning it as is. Not
                    # sure what causes the problem, but this does resolve it. The
                    # original symptoms were some widgets not changing after applying
                    # the engine's stylesheet, while others did.
                    if self.parent():
                        self.parent().setStyleSheet(self.parent().styleSheet())
            except Exception as e:
                engine.logger.warning(
                    "Unable to re-apply stylesheet for panel: %s %s" %
                    (title, e))
            finally:
                self._changing_stylesheet = False
            self._stylesheet_applied = True
Ejemplo n.º 9
0
    def init_engine(self):
        """
        Main initialization entry point.
        """        

        self.log_debug("%s: Initializing..." % self)

        if hou.applicationVersion()[0] < 12:
            raise tank.TankError("Your version of Houdini is not supported. Currently, Toolkit only supports version 12+")

        # Support OS X on 14+ only
        if sys.platform == "darwin" and hou.applicationVersion()[0] < 14:
            raise tank.TankError(
                "Your version of Houdini is not supported on OS X. Currently, "
                "Toolkit only supports version 14+ on OS X.")

        try:
            hou_ver_str = ".".join([str(v) for v in hou.applicationVersion()])
            self.log_user_attribute_metric("Houdini version", hou_ver_str)
        except:
            # ignore all errors. ex: using a core that doesn't support metrics
            pass

        # keep track of if a UI exists
        self._ui_enabled = hasattr(hou, 'ui')

        # pyside is integrated as of houdini 14.
        if hou.applicationVersion()[0] >= 14:
            self._integrated_pyside = True
            self._ui_type = "PySide"
            self.log_debug("Using integrated PySide.")
        else:
            self._integrated_pyside = False
            self._ui_type = None

        # add our built-in pyside to the python path when on windows
        if not self._integrated_pyside and sys.platform == "win32":
            py_ver = sys.version_info[0:2]
            if py_ver == (2, 6):
                pyside_path = os.path.join(self.disk_location, "resources", "pyside112_py26_win64")
                sys.path.append(pyside_path)
                self.log_debug("Using bundled PySide: %s" % (pyside_path,))
            elif py_ver == (2, 7):
                pyside_path = os.path.join(self.disk_location, "resources", "pyside121_py27_win64")
                sys.path.append(pyside_path)
                self.log_debug("Using bundled PySide: %s" % (pyside_path,))
            else:
                self.log_warning("PySide not bundled for python %d.%d" % (py_ver[0], py_ver[1]))
Ejemplo n.º 10
0
    def fetch_data_from_simulation_node(input_node):
        """Collects data from simulation input node.

    Assumes that input node is a simulation node

    Args:
      input_node: hou.Node, a simulation node.

    Returns:
      {str, object}, Submission parameters.
    """
        output_parm_names = dict(output='dopoutput', filecache='file')
        parm_name = output_parm_names.get(input_node.type().name())
        output_dir = input_node.parm(parm_name).unexpandedString()

        result = dict(output_filename=os.path.basename(output_dir),
                      renderer='simulation',
                      renderer_version=hou.applicationVersion(),
                      render_current_frame=False)

        result['frame_begin'] = input_node.parm('f1').eval()
        result['frame_end'] = input_node.parm('f2').eval()
        result['step'] = input_node.parm('f3').eval()

        return result
Ejemplo n.º 11
0
    def fetch_data_from_mantra_node(input_node):
        """Collects data form Mantra input node.

    Assumes that input node is Mantra node

    Args:
      input_node: hou.Node, Mantra node.

    Returns:
      {str, object}, Submission parameters.
    """
        output_picture = input_node.parm('vm_picture').unexpandedString()

        result = dict(output_filename=os.path.basename(output_picture),
                      renderer='mantra',
                      renderer_version=hou.applicationVersion(),
                      render_current_frame=False)

        if input_node.parm('trange').evalAsString() == 'off':
            current_frame = hou.frame()
            result['frame_begin'] = current_frame
            result['frame_end'] = current_frame
            result['step'] = 1
            # Resolution limits only apply to non- and limited-commercial, so "Render Current Frame"
            # isn't needed otherwise.
            result['render_current_frame'] = (
                hou.licenseCategory() != hou.licenseCategoryType.Commercial)
        else:
            result['frame_begin'] = input_node.parm('f1').eval()
            result['frame_end'] = input_node.parm('f2').eval()
            result['step'] = input_node.parm('f3').eval()

        return result
Ejemplo n.º 12
0
    def add_spare_parameters(self, target):
        vtuple = hou.applicationVersion()
        rfhtree = hou.getenv("RFHTREE")
        renderobjnames = ["geo"]
        rendercamnames = ["cam"]

        if target.type().name() in renderobjnames:
            path = rfhtree + "/18.5.351/soho/parameters/geoparms.ds"
        elif target.type().name() in rendercamnames:
            path = rfhtree + "/18.5.351/soho/parameters/camparms.ds"
        else:
            return None

        grp = target.parmTemplateGroup()
        spareparms = hou.ParmTemplateGroup()
        with open(path) as file:
            ds = file.read()
            spareparms.setToDialogScript(ds)
        for template in spareparms.parmTemplates():
            grp.append(template)

        try:
            target.parmsInFolder(("RenderMan",))
        except:
            target.setParmTemplateGroup(grp)

        if target.type().name() == "geo":
            hou.hscript("opproperty %s prman23geo *" % target.path())
        elif target.type().name() == "cam":
            hou.hscript("opproperty %s prman23cam *" % target.path())
Ejemplo n.º 13
0
 def findIcons(self):
     if hou.applicationVersion()[0] < 15:
         for category in os.listdir(self.path):
             for ico in os.listdir(os.path.join(self.path, category)):
                 iconPath = os.path.join(
                     os.path.join(self.path, category, ico))
                 iconName = '_'.join([category, os.path.splitext(ico)[0]])
                 self.icons[iconName] = QPixmap(iconPath)
     else:
         zf = zipfile.ZipFile(self.path, 'r')
         for f in zf.namelist():
             if f.startswith('old'): continue
             if os.path.splitext(f)[-1] == '.svg':
                 svg = QSvgRenderer(QByteArray(zf.read(f)))
                 if not svg.isValid():
                     continue
                 pixmap = QPixmap(iconSize, iconSize)
                 painter = QPainter()
                 painter.begin(pixmap)
                 pixmap.fill(QColor(Qt.black))
                 svg.render(painter)
                 painter.end()
                 category, ico = f.split('/')
                 iconName = '_'.join([category, os.path.splitext(ico)[0]])
                 self.icons[iconName] = pixmap
         zf.close()
Ejemplo n.º 14
0
    def show_dialog(self, title, bundle, widget_class, *args, **kwargs):
        """
        Shows a modeless dialog. Overridden from base class.
        """        
        from sgtk.platform.qt import QtCore, QtGui
        
        # In houdini, the script editor runs in a custom thread. Any commands executed here
        # which are calling UI functionality may cause problems with QT. Check that we are
        # running in the main thread
        if QtCore.QThread.currentThread() != QtGui.QApplication.instance().thread():
            self.execute_in_main_thread(self.logger.error, "Error creating dialog: You can only launch UIs "
                                        "in the main thread. Try using the execute_in_main_thread() method.")
            return

        # create the dialog:
        dialog, widget = self._create_dialog_with_widget(title, bundle, widget_class, *args, **kwargs)

        # show the dialog:
        dialog.show()

        # I don't have an answer to why this does what it does. We have
        # a situation in H16 where some aspects of our widgets can't be
        # styled...the changes just don't have any impact. However, if
        # we re-apply the parent's stylesheet, unchanged, after we show
        # our dialog, those styling changes we've applied either as part
        # of the app's style.qss, or tk-houdini's, everything sticks the
        # way it should.
        if hou.applicationVersion() >= (16, 0, 0):
            dialog.parent().setStyleSheet(dialog.parent().styleSheet())
        
        # lastly, return the instantiated widget
        return widget
Ejemplo n.º 15
0
  def fetch_data_from_simulation_node(input_node):
    """Collects data from simulation input node.

    Assumes that input node is a simulation node

    Args:
      input_node: hou.Node, a simulation node.

    Returns:
      {str, object}, Submission parameters.
    """
    output_parm_names = dict(
      output='dopoutput',
      filecache='file')
    parm_name = output_parm_names.get(input_node.type().name())
    output_dir = input_node.parm(parm_name).unexpandedString()

    result = dict(
      output_filename=os.path.basename(output_dir),
      renderer='simulation',
      renderer_version=hou.applicationVersion(),
      render_current_frame=False
    )

    result['frame_begin'] = input_node.parm('f1').eval()
    result['frame_end'] = input_node.parm('f2').eval()
    result['step'] = input_node.parm('f3').eval()

    return result
Ejemplo n.º 16
0
    def _panels_supported(self):
        """
        Returns True if panels are supported for current Houdini version.
        """

        ver = hou.applicationVersion()

        # first version where saving python panel in desktop was fixed
        if sys.platform.startswith("darwin"):
            # We have some serious painting problems with Python panes in
            # H16 that are specific to OS X. We have word out to SESI, and
            # are waiting to hear back from them as to how we might be able
            # to proceed. Until that is sorted out, though, we're going to
            # have to disable panel support on OS X for H16. Our panel apps
            # appear to function just fine in dialog mode.
            #
            # Update: H17 resolves some of the issues, but we still have problems
            # with item delegates not rendering consistently in the Shotgun Panel's
            # entity views.
            if ver >= (16, 0, 0):
                return False

        if ver >= (15, 0, 272):
            return True

        return False
Ejemplo n.º 17
0
  def fetch_data_from_mantra_node(input_node):
    """Collects data form Mantra input node.

    Assumes that input node is Mantra node

    Args:
      input_node: hou.Node, Mantra node.

    Returns:
      {str, object}, Submission parameters.
    """
    output_picture = input_node.parm('vm_picture').unexpandedString()

    result = dict(
      output_filename=os.path.basename(output_picture),
      renderer='mantra',
      renderer_version=hou.applicationVersion(),
      render_current_frame=False
    )

    if input_node.parm('trange').evalAsString() == 'off':
      current_frame = hou.frame()
      result['frame_begin'] = current_frame
      result['frame_end'] = current_frame
      result['step'] = 1
      # Resolution limits only apply to non- and limited-commercial, so "Render Current Frame"
      # isn't needed otherwise.
      result['render_current_frame'] = (hou.licenseCategory() != hou.licenseCategoryType.Commercial)
    else:
      result['frame_begin'] = input_node.parm('f1').eval()
      result['frame_end'] = input_node.parm('f2').eval()
      result['step'] = input_node.parm('f3').eval()

    return result
Ejemplo n.º 18
0
	def testContextCreator( self ) :
		# test generic creation
		n = IECoreHoudini.FnProceduralHolder.create( "test", "parameterTypes" )
		self.assertEqual( n.path(), "/obj/test/test" )
		
		# test contextArgs outside UI mode fallback to generic behaviour
		contextArgs = { "toolname" : "ieProceduralHolder" }
		n2 = IECoreHoudini.FnProceduralHolder.create( "test", "parameterTypes", contextArgs=contextArgs )
		self.assertEqual( n2.path(), "/obj/test1/test" )
		
		# test parent arg
		geo = hou.node( "/obj" ).createNode( "geo", run_init_scripts=False )
		n3 = IECoreHoudini.FnProceduralHolder.create( "test", "parameterTypes", parent=geo, contextArgs=contextArgs )
		self.assertEqual( n3.path(), "/obj/geo1/test" )
		
		# test automatic conversion
		contextArgs["shiftclick"] = True
		n4 = IECoreHoudini.FnProceduralHolder.create( "test", "parameterTypes", parent=geo, contextArgs=contextArgs )
		self.assertEqual( n4.path(), "/obj/geo1/test1" )
		self.assertEqual( len(n4.outputConnectors()[0]), 1 )
		self.assertEqual( n4.outputConnectors()[0][0].outputNode().type().name(), "ieCortexConverter" )
		
		# test automatic conversion and output connections
		mountain = geo.createNode( "mountain" )
		contextArgs["outputnodename"] = mountain.path()
		n5 = IECoreHoudini.FnOpHolder.create( "test", "parameterTypes", parent=geo, contextArgs=contextArgs )
		self.assertEqual( n5.path(), "/obj/geo1/test2" )
		self.assertEqual( len(n5.outputConnectors()[0]), 1 )
		converter = n5.outputConnectors()[0][0].outputNode()
		self.assertEqual( converter.type().name(), "ieCortexConverter" )
		self.assertEqual( len(converter.outputConnectors()[0]), 1 )
		outputNode = converter.outputConnectors()[0][0].outputNode()
		self.assertEqual( outputNode.type().name(), "mountain::2.0" if hou.applicationVersion()[0] >= 16 else "mountain" )
		self.assertEqual( outputNode, mountain )
Ejemplo n.º 19
0
 def setUp(self):
     IECoreHoudini.TestCase.setUp(self)
     self.__torusTestFile = "test/IECoreHoudini/data/torus.cob" if hou.applicationVersion(
     )[0] < 14 else "test/IECoreHoudini/data/torusH14.cob"
     self.__torusNormalsTestFile = "test/IECoreHoudini/data/torus_with_normals.cob"
     if not os.path.exists("test/opHolder_testData"):
         os.mkdir("test/opHolder_testData")
Ejemplo n.º 20
0
    def __createHoudiniQGLWidget(cls, format):

        try:
            import hou
        except ImportError:
            # we're not in houdini - createQGLWidget() will just make a
            # normal widget.
            return None

        import IECoreHoudini

        # Prior to Houdini 14 we are running embedded on the hou.ui idle loop,
        # so we needed to force the Houdini GL context to be current, and share
        # it, similar to how we do this in Maya.
        if hou.applicationVersion()[0] < 14:
            return cls.__createHostedQGLWidget(
                format, IECoreHoudini.makeMainGLContextCurrent)

        # In Houdini 14 and beyond, Qt is the native UI, and we can access
        # Houdini's shared QGLWidget directly, provided we are using a recent
        # Cortex version.
        return QtOpenGL.QGLWidget(format,
                                  shareWidget=GafferUI._qtObject(
                                      IECoreHoudini.sharedGLWidget(),
                                      QtOpenGL.QGLWidget))
Ejemplo n.º 21
0
 def findIcons(self):
     if hou.applicationVersion()[0] < 15:
         for category in os.listdir(self.path):
             for ico in os.listdir(os.path.join(self.path, category)):
                 iconPath = os.path.join(os.path.join(self.path, category, ico))
                 iconName = '_'.join([category, os.path.splitext(ico)[0]])
                 self.icons[iconName] = QPixmap(iconPath)
     else:
         zf = zipfile.ZipFile(self.path, 'r')
         for f in zf.namelist():
             if f.startswith('old'):continue
             if os.path.splitext(f)[-1] == '.svg':
                 svg = QSvgRenderer(QByteArray(zf.read(f)))
                 if not svg.isValid():
                     continue
                 pixmap = QPixmap(iconSize, iconSize)
                 painter = QPainter()
                 painter.begin(pixmap)
                 pixmap.fill(QColor(Qt.black))
                 svg.render(painter)
                 painter.end()
                 category, ico = f.split('/')
                 iconName = '_'.join([category, os.path.splitext(ico)[0]])
                 self.icons[iconName] = pixmap
         zf.close()
Ejemplo n.º 22
0
def version_creator():
    """Helper function for version_creator UI for Houdini
    """
    # connect to db
    do_db_setup()

    import logging
    from stalker import log
    log.logging_level = logging.WARNING

    from anima.ui import version_creator
    from anima.env import houdini
    reload(houdini)
    reload(version_creator)

    h = houdini.Houdini()

    logger.setLevel(logging.WARNING)

    if hou.applicationVersion()[0] <= 13:
        version_creator.UI(
            environment=h
        )
    else:
        version_creator.UI(
            environment=h,
            executor=Executor()
        )
Ejemplo n.º 23
0
 def __init__(self, parent_node, snippetcontext):
     super(InvalidContextError,
           self).__init__("this snippet has '%s' context" % snippetcontext)
     self.__necontext = getChildContext(parent_node,
                                        hou.applicationVersion())
     self.__snippetcontext = snippetcontext
     self.__node = parent_node
Ejemplo n.º 24
0
    def show_dialog(self, title, bundle, widget_class, *args, **kwargs):
        """
        Shows a modeless dialog. Overridden from base class.
        """        
        from sgtk.platform.qt import QtCore, QtGui
        
        # In houdini, the script editor runs in a custom thread. Any commands executed here
        # which are calling UI functionality may cause problems with QT. Check that we are
        # running in the main thread
        if QtCore.QThread.currentThread() != QtGui.QApplication.instance().thread():
            self.execute_in_main_thread(self.logger.error, "Error creating dialog: You can only launch UIs "
                                        "in the main thread. Try using the execute_in_main_thread() method.")
            return

        # create the dialog:
        dialog, widget = self._create_dialog_with_widget(title, bundle, widget_class, *args, **kwargs)

        # show the dialog:
        dialog.show()

        # I don't have an answer to why this does what it does. We have
        # a situation in H16 where some aspects of our widgets can't be
        # styled...the changes just don't have any impact. However, if
        # we re-apply the parent's stylesheet, unchanged, after we show
        # our dialog, those styling changes we've applied either as part
        # of the app's style.qss, or tk-houdini's, everything sticks the
        # way it should.
        if hou.applicationVersion() >= (16, 0, 0):
            dialog.parent().setStyleSheet(dialog.parent().styleSheet())
        
        # lastly, return the instantiated widget
        return widget
Ejemplo n.º 25
0
    def _panels_supported(self):
        """
        Returns True if panels are supported for current Houdini version.
        """
        
        ver = hou.applicationVersion()
    
        # first version where saving python panel in desktop was fixed
        if sys.platform.startswith("darwin"):
            # We have some serious painting problems with Python panes in
            # H16 that are specific to OS X. We have word out to SESI, and
            # are waiting to hear back from them as to how we might be able
            # to proceed. Until that is sorted out, though, we're going to
            # have to disable panel support on OS X for H16. Our panel apps
            # appear to function just fine in dialog mode.
            #
            # Update: H17 resolves some of the issues, but we still have problems
            # with item delegates not rendering consistently in the Shotgun Panel's
            # entity views.
            if ver >= (16, 0, 0):
                return False

        if ver >= (15, 0, 272):
            return True

        return False
Ejemplo n.º 26
0
    def init_engine(self):
        """
        Main initialization entry point.
        """
        self.log_debug("%s: Initializing..." % self)

        if hou.applicationVersion()[0] < 12:
            raise tank.TankError(
                "Your version of Houdini is not supported. Currently, Toolkit only supports version 12+"
            )

        # keep track of if a UI exists
        self._ui_enabled = hasattr(hou, 'ui')

        # add our built-in pyside to the python path when on windows
        if sys.platform == "win32":
            py_ver = sys.version_info[0:2]
            if py_ver == (2, 6):
                pyside_path = os.path.join(self.disk_location, "resources",
                                           "pyside112_py26_win64")
                sys.path.append(pyside_path)
            elif py_ver == (2, 7):
                pyside_path = os.path.join(self.disk_location, "resources",
                                           "pyside121_py27_win64")
                sys.path.append(pyside_path)
            else:
                self.log_warning("PySide not bundled for python %d.%d" %
                                 (py_ver[0], py_ver[1]))
Ejemplo n.º 27
0
    def __init__(self):
        super(iconsWidgetClass, self).__init__()

        self.setStyleSheet("background:#323232;")  # custom bg color

        self.vLy = QVBoxLayout(self)

        self.fLy = QHBoxLayout()
        self.vLy.addLayout(self.fLy)
        label = QLabel('Filter: ')
        self.fLy.addWidget(label)

        self.clear_btn = QPushButton('')
        self.clear_btn.setIcon(hou.ui.createQtIcon('BUTTONS_remove'))
        self.clear_btn.clicked.connect(self.fill)
        self.clear_btn.setFixedSize(QSize(20, 20))
        self.fLy.addWidget(self.clear_btn)

        @self.clear_btn.clicked.connect
        def clearFilter():
            if self.filter.text():
                self.filter.setText('')
                self.fill()

        self.filter = QLineEdit()
        self.filter.returnPressed.connect(self.fill)
        self.fLy.addWidget(self.filter)
        self.search_btn = QPushButton('Search')
        self.search_btn.clicked.connect(self.fill)
        self.fLy.addWidget(self.search_btn)

        # self.btn = QPushButton('Clear')
        # self.btn.clicked.connect(self.clearList)
        # self.vLy.addWidget(self.btn)

        self.scrollArea = QScrollArea(self)
        self.vLy.addWidget(self.scrollArea)
        self.scrollArea.setWidgetResizable(True)
        self.sawc = QFrame()
        self.ly = QVBoxLayout(self.sawc)
        self.scrollArea.setWidget(self.sawc)

        hfs = hou.getenv('HFS')
        if hou.applicationVersion()[0] < 15:
            path = os.path.join(hfs, 'houdini/help/icons/large')
        else:
            path = os.path.join(hfs, 'houdini/help/icons.zip')
        self.icons = {}
        self.content = None

        if os.path.exists(path):
            self.path = path
            self.findIcons()
            self.fill()
        else:
            err = QLabel('Icons not found!')
            err.setStyleSheet('font-size:25px;')
            err.setAlignment(Qt.AlignHCenter | Qt.AlignTop)
            self.ly.addWidget(err)
Ejemplo n.º 28
0
 def EmitDataChanged(self, index):
     # The PySide2 version of the dataChanged signal requires a
     # 3rd argument. Check the houdini version number to determine
     # whether to use the PySide or PySide2 version.
     if hou.applicationVersion()[0] >= 16:
         self.dataChanged.emit(index, index, [])
     else:
         self.dataChanged.emit(index, index)
Ejemplo n.º 29
0
 def EmitDataChanged(self, index):
     # The PySide2 version of the dataChanged signal requires a
     # 3rd argument. Check the houdini version number to determine
     # whether to use the PySide or PySide2 version.
     if hou.applicationVersion()[0] >= 16:
         self.dataChanged.emit(index, index, [])
     else:
         self.dataChanged.emit(index, index)
Ejemplo n.º 30
0
def get_hou_major_version():
    """
    A wrapper for returning Houdini's major version

    Returns:
        String: Returns a string containing Houdini's major version number. E.g. '15'
    """
    return str(hou.applicationVersion()[0])
Ejemplo n.º 31
0
def hcopyweb():
    qapp = QApplication.instance()
    try:
        nodes = hou.selectedItems()
    except:
        nodes = hou.selectedNodes()

    enctype = hpasteoptions.getOption('hpasteweb.encryption_type', 'None')
    key = None
    encparms = {}
    if enctype == 'AES-CBC':
        key = ''.join([
            random.choice(string.ascii_letters + string.digits)
            for x in xrange(AES.block_size)
        ])
        encparms = {'mode': AES.MODE_CBC}
        enctype = 'AES'
    elif enctype.lower() == 'none' or enctype == '':
        enctype = None

    if enctype is not None and key is None:
        print('Warning: unknown encryption method, disabling encryption')
        enctype = None

    try:
        s = nodesToString(nodes, encryption_type=enctype, key=key, **encparms)
    except RuntimeError as e:
        hou.ui.displayMessage("Error: %s" % str(e.message),
                              severity=hou.severityType.Error)
        return
    except RuntimeWarning as e:  # da heck?
        hou.ui.displayMessage("Warning: %s" % str(e.message),
                              severity=hou.severityType.Warning)
    #except Exception as e:
    #    hou.ui.displayMessage("Internal Error: %s %s" % (str(type(e)), str(e.message)), severity=hou.severityType.Error)
    #    return

    if isinstance(qapp, QApplication):
        qapp.setOverrideCursor(qtc.Qt.WaitCursor)
    try:
        s = webPack(s)
    except Exception as e:
        hou.ui.displayMessage(e.message,
                              severity=hou.severityType.Error,
                              title='error')
        return
    finally:
        if isinstance(qapp, QApplication):
            qapp.restoreOverrideCursor()

    # append key to snippet
    if enctype is not None:
        s = key + '!' + s
    if hou.applicationVersion()[0] > 15:
        hou.ui.copyTextToClipboard(s)
    else:
        qapp.clipboard().setText(s)
    hou.ui.setStatusMessage("Success: Cloud link copied to clipboard!")
Ejemplo n.º 32
0
def hpasteweb(pane=None):
    qapp = QApplication.instance()
    if hou.applicationVersion()[0] > 15:
        s = hou.ui.getTextFromClipboard()
    else:
        s = qapp.clipboard().text()

    if isinstance(qapp, QApplication):
        qapp.setOverrideCursor(qtc.Qt.WaitCursor)

    # check for compression key
    key = None
    if '!' in s:
        key, s = s.split('!', 1)
    try:
        s = webUnpack(s)
    except Exception as e:
        hou.ui.displayMessage(e.message, severity=hou.severityType.Error, title='error')
        return
    finally:
        if isinstance(qapp, QApplication):
            qapp.restoreOverrideCursor()

    try:
        stringToNodes(s, ne=pane, key=key)
    except InvalidContextError as e:
        nec, snc = e.contexts()
        if snc == 'Sop' and nec == 'Object':
            if hou.ui.displayMessage("Error: %s" % str(e.message), severity=hou.severityType.Warning, buttons=('Create geo node', 'Cancel'), default_choice=0, close_choice=1) == 0:
                geonode = e.node().createNode('geo')
                if pane is not None:
                    geonode.setPosition(pane.cursorPosition())
                stringToNodes(s, hou_parent=geonode, key=key)
        else:
            hou.ui.displayMessage("Error: %s" % str(e.message), severity=hou.severityType.Error)
            return
    except WrongKeyLengthError as e:
        hou.ui.displayMessage("Bad key length: %s. Check if you copied hpaste link correctly" % str(e.message), severity=hou.severityType.Error)
        return
    except NoKeyError as e:
        hou.ui.displayMessage("This snippet is encrypted and requires a key: %s. Check if you copied hpaste link correctly. key in the link usually goes in front of the snippet, separated by '!'" % str(e.message), severity=hou.severityType.Error)
        return
    except WrongKeyError as e:
        hou.ui.displayMessage("Wrong key: %s. Check if you copied hpaste link correctly" % str(e.message), severity=hou.severityType.Error)
        return
    except RuntimeError as e:
        hou.ui.displayMessage("Error: %s" % str(e.message), severity=hou.severityType.Error)
        return
    except RuntimeWarning as e:
        hou.ui.displayMessage("Warning: %s" % str(e.message), severity=hou.severityType.Warning)
    #except Exception as e:
    #    hou.ui.displayMessage("Internal Error: %s" % str(e.message), severity=hou.severityType.Error)
    #    return
    hou.ui.setStatusMessage("Success: Nodes pasted!")


# hpasteweb(kwargs['pane'])
Ejemplo n.º 33
0
    def exec_(self, app, dialog):
        self.application = app
        if hou.applicationVersion()[0] <= 15:
            self.application.setStyle('CleanLooks')
        else:
            self.application.setStyle('Fusion')

        hou.ui.addEventLoopCallback(self.processEvents)
        dialog.exec_()
Ejemplo n.º 34
0
	def sm_render_getDeadlineParams(self, origin, dlParams, homeDir):
		dlParams["pluginInfoFile"] = os.path.join( homeDir, "temp", "houdini_plugin_info.job" )
		dlParams["jobInfoFile"] = os.path.join(homeDir, "temp", "houdini_submit_info.job" )

		dlParams["jobInfos"]["Plugin"] = "Houdini"
		dlParams["jobInfos"]["Comment"] = "Prism-Submission-Houdini_%s" % origin.className

		dlParams["pluginInfos"]["OutputDriver"] = origin.node.path()
		dlParams["pluginInfos"]["IgnoreInputs"] = "True"

		if int(self.core.rfManagers["Deadline"].deadlineCommand( ["-version",] ).split(".")[0][1:]) > 9:
			dlParams["pluginInfos"]["Version"] = "%s.%s" % (hou.applicationVersion()[0], hou.applicationVersion()[1])
		else:
			dlParams["pluginInfos"]["Version"] = hou.applicationVersion()[0]

		if hasattr(origin, "chb_resOverride") and origin.chb_resOverride.isChecked():
			dlParams["pluginInfos"]["Width"] = origin.sp_resWidth.value()
			dlParams["pluginInfos"]["Height"] = origin.sp_resHeight.value()
Ejemplo n.º 35
0
    def exec_(self, app, dialog):
        self.application = app
        if hou.applicationVersion()[0] <= 15:
            self.application.setStyle('CleanLooks')
        else:
            self.application.setStyle('Fusion')

        hou.ui.addEventLoopCallback(self.processEvents)
        dialog.exec_()
Ejemplo n.º 36
0
    def exec_(self, app, dialog):
        self.application = app
        app_version = hou.applicationVersion()[0]
        if app_version <= 15:
            self.application.setStyle('CleanLooks')
        elif 15 < app_version <= 17:
            self.application.setStyle('Fusion')

        hou.ui.addEventLoopCallback(self.processEvents)
        dialog.exec_()
Ejemplo n.º 37
0
 def need_to_change_theme(self):
     import hou
     if '*' in self.theme_gb.title():
         if hou.applicationVersion()[0] >= 16:
             a = QMessageBox.question(self, 'Unsaved changes', 'Undo changes in the theme "%s"?' % self.theme['name'])
         else:
             a = QMessageBox.question(self, 'Unsaved changes',
                                      'Undo changes in the theme "%s"?' % self.theme['name'], QMessageBox.Yes | QMessageBox.No)
         return a == QMessageBox.Yes
     return True
Ejemplo n.º 38
0
    def get_output_path(cls, node):
        """
        Returns the evaluated output path for the supplied node.
        """

        output_parm = node.parm(cls.NODE_OUTPUT_PATH_PARM)
        if hou.applicationVersion()[0] >= 18:
            return hou.text.expandString(output_parm.evalAsString())
        else:
            return hou.expandString(output_parm.evalAsString())
Ejemplo n.º 39
0
    def process(self, instance):
        import math

        import hou

        node = instance[0]
        collection = instance.data["collection"]

        job_data = {}
        plugin_data = {}
        if "deadlineData" in instance.data:
            job_data = instance.data["deadlineData"]["job"].copy()
            plugin_data = instance.data["deadlineData"]["plugin"].copy()

        # Setting job data.
        job_data["Plugin"] = "Houdini"

        # Replace houdini frame padding with Deadline padding
        fmt = "{head}" + "#" * collection.padding + "{tail}"
        job_data["OutputFilename0"] = collection.format(fmt)
        job_data["Priority"] = instance.data["deadlinePriority"]
        job_data["Pool"] = instance.data["deadlinePool"]
        job_data["ConcurrentTasks"] = instance.data["deadlineConcurrentTasks"]

        # Frame range
        start_frame = int(node.parm("f1").eval())
        end_frame = int(node.parm("f2").eval())
        step_frame = int(node.parm("f3").eval())

        if node.parm("trange").eval() == 0:
            start_frame = end_frame = int(hou.frame())

        job_data["Frames"] = "{0}-{1}x{2}".format(start_frame, end_frame,
                                                  step_frame)

        # Chunk size
        job_data["ChunkSize"] = instance.data["deadlineChunkSize"]
        if len(list(collection)) == 1:
            job_data["ChunkSize"] = str(end_frame)
        else:
            tasks = (end_frame - start_frame + 1.0) / step_frame
            chunks = (end_frame - start_frame + 1.0) / job_data["ChunkSize"]
            # Deadline can only handle 5000 tasks maximum
            if tasks > 5000 and chunks > 5000:
                job_data["ChunkSize"] = str(int(math.ceil(tasks / 5000.0)))

        # Setting plugin data
        plugin_data["OutputDriver"] = node.path()
        plugin_data["Version"] = str(hou.applicationVersion()[0])
        plugin_data["IgnoreInputs"] = "0"
        plugin_data["SceneFile"] = instance.context.data["currentFile"]

        # Setting data
        data = {"job": job_data, "plugin": plugin_data}
        instance.data["deadlineData"] = data
Ejemplo n.º 40
0
def generate_completes(force=False):
    # check parsed functions
    cache_file = vex_settings.get_autocomplete_cache_file()
    if os.path.exists(cache_file) and not force:
        return True
    # get vcc
    vcc = os.path.join(hou.getenv('HFS'), 'bin', 'vcc').replace('/','\\')
    if os.name == 'nt':
        vcc = vcc + '.exe'
    if not os.path.exists(vcc):
        return False
    # generate new
    funcs = {}
    attrs = {}
    process = QProcess()
    process.start(' '.join([vcc, '-X']))
    process.waitForFinished()
    lines =  str(process.readAll()).split('\n')
    for context in lines:
        if context:
            process.start(' '.join([vcc, '-X', context]))
            process.waitForFinished()
            context_lines =  str(process.readAll())
            # variables
            variables = re.search(r'Global Variables:(.*)Control Statements:', context_lines, re.DOTALL)
            if variables:
                lines = variables.group(1).strip().split('\n')
                for l in lines:
                    s = l.split()
                    if len(s)==3:
                        attrs[s[-1]] = s[-2]
            # functions
            pat = r'^\s*(\w+\[?\]?)\s(\w+)(\(.+\))'
            for l in context_lines.split('\n'):
                func = re.findall(pat, str(l))
                if func:
                    f_name = func[0][1]
                    f_args = func[0][2]
                    if f_name in funcs:
                        if not f_args in funcs[f_name].get('args', []):
                            funcs[f_name]['args'].append(f_args)
                    else:
                        funcs[f_name] = {'args':  [f_args]}
    # parse help if Houdini 15
    if hou.applicationVersion()[0] >= 15:
        funcs = parse_help(funcs)
    # save to cache
    if os.path.exists(cache_file):
        comp = json.load(open(cache_file))
    else:
        comp = {}
    comp['functions'] = funcs
    comp['attributes'] = attrs
    json.dump(comp, open(cache_file, 'w'))
    return True
Ejemplo n.º 41
0
    def __init__(self):
        super(iconsWidgetClass, self).__init__()
        self.vLy = QVBoxLayout(self)

        self.fLy = QHBoxLayout()
        self.vLy.addLayout(self.fLy)
        label = QLabel('Filter: ')
        self.fLy.addWidget(label)

        self.clear_btn = QPushButton('')
        self.clear_btn.setIcon(hou.ui.createQtIcon('BUTTONS_remove'))
        self.clear_btn.clicked.connect(self.fill)
        self.clear_btn.setFixedSize(QSize(20,20))
        self.fLy.addWidget(self.clear_btn)
        @self.clear_btn.clicked.connect
        def clearFilter():
            if self.filter.text():
                self.filter.setText('')
                self.fill()

        self.filter = QLineEdit()
        self.filter.returnPressed.connect(self.fill)
        self.fLy.addWidget(self.filter)
        self.search_btn = QPushButton('Search')
        self.search_btn.clicked.connect(self.fill)
        self.fLy.addWidget(self.search_btn)

        # self.btn = QPushButton('Clear')
        # self.btn.clicked.connect(self.clearList)
        # self.vLy.addWidget(self.btn)

        self.scrollArea = QScrollArea(self)
        self.vLy.addWidget(self.scrollArea)
        self.scrollArea.setWidgetResizable(True)
        self.sawc = QFrame()
        self.ly = QVBoxLayout(self.sawc)
        self.scrollArea.setWidget(self.sawc)

        hfs = hou.getenv('HFS')
        if hou.applicationVersion()[0] < 15:
            path = os.path.join(hfs,'houdini/help/icons/large')
        else:
            path = os.path.join(hfs,'houdini/help/icons.zip')
        self.icons = {}
        self.content = None

        if os.path.exists(path):
            self.path = path
            self.findIcons()
            self.fill()
        else:
            err = QLabel('Icons not found!')
            err.setStyleSheet('font-size:25px;')
            err.setAlignment(Qt.AlignHCenter|Qt.AlignTop)
            self.ly.addWidget(err)
Ejemplo n.º 42
0
    def post_app_init(self):
        """
        Init that runs after all apps have been loaded.
        """

        tk_houdini = self.import_module("tk_houdini")
        bootstrap = tk_houdini.bootstrap

        if bootstrap.g_temp_env in os.environ:
            if self.has_ui:
                # setup houdini menus
                menu_file = os.path.join(os.environ[bootstrap.g_temp_env],
                                         'MainMenuCommon')

                # as of houdini 12.5 add .xml
                if hou.applicationVersion() > (12, 5, 0):
                    menu_file = menu_file + ".xml"

                menu = tk_houdini.MenuGenerator(self)
                if not os.path.exists(menu_file):
                    # just create the xml for the menus
                    menu.create_menu(menu_file)

                # get map of id to callback
                self._callback_map = menu.callback_map()

            # Figure out the tmp OP Library path for this session
            oplibrary_path = os.environ[bootstrap.g_temp_env].replace(
                "\\", "/")

            # Setup the OTLs that need to be loaded for the Toolkit apps
            self._load_otls(oplibrary_path)

        if self.has_ui:
            # startup Qt
            from tank.platform.qt import QtGui
            from tank.platform.qt import QtCore

            app = QtGui.QApplication.instance()
            if app is None:
                # create the QApplication
                sys.argv[0] = 'Shotgun'
                app = QtGui.QApplication(sys.argv)
                app.setQuitOnLastWindowClosed(False)
                app.setApplicationName(sys.argv[0])

                # tell QT to interpret C strings as utf-8
                utf8 = QtCore.QTextCodec.codecForName("utf-8")
                QtCore.QTextCodec.setCodecForCStrings(utf8)

                # set the stylesheet
                self._initialize_dark_look_and_feel()

            tk_houdini.python_qt_houdini.exec_(app)
Ejemplo n.º 43
0
    def __init__(self, name="", extensions=None, version=None):
        super(Houdini, self).__init__(name, extensions, version)

        from stalker import Repository
        # re initialize repo vars
        for repo in Repository.query.all():
            env_var_name = repo.env_var
            value = repo.path
            self.set_environment_variable(env_var_name, value)

        self.name = '%s%s' % (self.name, hou.applicationVersion()[0])
Ejemplo n.º 44
0
        def apply_stylesheet(self):
            import hou
            self._changing_stylesheet = True
            try:
                # This is only safe in pre-H16. If we do this in 16 it destroys
                # some styling in Houdini itself.
                if self.parent() and hou.applicationVersion() < (16, 0, 0):
                    self.parent().setStyleSheet("")

                engine._apply_external_styleshet(bundle, self)

                # Styling in H16+ is very different than in earlier versions of
                # Houdini. The result is that we have to be more careful about
                # behavior concerning stylesheets, because we might bleed into
                # Houdini itself if we change qss on parent objects or make use
                # of QStyles on the QApplication.
                #
                # Below, we're combining the engine-level qss with whatever is
                # already assigned to the widget. This means that the engine
                # styling is helping patch holes in any app- or framework-level
                # qss that might have already been applied.
                if hou.applicationVersion() >= (16, 0, 0):
                    qss_file = engine._get_engine_qss_file()
                    with open(qss_file, "rt") as f:
                        qss_data = f.read()
                        qss_data = engine._resolve_sg_stylesheet_tokens(qss_data)
                        qss_data = qss_data.replace("{{ENGINE_ROOT_PATH}}", engine._get_engine_root_path())
                        self.setStyleSheet(self.styleSheet() + qss_data)
                        self.update()

                    # We have some funky qss behavior in H16 that requires us to
                    # kick the parent's stylesheet by reassigning it as is. Not
                    # sure what causes the problem, but this does resolve it. The
                    # original symptoms were some widgets not changing after applying
                    # the engine's stylesheet, while others did.
                    if self.parent():
                        self.parent().setStyleSheet(self.parent().styleSheet())
            except Exception, e:
                engine.logger.warning(
                    "Unable to re-apply stylesheet for panel: %s %s" % (title, e)
                )
Ejemplo n.º 45
0
    def _panels_supported(self):
        """
        Returns True if panels are supported for current Houdini version.
        """
        
        ver = hou.applicationVersion()
    
        # first version where saving python panel in desktop was fixed
        if ver >= (15, 0, 272):
            return True

        return False
Ejemplo n.º 46
0
    def post_app_init(self):
        """
        Init that runs after all apps have been loaded.
        """
        
        tk_houdini = self.import_module("tk_houdini")
        bootstrap = tk_houdini.bootstrap

        if bootstrap.g_temp_env in os.environ:
            if self.has_ui:
                # setup houdini menus
                menu_file = os.path.join(os.environ[bootstrap.g_temp_env], 'MainMenuCommon')

                # as of houdini 12.5 add .xml
                if hou.applicationVersion() > (12, 5, 0):
                    menu_file = menu_file + ".xml"

                menu = tk_houdini.MenuGenerator(self)
                if not os.path.exists(menu_file):
                    # just create the xml for the menus
                    menu.create_menu(menu_file)

                # get map of id to callback
                self._callback_map = menu.callback_map()

            # Figure out the tmp OP Library path for this session
            oplibrary_path = os.environ[bootstrap.g_temp_env].replace("\\", "/")

            # Setup the OTLs that need to be loaded for the Toolkit apps
            self._load_otls(oplibrary_path)

        if self.has_ui:
            # startup Qt
            from tank.platform.qt import QtGui
            from tank.platform.qt import QtCore

            app = QtGui.QApplication.instance()
            if app is None:
                # create the QApplication
                sys.argv[0] = 'Shotgun'
                app = QtGui.QApplication(sys.argv)
                app.setQuitOnLastWindowClosed(False)
                app.setApplicationName(sys.argv[0])

                # tell QT to interpret C strings as utf-8
                utf8 = QtCore.QTextCodec.codecForName("utf-8")
                QtCore.QTextCodec.setCodecForCStrings(utf8)

                # set the stylesheet
                self._initialize_dark_look_and_feel()

            tk_houdini.python_qt_houdini.exec_(app)
Ejemplo n.º 47
0
    def create_menu(self, xml_path):
        """ Create the Shotgun Menu """

        import hou

        # houdini 15+ allows for dynamic menu creation, so do that if possible.
        # otherwise, fallback to the static menu
        if hou.applicationVersion()[0] >= 15:
            self._engine.log_debug("Constructing dynamic Shotgun menu.")
            self._create_dynamic_menu(xml_path)
        else:
            self._engine.log_debug("Constructing static Shotgun menu.")
            self._create_static_menu(xml_path)
Ejemplo n.º 48
0
	def torus( self ) :
		obj = hou.node( "/obj" )
		geo = obj.createNode( "geo", run_init_scripts=False )
		torus = geo.createNode( "torus" )
		facet = torus.createOutputNode( "facet" )
		facet.parm( "postnml" ).set( True )
		mountain = facet.createOutputNode( "mountain" )
		if hou.applicationVersion()[0] >= 16:
			mountain.parm("offsetx").setExpression("$FF")
		else:
			mountain.parm("offset1").setExpression( "$FF" )

		return mountain
Ejemplo n.º 49
0
	def testStandardAttributeConversion( self ) :
		
		merge = self.buildScene()
		color = merge.createOutputNode( "color" )
		color.parm( "colortype" ).set( 2 )
		rest = color.createOutputNode( "rest" )
		scale = rest.createOutputNode( "attribcreate" )
		scale.parm( "name1" ).set( "pscale" )
		scale.parm( "value1v1" ).setExpression( "$PT" )
		uvunwrap = scale.createOutputNode( "uvunwrap" )
		
		converter = IECoreHoudini.FromHoudiniGroupConverter( uvunwrap )
		result = converter.convert()
		for child in result.children() :
			if hou.applicationVersion()[0] >= 15 :
				self.assertEqual( child.keys(), ['Cs', 'P', 'Pref', 'accel', 'born', 'event', 'generator', 'generatorIndices', 'id', 'life', 'nextid', 'parent', 'pstate', 's', 'source', 't', 'v', 'width'] )
			else :
				self.assertEqual( child.keys(), ['Cs', 'P', 'Pref', 'accel', 'born', 'event', 'generator', 'generatorIndices', 'id', 'life', 'nextid', 'parent', 'pstate', 's', 'source', 't', 'v', 'varmap', 'width'] )

			self.assertTrue( child.arePrimitiveVariablesValid() )
			self.assertEqual( child["P"].data.getInterpretation(), IECore.GeometricData.Interpretation.Point )
			self.assertEqual( child["Pref"].data.getInterpretation(), IECore.GeometricData.Interpretation.Point )
			self.assertEqual( child["accel"].data.getInterpretation(), IECore.GeometricData.Interpretation.Vector )
			self.assertEqual( child["v"].data.getInterpretation(), IECore.GeometricData.Interpretation.Vector )
		
		converter["convertStandardAttributes"].setTypedValue( False )
		result = converter.convert()
		for child in result.children() :
			if hou.applicationVersion()[0] >= 15 :
				self.assertEqual( child.keys(), ['Cd', 'P', 'accel', 'born', 'event', 'generator', 'generatorIndices', 'id', 'life', 'nextid', 'parent', 'pscale', 'pstate', 'rest', 'source', 'uv', 'v'] )
			else :
				self.assertEqual( child.keys(), ['Cd', 'P', 'accel', 'born', 'event', 'generator', 'generatorIndices', 'id', 'life', 'nextid', 'parent', 'pscale', 'pstate', 'rest', 'source', 'uv', 'v', 'varmap'] )
			self.assertTrue( child.arePrimitiveVariablesValid() )
			self.assertEqual( child["P"].data.getInterpretation(), IECore.GeometricData.Interpretation.Point )
			self.assertEqual( child["rest"].data.getInterpretation(), IECore.GeometricData.Interpretation.Point )
			self.assertEqual( child["accel"].data.getInterpretation(), IECore.GeometricData.Interpretation.Vector )
			self.assertEqual( child["v"].data.getInterpretation(), IECore.GeometricData.Interpretation.Vector )
Ejemplo n.º 50
0
	def testAnimatingGeometry( self ) :
		curves = self.createCurves( 4 )
		mountain = curves.createOutputNode( "mountain" )
		if hou.applicationVersion()[0] >= 16:
			mountain.parm("offsetx").setExpression( "$FF" )
		else:
			mountain.parm( "offset1" ).setExpression( "$FF" )
		converter = IECoreHoudini.FromHoudiniCurvesConverter( mountain )
		hou.setFrame( 1 )
		result1 = converter.convert()
		hou.setFrame( 2 )
		converter = IECoreHoudini.FromHoudiniCurvesConverter( mountain )
		result2 = converter.convert()
		self.assertNotEqual( result1["P"].data, result2["P"].data )
		self.assertNotEqual( result1, result2 )
Ejemplo n.º 51
0
    def init_engine(self):
        """
        Main initialization entry point.
        """        

        self.logger.debug("%s: Initializing..." % self)

        if hou.applicationVersion()[0] < 14:
            raise sgtk.TankError(
                "Your version of Houdini is not supported. Currently, Toolkit "
                "only supports version 14+."
            )

        # keep track of if a UI exists
        self._ui_enabled = hasattr(hou, 'ui')
Ejemplo n.º 52
0
    def pre_app_init(self):
        """
        Called at startup, but after QT has been initialized.
        """

        if not self._ui_enabled:
            return

        if hou.applicationVersion()[0] >= 15:
            # In houdini 15+, we can use the dynamic menus and shelf api to
            # properly handle cases where a file is loaded outside of a SG
            # context. Make sure the timer that looks for current file changes
            # is running.
            tk_houdini = self.import_module("tk_houdini")
            tk_houdini.ensure_file_change_timer_running()
Ejemplo n.º 53
0
	def testInterpretation( self ) :
		
		merge = self.buildScene()
		converter = IECoreHoudini.FromHoudiniGroupConverter( merge )
		result = converter.convert()
		expectedKeys = ['Cs', 'P', 'accel', 'born', 'event', 'generator', 'generatorIndices', 'id', 'life', 'nextid', 'parent', 'pstate', 'source', 'v', 'varmap']
		if hou.applicationVersion()[0] >= 13 :
			expectedKeys.remove( "varmap" )
		
		for child in result.children() :
			self.assertTrue( child.isInstanceOf( IECore.TypeId.Primitive ) )
			self.assertEqual( sorted(child.keys()), expectedKeys )
			self.assertEqual( child["P"].data.getInterpretation(), IECore.GeometricData.Interpretation.Point )
			self.assertEqual( child["accel"].data.getInterpretation(), IECore.GeometricData.Interpretation.Vector )
			self.assertEqual( child["life"].data.getInterpretation(), IECore.GeometricData.Interpretation.None )
			self.assertEqual( child["v"].data.getInterpretation(), IECore.GeometricData.Interpretation.Vector )
Ejemplo n.º 54
0
		def addSopTags( node, tag, primRange ) :

			if hou.applicationVersion()[0] > 15:
				group = node.createOutputNode( "grouprange" )
				group.parm("groupname1").set(tag)
				group.parm("start1").set(primRange[0])
				group.parm("end1").set(primRange[1])
				group.parm("selecttotal1").set(1)
				group.parm("method1").set(0)
				group.setRenderFlag(True)
			else:
				group = node.createOutputNode("group")
				group.parm( "crname" ).set( tag )
				group.parm( "groupop" ).set( 1 ) # by range
				group.parm( "rangestart" ).set( primRange[0] )
				group.parm( "rangeend" ).deleteAllKeyframes()
				group.parm( "rangeend" ).set( primRange[1] )
				group.parm( "select2" ).set( 1 )
				group.setRenderFlag( True )
Ejemplo n.º 55
0
	def testNumericPresetMenus( self ) :

		# at present, Int/FloatParameters only support presetsOnly presets, due to the limitations of hou.MenuParmTemplate
		( holder, fn ) = self.testOpHolder()
		holder.createInputNode( 0, "box" )
		fn.setOp( "parameters/primitives/preset", 1 )
		parm = holder.parm( "parm_switch" )
		self.failUnless( isinstance( parm, hou.Parm ) )
		template = parm.parmTemplate()
		self.failUnless( isinstance( template, hou.MenuParmTemplate ) )
		# the int values are stored as strings in this crazy Houdini world
		self.assertEqual( template.menuItems(), ( "20", "30" ) )
		self.assertEqual( template.menuLabels(), ( "A", "B" ) )
		self.assertEqual( template.defaultValue(), 0 )
		self.assertEqual( template.defaultValueAsString(), "20" )
		self.assertEqual( parm.eval(), 0 )
		self.assertEqual( parm.evalAsString(), "20" )

		# but on the op values are really the ints we require
		op = fn.getOp()
		self.assertEqual( op["switch"].getTypedValue(), 20 )
		parm.set( 1 )
		holder.cook()
		self.assertEqual( op["switch"].getTypedValue(), 30 )
		# Houdini 16 does not allow ordered menu parms to be set to non-menu items
		# if the parm is set to an index, and the index doesn't exist, then the parm is set to the closest item menu
		if hou.applicationVersion()[0] < 16:
			parm.set( 2 )
			self.assertRaises( hou.OperationFailed, holder.cook )
			parm.set( -1 )
			self.assertRaises( hou.OperationFailed, holder.cook )
			parm.set( 0 )
			holder.cook()
			self.failUnless( not holder.errors() )

		newHolder = holder.parent().createNode( "ieOpHolder" )
		newFn = IECoreHoudini.FnOpHolder( newHolder )
		op["switch"].setTypedValue( 30 )
		newFn.setOp( op )
		newParm = newHolder.parm( "parm_switch" )
		self.assertEqual( newParm.eval(), 1 )
		self.assertEqual( newParm.evalAsString(), "30" )
    def update_complete_list(self, names=None):
        self.clear()
        if names:
            for i, n in enumerate(names):
                item = QListWidgetItem(self)
                # h14
                if hou.applicationVersion()[0] <= 14:
                    label = CompleterLabel(n, i%2, self)
                    self.setItemWidget(item, label)
                else:
                # h15
                    item.setText(n.name)

                item.setData(32, n)
                self.addItem(item)
            self.setCurrentRow(0)
            self.showMe()
        else:
            self.hideMe()
        self.e.update()
Ejemplo n.º 57
0
 def __init__(self, text, parent, desk):
     super(container, self).__init__()
     hbox = QHBoxLayout(self)
     hbox.setSpacing(0)
     hbox.setContentsMargins(0,0,0,0)
     # input widget
     self.edit = inputWidget.inputClass(parent, desk)
     self.edit.executeSignal.connect(parent.executeSelected)
     if text:
         self.edit.addText(text)
     # if not context == 'hou':
         # line number
     if context == 'hou':
         import hou
         if hou.applicationVersion()[0] > 14:
             hbox.addWidget(self.edit)
             return
     self.lineNum = numBarWidget.lineNumberBarClass(self.edit, self)
     hbox.addWidget(self.lineNum)
     hbox.addWidget(self.edit)
	def testAnimatingGeometry( self ) :
		obj = hou.node( "/obj" )
		geo = obj.createNode( "geo", run_init_scripts=False )
		torus = geo.createNode( "torus" )
		facet = geo.createNode( "facet" )
		facet.parm("postnml").set(True)
		mountain = geo.createNode( "mountain" )
		if hou.applicationVersion()[0] >= 16:
			mountain.parm( "offsetx" ).setExpression( "$FF" )
		else:
			mountain.parm("offset1").setExpression( "$FF" )
		facet.setInput( 0, torus )
		mountain.setInput( 0, facet )
		converter = IECoreHoudini.FromHoudiniPolygonsConverter( mountain )
		hou.setFrame( 1 )
		mesh1 = converter.convert()
		hou.setFrame( 2 )
		converter = IECoreHoudini.FromHoudiniPolygonsConverter( mountain )
		mesh2 = converter.convert()
		self.assertNotEqual( mesh1["P"].data, mesh2["P"].data )
		self.assertNotEqual( mesh1, mesh2 )