diff --git a/HE_scalp_mesh.py b/HE_scalp_mesh.py new file mode 100644 index 00000000..83a20cdf --- /dev/null +++ b/HE_scalp_mesh.py @@ -0,0 +1,1415 @@ +# ##### BEGIN GPL LICENSE BLOCK ##### +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 3 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software Foundation, +# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +# +# ##### END GPL LICENSE BLOCK ##### + +#by Noizirom + +def scalp_vertices(): + return [[-0.04461, 0.03254, -0.10046], + [-0.03806, 0.03898, -0.09903], + [-0.02974, 0.04644, -0.0969], + [-0.01956, 0.05167, -0.09533], + [-0.00969, 0.05546, -0.09403], + [-0.05781, 0.028, -0.06469], + [-0.06593, 0.03598, -0.01398], + [-0.07256, -0.00723, 0.0247], + [-0.07105, -0.03932, 0.0241], + [-0.06177, 0.0364, -0.04163], + [-0.05997, 0.03286, -0.05445], + [-0.04116, -0.09656, 0.03754], + [-0.03065, -0.1044, 0.03987], + [-0.05115, -0.08915, 0.03423], + [-0.06368, -0.07671, 0.02465], + [-0.02064, -0.11003, 0.04173], + [-0.00949, -0.11285, 0.04236], + [-0.07195, 0.01403, 0.01725], + [-0.07038, -0.04848, -0.06233], + [-0.0672, -0.07114, 0.01669], + [-0.05007, 0.02575, 0.05831], + [-0.04, 0.03135, 0.06673], + [-0.06842, 0.01582, 0.0284], + [-0.07708, 0.00275, -0.02223], + [-0.07633, -0.00433, -0.01943], + [-0.07671, 0.00916, -0.02533], + [-0.07573, 0.01442, -0.03509], + [-0.05717, 0.00264, 0.05529], + [-0.03988, 0.00776, 0.07404], + [-0.04981, 0.00487, 0.06502], + [-0.03764, -0.06405, 0.06921], + [-0.05418, 0.03465, -0.06279], + [-0.04568, 0.04839, -0.05897], + [-0.03919, 0.05507, -0.05709], + [-0.0295, 0.06189, -0.05504], + [-0.05595, 0.04005, -0.05116], + [-0.04726, 0.05469, -0.04595], + [-0.04053, 0.06147, -0.04389], + [-0.03073, 0.06797, -0.04195], + [-0.06892, -0.06119, 0.01959], + [-0.05779, 0.04427, -0.03688], + [-0.04942, 0.05982, -0.02896], + [-0.04243, 0.06687, -0.0264], + [-0.03309, 0.07386, -0.02493], + [-0.06495, -0.07982, 0.01334], + [-0.06295, 0.04355, -0.00662], + [-0.05457, 0.06075, 0.00596], + [-0.04769, 0.06861, 0.0099], + [-0.03854, 0.07614, 0.0134], + [-0.06715, 0.02857, 0.01893], + [-0.05541, 0.03845, 0.03604], + [-0.04791, 0.04499, 0.04288], + [-0.03911, 0.05325, 0.05033], + [-0.04072, -0.01112, 0.07629], + [-0.05067, -0.01122, 0.06756], + [-0.05017, -0.05786, 0.06163], + [-0.05791, -0.01101, 0.05685], + [-0.0697, -0.00721, 0.0355], + [-0.0693, 0.00333, 0.03352], + [-0.06834, -0.04233, 0.03484], + [-0.05897, -0.052, 0.05363], + [-0.05831, -0.06502, 0.04801], + [-0.06761, -0.05409, 0.03192], + [-0.0498, -0.07259, 0.05466], + [-0.03786, -0.08053, 0.06052], + [-0.01105, -0.09107, 0.06811], + [-0.01547, 0.06628, 0.05706], + [-0.01388, 0.08599, 0.01586], + [-0.01352, -0.01051, 0.08552], + [-0.01446, 0.01308, 0.08363], + [-0.01147, 0.08404, -0.02435], + [-0.01024, 0.07584, -0.04157], + [-0.00987, 0.07071, -0.05469], + [-0.01082, -0.07283, 0.07857], + [-0.024, -0.06907, 0.07481], + [-0.01886, 0.06685, -0.05488], + [-0.02682, 0.08179, 0.0155], + [-0.02218, 0.07957, -0.02463], + [-0.02008, 0.07379, -0.04167], + [-0.02879, 0.06204, 0.05585], + [-0.02785, 0.01116, 0.0801], + [-0.02762, -0.01116, 0.08271], + [-0.02447, -0.08659, 0.0651], + [-0.03761, -0.10498, 0.02864], + [-0.06105, -0.08578, 0.0195], + [-0.00808, -0.1179, 0.03163], + [-0.01848, -0.11613, 0.03123], + [-0.02788, -0.11163, 0.02992], + [-0.04723, -0.09825, 0.02634], + [-0.05588, -0.0778, 0.04179], + [-0.06607, -0.06598, 0.02862], + [-0.04611, -0.08534, 0.04634], + [-0.03458, -0.09352, 0.0502], + [-0.07032, -0.04043, -0.06233], + [-0.01066, -0.10349, 0.05469], + [-0.02297, -0.0998, 0.05326], + [-0.05583, 0.02325, -0.07381], + [-0.00944, 0.06172, -0.07236], + [-0.01876, 0.05826, -0.07331], + [-0.0277, 0.05189, -0.0744], + [-0.03637, 0.04556, -0.07576], + [-0.04276, 0.03927, -0.07737], + [-0.05194, 0.02448, -0.08089], + [-0.07031, -0.05038, 0.02232], + [-0.04249, 0.03564, -0.08651], + [-0.0364, 0.04287, -0.08491], + [-0.02839, 0.04919, -0.08382], + [-0.01911, 0.05393, -0.0825], + [-0.00985, 0.05843, -0.08124], + [-0.05764, 0.02107, 0.04974], + [-0.01433, 0.04072, 0.07398], + [-0.02776, 0.03686, 0.07213], + [-0.07641, 0.01261, -0.0304], + [-0.03957, 0.06919, 0.03372], + [-0.04786, 0.0603, 0.02729], + [-0.05539, 0.05319, 0.02264], + [-0.06478, 0.03832, 0.00739], + [-0.0154, 0.08061, 0.03808], + [-0.0283, 0.07637, 0.03735], + [-0.06772, 0.03274, -3e-05], + [-0.0455, 0.0698, -0.00768], + [-0.05224, 0.06232, -0.011], + [-0.0606, 0.04511, -0.02149], + [-0.03637, 0.07711, -0.00608], + [-0.01296, 0.08705, -0.00519], + [-0.02508, 0.08311, -0.00547], + [-0.06385, 0.03714, -0.02792], + [-0.07534, -0.00977, -0.01849], + [-0.07519, -0.01605, -0.01953], + [-0.07527, -0.02328, -0.02789], + [-0.07364, -0.03684, -0.02789], + [-0.07039, -0.034, -0.06233], + [-0.00955, 0.06597, -0.06416], + [-0.01873, 0.06248, -0.06454], + [-0.0282, 0.05629, -0.06503], + [-0.03707, 0.04921, -0.06682], + [-0.0436, 0.04282, -0.06868], + [-0.05234, 0.02908, -0.07186], + [-0.0716, -0.02856, -0.06233], + [-0.07245, 0.00274, 0.02217], + [-0.07034, 0.02451, 0.00952], + [-0.05636, 0.05435, -0.01516], + [-0.06184, 0.03365, 0.02906], + [-0.06363, -0.05881, 0.04018], + [-0.05995, 0.0453, 0.01551], + [-0.05344, 0.05282, -0.03216], + [-0.05893, 0.05266, 0.00075], + [-0.05157, 0.04896, -0.04786], + [-0.04979, 0.04242, -0.06041], + [-0.04804, 0.0288, -0.08807], + [-0.04687, 0.03225, -0.0791], + [-0.05516, -0.09172, 0.02319], + [-0.06177, -0.07108, 0.03572], + [-0.06406, 0.00348, 0.04531], + [-0.0586, -0.08258, 0.03027], + [-0.06345, 0.01822, 0.04044], + [-0.04783, 0.03661, -0.07001], + [-0.06433, -0.00888, 0.04684], + [-0.06454, -0.04668, 0.04464], + [-0.07112, -0.05497, 0.00529], + [-0.07527, 0.00877, 0.00098], + [-0.07352, -0.03604, 0.00818], + [-0.0755, -0.00845, 0.00674], + [-0.07284, -0.04558, 0.0071], + [-0.07215, 0.0214, -0.01423], + [-0.07567, 0.00015, 0.00481], + [-0.07409, 0.01633, -0.00554], + [-0.0671, -0.07181, 0.00115], + [-0.06845, -0.0692, -0.01352], + [-0.06935, -0.06379, 0.00333], + [-0.07068, -0.05973, -0.01421], + [-0.07117, -0.05369, -0.02804], + [-0.07146, -0.05146, -0.04303], + [-0.07252, -0.04975, -0.01185], + [-0.07242, -0.04626, -0.02932], + [-0.07204, -0.04421, -0.04478], + [-0.07239, -0.03624, -0.04704], + [-0.07458, -0.02991, -0.02789], + [-0.07398, -0.04131, -0.01121], + [-0.07455, -0.03319, -0.00954], + [-0.0755, -0.00959, -0.00659], + [-0.07591, -0.00249, -0.00787], + [-0.07591, 0.00484, -0.0107], + [-0.07518, 0.01135, -0.0158], + [-0.07391, 0.01576, -0.02281], + [-0.07061, 0.0238, -0.02512], + [-0.07302, 0.01788, -0.03132], + [-0.0694, 0.02449, -0.03662], + [-0.07187, 0.01834, -0.0404], + [-0.07112, 0.01772, -0.04948], + [-0.06832, 0.02384, -0.04738], + [-0.07002, 0.01637, -0.05877], + [-0.06698, 0.02133, -0.05771], + [-0.0651, 0.01806, -0.06662], + [-0.01257, -0.0332, 0.08569], + [-0.07286, -0.02936, -0.0494], + [-0.07349, -0.02849, -0.04352], + [-0.07432, -0.02412, -0.03399], + [-0.07405, -0.02776, -0.03933], + [-0.02676, -0.03223, 0.08257], + [-0.04062, -0.02994, 0.07709], + [-0.07246, -0.01736, 0.02561], + [-0.0591, -0.02434, 0.05738], + [-0.06969, -0.01827, 0.03612], + [-0.05146, -0.02708, 0.06758], + [-0.06476, -0.0209, 0.04684], + [-0.07474, -0.01721, 0.00832], + [-0.01198, -0.05386, 0.08333], + [-0.07517, -0.01704, -0.00602], + [-0.03922, -0.04797, 0.07457], + [-0.05978, -0.0385, 0.05693], + [-0.06963, -0.02988, 0.03627], + [-0.05138, -0.04327, 0.06526], + [-0.06514, -0.03427, 0.04687], + [-0.07183, -0.02817, 0.0259], + [-0.02565, -0.05134, 0.08066], + [-0.07407, -0.02648, 0.00872], + [-0.07482, -0.02537, -0.00797], + [-0.05653, 0.031, 0.04185], + [-0.04844, 0.04027, 0.04667], + [0.0, 0.05651, -0.09374], + [0.04461, 0.03254, -0.10046], + [0.03806, 0.03898, -0.09903], + [0.02974, 0.04644, -0.0969], + [0.01956, 0.05167, -0.09533], + [0.00969, 0.05546, -0.09403], + [0.0, -0.11314, 0.0427], + [0.0, -0.01043, 0.08679], + [0.0, -0.07288, 0.07946], + [0.0, 0.07257, -0.05405], + [0.0, 0.07978, -0.04111], + [0.0, 0.08669, -0.02402], + [0.0, 0.08942, 0.01627], + [0.0, 0.06848, 0.05872], + [0.0, -0.0909, 0.06864], + [0.0, -0.1182, 0.03195], + [0.0, -0.10413, 0.05527], + [0.0, 0.06335, -0.07178], + [0.0, 0.05992, -0.08066], + [0.0, 0.04367, 0.07566], + [0.0, 0.08232, 0.03921], + [0.0, 0.08911, -0.00504], + [0.0, 0.06757, -0.06341], + [0.0, -0.03336, 0.08646], + [0.0, -0.05374, 0.08478], + [0.05781, 0.028, -0.06469], + [0.06593, 0.03598, -0.01398], + [0.07256, -0.00723, 0.0247], + [0.07105, -0.03932, 0.0241], + [0.06177, 0.0364, -0.04163], + [0.05997, 0.03286, -0.05445], + [0.04116, -0.09656, 0.03754], + [0.03065, -0.1044, 0.03987], + [0.05115, -0.08915, 0.03423], + [0.06368, -0.07671, 0.02465], + [0.02064, -0.11003, 0.04173], + [0.00949, -0.11285, 0.04236], + [0.07195, 0.01403, 0.01725], + [0.07038, -0.04848, -0.06233], + [0.0672, -0.07114, 0.01669], + [0.05007, 0.02575, 0.05831], + [0.04, 0.03135, 0.06673], + [0.06842, 0.01582, 0.0284], + [0.07708, 0.00275, -0.02223], + [0.07633, -0.00433, -0.01943], + [0.07671, 0.00916, -0.02533], + [0.07573, 0.01442, -0.03509], + [0.05717, 0.00264, 0.05529], + [0.03988, 0.00776, 0.07404], + [0.04981, 0.00487, 0.06502], + [0.03764, -0.06405, 0.06921], + [0.05418, 0.03465, -0.06279], + [0.04568, 0.04839, -0.05897], + [0.03919, 0.05507, -0.05709], + [0.0295, 0.06189, -0.05504], + [0.05595, 0.04005, -0.05116], + [0.04726, 0.05469, -0.04595], + [0.04053, 0.06147, -0.04389], + [0.03073, 0.06797, -0.04195], + [0.06892, -0.06119, 0.01959], + [0.05779, 0.04427, -0.03688], + [0.04942, 0.05982, -0.02896], + [0.04243, 0.06687, -0.0264], + [0.03309, 0.07386, -0.02493], + [0.06495, -0.07982, 0.01334], + [0.06295, 0.04355, -0.00662], + [0.05457, 0.06075, 0.00596], + [0.04769, 0.06861, 0.0099], + [0.03854, 0.07614, 0.0134], + [0.06715, 0.02857, 0.01893], + [0.05541, 0.03845, 0.03604], + [0.04791, 0.04499, 0.04288], + [0.03911, 0.05325, 0.05033], + [0.04072, -0.01112, 0.07629], + [0.05067, -0.01122, 0.06756], + [0.05017, -0.05786, 0.06163], + [0.05791, -0.01101, 0.05685], + [0.0697, -0.00721, 0.0355], + [0.0693, 0.00333, 0.03352], + [0.06834, -0.04233, 0.03484], + [0.05897, -0.052, 0.05363], + [0.05831, -0.06502, 0.04801], + [0.06761, -0.05409, 0.03192], + [0.0498, -0.07259, 0.05466], + [0.03786, -0.08053, 0.06052], + [0.01105, -0.09107, 0.06811], + [0.01547, 0.06628, 0.05706], + [0.01388, 0.08599, 0.01586], + [0.01352, -0.01051, 0.08552], + [0.01446, 0.01308, 0.08363], + [0.01147, 0.08404, -0.02435], + [0.01024, 0.07584, -0.04157], + [0.00987, 0.07071, -0.05469], + [0.01082, -0.07283, 0.07857], + [0.024, -0.06907, 0.07481], + [0.01886, 0.06685, -0.05488], + [0.02682, 0.08179, 0.0155], + [0.02218, 0.07957, -0.02463], + [0.02008, 0.07379, -0.04167], + [0.02879, 0.06204, 0.05585], + [0.02785, 0.01116, 0.0801], + [0.02762, -0.01116, 0.08271], + [0.02447, -0.08659, 0.0651], + [0.03761, -0.10498, 0.02864], + [0.06105, -0.08578, 0.0195], + [0.00808, -0.1179, 0.03163], + [0.01848, -0.11613, 0.03123], + [0.02788, -0.11163, 0.02992], + [0.04723, -0.09825, 0.02634], + [0.05588, -0.0778, 0.04179], + [0.06607, -0.06598, 0.02862], + [0.04611, -0.08534, 0.04634], + [0.03458, -0.09352, 0.0502], + [0.07032, -0.04043, -0.06233], + [0.01066, -0.10349, 0.05469], + [0.02297, -0.0998, 0.05326], + [0.05583, 0.02325, -0.07381], + [0.00944, 0.06172, -0.07236], + [0.01876, 0.05826, -0.07331], + [0.0277, 0.05189, -0.0744], + [0.03637, 0.04556, -0.07576], + [0.04276, 0.03927, -0.07737], + [0.05194, 0.02448, -0.08089], + [0.07031, -0.05038, 0.02232], + [0.04249, 0.03564, -0.08651], + [0.0364, 0.04287, -0.08491], + [0.02839, 0.04919, -0.08382], + [0.01911, 0.05393, -0.0825], + [0.00985, 0.05843, -0.08124], + [0.05764, 0.02107, 0.04974], + [0.01433, 0.04072, 0.07398], + [0.02776, 0.03686, 0.07213], + [0.07641, 0.01261, -0.0304], + [0.03957, 0.06919, 0.03372], + [0.04786, 0.0603, 0.02729], + [0.05539, 0.05319, 0.02264], + [0.06478, 0.03832, 0.00739], + [0.0154, 0.08061, 0.03808], + [0.0283, 0.07637, 0.03735], + [0.06772, 0.03274, -3e-05], + [0.0455, 0.0698, -0.00768], + [0.05224, 0.06232, -0.011], + [0.0606, 0.04511, -0.02149], + [0.03637, 0.07711, -0.00608], + [0.01296, 0.08705, -0.00519], + [0.02508, 0.08311, -0.00547], + [0.06385, 0.03714, -0.02792], + [0.07534, -0.00977, -0.01849], + [0.07519, -0.01605, -0.01953], + [0.07527, -0.02328, -0.02789], + [0.07364, -0.03684, -0.02789], + [0.07039, -0.034, -0.06233], + [0.00955, 0.06597, -0.06416], + [0.01873, 0.06248, -0.06454], + [0.0282, 0.05629, -0.06503], + [0.03707, 0.04921, -0.06682], + [0.0436, 0.04282, -0.06868], + [0.05234, 0.02908, -0.07186], + [0.0716, -0.02856, -0.06233], + [0.07245, 0.00274, 0.02217], + [0.07034, 0.02451, 0.00952], + [0.05636, 0.05435, -0.01516], + [0.06184, 0.03365, 0.02906], + [0.06363, -0.05881, 0.04018], + [0.05995, 0.0453, 0.01551], + [0.05344, 0.05282, -0.03216], + [0.05893, 0.05266, 0.00075], + [0.05157, 0.04896, -0.04786], + [0.04979, 0.04242, -0.06041], + [0.04804, 0.0288, -0.08807], + [0.04687, 0.03225, -0.0791], + [0.05516, -0.09172, 0.02319], + [0.06177, -0.07108, 0.03572], + [0.06406, 0.00348, 0.04531], + [0.0586, -0.08258, 0.03027], + [0.06345, 0.01822, 0.04044], + [0.04783, 0.03661, -0.07001], + [0.06433, -0.00888, 0.04684], + [0.06454, -0.04668, 0.04464], + [0.07112, -0.05497, 0.00529], + [0.07527, 0.00877, 0.00098], + [0.07352, -0.03604, 0.00818], + [0.0755, -0.00845, 0.00674], + [0.07284, -0.04558, 0.0071], + [0.07215, 0.0214, -0.01423], + [0.07567, 0.00015, 0.00481], + [0.07409, 0.01633, -0.00554], + [0.0671, -0.07181, 0.00115], + [0.06845, -0.0692, -0.01352], + [0.06935, -0.06379, 0.00333], + [0.07068, -0.05973, -0.01421], + [0.07117, -0.05369, -0.02804], + [0.07146, -0.05146, -0.04303], + [0.07252, -0.04975, -0.01185], + [0.07242, -0.04626, -0.02932], + [0.07204, -0.04421, -0.04478], + [0.07239, -0.03624, -0.04704], + [0.07458, -0.02991, -0.02789], + [0.07398, -0.04131, -0.01121], + [0.07455, -0.03319, -0.00954], + [0.0755, -0.00959, -0.00659], + [0.07591, -0.00249, -0.00787], + [0.07591, 0.00484, -0.0107], + [0.07518, 0.01135, -0.0158], + [0.07391, 0.01576, -0.02281], + [0.07061, 0.0238, -0.02512], + [0.07302, 0.01788, -0.03132], + [0.0694, 0.02449, -0.03662], + [0.07187, 0.01834, -0.0404], + [0.07112, 0.01772, -0.04948], + [0.06832, 0.02384, -0.04738], + [0.07002, 0.01637, -0.05877], + [0.06698, 0.02133, -0.05771], + [0.0651, 0.01806, -0.06662], + [0.01257, -0.0332, 0.08569], + [0.07286, -0.02936, -0.0494], + [0.07349, -0.02849, -0.04352], + [0.07432, -0.02412, -0.03399], + [0.07405, -0.02776, -0.03933], + [0.02676, -0.03223, 0.08257], + [0.04062, -0.02994, 0.07709], + [0.07246, -0.01736, 0.02561], + [0.0591, -0.02434, 0.05738], + [0.06969, -0.01827, 0.03612], + [0.05146, -0.02708, 0.06758], + [0.06476, -0.0209, 0.04684], + [0.07474, -0.01721, 0.00832], + [0.01198, -0.05386, 0.08333], + [0.07517, -0.01704, -0.00602], + [0.03922, -0.04797, 0.07457], + [0.05978, -0.0385, 0.05693], + [0.06963, -0.02988, 0.03627], + [0.05138, -0.04327, 0.06526], + [0.06514, -0.03427, 0.04687], + [0.07183, -0.02817, 0.0259], + [0.02565, -0.05134, 0.08066], + [0.07407, -0.02648, 0.00872], + [0.07482, -0.02537, -0.00797], + [0.0, 0.01419, 0.08488], + [0.05653, 0.031, 0.04185], + [0.04844, 0.04027, 0.04667]] + +def scalp_face_vertices(): + return [[4, 3, 107, 108], + [122, 141, 145, 40], + [119, 116, 45, 6], + [152, 154, 13, 89], + [89, 13, 11, 91], + [91, 11, 12, 92], + [126, 122, 40, 9], + [29, 54, 53, 28], + [92, 12, 15, 95], + [52, 21, 111, 79], + [50, 218, 219, 51], + [51, 219, 52], + [103, 62, 59, 8], + [27, 56, 54, 29], + [153, 157, 56, 27], + [147, 36, 32, 148], + [142, 155, 218, 50], + [46, 115, 114, 47], + [79, 111, 110, 66], + [134, 34, 75, 133], + [147, 145, 41, 36], + [5, 10, 35, 31], + [37, 42, 43, 38], + [36, 41, 42, 37], + [121, 46, 47, 120], + [141, 146, 46, 121], + [120, 47, 48, 123], + [114, 51, 52, 113], + [115, 50, 51, 114], + [144, 142, 50, 115], + [204, 200, 53, 54], + [81, 80, 28, 53], + [36, 37, 33, 32], + [37, 38, 34, 33], + [133, 75, 72, 132], + [34, 38, 78, 75], + [205, 202, 56, 157], + [95, 15, 16, 94], + [201, 214, 211, 203], + [158, 143, 61, 60], + [8, 59, 211, 214], + [60, 61, 63, 55], + [74, 30, 64, 82], + [75, 78, 71, 72], + [30, 55, 63, 64], + [78, 77, 70, 71], + [202, 204, 54, 56], + [118, 79, 66, 117], + [125, 76, 67, 124], + [127, 180, 181, 24], + [5, 31, 137, 96], + [199, 194, 68, 81], + [68, 69, 80, 81], + [38, 43, 77, 78], + [113, 52, 79, 118], + [123, 48, 76, 125], + [200, 199, 81, 53], + [179, 177, 130, 178], + [73, 74, 82, 65], + [45, 122, 126, 6], + [139, 7, 57, 58], + [11, 83, 87, 12], + [154, 151, 88, 13], + [13, 88, 83, 11], + [12, 87, 86, 15], + [15, 86, 85, 16], + [106, 99, 98, 107], + [135, 134, 99, 100], + [136, 135, 100, 101], + [156, 136, 101, 150], + [22, 49, 140, 17], + [100, 99, 106, 105], + [7, 201, 203, 57], + [101, 100, 105, 104], + [150, 101, 104, 149], + [107, 98, 97, 108], + [47, 114, 113, 48], + [146, 144, 115, 46], + [48, 113, 118, 76], + [109, 155, 153, 27], + [49, 116, 119, 140], + [14, 90, 39, 19], + [19, 44, 84, 14], + [10, 9, 40, 35], + [76, 118, 117, 67], + [99, 134, 133, 98], + [23, 182, 183, 25], + [33, 34, 134, 135], + [32, 33, 135, 136], + [148, 32, 136, 156], + [39, 90, 62, 103], + [155, 22, 58, 153], + [20, 109, 27, 29], + [21, 20, 29, 28], + [111, 21, 28, 80], + [98, 133, 132, 97], + [141, 121, 41, 145], + [121, 120, 42, 41], + [120, 123, 43, 42], + [77, 43, 123, 125], + [110, 111, 80, 69], + [31, 148, 156, 137], + [45, 116, 144, 146], + [137, 156, 150, 102], + [14, 84, 151, 154], + [59, 62, 143, 158], + [203, 205, 157, 57], + [116, 49, 142, 144], + [122, 45, 146, 141], + [35, 40, 145, 147], + [49, 22, 155, 142], + [35, 147, 148, 31], + [58, 57, 157, 153], + [24, 181, 182, 23], + [90, 14, 154, 152], + [17, 160, 165, 139], + [140, 166, 160, 17], + [8, 161, 163, 103], + [139, 165, 162, 7], + [214, 216, 161, 8], + [119, 164, 166, 140], + [125, 124, 70, 77], + [167, 169, 170, 168], + [169, 159, 173, 170], + [93, 18, 172, 175], + [44, 19, 169, 167], + [19, 39, 159, 169], + [25, 183, 184, 112], + [131, 93, 175, 176], + [7, 162, 206, 201], + [26, 112, 184, 186], + [181, 180, 162, 165], + [182, 181, 165, 160], + [182, 160, 166, 183], + [183, 166, 164, 184], + [187, 126, 9, 190], + [190, 9, 10, 192], + [176, 195, 138, 131], + [206, 162, 180, 208], + [161, 179, 178, 163], + [5, 193, 192, 10], + [189, 190, 192, 191], + [188, 187, 190, 189], + [126, 187, 185, 6], + [187, 188, 186, 185], + [164, 185, 186, 184], + [195, 176, 130, 196], + [119, 6, 185, 164], + [129, 197, 198, 177], + [196, 130, 177, 198], + [216, 206, 208, 217], + [3, 2, 106, 107], + [2, 1, 105, 106], + [1, 0, 104, 105], + [22, 17, 139, 58], + [172, 171, 174, 175], + [174, 171, 170, 173], + [175, 174, 130, 176], + [211, 213, 205, 203], + [178, 130, 174, 173], + [173, 159, 163, 178], + [159, 39, 103, 163], + [62, 90, 152, 143], + [143, 152, 89, 61], + [63, 61, 89, 91], + [64, 63, 91, 92], + [82, 64, 92, 95], + [82, 95, 94, 65], + [209, 215, 199, 200], + [215, 207, 194, 199], + [210, 212, 204, 202], + [213, 210, 202, 205], + [220, 4, 108, 238], + [212, 209, 200, 204], + [208, 180, 127, 128], + [55, 30, 209, 212], + [158, 60, 210, 213], + [60, 55, 212, 210], + [74, 73, 207, 215], + [30, 74, 215, 209], + [59, 158, 213, 211], + [161, 216, 217, 179], + [201, 206, 216, 214], + [179, 217, 129, 177], + [217, 208, 128, 129], + [66, 110, 239, 233], + [71, 70, 231, 230], + [124, 67, 232, 241], + [117, 66, 233, 240], + [194, 243, 227, 68], + [94, 16, 226, 236], + [72, 71, 230, 229], + [227, 458, 69, 68], + [73, 228, 244, 207], + [65, 234, 228, 73], + [16, 85, 235, 226], + [132, 242, 237, 97], + [97, 237, 238, 108], + [67, 117, 240, 232], + [72, 229, 242, 132], + [239, 110, 69, 458], + [124, 241, 231, 70], + [65, 94, 236, 234], + [207, 244, 243, 194], + [219, 218, 109, 20], + [52, 219, 20, 21], + [218, 155, 109], + [186, 188, 26], + [192, 193, 191], + [96, 193, 5], + [137, 102, 96], + [149, 102, 150], + [104, 0, 149], + [225, 348, 347, 224], + [362, 280, 385, 381], + [359, 246, 285, 356], + [392, 329, 253, 394], + [329, 331, 251, 253], + [331, 332, 252, 251], + [366, 249, 280, 362], + [269, 268, 293, 294], + [332, 335, 255, 252], + [292, 319, 351, 261], + [290, 291, 460, 459], + [291, 292, 460], + [343, 248, 299, 302], + [267, 269, 294, 296], + [393, 267, 296, 397], + [387, 388, 272, 276], + [382, 290, 459, 395], + [286, 287, 354, 355], + [319, 306, 350, 351], + [374, 373, 315, 274], + [387, 276, 281, 385], + [245, 271, 275, 250], + [277, 278, 283, 282], + [276, 277, 282, 281], + [361, 360, 287, 286], + [381, 361, 286, 386], + [360, 363, 288, 287], + [354, 353, 292, 291], + [355, 354, 291, 290], + [384, 355, 290, 382], + [444, 294, 293, 440], + [321, 293, 268, 320], + [276, 272, 273, 277], + [277, 273, 274, 278], + [373, 372, 312, 315], + [274, 315, 318, 278], + [445, 397, 296, 442], + [335, 334, 256, 255], + [441, 443, 451, 454], + [398, 300, 301, 383], + [248, 454, 451, 299], + [300, 295, 303, 301], + [314, 322, 304, 270], + [315, 312, 311, 318], + [270, 304, 303, 295], + [318, 311, 310, 317], + [442, 296, 294, 444], + [358, 357, 306, 319], + [365, 364, 307, 316], + [367, 264, 421, 420], + [245, 336, 377, 271], + [439, 321, 308, 434], + [308, 321, 320, 309], + [278, 318, 317, 283], + [353, 358, 319, 292], + [363, 365, 316, 288], + [440, 293, 321, 439], + [419, 418, 370, 417], + [313, 305, 322, 314], + [285, 246, 366, 362], + [379, 298, 297, 247], + [251, 252, 327, 323], + [394, 253, 328, 391], + [253, 251, 323, 328], + [252, 255, 326, 327], + [255, 256, 325, 326], + [346, 347, 338, 339], + [375, 340, 339, 374], + [376, 341, 340, 375], + [396, 390, 341, 376], + [262, 257, 380, 289], + [340, 345, 346, 339], + [247, 297, 443, 441], + [341, 344, 345, 340], + [390, 389, 344, 341], + [347, 348, 337, 338], + [287, 288, 353, 354], + [386, 286, 355, 384], + [288, 316, 358, 353], + [349, 267, 393, 395], + [289, 380, 359, 356], + [254, 259, 279, 330], + [259, 254, 324, 284], + [250, 275, 280, 249], + [316, 307, 357, 358], + [339, 338, 373, 374], + [263, 265, 423, 422], + [273, 375, 374, 274], + [272, 376, 375, 273], + [388, 396, 376, 272], + [279, 343, 302, 330], + [395, 393, 298, 262], + [260, 269, 267, 349], + [261, 268, 269, 260], + [351, 320, 268, 261], + [338, 337, 372, 373], + [381, 385, 281, 361], + [361, 281, 282, 360], + [360, 282, 283, 363], + [317, 365, 363, 283], + [350, 309, 320, 351], + [271, 377, 396, 388], + [285, 386, 384, 356], + [377, 342, 390, 396], + [254, 394, 391, 324], + [299, 398, 383, 302], + [443, 297, 397, 445], + [356, 384, 382, 289], + [362, 381, 386, 285], + [275, 387, 385, 280], + [289, 382, 395, 262], + [275, 271, 388, 387], + [298, 393, 397, 297], + [264, 263, 422, 421], + [330, 392, 394, 254], + [257, 379, 405, 400], + [380, 257, 400, 406], + [248, 343, 403, 401], + [379, 247, 402, 405], + [454, 248, 401, 456], + [359, 380, 406, 404], + [365, 317, 310, 364], + [407, 408, 410, 409], + [409, 410, 413, 399], + [333, 415, 412, 258], + [284, 407, 409, 259], + [259, 409, 399, 279], + [265, 352, 424, 423], + [371, 416, 415, 333], + [247, 441, 446, 402], + [266, 426, 424, 352], + [421, 405, 402, 420], + [422, 400, 405, 421], + [422, 423, 406, 400], + [423, 424, 404, 406], + [427, 430, 249, 366], + [430, 432, 250, 249], + [416, 371, 378, 435], + [446, 448, 420, 402], + [401, 403, 418, 419], + [245, 250, 432, 433], + [429, 431, 432, 430], + [428, 429, 430, 427], + [366, 246, 425, 427], + [427, 425, 426, 428], + [404, 424, 426, 425], + [435, 436, 370, 416], + [359, 404, 425, 246], + [369, 417, 438, 437], + [436, 438, 417, 370], + [456, 457, 448, 446], + [224, 347, 346, 223], + [223, 346, 345, 222], + [222, 345, 344, 221], + [262, 298, 379, 257], + [412, 415, 414, 411], + [414, 413, 410, 411], + [415, 416, 370, 414], + [451, 443, 445, 453], + [418, 413, 414, 370], + [413, 418, 403, 399], + [399, 403, 343, 279], + [302, 383, 392, 330], + [383, 301, 329, 392], + [303, 331, 329, 301], + [304, 332, 331, 303], + [322, 335, 332, 304], + [322, 305, 334, 335], + [449, 440, 439, 455], + [455, 439, 434, 447], + [450, 442, 444, 452], + [453, 445, 442, 450], + [220, 238, 348, 225], + [452, 444, 440, 449], + [448, 368, 367, 420], + [295, 452, 449, 270], + [398, 453, 450, 300], + [300, 450, 452, 295], + [314, 455, 447, 313], + [270, 449, 455, 314], + [299, 451, 453, 398], + [401, 419, 457, 456], + [441, 454, 456, 446], + [419, 417, 369, 457], + [457, 369, 368, 448], + [306, 233, 239, 350], + [311, 230, 231, 310], + [364, 241, 232, 307], + [357, 240, 233, 306], + [434, 308, 227, 243], + [334, 236, 226, 256], + [312, 229, 230, 311], + [227, 308, 309, 458], + [313, 447, 244, 228], + [305, 313, 228, 234], + [256, 226, 235, 325], + [372, 337, 237, 242], + [337, 348, 238, 237], + [307, 232, 240, 357], + [312, 372, 242, 229], + [239, 458, 309, 350], + [364, 310, 231, 241], + [305, 234, 236, 334], + [447, 434, 243, 244], + [460, 260, 349, 459], + [292, 261, 260, 460], + [459, 349, 395], + [426, 266, 428], + [432, 431, 433], + [336, 245, 433], + [377, 336, 342], + [389, 390, 342], + [344, 389, 221]] + +def scalp_vert_groups(): + return {"head": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, + 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, + 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 293, 294, 295, 296, 297, 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, + 308, 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, + 324, 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, + 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, + 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, + 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, + 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, + 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, + 452, 453, 454, 455, 456, 457, 458, 459, 460], + "neck": [0, 1, 2, 3, 4, 31, 32, 33, 34, 72, 75, 96, 97, 98, 99, 100, 101, 102, + 104, 105, 106, 107, 108, 132, 133, 134, 135, 136, 137, 148, 149, 150, 156, 220, + 221, 222, 223, 224, 225, 229, 237, 238, 242, 271, 272, 273, 274, 312, 315, 336, + 337, 338, 339, 340, 341, 342, 344, 345, 346, 347, 348, 372, 373, 374, 375, 376, + 377, 388, 389, 390, 396], + "right": [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, + 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, + 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, + 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, + 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, + 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, + 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, + 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, + 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, + 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, + 212, 213, 214, 215, 216, 217, 218, 219, 220, 226, 227, 228, 229, 230, 231, 232, + 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 458], + "left": [220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, + 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 245, 246, 247, 248, 249, + 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 260, 261, 262, 263, 264, 265, + 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 281, + 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, 295, 296, 297, + 298, 299, 300, 301, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, + 314, 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, + 330, 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, + 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, + 362, 363, 364, 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, 376, 377, + 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, 388, 389, 390, 391, 392, 393, + 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, + 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, + 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, + 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, 457, + 458, 459, 460], + "top": [11, 12, 13, 15, 16, 20, 21, 27, 28, 29, 30, 52, 53, 54, 55, 56, 60, 61, + 63, 64, 65, 66, 68, 69, 73, 74, 79, 80, 81, 82, 83, 85, 86, 87, 88, 89, 91, 92, + 94, 95, 109, 110, 111, 143, 151, 152, 153, 154, 155, 157, 158, 194, 199, 200, + 202, 204, 205, 207, 209, 210, 212, 213, 215, 218, 219, 226, 227, 228, 233, 234, + 235, 236, 239, 243, 244, 251, 252, 253, 255, 256, 260, 261, 267, 268, 269, 270, + 292, 293, 294, 295, 296, 300, 301, 303, 304, 305, 306, 308, 309, 313, 314, 319, + 320, 321, 322, 323, 325, 326, 327, 328, 329, 331, 332, 334, 335, 349, 350, 351, + 383, 391, 392, 393, 394, 395, 397, 398, 434, 439, 440, 442, 444, 445, 447, 449, + 450, 452, 453, 455, 458, 459, 460], + "back": [0, 1, 2, 3, 4, 32, 33, 34, 36, 37, 38, 41, 42, 43, 46, 47, 48, 50, 51, + 52, 66, 67, 70, 71, 72, 75, 76, 77, 78, 79, 97, 98, 99, 100, 101, 104, 105, 106, + 107, 108, 113, 114, 115, 117, 118, 120, 121, 123, 124, 125, 132, 133, 134, 135, + 136, 141, 142, 144, 145, 146, 147, 148, 149, 150, 155, 156, 218, 219, 220, 221, + 222, 223, 224, 225, 229, 230, 231, 232, 233, 237, 238, 240, 241, 242, 272, 273, + 274, 276, 277, 278, 281, 282, 283, 286, 287, 288, 290, 291, 292, 306, 307, 310, + 311, 312, 315, 316, 317, 318, 319, 337, 338, 339, 340, 341, 344, 345, 346, 347, + 348, 353, 354, 355, 357, 358, 360, 361, 363, 364, 365, 372, 373, 374, 375, 376, + 381, 382, 384, 385, 386, 387, 388, 389, 390, 395, 396, 459, 460], + "sides": [5, 6, 7, 8, 9, 10, 14, 17, 18, 19, 22, 23, 24, 25, 26, 31, 35, 39, 40, + 44, 45, 49, 57, 58, 59, 62, 84, 90, 93, 96, 102, 103, 112, 116, 119, 122, 126, + 127, 128, 129, 130, 131, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, + 148, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, + 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, 176, 177, 178, 179, 180, + 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 195, 196, 197, + 198, 201, 203, 205, 206, 208, 211, 213, 214, 216, 217, 245, 246, 247, 248, 249, + 250, 254, 257, 258, 259, 262, 263, 264, 265, 266, 271, 275, 279, 280, 284, 285, + 289, 297, 298, 299, 302, 324, 330, 333, 336, 342, 343, 352, 356, 359, 362, 366, + 367, 368, 369, 370, 371, 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, 387, + 388, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, + 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, 433, 435, 436, 437, + 438, 441, 443, 445, 446, 448, 451, 453, 454, 456, 457], + "sideburns": [18, 93, 129, 130, 131, 138, 171, 172, 174, 175, 176, 177, 195, 196, + 197, 198, 258, 333, 369, 370, 371, 378, 411, 412, 414, 415, 416, 417, 435, 436, + 437, 438], + "mohawk": [2, 3, 4, 12, 15, 16, 21, 28, 30, 34, 38, 43, 48, 52, 53, 64, 65, 66, + 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 85, 86, 87, 92, + 94, 95, 97, 98, 99, 106, 107, 108, 110, 111, 113, 117, 118, 123, 124, 125, 132, + 133, 134, 194, 199, 200, 207, 209, 215, 220, 223, 224, 225, 226, 227, 228, 229, + 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, 240, 241, 242, 243, 244, 252, + 255, 256, 261, 268, 270, 274, 278, 283, 288, 292, 293, 304, 305, 306, 307, 308, + 309, 310, 311, 312, 313, 314, 315, 316, 317, 318, 319, 320, 321, 322, 325, 326, + 327, 332, 334, 335, 337, 338, 339, 346, 347, 348, 350, 351, 353, 357, 358, 363, + 364, 365, 372, 373, 374, 434, 439, 440, 447, 449, 455, 458], + "bang": [11, 12, 13, 14, 15, 16, 61, 62, 63, 64, 65, 82, 83, 84, 85, 86, 87, 88, + 89, 90, 91, 92, 94, 95, 143, 151, 152, 154, 226, 234, 235, 236, 251, 252, 253, + 254, 255, 256, 301, 302, 303, 304, 305, 322, 323, 324, 325, 326, 327, 328, 329, + 330, 331, 332, 334, 335, 383, 391, 392, 394]} + +import bpy +from time import time +from numpy import array, append, arange, empty, linalg, linspace, isin, sin, cos, radians, sum + + +# UTILS +#################### + +def centroid(co): + co = array(co, float) + return sum(co, axis=0)/len(co) + +def surface_constraint(ob, target): + ob.constraints.new(type='SHRINKWRAP') + con = ob.constraints["Shrinkwrap"] + con.name = f"CON_{ob.name}" + con.target = target + con.use_track_normal = True + con.track_axis = 'TRACK_Z' + +def show_collection(collection, mode=False): + bpy.data.collections[collection].hide_viewport = not mode + +def get_PSY_mods(ob): + return [mod for mod in ob.modifiers[:] if mod.name.startswith("PSY_")] + +def show_modifier(modifiers, mode=False): + for modifier in modifiers: + modifier.show_viewport = mode + +def show_muse(ob, mode=False): + show_modifier(get_PSY_mods(ob), mode=mode) + show_collection("MUSE", mode=mode) + +def point_on_curve(co, t): + from math import factorial + co = array(co, float) + n = len(co)-1 + comb = lambda k: factorial(n) // (factorial(k)*factorial(n-k)) + return sum(array([comb(i) * t**i * (1-t)**(n-i) * co[i] for i in range(n+1)]), axis=0) + +def plot_curve(co, segments=10): + return array([point_on_curve(co, t) for t in linspace(0, 1, segments)]) + +def adjust_(co, segments): + co = array(co) + allco = [] + for v in co: + pc = plot_curve(v, segments=segments) + allco.append(pc) + return array(allco) + +# PARTICLES +#################### +def hair_update(): + bpy.ops.particle.disconnect_hair(all=True) + bpy.ops.particle.connect_hair(all=True) + +def new_hair(ob, Name, count, length, step, curve_guide=1): + ob.modifiers.new(Name, 'PARTICLE_SYSTEM') + psys = bpy.data.particles[Name] + psys.type = 'HAIR' + psys.count = count + psys.hair_length = length + psys.hair_step = step + psys.effector_weights.curve_guide = curve_guide + return psys + +def ob_eval(ob): + depsgraph = bpy.context.evaluated_depsgraph_get() + return ob.evaluated_get(depsgraph) + +def get_particles(ob, psystem): + eval = ob_eval(ob) + return eval.particle_systems[psystem].particles + +def get_particles_list(ob): + eval = ob_eval(ob) + allp = eval.particle_systems[:] + return [i.name for i in allp if i.name.startswith("PSY_")] + +def get_plocation(ob, psystem): + particles = get_particles(ob, psystem) + count = len(particles) + co = empty(count*3, float) + particles.foreach_get("location", co) + return co.reshape((count, 3)) + +def set_plocation(ob, psystem, co): + particles = get_particles(ob, psystem) + co = array(co).ravel() + particles.foreach_set("location", co) + +def get_pstrand_co(ob, psystem, strand): + particles = get_particles(ob, psystem) + hair_keys = particles[strand].hair_keys + count = len(hair_keys) + co = empty(count*3, float) + hair_keys.foreach_get("co", co) + return co.reshape((count, 3)) + +def set_pstrand_co(ob, psystem, strand, co): + co = array(co) + count = len(co) + particles = get_particles(ob, psystem) + particles[strand].location = co[-1] + hair_keys = particles[strand].hair_keys + for v in range(count): + hair_keys[v].co = co[v] + +def get_phair_co(ob, psystem): + particles = get_particles(ob, psystem) + pcount = len(particles) + strands = [] + for strand in range(pcount): + strands.append(get_pstrand_co(ob, psystem, strand)) + return array(strands) + +def set_phair_co(ob, psystem, co): + active_ob(ob.name, None) + hair_update() + particles = get_particles(ob, psystem) + pcount = len(co) + bpy.ops.particle.particle_edit_toggle() + for strand in range(pcount): + set_pstrand_co(ob, psystem, strand, co[strand]) + +# OBJECT +#################### +def active_ob(object, objects): + bpy.ops.object.select_all(action='DESELECT') + bpy.data.objects[object].select_set(state=True) + bpy.context.view_layer.objects.active = bpy.data.objects[object] + if objects is not None: + for o in objects: + bpy.data.objects[o].select_set(state=True) + +def get_vert_groups(ob): + vg = ob.vertex_groups + vt = ob.data.vertices + gct = len(vg) + vct = len(vt) + vg_idx_dict = {i: [] for i in range(gct)} + vg_wt_dict = {i: [] for i in range(gct)} + vn = [v.name for v in vg] + for v in range(vct): + gr = vt[v].groups[:] + if gr == []: + continue + else: + for g in gr: + vg_idx_dict[g.group].append(v) + vg_wt_dict[g.group].append(g.weight) + return vg_idx_dict, vg_wt_dict, vn + +def get_modified_co(ob): + import bmesh + depsgraph = bpy.context.evaluated_depsgraph_get() + bm = bmesh.new() + bm.from_object(ob, depsgraph) + bm.verts.ensure_lookup_table() + co = array([v.co for v in bm.verts], float) + bm.free() + return co + +def find_faces(f_verts, idxs): + return array([all(isin(list(fv), list(idxs))) for fv in f_verts]) + +def copy_ob_co(ob, vert_idx): + vt = ob.data.vertices + fa = ob.data.polygons + countv = len(vt) + co = empty(countv * 3, float) + vt.foreach_get('co', co) + co.shape = (countv, 3) + countf = len(fa) + f_verts = array([i.vertices[:] for i in fa]) + fidx = arange(countf) + mask = find_faces(f_verts, vert_idx) + face_idx = f_verts[mask.tolist()] + v_count = len(vert_idx) + f_count = len(f_verts) + vlist = vert_idx + new_idx = [i for i in range(v_count)] + nv_Dict = {o: n for n, o in enumerate(vlist)} + new_f = [[nv_Dict[i] for i in nest] for nest in face_idx] + return co[vlist], new_f, nv_Dict + +# COLLECTION +#################### +def collection_object_list(collection): + return [o.name for o in bpy.data.collections[collection].objects[:]] + +def new_collection(Name): + if bpy.data.collections.get(Name) == None: + new_coll = bpy.data.collections.new(Name) + bpy.context.scene.collection.children.link(new_coll) + return new_coll + else: + return bpy.data.collections.get(Name) + +def new_subcollection(Name, collection): + if bpy.data.collections.get(Name) == None: + new_coll = bpy.data.collections.new(Name) + bpy.data.collections[collection].children.link(new_coll) + return new_coll + else: + return bpy.data.collections.get(Name) + +# OPS +#################### + +def move_bez_origin(ob, point): + point = array(point, float) + loc = array(ob.location, float) + mw = array(ob.matrix_world, float) + move = point - loc + bp = ob.data.splines[0].bezier_points + for _ in bp: + co = array(_.co, float) + hl = array(_.handle_left, float) + hr = array(_.handle_right, float) + _.co = co - move + _.handle_left = hl - move + _.handle_right = hr - move + trans = mw[:3:,3] + mw[:3:,3] = move + ob.matrix_world = mw + ob.location = point + +def guide_maker(Name, length): + handle = length/2 + bpy.ops.curve.primitive_bezier_curve_add(enter_editmode=False, align='WORLD', location=(0, 0, 0)) + curve = bpy.context.object + curve.name = Name + curve.data.name = Name + move_bez_origin(curve, [-1, 0, 0]) + bp = curve.data.splines[0].bezier_points + bp[0].co = (0, 0, 0) + bp[1].co = (0, 0, length) + bp[0].handle_left = (0, 0, -handle) + bp[0].handle_right = (0, 0, handle) + bp[1].handle_left = (0, 0, length-handle) + bp[1].handle_right = (0, 0, length+handle) + bp[0].select_control_point = False + bp[1].select_control_point = True + bpy.context.collection.objects.unlink(curve) + return curve + +def add_curve_guide(curve, location, collection, target): + curve.location = location + bpy.data.collections[collection].objects.link(curve) + surface_constraint(curve, target) + return curve + +def mod_hook(ob, target): + Name = f"HOK_{ob.name}" + ob.modifiers.new(Name, 'HOOK') + ob.modifiers[Name].object = target + return ob.modifiers[Name] + +def add_empty(Name, radius, collection, location=(0, 0, 0), rotation=(0, 0, 0), type='PLAIN_AXES'): + bpy.ops.object.empty_add(type=type, radius=radius, location=location, rotation=rotation) + emp = bpy.context.object + emp.name = Name + emp.select_set(state=False) + bpy.context.collection.objects.unlink(emp) + bpy.data.collections[collection].objects.link(emp) + return emp + +def curve_hook(curve, hook): + mod = mod_hook(curve, hook) + active_ob(curve.name, None) + bpy.ops.object.editmode_toggle() + bpy.ops.object.hook_assign(modifier=mod.name) + bpy.ops.object.editmode_toggle() + curve.select_set(state=False) + +#Main +#################### + +def scalp(): + scalp_name = "Scalp" + if scalp_name in [i.name for i in bpy.context.scene.objects[:]]: + scalp = bpy.data.objects[scalp_name] + pass + else: + scalp_collection = "HAIR" + scalp_mesh = bpy.data.meshes.new(f"{scalp_name}_{time()}") + scalp_mesh.from_pydata(scalp_vertices(), [], scalp_face_vertices()) + scalp_mesh.validate() + scalp_mesh.update(calc_edges=True) + scalp = bpy.data.objects.new(scalp_name, scalp_mesh) + scalp.data = scalp_mesh + svgs = scalp_vert_groups() + for group in svgs: + svg = scalp.vertex_groups.new(name=group) + svg.add(svgs[group], 1.0, "REPLACE") + # + scalp.location = (0, 0, 1.76) + sub = scalp.modifiers.new("SCP_Subsurf", 'SUBSURF') + sub.levels = 3 + sub.render_levels = 3 + arm = scalp.modifiers.new("SCP_Armature", 'ARMATURE') + arm.vertex_group = "head" + arm.use_vertex_groups = True + swp = scalp.modifiers.new("SCP_Shrinkwrap", 'SHRINKWRAP') + swp.wrap_method = 'NEAREST_SURFACEPOINT' + swp.wrap_mode = 'ON_SURFACE' + if bpy.data.collections.get(scalp_collection)==None: + coll = bpy.data.collections.new(scalp_collection) + bpy.context.scene.collection.children.link(coll) + else: + coll = bpy.data.collections.get(scalp_collection) + # + bpy.data.collections[scalp_collection].objects.link(scalp) + return scalp + +def hair_to_vg(ob, guide=True): + root_radius = .003 + gvg = get_vert_groups(ob) + vg_names = gvg[2] + c_ = 'CRV_' + t_ = 'TGT_' + p_ = 'PSY_' + g_ = 'GUD_' + muse = 'MUSE' + guid = 'HAIR_GUIDE' + count = len(vg_names) + loc = array(ob.location) + dim = array(ob.dimensions) + factor = linalg.norm(dim) + for i in range(count): + vi = gvg[0][i] + coc = copy_ob_co(ob, vi) + co = coc[0] + loc + faces = coc[1] + Name = vg_names[i] + c_Name = f'{c_}{Name}' + t_Name = f'{t_}{Name}' + p_Name = f'{p_}{Name}' + g_Name = f'{g_}{Name}' + ob.modifiers.new(p_Name, 'PARTICLE_SYSTEM') + psys = bpy.data.particles[p_Name] + psys.type = 'HAIR' + psys.count = 100 + psys.hair_length = factor + psys.hair_step = 10 + psys.effector_weights.curve_guide = 1 + psys.root_radius = root_radius + # + p = bpy.data.particles[p_Name] + p.child_type = 'INTERPOLATED' + ob.particle_systems[p_Name].vertex_group_density = Name + # add curve guide + if guide == True: + coll_muse = new_collection(muse) + coll_guide = new_subcollection(guid, muse) + coll_ = new_subcollection(g_Name, guid) + cen = centroid(co) + _, pt, norm, poly = ob.closest_point_on_mesh(cen) + target_origin = array(pt) + loc + target_end = array(norm)*(factor/2)+target_origin + p.effector_weights.collection = coll_ + curve_data = guide_maker(c_Name, factor/2) + curve = add_curve_guide(curve_data, target_origin, g_Name, ob) + curve.field.type = 'GUIDE' + emp = add_empty(t_Name, factor/8, g_Name, location=target_end, rotation=norm, type='SPHERE') + curve_hook(curve, emp) + +def tranfer_hair(ob, psys): + p = get_phair_co(ob, psys) + count = p.shape[0] + segments = p.shape[1] + active_ob(ob.name, None) + bpy.ops.object.modifier_convert(modifier=psys) + mesh = bpy.context.object + active_ob(mesh.name, None) + co = get_modified_co(mesh) + ct = co.shape[0] + pts = int(ct/count) + nco = co.reshape((count, pts, 3)) + bpy.ops.object.delete(use_global=False, confirm=False) + active_ob(ob.name, None) + return adjust_(nco, segments) + +def hair_baking(ob, psys): + co = tranfer_hair(ob, psys) + set_phair_co(ob, psys, co) + + diff --git a/__init__.py b/__init__.py index 404dbc98..abfed951 100644 --- a/__init__.py +++ b/__init__.py @@ -62,6 +62,7 @@ from . import measurescreator from . import skeleton_ops from . import vgroupscreator +from . import HE_scalp_mesh logger = logging.getLogger(__name__) @@ -72,7 +73,7 @@ bl_info = { "name": "MB-Lab", "author": "Manuel Bastioni, MB-Lab Community", - "version": (1, 7, 8, 42), + "version": (1, 7, 8, 50), "blender": (2, 81, 16), "location": "View3D > Tools > MB-Lab", "description": "A complete lab for character creation", @@ -192,7 +193,7 @@ def start_lab_session(): else: mblab_humanoid.reset_mesh() mblab_humanoid.update_character(mode="update_all") - + # All inits for creation tools. morphcreator.init_morph_names_database() mbcrea_expressionscreator.reset_expressions_items() @@ -409,11 +410,11 @@ def init_categories_props(humanoid_instance): items=get_categories_enum(), update=modifiers_update, name="Morphing categories") - + # Sub-categories for "Facial expressions" mbcrea_expressionscreator.set_expressions_modifiers(mblab_humanoid) sub_categories_enum = mbcrea_expressionscreator.get_expressions_sub_categories() - + bpy.types.Scene.expressionsSubCategory = bpy.props.EnumProperty( items=sub_categories_enum, update=modifiers_update, @@ -737,7 +738,7 @@ def hair_style_list(self, context): #Teto def mbcrea_enum_expressions_items_update(self, context): return mbcrea_expressionscreator.get_expressions_items() - + bpy.types.Scene.mbcrea_enum_expressions_items = bpy.props.EnumProperty( items=mbcrea_enum_expressions_items_update, @@ -2034,7 +2035,7 @@ def execute(self, context): scn = bpy.context.scene mblab_proxy.remove_fitting() return {'FINISHED'} - + class ApplyMeasures(bpy.types.Operator): """Fit the character to the measures""" @@ -2360,7 +2361,7 @@ def execute(self, context): # try: # bpy.ops.object.mode_set(mode='POSE') # except: - # pass + # pass return {'FINISHED'} class OBJECT_OT_manual_hair(bpy.types.Operator): @@ -2392,7 +2393,7 @@ def execute(self, context): # try: # bpy.ops.object.mode_set(mode='POSE') # except: - # pass + # pass return {'FINISHED'} class OBJECT_OT_change_hair_color(bpy.types.Operator): @@ -2481,6 +2482,64 @@ def execute(self, context): node_ops.replace_removed_shader(fileName, UN_shader_remove) return {'FINISHED'} +#Scalp Mesh +class GuideProp(bpy.types.PropertyGroup): + # + guide_bool: bpy.props.BoolProperty( + name = "Add Curve Guide", + description = "Add curve guide to hair", + default = False, + ) + +class AddScalp(bpy.types.Operator): + """Add scalp mesh""" + bl_idname = "mbast.add_scalp" + bl_label = "Add Scalp Mesh" + # + def execute(self, context): + HE_scalp_mesh.scalp() + return {'FINISHED'} + +class VertexGrouptoHair(bpy.types.Operator): + """Spawn hair from vertex groups""" + bl_idname = "mbast.vertex_group_to_hair" + bl_label = "Hair from Vertex Groups" + # + @classmethod + def poll(cls, context): + return context.object.type == 'MESH' + # + def execute(self, context): + guide = context.scene.add_guide.guide_bool + HE_scalp_mesh.hair_to_vg(context.object, guide=guide) + return {'FINISHED'} + +class BakeHairShape(bpy.types.Operator): + """Bakes hair into shape""" + bl_idname = "mbast.bake_hair_shape" + bl_label = "Bake Hair Shape" + # + @classmethod + def poll(cls, context): + return context.object.type == 'MESH' + # + def execute(self, context): + HE_scalp_mesh.hair_baking(context.object , context.object.particle_systems.active.name) + return {'FINISHED'} + +def draw_scalp_layout(self, context, layout): + scalp_box = layout.box() + scalp_box.label(text="Scalp Mesh") + scalp_box.operator(AddScalp.bl_idname) + hair_box = layout.box() + hair_box.label(text="Vertex Group to Hair") + hair_box.prop(context.scene.add_guide ,"guide_bool") + hair_box.operator(VertexGrouptoHair.bl_idname) + if context.scene.add_guide.guide_bool: + bake_box = layout.box() + bake_box.label(text="Bake Active Hair Particles") + bake_box.operator(BakeHairShape.bl_idname) + class StartSession(bpy.types.Operator): bl_idname = "mbast.init_character" bl_label = "Create character" @@ -2551,7 +2610,7 @@ def draw(self, context): box_new_opt.prop(scn, 'mbcrea_root_data') box_new_opt.prop(scn, 'mblab_character_name') box_new_opt.separator(factor=0.5) - + if mblab_humanoid.is_ik_rig_available(scn.mblab_character_name): box_new_opt.prop(scn, 'mblab_use_ik', icon='BONE_DATA') if mblab_humanoid.is_muscle_rig_available(scn.mblab_character_name): @@ -2561,7 +2620,7 @@ def draw(self, context): box_new_opt.prop(scn, 'mblab_use_eevee', icon='SHADING_RENDERED') if scn.mblab_use_cycles or scn.mblab_use_eevee: box_new_opt.prop(scn, 'mblab_use_lamps', icon='LIGHT_DATA') - + self.layout.separator(factor=0.5) self.layout.operator('mbast.init_character', icon='ARMATURE_DATA') @@ -2576,7 +2635,7 @@ def draw(self, context): box_post_opt.operator('mbast.button_facerig_off', icon=icon_collapse) # Face Rig - + box_face_rig = self.layout.box() box_face_rig_a = box_face_rig.column(align=True) #box_face_rig.label(text="Face Rig") @@ -2585,7 +2644,7 @@ def draw(self, context): box_face_rig_a.prop(scn, "mblab_facs_rig") # Expressions - + if gui_active_panel_fin != "expressions": box_post_opt.operator('mbast.button_expressions_on', icon=icon_expand) else: @@ -2615,7 +2674,7 @@ def draw(self, context): else: box_exp.enabled = False box_exp.label(text="No express. shapekeys", icon='INFO') - + # Assets, Fitting and Particle Hair if gui_active_panel_fin != "assets": @@ -2645,6 +2704,8 @@ def draw(self, context): box_asts_b.operator("mbast.del_hair_preset", icon='USER') box_asts_b.operator("mbast.rep_hair_preset", icon='USER') + draw_scalp_layout(self, context, box_asts) + # Proxy Fitting if gui_active_panel_fin != "proxy_fit": @@ -2789,9 +2850,9 @@ def draw(self, context): #self.layout.label(text="Tip: for slow PC, disable the subdivision in Display Options below", icon='INFO') # Sub-panel for all tools below box_act_tools_sub = self.layout.box() - + # Character library - + box_act_tools_sub.label(text="CHARACTER SET-UP", icon="RNA") box_act_tools_a = box_act_tools_sub.column(align=True) if gui_active_panel != "library": @@ -2806,9 +2867,9 @@ def draw(self, context): if mblab_humanoid.exists_phenotype_database(): box_lib.prop(obj, "ethnic") box_lib.prop(scn, 'mblab_mix_characters', icon='FORCE_CHARGE') - + # Randomize character - + if gui_active_panel != "random": box_act_tools_a.operator('mbast.button_random_on', icon=icon_expand) else: @@ -2832,9 +2893,9 @@ def draw(self, context): box_rand.prop(scn, "mblab_preserve_fantasy") box_rand.operator('mbast.character_generator', icon="FILE_REFRESH") - + # Automodelling tools - + if mblab_humanoid.exists_measure_database(): if gui_active_panel != "automodelling": box_act_tools_a.operator('mbast.button_automodelling_on', icon=icon_expand) @@ -2848,9 +2909,9 @@ def draw(self, context): box_auto = self.layout.box() box_auto.enabled = False box_auto.label(text="Automodelling not available for this character", icon='INFO') - + # Body measures - + box_act_tools_sub.label(text="CHARACTER DESIGN", icon="RNA") box_act_tools_b = box_act_tools_sub.column(align=True) if gui_active_panel_middle != "parameters": @@ -2869,7 +2930,7 @@ def draw(self, context): col.label(text="PARAMETERS") col.prop(scn, "morphingCategory") col.separator(factor=0.2) - + for prop in mblab_humanoid.get_properties_in_category(scn.morphingCategory): if hasattr(obj, prop) and not prop.startswith("Expressions_ID"): col.prop(obj, prop) @@ -2901,9 +2962,9 @@ def draw(self, context): sub = box_param.column(align=True) sub.label(text="RESET") sub.operator("mbast.reset_categoryonly", icon="RECOVER_LAST") - + # Poses - + if mblab_humanoid.exists_rest_poses_database(): if gui_active_panel_middle != "rest_pose": box_act_tools_b.operator('mbast.button_rest_pose_on', icon=icon_expand) @@ -2921,9 +2982,9 @@ def draw(self, context): box_act_pose.separator(factor=0.2) box_act_pose.operator("mbast.restpose_load", icon='IMPORT') box_act_pose.operator("mbast.restpose_save", icon='EXPORT') - + # Skin editor - + if gui_active_panel_middle != "skin": box_act_tools_b.operator('mbast.button_skin_on', icon=icon_expand) else: @@ -2938,11 +2999,11 @@ def draw(self, context): if mblab_humanoid.exists_displace_texture(): box_skin_b.operator("mbast.skindisplace_calculate", icon='MOD_DISPLACE') box_skin_b.label(text="Enable Displacement Preview to view updates", icon='INFO') - + box_skin = box_skin_b.column(align=True) for material_data_prop in sorted(mblab_humanoid.character_material_properties.keys()): box_skin.prop(obj, material_data_prop) - + # Finalize character box_act_tools_sub.label(text="OTHERS", icon="RNA") box_act_tools_c = box_act_tools_sub.column(align=True) @@ -2958,9 +3019,9 @@ def draw(self, context): box_fin.operator("mbast.finalize_character_and_images", icon='FREEZE') else: box_fin.operator("mbast.finalize_character", icon='FREEZE') - + # File tools - + if gui_active_panel_display != "file": box_act_tools_c.operator('mbast.button_file_on', icon=icon_expand) else: @@ -2991,9 +3052,9 @@ def draw(self, context): box_file.prop(scn, 'mblab_export_materials', icon='MATERIAL') box_file.operator("mbast.export_character", icon='EXPORT') box_file.operator("mbast.import_character", icon='IMPORT') - + # Display character - + if gui_active_panel_display != "display_opt": box_act_tools_c.operator('mbast.button_display_on', icon=icon_expand) else: @@ -3047,7 +3108,7 @@ def draw(self, context): is_objet, name = algorithms.looking_for_humanoid_obj() icon_expand = "DISCLOSURE_TRI_RIGHT" icon_collapse = "DISCLOSURE_TRI_DOWN" - + box_general = self.layout.box() box_general.label(text="https://www.mblab.dev") #box_general.operator('mbcrea.button_for_tests', icon='BLENDER') @@ -3076,7 +3137,7 @@ def draw(self, context): if len(scn.mblab_morph_name) > 0: morph_label = "Morph name : " + morphcreator.get_body_parts(scn.mblab_body_part_name) morph_label += "_" + scn.mblab_morph_name - morph_label += "_" + morphcreator.get_min_max(scn.mblab_morph_min_max) + morph_label += "_" + morphcreator.get_min_max(scn.mblab_morph_min_max) box_morphcreator.label(text=morph_label, icon='INFO') else: box_morphcreator.label(text="Name needed !", icon='ERROR') @@ -3440,7 +3501,7 @@ def draw(self, context): else: box_combinexpression.label(text="!NO COMPATIBLE MODEL!", icon='ERROR') box_combinexpression.enabled = False - + # Copy / Move / Delete utilities. elif scn.mbcrea_before_edition_tools == "cmd_utilities": box_cmd_morphs = self.layout.box() @@ -3562,7 +3623,7 @@ def draw(self, context): else: creation_tools_ops.init_config() box_compat_tools_sub.label(text="Choose a project name !", icon='ERROR') - + # Tools about Config file creation - Base models box_project_tools = self.layout.box() box_project_tools.label(text="TOOLS", icon="MODIFIER_ON") @@ -4224,7 +4285,7 @@ def mbcrea_enum_morph_items_update(self, context): global mbcrea_combined_morph_list mbcrea_combined_morph_list = algorithms.create_enum_property_items(props) return mbcrea_combined_morph_list - + bpy.types.Scene.mbcrea_morphs_items_1 = bpy.props.EnumProperty( items=mbcrea_enum_morph_items_update, name="", @@ -4300,7 +4361,7 @@ def morphs_items_minmax(box, items_str, minmax_str): bpy.types.Scene.mbcrea_integrate_material = bpy.props.BoolProperty( name="Integrate material", description="You can integrate the material or not.") - + bpy.types.Scene.mbcrea_special_preset = bpy.props.BoolProperty( name="Special", description="If the preset is special or common") @@ -4323,7 +4384,7 @@ def mbcrea_enum_transfor_category(self, context): name = "Tone" mbcrea_transfor_category_list.append((key, name, name)) return mbcrea_transfor_category_list - + bpy.types.Scene.mbcrea_transfor_category = bpy.props.EnumProperty( items=mbcrea_enum_transfor_category, @@ -4362,7 +4423,7 @@ def update_cmd_file(self, context): name="Spectrum", update=update_cmd_file, default="GE") - + bpy.types.Scene.mbcrea_gender_files_in = bpy.props.EnumProperty( items=morphcreator.get_gender_type_files(mblab_humanoid, "Gender"), name="Gender", @@ -4384,7 +4445,7 @@ def get_morph_file_categories(self, context): def update_cmd_categories(self, context): morphcreator.update_cmd_morphs() - + bpy.types.Scene.mbcrea_file_categories_content = bpy.props.EnumProperty( items=get_morph_file_categories, name="Category", @@ -4442,10 +4503,10 @@ def update_cmd_categories(self, context): name="", default="None", ) - + def update_template_list(self, context): return creation_tools_ops.get_templates_list() - + bpy.types.Scene.mbcrea_template_list = bpy.props.EnumProperty( items=update_template_list, name="", @@ -4459,7 +4520,7 @@ def update_template_new_name(self, context): return txt += "_" + scn.mbcrea_gender_list + "_base" creation_tools_ops.add_content("templates_list", None, txt) - + bpy.types.Scene.mbcrea_template_new_name = bpy.props.StringProperty( name="", description="The name for the template", @@ -4509,7 +4570,7 @@ def update_meshes_show(self, context): def get_character_list(self, context): return creation_tools_ops.get_character_list() - + def get_character_list_without(self, context): return creation_tools_ops.get_character_list(with_new=False) @@ -4582,47 +4643,47 @@ def update_character_new_name(self, context): def update_texture_items(self, context): return creation_tools_ops.get_file_list("textures", file_type="png") - + bpy.types.Scene.mbcrea_texture_albedo = bpy.props.EnumProperty( items=update_texture_items, name="Albedo", default=None) - + bpy.types.Scene.mbcrea_texture_bump = bpy.props.EnumProperty( items=update_texture_items, name="Bump", default=None) - + bpy.types.Scene.mbcrea_texture_displacement = bpy.props.EnumProperty( items=update_texture_items, name="Displacement", default=None) - + bpy.types.Scene.mbcrea_texture_subdermal = bpy.props.EnumProperty( items=update_texture_items, name="Subdermal", default=None) - + bpy.types.Scene.mbcrea_texture_thickness = bpy.props.EnumProperty( items=update_texture_items, name="Thickness", default=None) - + bpy.types.Scene.mbcrea_texture_frecklemask = bpy.props.EnumProperty( items=update_texture_items, name="Freckle mask", default=None) - + bpy.types.Scene.mbcrea_texture_blush = bpy.props.EnumProperty( items=update_texture_items, name="Blush", default=None) - + bpy.types.Scene.mbcrea_texture_sebum = bpy.props.EnumProperty( items=update_texture_items, name="Sebum", default=None) - + bpy.types.Scene.mbcrea_texture_eyes = bpy.props.EnumProperty( items=update_texture_items, name="Eyes", @@ -4632,47 +4693,47 @@ def update_texture_items(self, context): items=update_texture_items, name="Eyelash albedo", default=None) - + bpy.types.Scene.mbcrea_texture_iris_color = bpy.props.EnumProperty( items=update_texture_items, name="Iris color", default=None) - + bpy.types.Scene.mbcrea_texture_iris_bump = bpy.props.EnumProperty( items=update_texture_items, name="Iris bump", default=None) - + bpy.types.Scene.mbcrea_texture_sclera_color = bpy.props.EnumProperty( items=update_texture_items, name="Sclera color", default=None) - + bpy.types.Scene.mbcrea_texture_sclera_mask = bpy.props.EnumProperty( items=update_texture_items, name="Mask", default=None) - + bpy.types.Scene.mbcrea_texture_translucent_mask = bpy.props.EnumProperty( items=update_texture_items, name="Transluscent", default=None) - + bpy.types.Scene.mbcrea_texture_lipmap = bpy.props.EnumProperty( items=update_texture_items, name="Lip map", default=None) - + bpy.types.Scene.mbcrea_texture_tongue_albedo = bpy.props.EnumProperty( items=update_texture_items, name="Tongue albedo", default=None) - + bpy.types.Scene.mbcrea_texture_teeth_albedo = bpy.props.EnumProperty( items=update_texture_items, name="Teeth albedo", default=None) - + bpy.types.Scene.mbcrea_texture_nails_albedo = bpy.props.EnumProperty( items=update_texture_items, name="Nails albedo", @@ -4680,7 +4741,7 @@ def update_texture_items(self, context): def update_morph_items(self, context): return creation_tools_ops.get_file_list("morphs", file_type="json") - + bpy.types.Scene.mbcrea_shared_morphs_file = bpy.props.EnumProperty( items=update_morph_items, name="Main morphs", @@ -4693,7 +4754,7 @@ def update_morph_items(self, context): def update_bboxes_items(self, context): return creation_tools_ops.get_file_list("bboxes", file_type="json") - + bpy.types.Scene.mbcrea_bboxes_file = bpy.props.EnumProperty( items=update_bboxes_items, name="BBoxes", @@ -4701,7 +4762,7 @@ def update_bboxes_items(self, context): def update_joints_items(self, context): return creation_tools_ops.get_file_list("joints", file_type="json") - + bpy.types.Scene.mbcrea_joints_base_file = bpy.props.EnumProperty( items=update_joints_items, name="Base joints", @@ -4714,7 +4775,7 @@ def update_joints_items(self, context): def update_measures_items(self, context): return creation_tools_ops.get_file_list("measures", file_type="json") - + bpy.types.Scene.mbcrea_measures_file = bpy.props.EnumProperty( items=update_measures_items, name="Measures", @@ -4722,7 +4783,7 @@ def update_measures_items(self, context): def update_vgroups_items(self, context): return creation_tools_ops.get_file_list("vgroups", file_type="json") - + bpy.types.Scene.mbcrea_vgroups_base_file = bpy.props.EnumProperty( items=update_vgroups_items, name="VGroups base", @@ -4735,7 +4796,7 @@ def update_vgroups_items(self, context): def update_transfor_items(self, context): return creation_tools_ops.get_file_list("transformations", file_type="json") - + bpy.types.Scene.mbcrea_transfor_file = bpy.props.EnumProperty( items=update_transfor_items, name="Transformations", @@ -4743,7 +4804,7 @@ def update_transfor_items(self, context): def update_presets_folder(self, context): return creation_tools_ops.get_presets_folder_list() - + bpy.types.Scene.mbcrea_presets_folder = bpy.props.EnumProperty( items=update_presets_folder, name="Presets folder", @@ -4783,7 +4844,7 @@ def toggle_edit_object(self, context): bpy.ops.object.mode_set(mode='WEIGHT_PAINT') else: bpy.ops.object.mode_set(mode='OBJECT') - + bpy.types.Scene.mbcrea_toggle_edit_object = bpy.props.EnumProperty( items=[ ('OBJECT', 'Object', 'Object mode'), @@ -4796,7 +4857,7 @@ def toggle_edit_object(self, context): bpy.types.Scene.mbcrea_unselect_before = bpy.props.BoolProperty( name="Unselect all before", description="Unselect all before select\nnew vertices/edges/faces") - + bpy.types.Scene.mbcrea_measures_file_name = bpy.props.StringProperty( name="Other", description="Another name if you want to create a new measures file", @@ -5344,7 +5405,7 @@ def get_transfor_filepath(): name = tmp[0] + "_" + tmp[1] + "_" + algorithms.split_name(scn.mbcrea_agemasstone_name.lower()) + "_transf.json" filepath = os.path.join(file_ops.get_data_path(), "transformations", name) return filepath - + class ButtonTransforSave(bpy.types.Operator): bl_label = 'Save step / Finalize' bl_idname = 'mbcrea.button_transfor_save' @@ -5424,13 +5485,13 @@ def execute(self, context): #-------------------- mbcrea_transfor.check_compatibility_with_current_model(self.filepath) return {'FINISHED'} - + def ShowMessageBox(self, message = "", title = "Error !", icon = 'ERROR'): def draw(self, context): self.layout.label(text=message) bpy.context.window_manager.popup_menu(draw, title = title, icon = icon) - + class LoadTransformationFile(bpy.types.Operator, ImportHelper): @@ -5454,7 +5515,7 @@ def execute(self, context): #-------------------- mbcrea_transfor.load_transformation_from_file(self.filepath) return {'FINISHED'} - + def ShowMessageBox(self, message = "", title = "Error !", icon = 'ERROR'): def draw(self, context): @@ -5512,7 +5573,7 @@ def get_cmd_input_file_name(): if morphcreator.get_spectrum(scn.mbcrea_cmd_spectrum) == "Gender": return scn.mbcrea_gender_files_in return scn.mbcrea_body_type_files_in - + class ButtonCopyMorphs(bpy.types.Operator): bl_label = 'Copy to output file' bl_idname = 'mbcrea.button_copy_morph' @@ -5590,7 +5651,7 @@ class ButtonCompatToolsDir(bpy.types.Operator): @classmethod def poll(self, context): return not creation_tools_ops.is_directories_created() - + def execute(self, context): pn = creation_tools_ops.get_data_directory() creation_tools_ops.create_needed_directories(pn) @@ -5744,7 +5805,7 @@ def execute(self, context): scn = bpy.context.scene base = [] sculpted = [] - + try: base = morphcreator.get_vertices_list(0) except: @@ -6751,7 +6812,11 @@ def execute(self, context): ButtonCreateVGroupsBaseFile, ButtonCreateVGroupsMusclesFile, ButtonSaveVGroupsBaseFile, - ButtonSaveVGroupsMuscleFile + ButtonSaveVGroupsMuscleFile, + GuideProp, + AddScalp, + VertexGrouptoHair, + BakeHairShape, ) def register(): @@ -6763,6 +6828,8 @@ def register(): # register the example panel, to show updater buttons for cls in classes: bpy.utils.register_class(cls) + #curve guide property + bpy.types.Scene.add_guide = bpy.props.PointerProperty(type=GuideProp) def unregister(): @@ -6772,7 +6839,8 @@ def unregister(): # register the example panel, to show updater buttons for cls in reversed(classes): bpy.utils.unregister_class(cls) - + #curve guide property + del bpy.types.Scene.add_guide if __name__ == "__main__": register() diff --git a/algorithms.py b/algorithms.py index 9791317b..0b75003f 100644 --- a/algorithms.py +++ b/algorithms.py @@ -1066,7 +1066,7 @@ def apply_modifier(obj, modifier): if modifier_name in obj.modifiers: set_active_object(obj) try: - bpy.ops.object.modifier_apply(apply_as='DATA', modifier=modifier_name) + bpy.ops.object.modifier_apply(modifier=modifier_name) except AttributeError: logger.warning("Problems in applying %s. Is the modifier disabled?", modifier_name)