예제 #1
0
def findOpacityMap(material):
    """
		\remarks	looks for the opacity map for the inputed material based on its type
		\param		material	<Py3dsMax.mxs.Material>
		\return		<Py3dsMax.mxs.Map> opacityMap || None
	"""
    cls = mxs.classof(material)

    # return a standard material's opacity map
    if (cls == mxs.StandardMaterial):
        if material.opacityMapEnable:
            return material.opacityMap

    # return a vray material's opacity map
    elif (cls in (mxs.VrayMtl, mxs.VRaySkinMtl)):
        if material.texmap_opacity_on:
            return material.texmap_opacity

    # return a vray light material's opacity map
    elif (cls == mxs.VrayLightMtl):
        if material.opacity_texmap_on:
            return material.opacity_texmap

    # return a matte's opactiy map
    elif (cls in (mxs.Matte_Shadow_Reflection_mi,
                  mxs.mr_Matte_Shadow_Reflection_Mtl)):
        if material.opacity_connected:
            return material.opacity_shader

    # return an arch design's opacity map
    elif (cls == mxs.Arch___Design__mi):
        if material.cutoutmap_on:
            return material.cutout_map

    return None
예제 #2
0
def canDisableCaches( object ):
	# make sure this is a valid node
	if ( not mxs.isValidNode( object ) ):
		return True
	
	# make sure this object is not hidden, or a HairFXView object
	if ( not object.ishidden or mxs.classof( object ) == mxs.HairFXView ):
		return False
	
	# make sure all instances of this object are hidden
	instances = mxs.pyhelper.getInstances( object )
	for inst in instances:
		if ( not inst.ishidden ):
			return False
		
	# make sure all children of this object can be disabled
	for child in object.children:
		if ( not canDisableCaches( child ) ):
			return False
	
	# check all dependent nodes of this object can be disabled
	for dep in mxs.refs.dependentNodes( object ):
		if ( not canDisableCaches( object ) ):
			return False
	
	return True
예제 #3
0
	def _nativeSubmaterials(self):
		"""The native submaterials of this material."""
		mtl	= self._nativePointer
		# Processing multi/sub materials directly is faster than the getnumsubs
		# system.
		if mxs.classof(mtl) == mxs.MultiMaterial:
			return [mtl[i] for i in range(mtl.numsubs)]
		else:
			# Process all other kinds of materials.
			get_submtl = mxs.getSubMtl
			return [get_submtl(mtl, i+1) for i in range(mxs.getNumSubMtls(mtl))]
예제 #4
0
 def _nativeSubmaterials(self):
     """The native submaterials of this material."""
     mtl = self._nativePointer
     # Processing multi/sub materials directly is faster than the getnumsubs
     # system.
     if mxs.classof(mtl) == mxs.MultiMaterial:
         return [mtl[i] for i in range(mtl.numsubs)]
     else:
         # Process all other kinds of materials.
         get_submtl = mxs.getSubMtl
         return [
             get_submtl(mtl, i + 1) for i in range(mxs.getNumSubMtls(mtl))
         ]
예제 #5
0
    def cameraType(self):
        """
                \remarks	implements the AbstractSceneCamera.cameraType method to determine what type of camera this instance is
                \return		<cross3d.constants.CameraType>
        """
        cls = mxs.classof(self._nativePointer)
        if cls in (mxs.FreeCamera, mxs.TargetCamera):
            return CameraType.Standard

        elif cls == mxs.Physical:
            return CameraType.Physical

        elif cls == mxs.VRayPhysicalCamera:
            return CameraType.Physical
        return 0
예제 #6
0
    def cameraType(self):
        """
                \remarks	implements the AbstractSceneCamera.cameraType method to determine what type of camera this instance is
                \return		<cross3d.constants.CameraType>
        """
        cls = mxs.classof(self._nativePointer)
        if cls in (mxs.FreeCamera, mxs.TargetCamera):
            return CameraType.Standard

        elif cls == mxs.Physical:
            return CameraType.Physical

        elif cls == mxs.VRayPhysicalCamera:
            return CameraType.Physical
        return 0
예제 #7
0
	def rendererType( self ):
		"""
			\remarks	implements AbstractSceneRenderer.rendererType to return the renderer type for this instance
			\sa			setRendererType
			\return		<cross3d.constants.RendererType>
		"""
		from cross3d.constants import RendererType
		classname = str(mxs.classof(self._nativePointer)).lower()
		
		if ( classname == 'default_scanline_renderer' ):
			return RendererType.Scanline
		elif ( classname == 'mental_ray_renderer' ):
			return RendererType.MentalRay
		elif ( 'v_ray' in classname ):
			return RendererType.VRay
		
		return 0
예제 #8
0
    def filmWidth(self):
        """
                \remarks	Returns the film_width of the camera.
                \return		film_width (float)
        """
        cls = mxs.classof(self._nativePointer)
        width = None
        if cls == mxs.VRayPhysicalCamera:
            width = self._nativePointer.film_width

        elif cls == mxs.Physical:
            width = self._nativePointer.film_width_mm

        if not width:
            
            # If we failed to get a width from a camera, return the scene aperture setting.
            width = mxs.getRendApertureWidth()

        return width
예제 #9
0
    def filmWidth(self):
        """
                \remarks	Returns the film_width of the camera.
                \return		film_width (float)
        """
        cls = mxs.classof(self._nativePointer)
        width = None
        if cls == mxs.VRayPhysicalCamera:
            width = self._nativePointer.film_width

        elif cls == mxs.Physical:
            width = self._nativePointer.film_width_mm

        if not width:

            # If we failed to get a width from a camera, return the scene aperture setting.
            width = mxs.getRendApertureWidth()

        return width
예제 #10
0
    def filmHeight(self):
        """
                \remarks    Returns the film_height of the camera.
                \return     film_height (float)
        """
        cls = mxs.classof(self._nativePointer)
        height = None
        if cls == mxs.VRayPhysicalCamera:

            # TODO: Why is that wrapped in a try except?
            try:
                height = self._nativePointer.film_height
            except AttributeError:
                pass

        elif cls == mxs.Physical:
            height = self._nativePointer.film_height_mm

        if not height:
            # If we failed to get a width from a camera, return the scene aperture setting.
            height = self.filmWidth() * (mxs.renderPixelAspect / mxs.getRendImageAspect())

        return height
예제 #11
0
    def filmHeight(self):
        """
                \remarks    Returns the film_height of the camera.
                \return     film_height (float)
        """
        cls = mxs.classof(self._nativePointer)
        height = None
        if cls == mxs.VRayPhysicalCamera:

            # TODO: Why is that wrapped in a try except?
            try:
                height = self._nativePointer.film_height
            except AttributeError:
                pass

        elif cls == mxs.Physical:
            height = self._nativePointer.film_height_mm

        if not height:
            # If we failed to get a width from a camera, return the scene aperture setting.
            height = self.filmWidth() * (mxs.renderPixelAspect /
                                         mxs.getRendImageAspect())

        return height
예제 #12
0
    def keyframeTimeControllers(self, alembic=True):
        """ Takes all Alembic, PC and TMC time controllers and keyframe their original time controllers.

		This is used as a base setup for further time alterations.

		Returns:
			SceneAnimationController|boolean: The bezier float keyframed controller used to control time.
		"""

        np = self._nativePointer
        timeController = None
        frameRate = self._scene.animationFPS()

        # Processing Alembic controllers.
        alembicControllers = mxs.getClassInstances(
            mxs.Alembic_Float_Controller, target=np)
        alembicControllers += mxs.getClassInstances(mxs.Alembic_Xform,
                                                    target=np)
        alembicControllers += mxs.getClassInstances(mxs.Alembic_Mesh_Geometry,
                                                    target=np)
        alembicControllers += mxs.getClassInstances(mxs.Alembic_Mesh_Normals,
                                                    target=np)
        for alembicController in alembicControllers:

            # Instantiating if we already computed the time controller.
            if not timeController:

                # Unfortunately the start and end frame of the cache data is not stored on the controller so we have to parse the file.
                import cask
                archive = cask.Archive(str(alembicController.path))
                item = archive.top.children[str(alembicController.identifier)]

                # Sometimes the identifier will point to a Xform object.
                # Unfortunately I did not find a way to access the sample count from there.
                # So instead I am digging through the hierarchy.
                while item.children:
                    item = item.children[item.children.keys()[0]]

                properties = item.iobject.getProperties()
                geometry = properties.getProperty(0)
                core = geometry.getProperty(0)
                sampleCount = core.getNumSamples()
                startTime = core.getTimeSampling().getSampleTime(0)
                endTime = core.getTimeSampling().getSampleTime(
                    (sampleCount - 1))

                # Creating the controller.
                timeController = mxs.bezier_float()
                frames = [(round(startTime * frameRate), startTime),
                          (round(endTime * frameRate), endTime)]
                for frame, value in frames:
                    k = mxs.addNewKey(timeController, frame)
                    k.value = value
                    k.inTangentType = mxs.pyhelper.namify('linear')
                    k.outTangentType = mxs.pyhelper.namify('linear')

            # Assigning the controller.
            mxs.setPropertyController(alembicController, 'time',
                                      timeController)

        # Processing TMCs and PCs.
        nativeCaches = mxs.getClassInstances(
            mxs.Transform_Cache, target=np) + mxs.getClassInstances(
                mxs.Point_Cache, target=np)
        for nativeCache in nativeCaches:

            # Unfortunately the start and end frame of the cache data is not stored on the controller so we have to parse the file.
            if mxs.classof(nativeCache) == mxs.Point_Cache:
                from blur3d.lib.pclib import PointCacheInfo
                cacheInfo = PointCacheInfo.read(nativeCache.filename,
                                                header_only=True)

            elif mxs.classof(nativeCache) == mxs.Transform_Cache:
                # Ensure file exists
                try:
                    from blur3d.lib.tmclib import TMCInfo
                    cacheInfo = TMCInfo.read(nativeCache.CacheFile,
                                             header_only=True)
                except IOError as e:
                    print "Cache file does not exist: {0}".format(
                        nativeCache.CacheFile)
                    continue

            # Playback type 3 is "Playback Graph".
            nativeCache.playbackType = 3

            # Set the playback frame to a float controller with start and end values pulled from the cache.
            mxs.setPropertyController(nativeCache, 'playbackFrame',
                                      mxs.bezier_float())
            timeController = mxs.getPropertyController(nativeCache,
                                                       'playbackFrame')

            # Set keys on the playback frame cache that matches the current frame rate.
            duration = cacheInfo.end_frame - cacheInfo.start_frame + 1
            frames = [(cacheInfo.start_frame, 0),
                      (cacheInfo.end_frame, duration)]
            for frame, value in frames:
                key = mxs.addNewKey(timeController, frame)
                key.value = value
                key.inTangentType = mxs.pyhelper.namify('linear')
                key.outTangentType = mxs.pyhelper.namify('linear')

        # Processing XMeshes.
        xMeshes = mxs.getClassInstances(mxs.XMeshLoader, target=np)
        for xMesh in xMeshes:

            # Enable curve playback.
            xMesh.enablePlaybackGraph = True

            # Create a new bezier float controller for the time.
            mxs.setPropertyController(xMesh, 'playbackGraphTime',
                                      mxs.bezier_float())
            timeController = mxs.getPropertyController(xMesh,
                                                       'playbackGraphTime')

            # Set keys on the playback in and out frames.
            frames = (xMesh.rangeFirstFrame, xMesh.rangeLastFrame)
            for frame in frames:
                key = mxs.addNewKey(timeController, frame)
                key.value = frame
                key.inTangentType = mxs.pyhelper.namify('linear')
                key.outTangentType = mxs.pyhelper.namify('linear')

        # Processing Ray Fire caches.
        rayFireCaches = mxs.getClassInstances(mxs.RF_Cache, target=np)
        for rayFireCache in rayFireCaches:

            # Enable curve playback.
            xMesh.playUseGraph = True

            # Create a new bezier float controller for the time.
            mxs.setPropertyController(rayFireCache, 'playFrame',
                                      mxs.bezier_float())
            timeController = mxs.getPropertyController(rayFireCache,
                                                       'playFrame')

            # Set keys on the playback in and out frames.
            frames = (xMesh.rangeFirstFrame, xMesh.rangeLastFrame)
            for frame in frames:
                key = mxs.addNewKey(timeController, frame)
                key.value = frame
                key.inTangentType = mxs.pyhelper.namify('linear')
                key.outTangentType = mxs.pyhelper.namify('linear')

        # Returning the time controller if defined.
        if timeController:
            # Making the extrapolation linear.
            linear = mxs.pyhelper.namify('linear')
            mxs.setBeforeORT(timeController, linear)
            mxs.setAfterORT(timeController, linear)
            from cross3d import SceneAnimationController
            return SceneAnimationController(self._scene, timeController)

        return None
예제 #13
0
	def keyframeTimeControllers(self, alembic=True):
		""" Takes all Alembic, PC and TMC time controllers and keyframe their original time controllers.

		This is used as a base setup for further time alterations.

		Returns:
			SceneAnimationController|boolean: The bezier float keyframed controller used to control time.
		"""

		np = self._nativePointer
		timeController = None
		frameRate = self._scene.animationFPS()

		# Processing Alembic controllers.
		alembicControllers = mxs.getClassInstances(mxs.Alembic_Float_Controller, target=np)
		alembicControllers += mxs.getClassInstances(mxs.Alembic_Xform, target=np)
		alembicControllers += mxs.getClassInstances(mxs.Alembic_Mesh_Geometry, target=np)
		alembicControllers += mxs.getClassInstances(mxs.Alembic_Mesh_Normals, target=np)
		for alembicController in alembicControllers:

			# Instantiating if we already computed the time controller.
			if not timeController:

				# Unfortunately the start and end frame of the cache data is not stored on the controller so we have to parse the file.
				import cask
				archive = cask.Archive(str(alembicController.path))
				item = archive.top.children[str(alembicController.identifier)]

				# Sometimes the identifier will point to a Xform object.
				# Unfortunately I did not find a way to access the sample count from there.
				# So instead I am digging through the hierarchy.
				while item.children:
					item = item.children[item.children.keys()[0]]

				properties = item.iobject.getProperties()
				geometry = properties.getProperty(0)
				core = geometry.getProperty(0)
				sampleCount = core.getNumSamples()
				startTime = core.getTimeSampling().getSampleTime(0)
				endTime = core.getTimeSampling().getSampleTime((sampleCount - 1))

				# Creating the controller.
				timeController = mxs.bezier_float()
				frames = [(round(startTime * frameRate), startTime), (round(endTime * frameRate), endTime)]
				for frame, value in frames:
					k = mxs.addNewKey(timeController, frame)
					k.value = value
					k.inTangentType = mxs.pyhelper.namify('linear')
					k.outTangentType = mxs.pyhelper.namify('linear')

			# Assigning the controller.
			mxs.setPropertyController(alembicController, 'time', timeController)

		# Processing TMCs and PCs.
		nativeCaches = mxs.getClassInstances(mxs.Transform_Cache, target=np) + mxs.getClassInstances(mxs.Point_Cache, target=np)
		for nativeCache in nativeCaches:

			# Unfortunately the start and end frame of the cache data is not stored on the controller so we have to parse the file.
			if mxs.classof(nativeCache) == mxs.Point_Cache:
				from blur3d.lib.pclib import PointCacheInfo
				cacheInfo = PointCacheInfo.read(nativeCache.filename, header_only=True)

			elif mxs.classof(nativeCache) == mxs.Transform_Cache:
				# Ensure file exists
				try:
					from blur3d.lib.tmclib import TMCInfo
					cacheInfo = TMCInfo.read(nativeCache.CacheFile, header_only=True)
				except IOError as e:
					print "Cache file does not exist: {0}".format(nativeCache.CacheFile)
					continue

			# Playback type 3 is "Playback Graph".
			nativeCache.playbackType = 3

			# Set the playback frame to a float controller with start and end values pulled from the cache.
			mxs.setPropertyController(nativeCache, 'playbackFrame', mxs.bezier_float())
			timeController = mxs.getPropertyController(nativeCache, 'playbackFrame')

			# Set keys on the playback frame cache that matches the current frame rate.
			duration = cacheInfo.end_frame - cacheInfo.start_frame + 1
			frames = [(cacheInfo.start_frame, 0), (cacheInfo.end_frame, duration)]
			for frame, value in frames:
				key = mxs.addNewKey(timeController, frame)
				key.value = value
				key.inTangentType = mxs.pyhelper.namify('linear')
				key.outTangentType = mxs.pyhelper.namify('linear')

		# Processing XMeshes.
		xMeshes = mxs.getClassInstances(mxs.XMeshLoader, target=np)
		for xMesh in xMeshes:

			# Enable curve playback.
			xMesh.enablePlaybackGraph = True

			# Create a new bezier float controller for the time.
			mxs.setPropertyController(xMesh, 'playbackGraphTime', mxs.bezier_float())
			timeController = mxs.getPropertyController(xMesh, 'playbackGraphTime')

			# Set keys on the playback in and out frames.
			frames = (xMesh.rangeFirstFrame, xMesh.rangeLastFrame)
			for frame in frames:
				key = mxs.addNewKey(timeController, frame)
				key.value = frame
				key.inTangentType = mxs.pyhelper.namify('linear')
				key.outTangentType = mxs.pyhelper.namify('linear')

		# Processing Ray Fire caches.
		rayFireCaches = mxs.getClassInstances(mxs.RF_Cache, target=np)
		for rayFireCache in rayFireCaches:

			# Enable curve playback.
			xMesh.playUseGraph = True

			# Create a new bezier float controller for the time.
			mxs.setPropertyController(rayFireCache, 'playFrame', mxs.bezier_float())
			timeController = mxs.getPropertyController(rayFireCache, 'playFrame')

			# Set keys on the playback in and out frames.
			frames = (xMesh.rangeFirstFrame, xMesh.rangeLastFrame)
			for frame in frames:
				key = mxs.addNewKey(timeController, frame)
				key.value = frame
				key.inTangentType = mxs.pyhelper.namify('linear')
				key.outTangentType = mxs.pyhelper.namify('linear')

		# Returning the time controller if defined.
		if timeController:
			# Making the extrapolation linear.
			linear = mxs.pyhelper.namify('linear')
			mxs.setBeforeORT(timeController, linear)
			mxs.setAfterORT(timeController, linear)
			from cross3d import SceneAnimationController
			return SceneAnimationController(self._scene, timeController)

		return None
예제 #14
0
	def generatePlayblast( self, path, frameRange=None, resolution=None, slate='', effects=None, geometryOnly=True, pathFormat=r'{basePath}\{fileName}.{frame}.{ext}'):
		'''
			/option <bool> effects
		'''
		
		# Treating inputs.
		if isinstance(frameRange, int):
			frameRange = FrameRange([frameRange, frameRange])
			
		# collecting what we need
		scene = self._scene
		basePath, fn = os.path.split(path)
		fileSplit = fn.split( '.' )
		fileName = '.'.join( fileSplit[:-1] )
		initialRange = scene.animationRange()
		fileExtension = fileSplit[-1]
		
		# Creating folder if does not exist.
		dirName = os.path.dirname(path)
		if not os.path.exists(dirName):
			os.makedirs(dirName)

		# Checking inputs.
		if not frameRange:
			frameRange = initialRange
		if not resolution:
			resolution = scene.renderSize()
			
		# Setting slates.
		if slate:
			self.setSlateText(slate)
			self.setSlateIsActive(True)

		# storing infornation
		initialGeometryVisibility = mxs.hideByCategory.geometry
		initialShapesVisibility = mxs.hideByCategory.shapes
		initialLightsVisibility = mxs.hideByCategory.lights
		initialCamerasVisibility = mxs.hideByCategory.cameras
		initialHelpersVisibility = mxs.hideByCategory.helpers
		initialSpaceWarpsVisibility = mxs.hideByCategory.spacewarps
		initialParticleSystemsVisibility = mxs.hideByCategory.particles
		initialBoneObjectsVisibility = mxs.hideByCategory.bones
		initialGridVisibility = mxs.viewport.getGridVisibility( self._name )
		initialFrame = scene.currentFrame()
		initialSelection = scene.selection()
		initialSafeFrame = mxs.displaySafeFrames
		initialViewNumber = mxs.viewport.numViews

		# Getting the camera.
		camera = self.camera()
		
		# setting the scene
		scene.setAnimationRange( frameRange )
		
		# Setting the viewport.
		if geometryOnly:
			mxs.hideByCategory.geometry = False
			mxs.hideByCategory.shapes = True
			mxs.hideByCategory.lights = True
			mxs.hideByCategory.cameras = True
			mxs.hideByCategory.helpers = True
			mxs.hideByCategory.spacewarps = True
			mxs.hideByCategory.particles = False
			mxs.hideByCategory.bones = True
			
		scene.clearSelection()
		mxs.displaySafeFrames = False
		mxs.viewport.setGridVisibility( self._name, False )
		if initialViewNumber > 1:
			mxs.execute( 'max tool maximize' )
			
		# getting the viewport size information
		viewSize = self.size()
		completed = True 
		count = 0
		
		mxs.pyhelper.setViewportQuadSize( resolution.width(), resolution.height() )

		# Should we compute multi-pass effects.
		effects = camera.hasMultiPassEffects() and effects in [None, True]

		# This is my crappy way of figuring out if we are using Nitrous.
		nitrous = not mxs.gw.GetDriverString() and application.version() >= 15

		# We are going to use progressive rendering if the mode is set to Depth of Field (Mental Ray).
		physical = mxs.classof(camera.nativePointer()) in (mxs.VRayPhysicalCamera, mxs.Physical)
		progressive = nitrous and (physical or mxs.classof(camera.nativePointer().mpassEffect) == mxs.Depth_of_Field__mental_ray)

		# If the viewport is using Nitrous.
		if camera and effects and progressive:

			# Storing and setting up Nitrous options.
			nitrousSettings = mxs.NitrousGraphicsManager.GetActiveViewportSetting()
			initialFadingFactor = nitrousSettings.ProgressiveFadingFactor 
			nitrousSettings.ProgressiveFadingFactor = 0
			
		# For each frame.	
		for frame in range( frameRange[0], frameRange[1] + 1 ):
			image = None
			count = count + 1

			# Watching for Esc key.
			if mxs.keyboard.escPressed:
				completed = False
				break
			scene.setCurrentFrame(frame)

			if camera:
				if effects:

					# If we use a Nitrous viewport, we compute the depth of field the new way.
					passes = 0
					if progressive:
						while not mxs.NitrousGraphicsManager.isProgressiveRenderingFinished():
							mxs.NitrousGraphicsManager.progressiveRendering()
							passes += 1
							if passes == 32:
								break

					# Otherwise we compute it the old way by using the API method.
					else:
						camera.renderMultiPassEffects()

					# Text overlays are only supported until Max 2011.
					if slate and application.version() <= 13:
						self.slateDraw()	

				# For Max 2012 and above only the viewport object allows to save the picture with multipass effects.
				if application.version() >= 14 and effects:
					image = mxs.viewport.getViewportDib()

			if not image:
				image = mxs.gw.getViewportDib()

			imagePath = pathFormat.format(basePath=basePath, fileName=fileName, frame=frame, ext=fileExtension)
			image.filename = imagePath
			mxs.save(image)

			# Updating count.
			if count == 100:
				mxs.gc()
				count = 0
		
		# Restoring scene settings.
		scene.setAnimationRange(initialRange)
		
		# Restoring viewport settings.
		self._name = mxs.viewport.activeViewport
		self.slateClear()	
		scene.setSelection( initialSelection )
		scene.setCurrentFrame( initialFrame )
		mxs.displaySafeFrames = initialSafeFrame
		mxs.hideByCategory.geometry = initialGeometryVisibility
		mxs.hideByCategory.shapes =	initialShapesVisibility
		mxs.hideByCategory.lights =	initialLightsVisibility 
		mxs.hideByCategory.cameras = initialCamerasVisibility 
		mxs.hideByCategory.helpers = initialHelpersVisibility
		mxs.hideByCategory.spacewarps =	initialSpaceWarpsVisibility 
		mxs.hideByCategory.particles = initialParticleSystemsVisibility
		mxs.hideByCategory.bones = initialBoneObjectsVisibility
		mxs.viewport.setGridVisibility( self._name, initialGridVisibility )
		mxs.pyhelper.setViewportQuadSize( viewSize[0], viewSize[1] )
		self.setSlateIsActive( False )

		# Restoring Nitrous settings.
		if camera and progressive and camera.hasMultiPassEffects() and effects in [None, True]:

			# Restoring Nitrous settings.
			nitrousSettings.ProgressiveFadingFactor = initialFadingFactor
			
		if initialViewNumber != 1:
			mxs.execute( 'max tool maximize' )

		# After storing all these bitmaps. We make sure to flush Max's memory.
		mxs.gc()
		
		return completed
예제 #15
0
def findBumpMap(material):
    """
		\remarks	looks for the bump map for the inputed material based on its type
		\param		material	<Py3dsMax.mxs.Material>
		\return		<Py3dsMax.mxs.Map> opacityMap || None
	"""
    cls = mxs.classof(material)

    # return a standard material's bump map
    if (cls == mxs.StandardMaterial):
        if (material.bumpMapEnable):
            bumpmap = material.bumpMap
            if (bumpmap and material.bumpMapAmount != 100):
                bumpTexture = mxs.Output()
                bumpTexture.map1 = bumpmap
                bumpTexture.output.bump_amount = (material.bumpMapAmount /
                                                  100.0)
                return bumpTexture
            return bumpmap
        return None

    # return a vray bump map
    if (cls in (mxs.VrayMtl, mxs.VrayFastSSS2, mxs.VRaySkinMtl)):
        if (material.texmap_bump_on):
            bumpmap = material.texmap_bump
            if (bumpmap and material.texmap_bump_multiplier != 100):
                bumpTexture = mxs.Output()
                bumpTexture.map1 = bumpmap
                bumpTexture.output.bump_amount = (
                    material.texmap_bump_multiplier / 100.0)
                return bumpTexture
            return bumpmap
        return None

    # return a matte bump
    if (cls in (mxs.Matte_Shadow_Reflection__mi,
                mxs.mr_Matte_Shadow_Reflection_Mtl)):
        return material.bump

    # return an arch-design material
    if (cls == mxs.Arch___Design__mi):
        if (material.bump_map_on):
            bumpmap = material.bump_map
            if (bumpmap and material.bump_map_amt != 1.0):
                bumpTexture = mxs.Output()
                bumpTexture.map1 = bumpmap
                bumpTexture.output.bump_amount = mtl.bump_map_amt
                return bumpTexture
            return bumpmap
        return None

    # return a skin bump map
    if (cls in (mxs.SSS_Fast_Skin___w__Disp___mi, mxs.SSS_Fast_Skin___mi,
                mxs.SSS_Fast_Skin_Material_Displace__mi,
                mxs.SSS_Fast_Skin_Material__mi, mxs.SSS_Fast_Material__mi)):
        if (mxs.classof(material.bump) == mxs.Bump__3dsmax):
            bumpmap = material.bump.map
            if (bumpmap):
                bumpTexture = mxs.Output()
                bumpTexture.map1 = bumpmap
                bumpTexture.output.bump_amount = material.bump.multiplier
                return bumpTexture
            return None

        else:
            return material.bump

    # no bump map found
    return None
예제 #16
0
def findDisplacementMap(material):
    """
		\remarks	looks for the displacement map for the inputed material based on its type
		\param		material	<Py3dsMax.mxs.Material>
		\return		<Py3dsMax.mxs.Map> opacityMap || None
	"""
    cls = mxs.classof(material)

    is_prop = mxs.isproperty

    # return a standard material's displacement map
    if (cls == mxs.StandardMaterial):
        if (material.displacementMap and material.displacementMapEnable):
            return material.displacementMap
        elif (is_prop(material, 'mental_ray__material_custom_attribute')):
            mrattr = material.mental_ray__material_custom_attribute
            if (mrattr.displacementOn and not mrattr.displacementLocked):
                return mrattr.displacement
        return None

    # return a vray material's displacement map
    elif (cls in (mxs.VrayMtl, mxs.VRayFastSSS2, mxs.VRaySkinMtl)):
        if material.texmap_displacement_on:
            return material.texmap_displacement
        else:
            return None

    # return an arch design's material
    elif (cls == mxs.Arch___Design__mi):
        outMap = None

        # first check for mental ray properties
        if (is_prop(material, 'mental_ray__material_custom_attribute')):
            mrattr = material.mental_ray__material_custom_attribute
            if (mrattr.displacementOn and not mrattr.displacementLocked):
                outMap = mrattr.displacement
            else:
                outMap = None

        # create a custom output material to match the output amount
        if (not outMap and material.displacementMap
                and material.displacement_map_on):
            if (material.displacement_map_amt):
                outMap = mxs.Output()
                outMap.map1 = mtl.displacementMap
                outMap.map1Enabled = True
                outMap.output.Output_Amount = material.displacement_map_amt
            else:
                outMap = material.displacementMap

        return outMap

    # return a blend's displacement
    elif (cls == mxs.Blend):
        if (is_prop(material, 'mental_ray__material_custom_attribute')):
            mrattr = material.mental_ray__material_custom_attribute
            if (mrattr.displacementOn and not mrattr.displacementLocked):
                return mrattr.displacement
        return None

    # return skin shader displacements
    elif (cls in (mxs.SSS_Fast_Skin_Material_Displace__mi,
                  mxs.SSS_Fast_Skin___w__Disp___mi)):
        return material.displace

    # return a mental ray displacement
    elif (cls == mxs.mental_ray):
        if material.displaceOn:
            return material.displacement

    return None
예제 #17
0
def buildMaterialFrom(material,
                      opacityMap=None,
                      displacementMap=None,
                      bumpMap=None):
    """
		\remarks	creates a new material using the properties from the inputed material as its base,
					creating the material with an inputed opacity and displacement map overrides
		\param		material		<Py3dsMax.mxs.Material>
		\param		opacityMap		<Py3dsMax.mxs.Map>
		\param		displacementMap	<Py3dsMax.mxs.Map>
		\param		bumpMap			<Py3dsMax.mxs.Map>
		\return		<Py3dsMax.mxs.Material> builtMaterial
	"""
    # if there is no opacity of displacement map, then there is no need to modify the inputed material
    if (not (opacityMap or displacementMap or bumpMap)):
        return material

    # store useful methods
    mcopy = mxs.copy
    class_of = mxs.classof
    is_prop = mxs.isproperty
    cls = class_of(material)

    #----------------------------------------

    # GK 02/05/10 if texture is nested in a "Displacement 3D" or "Height Map" texture, get the root map
    # and use it in the material's own displacement slot. (trying to maintain some comaptibility between vray and mental ray here.)
    # if not nested, we must convert to mr connection displacement and put it there anyway since max's displacement spinner
    # does not correlate correctly to mental ray displacement amounts.
    displacementTexture = None

    # extract from a Displacement_3d texture
    if (class_of(displacementMap) == mxs.Displacement_3D__3dsmax):
        displacementTexture = displacementMap
        displacementMap = displacementMap.map

    # extract from a Height_Map texture
    elif (class_of(displacementMap) == mxs.Height_Map_Displacement__3dsmax):
        displacementTexture = displacementMap
        displacementMap = displacementMap.heightMap

    #----------------------------------------

    # build a matte shadow reflection material
    if (cls in (mxs.Matte_Shadow_Reflection__mi,
                mxs.mr_Matte_Shadow_Reflection_Mtl)):
        matteMtl = mcopy(material)
        matteMtl.opacity_shader = opacityMap
        output = mxs.mental_ray()
        output.surface = mxs.Material_to_Shader()
        output.surface.material = matteMtl

        if (displacementTexture):
            dispTexture = mxs.Displacement_3D__3dsmax()
            dispTexture.map = displacementMap

        output.displacement = displacementTexture
        output.bump = bumpMap
        return output

    # build a standard material
    elif (cls == mxs.StandardMaterial):
        output = mcopy(material)

        # use the opacity map
        if (opacityMap):
            output.opacityMap = opacityMap

        # use the bump map
        if (bumpMap):
            output.bumpMap = bumpMap
            output.bumpMapAmount = 100

        # use the displacement map
        if (displacementMap):
            output.displacementMap = displacementMap
            output.displacementMapEnable = True

            if (is_prop(output, 'mental_ray__material_custom_attribute')):
                if (not displacementTexture):
                    displacementTexture = mxs.Displacement_3D__3dsmax()
                    displacementTexture.map = displacementMap

                output.mental_ray__material_custom_attribute.displacement = displacementTexture
                output.mental_ray__material_custom_attribute.displacementLocked = False

        return output

    # build a Vray material
    elif (cls == mxs.VrayMtl):
        output = mcopy(material)

        # use the bump map
        if (bumpMap):
            output.texmap_bump = bumpMap
            output.texmap_bump_on = True
            output.texmap_bump_multiplier = 100

        # use the opacity map
        if (opacityMap):
            output.texmap_opacity = opacityMap
            output.texmap_opacity_on = True
            output.texmap_opacity_multiplier = 100

        # use the displacementmap
        if (displacementMap):
            output.texmap_displacement = displacementMap
            output.texmap_displacement_on = True
            output.texmap_displacement_multiplier = 100

        return output

    # build a Vray Light material
    elif (cls == mxs.VrayLightMtl):
        # light materials only need opacity maps
        if (not opacityMap):
            return material

        output = mcopy(material)
        output.opacity_texmap = opacityMap
        output.opacity_texmap_on = True
        return output

    # build a Arch_Design material
    elif (cls == mxs.Arch___Design__mi):
        output = mcopy(material)
        output.cutout_map = opacityMap

        # displace the texture
        if (not displacementTexture):
            output.displacementMap = displacementMap

        # use the bump map
        if (bumpMap):
            output.bump_map = bumpMap
            output.bump_map_amt = 1.0

        # displace the property
        elif (is_prop(material, 'mental_ray__material_custom_attribute')):
            output.mental_ray__material_custom_attribute.displacement = displacementTexture
            output.mental_ray__material_custom_attribute.displacementLocked = False

        return output

    # build a blend material
    elif (cls == mxs.Blend):
        if (displacementMap
                and is_prop('mental_ray__material_custom_attribute')):
            output = mcopy(material)

            # create a displacement texture
            if (not displacementTexture):
                displacementTexture = mxs.Displacement_3D__3dsmax()
                displacementTexutre.map = displacementMap

            output.displace = displacementTexture
            return output
        return material

    # build a fast skin shader
    elif (cls in (mxs.SSS_Fast_Skin_Material_Displace__mi,
                  mxs.SSS_Fast_Skin___w__Disp___mi)):
        if (displacementMap):
            output = mcopy(material)

            # use the bump map
            if (bumpMap):
                if (mxs.classof(bumpMap != mxs.Bump__3dsmax)):
                    bumpTexture = mxs.Bump__3dsmax
                    bumpTexture.map = bumpMap
                    output.bump = bumpTexture
                else:
                    output.bump = bumpMap

            # use the displacement texture
            if (not displacementTexture):
                displacementTexture = mxs.Displacement_3D__3dsmax()
                displacementTexture.map = displacementMap

            output.displace = displacementTexture

            return output
        return material

    # build a mental_ray shader
    elif (cls == mxs.Mental_Ray):
        output = mcopy(material)

        # use displacement
        if (displacementMap):
            if (not displacementTexture):
                displacementTexture = mxs.Displacement_3D__3dsmax()
                displacementTexture.map = displacementMap
            output.displacement = displacementTexture

        # use opacity
        if (opacityMap):
            opacityMtl = mxs.Opacity__base()
            opacityMtl.input_shader = material.surface
            opacityMtl.opacity_shader = opacityMap
            output.surface = opacityMtl

        return output

    # build a multi/material
    elif (cls == mxs.MultiMaterial):
        output = mcopy(material)
        count = material.numsubs
        output.numsubs = count

        for i in range(count):
            output[i] = buildMaterialFrom(material[i],
                                          opacityMap=opacityMap,
                                          displacementMap=displacementMap,
                                          bumpMap=bumpMap)

        return output

    # create a default material
    else:
        count = mxs.getNumSubMtls(material)
        if (count):
            output = mcopy(material)

            get_submtl = mxs.getSubMtl
            set_submtl = mxs.setSubMtl

            for i in range(output):
                set_submtl(
                    output, i + 1,
                    buildMaterialFrom(get_submtl(material, i + 1),
                                      opacityMap=opacityMap,
                                      displacementMap=displacementMap,
                                      bumpMap=bumpMap))

            return output

    return material
예제 #18
0
 def setFOVBased(self, fovBased):
     cls = mxs.classof(self._nativePointer)
     if cls == mxs.VRayPhysicalCamera:
         self._nativePointer.specify_fov = fovBased
         return True
     return False
예제 #19
0
 def fovBased(self):
     cls = mxs.classof(self._nativePointer)
     if cls == mxs.VRayPhysicalCamera:
         return self._nativePointer.specify_fov
     return True
예제 #20
0
 def fovBased(self):
     cls = mxs.classof(self._nativePointer)
     if cls == mxs.VRayPhysicalCamera:
         return self._nativePointer.specify_fov
     return True
예제 #21
0
 def setFOVBased(self, fovBased):
     cls = mxs.classof(self._nativePointer)
     if cls == mxs.VRayPhysicalCamera:
         self._nativePointer.specify_fov = fovBased
         return True
     return False