C4D测量脚本:Python : Aire et volume

2014-11-21 19:47 发布 | 作品版权归原作者所有,仅供参考学习,禁止商业使用!

插件脚本 /[测量移动]
1678 7 0
C4D测量脚本:Python : Aire et volume
C4D测量脚本:Python : Aire et volume - C4D之家 - image_01.png

Copier le dossier « vonc_airevol » dans le dossier « plugins » du répertoire de Cinéma 4D.
v 1.3 :
- Calcul de multiples objets.
- Mise à jour auto.
- Traduction tchèque par Lubo Bezek.

v 1.2 :
- Corrections mineures.

v 1.1 :
- Possibilité de changer l'unité.
- Prise en compte de l'échelle du document.


Calcule l'aire et le volume :
- d'objets fermés,
- d'objets ouverts,
- de sélections de polygones,
- de tracés (splines).
Fichier .PYP
  1. import os
  2. import c4d
  3. from c4d import gui, plugins, utils, bitmaps, Vector
  4. from c4d.utils import SendModelingCommand, Neighbor
  5. from c4d.plugins import GeLoadString as txt

  6. # César Vonc - code.vonc.fr

  7. MODULE_ID = 1030057
  8. VONC_AIRVOL_NOM = 1000
  9. VONC_AIRVOL_ETAT_0 = 1001
  10. VONC_AIRVOL_ETAT_1 = 1002
  11. VONC_AIRVOL_AIRE = 1003
  12. VONC_AIRVOL_VOLUME = 1004
  13. VONC_AIRVOL_CALCULER = 1005
  14. VONC_AIRVOL_POLSEL = 1006
  15. VONC_AIRVOL_LICENCE = 1007
  16. VONC_AIRVOL_CLEF = 1008
  17. VONC_AIRVOL_INFO = 1009
  18. VONC_AIRVOL_AIDE = 1010
  19. VONC_AIRVOL_OBJSEL = 1011
  20. VONC_AIRVOL_SOUSOBJ = 1012
  21. VONC_AIRVOL_TOTAL = 1013
  22. VONC_AIRVOL_TOTALE = 1014
  23. VONC_AIRVOL_MAJ = 1015
  24. VERSION = "1.3"

  25. class Airevolume() :

  26. def __init__(self, so) :
  27. self.objs = None
  28. self.sousObj = so
  29. self.aire = 0
  30. self.volume = 0
  31. self.sel = 0
  32. self.nbObj = 0
  33. self.liObjs = []
  34. self.liVol = []
  35. self.liAire = []

  36. self.doc = c4d.documents.GetActiveDocument()
  37. self.op = self.doc.GetActiveObject()

  38. if so :
  39. self.objs = self.doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_0)
  40. else :
  41. self.objs = self.doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)

  42. def fermeTrous(self, obj, mat) :
  43. obj.SetMg(mat)
  44. doc = self.doc
  45. doc.InsertObject(obj)
  46. polys = obj.GetAllPolygons()
  47. n = Neighbor()
  48. n.Init(obj)
  49. params = c4d.BaseContainer()
  50. params[c4d.MDATA_CLOSEHOLE_INDEX] = obj
  51. params[c4d.MDATA_CLOSEHOLE_TRI] = True
  52. mode = c4d.MODELINGCOMMANDMODE_EDGESELECTION
  53. commande = c4d.ID_MODELING_CLOSEHOLE_TOOL

  54. for i, pol in enumerate(polys):
  55. nab = n.GetNeighbor(pol.a, pol.b, i)
  56. nbc = n.GetNeighbor(pol.b, pol.c, i)
  57. ncd = n.GetNeighbor(pol.c, pol.d, i)
  58. nda = n.GetNeighbor(pol.d, pol.a, i)
  59. cotes = n.GetPolyInfo(i)["edge"]

  60. if nab == -1:
  61. params[c4d.MDATA_CLOSEHOLE_EDGE] = cotes[0]
  62. SendModelingCommand(command=commande, list=[obj], mode=mode, bc=params, doc=doc)
  63. n.Init(obj)
  64. if nbc == -1:
  65. params[c4d.MDATA_CLOSEHOLE_EDGE] = cotes[1]
  66. SendModelingCommand(command=commande, list=[obj], mode=mode, bc=params, doc=doc)
  67. n.Init(obj)
  68. if ((ncd == -1) and (pol.c != pol.d)):
  69. params[c4d.MDATA_CLOSEHOLE_EDGE] = cotes[2]
  70. SendModelingCommand(command=commande, list=[obj], mode=mode, bc=params, doc=doc)
  71. n.Init(obj)
  72. if nda == -1:
  73. params[c4d.MDATA_CLOSEHOLE_EDGE] = cotes[3]
  74. SendModelingCommand(command=commande, list=[obj], mode=mode, bc=params, doc=doc)
  75. n.Init(obj)

  76. obj.Remove()
  77. c4d.EventAdd()
  78. return obj

  79. def volumeTetraedre(self, p1, p2, p3) :
  80. return p1.Dot(p2.Cross(p3)) / 6.0

  81. def aireTriangle(self, A, B, C) :
  82. vAB = A - B
  83. vAC = A - C
  84. return vAB.Cross(vAC).GetLength() * 0.5

  85. def Calcule(self) :
  86. self.aire = 0
  87. self.volume = 0
  88. self.sel = 0
  89. tab3 = []
  90. for obj in self.objs :
  91. conv = SendModelingCommand(command=c4d.MCOMMAND_CURRENTSTATETOOBJECT, list=[obj], doc=self.doc)
  92. if not conv : continue
  93. conv = conv[0]
  94. conv.SetMg(obj.GetMg())
  95. cache = conv.GetDeformCache() or conv.GetCache() or conv
  96. cache = cache.GetDeformCache() or cache
  97. if cache : tab3.append(cache)

  98. self.objs = tab3

  99. if self.sousObj :
  100. tab = []
  101. tab2 = []
  102. for obj in self.objs :
  103. tab2.append(obj)
  104. sobj = obj.GetDown()
  105. if sobj : tab.append(sobj)
  106. for obj in tab :
  107. while obj :
  108. objs = [obj]
  109. for o in objs :
  110. tab2.append(o)
  111. objs.extend(o.GetChildren())
  112. obj = obj.GetNext()

  113. self.objs = tab2

  114. for obj in self.objs :
  115. aire, volume = self.CalculeObj(obj)
  116. self.aire += aire
  117. self.volume += volume
  118. if aire or volume :
  119. self.liObjs.append(obj.GetName())
  120. self.liAire.append(aire)
  121. self.liVol.append(volume)

  122. # self.nbObj = len(self.objs)
  123. self.nbObj = len(self.liObjs)


  124. def CalculeObj(self, obj):
  125. if not obj : return 0, 0
  126. doc = self.doc

  127. # Si cerce
  128. if obj.CheckType(c4d.Ospline) :
  129. peau = c4d.BaseObject(c4d.Oloft)
  130. obj.GetClone().InsertUnder(peau)
  131. retour = SendModelingCommand(command=c4d.MCOMMAND_CURRENTSTATETOOBJECT, list=[peau], doc=doc)
  132. if not retour : return 0, 0
  133. if retour[0].CheckType(c4d.Opolygon) : obj = retour[0]
  134. else : obj = retour[0].GetDown()
  135. if not obj : return 0, 0

  136. if not obj.CheckType(c4d.Opolygon) :
  137. return 0, 0

  138. # Détache la sélection
  139. if obj.GetBit(c4d.BIT_ACTIVE) :
  140. if doc.GetMode() == c4d.Mpolygons :
  141. bs = obj.GetPolygonS()
  142. self.sel += bs.GetCount()
  143. retour = SendModelingCommand(command=c4d.MCOMMAND_SPLIT, list=[obj],
  144. mode=c4d.MODELINGCOMMANDMODE_POLYGONSELECTION, doc=doc)
  145. if not retour : return 0, 0
  146. obj = retour[0]

  147. # Optimise
  148. params = c4d.BaseContainer()
  149. params[c4d.MDATA_OPTIMIZE_TOLERANCE] = 0.001
  150. params[c4d.MDATA_OPTIMIZE_POINTS] = False
  151. params[c4d.MDATA_OPTIMIZE_POLYGONS] = True
  152. params[c4d.MDATA_OPTIMIZE_UNUSEDPOINTS] = True
  153. SendModelingCommand(command=c4d.MCOMMAND_OPTIMIZE, list=[obj], bc=params, doc=doc)

  154. # Ferme les trous
  155. objVol = self.fermeTrous(obj.GetClone(), obj.GetMg())

  156. # Aligne les normales
  157. SendModelingCommand(command=c4d.MCOMMAND_ALIGNNORMALS, list=[obj], doc=doc)
  158. SendModelingCommand(command=c4d.MCOMMAND_ALIGNNORMALS, list=[objVol], doc=doc)

  159. # Triangule
  160. SendModelingCommand(command=c4d.MCOMMAND_TRIANGULATE, list=[obj], doc=doc)
  161. SendModelingCommand(command=c4d.MCOMMAND_TRIANGULATE, list=[objVol], doc=doc)

  162. # --

  163. polys = obj.GetAllPolygons()
  164. pts = obj.GetAllPoints()
  165. polysVol = objVol.GetAllPolygons()
  166. ptsVol = objVol.GetAllPoints()

  167. ech = Vector(obj.GetMg().v1.GetLength(), obj.GetMg().v2.GetLength(), obj.GetMg().v3.GetLength())
  168. pts = [pt.__rxor__(ech) for pt in pts]
  169. ech = Vector(objVol.GetMg().v1.GetLength(), objVol.GetMg().v2.GetLength(), objVol.GetMg().v3.GetLength())
  170. # ech = objVol.GetAbsScale()
  171. ptsVol = [pt.__rxor__(ech) for pt in ptsVol]

  172. aire = 0.0
  173. for pol in polys :
  174. aire += self.aireTriangle(pts[pol.a], pts[pol.b], pts[pol.c])

  175. volume = 0.0
  176. for pol in polysVol :
  177. volume += self.volumeTetraedre(ptsVol[pol.a], ptsVol[pol.b], ptsVol[pol.c])

  178. volume = abs(volume)
  179. return aire, volume

  180. class Dialogue(gui.GeDialog):

  181. def __init__(self) :
  182. self.airevol = None
  183. self.uniteFin = 0
  184. self.sousObj = True
  185. self.majAuto = True
  186. self.caches = [[],0,0,0,0]
  187. self.airevol = Airevolume(self.sousObj)
  188. self.airevol.Calcule()

  189. prefs = c4d.GetWorldContainer()
  190. unitePref = prefs[c4d.WPREF_UNITS_BASIC]
  191. self.uniteFin = unitePref

  192. def unite(self, v, valeur) :
  193. doc = c4d.documents.GetActiveDocument()

  194. donneesDoc = doc.GetData()[c4d.DOCUMENT_DOCUNIT]
  195. ech, uniteDoc = donneesDoc.GetUnitScale()

  196. uniteFin = self.uniteFin

  197. ufin = ""
  198. if uniteFin == c4d.UNIT_NONE : ufin = ""
  199. elif uniteFin == c4d.UNIT_KM : ufin = "km"
  200. elif uniteFin == c4d.UNIT_M : ufin = "m"
  201. elif uniteFin == c4d.UNIT_CM : ufin = "cm"
  202. elif uniteFin == c4d.UNIT_MM : ufin = "mm"
  203. elif uniteFin == c4d.UNIT_UM : ufin = "µm"
  204. elif uniteFin == c4d.UNIT_NM : ufin = "nm"
  205. elif uniteFin == c4d.UNIT_MILE : ufin = "mi"
  206. elif uniteFin == c4d.UNIT_YARD : ufin = "yd"
  207. elif uniteFin == c4d.UNIT_FEET : ufin = "ft"
  208. elif uniteFin == c4d.UNIT_INCH : ufin = "in"

  209. valeur *= ech**v

  210. fac = 1.0
  211. if uniteDoc == c4d.UNIT_KM : fac *= 10.0**(3*v)
  212. elif uniteDoc == c4d.UNIT_CM : fac *= 10.0**(-2*v)
  213. elif uniteDoc == c4d.UNIT_MM : fac *= 10.0**(-3*v)
  214. elif uniteDoc == c4d.UNIT_UM : fac *= 10.0**(-6*v)
  215. elif uniteDoc == c4d.UNIT_NM : fac *= 10.0**(-9*v)
  216. elif uniteDoc == c4d.UNIT_MILE : fac *= 1609.344**v
  217. elif uniteDoc == c4d.UNIT_YARD : fac *= 0.9144**v
  218. elif uniteDoc == c4d.UNIT_FEET : fac *= 0.3048**v
  219. elif uniteDoc == c4d.UNIT_INCH : fac *= 0.0254**v

  220. if ufin == "km" : fac *= 10.0**(-3*v)
  221. elif ufin == "cm" : fac *= 10.0**(2*v)
  222. elif ufin == "mm" : fac *= 10.0**(3*v)
  223. elif ufin == "µm" : fac *= 10.0**(6*v)
  224. elif ufin == "nm" : fac *= 10.0**(9*v)
  225. elif ufin == "mi" : fac /= 1609.344**v
  226. elif ufin == "yd" : fac /= 0.9144**v
  227. elif ufin == "ft" : fac /= 0.3048**v
  228. elif ufin == "in" : fac /= 0.0254**v

  229. valeur *= fac

  230. if v == 2 : v = "²"
  231. elif v == 3 : v = "³"
  232. if valeur > 10.0 : valeur = round(valeur, 4)
  233. retour = str(valeur) + " " + ufin + v
  234. return retour

  235. def rapport(self) :
  236. chn = ""
  237. chn += txt(VONC_AIRVOL_POLSEL) + " : " + str(self.airevol.sel) + "\r\n"
  238. chn += txt(VONC_AIRVOL_OBJSEL) + " : " + str(self.airevol.nbObj) + "\r\n"
  239. chn += "\r\n"

  240. liNb = len(self.airevol.liObjs)

  241. if liNb > 1 : chn += txt(VONC_AIRVOL_AIRE) + " : " + self.unite(2, self.airevol.aire) + "\r\n"
  242. else : chn += txt(VONC_AIRVOL_AIRE) + " : \r\n"
  243. for i in xrange(liNb) :
  244. chn += " " + self.airevol.liObjs[i] + " : " + self.unite(2, self.airevol.liAire[i]) + "\r\n"
  245. chn += "\r\n"

  246. if liNb > 1 : chn += txt(VONC_AIRVOL_VOLUME) + " : " + self.unite(3, self.airevol.volume) + "\r\n"
  247. else : chn += txt(VONC_AIRVOL_VOLUME) + " : \r\n"
  248. for i in xrange(liNb) :
  249. if i : chn += "\r\n"
  250. chn += " " + self.airevol.liObjs[i] + " : " + self.unite(3, self.airevol.liVol[i])

  251. return chn

  252. def opere(self, force=False) :
  253. self.sousObj = self.GetBool(23)
  254. self.majAuto = self.GetBool(24)

  255. doc = c4d.documents.GetActiveDocument()
  256. if self.sousObj :
  257. objs = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_0)
  258. else :
  259. objs = doc.GetActiveObjects(c4d.GETACTIVEOBJECTFLAGS_CHILDREN)
  260. caches = [objs, 0, 0, 0, 0]
  261. if objs :
  262. tabobjs = objs[:]
  263. for obj in tabobjs :
  264. caches[1] += obj.GetDirty(c4d.DIRTY_SELECT)
  265. caches[2] += obj.GetDirty(c4d.DIRTY_MATRIX)
  266. caches[3] += obj.GetDirty(c4d.DIRTY_DATA)
  267. caches[4] += obj.GetDirty(c4d.DIRTY_CHILDREN)
  268. tabobjs.extend(obj.GetChildren())
  269. if not force :
  270. if caches == self.caches :
  271. self.caches = caches
  272. return

  273. self.caches = caches
  274. self.airevol = Airevolume(self.sousObj)
  275. self.airevol.Calcule()
  276. self.uniteFin = self.GetLong(41)
  277. self.SetString(26, self.rapport())

  278. def CreateLayout(self) :
  279. self.GroupBegin(40, c4d.BFH_SCALEFIT, 2, 1)
  280. self.GroupBorderSpace(5, 0, 5, 0)
  281. self.AddButton(21, c4d.BFH_SCALE|c4d.BFH_RIGHT, initw=150, inith=20, name=txt(VONC_AIRVOL_CALCULER))
  282. self.AddComboBox(41, c4d.BFH_SCALE|c4d.BFH_CENTER, initw=60)
  283. # self.AddChild(41, c4d.UNIT_NONE, "")
  284. self.AddChild(41, c4d.UNIT_KM, "km")
  285. self.AddChild(41, c4d.UNIT_M, "m")
  286. self.AddChild(41, c4d.UNIT_CM, "cm")
  287. self.AddChild(41, c4d.UNIT_MM, "mm")
  288. self.AddChild(41, c4d.UNIT_UM, "µm")
  289. self.AddChild(41, c4d.UNIT_NM, "nm")
  290. self.AddChild(41, c4d.UNIT_MILE, "mi")
  291. self.AddChild(41, c4d.UNIT_YARD, "yd")
  292. self.AddChild(41, c4d.UNIT_FEET, "ft")
  293. self.AddChild(41, c4d.UNIT_INCH, "in")
  294. self.GroupEnd()

  295. self.GroupBegin(20, c4d.BFH_SCALEFIT, 1, 1)
  296. self.GroupBorderSpace(5, 0, 5, 0)
  297. self.AddCheckbox(23, c4d.BFH_SCALEFIT, 0, 0, txt(VONC_AIRVOL_SOUSOBJ))
  298. self.AddCheckbox(24, c4d.BFH_SCALEFIT, 0, 0, txt(VONC_AIRVOL_MAJ))
  299. self.GroupEnd()

  300. self.GroupBegin(25, c4d.BFH_SCALEFIT|c4d.BFV_SCALEFIT, 1, 1)
  301. self.GroupBorderSpace(5, 0, 5, 0)
  302. self.GroupBorderNoTitle(c4d.BORDER_THIN_IN)
  303. self.AddMultiLineEditText(26, c4d.BFH_SCALEFIT|c4d.BFV_SCALEFIT)
  304. self.GroupEnd()

  305. self.GroupBegin(30, c4d.BFH_SCALEFIT, 1, 1)
  306. self.GroupBorderSpace(5, 5, 5, 5)
  307. self.AddStaticText(31, c4d.BFH_SCALEFIT, name="v "+VERSION+" - "+txt(VONC_AIRVOL_INFO))
  308. self.GroupEnd()
  309. return True

  310. def InitValues(self) :
  311. self.SetTitle(txt(VONC_AIRVOL_NOM))
  312. self.SetLong(41, self.uniteFin)
  313. self.SetBool(23, self.sousObj)
  314. self.SetBool(24, self.majAuto)
  315. self.SetString(26, self.rapport())
  316. return True

  317. def Command(self, id, msg) :
  318. if id == 21 or id == 23 or id == 24 :
  319. self.opere(True)
  320. elif id == 41 :
  321. self.uniteFin = self.GetLong(41)
  322. self.SetString(26, self.rapport())

  323. return True

  324. def CoreMessage(self, id, msg) :

  325. if self.majAuto and id == c4d.EVMSG_CHANGE :
  326. self.opere()

  327. return True

  328. class AirevolumeCommande(c4d.plugins.CommandData):
  329. dialog = None

  330. def Execute(self, doc):
  331. if self.dialog is None:
  332. self.dialog = Dialogue()
  333. return self.dialog.Open(dlgtype=c4d.DLG_TYPE_ASYNC, pluginid=MODULE_ID, defaulth=300, defaultw=100)

  334. def RestoreLayout(self, sec_ref):
  335. if self.dialog is None:
  336. self.dialog = Dialogue()
  337. return self.dialog.Restore(pluginid=MODULE_ID, secret=sec_ref)

  338. if __name__ == "__main__":
  339. bmp = bitmaps.BaseBitmap()
  340. dir, f = os.path.split(__file__)
  341. fn = os.path.join(dir, "res", "vonc_airevol.tif")
  342. bmp.InitWith(fn)
  343. c4d.plugins.RegisterCommandPlugin(id=MODULE_ID, str=txt(VONC_AIRVOL_NOM),
  344. help=txt(VONC_AIRVOL_AIDE),info=0,
  345. dat=AirevolumeCommande(), icon=bmp)
复制代码

Fichier .H
  1. enum
  2. {
  3. VONC_AIRVOL_NOM = 1000,
  4. VONC_AIRVOL_ETAT_0 = 1001,
  5. VONC_AIRVOL_ETAT_1 = 1002,
  6. VONC_AIRVOL_AIRE = 1003,
  7. VONC_AIRVOL_VOLUME = 1004,
  8. VONC_AIRVOL_CALCULER = 1005,
  9. VONC_AIRVOL_POLSEL = 1006,
  10. VONC_AIRVOL_LICENCE = 1007,
  11. VONC_AIRVOL_CLEF = 1008,
  12. VONC_AIRVOL_INFO = 1009,
  13. VONC_AIRVOL_AIDE = 1010,
  14. VONC_AIRVOL_OBJSEL = 1011,
  15. VONC_AIRVOL_SOUSOBJ = 1012,
  16. VONC_AIRVOL_TOTAL = 1013,
  17. VONC_AIRVOL_TOTALE = 1014,
  18. VONC_AIRVOL_MAJ = 1015,

  19. _DUMMY_ELEMENT_
  20. };
复制代码

Fichier .STR
  1. STRINGTABLE
  2. {
  3. VONC_AIRVOL_NOM "Aire et Volume";
  4. VONC_AIRVOL_AIRE "Aire totale";
  5. VONC_AIRVOL_VOLUME "Volume total";
  6. VONC_AIRVOL_CALCULER "Calculer";
  7. VONC_AIRVOL_POLSEL "Polygones s\u00E9lectionn\u00E9s";
  8. VONC_AIRVOL_OBJSEL "Objets";
  9. VONC_AIRVOL_INFO "C\u00E9sar Vonc - http://code.vonc.fr";
  10. VONc_AIRVOL_AIDE "Calcule l'aire et le volume d'objets, de s\u00E9lections de polygones ou de splines.";
  11. VONC_AIRVOL_SOUSOBJ "Inclure les sous-objets";
  12. VONC_AIRVOL_MAJ "Mise \u00E0 jour auto";
  13. }
复制代码





B Color Smilies

Comment :7

插件脚本
软件性质:
适用版本: C4D R15 - C4D 2026
软件版本: Aire et volume v 1.3
系统平台: Win MAC
软件语言: 英文
插件来源: https://www.c4d.com.cn/c4dsoft.html
百套精美Kitbash3D模型专题合集下载
时尚卡通办公室人物C4D立体图标工程下载Cinema 4D Fashion Cartoon Office Character 3D Icon Project Download
C4D科技新闻片头电视栏目频道包装动画工程下载Cinema 4D Technology News Headline TV Program Channel Packaging Animation Project Download
关闭

C4D精选推荐 /10

知识
问答
快速回复 返回顶部 返回列表