Code Vonc


Ressources pour la programmation, tutoriels, scripts, maths.
Python : Perceuse
Module Python pour Cinéma 4D R13.
3 juillet 2013



Perceuse - v 1.1 - Télécharger

? Comment installer ?


Troue l'objet courant par un simple clic.

v 1.1 :
- Ajout de la quantification de la rotation en maintenant la touche Maj.
- Correction des mauvais polygones troués dans les vues Haut, Bas, Gauche, Droite.
- Correction diverses.

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







Codes sources


Fichier vonc_perceuse.PYP :
# Perceuse - César Vonc - http://code.vonc.fr
# v 1.1

import c4d
import os
import webbrowser
import math

from c4d import gui, plugins, bitmaps, Vector, Matrix, plugins
from c4d.utils import GeRayCollider, Neighbor, VectorToHPB, HPBToMatrix, SendModelingCommand, VectorAngle
from c4d.plugins import GeLoadString as txt
from c4d.modules import snap

PLUGIN_ID = 1030785

VONC_PERCEUSE_NOM = 1000
VONC_PERCEUSE_COTES = 1001
VONC_PERCEUSE_NGONES = 1002
VONC_PERCEUSE_AIDE = 1003
VONC_PERCEUSE_INFO = 1004
VONC_PERCEUSE_DON = 1005
VONC_PERCEUSE_NETT = 1006
VONC_PERCEUSE_NORMALE = 1007
VONC_PERCEUSE_PROF = 1008
VONC_PERCEUSE_AUTO = 1009

class PerceuseDialogue(gui.SubDialog):

	def __init__(self, arg):
		self.data = arg

	def CreateLayout(self):
		value = self.data['cotes']
		
		self.GroupBegin(1100, c4d.BFH_SCALEFIT, 2, 1)
		self.GroupBorderSpace(10, 5, 10, 5)
		
		self.AddStaticText(1101, c4d.BFH_LEFT, 0, 0, txt(VONC_PERCEUSE_COTES))
		self.AddEditNumberArrows(1102, c4d.BFH_LEFT)
		
		self.AddStaticText(1112, c4d.BFH_LEFT, 0, 0, txt(VONC_PERCEUSE_PROF))
		self.GroupBegin(1113, c4d.BFH_SCALEFIT, 3, 1)
		self.AddEditNumberArrows(1114, c4d.BFH_LEFT)
		self.AddStaticText(1115, c4d.BFH_LEFT, 0, 0, txt(VONC_PERCEUSE_AUTO))
		self.AddCheckbox(1116, c4d.BFH_SCALEFIT, 0, 0, "")
		self.GroupEnd()
		
		self.AddStaticText(1110, c4d.BFH_LEFT, 0, 0, txt(VONC_PERCEUSE_NORMALE))
		self.AddCheckbox(1111, c4d.BFH_SCALEFIT, 0, 0, "")
		self.AddStaticText(1108, c4d.BFH_LEFT, 0, 0, txt(VONC_PERCEUSE_NETT))
		self.AddCheckbox(1109, c4d.BFH_SCALEFIT, 0, 0, "")
		self.AddStaticText(1103, c4d.BFH_LEFT, 0, 0, txt(VONC_PERCEUSE_NGONES))
		self.AddCheckbox(1104, c4d.BFH_SCALEFIT, 0, 0, "")
		self.GroupEnd()
		self.AddSeparatorH(0)
		self.GroupBegin(1105, c4d.BFH_SCALEFIT, 1, 2)
		self.GroupBorderSpace(10, 5, 10, 5)
		self.AddStaticText(1106, c4d.BFH_LEFT, 0, 0, txt(VONC_PERCEUSE_INFO))
		self.AddButton(1107, c4d.BFH_LEFT, 0, 0, txt(VONC_PERCEUSE_DON))
		self.GroupEnd()
		
		self.SetReal(1102, self.data['cotes'], 3, 1000)
		self.SetBool(1104, self.data['ngones'])
		self.SetBool(1109, self.data['nettauto'])
		self.SetBool(1111, self.data['camera'])
		self.SetMeter(1114, self.data['profondeur'], 0)
		self.SetBool(1116, self.data['auto'])
		self.Enable(1114, not self.data['auto'])
		return True

	def Command(self, id, msg):
		if id == 1102 : self.data['cotes'] = self.GetLong(1102)
		elif id == 1104 : self.data['ngones'] = self.GetBool(1104)
		elif id == 1109 : self.data['nettauto'] = self.GetBool(1109)
		elif id == 1111 : self.data['camera'] = self.GetBool(1111)
		elif id == 1114 : self.data['profondeur'] = self.GetReal(1114)
		elif id == 1116 :
			auto = self.GetBool(1116)
			self.data['auto'] = auto
			self.Enable(1114, not auto)
		elif id == 1107 : webbrowser.open("http://code.vonc.fr/", 2, True)
		
		return True


class Perceuse(plugins.ToolData):
	doc = None
	matrice = Matrix()
	trou = None
	statut = False
	
	def _PlusPG(self, li, plusgrand=False) :
		if not li : return 0
		li.sort()
		if plusgrand : li.reverse()
		return li[0]
	
	def _CalculeProfondeur(self, disque, obj, laser, rayon) :
		objMg = obj.GetMg()
		taille = obj.GetRad() * 2
		taille_max = taille.x
		if taille.y > taille_max : taille_max = taille.y
		if taille.z > taille_max : taille_max = taille.z
		disque_nbpts = disque.GetPointCount()
		disque_pts = [disque.GetPoint(0)]
		disque_mg = disque.GetMg()
		
		pas = int((disque_nbpts-1) / 6)
		if pas < 1 : pas = 1
		for i in xrange(7) :
			if i == 0 : continue
			p = (i*pas) % disque_nbpts
			if p == 0 : break
			disque_pts.append(disque.GetPoint(p))
		
		direc = (~objMg).MulV(disque_mg.v3)
		tta = []
		for pos in disque_pts :
			ttb = []
			for i in xrange(2) :
				if i : direction = direc
				else : direction = direc * -1
				depart = (disque_mg).Mul(pos)
				depart = (~objMg).Mul(depart)
				coll = laser.Intersect(depart, direction, taille_max)
				inter = laser.GetNearestIntersection()
				if inter :
					ttb.append(inter["distance"])
			tta.append(self._PlusPG(ttb))
		
		plusgrand = self._PlusPG(tta, True)
		plusgrand *= 3
		if plusgrand < rayon : return rayon
		return plusgrand
	
	def _CalculeTrou(self, matrice, rayon=10, cotes=8, majpos=False) :
		if majpos and self.trou :
			self.trou.SetMg(matrice)
		else :
			self.trou = None
			disque = c4d.BaseObject(c4d.Odisc)
			disque.SetMg(matrice)
			disque[c4d.PRIM_DISC_ORAD] = rayon
			disque[c4d.PRIM_DISC_CSUB] = 1
			disque[c4d.PRIM_DISC_SEG] = cotes
			disque[c4d.PRIM_AXIS] = c4d.PRIM_AXIS_ZP
			disque[c4d.ID_BASEOBJECT_USECOLOR] = c4d.ID_BASEOBJECT_USECOLOR_ALWAYS
			disque[c4d.ID_BASEOBJECT_COLOR] = Vector(1, 0, 0)
			disque = SendModelingCommand(command=c4d.MCOMMAND_CURRENTSTATETOOBJECT, list=[disque], doc=self.doc) 
			if disque :
				self.trou = disque[0]
	
	def __init__(self):
		self.data = dict(cotes=8, ngones=False, nettauto=True, camera=False, profondeur=30.0, auto=True)
	
	def InitTool(self, doc, data, bt):
		self.statut = False
		return True
	
	def GetState(self, doc):
		if doc.GetMode()==c4d.Mpaint: return 0
		return c4d.CMD_ENABLED
	
	def KeyboardInput(self, doc, data, bd, win, msg):
		key = msg.GetLong(c4d.BFM_INPUT_CHANNEL)
		cstr = msg.GetString(c4d.BFM_INPUT_ASC)
		if key==c4d.KEY_ESC:
			return True
		if key==c4d.KEY_SHIFT:
			return True
		return False


	def MouseInput(self, doc, data, bd, win, msg):
		mx = msg[c4d.BFM_INPUT_X]
		my = msg[c4d.BFM_INPUT_Y]
		
		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:
			self.statut = False
			return True
		
		self.doc = doc
		obj = doc.GetActiveObject()
		if not obj or not obj.CheckType(c4d.Opolygon) :
			self.statut = False
			return True
		
		self.statut = True
		cam = bd.GetEditorCamera()
		objMg = obj.GetMg()
		laser = GeRayCollider()
		laser.Init(obj)
		cotes = self.data['cotes']
		ngones = self.data['ngones']
		nettauto = self.data['nettauto']
		camera = self.data['camera']
		profondeur = self.data['profondeur']
		auto = self.data['auto']
		
		dx = 0.0
		dy = 0.0
		
		win.MouseDragStart(button=device, mx=int(mx), my=int(my), flags=c4d.MOUSEDRAGFLAGS_DONTHIDEMOUSE|c4d.MOUSEDRAGFLAGS_NOMOVE)
		result, dx, dy, channel = win.MouseDrag()
		
		camMg = cam.GetMg()
		curA = bd.SW(c4d.Vector(mx, my, 0.0))
		if cam[c4d.CAMERA_PROJECTION] == c4d.Pperspective or cam[c4d.CAMERA_PROJECTION] == c4d.Pparallel :
			curB = bd.SW(c4d.Vector(mx, my, 1000.0))
		else :
			curB = bd.SW(c4d.Vector(mx, my, -1000.0))
		curA = (~objMg).Mul(curA)
		curB = (~objMg).Mul(curB)
		direc = curB - curA
		depart = curA
		distance = (camMg.off - objMg.off).GetLength() + (obj.GetMp().GetLength())
		coll = laser.Intersect(depart, direc, distance)
		inter = laser.GetNearestIntersection()
		if not inter :
			self.statut = False
			return True
		
		pos = inter["hitpos"]
		dist = inter["distance"]
		nor = inter["f_normal"]
		if camera : nor = direc.GetNormalized()
		ppoly_id = inter["face_id"]
		posabs = (objMg).Mul(pos)
		norabs = (objMg).MulV(nor)
		matrice = HPBToMatrix(VectorToHPB(norabs))
		matrice.off = posabs
		matrice_rel = HPBToMatrix(VectorToHPB(nor))
		matrice_rel.off = pos
		
		
		dmx = -mx
		dmy = -my
		rayon = 0.0
		self._CalculeTrou(matrice, rayon, cotes)
		commence = False
		rot_fac = 0.01
		if camera : rot_fac = -0.01
		
		c4d.DrawViews(c4d.DA_ONLY_ACTIVE_VIEW|c4d.DA_NO_THREAD|c4d.DA_NO_ANIMATION)
		
		# _quantVal = snap.GetQuantizeStep(doc, bd, c4d.QUANTIZE_ROTATE)
		# _quantAct = snap.IsQuantizeEnabled(doc)
		_quantVal = (math.pi * 0.5) / cotes
		_bss = c4d.BaseContainer()
		
		while result==c4d.MOUSEDRAGRESULT_CONTINUE:
			mx += dx
			my += dy
			
			# Si la souris ne bouge plus
			if dx==0.0 and dy==0.0:
				result, dx, dy, channel = win.MouseDrag()
				continue
			
			rot_fac2 = rot_fac
			if (dmx + mx) < 0 : rot_fac2 = -rot_fac
			rot = -(dmy + my) * rot_fac2
			rayon = abs((dmx + mx) * dist * 1.2)
			
			
			win.BfGetInputState(c4d.BFM_INPUT_KEYBOARD, c4d.KEY_SHIFT, _bss)
			if _bss[1768978017] :
				rot = rot - (rot % _quantVal)
				
			
			hpb = c4d.utils.MatrixToHPB(matrice)
			hpb.z = rot
			matx = HPBToMatrix(hpb)
			matx.off = matrice.off
			matrice = matx
			
			self._CalculeTrou(matrice, rayon, cotes)

			c4d.DrawViews(c4d.DA_ONLY_ACTIVE_VIEW|c4d.DA_NO_THREAD|c4d.DA_NO_ANIMATION)
			result, dx, dy, channel = win.MouseDrag()
			commence = True
		
		if not commence or rayon == 0.0 :
			self.statut = False
			return True
		
		# Calcule la profondeur
		if auto :
			profondeur = self._CalculeProfondeur(self.trou, obj, laser, rayon)
		
		# Calcule la matrice relative
		matrice_rel.v1 = (~objMg).MulV(matrice.v1)
		matrice_rel.v2 = (~objMg).MulV(matrice.v2)
		matrice_rel.v3 = (~objMg).MulV(matrice.v3)
		matrice_rel.off = (~objMg).Mul(matrice.off)
		
		##-- Calcul du trou --##
		
		nbpts = obj.GetPointCount()
		nbpol = obj.GetPolygonCount()
		t_pt_dist = [False] * nbpts # Tableau des points traites pour le calcul de la distance par rapport au point O.
		t_pol_voi = [False] * nbpol # Tableau des polys traites pour le calcul des voisins avec Neighbor.
		t_pol_aff = [] # Liste des polys affectés
		
		n = Neighbor()
		n.Init(obj)
		rayon2 = rayon * 1.3
		
		doc.AddUndo(c4d.UNDO_CHANGE, obj)
		bs = obj.GetPolygonS()
		bs.DeselectAll()
		bs2 = obj.GetPointS()
		bs2.DeselectAll()
		
		# Cherche les polys à trouer
		ppoly = obj.GetPolygon(ppoly_id)
		ppoly_abcd = [ppoly.a, ppoly.b, ppoly.c, ppoly.d]
		for pt in ppoly_abcd :
			polys = n.GetPointPolys(pt)
			for poly_id in polys :
				if t_pol_voi[poly_id] : continue
				bs.Select(poly_id)
				t_pol_voi[poly_id] = True
				t_pol_aff.append(poly_id)
				poly = obj.GetPolygon(poly_id)
				poly_abcd = [poly.a, poly.b, poly.c, poly.d]
				k = 0
				for i in poly_abcd :
					if t_pt_dist[i] : continue
					dist = (pos - obj.GetPoint(i)).GetLength()
					if dist < rayon2 :
						bs2.Select(i)
						k += 1
					t_pt_dist[i] = True
				if k : ppoly_abcd.extend(poly_abcd)
		
		t_pol_aff.sort()
		
		# Créé le cylindre et booléen
		bout = obj.GetClone()
		bout_bs = bout.GetPointS()
		bout_bs.SelectAll(bout.GetPointCount() - 1, 0)
		cylindre = c4d.BaseObject(c4d.Ocylinder)
		cylindre[c4d.PRIM_CYLINDER_RADIUS] = rayon
		cylindre[c4d.PRIM_CYLINDER_HEIGHT] = profondeur
		cylindre[c4d.PRIM_CYLINDER_SEG] = cotes
		cylindre[c4d.PRIM_AXIS] = c4d.PRIM_AXIS_ZP
		cylindre.SetMg(matrice_rel)
		booleen = c4d.BaseObject(c4d.Oboole)
		booleen[c4d.BOOLEOBJECT_SINGLE_OBJECT] = True
		booleen[c4d.BOOLEOBJECT_HIDE_NEW_EDGES] = True
		booleen[c4d.BOOLEOBJECT_TYPE] = c4d.BOOLEOBJECT_TYPE_WITHOUT
		booleen.SetMl(obj.GetMl())
		bout.SetMg(Matrix())
		bout.InsertUnder(booleen)
		cylindre.InsertAfter(bout)
		
		booleen.InsertAfter(obj)
		doc.AddUndo(c4d.UNDO_NEW, booleen)
		
		# Applati le booléen : créé l'objet Trou
		sortie = SendModelingCommand(command=c4d.MCOMMAND_CURRENTSTATETOOBJECT, list=[booleen], doc=doc)
		sortie = sortie[0]
		sortie.InsertAfter(obj)
		doc.AddUndo(c4d.UNDO_NEW, sortie)
		if sortie.CheckType(c4d.Onull) :
			trou = sortie.GetDown()
			trou.InsertAfter(obj)
			trou.SetMg(objMg)
			doc.AddUndo(c4d.UNDO_NEW, trou)
			doc.AddUndo(c4d.UNDOTYPE_DELETE, sortie)
			sortie.Remove()
		else : trou = sortie
		
		doc.AddUndo(c4d.UNDOTYPE_DELETE, booleen)
		booleen.Remove()
		
		
		trou_bs = trou.GetPointS()
		trou_nbpt = trou.GetPointCount()
		trou_pts_tour = []
		trou_pts_tour_complet = []
		nettoyer = True
		
		# Répertorie les points à virer (nettoyage du booléen)
		# Cherche les points du trou
		q_pt_trou = trou_nbpt - trou_bs.GetCount() # Nombre de points dans le trou
		j = 0
		for i, sel in enumerate(trou_bs.GetAll(trou_nbpt)) :
			if sel : continue
			trou_pts_tour_complet.append(i)
			if not j : j = i-1
			if i < (trou_nbpt - cotes) :
				trou_pts_tour.append(i)
	
		
		if nettauto :
			# Transforme les polys autour de ces points en triangles
			trou_bsp = trou.GetPolygonS()
			trou_bsp.DeselectAll()
			trou_n = Neighbor()
			trou_n.Init(trou)
			for i in trou_pts_tour :
				pols = trou_n.GetPointPolys(i)
				if len(pols) == 1 :
					nettoyer = False # Le point n'est lié qu'à un poly : point de bordure, le trou déborde, nettoyage trop complexe
					trou_pts_tour.remove(i)
					continue
				for pol in pols : trou_bsp.Select(pol)
			if trou_bsp.GetCount() :
				SendModelingCommand(command=c4d.MCOMMAND_TRIANGULATE, list=[trou], mode=c4d.MODELINGCOMMANDMODE_POLYGONSELECTION, doc=doc)
			
			# N-gone tout
			trou_n = Neighbor()
			trou_n.Init(trou)
			trou_bsp = trou.GetPolygonS()
			trou_bsp.DeselectAll()
			for i in trou_pts_tour_complet :
				pols = trou_n.GetPointPolys(i)
				for pol in pols : trou_bsp.Select(pol)
			SendModelingCommand(command=c4d.MCOMMAND_MELT, list=[trou], mode=c4d.MODELINGCOMMANDMODE_POLYGONSELECTION, doc=doc)
			
			# Vire les points
			trou_bs.DeselectAll()
			for i in trou_pts_tour : trou_bs.Select(i)
			SendModelingCommand(command=c4d.MCOMMAND_DELETE, list=[trou], mode=c4d.MODELINGCOMMANDMODE_POINTSELECTION, doc=doc)
			trou_bs.DeselectAll()
		
		else :
			# Sélectionne tout le tour
			trou_bsp = trou.GetPolygonS()
			trou_bsp.DeselectAll()
			trou_n = Neighbor()
			trou_n.Init(trou)
			for i in trou_pts_tour_complet :
				pols = trou_n.GetPointPolys(i)
				for pol in pols : trou_bsp.Select(pol)
		
		# Finalise
		trou[c4d.ID_BASELIST_NAME] = obj[c4d.ID_BASELIST_NAME]
		doc.AddUndo(c4d.UNDOTYPE_DELETE, obj)
		obj.Remove()
		
		trou.SetBit(c4d.BIT_ACTIVE)
		
		if not ngones :
			doc2 = doc.GetClone()
			doc2.InsertObject(trou.GetClone())
			c4d.documents.SetActiveDocument(doc2)
			doc2.SetMode(c4d.Mpolygons)
			c4d.CallCommand(c4d.ID_NGON_REMOVE_MENU)
			# trou2 = doc2.GetActiveObject()
			trou2 = doc2.GetFirstObject()
			
			trou2_bsp = trou2.GetPolygonS()
			trou2_bsp.DeselectAll()
			trou2_bs = trou2.GetPointS()
			trou2_bs.DeselectAll()
			
			c4d.documents.SetActiveDocument(doc)
			trou2.InsertAfter(trou)
			doc.AddUndo(c4d.UNDO_NEW, trou2)
			
			c4d.documents.KillDocument(doc2)
			
			doc.AddUndo(c4d.UNDOTYPE_DELETE, trou)
			trou.Remove()
		else :
			trou_bsp = trou.GetPolygonS()
			trou_bsp.DeselectAll()
			trou_bs = trou.GetPointS()
			trou_bs.DeselectAll()
		
		if win.MouseDragEnd()==c4d.MOUSEDRAGRESULT_ESCAPE:
			doc.DoUndo(True)
		
		c4d.EventAdd()
		self.statut = False
		return True
	
	
	def Draw(self, doc, data, bd, bh, bt, flags):
		if flags & c4d.TOOLDRAWFLAGS_HIGHLIGHT:
			if self.trou and self.statut : bd.DrawPolygonObject(bh, self.trou, c4d.DRAWOBJECT_NOBACKCULL|c4d.DRAWOBJECT_XRAY_ON)
		elif flags & c4d.TOOLDRAWFLAGS_INVERSE_Z:
			if self.trou and self.statut : bd.DrawPolygonObject(bh, self.trou, c4d.DRAWOBJECT_NOBACKCULL|c4d.DRAWOBJECT_XRAY_ON)
		elif not flags:
			pass
		return c4d.TOOLDRAW_0
		# return c4d.TOOLDRAW_HANDLES|c4d.TOOLDRAW_AXIS
	
	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_PERCEUSE_NOM))
		bc.SetLong(c4d.RESULT_CURSOR, c4d.MOUSE_POINT_HAND)
		return True

	def Message(self, doc, data, type, t_data) :
		# if type == c4d.MSG_TOOL_RESTART :
			# self.statut = False
		return True
	
	def AllocSubDialog(self, bc):
		return PerceuseDialogue(self.data)


if __name__ == "__main__":
	bmp = bitmaps.BaseBitmap()
	dir, file = os.path.split(__file__)
	fn = os.path.join(dir, "res", "vonc_perceuse.tif")
	bmp.InitWith(fn)
	plugins.RegisterToolPlugin(id=PLUGIN_ID, str="Perceuse",
								info=0, icon=bmp, 
								help=txt(VONC_PERCEUSE_AIDE),
								dat=Perceuse())


Fichier c4d_symbols.H :
enum
{
	VONC_PERCEUSE_NOM = 1000,
	VONC_PERCEUSE_COTES = 1001,
	VONC_PERCEUSE_NGONES = 1002,
	VONC_PERCEUSE_AIDE = 1003,
	VONC_PERCEUSE_INFO = 1004,
	VONC_PERCEUSE_DON = 1005,
	VONC_PERCEUSE_NETT = 1006,
	VONC_PERCEUSE_NORMALE = 1007,
	VONC_PERCEUSE_PROF = 1008,
	VONC_PERCEUSE_AUTO = 1009,
	
	// End of symbol definition
	_DUMMY_ELEMENT_
};


Fichier c4d_strings.STR :
STRINGTABLE
{
	VONC_PERCEUSE_NOM		"Perceuse";
	VONC_PERCEUSE_COTES		"C\u00F4t\u00E9s";
	VONC_PERCEUSE_NGONES	"Cr\u00E9er des n-gones";
	VONC_PERCEUSE_AIDE		"Troue l'objet actif";
	VONC_PERCEUSE_INFO		"v 1.0 - C\u00E9sar Vonc - http://code.vonc.fr";
	VONC_PERCEUSE_DON		"Faire un don";
	VONC_PERCEUSE_NETT		"Nettoyage auto";
	VONC_PERCEUSE_NORMALE	"Face \u00E0 la cam\u00E9ra";
	VONC_PERCEUSE_PROF		"Profondeur";
	VONC_PERCEUSE_AUTO		"Auto";
}

Cet outil est gratuit, n'oubliez pas de faire une donation afin de soutenir le site et aider à la création de nouvelles fonctions !

Bien sûr ! Je vais soutenir de ce pas.

Télécharger
Fermer ×




Commentaires
RN
Vendredi 18 octobre 2013 à 16:30:48

Hello, encore une fois merci pour le plug
et n'oublie pas d'ajouter une fonction de quantification d'angles :D


César
Dimanche 27 octobre 2013 à 17:08:18

Merci, j'en prends note.

Bogue connu : l'outil troue les polygones du haut dans la vue Bas et inversement.

César
Lundi 9 décembre 2013 à 15:32:10

Corrections appliquées dans la v 1.1 !

tehri
Mardi 24 décembre 2013 à 1:39:30

une fois installé dans le dossier plugin, je ne trouve celui çi une fois C4D ouvert... quelqu'un peut-il m'aider ?

César
Mercredi 25 décembre 2013 à 16:20:29

Quelle version de C4D utilises-tu ? L'outil se trouve dans l'onglet Modules externes. S'il n'y est pas, qu'affiche la console ? (onglet Script > Console (Maj + F10)).

Nouveau commentaire :

Pseudo :



Êtes-vous un robot ?

Commentaires (5)
Menu
César Vonc
Code Vonc