Code Vonc

Pipette à matériaux

v 1.0

Python pour Cinéma 4D R15.

TéléchargerDownload
Faire un donMake a donation
Comment installer ?How to install ?
CommentairesComments

Copier le dossier « vonc_pipemat » dans le dossier « plugins » du répertoire de Cinéma 4D.



Cliquez sur un objet de votre scène pour sélectionner automatiquement le matériau correspondant.



Codes sources


Fichier vonc_pipemat.PYP :

# Pipette à matériaux - César Vonc - http://code.vonc.fr
# v 1.0

import c4d
import os

from c4d import gui, plugins, bitmaps
from c4d.utils import ViewportSelect
from c4d.plugins import GeLoadString as txt

MODULE_ID = 1031129
VONC_PIPEMAT_NOM = 1000
VONC_PIPEMAT_INFO = 1001
VONC_PIPEMAT_AIDE = 1002
VONC_PIPEMAT_MAT = 1003
VONC_PIPEMAT_TEX = 1004
VONC_PIPEMAT_OBJ = 1005
VONC_PIPEMAT_GEN = 1006

class PipeDialogue(gui.SubDialog):

	def __init__(self, arg):
		self.data = arg
	
	def _grise(self) :
		if self.GetLong(1002) :
			self.SetLong(1001, 0)
			self.Enable(1001, False)
		else : self.Enable(1001, True)
	
	def CreateLayout(self):
		self.GroupBegin(id=1000, flags=c4d.BFH_SCALEFIT, cols=1, rows=1)
		self.GroupBorderSpace(10, 10, 10, 10)
		self.AddCheckbox(1002, c4d.BFH_SCALEFIT, 0, 0, txt(VONC_PIPEMAT_GEN))
		self.AddRadioGroup(1001, c4d.BFH_SCALEFIT, 1, 1)
		self.AddChild(1001, 0, txt(VONC_PIPEMAT_MAT))
		self.AddChild(1001, 1, txt(VONC_PIPEMAT_TEX))
		self.AddChild(1001, 2, txt(VONC_PIPEMAT_OBJ))
		self.AddSeparatorH(0)
		self.AddStaticText(1100, c4d.BFH_LEFT, 0, 0, txt(VONC_PIPEMAT_INFO))
		self.GroupEnd()
		
		return True
	
	def InitValues(self) :
		self.SetLong(1002, self.data['gen'])
		self.SetLong(1001, self.data['mode'])
		self._grise()
		return True
		
	def Command(self, id, msg):
		if id == 1001 or id == 1002 :
			self._grise()
			self.data['mode'] = self.GetLong(1001)
		if id == 1002 : self.data['gen'] = self.GetBool(1002)
		return True


class PipeMat(plugins.ToolData):
	
	def __init__(self):
		self.data = dict(mode=0, gen=False)
	
	def GetState(self, doc):
		if doc.GetMode()==c4d.Mpaint: return 0
		return c4d.CMD_ENABLED
	
	def _PipeMatBase(self, op) :
		materiau = None
		texture = None
		propsTex = []
		parent = op
		
		while not propsTex and parent :
			parProps = parent.GetTags()
			for p in parProps :
				if p.CheckType(c4d.Ttexture) :
					propsTex.append(p)
			parent = parent.GetUp()
		
		if propsTex :
			propsTex.reverse()
			texture = propsTex[0]
			materiau = texture[c4d.TEXTURETAG_MATERIAL]
		
		return materiau, texture
	
	def _PipeMatPoly(self, op, id) :
		materiau = None
		texture = None
		nbPolys = op.GetPolygonCount()
		props = op.GetTags()
		propsSelPol = {} # Nom : Propriété
		propsTex = []
		for p in props :
			if p.CheckType(c4d.Tpolygonselection) :
				propsSelPol[p.GetName()] = p
			elif p.CheckType(c4d.Ttexture) :
				propsTex.append(p)
		
		parent = op
		while not propsTex and parent :
			parent = parent.GetUp()
			if not parent : break
			parProps = parent.GetTags()
			for p in parProps :
				if p.CheckType(c4d.Ttexture) :
					propsTex.append(p)
		
		propsTex.reverse()
		for pTex in propsTex :
			if materiau : break
			
			pMat = pTex[c4d.TEXTURETAG_MATERIAL]
			pSelNom = pTex[c4d.TEXTURETAG_RESTRICTION]
			
			if not pSelNom :
				materiau = pMat
				texture = pTex
				break
			
			if (pSelNom in propsSelPol) :
				pSel = propsSelPol[pSelNom]
				bs = pSel.GetBaseSelect()
				for index, sel in enumerate(bs.GetAll(nbPolys)):
					if not sel : continue
					if index == id :
						materiau = pMat
						texture = pTex
						break
		
		return materiau, texture
	
	def MouseInput(self, doc, data, bd, win, msg):
		mx = msg[c4d.BFM_INPUT_X]
		my = msg[c4d.BFM_INPUT_Y]
		mode = self.data['mode']
		gen = self.data['gen']

		device = 0
		if msg[c4d.BFM_INPUT_CHANNEL]==c4d.BFM_INPUT_MOUSELEFT:
			device = c4d.KEY_MLEFT
		elif msg[c4d.BFM_INPUT_CHANNEL]==c4d.BFM_INPUT_MOUSERIGHT:
			device = c4d.KEY_MRIGHT
		else:
			return True
		
		img = bd.GetFrame()
		gauche = img["cl"]
		droite = img["cr"]
		haut = img["ct"]
		bas = img["cb"]
		
		c4d.CallCommand(100004767) # Tout désélectionner (objets, propriétés)
		c4d.CallCommand(300001026) # Tout désélectionner (matériaux)
		
		
		ops = []
		docu = None
		obj = None
		
		if gen :
			docu = doc.Polygonize()
			obj = docu.GetFirstObject()
		else :
			obj = doc.GetFirstObject()
		
		while obj :
			objs = [obj]
			for o in objs :
				if o.CheckType(c4d.Obase) :
					ops.append(o)
				objs.extend(o.GetChildren())
			obj = obj.GetNext()
		
		largeur = droite - gauche + 1
		hauteur = bas - haut + 1
		mx = int(mx)
		my = int(my)
		materiau = None
		texture = None
		op = None
		
		vs = ViewportSelect()
		vsInit = vs.Init(largeur, hauteur, bd, ops, c4d.Mpolygons, True, c4d.VIEWPORTSELECTFLAGS_USE_HN|c4d.VIEWPORTSELECTFLAGS_USE_DEFORMERS)
		
		if not vsInit :
			if gen : c4d.documents.KillDocument(docu)
			return True
		
		infospoly = vs.GetPixelInfoPolygon(mx, my)
		
		if infospoly :
			op = infospoly['op']
			id = infospoly['i']
		
		if not infospoly :
			objsSel = vs.PickObject(bd, doc, mx, my, 1, c4d.VIEWPORT_PICK_FLAGS_0)
			if not objsSel :
				if gen : c4d.documents.KillDocument(docu)
				return True
			op = objsSel[0]
		
		
		if (mode == 0 or mode == 1) : # Matériaux
			if infospoly :
				materiau, texture = self._PipeMatPoly(op, id)
			else :
				materiau, texture = self._PipeMatBase(op)
			
			if materiau and mode == 0 :
				if gen :
					materiauxDoc = doc.GetMaterials()
					materiauxDocu = docu.GetMaterials()
					if materiau in materiauxDocu :
						iMatDocu = materiauxDocu.index(materiau)
						materiau = materiauxDoc[iMatDocu]
				doc.SetActiveMaterial(materiau, c4d.SELECTION_NEW)
			
			if texture and mode == 1 :
				doc.SetActiveTag(texture, c4d.SELECTION_NEW)
				
		
		elif (mode == 2) : # Objet
			doc.SetActiveObject(op)
		
		if gen : c4d.documents.KillDocument(docu)
		c4d.EventAdd()
		return True
	
	
	def GetCursorInfo(self, doc, data, bd, x, y, bc):
		if bc.GetId()==c4d.BFM_CURSORINFO_REMOVE:
			return True
		
		bc.SetString(c4d.RESULT_BUBBLEHELP, txt(VONC_PIPEMAT_NOM))
		bc.SetLong(c4d.RESULT_CURSOR, c4d.MOUSE_PAINTPICK)
		return True
	
	def AllocSubDialog(self, bc):
		return PipeDialogue(self.data)


if __name__ == "__main__":
	bmp = bitmaps.BaseBitmap()
	dir, file = os.path.split(__file__)
	fn = os.path.join(dir, "res", "pipemat.tif")
	bmp.InitWith(fn)
	plugins.RegisterToolPlugin(id=MODULE_ID, str=txt(VONC_PIPEMAT_NOM),
								info=0, icon=bmp, 
								help=txt(VONC_PIPEMAT_AIDE),
								dat=PipeMat())


Fichier c4d_symbols.H :

enum
{
	VONC_PIPEMAT_NOM = 1000,
	VONC_PIPEMAT_INFO = 1001,
	VONC_PIPEMAT_AIDE = 1002,
	VONC_PIPEMAT_MAT = 1003,
	VONC_PIPEMAT_TEX = 1004,
	VONC_PIPEMAT_OBJ = 1005,
	VONC_PIPEMAT_GEN = 1006,
	
	// End of symbol definition
	_DUMMY_ELEMENT_
};


Fichier c4d_strings.STR :

STRINGTABLE
{
	VONC_PIPEMAT_NOM		"Pipette \u00E0 mat\u00E9riaux";
	VONC_PIPEMAT_INFO		"v 1.0 - C\u00E9sar Vonc - http://code.vonc.fr";
	VONC_PIPEMAT_AIDE		"Pr\u00E9lever un mat\u00E9riau affich\u00E9 dans la vue.";
	VONC_PIPEMAT_MAT		"S\u00E9lectionner le mat\u00E9riau";
	VONC_PIPEMAT_TEX		"S\u00E9lectionner la propri\u00E9t\u00E9 texture";
	VONC_PIPEMAT_OBJ		"S\u00E9lectionner l'objet";
	VONC_PIPEMAT_GEN		"Inclure les g\u00E9n\u00E9rateurs (plus lent)";
}